diff --git a/include/osm/osm_map.h b/include/osm/osm_map.h index ffeb727cf6ece440f71060247b770ecfcdca4094..1bf2f79e51230b43ec870a35a97887dd7592747e 100644 --- a/include/osm/osm_map.h +++ b/include/osm/osm_map.h @@ -9,6 +9,7 @@ #include "road_map.h" #include <osmium/handler.hpp> +#include <osmium/io/header.hpp> #include <osmium/tags/tags_filter.hpp> class COSMMap : public osmium::handler::Handler @@ -24,9 +25,8 @@ class COSMMap : public osmium::handler::Handler std::vector<COSMRestriction *> restrictions; osmium::TagsFilter way_filter; osmium::TagsFilter relation_filter; - double max_x,min_x,width; - double max_y,min_y,height; long int max_id; + int utm_zone; protected: void free(void); void process_map(void); @@ -39,9 +39,11 @@ class COSMMap : public osmium::handler::Handler void add_node(COSMNode *node); COSMNode *get_node_by_id(long int id); void add_restriction(COSMRestriction *restriction); - void normalize_locations(void); + void normalize_locations(std::vector<osmium::Box> &boxes); public: COSMMap(); + void set_utm_zone(int zone); + int get_utm_zone(void); void load(const std::string &filename); void node(const osmium::Node& node); void way(const osmium::Way& way); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ce4af31f69dab725be5ed4cfae390115dea87e4a..8600f515f15e66c09b1c9399c18d8c5ccfb14372 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,10 +10,13 @@ SET(osm_headers ../include/osm/osm_map.h ../include/osm/osm_node.h ../include/os list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/libosmium") +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};/usr/share/cmake/geographiclib") + # locate the necessary dependencies find_package(Eigen3 REQUIRED) find_package(iriutils REQUIRED) find_package(Osmium REQUIRED COMPONENTS xml io gdal) +find_package(GeographicLib REQUIRED) ADD_SUBDIRECTORY(xml) @@ -23,6 +26,7 @@ INCLUDE_DIRECTORIES(./) INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${iriutils_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${OSMIUM_INCLUDE_DIRS}) +INCLUDE_DIRECTORIES(${GeographicLib_INCLUDE_DIRS}) # create the shared library ADD_LIBRARY(${PROJECT_NAME} SHARED ${sources} ${opendrive_sources} ${osm_sources} ${XSD_SOURCES}) @@ -30,6 +34,7 @@ ADD_LIBRARY(${PROJECT_NAME} SHARED ${sources} ${opendrive_sources} ${osm_sources TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${XSD_LIBRARY}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${iriutils_LIBRARY}) TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${OSMIUM_LIBRARIES}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${GeographicLib_LIBRARIES}) ADD_DEPENDENCIES(${PROJECT_NAME} xsd_files_gen) diff --git a/src/osm/osm_map.cpp b/src/osm/osm_map.cpp index 9111591348dec3c4053c7925955cb4aebbf50c4e..b39be9e0782986bf8944cca508d40d7ef7f0c8a0 100644 --- a/src/osm/osm_map.cpp +++ b/src/osm/osm_map.cpp @@ -6,6 +6,7 @@ #include <osmium/io/xml_input.hpp> #include <osmium/visitor.hpp> #include <osmium/tags/taglist.hpp> +#include <GeographicLib/UTMUPS.hpp> #include "road.h" @@ -20,13 +21,8 @@ COSMMap::COSMMap() : this->way_filter.add_rule(true, "highway", highway_tags[i]); for(unsigned int i=0;i<relation_type_tags.size();i++) this->relation_filter.add_rule(true, "type", relation_type_tags[i]); - this->max_x=-std::numeric_limits<double>::max(); - this->min_x=std::numeric_limits<double>::max(); - this->width=0.0; - this->max_y=-std::numeric_limits<double>::max(); - this->min_y=std::numeric_limits<double>::max(); - this->height=0.0; this->max_id=-std::numeric_limits<long int>::max(); + this->utm_zone=31; } void COSMMap::free(void) @@ -61,19 +57,12 @@ void COSMMap::free(void) this->restrictions[i]=NULL; } this->ways.clear(); - this->max_x=-std::numeric_limits<double>::max(); - this->min_x=std::numeric_limits<double>::max(); - this->width=0.0; - this->max_y=-std::numeric_limits<double>::max(); - this->min_y=std::numeric_limits<double>::max(); - this->height=0.0; } void COSMMap::process_map(void) { std::vector<COSMNode *>::iterator node_it; std::vector<COSMWay *>::iterator way_it; - double x,y; // remove all nodes that do not belong to any road for(node_it=this->nodes.begin();node_it!=this->nodes.end();) @@ -103,20 +92,6 @@ void COSMMap::process_map(void) // remove nodes inside other ways width for(unsigned int i=0;i<this->nodes.size();i++) this->nodes[i]->remove_in_junction_nodes(); - for(unsigned int i=0;i<this->nodes.size();i++) - { - this->nodes[i]->get_location(x,y); - // get the coordinates - if(x>this->max_x) - this->max_x=x; - if(x<this->min_x) - this->min_x=x; - if(y>this->max_y) - this->max_y=y; - if(y<this->min_y) - this->min_y=y; - } - this->normalize_locations(); } void COSMMap::create_junctions(void) @@ -242,21 +217,36 @@ void COSMMap::add_restriction(COSMRestriction *restriction) this->restrictions.push_back(restriction); } -void COSMMap::normalize_locations(void) +void COSMMap::normalize_locations(std::vector<osmium::Box> &boxes) { - double center_x,center_y; + double max_x,min_x,max_y,min_y,center_x,center_y,gamma,k; + int zone; + bool northp; - center_x=(this->max_x+this->min_x)/2.0; - center_y=(this->max_y+this->min_y)/2.0; + if(boxes.size()!=1) + { + this->free(); + throw CException(_HERE_,"Invalid number of bounding boxes. Only one supported"); + } + osmium::Location top_right=boxes[0].top_right(); + osmium::Location bottom_left=boxes[0].bottom_left(); + GeographicLib::UTMUPS::Forward(top_right.lat(),top_right.lon(),zone,northp,max_x,max_y,gamma,k,this->utm_zone); + GeographicLib::UTMUPS::Forward(bottom_left.lat(),bottom_left.lon(),zone,northp,min_x,min_y,gamma,k,this->utm_zone); + center_x=(max_x+min_x)/2.0; + center_y=(max_y+min_y)/2.0; + std::cout << max_x << "," << min_x << "," << max_y << "," << min_y << "," << center_x << "," << center_y << std::endl; for(unsigned int i=0;i<this->nodes.size();i++) this->nodes[i]->normalize_location(center_x,center_y); - this->max_x-=center_x; - this->min_x-=center_x; - this->max_y-=center_y; - this->min_y-=center_y; - // compute the width and heigth - this->width=this->max_x-this->min_x; - this->height=this->max_y-this->min_y; +} + +void COSMMap::set_utm_zone(int zone) +{ + this->utm_zone=zone; +} + +int COSMMap::get_utm_zone(void) +{ + return this->utm_zone; } void COSMMap::load(const std::string &filename) @@ -282,6 +272,10 @@ void COSMMap::load(const std::string &filename) osmium::apply(relation_reader,*this); relation_reader.close(); + // read the bounds of the map + std::vector<osmium::Box> boxes=node_reader.header().boxes(); + this->normalize_locations(boxes); + this->process_map(); this->create_road_segments(); this->create_junctions(); diff --git a/src/osm/osm_node.cpp b/src/osm/osm_node.cpp index b9f026254648704844b5a71fb53ab0e88d92a68d..fdc1808d74b58fcf4de37057c1066c12fc8a5e31 100644 --- a/src/osm/osm_node.cpp +++ b/src/osm/osm_node.cpp @@ -8,14 +8,16 @@ #include <osmium/geom/coordinates.hpp> #include <osmium/geom/mercator_projection.hpp> +#include <GeographicLib/UTMUPS.hpp> COSMNode::COSMNode(const osmium::Node &node,COSMMap *parent) { + int zone; + bool northp; + double gamma,k; + this->id=node.id(); - osmium::geom::Coordinates loc(node.location()); - osmium::geom::Coordinates utm_loc=osmium::geom::lonlat_to_mercator(loc); - this->location.x=utm_loc.x; - this->location.y=utm_loc.y; + GeographicLib::UTMUPS::Forward(node.location().lat(),node.location().lon(),zone,northp,this->location.x,this->location.y,gamma,k,parent->get_utm_zone()); this->ways.clear(); this->junction=NULL; this->restrictions.clear();