Merge commit '879f7eb04200d7d2c28af565229bf6e3d54274fd' into retry/libosmium
This commit is contained in:
+7
-33
@@ -12,13 +12,17 @@ set(EXAMPLES
|
||||
area_test
|
||||
convert
|
||||
count
|
||||
create_node_cache
|
||||
debug
|
||||
filter_discussions
|
||||
index
|
||||
location_cache_create
|
||||
location_cache_use
|
||||
pub_names
|
||||
read
|
||||
read_with_progress
|
||||
road_length
|
||||
serdump
|
||||
use_node_cache
|
||||
tiles
|
||||
CACHE STRING "Example programs"
|
||||
)
|
||||
|
||||
@@ -28,7 +32,7 @@ set(EXAMPLES
|
||||
# Examples depending on wingetopt
|
||||
#
|
||||
#-----------------------------------------------------------------------------
|
||||
set(GETOPT_EXAMPLES area_test convert serdump)
|
||||
set(GETOPT_EXAMPLES area_test convert index serdump)
|
||||
if(NOT GETOPT_MISSING)
|
||||
foreach(example ${GETOPT_EXAMPLES})
|
||||
list(APPEND EXAMPLE_LIBS_${example} ${GETOPT_LIBRARY})
|
||||
@@ -42,36 +46,6 @@ else()
|
||||
endif()
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
# Examples depending on SparseHash
|
||||
#
|
||||
#-----------------------------------------------------------------------------
|
||||
if(NOT SPARSEHASH_FOUND)
|
||||
list(REMOVE_ITEM EXAMPLES area_test)
|
||||
message(STATUS "Configuring examples - Skipping examples because Google SparseHash not found:")
|
||||
message(STATUS " - osmium_area_test")
|
||||
endif()
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
# Examples depending on Boost Program Options
|
||||
#
|
||||
#-----------------------------------------------------------------------------
|
||||
unset(Boost_LIBRARIES)
|
||||
unset(Boost_FOUND)
|
||||
find_package(Boost 1.38 COMPONENTS program_options)
|
||||
|
||||
if(Boost_PROGRAM_OPTIONS_FOUND)
|
||||
list(APPEND EXAMPLE_LIBS_index ${Boost_PROGRAM_OPTIONS_LIBRARY})
|
||||
else()
|
||||
list(REMOVE_ITEM EXAMPLES index)
|
||||
message(STATUS "Configuring examples - Skipping examples because Boost program_options not found:")
|
||||
message(STATUS " - osmium_index")
|
||||
endif()
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
#
|
||||
# Configure examples
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
|
||||
# Osmium example programs
|
||||
|
||||
The programs in this directory are intended as examples for developers. They
|
||||
contain extensive comments explaining what's going on. Note that the examples
|
||||
only cover a small part of what Osmium can do, you should also read the
|
||||
documentation and API documentation.
|
||||
|
||||
All programs can be run without arguments and they will tell you how to run
|
||||
them.
|
||||
|
||||
## Very simple examples
|
||||
|
||||
* `osmium_read`
|
||||
* `osmium_count`
|
||||
* `osmium_debug`
|
||||
* `osmium_tiles`
|
||||
|
||||
## Still reasonably simple examples
|
||||
|
||||
* `osmium_filter_discussions`
|
||||
* `osmium_convert`
|
||||
|
||||
## More advanced examples
|
||||
|
||||
* `osmium_area_test`
|
||||
|
||||
## License
|
||||
|
||||
The code in these example files is released into the Public Domain. Feel free
|
||||
to copy the code and build on it.
|
||||
|
||||
+97
-32
@@ -1,48 +1,81 @@
|
||||
/*
|
||||
|
||||
This is an example tool that creates multipolygons from OSM data
|
||||
and dumps them to stdout.
|
||||
EXAMPLE osmium_area_test
|
||||
|
||||
Create multipolygons from OSM data and dump them to stdout in one of two
|
||||
formats: WKT or using the built-in Dump format.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input
|
||||
* location indexes and the NodeLocationsForWays handler
|
||||
* the MultipolygonCollector and Assembler to assemble areas (multipolygons)
|
||||
* your own handler that works with areas (multipolygons)
|
||||
* the WKTFactory to write geometries in WKT format
|
||||
* the Dump handler
|
||||
* the DynamicHandler
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
* osmium_count
|
||||
* osmium_debug
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <getopt.h>
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <getopt.h> // for getopt_long
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
|
||||
// For assembling multipolygons
|
||||
#include <osmium/area/assembler.hpp>
|
||||
#include <osmium/area/multipolygon_collector.hpp>
|
||||
|
||||
// For the DynamicHandler class
|
||||
#include <osmium/dynamic_handler.hpp>
|
||||
|
||||
// For the WKT factory
|
||||
#include <osmium/geom/wkt.hpp>
|
||||
|
||||
// For the Dump handler
|
||||
#include <osmium/handler/dump.hpp>
|
||||
|
||||
// For the NodeLocationForWays handler
|
||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
||||
#include <osmium/index/map/dummy.hpp>
|
||||
#include <osmium/index/map/sparse_mem_array.hpp>
|
||||
|
||||
// Allow any format of input files (XML, PBF, ...)
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
// For osmium::apply()
|
||||
#include <osmium/visitor.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;
|
||||
// For the location index. There are different types of indexes available.
|
||||
// This will work for small and medium sized input files.
|
||||
#include <osmium/index/map/sparse_mem_array.hpp>
|
||||
|
||||
// The type of index used. This must match the include file above
|
||||
using index_type = osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location>;
|
||||
|
||||
// The location handler always depends on the index type
|
||||
using location_handler_type = osmium::handler::NodeLocationsForWays<index_type>;
|
||||
|
||||
// This handler writes all area geometries out in WKT (Well Known Text) format.
|
||||
class WKTDump : public osmium::handler::Handler {
|
||||
|
||||
osmium::geom::WKTFactory<> m_factory ;
|
||||
|
||||
std::ostream& m_out;
|
||||
// This factory is used to create a geometry in WKT format from OSM
|
||||
// objects. The template parameter is empty here, because we output WGS84
|
||||
// coordinates, but could be used for a projection.
|
||||
osmium::geom::WKTFactory<> m_factory;
|
||||
|
||||
public:
|
||||
|
||||
WKTDump(std::ostream& out) :
|
||||
m_out(out) {
|
||||
}
|
||||
|
||||
// This callback is called by osmium::apply for each area in the data.
|
||||
void area(const osmium::Area& area) {
|
||||
try {
|
||||
m_out << m_factory.create_multipolygon(area) << "\n";
|
||||
} catch (osmium::geometry_error& e) {
|
||||
m_out << "GEOMETRY ERROR: " << e.what() << "\n";
|
||||
std::cout << m_factory.create_multipolygon(area) << "\n";
|
||||
} catch (const osmium::geometry_error& e) {
|
||||
std::cout << "GEOMETRY ERROR: " << e.what() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,8 +98,13 @@ int main(int argc, char* argv[]) {
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
// Initialize an empty DynamicHandler. Later it will be associated
|
||||
// with one of the handlers. You can think of the DynamicHandler as
|
||||
// a kind of "variant handler" or a "pointer handler" pointing to the
|
||||
// real handler.
|
||||
osmium::handler::DynamicHandler handler;
|
||||
|
||||
// Read options from command line.
|
||||
while (true) {
|
||||
int c = getopt_long(argc, argv, "hwo", long_options, 0);
|
||||
if (c == -1) {
|
||||
@@ -76,54 +114,81 @@ int main(int argc, char* argv[]) {
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_help();
|
||||
exit(0);
|
||||
std::exit(0);
|
||||
case 'w':
|
||||
handler.set<WKTDump>(std::cout);
|
||||
handler.set<WKTDump>();
|
||||
break;
|
||||
case 'o':
|
||||
handler.set<osmium::handler::Dump>(std::cout);
|
||||
break;
|
||||
default:
|
||||
exit(1);
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int remaining_args = argc - optind;
|
||||
if (remaining_args != 1) {
|
||||
std::cerr << "Usage: " << argv[0] << " [OPTIONS] OSMFILE\n";
|
||||
exit(1);
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
osmium::io::File infile(argv[optind]);
|
||||
osmium::io::File input_file{argv[optind]};
|
||||
|
||||
// Configuration for the multipolygon assembler. Here the default settings
|
||||
// are used, but you could change multiple settings.
|
||||
osmium::area::Assembler::config_type assembler_config;
|
||||
osmium::area::MultipolygonCollector<osmium::area::Assembler> collector(assembler_config);
|
||||
|
||||
// Initialize the MultipolygonCollector. Its job is to collect all
|
||||
// relations and member ways needed for each area. It then calls an
|
||||
// instance of the osmium::area::Assembler class (with the given config)
|
||||
// to actually assemble one area.
|
||||
osmium::area::MultipolygonCollector<osmium::area::Assembler> collector{assembler_config};
|
||||
|
||||
// We read the input file twice. In the first pass, only relations are
|
||||
// read and fed into the multipolygon collector.
|
||||
std::cerr << "Pass 1...\n";
|
||||
osmium::io::Reader reader1(infile, osmium::osm_entity_bits::relation);
|
||||
osmium::io::Reader reader1{input_file, osmium::osm_entity_bits::relation};
|
||||
collector.read_relations(reader1);
|
||||
reader1.close();
|
||||
std::cerr << "Pass 1 done\n";
|
||||
|
||||
// Output the amount of main memory used so far. All multipolygon relations
|
||||
// are in memory now.
|
||||
std::cerr << "Memory:\n";
|
||||
collector.used_memory();
|
||||
|
||||
index_pos_type index_pos;
|
||||
index_neg_type index_neg;
|
||||
location_handler_type location_handler(index_pos, index_neg);
|
||||
location_handler.ignore_errors(); // XXX
|
||||
// The index storing all node locations.
|
||||
index_type index;
|
||||
|
||||
// The handler that stores all node locations in the index and adds them
|
||||
// to the ways.
|
||||
location_handler_type location_handler{index};
|
||||
|
||||
// If a location is not available in the index, we ignore it. It might
|
||||
// not be needed (if it is not part of a multipolygon relation), so why
|
||||
// create an error?
|
||||
location_handler.ignore_errors();
|
||||
|
||||
// On the second pass we read all objects and run them first through the
|
||||
// node location handler and then the multipolygon collector. The collector
|
||||
// will put the areas it has created into the "buffer" which are then
|
||||
// fed through our "handler".
|
||||
std::cerr << "Pass 2...\n";
|
||||
osmium::io::Reader reader2(infile);
|
||||
osmium::io::Reader reader2{input_file};
|
||||
osmium::apply(reader2, location_handler, collector.handler([&handler](osmium::memory::Buffer&& buffer) {
|
||||
osmium::apply(buffer, handler);
|
||||
}));
|
||||
reader2.close();
|
||||
std::cerr << "Pass 2 done\n";
|
||||
|
||||
// Output the amount of main memory used so far. All complete multipolygon
|
||||
// relations have been cleaned up.
|
||||
std::cerr << "Memory:\n";
|
||||
collector.used_memory();
|
||||
|
||||
// If there were multipolgyon relations in the input, but some of their
|
||||
// members are not in the input file (which often happens for extracts)
|
||||
// this will write the IDs of the incomplete relations to stderr.
|
||||
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:";
|
||||
|
||||
+68
-24
@@ -1,16 +1,32 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_convert
|
||||
|
||||
Convert OSM files from one format into another.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input and output
|
||||
* file types
|
||||
* Osmium buffers
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <getopt.h>
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <exception> // for std::exception
|
||||
#include <getopt.h> // for getopt_long
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
#include <string> // for std::string
|
||||
|
||||
// Allow any format of input files (XML, PBF, ...)
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
// Allow any format of output files (XML, PBF, ...)
|
||||
#include <osmium/io/any_output.hpp>
|
||||
|
||||
void print_help() {
|
||||
@@ -43,9 +59,13 @@ int main(int argc, char* argv[]) {
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
// Input and output format are empty by default. Later this will mean that
|
||||
// the format should be taken from the input and output file suffix,
|
||||
// respectively.
|
||||
std::string input_format;
|
||||
std::string output_format;
|
||||
|
||||
// Read options from command line.
|
||||
while (true) {
|
||||
int c = getopt_long(argc, argv, "dhf:t:", long_options, 0);
|
||||
if (c == -1) {
|
||||
@@ -55,7 +75,7 @@ int main(int argc, char* argv[]) {
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_help();
|
||||
exit(0);
|
||||
std::exit(0);
|
||||
case 'f':
|
||||
input_format = optarg;
|
||||
break;
|
||||
@@ -63,49 +83,73 @@ int main(int argc, char* argv[]) {
|
||||
output_format = optarg;
|
||||
break;
|
||||
default:
|
||||
exit(1);
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
std::string input;
|
||||
std::string output;
|
||||
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 = argv[optind];
|
||||
output = argv[optind+1];
|
||||
} else if (remaining_args == 1) {
|
||||
input = argv[optind];
|
||||
std::cerr << "Usage: " << argv[0] << " [OPTIONS] [INFILE [OUTFILE]]\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
osmium::io::File infile(input, input_format);
|
||||
// Get input file name from command line.
|
||||
std::string input_file_name;
|
||||
if (remaining_args >= 1) {
|
||||
input_file_name = argv[optind];
|
||||
}
|
||||
|
||||
osmium::io::File outfile(output, output_format);
|
||||
// Get output file name from command line.
|
||||
std::string output_file_name;
|
||||
if (remaining_args == 2) {
|
||||
output_file_name = argv[optind+1];
|
||||
}
|
||||
|
||||
if (infile.has_multiple_object_versions() && !outfile.has_multiple_object_versions()) {
|
||||
// This declares the input and output files using either the suffix of
|
||||
// the file names or the format in the 2nd argument. It does not yet open
|
||||
// the files.
|
||||
osmium::io::File input_file{input_file_name, input_format};
|
||||
osmium::io::File output_file{output_file_name, output_format};
|
||||
|
||||
// Input and output files can be OSM data files (without history) or
|
||||
// OSM history files. History files are detected if they use the '.osh'
|
||||
// file suffix.
|
||||
if ( input_file.has_multiple_object_versions() &&
|
||||
!output_file.has_multiple_object_versions()) {
|
||||
std::cerr << "Warning! You are converting from an OSM file with (potentially) several versions of the same object to one that is not marked as such.\n";
|
||||
}
|
||||
|
||||
int exit_code = 0;
|
||||
|
||||
try {
|
||||
osmium::io::Reader reader(infile);
|
||||
// Initialize Reader
|
||||
osmium::io::Reader reader{input_file};
|
||||
|
||||
// Get header from input file and change the "generator" setting to
|
||||
// outselves.
|
||||
osmium::io::Header header = reader.header();
|
||||
header.set("generator", "osmium_convert");
|
||||
|
||||
osmium::io::Writer writer(outfile, header, osmium::io::overwrite::allow);
|
||||
// Initialize Writer using the header from above and tell it that it
|
||||
// is allowed to overwrite a possibly existing file.
|
||||
osmium::io::Writer writer(output_file, header, osmium::io::overwrite::allow);
|
||||
|
||||
// Copy the contents from the input to the output file one buffer at
|
||||
// a time. This is much easier and faster than copying each object
|
||||
// in the file. Buffers are moved around, so there is no cost for
|
||||
// copying in memory.
|
||||
while (osmium::memory::Buffer buffer = reader.read()) {
|
||||
writer(std::move(buffer));
|
||||
}
|
||||
|
||||
// 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();
|
||||
} catch (std::exception& e) {
|
||||
} catch (const std::exception& e) {
|
||||
// All exceptions used by the Osmium library derive from std::exception.
|
||||
std::cerr << e.what() << "\n";
|
||||
exit_code = 1;
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
|
||||
+54
-15
@@ -1,56 +1,95 @@
|
||||
/*
|
||||
|
||||
This is a small tool that counts the number of nodes, ways, and relations in
|
||||
the input file.
|
||||
EXAMPLE osmium_count
|
||||
|
||||
Counts the number of nodes, ways, and relations in the input file.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* OSM file input
|
||||
* your own handler
|
||||
* the memory usage utility class
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <cstdint> // for std::uint64_t
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
|
||||
// Allow any format of input files (XML, PBF, ...)
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
// We want to use the handler interface
|
||||
#include <osmium/handler.hpp>
|
||||
|
||||
// Utility class gives us access to memory usage information
|
||||
#include <osmium/util/memory.hpp>
|
||||
|
||||
// For osmium::apply()
|
||||
#include <osmium/visitor.hpp>
|
||||
|
||||
// Handler derive from the osmium::handler::Handler base class. Usually you
|
||||
// overwrite functions node(), way(), and relation(). Other functions are
|
||||
// available, too. Read the API documentation for details.
|
||||
struct CountHandler : public osmium::handler::Handler {
|
||||
|
||||
uint64_t nodes = 0;
|
||||
uint64_t ways = 0;
|
||||
uint64_t relations = 0;
|
||||
std::uint64_t nodes = 0;
|
||||
std::uint64_t ways = 0;
|
||||
std::uint64_t relations = 0;
|
||||
|
||||
void node(osmium::Node&) {
|
||||
// This callback is called by osmium::apply for each node in the data.
|
||||
void node(const osmium::Node&) noexcept {
|
||||
++nodes;
|
||||
}
|
||||
|
||||
void way(osmium::Way&) {
|
||||
// This callback is called by osmium::apply for each way in the data.
|
||||
void way(const osmium::Way&) noexcept {
|
||||
++ways;
|
||||
}
|
||||
|
||||
void relation(osmium::Relation&) {
|
||||
// This callback is called by osmium::apply for each relation in the data.
|
||||
void relation(const osmium::Relation&) noexcept {
|
||||
++relations;
|
||||
}
|
||||
|
||||
};
|
||||
}; // struct CountHandler
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
if (argc != 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
|
||||
exit(1);
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
osmium::io::File infile(argv[1]);
|
||||
osmium::io::Reader reader(infile);
|
||||
// The Reader is initialized here with an osmium::io::File, but could
|
||||
// also be directly initialized with a file name.
|
||||
osmium::io::File input_file{argv[1]};
|
||||
osmium::io::Reader reader{input_file};
|
||||
|
||||
// Create an instance of our own CountHandler and push the data from the
|
||||
// input file through it.
|
||||
CountHandler handler;
|
||||
osmium::apply(reader, handler);
|
||||
|
||||
// You do not have to close the Reader explicitly, but because the
|
||||
// destructor can't throw, you will not see any errors otherwise.
|
||||
reader.close();
|
||||
|
||||
std::cout << "Nodes: " << handler.nodes << "\n";
|
||||
std::cout << "Ways: " << handler.ways << "\n";
|
||||
std::cout << "Relations: " << handler.relations << "\n";
|
||||
|
||||
// Because of the huge amount of OSM data, some Osmium-based programs
|
||||
// (though not this one) can use huge amounts of data. So checking actual
|
||||
// memore usage is often useful and can be done easily with this class.
|
||||
// (Currently only works on Linux, not OSX and Windows.)
|
||||
osmium::MemoryUsage memory;
|
||||
|
||||
std::cout << "\nMemory used: " << memory.peak() << " MBytes\n";
|
||||
}
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
|
||||
This reads an OSM file and writes out the node locations to a cache
|
||||
file.
|
||||
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
#include <osmium/index/map/dummy.hpp>
|
||||
#include <osmium/index/map/dense_mmap_array.hpp>
|
||||
#include <osmium/index/map/dense_file_array.hpp>
|
||||
|
||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
||||
#include <osmium/visitor.hpp>
|
||||
|
||||
typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_neg_type;
|
||||
//typedef osmium::index::map::DenseMmapArray<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
|
||||
typedef osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
|
||||
|
||||
typedef osmium::handler::NodeLocationsForWays<index_pos_type, index_neg_type> location_handler_type;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSM_FILE CACHE_FILE\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string input_filename(argv[1]);
|
||||
osmium::io::Reader reader(input_filename, osmium::osm_entity_bits::node);
|
||||
|
||||
int fd = open(argv[2], O_RDWR | O_CREAT, 0666);
|
||||
if (fd == -1) {
|
||||
std::cerr << "Can not open node cache file '" << argv[2] << "': " << strerror(errno) << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
index_pos_type index_pos {fd};
|
||||
index_neg_type index_neg;
|
||||
location_handler_type location_handler(index_pos, index_neg);
|
||||
location_handler.ignore_errors();
|
||||
|
||||
osmium::apply(reader, location_handler);
|
||||
reader.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+36
-10
@@ -1,27 +1,46 @@
|
||||
/*
|
||||
|
||||
This is a small tool to dump the contents of the input file.
|
||||
EXAMPLE osmium_debug
|
||||
|
||||
Dump the contents of the input file in a debug format.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input reading only some types
|
||||
* the dump handler
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
* osmium_count
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
#include <string> // for std::string
|
||||
|
||||
// The Dump handler
|
||||
#include <osmium/handler/dump.hpp>
|
||||
|
||||
// Allow any format of input files (XML, PBF, ...)
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// Speed up output (not Osmium-specific)
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
|
||||
if (argc < 2 || argc > 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSMFILE [TYPES]\n";
|
||||
std::cerr << "TYPES can be any combination of 'n', 'w', 'r', and 'c' to indicate what types of OSM entities you want (default: all).\n";
|
||||
exit(1);
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
// Default is all entity types: nodes, ways, relations, and changesets
|
||||
osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::all;
|
||||
|
||||
// Get entity types from command line if there is a 2nd argument.
|
||||
if (argc == 3) {
|
||||
read_types = osmium::osm_entity_bits::nothing;
|
||||
std::string types = argv[2];
|
||||
@@ -31,20 +50,27 @@ int main(int argc, char* argv[]) {
|
||||
if (types.find('c') != std::string::npos) read_types |= osmium::osm_entity_bits::changeset;
|
||||
}
|
||||
|
||||
osmium::io::Reader reader(argv[1], read_types);
|
||||
osmium::io::Header header = reader.header();
|
||||
// Initialize Reader with file name and the types of entities we want to
|
||||
// read.
|
||||
osmium::io::Reader reader{argv[1], read_types};
|
||||
|
||||
// The file header can contain metadata such as the program that generated
|
||||
// the file and the bounding box of the data.
|
||||
osmium::io::Header header = reader.header();
|
||||
std::cout << "HEADER:\n generator=" << header.get("generator") << "\n";
|
||||
|
||||
for (auto& bbox : header.boxes()) {
|
||||
for (const auto& bbox : header.boxes()) {
|
||||
std::cout << " bbox=" << bbox << "\n";
|
||||
}
|
||||
|
||||
osmium::handler::Dump dump(std::cout);
|
||||
while (osmium::memory::Buffer buffer = reader.read()) {
|
||||
osmium::apply(buffer, dump);
|
||||
}
|
||||
// Initialize Dump handler.
|
||||
osmium::handler::Dump dump{std::cout};
|
||||
|
||||
// Read from input and send everything to Dump handler.
|
||||
osmium::apply(reader, dump);
|
||||
|
||||
// You do not have to close the Reader explicitly, but because the
|
||||
// destructor can't throw, you will not see any errors otherwise.
|
||||
reader.close();
|
||||
}
|
||||
|
||||
|
||||
+34
-14
@@ -1,53 +1,73 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_filter_discussions
|
||||
|
||||
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).
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input and output
|
||||
* setting file formats using the osmium::io::File class
|
||||
* OSM file headers
|
||||
* input and output iterators
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
* osmium_count
|
||||
|
||||
LICENSE
|
||||
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
|
||||
#include <cstdlib> // for std::exit
|
||||
#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)
|
||||
// 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
|
||||
// We want to write OSM files in XML format.
|
||||
#include <osmium/io/xml_output.hpp>
|
||||
|
||||
// We want to use input and output iterators for easy integration with the
|
||||
// algorithms of the standard library.
|
||||
#include <osmium/io/input_iterator.hpp>
|
||||
#include <osmium/io/output_iterator.hpp>
|
||||
|
||||
// we want to support any compressioon (.gz2 and .bz2)
|
||||
// We want to support any compression (none, gzip, and bzip2).
|
||||
#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);
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
// The input file, deduce file format from file suffix
|
||||
osmium::io::File infile(argv[1]);
|
||||
// The input file, deduce file format from file suffix.
|
||||
osmium::io::File input_file{argv[1]};
|
||||
|
||||
// The output file, force class XML OSM file format
|
||||
osmium::io::File outfile(argv[2], "osm");
|
||||
// The output file, force XML OSM file format.
|
||||
osmium::io::File output_file{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);
|
||||
osmium::io::Reader reader{input_file, osmium::osm_entity_bits::changeset};
|
||||
|
||||
// Get the header from the input file
|
||||
// Get the header from the input file.
|
||||
osmium::io::Header header = reader.header();
|
||||
|
||||
// Set the "generator" on the header to ourselves.
|
||||
header.set("generator", "osmium_filter_discussions");
|
||||
|
||||
// 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);
|
||||
osmium::io::Writer writer(output_file, header, osmium::io::overwrite::allow);
|
||||
|
||||
// Create range of input iterators that will iterator over all changesets
|
||||
// delivered from input file through the "reader".
|
||||
|
||||
+85
-62
@@ -12,7 +12,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <osmium/index/map/dense_file_array.hpp>
|
||||
#include <osmium/index/map/sparse_file_array.hpp>
|
||||
@@ -31,7 +31,7 @@ class IndexSearch {
|
||||
void dump_dense() {
|
||||
dense_index_type index(m_fd);
|
||||
|
||||
for (size_t i = 0; i < index.size(); ++i) {
|
||||
for (std::size_t i = 0; i < index.size(); ++i) {
|
||||
if (index.get(i) != TValue()) {
|
||||
std::cout << i << " " << index.get(i) << "\n";
|
||||
}
|
||||
@@ -51,9 +51,9 @@ class IndexSearch {
|
||||
|
||||
try {
|
||||
TValue value = index.get(key);
|
||||
std::cout << key << " " << value << std::endl;
|
||||
std::cout << key << " " << value << "\n";
|
||||
} catch (...) {
|
||||
std::cout << key << " not found" << std::endl;
|
||||
std::cout << key << " not found\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class IndexSearch {
|
||||
return lhs.first < rhs.first;
|
||||
});
|
||||
if (positions.first == positions.second) {
|
||||
std::cout << key << " not found" << std::endl;
|
||||
std::cout << key << " not found\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool search(std::vector<TKey> keys) {
|
||||
bool search(const std::vector<TKey>& keys) {
|
||||
bool found_all = true;
|
||||
|
||||
for (const auto key : keys) {
|
||||
@@ -124,82 +124,105 @@ enum return_code : int {
|
||||
fatal = 3
|
||||
};
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
class Options {
|
||||
|
||||
po::variables_map vm;
|
||||
std::vector<osmium::unsigned_object_id_type> m_ids;
|
||||
std::string m_type;
|
||||
std::string m_filename;
|
||||
bool m_dump = false;
|
||||
bool m_array_format = false;
|
||||
bool m_list_format = false;
|
||||
|
||||
void print_help() {
|
||||
std::cout << "Usage: osmium_index [OPTIONS]\n\n"
|
||||
<< "-h, --help Print this help message\n"
|
||||
<< "-a, --array=FILE Read given index file in array format\n"
|
||||
<< "-l, --list=FILE Read given index file in list format\n"
|
||||
<< "-d, --dump Dump contents of index file to STDOUT\n"
|
||||
<< "-s, --search=ID Search for given id (Option can appear multiple times)\n"
|
||||
<< "-t, --type=TYPE Type of value ('location' or 'offset')\n"
|
||||
;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Options(int argc, char* argv[]) {
|
||||
try {
|
||||
po::options_description desc("Allowed options");
|
||||
desc.add_options()
|
||||
("help,h", "Print this help message")
|
||||
("array,a", po::value<std::string>(), "Read given index file in array format")
|
||||
("list,l", po::value<std::string>(), "Read given index file in list format")
|
||||
("dump,d", "Dump contents of index file to STDOUT")
|
||||
("search,s", po::value<std::vector<osmium::unsigned_object_id_type>>(), "Search for given id (Option can appear multiple times)")
|
||||
("type,t", po::value<std::string>(), "Type of value ('location' or 'offset')")
|
||||
;
|
||||
static struct option long_options[] = {
|
||||
{"array", required_argument, 0, 'a'},
|
||||
{"dump", no_argument, 0, 'd'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"list", required_argument, 0, 'l'},
|
||||
{"search", required_argument, 0, 's'},
|
||||
{"type", required_argument, 0, 't'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
po::store(po::parse_command_line(argc, argv, desc), vm);
|
||||
po::notify(vm);
|
||||
|
||||
if (vm.count("help")) {
|
||||
std::cout << desc << "\n";
|
||||
exit(return_code::okay);
|
||||
while (true) {
|
||||
int c = getopt_long(argc, argv, "a:dhl:s:t:", long_options, 0);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (vm.count("array") && vm.count("list")) {
|
||||
std::cerr << "Only option --array or --list allowed." << std::endl;
|
||||
exit(return_code::fatal);
|
||||
switch (c) {
|
||||
case 'a':
|
||||
m_array_format = true;
|
||||
m_filename = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
m_dump = true;
|
||||
break;
|
||||
case 'h':
|
||||
print_help();
|
||||
std::exit(return_code::okay);
|
||||
case 'l':
|
||||
m_list_format = true;
|
||||
m_filename = optarg;
|
||||
break;
|
||||
case 's':
|
||||
m_ids.push_back(std::atoll(optarg));
|
||||
break;
|
||||
case 't':
|
||||
m_type = optarg;
|
||||
if (m_type != "location" && m_type != "offset") {
|
||||
std::cerr << "Unknown type '" << m_type << "'. Must be 'location' or 'offset'.\n";
|
||||
std::exit(return_code::fatal);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std::exit(return_code::fatal);
|
||||
}
|
||||
|
||||
if (!vm.count("array") && !vm.count("list")) {
|
||||
std::cerr << "Need one of option --array or --list." << std::endl;
|
||||
exit(return_code::fatal);
|
||||
}
|
||||
|
||||
if (!vm.count("type")) {
|
||||
std::cerr << "Need --type argument." << std::endl;
|
||||
exit(return_code::fatal);
|
||||
}
|
||||
|
||||
const std::string& type = vm["type"].as<std::string>();
|
||||
if (type != "location" && type != "offset") {
|
||||
std::cerr << "Unknown type '" << type << "'. Must be 'location' or 'offset'." << std::endl;
|
||||
exit(return_code::fatal);
|
||||
}
|
||||
} catch (boost::program_options::error& e) {
|
||||
std::cerr << "Error parsing command line: " << e.what() << std::endl;
|
||||
exit(return_code::fatal);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& filename() const {
|
||||
if (vm.count("array")) {
|
||||
return vm["array"].as<std::string>();
|
||||
} else {
|
||||
return vm["list"].as<std::string>();
|
||||
if (m_array_format == m_list_format) {
|
||||
std::cerr << "Need option --array or --list, but not both\n";
|
||||
std::exit(return_code::fatal);
|
||||
}
|
||||
|
||||
if (m_type.empty()) {
|
||||
std::cerr << "Need --type argument.\n";
|
||||
std::exit(return_code::fatal);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool dense_format() const {
|
||||
return vm.count("array") != 0;
|
||||
const std::string& filename() const noexcept {
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
bool do_dump() const {
|
||||
return vm.count("dump") != 0;
|
||||
bool dense_format() const noexcept {
|
||||
return m_array_format;
|
||||
}
|
||||
|
||||
std::vector<osmium::unsigned_object_id_type> search_keys() const {
|
||||
return vm["search"].as<std::vector<osmium::unsigned_object_id_type>>();
|
||||
bool do_dump() const noexcept {
|
||||
return m_dump;
|
||||
}
|
||||
|
||||
bool type_is(const char* type) const {
|
||||
return vm["type"].as<std::string>() == type;
|
||||
const std::vector<osmium::unsigned_object_id_type>& search_keys() const noexcept {
|
||||
return m_ids;
|
||||
}
|
||||
|
||||
bool type_is(const char* type) const noexcept {
|
||||
return m_type == type;
|
||||
}
|
||||
|
||||
}; // class Options
|
||||
@@ -232,6 +255,6 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
exit(result_okay ? return_code::okay : return_code::not_found);
|
||||
std::exit(result_okay ? return_code::okay : return_code::not_found);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_location_cache_create
|
||||
|
||||
Reads nodes from an OSM file and writes out their locations to a cache
|
||||
file. The cache file can then be read with osmium_location_cache_use.
|
||||
|
||||
Warning: The locations cache file will get huge (>32GB) if you are using
|
||||
the DenseFileArray index even if the input file is small, because
|
||||
it depends on the *largest* node ID, not the number of nodes.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input
|
||||
* location indexes and the NodeLocationsForWays handler
|
||||
* location indexes on disk
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
* osmium_count
|
||||
* osmium_road_length
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <cerrno> // for errno
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <cstring> // for strerror
|
||||
#include <fcntl.h> // for open
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
#include <string> // for std::string
|
||||
#include <sys/stat.h> // for open
|
||||
#include <sys/types.h> // for open
|
||||
|
||||
// Allow any format of input files (XML, PBF, ...)
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
// For the location index. There are different types of index implementation
|
||||
// available. These implementations put the index on disk. See below.
|
||||
#include <osmium/index/map/sparse_file_array.hpp>
|
||||
#include <osmium/index/map/dense_file_array.hpp>
|
||||
|
||||
// For the NodeLocationForWays handler
|
||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
||||
|
||||
// For osmium::apply()
|
||||
#include <osmium/visitor.hpp>
|
||||
|
||||
// Chose one of these two. "sparse" is best used for small and medium extracts,
|
||||
// the "dense" index for large extracts or the whole planet.
|
||||
using index_type = osmium::index::map::SparseFileArray<osmium::unsigned_object_id_type, osmium::Location>;
|
||||
//using index_type = osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, osmium::Location>;
|
||||
|
||||
// The location handler always depends on the index type
|
||||
using location_handler_type = osmium::handler::NodeLocationsForWays<index_type>;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSM_FILE CACHE_FILE\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
const std::string input_filename{argv[1]};
|
||||
const std::string cache_filename{argv[2]};
|
||||
|
||||
// Construct Reader reading only nodes
|
||||
osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::node};
|
||||
|
||||
// Initialize location index on disk creating a new file.
|
||||
const int fd = open(cache_filename.c_str(), O_RDWR | O_CREAT, 0666);
|
||||
if (fd == -1) {
|
||||
std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n";
|
||||
std::exit(1);
|
||||
}
|
||||
index_type index{fd};
|
||||
|
||||
// The handler that stores all node locations in the index.
|
||||
location_handler_type location_handler{index};
|
||||
|
||||
// Feed all nodes through the location handler.
|
||||
osmium::apply(reader, location_handler);
|
||||
|
||||
// Explicitly close input so we get notified of any errors.
|
||||
reader.close();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_location_cache_use
|
||||
|
||||
This reads ways from an OSM file and writes out the way node locations
|
||||
it got from a location cache generated with osmium_location_cache_create.
|
||||
|
||||
Warning: The locations cache file will get huge (>32GB) if you are using
|
||||
the DenseFileArray index even if the input file is small, because
|
||||
it depends on the *largest* node ID, not the number of nodes.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input
|
||||
* location indexes and the NodeLocationsForWays handler
|
||||
* location indexes on disk
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
* osmium_count
|
||||
* osmium_road_length
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <cerrno> // for errno
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <cstring> // for strerror
|
||||
#include <fcntl.h> // for open
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
#include <string> // for std::string
|
||||
#include <sys/stat.h> // for open
|
||||
#include <sys/types.h> // for open
|
||||
|
||||
// Allow any format of input files (XML, PBF, ...)
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
// For the location index. There are different types of index implementation
|
||||
// available. These implementations put the index on disk. See below.
|
||||
#include <osmium/index/map/dense_file_array.hpp>
|
||||
#include <osmium/index/map/sparse_file_array.hpp>
|
||||
|
||||
// For the NodeLocationForWays handler
|
||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
||||
|
||||
// For osmium::apply()
|
||||
#include <osmium/visitor.hpp>
|
||||
|
||||
// Chose one of these two. "sparse" is best used for small and medium extracts,
|
||||
// the "dense" index for large extracts or the whole planet.
|
||||
using index_type = osmium::index::map::SparseFileArray<osmium::unsigned_object_id_type, osmium::Location>;
|
||||
//using index_type = osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, osmium::Location>;
|
||||
|
||||
// The location handler always depends on the index type
|
||||
using location_handler_type = osmium::handler::NodeLocationsForWays<index_type>;
|
||||
|
||||
// This handler only implements the way() function which prints out the way
|
||||
// ID and all nodes IDs and locations in those ways.
|
||||
struct MyHandler : public osmium::handler::Handler {
|
||||
|
||||
void way(const osmium::Way& way) {
|
||||
std::cout << "way " << way.id() << "\n";
|
||||
for (const auto& nr : way.nodes()) {
|
||||
std::cout << " node " << nr.ref() << " " << nr.location() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
}; // struct MyHandler
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSM_FILE CACHE_FILE\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
const std::string input_filename{argv[1]};
|
||||
const std::string cache_filename{argv[2]};
|
||||
|
||||
// Construct Reader reading only ways
|
||||
osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::way};
|
||||
|
||||
// Initialize location index on disk using an existing file
|
||||
const int fd = open(cache_filename.c_str(), O_RDWR);
|
||||
if (fd == -1) {
|
||||
std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n";
|
||||
return 1;
|
||||
}
|
||||
index_type index{fd};
|
||||
|
||||
// The handler that adds node locations from the index to the ways.
|
||||
location_handler_type location_handler{index};
|
||||
|
||||
// Feed all ways through the location handler and then our own handler.
|
||||
MyHandler handler;
|
||||
osmium::apply(reader, location_handler, handler);
|
||||
|
||||
// Explicitly close input so we get notified of any errors.
|
||||
reader.close();
|
||||
}
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_pub_names
|
||||
|
||||
Show the names and addresses of all pubs found in an OSM file.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input
|
||||
* your own handler
|
||||
* access to tags
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
* osmium_count
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <cstring> // for std::strncmp
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
|
||||
// Allow any format of input files (XML, PBF, ...)
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
// We want to use the handler interface
|
||||
#include <osmium/handler.hpp>
|
||||
|
||||
// For osmium::apply()
|
||||
#include <osmium/visitor.hpp>
|
||||
|
||||
class NamesHandler : public osmium::handler::Handler {
|
||||
|
||||
void output_pubs(const osmium::OSMObject& object) {
|
||||
const osmium::TagList& tags = object.tags();
|
||||
if (tags.has_tag("amenity", "pub")) {
|
||||
|
||||
// Print name of the pub if it is set.
|
||||
const char* name = tags["name"];
|
||||
if (name) {
|
||||
std::cout << name << "\n";
|
||||
} else {
|
||||
std::cout << "pub with unknown name\n";
|
||||
}
|
||||
|
||||
// Iterate over all tags finding those which start with "addr:"
|
||||
// and print them.
|
||||
for (const osmium::Tag& tag : tags) {
|
||||
if (!std::strncmp(tag.key(), "addr:", 5)) {
|
||||
std::cout << " " << tag.key() << ": " << tag.value() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Nodes can be tagged amenity=pub.
|
||||
void node(const osmium::Node& node) {
|
||||
output_pubs(node);
|
||||
}
|
||||
|
||||
// Ways can be tagged amenity=pub, too (typically buildings).
|
||||
void way(const osmium::Way& way) {
|
||||
output_pubs(way);
|
||||
}
|
||||
|
||||
}; // class NamesHandler
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
// Construct the handler defined above
|
||||
NamesHandler names_handler;
|
||||
|
||||
// Initialize the reader with the filename from the command line and
|
||||
// tell it to only read nodes and ways. We are ignoring multipolygon
|
||||
// relations in this simple example.
|
||||
osmium::io::Reader reader{argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way};
|
||||
|
||||
// Apply input data to our own handler
|
||||
osmium::apply(reader, names_handler);
|
||||
}
|
||||
|
||||
+19
-7
@@ -1,30 +1,42 @@
|
||||
/*
|
||||
|
||||
This is a small tool that reads and discards the contents of the input file.
|
||||
(Used for timing.)
|
||||
EXAMPLE osmium_read
|
||||
|
||||
Reads and discards the contents of the input file.
|
||||
(It can be used for timing.)
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <iostream> // for std::cerr
|
||||
|
||||
// Allow any format of input files (XML, PBF, ...)
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
if (argc != 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
|
||||
exit(1);
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
osmium::io::File infile(argv[1]);
|
||||
osmium::io::Reader reader(infile);
|
||||
// The Reader is initialized here with an osmium::io::File, but could
|
||||
// also be directly initialized with a file name.
|
||||
osmium::io::File input_file{argv[1]};
|
||||
osmium::io::Reader reader{input_file};
|
||||
|
||||
// OSM data comes in buffers, read until there are no more.
|
||||
while (osmium::memory::Buffer buffer = reader.read()) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
// You do not have to close the Reader explicitly, but because the
|
||||
// destructor can't throw, you will not see any errors otherwise.
|
||||
reader.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_read_with_progress
|
||||
|
||||
Reads the contents of the input file showing a progress bar.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input
|
||||
* ProgressBar utility function
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <iostream> // for std::cerr
|
||||
|
||||
// Allow any format of input files (XML, PBF, ...)
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
// Get access to isatty utility function and progress bar utility class.
|
||||
#include <osmium/util/file.hpp>
|
||||
#include <osmium/util/progress_bar.hpp>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
// The Reader is initialized here with an osmium::io::File, but could
|
||||
// also be directly initialized with a file name.
|
||||
osmium::io::File input_file{argv[1]};
|
||||
osmium::io::Reader reader{input_file};
|
||||
|
||||
// Initialize progress bar, enable it only if STDERR is a TTY.
|
||||
osmium::ProgressBar progress{reader.file_size(), osmium::util::isatty(2)};
|
||||
|
||||
// OSM data comes in buffers, read until there are no more.
|
||||
while (osmium::memory::Buffer buffer = reader.read()) {
|
||||
// Update progress bar for each buffer.
|
||||
progress.update(reader.offset());
|
||||
}
|
||||
|
||||
// Progress bar is done.
|
||||
progress.done();
|
||||
|
||||
// You do not have to close the Reader explicitly, but because the
|
||||
// destructor can't throw, you will not see any errors otherwise.
|
||||
reader.close();
|
||||
}
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_road_length
|
||||
|
||||
Calculate the length of the road network (everything tagged `highway=*`)
|
||||
from the given OSM file.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input
|
||||
* location indexes and the NodeLocationsForWays handler
|
||||
* length calculation on the earth using the haversine function
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
* osmium_count
|
||||
* osmium_pub_names
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
|
||||
// Allow any format of input files (XML, PBF, ...)
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
// For the osmium::geom::haversine::distance() function
|
||||
#include <osmium/geom/haversine.hpp>
|
||||
|
||||
// For osmium::apply()
|
||||
#include <osmium/visitor.hpp>
|
||||
|
||||
// For the location index. There are different types of indexes available.
|
||||
// This will work for small and medium sized input files.
|
||||
#include <osmium/index/map/sparse_mem_array.hpp>
|
||||
|
||||
// For the NodeLocationForWays handler
|
||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
||||
|
||||
// The type of index used. This must match the include file above
|
||||
using index_type = osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, osmium::Location>;
|
||||
|
||||
// The location handler always depends on the index type
|
||||
using location_handler_type = osmium::handler::NodeLocationsForWays<index_type>;
|
||||
|
||||
// This handler only implements the way() function, we are not interested in
|
||||
// any other objects.
|
||||
struct RoadLengthHandler : public osmium::handler::Handler {
|
||||
|
||||
double length = 0;
|
||||
|
||||
// If the way has a "highway" tag, find its length and add it to the
|
||||
// overall length.
|
||||
void way(const osmium::Way& way) {
|
||||
const char* highway = way.tags()["highway"];
|
||||
if (highway) {
|
||||
length += osmium::geom::haversine::distance(way.nodes());
|
||||
}
|
||||
}
|
||||
|
||||
}; // struct RoadLengthHandler
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSMFILE\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
// Initialize the reader with the filename from the command line and
|
||||
// tell it to only read nodes and ways.
|
||||
osmium::io::Reader reader{argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way};
|
||||
|
||||
// The index to hold node locations.
|
||||
index_type index;
|
||||
|
||||
// The location handler will add the node locations to the index and then
|
||||
// to the ways
|
||||
location_handler_type location_handler{index};
|
||||
|
||||
// Our handler defined above
|
||||
RoadLengthHandler road_length_handler;
|
||||
|
||||
// Apply input data to first the location handler and then our own handler
|
||||
osmium::apply(reader, location_handler, road_length_handler);
|
||||
|
||||
// Output the length. The haversine function calculates it in meters,
|
||||
// so we first devide by 1000 to get kilometers.
|
||||
std::cout << "Length: " << road_length_handler.length / 1000 << " km\n";
|
||||
}
|
||||
|
||||
+12
-12
@@ -69,9 +69,9 @@ int main(int argc, char* argv[]) {
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_help();
|
||||
exit(0);
|
||||
std::exit(0);
|
||||
default:
|
||||
exit(2);
|
||||
std::exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
if (remaining_args != 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSMFILE DIR\n";
|
||||
exit(2);
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
std::string dir(argv[optind+1]);
|
||||
@@ -90,14 +90,14 @@ int main(int argc, char* argv[]) {
|
||||
#endif
|
||||
if (result == -1 && errno != EEXIST) {
|
||||
std::cerr << "Problem creating directory '" << dir << "': " << strerror(errno) << "\n";
|
||||
exit(2);
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
std::string data_file(dir + "/data.osm.ser");
|
||||
int data_fd = ::open(data_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (data_fd < 0) {
|
||||
std::cerr << "Can't open data file '" << data_file << "': " << strerror(errno) << "\n";
|
||||
exit(2);
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
offset_index_type node_index;
|
||||
@@ -127,7 +127,7 @@ int main(int argc, char* argv[]) {
|
||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (fd < 0) {
|
||||
std::cerr << "Can't open nodes index file '" << index_file << "': " << strerror(errno) << "\n";
|
||||
exit(2);
|
||||
std::exit(2);
|
||||
}
|
||||
node_index.dump_as_list(fd);
|
||||
close(fd);
|
||||
@@ -138,7 +138,7 @@ int main(int argc, char* argv[]) {
|
||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (fd < 0) {
|
||||
std::cerr << "Can't open ways index file '" << index_file << "': " << strerror(errno) << "\n";
|
||||
exit(2);
|
||||
std::exit(2);
|
||||
}
|
||||
way_index.dump_as_list(fd);
|
||||
close(fd);
|
||||
@@ -149,7 +149,7 @@ int main(int argc, char* argv[]) {
|
||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (fd < 0) {
|
||||
std::cerr << "Can't open relations index file '" << index_file << "': " << strerror(errno) << "\n";
|
||||
exit(2);
|
||||
std::exit(2);
|
||||
}
|
||||
relation_index.dump_as_list(fd);
|
||||
close(fd);
|
||||
@@ -161,7 +161,7 @@ int main(int argc, char* argv[]) {
|
||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (fd < 0) {
|
||||
std::cerr << "Can't open node->way map file '" << index_file << "': " << strerror(errno) << "\n";
|
||||
exit(2);
|
||||
std::exit(2);
|
||||
}
|
||||
map_node2way.dump_as_list(fd);
|
||||
close(fd);
|
||||
@@ -173,7 +173,7 @@ int main(int argc, char* argv[]) {
|
||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (fd < 0) {
|
||||
std::cerr << "Can't open node->rel map file '" << index_file << "': " << strerror(errno) << "\n";
|
||||
exit(2);
|
||||
std::exit(2);
|
||||
}
|
||||
map_node2relation.dump_as_list(fd);
|
||||
close(fd);
|
||||
@@ -185,7 +185,7 @@ int main(int argc, char* argv[]) {
|
||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (fd < 0) {
|
||||
std::cerr << "Can't open way->rel map file '" << index_file << "': " << strerror(errno) << "\n";
|
||||
exit(2);
|
||||
std::exit(2);
|
||||
}
|
||||
map_way2relation.dump_as_list(fd);
|
||||
close(fd);
|
||||
@@ -197,7 +197,7 @@ int main(int argc, char* argv[]) {
|
||||
int fd = ::open(index_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
if (fd < 0) {
|
||||
std::cerr << "Can't open rel->rel map file '" << index_file << "': " << strerror(errno) << "\n";
|
||||
exit(2);
|
||||
std::exit(2);
|
||||
}
|
||||
map_relation2relation.dump_as_list(fd);
|
||||
close(fd);
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_tiles
|
||||
|
||||
Convert WGS84 longitude and latitude to Mercator coordinates and tile
|
||||
coordinates.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* the Location and Coordinates classes
|
||||
* the Mercator projection function
|
||||
* the Tile class
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <cstdlib> // for std::exit, std::atoi, std::atof
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
|
||||
// The Location contains a longitude and latitude and is usually used inside
|
||||
// a node to store its location in the world.
|
||||
#include <osmium/osm/location.hpp>
|
||||
|
||||
// Needed for the Mercator projection function. Osmium supports the Mercator
|
||||
// projection out of the box, or pretty much any projection using the Proj.4
|
||||
// library (with the osmium::geom::Projection class).
|
||||
#include <osmium/geom/mercator_projection.hpp>
|
||||
|
||||
// The Tile class handles tile coordinates and zoom levels.
|
||||
#include <osmium/geom/tile.hpp>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 4) {
|
||||
std::cerr << "Usage: " << argv[0] << " ZOOM LON LAT\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
const int zoom = std::atoi(argv[1]);
|
||||
|
||||
if (zoom < 0 || zoom > 30) {
|
||||
std::cerr << "ERROR: Zoom must be between 0 and 30\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
const double lon = std::atof(argv[2]);
|
||||
const double lat = std::atof(argv[3]);
|
||||
|
||||
// Create location from WGS84 coordinates. In Osmium the order of
|
||||
// coordinate values is always x/longitude first, then y/latitude.
|
||||
const osmium::Location location{lon, lat};
|
||||
|
||||
std::cout << "WGS84: lon=" << lon << " lat=" << lat << "\n";
|
||||
|
||||
// A location can store some invalid locations, ie locations outside the
|
||||
// -180 to 180 and -90 to 90 degree range. This function checks for that.
|
||||
if (!location.valid()) {
|
||||
std::cerr << "ERROR: Location is invalid\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
// Project the coordinates using a helper function. You can also use the
|
||||
// osmium::geom::MercatorProjection class.
|
||||
const osmium::geom::Coordinates c = osmium::geom::lonlat_to_mercator(location);
|
||||
std::cout << "Mercator: x=" << c.x << " y=" << c.y << "\n";
|
||||
|
||||
// Create a tile at this location. This will also internally use the
|
||||
// Mercator projection and then calculate the tile coordinates.
|
||||
const osmium::geom::Tile tile{uint32_t(zoom), location};
|
||||
std::cout << "Tile: zoom=" << tile.z << " x=" << tile.x << " y=" << tile.y << "\n";
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
|
||||
This reads ways from an OSM file and writes out the node locations
|
||||
it got from a node cache generated with osmium_create_node_cache.
|
||||
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
#include <osmium/index/map/dummy.hpp>
|
||||
#include <osmium/index/map/dense_file_array.hpp>
|
||||
#include <osmium/index/map/dense_mmap_array.hpp>
|
||||
|
||||
#include <osmium/handler/node_locations_for_ways.hpp>
|
||||
#include <osmium/visitor.hpp>
|
||||
|
||||
typedef osmium::index::map::Dummy<osmium::unsigned_object_id_type, osmium::Location> index_neg_type;
|
||||
//typedef osmium::index::map::DenseMmapArray<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
|
||||
typedef osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, osmium::Location> index_pos_type;
|
||||
|
||||
typedef osmium::handler::NodeLocationsForWays<index_pos_type, index_neg_type> location_handler_type;
|
||||
|
||||
class MyHandler : public osmium::handler::Handler {
|
||||
|
||||
public:
|
||||
|
||||
void way(osmium::Way& way) {
|
||||
for (auto& nr : way.nodes()) {
|
||||
std::cout << nr << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
}; // class MyHandler
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSM_FILE CACHE_FILE\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string input_filename(argv[1]);
|
||||
osmium::io::Reader reader(input_filename, osmium::osm_entity_bits::way);
|
||||
|
||||
int fd = open(argv[2], O_RDWR);
|
||||
if (fd == -1) {
|
||||
std::cerr << "Can not open node cache file '" << argv[2] << "': " << strerror(errno) << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
index_pos_type index_pos {fd};
|
||||
index_neg_type index_neg;
|
||||
location_handler_type location_handler(index_pos, index_neg);
|
||||
location_handler.ignore_errors();
|
||||
|
||||
MyHandler handler;
|
||||
osmium::apply(reader, location_handler, handler);
|
||||
reader.close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user