Compare commits

..

159 Commits

Author SHA1 Message Date
Dennis Luxen b7980b83df removing dead comments 2013-08-15 15:51:07 +02:00
Dennis Luxen 0a0bed7ae0 Refactoring graph factory 2013-08-14 18:43:01 +02:00
Dennis Luxen b01e30acfd Moving DataStructures out of Plugin directory 2013-08-14 14:09:42 +02:00
Dennis Luxen 311c50df9f Moving DataStructures out of Plugin directory 2013-08-14 13:57:57 +02:00
Dennis Luxen c2f9467f61 Moving DataStructures out of Plugin directory 2013-08-14 13:54:59 +02:00
Dennis Luxen 06c8656b9e Moving DataStructures out of Plugin directory 2013-08-14 13:41:23 +02:00
Dennis Luxen 4748bca8a4 Refactoring _Coordinate class 2013-08-14 13:12:28 +02:00
Dennis Luxen 916387748c Refactor _Restriction class 2013-08-14 11:59:46 +02:00
Dennis Luxen 216d7dcb86 Fixing typos 2013-08-14 11:59:01 +02:00
Dennis Luxen 23f2c7e6f5 move windows specific defines behind define-fence 2013-08-14 11:58:23 +02:00
Dennis Luxen c8e0e5eca2 Export compile commands 2013-08-14 11:57:54 +02:00
Dennis Luxen 3167d3f451 Export compile commands 2013-08-14 11:57:33 +02:00
Dennis Luxen beb9c1ba74 use proper check for empty string 2013-08-13 18:37:21 +02:00
Dennis Luxen dcd88260e9 Add a few braces here and there 2013-08-13 18:36:23 +02:00
Dennis Luxen 5f4f631fc5 Remove dead code 2013-08-13 18:35:54 +02:00
Dennis Luxen dc6fda03a1 move const value to left-hand side of comparison 2013-08-13 18:35:22 +02:00
Dennis Luxen 764ad81537 Some mild refactoring 2013-08-13 18:34:33 +02:00
Dennis Luxen e26c41095f Some mild refactoring 2013-08-13 18:33:20 +02:00
Dennis Luxen d7bd78d612 correct timing of durations 2013-08-13 18:21:14 +02:00
Dennis Luxen c50b4c72d7 Refactoring of Plugins 2013-08-13 18:09:20 +02:00
Dennis Luxen 124e555ed0 Disabling debug output in release build 2013-08-13 10:48:02 +02:00
Dennis Luxen aeba3aa209 fixes #695 for bike profile 2013-08-12 18:00:56 +02:00
Emil Tin e50b5202b8 updated tests for car maxspeed forw/backw 2013-08-12 17:37:51 +02:00
Dennis Luxen 32c7578629 fixes #695, maxspeed:forward incorrectly made any way routable 2013-08-12 13:19:07 +02:00
Dennis Luxen 5bc5e0e8e9 logging into wrong channel 2013-08-11 23:25:22 +02:00
Dennis Luxen 7ee4692e84 properly order includes 2013-08-11 23:01:15 +02:00
Dennis Luxen 679688705d properly order includes 2013-08-11 22:53:31 +02:00
Dennis Luxen 83f0a2c094 Applying syntactic sugar 2013-08-11 22:49:33 +02:00
Dennis Luxen 504817058b remove checks for data that is not used here, log information through SimpleLogger 2013-08-11 22:35:13 +02:00
Dennis Luxen 45754b27de remove ignored const qualifiers 2013-08-11 22:10:05 +02:00
Dennis Luxen a75ae8bbef enable output for tools 2013-08-10 14:43:49 +02:00
Dennis Luxen c3e6dc69bb implements https://github.com/DennisOSRM/Project-OSRM/commit/0765ebf7355b0c4d70ca88f0dc78452dc84ede6c#commitcomment-3828005 2013-08-09 21:33:30 +02:00
Dennis Luxen 0285bb6ea5 Implements https://github.com/DennisOSRM/Project-OSRM/commit/34735b8aad06098d09d3fb907137697799a281e4#commitcomment-3828247 2013-08-09 20:16:26 +02:00
Dennis Luxen a542292ce2 Check if files exist and contain data, fixes #693 2013-08-09 17:47:11 +02:00
Dennis Luxen 0765ebf735 Implements #692 2013-08-09 14:47:09 +02:00
Dennis Luxen e86e8c37a8 const'ing parameters 2013-08-09 13:49:30 +02:00
Dennis Luxen 149a42cc94 Fixing coverity issue 1046672 and a potential memory leak 2013-08-09 13:24:05 +02:00
Dennis Luxen 8de4613a3e Fix coverity errors 1061543 751298 2013-08-09 12:55:08 +02:00
Dennis Luxen 60950c57e3 Fix coverity error 1061544 2013-08-09 12:53:23 +02:00
Dennis Luxen 4727bb5c9b Fix coverity error 1061545 2013-08-09 12:51:21 +02:00
Dennis Luxen 1e1e254897 Pass values by const ref 2013-08-09 12:50:21 +02:00
Dennis Luxen df5455121c Output uses new logging facility 2013-08-09 12:49:49 +02:00
Dennis Luxen 0e2570b204 enable logging for deamon 2013-08-08 16:23:28 +02:00
Dennis Luxen f57519b909 adapt tool to output logs with new mechanism 2013-08-08 16:20:05 +02:00
Dennis Luxen 088393ca12 Remove superflous output of endline 2013-08-08 16:19:25 +02:00
Dennis Luxen 375dc63db3 Make output conditional 2013-08-08 15:57:16 +02:00
Dennis Luxen 503324162f Configure project for actually different build types 2013-08-08 14:58:58 +02:00
Dennis Luxen 5445b64376 Configure project for actually different build types 2013-08-08 14:58:40 +02:00
Dennis Luxen 7fe997d38c Add missing newline on EOF 2013-08-08 14:53:49 +02:00
Dennis Luxen d7673dad7b fixing release build 2013-08-08 14:39:51 +02:00
Dennis Luxen 44eed9282b Adding new SimpleLogger class 2013-08-08 14:25:57 +02:00
Dennis Luxen 0eeb94b24c Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-08-08 14:18:13 +02:00
Dennis Luxen ef221e1c6c Replacing log macros by more sophisticated mechanism 2013-08-08 14:17:01 +02:00
Emil Tin 75cdefa4fe show name of missing .ini file 2013-08-07 21:33:43 +02:00
Dennis Luxen a609a1c6c2 Move common code into base class 2013-08-07 14:02:10 +02:00
Dennis Luxen f4906a97b9 pass const refs instead of copy 2013-08-07 14:01:56 +02:00
Dennis Luxen 21ffd441fa Refactoring base config class into proper ini file name 2013-08-06 17:46:49 +02:00
Dennis Luxen a82383d78e Refactoring base config class into proper ini file name 2013-08-06 17:33:26 +02:00
Dennis Luxen b405029f0f Refactoring base config class into proper ini file name 2013-08-06 17:23:40 +02:00
Dennis Luxen db7d4f56b3 Fix build with updated hash table 2013-08-06 16:58:31 +02:00
Dennis Luxen 3151197471 boost timer library not needed 2013-08-06 16:50:20 +02:00
Dennis Luxen e06fe6935a refactor Hashtable 2013-08-06 16:39:04 +02:00
Dennis Luxen e7cec83a4c Use boost timer to provide platform independent timing 2013-08-06 14:28:03 +02:00
Dennis Luxen e5f0ad4f0b Use boost timer to provide platform independent timing 2013-08-06 14:27:36 +02:00
Dennis Luxen cabbe70e47 reverting premature checkin 2013-08-06 14:01:03 +02:00
Dennis Luxen b86c3681bb reverting premature checkin 2013-08-06 13:54:04 +02:00
Dennis Luxen 0f8239bc8e Fixing build of tools 2013-08-06 12:28:19 +02:00
Dennis Luxen 13f5baf608 Moving node data structure into more meaningful class name 2013-08-05 19:35:47 +02:00
Dennis Luxen 4f5d7f79bd fixing tests for enhanced coordinate preceision 2013-08-05 19:00:09 +02:00
Dennis Luxen 23899613c3 Implement #495 2013-08-05 18:37:42 +02:00
Dennis Luxen db46a915cc simple wrapper around std::exception 2013-08-05 17:37:30 +02:00
Dennis Luxen b591aa013d Remove dead code 2013-08-05 17:35:16 +02:00
Dennis Luxen c0db8b71dd Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-08-05 17:30:17 +02:00
Dennis Luxen 444bf41fa4 use exceptions instead of hard abort 2013-08-05 17:29:34 +02:00
Dennis Luxen 54302a53e1 use exceptions instead of hard abort 2013-08-05 17:28:57 +02:00
Emil Tin 63059cfab3 make cuke tests work with ruby 2.x 2013-08-02 09:35:28 +02:00
Dennis Luxen ec7d3a9885 Fixing boost filesystem to work on old installations, too 2013-08-01 15:56:18 +02:00
Dennis Luxen 960b55fd6c accidentially called deprecated boost filesystem function 2013-07-31 22:55:20 +02:00
Dennis Luxen 3067ba60ae convert relative path in server.ini to absolute paths 2013-07-31 22:05:44 +02:00
Dennis Luxen c9a756eddc Updateing Readme to give proper reference (again) 2013-07-31 13:12:25 +02:00
Dennis Luxen d4ea5fc74f Updateing Readme to give proper reference 2013-07-31 13:09:25 +02:00
Dennis Luxen 92e52f1a5d Updateing Readme to display build status 2013-07-31 13:04:04 +02:00
Dennis Luxen f03d1a5d27 check release and debug builds in travis 2013-07-31 11:33:23 +02:00
Dennis Luxen 8a55b706ca testing with cucumber 2013-07-31 11:22:02 +02:00
Dennis Luxen 357133677a Add project to travis CI 2013-07-31 11:17:08 +02:00
Dennis Luxen 1b6c660a8f Merge pull request #689 from svenluzar/feature/roundabout4bikes
pull request moved to develop branch: roundabout handling from car profile moved to bike profile
2013-07-31 02:13:38 -07:00
Sven Luzar f2b81ba86c pull request moved to develop branch: roundabout handling from car profile moved to bike profile 2013-07-30 21:37:57 +02:00
Emil Tin 2542112301 fix cuke test for roundabout/cars 2013-07-30 18:00:44 +02:00
Emil Tin a45215ddf2 cuke test roundabout exit nr 2013-07-30 17:58:00 +02:00
Emil Tin cb28b2de07 cuke test for roundabout instructions 2013-07-30 17:01:25 +02:00
Dennis Luxen bf0b43aa24 Platform specific linker flags 2013-07-23 11:49:23 +02:00
Dennis Luxen 811d6deb41 Don't link against LuaJIT on OS X 2013-07-23 11:38:15 +02:00
Dennis Luxen bcdd9374c7 Compile fixes on OS X 2013-07-23 10:18:42 +02:00
DennisOSRM f70174d1d1 Link internal tools against UUID 2013-07-22 17:54:04 +02:00
DennisOSRM 4a39a4af1c Check for valid data files. Implements #224 2013-07-22 16:34:06 +02:00
DennisOSRM 0367399c89 Partial refactoring 2013-07-22 16:32:19 +02:00
DennisOSRM c5db4dc15f Check for correct magic number 2013-07-19 18:05:54 +02:00
DennisOSRM 31fbfa3a70 Link against UUID 2013-07-19 18:05:15 +02:00
DennisOSRM 3515ddcfe6 Automatic rebuild 2013-07-19 16:58:13 +02:00
DennisOSRM 90303d5952 further addition to cmake script 2013-07-19 16:36:57 +02:00
DennisOSRM 9a02421091 Some mild refactoring 2013-07-19 15:02:45 +02:00
DennisOSRM 4961b819f3 Trigger rebuild of fingerprint everytime 2013-07-19 15:00:41 +02:00
DennisOSRM 61c2ea9225 Trigger rebuild of fingerprint everytime 2013-07-19 14:53:47 +02:00
DennisOSRM f5f7269f70 Trigger rebuild of fingerprint everytime 2013-07-19 14:38:12 +02:00
DennisOSRM 03f1430ddc Trigger rebuild of fingerprint everytime 2013-07-19 14:37:40 +02:00
DennisOSRM c3dab15eb6 Several lookup fixes and fingerprinting of files with input IO, thx @alex85k 2013-07-18 14:11:45 +02:00
DennisOSRM a4f6ec516b Remove unnecessary file 2013-07-17 16:29:11 +02:00
DennisOSRM 1ca213cec6 Remove duplicate license header 2013-07-17 16:27:50 +02:00
DennisOSRM b782c8560c add forgotten include file 2013-07-17 16:27:09 +02:00
DennisOSRM d2e68068bf fixes #659 2013-07-17 16:23:57 +02:00
DennisOSRM 129a846393 add bit size to config object 2013-07-17 15:27:38 +02:00
DennisOSRM 15308931e9 (partially) adding new fingerprint objects 2013-07-17 14:47:22 +02:00
DennisOSRM 4dffeedd1c (partially) adding new fingerprint objects 2013-07-17 14:47:13 +02:00
DennisOSRM d0c4111429 Merge branch 'patch-3' of https://github.com/tyrasd/Project-OSRM into tyrasd-patch-3 2013-07-17 13:23:06 +02:00
DennisOSRM f579b6f971 Fixes #670 2013-07-17 13:20:48 +02:00
DennisOSRM f5124de327 Partially fixes #646. Values were incorrectly casted to int32_t and not uint32_t 2013-07-09 14:25:32 +02:00
DennisOSRM 9ab86ae2bf Fixes issue #663 2013-07-09 14:08:24 +02:00
DennisOSRM 51a7d3ff50 merge conflict CMakeLists.txt 2013-07-09 13:38:44 +02:00
DennisOSRM 80b9afc14d Merge branch 'libosrm' of https://github.com/DennisOSRM/Project-OSRM into libosrm 2013-07-08 15:10:43 +02:00
DennisOSRM 92ae8f37ba Reorder parameters 2013-07-08 14:59:51 +02:00
DennisOSRM df1f828488 Pass references instead of value types 2013-07-08 14:52:43 +02:00
DennisOSRM d8c97da087 Remove dead code and reformat 2013-07-08 14:51:55 +02:00
DennisOSRM 9d29e5d87a Base64 needs 3-byte padded inputs 2013-07-08 14:51:21 +02:00
DennisOSRM bf62147802 Fixing unneeded explicit conversion 2013-07-08 10:27:41 +02:00
Dennis Luxen 34735b8aad throw an exception when server.ini is missing 2013-07-05 22:36:51 +02:00
DennisOSRM 932b2b9acf Move pointer to member variables 2013-07-03 16:56:52 +02:00
DennisOSRM 7ab4472865 Fix non-critical memory leak 2013-07-03 16:54:51 +02:00
DennisOSRM e1e79206f9 fixing include typo 2013-07-03 16:01:59 +02:00
DennisOSRM 7ebe6de022 Proper check for luajit 2013-07-03 13:46:55 +02:00
DennisOSRM b234760e92 Check if platform supports 64 bits 2013-07-03 13:32:31 +02:00
DennisOSRM 3119e4b82b Use LuaJIT if available 2013-07-03 11:41:14 +02:00
DennisOSRM 2c3f05e6f1 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-07-03 10:03:08 +02:00
Dennis Luxen c3c0c8d881 readding profile.lua 2013-07-02 22:51:52 +02:00
Dennis Luxen 9de5e31a7a readding profile.lua 2013-07-02 22:51:21 +02:00
Martin Raifer dbf15c2db2 add test case for overruled implied oneways
On a motorway `oneway=no` should overrule the implied oneway rule.
2013-06-30 10:41:29 +02:00
Emil Tin c9c900b364 default cucumber profiles doesn't run @todo or @stress tests 2013-06-30 10:37:25 +02:00
Emil Tin 5c07204351 update rakefile for convenient cmake setup 2013-06-30 10:21:21 +02:00
Dennis Luxen de947d8b17 Add forgotten include 2013-06-28 10:23:58 -04:00
Dennis Luxen 8cb5e68b1a fixing coding style on OpenMP wrapper 2013-06-28 10:22:47 -04:00
Dennis Luxen 99aef2a178 fixing coding style on OpenMP wrapper 2013-06-28 10:14:31 -04:00
Dennis Luxen fff1460dfb ignore osrm-cli tool 2013-06-27 16:11:13 -04:00
Dennis Luxen e3b619fd54 Moved File 2013-06-27 16:09:40 -04:00
Dennis Luxen 29e363e7fb some refactoring 2013-06-27 16:09:21 -04:00
Dennis Luxen c209245b0e Moving cli client to tools directory 2013-06-27 16:09:01 -04:00
Dennis Luxen 4194ce3095 Moving cli client to tools directory 2013-06-27 16:08:33 -04:00
Dennis Luxen a0e9f59e04 Adding a simple example on how to call the lib 2013-06-27 13:21:33 -04:00
Dennis Luxen c940c2722e Fixing errors from static analysis 2013-06-27 11:44:55 -04:00
Dennis Luxen 5c84c12f40 Fixing errors from static analysis 2013-06-27 11:44:32 -04:00
Dennis Luxen 1bcacfab74 minor code massage 2013-06-27 10:57:40 -04:00
Dennis Luxen 1f5f8a76fb Removing files that are not used anymore 2013-06-27 09:54:58 -04:00
Dennis Luxen cfa8b1f0dd Moving coordinate auxiliary functions into the appropriate place 2013-06-27 09:45:28 -04:00
Dennis Luxen aecbcdd390 move OSRM core into library 2013-06-26 20:05:42 -04:00
Dennis Luxen 74729a372b some refactoring 2013-06-26 20:05:03 -04:00
Dennis Luxen 63d8abe32f First implementation of moving the algorithmic core into a library 2013-06-26 19:48:22 -04:00
Dennis Luxen 2c397bfa0b First implementation of moving the algorithmic core into a library 2013-06-26 19:48:02 -04:00
Dennis Luxen bfef8f39b7 First implementation of moving the algorithmic core into a library 2013-06-26 19:47:47 -04:00
Dennis Luxen 4430cbc3cb First implementation of moving the algorithmic core into a library 2013-06-26 19:47:16 -04:00
DennisOSRM b43a51f912 Merge branch 'develop' of https://github.com/DennisOSRM/Project-OSRM into develop 2013-06-25 20:49:51 +02:00
Dennis Luxen dd971d6b7d Fixing test for new Rtree 2013-06-05 11:38:45 +02:00
126 changed files with 3492 additions and 3107 deletions
+2 -1
View File
@@ -36,6 +36,7 @@ Thumbs.db
# build related files # # build related files #
####################### #######################
/build/ /build/
/Util/UUID.cpp
# Eclipse related files # # Eclipse related files #
######################### #########################
@@ -72,6 +73,7 @@ stxxl.errlog
/osrm-extract /osrm-extract
/osrm-routed /osrm-routed
/osrm-prepare /osrm-prepare
/osrm-cli
/nohup.out /nohup.out
# Sandbox folder # # Sandbox folder #
@@ -79,4 +81,3 @@ stxxl.errlog
/sandbox/ /sandbox/
/test/profile.lua /test/profile.lua
/profile.lua
+39
View File
@@ -0,0 +1,39 @@
language: cpp
compiler:
- gcc
# - clang
# Make sure CMake is installed
install:
- sudo apt-get update >/dev/null
- sudo apt-get -q install build-essential git cmake pkg-config libprotoc-dev libprotobuf7 protobuf-compiler libprotobuf-dev libosmpbf-dev libpng12-dev libbz2-dev libstxxl-dev libstxxl-doc libstxxl1 libxml2-dev libzip-dev libboost-thread-dev libboost-system-dev libboost-regex-dev libboost-filesystem-dev lua5.1 liblua5.1-0-dev libluabind-dev rubygems osmosis
before_script:
- sudo gem install bundler
- bundle install
- mkdir build
- cd build
- cmake .. $CMAKEOPTIONS
script: make
after_script:
- cd ..
- cucumber -p verify
branches:
only:
- master
- develop
env:
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release"
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug"
notifications:
irc:
channels:
- irc.oftc.net#osrm
on_success: change
on_failure: always
use_notice: true
skip_join: false
recipients:
- dennis@mapbox.com
email:
on_success: change
on_failure: always
+2 -1
View File
@@ -23,9 +23,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <cmath> #include <cmath>
#include <vector> #include <vector>
typedef std::pair<unsigned, unsigned> BresenhamPixel; typedef std::pair<unsigned, unsigned> BresenhamPixel;
inline void Bresenham (int x0, int y0, int x1, int y1, std::vector<BresenhamPixel> &resultList) { inline void Bresenham (int x0, int y0, const int x1, int const y1, std::vector<BresenhamPixel> &resultList) {
int dx = std::abs(x1-x0); int dx = std::abs(x1-x0);
int dy = std::abs(y1-y0); int dy = std::abs(y1-y0);
int sx = (x0 < x1 ? 1 : -1); int sx = (x0 < x1 ? 1 : -1);
+2 -2
View File
@@ -62,10 +62,10 @@ CRC32::CRC32CFunctionPtr CRC32::detectBestCRC32C() {
unsigned ecx = cpuid(1); unsigned ecx = cpuid(1);
bool hasSSE42 = ecx & (1 << SSE42_BIT); bool hasSSE42 = ecx & (1 << SSE42_BIT);
if (hasSSE42) { if (hasSSE42) {
std::cout << "using hardware base sse computation" << std::endl; SimpleLogger().Write() << "using hardware base sse computation";
return &CRC32::SSEBasedCRC32; //crc32 hardware accelarated; return &CRC32::SSEBasedCRC32; //crc32 hardware accelarated;
} else { } else {
std::cout << "using software base sse computation" << std::endl; SimpleLogger().Write() << "using software base sse computation";
return &CRC32::SoftwareBasedCRC32; //crc32cSlicingBy8; return &CRC32::SoftwareBasedCRC32; //crc32cSlicingBy8;
} }
} }
+2
View File
@@ -21,6 +21,8 @@
#ifndef CRC32_H_ #ifndef CRC32_H_
#define CRC32_H_ #define CRC32_H_
#include "../Util/SimpleLogger.h"
#include <boost/crc.hpp> // for boost::crc_32_type #include <boost/crc.hpp> // for boost::crc_32_type
#include <iostream> #include <iostream>
+3 -2
View File
@@ -21,12 +21,13 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef DOUGLASPEUCKER_H_ #ifndef DOUGLASPEUCKER_H_
#define DOUGLASPEUCKER_H_ #define DOUGLASPEUCKER_H_
#include "../DataStructures/Coordinate.h"
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#include <cfloat> #include <cfloat>
#include <stack> #include <stack>
#include <vector>
#include "../DataStructures/Coordinate.h"
/*This class object computes the bitvector of indicating generalized input points /*This class object computes the bitvector of indicating generalized input points
* according to the (Ramer-)Douglas-Peucker algorithm. * according to the (Ramer-)Douglas-Peucker algorithm.
+5 -3
View File
@@ -22,6 +22,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef ITERATORBASEDCRC32_H_ #ifndef ITERATORBASEDCRC32_H_
#define ITERATORBASEDCRC32_H_ #define ITERATORBASEDCRC32_H_
#include "../Util/SimpleLogger.h"
#include <boost/crc.hpp> // for boost::crc_32_type #include <boost/crc.hpp> // for boost::crc_32_type
#include <iostream> #include <iostream>
@@ -80,10 +82,10 @@ private:
unsigned ecx = cpuid(1); unsigned ecx = cpuid(1);
bool hasSSE42 = ecx & (1 << SSE42_BIT); bool hasSSE42 = ecx & (1 << SSE42_BIT);
if (hasSSE42) { if (hasSSE42) {
std::cout << "using hardware base sse computation" << std::endl; SimpleLogger().Write() << "using hardware based CRC32 computation";
return &IteratorbasedCRC32::SSEBasedCRC32; //crc32 hardware accelarated; return &IteratorbasedCRC32::SSEBasedCRC32; //crc32 hardware accelarated;
} else { } else {
std::cout << "using software base sse computation" << std::endl; SimpleLogger().Write() << "using software based CRC32 computation";
return &IteratorbasedCRC32::SoftwareBasedCRC32; //crc32cSlicingBy8; return &IteratorbasedCRC32::SoftwareBasedCRC32; //crc32cSlicingBy8;
} }
} }
@@ -93,7 +95,7 @@ public:
crcFunction = detectBestCRC32C(); crcFunction = detectBestCRC32C();
} }
virtual ~IteratorbasedCRC32() {}; virtual ~IteratorbasedCRC32() { }
unsigned operator()( ContainerT_iterator iter, const ContainerT_iterator end) { unsigned operator()( ContainerT_iterator iter, const ContainerT_iterator end) {
unsigned crc = 0; unsigned crc = 0;
+44 -18
View File
@@ -21,6 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef OBJECTTOBASE64_H_ #ifndef OBJECTTOBASE64_H_
#define OBJECTTOBASE64_H_ #define OBJECTTOBASE64_H_
#include "../Util/StringUtil.h"
#include <boost/assert.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp> #include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp> #include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp> #include <boost/archive/iterators/transform_width.hpp>
@@ -28,40 +31,63 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <algorithm> #include <algorithm>
#include <string> #include <string>
#include <vector>
#include "../Util/StringUtil.h"
typedef typedef
boost::archive::iterators::base64_from_binary< boost::archive::iterators::base64_from_binary<
boost::archive::iterators::transform_width<std::string::const_iterator, 6, 8> boost::archive::iterators::transform_width<const char *, 6, 8>
> base64_t; > base64_t;
typedef typedef
boost::archive::iterators::transform_width< boost::archive::iterators::transform_width<
boost::archive::iterators::binary_from_base64<std::string::const_iterator>, 8, 6 boost::archive::iterators::binary_from_base64<
std::string::const_iterator>, 8, 6
> binary_t; > binary_t;
template<class ToEncodeT> template<class ObjectT>
static void EncodeObjectToBase64(const ToEncodeT & object, std::string& encoded) { static void EncodeObjectToBase64(const ObjectT & object, std::string& encoded) {
encoded.clear(); const char * char_ptr_to_object = (const char *)&object;
char * pointerToOriginalObject = (char *)&object; std::vector<unsigned char> data(sizeof(object));
encoded = std::string(base64_t(pointerToOriginalObject), base64_t(pointerToOriginalObject+sizeof(ToEncodeT))); std::copy(
//replace "+" with "-" and "/" with "_" char_ptr_to_object,
char_ptr_to_object + sizeof(ObjectT),
data.begin()
);
unsigned char number_of_padded_chars = 0; // is in {0,1,2};
while(data.size() % 3 != 0) {
++number_of_padded_chars;
data.push_back(0x00);
}
BOOST_ASSERT_MSG(
0 == data.size() % 3,
"base64 input data size is not a multiple of 3!"
);
encoded.resize(sizeof(ObjectT));
encoded.assign(
base64_t( &data[0] ),
base64_t( &data[0] + (data.size() - number_of_padded_chars) )
);
replaceAll(encoded, "+", "-"); replaceAll(encoded, "+", "-");
replaceAll(encoded, "/", "_"); replaceAll(encoded, "/", "_");
} }
template<class ToEncodeT> template<class ObjectT>
static void DecodeObjectFromBase64(ToEncodeT & object, const std::string& _encoded) { static void DecodeObjectFromBase64(const std::string& input, ObjectT & object) {
try { try {
std::string encoded(_encoded); std::string encoded(input);
//replace "-" with "+" and "_" with "/" //replace "-" with "+" and "_" with "/"
replaceAll(encoded, "-", "+"); replaceAll(encoded, "-", "+");
replaceAll(encoded, "_", "/"); replaceAll(encoded, "_", "/");
char * pointerToDecodedObject = (char *)&object;
std::string dec(binary_t(encoded.begin()), binary_t(encoded.begin() + encoded.length() - 1)); std::copy (
std::copy ( dec.begin(), dec.end(), pointerToDecodedObject ); binary_t( encoded.begin() ),
} catch(...) {} binary_t( encoded.begin() + encoded.length() - 1),
(char *)&object
);
} catch(...) { }
} }
#endif /* OBJECTTOBASE64_H_ */ #endif /* OBJECTTOBASE64_H_ */
+9 -7
View File
@@ -21,12 +21,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef POLYLINECOMPRESSOR_H_ #ifndef POLYLINECOMPRESSOR_H_
#define POLYLINECOMPRESSOR_H_ #define POLYLINECOMPRESSOR_H_
#include <string>
//#include "../DataStructures/ExtractorStructs.h"
#include "../DataStructures/SegmentInformation.h" #include "../DataStructures/SegmentInformation.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <string>
class PolylineCompressor { class PolylineCompressor {
private: private:
inline void encodeVectorSignedNumber(std::vector<int> & numbers, std::string & output) const { inline void encodeVectorSignedNumber(std::vector<int> & numbers, std::string & output) const {
@@ -57,11 +56,14 @@ private:
} }
public: public:
inline void printEncodedString(const std::vector<SegmentInformation>& polyline, std::string &output) const { inline void printEncodedString(
const std::vector<SegmentInformation> & polyline,
std::string & output
) const {
std::vector<int> deltaNumbers; std::vector<int> deltaNumbers;
output += "\""; output += "\"";
if(!polyline.empty()) { if(!polyline.empty()) {
_Coordinate lastCoordinate = polyline[0].location; FixedPointCoordinate lastCoordinate = polyline[0].location;
deltaNumbers.push_back( lastCoordinate.lat ); deltaNumbers.push_back( lastCoordinate.lat );
deltaNumbers.push_back( lastCoordinate.lon ); deltaNumbers.push_back( lastCoordinate.lon );
for(unsigned i = 1; i < polyline.size(); ++i) { for(unsigned i = 1; i < polyline.size(); ++i) {
@@ -77,7 +79,7 @@ public:
} }
inline void printEncodedString(const std::vector<_Coordinate>& polyline, std::string &output) const { inline void printEncodedString(const std::vector<FixedPointCoordinate>& polyline, std::string &output) const {
std::vector<int> deltaNumbers(2*polyline.size()); std::vector<int> deltaNumbers(2*polyline.size());
output += "\""; output += "\"";
if(!polyline.empty()) { if(!polyline.empty()) {
@@ -92,7 +94,7 @@ public:
output += "\""; output += "\"";
} }
inline void printUnencodedString(std::vector<_Coordinate> & polyline, std::string & output) const { inline void printUnencodedString(std::vector<FixedPointCoordinate> & polyline, std::string & output) const {
output += "["; output += "[";
std::string tmp; std::string tmp;
for(unsigned i = 0; i < polyline.size(); i++) { for(unsigned i = 0; i < polyline.size(); i++) {
+122 -76
View File
@@ -16,38 +16,53 @@ You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
Strongly connected components using Tarjan's Algorithm
*/ */
#ifndef STRONGLYCONNECTEDCOMPONENTS_H_ #ifndef STRONGLYCONNECTEDCOMPONENTS_H_
#define STRONGLYCONNECTEDCOMPONENTS_H_ #define STRONGLYCONNECTEDCOMPONENTS_H_
#include <cassert> #include "../DataStructures/Coordinate.h"
#include <stack>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/make_shared.hpp>
#include <boost/unordered_map.hpp>
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#include "../DataStructures/DeallocatingVector.h" #include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h" #include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/ImportEdge.h" #include "../DataStructures/ImportEdge.h"
#include "../DataStructures/NodeCoords.h" #include "../DataStructures/QueryNode.h"
#include "../DataStructures/Percent.h" #include "../DataStructures/Percent.h"
#include "../DataStructures/Restriction.h" #include "../DataStructures/Restriction.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
// Strongly connected components using Tarjan's Algorithm #include "../Util/SimpleLogger.h"
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/integer.hpp>
#include <boost/make_shared.hpp>
#include <boost/unordered_map.hpp>
#ifdef __APPLE__
#include <gdal.h>
#include <ogrsf_frmts.h>
#else
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#endif
#include <cassert>
#include <stack>
#include <vector>
class TarjanSCC { class TarjanSCC {
private: private:
struct _NodeBasedEdgeData {
struct TarjanNode {
TarjanNode() : index(UINT_MAX), lowlink(UINT_MAX), onStack(false) {}
unsigned index;
unsigned lowlink;
bool onStack;
};
struct TarjanEdgeData {
int distance; int distance;
unsigned edgeBasedNodeID; unsigned edgeBasedNodeID;
unsigned nameID:31; unsigned nameID:31;
@@ -58,25 +73,31 @@ private:
bool backward:1; bool backward:1;
bool roundabout:1; bool roundabout:1;
bool ignoreInGrid:1; bool ignoreInGrid:1;
bool reversedEdge:1;
}; };
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph; struct TarjanStackFrame {
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge; explicit TarjanStackFrame(NodeID _v, NodeID p) : v(_v), parent(p) {}
std::vector<NodeInfo> inputNodeInfoList; NodeID v;
unsigned numberOfTurnRestrictions; NodeID parent;
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph; };
boost::unordered_map<NodeID, bool> _barrierNodes;
boost::unordered_map<NodeID, bool> _trafficLights;
typedef DynamicGraph<TarjanEdgeData> TarjanDynamicGraph;
typedef TarjanDynamicGraph::InputEdge TarjanEdge;
typedef std::pair<NodeID, NodeID> RestrictionSource; typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::pair<NodeID, bool> RestrictionTarget; typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector; typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap; typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<NodeInfo> inputNodeInfoList;
unsigned numberOfTurnRestrictions;
boost::shared_ptr<TarjanDynamicGraph> _nodeBasedGraph;
boost::unordered_map<NodeID, bool> _barrierNodes;
boost::unordered_map<NodeID, bool> _trafficLights;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector; std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
RestrictionMap _restrictionMap; RestrictionMap _restrictionMap;
public:
struct EdgeBasedNode { struct EdgeBasedNode {
bool operator<(const EdgeBasedNode & other) const { bool operator<(const EdgeBasedNode & other) const {
return other.id < id; return other.id < id;
@@ -95,25 +116,23 @@ public:
bool ignoreInGrid:1; bool ignoreInGrid:1;
}; };
private:
DeallocatingVector<EdgeBasedNode> edgeBasedNodes; DeallocatingVector<EdgeBasedNode> edgeBasedNodes;
struct TarjanNode {
TarjanNode() : index(UINT_MAX), lowlink(UINT_MAX), onStack(false) {}
unsigned index;
unsigned lowlink;
bool onStack;
};
struct TarjanStackFrame {
explicit TarjanStackFrame(NodeID _v, NodeID p) : v(_v), parent(p) {}
NodeID v;
NodeID parent;
};
public: public:
TarjanSCC(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeID> & bn, std::vector<NodeID> & tl, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI) : inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) { TarjanSCC(
BOOST_FOREACH(_Restriction & restriction, irs) { int nodes,
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode); std::vector<NodeBasedEdge> & inputEdges,
std::vector<NodeID> & bn,
std::vector<NodeID> & tl,
std::vector<TurnRestriction> & irs,
std::vector<NodeInfo> & nI
) :
inputNodeInfoList(nI),
numberOfTurnRestrictions(irs.size())
{
BOOST_FOREACH(const TurnRestriction & restriction, irs) {
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(
restriction.fromNode, restriction.viaNode
);
unsigned index; unsigned index;
RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource);
if(restrIter == _restrictionMap.end()) { if(restrIter == _restrictionMap.end()) {
@@ -131,7 +150,9 @@ public:
} }
} }
_restrictionBucketVector.at(index).push_back(std::make_pair(restriction.toNode, restriction.flags.isOnly)); _restrictionBucketVector.at(index).push_back(
std::make_pair(restriction.toNode, restriction.flags.isOnly)
);
} }
BOOST_FOREACH(NodeID id, bn) { BOOST_FOREACH(NodeID id, bn) {
@@ -141,10 +162,10 @@ public:
_trafficLights[id] = true; _trafficLights[id] = true;
} }
DeallocatingVector< _NodeBasedEdge > edges; DeallocatingVector< TarjanEdge > edges;
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) { for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) {
_NodeBasedEdge edge; TarjanEdge edge;
if(!i->isForward()) { if(!i->isForward()) {
edge.source = i->target(); edge.source = i->target();
edge.target = i->source(); edge.target = i->source();
@@ -168,21 +189,28 @@ public:
edge.data.type = i->type(); edge.data.type = i->type();
edge.data.isAccessRestricted = i->isAccessRestricted(); edge.data.isAccessRestricted = i->isAccessRestricted();
edge.data.edgeBasedNodeID = edges.size(); edge.data.edgeBasedNodeID = edges.size();
edge.data.reversedEdge = false;
edges.push_back( edge ); edges.push_back( edge );
if( edge.data.backward ) { if( edge.data.backward ) {
std::swap( edge.source, edge.target ); std::swap( edge.source, edge.target );
edge.data.forward = i->isBackward(); edge.data.forward = i->isBackward();
edge.data.backward = i->isForward(); edge.data.backward = i->isForward();
edge.data.edgeBasedNodeID = edges.size(); edge.data.edgeBasedNodeID = edges.size();
edge.data.reversedEdge = true;
edges.push_back( edge ); edges.push_back( edge );
} }
} }
std::vector<NodeBasedEdge>().swap(inputEdges); std::vector<NodeBasedEdge>().swap(inputEdges);
std::sort( edges.begin(), edges.end() ); std::sort( edges.begin(), edges.end() );
_nodeBasedGraph = boost::make_shared<_NodeBasedDynamicGraph>( nodes, edges ); _nodeBasedGraph = boost::make_shared<TarjanDynamicGraph>( nodes, edges );
} }
void Run() { void Run() {
//remove files from previous run if exist
DeleteFileIfExists("component.dbf");
DeleteFileIfExists("component.shx");
DeleteFileIfExists("component.shp");
Percent p(_nodeBasedGraph->GetNumberOfNodes()); Percent p(_nodeBasedGraph->GetNumberOfNodes());
const char *pszDriverName = "ESRI Shapefile"; const char *pszDriverName = "ESRI Shapefile";
@@ -231,7 +259,7 @@ public:
bool beforeRecursion = recursionStack.top().first; bool beforeRecursion = recursionStack.top().first;
TarjanStackFrame currentFrame = recursionStack.top().second; TarjanStackFrame currentFrame = recursionStack.top().second;
NodeID v = currentFrame.v; NodeID v = currentFrame.v;
// INFO("popping node " << v << (beforeRecursion ? " before " : " after ") << "recursion"); // SimpleLogger().Write() << "popping node " << v << (beforeRecursion ? " before " : " after ") << "recursion";
recursionStack.pop(); recursionStack.pop();
if(beforeRecursion) { if(beforeRecursion) {
@@ -244,45 +272,45 @@ public:
tarjanStack.push(v); tarjanStack.push(v);
tarjanNodes[v].onStack = true; tarjanNodes[v].onStack = true;
++index; ++index;
// INFO("pushing " << v << " onto tarjan stack, idx[" << v << "]=" << tarjanNodes[v].index << ", lowlink["<< v << "]=" << tarjanNodes[v].lowlink); // SimpleLogger().Write() << "pushing " << v << " onto tarjan stack, idx[" << v << "]=" << tarjanNodes[v].index << ", lowlink["<< v << "]=" << tarjanNodes[v].lowlink;
//Traverse outgoing edges //Traverse outgoing edges
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { for(TarjanDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) {
_NodeBasedDynamicGraph::NodeIterator vprime = _nodeBasedGraph->GetTarget(e2); TarjanDynamicGraph::NodeIterator vprime = _nodeBasedGraph->GetTarget(e2);
// INFO("traversing edge (" << v << "," << vprime << ")"); // SimpleLogger().Write() << "traversing edge (" << v << "," << vprime << ")";
if(UINT_MAX == tarjanNodes[vprime].index) { if(UINT_MAX == tarjanNodes[vprime].index) {
recursionStack.push(std::make_pair(true,TarjanStackFrame(vprime, v))); recursionStack.push(std::make_pair(true,TarjanStackFrame(vprime, v)));
} else { } else {
// INFO("Node " << vprime << " is already explored"); // SimpleLogger().Write() << "Node " << vprime << " is already explored";
if(tarjanNodes[vprime].onStack) { if(tarjanNodes[vprime].onStack) {
unsigned newLowlink = std::min(tarjanNodes[v].lowlink, tarjanNodes[vprime].index); unsigned newLowlink = std::min(tarjanNodes[v].lowlink, tarjanNodes[vprime].index);
// INFO("Setting lowlink[" << v << "] from " << tarjanNodes[v].lowlink << " to " << newLowlink); // SimpleLogger().Write() << "Setting lowlink[" << v << "] from " << tarjanNodes[v].lowlink << " to " << newLowlink;
tarjanNodes[v].lowlink = newLowlink; tarjanNodes[v].lowlink = newLowlink;
// } else { // } else {
// INFO("But node " << vprime << " is not on stack"); // SimpleLogger().Write() << "But node " << vprime << " is not on stack";
} }
} }
} }
} else { } else {
// INFO("we are at the end of recursion and checking node " << v); // SimpleLogger().Write() << "we are at the end of recursion and checking node " << v;
{ // setting lowlink in its own scope so it does not pollute namespace { // setting lowlink in its own scope so it does not pollute namespace
// NodeID parent = (UINT_MAX == tarjanNodes[v].parent ? v : tarjanNodes[v].parent ); // NodeID parent = (UINT_MAX == tarjanNodes[v].parent ? v : tarjanNodes[v].parent );
// INFO("parent=" << currentFrame.parent); // SimpleLogger().Write() << "parent=" << currentFrame.parent;
// INFO("tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << currentFrame.parent << "].lowlink=" << tarjanNodes[currentFrame.parent].lowlink); // SimpleLogger().Write() << "tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << currentFrame.parent << "].lowlink=" << tarjanNodes[currentFrame.parent].lowlink;
//Note the index shift by 1 compared to the recursive version //Note the index shift by 1 compared to the recursive version
tarjanNodes[currentFrame.parent].lowlink = std::min(tarjanNodes[currentFrame.parent].lowlink, tarjanNodes[v].lowlink); tarjanNodes[currentFrame.parent].lowlink = std::min(tarjanNodes[currentFrame.parent].lowlink, tarjanNodes[v].lowlink);
// INFO("Setting tarjanNodes[" << currentFrame.parent <<"].lowlink=" << tarjanNodes[currentFrame.parent].lowlink); // SimpleLogger().Write() << "Setting tarjanNodes[" << currentFrame.parent <<"].lowlink=" << tarjanNodes[currentFrame.parent].lowlink;
} }
// INFO("tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << v << "].index=" << tarjanNodes[v].index); // SimpleLogger().Write() << "tarjanNodes[" << v << "].lowlink=" << tarjanNodes[v].lowlink << ", tarjanNodes[" << v << "].index=" << tarjanNodes[v].index;
//after recursion, lets do cycle checking //after recursion, lets do cycle checking
//Check if we found a cycle. This is the bottom part of the recursion //Check if we found a cycle. This is the bottom part of the recursion
if(tarjanNodes[v].lowlink == tarjanNodes[v].index) { if(tarjanNodes[v].lowlink == tarjanNodes[v].index) {
NodeID vprime; NodeID vprime;
do { do {
// INFO("identified component " << currentComponent << ": " << tarjanStack.top()); // SimpleLogger().Write() << "identified component " << currentComponent << ": " << tarjanStack.top();
vprime = tarjanStack.top(); tarjanStack.pop(); vprime = tarjanStack.top(); tarjanStack.pop();
tarjanNodes[vprime].onStack = false; tarjanNodes[vprime].onStack = false;
componentsIndex[vprime] = currentComponent; componentsIndex[vprime] = currentComponent;
@@ -290,7 +318,7 @@ public:
} while( v != vprime); } while( v != vprime);
vectorOfComponentSizes.push_back(sizeOfCurrentComponent); vectorOfComponentSizes.push_back(sizeOfCurrentComponent);
if(sizeOfCurrentComponent > 1000) if(sizeOfCurrentComponent > 1000)
INFO("large component [" << currentComponent << "]=" << sizeOfCurrentComponent); SimpleLogger().Write() << "large component [" << currentComponent << "]=" << sizeOfCurrentComponent;
++currentComponent; ++currentComponent;
sizeOfCurrentComponent = 0; sizeOfCurrentComponent = 0;
} }
@@ -298,38 +326,50 @@ public:
} }
} }
INFO("identified: " << vectorOfComponentSizes.size() << " many components, marking small components"); SimpleLogger().Write() << "identified: " << vectorOfComponentSizes.size() << " many components, marking small components";
int singleCounter = 0; int singleCounter = 0;
for(unsigned i = 0; i < vectorOfComponentSizes.size(); ++i){ for(unsigned i = 0; i < vectorOfComponentSizes.size(); ++i){
if(1 == vectorOfComponentSizes[i]) if(1 == vectorOfComponentSizes[i])
++singleCounter; ++singleCounter;
} }
INFO("identified " << singleCounter << " SCCs of size 1"); SimpleLogger().Write() << "identified " << singleCounter << " SCCs of size 1";
uint64_t total_network_distance = 0;
p.reinit(_nodeBasedGraph->GetNumberOfNodes()); p.reinit(_nodeBasedGraph->GetNumberOfNodes());
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { for(TarjanDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) {
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) { p.printIncrement();
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1); for(TarjanDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) {
if(_nodeBasedGraph->GetEdgeData(e1).reversedEdge) {
continue;
}
TarjanDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1);
total_network_distance += 100*ApproximateDistance(
inputNodeInfoList[u].lat,
inputNodeInfoList[u].lon,
inputNodeInfoList[v].lat,
inputNodeInfoList[v].lon
);
if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) { if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) {
assert(e1 != UINT_MAX); assert(e1 != UINT_MAX);
assert(u != UINT_MAX); assert(u != UINT_MAX);
assert(v != UINT_MAX); assert(v != UINT_MAX);
//edges that end on bollard nodes may actually be in two distinct components //edges that end on bollard nodes may actually be in two distinct components
if(std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 10) { if(std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 10) {
//INFO("(" << inputNodeInfoList[u].lat/100000. << ";" << inputNodeInfoList[u].lon/100000. << ") -> (" << inputNodeInfoList[v].lat/100000. << ";" << inputNodeInfoList[v].lon/100000. << ")"); //INFO("(" << inputNodeInfoList[u].lat/COORDINATE_PRECISION << ";" << inputNodeInfoList[u].lon/COORDINATE_PRECISION << ") -> (" << inputNodeInfoList[v].lat/COORDINATE_PRECISION << ";" << inputNodeInfoList[v].lon/COORDINATE_PRECISION << ")");
OGRLineString lineString; OGRLineString lineString;
lineString.addPoint(inputNodeInfoList[u].lon/100000., inputNodeInfoList[u].lat/100000.); lineString.addPoint(inputNodeInfoList[u].lon/COORDINATE_PRECISION, inputNodeInfoList[u].lat/COORDINATE_PRECISION);
lineString.addPoint(inputNodeInfoList[v].lon/100000., inputNodeInfoList[v].lat/100000.); lineString.addPoint(inputNodeInfoList[v].lon/COORDINATE_PRECISION, inputNodeInfoList[v].lat/COORDINATE_PRECISION);
OGRFeature *poFeature; OGRFeature *poFeature;
poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() ); poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
poFeature->SetGeometry( &lineString ); poFeature->SetGeometry( &lineString );
if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE ) if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE ) {
{ throw OSRMException(
ERR( "Failed to create feature in shapefile.\n" ); "Failed to create feature in shapefile."
);
} }
OGRFeature::DestroyFeature( poFeature ); OGRFeature::DestroyFeature( poFeature );
} }
@@ -339,7 +379,7 @@ public:
OGRDataSource::DestroyDataSource( poDS ); OGRDataSource::DestroyDataSource( poDS );
std::vector<NodeID>().swap(vectorOfComponentSizes); std::vector<NodeID>().swap(vectorOfComponentSizes);
std::vector<NodeID>().swap(componentsIndex); std::vector<NodeID>().swap(componentsIndex);
SimpleLogger().Write() << "total network distance: " << (uint64_t)total_network_distance/100/1000. << " km";
} }
private: private:
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const { unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const {
@@ -368,6 +408,12 @@ private:
} }
return false; return false;
} }
void DeleteFileIfExists(const std::string file_name) const {
if (boost::filesystem::exists(file_name) ) {
boost::filesystem::remove(file_name);
}
}
}; };
#endif /* STRONGLYCONNECTEDCOMPONENTS_H_ */ #endif /* STRONGLYCONNECTEDCOMPONENTS_H_ */
+67 -18
View File
@@ -1,32 +1,63 @@
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
project(OSRM) project(OSRM)
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
TRY_RUN(SHARED_LIBRARY_PATH_TYPE SHARED_LIBRARY_PATH_INFO_COMPILED ${PROJECT_BINARY_DIR}/CMakeTmp ${PROJECT_SOURCE_DIR}/cmake/size.cpp OUTPUT_VARIABLE IS_64_SYSTEM)
if(IS_64_SYSTEM)
message(STATUS "System supports 64 bits.")
set( HAS64BITS 1 )
else(IS_64_SYSTEM)
MESSAGE(WARNING "Compiling on a 32 bit system is unsupported!")
set( HAS64BITS 0 )
endif(IS_64_SYSTEM)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/UUID.cpp UUID.cpp.alwaysbuild
COMMAND ${CMAKE_COMMAND} -P
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
DEPENDS
${CMAKE_SOURCE_DIR}/Util/UUID.cpp.in
${CMAKE_SOURCE_DIR}/cmake/UUID-Config.cmake
COMMENT "Configuring UUID.cpp"
VERBATIM)
add_custom_target(UUIDConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/UUID.cpp )
set(BOOST_COMPONENTS filesystem regex system thread) set(BOOST_COMPONENTS filesystem regex system thread)
file(GLOB ExtractorGlob Extractor/*.cpp) file(GLOB ExtractorGlob Extractor/*.cpp)
set(ExtractorSources extractor.cpp ${ExtractorGlob}) set(ExtractorSources extractor.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources}) add_executable(osrm-extract ${ExtractorSources} )
file(GLOB PrepareGlob Contractor/*.cpp) file(GLOB PrepareGlob Contractor/*.cpp)
set(PrepareSources createHierarchy.cpp ${PrepareGlob}) set(PrepareSources createHierarchy.cpp ${PrepareGlob})
add_executable(osrm-prepare ${PrepareSources}) add_executable(osrm-prepare ${PrepareSources} )
file(GLOB RoutedGlob Server/DataStructures/*.cpp Descriptors/*.cpp DataStructures/SearchEngine*.cpp) add_executable(osrm-routed routed.cpp )
set(RoutedSources routed.cpp ${RoutedGlob})
add_executable(osrm-routed ${RoutedSources})
set_target_properties(osrm-routed PROPERTIES COMPILE_FLAGS -DROUTED) set_target_properties(osrm-routed PROPERTIES COMPILE_FLAGS -DROUTED)
file(GLOB DescriptorGlob Descriptors/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp)
file(GLOB SearchEngineSource DataStructures/SearchEngine*.cpp)
file(GLOB ServerStructureGlob Server/DataStructures/*.cpp)
set(OSRMSources ${LibOSRMGlob} ${DescriptorGlob} ${SearchEngineSource} ${ServerStructureGlob})
add_library(OSRM SHARED ${OSRMSources})
add_library(UUID STATIC Util/UUID.cpp)
add_dependencies( UUID UUIDConfigure )
# Check the release mode # Check the release mode
if(NOT CMAKE_BUILD_TYPE MATCHES Debug) if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
endif(NOT CMAKE_BUILD_TYPE MATCHES Debug) endif(NOT CMAKE_BUILD_TYPE MATCHES Debug)
if(CMAKE_BUILD_TYPE MATCHES Debug) if(CMAKE_BUILD_TYPE MATCHES Debug)
message(STATUS "Configuring OSRM in debug mode") message(STATUS "Configuring OSRM in debug mode")
endif(CMAKE_BUILD_TYPE MATCHES Debug) endif(CMAKE_BUILD_TYPE MATCHES Debug)
if(CMAKE_BUILD_TYPE MATCHES Release) if(CMAKE_BUILD_TYPE MATCHES Release)
message(STATUS "Configuring OSRM in release mode") message(STATUS "Configuring OSRM in release mode")
endif(CMAKE_BUILD_TYPE MATCHES Release) endif(CMAKE_BUILD_TYPE MATCHES Release)
#Configuring compilers #Configuring compilers
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
@@ -35,7 +66,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
message(STATUS "OpenMP parallelization not available using clang++") message(STATUS "OpenMP parallelization not available using clang++")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC # using GCC
set(CMAKE_CXX_FLAGS "-Wall -fopenmp -pedantic") set(CMAKE_CXX_FLAGS "-Wall -fopenmp -pedantic")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
# using Intel C++ # using Intel C++
set(CMAKE_CXX_FLAGS "-static-intel -wd10237 -Wall -openmp -ipo") set(CMAKE_CXX_FLAGS "-static-intel -wd10237 -Wall -openmp -ipo")
@@ -55,25 +86,39 @@ if (NOT Boost_FOUND)
message(FATAL_ERROR "Fatal error: Boost (version >= 1.44.0) required.\n") message(FATAL_ERROR "Fatal error: Boost (version >= 1.44.0) required.\n")
endif (NOT Boost_FOUND) endif (NOT Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries( osrm-extract ${Boost_LIBRARIES} )
target_link_libraries( osrm-prepare ${Boost_LIBRARIES} ) IF( APPLE )
target_link_libraries( osrm-routed ${Boost_LIBRARIES} ) target_link_libraries( OSRM ${Boost_LIBRARIES} UUID )
ELSE( APPLE )
target_link_libraries( OSRM ${Boost_LIBRARIES} )
ENDIF( APPLE )
target_link_libraries( osrm-extract ${Boost_LIBRARIES} UUID )
target_link_libraries( osrm-prepare ${Boost_LIBRARIES} UUID )
target_link_libraries( osrm-routed ${Boost_LIBRARIES} OSRM UUID )
find_package ( BZip2 REQUIRED ) find_package ( BZip2 REQUIRED )
include_directories(${BZIP_INCLUDE_DIRS}) include_directories(${BZIP_INCLUDE_DIRS})
target_link_libraries (osrm-extract ${BZIP2_LIBRARIES}) target_link_libraries (osrm-extract ${BZIP2_LIBRARIES})
find_package( ZLIB REQUIRED ) find_package( ZLIB REQUIRED )
include_directories(${ZLIB_INCLUDE_DIRS})
target_link_libraries (osrm-extract ${ZLIB_LIBRARY}) target_link_libraries (osrm-extract ${ZLIB_LIBRARY})
target_link_libraries (osrm-routed ${ZLIB_LIBRARY}) target_link_libraries (osrm-routed ${ZLIB_LIBRARY})
find_package( Threads REQUIRED ) find_package( Threads REQUIRED )
target_link_libraries (osrm-extract ${Threads_LIBRARY}) target_link_libraries (osrm-extract ${Threads_LIBRARY})
find_package( Lua51 REQUIRED ) find_package( LuaJIT )
include_directories(${LUA_INCLUDE_DIR}) IF( NOT APPLE AND LUAJIT_INCLUDE_DIR AND LUAJIT_LIBRARIES)
target_link_libraries( osrm-extract ${LUA_LIBRARY} ) include_directories(${LUAJIT_INCLUDE_DIR})
target_link_libraries( osrm-prepare ${LUA_LIBRARY} ) target_link_libraries( osrm-extract ${LUAJIT_LIBRARIES} )
target_link_libraries( osrm-prepare ${LUAJIT_LIBRARIES} )
ELSE( LUAJIT_INCLUDE_DIR )
find_package( Lua51 REQUIRED AND LUAJIT_LIBRARIES )
include_directories(${LUA_INCLUDE_DIR})
target_link_libraries( osrm-extract ${LUA_LIBRARY} )
target_link_libraries( osrm-prepare ${LUA_LIBRARY} )
ENDIF( NOT APPLE AND LUAJIT_INCLUDE_DIR AND LUAJIT_LIBRARIES )
find_package( LibXml2 REQUIRED ) find_package( LibXml2 REQUIRED )
include_directories(${LIBXML2_INCLUDE_DIR}) include_directories(${LIBXML2_INCLUDE_DIR})
@@ -91,6 +136,7 @@ target_link_libraries (osrm-prepare ${PROTOBUF_LIBRARY})
find_package( STXXL REQUIRED ) find_package( STXXL REQUIRED )
include_directories(${STXXL_INCLUDE_DIR}) include_directories(${STXXL_INCLUDE_DIR})
target_link_libraries (OSRM ${STXXL_LIBRARY})
target_link_libraries (osrm-extract ${STXXL_LIBRARY}) target_link_libraries (osrm-extract ${STXXL_LIBRARY})
target_link_libraries (osrm-prepare ${STXXL_LIBRARY}) target_link_libraries (osrm-prepare ${STXXL_LIBRARY})
@@ -105,7 +151,10 @@ if(WITH_TOOLS)
if(GDAL_FOUND) if(GDAL_FOUND)
add_executable(osrm-components Tools/componentAnalysis.cpp) add_executable(osrm-components Tools/componentAnalysis.cpp)
include_directories(${GDAL_INCLUDE_DIR}) include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries( osrm-components ${GDAL_LIBRARIES} ) target_link_libraries(
target_link_libraries( osrm-components ${Boost_LIBRARIES} ) osrm-components ${GDAL_LIBRARIES} ${Boost_LIBRARIES} UUID
)
endif(GDAL_FOUND) endif(GDAL_FOUND)
add_executable ( osrm-cli Tools/simpleclient.cpp )
target_link_libraries( osrm-cli ${Boost_LIBRARIES} OSRM UUID )
endif(WITH_TOOLS) endif(WITH_TOOLS)
-261
View File
@@ -1,261 +0,0 @@
/*
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 CONTRACTIONCLEANUP_H_INCLUDED
#define CONTRACTIONCLEANUP_H_INCLUDED
#include <algorithm>
#ifndef _WIN32
#include <sys/time.h>
#endif
#include "Contractor.h"
class ContractionCleanup {
private:
struct _CleanupHeapData {
NodeID parent;
_CleanupHeapData( NodeID p ) {
parent = p;
}
};
typedef BinaryHeap< NodeID, NodeID, int, _CleanupHeapData > _Heap;
struct _ThreadData {
_Heap* _heapForward;
_Heap* _heapBackward;
_ThreadData( NodeID nodes ) {
_heapBackward = new _Heap(nodes);
_heapForward = new _Heap(nodes);
}
~_ThreadData() {
delete _heapBackward;
delete _heapForward;
}
};
public:
struct Edge {
NodeID source;
NodeID target;
struct EdgeData {
NodeID via;
unsigned nameID;
int distance;
TurnInstruction turnInstruction;
bool shortcut:1;
bool forward:1;
bool backward:1;
} data;
bool operator<( const Edge& right ) const {
if ( source != right.source )
return source < right.source;
return target < right.target;
}
//sorts by source and other attributes
static bool CompareBySource( const Edge& left, const Edge& right ) {
if ( left.source != right.source )
return left.source < right.source;
int l = ( left.data.forward ? -1 : 0 ) + ( left.data.backward ? -1 : 0 );
int r = ( right.data.forward ? -1 : 0 ) + ( right.data.backward ? -1 : 0 );
if ( l != r )
return l < r;
if ( left.target != right.target )
return left.target < right.target;
return left.data.distance < right.data.distance;
}
bool operator== ( const Edge& right ) const {
return ( source == right.source && target == right.target && data.distance == right.data.distance &&
data.shortcut == right.data.shortcut && data.forward == right.data.forward && data.backward == right.data.backward
&& data.via == right.data.via && data.nameID == right.data.nameID
);
}
};
ContractionCleanup( int numNodes, const std::vector< Edge >& edges ) {
_graph = edges;
_numNodes = numNodes;
}
~ContractionCleanup() {
}
void Run() {
RemoveUselessShortcuts();
}
template< class EdgeT >
void GetData( std::vector< EdgeT >& edges ) {
for ( int edge = 0, endEdges = ( int ) _graph.size(); edge != endEdges; ++edge ) {
if(_graph[edge].data.forward || _graph[edge].data.backward) {
EdgeT newEdge;
newEdge.source = _graph[edge].source;
newEdge.target = _graph[edge].target;
newEdge.data = _graph[edge].data;
edges.push_back( newEdge );
}
}
sort( edges.begin(), edges.end() );
}
private:
double _Timestamp() {
struct timeval tp;
gettimeofday(&tp, NULL);
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
}
void BuildOutgoingGraph() {
//sort edges by source
sort( _graph.begin(), _graph.end(), Edge::CompareBySource );
try {
_firstEdge.resize( _numNodes + 1 );
} catch(...) {
ERR("Not enough RAM on machine");
return;
}
_firstEdge[0] = 0;
for ( NodeID i = 0, node = 0; i < ( NodeID ) _graph.size(); i++ ) {
while ( _graph[i].source != node )
_firstEdge[++node] = i;
if ( i == ( NodeID ) _graph.size() - 1 )
while ( node < _numNodes )
_firstEdge[++node] = ( int ) _graph.size();
}
}
void RemoveUselessShortcuts() {
int maxThreads = omp_get_max_threads();
std::vector < _ThreadData* > threadData;
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
threadData.push_back( new _ThreadData( _numNodes ) );
}
INFO("Scanning for useless shortcuts");
BuildOutgoingGraph();
/*
#pragma omp parallel for
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
//only remove shortcuts
if ( !_graph[i].data.shortcut )
continue;
if ( _graph[i].data.forward ) {
int result = _ComputeDistance( _graph[i].source, _graph[i].target, threadData[omp_get_thread_num()] );
if ( result < _graph[i].data.distance ) {
_graph[i].data.forward = false;
}
}
if ( _graph[i].data.backward ) {
int result = _ComputeDistance( _graph[i].target, _graph[i].source, threadData[omp_get_thread_num()] );
if ( result < _graph[i].data.distance ) {
_graph[i].data.backward = false;
}
}
}
*/
INFO("Removing edges");
int useful = 0;
for ( int i = 0; i < ( int ) _graph.size(); i++ ) {
if ( !_graph[i].data.forward && !_graph[i].data.backward && _graph[i].data.shortcut ) {
continue;
}
_graph[useful] = _graph[i];
useful++;
}
INFO("Removed " << _graph.size() - useful << " useless shortcuts");
_graph.resize( useful );
for ( int threadNum = 0; threadNum < maxThreads; ++threadNum ) {
delete threadData[threadNum];
}
}
void _ComputeStep( _Heap* heapForward, _Heap* heapBackward, bool forwardDirection, NodeID* middle, int* targetDistance ) {
const NodeID node = heapForward->DeleteMin();
const int distance = heapForward->GetKey( node );
if ( distance > *targetDistance ) {
heapForward->DeleteAll();
return;
}
if ( heapBackward->WasInserted( node ) ) {
const int newDistance = heapBackward->GetKey( node ) + distance;
if ( newDistance < *targetDistance ) {
*middle = node;
*targetDistance = newDistance;
}
}
for ( int edge = _firstEdge[node], endEdges = _firstEdge[node + 1]; edge != endEdges; ++edge ) {
const NodeID to = _graph[edge].target;
const int edgeWeight = _graph[edge].data.distance;
assert( edgeWeight > 0 );
const int toDistance = distance + edgeWeight;
if ( (forwardDirection ? _graph[edge].data.forward : _graph[edge].data.backward ) ) {
//New Node discovered -> Add to Heap + Node Info Storage
if ( !heapForward->WasInserted( to ) )
heapForward->Insert( to, toDistance, node );
//Found a shorter Path -> Update distance
else if ( toDistance < heapForward->GetKey( to ) ) {
heapForward->DecreaseKey( to, toDistance );
//new parent
heapForward->GetData( to ) = node;
}
}
}
}
int _ComputeDistance( NodeID source, NodeID target, _ThreadData * data ) {
data->_heapForward->Clear();
data->_heapBackward->Clear();
//insert source into heap
data->_heapForward->Insert( source, 0, source );
data->_heapBackward->Insert( target, 0, target );
int targetDistance = std::numeric_limits< int >::max();
NodeID middle = std::numeric_limits<NodeID>::max();
while ( data->_heapForward->Size() + data->_heapBackward->Size() > 0 ) {
if ( data->_heapForward->Size() > 0 ) {
_ComputeStep( data->_heapForward, data->_heapBackward, true, &middle, &targetDistance );
}
if ( data->_heapBackward->Size() > 0 ) {
_ComputeStep( data->_heapBackward, data->_heapForward, false, &middle, &targetDistance );
}
}
return targetDistance;
}
NodeID _numNodes;
std::vector< Edge > _graph;
std::vector< unsigned > _firstEdge;
};
#endif // CONTRACTIONCLEANUP_H_INCLUDED
+10 -7
View File
@@ -29,6 +29,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/XORFastHash.h" #include "../DataStructures/XORFastHash.h"
#include "../DataStructures/XORFastHashStorage.h" #include "../DataStructures/XORFastHashStorage.h"
#include "../Util/OpenMPWrapper.h" #include "../Util/OpenMPWrapper.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
@@ -124,7 +125,8 @@ public:
BOOST_ASSERT_MSG( newEdge.data.distance > 0, "edge distance < 1" ); BOOST_ASSERT_MSG( newEdge.data.distance > 0, "edge distance < 1" );
#ifndef NDEBUG #ifndef NDEBUG
if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) { if ( newEdge.data.distance > 24 * 60 * 60 * 10 ) {
WARN("Edge weight large -> " << newEdge.data.distance); SimpleLogger().Write(logWARNING) <<
"Edge weight large -> " << newEdge.data.distance;
} }
#endif #endif
edges.push_back( newEdge ); edges.push_back( newEdge );
@@ -198,9 +200,9 @@ public:
// } // }
// } // }
// //
// INFO("edges at node with id " << highestNode << " has degree " << maxdegree); // SimpleLogger().Write() << "edges at node with id " << highestNode << " has degree " << maxdegree;
// for(unsigned i = _graph->BeginEdges(highestNode); i < _graph->EndEdges(highestNode); ++i) { // for(unsigned i = _graph->BeginEdges(highestNode); i < _graph->EndEdges(highestNode); ++i) {
// INFO(" ->(" << highestNode << "," << _graph->GetTarget(i) << "); via: " << _graph->GetEdgeData(i).via); // SimpleLogger().Write() << " ->(" << highestNode << "," << _graph->GetTarget(i) << "); via: " << _graph->GetEdgeData(i).via;
// } // }
//Create temporary file //Create temporary file
@@ -430,19 +432,20 @@ public:
// avgdegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() ); // avgdegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
// quaddegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() ); // quaddegree /= std::max((unsigned)1,(unsigned)remainingNodes.size() );
// //
// INFO("rest: " << remainingNodes.size() << ", max: " << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ", quad: " << quaddegree); // SimpleLogger().Write() << "rest: " << remainingNodes.size() << ", max: " << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ", quad: " << quaddegree;
p.printStatus(numberOfContractedNodes); p.printStatus(numberOfContractedNodes);
} }
BOOST_FOREACH(_ThreadData * data, threadData) BOOST_FOREACH(_ThreadData * data, threadData) {
delete data; delete data;
}
threadData.clear(); threadData.clear();
} }
template< class Edge > template< class Edge >
inline void GetEdges( DeallocatingVector< Edge >& edges ) { inline void GetEdges( DeallocatingVector< Edge >& edges ) {
Percent p (_graph->GetNumberOfNodes()); Percent p (_graph->GetNumberOfNodes());
INFO("Getting edges of minimized graph"); SimpleLogger().Write() << "Getting edges of minimized graph";
NodeID numberOfNodes = _graph->GetNumberOfNodes(); NodeID numberOfNodes = _graph->GetNumberOfNodes();
if(_graph->GetNumberOfNodes()) { if(_graph->GetNumberOfNodes()) {
for ( NodeID node = 0; node < numberOfNodes; ++node ) { for ( NodeID node = 0; node < numberOfNodes; ++node ) {
@@ -474,7 +477,7 @@ public:
newEdge.data.id = data.id; newEdge.data.id = data.id;
} }
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(
newEdge.data.id <= INT_MAX, //2^31 newEdge.data.id != INT_MAX, //2^31
"edge id invalid" "edge id invalid"
); );
newEdge.data.forward = data.forward; newEdge.data.forward = data.forward;
+370 -221
View File
@@ -20,188 +20,262 @@
#include "EdgeBasedGraphFactory.h" #include "EdgeBasedGraphFactory.h"
template<> EdgeBasedGraphFactory::EdgeBasedGraphFactory(
EdgeBasedGraphFactory::EdgeBasedGraphFactory(int nodes, std::vector<NodeBasedEdge> & inputEdges, std::vector<NodeID> & bn, std::vector<NodeID> & tl, std::vector<_Restriction> & irs, std::vector<NodeInfo> & nI, SpeedProfileProperties sp) : speedProfile(sp), inputNodeInfoList(nI), numberOfTurnRestrictions(irs.size()) { int number_of_nodes,
BOOST_FOREACH(const _Restriction & restriction, irs) { std::vector<ImportEdge> & input_edge_list,
std::pair<NodeID, NodeID> restrictionSource = std::make_pair(restriction.fromNode, restriction.viaNode); std::vector<NodeID> & barrier_node_list,
std::vector<NodeID> & traffic_light_node_list,
std::vector<TurnRestriction> & input_restrictions_list,
std::vector<NodeInfo> & m_node_info_list,
SpeedProfileProperties speed_profile
) : speed_profile(speed_profile),
m_turn_restrictions_count(0),
m_node_info_list(m_node_info_list)
{
BOOST_FOREACH(const TurnRestriction & restriction, input_restrictions_list) {
std::pair<NodeID, NodeID> restriction_source =
std::make_pair(restriction.fromNode, restriction.viaNode);
unsigned index; unsigned index;
RestrictionMap::iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::iterator restriction_iter = m_restriction_map.find(restriction_source);
if(restrIter == _restrictionMap.end()) { if(restriction_iter == m_restriction_map.end()) {
index = _restrictionBucketVector.size(); index = m_restriction_bucket_list.size();
_restrictionBucketVector.resize(index+1); m_restriction_bucket_list.resize(index+1);
_restrictionMap[restrictionSource] = index; m_restriction_map[restriction_source] = index;
} else { } else {
index = restrIter->second; index = restriction_iter->second;
//Map already contains an is_only_*-restriction //Map already contains an is_only_*-restriction
if(_restrictionBucketVector.at(index).begin()->second) if(m_restriction_bucket_list.at(index).begin()->second) {
continue; continue;
else if(restriction.flags.isOnly){ } else if(restriction.flags.isOnly) {
//We are going to insert an is_only_*-restriction. There can be only one. //We are going to insert an is_only_*-restriction. There can be only one.
_restrictionBucketVector.at(index).clear(); m_turn_restrictions_count -= m_restriction_bucket_list.at(index).size();
m_restriction_bucket_list.at(index).clear();
} }
} }
++m_turn_restrictions_count;
_restrictionBucketVector.at(index).push_back(std::make_pair(restriction.toNode, restriction.flags.isOnly)); m_restriction_bucket_list.at(index).push_back(
std::make_pair( restriction.toNode, restriction.flags.isOnly)
);
} }
_barrierNodes.insert(bn.begin(), bn.end()); m_barrier_nodes.insert(
_trafficLights.insert(tl.begin(), tl.end()); barrier_node_list.begin(),
barrier_node_list.end()
);
DeallocatingVector< _NodeBasedEdge > edges; m_traffic_lights.insert(
_NodeBasedEdge edge; traffic_light_node_list.begin(),
for ( std::vector< NodeBasedEdge >::const_iterator i = inputEdges.begin(); i != inputEdges.end(); ++i ) { traffic_light_node_list.end()
if(!i->isForward()) { );
edge.source = i->target();
edge.target = i->source(); DeallocatingVector< NodeBasedEdge > edges_list;
edge.data.backward = i->isForward(); NodeBasedEdge edge;
edge.data.forward = i->isBackward(); BOOST_FOREACH(const ImportEdge & import_edge, input_edge_list) {
if(!import_edge.isForward()) {
edge.source = import_edge.target();
edge.target = import_edge.source();
edge.data.backward = import_edge.isForward();
edge.data.forward = import_edge.isBackward();
} else { } else {
edge.source = i->source(); edge.source = import_edge.source();
edge.target = i->target(); edge.target = import_edge.target();
edge.data.forward = i->isForward(); edge.data.forward = import_edge.isForward();
edge.data.backward = i->isBackward(); edge.data.backward = import_edge.isBackward();
} }
if(edge.source == edge.target) { if(edge.source == edge.target) {
continue; continue;
} }
edge.data.distance = (std::max)((int)i->weight(), 1 ); edge.data.distance = (std::max)((int)import_edge.weight(), 1 );
assert( edge.data.distance > 0 ); assert( edge.data.distance > 0 );
edge.data.shortcut = false; edge.data.shortcut = false;
edge.data.roundabout = i->isRoundabout(); edge.data.roundabout = import_edge.isRoundabout();
edge.data.ignoreInGrid = i->ignoreInGrid(); edge.data.ignoreInGrid = import_edge.ignoreInGrid();
edge.data.nameID = i->name(); edge.data.nameID = import_edge.name();
edge.data.type = i->type(); edge.data.type = import_edge.type();
edge.data.isAccessRestricted = i->isAccessRestricted(); edge.data.isAccessRestricted = import_edge.isAccessRestricted();
edge.data.edgeBasedNodeID = edges.size(); edge.data.edgeBasedNodeID = edges_list.size();
edge.data.contraFlow = i->isContraFlow(); edge.data.contraFlow = import_edge.isContraFlow();
edges.push_back( edge ); edges_list.push_back( edge );
if( edge.data.backward ) { if( edge.data.backward ) {
std::swap( edge.source, edge.target ); std::swap( edge.source, edge.target );
edge.data.forward = i->isBackward(); edge.data.forward = import_edge.isBackward();
edge.data.backward = i->isForward(); edge.data.backward = import_edge.isForward();
edge.data.edgeBasedNodeID = edges.size(); edge.data.edgeBasedNodeID = edges_list.size();
edges.push_back( edge ); edges_list.push_back( edge );
} }
} }
std::vector<NodeBasedEdge>().swap(inputEdges); std::vector<ImportEdge>().swap(input_edge_list);
std::sort( edges.begin(), edges.end() ); std::sort( edges_list.begin(), edges_list.end() );
_nodeBasedGraph = boost::make_shared<_NodeBasedDynamicGraph>( nodes, edges ); m_node_based_graph = boost::make_shared<NodeBasedDynamicGraph>(
number_of_nodes, edges_list
);
} }
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector< EdgeBasedEdge >& outputEdgeList ) { void EdgeBasedGraphFactory::GetEdgeBasedEdges(
DeallocatingVector< EdgeBasedEdge >& output_edge_list
) {
BOOST_ASSERT_MSG( BOOST_ASSERT_MSG(
0 == outputEdgeList.size(), 0 == output_edge_list.size(),
"Vector is not empty" "Vector is not empty"
); );
edgeBasedEdges.swap(outputEdgeList); m_edge_based_edge_list.swap(output_edge_list);
} }
void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) { void EdgeBasedGraphFactory::GetEdgeBasedNodes( std::vector<EdgeBasedNode> & nodes) {
#ifndef NDEBUG #ifndef NDEBUG
BOOST_FOREACH(EdgeBasedNode & node, edgeBasedNodes){ BOOST_FOREACH(const EdgeBasedNode & node, m_edge_based_node_list){
assert(node.lat1 != INT_MAX); assert(node.lon1 != INT_MAX); assert(node.lat1 != INT_MAX); assert(node.lon1 != INT_MAX);
assert(node.lat2 != INT_MAX); assert(node.lon2 != INT_MAX); assert(node.lat2 != INT_MAX); assert(node.lon2 != INT_MAX);
} }
#endif #endif
nodes.swap(edgeBasedNodes); nodes.swap(m_edge_based_node_list);
} }
NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const { NodeID EdgeBasedGraphFactory::CheckForEmanatingIsOnlyTurn(
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); const NodeID u,
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); const NodeID v
if (restrIter != _restrictionMap.end()) { ) const {
unsigned index = restrIter->second; const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
BOOST_FOREACH(const RestrictionSource & restrictionTarget, _restrictionBucketVector.at(index)) { RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source);
if(restrictionTarget.second) { if (restriction_iter != m_restriction_map.end()) {
return restrictionTarget.first; const unsigned index = restriction_iter->second;
BOOST_FOREACH(
const RestrictionSource & restriction_target,
m_restriction_bucket_list.at(index)
) {
if(restriction_target.second) {
return restriction_target.first;
} }
} }
} }
return UINT_MAX; return UINT_MAX;
} }
bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const { bool EdgeBasedGraphFactory::CheckIfTurnIsRestricted(
const NodeID u,
const NodeID v,
const NodeID w
) const {
//only add an edge if turn is not a U-turn except it is the end of dead-end street. //only add an edge if turn is not a U-turn except it is the end of dead-end street.
std::pair < NodeID, NodeID > restrictionSource = std::make_pair(u, v); const std::pair < NodeID, NodeID > restriction_source = std::make_pair(u, v);
RestrictionMap::const_iterator restrIter = _restrictionMap.find(restrictionSource); RestrictionMap::const_iterator restriction_iter = m_restriction_map.find(restriction_source);
if (restrIter != _restrictionMap.end()) { if (restriction_iter != m_restriction_map.end()) {
unsigned index = restrIter->second; const unsigned index = restriction_iter->second;
BOOST_FOREACH(RestrictionTarget restrictionTarget, _restrictionBucketVector.at(index)) { BOOST_FOREACH(
if(w == restrictionTarget.first) const RestrictionTarget & restriction_target,
m_restriction_bucket_list.at(index)
) {
if(w == restriction_target.first) {
return true; return true;
}
} }
} }
return false; return false;
} }
void EdgeBasedGraphFactory::InsertEdgeBasedNode( void EdgeBasedGraphFactory::InsertEdgeBasedNode(
_NodeBasedDynamicGraph::EdgeIterator e1, EdgeIterator e1,
_NodeBasedDynamicGraph::NodeIterator u, NodeIterator u,
_NodeBasedDynamicGraph::NodeIterator v, NodeIterator v,
bool belongsToTinyComponent) { bool belongsToTinyComponent) {
_NodeBasedDynamicGraph::EdgeData & data = _nodeBasedGraph->GetEdgeData(e1); EdgeData & data = m_node_based_graph->GetEdgeData(e1);
EdgeBasedNode currentNode; EdgeBasedNode currentNode;
currentNode.nameID = data.nameID; currentNode.nameID = data.nameID;
currentNode.lat1 = inputNodeInfoList[u].lat; currentNode.lat1 = m_node_info_list[u].lat;
currentNode.lon1 = inputNodeInfoList[u].lon; currentNode.lon1 = m_node_info_list[u].lon;
currentNode.lat2 = inputNodeInfoList[v].lat; currentNode.lat2 = m_node_info_list[v].lat;
currentNode.lon2 = inputNodeInfoList[v].lon; currentNode.lon2 = m_node_info_list[v].lon;
currentNode.belongsToTinyComponent = belongsToTinyComponent; currentNode.belongsToTinyComponent = belongsToTinyComponent;
currentNode.id = data.edgeBasedNodeID; currentNode.id = data.edgeBasedNodeID;
currentNode.ignoreInGrid = data.ignoreInGrid; currentNode.ignoreInGrid = data.ignoreInGrid;
currentNode.weight = data.distance; currentNode.weight = data.distance;
edgeBasedNodes.push_back(currentNode); m_edge_based_node_list.push_back(currentNode);
} }
void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State *myLuaState) { void EdgeBasedGraphFactory::Run(
Percent p(_nodeBasedGraph->GetNumberOfNodes()); const char * original_edge_data_filename,
int numberOfSkippedTurns(0); lua_State *lua_state
int nodeBasedEdgeCounter(0); ) {
unsigned numberOfOriginalEdges(0); SimpleLogger().Write() << "Identifying components of the road network";
std::ofstream originalEdgeDataOutFile(originalEdgeDataFilename, std::ios::binary);
originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned));
Percent p(m_node_based_graph->GetNumberOfNodes());
unsigned skipped_turns_counter = 0;
unsigned node_based_edge_counter = 0;
unsigned original_edges_counter = 0;
INFO("Identifying small components"); std::ofstream edge_data_file(
original_edge_data_filename,
std::ios::binary
);
//writes a dummy value that is updated later
edge_data_file.write(
(char*)&original_edges_counter,
sizeof(unsigned)
);
unsigned current_component = 0, current_component_size = 0;
//Run a BFS on the undirected graph and identify small components //Run a BFS on the undirected graph and identify small components
std::queue<std::pair<NodeID, NodeID> > bfsQueue; std::queue<std::pair<NodeID, NodeID> > bfs_queue;
std::vector<unsigned> componentsIndex(_nodeBasedGraph->GetNumberOfNodes(), UINT_MAX); std::vector<unsigned> component_index_list(
std::vector<NodeID> vectorOfComponentSizes; m_node_based_graph->GetNumberOfNodes(),
unsigned currentComponent = 0, sizeOfCurrentComponent = 0; UINT_MAX
);
std::vector<NodeID> component_size_list;
//put unexplorered node with parent pointer into queue //put unexplorered node with parent pointer into queue
for(NodeID node = 0, endNodes = _nodeBasedGraph->GetNumberOfNodes(); node < endNodes; ++node) { for(
if(UINT_MAX == componentsIndex[node]) { NodeID node = 0,
bfsQueue.push(std::make_pair(node, node)); last_node = m_node_based_graph->GetNumberOfNodes();
node < last_node;
++node
) {
if(UINT_MAX == component_index_list[node]) {
bfs_queue.push(std::make_pair(node, node));
//mark node as read //mark node as read
componentsIndex[node] = currentComponent; component_index_list[node] = current_component;
p.printIncrement(); p.printIncrement();
while(!bfsQueue.empty()) { while(!bfs_queue.empty()) {
//fetch element from BFS queue //fetch element from BFS queue
std::pair<NodeID, NodeID> currentQueueItem = bfsQueue.front(); std::pair<NodeID, NodeID> current_queue_item = bfs_queue.front();
bfsQueue.pop(); bfs_queue.pop();
// INFO("sizeof queue: " << bfsQueue.size() << ", sizeOfCurrentComponents: " << sizeOfCurrentComponent << ", settled nodes: " << settledNodes++ << ", max: " << endNodes); // SimpleLogger().Write() << "sizeof queue: " << bfs_queue.size() <<
const NodeID v = currentQueueItem.first; //current node // ", current_component_sizes: " << current_component_size <<
const NodeID u = currentQueueItem.second; //parent //", settled nodes: " << settledNodes++ << ", max: " << endNodes;
const NodeID v = current_queue_item.first; //current node
const NodeID u = current_queue_item.second; //parent
//increment size counter of current component //increment size counter of current component
++sizeOfCurrentComponent; ++current_component_size;
const bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end()); const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
if(!isBollardNode) { if(!is_barrier_node) {
const NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v); const NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v);
//relaxieren edge outgoing edge like below where edge-expanded graph //relaxieren edge outgoing edge like below where edge-expanded graph
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { for(
_NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2); EdgeIterator e2 = m_node_based_graph->BeginEdges(v);
e2 < m_node_based_graph->EndEdges(v);
++e2
) {
NodeIterator w = m_node_based_graph->GetTarget(e2);
if(onlyToNode != UINT_MAX && w != onlyToNode) { //We are at an only_-restriction but not at the right turn. if(
to_node_of_only_restriction != UINT_MAX &&
w != to_node_of_only_restriction
) {
//We are at an only_-restriction but not at the right turn.
continue; continue;
} }
if( u != w ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street. if( u != w ) {
if (!CheckIfTurnIsRestricted(u, v, w) ) { //only add an edge if turn is not prohibited //only add an edge if turn is not a U-turn except
//insert next (node, parent) only if w has not yet been explored //when it is at the end of a dead-end street.
if(UINT_MAX == componentsIndex[w]) { if (!CheckIfTurnIsRestricted(u, v, w) ) {
//only add an edge if turn is not prohibited
if(UINT_MAX == component_index_list[w]) {
//insert next (node, parent) only if w has
//not yet been explored
//mark node as read //mark node as read
componentsIndex[w] = currentComponent; component_index_list[w] = current_component;
bfsQueue.push(std::make_pair(w,v)); bfs_queue.push(std::make_pair(w,v));
p.printIncrement(); p.printIncrement();
} }
} }
@@ -210,149 +284,228 @@ void EdgeBasedGraphFactory::Run(const char * originalEdgeDataFilename, lua_State
} }
} }
//push size into vector //push size into vector
vectorOfComponentSizes.push_back(sizeOfCurrentComponent); component_size_list.push_back(current_component_size);
//reset counters; //reset counters;
sizeOfCurrentComponent = 0; current_component_size = 0;
++currentComponent; ++current_component;
} }
} }
INFO("identified: " << vectorOfComponentSizes.size() << " many components"); SimpleLogger().Write() <<
"identified: " << component_size_list.size() << " many components";
p.reinit(_nodeBasedGraph->GetNumberOfNodes()); p.reinit(m_node_based_graph->GetNumberOfNodes());
//loop over all edges and generate new set of nodes. //loop over all edges and generate new set of nodes.
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { for(
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) { NodeIterator u = 0,
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1); number_of_nodes = m_node_based_graph->GetNumberOfNodes();
u < number_of_nodes;
++u
) {
for(
EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
last_edge = m_node_based_graph->EndEdges(u);
e1 < last_edge;
++e1
) {
NodeIterator v = m_node_based_graph->GetTarget(e1);
if(_nodeBasedGraph->GetEdgeData(e1).type != SHRT_MAX) { if(m_node_based_graph->GetEdgeData(e1).type != SHRT_MAX) {
assert(e1 != UINT_MAX); BOOST_ASSERT_MSG(e1 != UINT_MAX, "edge id invalid");
assert(u != UINT_MAX); BOOST_ASSERT_MSG(u != UINT_MAX, "souce node invalid");
assert(v != UINT_MAX); BOOST_ASSERT_MSG(v != UINT_MAX, "target node invalid");
//edges that end on bollard nodes may actually be in two distinct components //Note: edges that end on barrier nodes or on a turn restriction
InsertEdgeBasedNode(e1, u, v, (std::min(vectorOfComponentSizes[componentsIndex[u]], vectorOfComponentSizes[componentsIndex[v]]) < 1000) ); //may actually be in two distinct components. We choose the smallest
const unsigned size_of_component = std::min(
component_size_list[component_index_list[u]],
component_size_list[component_index_list[v]]
);
InsertEdgeBasedNode( e1, u, v, size_of_component < 1000 );
} }
} }
} }
std::vector<NodeID>().swap(vectorOfComponentSizes); std::vector<NodeID>().swap(component_size_list);
std::vector<NodeID>().swap(componentsIndex); BOOST_ASSERT_MSG(
0 == component_size_list.capacity(),
"component size vector not deallocated"
);
std::vector<NodeID>().swap(component_index_list);
BOOST_ASSERT_MSG(
0 == component_index_list.capacity(),
"component index vector not deallocated"
);
std::vector<OriginalEdgeData> original_edge_data_vector; std::vector<OriginalEdgeData> original_edge_data_vector;
original_edge_data_vector.reserve(10000); original_edge_data_vector.reserve(10000);
//Loop over all turns and generate new set of edges. //Loop over all turns and generate new set of edges.
//Three nested loop look super-linear, but we are dealing with a linear number of turns only. //Three nested loop look super-linear, but we are dealing with a (kind of)
for(_NodeBasedDynamicGraph::NodeIterator u = 0; u < _nodeBasedGraph->GetNumberOfNodes(); ++u ) { //linear number of turns only.
for(_NodeBasedDynamicGraph::EdgeIterator e1 = _nodeBasedGraph->BeginEdges(u); e1 < _nodeBasedGraph->EndEdges(u); ++e1) { for(
++nodeBasedEdgeCounter; NodeIterator u = 0,
_NodeBasedDynamicGraph::NodeIterator v = _nodeBasedGraph->GetTarget(e1); last_node = m_node_based_graph->GetNumberOfNodes();
bool isBollardNode = (_barrierNodes.find(v) != _barrierNodes.end()); u < last_node;
//EdgeWeight heightPenalty = ComputeHeightPenalty(u, v); ++u
NodeID onlyToNode = CheckForEmanatingIsOnlyTurn(u, v); ) {
for(_NodeBasedDynamicGraph::EdgeIterator e2 = _nodeBasedGraph->BeginEdges(v); e2 < _nodeBasedGraph->EndEdges(v); ++e2) { for(
const _NodeBasedDynamicGraph::NodeIterator w = _nodeBasedGraph->GetTarget(e2); EdgeIterator e1 = m_node_based_graph->BeginEdges(u),
last_edge_u = m_node_based_graph->EndEdges(u);
if(onlyToNode != UINT_MAX && w != onlyToNode) { //We are at an only_-restriction but not at the right turn. e1 < last_edge_u;
++numberOfSkippedTurns; ++e1
) {
++node_based_edge_counter;
NodeIterator v = m_node_based_graph->GetTarget(e1);
bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
NodeID to_node_of_only_restriction = CheckForEmanatingIsOnlyTurn(u, v);
for(
EdgeIterator e2 = m_node_based_graph->BeginEdges(v),
last_edge_v = m_node_based_graph->EndEdges(v);
e2 < last_edge_v;
++e2
) {
const NodeIterator w = m_node_based_graph->GetTarget(e2);
if(
to_node_of_only_restriction != UINT_MAX &&
w != to_node_of_only_restriction
) {
//We are at an only_-restriction but not at the right turn.
++skipped_turns_counter;
continue; continue;
} }
if(u == w && 1 != _nodeBasedGraph->GetOutDegree(v) ) { if(u == w && 1 != m_node_based_graph->GetOutDegree(v) ) {
continue; continue;
} }
if( !isBollardNode ) { //only add an edge if turn is not a U-turn except it is the end of dead-end street. if( !is_barrier_node ) {
if (!CheckIfTurnIsRestricted(u, v, w) || (onlyToNode != UINT_MAX && w == onlyToNode)) { //only add an edge if turn is not prohibited //only add an edge if turn is not a U-turn except when it is
const _NodeBasedDynamicGraph::EdgeData edgeData1 = _nodeBasedGraph->GetEdgeData(e1); //at the end of a dead-end street
const _NodeBasedDynamicGraph::EdgeData edgeData2 = _nodeBasedGraph->GetEdgeData(e2); if (
assert(edgeData1.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges()); !CheckIfTurnIsRestricted(u, v, w) ||
assert(edgeData2.edgeBasedNodeID < _nodeBasedGraph->GetNumberOfEdges()); (to_node_of_only_restriction != UINT_MAX && w == to_node_of_only_restriction)
) { //only add an edge if turn is not prohibited
const EdgeData edge_data1 = m_node_based_graph->GetEdgeData(e1);
const EdgeData edge_data2 = m_node_based_graph->GetEdgeData(e2);
assert(edge_data1.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges());
assert(edge_data2.edgeBasedNodeID < m_node_based_graph->GetNumberOfEdges());
if(!edgeData1.forward || !edgeData2.forward) { if(!edge_data1.forward || !edge_data2.forward) {
continue; continue;
} }
unsigned distance = edgeData1.distance; unsigned distance = edge_data1.distance;
if(_trafficLights.find(v) != _trafficLights.end()) { if(m_traffic_lights.find(v) != m_traffic_lights.end()) {
distance += speedProfile.trafficSignalPenalty; distance += speed_profile.trafficSignalPenalty;
}
const unsigned penalty =
GetTurnPenalty(u, v, w, lua_state);
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w);
if(turnInstruction == TurnInstructions.UTurn){
distance += speed_profile.uTurnPenalty;
} }
unsigned penalty = 0;
TurnInstruction turnInstruction = AnalyzeTurn(u, v, w, penalty, myLuaState);
if(turnInstruction == TurnInstructions.UTurn)
distance += speedProfile.uTurnPenalty;
// if(!edgeData1.isAccessRestricted && edgeData2.isAccessRestricted) {
// distance += TurnInstructions.AccessRestrictionPenalty;
// turnInstruction |= TurnInstructions.AccessRestrictionFlag;
// }
distance += penalty; distance += penalty;
assert(edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID);
//distance += heightPenalty; original_edge_data_vector.push_back(
//distance += ComputeTurnPenalty(u, v, w); OriginalEdgeData(
assert(edgeData1.edgeBasedNodeID != edgeData2.edgeBasedNodeID); v,
OriginalEdgeData oed(v,edgeData2.nameID, turnInstruction); edge_data2.nameID,
original_edge_data_vector.push_back(oed); turnInstruction
++numberOfOriginalEdges; )
);
++original_edges_counter;
if(original_edge_data_vector.size() > 100000) { if(original_edge_data_vector.size() > 100000) {
originalEdgeDataOutFile.write((char*)&(original_edge_data_vector[0]), original_edge_data_vector.size()*sizeof(OriginalEdgeData)); edge_data_file.write(
(char*)&(original_edge_data_vector[0]),
original_edge_data_vector.size()*sizeof(OriginalEdgeData)
);
original_edge_data_vector.clear(); original_edge_data_vector.clear();
} }
EdgeBasedEdge newEdge(edgeData1.edgeBasedNodeID, edgeData2.edgeBasedNodeID, edgeBasedEdges.size(), distance, true, false ); m_edge_based_edge_list.push_back(
edgeBasedEdges.push_back(newEdge); EdgeBasedEdge(
edge_data1.edgeBasedNodeID,
edge_data2.edgeBasedNodeID,
m_edge_based_edge_list.size(),
distance,
true,
false
)
);
} else { } else {
++numberOfSkippedTurns; ++skipped_turns_counter;
} }
} }
} }
} }
p.printIncrement(); p.printIncrement();
} }
originalEdgeDataOutFile.write((char*)&(original_edge_data_vector[0]), original_edge_data_vector.size()*sizeof(OriginalEdgeData)); edge_data_file.write(
originalEdgeDataOutFile.seekp(std::ios::beg); (char*)&(original_edge_data_vector[0]),
originalEdgeDataOutFile.write((char*)&numberOfOriginalEdges, sizeof(unsigned)); original_edge_data_vector.size()*sizeof(OriginalEdgeData)
originalEdgeDataOutFile.close(); );
edge_data_file.seekp(std::ios::beg);
edge_data_file.write(
(char*)&original_edges_counter,
sizeof(unsigned)
);
edge_data_file.close();
// INFO("Sorting edge-based Nodes"); SimpleLogger().Write() <<
// std::sort(edgeBasedNodes.begin(), edgeBasedNodes.end()); "Generated " << m_edge_based_node_list.size() << " edge based nodes";
// INFO("Removing duplicate nodes (if any)"); SimpleLogger().Write() <<
// edgeBasedNodes.erase( std::unique(edgeBasedNodes.begin(), edgeBasedNodes.end()), edgeBasedNodes.end() ); "Node-based graph contains " << node_based_edge_counter << " edges";
// INFO("Applying vector self-swap trick to free up memory"); SimpleLogger().Write() <<
// INFO("size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity()); "Edge-expanded graph ...";
// std::vector<EdgeBasedNode>(edgeBasedNodes).swap(edgeBasedNodes); SimpleLogger().Write() <<
// INFO("size: " << edgeBasedNodes.size() << ", cap: " << edgeBasedNodes.capacity()); " contains " << m_edge_based_edge_list.size() << " edges";
INFO("Node-based graph contains " << nodeBasedEdgeCounter << " edges"); SimpleLogger().Write() <<
INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges"); " skips " << skipped_turns_counter << " turns, "
// INFO("Edge-based graph contains " << edgeBasedEdges.size() << " edges, blowup is " << 2*((double)edgeBasedEdges.size()/(double)nodeBasedEdgeCounter)); "defined by " << m_turn_restrictions_count << " restrictions";
INFO("Edge-based graph skipped " << numberOfSkippedTurns << " turns, defined by " << numberOfTurnRestrictions << " restrictions.");
INFO("Generated " << edgeBasedNodes.size() << " edge based nodes");
} }
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, unsigned& penalty, lua_State *myLuaState) const { int EdgeBasedGraphFactory::GetTurnPenalty(
const double angle = GetAngleBetweenTwoEdges(inputNodeInfoList[u], inputNodeInfoList[v], inputNodeInfoList[w]); const NodeID u,
const NodeID v,
const NodeID w,
lua_State *lua_state
) const {
const double angle = GetAngleBetweenThreeFixedPointCoordinates (
m_node_info_list[u],
m_node_info_list[v],
m_node_info_list[w]
);
if( speedProfile.has_turn_penalty_function ) { if( speed_profile.has_turn_penalty_function ) {
try { try {
//call lua profile to compute turn penalty //call lua profile to compute turn penalty
penalty = luabind::call_function<int>( myLuaState, "turn_function", 180-angle ); return luabind::call_function<int>(
lua_state,
"turn_function",
180.-angle
);
} catch (const luabind::error &er) { } catch (const luabind::error &er) {
std::cerr << er.what() << std::endl; SimpleLogger().Write(logWARNING) << er.what();
//TODO handle lua errors
} }
} else {
penalty = 0;
} }
return 0;
}
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(
const NodeID u,
const NodeID v,
const NodeID w
) const {
if(u == w) { if(u == w) {
return TurnInstructions.UTurn; return TurnInstructions.UTurn;
} }
_NodeBasedDynamicGraph::EdgeIterator edge1 = _nodeBasedGraph->FindEdge(u, v); EdgeIterator edge1 = m_node_based_graph->FindEdge(u, v);
_NodeBasedDynamicGraph::EdgeIterator edge2 = _nodeBasedGraph->FindEdge(v, w); EdgeIterator edge2 = m_node_based_graph->FindEdge(v, w);
_NodeBasedDynamicGraph::EdgeData & data1 = _nodeBasedGraph->GetEdgeData(edge1); EdgeData & data1 = m_node_based_graph->GetEdgeData(edge1);
_NodeBasedDynamicGraph::EdgeData & data2 = _nodeBasedGraph->GetEdgeData(edge2); EdgeData & data2 = m_node_based_graph->GetEdgeData(edge2);
if(!data1.contraFlow && data2.contraFlow) { if(!data1.contraFlow && data2.contraFlow) {
return TurnInstructions.EnterAgainstAllowedDirection; return TurnInstructions.EnterAgainstAllowedDirection;
@@ -364,7 +517,7 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID
//roundabouts need to be handled explicitely //roundabouts need to be handled explicitely
if(data1.roundabout && data2.roundabout) { if(data1.roundabout && data2.roundabout) {
//Is a turn possible? If yes, we stay on the roundabout! //Is a turn possible? If yes, we stay on the roundabout!
if( 1 == (_nodeBasedGraph->EndEdges(v) - _nodeBasedGraph->BeginEdges(v)) ) { if( 1 == m_node_based_graph->GetOutDegree(v) ) {
//No turn possible. //No turn possible.
return TurnInstructions.NoTurn; return TurnInstructions.NoTurn;
} }
@@ -382,31 +535,27 @@ TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID u, const NodeID
} }
} }
//If street names stay the same and if we are certain that it is not a roundabout, we skip it. //If street names stay the same and if we are certain that it is not a
if( (data1.nameID == data2.nameID) && (0 != data1.nameID)) { //a segment of a roundabout, we skip it.
return TurnInstructions.NoTurn; if( data1.nameID == data2.nameID ) {
} //TODO: Here we should also do a small graph exploration to check for
if( (data1.nameID == data2.nameID) && (0 == data1.nameID) && (_nodeBasedGraph->GetOutDegree(v) <= 2) ) { // more complex situations
return TurnInstructions.NoTurn; if( 0 != data1.nameID ) {
return TurnInstructions.NoTurn;
} else if (m_node_based_graph->GetOutDegree(v) <= 2) {
return TurnInstructions.NoTurn;
}
} }
const double angle = GetAngleBetweenThreeFixedPointCoordinates (
m_node_info_list[u],
m_node_info_list[v],
m_node_info_list[w]
);
return TurnInstructions.GetTurnDirectionOfInstruction(angle); return TurnInstructions.GetTurnDirectionOfInstruction(angle);
} }
unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const { unsigned EdgeBasedGraphFactory::GetNumberOfNodes() const {
return _nodeBasedGraph->GetNumberOfEdges(); return m_node_based_graph->GetNumberOfEdges();
}
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
template<class CoordinateT>
double EdgeBasedGraphFactory::GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const {
const double v1x = (A.lon - C.lon)/100000.;
const double v1y = lat2y(A.lat/100000.) - lat2y(C.lat/100000.);
const double v2x = (B.lon - C.lon)/100000.;
const double v2y = lat2y(B.lat/100000.) - lat2y(C.lat/100000.);
double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI;
while(angle < 0)
angle += 360;
return angle;
} }
+88 -47
View File
@@ -18,9 +18,7 @@
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
/* // This class constructs the edge-expanded routing graph
* This class constructs the edge base representation of a graph from a given node based edge list
*/
#ifndef EDGEBASEDGRAPHFACTORY_H_ #ifndef EDGEBASEDGRAPHFACTORY_H_
#define EDGEBASEDGRAPHFACTORY_H_ #define EDGEBASEDGRAPHFACTORY_H_
@@ -31,14 +29,11 @@
#include "../Extractor/ExtractorStructs.h" #include "../Extractor/ExtractorStructs.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportEdge.h" #include "../DataStructures/ImportEdge.h"
#include "../DataStructures/MercatorUtil.h"
#include "../DataStructures/QueryEdge.h" #include "../DataStructures/QueryEdge.h"
#include "../DataStructures/Percent.h" #include "../DataStructures/Percent.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../Util/BaseConfiguration.h"
#include "../Util/LuaUtil.h" #include "../Util/LuaUtil.h"
#include "../Util/SimpleLogger.h"
#include <stxxl.h>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
@@ -47,15 +42,26 @@
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
#include <cstdlib>
#include <algorithm> #include <algorithm>
#include <fstream>
#include <queue> #include <queue>
#include <vector> #include <vector>
class EdgeBasedGraphFactory : boost::noncopyable { class EdgeBasedGraphFactory : boost::noncopyable {
public: public:
struct EdgeBasedNode { struct EdgeBasedNode {
EdgeBasedNode() :
id(INT_MAX),
lat1(INT_MAX),
lat2(INT_MAX),
lon1(INT_MAX),
lon2(INT_MAX >> 1),
belongsToTinyComponent(false),
nameID(UINT_MAX),
weight(UINT_MAX >> 1),
ignoreInGrid(false)
{ }
bool operator<(const EdgeBasedNode & other) const { bool operator<(const EdgeBasedNode & other) const {
return other.id < id; return other.id < id;
} }
@@ -64,8 +70,8 @@ public:
return id == other.id; return id == other.id;
} }
inline _Coordinate Centroid() const { inline FixedPointCoordinate Centroid() const {
_Coordinate centroid; FixedPointCoordinate centroid;
//The coordinates of the midpoint are given by: //The coordinates of the midpoint are given by:
//x = (x1 + x2) /2 and y = (y1 + y2) /2. //x = (x1 + x2) /2 and y = (y1 + y2) /2.
centroid.lon = (std::min(lon1, lon2) + std::max(lon1, lon2))/2; centroid.lon = (std::min(lon1, lon2) + std::max(lon1, lon2))/2;
@@ -76,6 +82,7 @@ public:
inline bool isIgnored() const { inline bool isIgnored() const {
return ignoreInGrid; return ignoreInGrid;
} }
NodeID id; NodeID id;
int lat1; int lat1;
int lat2; int lat2;
@@ -88,14 +95,47 @@ public:
}; };
struct SpeedProfileProperties{ struct SpeedProfileProperties{
SpeedProfileProperties() : trafficSignalPenalty(0), uTurnPenalty(0), has_turn_penalty_function(false) {} SpeedProfileProperties() :
trafficSignalPenalty(0),
uTurnPenalty(0),
has_turn_penalty_function(false)
{ }
int trafficSignalPenalty; int trafficSignalPenalty;
int uTurnPenalty; int uTurnPenalty;
bool has_turn_penalty_function; bool has_turn_penalty_function;
} speedProfile; } speed_profile;
explicit EdgeBasedGraphFactory(
int number_of_nodes,
std::vector<ImportEdge> & input_edge_list,
std::vector<NodeID> & barrier_node_list,
std::vector<NodeID> & traffic_light_node_list,
std::vector<TurnRestriction> & input_restrictions_list,
std::vector<NodeInfo> & m_node_info_list,
SpeedProfileProperties speed_profile
);
void Run(const char * originalEdgeDataFilename, lua_State *myLuaState);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
void GetOriginalEdgeData( std::vector<OriginalEdgeData> & originalEdgeData);
TurnInstruction AnalyzeTurn(
const NodeID u,
const NodeID v,
const NodeID w
) const;
int GetTurnPenalty(
const NodeID u,
const NodeID v,
const NodeID w,
lua_State *myLuaState
) const;
unsigned GetNumberOfNodes() const;
private: private:
struct _NodeBasedEdgeData { struct NodeBasedEdgeData {
int distance; int distance;
unsigned edgeBasedNodeID; unsigned edgeBasedNodeID;
unsigned nameID; unsigned nameID;
@@ -118,45 +158,46 @@ private:
TurnInstruction turnInstruction; TurnInstruction turnInstruction;
}; };
typedef DynamicGraph< _NodeBasedEdgeData > _NodeBasedDynamicGraph; unsigned m_turn_restrictions_count;
typedef _NodeBasedDynamicGraph::InputEdge _NodeBasedEdge;
std::vector<NodeInfo> inputNodeInfoList;
unsigned numberOfTurnRestrictions;
boost::shared_ptr<_NodeBasedDynamicGraph> _nodeBasedGraph; typedef DynamicGraph<NodeBasedEdgeData> NodeBasedDynamicGraph;
boost::unordered_set<NodeID> _barrierNodes; typedef NodeBasedDynamicGraph::InputEdge NodeBasedEdge;
boost::unordered_set<NodeID> _trafficLights; typedef NodeBasedDynamicGraph::NodeIterator NodeIterator;
typedef NodeBasedDynamicGraph::EdgeIterator EdgeIterator;
typedef std::pair<NodeID, NodeID> RestrictionSource; typedef NodeBasedDynamicGraph::EdgeData EdgeData;
typedef std::pair<NodeID, bool> RestrictionTarget; typedef std::pair<NodeID, NodeID> RestrictionSource;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector; typedef std::pair<NodeID, bool> RestrictionTarget;
typedef std::vector<RestrictionTarget> EmanatingRestrictionsVector;
typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap; typedef boost::unordered_map<RestrictionSource, unsigned > RestrictionMap;
std::vector<EmanatingRestrictionsVector> _restrictionBucketVector;
RestrictionMap _restrictionMap;
DeallocatingVector<EdgeBasedEdge> edgeBasedEdges; std::vector<NodeInfo> m_node_info_list;
std::vector<EdgeBasedNode> edgeBasedNodes; std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
std::vector<EdgeBasedNode> m_edge_based_node_list;
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
boost::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
boost::unordered_set<NodeID> m_barrier_nodes;
boost::unordered_set<NodeID> m_traffic_lights;
RestrictionMap m_restriction_map;
NodeID CheckForEmanatingIsOnlyTurn(
const NodeID u,
const NodeID v
) const;
bool CheckIfTurnIsRestricted(
const NodeID u,
const NodeID v,
const NodeID w
) const;
NodeID CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const;
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const;
void InsertEdgeBasedNode( void InsertEdgeBasedNode(
_NodeBasedDynamicGraph::EdgeIterator e1, NodeBasedDynamicGraph::EdgeIterator e1,
_NodeBasedDynamicGraph::NodeIterator u, NodeBasedDynamicGraph::NodeIterator u,
_NodeBasedDynamicGraph::NodeIterator v, NodeBasedDynamicGraph::NodeIterator v,
bool belongsToTinyComponent); bool belongsToTinyComponent);
template<class CoordinateT>
double GetAngleBetweenTwoEdges(const CoordinateT& A, const CoordinateT& C, const CoordinateT& B) const;
public:
template< class InputEdgeT >
explicit EdgeBasedGraphFactory(int nodes, std::vector<InputEdgeT> & inputEdges, std::vector<NodeID> & _bollardNodes, std::vector<NodeID> & trafficLights, std::vector<_Restriction> & inputRestrictions, std::vector<NodeInfo> & nI, SpeedProfileProperties speedProfile);
void Run(const char * originalEdgeDataFilename, lua_State *myLuaState);
void GetEdgeBasedEdges( DeallocatingVector< EdgeBasedEdge >& edges );
void GetEdgeBasedNodes( std::vector< EdgeBasedNode> & nodes);
void GetOriginalEdgeData( std::vector< OriginalEdgeData> & originalEdgeData);
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, unsigned& penalty, lua_State *myLuaState) const;
unsigned GetNumberOfNodes() const;
}; };
#endif /* EDGEBASEDGRAPHFACTORY_H_ */ #endif /* EDGEBASEDGRAPHFACTORY_H_ */
+11 -22
View File
@@ -18,16 +18,10 @@
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#include <boost/foreach.hpp>
#include "TemporaryStorage.h" #include "TemporaryStorage.h"
TemporaryStorage::TemporaryStorage() { TemporaryStorage::TemporaryStorage() {
try { tempDirectory = boost::filesystem::temp_directory_path();
tempDirectory = boost::filesystem::temp_directory_path();
} catch(boost::filesystem::filesystem_error & e) {
ERR("could not retrieve location of temporary path: " << e.what());
}
} }
TemporaryStorage & TemporaryStorage::GetInstance(){ TemporaryStorage & TemporaryStorage::GetInstance(){
@@ -41,12 +35,8 @@ TemporaryStorage::~TemporaryStorage() {
void TemporaryStorage::removeAll() { void TemporaryStorage::removeAll() {
boost::mutex::scoped_lock lock(mutex); boost::mutex::scoped_lock lock(mutex);
try { for(unsigned slot_id = 0; slot_id < vectorOfStreamDatas.size(); ++slot_id) {
for(unsigned slotID = 0; slotID < vectorOfStreamDatas.size(); ++slotID) deallocateSlot(slot_id);
deallocateSlot(slotID);
} catch(boost::filesystem::filesystem_error & e) {
ERR("could not retrieve location of temporary path: " << e.what());
} }
vectorOfStreamDatas.clear(); vectorOfStreamDatas.clear();
} }
@@ -55,7 +45,7 @@ int TemporaryStorage::allocateSlot() {
boost::mutex::scoped_lock lock(mutex); boost::mutex::scoped_lock lock(mutex);
try { try {
vectorOfStreamDatas.push_back(StreamData()); vectorOfStreamDatas.push_back(StreamData());
//INFO("created new temporary file: " << vectorOfStreamDatas.back().pathToTemporaryFile); //SimpleLogger().Write() << "created new temporary file: " << vectorOfStreamDatas.back().pathToTemporaryFile;
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); abort(e);
} }
@@ -66,13 +56,13 @@ void TemporaryStorage::deallocateSlot(int slotID) {
try { try {
StreamData & data = vectorOfStreamDatas[slotID]; StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(!boost::filesystem::exists(data.pathToTemporaryFile)) { if(!boost::filesystem::exists(data.pathToTemporaryFile)) {
return; return;
} }
if(data.streamToTemporaryFile->is_open()) if(data.streamToTemporaryFile->is_open()) {
data.streamToTemporaryFile->close(); data.streamToTemporaryFile->close();
}
//INFO("deallocating slot " << slotID << " and its file: " << data.pathToTemporaryFile);
boost::filesystem::remove(data.pathToTemporaryFile); boost::filesystem::remove(data.pathToTemporaryFile);
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); abort(e);
@@ -83,8 +73,10 @@ void TemporaryStorage::writeToSlot(int slotID, char * pointer, std::streamsize s
try { try {
StreamData & data = vectorOfStreamDatas[slotID]; StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
if(!data.writeMode) BOOST_ASSERT_MSG(
ERR("Writing after first read is not allowed"); data.writeMode,
"Writing after first read is not allowed"
);
data.streamToTemporaryFile->write(pointer, size); data.streamToTemporaryFile->write(pointer, size);
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); abort(e);
@@ -123,13 +115,11 @@ boost::filesystem::fstream::pos_type TemporaryStorage::tell(int slotID) {
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); abort(e);
} }
// INFO("telling position: " << position);
return position; return position;
} }
void TemporaryStorage::abort(boost::filesystem::filesystem_error& ) { void TemporaryStorage::abort(boost::filesystem::filesystem_error& ) {
removeAll(); removeAll();
// ERR("I/O Error occured: " << e.what());
} }
void TemporaryStorage::seek(int slotID, boost::filesystem::fstream::pos_type position) { void TemporaryStorage::seek(int slotID, boost::filesystem::fstream::pos_type position) {
@@ -137,7 +127,6 @@ void TemporaryStorage::seek(int slotID, boost::filesystem::fstream::pos_type pos
StreamData & data = vectorOfStreamDatas[slotID]; StreamData & data = vectorOfStreamDatas[slotID];
boost::mutex::scoped_lock lock(*data.readWriteMutex); boost::mutex::scoped_lock lock(*data.readWriteMutex);
data.streamToTemporaryFile->seekg(position); data.streamToTemporaryFile->seekg(position);
// INFO("seeking to position: " << position);
} catch(boost::filesystem::filesystem_error & e) { } catch(boost::filesystem::filesystem_error & e) {
abort(e); abort(e);
} }
+7 -2
View File
@@ -24,11 +24,15 @@
#include <vector> #include <vector>
#include <fstream> #include <fstream>
#include <boost/assert.hpp>
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
//This is one big workaround for latest boost renaming woes. //This is one big workaround for latest boost renaming woes.
@@ -101,8 +105,9 @@ private:
streamToTemporaryFile(new boost::filesystem::fstream(pathToTemporaryFile, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)), streamToTemporaryFile(new boost::filesystem::fstream(pathToTemporaryFile, std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary)),
readWriteMutex(new boost::mutex) readWriteMutex(new boost::mutex)
{ {
if(streamToTemporaryFile->fail()) if(streamToTemporaryFile->fail()) {
ERR("Aborting, because temporary file at " << pathToTemporaryFile << " could not be created"); throw OSRMException("temporary file could not be created");
}
} }
}; };
//vector of file streams that is used to store temporary data //vector of file streams that is used to store temporary data
+11 -9
View File
@@ -23,13 +23,15 @@ or see http://www.gnu.org/licenses/agpl.txt.
//Not compatible with non contiguous node ids //Not compatible with non contiguous node ids
#include <cassert>
#include <limits>
#include <vector>
#include <algorithm>
#include <map>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <cassert>
#include <algorithm>
#include <limits>
#include <map>
#include <vector>
template< typename NodeID, typename Key > template< typename NodeID, typename Key >
class ArrayStorage { class ArrayStorage {
public: public:
@@ -145,13 +147,13 @@ public:
return insertedNodes[index].weight; return insertedNodes[index].weight;
} }
bool WasRemoved( NodeID node ) { bool WasRemoved( const NodeID node ) {
assert( WasInserted( node ) ); assert( WasInserted( node ) );
const Key index = nodeIndex[node]; const Key index = nodeIndex[node];
return insertedNodes[index].key == 0; return insertedNodes[index].key == 0;
} }
bool WasInserted( NodeID node ) { bool WasInserted( const NodeID node ) {
const Key index = nodeIndex[node]; const Key index = nodeIndex[node];
if ( index >= static_cast<Key> (insertedNodes.size()) ) if ( index >= static_cast<Key> (insertedNodes.size()) )
return false; return false;
@@ -184,8 +186,8 @@ public:
void DecreaseKey( NodeID node, Weight weight ) { void DecreaseKey( NodeID node, Weight weight ) {
assert( UINT_MAX != node ); assert( UINT_MAX != node );
const Key index = nodeIndex[node]; const Key & index = nodeIndex[node];
Key key = insertedNodes[index].key; Key & key = insertedNodes[index].key;
assert ( key >= 0 ); assert ( key >= 0 );
insertedNodes[index].weight = weight; insertedNodes[index].weight = weight;
+74 -19
View File
@@ -18,8 +18,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef COORDINATE_H_ #ifndef FIXED_POINT_COORDINATE_H_
#define COORDINATE_H_ #define FIXED_POINT_COORDINATE_H_
#include "../DataStructures/MercatorUtil.h"
#include "../Util/StringUtil.h"
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
@@ -27,11 +30,14 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <iostream> #include <iostream>
struct _Coordinate { static const double COORDINATE_PRECISION = 1000000.;
struct FixedPointCoordinate {
int lat; int lat;
int lon; int lon;
_Coordinate () : lat(INT_MIN), lon(INT_MIN) {} FixedPointCoordinate () : lat(INT_MIN), lon(INT_MIN) {}
_Coordinate (int t, int n) : lat(t) , lon(n) {} explicit FixedPointCoordinate (int lat, int lon) : lat(lat) , lon(lon) {}
void Reset() { void Reset() {
lat = INT_MIN; lat = INT_MIN;
lon = INT_MIN; lon = INT_MIN;
@@ -40,17 +46,22 @@ struct _Coordinate {
return (INT_MIN != lat) && (INT_MIN != lon); return (INT_MIN != lat) && (INT_MIN != lon);
} }
inline bool isValid() const { inline bool isValid() const {
if(lat > 90*100000 || lat < -90*100000 || lon > 180*100000 || lon <-180*100000) { if(
lat > 90*COORDINATE_PRECISION ||
lat < -90*COORDINATE_PRECISION ||
lon > 180*COORDINATE_PRECISION ||
lon < -180*COORDINATE_PRECISION
) {
return false; return false;
} }
return true; return true;
} }
bool operator==(const _Coordinate & other) const { bool operator==(const FixedPointCoordinate & other) const {
return lat == other.lat && lon == other.lon; return lat == other.lat && lon == other.lon;
} }
}; };
inline std::ostream & operator<<(std::ostream & out, const _Coordinate & c){ inline std::ostream & operator<<(std::ostream & out, const FixedPointCoordinate & c){
out << "(" << c.lat << "," << c.lon << ")"; out << "(" << c.lat << "," << c.lon << ")";
return out; return out;
} }
@@ -61,10 +72,10 @@ inline double ApproximateDistance( const int lat1, const int lon1, const int lat
assert(lat2 != INT_MIN); assert(lat2 != INT_MIN);
assert(lon2 != INT_MIN); assert(lon2 != INT_MIN);
double RAD = 0.017453292519943295769236907684886; double RAD = 0.017453292519943295769236907684886;
double lt1 = lat1/100000.; double lt1 = lat1/COORDINATE_PRECISION;
double ln1 = lon1/100000.; double ln1 = lon1/COORDINATE_PRECISION;
double lt2 = lat2/100000.; double lt2 = lat2/COORDINATE_PRECISION;
double ln2 = lon2/100000.; double ln2 = lon2/COORDINATE_PRECISION;
double dlat1=lt1*(RAD); double dlat1=lt1*(RAD);
double dlong1=ln1*(RAD); double dlong1=ln1*(RAD);
@@ -83,20 +94,20 @@ inline double ApproximateDistance( const int lat1, const int lon1, const int lat
return distance; return distance;
} }
inline double ApproximateDistance(const _Coordinate &c1, const _Coordinate &c2) { inline double ApproximateDistance(const FixedPointCoordinate &c1, const FixedPointCoordinate &c2) {
return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon ); return ApproximateDistance( c1.lat, c1.lon, c2.lat, c2.lon );
} }
inline double ApproximateDistanceByEuclid(const _Coordinate &c1, const _Coordinate &c2) { inline double ApproximateEuclideanDistance(const FixedPointCoordinate &c1, const FixedPointCoordinate &c2) {
assert(c1.lat != INT_MIN); assert(c1.lat != INT_MIN);
assert(c1.lon != INT_MIN); assert(c1.lon != INT_MIN);
assert(c2.lat != INT_MIN); assert(c2.lat != INT_MIN);
assert(c2.lon != INT_MIN); assert(c2.lon != INT_MIN);
const double RAD = 0.017453292519943295769236907684886; const double RAD = 0.017453292519943295769236907684886;
const double lat1 = (c1.lat/100000.)*RAD; const double lat1 = (c1.lat/COORDINATE_PRECISION)*RAD;
const double lon1 = (c1.lon/100000.)*RAD; const double lon1 = (c1.lon/COORDINATE_PRECISION)*RAD;
const double lat2 = (c2.lat/100000.)*RAD; const double lat2 = (c2.lat/COORDINATE_PRECISION)*RAD;
const double lon2 = (c2.lon/100000.)*RAD; const double lon2 = (c2.lon/COORDINATE_PRECISION)*RAD;
const double x = (lon2-lon1) * cos((lat1+lat2)/2.); const double x = (lon2-lon1) * cos((lat1+lat2)/2.);
const double y = (lat2-lat1); const double y = (lat2-lat1);
@@ -105,4 +116,48 @@ inline double ApproximateDistanceByEuclid(const _Coordinate &c1, const _Coordina
return d; return d;
} }
#endif /* COORDINATE_H_ */ static inline void convertInternalLatLonToString(const int value, std::string & output) {
char buffer[100];
buffer[10] = 0; // Nullterminierung
char* string = printInt< 10, 6 >( buffer, value );
output = string;
}
static inline void convertInternalCoordinateToString(const FixedPointCoordinate & coord, std::string & output) {
std::string tmp;
convertInternalLatLonToString(coord.lon, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lat, tmp);
output += tmp;
output += " ";
}
static inline void convertInternalReversedCoordinateToString(const FixedPointCoordinate & coord, std::string & output) {
std::string tmp;
convertInternalLatLonToString(coord.lat, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lon, tmp);
output += tmp;
output += " ";
}
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
template<class CoordinateT>
static inline double GetAngleBetweenThreeFixedPointCoordinates (
const CoordinateT & A,
const CoordinateT & C,
const CoordinateT & B
) {
const double v1x = (A.lon - C.lon)/COORDINATE_PRECISION;
const double v1y = lat2y(A.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
const double v2x = (B.lon - C.lon)/COORDINATE_PRECISION;
const double v2y = lat2y(B.lat/COORDINATE_PRECISION) - lat2y(C.lat/COORDINATE_PRECISION);
double angle = (atan2(v2y,v2x) - atan2(v1y,v1x) )*180/M_PI;
while(angle < 0)
angle += 360;
return angle;
}
#endif /* FIXED_POINT_COORDINATE_H_ */
+1 -1
View File
@@ -194,7 +194,7 @@ class DynamicGraph {
//searches for a specific edge //searches for a specific edge
EdgeIterator FindEdge( const NodeIterator from, const NodeIterator to ) const { EdgeIterator FindEdge( const NodeIterator from, const NodeIterator to ) const {
for ( EdgeIterator i = BeginEdges( from ), iend = EndEdges( from ); i != iend; ++i ) { for ( EdgeIterator i = BeginEdges( from ), iend = EndEdges( from ); i != iend; ++i ) {
if ( m_edges[i].target == to ) { if ( to == m_edges[i].target ) {
return i; return i;
} }
} }
-82
View File
@@ -1,82 +0,0 @@
/*
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 GRIDEDGE_H_
#define GRIDEDGE_H_
#include "Coordinate.h"
struct _GridEdge {
_GridEdge(NodeID n, NodeID na, int w, _Coordinate sc, _Coordinate tc, bool bttc) : edgeBasedNode(n), nameID(na), weight(w), startCoord(sc), targetCoord(tc), belongsToTinyComponent(bttc) {}
_GridEdge() : edgeBasedNode(UINT_MAX), nameID(UINT_MAX), weight(INT_MAX), belongsToTinyComponent(false) {}
NodeID edgeBasedNode;
NodeID nameID;
int weight;
_Coordinate startCoord;
_Coordinate targetCoord;
bool belongsToTinyComponent;
bool operator< ( const _GridEdge& right) const {
return edgeBasedNode < right.edgeBasedNode;
}
bool operator== ( const _GridEdge& right) const {
return edgeBasedNode == right.edgeBasedNode;
}
};
struct GridEntry {
GridEntry() : fileIndex(UINT_MAX), ramIndex(UINT_MAX){}
GridEntry(_GridEdge e, unsigned f, unsigned r) : edge(e), fileIndex(f), ramIndex(r) {}
_GridEdge edge;
unsigned fileIndex;
unsigned ramIndex;
bool operator< ( const GridEntry& right ) const {
return (edge.edgeBasedNode < right.edge.edgeBasedNode);
}
bool operator==( const GridEntry& right ) const {
return right.edge.edgeBasedNode == edge.edgeBasedNode;
}
};
struct CompareGridEdgeDataByFileIndex {
bool operator () (const GridEntry & a, const GridEntry & b) const {
return a.fileIndex < b.fileIndex;
}
};
struct CompareGridEdgeDataByRamIndex {
typedef GridEntry value_type;
bool operator () (const GridEntry & a, const GridEntry & b) const {
return a.ramIndex < b.ramIndex;
}
value_type max_value() {
GridEntry e;
e.ramIndex = (1024*1024) - 1;
return e;
}
value_type min_value() {
GridEntry e;
e.ramIndex = 0;
return e;
}
};
#endif /* GRIDEDGE_H_ */
+15 -36
View File
@@ -24,56 +24,35 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef HASHTABLE_H_ #ifndef HASHTABLE_H_
#define HASHTABLE_H_ #define HASHTABLE_H_
#include <boost/ref.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
template<typename keyT, typename valueT> template<typename keyT, typename valueT>
class HashTable { class HashTable : public boost::unordered_map<keyT, valueT> {
typedef boost::unordered_map<keyT, valueT> MyHashTable; private:
typedef boost::unordered_map<keyT, valueT> super;
public: public:
typedef typename boost::unordered_map<keyT, valueT>::const_iterator MyIterator; HashTable() : super() { }
typedef MyIterator iterator;
HashTable() { } HashTable(const unsigned size) : super(size) { }
HashTable(const unsigned size) {
table.resize(size);
}
inline void Add(const keyT& key, const valueT& value){ inline void Add(const keyT& key, const valueT& value){
table[key] = value; super::insert(std::make_pair(key, value));
}
inline void Set(const keyT& key, const valueT& value){
table[key] = value;
} }
inline valueT Find(const keyT& key) const { inline valueT Find(const keyT& key) const {
if(table.find(key) == table.end()) if(super::find(key) == super::end()) {
return valueT(); return valueT();
return table.find(key)->second; }
return boost::ref(super::find(key)->second);
} }
inline bool Holds(const keyT& key) const { inline bool Holds(const keyT& key) const {
if(table.find(key) == table.end()) if(super::find(key) == super::end()) {
return false; return false;
}
return true; return true;
} }
void EraseAll() {
if(table.size() > 0)
table.clear();
}
inline valueT operator[] (keyT key) const {
if(table.find(key) == table.end())
return valueT();
return table.find(key)->second;
}
inline unsigned Size() const {
return table.size();
}
MyIterator begin() const {
return table.begin();
}
MyIterator end() const {
return table.end();
}
private:
MyHashTable table;
}; };
#endif /* HASHTABLE_H_ */ #endif /* HASHTABLE_H_ */
+6 -3
View File
@@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef HILBERTVALUE_H_ #ifndef HILBERTVALUE_H_
#define HILBERTVALUE_H_ #define HILBERTVALUE_H_
#include "Coordinate.h"
#include <boost/integer.hpp> #include <boost/integer.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
@@ -29,10 +31,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
class HilbertCode : boost::noncopyable { class HilbertCode : boost::noncopyable {
public: public:
static uint64_t GetHilbertNumberForCoordinate( static uint64_t GetHilbertNumberForCoordinate(
const _Coordinate & current_coordinate) { const FixedPointCoordinate & current_coordinate
) {
unsigned location[2]; unsigned location[2];
location[0] = current_coordinate.lat+( 90*100000); location[0] = current_coordinate.lat+( 90*COORDINATE_PRECISION);
location[1] = current_coordinate.lon+(180*100000); location[1] = current_coordinate.lon+(180*COORDINATE_PRECISION);
TransposeCoordinate(location); TransposeCoordinate(location);
const uint64_t result = BitInterleaving(location[0], location[1]); const uint64_t result = BitInterleaving(location[0], location[1]);
+30 -2
View File
@@ -21,6 +21,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef EDGE_H #ifndef EDGE_H
#define EDGE_H #define EDGE_H
#include "../Util/OSRMException.h"
#include <cassert> #include <cassert>
class NodeBasedEdge { class NodeBasedEdge {
@@ -40,8 +42,34 @@ public:
return (source() < e.source()); return (source() < e.source());
} }
explicit NodeBasedEdge(NodeID s, NodeID t, NodeID n, EdgeWeight w, bool f, bool b, short ty, bool ra, bool ig, bool ar, bool cf) : explicit NodeBasedEdge(
_source(s), _target(t), _name(n), _weight(w), forward(f), backward(b), _type(ty), _roundabout(ra), _ignoreInGrid(ig), _accessRestricted(ar), _contraFlow(cf) { if(ty < 0) {ERR("Type: " << ty);}; } NodeID s,
NodeID t,
NodeID n,
EdgeWeight w,
bool f,
bool b,
short ty,
bool ra,
bool ig,
bool ar,
bool cf
) : _source(s),
_target(t),
_name(n),
_weight(w),
forward(f),
backward(b),
_type(ty),
_roundabout(ra),
_ignoreInGrid(ig),
_accessRestricted(ar),
_contraFlow(cf)
{
if(ty < 0) {
throw OSRMException("negative edge type");
}
}
NodeID target() const {return _target; } NodeID target() const {return _target; }
NodeID source() const {return _source; } NodeID source() const {return _source; }
+3 -3
View File
@@ -21,7 +21,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef IMPORTNODE_H_ #ifndef IMPORTNODE_H_
#define IMPORTNODE_H_ #define IMPORTNODE_H_
#include "NodeCoords.h" #include "QueryNode.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
@@ -44,9 +44,9 @@ struct _Node : NodeInfo{
struct ImportNode : public _Node { struct ImportNode : public _Node {
HashTable<std::string, std::string> keyVals; HashTable<std::string, std::string> keyVals;
inline void Clear() { inline void Clear() {
keyVals.EraseAll(); keyVals.clear();
lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false; lat = 0; lon = 0; id = 0; bollard = false; trafficLight = false;
} }
}; };
-602
View File
@@ -1,602 +0,0 @@
/*
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 NNGRID_H_
#define NNGRID_H_
#include <cassert>
#include <cfloat>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <fstream>
#include <limits>
#include <vector>
#ifndef ROUTED
#include <stxxl.h>
#endif
#ifdef _WIN32
#include <math.h>
#endif
#include <boost/thread.hpp>
#include <boost/foreach.hpp>
#include <boost/unordered_map.hpp>
#include "DeallocatingVector.h"
#include "GridEdge.h"
#include "Percent.h"
#include "PhantomNodes.h"
#include "MercatorUtil.h"
#include "StaticGraph.h"
#include "TimingUtil.h"
#include "../Algorithms/Bresenham.h"
namespace NNGrid{
static boost::thread_specific_ptr<std::ifstream> localStream;
template<bool WriteAccess = false>
class NNGrid {
public:
NNGrid() /*: cellCache(500), fileCache(500)*/ {
ramIndexTable.resize((1024*1024), std::numeric_limits<uint64_t>::max());
}
NNGrid(const char* rif, const char* _i) {
if(WriteAccess) {
ERR("Not available in Write mode");
}
iif = std::string(_i);
ramIndexTable.resize((1024*1024), std::numeric_limits<uint64_t>::max());
ramInFile.open(rif, std::ios::in | std::ios::binary);
if(!ramInFile) { ERR(rif << " not found"); }
}
~NNGrid() {
if(ramInFile.is_open()) ramInFile.close();
#ifndef ROUTED
if (WriteAccess) {
entries.clear();
}
#endif
if(localStream.get() && localStream->is_open()) {
localStream->close();
}
}
void OpenIndexFiles() {
assert(ramInFile.is_open());
ramInFile.read(static_cast<char*>(static_cast<void*>(&ramIndexTable[0]) ), sizeof(uint64_t)*1024*1024);
ramInFile.close();
}
#ifndef ROUTED
template<typename EdgeT>
inline void ConstructGrid(DeallocatingVector<EdgeT> & edgeList, const char * ramIndexOut, const char * fileIndexOut) {
//TODO: Implement this using STXXL-Streams
Percent p(edgeList.size());
BOOST_FOREACH(EdgeT & edge, edgeList) {
p.printIncrement();
if(edge.ignoreInGrid)
continue;
int slat = 100000*lat2y(edge.lat1/100000.);
int slon = edge.lon1;
int tlat = 100000*lat2y(edge.lat2/100000.);
int tlon = edge.lon2;
AddEdge( _GridEdge( edge.id, edge.nameID, edge.weight, _Coordinate(slat, slon), _Coordinate(tlat, tlon), edge.belongsToTinyComponent ) );
}
if( 0 == entries.size() ) {
ERR("No viable edges for nearest neighbor index. Aborting");
}
double timestamp = get_timestamp();
//create index file on disk, old one is over written
indexOutFile.open(fileIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
//sort entries
stxxl::sort(entries.begin(), entries.end(), CompareGridEdgeDataByRamIndex(), 1024*1024*1024);
INFO("finished sorting after " << (get_timestamp() - timestamp) << "s");
std::vector<GridEntry> entriesInFileWithRAMSameIndex;
unsigned indexInRamTable = entries.begin()->ramIndex;
uint64_t lastPositionInIndexFile = 0;
std::cout << "writing data ..." << std::flush;
p.reinit(entries.size());
boost::unordered_map< unsigned, unsigned > cellMap(1024);
BOOST_FOREACH(GridEntry & gridEntry, entries) {
p.printIncrement();
if(gridEntry.ramIndex != indexInRamTable) {
cellMap.clear();
BuildCellIndexToFileIndexMap(indexInRamTable, cellMap);
unsigned numberOfBytesInCell = FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile, cellMap);
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
lastPositionInIndexFile += numberOfBytesInCell;
entriesInFileWithRAMSameIndex.clear();
indexInRamTable = gridEntry.ramIndex;
}
entriesInFileWithRAMSameIndex.push_back(gridEntry);
}
cellMap.clear();
BuildCellIndexToFileIndexMap(indexInRamTable, cellMap);
/*unsigned numberOfBytesInCell = */FillCell(entriesInFileWithRAMSameIndex, lastPositionInIndexFile, cellMap);
ramIndexTable[indexInRamTable] = lastPositionInIndexFile;
entriesInFileWithRAMSameIndex.clear();
std::vector<GridEntry>().swap(entriesInFileWithRAMSameIndex);
assert(entriesInFileWithRAMSameIndex.size() == 0);
//close index file
indexOutFile.close();
//Serialize RAM Index
std::ofstream ramFile(ramIndexOut, std::ios::out | std::ios::binary | std::ios::trunc);
//write 4 MB of index Table in RAM
ramFile.write((char *)&ramIndexTable[0], sizeof(uint64_t)*1024*1024 );
//close ram index file
ramFile.close();
}
#endif
inline bool CoordinatesAreEquivalent(const _Coordinate & a, const _Coordinate & b, const _Coordinate & c, const _Coordinate & d) const {
return (a == b && c == d) || (a == c && b == d) || (a == d && b == c);
}
bool FindPhantomNodeForCoordinate( const _Coordinate & location, PhantomNode & resultNode, const unsigned zoomLevel) {
bool ignoreTinyComponents = (zoomLevel <= 14);
// INFO("Coordinate: " << location << ", zoomLevel: " << zoomLevel << ", ignoring tinyComponentents: " << (ignoreTinyComponents ? "yes" : "no"));
// double time1 = get_timestamp();
bool foundNode = false;
const _Coordinate startCoord(100000*(lat2y(static_cast<double>(location.lat)/100000.)), location.lon);
/** search for point on edge close to source */
const unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
const int lowerBoundForLoop = (fileIndex < 32768 ? 0 : -32768);
for(int j = lowerBoundForLoop; (j < (32768+1)) && (fileIndex != UINT_MAX); j+=32768) {
for(int i = -1; i < 2; ++i){
// unsigned oldSize = candidates.size();
GetContentsOfFileBucketEnumerated(fileIndex+i+j, candidates);
// INFO("Getting fileIndex=" << fileIndex+i+j << " with " << candidates.size() - oldSize << " candidates");
}
}
// INFO("looked up " << candidates.size());
_GridEdge smallestEdge;
_Coordinate tmp, edgeStartCoord, edgeEndCoord;
double dist = std::numeric_limits<double>::max();
double r, tmpDist;
BOOST_FOREACH(const _GridEdge & candidate, candidates) {
if(candidate.belongsToTinyComponent && ignoreTinyComponents)
continue;
r = 0.;
tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
// INFO("dist " << startCoord << "->[" << candidate.startCoord << "-" << candidate.targetCoord << "]=" << tmpDist );
// INFO("Looking at edge " << candidate.edgeBasedNode << " at distance " << tmpDist);
if(tmpDist < dist && !DoubleEpsilonCompare(dist, tmpDist)) {
// INFO("a) " << candidate.edgeBasedNode << ", dist: " << tmpDist << ", tinyCC: " << (candidate.belongsToTinyComponent ? "yes" : "no"));
dist = tmpDist;
resultNode.edgeBasedNode = candidate.edgeBasedNode;
resultNode.nodeBasedEdgeNameID = candidate.nameID;
resultNode.weight1 = candidate.weight;
resultNode.weight2 = INT_MAX;
resultNode.location.lat = tmp.lat;
resultNode.location.lon = tmp.lon;
edgeStartCoord = candidate.startCoord;
edgeEndCoord = candidate.targetCoord;
foundNode = true;
smallestEdge = candidate;
//} else if(tmpDist < dist) {
//INFO("a) ignored " << candidate.edgeBasedNode << " at distance " << std::fabs(dist - tmpDist));
} else if(DoubleEpsilonCompare(dist, tmpDist) && 1 == std::abs(static_cast<int>(candidate.edgeBasedNode)-static_cast<int>(resultNode.edgeBasedNode) ) && CoordinatesAreEquivalent(edgeStartCoord, candidate.startCoord, edgeEndCoord, candidate.targetCoord)) {
resultNode.edgeBasedNode = std::min(candidate.edgeBasedNode, resultNode.edgeBasedNode);
resultNode.weight2 = candidate.weight;
//INFO("b) " << candidate.edgeBasedNode << ", dist: " << tmpDist);
}
}
// INFO("startcoord: " << smallestEdge.startCoord << ", tgtcoord" << smallestEdge.targetCoord << "result: " << newEndpoint);
// INFO("length of old edge: " << ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
// INFO("Length of new edge: " << ApproximateDistance(smallestEdge.startCoord, newEndpoint));
// assert(!resultNode.isBidirected() || (resultNode.weight1 == resultNode.weight2));
// if(resultNode.weight1 != resultNode.weight2) {
// INFO("-> Weight1: " << resultNode.weight1 << ", weight2: " << resultNode.weight2);
// INFO("-> node: " << resultNode.edgeBasedNode << ", bidir: " << (resultNode.isBidirected() ? "yes" : "no"));
// }
// INFO("startCoord: " << smallestEdge.startCoord << "; targetCoord: " << smallestEdge.targetCoord << "; newEndpoint: " << resultNode.location);
const double ratio = (foundNode ? std::min(1., ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord)) : 0);
resultNode.location.lat = round(100000.*(y2lat(static_cast<double>(resultNode.location.lat)/100000.)));
// INFO("Length of vector: " << ApproximateDistance(smallestEdge.startCoord, resultNode.location)/ApproximateDistance(smallestEdge.startCoord, smallestEdge.targetCoord));
//Hack to fix rounding errors and wandering via nodes.
if(std::abs(location.lon - resultNode.location.lon) == 1)
resultNode.location.lon = location.lon;
if(std::abs(location.lat - resultNode.location.lat) == 1)
resultNode.location.lat = location.lat;
resultNode.weight1 *= ratio;
if(INT_MAX != resultNode.weight2) {
resultNode.weight2 *= (1.-ratio);
}
resultNode.ratio = ratio;
// INFO("start: " << edgeStartCoord << ", end: " << edgeEndCoord);
// INFO("selected node: " << resultNode.edgeBasedNode << ", bidirected: " << (resultNode.isBidirected() ? "yes" : "no"));
// INFO("New weight1: " << resultNode.weight1 << ", new weight2: " << resultNode.weight2 << ", ratio: " << ratio);
// INFO("distance to input coordinate: " << ApproximateDistance(location, resultNode.location) << "\n--");
// double time2 = get_timestamp();
// INFO("NN-Lookup in " << 1000*(time2-time1) << "ms");
return foundNode;
}
bool FindRoutingStarts(const _Coordinate& start, const _Coordinate& target, PhantomNodes & routingStarts, unsigned zoomLevel) {
routingStarts.Reset();
return (FindPhantomNodeForCoordinate( start, routingStarts.startPhantom, zoomLevel) &&
FindPhantomNodeForCoordinate( target, routingStarts.targetPhantom, zoomLevel) );
}
bool FindNearestCoordinateOnEdgeInNodeBasedGraph(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate, unsigned zoomLevel = 18) {
PhantomNode resultNode;
bool foundNode = FindPhantomNodeForCoordinate(inputCoordinate, resultNode, zoomLevel);
outputCoordinate = resultNode.location;
return foundNode;
}
void FindNearestPointOnEdge(const _Coordinate& inputCoordinate, _Coordinate& outputCoordinate) {
_Coordinate startCoord(100000*(lat2y(static_cast<double>(inputCoordinate.lat)/100000.)), inputCoordinate.lon);
unsigned fileIndex = GetFileIndexForLatLon(startCoord.lat, startCoord.lon);
std::vector<_GridEdge> candidates;
boost::unordered_map< unsigned, unsigned > cellMap;
for(int j = -32768; j < (32768+1); j+=32768) {
for(int i = -1; i < 2; ++i) {
GetContentsOfFileBucket(fileIndex+i+j, candidates, cellMap);
}
}
_Coordinate tmp;
double dist = (std::numeric_limits<double>::max)();
BOOST_FOREACH(const _GridEdge & candidate, candidates) {
double r = 0.;
double tmpDist = ComputeDistance(startCoord, candidate.startCoord, candidate.targetCoord, tmp, &r);
if(tmpDist < dist) {
dist = tmpDist;
outputCoordinate.lat = round(100000*(y2lat(static_cast<double>(tmp.lat)/100000.)));
outputCoordinate.lon = tmp.lon;
}
}
}
private:
inline unsigned GetCellIndexFromRAMAndFileIndex(const unsigned ramIndex, const unsigned fileIndex) const {
unsigned lineBase = ramIndex/1024;
lineBase = lineBase*32*32768;
unsigned columnBase = ramIndex%1024;
columnBase=columnBase*32;
for (int i = 0;i < 32;++i) {
for (int j = 0;j < 32;++j) {
const unsigned localFileIndex = lineBase + i * 32768 + columnBase + j;
if(localFileIndex == fileIndex) {
unsigned cellIndex = i * 32 + j;
return cellIndex;
}
}
}
return UINT_MAX;
}
inline void BuildCellIndexToFileIndexMap(const unsigned ramIndex, boost::unordered_map<unsigned, unsigned >& cellMap){
unsigned lineBase = ramIndex/1024;
lineBase = lineBase*32*32768;
unsigned columnBase = ramIndex%1024;
columnBase=columnBase*32;
std::vector<std::pair<unsigned, unsigned> >insertionVector(1024);
for (int i = 0;i < 32;++i) {
for (int j = 0;j < 32;++j) {
unsigned fileIndex = lineBase + i * 32768 + columnBase + j;
unsigned cellIndex = i * 32 + j;
insertionVector[i * 32 + j] = std::make_pair(fileIndex, cellIndex);
}
}
cellMap.insert(insertionVector.begin(), insertionVector.end());
}
inline bool DoubleEpsilonCompare(const double d1, const double d2) const {
return (std::fabs(d1 - d2) < FLT_EPSILON);
}
#ifndef ROUTED
inline unsigned FillCell(std::vector<GridEntry>& entriesWithSameRAMIndex, const uint64_t fileOffset, boost::unordered_map< unsigned, unsigned > & cellMap ) {
std::vector<char> tmpBuffer(32*32*4096,0);
uint64_t indexIntoTmpBuffer = 0;
unsigned numberOfWrittenBytes = 0;
assert(indexOutFile.is_open());
std::vector<uint64_t> cellIndex(32*32,std::numeric_limits<uint64_t>::max());
for(unsigned i = 0; i < entriesWithSameRAMIndex.size() -1; ++i) {
assert(entriesWithSameRAMIndex[i].ramIndex== entriesWithSameRAMIndex[i+1].ramIndex);
}
//sort & unique
std::sort(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end(), CompareGridEdgeDataByFileIndex());
// entriesWithSameRAMIndex.erase(std::unique(entriesWithSameRAMIndex.begin(), entriesWithSameRAMIndex.end()), entriesWithSameRAMIndex.end());
//traverse each file bucket and write its contents to disk
std::vector<GridEntry> entriesWithSameFileIndex;
unsigned fileIndex = entriesWithSameRAMIndex.begin()->fileIndex;
BOOST_FOREACH(GridEntry & gridEntry, entriesWithSameRAMIndex) {
assert(cellMap.find(gridEntry.fileIndex) != cellMap.end() ); //asserting that file index belongs to cell index
if(gridEntry.fileIndex != fileIndex) {
// start in cellIndex vermerken
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
int localCellIndex = cellMap.find(localFileIndex)->second;
assert(cellMap.find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap.end());
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
fileIndex = gridEntry.fileIndex;
}
entriesWithSameFileIndex.push_back(gridEntry);
}
assert(cellMap.find(entriesWithSameFileIndex.begin()->fileIndex) != cellMap.end());
int localFileIndex = entriesWithSameFileIndex.begin()->fileIndex;
int localCellIndex = cellMap.find(localFileIndex)->second;
cellIndex[localCellIndex] = indexIntoTmpBuffer + fileOffset;
indexIntoTmpBuffer += FlushEntriesWithSameFileIndexToBuffer(entriesWithSameFileIndex, tmpBuffer, indexIntoTmpBuffer);
assert(entriesWithSameFileIndex.size() == 0);
indexOutFile.write(static_cast<char*>(static_cast<void*>(&cellIndex[0])),32*32*sizeof(uint64_t));
numberOfWrittenBytes += 32*32*sizeof(uint64_t);
//write contents of tmpbuffer to disk
indexOutFile.write(&tmpBuffer[0], indexIntoTmpBuffer*sizeof(char));
numberOfWrittenBytes += indexIntoTmpBuffer*sizeof(char);
return numberOfWrittenBytes;
}
inline unsigned FlushEntriesWithSameFileIndexToBuffer( std::vector<GridEntry> &vectorWithSameFileIndex, std::vector<char> & tmpBuffer, const uint64_t index) const {
sort( vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end() );
vectorWithSameFileIndex.erase(unique(vectorWithSameFileIndex.begin(), vectorWithSameFileIndex.end()), vectorWithSameFileIndex.end());
const unsigned lengthOfBucket = vectorWithSameFileIndex.size();
tmpBuffer.resize(tmpBuffer.size()+(sizeof(_GridEdge)*lengthOfBucket) + sizeof(unsigned) );
unsigned counter = 0;
for(unsigned i = 0; i < vectorWithSameFileIndex.size()-1; ++i) {
assert( vectorWithSameFileIndex[i].fileIndex == vectorWithSameFileIndex[i+1].fileIndex );
assert( vectorWithSameFileIndex[i].ramIndex == vectorWithSameFileIndex[i+1].ramIndex );
}
//write length of bucket
memcpy((char*)&(tmpBuffer[index+counter]), (char*)&lengthOfBucket, sizeof(lengthOfBucket));
counter += sizeof(lengthOfBucket);
BOOST_FOREACH(const GridEntry & entry, vectorWithSameFileIndex) {
char * data = (char*)&(entry.edge);
memcpy(static_cast<char*>(static_cast<void*>(&(tmpBuffer[index+counter]) )), data, sizeof(entry.edge));
counter += sizeof(entry.edge);
}
//Freeing data
vectorWithSameFileIndex.clear();
return counter;
}
#endif
inline void GetContentsOfFileBucketEnumerated(const unsigned fileIndex, std::vector<_GridEdge>& result) const {
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
uint64_t startIndexInFile = ramIndexTable[ramIndex];
if(startIndexInFile == std::numeric_limits<uint64_t>::max()) {
return;
}
unsigned enumeratedIndex = GetCellIndexFromRAMAndFileIndex(ramIndex, fileIndex);
if(!localStream.get() || !localStream->is_open()) {
localStream.reset(new std::ifstream(iif.c_str(), std::ios::in | std::ios::binary));
}
if(!localStream->good()) {
localStream->clear(std::ios::goodbit);
DEBUG("Resetting stale filestream");
}
//only read the single necessary cell index
localStream->seekg(startIndexInFile+(enumeratedIndex*sizeof(uint64_t)));
uint64_t fetchedIndex = 0;
localStream->read(static_cast<char*>( static_cast<void*>(&fetchedIndex)), sizeof(uint64_t));
if(fetchedIndex == std::numeric_limits<uint64_t>::max()) {
return;
}
const uint64_t position = fetchedIndex + 32*32*sizeof(uint64_t) ;
unsigned lengthOfBucket;
unsigned currentSizeOfResult = result.size();
localStream->seekg(position);
localStream->read(static_cast<char*>( static_cast<void*>(&(lengthOfBucket))), sizeof(unsigned));
result.resize(currentSizeOfResult+lengthOfBucket);
localStream->read(static_cast<char*>( static_cast<void*>(&result[currentSizeOfResult])), lengthOfBucket*sizeof(_GridEdge));
}
inline void GetContentsOfFileBucket(const unsigned fileIndex, std::vector<_GridEdge>& result, boost::unordered_map< unsigned, unsigned> & cellMap) {
unsigned ramIndex = GetRAMIndexFromFileIndex(fileIndex);
uint64_t startIndexInFile = ramIndexTable[ramIndex];
if(startIndexInFile == std::numeric_limits<uint64_t>::max()) {
return;
}
uint64_t cellIndex[32*32];
cellMap.clear();
BuildCellIndexToFileIndexMap(ramIndex, cellMap);
if(!localStream.get() || !localStream->is_open()) {
localStream.reset(new std::ifstream(iif.c_str(), std::ios::in | std::ios::binary));
}
if(!localStream->good()) {
localStream->clear(std::ios::goodbit);
DEBUG("Resetting stale filestream");
}
localStream->seekg(startIndexInFile);
localStream->read(static_cast<char*>(static_cast<void*>( cellIndex)), 32*32*sizeof(uint64_t));
assert(cellMap.find(fileIndex) != cellMap.end());
if(cellIndex[cellMap[fileIndex]] == std::numeric_limits<uint64_t>::max()) {
return;
}
const uint64_t position = cellIndex[cellMap[fileIndex]] + 32*32*sizeof(uint64_t) ;
unsigned lengthOfBucket;
unsigned currentSizeOfResult = result.size();
localStream->seekg(position);
localStream->read(static_cast<char*>(static_cast<void*>(&(lengthOfBucket))), sizeof(unsigned));
result.resize(currentSizeOfResult+lengthOfBucket);
localStream->read(static_cast<char*>(static_cast<void*>(&result[currentSizeOfResult])), lengthOfBucket*sizeof(_GridEdge));
}
#ifndef ROUTED
inline void AddEdge(const _GridEdge & edge) {
std::vector<BresenhamPixel> indexList;
GetListOfIndexesForEdgeAndGridSize(edge.startCoord, edge.targetCoord, indexList);
for(unsigned i = 0; i < indexList.size(); ++i) {
entries.push_back(GridEntry(edge, indexList[i].first, indexList[i].second));
}
}
#endif
inline double ComputeDistance(const _Coordinate& inputPoint, const _Coordinate& source, const _Coordinate& target, _Coordinate& nearest, double *r) {
// INFO("comparing point " << inputPoint << " to edge [" << source << "-" << target << "]");
const double x = static_cast<double>(inputPoint.lat);
const double y = static_cast<double>(inputPoint.lon);
const double a = static_cast<double>(source.lat);
const double b = static_cast<double>(source.lon);
const double c = static_cast<double>(target.lat);
const double d = static_cast<double>(target.lon);
double p,q,mX,nY;
// INFO("x=" << x << ", y=" << y << ", a=" << a << ", b=" << b << ", c=" << c << ", d=" << d);
if(fabs(a-c) > FLT_EPSILON){
const double m = (d-b)/(c-a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x + (m*y)) + (m*m*a - m*b))/(1. + m*m);
q = b + m*(p - a);
}
else{
p = c;
q = y;
}
nY = (d*p - c*q)/(a*d - b*c);
mX = (p - nY*a)/c;// These values are actually n/m+n and m/m+n , we neednot calculate the values of m an n as we are just interested in the ratio
// INFO("p=" << p << ", q=" << q << ", nY=" << nY << ", mX=" << mX);
if(std::isnan(mX)) {
*r = (target == inputPoint) ? 1. : 0.;
} else {
*r = mX;
}
// INFO("r=" << *r);
if(*r<=0.){
nearest.lat = source.lat;
nearest.lon = source.lon;
// INFO("a returning distance " << ((b - y)*(b - y) + (a - x)*(a - x)))
return ((b - y)*(b - y) + (a - x)*(a - x));
}
else if(*r >= 1.){
nearest.lat = target.lat;
nearest.lon = target.lon;
// INFO("b returning distance " << ((d - y)*(d - y) + (c - x)*(c - x)))
return ((d - y)*(d - y) + (c - x)*(c - x));
}
// point lies in between
nearest.lat = p;
nearest.lon = q;
// INFO("c returning distance " << (p-x)*(p-x) + (q-y)*(q-y))
return (p-x)*(p-x) + (q-y)*(q-y);
}
inline void GetListOfIndexesForEdgeAndGridSize(const _Coordinate& start, const _Coordinate& target, std::vector<BresenhamPixel> &indexList) const {
double lat1 = start.lat/100000.;
double lon1 = start.lon/100000.;
double x1 = ( lon1 + 180.0 ) / 360.0;
double y1 = ( lat1 + 180.0 ) / 360.0;
double lat2 = target.lat/100000.;
double lon2 = target.lon/100000.;
double x2 = ( lon2 + 180.0 ) / 360.0;
double y2 = ( lat2 + 180.0 ) / 360.0;
Bresenham(x1*32768, y1*32768, x2*32768, y2*32768, indexList);
BOOST_FOREACH(BresenhamPixel & pixel, indexList) {
int fileIndex = (pixel.second-1)*32768 + pixel.first;
int ramIndex = GetRAMIndexFromFileIndex(fileIndex);
pixel.first = fileIndex;
pixel.second = ramIndex;
}
}
inline unsigned GetFileIndexForLatLon(const int lt, const int ln) const {
double lat = lt/100000.;
double lon = ln/100000.;
double x = ( lon + 180.0 ) / 360.0;
double y = ( lat + 180.0 ) / 360.0;
if( x>1.0 || x < 0.)
return UINT_MAX;
if( y>1.0 || y < 0.)
return UINT_MAX;
unsigned line = (32768 * (32768-1))*y;
line = line - (line % 32768);
assert(line % 32768 == 0);
unsigned column = 32768.*x;
unsigned fileIndex = line+column;
return fileIndex;
}
inline unsigned GetRAMIndexFromFileIndex(const int fileIndex) const {
unsigned fileLine = fileIndex / 32768;
fileLine = fileLine / 32;
fileLine = fileLine * 1024;
unsigned fileColumn = (fileIndex % 32768);
fileColumn = fileColumn / 32;
unsigned ramIndex = fileLine + fileColumn;
assert(ramIndex < 1024*1024);
return ramIndex;
}
const static uint64_t END_OF_BUCKET_DELIMITER = boost::integer_traits<uint64_t>::const_max;
std::ifstream ramInFile;
#ifndef ROUTED
std::ofstream indexOutFile;
stxxl::vector<GridEntry> entries;
#endif
std::vector<uint64_t> ramIndexTable; //8 MB for first level index in RAM
std::string iif;
// LRUCache<int,std::vector<unsigned> > cellCache;
// LRUCache<int,std::vector<_Edge> > fileCache;
};
}
typedef NNGrid::NNGrid<false> ReadOnlyGrid;
typedef NNGrid::NNGrid<true > WritableGrid;
#endif /* NNGRID_H_ */
+92 -47
View File
@@ -21,30 +21,48 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef NODEINFORMATIONHELPDESK_H_ #ifndef NODEINFORMATIONHELPDESK_H_
#define NODEINFORMATIONHELPDESK_H_ #define NODEINFORMATIONHELPDESK_H_
#include "NodeCoords.h" #include "QueryNode.h"
#include "PhantomNodes.h" #include "PhantomNodes.h"
#include "QueryEdge.h"
#include "StaticRTree.h" #include "StaticRTree.h"
#include "../Contractor/EdgeBasedGraphFactory.h" #include "../Contractor/EdgeBasedGraphFactory.h"
#include "../Util/OSRMException.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <fstream>
#include <iostream> #include <iostream>
#include <string>
#include <vector> #include <vector>
typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf; typedef EdgeBasedGraphFactory::EdgeBasedNode RTreeLeaf;
class NodeInformationHelpDesk : boost::noncopyable{ class NodeInformationHelpDesk : boost::noncopyable {
public: public:
NodeInformationHelpDesk( NodeInformationHelpDesk(
const char* ramIndexInput, const std::string & ramIndexInput,
const char* fileIndexInput, const std::string & fileIndexInput,
const std::string & nodes_filename,
const std::string & edges_filename,
const unsigned number_of_nodes, const unsigned number_of_nodes,
const unsigned crc) : number_of_nodes(number_of_nodes), checkSum(crc) { const unsigned check_sum
) : number_of_nodes(number_of_nodes), check_sum(check_sum)
{
if ( ramIndexInput.empty() ) {
throw OSRMException("no ram index file name in server ini");
}
if ( fileIndexInput.empty() ) {
throw OSRMException("no mem index file name in server ini");
}
if ( nodes_filename.empty() ) {
throw OSRMException("no nodes file name in server ini");
}
if ( edges_filename.empty() ) {
throw OSRMException("no edges file name in server ini");
}
read_only_rtree = new StaticRTree<RTreeLeaf>( read_only_rtree = new StaticRTree<RTreeLeaf>(
ramIndexInput, ramIndexInput,
fileIndexInput fileIndexInput
@@ -53,6 +71,8 @@ public:
0 == coordinateVector.size(), 0 == coordinateVector.size(),
"Coordinate vector not empty" "Coordinate vector not empty"
); );
LoadNodesAndEdges(nodes_filename, edges_filename);
} }
//Todo: Shared memory mechanism //Todo: Shared memory mechanism
@@ -60,38 +80,6 @@ public:
delete read_only_rtree; delete read_only_rtree;
} }
void initNNGrid(
std::ifstream& nodesInstream,
std::ifstream& edgesInStream
) {
DEBUG("Loading node data");
NodeInfo b;
while(!nodesInstream.eof()) {
nodesInstream.read((char *)&b, sizeof(NodeInfo));
coordinateVector.push_back(_Coordinate(b.lat, b.lon));
}
std::vector<_Coordinate>(coordinateVector).swap(coordinateVector);
nodesInstream.close();
DEBUG("Loading edge data");
unsigned numberOfOrigEdges(0);
edgesInStream.read((char*)&numberOfOrigEdges, sizeof(unsigned));
origEdgeData_viaNode.resize(numberOfOrigEdges);
origEdgeData_nameID.resize(numberOfOrigEdges);
origEdgeData_turnInstruction.resize(numberOfOrigEdges);
OriginalEdgeData deserialized_originalEdgeData;
for(unsigned i = 0; i < numberOfOrigEdges; ++i) {
edgesInStream.read((char*)&(deserialized_originalEdgeData), sizeof(OriginalEdgeData));
origEdgeData_viaNode[i] = deserialized_originalEdgeData.viaNode;
origEdgeData_nameID[i] = deserialized_originalEdgeData.nameID;
origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction;
}
edgesInStream.close();
DEBUG("Loaded " << numberOfOrigEdges << " orig edges");
DEBUG("Opening NN indices");
}
inline int getLatitudeOfNode(const unsigned id) const { inline int getLatitudeOfNode(const unsigned id) const {
const NodeID node = origEdgeData_viaNode.at(id); const NodeID node = origEdgeData_viaNode.at(id);
return coordinateVector.at(node).lat; return coordinateVector.at(node).lat;
@@ -119,18 +107,21 @@ public:
} }
inline bool FindNearestNodeCoordForLatLon( inline bool FindNearestNodeCoordForLatLon(
const _Coordinate& input_coordinate, const FixedPointCoordinate& input_coordinate,
_Coordinate& result, FixedPointCoordinate& result,
const unsigned zoom_level = 18 const unsigned zoom_level = 18
) const { ) const {
PhantomNode resulting_phantom_node; PhantomNode resulting_phantom_node;
bool foundNode = FindPhantomNodeForCoordinate(input_coordinate, resulting_phantom_node, zoom_level); bool foundNode = FindPhantomNodeForCoordinate(
input_coordinate,
resulting_phantom_node, zoom_level
);
result = resulting_phantom_node.location; result = resulting_phantom_node.location;
return foundNode; return foundNode;
} }
inline bool FindPhantomNodeForCoordinate( inline bool FindPhantomNodeForCoordinate(
const _Coordinate & input_coordinate, const FixedPointCoordinate & input_coordinate,
PhantomNode & resulting_phantom_node, PhantomNode & resulting_phantom_node,
const unsigned zoom_level const unsigned zoom_level
) const { ) const {
@@ -142,18 +133,72 @@ public:
} }
inline unsigned GetCheckSum() const { inline unsigned GetCheckSum() const {
return checkSum; return check_sum;
} }
private: private:
std::vector<_Coordinate> coordinateVector; void LoadNodesAndEdges(
const std::string & nodes_filename,
const std::string & edges_filename
) {
boost::filesystem::path nodes_file(nodes_filename);
if ( !boost::filesystem::exists( nodes_file ) ) {
throw OSRMException("nodes file does not exist");
}
if ( 0 == boost::filesystem::file_size( nodes_file ) ) {
throw OSRMException("nodes file is empty");
}
boost::filesystem::path edges_file(edges_filename);
if ( !boost::filesystem::exists( edges_file ) ) {
throw OSRMException("edges file does not exist");
}
if ( 0 == boost::filesystem::file_size( edges_file ) ) {
throw OSRMException("edges file is empty");
}
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
boost::filesystem::ifstream edges_input_stream(edges_file, std::ios::binary);
SimpleLogger().Write(logDEBUG) << "Loading node data";
NodeInfo b;
while(!nodes_input_stream.eof()) {
nodes_input_stream.read((char *)&b, sizeof(NodeInfo));
coordinateVector.push_back(FixedPointCoordinate(b.lat, b.lon));
}
std::vector<FixedPointCoordinate>(coordinateVector).swap(coordinateVector);
nodes_input_stream.close();
SimpleLogger().Write(logDEBUG) << "Loading edge data";
unsigned numberOfOrigEdges(0);
edges_input_stream.read((char*)&numberOfOrigEdges, sizeof(unsigned));
origEdgeData_viaNode.resize(numberOfOrigEdges);
origEdgeData_nameID.resize(numberOfOrigEdges);
origEdgeData_turnInstruction.resize(numberOfOrigEdges);
OriginalEdgeData deserialized_originalEdgeData;
for(unsigned i = 0; i < numberOfOrigEdges; ++i) {
edges_input_stream.read(
(char*)&(deserialized_originalEdgeData),
sizeof(OriginalEdgeData)
);
origEdgeData_viaNode[i] = deserialized_originalEdgeData.viaNode;
origEdgeData_nameID[i] = deserialized_originalEdgeData.nameID;
origEdgeData_turnInstruction[i] = deserialized_originalEdgeData.turnInstruction;
}
edges_input_stream.close();
SimpleLogger().Write(logDEBUG) << "Loaded " << numberOfOrigEdges << " orig edges";
SimpleLogger().Write(logDEBUG) << "Opening NN indices";
}
std::vector<FixedPointCoordinate> coordinateVector;
std::vector<NodeID> origEdgeData_viaNode; std::vector<NodeID> origEdgeData_viaNode;
std::vector<unsigned> origEdgeData_nameID; std::vector<unsigned> origEdgeData_nameID;
std::vector<TurnInstruction> origEdgeData_turnInstruction; std::vector<TurnInstruction> origEdgeData_turnInstruction;
StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * read_only_rtree; StaticRTree<EdgeBasedGraphFactory::EdgeBasedNode> * read_only_rtree;
const unsigned number_of_nodes; const unsigned number_of_nodes;
const unsigned checkSum; const unsigned check_sum;
}; };
#endif /*NODEINFORMATIONHELPDESK_H_*/ #endif /*NODEINFORMATIONHELPDESK_H_*/
+1 -1
View File
@@ -21,9 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef PERCENT_H #ifndef PERCENT_H
#define PERCENT_H #define PERCENT_H
#include "../Util/OpenMPWrapper.h"
#include <iostream> #include <iostream>
class Percent class Percent
{ {
public: public:
+10 -3
View File
@@ -24,13 +24,20 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "Coordinate.h" #include "Coordinate.h"
struct PhantomNode { struct PhantomNode {
PhantomNode() : edgeBasedNode(UINT_MAX), nodeBasedEdgeNameID(UINT_MAX), weight1(INT_MAX), weight2(INT_MAX), ratio(0.) {} PhantomNode() :
edgeBasedNode(UINT_MAX),
nodeBasedEdgeNameID(UINT_MAX),
weight1(INT_MAX),
weight2(INT_MAX),
ratio(0.)
{ }
NodeID edgeBasedNode; NodeID edgeBasedNode;
unsigned nodeBasedEdgeNameID; unsigned nodeBasedEdgeNameID;
int weight1; int weight1;
int weight2; int weight2;
double ratio; double ratio;
_Coordinate location; FixedPointCoordinate location;
void Reset() { void Reset() {
edgeBasedNode = UINT_MAX; edgeBasedNode = UINT_MAX;
nodeBasedEdgeNameID = UINT_MAX; nodeBasedEdgeNameID = UINT_MAX;
@@ -88,7 +95,7 @@ inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn){
struct NodesOfEdge { struct NodesOfEdge {
NodeID edgeBasedNode; NodeID edgeBasedNode;
double ratio; double ratio;
_Coordinate projectedPoint; FixedPointCoordinate projectedPoint;
}; };
#endif /* PHANTOMNODES_H_ */ #endif /* PHANTOMNODES_H_ */
+10 -19
View File
@@ -18,8 +18,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef QUERYEDGE_H_ #ifndef QUERYEDGE_H_
#define QUERYEDGE_H_ #define QUERYEDGE_H_
@@ -29,7 +27,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <climits> #include <climits>
struct OriginalEdgeData{ struct OriginalEdgeData{
explicit OriginalEdgeData(NodeID v, unsigned n, TurnInstruction t) : viaNode(v), nameID(n), turnInstruction(t) {} explicit OriginalEdgeData(
NodeID viaNode,
unsigned nameID,
TurnInstruction turnInstruction
) : viaNode(viaNode), nameID(nameID), turnInstruction(turnInstruction) {}
OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(UCHAR_MAX) {} OriginalEdgeData() : viaNode(UINT_MAX), nameID(UINT_MAX), turnInstruction(UCHAR_MAX) {}
NodeID viaNode; NodeID viaNode;
unsigned nameID; unsigned nameID;
@@ -46,23 +48,12 @@ struct QueryEdge {
bool forward:1; bool forward:1;
bool backward:1; bool backward:1;
} data; } data;
bool operator<( const QueryEdge& right ) const {
if ( source != right.source )
return source < right.source;
return target < right.target;
}
//sorts by source and other attributes bool operator<( const QueryEdge& right ) const {
static bool CompareBySource( const QueryEdge& left, const QueryEdge& right ) { if ( source != right.source ) {
if ( left.source != right.source ) return source < right.source;
return left.source < right.source; }
int l = ( left.data.forward ? -1 : 0 ) + ( left.data.backward ? -1 : 0 ); return target < right.target;
int r = ( right.data.forward ? -1 : 0 ) + ( right.data.backward ? -1 : 0 );
if ( l != r )
return l < r;
if ( left.target != right.target )
return left.target < right.target;
return left.data.distance < right.data.distance;
} }
bool operator== ( const QueryEdge& right ) const { bool operator== ( const QueryEdge& right ) const {
@@ -21,32 +21,43 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef _NODE_COORDS_H #ifndef _NODE_COORDS_H
#define _NODE_COORDS_H #define _NODE_COORDS_H
#include <cassert> #include "Coordinate.h"
#include <cstddef>
#include <climits>
#include <limits>
#include "../typedefs.h" #include "../typedefs.h"
template<typename NodeT> #include <boost/assert.hpp>
struct NodeCoords {
typedef unsigned key_type; //type of NodeID #include <cstddef>
#include <climits>
#include <limits>
struct NodeInfo {
typedef NodeID key_type; //type of NodeID
typedef int value_type; //type of lat,lons typedef int value_type; //type of lat,lons
NodeCoords(int _lat, int _lon, NodeT _id) : lat(_lat), lon(_lon), id(_id) {} NodeInfo(int _lat, int _lon, NodeID _id) : lat(_lat), lon(_lon), id(_id) {}
NodeCoords() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {} NodeInfo() : lat(INT_MAX), lon(INT_MAX), id(UINT_MAX) {}
int lat; int lat;
int lon; int lon;
NodeT id; NodeID id;
static NodeCoords<NodeT> min_value() { static NodeInfo min_value() {
return NodeCoords<NodeT>(-90*100000,-180*100000,std::numeric_limits<NodeT>::min()); return NodeInfo(
} -90*COORDINATE_PRECISION,
static NodeCoords<NodeT> max_value() { -180*COORDINATE_PRECISION,
return NodeCoords<NodeT>(90*100000, 180*100000, std::numeric_limits<NodeT>::max()); std::numeric_limits<NodeID>::min()
);
} }
value_type operator[](std::size_t n) const { static NodeInfo max_value() {
return NodeInfo(
90*COORDINATE_PRECISION,
180*COORDINATE_PRECISION,
std::numeric_limits<NodeID>::max()
);
}
value_type operator[](const std::size_t n) const {
switch(n) { switch(n) {
case 1: case 1:
return lat; return lat;
@@ -55,15 +66,13 @@ struct NodeCoords {
return lon; return lon;
break; break;
default: default:
assert(false); BOOST_ASSERT_MSG(false, "should not happen");
return UINT_MAX; return UINT_MAX;
break; break;
} }
assert(false); BOOST_ASSERT_MSG(false, "should not happen");
return UINT_MAX; return UINT_MAX;
} }
}; };
typedef NodeCoords<NodeID> NodeInfo;
#endif //_NODE_COORDS_H #endif //_NODE_COORDS_H
@@ -21,8 +21,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef RAWROUTEDATA_H_ #ifndef RAWROUTEDATA_H_
#define RAWROUTEDATA_H_ #define RAWROUTEDATA_H_
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/PhantomNodes.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <vector>
struct _PathData { struct _PathData {
_PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { } _PathData(NodeID no, unsigned na, unsigned tu, unsigned dur) : node(no), nameID(na), durationOfSegment(dur), turnInstruction(tu) { }
NodeID node; NodeID node;
@@ -35,7 +39,7 @@ struct RawRouteData {
std::vector< _PathData > computedShortestPath; std::vector< _PathData > computedShortestPath;
std::vector< _PathData > computedAlternativePath; std::vector< _PathData > computedAlternativePath;
std::vector< PhantomNodes > segmentEndCoordinates; std::vector< PhantomNodes > segmentEndCoordinates;
std::vector< _Coordinate > rawViaNodeCoordinates; std::vector< FixedPointCoordinate > rawViaNodeCoordinates;
unsigned checkSum; unsigned checkSum;
int lengthOfShortestPath; int lengthOfShortestPath;
int lengthOfAlternativePath; int lengthOfAlternativePath;
+56 -20
View File
@@ -23,40 +23,78 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef RESTRICTION_H_ #ifndef RESTRICTION_H_
#define RESTRICTION_H_ #define RESTRICTION_H_
#include "../typedefs.h"
#include <climits> #include <climits>
struct _Restriction { struct TurnRestriction {
NodeID viaNode; NodeID viaNode;
NodeID fromNode; NodeID fromNode;
NodeID toNode; NodeID toNode;
struct Bits { //mostly unused struct Bits { //mostly unused
Bits() : isOnly(false), unused1(false), unused2(false), unused3(false), unused4(false), unused5(false), unused6(false), unused7(false) {} Bits()
char isOnly:1; :
char unused1:1; isOnly(false),
char unused2:1; unused1(false),
char unused3:1; unused2(false),
char unused4:1; unused3(false),
char unused5:1; unused4(false),
char unused6:1; unused5(false),
char unused7:1; unused6(false),
unused7(false)
{ }
bool isOnly:1;
bool unused1:1;
bool unused2:1;
bool unused3:1;
bool unused4:1;
bool unused5:1;
bool unused6:1;
bool unused7:1;
} flags; } flags;
_Restriction(NodeID vn) : viaNode(vn), fromNode(UINT_MAX), toNode(UINT_MAX) { } TurnRestriction(NodeID viaNode) :
_Restriction(bool isOnly = false) : viaNode(UINT_MAX), fromNode(UINT_MAX), toNode(UINT_MAX) { viaNode(viaNode),
fromNode(UINT_MAX),
toNode(UINT_MAX) {
}
TurnRestriction(const bool isOnly = false) :
viaNode(UINT_MAX),
fromNode(UINT_MAX),
toNode(UINT_MAX) {
flags.isOnly = isOnly; flags.isOnly = isOnly;
} }
}; };
inline bool CmpRestrictionByFrom ( _Restriction a, _Restriction b) { return (a.fromNode < b.fromNode); }
struct _RawRestrictionContainer { struct _RawRestrictionContainer {
_Restriction restriction; TurnRestriction restriction;
EdgeID fromWay; EdgeID fromWay;
EdgeID toWay; EdgeID toWay;
unsigned viaNode; unsigned viaNode;
_RawRestrictionContainer(EdgeID f, EdgeID t, NodeID vn, unsigned vw) : fromWay(f), toWay(t), viaNode(vw) { restriction.viaNode = vn;} _RawRestrictionContainer(
_RawRestrictionContainer(bool isOnly = false) : fromWay(UINT_MAX), toWay(UINT_MAX), viaNode(UINT_MAX) { restriction.flags.isOnly = isOnly;} EdgeID fromWay,
EdgeID toWay,
NodeID vn,
unsigned vw
) :
fromWay(fromWay),
toWay(toWay),
viaNode(vw)
{
restriction.viaNode = vn;
}
_RawRestrictionContainer(
bool isOnly = false
) :
fromWay(UINT_MAX),
toWay(UINT_MAX),
viaNode(UINT_MAX)
{
restriction.flags.isOnly = isOnly;
}
static _RawRestrictionContainer min_value() { static _RawRestrictionContainer min_value() {
return _RawRestrictionContainer(0, 0, 0, 0); return _RawRestrictionContainer(0, 0, 0, 0);
@@ -66,7 +104,7 @@ struct _RawRestrictionContainer {
} }
}; };
struct CmpRestrictionContainerByFrom: public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> { struct CmpRestrictionContainerByFrom : public std::binary_function<_RawRestrictionContainer, _RawRestrictionContainer, bool> {
typedef _RawRestrictionContainer value_type; typedef _RawRestrictionContainer value_type;
bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const { bool operator () (const _RawRestrictionContainer & a, const _RawRestrictionContainer & b) const {
return a.fromWay < b.fromWay; return a.fromWay < b.fromWay;
@@ -92,6 +130,4 @@ struct CmpRestrictionContainerByTo: public std::binary_function<_RawRestrictionC
} }
}; };
#endif /* RESTRICTION_H_ */ #endif /* RESTRICTION_H_ */
+2 -2
View File
@@ -33,14 +33,14 @@ SearchEngine::SearchEngine(
void SearchEngine::GetCoordinatesForNodeID( void SearchEngine::GetCoordinatesForNodeID(
NodeID id, NodeID id,
_Coordinate& result FixedPointCoordinate& result
) const { ) const {
result.lat = _queryData.nodeHelpDesk->getLatitudeOfNode(id); result.lat = _queryData.nodeHelpDesk->getLatitudeOfNode(id);
result.lon = _queryData.nodeHelpDesk->getLongitudeOfNode(id); result.lon = _queryData.nodeHelpDesk->getLongitudeOfNode(id);
} }
void SearchEngine::FindPhantomNodeForCoordinate( void SearchEngine::FindPhantomNodeForCoordinate(
const _Coordinate & location, const FixedPointCoordinate & location,
PhantomNode & result, PhantomNode & result,
const unsigned zoomLevel const unsigned zoomLevel
) const { ) const {
+5 -5
View File
@@ -45,17 +45,17 @@ public:
AlternativeRouting<SearchEngineData> alternativePaths; AlternativeRouting<SearchEngineData> alternativePaths;
SearchEngine( SearchEngine(
QueryGraph * g, QueryGraph * g,
NodeInformationHelpDesk * nh, NodeInformationHelpDesk * nh,
std::vector<std::string> & n std::vector<std::string> & n
); );
~SearchEngine(); ~SearchEngine();
void GetCoordinatesForNodeID(NodeID id, _Coordinate& result) const; void GetCoordinatesForNodeID(NodeID id, FixedPointCoordinate& result) const;
void FindPhantomNodeForCoordinate( void FindPhantomNodeForCoordinate(
const _Coordinate & location, const FixedPointCoordinate & location,
PhantomNode & result, PhantomNode & result,
unsigned zoomLevel unsigned zoomLevel
) const; ) const;
+6 -5
View File
@@ -21,21 +21,22 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef SEGMENTINFORMATION_H_ #ifndef SEGMENTINFORMATION_H_
#define SEGMENTINFORMATION_H_ #define SEGMENTINFORMATION_H_
#include "TurnInstructions.h"
#include "../typedefs.h"
#include <climits> #include <climits>
#include "TurnInstructions.h"
struct SegmentInformation { struct SegmentInformation {
_Coordinate location; FixedPointCoordinate location;
NodeID nameID; NodeID nameID;
double length; double length;
unsigned duration; unsigned duration;
double bearing; double bearing;
TurnInstruction turnInstruction; TurnInstruction turnInstruction;
bool necessary; bool necessary;
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const bool nec) : SegmentInformation(const FixedPointCoordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr, const bool nec) :
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(nec) {} location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(nec) {}
SegmentInformation(const _Coordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr) : SegmentInformation(const FixedPointCoordinate & loc, const NodeID nam, const double len, const unsigned dur, const TurnInstruction tInstr) :
location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(tInstr != 0) {} location(loc), nameID(nam), length(len), duration(dur), bearing(0.), turnInstruction(tInstr), necessary(tInstr != 0) {}
}; };
+11 -6
View File
@@ -21,11 +21,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef STATICGRAPH_H_INCLUDED #ifndef STATICGRAPH_H_INCLUDED
#define STATICGRAPH_H_INCLUDED #define STATICGRAPH_H_INCLUDED
#include <vector> #include "../Util/SimpleLogger.h"
#include <algorithm>
#include "../typedefs.h" #include "../typedefs.h"
#include "ImportEdge.h"
#include <algorithm>
#include <vector>
template< typename EdgeDataT> template< typename EdgeDataT>
class StaticGraph { class StaticGraph {
@@ -100,12 +100,17 @@ public:
if(data.shortcut) { if(data.shortcut) {
unsigned eid2 = FindEdgeInEitherDirection(u, data.id); unsigned eid2 = FindEdgeInEitherDirection(u, data.id);
if(eid2 == UINT_MAX) { if(eid2 == UINT_MAX) {
DEBUG("cannot find first segment of edge (" << u << "," << data.id << "," << v << ")"); SimpleLogger().Write(logWARNING) <<
"cannot find first segment of edge (" <<
u << "," << data.id << "," << v << ")";
data.shortcut = false; data.shortcut = false;
} }
eid2 = FindEdgeInEitherDirection(data.id, v); eid2 = FindEdgeInEitherDirection(data.id, v);
if(eid2 == UINT_MAX) { if(eid2 == UINT_MAX) {
DEBUG("cannot find second segment of edge (" << u << "," << data.id << "," << v << ")"); SimpleLogger().Write(logWARNING) <<
"cannot find second segment of edge (" <<
u << "," << data.id << "," << v << ")";
data.shortcut = false; data.shortcut = false;
} }
} }
+132 -209
View File
@@ -22,16 +22,20 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define STATICRTREE_H_ #define STATICRTREE_H_
#include "MercatorUtil.h" #include "MercatorUtil.h"
#include "TimingUtil.h"
#include "Coordinate.h" #include "Coordinate.h"
#include "PhantomNodes.h" #include "PhantomNodes.h"
#include "DeallocatingVector.h" #include "DeallocatingVector.h"
#include "HilbertValue.h" #include "HilbertValue.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/algorithm/minmax.hpp> #include <boost/algorithm/minmax.hpp>
#include <boost/algorithm/minmax_element.hpp> #include <boost/algorithm/minmax_element.hpp>
#include <boost/range/algorithm_ext/erase.hpp> #include <boost/range/algorithm_ext/erase.hpp>
@@ -43,8 +47,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <climits> #include <climits>
#include <algorithm> #include <algorithm>
#include <fstream>
#include <queue> #include <queue>
#include <string>
#include <vector> #include <vector>
//tuning parameters //tuning parameters
@@ -53,7 +57,7 @@ const static uint32_t RTREE_LEAF_NODE_SIZE = 1170;
// Implements a static, i.e. packed, R-tree // Implements a static, i.e. packed, R-tree
static boost::thread_specific_ptr<std::ifstream> thread_local_rtree_stream; static boost::thread_specific_ptr<boost::filesystem::ifstream> thread_local_rtree_stream;
template<class DataT> template<class DataT>
class StaticRTree : boost::noncopyable { class StaticRTree : boost::noncopyable {
@@ -96,8 +100,8 @@ private:
max_lat = std::max(max_lat, other.max_lat); max_lat = std::max(max_lat, other.max_lat);
} }
inline _Coordinate Centroid() const { inline FixedPointCoordinate Centroid() const {
_Coordinate centroid; FixedPointCoordinate centroid;
//The coordinates of the midpoints are given by: //The coordinates of the midpoints are given by:
//x = (x1 + x2) /2 and y = (y1 + y2) /2. //x = (x1 + x2) /2 and y = (y1 + y2) /2.
centroid.lon = (min_lon + max_lon)/2; centroid.lon = (min_lon + max_lon)/2;
@@ -106,10 +110,10 @@ private:
} }
inline bool Intersects(const RectangleInt2D & other) const { inline bool Intersects(const RectangleInt2D & other) const {
_Coordinate upper_left (other.max_lat, other.min_lon); FixedPointCoordinate upper_left (other.max_lat, other.min_lon);
_Coordinate upper_right(other.max_lat, other.max_lon); FixedPointCoordinate upper_right(other.max_lat, other.max_lon);
_Coordinate lower_right(other.min_lat, other.max_lon); FixedPointCoordinate lower_right(other.min_lat, other.max_lon);
_Coordinate lower_left (other.min_lat, other.min_lon); FixedPointCoordinate lower_left (other.min_lat, other.min_lon);
return ( return (
Contains(upper_left) Contains(upper_left)
@@ -119,7 +123,7 @@ private:
); );
} }
inline double GetMinDist(const _Coordinate & location) const { inline double GetMinDist(const FixedPointCoordinate & location) const {
bool is_contained = Contains(location); bool is_contained = Contains(location);
if (is_contained) { if (is_contained) {
return 0.0; return 0.0;
@@ -165,13 +169,13 @@ private:
return min_dist; return min_dist;
} }
inline double GetMinMaxDist(const _Coordinate & location) const { inline double GetMinMaxDist(const FixedPointCoordinate & location) const {
double min_max_dist = DBL_MAX; double min_max_dist = DBL_MAX;
//Get minmax distance to each of the four sides //Get minmax distance to each of the four sides
_Coordinate upper_left (max_lat, min_lon); FixedPointCoordinate upper_left (max_lat, min_lon);
_Coordinate upper_right(max_lat, max_lon); FixedPointCoordinate upper_right(max_lat, max_lon);
_Coordinate lower_right(min_lat, max_lon); FixedPointCoordinate lower_right(min_lat, max_lon);
_Coordinate lower_left (min_lat, min_lon); FixedPointCoordinate lower_left (min_lat, min_lon);
min_max_dist = std::min( min_max_dist = std::min(
min_max_dist, min_max_dist,
@@ -207,7 +211,7 @@ private:
return min_max_dist; return min_max_dist;
} }
inline bool Contains(const _Coordinate & location) const { inline bool Contains(const FixedPointCoordinate & location) const {
bool lats_contained = bool lats_contained =
(location.lat > min_lat) && (location.lat < max_lat); (location.lat > min_lat) && (location.lat < max_lat);
bool lons_contained = bool lons_contained =
@@ -215,8 +219,14 @@ private:
return lats_contained && lons_contained; return lats_contained && lons_contained;
} }
inline friend std::ostream & operator<< ( std::ostream & out, const RectangleInt2D & rect ) { inline friend std::ostream & operator<< (
out << rect.min_lat/100000. << "," << rect.min_lon/100000. << " " << rect.max_lat/100000. << "," << rect.max_lon/100000.; std::ostream & out,
const RectangleInt2D & rect
) {
out << rect.min_lat/COORDINATE_PRECISION << ","
<< rect.min_lon/COORDINATE_PRECISION << " "
<< rect.max_lat/COORDINATE_PRECISION << ","
<< rect.max_lon/COORDINATE_PRECISION;
return out; return out;
} }
}; };
@@ -224,8 +234,11 @@ private:
typedef RectangleInt2D RectangleT; typedef RectangleInt2D RectangleT;
struct WrappedInputElement { struct WrappedInputElement {
explicit WrappedInputElement(const uint32_t _array_index, const uint64_t _hilbert_value) : explicit WrappedInputElement(
m_array_index(_array_index), m_hilbert_value(_hilbert_value) {} const uint32_t _array_index,
const uint64_t _hilbert_value
) : m_array_index(_array_index), m_hilbert_value(_hilbert_value) {}
WrappedInputElement() : m_array_index(UINT_MAX), m_hilbert_value(0) {} WrappedInputElement() : m_array_index(UINT_MAX), m_hilbert_value(0) {}
uint32_t m_array_index; uint32_t m_array_index;
@@ -251,11 +264,13 @@ private:
}; };
struct QueryCandidate { struct QueryCandidate {
explicit QueryCandidate(const uint32_t n_id, const double dist) : node_id(n_id), min_dist(dist)/*, minmax_dist(DBL_MAX)*/ {} explicit QueryCandidate(
QueryCandidate() : node_id(UINT_MAX), min_dist(DBL_MAX)/*, minmax_dist(DBL_MAX)*/ {} const uint32_t n_id,
const double dist
) : node_id(n_id), min_dist(dist) {}
QueryCandidate() : node_id(UINT_MAX), min_dist(DBL_MAX) {}
uint32_t node_id; uint32_t node_id;
double min_dist; double min_dist;
// double minmax_dist;
inline bool operator<(const QueryCandidate & other) const { inline bool operator<(const QueryCandidate & other) const {
return min_dist < other.min_dist; return min_dist < other.min_dist;
} }
@@ -264,45 +279,43 @@ private:
std::vector<TreeNode> m_search_tree; std::vector<TreeNode> m_search_tree;
uint64_t m_element_count; uint64_t m_element_count;
std::string m_leaf_node_filename; const std::string m_leaf_node_filename;
public: public:
//Construct a pack R-Tree from the input-list with Kamel-Faloutsos algorithm [1] //Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1]
explicit StaticRTree(std::vector<DataT> & input_data_vector, const char * tree_node_filename, const char * leaf_node_filename) : explicit StaticRTree(
m_leaf_node_filename(leaf_node_filename) { std::vector<DataT> & input_data_vector,
m_element_count = input_data_vector.size(); const std::string tree_node_filename,
//remove elements that are flagged to be ignored const std::string leaf_node_filename
// boost::remove_erase_if(input_data_vector, boost::bind(&DataT::isIgnored, _1 )); )
: m_element_count(input_data_vector.size()),
m_leaf_node_filename(leaf_node_filename)
{
SimpleLogger().Write() <<
"constructing r-tree of " << m_element_count <<
" elements";
INFO("constructing r-tree of " << m_element_count << " elements");
// INFO("sizeof(LeafNode)=" << sizeof(LeafNode));
// INFO("sizeof(TreeNode)=" << sizeof(TreeNode));
// INFO("sizeof(WrappedInputElement)=" << sizeof(WrappedInputElement));
double time1 = get_timestamp(); double time1 = get_timestamp();
std::vector<WrappedInputElement> input_wrapper_vector(input_data_vector.size()); std::vector<WrappedInputElement> input_wrapper_vector(m_element_count);
//generate auxiliary vector of hilbert-values //generate auxiliary vector of hilbert-values
#pragma omp parallel for schedule(guided) #pragma omp parallel for schedule(guided)
for(uint64_t element_counter = 0; element_counter < m_element_count; ++element_counter) { for(uint64_t element_counter = 0; element_counter < m_element_count; ++element_counter) {
//INFO("ID: " << input_data_vector[element_counter].id);
input_wrapper_vector[element_counter].m_array_index = element_counter; input_wrapper_vector[element_counter].m_array_index = element_counter;
//Get Hilbert-Value for centroid in mercartor projection //Get Hilbert-Value for centroid in mercartor projection
DataT & current_element = input_data_vector[element_counter]; DataT & current_element = input_data_vector[element_counter];
_Coordinate current_centroid = current_element.Centroid(); FixedPointCoordinate current_centroid = current_element.Centroid();
current_centroid.lat = 100000*lat2y(current_centroid.lat/100000.); current_centroid.lat = COORDINATE_PRECISION*lat2y(current_centroid.lat/COORDINATE_PRECISION);
uint64_t current_hilbert_value = HilbertCode::GetHilbertNumberForCoordinate(current_centroid); uint64_t current_hilbert_value = HilbertCode::GetHilbertNumberForCoordinate(current_centroid);
input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value; input_wrapper_vector[element_counter].m_hilbert_value = current_hilbert_value;
} }
//INFO("finished wrapper setup");
//open leaf file //open leaf file
std::ofstream leaf_node_file(leaf_node_filename, std::ios::binary); boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary);
leaf_node_file.write((char*) &m_element_count, sizeof(uint64_t)); leaf_node_file.write((char*) &m_element_count, sizeof(uint64_t));
//sort the hilbert-value representatives //sort the hilbert-value representatives
std::sort(input_wrapper_vector.begin(), input_wrapper_vector.end()); std::sort(input_wrapper_vector.begin(), input_wrapper_vector.end());
// INFO("finished sorting");
std::vector<TreeNode> tree_nodes_in_level; std::vector<TreeNode> tree_nodes_in_level;
//pack M elements into leaf node and write to leaf file //pack M elements into leaf node and write to leaf file
@@ -313,19 +326,12 @@ public:
TreeNode current_node; TreeNode current_node;
for(uint32_t current_element_index = 0; RTREE_LEAF_NODE_SIZE > current_element_index; ++current_element_index) { for(uint32_t current_element_index = 0; RTREE_LEAF_NODE_SIZE > current_element_index; ++current_element_index) {
if(m_element_count > (processed_objects_count + current_element_index)) { if(m_element_count > (processed_objects_count + current_element_index)) {
// INFO("Checking element " << (processed_objects_count + current_element_index));
uint32_t index_of_next_object = input_wrapper_vector[processed_objects_count + current_element_index].m_array_index; uint32_t index_of_next_object = input_wrapper_vector[processed_objects_count + current_element_index].m_array_index;
current_leaf.objects[current_element_index] = input_data_vector[index_of_next_object]; current_leaf.objects[current_element_index] = input_data_vector[index_of_next_object];
++current_leaf.object_count; ++current_leaf.object_count;
} }
} }
if(0 == processed_objects_count) {
for(uint32_t i = 0; i < current_leaf.object_count; ++i) {
//INFO("[" << i << "] id: " << current_leaf.objects[i].id << ", weight: " << current_leaf.objects[i].weight << ", " << current_leaf.objects[i].lat1/100000. << "," << current_leaf.objects[i].lon1/100000. << ";" << current_leaf.objects[i].lat2/100000. << "," << current_leaf.objects[i].lon2/100000.);
}
}
//generate tree node that resemble the objects in leaf and store it for next level //generate tree node that resemble the objects in leaf and store it for next level
current_node.minimum_bounding_rectangle.InitializeMBRectangle(current_leaf.objects, current_leaf.object_count); current_node.minimum_bounding_rectangle.InitializeMBRectangle(current_leaf.objects, current_leaf.object_count);
current_node.child_is_on_disk = true; current_node.child_is_on_disk = true;
@@ -337,20 +343,21 @@ public:
processed_objects_count += current_leaf.object_count; processed_objects_count += current_leaf.object_count;
} }
// INFO("wrote " << processed_objects_count << " leaf objects");
//close leaf file //close leaf file
leaf_node_file.close(); leaf_node_file.close();
uint32_t processing_level = 0; uint32_t processing_level = 0;
while(1 < tree_nodes_in_level.size()) { while(1 < tree_nodes_in_level.size()) {
// INFO("processing " << (uint32_t)tree_nodes_in_level.size() << " tree nodes in level " << processing_level);
std::vector<TreeNode> tree_nodes_in_next_level; std::vector<TreeNode> tree_nodes_in_next_level;
uint32_t processed_tree_nodes_in_level = 0; uint32_t processed_tree_nodes_in_level = 0;
while(processed_tree_nodes_in_level < tree_nodes_in_level.size()) { while(processed_tree_nodes_in_level < tree_nodes_in_level.size()) {
TreeNode parent_node; TreeNode parent_node;
//pack RTREE_BRANCHING_FACTOR elements into tree_nodes each //pack RTREE_BRANCHING_FACTOR elements into tree_nodes each
for(uint32_t current_child_node_index = 0; RTREE_BRANCHING_FACTOR > current_child_node_index; ++current_child_node_index) { for(
uint32_t current_child_node_index = 0;
RTREE_BRANCHING_FACTOR > current_child_node_index;
++current_child_node_index
) {
if(processed_tree_nodes_in_level < tree_nodes_in_level.size()) { if(processed_tree_nodes_in_level < tree_nodes_in_level.size()) {
TreeNode & current_child_node = tree_nodes_in_level[processed_tree_nodes_in_level]; TreeNode & current_child_node = tree_nodes_in_level[processed_tree_nodes_in_level];
//add tree node to parent entry //add tree node to parent entry
@@ -364,15 +371,12 @@ public:
} }
} }
tree_nodes_in_next_level.push_back(parent_node); tree_nodes_in_next_level.push_back(parent_node);
// INFO("processed: " << processed_tree_nodes_in_level << ", generating " << (uint32_t)tree_nodes_in_next_level.size() << " parents");
} }
tree_nodes_in_level.swap(tree_nodes_in_next_level); tree_nodes_in_level.swap(tree_nodes_in_next_level);
++processing_level; ++processing_level;
} }
BOOST_ASSERT_MSG(1 == tree_nodes_in_level.size(), "tree broken, more than one root node"); BOOST_ASSERT_MSG(1 == tree_nodes_in_level.size(), "tree broken, more than one root node");
//last remaining entry is the root node; //last remaining entry is the root node, store it
// INFO("root node has " << (uint32_t)tree_nodes_in_level[0].child_count << " children");
//store root node
m_search_tree.push_back(tree_nodes_in_level[0]); m_search_tree.push_back(tree_nodes_in_level[0]);
//reverse and renumber tree to have root at index 0 //reverse and renumber tree to have root at index 0
@@ -388,7 +392,11 @@ public:
} }
//open tree file //open tree file
std::ofstream tree_node_file(tree_node_filename, std::ios::binary); boost::filesystem::ofstream tree_node_file(
tree_node_filename,
std::ios::binary
);
uint32_t size_of_tree = m_search_tree.size(); uint32_t size_of_tree = m_search_tree.size();
BOOST_ASSERT_MSG(0 < size_of_tree, "tree empty"); BOOST_ASSERT_MSG(0 < size_of_tree, "tree empty");
tree_node_file.write((char *)&size_of_tree, sizeof(uint32_t)); tree_node_file.write((char *)&size_of_tree, sizeof(uint32_t));
@@ -396,56 +404,52 @@ public:
//close tree node file. //close tree node file.
tree_node_file.close(); tree_node_file.close();
double time2 = get_timestamp(); double time2 = get_timestamp();
// INFO("written " << processed_objects_count << " leafs in " << sizeof(LeafNode)*(1+(unsigned)std::ceil(processed_objects_count/RTREE_LEAF_NODE_SIZE) )+sizeof(uint64_t) << " bytes"); SimpleLogger().Write() <<
// INFO("written search tree of " << size_of_tree << " tree nodes in " << sizeof(TreeNode)*size_of_tree+sizeof(uint32_t) << " bytes"); "finished r-tree construction in " << (time2-time1) << " seconds";
INFO("finished r-tree construction in " << (time2-time1) << " seconds");
//todo: test queries
/* INFO("first MBR:" << m_search_tree[0].minimum_bounding_rectangle);
DataT result;
time1 = get_timestamp();
bool found_nearest = NearestNeighbor(_Coordinate(50.191085,8.466479), result);
time2 = get_timestamp();
INFO("found nearest element to (50.191085,8.466479): " << (found_nearest ? "yes" : "no") << " in " << (time2-time1) << "s at (" << result.lat1/100000. << "," << result.lon1/100000. << " " << result.lat2/100000. << "," << result.lon2/100000. << ")");
time1 = get_timestamp();
found_nearest = NearestNeighbor(_Coordinate(50.23979, 8.51882), result);
time2 = get_timestamp();
INFO("found nearest element to (50.23979, 8.51882): " << (found_nearest ? "yes" : "no") << " in " << (time2-time1) << "s at (" << result.lat1/100000. << "," << result.lon1/100000. << " " << result.lat2/100000. << "," << result.lon2/100000. << ")");
time1 = get_timestamp();
found_nearest = NearestNeighbor(_Coordinate(49.0316,2.6937), result);
time2 = get_timestamp();
INFO("found nearest element to (49.0316,2.6937): " << (found_nearest ? "yes" : "no") << " in " << (time2-time1) << "s at (" << result.lat1/100000. << "," << result.lon1/100000. << " " << result.lat2/100000. << "," << result.lon2/100000. << ")");
*/
} }
//Read-only operation for queries //Read-only operation for queries
explicit StaticRTree( explicit StaticRTree(
const char * node_filename, const std::string & node_filename,
const char * leaf_filename const std::string & leaf_filename
) : m_leaf_node_filename(leaf_filename) { ) : m_leaf_node_filename(leaf_filename) {
//INFO("Loading nodes: " << node_filename);
//INFO("opening leafs: " << leaf_filename);
//open tree node file and load into RAM. //open tree node file and load into RAM.
std::ifstream tree_node_file(node_filename, std::ios::binary); boost::filesystem::path node_file(node_filename);
if ( !boost::filesystem::exists( node_file ) ) {
throw OSRMException("ram index file does not exist");
}
if ( 0 == boost::filesystem::file_size( node_file ) ) {
throw OSRMException("ram index file is empty");
}
boost::filesystem::ifstream tree_node_file( node_file, std::ios::binary );
uint32_t tree_size = 0; uint32_t tree_size = 0;
tree_node_file.read((char*)&tree_size, sizeof(uint32_t)); tree_node_file.read((char*)&tree_size, sizeof(uint32_t));
//INFO("reading " << tree_size << " tree nodes in " << (sizeof(TreeNode)*tree_size) << " bytes"); //SimpleLogger().Write() << "reading " << tree_size << " tree nodes in " << (sizeof(TreeNode)*tree_size) << " bytes";
m_search_tree.resize(tree_size); m_search_tree.resize(tree_size);
tree_node_file.read((char*)&m_search_tree[0], sizeof(TreeNode)*tree_size); tree_node_file.read((char*)&m_search_tree[0], sizeof(TreeNode)*tree_size);
tree_node_file.close(); tree_node_file.close();
//open leaf node file and store thread specific pointer //open leaf node file and store thread specific pointer
std::ifstream leaf_node_file(leaf_filename, std::ios::binary); boost::filesystem::path leaf_file(leaf_filename);
if ( !boost::filesystem::exists( leaf_file ) ) {
throw OSRMException("mem index file does not exist");
}
if ( 0 == boost::filesystem::file_size( leaf_file ) ) {
throw OSRMException("mem index file is empty");
}
boost::filesystem::ifstream leaf_node_file( leaf_file, std::ios::binary );
leaf_node_file.read((char*)&m_element_count, sizeof(uint64_t)); leaf_node_file.read((char*)&m_element_count, sizeof(uint64_t));
leaf_node_file.close(); leaf_node_file.close();
//INFO( tree_size << " nodes in search tree"); //SimpleLogger().Write() << tree_size << " nodes in search tree";
//INFO( m_element_count << " elements in leafs"); //SimpleLogger().Write() << m_element_count << " elements in leafs";
} }
/* /*
inline void FindKNearestPhantomNodesForCoordinate( inline void FindKNearestPhantomNodesForCoordinate(
const _Coordinate & location, const FixedPointCoordinate & location,
const unsigned zoom_level, const unsigned zoom_level,
const unsigned candidate_count, const unsigned candidate_count,
std::vector<std::pair<PhantomNode, double> > & result_vector std::vector<std::pair<PhantomNode, double> > & result_vector
@@ -456,12 +460,12 @@ public:
uint32_t io_count = 0; uint32_t io_count = 0;
uint32_t explored_tree_nodes_count = 0; uint32_t explored_tree_nodes_count = 0;
INFO("searching for coordinate " << input_coordinate); SimpleLogger().Write() << "searching for coordinate " << input_coordinate;
double min_dist = DBL_MAX; double min_dist = DBL_MAX;
double min_max_dist = DBL_MAX; double min_max_dist = DBL_MAX;
bool found_a_nearest_edge = false; bool found_a_nearest_edge = false;
_Coordinate nearest, current_start_coordinate, current_end_coordinate; FixedPointCoordinate nearest, current_start_coordinate, current_end_coordinate;
//initialize queue with root element //initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue; std::priority_queue<QueryCandidate> traversal_queue;
@@ -489,8 +493,8 @@ public:
double current_ratio = 0.; double current_ratio = 0.;
double current_perpendicular_distance = ComputePerpendicularDistance( double current_perpendicular_distance = ComputePerpendicularDistance(
input_coordinate, input_coordinate,
_Coordinate(current_edge.lat1, current_edge.lon1), FixedPointCoordinate(current_edge.lat1, current_edge.lon1),
_Coordinate(current_edge.lat2, current_edge.lon2), FixedPointCoordinate(current_edge.lat2, current_edge.lon2),
nearest, nearest,
&current_ratio &current_ratio
); );
@@ -519,11 +523,11 @@ public:
1 == abs(current_edge.id - result_phantom_node.edgeBasedNode ) 1 == abs(current_edge.id - result_phantom_node.edgeBasedNode )
&& CoordinatesAreEquivalent( && CoordinatesAreEquivalent(
current_start_coordinate, current_start_coordinate,
_Coordinate( FixedPointCoordinate(
current_edge.lat1, current_edge.lat1,
current_edge.lon1 current_edge.lon1
), ),
_Coordinate( FixedPointCoordinate(
current_edge.lat2, current_edge.lat2,
current_edge.lon2 current_edge.lon2
), ),
@@ -557,11 +561,20 @@ public:
} }
} }
const double distance_to_edge =
ApproximateDistance (
FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1),
result_phantom_node.location
);
const double length_of_edge =
ApproximateDistance(
FixedPointCoordinate(nearest_edge.lat1, nearest_edge.lon1),
FixedPointCoordinate(nearest_edge.lat2, nearest_edge.lon2)
);
const double ratio = (found_a_nearest_edge ? const double ratio = (found_a_nearest_edge ?
std::min(1., ApproximateDistance(_Coordinate(nearest_edge.lat1, nearest_edge.lon1), std::min(1., distance_to_edge/ length_of_edge ) : 0 );
result_phantom_node.location)/ApproximateDistance(_Coordinate(nearest_edge.lat1, nearest_edge.lon1), _Coordinate(nearest_edge.lat2, nearest_edge.lon2))
) : 0
);
result_phantom_node.weight1 *= ratio; result_phantom_node.weight1 *= ratio;
if(INT_MAX != result_phantom_node.weight2) { if(INT_MAX != result_phantom_node.weight2) {
result_phantom_node.weight2 *= (1.-ratio); result_phantom_node.weight2 *= (1.-ratio);
@@ -576,15 +589,14 @@ public:
result_phantom_node.location.lat = input_coordinate.lat; result_phantom_node.location.lat = input_coordinate.lat;
} }
INFO("mindist: " << min_dist << ", io's: " << io_count << ", nodes: " << explored_tree_nodes_count << ", loc: " << result_phantom_node.location << ", ratio: " << ratio << ", id: " << result_phantom_node.edgeBasedNode); SimpleLogger().Write() << "mindist: " << min_distphantom_node.isBidirected() ? "yes" : "no");
INFO("bidirected: " << (result_phantom_node.isBidirected() ? "yes" : "no") );
return found_a_nearest_edge; return found_a_nearest_edge;
} }
*/ */
bool FindPhantomNodeForCoordinate( bool FindPhantomNodeForCoordinate(
const _Coordinate & input_coordinate, const FixedPointCoordinate & input_coordinate,
PhantomNode & result_phantom_node, PhantomNode & result_phantom_node,
const unsigned zoom_level const unsigned zoom_level
) { ) {
@@ -594,12 +606,12 @@ public:
uint32_t io_count = 0; uint32_t io_count = 0;
uint32_t explored_tree_nodes_count = 0; uint32_t explored_tree_nodes_count = 0;
//INFO("searching for coordinate " << input_coordinate); //SimpleLogger().Write() << "searching for coordinate " << input_coordinate;
double min_dist = DBL_MAX; double min_dist = DBL_MAX;
double min_max_dist = DBL_MAX; double min_max_dist = DBL_MAX;
bool found_a_nearest_edge = false; bool found_a_nearest_edge = false;
_Coordinate nearest, current_start_coordinate, current_end_coordinate; FixedPointCoordinate nearest, current_start_coordinate, current_end_coordinate;
//initialize queue with root element //initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue; std::priority_queue<QueryCandidate> traversal_queue;
@@ -625,7 +637,7 @@ public:
LeafNode current_leaf_node; LeafNode current_leaf_node;
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node); LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
++io_count; ++io_count;
//INFO("checking " << current_leaf_node.object_count << " elements"); //SimpleLogger().Write() << "checking " << current_leaf_node.object_count << " elements";
for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) { for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) {
DataT & current_edge = current_leaf_node.objects[i]; DataT & current_edge = current_leaf_node.objects[i];
if(ignore_tiny_components && current_edge.belongsToTinyComponent) { if(ignore_tiny_components && current_edge.belongsToTinyComponent) {
@@ -638,16 +650,12 @@ public:
double current_ratio = 0.; double current_ratio = 0.;
double current_perpendicular_distance = ComputePerpendicularDistance( double current_perpendicular_distance = ComputePerpendicularDistance(
input_coordinate, input_coordinate,
_Coordinate(current_edge.lat1, current_edge.lon1), FixedPointCoordinate(current_edge.lat1, current_edge.lon1),
_Coordinate(current_edge.lat2, current_edge.lon2), FixedPointCoordinate(current_edge.lat2, current_edge.lon2),
nearest, nearest,
&current_ratio &current_ratio
); );
//INFO("[" << current_edge.id << "] (" << current_edge.lat1/100000. << "," << current_edge.lon1/100000. << ")==(" << current_edge.lat2/100000. << "," << current_edge.lon2/100000. << ") at distance " << current_perpendicular_distance << " min dist: " << min_dist
// << ", ratio " << current_ratio
// );
if( if(
current_perpendicular_distance < min_dist current_perpendicular_distance < min_dist
&& !DoubleEpsilonCompare( && !DoubleEpsilonCompare(
@@ -672,11 +680,11 @@ public:
1 == abs(current_edge.id - result_phantom_node.edgeBasedNode ) 1 == abs(current_edge.id - result_phantom_node.edgeBasedNode )
&& CoordinatesAreEquivalent( && CoordinatesAreEquivalent(
current_start_coordinate, current_start_coordinate,
_Coordinate( FixedPointCoordinate(
current_edge.lat1, current_edge.lat1,
current_edge.lon1 current_edge.lon1
), ),
_Coordinate( FixedPointCoordinate(
current_edge.lat2, current_edge.lat2,
current_edge.lon2 current_edge.lon2
), ),
@@ -684,15 +692,15 @@ public:
) )
) { ) {
BOOST_ASSERT_MSG(current_edge.id != result_phantom_node.edgeBasedNode, "IDs not different"); BOOST_ASSERT_MSG(current_edge.id != result_phantom_node.edgeBasedNode, "IDs not different");
//INFO("found bidirected edge on nodes " << current_edge.id << " and " << result_phantom_node.edgeBasedNode); //SimpleLogger().Write() << "found bidirected edge on nodes " << current_edge.id << " and " << result_phantom_node.edgeBasedNode;
result_phantom_node.weight2 = current_edge.weight; result_phantom_node.weight2 = current_edge.weight;
if(current_edge.id < result_phantom_node.edgeBasedNode) { if(current_edge.id < result_phantom_node.edgeBasedNode) {
result_phantom_node.edgeBasedNode = current_edge.id; result_phantom_node.edgeBasedNode = current_edge.id;
std::swap(result_phantom_node.weight1, result_phantom_node.weight2); std::swap(result_phantom_node.weight1, result_phantom_node.weight2);
std::swap(current_end_coordinate, current_start_coordinate); std::swap(current_end_coordinate, current_start_coordinate);
// INFO("case 2"); // SimpleLogger().Write() <<"case 2";
} }
//INFO("w1: " << result_phantom_node.weight1 << ", w2: " << result_phantom_node.weight2); //SimpleLogger().Write() << "w1: " << result_phantom_node.weight1 << ", w2: " << result_phantom_node.weight2;
} }
} }
} else { } else {
@@ -737,107 +745,22 @@ public:
result_phantom_node.location.lat = input_coordinate.lat; result_phantom_node.location.lat = input_coordinate.lat;
} }
// INFO("start: (" << nearest_edge.lat1 << "," << nearest_edge.lon1 << "), end: (" << nearest_edge.lat2 << "," << nearest_edge.lon2 << ")" );
// INFO("mindist: " << min_dist << ", io's: " << io_count << ", nodes: " << explored_tree_nodes_count << ", loc: " << result_phantom_node.location << ", ratio: " << ratio << ", id: " << result_phantom_node.edgeBasedNode);
// INFO("weight1: " << result_phantom_node.weight1 << ", weight2: " << result_phantom_node.weight2);
// INFO("bidirected: " << (result_phantom_node.isBidirected() ? "yes" : "no") );
// INFO("NameID: " << result_phantom_node.nodeBasedEdgeNameID);
return found_a_nearest_edge; return found_a_nearest_edge;
} }
/*
//Nearest-Neighbor query with the Roussopoulos et al. algorithm [2]
inline bool NearestNeighbor(const _Coordinate & input_coordinate, DataT & result_element) {
uint32_t io_count = 0;
uint32_t explored_tree_nodes_count = 0;
INFO("searching for coordinate " << input_coordinate);
double min_dist = DBL_MAX;
double min_max_dist = DBL_MAX;
bool found_return_value = false;
//initialize queue with root element
std::priority_queue<QueryCandidate> traversal_queue;
traversal_queue.push(QueryCandidate(0, m_search_tree[0].minimum_bounding_rectangle.GetMinDist(input_coordinate)));
BOOST_ASSERT_MSG(FLT_EPSILON > (0. - traversal_queue.top().min_dist), "Root element in NN Search has min dist != 0.");
while(!traversal_queue.empty()) {
const QueryCandidate current_query_node = traversal_queue.top(); traversal_queue.pop();
++explored_tree_nodes_count;
// INFO("popped node " << current_query_node.node_id << " at distance " << current_query_node.min_dist);
bool prune_downward = (current_query_node.min_dist >= min_max_dist);
bool prune_upward = (current_query_node.min_dist >= min_dist);
// INFO(" up prune: " << (prune_upward ? "y" : "n" ));
// INFO(" down prune: " << (prune_downward ? "y" : "n" ));
if( prune_downward || prune_upward ) { //downward pruning
// INFO(" pruned node " << current_query_node.node_id << " because " << current_query_node.min_dist << "<" << min_max_dist);
} else {
TreeNode & current_tree_node = m_search_tree[current_query_node.node_id];
if (current_tree_node.child_is_on_disk) {
// INFO(" Fetching child from disk for id: " << current_query_node.node_id);
LeafNode current_leaf_node;
LoadLeafFromDisk(current_tree_node.children[0], current_leaf_node);
++io_count;
double ratio = 0.;
_Coordinate nearest;
for(uint32_t i = 0; i < current_leaf_node.object_count; ++i) {
DataT & current_object = current_leaf_node.objects[i];
double current_perpendicular_distance = ComputePerpendicularDistance(
input_coordinate,
_Coordinate(current_object.lat1, current_object.lon1),
_Coordinate(current_object.lat2, current_object.lon2),
nearest,
&ratio
);
if(current_perpendicular_distance < min_dist && !DoubleEpsilonCompare(current_perpendicular_distance, min_dist)) { //found a new minimum
min_dist = current_perpendicular_distance;
result_element = current_object;
found_return_value = true;
}
}
} else {
//traverse children, prune if global mindist is smaller than local one
// INFO(" Checking " << current_tree_node.child_count << " children of node " << current_query_node.node_id);
for (uint32_t i = 0; i < current_tree_node.child_count; ++i) {
const int32_t child_id = current_tree_node.children[i];
TreeNode & child_tree_node = m_search_tree[child_id];
RectangleT & child_rectangle = child_tree_node.minimum_bounding_rectangle;
const double current_min_dist = child_rectangle.GetMinDist(input_coordinate);
const double current_min_max_dist = child_rectangle.GetMinMaxDist(input_coordinate);
if( current_min_max_dist < min_max_dist ) {
min_max_dist = current_min_max_dist;
}
if (current_min_dist > min_max_dist) {
continue;
}
if (current_min_dist > min_dist) { //upward pruning
continue;
}
// INFO(" pushing node " << child_id << " at distance " << current_min_dist);
traversal_queue.push(QueryCandidate(child_id, current_min_dist));
}
}
}
}
INFO("mindist: " << min_dist << ", io's: " << io_count << ", touched nodes: " << explored_tree_nodes_count);
return found_return_value;
}
*/
private: private:
inline void LoadLeafFromDisk(const uint32_t leaf_id, LeafNode& result_node) { inline void LoadLeafFromDisk(const uint32_t leaf_id, LeafNode& result_node) {
if(!thread_local_rtree_stream.get() || !thread_local_rtree_stream->is_open()) { if(!thread_local_rtree_stream.get() || !thread_local_rtree_stream->is_open()) {
thread_local_rtree_stream.reset( thread_local_rtree_stream.reset(
new std::ifstream( new boost::filesystem::ifstream(
m_leaf_node_filename.c_str(), m_leaf_node_filename,
std::ios::in | std::ios::binary std::ios::in | std::ios::binary
) )
); );
} }
if(!thread_local_rtree_stream->good()) { if(!thread_local_rtree_stream->good()) {
thread_local_rtree_stream->clear(std::ios::goodbit); thread_local_rtree_stream->clear(std::ios::goodbit);
DEBUG("Resetting stale filestream"); SimpleLogger().Write(logDEBUG) << "Resetting stale filestream";
} }
uint64_t seek_pos = sizeof(uint64_t) + leaf_id*sizeof(LeafNode); uint64_t seek_pos = sizeof(uint64_t) + leaf_id*sizeof(LeafNode);
thread_local_rtree_stream->seekg(seek_pos); thread_local_rtree_stream->seekg(seek_pos);
@@ -845,10 +768,10 @@ private:
} }
inline double ComputePerpendicularDistance( inline double ComputePerpendicularDistance(
const _Coordinate& inputPoint, const FixedPointCoordinate& inputPoint,
const _Coordinate& source, const FixedPointCoordinate& source,
const _Coordinate& target, const FixedPointCoordinate& target,
_Coordinate& nearest, double *r) const { FixedPointCoordinate& nearest, double *r) const {
const double x = static_cast<double>(inputPoint.lat); const double x = static_cast<double>(inputPoint.lat);
const double y = static_cast<double>(inputPoint.lon); const double y = static_cast<double>(inputPoint.lon);
const double a = static_cast<double>(source.lat); const double a = static_cast<double>(source.lat);
@@ -892,7 +815,7 @@ private:
return (p-x)*(p-x) + (q-y)*(q-y); return (p-x)*(p-x) + (q-y)*(q-y);
} }
inline bool CoordinatesAreEquivalent(const _Coordinate & a, const _Coordinate & b, const _Coordinate & c, const _Coordinate & d) const { inline bool CoordinatesAreEquivalent(const FixedPointCoordinate & a, const FixedPointCoordinate & b, const FixedPointCoordinate & c, const FixedPointCoordinate & d) const {
return (a == b && c == d) || (a == c && b == d) || (a == d && b == c); return (a == b && c == d) || (a == c && b == d) || (a == d && b == c);
} }
-50
View File
@@ -1,50 +0,0 @@
/*
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 TIMINGUTIL_H_
#define TIMINGUTIL_H_
#include <climits>
#include <cstdlib>
#ifdef _WIN32
#include <sys/timeb.h>
#include <sys/types.h>
#include <winsock.h>
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 <sys/time.h>
#endif
/** Returns a timestamp (now) in seconds (incl. a fractional part). */
static inline double get_timestamp() {
struct timeval tp;
gettimeofday(&tp, NULL);
return double(tp.tv_sec) + tp.tv_usec / 1000000.;
}
#endif /* TIMINGUTIL_H_ */
+2 -2
View File
@@ -21,12 +21,12 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef XORFASTHASHSTORAGE_H_ #ifndef XORFASTHASHSTORAGE_H_
#define XORFASTHASHSTORAGE_H_ #define XORFASTHASHSTORAGE_H_
#include "XORFastHash.h"
#include <climits> #include <climits>
#include <vector> #include <vector>
#include <bitset> #include <bitset>
#include "XORFastHash.h"
template< typename NodeID, typename Key > template< typename NodeID, typename Key >
class XORFastHashStorage { class XORFastHashStorage {
public: public:
+9 -8
View File
@@ -21,20 +21,21 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASE_DESCRIPTOR_H_ #ifndef BASE_DESCRIPTOR_H_
#define BASE_DESCRIPTOR_H_ #define BASE_DESCRIPTOR_H_
#include "../DataStructures/HashTable.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngine.h"
#include "../Server/BasicDatastructures.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <vector> #include <vector>
#include "../typedefs.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/SearchEngine.h"
#include "../Util/StringUtil.h"
#include "../Plugins/RawRouteData.h"
struct _DescriptorConfig { struct _DescriptorConfig {
_DescriptorConfig() : instructions(true), geometry(true), encodeGeometry(true), z(18) {} _DescriptorConfig() : instructions(true), geometry(true), encodeGeometry(true), z(18) {}
bool instructions; bool instructions;
+16 -13
View File
@@ -32,11 +32,14 @@ inline double DescriptionFactory::RadianToDegree(const double radian) const {
return radian * (180/M_PI); return radian * (180/M_PI);
} }
double DescriptionFactory::GetBearing(const _Coordinate& A, const _Coordinate& B) const { double DescriptionFactory::GetBearing(
double deltaLong = DegreeToRadian(B.lon/100000. - A.lon/100000.); const FixedPointCoordinate & A,
const FixedPointCoordinate & B
) const {
double deltaLong = DegreeToRadian(B.lon/COORDINATE_PRECISION - A.lon/COORDINATE_PRECISION);
double lat1 = DegreeToRadian(A.lat/100000.); double lat1 = DegreeToRadian(A.lat/COORDINATE_PRECISION);
double lat2 = DegreeToRadian(B.lat/100000.); double lat2 = DegreeToRadian(B.lat/COORDINATE_PRECISION);
double y = sin(deltaLong) * cos(lat2); double y = sin(deltaLong) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(deltaLong); double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(deltaLong);
@@ -59,7 +62,7 @@ void DescriptionFactory::SetEndSegment(const PhantomNode & _targetPhantom) {
pathDescription.push_back(SegmentInformation(_targetPhantom.location, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1, 0, true) ); pathDescription.push_back(SegmentInformation(_targetPhantom.location, _targetPhantom.nodeBasedEdgeNameID, 0, _targetPhantom.weight1, 0, true) );
} }
void DescriptionFactory::AppendSegment(const _Coordinate & coordinate, const _PathData & data ) { void DescriptionFactory::AppendSegment(const FixedPointCoordinate & coordinate, const _PathData & data ) {
if(1 == pathDescription.size() && pathDescription.back().location == coordinate) { if(1 == pathDescription.size() && pathDescription.back().location == coordinate) {
pathDescription.back().nameID = data.nameID; pathDescription.back().nameID = data.nameID;
} else { } else {
@@ -91,7 +94,7 @@ void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLev
/** starts at index 1 */ /** starts at index 1 */
pathDescription[0].length = 0; pathDescription[0].length = 0;
for(unsigned i = 1; i < pathDescription.size(); ++i) { for(unsigned i = 1; i < pathDescription.size(); ++i) {
pathDescription[i].length = ApproximateDistanceByEuclid(pathDescription[i-1].location, pathDescription[i].location); pathDescription[i].length = ApproximateEuclideanDistance(pathDescription[i-1].location, pathDescription[i].location);
} }
double lengthOfSegment = 0; double lengthOfSegment = 0;
@@ -123,7 +126,7 @@ void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLev
// || std::string::npos != string0.find(string1+" ;") // || std::string::npos != string0.find(string1+" ;")
// || std::string::npos != string0.find("; "+string1) // || std::string::npos != string0.find("; "+string1)
// ){ // ){
// INFO("->next correct: " << string0 << " contains " << string1); // SimpleLogger().Write() << "->next correct: " << string0 << " contains " << string1;
// for(; lastTurn != i; ++lastTurn) // for(; lastTurn != i; ++lastTurn)
// pathDescription[lastTurn].nameID = pathDescription[i].nameID; // pathDescription[lastTurn].nameID = pathDescription[i].nameID;
// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn; // pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
@@ -132,7 +135,7 @@ void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLev
// || std::string::npos != string1.find(string0+" ;") // || std::string::npos != string1.find(string0+" ;")
// || std::string::npos != string1.find("; "+string0) // || std::string::npos != string1.find("; "+string0)
// ){ // ){
// INFO("->prev correct: " << string1 << " contains " << string0); // SimpleLogger().Write() << "->prev correct: " << string1 << " contains " << string0;
// pathDescription[i].nameID = pathDescription[i-1].nameID; // pathDescription[i].nameID = pathDescription[i-1].nameID;
// pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn; // pathDescription[i].turnInstruction = TurnInstructionsClass::NoTurn;
// } // }
@@ -153,24 +156,24 @@ void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLev
if(TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) { if(TurnInstructionsClass::NoTurn != pathDescription[i].turnInstruction) {
//INFO("Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID); //SimpleLogger().Write() << "Turn after " << lengthOfSegment << "m into way with name id " << segment.nameID;
assert(pathDescription[i].necessary); assert(pathDescription[i].necessary);
lengthOfSegment = 0; lengthOfSegment = 0;
durationOfSegment = 0; durationOfSegment = 0;
indexOfSegmentBegin = i; indexOfSegmentBegin = i;
} }
} }
// INFO("#segs: " << pathDescription.size()); // SimpleLogger().Write() << "#segs: " << pathDescription.size();
//Post-processing to remove empty or nearly empty path segments //Post-processing to remove empty or nearly empty path segments
if(FLT_EPSILON > pathDescription.back().length) { if(FLT_EPSILON > pathDescription.back().length) {
// INFO("#segs: " << pathDescription.size() << ", last ratio: " << targetPhantom.ratio << ", length: " << pathDescription.back().length); // SimpleLogger().Write() << "#segs: " << pathDescription.size() << ", last ratio: " << targetPhantom.ratio << ", length: " << pathDescription.back().length;
if(pathDescription.size() > 2){ if(pathDescription.size() > 2){
pathDescription.pop_back(); pathDescription.pop_back();
pathDescription.back().necessary = true; pathDescription.back().necessary = true;
pathDescription.back().turnInstruction = TurnInstructions.NoTurn; pathDescription.back().turnInstruction = TurnInstructions.NoTurn;
targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID; targetPhantom.nodeBasedEdgeNameID = (pathDescription.end()-2)->nameID;
// INFO("Deleting last turn instruction"); // SimpleLogger().Write() << "Deleting last turn instruction";
} }
} else { } else {
pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.ratio); pathDescription[indexOfSegmentBegin].duration *= (1.-targetPhantom.ratio);
@@ -182,7 +185,7 @@ void DescriptionFactory::Run(const SearchEngine &sEngine, const unsigned zoomLev
pathDescription[0].turnInstruction = TurnInstructions.HeadOn; pathDescription[0].turnInstruction = TurnInstructions.HeadOn;
pathDescription[0].necessary = true; pathDescription[0].necessary = true;
startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID; startPhantom.nodeBasedEdgeNameID = pathDescription[0].nameID;
// INFO("Deleting first turn instruction, ratio: " << startPhantom.ratio << ", length: " << pathDescription[0].length); // SimpleLogger().Write() << "Deleting first turn instruction, ratio: " << startPhantom.ratio << ", length: " << pathDescription[0].length;
} }
} else { } else {
pathDescription[0].duration *= startPhantom.ratio; pathDescription[0].duration *= startPhantom.ratio;
+6 -5
View File
@@ -21,15 +21,16 @@
#ifndef DESCRIPTIONFACTORY_H_ #ifndef DESCRIPTIONFACTORY_H_
#define DESCRIPTIONFACTORY_H_ #define DESCRIPTIONFACTORY_H_
#include <vector>
#include "../typedefs.h"
#include "../Algorithms/DouglasPeucker.h" #include "../Algorithms/DouglasPeucker.h"
#include "../Algorithms/PolylineCompressor.h" #include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/Coordinate.h" #include "../DataStructures/Coordinate.h"
#include "../DataStructures/SearchEngine.h" #include "../DataStructures/SearchEngine.h"
#include "../DataStructures/SegmentInformation.h" #include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <vector>
/* This class is fed with all way segments in consecutive order /* This class is fed with all way segments in consecutive order
* and produces the description plus the encoded polyline */ * and produces the description plus the encoded polyline */
@@ -62,10 +63,10 @@ public:
std::vector <SegmentInformation> pathDescription; std::vector <SegmentInformation> pathDescription;
DescriptionFactory(); DescriptionFactory();
virtual ~DescriptionFactory(); virtual ~DescriptionFactory();
double GetBearing(const _Coordinate& C, const _Coordinate& B) const; double GetBearing(const FixedPointCoordinate& C, const FixedPointCoordinate& B) const;
void AppendEncodedPolylineString(std::string &output); void AppendEncodedPolylineString(std::string &output);
void AppendUnencodedPolylineString(std::string &output); void AppendUnencodedPolylineString(std::string &output);
void AppendSegment(const _Coordinate & coordinate, const _PathData & data); void AppendSegment(const FixedPointCoordinate & coordinate, const _PathData & data);
void BuildRouteSummary(const double distance, const unsigned time); void BuildRouteSummary(const double distance, const unsigned time);
void SetStartSegment(const PhantomNode & startPhantom); void SetStartSegment(const PhantomNode & startPhantom);
void SetEndSegment(const PhantomNode & startPhantom); void SetEndSegment(const PhantomNode & startPhantom);
+3 -2
View File
@@ -21,13 +21,14 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef GPX_DESCRIPTOR_H_ #ifndef GPX_DESCRIPTOR_H_
#define GPX_DESCRIPTOR_H_ #define GPX_DESCRIPTOR_H_
#include <boost/foreach.hpp>
#include "BaseDescriptor.h" #include "BaseDescriptor.h"
#include <boost/foreach.hpp>
class GPXDescriptor : public BaseDescriptor{ class GPXDescriptor : public BaseDescriptor{
private: private:
_DescriptorConfig config; _DescriptorConfig config;
_Coordinate current; FixedPointCoordinate current;
std::string tmp; std::string tmp;
public: public:
+12 -7
View File
@@ -21,11 +21,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef JSON_DESCRIPTOR_H_ #ifndef JSON_DESCRIPTOR_H_
#define JSON_DESCRIPTOR_H_ #define JSON_DESCRIPTOR_H_
#include <algorithm>
#include <boost/lambda/lambda.hpp>
#include <boost/bind.hpp>
#include "BaseDescriptor.h" #include "BaseDescriptor.h"
#include "DescriptionFactory.h" #include "DescriptionFactory.h"
#include "../Algorithms/ObjectToBase64.h" #include "../Algorithms/ObjectToBase64.h"
@@ -34,14 +29,24 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../Util/Azimuth.h" #include "../Util/Azimuth.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <algorithm>
class JSONDescriptor : public BaseDescriptor{ class JSONDescriptor : public BaseDescriptor{
private: private:
_DescriptorConfig config; _DescriptorConfig config;
DescriptionFactory descriptionFactory; DescriptionFactory descriptionFactory;
DescriptionFactory alternateDescriptionFactory; DescriptionFactory alternateDescriptionFactory;
_Coordinate current; FixedPointCoordinate current;
unsigned numberOfEnteredRestrictedAreas; unsigned numberOfEnteredRestrictedAreas;
struct { struct RoundAbout{
RoundAbout() :
startIndex(INT_MAX),
nameID(INT_MAX),
leaveAtExit(INT_MAX)
{}
int startIndex; int startIndex;
int nameID; int nameID;
int leaveAtExit; int leaveAtExit;
+18 -34
View File
@@ -29,38 +29,34 @@ extractor_callbacks(ec), scriptingEnvironment(se), luaState(NULL), use_turn_rest
void BaseParser::ReadUseRestrictionsSetting() { void BaseParser::ReadUseRestrictionsSetting() {
if( 0 != luaL_dostring( luaState, "return use_turn_restrictions\n") ) { if( 0 != luaL_dostring( luaState, "return use_turn_restrictions\n") ) {
ERR(lua_tostring( luaState,-1)<< " occured in scripting block"); throw OSRMException(
/*lua_tostring( luaState, -1 ) + */"ERROR occured in scripting block"
);
} }
if( lua_isboolean( luaState, -1) ) { if( lua_isboolean( luaState, -1) ) {
use_turn_restrictions = lua_toboolean(luaState, -1); use_turn_restrictions = lua_toboolean(luaState, -1);
} }
if( use_turn_restrictions ) { if( use_turn_restrictions ) {
INFO("Using turn restrictions" ); SimpleLogger().Write() << "Using turn restrictions";
} else { } else {
INFO("Ignoring turn restrictions" ); SimpleLogger().Write() << "Ignoring turn restrictions";
} }
} }
void BaseParser::ReadRestrictionExceptions() { void BaseParser::ReadRestrictionExceptions() {
if(lua_function_exists(luaState, "get_exceptions" )) { if(lua_function_exists(luaState, "get_exceptions" )) {
//get list of turn restriction exceptions //get list of turn restriction exceptions
try { luabind::call_function<void>(
luabind::call_function<void>( luaState,
luaState, "get_exceptions",
"get_exceptions", boost::ref(restriction_exceptions)
boost::ref(restriction_exceptions) );
); SimpleLogger().Write() << "Found " << restriction_exceptions.size() << " exceptions to turn restriction";
INFO("Found " << restriction_exceptions.size() << " exceptions to turn restriction"); BOOST_FOREACH(const std::string & str, restriction_exceptions) {
BOOST_FOREACH(std::string & str, restriction_exceptions) { SimpleLogger().Write() << " " << str;
INFO(" " << str);
}
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
} }
} else { } else {
INFO("Found no exceptions to turn restrictions"); SimpleLogger().Write() << "Found no exceptions to turn restrictions";
} }
} }
@@ -72,37 +68,25 @@ void BaseParser::report_errors(lua_State *L, const int status) const {
} }
void BaseParser::ParseNodeInLua(ImportNode& n, lua_State* localLuaState) { void BaseParser::ParseNodeInLua(ImportNode& n, lua_State* localLuaState) {
try { luabind::call_function<void>( localLuaState, "node_function", boost::ref(n) );
luabind::call_function<void>( localLuaState, "node_function", boost::ref(n) );
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
}
} }
void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* localLuaState) { void BaseParser::ParseWayInLua(ExtractionWay& w, lua_State* localLuaState) {
if(2 > w.path.size()) { if(2 > w.path.size()) {
return; return;
} }
try { luabind::call_function<void>( localLuaState, "way_function", boost::ref(w) );
luabind::call_function<void>( localLuaState, "way_function", boost::ref(w) );
} catch (const luabind::error &er) {
lua_State* Ler=er.state();
report_errors(Ler, -1);
ERR(er.what());
}
} }
bool BaseParser::ShouldIgnoreRestriction(const std::string& except_tag_string) const { bool BaseParser::ShouldIgnoreRestriction(const std::string& except_tag_string) const {
//should this restriction be ignored? yes if there's an overlap between: //should this restriction be ignored? yes if there's an overlap between:
//a) the list of modes in the except tag of the restriction (except_tag_string), ex: except=bus;bicycle //a) the list of modes in the except tag of the restriction (except_tag_string), ex: except=bus;bicycle
//b) the lua profile defines a hierachy of modes, ex: [access, vehicle, bicycle] //b) the lua profile defines a hierachy of modes, ex: [access, vehicle, bicycle]
if( "" == except_tag_string ) { if( "" == except_tag_string ) {
return false; return false;
} }
//Be warned, this is quadratic work here, but we assume that //Be warned, this is quadratic work here, but we assume that
//only a few exceptions are actually defined. //only a few exceptions are actually defined.
std::vector<std::string> exceptions; std::vector<std::string> exceptions;
+10 -8
View File
@@ -21,17 +21,19 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASEPARSER_H_ #ifndef BASEPARSER_H_
#define BASEPARSER_H_ #define BASEPARSER_H_
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
extern "C" { extern "C" {
#include <lua.h> #include <lua.h>
#include <lauxlib.h> #include <lauxlib.h>
#include <lualib.h> #include <lualib.h>
} }
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
class BaseParser : boost::noncopyable { class BaseParser : boost::noncopyable {
public: public:
BaseParser(ExtractorCallbacks* ec, ScriptingEnvironment& se); BaseParser(ExtractorCallbacks* ec, ScriptingEnvironment& se);
@@ -43,11 +45,11 @@ public:
virtual void ParseWayInLua(ExtractionWay& n, lua_State* luaStateForThread); virtual void ParseWayInLua(ExtractionWay& n, lua_State* luaStateForThread);
virtual void report_errors(lua_State *L, const int status) const; virtual void report_errors(lua_State *L, const int status) const;
protected: protected:
virtual void ReadUseRestrictionsSetting(); virtual void ReadUseRestrictionsSetting();
virtual void ReadRestrictionExceptions(); virtual void ReadRestrictionExceptions();
virtual bool ShouldIgnoreRestriction(const std::string& except_tag_string) const; virtual bool ShouldIgnoreRestriction(const std::string& except_tag_string) const;
ExtractorCallbacks* extractor_callbacks; ExtractorCallbacks* extractor_callbacks;
ScriptingEnvironment& scriptingEnvironment; ScriptingEnvironment& scriptingEnvironment;
lua_State* luaState; lua_State* luaState;
+9 -7
View File
@@ -20,7 +20,7 @@
#include "ExtractionContainers.h" #include "ExtractionContainers.h"
void ExtractionContainers::PrepareData(const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM) { void ExtractionContainers::PrepareData(const std::string & output_file_name, const std::string restrictionsFileName, const unsigned amountOfRAM) {
try { try {
unsigned usedNodeCounter = 0; unsigned usedNodeCounter = 0;
unsigned usedEdgeCounter = 0; unsigned usedEdgeCounter = 0;
@@ -117,20 +117,22 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
++restrictionsIT; ++restrictionsIT;
} }
std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl; std::cout << "ok, after " << get_timestamp() - time << "s" << std::endl;
INFO("usable restrictions: " << usableRestrictionsCounter ); SimpleLogger().Write() << "usable restrictions: " << usableRestrictionsCounter;
//serialize restrictions //serialize restrictions
std::ofstream restrictionsOutstream; std::ofstream restrictionsOutstream;
restrictionsOutstream.open(restrictionsFileName.c_str(), std::ios::binary); restrictionsOutstream.open(restrictionsFileName.c_str(), std::ios::binary);
restrictionsOutstream.write((char*)&uuid, sizeof(UUID));
restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned)); restrictionsOutstream.write((char*)&usableRestrictionsCounter, sizeof(unsigned));
for(restrictionsIT = restrictionsVector.begin(); restrictionsIT != restrictionsVector.end(); ++restrictionsIT) { for(restrictionsIT = restrictionsVector.begin(); restrictionsIT != restrictionsVector.end(); ++restrictionsIT) {
if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) { if(UINT_MAX != restrictionsIT->restriction.fromNode && UINT_MAX != restrictionsIT->restriction.toNode) {
restrictionsOutstream.write((char *)&(restrictionsIT->restriction), sizeof(_Restriction)); restrictionsOutstream.write((char *)&(restrictionsIT->restriction), sizeof(TurnRestriction));
} }
} }
restrictionsOutstream.close(); restrictionsOutstream.close();
std::ofstream fout; std::ofstream fout;
fout.open(outputFileName.c_str(), std::ios::binary); fout.open(output_file_name.c_str(), std::ios::binary);
fout.write((char*)&uuid, sizeof(UUID));
fout.write((char*)&usedNodeCounter, sizeof(unsigned)); fout.write((char*)&usedNodeCounter, sizeof(unsigned));
time = get_timestamp(); time = get_timestamp();
std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush; std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush;
@@ -158,7 +160,7 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
std::cout << "[extractor] setting number of nodes ... " << std::flush; std::cout << "[extractor] setting number of nodes ... " << std::flush;
std::ios::pos_type positionInFile = fout.tellp(); std::ios::pos_type positionInFile = fout.tellp();
fout.seekp(std::ios::beg); fout.seekp(std::ios::beg+sizeof(UUID));
fout.write((char*)&usedNodeCounter, sizeof(unsigned)); fout.write((char*)&usedNodeCounter, sizeof(unsigned));
fout.seekp(positionInFile); fout.seekp(positionInFile);
@@ -271,7 +273,7 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
std::cout << "ok" << std::endl; std::cout << "ok" << std::endl;
time = get_timestamp(); time = get_timestamp();
std::cout << "[extractor] writing street name index ... " << std::flush; std::cout << "[extractor] writing street name index ... " << std::flush;
std::string nameOutFileName = (outputFileName + ".names"); std::string nameOutFileName = (output_file_name + ".names");
std::ofstream nameOutFile(nameOutFileName.c_str(), std::ios::binary); std::ofstream nameOutFile(nameOutFileName.c_str(), std::ios::binary);
unsigned sizeOfNameIndex = nameVector.size(); unsigned sizeOfNameIndex = nameVector.size();
nameOutFile.write((char *)&(sizeOfNameIndex), sizeof(unsigned)); nameOutFile.write((char *)&(sizeOfNameIndex), sizeof(unsigned));
@@ -296,7 +298,7 @@ void ExtractionContainers::PrepareData(const std::string & outputFileName, const
// addressOutFile.close(); // addressOutFile.close();
// cout << "ok, after " << get_timestamp() - time << "s" << endl; // cout << "ok, after " << get_timestamp() - time << "s" << endl;
INFO("Processed " << usedNodeCounter << " nodes and " << usedEdgeCounter << " edges"); SimpleLogger().Write() << "Processed " << usedNodeCounter << " nodes and " << usedEdgeCounter << " edges";
} catch ( const std::exception& e ) { } catch ( const std::exception& e ) {
+7 -9
View File
@@ -22,7 +22,9 @@
#define EXTRACTIONCONTAINERS_H_ #define EXTRACTIONCONTAINERS_H_
#include "ExtractorStructs.h" #include "ExtractorStructs.h"
#include "../DataStructures/TimingUtil.h" #include "../Util/SimpleLogger.h"
#include "../Util/TimingUtil.h"
#include "../Util/UUID.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <stxxl.h> #include <stxxl.h>
@@ -38,14 +40,10 @@ public:
ExtractionContainers() { ExtractionContainers() {
//Check if another instance of stxxl is already running or if there is a general problem //Check if another instance of stxxl is already running or if there is a general problem
try { stxxl::vector<unsigned> testForRunningInstance;
stxxl::vector<unsigned> testForRunningInstance;
} catch(std::exception & e) {
ERR("Could not instantiate STXXL layer." << std::endl << e.what());
}
nameVector.push_back(""); nameVector.push_back("");
} }
virtual ~ExtractionContainers() { virtual ~ExtractionContainers() {
usedNodeIDs.clear(); usedNodeIDs.clear();
allNodes.clear(); allNodes.clear();
@@ -55,7 +53,7 @@ public:
wayStartEndVector.clear(); wayStartEndVector.clear();
} }
void PrepareData( const std::string & outputFileName, const std::string restrictionsFileName, const unsigned amountOfRAM); void PrepareData( const std::string & output_file_name, const std::string restrictionsFileName, const unsigned amountOfRAM);
STXXLNodeIDVector usedNodeIDs; STXXLNodeIDVector usedNodeIDs;
STXXLNodeVector allNodes; STXXLNodeVector allNodes;
@@ -63,7 +61,7 @@ public:
STXXLStringVector nameVector; STXXLStringVector nameVector;
STXXLRestrictionsVector restrictionsVector; STXXLRestrictionsVector restrictionsVector;
STXXLWayIDStartEndVector wayStartEndVector; STXXLWayIDStartEndVector wayStartEndVector;
const UUID uuid;
}; };
#endif /* EXTRACTIONCONTAINERS_H_ */ #endif /* EXTRACTIONCONTAINERS_H_ */
+2 -5
View File
@@ -18,19 +18,16 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef EXTRACTIONHELPERFUNCTIONS_H_ #ifndef EXTRACTIONHELPERFUNCTIONS_H_
#define EXTRACTIONHELPERFUNCTIONS_H_ #define EXTRACTIONHELPERFUNCTIONS_H_
#include "../Util/StringUtil.h"
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/algorithm/string_regex.hpp> #include <boost/algorithm/string_regex.hpp>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include <climits> #include <climits>
#include "../Util/StringUtil.h"
namespace qi = boost::spirit::qi; namespace qi = boost::spirit::qi;
//TODO: Move into LUA //TODO: Move into LUA
+6 -24
View File
@@ -12,26 +12,6 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. 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.
*/
/*
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 You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -40,7 +20,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "ExtractorCallbacks.h" #include "ExtractorCallbacks.h"
#include "ExtractionHelperFunctions.h"
ExtractorCallbacks::ExtractorCallbacks() {externalMemory = NULL; stringMap = NULL; } ExtractorCallbacks::ExtractorCallbacks() {externalMemory = NULL; stringMap = NULL; }
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap) { ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers * ext, StringMap * strMap) {
@@ -52,7 +31,7 @@ ExtractorCallbacks::~ExtractorCallbacks() { }
/** warning: caller needs to take care of synchronization! */ /** warning: caller needs to take care of synchronization! */
void ExtractorCallbacks::nodeFunction(const _Node &n) { void ExtractorCallbacks::nodeFunction(const _Node &n) {
if(n.lat <= 85*100000 && n.lat >= -85*100000) { if(n.lat <= 85*COORDINATE_PRECISION && n.lat >= -85*COORDINATE_PRECISION) {
externalMemory->allNodes.push_back(n); externalMemory->allNodes.push_back(n);
} }
} }
@@ -66,7 +45,9 @@ bool ExtractorCallbacks::restrictionFunction(const _RawRestrictionContainer &r)
void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) { void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
if((0 < parsed_way.speed) || (0 < parsed_way.duration)) { //Only true if the way is specified by the speed profile if((0 < parsed_way.speed) || (0 < parsed_way.duration)) { //Only true if the way is specified by the speed profile
if(UINT_MAX == parsed_way.id){ if(UINT_MAX == parsed_way.id){
DEBUG("found bogus way with id: " << parsed_way.id << " of size " << parsed_way.path.size()); SimpleLogger().Write(logDEBUG) <<
"found bogus way with id: " << parsed_way.id <<
" of size " << parsed_way.path.size();
return; return;
} }
@@ -76,7 +57,8 @@ void ExtractorCallbacks::wayFunction(ExtractionWay &parsed_way) {
} }
if(FLT_EPSILON >= fabs(-1. - parsed_way.speed)){ if(FLT_EPSILON >= fabs(-1. - parsed_way.speed)){
DEBUG("found way with bogus speed, id: " << parsed_way.id); SimpleLogger().Write(logDEBUG) <<
"found way with bogus speed, id: " << parsed_way.id;
return; return;
} }
+7 -4
View File
@@ -21,8 +21,11 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef EXTRACTORCALLBACKS_H_ #ifndef EXTRACTORCALLBACKS_H_
#define EXTRACTORCALLBACKS_H_ #define EXTRACTORCALLBACKS_H_
#include <string> #include "ExtractionContainers.h"
#include <vector> #include "ExtractionHelperFunctions.h"
#include "ExtractorStructs.h"
#include "../DataStructures/Coordinate.h"
#include <cfloat> #include <cfloat>
@@ -30,8 +33,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <boost/algorithm/string/regex.hpp> #include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include "ExtractionContainers.h" #include <string>
#include "ExtractorStructs.h" #include <vector>
class ExtractorCallbacks{ class ExtractorCallbacks{
private: private:
+12 -13
View File
@@ -21,21 +21,20 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef EXTRACTORSTRUCTS_H_ #ifndef EXTRACTORSTRUCTS_H_
#define EXTRACTORSTRUCTS_H_ #define EXTRACTORSTRUCTS_H_
#include <climits> #include "../DataStructures/Coordinate.h"
#include <string> #include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/Restriction.h"
#include "../typedefs.h"
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp> #include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include "../DataStructures/Coordinate.h" #include <climits>
#include "../DataStructures/HashTable.h" #include <string>
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/NodeCoords.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/TimingUtil.h"
#include "../typedefs.h"
typedef boost::unordered_map<std::string, NodeID > StringMap; typedef boost::unordered_map<std::string, NodeID > StringMap;
typedef boost::unordered_map<std::string, std::pair<int, short> > StringToIntPairMap; typedef boost::unordered_map<std::string, std::pair<int, short> > StringToIntPairMap;
@@ -44,12 +43,12 @@ struct ExtractionWay {
ExtractionWay() { ExtractionWay() {
Clear(); Clear();
} }
inline void Clear(){ inline void Clear(){
id = UINT_MAX; id = UINT_MAX;
nameID = UINT_MAX; nameID = UINT_MAX;
path.clear(); path.clear();
keyVals.EraseAll(); keyVals.clear();
direction = ExtractionWay::notSure; direction = ExtractionWay::notSure;
speed = -1; speed = -1;
backward_speed = -1; backward_speed = -1;
@@ -110,8 +109,8 @@ struct InternalExtractorEdge {
bool isAccessRestricted; bool isAccessRestricted;
bool isContraFlow; bool isContraFlow;
_Coordinate startCoord; FixedPointCoordinate startCoord;
_Coordinate targetCoord; FixedPointCoordinate targetCoord;
static InternalExtractorEdge min_value() { static InternalExtractorEdge min_value() {
return InternalExtractorEdge(0,0); return InternalExtractorEdge(0,0);
+14 -9
View File
@@ -28,7 +28,7 @@ PBFParser::PBFParser(const char * fileName, ExtractorCallbacks* ec, ScriptingEnv
input.open(fileName, std::ios::in | std::ios::binary); input.open(fileName, std::ios::in | std::ios::binary);
if (!input) { if (!input) {
std::cerr << fileName << ": File not found." << std::endl; throw OSRMException("pbf file not found.");
} }
#ifndef NDEBUG #ifndef NDEBUG
@@ -50,7 +50,10 @@ PBFParser::~PBFParser() {
google::protobuf::ShutdownProtobufLibrary(); google::protobuf::ShutdownProtobufLibrary();
#ifndef NDEBUG #ifndef NDEBUG
DEBUG("parsed " << blockCount << " blocks from pbf with " << groupCount << " groups"); SimpleLogger().Write(logDEBUG) <<
"parsed " << blockCount <<
" blocks from pbf with " << groupCount <<
" groups";
#endif #endif
} }
@@ -108,7 +111,7 @@ inline void PBFParser::ParseData() {
_ThreadData *threadData; _ThreadData *threadData;
threadDataQueue->wait_and_pop(threadData); threadDataQueue->wait_and_pop(threadData);
if( NULL==threadData ) { if( NULL==threadData ) {
INFO("Parse Data Thread Finished"); SimpleLogger().Write() << "Parse Data Thread Finished";
threadDataQueue->push(NULL); // Signal end of data for other threads threadDataQueue->push(NULL); // Signal end of data for other threads
break; break;
} }
@@ -166,8 +169,8 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
m_lastDenseLatitude += dense.lat( i ); m_lastDenseLatitude += dense.lat( i );
m_lastDenseLongitude += dense.lon( i ); m_lastDenseLongitude += dense.lon( i );
extracted_nodes_vector[i].id = m_lastDenseID; extracted_nodes_vector[i].id = m_lastDenseID;
extracted_nodes_vector[i].lat = 100000*( ( double ) m_lastDenseLatitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lat_offset() ) / NANO; extracted_nodes_vector[i].lat = COORDINATE_PRECISION*( ( double ) m_lastDenseLatitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lat_offset() ) / NANO;
extracted_nodes_vector[i].lon = 100000*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO; extracted_nodes_vector[i].lon = COORDINATE_PRECISION*( ( double ) m_lastDenseLongitude * threadData->PBFprimitiveBlock.granularity() + threadData->PBFprimitiveBlock.lon_offset() ) / NANO;
while (denseTagIndex < dense.keys_vals_size()) { while (denseTagIndex < dense.keys_vals_size()) {
const int tagValue = dense.keys_vals( denseTagIndex ); const int tagValue = dense.keys_vals( denseTagIndex );
if( 0==tagValue ) { if( 0==tagValue ) {
@@ -177,7 +180,7 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
const int keyValue = dense.keys_vals ( denseTagIndex+1 ); const int keyValue = dense.keys_vals ( denseTagIndex+1 );
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data(); const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(tagValue).data();
const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data(); const std::string & value = threadData->PBFprimitiveBlock.stringtable().s(keyValue).data();
extracted_nodes_vector[i].keyVals.Add(key, value); extracted_nodes_vector[i].keyVals.insert(std::make_pair(key, value));
denseTagIndex += 2; denseTagIndex += 2;
} }
} }
@@ -194,7 +197,9 @@ inline void PBFParser::parseDenseNode(_ThreadData * threadData) {
} }
inline void PBFParser::parseNode(_ThreadData * ) { inline void PBFParser::parseNode(_ThreadData * ) {
ERR("Parsing of simple nodes not supported. PBF should use dense nodes"); throw OSRMException(
"Parsing of simple nodes not supported. PBF should use dense nodes"
);
} }
inline void PBFParser::parseRelation(_ThreadData * threadData) { inline void PBFParser::parseRelation(_ThreadData * threadData) {
@@ -304,7 +309,7 @@ inline void PBFParser::parseWay(_ThreadData * threadData) {
for(int j = 0; j < number_of_keys; ++j) { for(int j = 0; j < number_of_keys; ++j) {
const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(j)); const std::string & key = threadData->PBFprimitiveBlock.stringtable().s(inputWay.keys(j));
const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(j)); const std::string & val = threadData->PBFprimitiveBlock.stringtable().s(inputWay.vals(j));
parsed_way_vector[i].keyVals.Add(key, val); parsed_way_vector[i].keyVals.insert(std::make_pair(key, val));
} }
} }
@@ -475,7 +480,7 @@ bool PBFParser::readNextBlock(std::fstream& stream, _ThreadData * threadData) {
} }
if ( !threadData->PBFprimitiveBlock.ParseFromArray( &(threadData->charBuffer[0]), threadData-> charBuffer.size() ) ) { if ( !threadData->PBFprimitiveBlock.ParseFromArray( &(threadData->charBuffer[0]), threadData-> charBuffer.size() ) ) {
ERR("failed to parse PrimitiveBlock"); std::cerr << "failed to parse PrimitiveBlock" << std::endl;
return false; return false;
} }
return true; return true;
+5 -3
View File
@@ -21,13 +21,17 @@
#ifndef PBFPARSER_H_ #ifndef PBFPARSER_H_
#define PBFPARSER_H_ #define PBFPARSER_H_
#include "BaseParser.h"
#include "../DataStructures/Coordinate.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/ConcurrentQueue.h" #include "../DataStructures/ConcurrentQueue.h"
#include "../Util/MachineInfo.h" #include "../Util/MachineInfo.h"
#include "../Util/OpenMPWrapper.h" #include "../Util/OpenMPWrapper.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h" #include "../typedefs.h"
#include "BaseParser.h"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
@@ -37,8 +41,6 @@
#include <zlib.h> #include <zlib.h>
class PBFParser : public BaseParser { class PBFParser : public BaseParser {
enum EntityType { enum EntityType {
+46 -45
View File
@@ -22,11 +22,12 @@
ScriptingEnvironment::ScriptingEnvironment() {} ScriptingEnvironment::ScriptingEnvironment() {}
ScriptingEnvironment::ScriptingEnvironment(const char * fileName) { ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
INFO("Using script " << fileName); SimpleLogger().Write() << "Using script " << fileName;
// Create a new lua state // Create a new lua state
for(int i = 0; i < omp_get_max_threads(); ++i) for(int i = 0; i < omp_get_max_threads(); ++i) {
luaStateVector.push_back(luaL_newstate()); luaStateVector.push_back(luaL_newstate());
}
// Connect LuaBind to this lua state for all threads // Connect LuaBind to this lua state for all threads
#pragma omp parallel #pragma omp parallel
@@ -40,59 +41,59 @@ ScriptingEnvironment::ScriptingEnvironment(const char * fileName) {
// Add our function to the state's global scope // Add our function to the state's global scope
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::def("print", LUA_print<std::string>), luabind::def("print", LUA_print<std::string>),
luabind::def("parseMaxspeed", parseMaxspeed), luabind::def("parseMaxspeed", parseMaxspeed),
luabind::def("durationIsValid", durationIsValid), luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration) luabind::def("parseDuration", parseDuration)
]; ];
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::class_<HashTable<std::string, std::string> >("keyVals") luabind::class_<HashTable<std::string, std::string> >("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add) .def("Add", &HashTable<std::string, std::string>::Add)
.def("Find", &HashTable<std::string, std::string>::Find) .def("Find", &HashTable<std::string, std::string>::Find)
.def("Holds", &HashTable<std::string, std::string>::Holds) .def("Holds", &HashTable<std::string, std::string>::Holds)
]; ];
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::class_<ImportNode>("Node") luabind::class_<ImportNode>("Node")
.def(luabind::constructor<>()) .def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat) .def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon) .def_readwrite("lon", &ImportNode::lon)
.def_readwrite("id", &ImportNode::id) .def_readwrite("id", &ImportNode::id)
.def_readwrite("bollard", &ImportNode::bollard) .def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight) .def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals) .def_readwrite("tags", &ImportNode::keyVals)
]; ];
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::class_<ExtractionWay>("Way") luabind::class_<ExtractionWay>("Way")
.def(luabind::constructor<>()) .def(luabind::constructor<>())
.def_readwrite("name", &ExtractionWay::name) .def_readwrite("name", &ExtractionWay::name)
.def_readwrite("speed", &ExtractionWay::speed) .def_readwrite("speed", &ExtractionWay::speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed) .def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("duration", &ExtractionWay::duration) .def_readwrite("duration", &ExtractionWay::duration)
.def_readwrite("type", &ExtractionWay::type) .def_readwrite("type", &ExtractionWay::type)
.def_readwrite("access", &ExtractionWay::access) .def_readwrite("access", &ExtractionWay::access)
.def_readwrite("roundabout", &ExtractionWay::roundabout) .def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted) .def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid) .def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
.def_readwrite("tags", &ExtractionWay::keyVals) .def_readwrite("tags", &ExtractionWay::keyVals)
.def_readwrite("direction", &ExtractionWay::direction) .def_readwrite("direction", &ExtractionWay::direction)
.enum_("constants") .enum_("constants") [
[ luabind::value("notSure", 0),
luabind::value("notSure", 0), luabind::value("oneway", 1),
luabind::value("oneway", 1), luabind::value("bidirectional", 2),
luabind::value("bidirectional", 2), luabind::value("opposite", 3)
luabind::value("opposite", 3) ]
] ];
];
luabind::module(myLuaState) [ luabind::module(myLuaState) [
luabind::class_<std::vector<std::string> >("vector") luabind::class_<std::vector<std::string> >("vector")
.def("Add", &std::vector<std::string>::push_back) .def("Add", &std::vector<std::string>::push_back)
]; ];
if(0 != luaL_dofile(myLuaState, fileName) ) { if(0 != luaL_dofile(myLuaState, fileName) ) {
ERR(lua_tostring(myLuaState,-1)<< " occured in scripting block"); throw OSRMException("ERROR occured in scripting block");
} }
} }
} }
+5 -9
View File
@@ -21,20 +21,16 @@
#ifndef SCRIPTINGENVIRONMENT_H_ #ifndef SCRIPTINGENVIRONMENT_H_
#define SCRIPTINGENVIRONMENT_H_ #define SCRIPTINGENVIRONMENT_H_
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include <luabind/luabind.hpp>
#include "ExtractionHelperFunctions.h" #include "ExtractionHelperFunctions.h"
#include "ExtractorStructs.h" #include "ExtractorStructs.h"
#include "../typedefs.h"
#include "../DataStructures/ImportNode.h" #include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h" #include "../Util/LuaUtil.h"
#include "../Util/OpenMPWrapper.h" #include "../Util/OpenMPWrapper.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../typedefs.h"
#include <vector>
class ScriptingEnvironment { class ScriptingEnvironment {
public: public:
+14 -13
View File
@@ -18,17 +18,18 @@
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#include <boost/ref.hpp>
#include "XMLParser.h" #include "XMLParser.h"
#include "ExtractorStructs.h" #include "ExtractorStructs.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/InputReaderFactory.h" #include "../DataStructures/InputReaderFactory.h"
#include <boost/ref.hpp>
XMLParser::XMLParser(const char * filename, ExtractorCallbacks* ec, ScriptingEnvironment& se) : BaseParser(ec, se) { XMLParser::XMLParser(const char * filename, ExtractorCallbacks* ec, ScriptingEnvironment& se) : BaseParser(ec, se) {
WARN("Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf"); SimpleLogger().Write(logWARNING) <<
"Parsing plain .osm/.osm.bz2 is deprecated. Switch to .pbf";
inputReader = inputReaderFactory(filename); inputReader = inputReaderFactory(filename);
} }
@@ -43,12 +44,12 @@ bool XMLParser::Parse() {
if ( type != 1 ) { if ( type != 1 ) {
continue; continue;
} }
xmlChar* currentName = xmlTextReaderName( inputReader ); xmlChar* currentName = xmlTextReaderName( inputReader );
if ( currentName == NULL ) { if ( currentName == NULL ) {
continue; continue;
} }
if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) { if ( xmlStrEqual( currentName, ( const xmlChar* ) "node" ) == 1 ) {
ImportNode n = _ReadXMLNode(); ImportNode n = _ReadXMLNode();
ParseNodeInLua( n, luaState ); ParseNodeInLua( n, luaState );
@@ -130,13 +131,13 @@ _RawRestrictionContainer XMLParser::_ReadXMLRestriction() {
xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" ); xmlChar * type = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "type" );
if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) { if(xmlStrEqual(role, (const xmlChar *) "to") && xmlStrEqual(type, (const xmlChar *) "way")) {
restriction.toWay = atoi((const char*) ref); restriction.toWay = stringToUint((const char*) ref);
} }
if(xmlStrEqual(role, (const xmlChar *) "from") && xmlStrEqual(type, (const xmlChar *) "way")) { if(xmlStrEqual(role, (const xmlChar *) "from") && xmlStrEqual(type, (const xmlChar *) "way")) {
restriction.fromWay = atoi((const char*) ref); restriction.fromWay = stringToUint((const char*) ref);
} }
if(xmlStrEqual(role, (const xmlChar *) "via") && xmlStrEqual(type, (const xmlChar *) "node")) { if(xmlStrEqual(role, (const xmlChar *) "via") && xmlStrEqual(type, (const xmlChar *) "node")) {
restriction.restriction.viaNode = atoi((const char*) ref); restriction.restriction.viaNode = stringToUint((const char*) ref);
} }
if(NULL != type) { if(NULL != type) {
@@ -177,7 +178,7 @@ ExtractionWay XMLParser::_ReadXMLWay() {
if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) { if ( depth == childDepth && childType == 15 && xmlStrEqual( childName, ( const xmlChar* ) "way" ) == 1 ) {
xmlChar* id = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" ); xmlChar* id = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
way.id = atoi((char*)id); way.id = stringToUint((char*)id);
xmlFree(id); xmlFree(id);
xmlFree( childName ); xmlFree( childName );
break; break;
@@ -203,7 +204,7 @@ ExtractionWay XMLParser::_ReadXMLWay() {
} else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) { } else if ( xmlStrEqual( childName, ( const xmlChar* ) "nd" ) == 1 ) {
xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" ); xmlChar* ref = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "ref" );
if ( ref != NULL ) { if ( ref != NULL ) {
way.path.push_back( atoi(( const char* ) ref ) ); way.path.push_back( stringToUint(( const char* ) ref ) );
xmlFree( ref ); xmlFree( ref );
} }
} }
@@ -218,17 +219,17 @@ ImportNode XMLParser::_ReadXMLNode() {
xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" ); xmlChar* attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lat" );
if ( attribute != NULL ) { if ( attribute != NULL ) {
node.lat = static_cast<NodeID>(100000.*atof(( const char* ) attribute ) ); node.lat = static_cast<NodeID>(COORDINATE_PRECISION*atof(( const char* ) attribute ) );
xmlFree( attribute ); xmlFree( attribute );
} }
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" ); attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "lon" );
if ( attribute != NULL ) { if ( attribute != NULL ) {
node.lon = static_cast<NodeID>(100000.*atof(( const char* ) attribute )); node.lon = static_cast<NodeID>(COORDINATE_PRECISION*atof(( const char* ) attribute ));
xmlFree( attribute ); xmlFree( attribute );
} }
attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" ); attribute = xmlTextReaderGetAttribute( inputReader, ( const xmlChar* ) "id" );
if ( attribute != NULL ) { if ( attribute != NULL ) {
node.id = atoi(( const char* ) attribute ); node.id = stringToUint(( const char* ) attribute );
xmlFree( attribute ); xmlFree( attribute );
} }
+10 -6
View File
@@ -1,17 +1,17 @@
/* /*
open source routing machine open source routing machine
Copyright (C) Dennis Luxen, others 2010 Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify 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 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 the Free Software Foundation; either version 3 of the License, or
any later version. any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -21,17 +21,21 @@
#ifndef XMLPARSER_H_ #ifndef XMLPARSER_H_
#define XMLPARSER_H_ #define XMLPARSER_H_
#include "BaseParser.h"
#include "../DataStructures/Coordinate.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <libxml/xmlreader.h> #include <libxml/xmlreader.h>
#include "../typedefs.h"
#include "BaseParser.h"
class XMLParser : public BaseParser { class XMLParser : public BaseParser {
public: public:
XMLParser(const char* filename, ExtractorCallbacks* ec, ScriptingEnvironment& se); XMLParser(const char* filename, ExtractorCallbacks* ec, ScriptingEnvironment& se);
bool ReadHeader(); bool ReadHeader();
bool Parse(); bool Parse();
private: private:
_RawRestrictionContainer _ReadXMLRestriction(); _RawRestrictionContainer _ReadXMLRestriction();
ExtractionWay _ReadXMLWay(); ExtractionWay _ReadXMLWay();
+122
View File
@@ -0,0 +1,122 @@
/*
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.
*/
#include "OSRM.h"
OSRM::OSRM(const char * server_ini_path) {
if( !testDataFile(server_ini_path) ){
std::string error_message = std::string(server_ini_path) + " not found";
throw OSRMException(error_message.c_str());
}
IniFile serverConfig(server_ini_path);
boost::filesystem::path base_path =
boost::filesystem::absolute(server_ini_path).parent_path();
if ( !serverConfig.Holds("hsgrData")) {
throw OSRMException("no ram index file name in server ini");
}
if ( !serverConfig.Holds("ramIndex") ) {
throw OSRMException("no mem index file name in server ini");
}
if ( !serverConfig.Holds("fileIndex") ) {
throw OSRMException("no nodes file name in server ini");
}
if ( !serverConfig.Holds("nodesData") ) {
throw OSRMException("no nodes file name in server ini");
}
if ( !serverConfig.Holds("edgesData") ) {
throw OSRMException("no edges file name in server ini");
}
boost::filesystem::path hsgr_path = boost::filesystem::absolute(
serverConfig.GetParameter("hsgrData"),
base_path
);
boost::filesystem::path ram_index_path = boost::filesystem::absolute(
serverConfig.GetParameter("ramIndex"),
base_path
);
boost::filesystem::path file_index_path = boost::filesystem::absolute(
serverConfig.GetParameter("fileIndex"),
base_path
);
boost::filesystem::path node_data_path = boost::filesystem::absolute(
serverConfig.GetParameter("nodesData"),
base_path
);
boost::filesystem::path edge_data_path = boost::filesystem::absolute(
serverConfig.GetParameter("edgesData"),
base_path
);
boost::filesystem::path name_data_path = boost::filesystem::absolute(
serverConfig.GetParameter("namesData"),
base_path
);
boost::filesystem::path timestamp_path = boost::filesystem::absolute(
serverConfig.GetParameter("timestamp"),
base_path
);
objects = new QueryObjectsStorage(
hsgr_path.string(),
ram_index_path.string(),
file_index_path.string(),
node_data_path.string(),
edge_data_path.string(),
name_data_path.string(),
timestamp_path.string()
);
RegisterPlugin(new HelloWorldPlugin());
RegisterPlugin(new LocatePlugin(objects));
RegisterPlugin(new NearestPlugin(objects));
RegisterPlugin(new TimestampPlugin(objects));
RegisterPlugin(new ViaRoutePlugin(objects));
}
OSRM::~OSRM() {
BOOST_FOREACH(PluginMap::value_type & plugin_pointer, pluginMap) {
delete plugin_pointer.second;
}
delete objects;
}
void OSRM::RegisterPlugin(BasePlugin * plugin) {
SimpleLogger().Write() << "loaded plugin: " << plugin->GetDescriptor();
if( pluginMap.find(plugin->GetDescriptor()) != pluginMap.end() ) {
delete pluginMap[plugin->GetDescriptor()];
}
pluginMap.insert(std::make_pair(plugin->GetDescriptor(), plugin));
}
void OSRM::RunQuery(RouteParameters & route_parameters, http::Reply & reply) {
const PluginMap::const_iterator & iter = pluginMap.find(route_parameters.service);
if(pluginMap.end() != iter) {
reply.status = http::Reply::ok;
iter->second->HandleRequest(route_parameters, reply );
} else {
reply = http::Reply::stockReply(http::Reply::badRequest);
}
}
+58
View File
@@ -0,0 +1,58 @@
/*
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 OSRM_H
#define OSRM_H
#include "OSRM.h"
#include "../Plugins/BasePlugin.h"
#include "../Plugins/HelloWorldPlugin.h"
#include "../Plugins/LocatePlugin.h"
#include "../Plugins/NearestPlugin.h"
#include "../Plugins/TimestampPlugin.h"
#include "../Plugins/ViaRoutePlugin.h"
#include "../Server/DataStructures/RouteParameters.h"
#include "../Util/IniFile.h"
#include "../Util/InputFileUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
#include "../Server/BasicDatastructures.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/noncopyable.hpp>
#include <boost/thread.hpp>
#include <vector>
class OSRM : boost::noncopyable {
typedef boost::unordered_map<std::string, BasePlugin *> PluginMap;
QueryObjectsStorage * objects;
public:
OSRM(const char * server_ini_path);
~OSRM();
void RunQuery(RouteParameters & route_parameters, http::Reply & reply);
private:
void RegisterPlugin(BasePlugin * plugin);
PluginMap pluginMap;
};
#endif //OSRM_H
+17 -6
View File
@@ -21,21 +21,32 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASEPLUGIN_H_ #ifndef BASEPLUGIN_H_
#define BASEPLUGIN_H_ #define BASEPLUGIN_H_
#include <cassert> #include "../DataStructures/Coordinate.h"
#include "../Server/BasicDatastructures.h"
#include "../Server/DataStructures/RouteParameters.h"
#include <string> #include <string>
#include <vector> #include <vector>
#include "RouteParameters.h"
#include "../Server/BasicDatastructures.h"
class BasePlugin { class BasePlugin {
public: public:
BasePlugin() { } BasePlugin() { }
//Maybe someone can explain the pure virtual destructor thing to me (dennis) //Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BasePlugin() { } virtual ~BasePlugin() { }
virtual std::string GetDescriptor() const = 0; virtual const std::string & GetDescriptor() const = 0;
virtual std::string GetVersionString() const = 0 ;
virtual void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) = 0; virtual void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) = 0;
inline bool checkCoord(const FixedPointCoordinate & c) {
if(
c.lat > 90*COORDINATE_PRECISION ||
c.lat < -90*COORDINATE_PRECISION ||
c.lon > 180*COORDINATE_PRECISION ||
c.lon < -180*COORDINATE_PRECISION
) {
return false;
}
return true;
}
}; };
#endif /* BASEPLUGIN_H_ */ #endif /* BASEPLUGIN_H_ */
+25 -12
View File
@@ -1,24 +1,35 @@
/* /*
* LocatePlugin.h open source routing machine
* Copyright (C) Dennis Luxen, 2010
* Created on: 01.01.2011
* Author: dennis 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 HELLOWORLDPLUGIN_H_ #ifndef HELLOWORLDPLUGIN_H_
#define HELLOWORLDPLUGIN_H_ #define HELLOWORLDPLUGIN_H_
#include <sstream>
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include <sstream>
class HelloWorldPlugin : public BasePlugin { class HelloWorldPlugin : public BasePlugin {
public: public:
HelloWorldPlugin() {} HelloWorldPlugin() : descriptor_string("hello"){}
virtual ~HelloWorldPlugin() { /*std::cout << GetDescriptor() << " destructor" << std::endl;*/ } virtual ~HelloWorldPlugin() { }
std::string GetDescriptor() const { return std::string("hello"); } const std::string & GetDescriptor() const { return descriptor_string; }
std::string GetVersionString() const { return std::string("0.1a"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
@@ -35,7 +46,7 @@ public:
content << "language: " << routeParameters.language << "<br>"; content << "language: " << routeParameters.language << "<br>";
content << "Number of locations: " << routeParameters.coordinates.size() << "\n"; content << "Number of locations: " << routeParameters.coordinates.size() << "\n";
for(unsigned i = 0; i < routeParameters.coordinates.size(); ++i) { for(unsigned i = 0; i < routeParameters.coordinates.size(); ++i) {
content << " [" << i << "] " << routeParameters.coordinates[i].lat/100000. << "," << routeParameters.coordinates[i].lon/100000. << "\n"; content << " [" << i << "] " << routeParameters.coordinates[i].lat/COORDINATE_PRECISION << "," << routeParameters.coordinates[i].lon/COORDINATE_PRECISION << "\n";
} }
content << "Number of hints: " << routeParameters.hints.size() << "\n"; content << "Number of hints: " << routeParameters.hints.size() << "\n";
for(unsigned i = 0; i < routeParameters.hints.size(); ++i) { for(unsigned i = 0; i < routeParameters.hints.size(); ++i) {
@@ -45,6 +56,8 @@ public:
reply.content.append(content.str()); reply.content.append(content.str());
reply.content.append("</body></html>"); reply.content.append("</body></html>");
} }
private:
std::string descriptor_string;
}; };
#endif /* HELLOWORLDPLUGIN_H_ */ #endif /* HELLOWORLDPLUGIN_H_ */
+5 -14
View File
@@ -22,23 +22,19 @@ or see http://www.gnu.org/licenses/agpl.txt.
#define LOCATEPLUGIN_H_ #define LOCATEPLUGIN_H_
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include "../DataStructures/NodeInformationHelpDesk.h" #include "../DataStructures/NodeInformationHelpDesk.h"
#include "../Server/DataStructures/QueryObjectsStorage.h" #include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <fstream>
/* /*
* This Plugin locates the nearest node in the road network for a given coordinate. * This Plugin locates the nearest node in the road network for a given coordinate.
*/ */
class LocatePlugin : public BasePlugin { class LocatePlugin : public BasePlugin {
public: public:
LocatePlugin(QueryObjectsStorage * objects) { LocatePlugin(QueryObjectsStorage * objects) : descriptor_string("locate") {
nodeHelpDesk = objects->nodeHelpDesk; nodeHelpDesk = objects->nodeHelpDesk;
} }
std::string GetDescriptor() const { return std::string("locate"); } const std::string & GetDescriptor() const { return descriptor_string; }
std::string GetVersionString() const { return std::string("0.3 (DL)"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
//check number of parameters //check number of parameters
if(!routeParameters.coordinates.size()) { if(!routeParameters.coordinates.size()) {
@@ -51,7 +47,7 @@ public:
} }
//query to helpdesk //query to helpdesk
_Coordinate result; FixedPointCoordinate result;
std::string tmp; std::string tmp;
//json //json
@@ -99,15 +95,10 @@ public:
reply.headers[0].value = tmp; reply.headers[0].value = tmp;
return; return;
} }
private:
inline bool checkCoord(const _Coordinate & c) {
if(c.lat > 90*100000 || c.lat < -90*100000 || c.lon > 180*100000 || c.lon <-180*100000) {
return false;
}
return true;
}
private:
NodeInformationHelpDesk * nodeHelpDesk; NodeInformationHelpDesk * nodeHelpDesk;
std::string descriptor_string;
}; };
#endif /* LOCATEPLUGIN_H_ */ #endif /* LOCATEPLUGIN_H_ */
+11 -17
View File
@@ -21,14 +21,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef NearestPlugin_H_ #ifndef NearestPlugin_H_
#define NearestPlugin_H_ #define NearestPlugin_H_
#include <fstream>
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../DataStructures/NodeInformationHelpDesk.h" #include "../DataStructures/NodeInformationHelpDesk.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
/* /*
@@ -36,14 +32,17 @@ or see http://www.gnu.org/licenses/agpl.txt.
*/ */
class NearestPlugin : public BasePlugin { class NearestPlugin : public BasePlugin {
public: public:
NearestPlugin(QueryObjectsStorage * objects) : names(objects->names) { NearestPlugin(QueryObjectsStorage * objects )
:
names(objects->names),
descriptor_string("nearest")
{
nodeHelpDesk = objects->nodeHelpDesk; nodeHelpDesk = objects->nodeHelpDesk;
descriptorTable.Set("", 0); //default descriptor descriptorTable.insert(std::make_pair("" , 0)); //default descriptor
descriptorTable.Set("json", 1); descriptorTable.insert(std::make_pair("json", 1));
} }
std::string GetDescriptor() const { return std::string("nearest"); } const std::string & GetDescriptor() const { return descriptor_string; }
std::string GetVersionString() const { return std::string("0.3 (DL)"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
//check number of parameters //check number of parameters
if(!routeParameters.coordinates.size()) { if(!routeParameters.coordinates.size()) {
@@ -108,17 +107,12 @@ public:
intToString(reply.content.size(), tmp); intToString(reply.content.size(), tmp);
reply.headers[0].value = tmp; reply.headers[0].value = tmp;
} }
private:
inline bool checkCoord(const _Coordinate & c) {
if(c.lat > 90*100000 || c.lat < -90*100000 || c.lon > 180*100000 || c.lon <-180*100000) {
return false;
}
return true;
}
private:
NodeInformationHelpDesk * nodeHelpDesk; NodeInformationHelpDesk * nodeHelpDesk;
HashTable<std::string, unsigned> descriptorTable; HashTable<std::string, unsigned> descriptorTable;
std::vector<std::string> & names; std::vector<std::string> & names;
std::string descriptor_string;
}; };
#endif /* NearestPlugin_H_ */ #endif /* NearestPlugin_H_ */
+5 -7
View File
@@ -21,17 +21,14 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef TIMESTAMPPLUGIN_H_ #ifndef TIMESTAMPPLUGIN_H_
#define TIMESTAMPPLUGIN_H_ #define TIMESTAMPPLUGIN_H_
#include <cassert>
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
class TimestampPlugin : public BasePlugin { class TimestampPlugin : public BasePlugin {
public: public:
TimestampPlugin(QueryObjectsStorage * o) : objects(o) { TimestampPlugin(QueryObjectsStorage * o)
} : objects(o), descriptor_string("timestamp")
std::string GetDescriptor() const { return std::string("timestamp"); } { }
std::string GetVersionString() const { return std::string("0.3 (DL)"); } const std::string & GetDescriptor() const { return descriptor_string; }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
std::string tmp; std::string tmp;
@@ -70,6 +67,7 @@ public:
} }
private: private:
QueryObjectsStorage * objects; QueryObjectsStorage * objects;
std::string descriptor_string;
}; };
#endif /* TIMESTAMPPLUGIN_H_ */ #endif /* TIMESTAMPPLUGIN_H_ */
+29 -37
View File
@@ -21,29 +21,24 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef VIAROUTEPLUGIN_H_ #ifndef VIAROUTEPLUGIN_H_
#define VIAROUTEPLUGIN_H_ #define VIAROUTEPLUGIN_H_
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include "BasePlugin.h" #include "BasePlugin.h"
#include "RouteParameters.h"
#include "../Algorithms/ObjectToBase64.h" #include "../Algorithms/ObjectToBase64.h"
#include "../Descriptors/BaseDescriptor.h"
#include "../Descriptors/GPXDescriptor.h"
#include "../Descriptors/JSONDescriptor.h"
#include "../DataStructures/HashTable.h" #include "../DataStructures/HashTable.h"
#include "../DataStructures/QueryEdge.h" #include "../DataStructures/QueryEdge.h"
#include "../DataStructures/StaticGraph.h" #include "../DataStructures/StaticGraph.h"
#include "../DataStructures/SearchEngine.h" #include "../DataStructures/SearchEngine.h"
#include "../Descriptors/BaseDescriptor.h"
#include "../Descriptors/GPXDescriptor.h"
#include "../Descriptors/JSONDescriptor.h"
#include "../Server/DataStructures/QueryObjectsStorage.h"
#include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include "../Server/DataStructures/QueryObjectsStorage.h" #include <cstdlib>
#include <string>
#include <vector>
class ViaRoutePlugin : public BasePlugin { class ViaRoutePlugin : public BasePlugin {
private: private:
@@ -51,27 +46,30 @@ private:
std::vector<std::string> & names; std::vector<std::string> & names;
StaticGraph<QueryEdge::EdgeData> * graph; StaticGraph<QueryEdge::EdgeData> * graph;
HashTable<std::string, unsigned> descriptorTable; HashTable<std::string, unsigned> descriptorTable;
std::string pluginDescriptorString;
SearchEngine * searchEnginePtr; SearchEngine * searchEnginePtr;
public: public:
ViaRoutePlugin(QueryObjectsStorage * objects, std::string psd = "viaroute") : names(objects->names), pluginDescriptorString(psd) { ViaRoutePlugin(QueryObjectsStorage * objects)
:
names(objects->names),
descriptor_string("viaroute")
{
nodeHelpDesk = objects->nodeHelpDesk; nodeHelpDesk = objects->nodeHelpDesk;
graph = objects->graph; graph = objects->graph;
searchEnginePtr = new SearchEngine(graph, nodeHelpDesk, names); searchEnginePtr = new SearchEngine(graph, nodeHelpDesk, names);
descriptorTable.Set("", 0); //default descriptor descriptorTable.insert(std::make_pair("" , 0));
descriptorTable.Set("json", 0); descriptorTable.insert(std::make_pair("json", 0));
descriptorTable.Set("gpx", 1); descriptorTable.insert(std::make_pair("gpx" , 1));
} }
virtual ~ViaRoutePlugin() { virtual ~ViaRoutePlugin() {
delete searchEnginePtr; delete searchEnginePtr;
} }
std::string GetDescriptor() const { return pluginDescriptorString; } const std::string & GetDescriptor() const { return descriptor_string; }
std::string GetVersionString() const { return std::string("0.3 (DL)"); }
void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) { void HandleRequest(const RouteParameters & routeParameters, http::Reply& reply) {
//check number of parameters //check number of parameters
if( 2 > routeParameters.coordinates.size() ) { if( 2 > routeParameters.coordinates.size() ) {
@@ -93,14 +91,14 @@ public:
std::vector<PhantomNode> phantomNodeVector(rawRoute.rawViaNodeCoordinates.size()); std::vector<PhantomNode> phantomNodeVector(rawRoute.rawViaNodeCoordinates.size());
for(unsigned i = 0; i < rawRoute.rawViaNodeCoordinates.size(); ++i) { for(unsigned i = 0; i < rawRoute.rawViaNodeCoordinates.size(); ++i) {
if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) { if(checksumOK && i < routeParameters.hints.size() && "" != routeParameters.hints[i]) {
// INFO("Decoding hint: " << routeParameters.hints[i] << " for location index " << i); // SimpleLogger().Write() <<"Decoding hint: " << routeParameters.hints[i] << " for location index " << i;
DecodeObjectFromBase64(phantomNodeVector[i], routeParameters.hints[i]); DecodeObjectFromBase64(routeParameters.hints[i], phantomNodeVector[i]);
if(phantomNodeVector[i].isValid(nodeHelpDesk->getNumberOfNodes())) { if(phantomNodeVector[i].isValid(nodeHelpDesk->getNumberOfNodes())) {
// INFO("Decoded hint " << i << " successfully"); // SimpleLogger().Write() << "Decoded hint " << i << " successfully";
continue; continue;
} }
} }
// INFO("Brute force lookup of coordinate " << i); // SimpleLogger().Write() << "Brute force lookup of coordinate " << i;
searchEnginePtr->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i], routeParameters.zoomLevel); searchEnginePtr->FindPhantomNodeForCoordinate( rawRoute.rawViaNodeCoordinates[i], phantomNodeVector[i], routeParameters.zoomLevel);
} }
@@ -111,7 +109,7 @@ public:
rawRoute.segmentEndCoordinates.push_back(segmentPhantomNodes); rawRoute.segmentEndCoordinates.push_back(segmentPhantomNodes);
} }
if( ( routeParameters.alternateRoute ) && (1 == rawRoute.segmentEndCoordinates.size()) ) { if( ( routeParameters.alternateRoute ) && (1 == rawRoute.segmentEndCoordinates.size()) ) {
// INFO("Checking for alternative paths"); // SimpleLogger().Write() << "Checking for alternative paths";
searchEnginePtr->alternativePaths(rawRoute.segmentEndCoordinates[0], rawRoute); searchEnginePtr->alternativePaths(rawRoute.segmentEndCoordinates[0], rawRoute);
} else { } else {
@@ -120,7 +118,7 @@ public:
if(INT_MAX == rawRoute.lengthOfShortestPath ) { if(INT_MAX == rawRoute.lengthOfShortestPath ) {
DEBUG( "Error occurred, single path not found" ); SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found";
} }
reply.status = http::Reply::ok; reply.status = http::Reply::ok;
@@ -155,10 +153,10 @@ public:
PhantomNodes phantomNodes; PhantomNodes phantomNodes;
phantomNodes.startPhantom = rawRoute.segmentEndCoordinates[0].startPhantom; phantomNodes.startPhantom = rawRoute.segmentEndCoordinates[0].startPhantom;
// INFO("Start location: " << phantomNodes.startPhantom.location) // SimpleLogger().Write() << "Start location: " << phantomNodes.startPhantom.location;
phantomNodes.targetPhantom = rawRoute.segmentEndCoordinates[rawRoute.segmentEndCoordinates.size()-1].targetPhantom; phantomNodes.targetPhantom = rawRoute.segmentEndCoordinates[rawRoute.segmentEndCoordinates.size()-1].targetPhantom;
// INFO("TargetLocation: " << phantomNodes.targetPhantom.location); // SimpleLogger().Write() << "TargetLocation: " << phantomNodes.targetPhantom.location;
// INFO("Number of segments: " << rawRoute.segmentEndCoordinates.size()); // SimpleLogger().Write() << "Number of segments: " << rawRoute.segmentEndCoordinates.size();
desc->SetConfig(descriptorConfig); desc->SetConfig(descriptorConfig);
desc->Run(reply, rawRoute, phantomNodes, *searchEnginePtr); desc->Run(reply, rawRoute, phantomNodes, *searchEnginePtr);
@@ -204,7 +202,6 @@ public:
reply.headers[2].name = "Content-Disposition"; reply.headers[2].name = "Content-Disposition";
reply.headers[2].value = "attachment; filename=\"route.json\""; reply.headers[2].value = "attachment; filename=\"route.json\"";
} }
break; break;
} }
@@ -212,12 +209,7 @@ public:
return; return;
} }
private: private:
inline bool checkCoord(const _Coordinate & c) { std::string descriptor_string;
if(c.lat > 90*100000 || c.lat < -90*100000 || c.lon > 180*100000 || c.lon <-180*100000) {
return false;
}
return true;
}
}; };
+1 -21
View File
@@ -4,24 +4,4 @@ https://github.com/DennisOSRM/Project-OSRM/wiki
or use our free and daily updated online service at or use our free and daily updated online service at
http://map.project-osrm.org http://map.project-osrm.org
When using the code in a scientific publication, please cite
@inproceedings{luxen-vetter-2011,
author = {Luxen, Dennis and Vetter, Christian},
title = {Real-time routing with OpenStreetMap data},
booktitle = {Proceedings of the 19th ACM SIGSPATIAL International Conference on Advances in Geographic Information Systems},
series = {GIS '11},
year = {2011},
isbn = {978-1-4503-1031-4},
location = {Chicago, Illinois},
pages = {513--516},
numpages = {4},
url = {http://doi.acm.org/10.1145/2093973.2094062},
doi = {10.1145/2093973.2094062},
acmid = {2094062},
publisher = {ACM},
address = {New York, NY, USA},
}
+40
View File
@@ -0,0 +1,40 @@
# Readme
For instructions on how to compile and run OSRM, please consult the Wiki at
https://github.com/DennisOSRM/Project-OSRM/wiki
or use our free and daily updated online service at
http://map.project-osrm.org
## References in publications
When using the code in a (scientific) publication, please cite
```
@inproceedings{luxen-vetter-2011,
author = {Luxen, Dennis and Vetter, Christian},
title = {Real-time routing with OpenStreetMap data},
booktitle = {Proceedings of the 19th ACM SIGSPATIAL International Conference on Advances in Geographic Information Systems},
series = {GIS '11},
year = {2011},
isbn = {978-1-4503-1031-4},
location = {Chicago, Illinois},
pages = {513--516},
numpages = {4},
url = {http://doi.acm.org/10.1145/2093973.2094062},
doi = {10.1145/2093973.2094062},
acmid = {2094062},
publisher = {ACM},
address = {New York, NY, USA},
}
```
## Current build status
| build config | branch | status |
|:-------------|:--------|:------------|
| Project OSRM | master | [![Build Status](https://travis-ci.org/DennisOSRM/Project-OSRM.png?branch=master)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| Project OSRM | develop | [![Build Status](https://travis-ci.org/DennisOSRM/Project-OSRM.png?branch=develop)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| LUAbind fork | master | [![Build Status](https://travis-ci.org/DennisOSRM/luabind.png?branch=master)](https://travis-ci.org/DennisOSRM/luabind) |
+6 -2
View File
@@ -82,8 +82,12 @@ task :default => [:build]
desc "Build using CMake." desc "Build using CMake."
task :build do task :build do
Dir.chdir BUILD_FOLDER do if Dir.exists? BUILD_FOLDER
system "make" Dir.chdir BUILD_FOLDER do
system "make"
end
else
system "mkdir build; cd build; cmake ..; make"
end end
end end
+4 -5
View File
@@ -21,11 +21,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef ALTERNATIVEROUTES_H_ #ifndef ALTERNATIVEROUTES_H_
#define ALTERNATIVEROUTES_H_ #define ALTERNATIVEROUTES_H_
#include <boost/unordered_map.hpp>
#include <vector>
#include <cmath>
#include "BasicRoutingInterface.h" #include "BasicRoutingInterface.h"
#include <boost/unordered_map.hpp>
#include <cmath>
#include <vector>
const double VIAPATH_ALPHA = 0.15; const double VIAPATH_ALPHA = 0.15;
const double VIAPATH_EPSILON = 0.10; //alternative at most 15% longer const double VIAPATH_EPSILON = 0.10; //alternative at most 15% longer
@@ -308,7 +307,7 @@ private:
int aindex = 0; int aindex = 0;
//compute forward sharing //compute forward sharing
while( (packedAlternativePath[aindex] == packedShortestPath[aindex]) && (packedAlternativePath[aindex+1] == packedShortestPath[aindex+1]) ) { while( (packedAlternativePath[aindex] == packedShortestPath[aindex]) && (packedAlternativePath[aindex+1] == packedShortestPath[aindex+1]) ) {
// INFO("retrieving edge (" << packedAlternativePath[aindex] << "," << packedAlternativePath[aindex+1] << ")"); // SimpleLogger().Write() << "retrieving edge (" << packedAlternativePath[aindex] << "," << packedAlternativePath[aindex+1] << ")";
typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex+1]); typename SearchGraph::EdgeIterator edgeID = search_graph->FindEdgeInEitherDirection(packedAlternativePath[aindex], packedAlternativePath[aindex+1]);
sharing += search_graph->GetEdgeData(edgeID).distance; sharing += search_graph->GetEdgeData(edgeID).distance;
++aindex; ++aindex;
+3 -2
View File
@@ -23,8 +23,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASICROUTINGINTERFACE_H_ #ifndef BASICROUTINGINTERFACE_H_
#define BASICROUTINGINTERFACE_H_ #define BASICROUTINGINTERFACE_H_
#include "../Plugins/RawRouteData.h" #include "../DataStructures/RawRouteData.h"
#include "../Util/ContainerUtils.h" #include "../Util/ContainerUtils.h"
#include "../Util/SimpleLogger.h"
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
@@ -44,7 +45,7 @@ public:
inline void RoutingStep(typename QueryDataT::QueryHeap & _forwardHeap, typename QueryDataT::QueryHeap & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset, const bool forwardDirection) const { inline void RoutingStep(typename QueryDataT::QueryHeap & _forwardHeap, typename QueryDataT::QueryHeap & _backwardHeap, NodeID *middle, int *_upperbound, const int edgeBasedOffset, const bool forwardDirection) const {
const NodeID node = _forwardHeap.DeleteMin(); const NodeID node = _forwardHeap.DeleteMin();
const int distance = _forwardHeap.GetKey(node); const int distance = _forwardHeap.GetKey(node);
//INFO("Settled (" << _forwardHeap.GetData( node ).parent << "," << node << ")=" << distance); //SimpleLogger().Write() << "Settled (" << _forwardHeap.GetData( node ).parent << "," << node << ")=" << distance;
if(_backwardHeap.WasInserted(node) ){ if(_backwardHeap.WasInserted(node) ){
const int newDistance = _backwardHeap.GetKey(node) + distance; const int newDistance = _backwardHeap.GetKey(node) + distance;
if(newDistance < *_upperbound ){ if(newDistance < *_upperbound ){
+6 -6
View File
@@ -73,23 +73,23 @@ public:
//insert new starting nodes into forward heap, adjusted by previous distances. //insert new starting nodes into forward heap, adjusted by previous distances.
if(searchFrom1stStartNode) { if(searchFrom1stStartNode) {
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode, -phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode); forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode, -phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode);
INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1); // INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1);
forward_heap2.Insert(phantomNodePair.startPhantom.edgeBasedNode, -phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode); forward_heap2.Insert(phantomNodePair.startPhantom.edgeBasedNode, -phantomNodePair.startPhantom.weight1, phantomNodePair.startPhantom.edgeBasedNode);
INFO("fw2: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1); // INFO("fw2: " << phantomNodePair.startPhantom.edgeBasedNode << "´, w: " << -phantomNodePair.startPhantom.weight1);
} }
if(phantomNodePair.startPhantom.isBidirected() && searchFrom2ndStartNode) { if(phantomNodePair.startPhantom.isBidirected() && searchFrom2ndStartNode) {
forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode+1, -phantomNodePair.startPhantom.weight2, phantomNodePair.startPhantom.edgeBasedNode+1); forward_heap1.Insert(phantomNodePair.startPhantom.edgeBasedNode+1, -phantomNodePair.startPhantom.weight2, phantomNodePair.startPhantom.edgeBasedNode+1);
INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2); // INFO("fw1: " << phantomNodePair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2);
forward_heap2.Insert(phantomNodePair.startPhantom.edgeBasedNode+1, -phantomNodePair.startPhantom.weight2, phantomNodePair.startPhantom.edgeBasedNode+1); forward_heap2.Insert(phantomNodePair.startPhantom.edgeBasedNode+1, -phantomNodePair.startPhantom.weight2, phantomNodePair.startPhantom.edgeBasedNode+1);
INFO("fw2: " << phantomNodePair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2); // INFO("fw2: " << phantomNodePair.startPhantom.edgeBasedNode+1 << "´, w: " << -phantomNodePair.startPhantom.weight2);
} }
//insert new backward nodes into backward heap, unadjusted. //insert new backward nodes into backward heap, unadjusted.
reverse_heap1.Insert(phantomNodePair.targetPhantom.edgeBasedNode, phantomNodePair.targetPhantom.weight1, phantomNodePair.targetPhantom.edgeBasedNode); reverse_heap1.Insert(phantomNodePair.targetPhantom.edgeBasedNode, phantomNodePair.targetPhantom.weight1, phantomNodePair.targetPhantom.edgeBasedNode);
INFO("rv1: " << phantomNodePair.targetPhantom.edgeBasedNode << ", w;" << phantomNodePair.targetPhantom.weight1 ); // INFO("rv1: " << phantomNodePair.targetPhantom.edgeBasedNode << ", w;" << phantomNodePair.targetPhantom.weight1 );
if(phantomNodePair.targetPhantom.isBidirected() ) { if(phantomNodePair.targetPhantom.isBidirected() ) {
reverse_heap2.Insert(phantomNodePair.targetPhantom.edgeBasedNode+1, phantomNodePair.targetPhantom.weight2, phantomNodePair.targetPhantom.edgeBasedNode+1); reverse_heap2.Insert(phantomNodePair.targetPhantom.edgeBasedNode+1, phantomNodePair.targetPhantom.weight2, phantomNodePair.targetPhantom.edgeBasedNode+1);
INFO("rv2: " << phantomNodePair.targetPhantom.edgeBasedNode+1 << ", w;" << phantomNodePair.targetPhantom.weight2 ); // INFO("rv2: " << phantomNodePair.targetPhantom.edgeBasedNode+1 << ", w;" << phantomNodePair.targetPhantom.weight2 );
} }
const int forward_offset = phantomNodePair.startPhantom.weight1 + (phantomNodePair.startPhantom.isBidirected() ? phantomNodePair.startPhantom.weight2 : 0); const int forward_offset = phantomNodePair.startPhantom.weight1 + (phantomNodePair.startPhantom.isBidirected() ? phantomNodePair.startPhantom.weight2 : 0);
const int reverse_offset = phantomNodePair.targetPhantom.weight1 + (phantomNodePair.targetPhantom.isBidirected() ? phantomNodePair.targetPhantom.weight2 : 0); const int reverse_offset = phantomNodePair.targetPhantom.weight1 + (phantomNodePair.targetPhantom.isBidirected() ? phantomNodePair.targetPhantom.weight2 : 0);
+9 -5
View File
@@ -20,12 +20,16 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef BASIC_DATASTRUCTURES_H #ifndef BASIC_DATASTRUCTURES_H
#define BASIC_DATASTRUCTURES_H #define BASIC_DATASTRUCTURES_H
#include <string>
#include <sstream>
#include <boost/foreach.hpp>
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include <boost/asio.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <sstream>
#include <vector>
namespace http { namespace http {
const std::string okString = "HTTP/1.0 200 OK\r\n"; const std::string okString = "HTTP/1.0 200 OK\r\n";
@@ -77,7 +81,7 @@ struct Reply {
BOOST_FOREACH ( Header& h, headers) { BOOST_FOREACH ( Header& h, headers) {
if("Content-Length" == h.name) { if("Content-Length" == h.name) {
std::string sizeString; std::string sizeString;
intToString(size,h.value ); intToString(size,h.value);
} }
} }
} }
@@ -139,7 +143,7 @@ Reply Reply::stockReply(Reply::status_type status) {
Reply rep; Reply rep;
rep.status = status; rep.status = status;
rep.content = ToString(status); rep.content = ToString(status);
rep.headers.resize(3); rep.headers.resize(3);
rep.headers[0].name = "Access-Control-Allow-Origin"; rep.headers[0].name = "Access-Control-Allow-Origin";
rep.headers[0].value = "*"; rep.headers[0].value = "*";
rep.headers[1].name = "Content-Length"; rep.headers[1].name = "Content-Length";
+5 -5
View File
@@ -21,7 +21,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef CONNECTION_H #ifndef CONNECTION_H
#define CONNECTION_H #define CONNECTION_H
#include <vector> #include "BasicDatastructures.h"
#include "RequestHandler.h"
#include "RequestParser.h"
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/array.hpp> #include <boost/array.hpp>
@@ -30,11 +32,9 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp> #include <boost/enable_shared_from_this.hpp>
#include "BasicDatastructures.h" #include <zlib.h>
#include "RequestHandler.h"
#include "RequestParser.h"
#include "zlib.h" #include <vector>
namespace http { namespace http {
+68 -38
View File
@@ -20,77 +20,107 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "QueryObjectsStorage.h" #include "QueryObjectsStorage.h"
#include "../../Util/GraphLoader.h"
QueryObjectsStorage::QueryObjectsStorage( QueryObjectsStorage::QueryObjectsStorage(
std::string hsgrPath, const std::string & hsgrPath,
std::string ramIndexPath, const std::string & ramIndexPath,
std::string fileIndexPath, const std::string & fileIndexPath,
std::string nodesPath, const std::string & nodesPath,
std::string edgesPath, const std::string & edgesPath,
std::string namesPath, const std::string & namesPath,
std::string timestampPath const std::string & timestampPath
) { ) {
INFO("loading graph data"); if( hsgrPath.empty() ) {
std::ifstream hsgrInStream(hsgrPath.c_str(), std::ios::binary); throw OSRMException("no hsgr file given in ini file");
if(!hsgrInStream) { ERR(hsgrPath << " not found"); } }
if( ramIndexPath.empty() ) {
throw OSRMException("no ram index file given in ini file");
}
if( fileIndexPath.empty() ) {
throw OSRMException("no mem index file given in ini file");
}
if( nodesPath.empty() ) {
throw OSRMException("no nodes file given in ini file");
}
if( edgesPath.empty() ) {
throw OSRMException("no edges file given in ini file");
}
if( namesPath.empty() ) {
throw OSRMException("no names file given in ini file");
}
SimpleLogger().Write() << "loading graph data";
//Deserialize road network graph //Deserialize road network graph
std::vector< QueryGraph::_StrNode> nodeList; std::vector< QueryGraph::_StrNode> nodeList;
std::vector< QueryGraph::_StrEdge> edgeList; std::vector< QueryGraph::_StrEdge> edgeList;
const int n = readHSGRFromStream( const int n = readHSGRFromStream(
hsgrInStream, hsgrPath,
nodeList, nodeList,
edgeList, edgeList,
&checkSum &checkSum
); );
INFO("Data checksum is " << checkSum); SimpleLogger().Write() << "Data checksum is " << checkSum;
graph = new QueryGraph(nodeList, edgeList); graph = new QueryGraph(nodeList, edgeList);
assert(0 == nodeList.size()); assert(0 == nodeList.size());
assert(0 == edgeList.size()); assert(0 == edgeList.size());
if(timestampPath.length()) { if(timestampPath.length()) {
INFO("Loading Timestamp"); SimpleLogger().Write() << "Loading Timestamp";
std::ifstream timestampInStream(timestampPath.c_str()); std::ifstream timestampInStream(timestampPath.c_str());
if(!timestampInStream) { WARN(timestampPath << " not found"); } if(!timestampInStream) {
SimpleLogger().Write(logWARNING) << timestampPath << " not found";
}
getline(timestampInStream, timestamp); getline(timestampInStream, timestamp);
timestampInStream.close(); timestampInStream.close();
} }
if(!timestamp.length()) if(!timestamp.length()) {
timestamp = "n/a"; timestamp = "n/a";
if(25 < timestamp.length()) }
if(25 < timestamp.length()) {
timestamp.resize(25); timestamp.resize(25);
}
INFO("Loading auxiliary information"); SimpleLogger().Write() << "Loading auxiliary information";
//Init nearest neighbor data structure //Init nearest neighbor data structure
std::ifstream nodesInStream(nodesPath.c_str(), std::ios::binary); nodeHelpDesk = new NodeInformationHelpDesk(
if(!nodesInStream) { ERR(nodesPath << " not found"); } ramIndexPath,
std::ifstream edgesInStream(edgesPath.c_str(), std::ios::binary); fileIndexPath,
if(!edgesInStream) { ERR(edgesPath << " not found"); } nodesPath,
nodeHelpDesk = new NodeInformationHelpDesk(ramIndexPath.c_str(), fileIndexPath.c_str(), n, checkSum); edgesPath,
nodeHelpDesk->initNNGrid(nodesInStream, edgesInStream); n,
checkSum
);
//deserialize street name list //deserialize street name list
INFO("Loading names index"); SimpleLogger().Write() << "Loading names index";
std::ifstream namesInStream(namesPath.c_str(), std::ios::binary); boost::filesystem::path names_file(namesPath);
if(!namesInStream) { ERR(namesPath << " not found"); }
unsigned size(0); if ( !boost::filesystem::exists( names_file ) ) {
namesInStream.read((char *)&size, sizeof(unsigned)); throw OSRMException("names file does not exist");
// names = new std::vector<std::string>(); }
if ( 0 == boost::filesystem::file_size( names_file ) ) {
throw OSRMException("names file is empty");
}
boost::filesystem::ifstream name_stream(names_file, std::ios::binary);
unsigned size = 0;
name_stream.read((char *)&size, sizeof(unsigned));
BOOST_ASSERT_MSG(0 != size, "name file empty");
char buf[1024]; char buf[1024];
for(unsigned i = 0; i < size; ++i) { for( unsigned i = 0; i < size; ++i ) {
unsigned sizeOfString = 0; unsigned size_of_string = 0;
namesInStream.read((char *)&sizeOfString, sizeof(unsigned)); name_stream.read((char *)&size_of_string, sizeof(unsigned));
buf[sizeOfString] = '\0'; // instead of memset buf[size_of_string] = '\0'; // instead of memset
namesInStream.read(buf, sizeOfString); name_stream.read(buf, size_of_string);
names.push_back(buf); names.push_back(buf);
} }
std::vector<std::string>(names).swap(names); std::vector<std::string>(names).swap(names);
hsgrInStream.close(); BOOST_ASSERT_MSG(0 != names.size(), "could not load any names");
namesInStream.close(); name_stream.close();
INFO("All query data structures loaded"); SimpleLogger().Write() << "All query data structures loaded";
} }
QueryObjectsStorage::~QueryObjectsStorage() { QueryObjectsStorage::~QueryObjectsStorage() {
+22 -6
View File
@@ -22,16 +22,24 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef QUERYOBJECTSSTORAGE_H_ #ifndef QUERYOBJECTSSTORAGE_H_
#define QUERYOBJECTSSTORAGE_H_ #define QUERYOBJECTSSTORAGE_H_
#include<vector> #include "../../Util/GraphLoader.h"
#include<string> #include "../../Util/OSRMException.h"
#include "../../Util/SimpleLogger.h"
#include "../../DataStructures/NodeInformationHelpDesk.h" #include "../../DataStructures/NodeInformationHelpDesk.h"
#include "../../DataStructures/QueryEdge.h" #include "../../DataStructures/QueryEdge.h"
#include "../../DataStructures/StaticGraph.h" #include "../../DataStructures/StaticGraph.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <vector>
#include <string>
struct QueryObjectsStorage { struct QueryObjectsStorage {
typedef StaticGraph<QueryEdge::EdgeData> QueryGraph; typedef StaticGraph<QueryEdge::EdgeData> QueryGraph;
typedef QueryGraph::InputEdge InputEdge; typedef QueryGraph::InputEdge InputEdge;
NodeInformationHelpDesk * nodeHelpDesk; NodeInformationHelpDesk * nodeHelpDesk;
std::vector<std::string> names; std::vector<std::string> names;
@@ -39,7 +47,15 @@ struct QueryObjectsStorage {
std::string timestamp; std::string timestamp;
unsigned checkSum; unsigned checkSum;
QueryObjectsStorage(std::string hsgrPath, std::string ramIndexPath, std::string fileIndexPath, std::string nodesPath, std::string edgesPath, std::string namesPath, std::string timestampPath); QueryObjectsStorage(
const std::string & hsgrPath,
const std::string & ramIndexPath,
const std::string & fileIndexPath,
const std::string & nodesPath,
const std::string & edgesPath,
const std::string & namesPath,
const std::string & timestampPath
);
~QueryObjectsStorage(); ~QueryObjectsStorage();
}; };
@@ -21,15 +21,25 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef ROUTE_PARAMETERS_H #ifndef ROUTE_PARAMETERS_H
#define ROUTE_PARAMETERS_H #define ROUTE_PARAMETERS_H
#include "../../DataStructures/Coordinate.h"
#include "../../DataStructures/HashTable.h"
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/fusion/sequence/intrinsic.hpp>
#include "../DataStructures/Coordinate.h"
struct RouteParameters { struct RouteParameters {
RouteParameters() : zoomLevel(18), printInstructions(false), alternateRoute(true), geometry(true), compression(true), deprecatedAPI(false), checkSum(-1) {} RouteParameters() :
zoomLevel(18),
printInstructions(false),
alternateRoute(true),
geometry(true),
compression(true),
deprecatedAPI(false),
checkSum(-1) {}
short zoomLevel; short zoomLevel;
bool printInstructions; bool printInstructions;
bool alternateRoute; bool alternateRoute;
@@ -42,12 +52,13 @@ struct RouteParameters {
std::string jsonpParameter; std::string jsonpParameter;
std::string language; std::string language;
std::vector<std::string> hints; std::vector<std::string> hints;
std::vector<_Coordinate> coordinates; std::vector<FixedPointCoordinate> coordinates;
typedef HashTable<std::string, std::string>::MyIterator OptionsIterator; typedef HashTable<std::string, std::string>::const_iterator OptionsIterator;
void setZoomLevel(const short i) { void setZoomLevel(const short i) {
if (18 > i && 0 < i) if (18 > i && 0 < i) {
zoomLevel = i; zoomLevel = i;
}
} }
void setAlternateRouteFlag(const bool b) { void setAlternateRouteFlag(const bool b) {
@@ -95,13 +106,11 @@ struct RouteParameters {
compression = b; compression = b;
} }
void addCoordinate(boost::fusion::vector < double, double > arg_) { void addCoordinate(const boost::fusion::vector < double, double > & arg_) {
int lat = 100000.*boost::fusion::at_c < 0 > (arg_); int lat = COORDINATE_PRECISION*boost::fusion::at_c < 0 > (arg_);
int lon = 100000.*boost::fusion::at_c < 1 > (arg_); int lon = COORDINATE_PRECISION*boost::fusion::at_c < 1 > (arg_);
_Coordinate myCoordinate(lat, lon); coordinates.push_back(FixedPointCoordinate(lat, lon));
coordinates.push_back(_Coordinate(lat, lon));
} }
}; };
#endif /*ROUTE_PARAMETERS_H*/ #endif /*ROUTE_PARAMETERS_H*/
+46 -51
View File
@@ -21,58 +21,61 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef REQUEST_HANDLER_H #ifndef REQUEST_HANDLER_H
#define REQUEST_HANDLER_H #define REQUEST_HANDLER_H
#include <algorithm>
#include <cctype> // std::tolower
#include <string>
#include <iostream>
#include <boost/noncopyable.hpp>
#include "APIGrammar.h" #include "APIGrammar.h"
#include "BasicDatastructures.h" #include "BasicDatastructures.h"
#include "../DataStructures/HashTable.h" #include "DataStructures/RouteParameters.h"
#include "../Plugins/BasePlugin.h" #include "../Library/OSRM.h"
#include "../Plugins/RouteParameters.h" #include "../Util/SimpleLogger.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include "../typedefs.h" #include "../typedefs.h"
namespace http { #include <boost/foreach.hpp>
#include <boost/noncopyable.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
class RequestHandler : private boost::noncopyable { class RequestHandler : private boost::noncopyable {
public: public:
explicit RequestHandler() : _pluginCount(0) { } typedef APIGrammar<std::string::iterator, RouteParameters> APIGrammarParser;
explicit RequestHandler() { }
~RequestHandler() { void handle_request(const http::Request& req, http::Reply& rep){
for(unsigned i = 0; i < _pluginVector.size(); i++) {
BasePlugin * tempPointer = _pluginVector[i];
delete tempPointer;
}
}
void handle_request(const Request& req, Reply& rep){
//parse command //parse command
try { try {
std::string request(req.uri); std::string request(req.uri);
{ //This block logs the current request to std out. should be moved to a logging component time_t ltime;
time_t ltime; struct tm *Tm;
struct tm *Tm;
ltime=time(NULL); ltime=time(NULL);
Tm=localtime(&ltime); Tm=localtime(&ltime);
INFO((Tm->tm_mday < 10 ? "0" : "" ) << Tm->tm_mday << "-" << (Tm->tm_mon+1 < 10 ? "0" : "" ) << (Tm->tm_mon+1) << "-" << 1900+Tm->tm_year << " " << (Tm->tm_hour < 10 ? "0" : "" ) << Tm->tm_hour << ":" << (Tm->tm_min < 10 ? "0" : "" ) << Tm->tm_min << ":" << (Tm->tm_sec < 10 ? "0" : "" ) << Tm->tm_sec << " " << SimpleLogger().Write() <<
req.endpoint.to_string() << " " << req.referrer << ( 0 == req.referrer.length() ? "- " :" ") << req.agent << ( 0 == req.agent.length() ? "- " :" ") << req.uri ); (Tm->tm_mday < 10 ? "0" : "" ) << Tm->tm_mday << "-" <<
} (Tm->tm_mon+1 < 10 ? "0" : "" ) << (Tm->tm_mon+1) << "-" <<
1900+Tm->tm_year << " " << (Tm->tm_hour < 10 ? "0" : "" ) <<
Tm->tm_hour << ":" << (Tm->tm_min < 10 ? "0" : "" ) <<
Tm->tm_min << ":" << (Tm->tm_sec < 10 ? "0" : "" ) <<
Tm->tm_sec << " " << req.endpoint.to_string() << " " <<
req.referrer << ( 0 == req.referrer.length() ? "- " :" ") <<
req.agent << ( 0 == req.agent.length() ? "- " :" ") << req.uri;
RouteParameters routeParameters; RouteParameters routeParameters;
APIGrammar<std::string::iterator, RouteParameters> apiParser(&routeParameters); APIGrammarParser apiParser(&routeParameters);
std::string::iterator it = request.begin(); std::string::iterator it = request.begin();
bool result = boost::spirit::qi::parse(it, request.end(), apiParser); // returns true if successful const bool result = boost::spirit::qi::parse(
if (!result || (it != request.end()) ) { it,
request.end(),
apiParser
);
if ( !result || (it != request.end()) ) {
rep = http::Reply::stockReply(http::Reply::badRequest); rep = http::Reply::stockReply(http::Reply::badRequest);
int position = std::distance(request.begin(), it); const int position = std::distance(request.begin(), it);
std::string tmp_position_string; std::string tmp_position_string;
intToString(position, tmp_position_string); intToString(position, tmp_position_string);
rep.content += "Input seems to be malformed close to position "; rep.content += "Input seems to be malformed close to position ";
@@ -80,38 +83,30 @@ public:
rep.content += request; rep.content += request;
rep.content += tmp_position_string; rep.content += tmp_position_string;
rep.content += "<br>"; rep.content += "<br>";
for(unsigned i = 0, end = std::distance(request.begin(), it); i < end; ++i) const unsigned end = std::distance(request.begin(), it);
for(unsigned i = 0; i < end; ++i) {
rep.content += "&nbsp;"; rep.content += "&nbsp;";
}
rep.content += "^<br></pre>"; rep.content += "^<br></pre>";
} else { } else {
//Finished parsing, lets call the right plugin to handle the request //parsing done, lets call the right plugin to handle the request
if(pluginMap.Holds(routeParameters.service)) { routing_machine->RunQuery(routeParameters, rep);
rep.status = Reply::ok;
_pluginVector[pluginMap.Find(routeParameters.service)]->HandleRequest(routeParameters, rep );
} else {
rep = Reply::stockReply(Reply::badRequest);
}
return; return;
} }
} catch(std::exception& e) { } catch(std::exception& e) {
rep = Reply::stockReply(Reply::internalServerError); rep = http::Reply::stockReply(http::Reply::internalServerError);
std::cerr << "[server error] code: " << e.what() << ", uri: " << req.uri << std::endl; SimpleLogger().Write(logWARNING) <<
"[server error] code: " << e.what() << ", uri: " << req.uri;
return; return;
} }
}; };
void RegisterPlugin(BasePlugin * plugin) { void RegisterRoutingMachine(OSRM * osrm) {
std::cout << "[handler] registering plugin " << plugin->GetDescriptor() << std::endl; routing_machine = osrm;
pluginMap.Add(plugin->GetDescriptor(), _pluginCount);
_pluginVector.push_back(plugin);
++_pluginCount;
} }
private: private:
HashTable<std::string, unsigned> pluginMap; OSRM * routing_machine;
std::vector<BasePlugin *> _pluginVector;
unsigned _pluginCount;
}; };
} // namespace http
#endif // REQUEST_HANDLER_H #endif // REQUEST_HANDLER_H
+2 -1
View File
@@ -21,9 +21,10 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef REQUEST_PARSER_H #ifndef REQUEST_PARSER_H
#define REQUEST_PARSER_H #define REQUEST_PARSER_H
#include "BasicDatastructures.h"
#include <boost/logic/tribool.hpp> #include <boost/logic/tribool.hpp>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include "BasicDatastructures.h"
namespace http { namespace http {
+34 -14
View File
@@ -21,21 +21,29 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef SERVER_H #ifndef SERVER_H
#define SERVER_H #define SERVER_H
#include <vector> #include "Connection.h"
#include "RequestHandler.h"
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include "Connection.h" #include <vector>
#include "RequestHandler.h"
namespace http {
class Server: private boost::noncopyable { class Server: private boost::noncopyable {
public: public:
explicit Server(const std::string& address, const std::string& port, unsigned thread_pool_size) : threadPoolSize(thread_pool_size), acceptor(ioService), newConnection(new Connection(ioService, requestHandler)), requestHandler(){ explicit Server(
const std::string& address,
const std::string& port,
unsigned thread_pool_size
) :
threadPoolSize(thread_pool_size),
acceptor(ioService),
newConnection(new http::Connection(ioService, requestHandler)),
requestHandler()
{
boost::asio::ip::tcp::resolver resolver(ioService); boost::asio::ip::tcp::resolver resolver(ioService);
boost::asio::ip::tcp::resolver::query query(address, port); boost::asio::ip::tcp::resolver::query query(address, port);
boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query); boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
@@ -44,7 +52,14 @@ public:
acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
acceptor.bind(endpoint); acceptor.bind(endpoint);
acceptor.listen(); acceptor.listen();
acceptor.async_accept(newConnection->socket(), boost::bind(&Server::handleAccept, this, boost::asio::placeholders::error)); acceptor.async_accept(
newConnection->socket(),
boost::bind(
&Server::handleAccept,
this,
boost::asio::placeholders::error
)
);
} }
void Run() { void Run() {
@@ -66,23 +81,28 @@ public:
} }
private: private:
typedef boost::shared_ptr<Connection > ConnectionPtr;
void handleAccept(const boost::system::error_code& e) { void handleAccept(const boost::system::error_code& e) {
if (!e) { if (!e) {
newConnection->start(); newConnection->start();
newConnection.reset(new Connection(ioService, requestHandler)); newConnection.reset(
acceptor.async_accept(newConnection->socket(), boost::bind(&Server::handleAccept, this, boost::asio::placeholders::error)); new http::Connection(ioService, requestHandler)
);
acceptor.async_accept(
newConnection->socket(),
boost::bind(
&Server::handleAccept,
this,
boost::asio::placeholders::error
)
);
} }
} }
unsigned threadPoolSize; unsigned threadPoolSize;
boost::asio::io_service ioService; boost::asio::io_service ioService;
boost::asio::ip::tcp::acceptor acceptor; boost::asio::ip::tcp::acceptor acceptor;
ConnectionPtr newConnection; boost::shared_ptr<http::Connection> newConnection;
RequestHandler requestHandler; RequestHandler requestHandler;
}; };
} // namespace http
#endif // SERVER_H #endif // SERVER_H
+25 -41
View File
@@ -16,67 +16,51 @@ You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
Created on: 26.11.2010
Author: dennis
*/ */
#ifndef SERVERFACTORY_H_ #ifndef SERVERFACTORY_H_
#define SERVERFACTORY_H_ #define SERVERFACTORY_H_
#include <zlib.h>
#include "Server.h" #include "Server.h"
#include "ServerConfiguration.h" #include "../Util/IniFile.h"
#include "../Util/SimpleLogger.h"
#include "../Util/InputFileUtil.h"
#include "../Util/OpenMPWrapper.h"
#include "../Util/StringUtil.h" #include "../Util/StringUtil.h"
#include "../typedefs.h" #include <zlib.h>
typedef http::Server Server; #include <boost/noncopyable.hpp>
struct ServerFactory {
static Server * CreateServer(ServerConfiguration& serverConfig) {
if(!testDataFile(serverConfig.GetParameter("nodesData"))) {
ERR("nodes file not found");
}
if(!testDataFile(serverConfig.GetParameter("hsgrData"))) {
ERR("hsgr file not found");
}
if(!testDataFile(serverConfig.GetParameter("namesData"))) {
ERR("names file not found");
}
if(!testDataFile(serverConfig.GetParameter("ramIndex"))) {
ERR("ram index file not found");
}
if(!testDataFile(serverConfig.GetParameter("fileIndex"))) {
ERR("file index file not found");
}
struct ServerFactory : boost::noncopyable {
static Server * CreateServer( IniFile & serverConfig ) {
int threads = omp_get_num_procs(); int threads = omp_get_num_procs();
if(serverConfig.GetParameter("IP") == "") if( serverConfig.GetParameter("IP").empty() ) {
serverConfig.SetParameter("IP", "0.0.0.0"); serverConfig.SetParameter("IP", "0.0.0.0");
if(serverConfig.GetParameter("Port") == "") }
if( serverConfig.GetParameter("Port").empty() ) {
serverConfig.SetParameter("Port", "5000"); serverConfig.SetParameter("Port", "5000");
}
if(stringToInt(serverConfig.GetParameter("Threads")) != 0 && stringToInt(serverConfig.GetParameter("Threads")) <= threads) if(
stringToInt(serverConfig.GetParameter("Threads")) >= 1 &&
stringToInt(serverConfig.GetParameter("Threads")) <= threads
) {
threads = stringToInt( serverConfig.GetParameter("Threads") ); threads = stringToInt( serverConfig.GetParameter("Threads") );
}
std::cout << "[server] http 1.1 compression handled by zlib version " << zlibVersion() << std::endl; SimpleLogger().Write() <<
Server * server = new Server(serverConfig.GetParameter("IP"), serverConfig.GetParameter("Port"), threads); "http 1.1 compression handled by zlib version " << zlibVersion();
Server * server = new Server(
serverConfig.GetParameter("IP"),
serverConfig.GetParameter("Port"),
threads
);
return server; return server;
} }
static Server * CreateServer(const char * iniFile) { static Server * CreateServer(const char * iniFile) {
ServerConfiguration serverConfig(iniFile); IniFile serverConfig(iniFile);
return CreateServer(serverConfig); return CreateServer(serverConfig);
} }
}; };
+78 -58
View File
@@ -18,23 +18,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#define VERBOSE(x) x
#define VERBOSE2(x)
#ifdef NDEBUG
#undef VERBOSE
#undef VERBOSE2
#endif
#include <boost/foreach.hpp>
#include <fstream>
#include <istream>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include "../typedefs.h" #include "../typedefs.h"
#include "../Algorithms/StronglyConnectedComponents.h" #include "../Algorithms/StronglyConnectedComponents.h"
#include "../DataStructures/BinaryHeap.h" #include "../DataStructures/BinaryHeap.h"
@@ -42,61 +25,98 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include "../DataStructures/DynamicGraph.h" #include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/QueryEdge.h" #include "../DataStructures/QueryEdge.h"
#include "../DataStructures/TurnInstructions.h" #include "../DataStructures/TurnInstructions.h"
#include "../Util/BaseConfiguration.h"
#include "../Util/InputFileUtil.h"
#include "../Util/GraphLoader.h" #include "../Util/GraphLoader.h"
#include "../Util/IniFile.h"
#include "../Util/InputFileUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/SimpleLogger.h"
using namespace std; #include <boost/foreach.hpp>
#include <fstream>
#include <istream>
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
typedef QueryEdge::EdgeData EdgeData; typedef QueryEdge::EdgeData EdgeData;
typedef DynamicGraph<EdgeData>::InputEdge InputEdge; typedef DynamicGraph<EdgeData>::InputEdge InputEdge;
typedef BaseConfiguration ContractorConfiguration;
std::vector<NodeInfo> internalToExternalNodeMapping; std::vector<NodeInfo> internal_to_external_node_map;
std::vector<_Restriction> inputRestrictions; std::vector<TurnRestriction> restrictions_vector;
std::vector<NodeID> bollardNodes; std::vector<NodeID> bollard_node_IDs_vector;
std::vector<NodeID> trafficLightNodes; std::vector<NodeID> traffic_light_node_IDs_vector;
int main (int argc, char *argv[]) { int main (int argc, char * argv[]) {
LogPolicy::GetInstance().Unmute();
if(argc < 3) { if(argc < 3) {
ERR("usage: " << std::endl << argv[0] << " <osrm-data> <osrm-restrictions>"); SimpleLogger().Write(logWARNING) <<
} "usage:\n" << argv[0] << " <osrm> <osrm.restrictions>";
std::string SRTM_ROOT; return -1;
INFO("Using restrictions from file: " << argv[2]);
std::ifstream restrictionsInstream(argv[2], ios::binary);
if(!restrictionsInstream.good()) {
ERR("Could not access <osrm-restrictions> files");
}
_Restriction restriction;
unsigned usableRestrictionsCounter(0);
restrictionsInstream.read((char*)&usableRestrictionsCounter, sizeof(unsigned));
inputRestrictions.resize(usableRestrictionsCounter);
restrictionsInstream.read((char *)&(inputRestrictions[0]), usableRestrictionsCounter*sizeof(_Restriction));
restrictionsInstream.close();
std::ifstream in;
in.open (argv[1], std::ifstream::in | std::ifstream::binary);
if (!in.is_open()) {
ERR("Cannot open " << argv[1]);
} }
std::vector<ImportEdge> edgeList; SimpleLogger().Write() <<
NodeID nodeBasedNodeNumber = readBinaryOSRMGraphFromStream(in, edgeList, bollardNodes, trafficLightNodes, &internalToExternalNodeMapping, inputRestrictions); "Using restrictions from file: " << argv[2];
in.close(); std::ifstream restriction_ifstream(argv[2], std::ios::binary);
INFO(inputRestrictions.size() << " restrictions, " << bollardNodes.size() << " bollard nodes, " << trafficLightNodes.size() << " traffic lights"); if(!restriction_ifstream.good()) {
throw OSRMException("Could not access <osrm-restrictions> files");
}
uint32_t usable_restriction_count = 0;
restriction_ifstream.read(
(char*)&usable_restriction_count,
sizeof(uint32_t)
);
restrictions_vector.resize(usable_restriction_count);
restriction_ifstream.read(
(char *)&(restrictions_vector[0]),
usable_restriction_count*sizeof(TurnRestriction)
);
restriction_ifstream.close();
std::ifstream input_stream;
input_stream.open( argv[1], std::ifstream::in | std::ifstream::binary );
if (!input_stream.is_open()) {
throw OSRMException("Cannot open osrm file");
}
std::vector<ImportEdge> edge_list;
NodeID node_based_node_count = readBinaryOSRMGraphFromStream(
input_stream,
edge_list,
bollard_node_IDs_vector,
traffic_light_node_IDs_vector,
&internal_to_external_node_map,
restrictions_vector
);
input_stream.close();
SimpleLogger().Write() <<
restrictions_vector.size() << " restrictions, " <<
bollard_node_IDs_vector.size() << " bollard nodes, " <<
traffic_light_node_IDs_vector.size() << " traffic lights";
/*** /***
* Building an edge-expanded graph from node-based input an turn restrictions * Building an edge-expanded graph from node-based input an turn restrictions
*/ */
INFO("Starting SCC graph traversal"); SimpleLogger().Write() << "Starting SCC graph traversal";
TarjanSCC * tarjan = new TarjanSCC (nodeBasedNodeNumber, edgeList, bollardNodes, trafficLightNodes, inputRestrictions, internalToExternalNodeMapping); TarjanSCC * tarjan = new TarjanSCC (
std::vector<ImportEdge>().swap(edgeList); node_based_node_count,
edge_list,
bollard_node_IDs_vector,
traffic_light_node_IDs_vector,
restrictions_vector,
internal_to_external_node_map
);
std::vector<ImportEdge>().swap(edge_list);
tarjan->Run(); tarjan->Run();
std::vector<_Restriction>().swap(inputRestrictions);
std::vector<NodeID>().swap(bollardNodes); std::vector<TurnRestriction>().swap(restrictions_vector);
std::vector<NodeID>().swap(trafficLightNodes); std::vector<NodeID>().swap(bollard_node_IDs_vector);
INFO("finished component analysis"); std::vector<NodeID>().swap(traffic_light_node_IDs_vector);
SimpleLogger().Write() << "finished component analysis";
return 0; return 0;
} }
+93
View File
@@ -0,0 +1,93 @@
/*
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.
*/
#include "../Library/OSRM.h"
#include "../Util/SimpleLogger.h"
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
//Dude, real recursions on the OS stack? You must be brave...
void print_tree(boost::property_tree::ptree const& pt, const unsigned recursion_depth)
{
boost::property_tree::ptree::const_iterator end = pt.end();
for (boost::property_tree::ptree::const_iterator it = pt.begin(); it != end; ++it) {
for(unsigned i = 0; i < recursion_depth; ++i) {
std::cout << " " << std::flush;
}
std::cout << it->first << ": " << it->second.get_value<std::string>() << std::endl;
print_tree(it->second, recursion_depth+1);
}
}
int main (int argc, char * argv[]) {
LogPolicy::GetInstance().Unmute();
try {
std::cout << "\n starting up engines, compile at "
<< __DATE__ << ", " __TIME__ << std::endl;
IniFile serverConfig((argc > 1 ? argv[1] : "server.ini"));
OSRM routing_machine((argc > 1 ? argv[1] : "server.ini"));
RouteParameters route_parameters;
route_parameters.zoomLevel = 18; //no generalization
route_parameters.printInstructions = true; //turn by turn instructions
route_parameters.alternateRoute = true; //get an alternate route, too
route_parameters.geometry = true; //retrieve geometry of route
route_parameters.compression = true; //polyline encoding
route_parameters.checkSum = UINT_MAX; //see wiki
route_parameters.service = "viaroute"; //that's routing
route_parameters.outputFormat = "json";
route_parameters.jsonpParameter = ""; //set for jsonp wrapping
route_parameters.language = ""; //unused atm
//route_parameters.hints.push_back(); // see wiki, saves I/O if done properly
FixedPointCoordinate start_coordinate(52.519930*COORDINATE_PRECISION,13.438640*COORDINATE_PRECISION);
FixedPointCoordinate target_coordinate(52.513191*COORDINATE_PRECISION,13.415852*COORDINATE_PRECISION);
route_parameters.coordinates.push_back(start_coordinate);
route_parameters.coordinates.push_back(target_coordinate);
http::Reply osrm_reply;
routing_machine.RunQuery(route_parameters, osrm_reply);
std::cout << osrm_reply.content << std::endl;
//attention: super-inefficient hack below:
std::stringstream ss;
ss << osrm_reply.content;
boost::property_tree::ptree pt;
boost::property_tree::read_json(ss, pt);
print_tree(pt, 0);
} catch (std::exception & e) {
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
return -1;
}
return 0;
}
-107
View File
@@ -1,107 +0,0 @@
/*
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 BASECONFIGURATION_H_
#define BASECONFIGURATION_H_
#include <iostream>
#include <string>
#include <exception>
#include <fstream>
#include "../DataStructures/HashTable.h"
class BaseConfiguration {
public:
BaseConfiguration(const char * configFile) {
std::ifstream config( configFile );
if(!config) {
std::cerr << "[config] .ini not found" << std::endl;
return;
}
std::string line;
try {
if (config.is_open()) {
while ( config.good() ) {
getline (config,line);
std::vector<std::string> tokens;
Tokenize(line, tokens);
if(2 == tokens.size() )
parameters.Add(tokens[0], tokens[1]);
}
config.close();
}
} catch(std::exception& e) {
ERR("[config] " << configFile << " not found -> Exception: " <<e.what());
if(config.is_open())
config.close();
}
}
std::string GetParameter(const char * key){
return GetParameter(std::string(key));
}
std::string GetParameter(std::string key) {
return parameters.Find(key);
}
void SetParameter(const char* key, const char* value) {
SetParameter(std::string(key), std::string(value));
}
void SetParameter(std::string key, std::string value) {
parameters.Set(key, value);
}
private:
void Tokenize(const std::string& str, std::vector<std::string>& tokens, const std::string& delimiters = "=") {
std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
std::string::size_type pos = str.find_first_of(delimiters, lastPos);
while (std::string::npos != pos || std::string::npos != lastPos) {
std::string temp = str.substr(lastPos, pos - lastPos);
TrimStringRight(temp);
TrimStringLeft(temp);
tokens.push_back( temp );
lastPos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, lastPos);
}
}
void TrimStringRight(std::string& str) {
std::string::size_type pos = str.find_last_not_of(" ");
if (pos != std::string::npos)
str.erase(pos+1);
else
str.erase( str.begin() , str.end() );
}
void TrimStringLeft(std::string& str) {
std::string::size_type pos = str.find_first_not_of(" ");
if (pos != std::string::npos)
str.erase(0, pos);
else
str.erase( str.begin() , str.end() );
}
HashTable<std::string, std::string> parameters;
};
#endif /* BASECONFIGURATION_H_ */
+119 -43
View File
@@ -21,13 +21,18 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef GRAPHLOADER_H #ifndef GRAPHLOADER_H
#define GRAPHLOADER_H #define GRAPHLOADER_H
#include "OSRMException.h"
#include "../DataStructures/ImportNode.h" #include "../DataStructures/ImportNode.h"
#include "../DataStructures/ImportEdge.h" #include "../DataStructures/ImportEdge.h"
#include "../DataStructures/NodeCoords.h" #include "../DataStructures/QueryNode.h"
#include "../DataStructures/Restriction.h" #include "../DataStructures/Restriction.h"
#include "../Util/SimpleLogger.h"
#include "../Util/UUID.h"
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <cassert> #include <cassert>
@@ -49,22 +54,41 @@ struct _ExcessRemover {
}; };
template<typename EdgeT> template<typename EdgeT>
NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, std::vector<NodeID> &bollardNodes, std::vector<NodeID> &trafficLightNodes, std::vector<NodeInfo> * int2ExtNodeMap, std::vector<_Restriction> & inputRestrictions) { NodeID readBinaryOSRMGraphFromStream(
std::istream &in,
std::vector<EdgeT>& edgeList,
std::vector<NodeID> &bollardNodes,
std::vector<NodeID> &trafficLightNodes,
std::vector<NodeInfo> * int2ExtNodeMap,
std::vector<TurnRestriction> & inputRestrictions
) {
const UUID uuid_orig;
UUID uuid_loaded;
in.read((char *) &uuid_loaded, sizeof(UUID));
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
SimpleLogger().Write(logWARNING) <<
".osrm was prepared with different build.\n"
"Reprocess to get rid of this warning.";
}
NodeID n, source, target; NodeID n, source, target;
EdgeID m; EdgeID m;
short dir;// direction (0 = open, 1 = forward, 2+ = open) short dir;// direction (0 = open, 1 = forward, 2+ = open)
ExternalNodeMap ext2IntNodeMap; ExternalNodeMap ext2IntNodeMap;
in.read((char*)&n, sizeof(NodeID)); in.read((char*)&n, sizeof(NodeID));
DEBUG("Importing n = " << n << " nodes "); SimpleLogger().Write() << "Importing n = " << n << " nodes ";
_Node node; _Node node;
for (NodeID i=0; i<n; ++i) { for (NodeID i=0; i<n; ++i) {
in.read((char*)&node, sizeof(_Node)); in.read((char*)&node, sizeof(_Node));
int2ExtNodeMap->push_back(NodeInfo(node.lat, node.lon, node.id)); int2ExtNodeMap->push_back(NodeInfo(node.lat, node.lon, node.id));
ext2IntNodeMap.insert(std::make_pair(node.id, i)); ext2IntNodeMap.insert(std::make_pair(node.id, i));
if(node.bollard) if(node.bollard) {
bollardNodes.push_back(i); bollardNodes.push_back(i);
if(node.trafficLight) }
if(node.trafficLight) {
trafficLightNodes.push_back(i); trafficLightNodes.push_back(i);
}
} }
//tighten vector sizes //tighten vector sizes
@@ -72,11 +96,11 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
std::vector<NodeID>(trafficLightNodes).swap(trafficLightNodes); std::vector<NodeID>(trafficLightNodes).swap(trafficLightNodes);
in.read((char*)&m, sizeof(unsigned)); in.read((char*)&m, sizeof(unsigned));
DEBUG(" and " << m << " edges "); SimpleLogger().Write() << " and " << m << " edges ";
for(unsigned i = 0; i < inputRestrictions.size(); ++i) { for(unsigned i = 0; i < inputRestrictions.size(); ++i) {
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(inputRestrictions[i].fromNode); ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(inputRestrictions[i].fromNode);
if( intNodeID == ext2IntNodeMap.end()) { if( intNodeID == ext2IntNodeMap.end()) {
DEBUG("Unmapped from Node of restriction"); SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction";
continue; continue;
} }
@@ -84,14 +108,14 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].viaNode); intNodeID = ext2IntNodeMap.find(inputRestrictions[i].viaNode);
if( intNodeID == ext2IntNodeMap.end()) { if( intNodeID == ext2IntNodeMap.end()) {
DEBUG("Unmapped via node of restriction"); SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction";
continue; continue;
} }
inputRestrictions[i].viaNode = intNodeID->second; inputRestrictions[i].viaNode = intNodeID->second;
intNodeID = ext2IntNodeMap.find(inputRestrictions[i].toNode); intNodeID = ext2IntNodeMap.find(inputRestrictions[i].toNode);
if( intNodeID == ext2IntNodeMap.end()) { if( intNodeID == ext2IntNodeMap.end()) {
DEBUG("Unmapped to node of restriction"); SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction";
continue; continue;
} }
inputRestrictions[i].toNode = intNodeID->second; inputRestrictions[i].toNode = intNodeID->second;
@@ -132,7 +156,8 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source); ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source);
if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) { if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) {
#ifndef NDEBUG #ifndef NDEBUG
WARN(" unresolved source NodeID: " << source ); SimpleLogger().Write(logWARNING) <<
" unresolved source NodeID: " << source;
#endif #endif
continue; continue;
} }
@@ -140,7 +165,8 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
intNodeID = ext2IntNodeMap.find(target); intNodeID = ext2IntNodeMap.find(target);
if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) { if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) {
#ifndef NDEBUG #ifndef NDEBUG
WARN("unresolved target NodeID : " << target ); SimpleLogger().Write(logWARNING) <<
"unresolved target NodeID : " << target;
#endif #endif
continue; continue;
} }
@@ -191,7 +217,7 @@ NodeID readBinaryOSRMGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeL
typename std::vector<EdgeT>::iterator newEnd = std::remove_if(edgeList.begin(), edgeList.end(), _ExcessRemover<EdgeT>()); typename std::vector<EdgeT>::iterator newEnd = std::remove_if(edgeList.begin(), edgeList.end(), _ExcessRemover<EdgeT>());
ext2IntNodeMap.clear(); ext2IntNodeMap.clear();
std::vector<EdgeT>(edgeList.begin(), newEnd).swap(edgeList); //remove excess candidates. std::vector<EdgeT>(edgeList.begin(), newEnd).swap(edgeList); //remove excess candidates.
INFO("Graph loaded ok and has " << edgeList.size() << " edges"); SimpleLogger().Write() << "Graph loaded ok and has " << edgeList.size() << " edges";
return n; return n;
} }
template<typename EdgeT> template<typename EdgeT>
@@ -201,14 +227,14 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open) int dir, xcoord, ycoord;// direction (0 = open, 1 = forward, 2+ = open)
ExternalNodeMap ext2IntNodeMap; ExternalNodeMap ext2IntNodeMap;
in >> n; in >> n;
DEBUG("Importing n = " << n << " nodes "); SimpleLogger().Write(logDEBUG) << "Importing n = " << n << " nodes ";
for (NodeID i=0; i<n;++i) { for (NodeID i=0; i<n; ++i) {
in >> id >> ycoord >> xcoord; in >> id >> ycoord >> xcoord;
int2ExtNodeMap->push_back(NodeInfo(xcoord, ycoord, id)); int2ExtNodeMap->push_back(NodeInfo(xcoord, ycoord, id));
ext2IntNodeMap.insert(std::make_pair(id, i)); ext2IntNodeMap.insert(std::make_pair(id, i));
} }
in >> m; in >> m;
DEBUG(" and " << m << " edges"); SimpleLogger().Write(logDEBUG) << " and " << m << " edges";
edgeList.reserve(m); edgeList.reserve(m);
for (EdgeID i=0; i<m; ++i) { for (EdgeID i=0; i<m; ++i) {
@@ -219,9 +245,9 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
int length; int length;
in >> source >> target >> length >> dir >> speedType; in >> source >> target >> length >> dir >> speedType;
if(dir == 3) if(dir == 3) {
dir = 0; dir = 0;
}
switch(speedType) { switch(speedType) {
case 1: case 1:
weight = 130; weight = 130;
@@ -271,32 +297,44 @@ NodeID readDTMPGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
} }
weight = length*weight/3.6; weight = length*weight/3.6;
if(speedType == 13) if(speedType == 13) {
weight = length; weight = length;
}
assert(length > 0); assert(length > 0);
assert(weight > 0); assert(weight > 0);
if(dir <0 || dir > 2) if(dir <0 || dir > 2) {
WARN("direction bogus: " << dir); SimpleLogger().Write(logWARNING) << "direction bogus: " << dir;
}
assert(0<=dir && dir<=2); assert(0<=dir && dir<=2);
bool forward = true; bool forward = true;
bool backward = true; bool backward = true;
if (dir == 1) backward = false; if (dir == 1) {
if (dir == 2) forward = false; backward = false;
}
if (dir == 2) {
forward = false;
}
if(length == 0) { ERR("loaded null length edge"); } if(length == 0) {
throw OSRMException("loaded null length edge");
}
// translate the external NodeIDs to internal IDs // translate the external NodeIDs to internal IDs
ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source); ExternalNodeMap::iterator intNodeID = ext2IntNodeMap.find(source);
if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) { if( ext2IntNodeMap.find(source) == ext2IntNodeMap.end()) {
ERR("after " << edgeList.size() << " edges" << "\n->" << source << "," << target << "," << length << "," << dir << "," << weight << "\n->unresolved source NodeID: " << source); throw OSRMException("unresolvable source Node ID");
} }
source = intNodeID->second; source = intNodeID->second;
intNodeID = ext2IntNodeMap.find(target); intNodeID = ext2IntNodeMap.find(target);
if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) { ERR("unresolved target NodeID : " << target); } if(ext2IntNodeMap.find(target) == ext2IntNodeMap.end()) {
throw OSRMException("unresolvable target Node ID");
}
target = intNodeID->second; target = intNodeID->second;
if(source == UINT_MAX || target == UINT_MAX) { ERR("nonexisting source or target" ); } if(source == UINT_MAX || target == UINT_MAX) {
throw OSRMException("nonexisting source or target" );
}
EdgeT inputEdge(source, target, 0, weight, forward, backward, type ); EdgeT inputEdge(source, target, 0, weight, forward, backward, type );
edgeList.push_back(inputEdge); edgeList.push_back(inputEdge);
@@ -318,17 +356,19 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
in >> d; in >> d;
in >> n; in >> n;
in >> m; in >> m;
#ifndef DEBUG
std::cout << "expecting " << n << " nodes and " << m << " edges ..." << flush; SimpleLogger().Write(logDEBUG) <<
#endif "expecting " << n << " nodes and " << m << " edges ...";
edgeList.reserve(m); edgeList.reserve(m);
for (EdgeID i=0; i<m; i++) { for (EdgeID i=0; i<m; i++) {
EdgeWeight weight; EdgeWeight weight;
in >> source >> target >> weight >> dir; in >> source >> target >> weight >> dir;
assert(weight > 0); assert(weight > 0);
if(dir <0 || dir > 3) if(dir <0 || dir > 3) {
ERR( "[error] direction bogus: " << dir ); throw OSRMException( "[error] direction bogus");
}
assert(0<=dir && dir<=3); assert(0<=dir && dir<=3);
bool forward = true; bool forward = true;
@@ -337,7 +377,9 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
if (dir == 2) forward = false; if (dir == 2) forward = false;
if (dir == 3) {backward = true; forward = true;} if (dir == 3) {backward = true; forward = true;}
if(weight == 0) { ERR("loaded null length edge"); } if(weight == 0) {
throw OSRMException("loaded null length edge");
}
if( nodeMap.find(source) == nodeMap.end()) { if( nodeMap.find(source) == nodeMap.end()) {
nodeMap.insert(std::make_pair(source, numberOfNodes )); nodeMap.insert(std::make_pair(source, numberOfNodes ));
@@ -359,19 +401,53 @@ NodeID readDDSGGraphFromStream(std::istream &in, std::vector<EdgeT>& edgeList, s
} }
template<typename NodeT, typename EdgeT> template<typename NodeT, typename EdgeT>
unsigned readHSGRFromStream(std::istream &in, std::vector<NodeT>& nodeList, std::vector<EdgeT> & edgeList, unsigned * checkSum) { unsigned readHSGRFromStream(
unsigned numberOfNodes = 0; const std::string & hsgr_filename,
in.read((char*) checkSum, sizeof(unsigned)); std::vector<NodeT> & node_list,
in.read((char*) & numberOfNodes, sizeof(unsigned)); std::vector<EdgeT> & edge_list,
nodeList.resize(numberOfNodes + 1); unsigned * check_sum
in.read((char*) &(nodeList[0]), numberOfNodes*sizeof(NodeT)); ) {
boost::filesystem::path hsgr_file(hsgr_filename);
if ( !boost::filesystem::exists( hsgr_file ) ) {
throw OSRMException("hsgr file does not exist");
}
if ( 0 == boost::filesystem::file_size( hsgr_file ) ) {
throw OSRMException("hsgr file is empty");
}
unsigned numberOfEdges = 0; boost::filesystem::ifstream hsgr_input_stream(hsgr_file, std::ios::binary);
in.read((char*) &numberOfEdges, sizeof(unsigned));
edgeList.resize(numberOfEdges);
in.read((char*) &(edgeList[0]), numberOfEdges*sizeof(EdgeT));
return numberOfNodes; UUID uuid_loaded, uuid_orig;
hsgr_input_stream.read((char *)&uuid_loaded, sizeof(UUID));
if( !uuid_loaded.TestGraphUtil(uuid_orig) ) {
SimpleLogger().Write(logWARNING) <<
".hsgr was prepared with different build. "
"Reprocess to get rid of this warning.";
}
unsigned number_of_nodes = 0;
hsgr_input_stream.read((char*) check_sum, sizeof(unsigned));
hsgr_input_stream.read((char*) & number_of_nodes, sizeof(unsigned));
BOOST_ASSERT_MSG( 0 != number_of_nodes, "number of nodes is zero");
node_list.resize(number_of_nodes + 1);
hsgr_input_stream.read(
(char*) &(node_list[0]),
number_of_nodes*sizeof(NodeT)
);
unsigned number_of_edges = 0;
hsgr_input_stream.read(
(char*) &number_of_edges,
sizeof(unsigned)
);
BOOST_ASSERT_MSG( 0 != number_of_edges, "number of edges is zero");
edge_list.resize(number_of_edges);
hsgr_input_stream.read(
(char*) &(edge_list[0]),
number_of_edges*sizeof(EdgeT)
);
hsgr_input_stream.close();
return number_of_nodes;
} }
#endif // GRAPHLOADER_H #endif // GRAPHLOADER_H
+100
View File
@@ -0,0 +1,100 @@
/*
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 INI_FILE_H_
#define INI_FILE_H_
#include "OSRMException.h"
#include "../DataStructures/HashTable.h"
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <exception>
#include <iostream>
#include <string>
class IniFile {
public:
IniFile(const char * config_filename) {
boost::filesystem::path config_file(config_filename);
if ( !boost::filesystem::exists( config_file ) ) {
std::string error = std::string(config_filename) + " not found";
throw OSRMException(error);
}
if ( 0 == boost::filesystem::file_size( config_file ) ) {
std::string error = std::string(config_filename) + " is empty";
throw OSRMException(error);
}
boost::filesystem::ifstream config( config_file );
std::string line;
if (config.is_open()) {
while ( config.good() ) {
getline (config,line);
std::vector<std::string> tokens;
Tokenize(line, tokens);
if(2 == tokens.size() ) {
parameters.insert(std::make_pair(tokens[0], tokens[1]));
}
}
config.close();
}
}
std::string GetParameter(const std::string & key){
return parameters.Find(key);
}
bool Holds(const std::string & key) const {
return parameters.Holds(key);
}
void SetParameter(const char* key, const char* value) {
SetParameter(std::string(key), std::string(value));
}
void SetParameter(const std::string & key, const std::string & value) {
parameters.insert(std::make_pair(key, value));
}
private:
void Tokenize(
const std::string& str,
std::vector<std::string>& tokens,
const std::string& delimiters = "="
) {
std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
std::string::size_type pos = str.find_first_of(delimiters, lastPos);
while (std::string::npos != pos || std::string::npos != lastPos) {
std::string temp = str.substr(lastPos, pos - lastPos);
boost::trim(temp);
tokens.push_back( temp );
lastPos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, lastPos);
}
}
HashTable<std::string, std::string> parameters;
};
#endif /* INI_FILE_H_ */
+5 -3
View File
@@ -21,15 +21,17 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef INPUTFILEUTIL_H_ #ifndef INPUTFILEUTIL_H_
#define INPUTFILEUTIL_H_ #define INPUTFILEUTIL_H_
#include <boost/filesystem.hpp>
#include "../typedefs.h" #include "../typedefs.h"
#include <boost/filesystem.hpp>
// Check if file exists and if it can be opened for reading with ifstream an object // Check if file exists and if it can be opened for reading with ifstream an object
inline bool testDataFile(const std::string & filename){ inline bool testDataFile(const std::string & filename){
boost::filesystem::path fileToTest(filename); boost::filesystem::path fileToTest(filename);
if(!boost::filesystem::exists(fileToTest)) { if(!boost::filesystem::exists(fileToTest)) {
WARN("Failed to open file " << filename << " for reading."); SimpleLogger().Write(logWARNING) <<
"Failed to open file " << filename << " for reading.";
return false; return false;
} }
return true; return true;
-1
View File
@@ -25,7 +25,6 @@ or see http://www.gnu.org/licenses/agpl.txt.
#include <string> #include <string>
#ifdef __linux__ #ifdef __linux__
#include <cxxabi.h> #include <cxxabi.h>
#include <execinfo.h> #include <execinfo.h>
+11 -11
View File
@@ -1,17 +1,17 @@
/* /*
open source routing machine open source routing machine
Copyright (C) Dennis Luxen, others 2010 Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify 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 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 the Free Software Foundation; either version 3 of the License, or
any later version. any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -23,11 +23,11 @@
#if defined(__APPLE__) || defined(__FreeBSD__) #if defined(__APPLE__) || defined(__FreeBSD__)
extern "C" { extern "C" {
#include <sys/types.h> #include <sys/types.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
} }
#elif defined _WIN32 #elif defined _WIN32
#include <windows.h> #include <windows.h>
#endif #endif
enum Endianness { enum Endianness {
@@ -55,28 +55,28 @@ inline unsigned swapEndian(unsigned x) {
inline unsigned GetPhysicalmemory(void){ inline unsigned GetPhysicalmemory(void){
#if defined(SUN5) || defined(__linux__) #if defined(SUN5) || defined(__linux__)
return (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE)); return (sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE));
#elif defined(__APPLE__) #elif defined(__APPLE__)
int mib[2] = {CTL_HW, HW_MEMSIZE}; int mib[2] = {CTL_HW, HW_MEMSIZE};
long long memsize; long long memsize;
size_t len = sizeof(memsize); size_t len = sizeof(memsize);
sysctl(mib, 2, &memsize, &len, NULL, 0); sysctl(mib, 2, &memsize, &len, NULL, 0);
return memsize/1024; return memsize/1024;
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
int mib[2] = {CTL_HW, HW_PHYSMEM}; int mib[2] = {CTL_HW, HW_PHYSMEM};
long long memsize; long long memsize;
size_t len = sizeof(memsize); size_t len = sizeof(memsize);
sysctl(mib, 2, &memsize, &len, NULL, 0); sysctl(mib, 2, &memsize, &len, NULL, 0);
return memsize/1024; return memsize/1024;
#elif defined(_WIN32) #elif defined(_WIN32)
MEMORYSTATUSEX status; MEMORYSTATUSEX status;
status.dwLength = sizeof(status); status.dwLength = sizeof(status);
GlobalMemoryStatusEx(&status); GlobalMemoryStatusEx(&status);
return status.ullTotalPhys/1024; return status.ullTotalPhys/1024;
#else #else
std::cout << "[Warning] Compiling on unknown architecture." << std::endl std::cout << "[Warning] Compiling on unknown architecture." << std::endl
<< "Please file a ticket at http://project-osrm.org" << std::endl; << "Please file a ticket at http://project-osrm.org" << std::endl;
return 2048*1024; /* 128 Mb default memory */ return 2048*1024; /* 128 Mb default memory */
@@ -18,17 +18,22 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef PLUGINMAPFACTORY_H_ #ifndef OSRM_EXCEPTION_H
#define PLUGINMAPFACTORY_H_ #define OSRM_EXCEPTION_H
//#include "../DataStructures/HashTable.h" #include <exception>
//#include "../Plugins/BasePlugin.h" #include <string>
//
//struct PluginMapFactory {
// static HashTable<std::string, BasePlugin *> * CreatePluginMap() {
// HashTable<std::string, BasePlugin *> * map = new HashTable<std::string, BasePlugin *>();
//
// }
//};
#endif /* PLUGINMAPFACTORY_H_ */ class OSRMException: public std::exception {
public:
OSRMException(const char * message) : message(message) {}
OSRMException(const std::string & message) : message(message) {}
virtual ~OSRMException() throw() {}
private:
virtual const char* what() const throw() {
return message.c_str();
}
const std::string message;
};
#endif /* OSRM_EXCEPTION_H */
+11 -10
View File
@@ -19,16 +19,17 @@ or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef _OPENMPREPLACEMENTY_H #ifndef _OPENMWRAPPER_H
#define _OPENMPREPLACEMENTY_H #define _OPENMWRAPPER_H
#ifdef _OPENMP #ifdef _OPENMP
#include <omp.h> extern "C" {
#include <omp.h>
}
#else #else
inline const int omp_get_num_procs() { return 1; } inline int omp_get_num_procs () { return 1; }
inline const int omp_get_max_threads() { return 1; } inline int omp_get_max_threads () { return 1; }
inline const int omp_get_thread_num() { return 0; } inline int omp_get_thread_num () { return 0; }
inline const void omp_set_num_threads(int i) {} inline void omp_set_num_threads (int i) {}
#endif #endif /* _OPENMP */
#endif /* _OPENMWRAPPER_H */
#endif
+114
View File
@@ -0,0 +1,114 @@
/*
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 SIMPLE_LOGGER_H_
#define SIMPLE_LOGGER_H_
#include <boost/assert.hpp>
#include <boost/noncopyable.hpp>
#include <boost/thread/mutex.hpp>
#include <ostream>
#include <iostream>
enum LogLevel { logINFO, logWARNING, logDEBUG };
static boost::mutex logger_mutex;
class LogPolicy : boost::noncopyable {
public:
void Unmute() {
m_is_mute = false;
}
void Mute() {
m_is_mute = true;
}
bool IsMute() const {
return m_is_mute;
}
static LogPolicy & GetInstance() {
static LogPolicy runningInstance;
return runningInstance;
}
private:
LogPolicy() : m_is_mute(true) { }
bool m_is_mute;
};
class SimpleLogger {
public:
std::ostringstream& Write(LogLevel l = logINFO) {
try {
boost::mutex::scoped_lock lock(logger_mutex);
level = l;
os << "[";
switch(level) {
case logINFO:
os << "info";
break;
case logWARNING:
os << "warn";
break;
case logDEBUG:
#ifndef NDEBUG
os << "debug";
#endif
break;
default:
BOOST_ASSERT_MSG(false, "should not happen");
break;
}
os << "] ";
} catch (...) { }
return os;
}
virtual ~SimpleLogger() {
if(!LogPolicy::GetInstance().IsMute()) {
switch(level) {
case logINFO:
std::cout << os.str() << std::endl;
break;
case logWARNING:
std::cerr << os.str() << std::endl;
break;
case logDEBUG:
#ifndef NDEBUG
std::cout << os.str() << std::endl;
#endif
break;
default:
BOOST_ASSERT_MSG(false, "should not happen");
break;
}
}
}
private:
LogLevel level;
std::ostringstream os;
};
#endif /* SIMPLE_LOGGER_H_ */
+50 -47
View File
@@ -21,16 +21,15 @@ or see http://www.gnu.org/licenses/agpl.txt.
#ifndef STRINGUTIL_H_ #ifndef STRINGUTIL_H_
#define STRINGUTIL_H_ #define STRINGUTIL_H_
#include <string> #include "../typedefs.h"
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/spirit/include/karma.hpp> #include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/qi.hpp> #include <boost/spirit/include/qi.hpp>
#include <cstdio> #include <cstdio>
#include <string>
#include "../DataStructures/Coordinate.h"
#include "../typedefs.h"
// precision: position after decimal point // precision: position after decimal point
// length: maximum number of digits including comma and decimals // length: maximum number of digits including comma and decimals
@@ -63,23 +62,63 @@ static inline char* printInt( char* buffer, int value ) {
} }
static inline void intToString(const int value, std::string & output) { static inline void intToString(const int value, std::string & output) {
// The largest 32-bit integer is 4294967295, that is 10 chars
// On the safe side, add 1 for sign, and 1 for trailing zero
output.clear(); output.clear();
std::back_insert_iterator<std::string> sink(output); std::back_insert_iterator<std::string> sink(output);
boost::spirit::karma::generate(sink, boost::spirit::karma::int_, value); boost::spirit::karma::generate(sink, boost::spirit::karma::int_, value);
} }
static inline void int64ToString(const int64_t value, std::string & output) {
output.clear();
std::back_insert_iterator<std::string> sink(output);
boost::spirit::karma::generate(sink, boost::spirit::karma::long_long, value);
}
static inline int stringToInt(const std::string& input) { static inline int stringToInt(const std::string& input) {
std::string::const_iterator realBeginOfNumber = input.begin(); std::string::const_iterator first_digit = input.begin();
//Delete any trailing white-spaces //Delete any trailing white-spaces
while(realBeginOfNumber != input.end() && std::isspace(*realBeginOfNumber)) while(first_digit != input.end() && std::isspace(*first_digit)) {
++realBeginOfNumber; ++first_digit;
int value = 0; // 2 }
boost::spirit::qi::parse(realBeginOfNumber, input.end(), boost::spirit::int_, value); // 3 int value = 0;
boost::spirit::qi::parse(
first_digit,
input.end(),
boost::spirit::int_, value
);
return value; return value;
} }
static inline unsigned stringToUint(const std::string& input) {
std::string::const_iterator first_digit = input.begin();
//Delete any trailing white-spaces
while(first_digit != input.end() && std::isspace(*first_digit)) {
++first_digit;
}
int value = 0;
boost::spirit::qi::parse(
first_digit,
input.end(),
boost::spirit::uint_, value
);
return value;
}
static inline uint64_t stringToInt64(const std::string& input) {
std::string::const_iterator first_digit = input.begin();
//Delete any trailing white-spaces
while(first_digit != input.end() && std::isspace(*first_digit)) {
++first_digit;
}
uint64_t value = 0;
boost::spirit::qi::parse(
first_digit,
input.end(),
boost::spirit::long_long, value
);
return value;
}
static inline void doubleToString(const double value, std::string & output){ static inline void doubleToString(const double value, std::string & output){
output.clear(); output.clear();
std::back_insert_iterator<std::string> sink(output); std::back_insert_iterator<std::string> sink(output);
@@ -94,32 +133,6 @@ static inline void doubleToStringWithTwoDigitsBehindComma(const double value, st
output = buffer ; output = buffer ;
} }
static inline void convertInternalLatLonToString(const int value, std::string & output) {
char buffer[100];
buffer[10] = 0; // Nullterminierung
char* string = printInt< 10, 5 >( buffer, value );
output = string;
}
static inline void convertInternalCoordinateToString(const _Coordinate & coord, std::string & output) {
std::string tmp;
convertInternalLatLonToString(coord.lon, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lat, tmp);
output += tmp;
output += " ";
}
static inline void convertInternalReversedCoordinateToString(const _Coordinate & coord, std::string & output) {
std::string tmp;
convertInternalLatLonToString(coord.lat, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lon, tmp);
output += tmp;
output += " ";
}
inline void replaceAll(std::string &s, const std::string &sub, const std::string &other) { inline void replaceAll(std::string &s, const std::string &sub, const std::string &other) {
boost::replace_all(s, sub, other); boost::replace_all(s, sub, other);
} }
@@ -150,14 +163,4 @@ inline bool StringStartsWith(const std::string & input, const std::string & pref
return boost::starts_with(input, prefix); return boost::starts_with(input, prefix);
} }
// Function returns a 'random' filename in temporary directors.
// May not be platform independent.
inline void GetTemporaryFileName(std::string & filename) {
char buffer[L_tmpnam];
char * retPointer = tmpnam (buffer);
if(0 == retPointer)
ERR("Could not create temporary file name");
filename = buffer;
}
#endif /* STRINGUTIL_H_ */ #endif /* STRINGUTIL_H_ */
@@ -1,6 +1,6 @@
/* /*
open source routing machine open source routing machine
Copyright (C) Dennis Luxen, 2010 Copyright (C) Dennis Luxen, others 2010
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU AFFERO General Public License as published by
@@ -16,13 +16,18 @@ You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
or see http://www.gnu.org/licenses/agpl.txt. or see http://www.gnu.org/licenses/agpl.txt.
*/ */
#ifndef SERVERCONFIGURATION_H_ #ifndef TIMINGUTIL_H_
#define SERVERCONFIGURATION_H_ #define TIMINGUTIL_H_
#include "../Util/BaseConfiguration.h" #include <boost/timer.hpp>
typedef BaseConfiguration ServerConfiguration; static boost::timer my_timer;
#endif /* SERVERCONFIGURATION_H_ */ /** Returns a timestamp (now) in seconds (incl. a fractional part). */
static inline double get_timestamp() {
return my_timer.elapsed();
}
#endif /* TIMINGUTIL_H_ */
+95
View File
@@ -0,0 +1,95 @@
/*
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.
*/
#include "UUID.h"
#cmakedefine01 HAS64BITS
#cmakedefine MD5PREPARE "${MD5PREPARE}"
#cmakedefine MD5RTREE "${MD5RTREE}"
#cmakedefine MD5NODEINFO "${MD5NODEINFO}"
#cmakedefine MD5GRAPH "${MD5GRAPH}"
#cmakedefine MD5OBJECTS "${MD5OBJECTS}"
UUID::UUID() : magic_number(1297240911) {
boost::uuids::name_generator gen(named_uuid);
std::string temp_string(__DATE__);
temp_string += __TIME__;
std::copy(MD5PREPARE, MD5PREPARE+strlen(MD5PREPARE), md5_prepare);
temp_string += md5_prepare;
std::copy(MD5RTREE, MD5RTREE+32, md5_tree);
temp_string += md5_tree;
std::copy(MD5NODEINFO, MD5NODEINFO+32, md5_nodeinfo);
temp_string += md5_nodeinfo;
std::copy(MD5GRAPH, MD5GRAPH+32, md5_graph);
temp_string += md5_graph;
std::copy(MD5OBJECTS, MD5OBJECTS+32, md5_objects);
temp_string += md5_objects;
named_uuid = gen(temp_string);
has_64_bits = HAS64BITS;
}
UUID::~UUID() {
}
const boost::uuids::uuid & UUID::GetUUID() const {
return named_uuid;
}
bool UUID::IsMagicNumberOK() const {
return 1297240911 == magic_number;
}
bool UUID::TestGraphUtil(const UUID & other) const {
if(!other.IsMagicNumberOK()) {
throw OSRMException("hsgr input file misses magic number. Check or reprocess the file");
}
return std::equal(md5_graph, md5_graph+32, other.md5_graph);
}
bool UUID::TestPrepare(const UUID & other) const {
if(!other.IsMagicNumberOK()) {
throw OSRMException("extracted input file misses magic number. Check or reprocess the file");
}
return std::equal(md5_prepare, md5_prepare+32, other.md5_prepare);
}
bool UUID::TestRTree(const UUID & other) const {
if(!other.IsMagicNumberOK()) {
throw OSRMException("r-tree input file misses magic number. Check or reprocess the file");
}
return std::equal(md5_tree, md5_tree+32, other.md5_tree);
}
bool UUID::TestNodeInfo(const UUID & other) const {
if(!other.IsMagicNumberOK()) {
throw OSRMException("nodes file misses magic number. Check or reprocess the file");
}
return std::equal(md5_nodeinfo, md5_nodeinfo+32, other.md5_nodeinfo);
}
bool UUID::TestQueryObjects(const UUID & other) const {
if(!other.IsMagicNumberOK()) {
throw OSRMException("missing magic number. Check or reprocess the file");
}
return std::equal(md5_objects, md5_objects+32, other.md5_objects);
}
+63
View File
@@ -0,0 +1,63 @@
/*
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 UUID_H
#define UUID_H
#include "OSRMException.h"
#include "../typedefs.h"
#include <boost/noncopyable.hpp>
#include <boost/uuid/uuid.hpp> // uuid class
#include <boost/uuid/uuid_generators.hpp> // generators
#include <boost/uuid/uuid_io.hpp> // streaming operators etc.
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
//implements a singleton, i.e. there is one and only one conviguration object
class UUID : boost::noncopyable {
public:
UUID();
~UUID();
const boost::uuids::uuid & GetUUID() const;
bool IsMagicNumberOK() const;
bool TestGraphUtil(const UUID & other) const;
bool TestPrepare(const UUID & other) const;
bool TestRTree(const UUID & other) const;
bool TestNodeInfo(const UUID & other) const;
bool TestQueryObjects(const UUID & other) const;
private:
const unsigned magic_number;
char md5_prepare[33];
char md5_tree[33];
char md5_nodeinfo[33];
char md5_graph[33];
char md5_objects[33];
// initialize to {6ba7b810-9dad-11d1-80b4-00c04fd430c8}
boost::uuids::uuid named_uuid;
bool has_64_bits;
};
#endif /* UUID_H */
+86
View File
@@ -0,0 +1,86 @@
# Locate Lua library
# This module defines
# LUAJIT_FOUND, if false, do not try to link to Lua
# LUAJIT_LIBRARIES
# LUAJIT_INCLUDE_DIR, where to find lua.h
#
# Note that the expected include convention is
# #include "lua.h"
# and not
# #include <lua/lua.h>
# This is because, the lua location is not standardized and may exist
# in locations other than lua/
#=============================================================================
# Copyright 2007-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distributed this file outside of CMake, substitute the full
# License text for the above reference.)
#
# ################
# 2010 - modified for cronkite to find luajit instead of lua, as it was before.
#
IF( NOT LUAJIT_FIND_QUIETLY )
MESSAGE(STATUS "Looking for LuaJIT...")
ENDIF()
FIND_PATH(LUAJIT_INCLUDE_DIR lua.h
HINTS
$ENV{LUAJIT_DIR}
PATH_SUFFIXES include/luajit-2.0 include/luajit2.0 include/luajit include
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
)
FIND_LIBRARY(LUAJIT_LIBRARY
NAMES luajit-51 luajit-5.1 luajit
HINTS
$ENV{LUAJIT_DIR}
PATH_SUFFIXES lib64 lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/sw
/opt/local
/opt/csw
/opt
)
# include the math library for Unix
IF(UNIX AND NOT APPLE)
FIND_LIBRARY(LUAJIT_MATH_LIBRARY m)
SET( LUAJIT_LIBRARIES "${LUAJIT_LIBRARY};${LUAJIT_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
# For Windows and Mac, don't need to explicitly include the math library
ELSE(UNIX AND NOT APPLE)
SET( LUAJIT_LIBRARIES "${LUAJIT_LIBRARY}" CACHE STRING "Lua Libraries")
ENDIF(UNIX AND NOT APPLE)
#ENDIF(LUAJIT_LIBRARY)
INCLUDE(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJIT DEFAULT_MSG LUAJIT_LIBRARIES LUAJIT_INCLUDE_DIR)
IF( NOT LUAJIT_FIND_QUIETLY )
IF( LUAJIT_FOUND )
MESSAGE(STATUS "Found LuaJIT: ${LUAJIT_LIBRARY}" )
ENDIF()
ENDIF()
MARK_AS_ADVANCED(LUAJIT_INCLUDE_DIR LUAJIT_LIBRARIES LUAJIT_LIBRARY LUAJIT_MATH_LIBRARY)
+2 -2
View File
@@ -27,7 +27,7 @@ FIND_PATH(LUABIND_INCLUDE_DIR luabind.hpp
) )
FIND_LIBRARY(LUABIND_LIBRARY FIND_LIBRARY(LUABIND_LIBRARY
NAMES luabind NAMES luabind luabind09
HINTS HINTS
$ENV{LUABIND_DIR} $ENV{LUABIND_DIR}
PATH_SUFFIXES lib64 lib PATH_SUFFIXES lib64 lib
@@ -72,4 +72,4 @@ IF( NOT LUABIND_FIND_QUIETLY )
ENDIF() ENDIF()
ENDIF() ENDIF()
MARK_AS_ADVANCED(LUABIND_INCLUDE_DIR LUABIND_LIBRARIES LUABIND_LIBRARY LUABIND_LIBRARY_DBG) MARK_AS_ADVANCED(LUABIND_INCLUDE_DIR LUABIND_LIBRARIES LUABIND_LIBRARY LUABIND_LIBRARY_DBG)
-123
View File
@@ -1,123 +0,0 @@
# - Returns a version string from Git
#
# These functions force a re-configure on each git commit so that you can
# trust the values of the variables in your build system.
#
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
#
# Returns the refspec and sha hash of the current head revision
#
# git_describe(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe on the source tree, and adjusting
# the output so that it tests false if an error occurs.
#
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
#
# Returns the results of git describe --exact-match on the source tree,
# and adjusting the output so that it tests false if there was no exact
# matching tag.
#
# Requires CMake 2.6 or newer (uses the 'function' command)
#
# Original Author:
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
# http://academic.cleardefinition.com
# Iowa State University HCI Graduate Program/VRAC
#
# Copyright Iowa State University 2009-2010.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
if(__get_git_revision_description)
return()
endif()
set(__get_git_revision_description YES)
# We must run the following at "include" time, not at function call time,
# to find the path to this module rather than the path to a calling list file
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
function(get_git_head_revision _refspecvar _hashvar)
set(GIT_PARENT_DIR "${CMAKE_SOURCE_DIR}")
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
# We have reached the root directory, we are not in git
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
return()
endif()
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
endwhile()
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
if(NOT EXISTS "${GIT_DATA}")
file(MAKE_DIRECTORY "${GIT_DATA}")
endif()
if(NOT EXISTS "${GIT_DIR}/HEAD")
return()
endif()
set(HEAD_FILE "${GIT_DATA}/HEAD")
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
"${GIT_DATA}/grabRef.cmake"
@ONLY)
include("${GIT_DATA}/grabRef.cmake")
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
endfunction()
function(git_describe _var)
if(NOT GIT_FOUND)
find_package(Git QUIET)
endif()
get_git_head_revision(refspec hash)
if(NOT GIT_FOUND)
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
if(NOT hash)
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
return()
endif()
# TODO sanitize
#if((${ARGN}" MATCHES "&&") OR
# (ARGN MATCHES "||") OR
# (ARGN MATCHES "\\;"))
# message("Please report the following error to the project!")
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
#endif()
#message(STATUS "Arguments to execute_process: ${ARGN}")
execute_process(COMMAND
"${GIT_EXECUTABLE}"
describe
${hash}
${ARGN}
WORKING_DIRECTORY
"${CMAKE_SOURCE_DIR}"
RESULT_VARIABLE
res
OUTPUT_VARIABLE
out
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT res EQUAL 0)
set(out "${out}-${res}-NOTFOUND")
endif()
set(${_var} "${out}" PARENT_SCOPE)
endfunction()
function(git_get_exact_tag _var)
git_describe(out --exact-match ${ARGN})
set(${_var} "${out}" PARENT_SCOPE)
endfunction()

Some files were not shown because too many files have changed in this diff Show More