Merge commit 'babbda98a6ea1d53a8bc5015ef5dfb313c47186a' into libosmium-2.10.0
This commit is contained in:
+5
-3
@@ -10,18 +10,20 @@ message(STATUS "Configuring examples")
|
||||
|
||||
set(EXAMPLES
|
||||
area_test
|
||||
change_tags
|
||||
convert
|
||||
count
|
||||
create_pois
|
||||
debug
|
||||
dump_internal
|
||||
filter_discussions
|
||||
index
|
||||
index_lookup
|
||||
location_cache_create
|
||||
location_cache_use
|
||||
pub_names
|
||||
read
|
||||
read_with_progress
|
||||
road_length
|
||||
serdump
|
||||
tiles
|
||||
CACHE STRING "Example programs"
|
||||
)
|
||||
@@ -32,7 +34,7 @@ set(EXAMPLES
|
||||
# Examples depending on wingetopt
|
||||
#
|
||||
#-----------------------------------------------------------------------------
|
||||
set(GETOPT_EXAMPLES area_test convert index serdump)
|
||||
set(GETOPT_EXAMPLES area_test convert index_lookup)
|
||||
if(NOT GETOPT_MISSING)
|
||||
foreach(example ${GETOPT_EXAMPLES})
|
||||
list(APPEND EXAMPLE_LIBS_${example} ${GETOPT_LIBRARY})
|
||||
|
||||
+12
@@ -18,12 +18,24 @@ them.
|
||||
|
||||
## Still reasonably simple examples
|
||||
|
||||
* `osmium_read_with_progress`
|
||||
* `osmium_filter_discussions`
|
||||
* `osmium_convert`
|
||||
* `osmium_pub_names`
|
||||
* `osmium_road_length`
|
||||
|
||||
## More advanced examples
|
||||
|
||||
* `osmium_area_test`
|
||||
* `osmium_create_pois`
|
||||
|
||||
## Even more advanced examples
|
||||
|
||||
* `osmium_change_tags`
|
||||
* `osmium_location_cache_create`
|
||||
* `osmium_location_cache_use`
|
||||
* `osmium_dump_internal`
|
||||
* `osmium_index_lookup`
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+2
-2
@@ -106,7 +106,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
// Read options from command line.
|
||||
while (true) {
|
||||
int c = getopt_long(argc, argv, "hwo", long_options, 0);
|
||||
const int c = getopt_long(argc, argv, "hwo", long_options, 0);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
@@ -126,7 +126,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
int remaining_args = argc - optind;
|
||||
const int remaining_args = argc - optind;
|
||||
if (remaining_args != 1) {
|
||||
std::cerr << "Usage: " << argv[0] << " [OPTIONS] OSMFILE\n";
|
||||
std::exit(1);
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_change_tags
|
||||
|
||||
An example how tags in OSM files can be removed or changed. Removes
|
||||
"created_by" tags and changes tag "landuse=forest" into "natural_wood".
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input and output
|
||||
* Osmium buffers
|
||||
* your own handler
|
||||
* access to tags
|
||||
* using builders to write data
|
||||
|
||||
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 <cstring> // for std::strcmp
|
||||
#include <exception> // for std::exception
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
#include <string> // for std::string
|
||||
#include <utility> // for std::move
|
||||
|
||||
// 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>
|
||||
|
||||
// We want to use the builder interface
|
||||
#include <osmium/builder/osm_object_builder.hpp>
|
||||
|
||||
// We want to use the handler interface
|
||||
#include <osmium/handler.hpp>
|
||||
|
||||
// For osmium::apply()
|
||||
#include <osmium/visitor.hpp>
|
||||
|
||||
// The functions in this class will be called for each object in the input
|
||||
// and will write a (changed) copy of those objects to the given buffer.
|
||||
class RewriteHandler : public osmium::handler::Handler {
|
||||
|
||||
osmium::memory::Buffer& m_buffer;
|
||||
|
||||
// Copy attributes common to all OSM objects (nodes, ways, and relations).
|
||||
template <typename T>
|
||||
void copy_attributes(T& builder, const osmium::OSMObject& object) {
|
||||
// The setter functions on the builder object all return the same
|
||||
// builder object so they can be chained.
|
||||
builder.set_id(object.id())
|
||||
.set_version(object.version())
|
||||
.set_changeset(object.changeset())
|
||||
.set_timestamp(object.timestamp())
|
||||
.set_uid(object.uid())
|
||||
.set_user(object.user());
|
||||
}
|
||||
|
||||
// Copy all tags with two changes:
|
||||
// * Do not copy "created_by" tags
|
||||
// * Change "landuse=forest" into "natural=wood"
|
||||
void copy_tags(osmium::builder::Builder& parent, const osmium::TagList& tags) {
|
||||
|
||||
// The TagListBuilder is used to create a list of tags. The parameter
|
||||
// to create it is a reference to the builder of the object that
|
||||
// should have those tags.
|
||||
osmium::builder::TagListBuilder builder{parent};
|
||||
|
||||
// Iterate over all tags and build new tags using the new builder
|
||||
// based on the old ones.
|
||||
for (const auto& tag : tags) {
|
||||
if (std::strcmp(tag.key(), "created_by")) {
|
||||
if (!std::strcmp(tag.key(), "landuse") && !std::strcmp(tag.value(), "forest")) {
|
||||
// add_tag() can be called with key and value C strings
|
||||
builder.add_tag("natural", "wood");
|
||||
} else {
|
||||
// add_tag() can also be called with an osmium::Tag
|
||||
builder.add_tag(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
// Constructor. New data will be added to the given buffer.
|
||||
RewriteHandler(osmium::memory::Buffer& buffer) :
|
||||
m_buffer(buffer) {
|
||||
}
|
||||
|
||||
// The node handler is called for each node in the input data.
|
||||
void node(const osmium::Node& node) {
|
||||
// Open a new scope, because the NodeBuilder we are creating has to
|
||||
// be destructed, before we can call commit() below.
|
||||
{
|
||||
// To create a node, we need a NodeBuilder object. It will create
|
||||
// the node in the given buffer.
|
||||
osmium::builder::NodeBuilder builder{m_buffer};
|
||||
|
||||
// Copy common object attributes over to the new node.
|
||||
copy_attributes(builder, node);
|
||||
|
||||
// Copy the location over to the new node.
|
||||
builder.set_location(node.location());
|
||||
|
||||
// Copy (changed) tags.
|
||||
copy_tags(builder, node.tags());
|
||||
}
|
||||
|
||||
// Once the object is written to the buffer completely, we have to call
|
||||
// commit().
|
||||
m_buffer.commit();
|
||||
}
|
||||
|
||||
// The way handler is called for each node in the input data.
|
||||
void way(const osmium::Way& way) {
|
||||
{
|
||||
osmium::builder::WayBuilder builder{m_buffer};
|
||||
copy_attributes(builder, way);
|
||||
copy_tags(builder, way.tags());
|
||||
|
||||
// Copy the node list over to the new way.
|
||||
builder.add_item(way.nodes());
|
||||
}
|
||||
m_buffer.commit();
|
||||
}
|
||||
|
||||
// The relation handler is called for each node in the input data.
|
||||
void relation(const osmium::Relation& relation) {
|
||||
{
|
||||
osmium::builder::RelationBuilder builder{m_buffer};
|
||||
copy_attributes(builder, relation);
|
||||
copy_tags(builder, relation.tags());
|
||||
|
||||
// Copy the relation member list over to the new way.
|
||||
builder.add_item(relation.members());
|
||||
}
|
||||
m_buffer.commit();
|
||||
}
|
||||
|
||||
}; // class RewriteHandler
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " INFILE OUTFILE\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
// Get input and output file names from command line.
|
||||
std::string input_file_name{argv[1]};
|
||||
std::string output_file_name{argv[2]};
|
||||
|
||||
try {
|
||||
// Initialize Reader
|
||||
osmium::io::Reader reader{input_file_name};
|
||||
|
||||
// Get header from input file and change the "generator" setting to
|
||||
// ourselves.
|
||||
osmium::io::Header header = reader.header();
|
||||
header.set("generator", "osmium_change_tags");
|
||||
|
||||
// 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_name, header, osmium::io::overwrite::allow};
|
||||
|
||||
// Read in buffers with OSM objects until there are no more.
|
||||
while (osmium::memory::Buffer input_buffer = reader.read()) {
|
||||
// Create an empty buffer with the same size as the input buffer.
|
||||
// We'll copy the changed data into output buffer, the changes
|
||||
// are small, so the output buffer needs to be about the same size.
|
||||
// In case it has to be bigger, we allow it to grow automatically
|
||||
// by adding the auto_grow::yes parameter.
|
||||
osmium::memory::Buffer output_buffer{input_buffer.committed(), osmium::memory::Buffer::auto_grow::yes};
|
||||
|
||||
// Construct a handler as defined above and feed the input buffer
|
||||
// to it.
|
||||
RewriteHandler handler{output_buffer};
|
||||
osmium::apply(input_buffer, handler);
|
||||
|
||||
// Write out the contents of the output buffer.
|
||||
writer(std::move(output_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 (const std::exception& e) {
|
||||
// All exceptions used by the Osmium library derive from std::exception.
|
||||
std::cerr << e.what() << "\n";
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -67,7 +67,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
// Read options from command line.
|
||||
while (true) {
|
||||
int c = getopt_long(argc, argv, "dhf:t:", long_options, 0);
|
||||
const int c = getopt_long(argc, argv, "dhf:t:", long_options, 0);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
@@ -87,7 +87,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
|
||||
int remaining_args = argc - optind;
|
||||
const int remaining_args = argc - optind;
|
||||
if (remaining_args > 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " [OPTIONS] [INFILE [OUTFILE]]\n";
|
||||
std::exit(1);
|
||||
@@ -124,13 +124,13 @@ int main(int argc, char* argv[]) {
|
||||
osmium::io::Reader reader{input_file};
|
||||
|
||||
// Get header from input file and change the "generator" setting to
|
||||
// outselves.
|
||||
// ourselves.
|
||||
osmium::io::Header header = reader.header();
|
||||
header.set("generator", "osmium_convert");
|
||||
|
||||
// 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);
|
||||
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
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_create_pois
|
||||
|
||||
Showing how to create nodes for points of interest out of thin air.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file output
|
||||
* Osmium buffers
|
||||
* using builders to write data
|
||||
|
||||
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 <cstring> // for std::strcmp
|
||||
#include <ctime> // for std::time
|
||||
#include <exception> // for std::exception
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
#include <string> // for std::string
|
||||
#include <utility> // for std::move
|
||||
|
||||
// Allow any format of output files (XML, PBF, ...)
|
||||
#include <osmium/io/any_output.hpp>
|
||||
|
||||
// We want to use the builder interface
|
||||
#include <osmium/builder/osm_object_builder.hpp>
|
||||
#include <osmium/builder/attr.hpp>
|
||||
|
||||
// Declare this to use the functions starting with the underscore (_) below.
|
||||
using namespace osmium::builder::attr;
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " OUTFILE\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
// Get output file name from command line.
|
||||
std::string output_file_name{argv[1]};
|
||||
|
||||
try {
|
||||
// Create a buffer where all objects will live. Use a sensible initial
|
||||
// buffer size and set the buffer to automatically grow if needed.
|
||||
const size_t initial_buffer_size = 10000;
|
||||
osmium::memory::Buffer buffer{initial_buffer_size, osmium::memory::Buffer::auto_grow::yes};
|
||||
|
||||
// Add nodes to the buffer. This is, of course, only an example.
|
||||
// You can set any of the attributes and more tags, etc. Ways and
|
||||
// relations can be added in a similar way.
|
||||
osmium::builder::add_node(buffer,
|
||||
_id(-1),
|
||||
_version(1),
|
||||
_timestamp(std::time(nullptr)),
|
||||
_location(osmium::Location{1.23, 3.45}),
|
||||
_tag("amenity", "post_box")
|
||||
);
|
||||
|
||||
osmium::builder::add_node(buffer,
|
||||
_id(-2),
|
||||
_version(1),
|
||||
_timestamp(std::time(nullptr)),
|
||||
_location(1.24, 3.46),
|
||||
_tags({{"amenity", "restaurant"},
|
||||
{"name", "Chez OSM"}})
|
||||
);
|
||||
|
||||
// Create header and set generator.
|
||||
osmium::io::Header header;
|
||||
header.set("generator", "osmium_create_pois");
|
||||
|
||||
// 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_name, header, osmium::io::overwrite::allow};
|
||||
|
||||
// Write out the contents of the output buffer.
|
||||
writer(std::move(buffer));
|
||||
|
||||
// Explicitly close the writer. Will throw an exception if there is
|
||||
// a problem. If you wait for the destructor to close the writer, you
|
||||
// will not notice the problem, because destructors must not throw.
|
||||
writer.close();
|
||||
} catch (const std::exception& e) {
|
||||
// All exceptions used by the Osmium library derive from std::exception.
|
||||
std::cerr << e.what() << "\n";
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_dump_internal
|
||||
|
||||
Reads an OSM file and dumps the internal datastructure to disk including
|
||||
indexes to find objects and object relations.
|
||||
|
||||
Note that this example programm will only work with small and medium sized
|
||||
OSM file, not with the planet.
|
||||
|
||||
You can use the osmium_index example program to inspect the indexes.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* file input
|
||||
* indexes and maps
|
||||
* use of the DiskStore handler
|
||||
* use of the ObjectRelations handler
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
* osmium_count
|
||||
* osmium_road_length
|
||||
* osmium_location_cache_create
|
||||
* osmium_location_cache_use
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <cerrno> // for errno
|
||||
#include <cstring> // for std::strerror
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
#include <string> // for std::string
|
||||
#include <sys/stat.h> // for open
|
||||
#include <sys/types.h> // for open
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <direct.h>
|
||||
#endif
|
||||
|
||||
// Allow any format of input files (XML, PBF, ...)
|
||||
#include <osmium/io/any_input.hpp>
|
||||
|
||||
// The DiskStore handler
|
||||
#include <osmium/handler/disk_store.hpp>
|
||||
|
||||
// The ObjectRelations handler
|
||||
#include <osmium/handler/object_relations.hpp>
|
||||
|
||||
// The indexes
|
||||
#include <osmium/index/map/sparse_mem_array.hpp>
|
||||
#include <osmium/index/multimap/sparse_mem_array.hpp>
|
||||
|
||||
using offset_index_type = osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, size_t>;
|
||||
using map_type = osmium::index::multimap::SparseMemArray<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type>;
|
||||
|
||||
/**
|
||||
* Small class wrapping index files, basically making sure errors are handled
|
||||
* and the files are closed on destruction.
|
||||
*/
|
||||
class IndexFile {
|
||||
|
||||
int m_fd;
|
||||
|
||||
public:
|
||||
|
||||
IndexFile(const std::string& filename) :
|
||||
m_fd(::open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666)) {
|
||||
if (m_fd < 0) {
|
||||
std::cerr << "Can't open index file '" << filename << "': " << std::strerror(errno) << "\n";
|
||||
std::exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
~IndexFile() {
|
||||
if (m_fd >= 0) {
|
||||
close(m_fd);
|
||||
}
|
||||
}
|
||||
|
||||
int fd() const noexcept {
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
}; // class IndexFile
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSMFILE DIR\n";
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
const std::string input_file_name{argv[1]};
|
||||
const std::string output_dir{argv[2]};
|
||||
|
||||
// Create output directory. Ignore the error if it already exists.
|
||||
#ifndef _WIN32
|
||||
const int result = ::mkdir(output_dir.c_str(), 0777);
|
||||
#else
|
||||
const int result = mkdir(output_dir.c_str());
|
||||
#endif
|
||||
if (result == -1 && errno != EEXIST) {
|
||||
std::cerr << "Problem creating directory '" << output_dir << "': " << std::strerror(errno) << "\n";
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
// Create the output file which will contain our serialized OSM data
|
||||
const std::string data_file{output_dir + "/data.osm.ser"};
|
||||
const 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 << "': " << std::strerror(errno) << "\n";
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
// These indexes store the offset in the data file where each node, way,
|
||||
// or relation is stored.
|
||||
offset_index_type node_index;
|
||||
offset_index_type way_index;
|
||||
offset_index_type relation_index;
|
||||
|
||||
// This handler will dump the internal data to disk using the given file
|
||||
// descriptor while updating the indexes.
|
||||
osmium::handler::DiskStore disk_store_handler{data_fd, node_index, way_index, relation_index};
|
||||
|
||||
// These indexes store the mapping from node id to the ids of the ways
|
||||
// containing this node, and from node/way/relation ids to the ids of the
|
||||
// relations containing those objects.
|
||||
map_type map_node2way;
|
||||
map_type map_node2relation;
|
||||
map_type map_way2relation;
|
||||
map_type map_relation2relation;
|
||||
|
||||
// This handler will update the map indexes.
|
||||
osmium::handler::ObjectRelations object_relations_handler{map_node2way, map_node2relation, map_way2relation, map_relation2relation};
|
||||
|
||||
// Read OSM data buffer by buffer.
|
||||
osmium::io::Reader reader{input_file_name};
|
||||
|
||||
while (osmium::memory::Buffer buffer = reader.read()) {
|
||||
// Write buffer to disk and update indexes.
|
||||
disk_store_handler(buffer);
|
||||
|
||||
// Update object relation index maps.
|
||||
osmium::apply(buffer, object_relations_handler);
|
||||
}
|
||||
|
||||
reader.close();
|
||||
|
||||
// Write out node, way, and relation offset indexes to disk.
|
||||
IndexFile nodes_idx{output_dir + "/nodes.idx"};
|
||||
node_index.dump_as_list(nodes_idx.fd());
|
||||
|
||||
IndexFile ways_idx{output_dir + "/ways.idx"};
|
||||
way_index.dump_as_list(ways_idx.fd());
|
||||
|
||||
IndexFile relations_idx{output_dir + "/relations.idx"};
|
||||
relation_index.dump_as_list(relations_idx.fd());
|
||||
|
||||
// Sort the maps (so later binary search will work on them) and write
|
||||
// them to disk.
|
||||
map_node2way.sort();
|
||||
IndexFile node2way_idx{output_dir + "/node2way.map"};
|
||||
map_node2way.dump_as_list(node2way_idx.fd());
|
||||
|
||||
map_node2relation.sort();
|
||||
IndexFile node2relation_idx{output_dir + "/node2rel.map"};
|
||||
map_node2relation.dump_as_list(node2relation_idx.fd());
|
||||
|
||||
map_way2relation.sort();
|
||||
IndexFile way2relation_idx{output_dir + "/way2rel.map"};
|
||||
map_way2relation.dump_as_list(way2relation_idx.fd());
|
||||
|
||||
map_relation2relation.sort();
|
||||
IndexFile relation2relation_idx{output_dir + "/rel2rel.map"};
|
||||
map_relation2relation.dump_as_list(relation2relation_idx.fd());
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ int main(int argc, char* argv[]) {
|
||||
// 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(output_file, 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".
|
||||
|
||||
-260
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
|
||||
Example program to look at Osmium indexes on disk.
|
||||
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include <osmium/index/map/dense_file_array.hpp>
|
||||
#include <osmium/index/map/sparse_file_array.hpp>
|
||||
#include <osmium/osm/location.hpp>
|
||||
#include <osmium/osm/types.hpp>
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
class IndexSearch {
|
||||
|
||||
typedef typename osmium::index::map::DenseFileArray<TKey, TValue> dense_index_type;
|
||||
typedef typename osmium::index::map::SparseFileArray<TKey, TValue> sparse_index_type;
|
||||
|
||||
int m_fd;
|
||||
bool m_dense_format;
|
||||
|
||||
void dump_dense() {
|
||||
dense_index_type index(m_fd);
|
||||
|
||||
for (std::size_t i = 0; i < index.size(); ++i) {
|
||||
if (index.get(i) != TValue()) {
|
||||
std::cout << i << " " << index.get(i) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump_sparse() {
|
||||
sparse_index_type index(m_fd);
|
||||
|
||||
for (auto& element : index) {
|
||||
std::cout << element.first << " " << element.second << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool search_dense(TKey key) {
|
||||
dense_index_type index(m_fd);
|
||||
|
||||
try {
|
||||
TValue value = index.get(key);
|
||||
std::cout << key << " " << value << "\n";
|
||||
} catch (...) {
|
||||
std::cout << key << " not found\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool search_sparse(TKey key) {
|
||||
typedef typename sparse_index_type::element_type element_type;
|
||||
sparse_index_type index(m_fd);
|
||||
|
||||
element_type elem {key, TValue()};
|
||||
auto positions = std::equal_range(index.begin(), index.end(), elem, [](const element_type& lhs, const element_type& rhs) {
|
||||
return lhs.first < rhs.first;
|
||||
});
|
||||
if (positions.first == positions.second) {
|
||||
std::cout << key << " not found\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& it = positions.first; it != positions.second; ++it) {
|
||||
std::cout << it->first << " " << it->second << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
IndexSearch(int fd, bool dense_format) :
|
||||
m_fd(fd),
|
||||
m_dense_format(dense_format) {
|
||||
}
|
||||
|
||||
void dump() {
|
||||
if (m_dense_format) {
|
||||
dump_dense();
|
||||
} else {
|
||||
dump_sparse();
|
||||
}
|
||||
}
|
||||
|
||||
bool search(TKey key) {
|
||||
if (m_dense_format) {
|
||||
return search_dense(key);
|
||||
} else {
|
||||
return search_sparse(key);
|
||||
}
|
||||
}
|
||||
|
||||
bool search(const std::vector<TKey>& keys) {
|
||||
bool found_all = true;
|
||||
|
||||
for (const auto key : keys) {
|
||||
if (!search(key)) {
|
||||
found_all = false;
|
||||
}
|
||||
}
|
||||
|
||||
return found_all;
|
||||
}
|
||||
|
||||
}; // class IndexSearch
|
||||
|
||||
enum return_code : int {
|
||||
okay = 0,
|
||||
not_found = 1,
|
||||
error = 2,
|
||||
fatal = 3
|
||||
};
|
||||
|
||||
class Options {
|
||||
|
||||
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[]) {
|
||||
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}
|
||||
};
|
||||
|
||||
while (true) {
|
||||
int c = getopt_long(argc, argv, "a:dhl:s:t:", long_options, 0);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
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 (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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string& filename() const noexcept {
|
||||
return m_filename;
|
||||
}
|
||||
|
||||
bool dense_format() const noexcept {
|
||||
return m_array_format;
|
||||
}
|
||||
|
||||
bool do_dump() const noexcept {
|
||||
return m_dump;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
|
||||
Options options(argc, argv);
|
||||
|
||||
std::cout << std::fixed << std::setprecision(7);
|
||||
int fd = open(options.filename().c_str(), O_RDWR);
|
||||
|
||||
bool result_okay = true;
|
||||
|
||||
if (options.type_is("location")) {
|
||||
IndexSearch<osmium::unsigned_object_id_type, osmium::Location> is(fd, options.dense_format());
|
||||
|
||||
if (options.do_dump()) {
|
||||
is.dump();
|
||||
} else {
|
||||
result_okay = is.search(options.search_keys());
|
||||
}
|
||||
} else {
|
||||
IndexSearch<osmium::unsigned_object_id_type, size_t> is(fd, options.dense_format());
|
||||
|
||||
if (options.do_dump()) {
|
||||
is.dump();
|
||||
} else {
|
||||
result_okay = is.search(options.search_keys());
|
||||
}
|
||||
}
|
||||
|
||||
std::exit(result_okay ? return_code::okay : return_code::not_found);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
|
||||
EXAMPLE osmium_index
|
||||
|
||||
Example program to look at Osmium indexes on disk.
|
||||
|
||||
You can use the osmium_dump_internal example program to create the offset
|
||||
indexes or osmium_location_cache_create to create a node location index.
|
||||
|
||||
DEMONSTRATES USE OF:
|
||||
* access to indexes on disk
|
||||
|
||||
SIMPLER EXAMPLES you might want to understand first:
|
||||
* osmium_read
|
||||
* osmium_count
|
||||
* osmium_road_length
|
||||
* osmium_location_cache_create
|
||||
* osmium_location_cache_use
|
||||
|
||||
LICENSE
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <algorithm> // for std::all_of, std::equal_range
|
||||
#include <cstdlib> // for std::exit
|
||||
#include <fcntl.h> // for open
|
||||
#include <getopt.h> // for getopt_long
|
||||
#include <iostream> // for std::cout, std::cerr
|
||||
#include <memory> // for std::unique_ptr
|
||||
#include <string> // for std::string
|
||||
#include <sys/stat.h> // for open
|
||||
#include <sys/types.h> // for open
|
||||
#include <vector> // for std::vector
|
||||
|
||||
// Disk-based indexes
|
||||
#include <osmium/index/map/dense_file_array.hpp>
|
||||
#include <osmium/index/map/sparse_file_array.hpp>
|
||||
|
||||
// osmium::Location
|
||||
#include <osmium/osm/location.hpp>
|
||||
|
||||
// Basic Osmium types
|
||||
#include <osmium/osm/types.hpp>
|
||||
|
||||
// Virtual class for disk index access. If offers functions to dump the
|
||||
// indexes and to search for ids in the index.
|
||||
template <typename TValue>
|
||||
class IndexAccess {
|
||||
|
||||
int m_fd;
|
||||
|
||||
public:
|
||||
|
||||
IndexAccess(int fd) :
|
||||
m_fd(fd) {
|
||||
}
|
||||
|
||||
int fd() const noexcept {
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
virtual ~IndexAccess() = default;
|
||||
|
||||
virtual void dump() const = 0;
|
||||
|
||||
virtual bool search(const osmium::unsigned_object_id_type& key) const = 0;
|
||||
|
||||
bool search(const std::vector<osmium::unsigned_object_id_type>& keys) const {
|
||||
return std::all_of(keys.cbegin(), keys.cend(), [this](const osmium::unsigned_object_id_type& key) {
|
||||
return search(key);
|
||||
});
|
||||
}
|
||||
|
||||
}; // class IndexAccess
|
||||
|
||||
// Implementation of IndexAccess for dense indexes usually used for very large
|
||||
// extracts or the planet.
|
||||
template <typename TValue>
|
||||
class IndexAccessDense : public IndexAccess<TValue> {
|
||||
|
||||
using index_type = typename osmium::index::map::DenseFileArray<osmium::unsigned_object_id_type, TValue>;
|
||||
|
||||
public:
|
||||
|
||||
IndexAccessDense(int fd) :
|
||||
IndexAccess<TValue>(fd) {
|
||||
}
|
||||
|
||||
void dump() const override {
|
||||
index_type index{this->fd()};
|
||||
|
||||
for (std::size_t i = 0; i < index.size(); ++i) {
|
||||
if (index.get(i) != TValue{}) {
|
||||
std::cout << i << " " << index.get(i) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool search(const osmium::unsigned_object_id_type& key) const override {
|
||||
index_type index{this->fd()};
|
||||
|
||||
try {
|
||||
TValue value = index.get(key);
|
||||
std::cout << key << " " << value << "\n";
|
||||
} catch (...) {
|
||||
std::cout << key << " not found\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // class IndexAccessDense
|
||||
|
||||
// Implementation of IndexAccess for sparse indexes usually used for small or
|
||||
// medium sized extracts or for "multimap" type indexes.
|
||||
template <typename TValue>
|
||||
class IndexAccessSparse : public IndexAccess<TValue> {
|
||||
|
||||
using index_type = typename osmium::index::map::SparseFileArray<osmium::unsigned_object_id_type, TValue>;
|
||||
|
||||
public:
|
||||
|
||||
IndexAccessSparse(int fd) :
|
||||
IndexAccess<TValue>(fd) {
|
||||
}
|
||||
|
||||
void dump() const override {
|
||||
index_type index{this->fd()};
|
||||
|
||||
for (const auto& element : index) {
|
||||
std::cout << element.first << " " << element.second << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool search(const osmium::unsigned_object_id_type& key) const override {
|
||||
using element_type = typename index_type::element_type;
|
||||
index_type index{this->fd()};
|
||||
|
||||
element_type elem{key, TValue{}};
|
||||
const auto positions = std::equal_range(index.begin(),
|
||||
index.end(),
|
||||
elem,
|
||||
[](const element_type& lhs,
|
||||
const element_type& rhs) {
|
||||
return lhs.first < rhs.first;
|
||||
});
|
||||
if (positions.first == positions.second) {
|
||||
std::cout << key << " not found\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto it = positions.first; it != positions.second; ++it) {
|
||||
std::cout << it->first << " " << it->second << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // class IndexAccessSparse
|
||||
|
||||
// This class contains the code to parse the command line arguments, check
|
||||
// them and present the results to the rest of the program in an easy-to-use
|
||||
// way.
|
||||
class Options {
|
||||
|
||||
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_lookup [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', 'id', or 'offset')\n"
|
||||
;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Options(int argc, char* argv[]) {
|
||||
if (argc == 1) {
|
||||
print_help();
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
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}
|
||||
};
|
||||
|
||||
while (true) {
|
||||
const int c = getopt_long(argc, argv, "a:dhl:s:t:", long_options, 0);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'a':
|
||||
m_array_format = true;
|
||||
m_filename = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
m_dump = true;
|
||||
break;
|
||||
case 'h':
|
||||
print_help();
|
||||
std::exit(0);
|
||||
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 != "id" && m_type != "offset") {
|
||||
std::cerr << "Unknown type '" << m_type
|
||||
<< "'. Must be 'location', 'id', or 'offset'.\n";
|
||||
std::exit(2);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std::exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_array_format == m_list_format) {
|
||||
std::cerr << "Need option --array or --list, but not both\n";
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
if (m_dump && !m_ids.empty()) {
|
||||
std::cerr << "Need option --dump or --search, but not both\n";
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
if (m_type.empty()) {
|
||||
std::cerr << "Need --type argument.\n";
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const char* filename() const noexcept {
|
||||
return m_filename.c_str();
|
||||
}
|
||||
|
||||
bool dense_format() const noexcept {
|
||||
return m_array_format;
|
||||
}
|
||||
|
||||
bool do_dump() const noexcept {
|
||||
return m_dump;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
||||
// Factory function to create the right IndexAccess-derived class.
|
||||
template <typename TValue>
|
||||
std::unique_ptr<IndexAccess<TValue>> create(bool dense, int fd) {
|
||||
std::unique_ptr<IndexAccess<TValue>> ptr;
|
||||
|
||||
if (dense) {
|
||||
ptr.reset(new IndexAccessDense<TValue>{fd});
|
||||
} else {
|
||||
ptr.reset(new IndexAccessSparse<TValue>{fd});
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// Do the actual work: Either dump the index or search in the index.
|
||||
template <typename TValue>
|
||||
int run(const IndexAccess<TValue>& index, const Options& options) {
|
||||
if (options.do_dump()) {
|
||||
index.dump();
|
||||
return 0;
|
||||
} else {
|
||||
return index.search(options.search_keys()) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
// Parse command line options.
|
||||
Options options{argc, argv};
|
||||
|
||||
// Open the index file.
|
||||
const int fd = open(options.filename(), O_RDWR);
|
||||
if (fd < 0) {
|
||||
std::cerr << "Can not open file '" << options.filename()
|
||||
<< "': " << std::strerror(errno) << '\n';
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
// Depending on the type of index, we have different implementations.
|
||||
if (options.type_is("location")) {
|
||||
// index id -> location
|
||||
const auto index = create<osmium::Location>(options.dense_format(), fd);
|
||||
return run(*index, options);
|
||||
} else if (options.type_is("id")) {
|
||||
// index id -> id
|
||||
const auto index = create<osmium::unsigned_object_id_type>(options.dense_format(), fd);
|
||||
return run(*index, options);
|
||||
} else {
|
||||
// index id -> offset
|
||||
const auto index = create<std::size_t>(options.dense_format(), fd);
|
||||
return run(*index, options);
|
||||
}
|
||||
}
|
||||
|
||||
-206
@@ -1,206 +0,0 @@
|
||||
/*
|
||||
|
||||
This is a small tool to dump the contents of the input file
|
||||
in serialized format to stdout.
|
||||
|
||||
The code in this example file is released into the Public Domain.
|
||||
|
||||
*/
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <getopt.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <direct.h>
|
||||
#endif
|
||||
|
||||
#include <osmium/io/any_input.hpp>
|
||||
#include <osmium/handler/disk_store.hpp>
|
||||
#include <osmium/handler/object_relations.hpp>
|
||||
|
||||
#include <osmium/index/map/sparse_mem_array.hpp>
|
||||
#include <osmium/index/multimap/sparse_mem_multimap.hpp>
|
||||
#include <osmium/index/multimap/sparse_mem_array.hpp>
|
||||
#include <osmium/index/multimap/hybrid.hpp>
|
||||
|
||||
// ==============================================================================
|
||||
// Choose the following depending on the size of the input OSM files:
|
||||
// ==============================================================================
|
||||
// for smaller OSM files (extracts)
|
||||
typedef osmium::index::map::SparseMemArray<osmium::unsigned_object_id_type, size_t> offset_index_type;
|
||||
//typedef osmium::index::map::SparseMapMmap<osmium::unsigned_object_id_type, size_t> offset_index_type;
|
||||
//typedef osmium::index::map::SparseMapFile<osmium::unsigned_object_id_type, size_t> offset_index_type;
|
||||
|
||||
typedef osmium::index::multimap::SparseMemArray<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type> map_type;
|
||||
//typedef osmium::index::multimap::SparseMemMultimap<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type> map_type;
|
||||
//typedef osmium::index::multimap::Hybrid<osmium::unsigned_object_id_type, osmium::unsigned_object_id_type> map_type;
|
||||
|
||||
// ==============================================================================
|
||||
// for very large OSM files (planet)
|
||||
//typedef osmium::index::map::DenseMmapArray<osmium::unsigned_object_id_type, size_t> offset_index_type;
|
||||
// ==============================================================================
|
||||
|
||||
void print_help() {
|
||||
std::cout << "osmium_serdump OSMFILE DIR\n" \
|
||||
<< "Serialize content of OSMFILE into data file in DIR.\n" \
|
||||
<< "\nOptions:\n" \
|
||||
<< " -h, --help This help message\n";
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
while (true) {
|
||||
int c = getopt_long(argc, argv, "h", long_options, 0);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_help();
|
||||
std::exit(0);
|
||||
default:
|
||||
std::exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
int remaining_args = argc - optind;
|
||||
|
||||
if (remaining_args != 2) {
|
||||
std::cerr << "Usage: " << argv[0] << " OSMFILE DIR\n";
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
std::string dir(argv[optind+1]);
|
||||
#ifndef _WIN32
|
||||
int result = ::mkdir(dir.c_str(), 0777);
|
||||
#else
|
||||
int result = mkdir(dir.c_str());
|
||||
#endif
|
||||
if (result == -1 && errno != EEXIST) {
|
||||
std::cerr << "Problem creating directory '" << dir << "': " << strerror(errno) << "\n";
|
||||
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";
|
||||
std::exit(2);
|
||||
}
|
||||
|
||||
offset_index_type node_index;
|
||||
offset_index_type way_index;
|
||||
offset_index_type relation_index;
|
||||
|
||||
osmium::handler::DiskStore disk_store_handler(data_fd, node_index, way_index, relation_index);
|
||||
|
||||
map_type map_node2way;
|
||||
map_type map_node2relation;
|
||||
map_type map_way2relation;
|
||||
map_type map_relation2relation;
|
||||
|
||||
osmium::handler::ObjectRelations object_relations_handler(map_node2way, map_node2relation, map_way2relation, map_relation2relation);
|
||||
|
||||
osmium::io::Reader reader(argv[1]);
|
||||
|
||||
while (osmium::memory::Buffer buffer = reader.read()) {
|
||||
disk_store_handler(buffer); // XXX
|
||||
osmium::apply(buffer, object_relations_handler);
|
||||
}
|
||||
|
||||
reader.close();
|
||||
|
||||
{
|
||||
std::string index_file(dir + "/nodes.idx");
|
||||
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";
|
||||
std::exit(2);
|
||||
}
|
||||
node_index.dump_as_list(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
{
|
||||
std::string index_file(dir + "/ways.idx");
|
||||
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";
|
||||
std::exit(2);
|
||||
}
|
||||
way_index.dump_as_list(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
{
|
||||
std::string index_file(dir + "/relations.idx");
|
||||
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";
|
||||
std::exit(2);
|
||||
}
|
||||
relation_index.dump_as_list(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
{
|
||||
map_node2way.sort();
|
||||
std::string index_file(dir + "/node2way.map");
|
||||
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";
|
||||
std::exit(2);
|
||||
}
|
||||
map_node2way.dump_as_list(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
{
|
||||
map_node2relation.sort();
|
||||
std::string index_file(dir + "/node2rel.map");
|
||||
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";
|
||||
std::exit(2);
|
||||
}
|
||||
map_node2relation.dump_as_list(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
{
|
||||
map_way2relation.sort();
|
||||
std::string index_file(dir + "/way2rel.map");
|
||||
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";
|
||||
std::exit(2);
|
||||
}
|
||||
map_way2relation.dump_as_list(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
{
|
||||
map_relation2relation.sort();
|
||||
std::string index_file(dir + "/rel2rel.map");
|
||||
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";
|
||||
std::exit(2);
|
||||
}
|
||||
map_relation2relation.dump_as_list(fd);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user