diff --git a/DataStructures/extractorStructs.h b/DataStructures/extractorStructs.h new file mode 100644 index 000000000..826489804 --- /dev/null +++ b/DataStructures/extractorStructs.h @@ -0,0 +1,317 @@ +/* + open source routing machine + Copyright (C) Dennis Luxen, 2010 + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. +*/ + +#ifndef EXTRACTORSTRUCTS_H_ +#define EXTRACTORSTRUCTS_H_ + + +struct _Node : NodeInfo{ + bool trafficSignal; + + _Node(int _lat, int _lon, unsigned int _id) : NodeInfo(_lat, _lon, _id) {} + _Node() {} + + static _Node min_value() + { + return _Node(0,0,0); + } + static _Node max_value() + { + return _Node(numeric_limits::max(), numeric_limits::max(), numeric_limits::max()); + } + NodeID key() const + { + return id; + } +}; + +struct _Way { + std::vector< NodeID > path; + enum { + notSure = 0, oneway, bidirectional, opposite + } direction; + double maximumSpeed; + bool usefull:1; + bool access:1; + short type; +}; + +struct _Stats { + NodeID numberOfNodes; + NodeID numberOfEdges; + NodeID numberOfWays; + NodeID numberOfMaxspeed; +}; + +struct Settings { + struct SpeedProfile { + vector< double > speed; + vector< string > names; + } speedProfile; + vector accessList; + int trafficLightPenalty; + int indexInAccessListOf( const string & key) + { + for(int i = 0; i< accessList.size(); i++) + { + if(accessList[i] == key) + return i; + } + return -1; + } +}; + +struct Cmp : public std::binary_function +{ + typedef unsigned value_type; + bool operator () (const NodeID & a, const NodeID & b) const + { + return a < b; + } + value_type max_value() + { + return 0xffffffff; + } + value_type min_value() + { + return 0x0; + } +}; + +_Way _ReadXMLWay( xmlTextReaderPtr& inputReader, Settings& settings, _Stats& stats ) { + _Way way; + way.direction = _Way::notSure; + way.maximumSpeed = -1; + way.type = -1; + way.usefull = false; + way.access = true; + + if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { + const int depth = xmlTextReaderDepth( inputReader ); + while ( xmlTextReaderRead( inputReader ) == 1 ) { + const int childType = xmlTextReaderNodeType( inputReader ); + if ( childType != 1 && childType != 15 ) + continue; + const int childDepth = xmlTextReaderDepth( inputReader ); + xmlChar* childName = xmlTextReaderName( inputReader ); + if ( childName == NULL ) + continue; + + if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) { + xmlFree( childName ); + break; + } + if ( childType != 1 ) { + xmlFree( childName ); + continue; + } + + if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) { + xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" ); + xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" ); + if ( k != NULL && value != NULL ) { + if ( xmlStrEqual( k, ( const xmlChar* ) "oneway" ) == 1 ) { + if ( xmlStrEqual( value, ( const xmlChar* ) "no" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "false" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "0" ) == 1 ) + way.direction = _Way::bidirectional; + else if ( xmlStrEqual( value, ( const xmlChar* ) "yes" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "true" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "1" ) == 1 ) + way.direction = _Way::oneway; + else if ( xmlStrEqual( value, ( const xmlChar* ) "-1" ) == 1 ) + way.direction = _Way::opposite; + } else if ( xmlStrEqual( k, ( const xmlChar* ) "junction" ) == 1 ) { + if ( xmlStrEqual( value, ( const xmlChar* ) "roundabout" ) == 1 ) { + if ( way.direction == _Way::notSure ) { + way.direction = _Way::oneway; + } + if ( way.maximumSpeed == -1 ) + way.maximumSpeed = 10; + way.usefull = true; + } + } else if ( xmlStrEqual( k, ( const xmlChar* ) "highway" ) == 1 ) { + string name( ( const char* ) value ); + for ( int i = 0; i < settings.speedProfile.names.size(); i++ ) { + if ( name == settings.speedProfile.names[i] ) { + way.type = i; + way.usefull = true; + break; + } + } + if ( name == "motorway" ) { + if ( way.direction == _Way::notSure ) { + way.direction = _Way::oneway; + } + } else if ( name == "motorway_link" ) { + if ( way.direction == _Way::notSure ) { + way.direction = _Way::oneway; + } + } + } else if ( xmlStrEqual( k, ( const xmlChar* ) "maxspeed" ) == 1 ) { + double maxspeed = atof(( const char* ) value ); + + xmlChar buffer[100]; + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + stats.numberOfMaxspeed++; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf kmh", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + stats.numberOfMaxspeed++; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkmh", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + stats.numberOfMaxspeed++; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf km/h", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + stats.numberOfMaxspeed++; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkm/h", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + stats.numberOfMaxspeed++; + } + } + } + } + } + } else { + // string key( ( const char* ) k ); + // int index = -1;// settings.accessList.indexOf( key ); + // if ( index != -1 ) { //&& index < way.accessPriority ) { + if ( xmlStrEqual( value, ( const xmlChar* ) "private" ) == 1 + || xmlStrEqual( value, ( const xmlChar* ) "no" ) == 1 + || xmlStrEqual( value, ( const xmlChar* ) "agricultural" ) == 1 + || xmlStrEqual( value, ( const xmlChar* ) "forestry" ) == 1 + || xmlStrEqual( value, ( const xmlChar* ) "delivery" ) == 1 + ) { + way.access = false; + } + else if ( xmlStrEqual( value, ( const xmlChar* ) "yes" ) == 1 + || xmlStrEqual( value, ( const xmlChar* ) "designated" ) == 1 + || xmlStrEqual( value, ( const xmlChar* ) "official" ) == 1 + || xmlStrEqual( value, ( const xmlChar* ) "permissive" ) == 1 + ) { + way.access = true; + } + // } + } + + if ( k != NULL ) + xmlFree( k ); + if ( value != NULL ) + xmlFree( value ); + } + } else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) { + xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" ); + if ( ref != NULL ) { + way.path.push_back( atoi(( const char* ) ref ) ); + xmlFree( ref ); + } + } + + xmlFree( childName ); + } + } + return way; +} + +_Node _ReadXMLNode( xmlTextReaderPtr& inputReader ) { + _Node node; + node.trafficSignal = false; + + xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" ); + if ( attribute != NULL ) { + node.lat = static_cast(100000*atof(( const char* ) attribute ) ); + xmlFree( attribute ); + } + attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" ); + if ( attribute != NULL ) { + node.lon = static_cast(100000*atof(( const char* ) attribute )); + xmlFree( attribute ); + } + attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" ); + if ( attribute != NULL ) { + node.id = atoi(( const char* ) attribute ); + xmlFree( attribute ); + } + + if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { + const int depth = xmlTextReaderDepth( inputReader ); + while ( xmlTextReaderRead( inputReader ) == 1 ) { + const int childType = xmlTextReaderNodeType( inputReader ); + // 1 = Element, 15 = EndElement + if ( childType != 1 && childType != 15 ) + continue; + const int childDepth = xmlTextReaderDepth( inputReader ); + xmlChar* childName = xmlTextReaderName( inputReader ); + if ( childName == NULL ) + continue; + + if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) { + xmlFree( childName ); + break; + } + if ( childType != 1 ) { + xmlFree( childName ); + continue; + } + + if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) { + xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" ); + xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" ); + if ( k != NULL && value != NULL ) { + if ( xmlStrEqual( k, ( const xmlChar* ) "highway" ) == 1 ) { + if ( xmlStrEqual( value, ( const xmlChar* ) "traffic_signals" ) == 1 ) + node.trafficSignal = true; + } + } + if ( k != NULL ) + xmlFree( k ); + if ( value != NULL ) + xmlFree( value ); + } + + xmlFree( childName ); + } + } + return node; +} + + +double ApproximateDistance( const int lat1, const int lon1, const int lat2, const int lon2 ) { + static const double DEG_TO_RAD = 0.017453292519943295769236907684886; + ///Earth's quatratic mean radius for WGS-84 + static const double EARTH_RADIUS_IN_METERS = 6372797.560856; + double latitudeArc = ( lat1/100000. - lat2/100000. ) * DEG_TO_RAD; + double longitudeArc = ( lon1/100000. - lon2/100000. ) * DEG_TO_RAD; + double latitudeH = sin( latitudeArc * 0.5 ); + latitudeH *= latitudeH; + double lontitudeH = sin( longitudeArc * 0.5 ); + lontitudeH *= lontitudeH; + double tmp = cos( lat1/100000. * DEG_TO_RAD ) * cos( lat2/100000. * DEG_TO_RAD ); + double distanceArc = 2.0 * asin( sqrt( latitudeH + tmp * lontitudeH ) ); + return EARTH_RADIUS_IN_METERS * distanceArc; +} + + +#endif /* EXTRACTORSTRUCTS_H_ */ diff --git a/extractLargeNetwork.cpp b/extractLargeNetwork.cpp index 63c4235c0..c16aba975 100644 --- a/extractLargeNetwork.cpp +++ b/extractLargeNetwork.cpp @@ -37,93 +37,17 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include "typedefs.h" +#include "DataStructures/extractorStructs.h" using namespace std; - -struct _Node : NodeInfo{ - bool trafficSignal; - - _Node(int _lat, int _lon, unsigned int _id) : NodeInfo(_lat, _lon, _id) {} - _Node() {} - - static _Node min_value() - { - return _Node(0,0,0); - } - static _Node max_value() - { - return _Node(numeric_limits::max(), numeric_limits::max(), numeric_limits::max()); - } - NodeID key() const - { - return id; - } -}; - -struct _Way { - std::vector< NodeID > path; - enum { - notSure = 0, oneway, bidirectional, opposite - } direction; - double maximumSpeed; - bool usefull:1; - bool access:1; - short type; -}; - -struct _Stats { - NodeID numberOfNodes; - NodeID numberOfEdges; - NodeID numberOfWays; - NodeID numberOfMaxspeed; -}; - -struct Settings { - struct SpeedProfile { - vector< double > speed; - vector< string > names; - } speedProfile; - vector accessList; - int trafficLightPenalty; - int indexInAccessListOf( const string & key) - { - for(int i = 0; i< accessList.size(); i++) - { - if(accessList[i] == key) - return i; - } - return -1; - } -}; - -struct Cmp : public std::binary_function -{ - typedef unsigned value_type; - bool operator () (const NodeID & a, const NodeID & b) const - { - return a < b; - } - value_type max_value() - { - return 0xffffffff; - } - value_type min_value() - { - return 0x0; - } -}; - typedef google::dense_hash_map NodeMap; -_Way _ReadXMLWay( xmlTextReaderPtr& inputReader ); -_Node _ReadXMLNode( xmlTextReaderPtr& inputReader ); -double ApproximateDistance( const int lat1, const int lon1, const int lat2, const int lon2 ); - _Stats stats; Settings settings; - vector SignalNodes; + NodeMap * nodeMap = new NodeMap(); + int main (int argc, char *argv[]) { if(argc <= 1) @@ -148,7 +72,7 @@ int main (int argc, char *argv[]) living_street 30 service 20 */ - + double time = get_timestamp(); string names[13] = { "motorway", "motorway_link", "trunk", "trunk_link", "secondary", "secondary_link", "primary", "primary_link", "tertiary", "unclassified", "residential", "living_street", "service" }; double speeds[13] = { 120, 80, 100, 80, 100, 50, 100, 50, 100, 50, 50 , 30, 20}; settings.speedProfile.names.insert(settings.speedProfile.names.begin(), names, names+13); @@ -182,7 +106,7 @@ int main (int argc, char *argv[]) } else if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) { stats.numberOfWays++; - _Way way = _ReadXMLWay( inputReader ); + _Way way = _ReadXMLWay( inputReader, settings, stats ); if ( way.usefull && way.access && way.path.size() ) { for ( unsigned i = 0; i < way.path.size(); ++i ) { @@ -201,7 +125,7 @@ int main (int argc, char *argv[]) for(vector< NodeID >::size_type n = 0; n < path.size()-1; n++) { - //serialize path[n], path[n+1] + //serialize edge (path[n], path[n+1]) wayFile.write((char*)&way.path[n], sizeof(NodeID)); wayFile.write((char*)&way.path[n+1], sizeof(NodeID)); wayFile.write((char*)&way.type, sizeof(short)); @@ -216,8 +140,8 @@ int main (int argc, char *argv[]) allNodeFile.close(); usedNodesFile.close(); wayFile.close(); - cout << "ok" << endl; - //sort(UsedNodes.begin(), UsedNodes.end()); + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); unsigned memory_to_use = 1024 * 1024 * 1024; stxxl::syscall_file f("_usednodes", stxxl::file::DIRECT | stxxl::file::RDWR); @@ -226,11 +150,13 @@ int main (int argc, char *argv[]) usedNodesVectorType usedNodes( &f); cout << "Sorting used nodes ..." << flush; stxxl::sort(usedNodes.begin(), usedNodes.end(), Cmp(), memory_to_use); - cout << "ok" << endl; + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); cout << "Erasing duplicate entries ..." << flush; stxxl::vector::iterator NewEnd = unique ( usedNodes.begin(),usedNodes.end() ) ; usedNodes.resize ( NewEnd - usedNodes.begin() ); - cout << "ok" << endl; + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); stxxl::syscall_file fallnodes("_allnodes", stxxl::file::DIRECT | stxxl::file::RDWR); typedef stxxl::vector< _Node > second_vector_type; @@ -238,23 +164,22 @@ int main (int argc, char *argv[]) second_vector_type van(&fallnodes); cout << "Sorting all nodes ..." << flush; stxxl::ksort(van.begin(), van.end(), memory_to_use); - cout << "ok" << endl; + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); - - // cout << endl << "Statistics: " << endl; - // cout << "All Nodes: " << stats.numberOfNodes << endl; - // // cout << "Used Nodes: " << UsedNodes.size() << endl; - // cout << "Number of Ways: " << stats.numberOfWays << endl; - // cout << "Edges in graph: " << stats.numberOfEdges << endl; - // cout << "Number of ways with maxspeed information: " << stats.numberOfMaxspeed << endl; - // cout << "Number of nodes with traffic lights: " << SignalNodes.size() << endl; - // cout << "finished loading data" << endl; - // cout << "calculated edge weights and writing to disk ..." << flush; + cout << endl << "Statistics: " << endl; + cout << "All Nodes: " << stats.numberOfNodes << endl; + cout << "Used Nodes: " << nodeMap->size() << endl; + cout << "Number of Ways: " << stats.numberOfWays << endl; + cout << "Edges in graph: " << stats.numberOfEdges << endl; + cout << "Number of ways with maxspeed information: " << stats.numberOfMaxspeed << endl; + cout << "Number of nodes with traffic lights: " << SignalNodes.size() << endl; + cout << "finished loading data" << endl; + cout << "calculated edge weights and writing to disk ..." << flush; string name(argv[1]); int pos=name.find(".osm"); // pos=9 if(pos!=string::npos) { - //replace name.replace(pos, 5, ".osrm"); } else { name.append(".osrm"); @@ -282,7 +207,8 @@ int main (int argc, char *argv[]) nodeMap->insert(std::make_pair(current_Node.id, current_Node)); counter++; } - cout << "ok" << endl; + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); cout << "writing used ways ..." << endl; NodeID start, target; @@ -339,7 +265,8 @@ int main (int argc, char *argv[]) } inway.close(); fout.close(); - cout << "ok" << endl; + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); } catch ( const std::exception& e ) { cerr << "Caught Execption:" << e.what() << endl; return false; @@ -353,219 +280,3 @@ int main (int argc, char *argv[]) return true; } -_Way _ReadXMLWay( xmlTextReaderPtr& inputReader ) { - _Way way; - way.direction = _Way::notSure; - way.maximumSpeed = -1; - way.type = -1; - way.usefull = false; - way.access = true; - - if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { - const int depth = xmlTextReaderDepth( inputReader ); - while ( xmlTextReaderRead( inputReader ) == 1 ) { - const int childType = xmlTextReaderNodeType( inputReader ); - if ( childType != 1 && childType != 15 ) - continue; - const int childDepth = xmlTextReaderDepth( inputReader ); - xmlChar* childName = xmlTextReaderName( inputReader ); - if ( childName == NULL ) - continue; - - if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) { - xmlFree( childName ); - break; - } - if ( childType != 1 ) { - xmlFree( childName ); - continue; - } - - if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) { - xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" ); - xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" ); - if ( k != NULL && value != NULL ) { - if ( xmlStrEqual( k, ( const xmlChar* ) "oneway" ) == 1 ) { - if ( xmlStrEqual( value, ( const xmlChar* ) "no" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "false" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "0" ) == 1 ) - way.direction = _Way::bidirectional; - else if ( xmlStrEqual( value, ( const xmlChar* ) "yes" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "true" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "1" ) == 1 ) - way.direction = _Way::oneway; - else if ( xmlStrEqual( value, ( const xmlChar* ) "-1" ) == 1 ) - way.direction = _Way::opposite; - } else if ( xmlStrEqual( k, ( const xmlChar* ) "junction" ) == 1 ) { - if ( xmlStrEqual( value, ( const xmlChar* ) "roundabout" ) == 1 ) { - if ( way.direction == _Way::notSure ) { - way.direction = _Way::oneway; - } - if ( way.maximumSpeed == -1 ) - way.maximumSpeed = 10; - way.usefull = true; - } - } else if ( xmlStrEqual( k, ( const xmlChar* ) "highway" ) == 1 ) { - string name( ( const char* ) value ); - for ( int i = 0; i < settings.speedProfile.names.size(); i++ ) { - if ( name == settings.speedProfile.names[i] ) { - way.type = i; - way.usefull = true; - break; - } - } - if ( name == "motorway" ) { - if ( way.direction == _Way::notSure ) { - way.direction = _Way::oneway; - } - } else if ( name == "motorway_link" ) { - if ( way.direction == _Way::notSure ) { - way.direction = _Way::oneway; - } - } - } else if ( xmlStrEqual( k, ( const xmlChar* ) "maxspeed" ) == 1 ) { - double maxspeed = atof(( const char* ) value ); - - xmlChar buffer[100]; - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - stats.numberOfMaxspeed++; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf kmh", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - stats.numberOfMaxspeed++; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkmh", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - stats.numberOfMaxspeed++; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf km/h", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - stats.numberOfMaxspeed++; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkm/h", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - stats.numberOfMaxspeed++; - } - } - } - } - } - } else { - // string key( ( const char* ) k ); - // int index = -1;// settings.accessList.indexOf( key ); - // if ( index != -1 ) { //&& index < way.accessPriority ) { - if ( xmlStrEqual( value, ( const xmlChar* ) "private" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "no" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "agricultural" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "forestry" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "delivery" ) == 1 - ) { - way.access = false; - } - else if ( xmlStrEqual( value, ( const xmlChar* ) "yes" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "designated" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "official" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "permissive" ) == 1 - ) { - way.access = true; - } - // } - } - - if ( k != NULL ) - xmlFree( k ); - if ( value != NULL ) - xmlFree( value ); - } - } else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) { - xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" ); - if ( ref != NULL ) { - way.path.push_back( atoi(( const char* ) ref ) ); - xmlFree( ref ); - } - } - - xmlFree( childName ); - } - } - return way; -} - -_Node _ReadXMLNode( xmlTextReaderPtr& inputReader ) { - _Node node; - node.trafficSignal = false; - - xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" ); - if ( attribute != NULL ) { - node.lat = static_cast(100000*atof(( const char* ) attribute ) ); - xmlFree( attribute ); - } - attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" ); - if ( attribute != NULL ) { - node.lon = static_cast(100000*atof(( const char* ) attribute )); - xmlFree( attribute ); - } - attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" ); - if ( attribute != NULL ) { - node.id = atoi(( const char* ) attribute ); - xmlFree( attribute ); - } - - if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { - const int depth = xmlTextReaderDepth( inputReader ); - while ( xmlTextReaderRead( inputReader ) == 1 ) { - const int childType = xmlTextReaderNodeType( inputReader ); - // 1 = Element, 15 = EndElement - if ( childType != 1 && childType != 15 ) - continue; - const int childDepth = xmlTextReaderDepth( inputReader ); - xmlChar* childName = xmlTextReaderName( inputReader ); - if ( childName == NULL ) - continue; - - if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) { - xmlFree( childName ); - break; - } - if ( childType != 1 ) { - xmlFree( childName ); - continue; - } - - if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) { - xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" ); - xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" ); - if ( k != NULL && value != NULL ) { - if ( xmlStrEqual( k, ( const xmlChar* ) "highway" ) == 1 ) { - if ( xmlStrEqual( value, ( const xmlChar* ) "traffic_signals" ) == 1 ) - node.trafficSignal = true; - } - } - if ( k != NULL ) - xmlFree( k ); - if ( value != NULL ) - xmlFree( value ); - } - - xmlFree( childName ); - } - } - return node; -} - -double ApproximateDistance( const int lat1, const int lon1, const int lat2, const int lon2 ) { - static const double DEG_TO_RAD = 0.017453292519943295769236907684886; - ///Earth's quatratic mean radius for WGS-84 - static const double EARTH_RADIUS_IN_METERS = 6372797.560856; - double latitudeArc = ( lat1/100000. - lat2/100000. ) * DEG_TO_RAD; - double longitudeArc = ( lon1/100000. - lon2/100000. ) * DEG_TO_RAD; - double latitudeH = sin( latitudeArc * 0.5 ); - latitudeH *= latitudeH; - double lontitudeH = sin( longitudeArc * 0.5 ); - lontitudeH *= lontitudeH; - double tmp = cos( lat1/100000. * DEG_TO_RAD ) * cos( lat2/100000. * DEG_TO_RAD ); - double distanceArc = 2.0 * asin( sqrt( latitudeH + tmp * lontitudeH ) ); - return EARTH_RADIUS_IN_METERS * distanceArc; -} diff --git a/extractNetwork.cpp b/extractNetwork.cpp index 26d5ec81e..aab0d916a 100644 --- a/extractNetwork.cpp +++ b/extractNetwork.cpp @@ -26,57 +26,13 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include #include +#include #include "typedefs.h" - +#include "DataStructures/extractorStructs.h" using namespace std; - -struct _Node : NodeInfo{ - bool trafficSignal:1; -}; - -struct _Way { - std::vector< NodeID > path; - enum { - notSure = 0, oneway, bidirectional, opposite - } direction; - double maximumSpeed; - bool usefull:1; - bool access:1; - short type; -}; - typedef google::dense_hash_map NodeMap; -struct _Stats { - NodeID numberOfNodes; - NodeID numberOfEdges; - NodeID numberOfWays; - NodeID numberOfMaxspeed; -}; - -struct Settings { - struct SpeedProfile { - vector< double > speed; - vector< string > names; - } speedProfile; - vector accessList; - int trafficLightPenalty; - int indexInAccessListOf( const string & key) - { - for(int i = 0; i< accessList.size(); i++) - { - if(accessList[i] == key) - return i; - } - return -1; - } -}; - -_Way _ReadXMLWay( xmlTextReaderPtr& inputReader ); -_Node _ReadXMLNode( xmlTextReaderPtr& inputReader ); -double ApproximateDistance( const int lat1, const int lon1, const int lat2, const int lon2 ); - _Stats stats; Settings settings; NodeMap AllNodes; @@ -142,7 +98,7 @@ int main (int argc, char *argv[]) } else if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) { stats.numberOfWays++; - _Way way = _ReadXMLWay( inputReader ); + _Way way = _ReadXMLWay( inputReader, settings, stats ); if ( way.usefull && way.access && way.path.size() ) { for ( unsigned i = 0; i < way.path.size(); ++i ) { @@ -258,219 +214,3 @@ int main (int argc, char *argv[]) return true; } -_Way _ReadXMLWay( xmlTextReaderPtr& inputReader ) { - _Way way; - way.direction = _Way::notSure; - way.maximumSpeed = -1; - way.type = -1; - way.usefull = false; - way.access = true; - - if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { - const int depth = xmlTextReaderDepth( inputReader ); - while ( xmlTextReaderRead( inputReader ) == 1 ) { - const int childType = xmlTextReaderNodeType( inputReader ); - if ( childType != 1 && childType != 15 ) - continue; - const int childDepth = xmlTextReaderDepth( inputReader ); - xmlChar* childName = xmlTextReaderName( inputReader ); - if ( childName == NULL ) - continue; - - if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) { - xmlFree( childName ); - break; - } - if ( childType != 1 ) { - xmlFree( childName ); - continue; - } - - if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) { - xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" ); - xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" ); - if ( k != NULL && value != NULL ) { - if ( xmlStrEqual( k, ( const xmlChar* ) "oneway" ) == 1 ) { - if ( xmlStrEqual( value, ( const xmlChar* ) "no" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "false" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "0" ) == 1 ) - way.direction = _Way::bidirectional; - else if ( xmlStrEqual( value, ( const xmlChar* ) "yes" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "true" ) == 1 || xmlStrEqual( value, ( const xmlChar* ) "1" ) == 1 ) - way.direction = _Way::oneway; - else if ( xmlStrEqual( value, ( const xmlChar* ) "-1" ) == 1 ) - way.direction = _Way::opposite; - } else if ( xmlStrEqual( k, ( const xmlChar* ) "junction" ) == 1 ) { - if ( xmlStrEqual( value, ( const xmlChar* ) "roundabout" ) == 1 ) { - if ( way.direction == _Way::notSure ) { - way.direction = _Way::oneway; - } - if ( way.maximumSpeed == -1 ) - way.maximumSpeed = 10; - way.usefull = true; - } - } else if ( xmlStrEqual( k, ( const xmlChar* ) "highway" ) == 1 ) { - string name( ( const char* ) value ); - for ( int i = 0; i < settings.speedProfile.names.size(); i++ ) { - if ( name == settings.speedProfile.names[i] ) { - way.type = i; - way.usefull = true; - break; - } - } - if ( name == "motorway" ) { - if ( way.direction == _Way::notSure ) { - way.direction = _Way::oneway; - } - } else if ( name == "motorway_link" ) { - if ( way.direction == _Way::notSure ) { - way.direction = _Way::oneway; - } - } - } else if ( xmlStrEqual( k, ( const xmlChar* ) "maxspeed" ) == 1 ) { - double maxspeed = atof(( const char* ) value ); - - xmlChar buffer[100]; - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - stats.numberOfMaxspeed++; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf kmh", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - stats.numberOfMaxspeed++; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkmh", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - stats.numberOfMaxspeed++; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf km/h", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - stats.numberOfMaxspeed++; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkm/h", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - stats.numberOfMaxspeed++; - } - } - } - } - } - } else { -// string key( ( const char* ) k ); - // int index = -1;// settings.accessList.indexOf( key ); - // if ( index != -1 ) { //&& index < way.accessPriority ) { - if ( xmlStrEqual( value, ( const xmlChar* ) "private" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "no" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "agricultural" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "forestry" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "delivery" ) == 1 - ) { - way.access = false; - } - else if ( xmlStrEqual( value, ( const xmlChar* ) "yes" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "designated" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "official" ) == 1 - || xmlStrEqual( value, ( const xmlChar* ) "permissive" ) == 1 - ) { - way.access = true; - } - // } - } - - if ( k != NULL ) - xmlFree( k ); - if ( value != NULL ) - xmlFree( value ); - } - } else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) { - xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" ); - if ( ref != NULL ) { - way.path.push_back( atoi(( const char* ) ref ) ); - xmlFree( ref ); - } - } - - xmlFree( childName ); - } - } - return way; -} - -_Node _ReadXMLNode( xmlTextReaderPtr& inputReader ) { - _Node node; - node.trafficSignal = false; - - xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" ); - if ( attribute != NULL ) { - node.lat = static_cast(100000*atof(( const char* ) attribute ) ); - xmlFree( attribute ); - } - attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" ); - if ( attribute != NULL ) { - node.lon = static_cast(100000*atof(( const char* ) attribute )); - xmlFree( attribute ); - } - attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" ); - if ( attribute != NULL ) { - node.id = atoi(( const char* ) attribute ); - xmlFree( attribute ); - } - - if ( xmlTextReaderIsEmptyElement( inputReader ) != 1 ) { - const int depth = xmlTextReaderDepth( inputReader ); - while ( xmlTextReaderRead( inputReader ) == 1 ) { - const int childType = xmlTextReaderNodeType( inputReader ); - // 1 = Element, 15 = EndElement - if ( childType != 1 && childType != 15 ) - continue; - const int childDepth = xmlTextReaderDepth( inputReader ); - xmlChar* childName = xmlTextReaderName( inputReader ); - if ( childName == NULL ) - continue; - - if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "node" ) == 1 ) { - xmlFree( childName ); - break; - } - if ( childType != 1 ) { - xmlFree( childName ); - continue; - } - - if ( xmlStrEqual( childName, ( const xmlChar* ) "tag" ) == 1 ) { - xmlChar* k = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "k" ); - xmlChar* value = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "v" ); - if ( k != NULL && value != NULL ) { - if ( xmlStrEqual( k, ( const xmlChar* ) "highway" ) == 1 ) { - if ( xmlStrEqual( value, ( const xmlChar* ) "traffic_signals" ) == 1 ) - node.trafficSignal = true; - } - } - if ( k != NULL ) - xmlFree( k ); - if ( value != NULL ) - xmlFree( value ); - } - - xmlFree( childName ); - } - } - return node; -} - -double ApproximateDistance( const int lat1, const int lon1, const int lat2, const int lon2 ) { - static const double DEG_TO_RAD = 0.017453292519943295769236907684886; - ///Earth's quatratic mean radius for WGS-84 - static const double EARTH_RADIUS_IN_METERS = 6372797.560856; - double latitudeArc = ( lat1/100000. - lat2/100000. ) * DEG_TO_RAD; - double longitudeArc = ( lon1/100000. - lon2/100000. ) * DEG_TO_RAD; - double latitudeH = sin( latitudeArc * 0.5 ); - latitudeH *= latitudeH; - double lontitudeH = sin( longitudeArc * 0.5 ); - lontitudeH *= lontitudeH; - double tmp = cos( lat1/100000. * DEG_TO_RAD ) * cos( lat2/100000. * DEG_TO_RAD ); - double distanceArc = 2.0 * asin( sqrt( latitudeH + tmp * lontitudeH ) ); - return EARTH_RADIUS_IN_METERS * distanceArc; -}