diff --git a/DataStructures/InputReaderFactory.h b/DataStructures/InputReaderFactory.h new file mode 100644 index 000000000..a1c54814a --- /dev/null +++ b/DataStructures/InputReaderFactory.h @@ -0,0 +1,84 @@ +/* + open source routing machine + Copyright (C) Dennis Luxen, others 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 BZ2INPUTREADER_H +#define BZ2INPUTREADER_H + +#include +#include +#include + +#include + +struct Context { + FILE* file; + BZFILE* bz2; + bool error; +}; + +int readFromBz2Stream( void* pointer, char* buffer, int len ) +{ + Context* context = (Context*) pointer; + if ( len == 0 || context->error ) + return 0; + + int error = 0; + int read = BZ2_bzRead( &error, context->bz2, buffer, len ); + if ( error == BZ_OK ) + return read; + + context->error = true; + if ( error == BZ_STREAM_END ) + return read; + return 0; +} + +int closeBz2Stream( void *pointer ) +{ + Context* context = (Context*) pointer; + BZ2_bzclose( context->bz2 ); + fclose( context->file ); + delete context; + return 0; +} + +xmlTextReaderPtr inputReaderFactory( const char* name ) +{ + std::string inputName(name); + + if(inputName.find(".osm.bz2")!=string::npos) + { + Context* context = new Context; + context->error = false; + context->file = fopen( name, "r" ); + int error; + context->bz2 = BZ2_bzReadOpen( &error, context->file, 0, 0, NULL, 0 ); + if ( context->bz2 == NULL || context->file == NULL ) { + delete context; + return NULL; + } + + return xmlReaderForIO( readFromBz2Stream, closeBz2Stream, (void*) context, NULL, NULL, 0 ); + } else { + return xmlNewTextReaderFilename(name); + } +} + +#endif // BZ2INPUTREADER_H diff --git a/DataStructures/extractorStructs.h b/DataStructures/extractorStructs.h index 3952aa880..8603c738b 100644 --- a/DataStructures/extractorStructs.h +++ b/DataStructures/extractorStructs.h @@ -21,6 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #ifndef EXTRACTORSTRUCTS_H_ #define EXTRACTORSTRUCTS_H_ +#include #include /* Default Speed Profile: @@ -43,304 +44,349 @@ string names[13] = { "motorway", "motorway_link", "trunk", "trunk_link", "primar double speeds[13] = { 110, 90, 90, 70, 70, 60, 60, 50, 55, 50, 40 , 10, 30}; struct _Node : NodeInfo{ - bool trafficSignal; + bool trafficSignal; - _Node(int _lat, int _lon, unsigned int _id) : NodeInfo(_lat, _lon, _id) {} - _Node() {} + _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; - } + 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 _Coordinate { + int lat; + int lon; + _Coordinate () : lat(INT_MIN), lon(INT_MIN) {}; }; struct _Way { - std::vector< NodeID > path; - enum { - notSure = 0, oneway, bidirectional, opposite - } direction; - double maximumSpeed; - bool usefull:1; - bool access:1; - short type; + std::vector< NodeID > path; + enum { + notSure = 0, oneway, bidirectional, opposite + } direction; + double maximumSpeed; + bool usefull:1; + bool access:1; + short type; }; struct _Edge { - NodeID start; - NodeID target; - short type; - short direction; - double speed; + _Edge() {}; + _Edge(NodeID s, NodeID t) : start(s), target(t) { } + NodeID start; + NodeID target; + short type; + short direction; + double speed; + + _Coordinate startCoord; + _Coordinate targetCoord; }; 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 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 NodeID 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; + } +}; + +struct CompareEdgeByStart : public std::binary_function<_Edge, _Edge, bool> +{ + typedef _Edge value_type; + bool operator () (const _Edge & a, const _Edge & b) const + { + return a.start < b.start; + } + value_type max_value() + { + return _Edge(UINT_MAX, UINT_MAX); + } + value_type min_value() + { + return _Edge(0, 0); + } +}; + +struct CompareEdgeByTarget : public std::binary_function<_Edge, _Edge, bool> +{ + typedef _Edge value_type; + bool operator () (const _Edge & a, const _Edge & b) const + { + return a.target < b.target; + } + value_type max_value() + { + return _Edge(UINT_MAX, UINT_MAX); + } + value_type min_value() + { + return _Edge(0, 0); + } }; _Way _ReadXMLWay( xmlTextReaderPtr& inputReader, Settings& settings ) { - _Way way; - way.direction = _Way::notSure; - way.maximumSpeed = -1; - way.type = -1; - way.usefull = false; - way.access = true; + _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 ( 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 ( 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 ); + 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; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf kmh", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkmh", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf km/h", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkm/h", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf mph", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfmph", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf mp/h", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - } else { - xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfmp/h", maxspeed ); - if ( xmlStrEqual( value, buffer ) == 1 ) { - way.maximumSpeed = maxspeed; - } - } - } - } - } - } - } - } - } - } else { - 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; - } - } + xmlChar buffer[100]; + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf kmh", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkmh", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf km/h", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfkm/h", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf mph", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfmph", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lf mp/h", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + } else { + xmlStrPrintf( buffer, 100, ( const xmlChar* ) "%.lfmp/h", maxspeed ); + if ( xmlStrEqual( value, buffer ) == 1 ) { + way.maximumSpeed = maxspeed; + } + } + } + } + } + } + } + } + } + } else { + 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; + 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; + _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 ); - } + 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 ( 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 ( 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 ); - } + 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; + 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; + 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/Docs/3rdparty.txt b/Docs/3rdparty.txt index 593889d4b..80d2569db 100644 --- a/Docs/3rdparty.txt +++ b/Docs/3rdparty.txt @@ -3,4 +3,5 @@ Third Party Libraries: Scons 1.3+ Boost 1.37+ sparsehash 1.4+ -stxxl 1.2.1+ \ No newline at end of file +stxxl 1.2.1+ +libz2-dev 1.0.5+ \ No newline at end of file diff --git a/SConstruct b/SConstruct index f06b5b336..3684295d0 100644 --- a/SConstruct +++ b/SConstruct @@ -53,6 +53,9 @@ if not conf.CheckCXXHeader('google/sparse_hash_map'): if not conf.CheckCXXHeader('boost/asio.hpp'): print "boost/asio.hpp not found. Exiting" Exit(-1) +if not conf.CheckLibWithHeader('bz2', 'bzlib.h', 'CXX'): + print "bz2 library not found. Exiting" + Exit(-1) if not conf.CheckLib('boost_thread'): if not conf.CheckLib('boost_thread-mt'): print "boost thread library not found. Exiting" @@ -87,8 +90,8 @@ env.Append(LINKFLAGS = ' -fopenmp') env.Program("extractNetwork.cpp") env.Program("extractLargeNetwork.cpp") env.Program("createHierarchy.cpp") -env.Append(CCFLAGS = ' -lboost_regex -lboost_iostreams -lboost_system') -env.Append(LINKFLAGS = ' -lboost_regex -lboost_iostreams -lboost_system') +env.Append(CCFLAGS = ' -lboost_regex -lboost_iostreams -lboost_system -lbz2') +env.Append(LINKFLAGS = ' -lboost_regex -lboost_iostreams -lboost_system -lbz2') env.Program("routed.cpp") env = conf.Finish() diff --git a/extractLargeNetwork.cpp b/extractLargeNetwork.cpp index 8411c15b8..56e035594 100644 --- a/extractLargeNetwork.cpp +++ b/extractLargeNetwork.cpp @@ -36,6 +36,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include "typedefs.h" +#include "DataStructures/InputReaderFactory.h" #include "DataStructures/extractorStructs.h" using namespace std; @@ -55,220 +56,230 @@ NodeMap * nodeMap = new NodeMap(); int main (int argc, char *argv[]) { - if(argc <= 1) - { - cerr << "usage: " << endl << argv[0] << " " << endl; - exit(-1); - } - cout << "reading input file. This may take some time ..." << flush; - double time = get_timestamp(); - settings.speedProfile.names.insert(settings.speedProfile.names.begin(), names, names+13); - settings.speedProfile.speed.insert(settings.speedProfile.speed.begin(), speeds, speeds+13); + if(argc <= 1) + { + cerr << "usage: " << endl << argv[0] << " " << endl; + exit(-1); + } + cout << "reading input file. This may take some time ..." << flush; + xmlTextReaderPtr inputReader = inputReaderFactory(argv[1]); - xmlTextReaderPtr inputReader = xmlNewTextReaderFilename( argv[1] ); - nodeMap->set_empty_key(UINT_MAX); - try { - while ( xmlTextReaderRead( inputReader ) == 1 ) { - const int type = xmlTextReaderNodeType( inputReader ); + double time = get_timestamp(); + settings.speedProfile.names.insert(settings.speedProfile.names.begin(), names, names+13); + settings.speedProfile.speed.insert(settings.speedProfile.speed.begin(), speeds, speeds+13); - //1 is Element - if ( type != 1 ) - continue; + nodeMap->set_empty_key(UINT_MAX); + try { + while ( xmlTextReaderRead( inputReader ) == 1 ) { + const int type = xmlTextReaderNodeType( inputReader ); - xmlChar* currentName = xmlTextReaderName( inputReader ); - if ( currentName == NULL ) - continue; + //1 is Element + if ( type != 1 ) + continue; - if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) { - _Node node = _ReadXMLNode( inputReader ); - allNodes.push_back(node); - if ( node.trafficSignal ) - SignalNodes.push_back( node.id ); + xmlChar* currentName = xmlTextReaderName( inputReader ); + if ( currentName == NULL ) + continue; - } - else if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) { - _Way way = _ReadXMLWay( inputReader, settings ); + if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) { + _Node node = _ReadXMLNode( inputReader ); + allNodes.push_back(node); + if ( node.trafficSignal ) + SignalNodes.push_back( node.id ); - if ( way.usefull && way.access && way.path.size() ) { - for ( unsigned i = 0; i < way.path.size(); ++i ) { - usedNodes.push_back(way.path[i]); - } + } + else if ( xmlStrEqual( currentName, ( const xmlChar* ) "way" ) == 1 ) { + _Way way = _ReadXMLWay( inputReader, settings ); - if ( way.direction == _Way::opposite ) - std::reverse( way.path.begin(), way.path.end() ); + if ( way.usefull && way.access && way.path.size() ) { + for ( unsigned i = 0; i < way.path.size(); ++i ) { + usedNodes.push_back(way.path[i]); + } - { - vector< NodeID > & path = way.path; - double speed = way.maximumSpeed; - assert(way.type > -1 || way.maximumSpeed != -1); - assert(path.size()>0); + if ( way.direction == _Way::opposite ) + std::reverse( way.path.begin(), way.path.end() ); - for(vector< NodeID >::size_type n = 0; n < path.size()-1; n++) - { - _Edge e; - e.start = way.path[n]; - e.target = way.path[n+1]; - e.type = way.type; - e.direction = way.direction; - e.speed = way.maximumSpeed; - allEdges.push_back(e); - } - } - } - } - xmlFree( currentName ); - } - cout << "ok, after " << get_timestamp() - time << "s" << endl; - time = get_timestamp(); - unsigned memory_to_use = 1024 * 1024 * 1024; + { + vector< NodeID > & path = way.path; + double speed = way.maximumSpeed; + assert(way.type > -1 || way.maximumSpeed != -1); + assert(path.size()>0); - cout << "Sorting used nodes ..." << flush; - stxxl::sort(usedNodes.begin(), usedNodes.end(), Cmp(), memory_to_use); - 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, after " << get_timestamp() - time << "s" << endl; - time = get_timestamp(); + for(vector< NodeID >::size_type n = 0; n < path.size()-1; n++) + { + _Edge e; + e.start = way.path[n]; + e.target = way.path[n+1]; + e.type = way.type; + e.direction = way.direction; + e.speed = way.maximumSpeed; + allEdges.push_back(e); + } + } + } + } + xmlFree( currentName ); + } + cout << "raw no. of nodes: " << allNodes.size() << endl; + cout << "raw no. of edges: " << allEdges.size() << endl; - cout << "Sorting all nodes ..." << flush; - stxxl::ksort(allNodes.begin(), allNodes.end(), memory_to_use); - cout << "ok, after " << get_timestamp() - time << "s" << endl; - time = get_timestamp(); + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); + unsigned memory_to_use = 1024 * 1024 * 1024; - string name(argv[1]); - int pos=name.find(".osm"); // pos=9 - if(pos!=string::npos) - { - name.replace(pos, 5, ".osrm"); - } else { - name.append(".osrm"); - } + cout << "Sorting used nodes ..." << flush; + stxxl::sort(usedNodes.begin(), usedNodes.end(), Cmp(), memory_to_use); + 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, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); - ofstream fout; - fout.open(name.c_str()); - // ifstream inway("_ways", ios::binary); + cout << "Sorting all nodes ..." << flush; + stxxl::ksort(allNodes.begin(), allNodes.end(), memory_to_use); + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); - cout << "Confirming used nodes ..." << flush; - NodeID counter = 0; - NodeID notfound = 0; - STXXLNodeVector::iterator nvit = allNodes.begin(); - STXXLNodeIDVector::iterator niit = usedNodes.begin(); - while(niit != usedNodes.end() && nvit != allNodes.end()) - { - if(*niit < nvit->id){ - niit++; - continue; - } - if(*niit > nvit->id) - { - nvit++; - continue; - } - if(*niit == nvit->id) - { - confirmedNodes.push_back(*nvit); - nodeMap->insert(std::make_pair(nvit->id, *nvit)); - niit++; - nvit++; - } - } - cout << "ok, after " << get_timestamp() - time << "s" << endl; - time = get_timestamp(); + string name(argv[1]); + int pos; + pos = name.find(".osm.bz2"); + if(pos!=string::npos) + { + name.replace(pos, 8, ".osrm"); + } else { + pos=name.find(".osm"); + if(pos!=string::npos) + { + name.replace(pos, 5, ".osrm"); + } else { + name.append(".osrm"); + } + } - cout << "Writing used nodes ..." << flush; - fout << confirmedNodes.size() << endl; - for(STXXLNodeVector::iterator ut = confirmedNodes.begin(); ut != confirmedNodes.end(); ut++) - { - fout << ut->id<< " " << ut->lon << " " << ut->lat << "\n"; - } + ofstream fout; + fout.open(name.c_str()); - cout << "ok, after " << get_timestamp() - time << "s" << endl; - time = get_timestamp(); + cout << "Confirming used nodes ..." << flush; + NodeID counter = 0; + NodeID notfound = 0; + STXXLNodeVector::iterator nvit = allNodes.begin(); + STXXLNodeIDVector::iterator niit = usedNodes.begin(); + while(niit != usedNodes.end() && nvit != allNodes.end()) + { + if(*niit < nvit->id){ + niit++; + continue; + } + if(*niit > nvit->id) + { + nvit++; + continue; + } + if(*niit == nvit->id) + { + confirmedNodes.push_back(*nvit); + nodeMap->insert(std::make_pair(nvit->id, *nvit)); + niit++; + nvit++; + } + } + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); - cout << "confirming used ways ..." << flush; - for(STXXLEdgeVector::iterator eit = allEdges.begin(); eit != allEdges.end(); eit++) - { - assert(eit->type > -1 || eit->speed != -1); + cout << "Writing used nodes ..." << flush; + fout << confirmedNodes.size() << endl; + for(STXXLNodeVector::iterator ut = confirmedNodes.begin(); ut != confirmedNodes.end(); ut++) + { + fout << ut->id<< " " << ut->lon << " " << ut->lat << "\n"; + } - NodeMap::iterator startit = nodeMap->find(eit->start); - if(startit == nodeMap->end()) - { - continue; - } - NodeMap::iterator targetit = nodeMap->find(eit->target); + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); - if(targetit == nodeMap->end()) - { - continue; - } - confirmedEdges.push_back(*eit); - } - fout << confirmedEdges.size() << "\n"; - cout << "ok, after " << get_timestamp() - time << "s" << endl; - time = get_timestamp(); + cout << "confirming used ways ..." << flush; + for(STXXLEdgeVector::iterator eit = allEdges.begin(); eit != allEdges.end(); eit++) + { + assert(eit->type > -1 || eit->speed != -1); - cout << "writing confirmed ways ..." << flush; + NodeMap::iterator startit = nodeMap->find(eit->start); + if(startit == nodeMap->end()) + { + continue; + } + NodeMap::iterator targetit = nodeMap->find(eit->target); - for(STXXLEdgeVector::iterator eit = confirmedEdges.begin(); eit != confirmedEdges.end(); eit++) - { - NodeMap::iterator startit = nodeMap->find(eit->start); - if(startit == nodeMap->end()) - { - continue; - } - NodeMap::iterator targetit = nodeMap->find(eit->target); + if(targetit == nodeMap->end()) + { + continue; + } + confirmedEdges.push_back(*eit); + } + fout << confirmedEdges.size() << "\n"; + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); - if(targetit == nodeMap->end()) - { - continue; - } - double distance = ApproximateDistance(startit->second.lat, startit->second.lon, targetit->second.lat, targetit->second.lon); - if(eit->speed == -1) - eit->speed = settings.speedProfile.speed[eit->type]; - double weight = ( distance * 10. ) / (eit->speed / 3.6); - double intWeight = max(1, (int) weight); - switch(eit->direction) - { - case _Way::notSure: - fout << startit->first << " " << targetit->first << " " << max(1, (int)distance) << " " << 0 << " " << intWeight << "\n"; - break; - case _Way::oneway: - fout << startit->first << " " << targetit->first << " " << max(1, (int)distance) << " " << 1 << " " << intWeight << "\n"; - break; - case _Way::bidirectional: - fout << startit->first << " " << targetit->first << " " << max(1, (int)distance) << " " << 0 << " " << intWeight << "\n"; - break; - case _Way::opposite: - fout << startit->first << " " << targetit->first << " " << max(1, (int)distance) << " " << 1 << " " << intWeight << "\n"; - break; - default: - assert(false); - break; - } - } - fout.close(); - cout << "ok, after " << get_timestamp() - time << "s" << endl; - time = get_timestamp(); - } catch ( const std::exception& e ) { - cerr << "Caught Execption:" << e.what() << endl; - return false; - } + cout << "writing confirmed ways ..." << flush; - cout << endl << "Statistics:" << endl; - cout << "-----------" << endl; - cout << "Usable Nodes: " << confirmedNodes.size() << endl; - cout << "Usable Ways : " << confirmedEdges.size() << endl; + for(STXXLEdgeVector::iterator eit = confirmedEdges.begin(); eit != confirmedEdges.end(); eit++) + { + NodeMap::iterator startit = nodeMap->find(eit->start); + if(startit == nodeMap->end()) + { + continue; + } + NodeMap::iterator targetit = nodeMap->find(eit->target); - SignalNodes.clear(); - usedNodes.clear(); - allNodes.clear(); - confirmedNodes.clear(); - allEdges.clear(); - confirmedEdges.clear(); + if(targetit == nodeMap->end()) + { + continue; + } + double distance = ApproximateDistance(startit->second.lat, startit->second.lon, targetit->second.lat, targetit->second.lon); + if(eit->speed == -1) + eit->speed = settings.speedProfile.speed[eit->type]; + double weight = ( distance * 10. ) / (eit->speed / 3.6); + double intWeight = max(1, (int) weight); + switch(eit->direction) + { + case _Way::notSure: + fout << startit->first << " " << targetit->first << " " << max(1, (int)distance) << " " << 0 << " " << intWeight << "\n"; + break; + case _Way::oneway: + fout << startit->first << " " << targetit->first << " " << max(1, (int)distance) << " " << 1 << " " << intWeight << "\n"; + break; + case _Way::bidirectional: + fout << startit->first << " " << targetit->first << " " << max(1, (int)distance) << " " << 0 << " " << intWeight << "\n"; + break; + case _Way::opposite: + fout << startit->first << " " << targetit->first << " " << max(1, (int)distance) << " " << 1 << " " << intWeight << "\n"; + break; + default: + assert(false); + break; + } + } + fout.close(); + cout << "ok, after " << get_timestamp() - time << "s" << endl; + time = get_timestamp(); + } catch ( const std::exception& e ) { + cerr << "Caught Execption:" << e.what() << endl; + return false; + } - xmlFreeTextReader(inputReader); - return 0; + cout << endl << "Statistics:" << endl; + cout << "-----------" << endl; + cout << "Usable Nodes: " << confirmedNodes.size() << endl; + cout << "Usable Ways : " << confirmedEdges.size() << endl; + + SignalNodes.clear(); + usedNodes.clear(); + allNodes.clear(); + confirmedNodes.clear(); + allEdges.clear(); + confirmedEdges.clear(); + + // xmlFreeTextReader(inputReader); + return 0; }