Skip to content

Instantly share code, notes, and snippets.

@rnorris
Created August 8, 2014 21:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rnorris/6efe00b00e70821c5b23 to your computer and use it in GitHub Desktop.
Save rnorris/6efe00b00e70821c5b23 to your computer and use it in GitHub Desktop.
OSM Highway Lengths using libosmium
/*
The code in this example file is released into the Public Domain.
Simple output of road lengths (anything tagged highway=*) with optional print out of the split across highway types
Easiest way to compile is to replace the file road_lengths.cpp in
https://github.com/osmcode/osmium-contrib
with this version, and the run make on the command line.
*/
#include <cstdlib>
#include <osmium/index/map/sparse_table.hpp>
#include <osmium/handler/node_locations_for_ways.hpp>
#include <osmium/io/any_input.hpp>
#include <osmium/visitor.hpp>
#include <osmium/osm/types.hpp>
#include <osmium/geom/haversine.hpp>
typedef osmium::index::map::SparseTable<osmium::unsigned_object_id_type, osmium::Location> index_type;
typedef osmium::handler::NodeLocationsForWays<index_type> location_handler_type;
class RoadLengthHandler : public osmium::handler::Handler {
std::map<std::string, double> lengths;
std::string hwy;
bool verbose = false;
public:
// Not using/don't need default destructor function
RoadLengthHandler ( const bool vb )
{
verbose = vb;
}
void way(const osmium::Way& way)
{
try {
const char* highway = way.tags().get_value_by_key("highway");
if (highway) {
hwy.assign(highway);
lengths[hwy] += osmium::geom::haversine::distance (way.nodes());
}
}
catch (std::exception& e) {
std::cerr << "Ignoring illegal geometry for way " << way.id() << ".\n";
}
}
void done()
{
double total = 0.0;
for (auto& l : lengths)
{
if (verbose)
printf("%-20s%8.1f km\n", l.first.c_str(), l.second/1000.0 );
total += l.second;
}
printf("TOTAL %8.1f km\n", total/1000.0);
}
};
int main(int argc, char *argv[])
{
if (argc != 2 && argc != 3 ) {
std::cerr << "Usage: " << argv[0] << " OSMFILE" << " [-v]"<< std::endl;
exit(1);
}
try {
osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::way | osmium::osm_entity_bits::node;
osmium::io::File infile(argv[1]);
osmium::io::Reader reader(infile, read_types);
// By defualt processing ways only contains node references
// Thus we have to create these tables of lookups to access positional node information of a way
index_type index;
location_handler_type location_handler(index);
location_handler.ignore_errors();
RoadLengthHandler handler ( argc == 3 );
osmium::apply(reader, location_handler, handler );
// 'done' no longer part of osmium::handler class so invoke manually
handler.done();
}
catch (std::exception& e) {
std::cerr << "Can not open file: " << argv[1] << std::endl;
exit (2);
}
google::protobuf::ShutdownProtobufLibrary();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment