Created
August 8, 2014 21:51
-
-
Save rnorris/6efe00b00e70821c5b23 to your computer and use it in GitHub Desktop.
OSM Highway Lengths using libosmium
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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