[libosmium] 01/07: Imported Upstream version 2.4.0
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Sat Aug 29 11:17:33 UTC 2015
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository libosmium.
commit 93fff149e7a19202e1307c9f5b1443968b081b72
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Sat Aug 29 12:04:56 2015 +0200
Imported Upstream version 2.4.0
---
CHANGELOG.md | 34 ++-
CMakeLists.txt | 28 +-
appveyor.yml | 31 +--
cmake/FindOsmium.cmake | 69 ++---
examples/CMakeLists.txt | 26 +-
examples/osmium_toogr.cpp | 244 -----------------
examples/osmium_toogr2.cpp | 331 -----------------------
examples/osmium_toogr2_exp.cpp | 305 ---------------------
include/gdalcpp.hpp | 302 +++++++++++++++++++++
include/osmium/area/problem_reporter_ogr.hpp | 130 ++-------
include/osmium/builder/osm_object_builder.hpp | 67 ++---
include/osmium/geom/factory.hpp | 1 +
include/osmium/geom/ogr.hpp | 30 +-
include/osmium/geom/tile.hpp | 4 +-
include/osmium/io/detail/debug_output_format.hpp | 4 +-
include/osmium/io/detail/input_format.hpp | 11 +-
include/osmium/io/detail/output_format.hpp | 4 +-
include/osmium/io/detail/pbf_decoder.hpp | 29 +-
include/osmium/io/detail/pbf_output_format.hpp | 32 ++-
include/osmium/io/detail/read_write.hpp | 3 +
include/osmium/io/detail/string_table.hpp | 28 +-
include/osmium/io/file.hpp | 3 +-
include/osmium/io/reader.hpp | 6 +-
include/osmium/io/writer.hpp | 2 +-
include/osmium/osm/crc.hpp | 36 +--
include/osmium/osm/types.hpp | 3 +
include/osmium/util/delta.hpp | 8 +-
include/osmium/util/memory_mapping.hpp | 7 +
include/protozero/varint.hpp | 4 -
include/protozero/version.hpp | 22 ++
scripts/travis_script.sh | 7 +
test/data-tests/testdata-multipolygon.cpp | 171 +++---------
test/data-tests/testdata-overview.cpp | 154 ++---------
test/t/basic/test_crc.cpp | 21 ++
test/t/basic/test_relation.cpp | 11 +
test/t/tags/test_tag_list.cpp | 11 +
36 files changed, 691 insertions(+), 1488 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 22eb06a..9b7bd8d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,35 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
+
+## [2.4.0] - 2015-08-29
+
+### Added
+
+- Checks that user names, member roles and tag keys and values are not longer
+ than 256 * 4 bytes. That is the maximum length 256 Unicode characters
+ can have in UTF-8 encoding.
+- Support for GDAL 2. GDAL 1 still works.
+
+### Changed
+
+- Improved CMake build scripts.
+- Updated internal version of Protozero to 1.1.0.
+- Removed `toogr*` examples. They are in their own repository now.
+ See https://github.com/osmcode/osm-gis-export.
+- Files about to be memory-mapped (for instance index files) are now set
+ to binary mode on Windows so the application doesn't have to do this.
+
+### Fixed
+
+- Hanging program when trying to open file with an unknown file format.
+- Building problems with old boost versions.
+- Initialization errors in PBF writer.
+- Bug in byte swap code.
+- Output on Windows now always uses binary mode, even when writing to
+ stdout, so OSM xml and opl files always use LF line endings.
+
+
## [2.3.0] - 2015-08-18
### Added
@@ -108,8 +137,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
Doxygen (up to version 1.8.8). This version contains a workaround to fix
this.
-[unreleased]: https://github.com/osmcode/libosmium/compare/v2.3.0...HEAD
-[2.3.0]: https://github.com/osmcode/libosmium/compare/v2.3.0...v2.3.0
+[unreleased]: https://github.com/osmcode/libosmium/compare/v2.4.0...HEAD
+[2.4.0]: https://github.com/osmcode/libosmium/compare/v2.3.0...v2.4.0
+[2.3.0]: https://github.com/osmcode/libosmium/compare/v2.2.0...v2.3.0
[2.2.0]: https://github.com/osmcode/libosmium/compare/v2.1.0...v2.2.0
[2.1.0]: https://github.com/osmcode/libosmium/compare/v2.0.0...v2.1.0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fba967a..fc08036 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,13 +26,11 @@ set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel;Dev;Cover
project(libosmium)
set(LIBOSMIUM_VERSION_MAJOR 2)
-set(LIBOSMIUM_VERSION_MINOR 3)
+set(LIBOSMIUM_VERSION_MINOR 4)
set(LIBOSMIUM_VERSION_PATCH 0)
set(LIBOSMIUM_VERSION
- "${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}"
- CACHE STRING
- "Libosmium version")
+ "${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}")
#-----------------------------------------------------------------------------
@@ -118,29 +116,39 @@ find_package(Boost 1.38)
mark_as_advanced(CLEAR BOOST_ROOT)
if(Boost_FOUND)
- include_directories(${Boost_INCLUDE_DIRS})
+ include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
else()
set(BOOST_ROOT "NOT FOUND: please choose" CACHE PATH "")
message(FATAL_ERROR "PLEASE, specify the directory where the Boost library is installed in BOOST_ROOT")
endif()
-set(OSMIUM_INCLUDE_DIR include)
+# set OSMIUM_INCLUDE_DIR so FindOsmium will not set anything different
+set(OSMIUM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include")
+
+include_directories(${OSMIUM_INCLUDE_DIR})
+
find_package(Osmium COMPONENTS io gdal geos proj sparsehash)
-include_directories(${OSMIUM_INCLUDE_DIRS})
+
+# The find_package put the directory where it found the libosmium includes
+# into OSMIUM_INCLUDE_DIRS. We remove it again, because we want to make
+# sure to use our own include directory already set up above.
+list(FIND OSMIUM_INCLUDE_DIRS "${OSMIUM_INCLUDE_DIR}" _own_index)
+list(REMOVE_AT OSMIUM_INCLUDE_DIRS ${_own_index})
+set(_own_index)
+
+include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
if(MSVC)
find_path(GETOPT_INCLUDE_DIR getopt.h)
find_library(GETOPT_LIBRARY NAMES wingetopt)
if(GETOPT_INCLUDE_DIR AND GETOPT_LIBRARY)
- include_directories(${GETOPT_INCLUDE_DIR})
+ include_directories(SYSTEM ${GETOPT_INCLUDE_DIR})
list(APPEND OSMIUM_LIBRARIES ${GETOPT_LIBRARY})
else()
set(GETOPT_MISSING 1)
endif()
endif()
-include_directories(include)
-
#-----------------------------------------------------------------------------
#
diff --git a/appveyor.yml b/appveyor.yml
index a05c396..8244d98 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -9,16 +9,10 @@ environment:
- config: Dev
- config: RelWithDebInfo
-# branches to build
-branches:
- # whitelist
- only:
- - master
-
shallow_clone: true
# Operating system (build VM template)
-os: Visual Studio 2014 CTP4
+os: Visual Studio 2015
# scripts that are called at very beginning, before repo cloning
init:
@@ -46,6 +40,8 @@ install:
- set PATH=%LODEPSDIR%\expat\lib;%PATH%
#libtiff.dll
- set PATH=%LODEPSDIR%\libtiff\lib;%PATH%
+ #jpeg.dll
+ - set PATH=%LODEPSDIR%\jpeg\lib;%PATH%
#zlibwapi.dll
- set PATH=%LODEPSDIR%\zlib\lib;%PATH%
#convert backslashes in bzip2 path to forward slashes
@@ -71,27 +67,16 @@ build_script:
# This will produce lots of LNK4099 warnings which can be ignored.
# Unfortunately they can't be disabled, see
# http://stackoverflow.com/questions/661606/visual-c-how-to-disable-specific-linker-warnings
- - cmake .. -LA -G "Visual Studio 14 Win64"
+ - cmake -LA -G "Visual Studio 14 Win64"
-DOsmium_DEBUG=TRUE
-DCMAKE_BUILD_TYPE=%config%
-DBUILD_HEADERS=OFF
-DBOOST_ROOT=%LODEPSDIR%\boost
- -DBoost_PROGRAM_OPTIONS_LIBRARY=%LODEPSDIR%\boost\lib\libboost_program_options-vc140-mt-1_57.lib
+ -DBoost_PROGRAM_OPTIONS_LIBRARY=%LODEPSDIR%\boost\lib\libboost_program_options-vc140-mt-1_58.lib
-DZLIB_LIBRARY=%LODEPSDIR%\zlib\lib\zlibwapi.lib
- -DZLIB_INCLUDE_DIR=%LODEPSDIR%\zlib\include
- -DEXPAT_LIBRARY=%LODEPSDIR%\expat\lib\libexpat.lib
- -DEXPAT_INCLUDE_DIR=%LODEPSDIR%\expat\include
- -DBZIP2_LIBRARIES=%LIBBZIP2%
- -DBZIP2_INCLUDE_DIR=%LODEPSDIR%\bzip2\include
- -DGDAL_LIBRARY=%LODEPSDIR%\gdal\lib\gdal_i.lib
- -DGDAL_INCLUDE_DIR=%LODEPSDIR%\gdal\include
- -DGEOS_LIBRARY=%LODEPSDIR%\geos\lib\geos.lib
- -DGEOS_INCLUDE_DIR=%LODEPSDIR%\geos\include
- -DPROJ_LIBRARY=%LODEPSDIR%\proj\lib\proj.lib
- -DPROJ_INCLUDE_DIR=%LODEPSDIR%\proj\include
- -DSPARSEHASH_INCLUDE_DIR=%LODEPSDIR%\sparsehash\include
- -DGETOPT_LIBRARY=%LODEPSDIR%\wingetopt\lib\wingetopt.lib
- -DGETOPT_INCLUDE_DIR=%LODEPSDIR%\wingetopt\include
+ -DBZIP2_LIBRARY_RELEASE=%LIBBZIP2%
+ -DCMAKE_PREFIX_PATH=%LODEPSDIR%\zlib;%LODEPSDIR%\expat;%LODEPSDIR%\bzip2;%LODEPSDIR%\geos;%LODEPSDIR%\gdal;%LODEPSDIR%\proj;%LODEPSDIR%\sparsehash;%LODEPSDIR%\wingetopt
+ ..
- msbuild libosmium.sln /p:Configuration=%config% /toolsversion:14.0 /p:Platform=x64 /p:PlatformToolset=v140
#- cmake .. -LA -G "NMake Makefiles"
# -DOsmium_DEBUG=TRUE
diff --git a/cmake/FindOsmium.cmake b/cmake/FindOsmium.cmake
index bb14071..b3a4c95 100644
--- a/cmake/FindOsmium.cmake
+++ b/cmake/FindOsmium.cmake
@@ -19,7 +19,7 @@
# Then add the following in your CMakeLists.txt:
#
# find_package(Osmium REQUIRED COMPONENTS <XXX>)
-# include_directories(${OSMIUM_INCLUDE_DIRS})
+# include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
#
# For the <XXX> substitute a space separated list of one or more of the
# following components:
@@ -56,32 +56,12 @@ find_path(OSMIUM_INCLUDE_DIR osmium/osm.hpp
PATH_SUFFIXES include
PATHS
../libosmium
- ../../libosmium
- libosmium
~/Library/Frameworks
/Library/Frameworks
- /usr/local
- /usr/
/opt/local # DarwinPorts
/opt
)
-# Handle the QUIETLY and REQUIRED arguments and set OSMIUM_FOUND to TRUE if
-# all listed variables are TRUE.
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(OSMIUM REQUIRED_VARS OSMIUM_INCLUDE_DIR)
-
-# Copy the results to the output variables.
-if(OSMIUM_FOUND)
- set(OSMIUM_INCLUDE_DIRS ${OSMIUM_INCLUDE_DIR})
-else()
- set(OSMIUM_INCLUDE_DIRS "")
-endif()
-
-if(Osmium_FIND_REQUIRED AND NOT OSMIUM_FOUND)
- message(FATAL_ERROR "Can not find libosmium headers, please install them or configure the paths")
-endif()
-
#----------------------------------------------------------------------
#
# Check for optional components
@@ -113,6 +93,7 @@ if(Osmium_USE_PBF)
find_package(ZLIB)
find_package(Threads)
+ list(APPEND OSMIUM_EXTRA_FIND_VARS ZLIB_FOUND Threads_FOUND)
if(ZLIB_FOUND AND Threads_FOUND)
list(APPEND OSMIUM_PBF_LIBRARIES
${ZLIB_LIBRARIES}
@@ -125,7 +106,6 @@ if(Osmium_USE_PBF)
${ZLIB_INCLUDE_DIR}
)
else()
- set(_missing_libraries 1)
message(WARNING "Osmium: Can not find some libraries for PBF input/output, please install them or configure the paths.")
endif()
endif()
@@ -138,6 +118,7 @@ if(Osmium_USE_XML)
find_package(ZLIB)
find_package(Threads)
+ list(APPEND OSMIUM_EXTRA_FIND_VARS EXPAT_FOUND BZIP2_FOUND ZLIB_FOUND Threads_FOUND)
if(EXPAT_FOUND AND BZIP2_FOUND AND ZLIB_FOUND AND Threads_FOUND)
list(APPEND OSMIUM_XML_LIBRARIES
${EXPAT_LIBRARIES}
@@ -151,7 +132,6 @@ if(Osmium_USE_XML)
${ZLIB_INCLUDE_DIR}
)
else()
- set(_missing_libraries 1)
message(WARNING "Osmium: Can not find some libraries for XML input/output, please install them or configure the paths.")
endif()
endif()
@@ -172,12 +152,12 @@ if(Osmium_USE_GEOS)
find_path(GEOS_INCLUDE_DIR geos/geom.h)
find_library(GEOS_LIBRARY NAMES geos)
+ list(APPEND OSMIUM_EXTRA_FIND_VARS GEOS_INCLUDE_DIR GEOS_LIBRARY)
if(GEOS_INCLUDE_DIR AND GEOS_LIBRARY)
SET(GEOS_FOUND 1)
list(APPEND OSMIUM_LIBRARIES ${GEOS_LIBRARY})
list(APPEND OSMIUM_INCLUDE_DIRS ${GEOS_INCLUDE_DIR})
else()
- set(_missing_libraries 1)
message(WARNING "Osmium: GEOS library is required but not found, please install it or configure the paths.")
endif()
endif()
@@ -187,11 +167,11 @@ endif()
if(Osmium_USE_GDAL)
find_package(GDAL)
+ list(APPEND OSMIUM_EXTRA_FIND_VARS GDAL_FOUND)
if(GDAL_FOUND)
list(APPEND OSMIUM_LIBRARIES ${GDAL_LIBRARIES})
list(APPEND OSMIUM_INCLUDE_DIRS ${GDAL_INCLUDE_DIRS})
else()
- set(_missing_libraries 1)
message(WARNING "Osmium: GDAL library is required but not found, please install it or configure the paths.")
endif()
endif()
@@ -202,12 +182,12 @@ if(Osmium_USE_PROJ)
find_path(PROJ_INCLUDE_DIR proj_api.h)
find_library(PROJ_LIBRARY NAMES proj)
+ list(APPEND OSMIUM_EXTRA_FIND_VARS PROJ_INCLUDE_DIR PROJ_LIBRARY)
if(PROJ_INCLUDE_DIR AND PROJ_LIBRARY)
set(PROJ_FOUND 1)
list(APPEND OSMIUM_LIBRARIES ${PROJ_LIBRARY})
list(APPEND OSMIUM_INCLUDE_DIRS ${PROJ_INCLUDE_DIR})
else()
- set(_missing_libraries 1)
message(WARNING "Osmium: PROJ.4 library is required but not found, please install it or configure the paths.")
endif()
endif()
@@ -217,21 +197,19 @@ endif()
if(Osmium_USE_SPARSEHASH)
find_path(SPARSEHASH_INCLUDE_DIR google/sparsetable)
+ list(APPEND OSMIUM_EXTRA_FIND_VARS SPARSEHASH_INCLUDE_DIR)
if(SPARSEHASH_INCLUDE_DIR)
# Find size of sparsetable::size_type. This does not work on older
# CMake versions because they can do this check only in C, not in C++.
- include(CheckTypeSize)
- set(CMAKE_REQUIRED_INCLUDES ${SPARSEHASH_INCLUDE_DIR})
- set(CMAKE_EXTRA_INCLUDE_FILES "google/sparsetable")
- check_type_size("google::sparsetable<int>::size_type" SPARSETABLE_SIZE_TYPE LANGUAGE CXX)
- set(CMAKE_EXTRA_INCLUDE_FILES)
- set(CMAKE_REQUIRED_INCLUDES)
-
- # Falling back to checking size_t if google::sparsetable<int>::size_type
- # could not be checked.
- if(SPARSETABLE_SIZE_TYPE STREQUAL "")
- check_type_size("void*" VOID_PTR_SIZE)
- set(SPARSETABLE_SIZE_TYPE ${VOID_PTR_SIZE})
+ if (NOT CMAKE_VERSION VERSION_LESS 3.0)
+ include(CheckTypeSize)
+ set(CMAKE_REQUIRED_INCLUDES ${SPARSEHASH_INCLUDE_DIR})
+ set(CMAKE_EXTRA_INCLUDE_FILES "google/sparsetable")
+ check_type_size("google::sparsetable<int>::size_type" SPARSETABLE_SIZE_TYPE LANGUAGE CXX)
+ set(CMAKE_EXTRA_INCLUDE_FILES)
+ set(CMAKE_REQUIRED_INCLUDES)
+ else()
+ set(SPARSETABLE_SIZE_TYPE ${CMAKE_SIZEOF_VOID_P})
endif()
# Sparsetable::size_type must be at least 8 bytes (64bit), otherwise
@@ -244,7 +222,6 @@ if(Osmium_USE_SPARSEHASH)
message(WARNING "Osmium: Disabled Google SparseHash library on 32bit system (size_type=${SPARSETABLE_SIZE_TYPE}).")
endif()
else()
- set(_missing_libraries 1)
message(WARNING "Osmium: Google SparseHash library is required but not found, please install it or configure the paths.")
endif()
endif()
@@ -274,8 +251,18 @@ endif()
# Check that all required libraries are available
#
#----------------------------------------------------------------------
-if(Osmium_FIND_REQUIRED AND _missing_libraries)
- message(FATAL_ERROR "Required library or libraries missing. Aborting.")
+list(REMOVE_DUPLICATES OSMIUM_EXTRA_FIND_VARS)
+# Handle the QUIETLY and REQUIRED arguments and set OSMIUM_FOUND to TRUE if
+# all listed variables are TRUE.
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Osmium REQUIRED_VARS OSMIUM_INCLUDE_DIR ${OSMIUM_EXTRA_FIND_VARS})
+unset(OSMIUM_EXTRA_FIND_VARS)
+
+# Copy the results to the output variables.
+if(OSMIUM_FOUND)
+ set(OSMIUM_INCLUDE_DIRS ${OSMIUM_INCLUDE_DIR} ${OSMIUM_INCLUDE_DIRS})
+else()
+ set(OSMIUM_INCLUDE_DIRS "")
endif()
#----------------------------------------------------------------------
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index c9f5960..2ee15e1 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -17,9 +17,6 @@ set(EXAMPLES
index
read
serdump
- toogr
- toogr2
- toogr2_exp
use_node_cache
CACHE STRING "Example programs"
)
@@ -30,7 +27,7 @@ set(EXAMPLES
# Examples depending on wingetopt
#
#-----------------------------------------------------------------------------
-set(GETOPT_EXAMPLES area_test convert serdump toogr toogr2 toogr2_exp)
+set(GETOPT_EXAMPLES area_test convert serdump)
if(NOT GETOPT_MISSING)
foreach(example ${GETOPT_EXAMPLES})
list(APPEND EXAMPLE_LIBS_${example} ${GETOPT_LIBRARY})
@@ -76,27 +73,6 @@ endif()
#-----------------------------------------------------------------------------
#
-# Examples depending on GDAL/PROJ.4/SparseHash
-#
-#-----------------------------------------------------------------------------
-set(OGR_EXAMPLES toogr toogr2 toogr2_exp)
-
-if(GDAL_FOUND AND PROJ_FOUND AND SPARSEHASH_FOUND)
- foreach(example ${OGR_EXAMPLES})
- list(APPEND EXAMPLE_LIBS_${example} ${GDAL_LIBRARIES})
- list(APPEND EXAMPLE_LIBS_${example} ${PROJ_LIBRARIES})
- endforeach()
-else()
- message(STATUS "Configuring examples - Skipping examples because GDAL and/or Proj.4 and/or SparseHash not found:")
- foreach(example ${OGR_EXAMPLES})
- message(STATUS " - osmium_${example}")
- list(REMOVE_ITEM EXAMPLES ${example})
- endforeach()
-endif()
-
-
-#-----------------------------------------------------------------------------
-#
# Configure examples
#
#-----------------------------------------------------------------------------
diff --git a/examples/osmium_toogr.cpp b/examples/osmium_toogr.cpp
deleted file mode 100644
index 7c5a965..0000000
--- a/examples/osmium_toogr.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
-
- This is an example tool that converts OSM data to some output format
- like Spatialite or Shapefiles using the OGR library.
-
- The code in this example file is released into the Public Domain.
-
-*/
-
-#include <iostream>
-#include <getopt.h>
-
-#include <osmium/index/map/all.hpp>
-#include <osmium/handler/node_locations_for_ways.hpp>
-#include <osmium/visitor.hpp>
-
-#include <osmium/geom/ogr.hpp>
-#include <osmium/io/any_input.hpp>
-#include <osmium/handler.hpp>
-
-typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_neg_type;
-typedef osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
-
-typedef osmium::handler::NodeLocationsForWays<index_pos_type, index_neg_type> location_handler_type;
-
-class MyOGRHandler : public osmium::handler::Handler {
-
- OGRDataSource* m_data_source;
- OGRLayer* m_layer_point;
- OGRLayer* m_layer_linestring;
-
- osmium::geom::OGRFactory<> m_factory;
-
-public:
-
- MyOGRHandler(const std::string& driver_name, const std::string& filename) {
-
- OGRRegisterAll();
-
- OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str());
- if (!driver) {
- std::cerr << driver_name << " driver not available.\n";
- exit(1);
- }
-
- CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
- const char* options[] = { "SPATIALITE=TRUE", nullptr };
- m_data_source = driver->CreateDataSource(filename.c_str(), const_cast<char**>(options));
- if (!m_data_source) {
- std::cerr << "Creation of output file failed.\n";
- exit(1);
- }
-
- OGRSpatialReference sparef;
- sparef.SetWellKnownGeogCS("WGS84");
- m_layer_point = m_data_source->CreateLayer("postboxes", &sparef, wkbPoint, nullptr);
- if (!m_layer_point) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_point_field_id("id", OFTReal);
- layer_point_field_id.SetWidth(10);
-
- if (m_layer_point->CreateField(&layer_point_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_point_field_operator("operator", OFTString);
- layer_point_field_operator.SetWidth(30);
-
- if (m_layer_point->CreateField(&layer_point_field_operator) != OGRERR_NONE) {
- std::cerr << "Creating operator field failed.\n";
- exit(1);
- }
-
- /* Transactions might make things faster, then again they might not.
- Feel free to experiment and benchmark and report back. */
- m_layer_point->StartTransaction();
-
- m_layer_linestring = m_data_source->CreateLayer("roads", &sparef, wkbLineString, nullptr);
- if (!m_layer_linestring) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_linestring_field_id("id", OFTReal);
- layer_linestring_field_id.SetWidth(10);
-
- if (m_layer_linestring->CreateField(&layer_linestring_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_linestring_field_type("type", OFTString);
- layer_linestring_field_type.SetWidth(30);
-
- if (m_layer_linestring->CreateField(&layer_linestring_field_type) != OGRERR_NONE) {
- std::cerr << "Creating type field failed.\n";
- exit(1);
- }
-
- m_layer_linestring->StartTransaction();
- }
-
- ~MyOGRHandler() {
- m_layer_linestring->CommitTransaction();
- m_layer_point->CommitTransaction();
- OGRDataSource::DestroyDataSource(m_data_source);
- OGRCleanupAll();
- }
-
- void node(const osmium::Node& node) {
- const char* amenity = node.tags().get_value_by_key("amenity");
- if (amenity && !strcmp(amenity, "post_box")) {
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_point->GetLayerDefn());
- std::unique_ptr<OGRPoint> ogr_point = m_factory.create_point(node);
- feature->SetGeometry(ogr_point.get());
- feature->SetField("id", static_cast<double>(node.id()));
- feature->SetField("operator", node.tags().get_value_by_key("operator"));
-
- if (m_layer_point->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
- }
- }
-
- void way(const osmium::Way& way) {
- const char* highway = way.tags().get_value_by_key("highway");
- if (highway) {
- try {
- std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way);
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_linestring->GetLayerDefn());
- feature->SetGeometry(ogr_linestring.get());
- feature->SetField("id", static_cast<double>(way.id()));
- feature->SetField("type", highway);
-
- if (m_layer_linestring->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
- } catch (osmium::geometry_error&) {
- std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n";
- }
- }
- }
-
-};
-
-/* ================================================== */
-
-void print_help() {
- std::cout << "osmium_toogr [OPTIONS] [INFILE [OUTFILE]]\n\n" \
- << "If INFILE is not given stdin is assumed.\n" \
- << "If OUTFILE is not given 'ogr_out' is used.\n" \
- << "\nOptions:\n" \
- << " -h, --help This help message\n" \
- << " -l, --location_store=TYPE Set location store\n" \
- << " -f, --format=FORMAT Output OGR format (Default: 'SQLite')\n" \
- << " -L See available location stores\n";
-}
-
-int main(int argc, char* argv[]) {
- const auto& map_factory = osmium::index::MapFactory<osmium::unsigned_object_id_type, osmium::Location>::instance();
-
- static struct option long_options[] = {
- {"help", no_argument, 0, 'h'},
- {"format", required_argument, 0, 'f'},
- {"location_store", required_argument, 0, 'l'},
- {"list_location_stores", no_argument, 0, 'L'},
- {0, 0, 0, 0}
- };
-
- std::string output_format { "SQLite" };
- std::string location_store { "sparse_mem_array" };
-
- while (true) {
- int c = getopt_long(argc, argv, "hf:l:L", long_options, 0);
- if (c == -1) {
- break;
- }
-
- switch (c) {
- case 'h':
- print_help();
- exit(0);
- case 'f':
- output_format = optarg;
- break;
- case 'l':
- location_store = optarg;
- break;
- case 'L':
- std::cout << "Available map types:\n";
- for (const auto& map_type : map_factory.map_types()) {
- std::cout << " " << map_type << "\n";
- }
- exit(0);
- default:
- exit(1);
- }
- }
-
- std::string input_filename;
- std::string output_filename("ogr_out");
- int remaining_args = argc - optind;
- if (remaining_args > 2) {
- std::cerr << "Usage: " << argv[0] << " [OPTIONS] [INFILE [OUTFILE]]" << std::endl;
- exit(1);
- } else if (remaining_args == 2) {
- input_filename = argv[optind];
- output_filename = argv[optind+1];
- } else if (remaining_args == 1) {
- input_filename = argv[optind];
- } else {
- input_filename = "-";
- }
-
- osmium::io::Reader reader(input_filename);
-
- std::unique_ptr<index_pos_type> index_pos = map_factory.create_map(location_store);
- index_neg_type index_neg;
- location_handler_type location_handler(*index_pos, index_neg);
- location_handler.ignore_errors();
-
- MyOGRHandler ogr_handler(output_format, output_filename);
-
- osmium::apply(reader, location_handler, ogr_handler);
- reader.close();
-
- int locations_fd = open("locations.dump", O_WRONLY | O_CREAT, 0644);
- if (locations_fd < 0) {
- throw std::system_error(errno, std::system_category(), "Open failed");
- }
- index_pos->dump_as_list(locations_fd);
- close(locations_fd);
-}
-
diff --git a/examples/osmium_toogr2.cpp b/examples/osmium_toogr2.cpp
deleted file mode 100644
index e1b5056..0000000
--- a/examples/osmium_toogr2.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
-
- This is an example tool that converts OSM data to some output format
- like Spatialite or Shapefiles using the OGR library.
-
- This version does multipolygon handling (in contrast to the osmium_toogr
- example which doesn't).
-
- The code in this example file is released into the Public Domain.
-
-*/
-
-#include <iostream>
-#include <getopt.h>
-
-// usually you only need one or two of these
-#include <osmium/index/map/dummy.hpp>
-#include <osmium/index/map/sparse_mem_array.hpp>
-
-#include <osmium/handler/node_locations_for_ways.hpp>
-#include <osmium/visitor.hpp>
-#include <osmium/area/multipolygon_collector.hpp>
-#include <osmium/area/assembler.hpp>
-
-#include <osmium/geom/mercator_projection.hpp>
-//#include <osmium/geom/projection.hpp>
-#include <osmium/geom/ogr.hpp>
-#include <osmium/io/any_input.hpp>
-#include <osmium/handler.hpp>
-
-typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_neg_type;
-
-typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
-
-typedef osmium::handler::NodeLocationsForWays<index_pos_type, index_neg_type> location_handler_type;
-
-class MyOGRHandler : public osmium::handler::Handler {
-
- OGRDataSource* m_data_source;
- OGRLayer* m_layer_point;
- OGRLayer* m_layer_linestring;
- OGRLayer* m_layer_polygon;
-
- // Choose one of the following:
-
- // 1. Use WGS84, do not project coordinates.
- //osmium::geom::OGRFactory<> m_factory {};
-
- // 2. Project coordinates into "Web Mercator".
- osmium::geom::OGRFactory<osmium::geom::MercatorProjection> m_factory;
-
- // 3. Use any projection that the proj library can handle.
- // (Initialize projection with EPSG code or proj string).
- // In addition you need to link with "-lproj" and add
- // #include <osmium/geom/projection.hpp>.
- //osmium::geom::OGRFactory<osmium::geom::Projection> m_factory {osmium::geom::Projection(3857)};
-
-public:
-
- MyOGRHandler(const std::string& driver_name, const std::string& filename) {
-
- OGRRegisterAll();
-
- OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str());
- if (!driver) {
- std::cerr << driver_name << " driver not available.\n";
- exit(1);
- }
-
- CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
- const char* options[] = { "SPATIALITE=TRUE", nullptr };
- m_data_source = driver->CreateDataSource(filename.c_str(), const_cast<char**>(options));
- if (!m_data_source) {
- std::cerr << "Creation of output file failed.\n";
- exit(1);
- }
-
- OGRSpatialReference sparef;
- sparef.importFromProj4(m_factory.proj_string().c_str());
-
- m_layer_point = m_data_source->CreateLayer("postboxes", &sparef, wkbPoint, nullptr);
- if (!m_layer_point) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_point_field_id("id", OFTReal);
- layer_point_field_id.SetWidth(10);
-
- if (m_layer_point->CreateField(&layer_point_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_point_field_operator("operator", OFTString);
- layer_point_field_operator.SetWidth(30);
-
- if (m_layer_point->CreateField(&layer_point_field_operator) != OGRERR_NONE) {
- std::cerr << "Creating operator field failed.\n";
- exit(1);
- }
-
- /* Transactions might make things faster, then again they might not.
- Feel free to experiment and benchmark and report back. */
- m_layer_point->StartTransaction();
-
- m_layer_linestring = m_data_source->CreateLayer("roads", &sparef, wkbLineString, nullptr);
- if (!m_layer_linestring) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_linestring_field_id("id", OFTReal);
- layer_linestring_field_id.SetWidth(10);
-
- if (m_layer_linestring->CreateField(&layer_linestring_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_linestring_field_type("type", OFTString);
- layer_linestring_field_type.SetWidth(30);
-
- if (m_layer_linestring->CreateField(&layer_linestring_field_type) != OGRERR_NONE) {
- std::cerr << "Creating type field failed.\n";
- exit(1);
- }
-
- m_layer_linestring->StartTransaction();
-
- m_layer_polygon = m_data_source->CreateLayer("buildings", &sparef, wkbMultiPolygon, nullptr);
- if (!m_layer_polygon) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_polygon_field_id("id", OFTInteger);
- layer_polygon_field_id.SetWidth(10);
-
- if (m_layer_polygon->CreateField(&layer_polygon_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_polygon_field_type("type", OFTString);
- layer_polygon_field_type.SetWidth(30);
-
- if (m_layer_polygon->CreateField(&layer_polygon_field_type) != OGRERR_NONE) {
- std::cerr << "Creating type field failed.\n";
- exit(1);
- }
-
- m_layer_polygon->StartTransaction();
- }
-
- ~MyOGRHandler() {
- m_layer_polygon->CommitTransaction();
- m_layer_linestring->CommitTransaction();
- m_layer_point->CommitTransaction();
- OGRDataSource::DestroyDataSource(m_data_source);
- OGRCleanupAll();
- }
-
- void node(const osmium::Node& node) {
- const char* amenity = node.tags()["amenity"];
- if (amenity && !strcmp(amenity, "post_box")) {
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_point->GetLayerDefn());
- std::unique_ptr<OGRPoint> ogr_point = m_factory.create_point(node);
- feature->SetGeometry(ogr_point.get());
- feature->SetField("id", static_cast<double>(node.id()));
- feature->SetField("operator", node.tags()["operator"]);
-
- if (m_layer_point->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
- }
- }
-
- void way(const osmium::Way& way) {
- const char* highway = way.tags()["highway"];
- if (highway) {
- try {
- std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way);
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_linestring->GetLayerDefn());
- feature->SetGeometry(ogr_linestring.get());
- feature->SetField("id", static_cast<double>(way.id()));
- feature->SetField("type", highway);
-
- if (m_layer_linestring->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
- } catch (osmium::geometry_error&) {
- std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n";
- }
- }
- }
-
- void area(const osmium::Area& area) {
- const char* building = area.tags()["building"];
- if (building) {
- try {
- std::unique_ptr<OGRMultiPolygon> ogr_polygon = m_factory.create_multipolygon(area);
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_polygon->GetLayerDefn());
- feature->SetGeometry(ogr_polygon.get());
- feature->SetField("id", static_cast<int>(area.id()));
- feature->SetField("type", building);
-
- std::string type = "";
- if (area.from_way()) {
- type += "w";
- } else {
- type += "r";
- }
- feature->SetField("type", type.c_str());
-
- if (m_layer_polygon->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
- } catch (osmium::geometry_error&) {
- std::cerr << "Ignoring illegal geometry for area " << area.id() << " created from " << (area.from_way() ? "way" : "relation") << " with id=" << area.orig_id() << ".\n";
- }
- }
- }
-
-};
-
-/* ================================================== */
-
-void print_help() {
- std::cout << "osmium_toogr [OPTIONS] [INFILE [OUTFILE]]\n\n" \
- << "If INFILE is not given stdin is assumed.\n" \
- << "If OUTFILE is not given 'ogr_out' is used.\n" \
- << "\nOptions:\n" \
- << " -h, --help This help message\n" \
- << " -d, --debug Enable debug output\n" \
- << " -f, --format=FORMAT Output OGR format (Default: 'SQLite')\n";
-}
-
-int main(int argc, char* argv[]) {
- static struct option long_options[] = {
- {"help", no_argument, 0, 'h'},
- {"debug", no_argument, 0, 'd'},
- {"format", required_argument, 0, 'f'},
- {0, 0, 0, 0}
- };
-
- std::string output_format("SQLite");
- bool debug = false;
-
- while (true) {
- int c = getopt_long(argc, argv, "hdf:", long_options, 0);
- if (c == -1) {
- break;
- }
-
- switch (c) {
- case 'h':
- print_help();
- exit(0);
- case 'd':
- debug = true;
- break;
- case 'f':
- output_format = optarg;
- break;
- default:
- exit(1);
- }
- }
-
- std::string input_filename;
- std::string output_filename("ogr_out");
- int remaining_args = argc - optind;
- if (remaining_args > 2) {
- std::cerr << "Usage: " << argv[0] << " [OPTIONS] [INFILE [OUTFILE]]" << std::endl;
- exit(1);
- } else if (remaining_args == 2) {
- input_filename = argv[optind];
- output_filename = argv[optind+1];
- } else if (remaining_args == 1) {
- input_filename = argv[optind];
- } else {
- input_filename = "-";
- }
-
- osmium::area::Assembler::config_type assembler_config;
- assembler_config.enable_debug_output(debug);
- osmium::area::MultipolygonCollector<osmium::area::Assembler> collector(assembler_config);
-
- std::cerr << "Pass 1...\n";
- osmium::io::Reader reader1(input_filename);
- collector.read_relations(reader1);
- reader1.close();
- std::cerr << "Pass 1 done\n";
-
- index_pos_type index_pos;
- index_neg_type index_neg;
- location_handler_type location_handler(index_pos, index_neg);
- location_handler.ignore_errors();
-
- MyOGRHandler ogr_handler(output_format, output_filename);
-
- std::cerr << "Pass 2...\n";
- osmium::io::Reader reader2(input_filename);
-
- osmium::apply(reader2, location_handler, ogr_handler, collector.handler([&ogr_handler](const osmium::memory::Buffer& area_buffer) {
- osmium::apply(area_buffer, ogr_handler);
- }));
-
- reader2.close();
- std::cerr << "Pass 2 done\n";
-
- std::vector<const osmium::Relation*> incomplete_relations = collector.get_incomplete_relations();
- if (!incomplete_relations.empty()) {
- std::cerr << "Warning! Some member ways missing for these multipolygon relations:";
- for (const auto* relation : incomplete_relations) {
- std::cerr << " " << relation->id();
- }
- std::cerr << "\n";
- }
-}
-
diff --git a/examples/osmium_toogr2_exp.cpp b/examples/osmium_toogr2_exp.cpp
deleted file mode 100644
index db8d5cf..0000000
--- a/examples/osmium_toogr2_exp.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
-
- This is an example tool that converts OSM data to some output format
- like Spatialite or Shapefiles using the OGR library.
-
- This version does multipolygon handling (in contrast to the osmium_toogr
- example which doesn't).
-
- This version (..._exp) uses a new experimental unsupported interface.
-
- The code in this example file is released into the Public Domain.
-
-*/
-
-#include <iostream>
-#include <getopt.h>
-
-#include <osmium/index/map/sparse_mem_array.hpp>
-
-#include <osmium/visitor.hpp>
-
-#include <osmium/geom/mercator_projection.hpp>
-//#include <osmium/geom/projection.hpp>
-#include <osmium/geom/ogr.hpp>
-#include <osmium/io/any_input.hpp>
-#include <osmium/handler.hpp>
-#include <osmium/experimental/flex_reader.hpp>
-
-typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location> index_type;
-typedef osmium::handler::NodeLocationsForWays<index_type> location_handler_type;
-
-class MyOGRHandler : public osmium::handler::Handler {
-
- OGRDataSource* m_data_source;
- OGRLayer* m_layer_point;
- OGRLayer* m_layer_linestring;
- OGRLayer* m_layer_polygon;
-
- // Choose one of the following:
-
- // 1. Use WGS84, do not project coordinates.
- //osmium::geom::OGRFactory<> m_factory {};
-
- // 2. Project coordinates into "Web Mercator".
- osmium::geom::OGRFactory<osmium::geom::MercatorProjection> m_factory;
-
- // 3. Use any projection that the proj library can handle.
- // (Initialize projection with EPSG code or proj string).
- // In addition you need to link with "-lproj" and add
- // #include <osmium/geom/projection.hpp>.
- //osmium::geom::OGRFactory<osmium::geom::Projection> m_factory {osmium::geom::Projection(3857)};
-
-public:
-
- MyOGRHandler(const std::string& driver_name, const std::string& filename) {
-
- OGRRegisterAll();
-
- OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str());
- if (!driver) {
- std::cerr << driver_name << " driver not available.\n";
- exit(1);
- }
-
- CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
- const char* options[] = { "SPATIALITE=TRUE", nullptr };
- m_data_source = driver->CreateDataSource(filename.c_str(), const_cast<char**>(options));
- if (!m_data_source) {
- std::cerr << "Creation of output file failed.\n";
- exit(1);
- }
-
- OGRSpatialReference sparef;
- sparef.importFromProj4(m_factory.proj_string().c_str());
-
- m_layer_point = m_data_source->CreateLayer("postboxes", &sparef, wkbPoint, nullptr);
- if (!m_layer_point) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_point_field_id("id", OFTReal);
- layer_point_field_id.SetWidth(10);
-
- if (m_layer_point->CreateField(&layer_point_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_point_field_operator("operator", OFTString);
- layer_point_field_operator.SetWidth(30);
-
- if (m_layer_point->CreateField(&layer_point_field_operator) != OGRERR_NONE) {
- std::cerr << "Creating operator field failed.\n";
- exit(1);
- }
-
- /* Transactions might make things faster, then again they might not.
- Feel free to experiment and benchmark and report back. */
- m_layer_point->StartTransaction();
-
- m_layer_linestring = m_data_source->CreateLayer("roads", &sparef, wkbLineString, nullptr);
- if (!m_layer_linestring) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_linestring_field_id("id", OFTReal);
- layer_linestring_field_id.SetWidth(10);
-
- if (m_layer_linestring->CreateField(&layer_linestring_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_linestring_field_type("type", OFTString);
- layer_linestring_field_type.SetWidth(30);
-
- if (m_layer_linestring->CreateField(&layer_linestring_field_type) != OGRERR_NONE) {
- std::cerr << "Creating type field failed.\n";
- exit(1);
- }
-
- m_layer_linestring->StartTransaction();
-
- m_layer_polygon = m_data_source->CreateLayer("buildings", &sparef, wkbMultiPolygon, nullptr);
- if (!m_layer_polygon) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_polygon_field_id("id", OFTInteger);
- layer_polygon_field_id.SetWidth(10);
-
- if (m_layer_polygon->CreateField(&layer_polygon_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_polygon_field_type("type", OFTString);
- layer_polygon_field_type.SetWidth(30);
-
- if (m_layer_polygon->CreateField(&layer_polygon_field_type) != OGRERR_NONE) {
- std::cerr << "Creating type field failed.\n";
- exit(1);
- }
-
- m_layer_polygon->StartTransaction();
- }
-
- ~MyOGRHandler() {
- m_layer_polygon->CommitTransaction();
- m_layer_linestring->CommitTransaction();
- m_layer_point->CommitTransaction();
- OGRDataSource::DestroyDataSource(m_data_source);
- OGRCleanupAll();
- }
-
- void node(const osmium::Node& node) {
- const char* amenity = node.tags()["amenity"];
- if (amenity && !strcmp(amenity, "post_box")) {
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_point->GetLayerDefn());
- std::unique_ptr<OGRPoint> ogr_point = m_factory.create_point(node);
- feature->SetGeometry(ogr_point.get());
- feature->SetField("id", static_cast<double>(node.id()));
- feature->SetField("operator", node.tags()["operator"]);
-
- if (m_layer_point->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
- }
- }
-
- void way(const osmium::Way& way) {
- const char* highway = way.tags()["highway"];
- if (highway) {
- try {
- std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way);
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_linestring->GetLayerDefn());
- feature->SetGeometry(ogr_linestring.get());
- feature->SetField("id", static_cast<double>(way.id()));
- feature->SetField("type", highway);
-
- if (m_layer_linestring->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
- } catch (osmium::geometry_error&) {
- std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n";
- }
- }
- }
-
- void area(const osmium::Area& area) {
- const char* building = area.tags()["building"];
- if (building) {
- try {
- std::unique_ptr<OGRMultiPolygon> ogr_polygon = m_factory.create_multipolygon(area);
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_polygon->GetLayerDefn());
- feature->SetGeometry(ogr_polygon.get());
- feature->SetField("id", static_cast<int>(area.id()));
- feature->SetField("type", building);
-
- std::string type = "";
- if (area.from_way()) {
- type += "w";
- } else {
- type += "r";
- }
- feature->SetField("type", type.c_str());
-
- if (m_layer_polygon->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
- } catch (osmium::geometry_error&) {
- std::cerr << "Ignoring illegal geometry for area " << area.id() << " created from " << (area.from_way() ? "way" : "relation") << " with id=" << area.orig_id() << ".\n";
- }
- }
- }
-
-};
-
-/* ================================================== */
-
-void print_help() {
- std::cout << "osmium_toogr [OPTIONS] [INFILE [OUTFILE]]\n\n" \
- << "If INFILE is not given stdin is assumed.\n" \
- << "If OUTFILE is not given 'ogr_out' is used.\n" \
- << "\nOptions:\n" \
- << " -h, --help This help message\n" \
- << " -f, --format=FORMAT Output OGR format (Default: 'SQLite')\n";
-}
-
-int main(int argc, char* argv[]) {
- static struct option long_options[] = {
- {"help", no_argument, 0, 'h'},
- {"format", required_argument, 0, 'f'},
- {0, 0, 0, 0}
- };
-
- std::string output_format("SQLite");
-
- while (true) {
- int c = getopt_long(argc, argv, "hf:", long_options, 0);
- if (c == -1) {
- break;
- }
-
- switch (c) {
- case 'h':
- print_help();
- exit(0);
- case 'f':
- output_format = optarg;
- break;
- default:
- exit(1);
- }
- }
-
- std::string input_filename;
- std::string output_filename("ogr_out");
- int remaining_args = argc - optind;
- if (remaining_args > 2) {
- std::cerr << "Usage: " << argv[0] << " [OPTIONS] [INFILE [OUTFILE]]" << std::endl;
- exit(1);
- } else if (remaining_args == 2) {
- input_filename = argv[optind];
- output_filename = argv[optind+1];
- } else if (remaining_args == 1) {
- input_filename = argv[optind];
- } else {
- input_filename = "-";
- }
-
- index_type index_pos;
- location_handler_type location_handler(index_pos);
- osmium::experimental::FlexReader<location_handler_type> exr(input_filename, location_handler, osmium::osm_entity_bits::object);
-
- MyOGRHandler ogr_handler(output_format, output_filename);
-
- while (auto buffer = exr.read()) {
- osmium::apply(buffer, ogr_handler);
- }
-
- exr.close();
-
- std::vector<const osmium::Relation*> incomplete_relations = exr.collector().get_incomplete_relations();
- if (!incomplete_relations.empty()) {
- std::cerr << "Warning! Some member ways missing for these multipolygon relations:";
- for (const auto* relation : incomplete_relations) {
- std::cerr << " " << relation->id();
- }
- std::cerr << "\n";
- }
-}
-
diff --git a/include/gdalcpp.hpp b/include/gdalcpp.hpp
new file mode 100644
index 0000000..a66e1ea
--- /dev/null
+++ b/include/gdalcpp.hpp
@@ -0,0 +1,302 @@
+#ifndef GDALCPP_HPP
+#define GDALCPP_HPP
+
+/*
+
+C++11 wrapper classes for GDAL/OGR.
+
+Version 1.0.0
+
+https://github.com/joto/gdalcpp
+
+Copyright 2015 Jochen Topf <jochen at topf.org>
+
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include <algorithm>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+#include <gdal_priv.h>
+#include <gdal_version.h>
+#include <ogr_api.h>
+#include <ogrsf_frmts.h>
+
+namespace gdalcpp {
+
+#if GDAL_VERSION_MAJOR >= 2
+ typedef GDALDriver gdal_driver_type;
+ typedef GDALDataset gdal_dataset_type;
+#else
+ typedef OGRSFDriver gdal_driver_type;
+ typedef OGRDataSource gdal_dataset_type;
+#endif
+
+ class gdal_error : public std::runtime_error {
+
+ std::string m_driver;
+ std::string m_dataset;
+ std::string m_layer;
+ std::string m_field;
+
+ public:
+
+ gdal_error(const std::string& message,
+ const std::string& driver = "",
+ const std::string& dataset = "",
+ const std::string& layer = "",
+ const std::string& field = "") :
+ std::runtime_error(message),
+ m_driver(driver),
+ m_dataset(dataset),
+ m_layer(layer),
+ m_field(field) {
+ }
+
+ const std::string& driver() const {
+ return m_driver;
+ }
+
+ const std::string& dataset() const {
+ return m_dataset;
+ }
+
+ const std::string& layer() const {
+ return m_layer;
+ }
+
+ const std::string& field() const {
+ return m_field;
+ }
+
+ }; // class gdal_error
+
+ namespace detail {
+
+ struct init_wrapper {
+ init_wrapper() { OGRRegisterAll(); }
+ ~init_wrapper() { OGRCleanupAll(); }
+ };
+
+ struct init_library {
+ init_library() {
+ static init_wrapper iw;
+ }
+ };
+
+ class Driver : private init_library {
+
+ gdal_driver_type* m_driver;
+
+ public:
+
+ Driver(const std::string& driver_name) :
+ init_library(),
+ m_driver(OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str())) {
+ if (!m_driver) {
+ throw gdal_error(std::string("unknown driver: '") + driver_name + "'", driver_name);
+ }
+ }
+
+ gdal_driver_type& get() const {
+ return *m_driver;
+ }
+
+ }; // struct Driver
+
+ struct Options {
+
+ std::vector<std::string> m_options;
+ std::unique_ptr<const char*[]> m_ptrs;
+
+ Options(const std::vector<std::string>& options) :
+ m_options(options),
+ 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 {
+ return const_cast<char**>(m_ptrs.get());
+ }
+
+ }; // struct Options
+
+ } // namespace detail
+
+ class Dataset {
+
+ struct gdal_dataset_deleter {
+
+ void operator()(gdal_dataset_type* ds) {
+#if GDAL_VERSION_MAJOR >= 2
+ GDALClose(ds);
+#else
+ OGRDataSource::DestroyDataSource(ds);
+#endif
+ }
+
+ }; // struct gdal_dataset_deleter
+
+ std::string m_driver_name;
+ std::string m_dataset_name;
+ detail::Options m_options;
+ std::unique_ptr<gdal_dataset_type, gdal_dataset_deleter> m_dataset;
+ OGRSpatialReference m_spatial_reference;
+
+ public:
+
+ Dataset(const std::string& driver_name, const std::string& dataset_name, const std::string& proj = "", const std::vector<std::string>& options = {}) :
+ m_driver_name(driver_name),
+ m_dataset_name(dataset_name),
+ m_options(options),
+#if GDAL_VERSION_MAJOR >= 2
+ m_dataset(detail::Driver(driver_name).get().Create(dataset_name.c_str(), 0, 0, 0, GDT_Unknown, m_options.get())) {
+#else
+ 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 + "'", driver_name, dataset_name);
+ }
+ if (proj.empty()) {
+ m_spatial_reference.SetWellKnownGeogCS("WGS84");
+ } else {
+ m_spatial_reference.importFromProj4(proj.c_str());
+ }
+ }
+
+ const std::string& driver_name() const {
+ return m_driver_name;
+ }
+
+ const std::string& dataset_name() const {
+ return m_dataset_name;
+ }
+
+ gdal_dataset_type& get() const {
+ return *m_dataset;
+ }
+
+ OGRSpatialReference* spatial_reference() {
+ return &m_spatial_reference;
+ }
+
+ Dataset& start_transaction() {
+#if GDAL_VERSION_MAJOR >= 2
+ m_dataset->StartTransaction();
+#endif
+ return *this;
+ }
+
+ Dataset& commit_transaction() {
+#if GDAL_VERSION_MAJOR >= 2
+ m_dataset->CommitTransaction();
+#endif
+ return *this;
+ }
+
+ }; // class Dataset
+
+ class Layer {
+
+ Dataset& m_dataset;
+ OGRLayer* m_layer;
+
+ public:
+
+ Layer(Dataset& dataset, const std::string& layer_name, OGRwkbGeometryType type) :
+ m_dataset(dataset),
+ m_layer(dataset.get().CreateLayer(layer_name.c_str(), dataset.spatial_reference(), type)) {
+ if (!m_layer) {
+ throw gdal_error(std::string("failed to create layer '") + layer_name + "'",
+ dataset.driver_name(), dataset.dataset_name(), layer_name);
+ }
+ }
+
+ OGRLayer* get() const {
+ return m_layer;
+ }
+
+ const char* name() {
+ return m_layer->GetName();
+ }
+
+ Layer& add_field(const std::string& field_name, OGRFieldType type, int width, int precision=0) {
+ OGRFieldDefn field(field_name.c_str(), type);
+ field.SetWidth(width);
+ field.SetPrecision(precision);
+
+ if (m_layer->CreateField(&field) != OGRERR_NONE) {
+ throw gdal_error(std::string("failed to create field '") + field_name + "' in layer '" + name() + "'",
+ m_dataset.driver_name(), m_dataset.dataset_name(), name(), field_name);
+ }
+
+ return *this;
+ }
+
+ }; // class Layer
+
+ class Feature {
+
+ OGRLayer* m_layer;
+ OGRFeature m_feature;
+
+ public:
+
+ Feature(Layer& layer, std::unique_ptr<OGRGeometry>&& geometry) :
+ m_layer(layer.get()),
+ m_feature(m_layer->GetLayerDefn()) {
+ m_feature.SetGeometry(geometry.get());
+ }
+
+ void add_to_layer() {
+ if (m_layer->CreateFeature(&m_feature) != OGRERR_NONE) {
+ std::runtime_error("feature creation failed");
+ }
+ }
+
+ template <class T>
+ Feature& set_field(int n, T&& arg) {
+ m_feature.SetField(n, std::forward<T>(arg));
+ return *this;
+ }
+
+ template <class T>
+ Feature& set_field(const char* name, T&& arg) {
+ m_feature.SetField(name, std::forward<T>(arg));
+ return *this;
+ }
+
+ }; // class Feature
+
+} // namespace gdalcpp
+
+#endif // GDALCPP_HPP
diff --git a/include/osmium/area/problem_reporter_ogr.hpp b/include/osmium/area/problem_reporter_ogr.hpp
index c437a3f..d98a5b2 100644
--- a/include/osmium/area/problem_reporter_ogr.hpp
+++ b/include/osmium/area/problem_reporter_ogr.hpp
@@ -42,33 +42,11 @@ DEALINGS IN THE SOFTWARE.
* @attention If you include this file, you'll need to link with `libgdal`.
*/
-#ifdef _MSC_VER
-# pragma warning(push)
-# pragma warning(disable : 4458)
-#else
-# pragma GCC diagnostic push
-# ifdef __clang__
-# pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
-# endif
-# pragma GCC diagnostic ignored "-Wfloat-equal"
-# pragma GCC diagnostic ignored "-Wold-style-cast"
-# pragma GCC diagnostic ignored "-Wpadded"
-# pragma GCC diagnostic ignored "-Wredundant-decls"
-# pragma GCC diagnostic ignored "-Wshadow"
-#endif
-
-#include <ogr_api.h>
-#include <ogrsf_frmts.h>
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#else
-# pragma GCC diagnostic pop
-#endif
-
#include <memory>
#include <stdexcept>
+#include <gdalcpp.hpp>
+
#include <osmium/area/problem_reporter.hpp>
#include <osmium/geom/ogr.hpp>
#include <osmium/osm/location.hpp>
@@ -86,24 +64,15 @@ namespace osmium {
osmium::geom::OGRFactory<> m_ogr_factory;
- OGRDataSource* m_data_source;
-
- OGRLayer* m_layer_perror;
- OGRLayer* m_layer_lerror;
+ gdalcpp::Layer m_layer_perror;
+ gdalcpp::Layer m_layer_lerror;
void write_point(const char* problem_type, osmium::object_id_type id1, osmium::object_id_type id2, osmium::Location location) {
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_perror->GetLayerDefn());
- std::unique_ptr<OGRPoint> ogr_point = m_ogr_factory.create_point(location);
- feature->SetGeometry(ogr_point.get());
- feature->SetField("id1", static_cast<double>(id1));
- feature->SetField("id2", static_cast<double>(id2));
- feature->SetField("problem_type", problem_type);
-
- if (m_layer_perror->CreateFeature(feature) != OGRERR_NONE) {
- std::runtime_error("Failed to create feature on layer 'perrors'");
- }
-
- OGRFeature::DestroyFeature(feature);
+ gdalcpp::Feature feature(m_layer_perror, m_ogr_factory.create_point(location));
+ feature.set_field("id1", static_cast<double>(id1));
+ feature.set_field("id2", static_cast<double>(id2));
+ feature.set_field("problem_type", problem_type);
+ feature.add_to_layer();
}
void write_line(const char* problem_type, osmium::object_id_type id1, osmium::object_id_type id2, osmium::Location loc1, osmium::Location loc2) {
@@ -112,80 +81,27 @@ namespace osmium {
std::unique_ptr<OGRLineString> ogr_linestring = std::unique_ptr<OGRLineString>(new OGRLineString());
ogr_linestring->addPoint(ogr_point1.get());
ogr_linestring->addPoint(ogr_point2.get());
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_lerror->GetLayerDefn());
- feature->SetGeometry(ogr_linestring.get());
- feature->SetField("id1", static_cast<double>(id1));
- feature->SetField("id2", static_cast<double>(id2));
- feature->SetField("problem_type", problem_type);
- if (m_layer_lerror->CreateFeature(feature) != OGRERR_NONE) {
- std::runtime_error("Failed to create feature on layer 'lerrors'");
- }
-
- OGRFeature::DestroyFeature(feature);
+ gdalcpp::Feature feature(m_layer_lerror, std::move(ogr_linestring));
+ feature.set_field("id1", static_cast<double>(id1));
+ feature.set_field("id2", static_cast<double>(id2));
+ feature.set_field("problem_type", problem_type);
+ feature.add_to_layer();
}
public:
- explicit ProblemReporterOGR(OGRDataSource* data_source) :
- m_data_source(data_source) {
-
- OGRSpatialReference sparef;
- sparef.SetWellKnownGeogCS("WGS84");
-
- m_layer_perror = m_data_source->CreateLayer("perrors", &sparef, wkbPoint, nullptr);
- if (!m_layer_perror) {
- std::runtime_error("Layer creation failed for layer 'perrors'");
- }
-
- OGRFieldDefn layer_perror_field_id1("id1", OFTReal);
- layer_perror_field_id1.SetWidth(10);
-
- if (m_layer_perror->CreateField(&layer_perror_field_id1) != OGRERR_NONE) {
- std::runtime_error("Creating field 'id1' failed for layer 'perrors'");
- }
-
- OGRFieldDefn layer_perror_field_id2("id2", OFTReal);
- layer_perror_field_id2.SetWidth(10);
-
- if (m_layer_perror->CreateField(&layer_perror_field_id2) != OGRERR_NONE) {
- std::runtime_error("Creating field 'id2' failed for layer 'perrors'");
- }
-
- OGRFieldDefn layer_perror_field_problem_type("problem_type", OFTString);
- layer_perror_field_problem_type.SetWidth(30);
-
- if (m_layer_perror->CreateField(&layer_perror_field_problem_type) != OGRERR_NONE) {
- std::runtime_error("Creating field 'problem_type' failed for layer 'perrors'");
- }
-
- /**************/
-
- m_layer_lerror = m_data_source->CreateLayer("lerrors", &sparef, wkbLineString, nullptr);
- if (!m_layer_lerror) {
- std::runtime_error("Layer creation failed for layer 'lerrors'");
- }
-
- OGRFieldDefn layer_lerror_field_id1("id1", OFTReal);
- layer_lerror_field_id1.SetWidth(10);
-
- if (m_layer_lerror->CreateField(&layer_lerror_field_id1) != OGRERR_NONE) {
- std::runtime_error("Creating field 'id1' failed for layer 'lerrors'");
- }
-
- OGRFieldDefn layer_lerror_field_id2("id2", OFTReal);
- layer_lerror_field_id2.SetWidth(10);
-
- if (m_layer_lerror->CreateField(&layer_lerror_field_id2) != OGRERR_NONE) {
- std::runtime_error("Creating field 'id2' failed for layer 'lerrors'");
- }
+ explicit ProblemReporterOGR(gdalcpp::Dataset& dataset) :
+ m_layer_perror(dataset, "perrors", wkbPoint),
+ m_layer_lerror(dataset, "lerrors", wkbLineString) {
- OGRFieldDefn layer_lerror_field_problem_type("problem_type", OFTString);
- layer_lerror_field_problem_type.SetWidth(30);
+ m_layer_perror.add_field("id1", OFTReal, 10);
+ m_layer_perror.add_field("id2", OFTReal, 10);
+ m_layer_perror.add_field("problem_type", OFTString, 30);
- if (m_layer_lerror->CreateField(&layer_lerror_field_problem_type) != OGRERR_NONE) {
- std::runtime_error("Creating field 'problem_type' failed for layer 'lerrors'");
- }
+ m_layer_lerror.add_field("id1", OFTReal, 10);
+ m_layer_lerror.add_field("id2", OFTReal, 10);
+ m_layer_lerror.add_field("problem_type", OFTString, 30);
}
virtual ~ProblemReporterOGR() = default;
diff --git a/include/osmium/builder/osm_object_builder.hpp b/include/osmium/builder/osm_object_builder.hpp
index 074076c..5827243 100644
--- a/include/osmium/builder/osm_object_builder.hpp
+++ b/include/osmium/builder/osm_object_builder.hpp
@@ -76,6 +76,12 @@ namespace osmium {
* @param value Tag value (0-terminated string).
*/
void add_tag(const char* key, const char* value) {
+ if (std::strlen(key) > osmium::max_osm_string_length) {
+ throw std::length_error("OSM tag key is too long");
+ }
+ if (std::strlen(value) > osmium::max_osm_string_length) {
+ throw std::length_error("OSM tag value is too long");
+ }
add_size(append(key) + append(value));
}
@@ -87,8 +93,15 @@ namespace osmium {
* @param value Pointer to tag value.
* @param value_length Length of value (not including the \0 byte).
*/
- void add_tag(const char* key, const string_size_type key_length, const char* value, const string_size_type value_length) {
- add_size(append(key, key_length) + append_zero() + append(value, value_length) + append_zero());
+ void add_tag(const char* key, const size_t key_length, const char* value, const size_t value_length) {
+ if (key_length > osmium::max_osm_string_length) {
+ throw std::length_error("OSM tag key is too long");
+ }
+ if (value_length > osmium::max_osm_string_length) {
+ throw std::length_error("OSM tag value is too long");
+ }
+ add_size(append(key, osmium::memory::item_size_type(key_length)) + append_zero() +
+ append(value, osmium::memory::item_size_type(value_length)) + append_zero());
}
/**
@@ -98,8 +111,14 @@ namespace osmium {
* @param value Tag value.
*/
void add_tag(const std::string& key, const std::string& value) {
- add_size(append(key.data(), static_cast_with_assert<string_size_type>(key.size() + 1)) +
- append(value.data(), static_cast_with_assert<string_size_type>(value.size() + 1)));
+ if (key.size() > osmium::max_osm_string_length) {
+ throw std::length_error("OSM tag key is too long");
+ }
+ if (value.size() > osmium::max_osm_string_length) {
+ throw std::length_error("OSM tag value is too long");
+ }
+ add_size(append(key.data(), osmium::memory::item_size_type(key.size()) + 1) +
+ append(value.data(), osmium::memory::item_size_type(value.size()) + 1));
}
}; // class TagListBuilder
@@ -141,35 +160,17 @@ namespace osmium {
* will be set.
* @param role The role.
* @param length Length of role (without \0 termination).
+ * @throws std:length_error If role is longer than osmium::max_osm_string_length
*/
- void add_role(osmium::RelationMember& member, const char* role, const string_size_type length) {
- member.set_role_size(length + 1);
- add_size(append(role, length) + append_zero());
+ void add_role(osmium::RelationMember& member, const char* role, const size_t length) {
+ if (length > osmium::max_osm_string_length) {
+ throw std::length_error("OSM relation member role is too long");
+ }
+ member.set_role_size(osmium::string_size_type(length) + 1);
+ add_size(append(role, osmium::memory::item_size_type(length)) + append_zero());
add_padding(true);
}
- /**
- * Add role to buffer.
- *
- * @param member Relation member object where the length of the role
- * will be set.
- * @param role \0-terminated role.
- */
- void add_role(osmium::RelationMember& member, const char* role) {
- add_role(member, role, static_cast_with_assert<string_size_type>(std::strlen(role)));
- }
-
- /**
- * Add role to buffer.
- *
- * @param member Relation member object where the length of the role
- * will be set.
- * @param role Role.
- */
- void add_role(osmium::RelationMember& member, const std::string& role) {
- add_role(member, role.data(), static_cast_with_assert<string_size_type>(role.size()));
- }
-
public:
explicit RelationMemberListBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) :
@@ -190,8 +191,10 @@ namespace osmium {
* @param full_member Optional pointer to the member object. If it
* is available a copy will be added to the
* relation.
+ * @throws std:length_error If role_length is greater than
+ * osmium::max_osm_string_length
*/
- void add_member(osmium::item_type type, object_id_type ref, const char* role, const string_size_type role_length, const osmium::OSMObject* full_member = nullptr) {
+ void add_member(osmium::item_type type, object_id_type ref, const char* role, const size_t role_length, const osmium::OSMObject* full_member = nullptr) {
osmium::RelationMember* member = reserve_space_for<osmium::RelationMember>();
new (member) osmium::RelationMember(ref, type, full_member != nullptr);
add_size(sizeof(RelationMember));
@@ -210,9 +213,10 @@ namespace osmium {
* @param full_member Optional pointer to the member object. If it
* is available a copy will be added to the
* relation.
+ * @throws std:length_error If role is longer than osmium::max_osm_string_length
*/
void add_member(osmium::item_type type, object_id_type ref, const char* role, const osmium::OSMObject* full_member = nullptr) {
- add_member(type, ref, role, strlen(role), full_member);
+ add_member(type, ref, role, std::strlen(role), full_member);
}
/**
@@ -224,6 +228,7 @@ namespace osmium {
* @param full_member Optional pointer to the member object. If it
* is available a copy will be added to the
* relation.
+ * @throws std:length_error If role is longer than osmium::max_osm_string_length
*/
void add_member(osmium::item_type type, object_id_type ref, const std::string& role, const osmium::OSMObject* full_member = nullptr) {
add_member(type, ref, role.data(), role.size(), full_member);
diff --git a/include/osmium/geom/factory.hpp b/include/osmium/geom/factory.hpp
index 9be050d..13e5955 100644
--- a/include/osmium/geom/factory.hpp
+++ b/include/osmium/geom/factory.hpp
@@ -182,6 +182,7 @@ namespace osmium {
m_impl(std::forward<TArgs>(args)...) {
}
+ typedef TProjection projection_type;
typedef typename TGeomImpl::point_type point_type;
typedef typename TGeomImpl::linestring_type linestring_type;
typedef typename TGeomImpl::polygon_type polygon_type;
diff --git a/include/osmium/geom/ogr.hpp b/include/osmium/geom/ogr.hpp
index f33971c..7f726ed 100644
--- a/include/osmium/geom/ogr.hpp
+++ b/include/osmium/geom/ogr.hpp
@@ -47,35 +47,7 @@ DEALINGS IN THE SOFTWARE.
#include <memory>
#include <utility>
-#ifdef _MSC_VER
-# pragma warning(push)
-# pragma warning(disable : 4458)
-# pragma warning(disable : 4251)
-#else
-# pragma GCC diagnostic push
-# ifdef __clang__
-# pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
-# endif
-# pragma GCC diagnostic ignored "-Wfloat-equal"
-# pragma GCC diagnostic ignored "-Wold-style-cast"
-# pragma GCC diagnostic ignored "-Wpadded"
-# pragma GCC diagnostic ignored "-Wredundant-decls"
-# pragma GCC diagnostic ignored "-Wshadow"
-#endif
-
-/* Strictly speaking the following include would be enough here,
- but everybody using this file will very likely need the other includes,
- so we are adding them here, so that not everybody will need all those
- pragmas to disable warnings. */
-//#include <ogr_geometry.h>
-#include <ogr_api.h>
-#include <ogrsf_frmts.h>
-
-#ifdef _MSC_VER
-# pragma warning(pop)
-#else
-# pragma GCC diagnostic pop
-#endif
+#include <ogr_geometry.h>
#include <osmium/geom/coordinates.hpp>
#include <osmium/geom/factory.hpp>
diff --git a/include/osmium/geom/tile.hpp b/include/osmium/geom/tile.hpp
index 9cd0b28..1392480 100644
--- a/include/osmium/geom/tile.hpp
+++ b/include/osmium/geom/tile.hpp
@@ -69,8 +69,8 @@ namespace osmium {
osmium::geom::Coordinates c = lonlat_to_mercator(location);
const int32_t n = 1LL << zoom;
const double scale = detail::max_coordinate_epsg3857 * 2 / n;
- x = detail::restrict_to_range<int32_t>((c.x + detail::max_coordinate_epsg3857) / scale, 0, n-1);
- y = detail::restrict_to_range<int32_t>((detail::max_coordinate_epsg3857 - c.y) / scale, 0, n-1);
+ x = detail::restrict_to_range<int32_t>(int32_t((c.x + detail::max_coordinate_epsg3857) / scale), 0, n-1);
+ y = detail::restrict_to_range<int32_t>(int32_t((detail::max_coordinate_epsg3857 - c.y) / scale), 0, n-1);
}
}; // struct Tile
diff --git a/include/osmium/io/detail/debug_output_format.hpp b/include/osmium/io/detail/debug_output_format.hpp
index efecc58..026cdc3 100644
--- a/include/osmium/io/detail/debug_output_format.hpp
+++ b/include/osmium/io/detail/debug_output_format.hpp
@@ -211,14 +211,14 @@ namespace osmium {
*m_out += padding;
output_formatted(" %d\n", tags.size());
- osmium::max_op<int> max;
+ osmium::max_op<size_t> max;
for (const auto& tag : tags) {
max.update(std::strlen(tag.key()));
}
for (const auto& tag : tags) {
*m_out += " ";
write_string(tag.key());
- int spacing = max() - std::strlen(tag.key());
+ auto spacing = max() - std::strlen(tag.key());
while (spacing--) {
*m_out += " ";
}
diff --git a/include/osmium/io/detail/input_format.hpp b/include/osmium/io/detail/input_format.hpp
index 03e1190..743845c 100644
--- a/include/osmium/io/detail/input_format.hpp
+++ b/include/osmium/io/detail/input_format.hpp
@@ -136,15 +136,12 @@ namespace osmium {
return true;
}
- std::unique_ptr<osmium::io::detail::InputFormat> create_input(const osmium::io::File& file, osmium::osm_entity_bits::type read_which_entities, osmium::thread::Queue<std::string>& input_queue) {
- file.check();
-
+ create_input_type* get_creator_function(const osmium::io::File& file) {
auto it = m_callbacks.find(file.format());
- if (it != m_callbacks.end()) {
- return std::unique_ptr<osmium::io::detail::InputFormat>((it->second)(file, read_which_entities, input_queue));
+ if (it == m_callbacks.end()) {
+ throw std::runtime_error(std::string("Can not open file '") + file.filename() + "' with type '" + as_string(file.format()) + "'. No support for reading this format in this program.");
}
-
- throw std::runtime_error(std::string("Support for input format '") + as_string(file.format()) + "' not compiled into this binary.");
+ return &(it->second);
}
}; // class InputFormatFactory
diff --git a/include/osmium/io/detail/output_format.hpp b/include/osmium/io/detail/output_format.hpp
index 529a189..ed48b38 100644
--- a/include/osmium/io/detail/output_format.hpp
+++ b/include/osmium/io/detail/output_format.hpp
@@ -135,14 +135,12 @@ namespace osmium {
}
std::unique_ptr<osmium::io::detail::OutputFormat> create_output(const osmium::io::File& file, data_queue_type& output_queue) {
- file.check();
-
auto it = m_callbacks.find(file.format());
if (it != m_callbacks.end()) {
return std::unique_ptr<osmium::io::detail::OutputFormat>((it->second)(file, output_queue));
}
- throw std::runtime_error(std::string("Support for output format '") + as_string(file.format()) + "' not compiled into this binary.");
+ throw std::runtime_error(std::string("Can not open file '") + file.filename() + "' with type '" + as_string(file.format()) + "'. No support for writing this format in this program.");
}
}; // class OutputFormatFactory
diff --git a/include/osmium/io/detail/pbf_decoder.hpp b/include/osmium/io/detail/pbf_decoder.hpp
index 79e899f..e9e0e82 100644
--- a/include/osmium/io/detail/pbf_decoder.hpp
+++ b/include/osmium/io/detail/pbf_decoder.hpp
@@ -62,13 +62,14 @@ namespace osmium {
namespace detail {
using ptr_len_type = std::pair<const char*, size_t>;
+ using osm_string_len_type = std::pair<const char*, osmium::string_size_type>;
class PBFPrimitiveBlockDecoder {
static constexpr size_t initial_buffer_size = 2 * 1024 * 1024;
ptr_len_type m_data;
- std::vector<ptr_len_type> m_stringtable;
+ std::vector<osm_string_len_type> m_stringtable;
int64_t m_lon_offset = 0;
int64_t m_lat_offset = 0;
@@ -86,7 +87,11 @@ namespace osmium {
protozero::pbf_message<OSMFormat::StringTable> pbf_string_table(data);
while (pbf_string_table.next(OSMFormat::StringTable::repeated_bytes_s)) {
- m_stringtable.push_back(pbf_string_table.get_data());
+ auto str_len = pbf_string_table.get_data();
+ if (str_len.second > osmium::max_osm_string_length) {
+ throw osmium::pbf_error("overlong string in string table");
+ }
+ m_stringtable.emplace_back(str_len.first, osmium::string_size_type(str_len.second));
}
}
@@ -156,8 +161,8 @@ namespace osmium {
}
}
- ptr_len_type decode_info(const ptr_len_type& data, osmium::OSMObject& object) {
- ptr_len_type user = std::make_pair("", 0);
+ osm_string_len_type decode_info(const ptr_len_type& data, osmium::OSMObject& object) {
+ osm_string_len_type user = std::make_pair("", 0);
protozero::pbf_message<OSMFormat::Info> pbf_info(data);
while (pbf_info.next()) {
@@ -220,7 +225,7 @@ namespace osmium {
}
int32_t convert_pbf_coordinate(int64_t c) const {
- return (c * m_granularity + m_lon_offset) / resolution_convert;
+ return int32_t((c * m_granularity + m_lon_offset) / resolution_convert);
}
void decode_node(const ptr_len_type& data) {
@@ -232,7 +237,7 @@ namespace osmium {
int64_t lon = std::numeric_limits<int64_t>::max();
int64_t lat = std::numeric_limits<int64_t>::max();
- ptr_len_type user = { "", 0 };
+ osm_string_len_type user = { "", 0 };
protozero::pbf_message<OSMFormat::Node> pbf_node(data);
while (pbf_node.next()) {
@@ -285,7 +290,7 @@ namespace osmium {
kv_type vals;
std::pair<protozero::pbf_reader::const_sint64_iterator, protozero::pbf_reader::const_sint64_iterator> refs;
- ptr_len_type user = { "", 0 };
+ osm_string_len_type user = { "", 0 };
protozero::pbf_message<OSMFormat::Way> pbf_way(data);
while (pbf_way.next()) {
@@ -334,7 +339,7 @@ namespace osmium {
std::pair<protozero::pbf_reader::const_sint64_iterator, protozero::pbf_reader::const_sint64_iterator> refs;
std::pair<protozero::pbf_reader::const_int32_iterator, protozero::pbf_reader::const_int32_iterator> types;
- ptr_len_type user = { "", 0 };
+ osm_string_len_type user = { "", 0 };
protozero::pbf_message<OSMFormat::Relation> pbf_relation(data);
while (pbf_relation.next()) {
@@ -512,7 +517,7 @@ namespace osmium {
// this is against the spec, must have same number of elements
throw osmium::pbf_error("PBF format error");
}
- visible = *visibles.first++;
+ visible = (*visibles.first++) != 0;
}
node.set_visible(visible);
@@ -579,8 +584,8 @@ namespace osmium {
}; // class PBFPrimitiveBlockDecoder
inline ptr_len_type decode_blob(const std::string& blob_data, std::string& output) {
- int32_t raw_size;
- std::pair<const char*, protozero::pbf_length_type> zlib_data;
+ int32_t raw_size = 0;
+ std::pair<const char*, protozero::pbf_length_type> zlib_data = {nullptr, 0};
protozero::pbf_message<FileFormat::Blob> pbf_blob(blob_data);
while (pbf_blob.next()) {
@@ -609,7 +614,7 @@ namespace osmium {
}
}
- if (zlib_data.second != 0) {
+ if (zlib_data.second != 0 && raw_size != 0) {
return osmium::io::detail::zlib_uncompress_string(
zlib_data.first,
static_cast<unsigned long>(zlib_data.second),
diff --git a/include/osmium/io/detail/pbf_output_format.hpp b/include/osmium/io/detail/pbf_output_format.hpp
index 8d8a079..9098b47 100644
--- a/include/osmium/io/detail/pbf_output_format.hpp
+++ b/include/osmium/io/detail/pbf_output_format.hpp
@@ -47,6 +47,8 @@ DEALINGS IN THE SOFTWARE.
#include <time.h>
#include <utility>
+// needed for older boost libraries
+#define BOOST_RESULT_OF_USE_DECLTYPE
#include <boost/iterator/transform_iterator.hpp>
#include <protozero/pbf_builder.hpp>
@@ -113,11 +115,13 @@ namespace osmium {
* @param use_compression Should the output be compressed using zlib?
*/
inline std::string serialize_blob(const std::string& type, const std::string& msg, bool use_compression) {
+ assert(msg.size() <= max_uncompressed_blob_size);
+
std::string blob_data;
protozero::pbf_builder<FileFormat::Blob> pbf_blob(blob_data);
if (use_compression) {
- pbf_blob.add_int32(FileFormat::Blob::optional_int32_raw_size, msg.size());
+ pbf_blob.add_int32(FileFormat::Blob::optional_int32_raw_size, int32_t(msg.size()));
pbf_blob.add_bytes(FileFormat::Blob::optional_bytes_zlib_data, osmium::io::detail::zlib_compress(msg));
} else {
pbf_blob.add_bytes(FileFormat::Blob::optional_bytes_raw, msg);
@@ -127,7 +131,7 @@ namespace osmium {
protozero::pbf_builder<FileFormat::BlobHeader> pbf_blob_header(blob_header_data);
pbf_blob_header.add_string(FileFormat::BlobHeader::required_string_type, type);
- pbf_blob_header.add_int32(FileFormat::BlobHeader::required_int32_datasize, blob_data.size());
+ pbf_blob_header.add_int32(FileFormat::BlobHeader::required_int32_datasize, static_cast_with_assert<int32_t>(blob_data.size()));
uint32_t sz = htonl(static_cast_with_assert<uint32_t>(blob_header_data.size()));
@@ -312,7 +316,7 @@ namespace osmium {
++m_count;
}
- size_t add_string(const char* s) {
+ uint32_t store_in_stringtable(const char* s) {
return m_stringtable.add(s);
}
@@ -395,11 +399,11 @@ namespace osmium {
void add_meta(const osmium::OSMObject& object, T& pbf_object) {
const osmium::TagList& tags = object.tags();
- auto map_tag_key = [this](const osmium::Tag& tag) -> size_t {
- return m_primitive_block.add_string(tag.key());
+ auto map_tag_key = [this](const osmium::Tag& tag) -> uint32_t {
+ return m_primitive_block.store_in_stringtable(tag.key());
};
- auto map_tag_value = [this](const osmium::Tag& tag) -> size_t {
- return m_primitive_block.add_string(tag.value());
+ auto map_tag_value = [this](const osmium::Tag& tag) -> uint32_t {
+ return m_primitive_block.store_in_stringtable(tag.value());
};
pbf_object.add_packed_uint32(T::enum_type::packed_uint32_keys,
@@ -417,7 +421,7 @@ namespace osmium {
pbf_info.add_int64(OSMFormat::Info::optional_int64_timestamp, object.timestamp());
pbf_info.add_int64(OSMFormat::Info::optional_int64_changeset, object.changeset());
pbf_info.add_int32(OSMFormat::Info::optional_int32_uid, object.uid());
- pbf_info.add_uint32(OSMFormat::Info::optional_uint32_user_sid, m_primitive_block.add_string(object.user()));
+ pbf_info.add_uint32(OSMFormat::Info::optional_uint32_user_sid, m_primitive_block.store_in_stringtable(object.user()));
if (m_add_visible) {
pbf_info.add_bool(OSMFormat::Info::optional_bool_visible, object.visible());
}
@@ -450,10 +454,10 @@ namespace osmium {
protozero::pbf_builder<OSMFormat::HeaderBBox> pbf_header_bbox(pbf_header_block, OSMFormat::HeaderBlock::optional_HeaderBBox_bbox);
osmium::Box box = header.joined_boxes();
- pbf_header_bbox.add_sint64(OSMFormat::HeaderBBox::required_sint64_left, box.bottom_left().lon() * lonlat_resolution);
- pbf_header_bbox.add_sint64(OSMFormat::HeaderBBox::required_sint64_right, box.top_right().lon() * lonlat_resolution);
- pbf_header_bbox.add_sint64(OSMFormat::HeaderBBox::required_sint64_top, box.top_right().lat() * lonlat_resolution);
- pbf_header_bbox.add_sint64(OSMFormat::HeaderBBox::required_sint64_bottom, box.bottom_left().lat() * lonlat_resolution);
+ pbf_header_bbox.add_sint64(OSMFormat::HeaderBBox::required_sint64_left, int64_t(box.bottom_left().lon() * lonlat_resolution));
+ pbf_header_bbox.add_sint64(OSMFormat::HeaderBBox::required_sint64_right, int64_t(box.top_right().lon() * lonlat_resolution));
+ pbf_header_bbox.add_sint64(OSMFormat::HeaderBBox::required_sint64_top, int64_t(box.top_right().lat() * lonlat_resolution));
+ pbf_header_bbox.add_sint64(OSMFormat::HeaderBBox::required_sint64_bottom, int64_t(box.bottom_left().lat() * lonlat_resolution));
}
pbf_header_block.add_string(OSMFormat::HeaderBlock::repeated_string_required_features, "OsmSchema-V0.6");
@@ -538,8 +542,8 @@ namespace osmium {
pbf_relation.add_int64(OSMFormat::Relation::required_int64_id, relation.id());
add_meta(relation, pbf_relation);
- auto map_member_role = [this](const osmium::RelationMember& member) -> size_t {
- return m_primitive_block.add_string(member.role());
+ auto map_member_role = [this](const osmium::RelationMember& member) -> uint32_t {
+ return m_primitive_block.store_in_stringtable(member.role());
};
pbf_relation.add_packed_int32(OSMFormat::Relation::packed_int32_roles_sid,
boost::make_transform_iterator(relation.members().begin(), map_member_role),
diff --git a/include/osmium/io/detail/read_write.hpp b/include/osmium/io/detail/read_write.hpp
index 9863bd7..773497c 100644
--- a/include/osmium/io/detail/read_write.hpp
+++ b/include/osmium/io/detail/read_write.hpp
@@ -68,6 +68,9 @@ namespace osmium {
*/
inline int open_for_writing(const std::string& filename, osmium::io::overwrite allow_overwrite = osmium::io::overwrite::no) {
if (filename == "" || filename == "-") {
+#ifdef _WIN32
+ _setmode(1, _O_BINARY);
+#endif
return 1; // stdout
} else {
int flags = O_WRONLY | O_CREAT;
diff --git a/include/osmium/io/detail/string_table.hpp b/include/osmium/io/detail/string_table.hpp
index ae9d5f0..a048de3 100644
--- a/include/osmium/io/detail/string_table.hpp
+++ b/include/osmium/io/detail/string_table.hpp
@@ -41,6 +41,8 @@ DEALINGS IN THE SOFTWARE.
#include <map>
#include <string>
+#include <osmium/io/detail/pbf.hpp>
+
namespace osmium {
namespace io {
@@ -172,15 +174,15 @@ namespace osmium {
// These functions get you some idea how much memory was
// used.
- int get_chunk_size() const noexcept {
+ size_t get_chunk_size() const noexcept {
return m_chunk_size;
}
- int get_chunk_count() const noexcept {
+ size_t get_chunk_count() const noexcept {
return m_chunks.size();
}
- int get_used_bytes_in_last_chunk() const noexcept {
+ size_t get_used_bytes_in_last_chunk() const noexcept {
return m_chunks.front().size();
}
@@ -196,9 +198,16 @@ namespace osmium {
class StringTable {
+ // This is the maximum number of entries in a string table.
+ // This should never be reached in practice but we better
+ // make sure it doesn't. If we had max_uncompressed_blob_size
+ // many entries, we are sure they would never fit into a PBF
+ // Blob.
+ static constexpr const uint32_t max_entries = max_uncompressed_blob_size;
+
StringStore m_strings;
std::map<const char*, size_t, StrComp> m_index;
- size_t m_size;
+ uint32_t m_size;
public:
@@ -216,18 +225,23 @@ namespace osmium {
m_strings.add("");
}
- size_t size() const noexcept {
+ uint32_t size() const noexcept {
return m_size + 1;
}
- size_t add(const char* s) {
+ uint32_t add(const char* s) {
auto f = m_index.find(s);
if (f != m_index.end()) {
- return f->second;
+ return uint32_t(f->second);
}
const char* cs = m_strings.add(s);
m_index[cs] = ++m_size;
+
+ if (m_size > max_entries) {
+ throw osmium::pbf_error("string table has too many entries");
+ }
+
return m_size;
}
diff --git a/include/osmium/io/file.hpp b/include/osmium/io/file.hpp
index 3bbfacc..f5acef4 100644
--- a/include/osmium/io/file.hpp
+++ b/include/osmium/io/file.hpp
@@ -257,7 +257,7 @@ namespace osmium {
*
* @throws std::runtime_error
*/
- void check() const {
+ const File& check() const {
if (m_file_format == file_format::unknown) {
std::string msg = "Could not detect file format";
if (!m_format_string.empty()) {
@@ -275,6 +275,7 @@ namespace osmium {
msg += ".";
throw std::runtime_error(msg);
}
+ return *this;
}
file_format format() const noexcept {
diff --git a/include/osmium/io/reader.hpp b/include/osmium/io/reader.hpp
index c68a8e1..e093533 100644
--- a/include/osmium/io/reader.hpp
+++ b/include/osmium/io/reader.hpp
@@ -75,6 +75,7 @@ namespace osmium {
class Reader {
osmium::io::File m_file;
+ osmium::io::detail::InputFormatFactory::create_input_type* m_input_format_creator;
osmium::osm_entity_bits::type m_read_which_entities;
std::atomic<bool> m_input_done;
int m_childpid;
@@ -168,7 +169,8 @@ namespace osmium {
* parsed.
*/
explicit Reader(const osmium::io::File& file, osmium::osm_entity_bits::type read_which_entities = osmium::osm_entity_bits::all) :
- m_file(file),
+ m_file(file.check()),
+ m_input_format_creator(osmium::io::detail::InputFormatFactory::instance().get_creator_function(m_file)),
m_read_which_entities(read_which_entities),
m_input_done(false),
m_childpid(0),
@@ -177,7 +179,7 @@ namespace osmium {
osmium::io::CompressionFactory::instance().create_decompressor(file.compression(), m_file.buffer(), m_file.buffer_size()) :
osmium::io::CompressionFactory::instance().create_decompressor(file.compression(), open_input_file_or_url(m_file.filename(), &m_childpid))),
m_read_future(std::async(std::launch::async, detail::ReadThread(m_input_queue, m_decompressor.get(), m_input_done))),
- m_input(osmium::io::detail::InputFormatFactory::instance().create_input(m_file, m_read_which_entities, m_input_queue)) {
+ m_input((*m_input_format_creator)(m_file, m_read_which_entities, m_input_queue)) {
}
explicit Reader(const std::string& filename, osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::all) :
diff --git a/include/osmium/io/writer.hpp b/include/osmium/io/writer.hpp
index 64afe20..018dd11 100644
--- a/include/osmium/io/writer.hpp
+++ b/include/osmium/io/writer.hpp
@@ -87,7 +87,7 @@ namespace osmium {
* @throws std::system_error If the file could not be opened.
*/
explicit Writer(const osmium::io::File& file, const osmium::io::Header& header = osmium::io::Header(), overwrite allow_overwrite = overwrite::no) :
- m_file(file),
+ m_file(file.check()),
m_output_queue(20, "raw_output"), // XXX
m_output(osmium::io::detail::OutputFormatFactory::instance().create_output(m_file, m_output_queue)),
m_compressor(osmium::io::CompressionFactory::instance().create_compressor(file.compression(), osmium::io::detail::open_for_writing(m_file.filename(), allow_overwrite))),
diff --git a/include/osmium/osm/crc.hpp b/include/osmium/osm/crc.hpp
index eefa4a1..61ef249 100644
--- a/include/osmium/osm/crc.hpp
+++ b/include/osmium/osm/crc.hpp
@@ -46,10 +46,9 @@ DEALINGS IN THE SOFTWARE.
namespace osmium {
- template <class TCRC>
- class CRC {
+ namespace util {
- static inline uint16_t byte_swap_16(uint16_t value) noexcept {
+ inline uint16_t byte_swap_16(uint16_t value) noexcept {
# if defined(__GNUC__) || defined(__clang__)
return __builtin_bswap16(value);
# else
@@ -57,27 +56,32 @@ namespace osmium {
# endif
}
- static inline uint32_t byte_swap_32(uint32_t value) noexcept {
+ inline uint32_t byte_swap_32(uint32_t value) noexcept {
# if defined(__GNUC__) || defined(__clang__)
return __builtin_bswap32(value);
# else
return (value >> 24) |
- ((value >> 8) & 0x0000FF00) |
- ((value << 8) & 0x00FF0000) |
+ ((value >> 8) & 0x0000FF00) |
+ ((value << 8) & 0x00FF0000) |
(value << 24);
# endif
}
- static inline uint64_t byte_swap_64(uint64_t value) noexcept {
+ inline uint64_t byte_swap_64(uint64_t value) noexcept {
# if defined(__GNUC__) || defined(__clang__)
return __builtin_bswap64(value);
# else
uint64_t val1 = byte_swap_32(value & 0xFFFFFFFF);
uint64_t val2 = byte_swap_32(value >> 32);
- return (val1 << 32) & val2;
+ return (val1 << 32) | val2;
# endif
}
+ }
+
+ template <class TCRC>
+ class CRC {
+
TCRC m_crc;
public:
@@ -90,37 +94,37 @@ namespace osmium {
return m_crc;
}
- void update_bool(bool value) {
+ void update_bool(const bool value) {
m_crc.process_byte(value);
}
- void update_int8(uint8_t value) {
+ void update_int8(const uint8_t value) {
m_crc.process_byte(value);
}
- void update_int16(uint16_t value) {
+ void update_int16(const uint16_t value) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
m_crc.process_bytes(&value, sizeof(uint16_t));
#else
- uint16_t v = byte_swap_16(value);
+ uint16_t v = osmium::util::byte_swap_16(value);
m_crc.process_bytes(&v, sizeof(uint16_t));
#endif
}
- void update_int32(uint32_t value) {
+ void update_int32(const uint32_t value) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
m_crc.process_bytes(&value, sizeof(uint32_t));
#else
- uint32_t v = byte_swap_32(value);
+ uint32_t v = osmium::util::byte_swap_32(value);
m_crc.process_bytes(&v, sizeof(uint32_t));
#endif
}
- void update_int64(uint64_t value) {
+ void update_int64(const uint64_t value) {
#if __BYTE_ORDER == __LITTLE_ENDIAN
m_crc.process_bytes(&value, sizeof(uint64_t));
#else
- uint64_t v = byte_swap_64(value);
+ uint64_t v = osmium::util::byte_swap_64(value);
m_crc.process_bytes(&v, sizeof(uint64_t));
#endif
}
diff --git a/include/osmium/osm/types.hpp b/include/osmium/osm/types.hpp
index b3414e5..c9ab423 100644
--- a/include/osmium/osm/types.hpp
+++ b/include/osmium/osm/types.hpp
@@ -57,6 +57,9 @@ namespace osmium {
*/
typedef uint16_t string_size_type;
+ // maximum of 256 characters of max 4 bytes each (in UTF-8 encoding)
+ constexpr const int max_osm_string_length = 256 * 4;
+
} // namespace osmium
#endif // OSMIUM_OSM_TYPES_HPP
diff --git a/include/osmium/util/delta.hpp b/include/osmium/util/delta.hpp
index 0c77e52..f5d6719 100644
--- a/include/osmium/util/delta.hpp
+++ b/include/osmium/util/delta.hpp
@@ -99,18 +99,18 @@ namespace osmium {
TBaseIterator m_it;
TBaseIterator m_end;
+ TTransform m_trans;
value_type m_delta;
DeltaEncode<value_type> m_value;
- TTransform m_trans;
public:
DeltaEncodeIterator(TBaseIterator first, TBaseIterator last, TTransform& trans) :
m_it(first),
m_end(last),
- m_delta(m_trans(m_it)),
- m_value(m_delta),
- m_trans(trans) {
+ m_trans(trans),
+ m_delta(m_it != m_end ? m_trans(m_it) : 0),
+ m_value(m_delta) {
}
DeltaEncodeIterator& operator++() {
diff --git a/include/osmium/util/memory_mapping.hpp b/include/osmium/util/memory_mapping.hpp
index e48aff2..4bb3641 100644
--- a/include/osmium/util/memory_mapping.hpp
+++ b/include/osmium/util/memory_mapping.hpp
@@ -43,6 +43,7 @@ DEALINGS IN THE SOFTWARE.
#ifndef _WIN32
# include <sys/mman.h>
#else
+# include <fcntl.h>
# include <io.h>
# include <windows.h>
# include <sys/types.h>
@@ -85,6 +86,9 @@ namespace osmium {
* On Unix systems this wraps the mmap(), munmap(), and the mremap()
* system calls. On Windows it wraps the CreateFileMapping(),
* CloseHandle(), MapViewOfFile(), and UnmapViewOfFile() functions.
+ *
+ * On Windows the file will be set to binary mode before the memory
+ * mapping.
*/
class MemoryMapping {
@@ -655,6 +659,9 @@ inline HANDLE osmium::util::MemoryMapping::get_handle() const noexcept {
}
inline HANDLE osmium::util::MemoryMapping::create_file_mapping() const noexcept {
+ if (m_fd != -1) {
+ _setmode(m_fd, _O_BINARY);
+ }
return CreateFileMapping(get_handle(), nullptr, get_protection(), osmium::util::dword_hi(static_cast<uint64_t>(m_size) + m_offset), osmium::util::dword_lo(static_cast<uint64_t>(m_size) + m_offset), nullptr);
}
diff --git a/include/protozero/varint.hpp b/include/protozero/varint.hpp
index bc9c329..27536fd 100644
--- a/include/protozero/varint.hpp
+++ b/include/protozero/varint.hpp
@@ -16,10 +16,6 @@ documentation.
* @brief Contains low-level varint and zigzag encoding and decoding functions.
*/
-#if __BYTE_ORDER != __LITTLE_ENDIAN
-# error "This code only works on little endian machines."
-#endif
-
#include <cstdint>
#include <protozero/exception.hpp>
diff --git a/include/protozero/version.hpp b/include/protozero/version.hpp
new file mode 100644
index 0000000..098492e
--- /dev/null
+++ b/include/protozero/version.hpp
@@ -0,0 +1,22 @@
+#ifndef PROTOZERO_VERSION_HPP
+#define PROTOZERO_VERSION_HPP
+
+/*****************************************************************************
+
+protozero - Minimalistic protocol buffer decoder and encoder in C++.
+
+This file is from https://github.com/mapbox/protozero where you can find more
+documentation.
+
+*****************************************************************************/
+
+#define PROTOZERO_VERSION_MAJOR 1
+#define PROTOZERO_VERSION_MINOR 1
+#define PROTOZERO_VERSION_PATCH 0
+
+#define PROTOZERO_VERSION_CODE (PROTOZERO_VERSION_MAJOR * 10000 + PROTOZERO_VERSION_MINOR * 100 + PROTOZERO_VERSION_PATCH)
+
+#define PROTOZERO_VERSION_STRING "1.1.0"
+
+
+#endif // PROTOZERO_VERSION_HPP
diff --git a/scripts/travis_script.sh b/scripts/travis_script.sh
index 75b3b36..d11ac79 100755
--- a/scripts/travis_script.sh
+++ b/scripts/travis_script.sh
@@ -19,11 +19,18 @@ if [ "${CXX}" = "g++" ]; then
CC=gcc-4.8
fi
+echo "travis_fold:start:cmake\nRunning cmake..."
cmake -LA \
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
${WORKAROUND} \
..
+echo "travis_fold:end:cmake"
+echo "travis_fold:start:make\nRunning make..."
make VERBOSE=1
+echo "travis_fold:end:make"
+
+echo "travis_fold:start:ctest\nRunning ctest..."
ctest --output-on-failure
+echo "travis_fold:end:ctest"
diff --git a/test/data-tests/testdata-multipolygon.cpp b/test/data-tests/testdata-multipolygon.cpp
index 0fd0d98..e0d6583 100644
--- a/test/data-tests/testdata-multipolygon.cpp
+++ b/test/data-tests/testdata-multipolygon.cpp
@@ -3,6 +3,8 @@
#include <fstream>
#include <map>
+#include <gdalcpp.hpp>
+
#include <osmium/index/map/sparse_mem_array.hpp>
#include <osmium/area/assembler.hpp>
@@ -41,10 +43,9 @@ inline tagmap_type create_map(const osmium::TagList& taglist) {
class TestHandler : public osmium::handler::Handler {
- OGRDataSource* m_data_source;
- OGRLayer* m_layer_point;
- OGRLayer* m_layer_linestring;
- OGRLayer* m_layer_polygon;
+ gdalcpp::Layer m_layer_point;
+ gdalcpp::Layer m_layer_lines;
+ gdalcpp::Layer m_layer_mpoly;
osmium::geom::OGRFactory<> m_ogr_factory;
osmium::geom::WKTFactory<> m_wkt_factory;
@@ -55,84 +56,20 @@ class TestHandler : public osmium::handler::Handler {
public:
- TestHandler(OGRDataSource* data_source) :
- m_data_source(data_source),
+ TestHandler(gdalcpp::Dataset& dataset) :
+ m_layer_point(dataset, "points", wkbPoint),
+ m_layer_lines(dataset, "lines", wkbLineString),
+ m_layer_mpoly(dataset, "multipolygons", wkbMultiPolygon),
m_out("multipolygon-tests.json") {
- OGRSpatialReference sparef;
- sparef.SetWellKnownGeogCS("WGS84");
-
- /**************/
-
- m_layer_point = m_data_source->CreateLayer("points", &sparef, wkbPoint, nullptr);
- if (!m_layer_point) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_point_field_id("id", OFTReal);
- layer_point_field_id.SetWidth(10);
-
- if (m_layer_point->CreateField(&layer_point_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_point_field_type("type", OFTString);
- layer_point_field_type.SetWidth(30);
-
- if (m_layer_point->CreateField(&layer_point_field_type) != OGRERR_NONE) {
- std::cerr << "Creating type field failed.\n";
- exit(1);
- }
-
- /**************/
+ m_layer_point.add_field("id", OFTReal, 10);
+ m_layer_point.add_field("type", OFTString, 30);
- m_layer_linestring = m_data_source->CreateLayer("lines", &sparef, wkbLineString, nullptr);
- if (!m_layer_linestring) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
+ m_layer_lines.add_field("id", OFTReal, 10);
+ m_layer_lines.add_field("type", OFTString, 30);
- OGRFieldDefn layer_linestring_field_id("id", OFTReal);
- layer_linestring_field_id.SetWidth(10);
-
- if (m_layer_linestring->CreateField(&layer_linestring_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_linestring_field_type("type", OFTString);
- layer_linestring_field_type.SetWidth(30);
-
- if (m_layer_linestring->CreateField(&layer_linestring_field_type) != OGRERR_NONE) {
- std::cerr << "Creating type field failed.\n";
- exit(1);
- }
-
- /**************/
-
- m_layer_polygon = m_data_source->CreateLayer("multipolygons", &sparef, wkbMultiPolygon, nullptr);
- if (!m_layer_polygon) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_polygon_field_id("id", OFTInteger);
- layer_polygon_field_id.SetWidth(10);
-
- if (m_layer_polygon->CreateField(&layer_polygon_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_polygon_field_from_type("from_type", OFTString);
- layer_polygon_field_from_type.SetWidth(1);
-
- if (m_layer_polygon->CreateField(&layer_polygon_field_from_type) != OGRERR_NONE) {
- std::cerr << "Creating from_type field failed.\n";
- exit(1);
- }
+ m_layer_mpoly.add_field("id", OFTReal, 10);
+ m_layer_mpoly.add_field("from_type", OFTString, 1);
}
~TestHandler() {
@@ -140,34 +77,18 @@ public:
}
void node(const osmium::Node& node) {
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_point->GetLayerDefn());
- std::unique_ptr<OGRPoint> ogr_point = m_ogr_factory.create_point(node);
- feature->SetGeometry(ogr_point.get());
- feature->SetField("id", static_cast<double>(node.id()));
- feature->SetField("type", node.tags().get_value_by_key("type"));
-
- if (m_layer_point->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
+ gdalcpp::Feature feature(m_layer_point, m_ogr_factory.create_point(node));
+ feature.set_field("id", static_cast<double>(node.id()));
+ feature.set_field("type", node.tags().get_value_by_key("type"));
+ feature.add_to_layer();
}
void way(const osmium::Way& way) {
try {
- std::unique_ptr<OGRLineString> ogr_linestring = m_ogr_factory.create_linestring(way);
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_linestring->GetLayerDefn());
- feature->SetGeometry(ogr_linestring.get());
- feature->SetField("id", static_cast<double>(way.id()));
- feature->SetField("type", way.tags().get_value_by_key("type"));
-
- if (m_layer_linestring->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
+ gdalcpp::Feature feature(m_layer_lines, m_ogr_factory.create_linestring(way));
+ feature.set_field("id", static_cast<double>(way.id()));
+ feature.set_field("type", way.tags().get_value_by_key("type"));
+ feature.add_to_layer();
} catch (osmium::geometry_error&) {
std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n";
}
@@ -200,10 +121,8 @@ public:
m_out << "INVALID\"\n}";
}
try {
- std::unique_ptr<OGRMultiPolygon> ogr_polygon = m_ogr_factory.create_multipolygon(area);
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_polygon->GetLayerDefn());
- feature->SetGeometry(ogr_polygon.get());
- feature->SetField("id", static_cast<int>(area.orig_id()));
+ gdalcpp::Feature feature(m_layer_mpoly, m_ogr_factory.create_multipolygon(area));
+ feature.set_field("id", static_cast<double>(area.orig_id()));
std::string from_type;
if (area.from_way()) {
@@ -211,14 +130,8 @@ public:
} else {
from_type = "r";
}
- feature->SetField("from_type", from_type.c_str());
-
- if (m_layer_polygon->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
+ feature.set_field("from_type", from_type.c_str());
+ feature.add_to_layer();
} catch (osmium::geometry_error&) {
std::cerr << "Ignoring illegal geometry for area " << area.id() << " created from " << (area.from_way() ? "way" : "relation") << " with id=" << area.orig_id() << ".\n";
}
@@ -228,26 +141,6 @@ public:
/* ================================================== */
-OGRDataSource* initialize_database(const std::string& output_format, const std::string& output_filename) {
- OGRRegisterAll();
-
- OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(output_format.c_str());
- if (!driver) {
- std::cerr << output_format << " driver not available.\n";
- exit(1);
- }
-
- CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
- const char* options[] = { "SPATIALITE=TRUE", nullptr };
- OGRDataSource* data_source = driver->CreateDataSource(output_filename.c_str(), const_cast<char**>(options));
- if (!data_source) {
- std::cerr << "Creation of output file failed.\n";
- exit(1);
- }
-
- return data_source;
-}
-
int main(int argc, char* argv[]) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " INFILE\n";
@@ -258,9 +151,10 @@ int main(int argc, char* argv[]) {
std::string input_filename(argv[1]);
std::string output_filename("multipolygon.db");
- OGRDataSource* data_source = initialize_database(output_format, output_filename);
+ CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
+ gdalcpp::Dataset dataset(output_format, output_filename, "", { "SPATIALITE=TRUE" });
- osmium::area::ProblemReporterOGR problem_reporter(data_source);
+ osmium::area::ProblemReporterOGR problem_reporter(dataset);
osmium::area::Assembler::config_type assembler_config(&problem_reporter);
assembler_config.enable_debug_output();
osmium::area::MultipolygonCollector<osmium::area::Assembler> collector(assembler_config);
@@ -275,7 +169,7 @@ int main(int argc, char* argv[]) {
location_handler_type location_handler(index);
location_handler.ignore_errors();
- TestHandler test_handler(data_source);
+ TestHandler test_handler(dataset);
std::cerr << "Pass 2...\n";
osmium::io::Reader reader2(input_filename);
@@ -284,8 +178,5 @@ int main(int argc, char* argv[]) {
}));
reader2.close();
std::cerr << "Pass 2 done\n";
-
- OGRDataSource::DestroyDataSource(data_source);
- OGRCleanupAll();
}
diff --git a/test/data-tests/testdata-overview.cpp b/test/data-tests/testdata-overview.cpp
index 2d63dc6..2c88ece 100644
--- a/test/data-tests/testdata-overview.cpp
+++ b/test/data-tests/testdata-overview.cpp
@@ -2,6 +2,8 @@
#include <iostream>
+#include <gdalcpp.hpp>
+
#include <osmium/index/map/sparse_mem_array.hpp>
#include <osmium/geom/ogr.hpp>
@@ -15,154 +17,53 @@ typedef osmium::handler::NodeLocationsForWays<index_type> location_handler_type;
class TestOverviewHandler : public osmium::handler::Handler {
- OGRDataSource* m_data_source;
-
- OGRLayer* m_layer_nodes;
- OGRLayer* m_layer_labels;
- OGRLayer* m_layer_ways;
+ gdalcpp::Layer m_layer_nodes;
+ gdalcpp::Layer m_layer_labels;
+ gdalcpp::Layer m_layer_ways;
osmium::geom::OGRFactory<> m_factory;
public:
- TestOverviewHandler(const std::string& driver_name, const std::string& filename) {
-
- OGRRegisterAll();
-
- OGRSFDriver* driver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str());
- if (!driver) {
- std::cerr << driver_name << " driver not available.\n";
- exit(1);
- }
-
- CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
- const char* options[] = { "SPATIALITE=TRUE", nullptr };
- m_data_source = driver->CreateDataSource(filename.c_str(), const_cast<char**>(options));
- if (!m_data_source) {
- std::cerr << "Creation of output file failed.\n";
- exit(1);
- }
-
- OGRSpatialReference sparef;
- sparef.SetWellKnownGeogCS("WGS84");
+ TestOverviewHandler(gdalcpp::Dataset& dataset) :
+ m_layer_nodes(dataset, "nodes", wkbPoint),
+ m_layer_labels(dataset, "labels", wkbPoint),
+ m_layer_ways(dataset, "ways", wkbLineString) {
- // nodes layer
-
- m_layer_nodes = m_data_source->CreateLayer("nodes", &sparef, wkbPoint, nullptr);
- if (!m_layer_nodes) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_nodes_field_id("id", OFTReal);
- layer_nodes_field_id.SetWidth(10);
-
- if (m_layer_nodes->CreateField(&layer_nodes_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- // labels layer
-
- m_layer_labels = m_data_source->CreateLayer("labels", &sparef, wkbPoint, nullptr);
- if (!m_layer_labels) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_labels_field_id("id", OFTReal);
- layer_labels_field_id.SetWidth(10);
-
- if (m_layer_labels->CreateField(&layer_labels_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
+ m_layer_nodes.add_field("id", OFTReal, 10);
- OGRFieldDefn layer_labels_field_label("label", OFTString);
- layer_labels_field_label.SetWidth(30);
+ m_layer_labels.add_field("id", OFTReal, 10);
+ m_layer_labels.add_field("label", OFTString, 30);
- if (m_layer_labels->CreateField(&layer_labels_field_label) != OGRERR_NONE) {
- std::cerr << "Creating label field failed.\n";
- exit(1);
- }
-
- // ways layer
-
- m_layer_ways = m_data_source->CreateLayer("ways", &sparef, wkbLineString, nullptr);
- if (!m_layer_ways) {
- std::cerr << "Layer creation failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_way_field_id("id", OFTReal);
- layer_way_field_id.SetWidth(10);
-
- if (m_layer_ways->CreateField(&layer_way_field_id) != OGRERR_NONE) {
- std::cerr << "Creating id field failed.\n";
- exit(1);
- }
-
- OGRFieldDefn layer_way_field_test("test", OFTInteger);
- layer_way_field_test.SetWidth(3);
-
- if (m_layer_ways->CreateField(&layer_way_field_test) != OGRERR_NONE) {
- std::cerr << "Creating test field failed.\n";
- exit(1);
- }
- }
-
- ~TestOverviewHandler() {
- OGRDataSource::DestroyDataSource(m_data_source);
- OGRCleanupAll();
+ m_layer_ways.add_field("id", OFTReal, 10);
+ m_layer_ways.add_field("test", OFTInteger, 3);
}
void node(const osmium::Node& node) {
const char* label = node.tags().get_value_by_key("label");
if (label) {
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_labels->GetLayerDefn());
- std::unique_ptr<OGRPoint> ogr_point = m_factory.create_point(node);
- feature->SetGeometry(ogr_point.get());
- feature->SetField("id", static_cast<double>(node.id()));
- feature->SetField("label", label);
-
- if (m_layer_labels->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
-
- OGRFeature::DestroyFeature(feature);
+ gdalcpp::Feature feature(m_layer_labels, m_factory.create_point(node));
+ feature.set_field("id", static_cast<double>(node.id()));
+ feature.set_field("label", label);
+ feature.add_to_layer();
} else {
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_nodes->GetLayerDefn());
- std::unique_ptr<OGRPoint> ogr_point = m_factory.create_point(node);
- feature->SetGeometry(ogr_point.get());
- feature->SetField("id", static_cast<double>(node.id()));
-
- if (m_layer_nodes->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
- }
- OGRFeature::DestroyFeature(feature);
+ gdalcpp::Feature feature(m_layer_nodes, m_factory.create_point(node));
+ feature.set_field("id", static_cast<double>(node.id()));
+ feature.add_to_layer();
}
}
void way(const osmium::Way& way) {
try {
- std::unique_ptr<OGRLineString> ogr_linestring = m_factory.create_linestring(way);
- OGRFeature* feature = OGRFeature::CreateFeature(m_layer_ways->GetLayerDefn());
- feature->SetGeometry(ogr_linestring.get());
- feature->SetField("id", static_cast<double>(way.id()));
+ gdalcpp::Feature feature(m_layer_ways, m_factory.create_linestring(way));
+ feature.set_field("id", static_cast<double>(way.id()));
const char* test = way.tags().get_value_by_key("test");
if (test) {
- feature->SetField("test", test);
- }
-
- if (m_layer_ways->CreateFeature(feature) != OGRERR_NONE) {
- std::cerr << "Failed to create feature.\n";
- exit(1);
+ feature.set_field("test", test);
}
- OGRFeature::DestroyFeature(feature);
+ feature.add_to_layer();
} catch (osmium::geometry_error&) {
std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n";
}
@@ -183,13 +84,16 @@ int main(int argc, char* argv[]) {
std::string output_filename("testdata-overview.db");
::unlink(output_filename.c_str());
+ CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE");
+ gdalcpp::Dataset dataset(output_format, output_filename, "", { "SPATIALITE=TRUE" });
+
osmium::io::Reader reader(input_filename);
index_type index;
location_handler_type location_handler(index);
location_handler.ignore_errors();
- TestOverviewHandler handler(output_format, output_filename);
+ TestOverviewHandler handler(dataset);
osmium::apply(reader, location_handler, handler);
reader.close();
diff --git a/test/t/basic/test_crc.cpp b/test/t/basic/test_crc.cpp
index aab1013..fcd50a1 100644
--- a/test/t/basic/test_crc.cpp
+++ b/test/t/basic/test_crc.cpp
@@ -24,6 +24,27 @@ TEST_CASE("CRC of basic datatypes") {
REQUIRE(crc32().checksum() == 0x8fe62899);
}
+ SECTION("Int16") {
+ crc32.update_int16(0x0123U);
+ crc32.update_int16(0x1234U);
+
+ REQUIRE(crc32().checksum() == 0xda923744);
+ }
+
+ SECTION("Int32") {
+ crc32.update_int32(0x01234567UL);
+ crc32.update_int32(0x12345678UL);
+
+ REQUIRE(crc32().checksum() == 0x9b4e2af3);
+ }
+
+ SECTION("Int64") {
+ crc32.update_int64(0x0123456789abcdefULL);
+ crc32.update_int64(0x123456789abcdef0ULL);
+
+ REQUIRE(crc32().checksum() == 0x6d8b7267);
+ }
+
SECTION("String") {
const char* str = "foobar";
crc32.update_string(str);
diff --git a/test/t/basic/test_relation.cpp b/test/t/basic/test_relation.cpp
index fd5c7b4..4b608ff 100644
--- a/test/t/basic/test_relation.cpp
+++ b/test/t/basic/test_relation.cpp
@@ -63,3 +63,14 @@ TEST_CASE("Build relation") {
crc32.update(relation);
REQUIRE(crc32().checksum() == 0xebcd836d);
}
+
+TEST_CASE("Member role too long") {
+ osmium::memory::Buffer buffer(10000);
+
+ osmium::builder::RelationMemberListBuilder builder(buffer);
+
+ const char role[2000] = "";
+ builder.add_member(osmium::item_type::node, 1, role, 1024);
+ REQUIRE_THROWS(builder.add_member(osmium::item_type::node, 1, role, 1025));
+}
+
diff --git a/test/t/tags/test_tag_list.cpp b/test/t/tags/test_tag_list.cpp
index 77523e7..295f51a 100644
--- a/test/t/tags/test_tag_list.cpp
+++ b/test/t/tags/test_tag_list.cpp
@@ -100,3 +100,14 @@ TEST_CASE("empty keys and values are okay") {
REQUIRE(std::string("") == tl.get_value_by_key("empty value"));
REQUIRE(std::string("empty key") == tl.get_value_by_key(""));
}
+
+TEST_CASE("tag key or value is too long") {
+ osmium::memory::Buffer buffer(10240);
+ osmium::builder::TagListBuilder builder(buffer);
+
+ const char kv[2000] = "";
+ builder.add_tag(kv, 1, kv, 1000);
+ REQUIRE_THROWS(builder.add_tag(kv, 1500, kv, 1));
+ REQUIRE_THROWS(builder.add_tag(kv, 1, kv, 1500));
+}
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/libosmium.git
More information about the Pkg-grass-devel
mailing list