From 54d8a362fcf0e8b037f99e61491484180c5683ee Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Wed, 28 Sep 2011 17:22:03 +0200 Subject: [PATCH] Windows support, thanks sivetic --- Contractor/ContractionCleanup.h | 8 +++-- Contractor/Contractor.h | 18 +++++----- DataStructures/BinaryHeap.h | 6 ++-- DataStructures/DynamicGraph.h | 4 +-- DataStructures/ExtractorStructs.h | 12 +++---- DataStructures/NNGrid.h | 23 ++++++++----- DataStructures/PBFParser.h | 17 ++++++++-- DataStructures/Util.h | 26 +++++++++++++-- Plugins/BaseDescriptor.h | 2 +- Plugins/JSONDescriptor.h | 2 +- README.TXT | 42 +++++++++++++++++++++++ createHierarchy.cpp | 2 +- routed.cpp | 55 +++++++++++++++++++++++++++---- typedefs.h | 9 +++++ 14 files changed, 179 insertions(+), 47 deletions(-) diff --git a/Contractor/ContractionCleanup.h b/Contractor/ContractionCleanup.h index 993641ca8..c8448930b 100644 --- a/Contractor/ContractionCleanup.h +++ b/Contractor/ContractionCleanup.h @@ -26,7 +26,9 @@ or see http://www.gnu.org/licenses/agpl.txt. #else #include #endif +#ifndef _WIN32 #include +#endif #include "Contractor.h" #ifdef _OPENMP @@ -169,7 +171,7 @@ private: cout << "Scanning for useless shortcuts" << endl; BuildOutgoingGraph(); #pragma omp parallel for - for ( unsigned i = 0; i < ( unsigned ) _graph.size(); i++ ) { + for ( int i = 0; i < ( unsigned ) _graph.size(); i++ ) { for ( unsigned edge = _firstEdge[_graph[i].source]; edge < _firstEdge[_graph[i].source + 1]; ++edge ) { if ( edge == i ) continue; @@ -265,8 +267,8 @@ private: data->_heapForward->Insert( source, 0, source ); data->_heapBackward->Insert( target, 0, target ); - int targetDistance = std::numeric_limits< int >::max(); - NodeID middle = std::numeric_limits::max(); + int targetDistance = (std::numeric_limits< int >::max)(); + NodeID middle = (std::numeric_limits::max)(); while ( data->_heapForward->Size() + data->_heapBackward->Size() > 0 ) { if ( data->_heapForward->Size() > 0 ) { diff --git a/Contractor/Contractor.h b/Contractor/Contractor.h index e35c7a7bc..0fa376e33 100644 --- a/Contractor/Contractor.h +++ b/Contractor/Contractor.h @@ -109,7 +109,7 @@ public: edge.source = i->source(); edge.target = i->target(); - edge.data.distance = std::max((int)i->weight(), 1 ); + edge.data.distance = (std::max)((int)i->weight(), 1 ); assert( edge.data.distance > 0 ); #ifdef DEBUG if ( edge.data.distance > 24 * 60 * 60 * 10 ) { @@ -157,26 +157,26 @@ public: forwardEdge.data.middleName.nameID = backwardEdge.data.middleName.nameID = middle; forwardEdge.data.shortcut = backwardEdge.data.shortcut = false; forwardEdge.data.originalEdges = backwardEdge.data.originalEdges = 1; - forwardEdge.data.distance = backwardEdge.data.distance = std::numeric_limits< int >::max(); + forwardEdge.data.distance = backwardEdge.data.distance = (std::numeric_limits< int >::max)(); //remove parallel edges while ( i < edges.size() && edges[i].source == source && edges[i].target == target ) { if ( edges[i].data.forward ) - forwardEdge.data.distance = std::min( edges[i].data.distance, forwardEdge.data.distance ); + forwardEdge.data.distance = (std::min)( edges[i].data.distance, forwardEdge.data.distance ); if ( edges[i].data.backward ) - backwardEdge.data.distance = std::min( edges[i].data.distance, backwardEdge.data.distance ); + backwardEdge.data.distance = (std::min)( edges[i].data.distance, backwardEdge.data.distance ); i++; } //merge edges (s,t) and (t,s) into bidirectional edge if ( forwardEdge.data.distance == backwardEdge.data.distance ) { - if ( (int)forwardEdge.data.distance != std::numeric_limits< int >::max() ) { + if ( (int)forwardEdge.data.distance != (std::numeric_limits< int >::max)() ) { forwardEdge.data.backward = true; edges[edge++] = forwardEdge; } } else { //insert seperate edges - if ( (int)forwardEdge.data.distance != std::numeric_limits< int >::max() ) { + if ( (int)forwardEdge.data.distance != (std::numeric_limits< int >::max)() ) { edges[edge++] = forwardEdge; } - if ( (int)backwardEdge.data.distance != std::numeric_limits< int >::max() ) { + if ( (int)backwardEdge.data.distance != (std::numeric_limits< int >::max)() ) { edges[edge++] = backwardEdge; } } @@ -485,7 +485,7 @@ private: continue; const NodeID target = _graph->GetTarget( outEdge ); const int pathDistance = inData.distance + outData.distance; - maxDistance = std::max( maxDistance, pathDistance ); + maxDistance = (std::max)( maxDistance, pathDistance ); if ( !heap.WasInserted( target ) ) heap.Insert( target, pathDistance, _HeapData(true) ); else if ( pathDistance < heap.GetKey( target ) ) @@ -563,7 +563,7 @@ private: if ( u == node ) continue; neighbours.push_back( u ); - ( *nodeData )[u].depth = std::max(( *nodeData )[node].depth + 1, ( *nodeData )[u].depth ); + ( *nodeData )[u].depth = (std::max)(( *nodeData )[node].depth + 1, ( *nodeData )[u].depth ); } //eliminate duplicate entries ( forward + backward edges ) std::sort( neighbours.begin(), neighbours.end() ); diff --git a/DataStructures/BinaryHeap.h b/DataStructures/BinaryHeap.h index e2ea1ec2f..a36d998a1 100644 --- a/DataStructures/BinaryHeap.h +++ b/DataStructures/BinaryHeap.h @@ -32,7 +32,7 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include -template< typename NodeID, typename Key, bool initialize = false > +template< typename NodeID, typename Key, bool initialize = true > class ArrayStorage { public: @@ -144,7 +144,7 @@ public: void Clear() { heap.resize( 1 ); insertedNodes.clear(); - heap[0].weight = std::numeric_limits< Weight >::min(); + heap[0].weight = (std::numeric_limits< Weight >::min)(); nodeIndex.Clear(); } @@ -208,7 +208,7 @@ public: for ( typename std::vector< HeapElement >::iterator i = heap.begin() + 1, iend = heap.end(); i != iend; ++i ) insertedNodes[i->index].key = 0; heap.resize( 1 ); - heap[0].weight = std::numeric_limits< Weight >::min(); + heap[0].weight = (std::numeric_limits< Weight >::min)(); } void DecreaseKey( NodeID node, Weight weight ) { diff --git a/DataStructures/DynamicGraph.h b/DataStructures/DynamicGraph.h index fb626c133..e94afc340 100644 --- a/DataStructures/DynamicGraph.h +++ b/DataStructures/DynamicGraph.h @@ -200,12 +200,12 @@ class DynamicGraph { bool isDummy( EdgeIterator edge ) const { - return m_edges[edge].target == std::numeric_limits< NodeIterator >::max(); + return m_edges[edge].target == (std::numeric_limits< NodeIterator >::max)(); } void makeDummy( EdgeIterator edge ) { - m_edges[edge].target = std::numeric_limits< NodeIterator >::max(); + m_edges[edge].target = (std::numeric_limits< NodeIterator >::max)(); } struct Node { diff --git a/DataStructures/ExtractorStructs.h b/DataStructures/ExtractorStructs.h index e597be283..912332d52 100644 --- a/DataStructures/ExtractorStructs.h +++ b/DataStructures/ExtractorStructs.h @@ -61,7 +61,7 @@ struct _Node : NodeInfo{ return _Node(0,0,0); } static _Node max_value() { - return _Node(numeric_limits::max(), numeric_limits::max(), numeric_limits::max()); + return _Node((numeric_limits::max)(), (numeric_limits::max)(), (numeric_limits::max)()); } NodeID key() const { return id; @@ -157,7 +157,7 @@ struct _Edge { return _Edge(0,0); } static _Edge max_value() { - return _Edge(numeric_limits::max(), numeric_limits::max()); + return _Edge((numeric_limits::max)(), (numeric_limits::max)()); } }; @@ -194,10 +194,10 @@ struct _RawRestrictionContainer { _RawRestrictionContainer(bool isOnly = false) : fromWay(UINT_MAX), toWay(UINT_MAX), viaWay(UINT_MAX) { restriction.flags.isOnly = isOnly;} static _RawRestrictionContainer min_value() { - return _RawRestrictionContainer(numeric_limits::min(), numeric_limits::min(), numeric_limits::min(), numeric_limits::min()); + return _RawRestrictionContainer((numeric_limits::min)(), (numeric_limits::min)(), (numeric_limits::min)(), (numeric_limits::min)()); } static _RawRestrictionContainer max_value() { - return _RawRestrictionContainer(numeric_limits::max(), numeric_limits::max(), numeric_limits::max(), numeric_limits::max()); + return _RawRestrictionContainer((numeric_limits::max)(), (numeric_limits::max)(), (numeric_limits::max)(), (numeric_limits::max)()); } }; @@ -238,10 +238,10 @@ struct _WayIDStartAndEndEdge { _WayIDStartAndEndEdge(unsigned w, NodeID fs, NodeID ft, NodeID ls, NodeID lt) : wayID(w), firstStart(fs), firstTarget(ft), lastStart(ls), lastTarget(lt) {} static _WayIDStartAndEndEdge min_value() { - return _WayIDStartAndEndEdge(numeric_limits::min(), numeric_limits::min(), numeric_limits::min(), numeric_limits::min(), numeric_limits::min()); + return _WayIDStartAndEndEdge((numeric_limits::min)(), (numeric_limits::min)(), (numeric_limits::min)(), (numeric_limits::min)(), (numeric_limits::min)()); } static _WayIDStartAndEndEdge max_value() { - return _WayIDStartAndEndEdge(numeric_limits::max(), numeric_limits::max(), numeric_limits::max(), numeric_limits::max(), numeric_limits::max()); + return _WayIDStartAndEndEdge((numeric_limits::max)(), (numeric_limits::max)(), (numeric_limits::max)(), (numeric_limits::max)(), (numeric_limits::max)()); } }; diff --git a/DataStructures/NNGrid.h b/DataStructures/NNGrid.h index 153a62220..33508eaeb 100644 --- a/DataStructures/NNGrid.h +++ b/DataStructures/NNGrid.h @@ -28,6 +28,11 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include #include +#include + +#ifdef _WIN32 +#include +#endif #include #include @@ -160,7 +165,7 @@ public: } NNGrid(const char* rif, const char* _i, unsigned numberOfThreads = omp_get_num_procs()): cellCache(500), fileCache(500) { - iif = _i; + iif = std::string(_i); ramIndexTable.resize((1024*1024), UINT_MAX); ramInFile.open(rif, std::ios::in | std::ios::binary); } @@ -271,7 +276,7 @@ public: } } _Coordinate tmp; - double dist = numeric_limits::max(); + double dist = (numeric_limits::max)(); timestamp = get_timestamp(); for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) { double r = 0.; @@ -286,7 +291,7 @@ public: nodesOfEdge.projectedPoint.lon = tmp.lon; } } - if(dist != numeric_limits::max()) { + if(dist != (numeric_limits::max)()) { return true; } return false; @@ -307,7 +312,7 @@ public: } _Coordinate tmp; - double dist = numeric_limits::max(); + double dist = (numeric_limits::max)(); // timestamp = get_timestamp(); for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) { double r = 0.; @@ -342,7 +347,7 @@ public: } } _Coordinate tmp; - double dist = numeric_limits::max(); + double dist = (numeric_limits::max)(); timestamp = get_timestamp(); for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) { double r = 0.; @@ -366,7 +371,7 @@ public: } } _Coordinate tmp; - double dist = numeric_limits::max(); + double dist = (numeric_limits::max)(); for(std::vector<_Edge>::iterator it = candidates.begin(); it != candidates.end(); it++) { double r = 0.; double tmpDist = ComputeDistance(startCoord, it->startCoord, it->targetCoord, tmp, &r); @@ -561,7 +566,7 @@ private: // if(cellCache.exists(startIndexInFile)) { // cellCache.fetch(startIndexInFile, cellIndex); // } else { - std::ifstream localStream(iif, std::ios::in | std::ios::binary); + std::ifstream localStream(iif.c_str(), std::ios::in | std::ios::binary); localStream.seekg(startIndexInFile); localStream.read((char*) &cellIndex[0], 32*32*sizeof(unsigned)); localStream.close(); @@ -579,7 +584,7 @@ private: // if(fileCache.exists(position)) { // fileCache.fetch(position, result); // } else { - std::ifstream localStream(iif, std::ios::in | std::ios::binary); + std::ifstream localStream(iif.c_str(), std::ios::in | std::ios::binary); localStream.seekg(position); DiskEdge diskEdge; do { @@ -655,7 +660,7 @@ private: ifstream ramInFile; stxxl::vector * entries; std::vector ramIndexTable; //4 MB for first level index in RAM - const char * iif; + std::string iif; LRUCache > cellCache; LRUCache > fileCache; }; diff --git a/DataStructures/PBFParser.h b/DataStructures/PBFParser.h index aaf6b66d7..5ff24df4c 100644 --- a/DataStructures/PBFParser.h +++ b/DataStructures/PBFParser.h @@ -373,18 +373,20 @@ private: if ( size > MAX_BLOB_HEADER_SIZE || size < 0 ) { return false; } - char data[size]; + char *data = (char*)malloc(size); stream.read(data, size*sizeof(data[0])); if ( !(threadData->PBFBlobHeader).ParseFromArray( data, size ) ){ + free(data); return false; } + free(data); return true; } bool unpackZLIB(std::fstream & stream, _ThreadData * threadData) { unsigned rawSize = threadData->PBFBlob.raw_size(); - char unpackedDataArray[rawSize]; + char* unpackedDataArray = (char*)malloc(rawSize); z_stream compressedDataStream; compressedDataStream.next_in = ( unsigned char* ) threadData->PBFBlob.zlib_data().data(); compressedDataStream.avail_in = threadData->PBFBlob.zlib_data().size(); @@ -396,6 +398,7 @@ private: int ret = inflateInit( &compressedDataStream ); if ( ret != Z_OK ) { std::cerr << "[error] failed to init zlib stream" << std::endl; + free(unpackedDataArray); return false; } @@ -403,12 +406,14 @@ private: if ( ret != Z_STREAM_END ) { std::cerr << "[error] failed to inflate zlib stream" << std::endl; std::cerr << "[error] Error type: " << ret << std::endl; + free(unpackedDataArray); return false; } ret = inflateEnd( &compressedDataStream ); if ( ret != Z_OK ) { std::cerr << "[error] failed to deinit zlib stream" << std::endl; + free(unpackedDataArray); return false; } @@ -416,6 +421,7 @@ private: for(unsigned i = 0; i < rawSize; i++) { threadData->charBuffer[i] = unpackedDataArray[i]; } + free(unpackedDataArray); return true; } @@ -433,11 +439,12 @@ private: return false; } - char data[size]; + char* data = (char*)malloc(size); stream.read(data, sizeof(data[0])*size); if ( !threadData->PBFBlob.ParseFromArray( data, size ) ) { std::cerr << "[error] failed to parse blob" << std::endl; + free(data); return false; } @@ -451,16 +458,20 @@ private: } else if ( threadData->PBFBlob.has_zlib_data() ) { if ( !unpackZLIB(stream, threadData) ) { std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl; + free(data); return false; } } else if ( threadData->PBFBlob.has_lzma_data() ) { if ( !unpackLZMA(stream, threadData) ) std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl; + free(data); return false; } else { std::cerr << "[error] Blob contains no data" << std::endl; + free(data); return false; } + free(data); return true; } diff --git a/DataStructures/Util.h b/DataStructures/Util.h index 7fea6754f..4b7bb05d4 100644 --- a/DataStructures/Util.h +++ b/DataStructures/Util.h @@ -24,8 +24,30 @@ or see http://www.gnu.org/licenses/agpl.txt. #include #include #include -#include -#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifdef _WIN32 + #include + #include + #include + void gettimeofday(struct timeval* t,void* timezone) + { struct _timeb timebuffer; + _ftime( &timebuffer ); + t->tv_sec=timebuffer.time; + t->tv_usec=1000*timebuffer.millitm; + } +#else + #include +#endif + +#ifdef _WIN32 + #include +#else + #include +#endif #include /** Returns a timestamp (now) in seconds (incl. a fractional part). */ diff --git a/Plugins/BaseDescriptor.h b/Plugins/BaseDescriptor.h index 01bbc1bcb..55f5c7fc6 100644 --- a/Plugins/BaseDescriptor.h +++ b/Plugins/BaseDescriptor.h @@ -44,7 +44,7 @@ static double GetAngleBetweenTwoEdges(const _Coordinate& A, const _Coordinate& C int v2x = B.lon - C.lon; int v2y = B.lat - C.lat; - double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI; + double angle = (atan2((double)v2y,v2x) - atan2((double)v1y,v1x) )*180/M_PI; while(angle < 0) angle += 360; diff --git a/Plugins/JSONDescriptor.h b/Plugins/JSONDescriptor.h index 2b467f7d3..7bfcec595 100644 --- a/Plugins/JSONDescriptor.h +++ b/Plugins/JSONDescriptor.h @@ -157,7 +157,7 @@ public: } descriptorState.distanceOfInstruction += ApproximateDistance(descriptorState.currentCoordinate, descriptorState.nextCoordinate); lastNodeID = it->node; - if(it != path.begin()-1) { + if(it != path.begin()) { descriptorState.previousCoordinate = descriptorState.currentCoordinate; descriptorState.currentCoordinate = descriptorState.nextCoordinate; } diff --git a/README.TXT b/README.TXT index 7897807bf..a99f3cc33 100644 --- a/README.TXT +++ b/README.TXT @@ -24,6 +24,48 @@ Once the dependencies are properly installed running 'scons' should build the binaries. The Sconstruct has been built for Ubuntu 10.04, but it should work under any recent Linux. +Compiling Under Windows +--- + +Visual Studio 2008 solution and projects are included for Windows compilation, and +can be found in the vsproject directory. All required dependencies need to be +present, and the osrm.vsprops file will need to be edited to point to the various +dependency directories. The suggested directory structure for dependencies is: + +lib\ + boost\ + boost (contains includes) + lib + bzip2\ + bin (contains libbz2.dll) + include + lib + iconv\ + bin + include + lib + libxml2\ + bin + include + lib + protobuf + bin (contains protoc.exe) + include + lib (contains libprotobuf.lib and libprotobuf-debug.lib) + sparsehash + src + stxxl + include + lib (contains libstxxl.lib and libstxxl-debug.lib) + zlib + bin + include + lib (zlib.lib and zlibd.lib) + +Using the above structure, the only changes necessary for compilations are setting +the base paths in osrm.vsprops. + + Running the Server --- Running the server requires preprocessing data from Openstreetmap. To do so you diff --git a/createHierarchy.cpp b/createHierarchy.cpp index 77b418d94..a25976013 100644 --- a/createHierarchy.cpp +++ b/createHierarchy.cpp @@ -80,7 +80,7 @@ int main (int argc, char *argv[]) { #endif ifstream in; - in.open (argv[1]); + in.open (argv[1], ifstream::in | ifstream::binary); if (!in.is_open()) { cerr << "Cannot open " << argv[1] << endl; exit(-1); } diff --git a/routed.cpp b/routed.cpp index 3fdfb3b58..74d4cba45 100644 --- a/routed.cpp +++ b/routed.cpp @@ -39,26 +39,56 @@ or see http://www.gnu.org/licenses/agpl.txt. #include "Plugins/RoutePlugin.h" #include "Plugins/ViaRoutePlugin.h" #include "Util/InputFileUtil.h" + +#ifndef _WIN32 #include "Util/LinuxStackTrace.h" +#endif + using namespace std; typedef http::RequestHandler RequestHandler; -int main (int argc, char *argv[]) { - installCrashHandler(argv[0]); +#ifdef _WIN32 +boost::function0 console_ctrl_function; - if(testDataFiles(argc, argv)==false) { - std::cerr << "[error] at least one data file name seems to be bogus!" << std::endl; - exit(-1); - } +BOOL WINAPI console_ctrl_handler(DWORD ctrl_type) +{ + switch (ctrl_type) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_SHUTDOWN_EVENT: + console_ctrl_function(); + return TRUE; + default: + return FALSE; + } +} +#endif + +int main (int argc, char *argv[]) { +#ifndef _WIN32 + installCrashHandler(argv[0]); +#endif + + // Bug - testing not necessary. testDataFiles also tries to open the first + // argv, which is the name of exec file + //if(testDataFiles(argc, argv)==false) { + //std::cerr << "[error] at least one data file name seems to be bogus!" << std::endl; + //exit(-1); + //} try { std::cout << "[server] starting up engines, saved at " << __TIMESTAMP__ << std::endl; + +#ifndef _WIN32 int sig = 0; sigset_t new_mask; sigset_t old_mask; sigfillset(&new_mask); pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask); +#endif ServerConfiguration serverConfig("server.ini"); Server * s = ServerFactory::CreateServer(serverConfig); @@ -82,6 +112,7 @@ int main (int argc, char *argv[]) { boost::thread t(boost::bind(&Server::Run, s)); +#ifndef _WIN32 sigset_t wait_mask; pthread_sigmask(SIG_SETMASK, &old_mask, 0); sigemptyset(&wait_mask); @@ -89,8 +120,18 @@ int main (int argc, char *argv[]) { sigaddset(&wait_mask, SIGQUIT); sigaddset(&wait_mask, SIGTERM); pthread_sigmask(SIG_BLOCK, &wait_mask, 0); - std::cout << "[server] running and waiting for requests" << std::endl; + sigwait(&wait_mask, &sig); +#else + // Set console control handler to allow server to be stopped. + console_ctrl_function = boost::bind(&Server::Stop, s); + SetConsoleCtrlHandler(console_ctrl_handler, TRUE); + + s->Run(); +#endif + + std::cout << "[server] running and waiting for requests" << std::endl; + std::cout << std::endl << "[server] shutting down" << std::endl; s->Stop(); t.join(); diff --git a/typedefs.h b/typedefs.h index 48cea13a5..d749c171b 100644 --- a/typedefs.h +++ b/typedefs.h @@ -44,6 +44,15 @@ using namespace std; #define DELETE(x) { if(NULL != x) { delete x; x = NULL; } } +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#ifndef HAVE_ROUNDF +#include +using namespace boost::math; +#endif + typedef unsigned int NodeID; typedef unsigned int EdgeID; typedef unsigned int EdgeWeight;