Update in-tree libosmium dependency to 2.5.4
The latest releases have some critical fixes, see the changelog: https://github.com/osmcode/libosmium/blob/v2.5.4/CHANGELOG.md Merge commit 'afdf8e7b21fbaf597e91d9d8a7542635e60ee9a1' into use_libosmium_2_5_4
This commit is contained in:
+2
-25
@@ -14,12 +14,10 @@ set(EXAMPLES
|
||||
count
|
||||
create_node_cache
|
||||
debug
|
||||
filter_discussions
|
||||
index
|
||||
read
|
||||
serdump
|
||||
toogr
|
||||
toogr2
|
||||
toogr2_exp
|
||||
use_node_cache
|
||||
CACHE STRING "Example programs"
|
||||
)
|
||||
@@ -30,7 +28,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})
|
||||
@@ -74,27 +72,6 @@ else()
|
||||
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
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
|
||||
Read OSM changesets with discussions from a changeset dump like the one
|
||||
you get from http://planet.osm.org/planet/discussions-latest.osm.bz2
|
||||
and write out only those changesets which have discussions (ie comments).
|
||||
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <algorithm> // for std::copy_if
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
|
||||
// we want to read OSM files in XML format
|
||||
// (other formats don't support full changesets, so only XML is needed here)
|
||||
#include <osmium/io/xml_input.hpp>
|
||||
#include <osmium/io/input_iterator.hpp>
|
||||
|
||||
// we want to write OSM files in XML format
|
||||
#include <osmium/io/xml_output.hpp>
|
||||
#include <osmium/io/output_iterator.hpp>
|
||||
|
||||
// we want to support any compressioon (.gz2 and .bz2)
|
||||
#include <osmium/io/any_compression.hpp>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
std::cout << "Usage: " << argv[0] << " INFILE OUTFILE\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// The input file, deduce file format from file suffix
|
||||
osmium::io::File infile(argv[1]);
|
||||
|
||||
// The output file, force class XML OSM file format
|
||||
osmium::io::File outfile(argv[2], "osm");
|
||||
|
||||
// Initialize Reader for the input file.
|
||||
// Read only changesets (will ignore nodes, ways, and
|
||||
// relations if there are any).
|
||||
osmium::io::Reader reader(infile, osmium::osm_entity_bits::changeset);
|
||||
|
||||
// Get the header from the input file
|
||||
osmium::io::Header header = reader.header();
|
||||
|
||||
// Initialize writer for the output file. Use the header from the input
|
||||
// file for the output file. This will copy over some header information.
|
||||
// The last parameter will tell the writer that it is allowed to overwrite
|
||||
// an existing file. Without it, it will refuse to do so.
|
||||
osmium::io::Writer writer(outfile, header, osmium::io::overwrite::allow);
|
||||
|
||||
// Create range of input iterators that will iterator over all changesets
|
||||
// delivered from input file through the "reader".
|
||||
auto input_range = osmium::io::make_input_iterator_range<osmium::Changeset>(reader);
|
||||
|
||||
// Create an output iterator writing through the "writer" object to the
|
||||
// output file.
|
||||
auto output_iterator = osmium::io::make_output_iterator(writer);
|
||||
|
||||
// Copy all changesets from input to output that have at least one comment.
|
||||
std::copy_if(input_range.begin(), input_range.end(), output_iterator, [](const osmium::Changeset& changeset) {
|
||||
return changeset.num_comments() > 0;
|
||||
});
|
||||
|
||||
// Explicitly close the writer and reader. Will throw an exception if
|
||||
// there is a problem. If you wait for the destructor to close the writer
|
||||
// and reader, you will not notice the problem, because destructors must
|
||||
// not throw.
|
||||
writer.close();
|
||||
reader.close();
|
||||
}
|
||||
|
||||
-244
@@ -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);
|
||||
}
|
||||
|
||||
-331
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user