Compare commits

...

828 Commits

Author SHA1 Message Date
Patrick Niklaus f6116db957 Merge pull request #1902 from Project-OSRM/4.9.1
Bug fix release 4.9.1
2016-01-19 19:00:11 -05:00
Patrick Niklaus c824429458 Include the travel mode in the last instruction by copying it from the previous instruction. 2016-01-19 23:23:32 +01:00
Daniel Patterson 23b2154d98 Adds a shared/exclusive lock around queries and CheckAndReloadFacade.
Without this, it's possible for CheckAndReloadFacade to start working
while a query is still in progress, leading to undefined behaviour.
2016-01-19 21:26:30 +01:00
Daniel J. Hofmann 25c8711aad Fix shared memory non-copyable properties 2016-01-19 20:31:14 +01:00
Daniel Patterson cf30628d4e DataFacade should only remove shared segments if they're actually different from the last time they were checked. 2016-01-19 20:31:03 +01:00
Patrick Niklaus 7675c730b6 Fix wrong assertion and emplace_back bug in trip plugin 2016-01-19 17:38:02 +01:00
Patrick Niklaus 2ce74c05e1 Use a sane gps_precision multipler 2016-01-15 22:15:05 +01:00
Patrick Niklaus 88e6558da3 Fix handling unexpected errors. 2016-01-15 22:08:04 +01:00
Patrick Niklaus f1140ec903 Fix uturns at dead-end streets 2016-01-15 21:48:14 +01:00
Patrick Niklaus a2e114e852 Merge branch 'develop' 2015-12-24 11:22:16 +01:00
Patrick Niklaus 0baf90a218 Adjust error string of distance_table to other plugins 2015-12-19 01:40:55 +01:00
Patrick Niklaus f9f3d43152 Fix min average sample time 2015-12-19 01:40:55 +01:00
Patrick Niklaus 326f2d2743 Accidentally broke the trip plugin 2015-12-18 19:22:02 +01:00
Patrick Niklaus 57f257dce5 Fix status messages and don't include 2015-12-18 18:18:48 +01:00
Patrick Niklaus c27fc4e4d8 Add comments to profiles about uturn 2015-12-18 15:54:33 +01:00
Moritz Kobitzsch a37192c102 alignment 2015-12-18 12:28:03 +01:00
Moritz Kobitzsch 68bd6a29b6 modified local state of u_turn_penalty_variable 2015-12-18 12:25:46 +01:00
Patrick Niklaus da11113bf1 Fix generate options parameter 2015-12-17 17:57:39 +01:00
Patrick Niklaus 70f4cdd0ca Replace codes with enum 2015-12-17 16:45:15 +01:00
Patrick Niklaus 78ac3cffde Add max values for viaroute and trip and reorganize return code handling
"status" is now always:
 - 200 if the request was successful
 - 207 if the result is empty (no path found)
 - 400 if the request is invalid

 viaroute and trip now have a maximum of 500 and 100 locations
 respectively. Override with the --max-viaroute-size and --max-trip-size
 parameters.
2015-12-17 04:14:34 +01:00
Patrick Niklaus 7eb2af6cd3 Add snapping regression test for viaroute 2015-12-16 22:51:01 +01:00
Patrick Niklaus 0b1c9d33a5 Don't use phantom node pairs as input for distance table 2015-12-16 22:51:01 +01:00
Patrick Niklaus 648a62112e Fix snapping to small components 2015-12-16 22:51:01 +01:00
Patrick Niklaus ff7cb91d9c Use the Koenig swap and add free swap function for DeallocationVector 2015-12-16 22:03:46 +01:00
Patrick Niklaus fd5881670d Use std::swap 2015-12-16 22:03:46 +01:00
Patrick Niklaus fc8768b79b Add test for car mode snapping 2015-12-16 22:03:46 +01:00
Patrick Niklaus 914570b053 Don't snap to ferries in car profile 2015-12-16 22:03:46 +01:00
Patrick Niklaus 1a8783cfa0 Fix unused variable warning 2015-12-16 22:03:46 +01:00
Patrick Niklaus 28bfefcac6 Add option to set segments as non-snapable from lua 2015-12-16 22:03:46 +01:00
Patrick Niklaus bec56522e3 Add stxxl/vector include to range_table test 2015-12-16 22:02:34 +01:00
Patrick Niklaus 0ddd473477 Use ::min() instead of -::max() 2015-12-16 19:41:06 +01:00
Patrick Niklaus 2defc8e826 Correctly initialize the min value 2015-12-16 19:35:12 +01:00
Patrick Niklaus c3756f6b58 Template the vector type in RangeTable 2015-12-16 18:17:04 +01:00
Patrick Niklaus 66af3d260c Merge pull request #1822 from rparanjpe-tesla/develop
name_lengths std::vector --> stxxl::vector
2015-12-16 11:49:59 -05:00
rparanjpe 5c3398c280 name_lengths std::vector --> stxxl::vector 2015-12-15 19:12:33 -08:00
Patrick Niklaus 63a59325f5 Fix SimpleClient 2015-12-16 00:26:13 +01:00
Patrick Niklaus f1091f97fc Fix cucumber help text test 2015-12-15 23:38:12 +01:00
Patrick Niklaus fe9bdfef79 Fix case when not specifing path or sharedmemory to osrm-routed 2015-12-15 22:27:12 +01:00
Patrick Niklaus a8f11981e3 Include tbb in libosrm.pc 2015-12-15 21:42:32 +01:00
Patrick Niklaus 94651744af Remove assertion in farest insertion 2015-12-15 21:33:59 +01:00
Patrick Niklaus 24e7d00af5 Fix call to shortest_path from match plugin /cc @danpat 2015-12-15 21:27:03 +01:00
Patrick Niklaus f85a35b5fc Fix map matching coordinate check 2015-12-15 21:14:43 +01:00
Patrick Niklaus a27aad0061 Fix osrm-routed options 2015-12-15 21:08:09 +01:00
Patrick Niklaus 9a332d2f86 Fix osrm.hpp placement 2015-12-15 19:25:26 +01:00
Patrick Niklaus 1264983688 Fix build 2015-12-15 16:31:28 +01:00
Patrick Niklaus 53cee90933 Fix removed server_paths reference 2015-12-15 05:17:31 +01:00
Patrick Niklaus 6daa3290d4 Cleanup library setup 2015-12-14 22:00:20 +01:00
Patrick Niklaus 5a9bee0527 Don't include zero characters in empty names 2015-12-13 20:31:47 +01:00
Daniel Patterson 6914d26187 Correct data entry for the empty string.
Rename name_offsets to name_lengths, because that makes more sense.
2015-12-13 11:02:55 -08:00
Daniel Patterson 68c01d09bb Merge branch 'rparanjpe-tesla-fix_stxxl_write' into develop 2015-12-11 15:40:03 -08:00
rparanjpe 4bf1ad2566 Write out stxxl vector for names correctly 2015-12-11 15:18:55 -08:00
Patrick Niklaus 00ed526fb0 Fix return value for node snapping 2015-12-11 17:37:48 +01:00
Patrick Niklaus 9bdc58069b Adapt snapping test to viaroute behaviour 2015-12-11 16:53:10 +01:00
Daniel Patterson 4ddbd2efb6 Expose component size variable as command-line option (this allows testing of big/small components in cucumber tests).
Add ability to pass extra parameters to  during tests.
Limit distance table search so that it doesn't return any big components if they're beyond max_distance.
2015-12-11 16:53:10 +01:00
Daniel Patterson f3f153cb38 Reduce source/targets to a single phantom node based on the small/big components that are present. 2015-12-11 16:53:10 +01:00
Patrick Niklaus 9414a8085d Fixed shortest_path when called from match plugin 2015-12-11 05:44:05 +01:00
Patrick Niklaus 33b18df1a0 Merge pull request #1809 from rparanjpe-tesla/develop
Use a std::vector in place of stxxl:vector for the names list
2015-12-10 11:13:05 -05:00
rparanjpe da91d342f7 name_list --> name_char_data and name_offsets
-Use stxxl vectors with char and unsigned int containers
-Write out the entire character vector to fil
-Cap the names at length 255 during the parsing so we reduce
 the amount of memory used by stxxl vectors and we can do a
 direct writing of the character vector to .names
2015-12-09 17:28:34 -08:00
Patrick Niklaus 4950e044ba Remove warnings and fix tests 2015-12-09 23:37:06 +01:00
Patrick Niklaus b41af5f580 Incoperate PR comments 2015-12-09 23:37:06 +01:00
Patrick Niklaus 24090d4642 Fix StaticRTree benchmark 2015-12-09 23:37:05 +01:00
Patrick Niklaus cdb1918973 Refactor StaticRTree to remove application dependent code
StaticRTree now acts like a container, just returning the input data
(NodeBasedEdge) and not PhantomNodes.
2015-12-09 23:37:05 +01:00
Patrick Niklaus a8e8f04fa3 std::vector<bool>::emplace_back -> push_back for gcc 4.8 2015-12-09 22:39:10 +01:00
Patrick Niklaus 4ec3102df2 Refactor cucumber tests 2015-12-09 21:17:18 +01:00
Patrick Niklaus 7e722db3ee Make the API grammar more strict to actually error 2015-12-09 21:17:18 +01:00
Patrick Niklaus 20c45be3b3 Address PR comments 2015-12-09 21:17:18 +01:00
Fabien Girard f2ee0aad20 Use now 3 parameters for matrix: loc/dst/src 2015-12-09 21:17:18 +01:00
Fabien Girard 478d4a571a Support rectangular matrix with less sources than targets 2015-12-09 21:17:18 +01:00
Patrick Niklaus 4253ebf243 Fix inverted error message. 2015-12-09 21:16:53 +01:00
rparanjpe 5b782a783a Use a std::vector in place of stxxl:vector for the names list
-For large datasets with very many unique names, stxxl::vector can corrupt
 data. Technically, we should only be using stxxl:vectors with POD. Other
 types might lead to strange/unpredictable behavior as we noticed here.
-See http://algo2.iti.kit.edu/dementiev/stxxl/trunk/FAQ.html
2015-12-08 23:31:58 -08:00
Patrick Niklaus c38183423f Move assertion to caller to save parameter 2015-12-05 01:27:01 +01:00
Patrick Niklaus 019e26dd8e Refactor direct_shortest_path and shortest_path 2015-12-04 23:34:24 +01:00
Patrick Niklaus 6d2a65b4ea Add additional uturn test 2015-12-04 20:52:21 +01:00
Patrick Niklaus 4206d98b55 Move leg search to routing base 2015-12-04 20:52:21 +01:00
Daniel Patterson 9005fe2f61 Merge pull request #1793 from Project-OSRM/fix/64bit_osm_ids
Add support for 64bit OSM node identifiers
2015-11-30 13:04:48 -08:00
Daniel Patterson f87f18a291 Add support for 64bit OSM node id values. 2015-11-30 12:37:58 -08:00
Patrick Niklaus c0fdcb381a Fix MVS compilation. 2015-11-25 00:27:37 +01:00
Patrick Niklaus aeaf0e7ba8 Fix unit test compilation 2015-11-25 00:27:20 +01:00
Patrick Niklaus 6dada4e347 Fix impossible route status message 2015-11-25 00:27:20 +01:00
Patrick Niklaus 61f015eef6 Fix match plugin status codes 2015-11-25 00:27:20 +01:00
Patrick Niklaus d843521839 Preserve information about big components
This uses a bit flag to differenciate between small and big components
and keeps the ids for both. This makes it possible to give better
error messages.
2015-11-25 00:27:20 +01:00
Patrick Niklaus 420369fe13 Fix off-by-one in via_indices 2015-11-24 21:05:18 +01:00
Daniel J. Hofmann 71bf1edc5e Run Modernizer 2015-11-21 22:17:55 +01:00
Patrick Niklaus d06ac519ab Only build using calng 3.8, gcc 4.8 & 5.0 2015-11-20 19:52:22 +01:00
Patrick Niklaus 50512b52e1 Remove -m parameter from routed as it conflicts. Use the long names instead. 2015-11-20 18:50:14 +01:00
Patrick Niklaus 543e77b9be Add pre-turn bearing as last field to instruction 2015-11-20 16:06:33 +01:00
Patrick Niklaus 783d455bd7 Add support for advisory speed limits
This adds support for the maxspeed:advisory class of speed tags.
2015-11-19 21:25:12 +01:00
Patrick Niklaus 6c35272fe2 Remove obsolte code as we use a turn function now 2015-11-19 21:25:12 +01:00
Daniel Patterson 6955978a62 Remove commented out line in windows build script. History is what git is for. 2015-11-19 15:02:42 -05:00
Daniel Patterson 27d87dff79 Remove some accidentally merged changes. 2015-11-19 15:00:29 -05:00
Daniel Patterson d8ca58a04e Merge pull request #1785 from Project-OSRM/feature/weight_debugging
Adds ability to dump GeoJSON with detailed edge weight info.
2015-11-19 12:01:08 -05:00
Patrick Niklaus ce34798685 Merge pull request #1782 from Mapotempo/pkgconfig
Fix pkgconfig cmake template
2015-11-19 11:42:34 -05:00
Fabien Girard 16fd5249dd Fix pkgconfig cmake template 2015-11-19 17:38:04 +01:00
Daniel Patterson b9a4c322a7 Add ability to debug routing graph visually by dumping
annotated GeoJSON during processing.
2015-11-19 10:41:44 -05:00
Daniel Patterson 673bf356e4 Merge pull request #1764 from Project-OSRM/edge_segment_lookup
Enable per-segment speed updates just before contraction.
2015-11-18 16:15:04 -05:00
Daniel Patterson 6228412e61 Enable just-before-contraction updates to edge weights. For small
datasets, this enables things like traffic-based updates in the
shortest possible processing turnaround time.
2015-11-18 16:14:08 -05:00
Daniel Patterson 578d947e2d Comment out failing bearing test - wontfix this problem for now 2015-11-18 14:08:12 -05:00
Daniel Patterson 72629d0081 Fix test cases for level cache command-line option. 2015-11-18 11:48:28 -05:00
Daniel Patterson d7989f19cf Fix bug in bearing filter related to reverse edges. Fix tests to catch it. Still one outstanding test failure that looks like a problem in the viaroute results. 2015-11-18 10:57:20 -05:00
Daniel Patterson 8b11cdbf61 Merge pull request #1780 from Project-OSRM/build_shared_libs
Enable building of shared libraries on Travis.
2015-11-18 09:56:59 -05:00
Daniel Patterson 5c1f76e3cf Build shared libraries on a selection of platforms. 2015-11-18 09:54:33 -05:00
Patrick Niklaus 63ba6018f3 Cache the node priorities between runs
This speeds up processings on the same dataset significantly by creating
a .level file that saves the level in which a node was contracted.
It removes the need for expensive recomputation of priorities and such.

Use with care! Running `osrm-extract` again will invalidate .level
files.
2015-11-18 00:56:33 +01:00
Daniel Patterson 8f3482561b Rename great_circle_distance->haversine_distance, and euclidean_distance->great_circle_distance, because that's what they actually are. 2015-11-17 17:10:06 -05:00
Daniel Patterson 13ceeb191c Merge pull request #1766 from Project-OSRM/feature/bearing_selection
Add bearing support to all plugins, add optional range to bearing parameter.
2015-11-17 16:41:34 -05:00
Daniel Patterson 1536d1c044 Add bearing filter support to viaroute, trip, nearest, and distance
table plugins.
Make bearing range configurable by adding a comma-separated second part
to the bearing paramenter, like so:

    b=<bearing:0-359>(,<range:0-180>)

If no range is supplied, it defaults to +/- 10 degrees.
2015-11-17 16:35:20 -05:00
Daniel Patterson 16b6c26d6e Merge pull request #1774 from Project-OSRM/feature/match_summary
Add a route summary to each match result.
2015-11-17 15:32:00 -05:00
Daniel Patterson c7e30e2266 Add a summary to each match result showing distance and duration.
Helpful for comparing how long the routing engine thinks the matched
trace should take to travel.
2015-11-17 15:28:21 -05:00
Daniel Patterson d5e4495f89 Merge pull request #1723 from Project-OSRM/i_like_travis
New Travis CI integration - upgrades Linux builds to Ubuntu trusty, simplifies dependency installation because system packages are now available for most things.
2015-11-17 15:26:29 -05:00
Daniel J. Hofmann 963960a44c Switch Travis builds over to trusty for Linux (simpler dependency installs), build
with mutliple compilers, fix debug builds.

OSX builds are disabled until we fix #1778
2015-11-17 15:15:31 -05:00
Daniel Patterson a62c10321c Update variant to 91ba0301a672ea0a3131390d44d304c5493de84a, specifically this commit: https://github.com/mapbox/variant/commit/39a631394e185f527159164c8b0fffae755b8512, which fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68073 under GCC 5.2.1.
Fixes  #1758
2015-11-03 21:56:26 -08:00
Patrick Niklaus bb49e03435 Merge pull request #1743 from c0nk/wip-build
Don't generate files in source tree
2015-10-22 16:32:28 -04:00
Kal Conley 38e7b1a262 Remove non-existent git_sha.cpp from .gitignore 2015-10-19 21:33:10 +02:00
Kal Conley a00d3dfc00 Don't generate util/version.hpp in source tree 2015-10-19 21:33:10 +02:00
Kal Conley cd458e7a44 Don't generate util/fingerprint_impl.hpp in source tree 2015-10-19 21:33:10 +02:00
Patrick Niklaus 3f82570469 Merge pull request #1740 from c0nk/develop
Fix various bugs
2015-10-19 20:31:23 +02:00
Kal Conley a8642bd208 Fix segmentation fault when "hsgrdata" unset 2015-10-19 20:13:02 +02:00
Kal Conley b404c79ca4 Fix json renderer always rendering arrays empty 2015-10-19 20:13:02 +02:00
Kal Conley 29c75337f2 Fix segmentation fault when sizeof(size_t) < sizeof(int64_t) 2015-10-19 20:13:02 +02:00
Patrick Niklaus fca4aeb50b Merge pull request #1741 from Project-OSRM/oom_messages
Catch `std::bad_alloc` at the top and translate to human readable messages
2015-10-19 19:29:53 +02:00
Daniel J. Hofmann 1dfa2d6e91 Catch bad_alloc and provide human reasable error messages 2015-10-19 18:18:11 +02:00
Daniel J. Hofmann 79650ca3fd Flatten main executable entry points by using functional try blocks 2015-10-19 18:18:11 +02:00
Patrick Niklaus fd84827e51 Don't use stalling in core search 2015-10-19 17:11:03 +02:00
Daniel J. Hofmann 78283a0e0e Check if memory locking should be done before locking unconditionally 2015-10-19 16:23:18 +02:00
Daniel J. Hofmann 993321e971 Lock by default, set fail on error 2015-10-19 16:23:18 +02:00
Daniel J. Hofmann f7a1e2f652 Flatten routed by using functional try-catch blocks 2015-10-19 16:23:18 +02:00
Daniel J. Hofmann e75be68466 Only lock the virtual address space when shared memory was requested
In addition, some improvements:

- unlock only when locking succeeded
- scoped exception safe RAII locker

Reference:

- https://github.com/Project-OSRM/osrm-backend/issues/1698#issuecomment-144003177
2015-10-19 16:23:18 +02:00
Daniel J. Hofmann 74ac283c52 We are on v4.8.1. 2015-10-09 16:53:17 +02:00
Patrick Niklaus 9ef1f8cba3 Fix fore core factors < 0.3 2015-10-08 20:58:21 +02:00
Daniel Patterson e45656e5bf Refactor edge expansion into extract phase. New temporary file is generated - '.osrm.ebg' which is used by 2015-10-06 09:23:17 -07:00
Patrick Niklaus cdc4fb45f2 Merge pull request #1720 from jordanmarkov/fix/invalid_nodes_left_in_data
Fixed a bug when extracting data from a file with cut streets (with m…
2015-10-06 11:44:51 +02:00
Daniel J. Hofmann 5379a555db Use ccache by default if available and a suitable compiler is used.
This checks if `ccache` is available, and if so uses it.
The user can stil disable it via the ccache env variable, quoting:

    disable (CCACHE_DISABLE) [boolean]
        When true, ccache will just call the real compiler, bypassing the cache completely. The default is false.

At least Clang required `CCACHE_CPP2`.

The user does not have to set up anything, just to install ccache.
Of course, things like the cache's max size, its location and so on can
be configured.

References:

- https://ccache.samba.org/manual.html
2015-10-06 11:18:43 +02:00
Daniel Patterson d07c0bde80 Adds support for a new b= parameter on the viaroute and match
plugins, allowing for better nearest neighbor matching when a heading
is known.
2015-10-06 11:15:10 +02:00
Patrick Niklaus 7015ed203a Don't count ferries as public transportation 2015-10-06 11:13:39 +02:00
Johan Uhle 1ead4cbb14 osrm-components: remove unused param
We don't use restrictions anymore
2015-10-06 11:12:56 +02:00
Jordan Markov 84ebca0dd2 Fixed a bug when extracting data from a file with cut streets (with missing nodes). 2015-10-06 09:42:52 +03:00
Daniel Patterson cf45b2cddb Properly initialize UUID used in Fingerprint class. Fixes #1721 2015-10-03 09:18:10 -07:00
Daniel J. Hofmann 8f8bd05f83 Silence warnings with GCC, LTO does not yet respect the -isystem switch 2015-09-30 18:22:26 +02:00
Daniel J. Hofmann b1155a202c Re-enable manual -fPIC flag from cae59c7. 2015-09-30 18:22:26 +02:00
Daniel J. Hofmann d4aaaf16f8 Revert "Re-enable position independent code, but in a portable way."
This reverts commit 2143dc97fa65c786c6566db1343ad270347dcfd3.
2015-09-30 18:22:26 +02:00
Daniel J. Hofmann 119fb63576 LTO is broken on GCC < 4.9.0, disable it.
References:

- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57038
- https://github.com/Project-OSRM/node-osrm/pull/112
2015-09-30 18:22:26 +02:00
Daniel J. Hofmann 3f7afd47d2 Do not violate the One Definition Rule (ODR).
By linking in the coordinate object file twice, we violate the ODR,
resulting in our program to not be "well-formed" in language lawyer
speak (hint: bad, very bad).

(How come no one noticed this all the time, this was introduced
somewhere between v4.5.0 and v4.6.0 from a quick look...)

References:

- C++14 standard (N3936.pfd): 3.2 One definition rule [basic.def.odr]
- http://eel.is/c++draft/basic.def.odr
2015-09-30 18:22:26 +02:00
Daniel J. Hofmann ca0f8ed653 Immensly increase lua/luabind detection and check in buildsystem.
Instead of including the `luabind.hpp` header that transitively includes
basically everything else, we now only include the appropriate header
for luabind's open function.

It is important that this function is declared in the header but the
definition comes from the luabind shared object (library), such that we
can detect linker errors, too.

By only including this header, we also no longer transitively include
the header for the `luaL_newstate` function, with we have to add
manually.

With these changes, detecting, compiling, linking and checking for
lua/luabind with cmake now works instantly, instead of the 3-4
seconds as it was before! Yay, progress!
2015-09-30 18:22:26 +02:00
Daniel J. Hofmann 809bdb7c1f Fixes version generation, no longer derives version on git tags.
We were stuck on the 4.5.0 tag from develop, since we searched for the
latest tag, but release tags are done on the master branch.

This commit rips out all the code for deriving the version on git tags.

Instead, we define major, minor, and patch versions in the CMakeLists
and then pass it on to:

- the `libosrm.pc` `pkg-config` file

- a `version.hpp` header that makes use of the preprocessor's string
  concatenation to provide an easy way for generating version string
  literals such as "v4.8.0".

That is, in the source code please now use the following defines:

    #define OSRM_VERSION_MAJOR "@OSRM_VERSION_MAJOR@"
    #define OSRM_VERSION_MINOR "@OSRM_VERSION_MINOR@"
    #define OSRM_VERSION_PATCH "@OSRM_VERSION_PATCH@"

    #define OSRM_VERSION "v" OSRM_VERSION_MAJOR "." OSRM_VERSION_MINOR "." OSRM_VERSION_PATCH
2015-09-30 18:22:25 +02:00
Daniel J. Hofmann 0424ff0818 Do not pass linker flags for static libraries.
Static libraries get the linker flags from the user / pkg-config.
2015-09-30 18:20:00 +02:00
Daniel J. Hofmann 9b952ff48c Improve debug build performance while keeping symbols.
- remove profiling/coverage mix from debug build, as it is useless as of
  now, re-enable this for a separate coverage build in the future

- use gcc's `-ggdb` and `-Og` flag (requires recent gcc) to provide
  better debug information targeted for gdb and optimize what we can

- use `-fno-inline` and `-fno-omit-stack-pointer`, in order to be able
  to jump around in gdb without functions being gone and keeping the
  stack reference
2015-09-30 18:20:00 +02:00
Daniel J. Hofmann c5064710a8 Re-enable position independent code, but in a portable way.
CMake 2.8.9 introduce a `POSITION_INDEPENDENT_CODE` property.

This sets `-fPIE` on executables, giving us back optimizations such as
inlining of global variables and functions, while setting `-fPIC` on
libraries.

Although we do not need position independent code on executables, it
seems like some gcc versions (like 4.9.2) have issues in combinations
with `_FORTIFY_SOURCE`.

On shared libraries, CMake should per documentation even use position
independent code by default.

References:

- http://www.cmake.org/cmake/help/v3.0/prop_tgt/POSITION_INDEPENDENT_CODE.html#prop_tgt:POSITION_INDEPENDENT_CODE
- http://public.kitware.com/pipermail/cmake-developers/2012-May/015839.html
- https://github.com/Project-OSRM/osrm-backend/pull/1647
- https://github.com/Project-OSRM/osrm-backend/commit/cae59c73953b02f18025a1ef1bbf2ca4ee8f239a
2015-09-30 18:20:00 +02:00
Daniel J. Hofmann 57e522065a Add linker optimizations and dead code and data elimination.
Linkers also have options we can configure! The most usefull feature is
to give every function its own section. This results in some bloat at
compile time, but at link time now the linker can do dead code and data
elimination by simply discarding appropriate sections.

This works by splitting the `.text` section in a way that makes it
possible to later only pull in sections that are actually referenced.

That is, the basic idea is to keep the matching between sections and
functions intact, so we can optimize based on it in the linking stage.

Note: there's still an issue with how `libOSRM.a` gets build. CMake
currently passes the linker flags on to ar, in order to create a static
library. But ar does not understand the linker's flags.

Referenes:

- https://sourceware.org/binutils/docs/ld/Options.html#Options
- http://elinux.org/images/2/2d/ELC2010-gc-sections_Denys_Vlasenko.pdfMCþ"
- http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_EXE_LINKER_FLAGS.html
- http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_MODULE_LINKER_FLAGS.html
- http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_SHARED_LINKER_FLAGS.html
- http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_STATIC_LINKER_FLAGS.html
2015-09-30 18:20:00 +02:00
Daniel J. Hofmann 7143daf500 There is no CMAKE_LINKER_FLAGS variable.
There really isn't; deal with it.

Also, those are not linker flags but instead meant for the compiler.

References:

- http://www.cmake.org/cmake/help/v3.0/manual/cmake-variables.7.html
2015-09-30 18:20:00 +02:00
Daniel J. Hofmann 71a00fc01b Make lto detection more robust and not resetting cxx flags when lto fails.
This refines the last commit of parallelizing lto.

Discussion: this is ugly as hell, dispatching 1/ on the availability of
the `-flto` flag, then 2/ on the compiler since GCC allows `-flto=n`
whereas Clang for example does not.

I tried setting the CMake property `INTERPROCEDURAL_OPTIMIZATION`,
without any effect. All I could see was some lto related utilities in
the cmake debug output, but not in the actual compiler or linker
invocation.

This would eliminate the need for our hacks, with 1/ using an option
`WITH_LTO` setting `ON` by default, and based on this value setting the
`INTERPROCEDURAL_OPTIMIZATION` flag with CMake doing the actual work of
selecting the best LTO method on the target platform.

By the way, this also fixes a bug where we reset the `CMAKE_CXX_FLAGS`
to a variable that was never defined, resulting in setting the flags to
an empty string. Yay CMake, as usual.

References:

- http://www.cmake.org/cmake/help/v3.0/prop_tgt/INTERPROCEDURAL_OPTIMIZATION.html
2015-09-30 18:20:00 +02:00
Daniel J. Hofmann 941483c14d Parallelize optimization and code generation for link time optimization.
This parallelizes the `-flto` feature resulting in parallel optimization
and code generation for link time optimization based on the number of
logical processors available.

Note: this has the side-effect of using more memory during linking.

References:

- https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html (see: -flto)
- http://www.cmake.org/cmake/help/v3.0/module/ProcessorCount.htmMC
2015-09-30 18:20:00 +02:00
Daniel J. Hofmann 17d8e65c64 Silence unused variable warnings 2015-09-30 18:20:00 +02:00
Daniel J. Hofmann 72c0feb048 Silence warnings for system headers that we or third_party transitively includes.
GCC with link time optimizations does not to respect this mode
unfortunately, reuslting in warnings in release (default) build
mode from system includes such as boost, luabind and so on.
2015-09-30 18:18:36 +02:00
Daniel J. Hofmann 9e20dbe226 Remove -fPIC flag from build system.
This remove the `-fPIC` flag, indicating position independant code
generation, from the build system.

Citing GCC's official code generation docs:

> This option makes a difference on the m68k, PowerPC and SPARC.

We do not support any of these architectures, so remove the flag!

References:

- https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options
2015-09-30 18:18:36 +02:00
Daniel J. Hofmann 06f2738c03 Add stricter compiler warnings to build system.
These are for standard compliance and should on by default:

    -Wall -Wextra -pedantic

The problem is that even `-Wall` and `-Wextra` does not cover all
warnings, as to not break backward compatibility. Clang therefore
has the `-Weverything` flag, that really includes everything but is
overkill for the day to day development.

Thus, we in addition add:

    -Wuninitialized -Wunreachable-code

to guard against undefined behavior from reading uninitialized variables
and warn for unreachable code.

With:

    -Wstrict-overflow=1

the compiler warns us when it's doing optimizations based on the fact
that signed integer overflows are undefined behavior.

With:

    -D_FORTIFY_SOURCE=2

we tell the compiler to replace functions like strcpy with strncpy where
it can do so, resulting in cheap and useful buffer overflow protection.

References:

- https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
- https://securityblog.redhat.com/2014/03/26/fortify-and-you/
- https://wiki.debian.org/Hardening
2015-09-30 18:18:36 +02:00
Daniel J. Hofmann 5a257416ca Completely rip out Boost's Spirit / Karma for casting.
This rips out the Bost Spirit / Karma conversion code, using the stdlib
and lightweight alternatives instead.

The main benefit is an immense decrease in compilation times, for every
translation unit that requires the `util/cast.hpp` header.

Note: compared to the version before, there is a minor change in
behavior: the double `-0` was printed as `0` before and is now printed
as `-0`. This comes from the IEE754 standard, specifying signed zeros,
that is `+0` and `-0`. Interesting for us: JavaScript uses IEE754,
resulting in no breakage if used in arithmetic.

Small test case, left hand side was before, right hand side is now:

    $ ./a.out
    -1.123457 vs -1.123457
    -1 vs -1
    -1.3 vs -1.3
    0 vs -0
    0 vs 0
    0 vs 0
    1.3 vs 1.3
    1.123457 vs 1.123457

References:

- https://en.wikipedia.org/wiki/Signed_zero
- http://www.boost.org/doc/libs/1_59_0/doc/html/boost/algorithm/trim_right_if.html
- http://www.boost.org/doc/libs/1_59_0/doc/html/boost/algorithm/is_any_of.html
2015-09-29 16:15:54 +02:00
Daniel J. Hofmann f9f0ffb64d Remove hand written conversion code and replace with stdlib features.
With C++11 the stdlib gains:

- `std::stoi` function family to convert from `std::string` to integral type

- `std::to_string` to convert from number types to `std::string`

The only reason for hand-writing the conversion code therefore is
performance. I benchmarked an `osrm-extract` with the hand-written code
against one with the stdlib conversion features and could not find any
significant difference (we switch back and forth between C++ and Lua,
shaving off a few us in conversion doesn't gain us much).

Formatting arithmetic types in the default format with given precision
requires streams, but is doable in a few lines of idiomatic stdlib code.

For this, there is now the following function template available:

    template <Arithmetic T, int Precision = 6>
    inline std::string to_string_with_precision(const T);

that requires integral or floating point types and returns a formatted
string in the defaukt format with the given precision applied.

In addition this completely rips out Boost.Spirit from the `casts.hpp`
header, resulting in faster compile times.

Boom!

References:

- http://en.cppreference.com/w/cpp/string/basic_string/stol
- http://en.cppreference.com/w/cpp/string/basic_string/to_string
- http://www.kumobius.com/2013/08/c-string-to-int/
2015-09-29 16:15:54 +02:00
Daniel J. Hofmann 31cf8a8813 Remove Boost.Filesystem v3 fix for Boost < 1.48, refactor call sites.
We needed this for Boost < 1.48, but per our Wiki on building OSRM:

> On Ubuntu 12.04 you will be limited to OSRM tag v0.3.10 because
> later versions **require Boost v1.49+** and installing this
> causes problems with libluabind-dev package.

Thus, rip it out!

To keep the commits atomic and isolated, I also refactored all call
sites that used the functionality from the portability fix.

While doing this, I also simplified the monster of around ~100 lines of
file path checking --- lambda's are awesome' use them!

References:

- http://stackoverflow.com/a/1750710
- https://github.com/Project-OSRM/osrm-backend/wiki/Building-on-Ubuntu
2015-09-29 16:15:54 +02:00
Daniel J. Hofmann 98b7e0a407 Refactor bearing implementation.
- removes `noexcept` specifier as we can not guarantee for not throwing

- uses a namespace instead of a struct + static function combination

- asserts for heading degree in [0, 360] range (both sides inclusive!)

- header only since implementation does not hide anything

- adds `inline` specifier as compiler hint
2015-09-29 16:15:54 +02:00
Daniel J. Hofmann 7ed63d2ab5 Remove TBB usage from hot code paths 2015-09-28 20:37:09 +02:00
Daniel J. Hofmann 6e6b38e8e9 Revert the usage of TBB's iterator pair taking overloads.
This reverts the range based overload usage introduced in @6b2bf495.

Old TBB versions do not provide the range overloads.
2015-09-28 20:37:09 +02:00
Daniel J. Hofmann 829b9d96e4 Revert parallelization on algorithms that are used in the server. Let node do this.
This reverts @6b2bf49 on the server algorithms.
2015-09-28 20:26:29 +02:00
Daniel J. Hofmann 85cef7e37c Revert parallelization on util that is used in the server. Let node do this.
This reverts @6b2bf49 on the server component utils.
2015-09-28 20:26:29 +02:00
Daniel J. Hofmann c526bec798 Revert parallelization on server part. Let node do this.
This reverts @6b2bf49 on the server components.

We do not want to parallelize there, as node should be used for
parallelizing the user requests onto multiple processes.
2015-09-28 20:26:03 +02:00
Daniel J. Hofmann 9231335eef Use Intel TBB's parallel_sort even for nested parallelism.
TBB has a global task scheduler (that's one of the reason TBB is not
linked statically but dyanmically instead). This allows control over all
running threads, enabling us to use nested parallelism and the scheduler
doing all the task allocation itself.

That is, nested parallel execution such as in

    parallel_for(seq, [](const auto& rng){
      parallel_sort(rng);
    });

is no problem at all, as the scheduler still claims control over the
global environment.

Therefore, use `parallel_sort` Range overload where possible.

References:

- https://www.threadingbuildingblocks.org/docs/help/hh_goto.htm#reference/algorithms.htm
- https://www.threadingbuildingblocks.org/docs/help/hh_goto.htm#reference/algorithms/parallel_sort_func.htm
- https://www.threadingbuildingblocks.org/docs/help/hh_goto.htm#reference/task_scheduler.htm
- https://www.threadingbuildingblocks.org/docs/help/hh_goto.htm#reference/task_scheduler/task_scheduler_init_cls.htm
- https://www.threadingbuildingblocks.org/docs/help/hh_goto.htm#tbb_userguide/Initializing_and_Terminating_the_Library.htm
2015-09-28 20:26:03 +02:00
Daniel J. Hofmann dfac34beac Do not use an incomplete type with value semantics 2015-09-28 16:50:36 +02:00
Daniel J. Hofmann 82dd5d8ccf Use Boost.Optional instead of custom optional monad implementation.
This switches out the `<variant/optional.hpp>` implementation of the
optional monad to the one from Boost.

The following trick makes sure we keep compile times down:

- use `<boost/optional/optional_fwd.hpp>` to forward declare the
  optional type in header, then include the full blown optional header
  only in the implementation file.

- do the same for the files we touch, e.g. forward declare osmium types,
  allowing us to remove the osmium header dependency from our headers:

      `namespace osmium { class Relation; }

  and then include the appropriate osmium headers in the implementation
  file only. We should do this globally...

References:

- http://www.boost.org/doc/libs/1_59_0/libs/optional/doc/html/index.html
- https://github.com/osmcode/libosmium/issues/123
2015-09-28 15:00:21 +02:00
Daniel J. Hofmann be506f7121 Change integer_range's .size() member function return type to size_t.
Instead of the return type being the templated `Integer` parameter.

The integer type and the size of the range are not connected.
2015-09-28 15:00:21 +02:00
Daniel J. Hofmann 2470494009 Implement saity checks for irange and its returned type iterator_range.
The implementation does not support backwards counting ranges, but fails
to assert on this condition. Fix this once and for all.
2015-09-28 15:00:21 +02:00
Daniel J. Hofmann f95a4b9b46 Remove iterator_range dead code 2015-09-28 15:00:21 +02:00
Daniel J. Hofmann 6b444a0877 Do not include Boost.Thread is a sub-header is good enough.
`boost::thread_specific_ptr` lives in `<boost/thread/tss.hpp>`.

In addition, fix the includes in the touched header.

Reference:

- http://www.boost.org/doc/libs/1_59_0/doc/html/thread/thread_local_storage.html
2015-09-28 15:00:20 +02:00
Daniel J. Hofmann 5c4a845b55 Remove template-heavy Boost.MPL headers where not needed.
This removed mpl headers from the code base, where not needed.

This mostly affects unit tests, where mpl's type list is actually only
used once to automatically generate tests for multiple types (see ref).

In addition, this commit also fixes the includes in the touched headers.

Resulting in 1/ reduces build times and 2/ proper includes.

Reference:

- http://www.boost.org/doc/libs/1_59_0/libs/test/doc/html/boost_test/tests_organization/test_cases/test_organization_templates.html#ref_BOOST_AUTO_TEST_CASE_TEMPLATE
2015-09-28 15:00:20 +02:00
Daniel J. Hofmann 468c01056f Replace custom replace utility with the stdlib's replace algorithm.
This removes the custom `replaceAll` function, replacing it with
`std::replace` from the stdlib's `<algorithm>` header.

This also removes the respective unit test.

More importantly, this removes the dependency on the
`<boost/algorithm/string.hpp>` header in the `string_util.hpp` header.
2015-09-28 15:00:20 +02:00
Daniel J. Hofmann 397078758e Remove boost/thread from rtree, include header for hash_combine in unit test.
The `static_rtree.hpp` header included `<booost/thread.hpp>` without using
anything from this header.

Removing it showed why:

the unit test for the rtree no longer built, since it was missing symbols
for Boost's `hash_combine`, used in the unit test.

Instead of relying on `<boost/thread.hpp>` including the proper header
for `hash_combine` by chance that we only use in the unit test, do the
following:

- remove `<boost/thread.hpp>` from the rtree implementation
- add `<boost/functional/hash.hpp>` to the rtree unit test

As always, include what you use.
2015-09-28 15:00:20 +02:00
Daniel J. Hofmann c9af06c9e0 Remove hand-written ConcurrentQueue class template.
We already rely on Intel TBB, which provides battle-tested
concurrency containers, such as:

- `concurrent_queue`,
- `concurrent_bounded_queue`,
- `concurrent_priority_queue`.

The `ConcurrentQueue` class template was never used. If the need
comes up again, we should strongly prefer those instead of writing
one ourselves.

References:

- https://www.threadingbuildingblocks.org/docs/help/reference/containers_overview/concurrent_queue_cls.htm
- https://www.threadingbuildingblocks.org/docs/help/reference/containers_overview/concurrent_bounded_queue_cls.htm
- https://www.threadingbuildingblocks.org/docs/help/reference/containers_overview/concurrent_priority_queue_cls.htm
2015-09-28 15:00:20 +02:00
Patrick Niklaus 5a7e663b1d Merge pull request #1707 from arnekaiser/develop
Bugfix: allow POST request without POST data
2015-09-27 17:57:31 +02:00
akaiser e0550cd20b Bugfix: allow POST request without POST data 2015-09-24 14:40:35 +02:00
Daniel Patterson 5844231a37 Include (road) name of matched nodes in addition to coordinate. 2015-09-23 17:53:34 +02:00
Lauren Budorick 8d435638e1 Delete accidental/extraneous files 2015-09-23 10:33:27 -04:00
Freenerd 55cad1b3ac Refactor alternative route test 2015-09-23 15:54:23 +02:00
Daniel J. Hofmann 9deadc1371 Static analysis: integration with the Static Analyzer.
This provides a wrapper script to invoke the Static Analyzer on the code
base. The script simply wraps your commands, that is you have to do the
following:

    ..scripts/analyze cmake ..
    ..scripts/analyze cmake --build .

Note: the Static Analyzer is integrated in Xcode, so if you are on a
Mac, consider using Xcode natively instead of this wrapper script that
will only give you HTML output.

Reference:

- http://clang-analyzer.llvm.org/
2015-09-22 17:32:32 +02:00
Daniel J. Hofmann 998abf05ba Integration scripts for Clang's Modernize and Tidy tool.
New directory: `scripts/`, in which small scripts for developers reside.

- `modernize`: runs all cpp files through `clang-modernize`, respecting
  out targeted compiler versions, applying C++11 transformations, doing
  syntax checks and formatting --- in parallel.

- `tidy`: runs all cpp files through `clang-tidy`, with selected
  warnings only, since we do not want to warn on every small detail.

Please check the talk slides for `clang-tidy` linked in the references!

References:

- http://clang.llvm.org/extra/clang-tidy/
- http://llvm.org/devmtg/2014-04/PDFs/Talks/clang-tidy%20LLVM%20Euro%202014.pdf
- http://clang.llvm.org/extra/clang-tidy/checks/list.html
- https://github.com/Project-OSRM/osrm-backend/pull/1603
2015-09-22 17:32:32 +02:00
Daniel J. Hofmann aab5092da3 Use Readme.md as mainpage untill we have something better. 2015-09-22 16:26:21 +02:00
Daniel J. Hofmann 65ee5c4bbb Exclude unit tests and benchmarks from doxygen and make it more robust.
Only specify the flags we change from the default.

    doxygen -g Doxyfile

Generates a default Doxyfile.

Also, make the docs not depend on `dot`, but conditionally create graphs
if `dot` is available, and if not still generate docs.
2015-09-22 16:26:21 +02:00
Daniel J. Hofmann 42ab938a19 No longer generate XML from Doxygen, was used for Breathe+Sphinx integration. 2015-09-22 16:26:21 +02:00
Daniel J. Hofmann 2891de2fcd Add dependency on Dot to CMakeLists for Doxygen integration.
Reference:

- http://www.cmake.org/cmake/help/v3.0/module/FindDoxygen.html
2015-09-22 16:26:21 +02:00
Daniel J. Hofmann ed3758874d Target developers with doxygen output, more callgraphs, internals.
See the changed flags for their detailed description, in short: this
makes the doxygen output even more awesome for developers.
2015-09-22 16:26:21 +02:00
Daniel Patterson 895d8179a2 Adds basic Doxygen support. Run and docs will end up in 2015-09-22 16:26:21 +02:00
Patrick Niklaus 8f6fc0146b Merge branch 'develop' 2015-09-20 13:30:19 +02:00
Freenerd e1ac1c4fdc Test that alternative route exists
Complement to a6b44a1470
2015-09-18 17:30:53 +02:00
Daniel Patterson a6b44a1470 Revert alternative instructions array nesting to previous behaviour. 2015-09-17 09:06:51 -07:00
Daniel J. Hofmann e8834a68f3 Script for fully automated test bisecting.
Automate cucumber tests bisecting by providing a `git bisect` script.

Because it is stored in source control, but bisecting changes the HEAD,
it is advised to first copy over the script to a place outside source
control, e.g. `/tmp`.

Usage:

    git bisect start HEAD HEAD~10
    bit bisect run /tmp/bisect_cucumber.sh

This automatically configures and builds OSRM, spawns the cucumber tests
and communicates with `git bisect` based on its return code.

Reference:

- man git-bisect
2015-09-16 19:13:31 +02:00
Patrick Niklaus 6ad1cd3fb5 Merge branch 'develop' 2015-09-16 18:18:54 +02:00
Daniel J. Hofmann 3279cbac24 Extend compressed output lifetime till the async write function finishes.
This extends the compressed output vector's lifetime, as we issue an
asynchronous write operation that only receives a non-owning buffer to
the compressed data.

When the compressed output vector then goes out of scope, its destructor
is called and the data gets (potentially) destroyed. If the asynchronous
write happens afterwards, it's accessing data that is no longer there.

This is the reason for race conditions --- well, for undefined behavior
in general, but it manifests in the routed _sometimes_ not responding at
all.

The fix works like this: keep the compressed output associated with a
connection. Connections inherit from `std::enable_shared_from_this` and
issues a `shared_from_this()` call, passing a `std::shared_ptr` to the
asynchronous write function, thus extending their lifetime.

Connecitons thus manage their lifetime by themselves, extending it when
needed (and of course via the `std::shared_pointers` pointing to it).

Buffer's non owning property, from the `async_write` documentation:

> One or more buffers containing the data to be written. Although
> the buffers object may be copied as necessary, ownership of the
> underlying memory blocks is retained by the caller, which must
> guarantee that they remain valid until the handler is called.

Reference:

- http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/reference/async_write/overload1.html
2015-09-16 02:06:58 +02:00
bergwerkgis 5094bad838 kick off AppVeyor to test new binary Windows deps package, refs #1628 2015-09-15 12:23:25 +00:00
Daniel J. Hofmann 94af9b7f13 Caches iterators instead of invoking function calls on every iteration.
This caches iterators, i.e. especially the end iterator when possible.

The problem:

    for (auto it = begin(seq); it != end(seq); ++it)

this has to call `end(seq)` on every iteration, since the compiler is
not able to reason about the call's site effects (to bad, huh).

Instead do it like this:

    for (auto it = begin(seq), end = end(seq); it != end; ++it)

caching the end iterator.

Of course, still better would be:

    for (auto&& each : seq)

if all you want is value semantics.

Why `auto&&` you may ask? Because it binds to everything and never copies!

Skim the referenced proposal (that was rejected, but nevertheless) for a
detailed explanation on range-based for loops and why `auto&&` is great.

Reference:

- http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3853.htm
2015-09-15 12:09:39 +02:00
Patrick Niklaus 8e02263084 Fix off-by one error in decoder and make padding deterministic. 2015-09-14 23:01:38 +02:00
Patrick Niklaus fe0fe1873a Add simplification reset that was accidentally removed 2015-09-11 01:34:10 +02:00
Andreas Gruß de29574314 tests + instructions for map matching 2015-09-11 01:34:10 +02:00
Lauren Budorick 5ac024788e Parse specific restriction:* tags based on profile exceptions 2015-09-10 15:52:26 -07:00
Patrick Niklaus a1e273e983 Add switch for handling fallback name 2015-09-10 14:11:18 +02:00
Patrick Niklaus a95bf64ccf Fix processing for data files with incorrect node references 2015-09-10 12:22:03 +02:00
Daniel J. Hofmann 4fa9022932 Use iterator pair taking parallel_sort, old TBB versions have no range overload. 2015-09-10 11:04:50 +02:00
Daniel J. Hofmann f10fb77a81 Ownership: vector already owns, no need for wrapping in unique_ptr.
Removes the pointless `std::unique_ptr<std::vector<T>>` usage,
as a `std::vector` already owns its resources and manages them.

Results in one indirection less (hint: good).
2015-09-09 18:53:11 +02:00
Daniel J. Hofmann db092c828e Don't pass by const-value for a read-only view.
I can't see a reason we pass by const-value here.

Note: changes API because of the `route_parameters` header.
2015-09-08 23:34:20 +02:00
bergwerkgis bed0598530 AppVeyor: make tests pass again 2015-09-07 19:45:54 +02:00
bergwerkgis b734d4bbc1 [skip ci] AppVeyor: fail again, if tests fail 2015-09-07 14:43:24 +00:00
bergwerkgis d2080808db AppVeyor: include osrm.lib in artifact. don't stick to AppVeyor directory structure in build scripts. 2015-09-07 14:26:47 +00:00
Daniel J. Hofmann 345d5e8d9e Make an exception for block barriers in bicycle and foot profile.
This adds `barrier=block` exceptions to the respective white lists.

In addition this adds tests to check for the exception in bicycle and
foot profiles and makes sure cars are still not able to cross them.

Checked with:

    cucumber --tags @barrier -p verify

References:

- https://github.com/Project-OSRM/osrm-backend/issues/1643
- http://wiki.openstreetmap.org/wiki/Tag:barrier%3Dblock
2015-09-07 12:23:21 +02:00
Daniel J. Hofmann bcc41bf3d1 Fixes undefined behavior from shifting into signed bit; use unsigned literal instead 2015-09-06 01:11:54 +02:00
Daniel Patterson b2d444d782 Only replace fingerprint file when MD5 changes. Avoids rebuilding several things if nothing has actually changes, as cmake is only looking at timestamps. 2015-09-04 14:07:40 +02:00
Lauren Budorick bac6703f8e Implement raster source feature to read data from third-party sources, to be used in lua profiles.
* Adds a data structure, RasterSource, to store parsed + queryable data
* Adds bindings for that and relevant data structures as well as source_function and segment_function
* Adds relevant unit tests and cucumber tests
* Bring-your-own-data feature
2015-09-03 22:28:18 -07:00
Daniel J. Hofmann 6cbbd1e5a1 Move destination to access tag white list instead of making exception in car profile.
Tested with:

    cucumber --tags @access -p verify

References:

- https://github.com/Project-OSRM/osrm-backend/issues/1617
- https://github.com/Project-OSRM/osrm-backend/pull/1639
2015-09-03 17:46:20 +02:00
Daniel J. Hofmann b6ef558c86 Make pedestrian roads marked as destination routable with car profile.
Check provided tests with:

    cucumber --tags @access -p verify

References:

- https://github.com/Project-OSRM/osrm-backend/issues/1617
- http://wiki.openstreetmap.org/wiki/Tag:highway%3Dpedestrian
- http://wiki.openstreetmap.org/wiki/Key:motorcar
- http://wiki.openstreetmap.org/wiki/Key:access
2015-09-03 17:46:20 +02:00
Patrick Niklaus 70bb082973 Fix endless loop 2015-09-03 17:02:34 +02:00
Patrick Niklaus 8b8a19c75d Fix failing matching tests due to gps precision 2015-09-03 17:02:34 +02:00
Patrick Niklaus 0b53242564 Move distance calculation out of loop 2015-09-03 17:02:34 +02:00
Patrick Niklaus f11bd509b0 Also prune on MAX_DOUBLE 2015-09-03 17:02:33 +02:00
Patrick Niklaus 57608628a4 Use median sample time instead of average to harden against outliers 2015-09-03 17:02:33 +02:00
Patrick Niklaus f167c3e12e Move heap initialization out of loop 2015-09-03 17:02:33 +02:00
Patrick Niklaus 262b380280 Candidate query for match is now only depending on gps_precision 2015-09-03 17:02:33 +02:00
Patrick Niklaus ee0c20ae44 Fix typo 2015-09-03 17:02:33 +02:00
Patrick Niklaus c30c144120 Move matching default in route_parameters.cpp 2015-09-03 17:02:33 +02:00
Patrick Niklaus a5ee82b0d1 Make matching thresholds adaptable to different sample lengths 2015-09-03 17:02:33 +02:00
Patrick Niklaus a4f558181d Add status field to match plugin response 2015-09-03 17:02:33 +02:00
Daniel Patterson 120303e6e3 Fixed test case that uses the car profile. 2015-09-03 17:01:11 +02:00
Daniel Patterson b3822d5802 Enable turn penalties on car profile, using values tuned by comparing real-world sample routes with map-matched routes. 2015-09-03 17:01:11 +02:00
Daniel J. Hofmann 980e4ee89a Don't mix signed and unsigned in comparisons as signed is converted first to unsigned.
This is true:

    -1 > 1u

because the integer literal `-1` is first converted to a large unsigned
value and then compared to the unsigned `1`.

This patch fixes several of those isses in the farthest insertion
algorithm.

`-Wsign-compare` catches those issues.

References:

- http://stackoverflow.com/a/5416498
- C++14 standard
2015-09-02 16:33:03 +02:00
Daniel J. Hofmann bb1428eeb1 Remove unneeded semicola from profiles.
Nothing fancy, does what it says.
2015-09-02 12:23:26 +02:00
Huyen Chau Nguyen f6a90e9b42 add missing include and clang-format 2015-09-01 15:20:35 +02:00
Huyen Chau Nguyen a71159667d add cucumber test for the trip plugin 2015-09-01 15:20:35 +02:00
Huyen Chau Nguyen 74e00cf652 fix some small issues:
remove empty unit test

remove compiler directives

move trip related files from routing_algorithms to algorithms

run clang-format on files

fix all std::size_t related issues

improve code by adding std::move()s

clean up includes

fixing several code stye and improvement issues

add several small code improvements

return single scc in SplitUnaccessibleLocations() when theres only one

change ComputeRoute() to return an InternalRouteResult by value

improve some code style issues
2015-09-01 15:20:35 +02:00
Huyen Chau Nguyen e773a80b06 remove possibility to choose algorithm but only use brute force and farthest insertion 2015-09-01 15:20:34 +02:00
Huyen Chau Nguyen e6eea67eeb rename all names with round_trip, trip or tsp to trip to standardize the naming 2015-09-01 15:20:34 +02:00
Huyen Chau Nguyen 8429a1e792 add assertions 2015-09-01 15:20:34 +02:00
Huyen Chau Nguyen 47fbd2a2b5 fix json output such that each trip returns a json object with all information of the trip 2015-09-01 15:20:34 +02:00
Huyen Chau Nguyen 93835b9b94 change input param for tsp algos from a vector to a begin and an end iterator 2015-09-01 15:20:34 +02:00
Huyen Chau Nguyen 2de3fc9f6f fix GetAdjacendEdgeRange of matrix wrapper for tarjan scc and fix wrongly solved merge conflict 2015-09-01 15:20:34 +02:00
Huyen Chau Nguyen 78a8cf6982 add a wrapper for the distance table for better access 2015-09-01 15:20:34 +02:00
Huyen Chau Nguyen 99cf3219d4 have less redundant code for requests with one or multiple SCCs 2015-09-01 15:20:34 +02:00
Huyen Chau Nguyen 7587e97d46 use typedefs from typedefs.h
return roundtrip result as a return parameter and not as an input parameter
2015-09-01 15:20:34 +02:00
Huyen Chau Nguyen 3061c8b854 solve merge conflicts 2015-09-01 15:20:34 +02:00
Huyen Chau Nguyen 77e9e95067 fix bugs
and add todos of code review session with daniel-j-h
2015-09-01 15:20:33 +02:00
Chau Nguyen 6191b6bee2 add parameter to choose algorithm for tsp calculation and remove redundant code 2015-09-01 15:20:33 +02:00
Chau Nguyen b15f8f68e4 refactor and improve the round trip computation of multiple SCCs
Problem:
- old solution was slow
- depending on the result of TarjanSCC, new distance tables and new phantom node vectors were created to run tsp on it

Solution:
- dont create new distance tables and phantom node vectors
- pass an additional vector with the information which locations are in the same component and ignore all others

fix bug for scc split computation
2015-09-01 15:20:33 +02:00
Chau Nguyen 84c12793e8 clean up some code 2015-09-01 15:20:33 +02:00
Chau Nguyen 6eeadddd4d remove attention on unaccessible locations as we filter them beforehand 2015-09-01 15:20:33 +02:00
Chau Nguyen a40b3a98dc split algorithms in different plugins for better evaluation
split tsp brute force algorithm for better testing

refactor and clean up
2015-09-01 15:20:33 +02:00
Chau Nguyen f0d66ff0fb move implementation of algorithms to own hpp in routing_algorithms folder
add changes to improve readability
2015-09-01 15:20:33 +02:00
Chau Nguyen d3ebd360b2 add brute force algorithm for tsp for small tests 2015-09-01 15:20:33 +02:00
chaupow ebbe1692c8 add description of farthest insertion algorithm
add farthest insertion algorithm for round trip

farthest insertion: always add the node that add the biggest distance to the total route

farthest insertion: remove total distance computation and compute only diff instead
2015-09-01 15:20:33 +02:00
chaupow ca7d406787 add timer to check runtime of round trip algorithm 2015-09-01 15:20:33 +02:00
chaupow a2dc8378f5 rename result_table to dist_table 2015-09-01 15:20:33 +02:00
chaupow b570e89dbd capsule tsp round trip computation in a private method 2015-09-01 15:20:32 +02:00
chaupow 108f87678a fix bugs and add comments
rename subroute to via_point

merge is_lonely_island and is_connected to make code easier to understand
2015-09-01 15:20:32 +02:00
chaupow 00146ae87c add support for locations that are not reachable as well as information about location permutaton 2015-09-01 15:20:32 +02:00
chaupow e3757fbbfa add round trip plugin with greedy approximation 2015-09-01 15:20:32 +02:00
Daniel J. Hofmann ac64e8b15e Remove protobuf dependencies from travis config 2015-08-31 16:57:42 +02:00
Daniel J. Hofmann c39ca7189b Remove protobuf dependencies from build system 2015-08-31 16:54:22 +02:00
Daniel J. Hofmann 03c8fdd30a Remove protobuf dependencies from docker setup 2015-08-31 16:48:27 +02:00
Patrick Niklaus 048be2da2c Merge commit '788bc67faa7738cf7c6b2a192ecf3e3567d1c20e' into develop 2015-08-28 12:42:03 +02:00
Patrick Niklaus 788bc67faa Squashed 'third_party/libosmium/' changes from 8bcd4ea..c43f8db
c43f8db Release v2.3.0
44c135f Update README to show dependencies used internally.
ece54cd Add external licenses.
908cd5f Updated change log.
96dbf0e Change %-escape in OPL format.
98f6e27 Change write benchmark to interleave reading and writing.
39620ce Make writing of metadata configurable for XML and OPL output.
e5a4e5e Add debug output format.
597390f Remove superfluous include and pragmas.
ecc57b0 Update pbf reader/writer to use new protozero functions.
5d1e8d2 Update protozero from upstream.
ef8746b Fix build on Windows.
ddba46f Remove superfluous include.
098c57f Add some paranoia checks to pbf reader.
0f804c2 Try building with newer boost library on travis.
6f79d63 Use explicit return types on lambdas.
355f3b1 New PBF reader and writer based on protozero.
71d719b Add pbf writing benchmark.
f014b4c Fix iwyu.sh script: Works now if build directory doesn't exist.
a0ace49 Use utf8cpp header-only lib instead of boost for utf8 decoding.
796f18e Bugfix: Reading large XML files could block.
5a2bcbe Replace strcmp by std::string comparison in test.
bc49e2c Bugfix: XML writer was not writing whitespace correctly.
61222f8 Fix 64bit byte swap.
e56f090 Fix new CRC code on OSX and Windows.
70229aa Add low-level building blocks that allow calculating CRC of OSM data.
0968a66 Remove assert checking for unset version.
62e0261 Refactor test case.
4bfc7fc Allow instantiating osmium::geom::GEOSFactory with existing GEOS factory.
e70af0c Remove calls to protobuf cleanup function im benchmarks and examples.
718518d Bugfix in OPL output. Relation member roles were not encoded.
759d5cb Rename parameter that had the same name as a type.
7054cab Provide (Typed)MemoryMapping constructors for backwards compatibility.
d09f5d1 Fix typo.
b4e578f Make memory mapping utility class more flexible.
633fa8e Travis build without sudo.
7ff23f1 Improved code setting file format from suffix/format argument.
90ef3b9 Remove some tests that didn't test much and failed on FreeBSD.
af86273 Add some pragmas to disable warnings for GCC.
efac7fd Fix some include problems found by IWYU.
79d2f4c Changed add_user() and add_role() in builders. Add add_member().
9375d00 Add function to set tags from ptr + length. Improve TagBuilder tests.
bafca20 Test helper: Use more const and have sub-builders in their own scope.
f73c993 Simplify code.
fee1710 Disable warning only when compiling with GCC.
74402f3 Merge pull request #98 from dforsi/master
2c4b449 Update to new upstream catch.hpp version.
1318732 Release v2.2.0
1873998 Add missing test.
2e5ea1d Do not add timestamp to html doc pages.
1b2ea89 Remove debug output.
0be9599 Improved parsing of ids, versions, uids, etc. from strings.
4308d80 Add second version of split_string utility function.
f18c9e5 Move part of pbf.hpp into new pbf_type_conv.hpp.
d201152 Use new DeltaEncode class in pbf writer.
e205610 Add DeltaEncode/DeltaDecode utility classes.
32905d6 Bugfix: Actually throw the exception we are creating...
d3e86d8 Add functions to convert item_type to zero-based index.
daddf07 Bugfix: Programs writing OSM files can stall up to a second after writing.
00b0247 Add function to set the id of a relation member.
f85316a Fix error message.
19bc6cc Fix name of travis install script.
719cd33 spatialite-bin package now available on travis
cb03821 Shorten long test string (MSVC doesn't like it).
c3440a6 Add BoolVector index class.
da08073 Add min_op/max_op utility functions.
411d112 AppVeyor.yml: new links for binary deps
7d9095f add test for badly formatted timestamps
a073f73 Add helper methods to DiffObject.
3b9819a Add GeoJSON factory using the RapidJSON library.
107bca5 Use a reference instead of a copy.
a6943a4 Mark a few variables that are not changing as const.
51b7e53 Improved error message for geometry exceptions.
5c37a13 Some minor spelling fixes
8ae5723 Bugfix: Dense location store was written out only partially.
5994322 Add support for tiles.
2168bac Add has_map_type() method to map factory.
a9634bd Add more tests for mercator projection.
3c13e4d Add functionality to create simple polygons from ways in geom factories.
e8c5bb1 Use uint64_t as counter, so there can be no overflows.
07fc9b9 libsparsehash-dev now in travis package whitelist
820e112 Add coverage support to CMake config.
5e9f943 Bugfix: Use the right include to really allow any input file type.
d4b48eb CMake: Make version string a cached variable.
e6baccb Add (c)begin/end functions to TypedMemoryMapping. Removed get_addr().
3e32710 Use size() from MemoryMapping in TypedMemoryMapping.
96390db Improve MemoryMapping class documentation.
60a6217 Do not round memory mapped files to page size boundaries.
4907cbe Bugfix: function name.
cac01d8 Use _filelengthi64 on Windows instead of fstat(2).
6a25bdf Windows: Put invalid parameter handler into wrapper class. Re-enable test.
110df9b Add invalid parameter handler on Windows to test.
549ed5f Disable some tests (to find which one fails on appveyor).
a5b8873 Use resize_file() in memory mapping test instead of ftruncate directly.
40e41d3 Use _chsize_s() instead of _chsize() on Windows.
048397e Refactoring: Use low-level util functions in DataFile.
6a033f9 Remove now unused Windows implementation of mmap.
3eccdbb Move dword_hi/lo functions into osmium::util namespace.
be7351b Remove unused code.
b859b18 Make dword_hi/lo functions inline.
2e3bc37 Simplify mmap_vector_base/anon/file.
f819cf3 Always map full pages. Make sure files behind mapping are large enough.
d0c84b6 Add some low-level helper functions for file system access.
62e8d91 Make DataFile constructor explicit.
fba684c Fix memory mapping test for windows.
78a7fd5 Add constructor to DataFile to create tmp file with given size.
f911893 Bugfix: typo.
1cf2739 Add AnonymousMemoryMapping class.
56eac30 Implement MemoryMapping::resize() function.
1a73262 Bugfix: Counter variables were too small.
1ade32c Fix include position.
b03aec3 Fixed some bugs in new DataFile class/tests.
f109534 Add DataFile utility class.
9ed3c43 Fix/cleanup some code.
4f326c9 Fix bug: Copy-and-paste error.
78a5b2f Use reinterpret_cast instead of static_cast to get HANDLE on Windows.
7baa318 Fix typo.
e669069 Make huge value even huger to see if code reliable fails then.
66137ad Improved documentation of MemoryMapping and TypedMemoryMapping classes.
3121393 Add TypedMemoryMapping class.
f45335e Default for get_addr() template type.
685bbaf Remove unused code from tests.
ce65bd4 Fix some issue with new MemoryMapping class.
e7b8e15 Added MemoryMapping wrapper class for mmap() and Windows equivalent.
6b1effe typo fixed
33d479d Refactored travis build.
4348522 Fix xml data test.
769b1e8 Bugfix: Better check for invalid locations.
bba7e68 Appveyor: Disable test failing because of missing dependency.
3d40dc7 Link with /debug on MSVC, add note about LNK4099 warnings.
5ef051f Appveyor: Disable header builds, add benchmarks.
ce7485e Reformat Appveyor config.
c60e505 use shallow clones for faster git fetch
3b18bca Travis cleanups.
b8dfac0 Cleanup travis build.
5f19838 Trying to fix travis gcc build...
d4255a4 Remove -Wno-return-type from recommended options.
5f1a41b Add dump_as_array() function to maps.
ff22f76 Add constructors and begin()/end() functions to VectorBasedSparseMultimap.
c7e05dd Bugfix: Make REGISTER_MAP() macro work when called several time with same name parameter.
abdc317 Bugfix: Mark cbegin() and cend() of mmap_vector_base as const functions.
d81d439 Add close() function to mmap_vector_base class.
d74cff2 Add function on Buffer to get iterator to specific offset.

git-subtree-dir: third_party/libosmium
git-subtree-split: c43f8db50d93912a8bec5cd9fea733f7fec05549
2015-08-28 12:42:03 +02:00
Patrick Niklaus 8e1f70865e Use curl instead of http in update script. 2015-08-28 12:40:40 +02:00
bergwerkgis 6143f1ff5b AppVeyor: try "os:VS2015" 2015-08-28 12:15:42 +02:00
Daniel J. Hofmann db30836b53 Add rising bollard exception to barriers for car profile.
This handles `barrier=bollard` with `bollard=rising`, by making an
exception to the barrier whitelist. Barriers tagged as such do no longer
require an explicit access tag.

This also adds corresponding tests, check this out:

    cucumber --tags @barrier

References:

- http://wiki.openstreetmap.org/wiki/Tag:barrier%3Dbollard
- http://wiki.openstreetmap.org/wiki/Key:bollard
- https://github.com/Project-OSRM/osrm-backend/issues/1616
2015-08-25 14:52:45 +02:00
Daniel J. Hofmann 3e8ef5e462 Remove unused obey_bollards from profiles, already handled via barrier_whitelist. 2015-08-25 14:24:43 +02:00
Lauren Budorick 0a53dccd4c Use .round instead of .to_i for cucumber speeds 2015-08-25 00:06:57 +02:00
Wilhelm Berg 2b5aa142fb appveyor.yml update url to binary deps 2015-08-24 23:29:30 +02:00
Wilhelm Berg 40443d1e25 appveyor.yml update url to binary deps 2015-08-24 21:23:12 +02:00
Daniel J. Hofmann cb4e7614ee Actually do the subtree pull instead of just notifying the user 2015-08-21 12:16:19 +02:00
Daniel J. Hofmann 3d84dbc73f Check for releases and request user confirmation before updating subtrees 2015-08-21 12:16:19 +02:00
Daniel J. Hofmann beb2ab9ad5 Add script to update subtree-ed third party dependencies more easily.
Note: this updates the subtrees immediately.

Discussion: would it make sense to do something along the lines of:

    $ http --body https://api.github.com/repos/mapbox/variant/releases/latest | jq ".tag_name"
    "v1.0"

And warn the user if the latest release tag is not the tag the update
script was called with. Or at least ask for confirmation?
2015-08-21 12:16:19 +02:00
Daniel J. Hofmann 9a0877379c Remove dead code. 2015-08-20 16:15:20 +02:00
Patrick Niklaus bbd0239ece Fix Coverity warning in EBGF 2015-08-20 12:28:14 +02:00
Patrick Niklaus 92956f2b45 Also support loading core information into shared memory 2015-08-19 12:27:44 +02:00
Patrick Niklaus 48d1a5ec5d Make sure to terminate when the core heaps are empty 2015-08-19 12:27:44 +02:00
Patrick Niklaus 2ff2ce460c Add .core to cucumber renaming 2015-08-19 12:27:44 +02:00
Patrick Niklaus 7cc875b8db Initial version of core based search 2015-08-19 12:27:44 +02:00
Patrick Niklaus 9387f583fa Add loading of .core file to InternalDataFacade 2015-08-19 12:27:44 +02:00
Patrick Niklaus 707dd700b0 Write number of markers to .core file 2015-08-19 12:27:44 +02:00
Patrick Niklaus ddff9b612f Serialize out .core file containing core node markers 2015-08-19 12:27:44 +02:00
Patrick Niklaus 338ac5d4a3 Rename map to describe what it actually does 2015-08-19 12:27:44 +02:00
Patrick Niklaus ca7abd727a Merge pull request #1603 from Project-OSRM/refactor/clang_modernize
Modernize the code base to C++11 standards and beyond.
2015-08-19 12:26:58 +02:00
Daniel J. Hofmann 62b20769ee Modernize the code base to C++11 standards and beyond.
Apply `clang-modernize` (based on Clang 3.6) transformations to the
codebase while making sure to support Clang>=3.4 and GCC>=4.8.

We apply the transformations in parallel to speed up the quite
time consuming process, and use our `clang-format` style file
to automatically format the code respecting our coding conventions.

We use the following self-explanatory transformations:

* AddOverride
* LoopConvert
* PassByValue
* ReplaceAutoPtr
* UseAuto
* UseNullptr

This required a `compile_commands.json` compilation database, e.g.

    ccmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=1

for CMake or check Bear for a Makefile based solution (or even Ninja).

    git ls-files -x '*.cpp|*.h' | \
      xargs -I{} -P $(nproc) clang-modernize -p build -final-syntax-check -format -style=file -summary -for-compilers=clang-3.4,gcc-4.8 -include . -exclude third_party {}

Boom!

References:

* http://clang.llvm.org/extra/clang-modernize.html
* http://clang.llvm.org/extra/ModernizerUsage.html
2015-08-18 12:56:34 +02:00
Patrick Niklaus 4ec323c5cc Merge commit '9958937fd1c1f9dd60126a56e1c4f25ceefaf70e' 2015-08-15 00:11:31 +02:00
Patrick Niklaus 84e72ede72 Warn if an edge references a missing node 2015-08-14 23:57:01 +02:00
Patrick Niklaus bd37c48596 Add test for mode change 2015-08-12 13:02:18 +02:00
Patrick Niklaus e30f0e8e11 Always announce a turn on mode change
Fixes #1558
2015-08-12 13:02:18 +02:00
Patrick Niklaus c43a2513a8 Rename tiny_components.hpp to tarjan_scc.hpp
Fixes #1561
2015-08-12 13:02:18 +02:00
Patrick Niklaus 4b4bc0dde2 Fix postgis lua example
Fixes #1573.
2015-08-12 13:02:18 +02:00
Patrick Niklaus 49adf2192a Move calculate_coordinate to algorithms/
Fixes #1367
2015-08-12 13:02:18 +02:00
Andreas Gruß a7eabeb73f gps_precision and matching_beta can be used as a float value 2015-08-11 11:06:11 +02:00
Patrick Niklaus f838f3427b Fix static graph test 2015-08-06 15:09:28 +02:00
Patrick Niklaus 1cc75ca636 Only swap nodes if it contains a big component 2015-08-06 13:20:29 +02:00
Patrick Niklaus d4356b0453 Move comparators to struct 2015-08-06 11:13:25 +02:00
Patrick Niklaus 35542e5823 Change interface of Tarjan get_component_size to take component id 2015-08-06 11:13:25 +02:00
Patrick Niklaus c80c2233c5 Find components on edge-expanded graph 2015-08-06 11:13:25 +02:00
Patrick Niklaus c2f0e4f683 Implement correct const iterator for DeallocatingVector 2015-08-06 11:13:25 +02:00
Patrick Niklaus 2621f4a2fa Allow any input format for StaticGraph and check if edge list is sorted 2015-08-06 11:13:25 +02:00
Patrick Niklaus 3c055642d5 Remove reference to restrictions and bollard nodes because it does not work 2015-08-06 11:13:25 +02:00
Patrick Niklaus 43b881d0cd Simplify test.sh 2015-08-02 14:45:27 +02:00
Patrick Niklaus 8b7b32e225 Added ccmake to docker image 2015-08-02 14:45:27 +02:00
Patrick Niklaus 00b0ff50f3 Add clang and README 2015-08-02 14:45:27 +02:00
Patrick Niklaus 1acde593b5 Fix docker run step 2015-08-02 14:45:27 +02:00
Patrick Niklaus c43c043521 Add docker port of build instructions 2015-08-02 14:45:26 +02:00
MoKob b526cadebd Initial version of core ch
This improves preprocessing times in favour of worse query performance.
Core size can be set over the --core parameater, default is the old
behaviour to fully contract the graph.
2015-08-01 18:00:48 +02:00
Patrick Niklaus 94f44e1d5d Make sure to capture floating point return values from lua 2015-08-01 17:46:47 +02:00
bergwerkgis 0352d9c99e AppVeyor: wrong paths when creating artifacts 2015-07-13 14:49:30 +00:00
bergwerkgis 0cd3f37e1b AppVeyor: create artifacts 2015-07-13 16:03:18 +02:00
Patrick Niklaus 486d7b6d62 Fix typo in foot profile that removed traffic lights 2015-07-09 21:24:07 +02:00
Patrick Niklaus 8f4e332409 Link restrictions to datastore test 2015-07-08 20:26:54 +02:00
Patrick Niklaus f0389c0b2f Restructure CMakeFile to fix shared library linking errors 2015-07-08 18:26:25 +02:00
Patrick Niklaus 922e8a4912 Return the correct size 2015-07-01 18:07:29 +02:00
Patrick Niklaus 021a1c7a39 Restructure the construction of the undirected graph 2015-07-01 18:07:29 +02:00
Patrick Niklaus 4a7451682b Fix data_structure test thanks to new assertion 2015-07-01 18:07:29 +02:00
Patrick Niklaus faa880d60a Remove unused memebers and rename to currrent style convention 2015-07-01 18:07:29 +02:00
Patrick Niklaus fd30e82836 Add graph compressor unit tests 2015-07-01 18:07:29 +02:00
Patrick Niklaus 3ef34fbb56 Rename GeometryCompressor and add unit tests 2015-07-01 18:07:29 +02:00
Patrick Niklaus 7345dc6861 Move graph compression code outside of EBGF 2015-07-01 18:07:29 +02:00
Patrick Niklaus 9958937fd1 At least check 4*LEAF_SIZE edges before returning none. 2015-07-01 17:57:03 +02:00
Patrick Niklaus f19c57200d Fix endless loop 2015-06-30 00:22:40 +02:00
Patrick Niklaus 8a2652f53d Only penaltize bidirectional ways if they have 1 lane 2015-06-27 16:26:18 +02:00
Patrick Niklaus dddde4ddab Fix backwards speed on oneway=-1 streets 2015-06-27 16:26:18 +02:00
Patrick Niklaus 300d901618 Merge branch 'develop' 2015-06-22 13:06:50 +02:00
Patrick Niklaus 1cb72acd27 Remove unused header 2015-06-22 08:36:21 +02:00
Patrick Niklaus a17776cb5f Check if FingerPrint is trivial. TODO: Add this for all other data that is going to be serialized 2015-06-19 18:10:49 +02:00
Patrick Niklaus 94b749ab00 Fix magic number check for fingerprint 2015-06-19 17:51:35 +02:00
Patrick Niklaus 5fc0d284cb Revert "Simplify offeset calculation logic a little bit"
This reverts commit 8ade26b4a4.
One of the assertions triggers when run on an extract of Serok. Since
this code does not fix any bugs, I'll just revert this for now.
This definetly needs investigation.
2015-06-19 16:50:48 +02:00
Patrick Niklaus bbe1211451 Merge pull request #1534 from Project-OSRM/profile/lane-penalty
Profile/lane penalty
2015-06-19 00:25:32 +02:00
Patrick Niklaus ce152b205f Merge pull request #1535 from Project-OSRM/develop-vs2015
make AppVeyor green again
2015-06-19 00:25:11 +02:00
bergwerkgis a5fd7cf4e9 make AppVeyor green again 2015-06-18 18:16:51 +02:00
Dane Springmeyer da38a1367a try building with vs2015 as CTP_Nov2013 appears broken now on appveyor 2015-06-18 18:15:34 +02:00
Patrick Niklaus 1445f11c19 Add test for lane penalty 2015-06-18 17:35:39 +02:00
Patrick Niklaus 86df55f5cc Add penalty if there is only one lane for both directions 2015-06-18 17:31:49 +02:00
Patrick Niklaus cf294c938e Merge pull request #1508 from agruss/geometry_string
Polyline string as parameter
2015-06-18 16:29:29 +02:00
Patrick Niklaus ebff45f803 Add new regression test for looping bugs 2015-06-18 00:18:54 +02:00
Patrick Niklaus 7b8021a36e Merge pull request #1531 from Project-OSRM/fix/poland-motorway-bug
Fix/poland motorway bug
2015-06-17 23:25:41 +02:00
Patrick Niklaus 5c77bb7c67 Fix inversion of sign 2015-06-17 23:25:16 +02:00
Patrick Niklaus 8ade26b4a4 Simplify offeset calculation logic a little bit 2015-06-17 23:25:16 +02:00
Patrick Niklaus bdbc60b4f7 Fix comments in edge based graph factory 2015-06-17 23:25:16 +02:00
Patrick Niklaus 373fa7a7d9 Merge pull request #1502 from agruss/develop
Accepting HTTP Post Request
2015-06-17 23:24:41 +02:00
Lauren Budorick eec4f173a7 Fix tag misspellings in profiles + tests: forestry, pebblestone 2015-06-09 20:16:58 -07:00
Andreas Gruß d726ce6340 removed send_simple_request 2015-06-07 12:20:03 +02:00
Andreas Gruß b406844c96 rearranged send_request parameters 2015-06-07 11:06:37 +02:00
Andreas Gruß 153d38f10c post/get handler added, background section for HTTP request 2015-06-05 13:26:27 +02:00
Andreas Gruß dce917eb74 post tests via query options available 2015-06-04 17:39:54 +02:00
Andreas Gruß eb711787ae tests added 2015-06-03 15:31:20 +02:00
Patrick Niklaus 9967dbbaa9 Don't remove small segments at start/begin if they are vias 2015-06-02 17:51:17 +02:00
Patrick Niklaus 71dc10ebea Add failing test case 2015-06-02 16:59:30 +02:00
Andreas Gruß 782fba2ce7 updated to 1E6 based polyline format 2015-06-02 13:15:31 +02:00
Andreas Gruß 4d73f98050 made geometry_string a const reference 2015-06-02 13:06:06 +02:00
Andreas Gruß 79d2083a00 changed parameter from geometry_string to locs 2015-06-02 12:10:28 +02:00
Andreas Gruß ee3b296a99 fixed values of test 2015-06-02 12:10:13 +02:00
Andreas Gruß 8b62d04453 test added 2015-06-02 12:09:59 +02:00
Andreas Gruß 9b0d3dfaeb polyline string as parameter added 2015-06-02 12:09:46 +02:00
Patrick Niklaus b1ef4cfee9 Remove debugging code 2015-06-01 17:22:12 +02:00
Patrick Niklaus f12f6a56ba Fix debug message 2015-06-01 17:22:12 +02:00
Patrick Niklaus 2777d53a12 Direct edges in contractor correctly and add better graph validation. 2015-06-01 17:22:12 +02:00
Patrick Niklaus aba3ec692f Verify graph before compression 2015-06-01 17:22:12 +02:00
Patrick Niklaus b7c8fcd062 Also print edge source/target for suspicious edge weights 2015-06-01 17:22:12 +02:00
Patrick Niklaus 3065de63dd Move renumbering and edge deduplication in extractor 2015-06-01 17:22:12 +02:00
Patrick Niklaus a57fb4f1ab First step into overhauling the edge storage 2015-06-01 17:22:12 +02:00
Patrick Niklaus c493a22765 Add test case for leisure=track 2015-06-01 11:20:17 +02:00
Patrick Niklaus d85e5def5d Add running tracks to foot profile 2015-06-01 11:20:17 +02:00
Patrick Niklaus 0aba499c8e Use spaces instead of tabs 2015-06-01 11:20:17 +02:00
Patrick Niklaus 4146695f34 Add test to check new way naming convention 2015-06-01 11:19:27 +02:00
Patrick Niklaus 4e57e10ba8 Use 'name (ref)' if both are present 2015-06-01 11:19:27 +02:00
Andreas Gruß daa6d02887 Content Type validation added 2015-06-01 09:42:22 +02:00
Daniel Patterson a87d89302f Handle POST request when spanning multiple packets 2015-05-31 21:34:38 +02:00
Patrick Niklaus 2a9b1311d3 Add test for ignoring crossing nodes 2015-05-30 19:30:33 +02:00
Patrick Niklaus 7d73501b87 Update bicycle profile to ignore crossing nodes 2015-05-30 19:26:56 +02:00
Daniel Patterson 039d6acd3e Fix test case, it was missing 'via' instructions 2015-05-29 16:52:08 +02:00
Daniel Patterson 405fcdc483 We really need to run these tests. 2015-05-29 16:52:08 +02:00
Daniel Patterson f52abc1a62 When replacing packed_path1/2, also need to replace distance1/2 to properly track. 2015-05-29 16:52:08 +02:00
Daniel Patterson e763953562 Address #1424 by using the original fix 2015-05-29 16:52:08 +02:00
Patrick Niklaus 4cab617c25 Fix Coverity issue by initializing member 2015-05-29 09:13:28 +02:00
Patrick Niklaus 0190b5e5af Merge pull request #1501 from Project-OSRM/refactor/contractor
First part of the contractor refactor
2015-05-29 01:08:55 +02:00
Patrick Niklaus abc0952247 Fix accessing DeallocatingVector 2015-05-28 22:22:02 +02:00
Patrick Niklaus 6ce2726a87 Fix return codes for osrm-prepare 2015-05-28 15:18:48 +02:00
Patrick Niklaus 17a4463f59 More assertions 2015-05-28 15:18:48 +02:00
Patrick Niklaus e76d8df246 Fix tools to build with new graph reader interface 2015-05-28 15:18:48 +02:00
Patrick Niklaus a46bcf45d5 Move option parsing to own class 2015-05-28 15:18:48 +02:00
Patrick Niklaus 1f985d04a2 Move writing graph to an own function 2015-05-28 15:18:48 +02:00
Patrick Niklaus d64e6e6c1f Move more function from Run in subfunctions 2015-05-28 15:18:48 +02:00
Patrick Niklaus 1164a65df8 Refactor processing_chain by splitting into sub functions 2015-05-28 15:18:48 +02:00
Patrick Niklaus d57f07d57e Merge pull request #1500 from Project-OSRM/fix/scc-only-barrier
Enable barrier check for TarjanSCC
2015-05-28 15:17:36 +02:00
Patrick Niklaus 5c0a964321 Remove unused code SimpleNodeBasedDynamicGraph 2015-05-28 12:43:55 +02:00
Patrick Niklaus cf3b8d09d9 Also run the algorithm tests on travis 2015-05-28 12:43:27 +02:00
Patrick Niklaus 1c7397fb21 Enable barrier check for TarjanSCC
Re-enabling turn restrictions as well requires some further work to
extend the algorithm.
2015-05-28 12:31:59 +02:00
Andreas Gruß 6a08d93e2c http post requests implemented 2015-05-27 15:40:10 +02:00
Patrick Niklaus 4c03ace9eb Remove pruning in IncrementalFindPhantomNode 2015-05-25 02:07:01 +02:00
Patrick Niklaus 2cd616dd30 Merge pull request #1485 from danpat/fix/lua_err_display
Return error message when lua error occurs.
2015-05-22 09:45:26 +02:00
Daniel Patterson eab87c0827 Return error message when lua error occurs.
The error may not be the first item in the stack while we're inside the error handler.  ::from_stack() works OK outside the error callback, but not inside.
2015-05-21 15:39:23 -07:00
Patrick Niklaus 8b8188710e Merge pull request #1481 from Project-OSRM/fix/no-big-cc-pruning
Only activate pruning for big cc after one was found
2015-05-18 16:18:17 +02:00
Patrick Niklaus fd9bb3ac43 Only activate pruning for big cc after one was found 2015-05-18 09:41:41 +02:00
Patrick Niklaus 6d9c3bca33 Merge pull request #1478 from Project-OSRM/fix/profiles-cleanup
Cleanup the profiles
2015-05-18 00:09:45 +02:00
Patrick Niklaus dd33a45644 Revert "fix incorrect behavior when via point was on same one-way street as destination but should have been reached before, closes #1424"
This reopens #1424 but potentially fixes #1429.

This reverts commit 11c671354b.
2015-05-17 23:35:31 +02:00
Patrick Niklaus 074c7a9c40 Fix access module 2015-05-17 17:26:10 +02:00
Patrick Niklaus de2f06970d Fix missing values and activate fallback names by default 2015-05-16 14:39:49 +02:00
Patrick Niklaus 6166d946f7 Fix access tag check 2015-05-16 14:39:49 +02:00
Patrick Niklaus c778ab9622 Make bicycle profile backwards compatible 2015-05-16 14:39:49 +02:00
Patrick Niklaus aad846b968 Fix call to function and transportation if clause 2015-05-16 14:39:49 +02:00
Patrick Niklaus f04a3e3d2e Fix bicycle profile syntax 2015-05-16 14:39:49 +02:00
Patrick Niklaus 7ad52de2b1 Cleanup the profiles 2015-05-16 14:39:49 +02:00
Patrick Niklaus 0706ba9bec Merge pull request #1457 from Project-OSRM/develop-lua52
Modify profiles to use Lua 5.2+ without needing compatibility flags
2015-05-16 14:29:32 +02:00
Patrick Niklaus ed53888fce Follow symlinks 2015-05-15 15:30:41 +02:00
Lauren Budorick fd76fba235 Keep apt-get 5.1 for now 2015-05-15 15:02:23 +02:00
Patrick Niklaus 95088a785a Make using profile.lua work again.
Symbolic links are a _bad_ idea with lua script. Lua will search at the
place of the symbolic link for modules _not_ at the actual location of
the script.
2015-05-15 15:02:23 +02:00
Lauren Budorick f46b600ec0 Upgrade lua to 5.2 on travis 2015-05-15 15:02:23 +02:00
Lauren Budorick 566ab993df Use lua 5.2+ without needing compatibility flags. 2015-05-15 15:02:23 +02:00
Patrick Niklaus 407036e215 Merge pull request #1476 from Project-OSRM/fix/distance-based-radius
Use distance based search radius
2015-05-15 10:49:19 +02:00
Patrick Niklaus 7b1a5566fb Move nodes inside the search radius 2015-05-15 00:34:53 +02:00
Patrick Niklaus 1b0d8739c1 Increase max distance to 1100 to fix unrelated test cases 2015-05-15 00:34:34 +02:00
Patrick Niklaus 266feea397 Merge pull request #1465 from alex85k/develop
fix cucumber tests running on Windows
2015-05-14 22:25:52 +02:00
Patrick Niklaus c4c6ab2494 Use distance based search radius
This limits the nearest neighbour search to a maximum distance
of 1000 meters, but will also work in dense areas.
2015-05-14 22:24:07 +02:00
Emil Tin 079eea3f2b add test for route duration formats 2015-05-10 20:09:09 +02:00
alex85k a457d69034 fix cucumber tests running on Windows 2015-05-09 19:22:16 +05:00
Patrick Niklaus d0175798bf Add link to documentation in the wiki 2015-05-02 15:18:13 +02:00
Patrick Niklaus 80e07943ee Make README more meaningful 2015-05-02 01:30:44 +02:00
Will White e2954211ec Fix travis links. 2015-05-01 20:04:05 +02:00
Patrick Niklaus 337bed8176 Merge pull request #1455 from Project-OSRM/fix/cucumber2.0
upgrade to cucumber 2.0
2015-05-01 18:32:26 +02:00
Emil Tin 71197e1c89 remove last use of routing_diff 2015-04-30 18:29:56 +02:00
Emil Tin e1a13f5ce8 remove obsolete cucumber patch 2015-04-30 18:15:46 +02:00
Emil Tin 1ed2c16a51 upgrade to cucumber 2.0 2015-04-30 18:15:46 +02:00
Patrick Niklaus 12e1bd80b3 Send travis mails to me 2015-04-29 14:00:17 +02:00
Patrick Niklaus fd6daa580a Merge branch 'develop' 2015-04-22 10:34:56 +02:00
Patrick Niklaus d2a19ec8ec Merge pull request #1446 from Project-OSRM/fix/sharedmemory-default
Fix/sharedmemory default
2015-04-22 09:50:46 +02:00
Patrick Niklaus 8f3feac916 Ensure routed is backwards compatible 2015-04-22 09:49:08 +02:00
Patrick Niklaus c0e066440c Use shared memory if no server paths are provided.
This caused a bug in the node bindings that would invoke the constructor
without parameters.
2015-04-22 09:49:08 +02:00
Patrick Niklaus fbb4e9078a Updated restriction parser doc 2015-04-21 20:00:58 +02:00
Patrick Niklaus d96e90c6f4 Add documentation to ExtractionContainer 2015-04-21 20:00:58 +02:00
Patrick Niklaus 3b435d8956 Add documentation to ScriptingEnvironment 2015-04-21 20:00:58 +02:00
Patrick Niklaus 345dd2481b Add documentation to InputRestrictionContainer 2015-04-21 20:00:58 +02:00
Patrick Niklaus 006bcc0fc8 Add some documentation to the restriction parser 2015-04-21 20:00:58 +02:00
Patrick Niklaus c25d14e454 Remove unnecessary header include 2015-04-21 20:00:58 +02:00
Patrick Niklaus 5ff95dc32d Move string_map inside external_callbacks
It is not referenced outside this calls, thus the lifetime
can be safely handled by it.
2015-04-21 20:00:58 +02:00
Patrick Niklaus 34031aab1b Add further documentation to ExtractorCallbacks 2015-04-21 20:00:57 +02:00
Patrick Niklaus 3035219212 Add further documentation 2015-04-21 20:00:57 +02:00
Patrick Niklaus 8a608eb930 Add some doc to the extractor 2015-04-21 20:00:57 +02:00
Patrick Niklaus c2fc47df34 Merge branch 'develop' 2015-04-17 22:51:40 +02:00
Dennis Luxen d4065774ce Merge pull request #1440 from Project-OSRM/feature/check_graph_implementations
fix incorrect SCC generation
2015-04-17 09:50:46 +02:00
Patrick Niklaus 6d43d9f2b6 Add unit test for dynamic graph
Also simplify the unit tests.
2015-04-17 00:38:09 +02:00
Patrick Niklaus 94d7fd9112 Adapt osrm-components to new FindEdge interface 2015-04-17 00:25:01 +02:00
Patrick Niklaus 04b5833e98 Adapt EdgeBasedGraphFactory to new FindEdge behaviour 2015-04-17 00:23:58 +02:00
Patrick Niklaus 52592b84fd Add functions to find reverse edge to DynamicGraph 2015-04-17 00:22:51 +02:00
Patrick Niklaus f2cd68e3ec Return SPECIAL_EDGEID if no edge was found 2015-04-17 00:21:57 +02:00
Dennis Luxen aff590a44d make implementation of FindEdge consistent among graph implementations, introduce FindSmallestEdge() function to return the edge with smallest weight if there are multiple, fixes #1427 2015-04-16 16:12:08 +02:00
Dennis Luxen 0d432f6377 fix comparison to recognize small components in a static graph 2015-04-16 16:11:06 +02:00
Dennis Luxen 59bceee258 make sure GetNumberOfNodes() is only called once 2015-04-16 16:08:10 +02:00
Dennis Luxen 4a0a0bac1d clear right edge list after graph instantiation 2015-04-16 14:38:42 +02:00
Dennis Luxen c7bd96ea8b fix unintended signed/unsigned comparison 2015-04-16 14:31:13 +02:00
Dennis Luxen 0eb2106067 reorder includes, add tuple include 2015-04-16 14:30:52 +02:00
Dennis Luxen c03aec364c add comparison tool for graph classes 2015-04-16 11:25:43 +02:00
Patrick Niklaus f2cdb97867 Change max distance delta to 200m 2015-04-13 22:39:55 +02:00
Patrick Niklaus 727e284ed0 Reduce map beta, as it fits better to the intended sample rate 2015-04-13 22:39:55 +02:00
Patrick Niklaus 3248977e02 Update classifier parameters 2015-04-13 22:39:55 +02:00
Patrick Niklaus 7ee8776165 Remove second stage classifier: obsolete with trace splitting 2015-04-13 22:39:55 +02:00
Patrick Niklaus f89f4bd20b Add option to enable json logging 2015-04-13 22:39:55 +02:00
Patrick Niklaus a372ade7ce Mark suspicious transitions 2015-04-13 22:39:55 +02:00
Patrick Niklaus 61dca4a35e Merge pull request #1433 from Project-OSRM/feature/node-location
Make node location accessible
2015-04-13 16:53:02 +02:00
Dennis Luxen c0402345f7 Squashed 'third_party/libosmium/' changes from f074d94..8bcd4ea
8bcd4ea Add explicit cast operator from osmium::Timestamp to uint32_t.
0b24814 Fixed the full_queue_sleep_duration const (again).
5e19dd2 Try different workaround for windows...
df5d6c9 Fix build error on Windows.
1553adf Workaround for missing support for u8 string literals on Windows.
aa5e44a Do not build benchmarks in Appveyor to speed up build.
2b22b31 Remove warning generated by assert by casting to largest type.
148c5e3 Fix inclusion of our own css file into doxygen documentation.
13bce6f Split out test thats fails on Windows and do not run it on appveyor.
ca04757 Make CMake add_unit_test() function more flexible.
6c04a63 Tell CMake to output json file with compile commands.
c0dd848 Fix indentation in some tests.
dfa7e4b Formatting: Consistently use spaces around equal signs.
08fe6db Add change log, release version 2.1.0.
667192e Add XML tests.
28acfc7 Make sorting the PBF stringtables optional.
8184781 Fix PBFInputFormat. Use member variable instead of static variable.
2b48945 Fix comment.
6d37054 Rename m_done to m_quit_input_thread to clarify what it is for.
bc23083 Fix race condition in PBF reader.
7fc380e Add various docs, noexcepts, asserts, and tests.
aeaf4d7 Not a good idea to how overbroad patterns in .gitignore.
c1ef2f9 Bugfix: Multipolygon collector was accessing non-existent NodeRef.
0ef9a13 Add noexcept and docs to some functions in NodeRefList class.
da4d764 Workaround for Doxygen bug.
e67d5d9 use absolute paths to osmium in YouCompleteMe configuration
38abeac remove template parameter from NodeRefList
c47adf0 Add check that osm xml file has <osm> or <osmChange> as top-level element.
5e4af90 Updated version number to 2.0.0.
5b2bc3e Workaround in cmake test for sparsehash size.

git-subtree-dir: third_party/libosmium
git-subtree-split: 8bcd4ea771696812bbb08ebc58e3ee22d0538070
2015-04-13 15:44:38 +02:00
Dennis Luxen 9cc68b26e2 pull in latest osmcode/libosmium changes 2015-04-13 15:44:38 +02:00
Dennis Luxen 27c9230a82 pull latest mapbox/variant changes in 2015-04-13 15:37:43 +02:00
Dennis Luxen e985c9714b Squashed 'third_party/variant/' changes from 3b02ca0..bf485df
bf485df Revert "pass F (functor) by ref/const ref"
e031c53 Revert "pass by const ref in 'apply_const'"
a3014f5 pass by const ref in 'apply_const'
2e0ce4a pass F (functor) by ref/const ref
5875195 add support for 'unwrapping' std::reference_wrapper<T> and accessing std::reference_wrapper<T>::type through get<T>() + update test
c53422f remove boost variant header
5a2d5c5 add reference_wrapper test

git-subtree-dir: third_party/variant
git-subtree-split: bf485dfb59aef26f3ef2183d7c8c1111ad97062b
2015-04-13 15:37:43 +02:00
Dennis Luxen 6c5015811e do not build concurrently on Travis, also build (but not run) benchmarks 2015-04-13 14:43:35 +02:00
Dennis Luxen 86e7de4d62 Merge branch 'revert-1375-master' into develop 2015-04-13 10:07:29 +02:00
Dennis Luxen 147d35e40d Revert "added lua binding for osmium::Way::id()" 2015-04-13 10:04:23 +02:00
Dennis Luxen b76fc724fd make node id available thru Lua bindings 2015-04-13 09:58:59 +02:00
Dennis Luxen 1bfab4e279 Merge pull request #1375 from bjtaylor1/master
added lua binding for osmium::Way::id()
2015-04-13 09:52:56 +02:00
Dennis Luxen 11bdfba37e traffic signal penalty ignored on white-listed barriers, cf. #1365 2015-04-13 09:47:12 +02:00
Patrick Niklaus 405f08b807 Make node location accessible 2015-04-10 11:45:24 +02:00
Dennis Luxen 592211cecd activate __get_cpuid on all non X64 platform, fixes #1193 2015-04-07 14:45:21 +02:00
Dennis Luxen a4f31001e8 MSVC doesnt properly support the noexcept operator 2015-04-02 15:11:23 +02:00
Dennis Luxen c2deedac8b sprinkle a number of noexcepts into the code 2015-04-02 11:36:04 +02:00
Dennis Luxen 9a61f8b894 add more const keywords, avoid implicit type conversions 2015-04-02 11:27:51 +02:00
Dennis Luxen 3a291f5c8e fix escaping of double quote in JSON response, fixes #1410 and also adds a unit test for that case. 2015-04-02 10:34:40 +02:00
Dennis Luxen 559a2dcec7 move shared lib testing to distinct port on travis 2015-03-31 17:33:56 +02:00
Dennis Luxen b7f003c4aa Merge branch 'opengisch-sharedlib' into develop 2015-03-31 17:33:36 +02:00
Matthias Kuhn d11c0bbd5c Do not compile Coordinate sources directly into the OSRM library
It is already included in the COORDINATES "OBJECT" target to which the OSRM
library is linked.
This fixes the possibility to build OSRM as a shared library.
2015-03-31 16:57:41 +02:00
Matthias Kuhn c2f775fcaa Add test for building as shared library 2015-03-31 16:57:41 +02:00
Dennis Luxen 19ac831c2e remove another quoted compare 2015-03-31 12:59:56 +02:00
Dennis Luxen 23b413a398 remove quotes from string compares against variable in CMakeLists 2015-03-31 12:35:20 +02:00
Dennis Luxen 098de196e2 reactivate profiling flags for debug build 2015-03-31 11:21:36 +02:00
Dennis Luxen 27d2c31f28 add (new) fingerprint.cpp that includes the generated headers 2015-03-31 10:47:21 +02:00
Dennis Luxen c9c9edeb23 deleted: util/fingerprint.cpp.in 2015-03-31 10:46:55 +02:00
Dennis Luxen 5adf792fad fix build issue where cmake does not pick up generated output of a custom target
renamed:    ../util/fingerprint.cpp.in -> ../util/fingerprint_impl.hpp.in
2015-03-31 10:45:35 +02:00
Dennis Luxen 81af7d73a6 make FINGERPRINT a global dependency 2015-03-30 15:55:23 +02:00
Dennis Luxen 23e4e0786d also enable C as a project language 2015-03-30 13:26:06 +02:00
Dennis Luxen 0640ce9632 set project and fingerprint target language to CXX explicitly, fixes AppVeyor build. Potentially Travis, too. 2015-03-30 13:21:03 +02:00
Dennis Luxen 3e49bf4f42 add const keywords where possible 2015-03-30 13:16:22 +02:00
Dennis Luxen 66b038a010 reorder includes 2015-03-30 13:14:13 +02:00
Dennis Luxen 9bbbebf31d use empty() instead of 1>size() to make intent more clear 2015-03-30 13:13:13 +02:00
Dennis Luxen 19765cfa14 remove unneeded include 2015-03-30 13:10:03 +02:00
Dennis Luxen d6badca610 use lamda function to do complex initialization with a (wanted) side-effect 2015-03-30 13:09:10 +02:00
Dennis Luxen 6933804aa4 remove unused html en/decoding entities, we use JSON now 2015-03-30 12:40:54 +02:00
Dennis Luxen 5bed7f292f add test for printInt() sign correctness 2015-03-30 12:37:39 +02:00
Dennis Luxen f553896e2d printInt(): fix sign issue when outputting 0, use postfix in/decrement 2015-03-30 12:36:39 +02:00
Dennis Luxen 60663b5433 reorder build dependencies 2015-03-30 11:09:41 +02:00
Dennis Luxen 1851a31e66 add unit tests for functions escape_JSON, printInt and replaceAll in string_util.hpp 2015-03-27 18:15:58 +01:00
Dennis Luxen d853310bee use range-based for in escape_JSON() function 2015-03-27 18:15:13 +01:00
Dennis Luxen 11c671354b fix incorrect behavior when via point was on same one-way street as destination but should have been reached before, closes #1424 2015-03-27 12:29:29 +01:00
Dennis Luxen b15599f01e simplify logic to compute edge offset 2015-03-27 12:28:01 +01:00
Dennis Luxen 4b957abc0c fix rounding error/uncertainty on some systems 2015-03-27 12:27:15 +01:00
Dennis Luxen 8ee82d1e03 replace old-style typefs with using 2015-03-23 17:06:10 +01:00
Dennis Luxen 5565662d87 fix compilation with CMake 3.2, closes #1422
CMake 3.2 changed the behavior of add_custom_command and ungenerated dependencies. Replaced with add_custom_target that works on version 2.8+
2015-03-23 16:14:24 +01:00
Patrick Niklaus 78735fae6b Fix match test by using the new threshold 2015-03-18 00:21:04 +01:00
Patrick Niklaus d3b9911445 Fix match geometry output 2015-03-17 23:50:59 +01:00
Patrick Niklaus 7813dafc96 Increase the time split threshold to a more reasonable value 2015-03-17 23:50:47 +01:00
Patrick Niklaus 02b561edd2 Pass route leg by reference, not by value 2015-03-17 23:24:31 +01:00
Dennis Luxen 272a1fda54 Merge pull request #1407 from Project-OSRM/feature/matching
Map Matching
2015-03-10 06:08:11 -07:00
Patrick Niklaus bc8666df83 Add tests for matching 2015-03-08 01:32:13 +01:00
Patrick Niklaus 028fad94af Fix overflows when handling size_t 2015-03-08 00:53:15 +01:00
Patrick Niklaus 0c735953c9 Make uturn detection a little less sensitive. 2015-03-08 00:51:07 +01:00
Patrick Niklaus 736bc87480 Fix inverted operator in maximum check 2015-03-07 23:02:14 +01:00
Dennis Luxen dd94a64048 remove lint from #1409
- fix copyright header
- remove dead code
2015-03-05 14:03:35 +01:00
Dennis Luxen cf9f88f8ce Merge pull request #1409 from RockLobster/develop
FIX: Moved the GeometryCompressor's free_list_maximum into a member variable of the class.
2015-03-05 14:02:34 +01:00
RockLobster 5694aeda5f FIX:
Moved the GeometryCompressor's free_list_maximum into a member variable of the class.
(+UniqueNumber() commented out since it is not being used anywhere in all of OSRM)

There was absolutely no need for free_list_maximum to be a static variable and it caused major issues in my code.
Short description:
- I ran osrm-prepare's Prepare().Process(..) function in my own code multiple times for multiple files
	=> After the first file is done, free_list_maximum is still on the same size, but a new GeometryCompressor will start at a size of 100 again.
	=> Indices broken.
2015-03-05 11:30:52 +01:00
Patrick Niklaus 7829e3c132 Add step definition and support code for matching 2015-03-05 00:12:26 +01:00
Dennis Luxen 2ce0d60db1 Squashed 'third_party/libosmium/' changes from 6522da5..f074d94
f074d94 Use shorter path names in Doxygen doc.
5117d5a Make Doxygen-generated HTML docs work better on small screens.
41607ac Appveyor config: Use lowercase command names everywhere. Filter 7z output.
9e77a39 Remove debug output.
3416c4b Revert "Comment out test to see if there are dependencies between tests."
fa49dde Comment out test to see if there are dependencies between tests.
5add75d Fix typo in appveyor conf: nul.
53b3778 Use different file names for tests.
1091c0b Fix Windows munmap() to return the same as the posix one.
14fdc4e Revert "CMake: Remove unneeded build type setting."
0270087 Workaround for MSVC.
56c2120 Another try...
8e96a6f Trying to fix test on Windows...
11a64c2 CMake workaround: Set CMAKE_CONFIGURATION_TYPES before project(). As per http://www.cmake.org/pipermail/cmake/2012-January/048856.html
3847e7a CMake: Remove unneeded build type setting.
a1bcaf1 CMake: Make CMAKE_CONFIGURATION_TYPES a cache variable.
ddab3e3 Create test file in test_typed_mmap in current dir instead of tmp.
ce1d3bd Build "RelWithDebInfo" on appveyor instead of "Release".
b6db34f Add README showing source of FindGem.cmake.
2c86c55 Better error message and some comments in CMake for sparsetable check.
b16a5a3 Fix ctest on Windows.
2203bc8 Fix FindGem.cmake.
5d1f81d Another try to fix travis build.
ddd3f5e Hopefully fix problem where travis doesn't find osm-testdata.
0e673ea More debug output to find travis problem.
eb01107 Updated data-tests README.
8a971c8 Remove special case of the multipolygon test in travis/appveyor config.
dce792c CMake: Check dependencies of multipolygon test and run as CMake script.
b967677 Add tests for thread pool.
400e9b3 Bugfix: Handle exception in one pool threads properly.
a1ba489 More detailed error reporting from zlib.
95cf621 Disable SparseMemTable if sparsetable size_type is smaller than 8.
7b601b5 Add missing overload to cast_with_assert() function.
60a7d86 Giving up on trying to remove LNK4221 warning.
35ed5df Try another way to get rid of MSV warning...
f9c7d92 Disable a warning about changed behaviour on MSVC.
c3c6b2d CTest: Only output failed tests.
9c99996 Try setting option in a different way for getting rid of LNK4221 on MSVC.
4ac563c Another ssize_t fix for Windows.
11db84f Fix mmap for windows. Convert macro to function.
95d8f75 Fix test on Windows (which doesn't have ssize_t).
df51aa4 Do not write huge files in one system call.
9c4f772 Change mmap() implementation for Windows.
5be817c Rewrote function to work on Windows without warnings.
ea84f73 Fix warnings on Windows.
572d692 Fixed the static_cast_with_assert function and added tests.
89ef86b Use SparseMemArray instead of SparseMemTable in examples.

git-subtree-dir: third_party/libosmium
git-subtree-split: f074d949a5585a81578d682035f2163de971beb3
2015-03-04 12:50:42 +01:00
Dennis Luxen 68e66dad06 upgrade libosmium dependency 2015-03-04 12:50:42 +01:00
Dennis Luxen 80db907857 upgrade variant dependency 2015-03-04 12:48:19 +01:00
Dennis Luxen 76674a3594 Squashed 'third_party/variant/' changes from 24dcab2..3b02ca0
3b02ca0 add which() method returning zero based index of stored T in Types... for boost::variant() compatibility
c117592 update unit test to match c64c74775a80474f2012c1a49ab2865e3666107a
36f1e12 add get<T>() overloads for when T is stored in recursive_wrapper<T> also makes get<T>() a compile time error where T is not in Types... (ref #24)
7dfdfa2 clean up coverage files in test directory too [skip ci]
89f8a41 add coverage report

git-subtree-dir: third_party/variant
git-subtree-split: 3b02ca0e3ab1a36dd6ec9138e7f93eb3176ae5f7
2015-03-04 12:48:18 +01:00
Patrick Niklaus 98dba11c5e Address some of the remaining issues of the code review 2015-03-04 01:34:45 +01:00
Dennis Luxen de261d28ef add override specifier 2015-03-03 18:26:38 +01:00
Dennis Luxen d43716612b several copyedits to brush up code
- remove unneeded includes
- replace size() <==> 0 comparisions with calls to empty()
- use fp instead of integer literals
- use range-based for loops with integer ranges
- add a couple of consts
2015-03-03 18:17:12 +01:00
Dennis Luxen cfaacf7cb2 put util/compute_angle.cpp into OBJECT library to avoid repetetive compiles 2015-03-03 17:58:17 +01:00
Dennis Luxen b9922bc90b replace C-style comments 2015-03-03 17:43:37 +01:00
Dennis Luxen 31cae8f05f several copy edits to brush up the code
- fix copyright header
- rename probabilityDensityFunction -> density_function
- use double-precision fp literal to indicate intent
- remove redundant enum class start value
- replace C-style comments with C++ style
- make functions const
2015-03-03 17:42:07 +01:00
Dennis Luxen 133e382aae remove constexpr qualifier as numeric_limits is not yet constexpr on MSVC compiler 2015-03-03 14:43:38 +01:00
Dennis Luxen e02c721c2b further untangle model from functionality and put classes into seperate headers
- move get_network_distance() into routing base class
- don't reallocate queues every time but clear them. Should be cheaper
2015-03-03 14:22:52 +01:00
Dennis Luxen 5af0ceb2d2 use range based for loop 2015-03-03 14:22:27 +01:00
Dennis Luxen 6460fdc62b use std::size_t for timestamps to avoid implicit casts, use range-based for loops 2015-03-03 13:03:00 +01:00
Dennis Luxen 402ca780bf fix test expectation osrm-routed help output 2015-03-03 12:56:37 +01:00
Dennis Luxen 643ab92cd2 fix default value for max_locations_map_matching 2015-03-03 12:55:42 +01:00
Dennis Luxen a9c3b343fc separate model and computation in HMM matching 2015-03-03 12:48:33 +01:00
Dennis Luxen 592bebaf29 renamed: plugins/map_matching.hpp -> plugins/match.hpp to avoid confusion with routing_algorithms/map_matching.hpp 2015-03-03 12:01:40 +01:00
Dennis Luxen 4df215e674 replace -std::numeric_limits<T>::max() with ::lowest() 2015-03-03 11:53:31 +01:00
Dennis Luxen 91792f45ea fix compilation
- missing new 10th parameter to GenerateServerProgramOptions
2015-03-03 11:50:37 +01:00
Dennis Luxen 20091e94c8 fix compilation
- remove wrong comments
- fix include guard footer
- add curly braces
- add template specialization for std::vector<bool> in make_array
- reformat
2015-03-03 11:50:02 +01:00
Dennis Luxen 76aa494be4 fix compilation
- std::log and M_PI are not constexpr's by the standard. replace by a constant
- reformat
2015-03-03 11:48:15 +01:00
Dennis Luxen 6fb8fdc2bd fix compilation
- define max_number_of_candidates where its used
- add curly braces
- reformat
2015-03-03 11:46:24 +01:00
Patrick Niklaus 0d879ed290 Split trace if timestamp delta is over threshold
Even when matching is not broken we split the trace, if the
sampling frequency goes below 2 samples/minute.
2015-03-03 00:48:57 +01:00
Patrick Niklaus d8d46e0f3e Add routed parameter to limit matching size 2015-03-03 00:48:57 +01:00
Patrick Niklaus e5830b0116 Add parameters for map matching 2015-03-03 00:48:57 +01:00
Patrick Niklaus d89b171f49 Simplify json code in map matching plugin 2015-03-03 00:48:57 +01:00
Patrick Niklaus a760aec791 Add json logger to map_matching
This adds additional data to the json response, when OSRM is compiled
in debug mode.
2015-03-03 00:48:57 +01:00
Patrick Niklaus 34d5d353af Apply clang-format and split out json_util 2015-03-03 00:48:57 +01:00
Patrick Niklaus e8e637c4f2 Replace descriptor code with code that generates only geometry 2015-03-03 00:48:57 +01:00
Patrick Niklaus adbca39fef Fix include guard 2015-03-03 00:48:57 +01:00
Dennis Luxen a2c88b607f lint corrections
- fix license header
- let shared_ptr autodestruct as it's shared
- rename fences to resemble file names
- reorder includes into lexicographic order
2015-03-03 00:48:57 +01:00
Patrick Niklaus 2115a67d24 Link libOSRM with compute_angle 2015-03-03 00:48:57 +01:00
Patrick Niklaus dec73b02e9 Rename traces to matchings in response 2015-03-03 00:48:57 +01:00
Patrick Niklaus 0e6ed53cee Adapt to JSON container rename 2015-03-03 00:48:57 +01:00
Patrick Niklaus fd6c70afe1 Fix regression in sub-matching length check 2015-03-03 00:48:57 +01:00
Patrick Niklaus c4f193b13e Fix comment 2015-03-03 00:48:57 +01:00
Patrick Niklaus 70703c39f3 Add timestamp parameters and reset to beginning of breakage 2015-03-03 00:48:57 +01:00
Patrick Niklaus d429485f0c Fix stupid error in backtracking 2015-03-03 00:48:57 +01:00
Patrick Niklaus 89460dd39c Return indices instead of points 2015-03-03 00:48:57 +01:00
Patrick Niklaus f46b259384 Fix splitting traces 2015-03-03 00:48:56 +01:00
Patrick Niklaus fb0ce48f2f Simplify matching response 2015-03-03 00:48:56 +01:00
Patrick Niklaus cb4a81008c Split traces into subtraces 2015-03-03 00:48:56 +01:00
Patrick Niklaus d620da365e Implement more general pruning 2015-03-03 00:48:56 +01:00
Patrick Niklaus 0c3102721c Make number of candidates a parameter 2015-03-03 00:48:56 +01:00
Patrick Niklaus b3fa03043d Calculate the real route length for classification 2015-03-03 00:48:56 +01:00
Patrick Niklaus 38d7db49c8 Add state position to debug output 2015-03-03 00:48:56 +01:00
Patrick Niklaus 1a8c832039 Update format of debug json ouput 2015-03-03 00:48:56 +01:00
Patrick Niklaus 6e54f8cfa6 Tighter threshold on low probability transistions 2015-03-03 00:48:56 +01:00
Patrick Niklaus 4838ffb82d Fix nan values if matched to single point 2015-03-03 00:48:56 +01:00
Patrick Niklaus 1bcf41d382 Prune low probability transitions 2015-03-03 00:48:56 +01:00
Patrick Niklaus e381566494 Eliminate branch 2015-03-03 00:48:56 +01:00
Patrick Niklaus 66d7a073d3 Move splitting candidates to plugin 2015-03-03 00:48:56 +01:00
Patrick Niklaus 0637215b85 Skip computing viterbi if viterbi of previous state is lower than lower bound
This causes a speedup of 300%.
2015-03-03 00:48:56 +01:00
Patrick Niklaus dc1405ffa8 Fix typo in debugging code 2015-03-03 00:48:56 +01:00
Patrick Niklaus 0fce20c503 Directly compute log probabilities 2015-03-03 00:48:56 +01:00
Patrick Niklaus 1b16dd126b Actually compute and transmit confidence in the response 2015-03-03 00:48:56 +01:00
Patrick Niklaus fe07f9208c Add bayes classifier 2015-03-03 00:48:56 +01:00
Patrick Niklaus f092fc3fc6 Fix minimum number of candidates 2015-03-03 00:48:56 +01:00
Patrick Niklaus b5228dcda0 Detect possible uturns in the data.
To make them work, we have to disable PhantomNode splitting
for this coordinates.
2015-03-03 00:48:56 +01:00
Patrick Niklaus a5db3ea25b Print warning when more than 10 points are removed 2015-03-03 00:48:56 +01:00
Patrick Niklaus 173fad2362 Return error when less than 2 points left. 2015-03-03 00:48:55 +01:00
Patrick Niklaus 496338d84d Implemented pruning and breakage detection 2015-03-03 00:48:55 +01:00
Patrick Niklaus 59727a6967 Get all nodes in dense areas but make sure we don't underflow in sparse ones 2015-03-03 00:48:55 +01:00
Patrick Niklaus 3a5e41ed91 Implement missing matching pieces 2015-03-03 00:48:55 +01:00
Dennis Luxen 2259bce05f Add skeleton code for matching 2015-03-03 00:48:55 +01:00
Dennis Luxen 7e00a86bb4 implement ISO 8601 durations parsing, cf. #1399 2015-03-02 17:18:52 +01:00
Dennis Luxen 73a2a938b4 use CRTP instead of virtual functions in routing plugins 2015-03-02 11:55:55 +01:00
Dennis Luxen c2098938f5 add convenience variadic template function to append elements to a container 2015-02-27 13:52:58 +01:00
Dennis Luxen 773ff182ee fix license header 2015-02-26 18:54:13 +01:00
Dennis Luxen 878c49e4e1 fix incomplete implementation of movable bridges in bike profiles, plenty of regressions 2015-02-26 17:17:43 +01:00
Dennis Luxen 023dd3e880 fix regression in bike profile 2015-02-26 16:44:26 +01:00
Dennis Luxen 6b88856c16 add support for movable bridges in the biking profile, cf #1399 2015-02-26 16:28:04 +01:00
Dennis Luxen dd5f926077 respect capacity:car for movable bridges in car profile 2015-02-26 16:22:18 +01:00
Dennis Luxen 845020b0e2 remove debug output 2015-02-26 16:17:42 +01:00
Dennis Luxen 7cf363eb06 reorder includes, fixes style regression from commit fdf2e59. 2015-02-26 16:09:48 +01:00
Dennis Luxen f67e670621 Merge pull request #1400 from Project-OSRM/feature/bridge_movable
add movable bridge support to the car profile. Implements #1399
2015-02-26 15:58:30 +01:00
Dennis Luxen 645e3ccbb3 add movable bridge support to the car profile. Implements #1399 2015-02-26 14:56:01 +01:00
Dennis Luxen ab385f2bf5 Merge pull request #1396 from RockLobster/develop
Small change in order to be able to use OSRM as submodule in other projects
2015-02-26 11:07:24 +01:00
Dennis Luxen 5080b9a82b Merge pull request #1397 from Project-OSRM/escape-fix
JSON string escape fix
2015-02-26 11:05:59 +01:00
Dennis Luxen 51e42ded44 - output only get escaped when actually output. Better seperation of functionality
- refactor facade::GetEscapeName() into get_name_for_id() call that is implemented in subclasses
- remove dead code
- fix failing tests where names got double-escaped
- fixes https://github.com/Project-OSRM/node-osrm/issues/83
2015-02-26 10:11:33 +01:00
Dennis Luxen 37fb89c691 add size() call to integer range 2015-02-26 10:10:19 +01:00
Patrick Niklaus 440eda3807 Escape string in json renderer 2015-02-25 21:11:02 +01:00
RockLobster bad2576397 Replaced CMAKE_SOURCE_DIR in osrm root dir's cmake file with CMAKE_CURRENT_SOURCE_DIR
=> Allows osrm to be used as a subproject aswell
2015-02-25 18:25:03 +01:00
Patrick Niklaus fdf2e5934d Add algorithm include for any_of 2015-02-24 20:29:43 +01:00
Dennis Luxen 3da1e8598b fix copyright year 2015-02-24 14:36:38 +01:00
Dennis Luxen 0296c767bf fix code-format regression 2015-02-24 09:08:59 +01:00
Dennis Luxen c215c42289 Merge pull request #1390 from Project-OSRM/feature/width_penalty
implements a penalty for very narrow roads
2015-02-24 08:56:11 +01:00
Dennis Luxen 8adab95973 refactor iterator range utility class 2015-02-20 11:59:03 +01:00
Dennis Luxen b89c7580e6 implement scaling for narrow roads as an alternative expected speed and take the minimum. Follows @emiltin's idea. 2015-02-20 10:33:14 +01:00
Dennis Luxen a85fe2cb08 remove debug output, thx @emiltin 2015-02-20 10:33:14 +01:00
Dennis Luxen 4c4c126361 implements a penalty for very narrow road:
- implements discussion of #1388
- implements basic test cases
2015-02-20 10:33:14 +01:00
Patrick Niklaus e9e12b88f8 Add CORS Content-Type HTTP header flag
Firefox needs this for JSON.
2015-02-20 00:36:36 +01:00
Dennis Luxen dc08c516bf use std::tie() to simplify lexicographic comparisons 2015-02-19 19:15:16 +01:00
Patrick Niklaus 9b1f108051 Allow CORS requests in osrm-routed. 2015-02-19 10:42:45 +01:00
Dennis Luxen b0f9a0feb4 rename variable name to be a little more telling 2015-02-19 10:11:49 +01:00
Dennis Luxen 3bd27ae8c5 change copyright line from personal names to project 2015-02-19 09:19:51 +01:00
Dennis Luxen 79b9bdf7ce rename JSON namespace to osrm::json to avoid namespace clash with V8 2015-02-18 17:27:31 +01:00
Dennis Luxen 9e09168597 un-lint CMakeLists.txt 2015-02-16 14:18:04 +01:00
Dennis Luxen e5f12347bd simplify code by using new phantom node ctor 2015-02-13 14:26:19 +01:00
Dennis Luxen 86d3556c6d add ctor that converts from rtree segment to phantom node 2015-02-13 14:24:05 +01:00
Dennis Luxen 45838b33b7 avoid implicit conversion to int 2015-02-12 15:40:55 +01:00
Dennis Luxen a1d4798ded refactor AlternativePathRouting step to have the same interface semantics regardless of search direction 2015-02-12 15:03:53 +01:00
Dennis Luxen 25c52b7482 rewrite sort/unique function to be more generic 2015-02-12 15:02:16 +01:00
Dennis Luxen fcf9f266ad Merge pull request #1381 from neilbu/develop
Made the request parser a member of the Connection
2015-02-12 14:26:48 +01:00
Neil Buckman fa638ae3a0 Removed debug logging 2015-02-12 09:55:13 +00:00
Neil Buckman 6d9cd504a0 Made the request parser a member of the Connection
Previously, the request parser was created on demand...but this could
cause requests to be flagged as bad requests if the string length was
large enough to cause the string to be split up into chunks by boost's
read_some method.
2015-02-12 08:01:46 +00:00
Dennis Luxen f9e9bb8870 update slack channel 2015-02-11 13:22:18 +01:00
Dennis Luxen 85ab2425a8 move travis notifications to slack 2015-02-11 11:47:25 +01:00
Dennis Luxen 9931155c68 port make_unique from libcxx 2015-02-10 18:02:23 +01:00
Dennis Luxen 56b6d928b6 add include to be self-sufficient 2015-02-10 12:34:13 +01:00
Dennis Luxen b865bea482 fix floating point comparison, remove superflous inline keywords 2015-02-10 12:29:52 +01:00
Dennis Luxen b6314e0c73 remove unnecessary casts in debug build 2015-02-10 12:27:27 +01:00
Dennis Luxen 2c773750c7 fix const correctness 2015-02-10 12:26:57 +01:00
Dennis Luxen 539b9be1d3 fix warning: use of old-style cast 2015-02-10 12:12:05 +01:00
Dennis Luxen 00e8caa0e3 fix signed/unsigned comparisons and casts 2015-02-10 12:08:17 +01:00
Dennis Luxen 1ff8b62bf5 fix warning: extra ';' after member function definition 2015-02-10 12:03:23 +01:00
Dennis Luxen 25fb985af8 fix warning: use of old-style cast 2015-02-10 12:02:13 +01:00
Dennis Luxen 858245db7d fix warning: implicit signed/unsigned warning 2015-02-10 11:58:56 +01:00
Dennis Luxen 09bea2ad5b fix warning: implicit float/double cast 2015-02-10 11:32:39 +01:00
Dennis Luxen adb520ec2a fix old-style casts 2015-02-10 11:31:36 +01:00
Dennis Luxen 5a1ff4b50d fix warning: implicit conversion changes signedness: 'int' to 'unsigned int' 2015-02-10 11:09:51 +01:00
Dennis Luxen e0f8acf733 make constant a float to avoid implicit cast 2015-02-10 11:04:49 +01:00
Dennis Luxen a81542eeee add virtual keyword to functions with override final specifiers 2015-02-10 10:07:35 +01:00
Dennis Luxen f67eeb66aa untangle includes using iwyu 2015-02-09 17:38:40 +01:00
Dennis Luxen 884c998622 Squashed 'third_party/variant/' content from commit 24dcab2
git-subtree-dir: third_party/variant
git-subtree-split: 24dcab23c4f70e54838e4a32a228aba8045ae17b
2015-02-09 15:19:35 +01:00
Dennis Luxen 88c8d73a94 Merge commit '884c9986229d4228374959265905cfd7b7c90c08' as 'third_party/variant' 2015-02-09 15:19:35 +01:00
Dennis Luxen 86576768d1 remove manually add variant dir 2015-02-09 15:19:19 +01:00
Dennis Luxen 3327c32b20 remove useless parantheses 2015-02-09 14:09:09 +01:00
Dennis Luxen 97ed6a3a4e remove method stubs 2015-02-09 14:06:14 +01:00
Dennis Luxen 85d8e0ac2c minor reformat 2015-02-09 09:21:44 +01:00
Dennis Luxen 2a68f9f532 rename variable name 2015-02-06 11:58:41 +01:00
Dennis Luxen b55d35c7bb remove a number of useless parentheses 2015-02-06 09:54:34 +01:00
Dennis Luxen 98f85d7728 remove some lint in variable names 2015-02-05 18:33:21 +01:00
Dennis Luxen 328a7caf61 rename short variable names to be more telling 2015-02-05 17:54:32 +01:00
Dennis Luxen 275ea9b0bb mark GetTravelModeForEdgeID as override final 2015-02-05 15:20:15 +01:00
Dennis Luxen bb78bc8fe3 Squashed 'third_party/libosmium/' changes from 910f8f1..6522da5
6522da5 Merge pull request #79 from DennisOSRM/master
7c8d8dc add override keyword to close(), overridden function in include/osmium/io/detail/input_format.hpp
d24841e Changes copyright dates in all files to a consistent "2013-2015".
3adc7d7 Another try to make it compile on Windows.
20dad8e Use auto instead of hard-coded types, hopefully fixes Windows build.
b73ab3f Set build config in appveyor ctest call.
3e33857 Merge pull request #76 from BergWerkGIS/master
c78ca6e Merge remote-tracking branch 'upstream/master'
cf42013 enable test again
69e4a91 include compatibility.h
6f79b5c CMake: Remove Dart include, it seems to be superfluous.
4d40a18 Explicitly set copy constructors etc. for OutputIterator and test it.
69ee34c Run tests in build directory instead of source directory.
11c44c8 Fix typo.
675cc11 Fix formatting CMake config.
7aa3cb0 Add a benchmark counting amenity=post_box tags.
89fd942 Make it more evident that we handling constant tag lists.
c72bbdf Add count() and empty() functions to Filter class.
88b9543 Disable annoying warnings from YouCompleteMe.
6cec403 Benchmarks: Only find files, not directories etc. in data dir.
09c4630 Follow redirects in benchmark download script.
a8a552e Use Approx() function from Catch framework for floating point comparisons.
7db5086 Reorder data tests so fast tests run first.
24ce403 Fix #includes.
ad9515c Add some comments in different config files to explain what they are.
987aa9c Some README updates.
3c18de7 Add configuration for YouCompleteMe Vim plugin.
433148e Explicit comparison against 0 to avoid warning with MSVC.
e64a459 Small updates in benchmarks README.
e4aff7f Add benchmark to compare static vs. dynamic index maps.
f702634 Add missing include.
95a8c3b Merge branch 'master' of github.com:osmcode/libosmium
560a2ae Merge pull request #73 from osmcode/travis-fix
f41e4ca remove incorrect cd
f826107 Add some helper functions for working with entity_bits.
8fec1c1 Updated README: Lots of documentation is now on wiki.
6110cc8 Make cmake config work if no components are given.
8136557 Use 'Libosmium' instead of 'Osmium' as project name in doc.
10e631a Improved documenation: Dependencies to link with.
41d0ca4 Merge remote-tracking branch 'upstream/master'
6768026 SLN configuration is always 'Release'
5d985cf av: show env vars.
272ac88 don't use '%CONFIGURATION%' expands to e.g. 'Dev|x86'
59b15eb use cmake 3.1.0 again. old cmake on AppVeyor doesn't know yet about VS2014 SLN
0d0d71a try building with VS, Dev works only with VS at least locally
2fe6d02 name of geos.lib changed
fc4662e test latest binary package
d4a265f Add more labels to tests.
8722a3d Only check for valgrind if testing is enabled.
cf7dc56 README improvements.
13a426e Fix cpack configuration.
ae649c8 travis build: fix double install of make package
c102040 Move cmake config for documentation into doc directory.
6064d55 Also list advanced cmake variables in travis build.
c299bfa constexprt workaround for MSVC.
afcf7a1 Cleanup/formatting of cmake config.
a536720 Fix travis build by cloning osm-testdata in the right place.
2bdbf7f cmake: Don't clone osm-testdata repository any more.
5bdbb28 Rename test/osm-testdata to test/data-tests.
0ad0020 cmake: build data tests only by default on Dev builds
2cefa50 Add some benchmarks.
3fdb6e1 Remove outdated make_osmium_project.sh script.
aca58ac Fix cmake config: overwriting of variables.
152e318 Fix compilation of examples that need wingetopt on Windows.
ae17cd0 Remove superfluous warning on Windows for header test builds.
f88d4c2 Switch to /W3 on Windows.
8edeba5 Remove duplicate copy constructor.
cdb474e Cleanup examples cmake config
ca9045a Cmake cleanup.
501eb61 Update to new version of catch unit test framework.
0646d6c Parenthesize expression to make test clearer and avoid warnings.
dfdaeae Disable a warning that gdal throws on Windows.
eacfe4f Explicitly test int !=0 to convert to bool.
b3ba693 Cleanup of cmake config (mostly warning options Linux vs. Win)
3f5cb81 Appveyor: Also show advanced cmake variables.
b544bd9 Never return valid but empty buffer from Reader.read() call.
a34bb5d Declare var in a more local scope.
b83e5f1 Merge pull request #66 from BergWerkGIS/master
04ef1b2 Last try for today, should solve geos test failures
a749d6c hey AppVeyor: what's going on?
73131fb av: boost not found?? show directory tree
5e02886 av: should solve most "***Exception: Other" except for geos.dll related problem. should solve projection test fails.
a7ae560 FlexReader now takes location handler as parameter.
6f1bd8d Disable non-existing Debian build in Makefile.
3d75178 Change warning level on MSVC.
3f0abc0 Appveyor: List cached variables from cmake.
d1e1e9f Travis/Appveyor build in Dev and Release mode. Call ctest on Appveyor.
116bcc9 Fix default node location store.
dedfe0e Make classes we submit to queue properly copyable.
8a432c9 Try the same ugly hack on OPLOutputBlock.
9c5b314 Try a hack to see whether it works on MSVC.
9592132 Give XMLOutputBlock a copy constructor.
991f91a Disable warning C4715: "not all control paths return a value"
340a4d7 Fix copy constructor.
7ceae00 Give OPLOutputBlock a copy constructor which basically does a move.
e82951a Use rvalue as paremeter for queue submit function.
54a9cec Use explicit cast to double to silence warning.
7c5d04c Simplified use of ogr includes.
43fd388 Use appveyor supplied cmake.
ce4311e cmake cleanup.
1108517 Disable warnings from MSVC in OGR headers.
2fe820c Harmonize signature of virtual member function dump_as_list().
93c31b4 Parenthesize string in pragma message.
54ae1a0 Explicitly int to bool conversion to silence warning on MSVC.
4bde9b7 Formatting: Use spaces instead of tabs.
7224d84 cmake: Don't try to set C++ version with -std= with MSVC.
53fbcfd Remove trailing semikolon (which gcc doesn't like).
3b0c9ed Removed command that doesn't work on older cmakes.
de6cc78 Merge pull request #62 from BergWerkGIS/master
9126530 Use less warning options on Windows.
6ec79fb Silence unknown pragma warning on Windows.
b611589 Add static_cast to silence warning on windows.
18e54e9 remove call to build2.bat
b0d9d28 try again with -DCMAKE_BUILD_TYPE=Release
b495018 usage installed cmake, -DCMAKE_BUILD_TYPE=Dev
5bac95d Merge remote-tracking branch 'upstream/master'
d41ea31 cmake: Do not use -Werror when using MSVC compiler
04cfe00 Provide convenience include file to include all index maps.
72fbaa7 Rename multimap indexes according to new schema.
af49a27 Make registering index map types easier.
0a35701 av: remove debug echo calls
886c15f av: ditch -DCMAKE_BUILD_TYPE=Dev
ad0a629 The great renaming of map index classes.
97b4d34 av: try again
bf243b2 Move some hpp files into detail directory and fix include guards.
64e4841 av: try again calling cmake directly
1700789 Add way to dynamically choose node location index.
da49b7f av: try again with build2.bat
4bf55f5 is appveyor working again?
5e63433 delete ws_32.lib patch. generate makefile instead of VS
1054016 Merge remote-tracking branch 'upstream/master'
8c198fc av: try even newer cmake
7cccb06 av: maybe newer cmake helps
d04967a av: no existing env var was still there
80763c6 av: no build.bat, call cmake directly
3b58fc6 av: no cmds over spanning serveral lines?
33c09a0 CALL bat
34639c6 maybe double quotes?
72572de explicitly call VS2014 cmd prompt
6955e87 1st try on AppVeyor

git-subtree-dir: third_party/libosmium
git-subtree-split: 6522da53748e12379bbfaf70ad29ee7bd98ef02d
2015-02-05 15:13:48 +01:00
Dennis Luxen 10224a692b Merge commit 'bb78bc8fe305eef39ca0a5d5e9dedc466f803dfb' into develop 2015-02-05 15:13:48 +01:00
Dennis Luxen 3eb83d0737 add override final specifier to GetTravelMode function in facades 2015-02-05 14:58:07 +01:00
Dennis Luxen f35fa0049c reformat cherry-picked commit 2015-02-05 11:54:30 +01:00
Ben d77a88c21e added lua binding for osmium::Way::id()
Conflicts:
	extractor/scripting_environment.cpp
2015-02-05 11:54:07 +01:00
Dennis Luxen 3d55622237 search quietly for OpenMP 2015-02-05 11:37:55 +01:00
Dennis Luxen bf76465029 use C++11s std::hypot() instead of hand-rolled code 2015-02-05 11:22:46 +01:00
Ben 129a6ed99e added lua binding for osmium::Way::id() 2015-02-04 19:36:39 +00:00
Dennis Luxen 9f5fc4ab0c reorder includes 2015-01-31 21:17:16 +01:00
Dennis Luxen 97f6468663 yet another try to unhack libgomp linking: use OpenMP binding if and only if present 2015-01-29 17:29:03 +01:00
Dennis Luxen a883b73981 add explicit cmake checking step for libgomp 2015-01-29 17:01:08 +01:00
Dennis Luxen 36aadc21a7 fix names of fwd declarations 2015-01-29 16:48:59 +01:00
Dennis Luxen da469911d3 always link against libgomp 2015-01-29 16:23:04 +01:00
Dennis Luxen 4195b0d0e6 Merge pull request #1364 from Project-OSRM/feature/check_libgomp
check if stxxl compiles with or without libgomp, fixes #1361
2015-01-29 12:54:27 +01:00
Dennis Luxen d241aef502 fix checking for successful compilation of stxxl with OpenMP 2015-01-29 12:52:54 +01:00
Dennis Luxen 8b2ca6b13d check if stxxl compiles with or without libgomp, fixes #1361 2015-01-29 12:52:54 +01:00
Dennis Luxen ade94c87b5 remove constexpr keyword that MSVC2013CTP isnt able to handle 2015-01-29 12:50:06 +01:00
Dennis Luxen 46f3426c35 remove Http dir 2015-01-28 12:40:42 +01:00
Dennis Luxen 3503cd9b71 remove another windows directory from ignored files/dirs 2015-01-28 12:35:52 +01:00
Dennis Luxen 73cc040792 add new lower case files and directories to .gitignore 2015-01-28 12:32:09 +01:00
Dennis Luxen 6c6029618a remove left-over directories from the renaming spree 2015-01-28 12:30:14 +01:00
Dennis Luxen 2a8084b6c6 clean up derived classed and their functions to correctly use final keyword:
functions marked as final need to be marked virtual. use override specifier to do so
2015-01-28 12:03:21 +01:00
Dennis Luxen 86ca9bd0f9 mark simple logger write function as noexcept. 2015-01-28 10:09:46 +01:00
Dennis Luxen b192678abf add dummy case to switch statement. reflects all cases are covered and should shut up compiler warnings 2015-01-27 18:44:06 +01:00
Dennis Luxen 9a998d7b41 rename short variable name to be more telling 2015-01-27 18:40:01 +01:00
Dennis Luxen 64a6859753 reduce number of old-style casts 2015-01-27 18:37:52 +01:00
Dennis Luxen b20b7e65bf renamed: Util/* -> util/* 2015-01-27 17:47:23 +01:00
Dennis Luxen 203e3ef077 fix test after header file rename 2015-01-27 17:16:50 +01:00
Dennis Luxen 7be5502a12 renamed: Util/BoostFileSystemFix.h -> Util/boost_filesystem_2_fix.hpp
renamed:    Util/TrigonometryTables.h -> Util/trigonometry_table.hpp
2015-01-27 17:14:03 +01:00
Dennis Luxen 0de6e4ccbb renamed: Util/DataStoreOptions.h -> Util/datastore_options.hpp
renamed:    Util/ProgramOptions.h -> Util/routed_options.hpp
2015-01-27 17:06:10 +01:00
Dennis Luxen c8041bacd6 renamed: Util/IniFileUtil.h -> Util/ini_file.hpp 2015-01-27 16:57:50 +01:00
Dennis Luxen 1187f83ffd renamed: Library/*.h -> library/*.hpp 2015-01-27 16:35:19 +01:00
Dennis Luxen dd3b8469dd renamed: Include/* include/* 2015-01-27 13:17:18 +01:00
Dennis Luxen 34bbd7dcaa renaming yet another variable to fix gcc name lookup 2015-01-27 13:11:04 +01:00
Dennis Luxen 8318b3ba83 rename variable to be more telling that it's not a type but a variable 2015-01-27 13:01:33 +01:00
Dennis Luxen 6768ecc3fc rename variable to make name lookup not fail on gcc 2015-01-27 12:52:55 +01:00
Dennis Luxen 9672f00ec3 renamed: Server/*/*.h -> server/*/*.hpp 2015-01-27 12:35:29 +01:00
Dennis Luxen 0c1101739d renamed: Server/DataStructures/*.h -> Server/data_structures/*.hpp 2015-01-27 12:14:08 +01:00
Dennis Luxen 872cb2d9c8 rename string literal names to replace odd camel case 2015-01-27 11:52:56 +01:00
Dennis Luxen 3e47fe54fa refactor Server/Http to remove camel case 2015-01-27 11:45:33 +01:00
Dennis Luxen f0d3d23b5f make http header parsing case insensitive, and remove some dead code (reset function) 2015-01-27 09:58:26 +01:00
Dennis Luxen 69e59b0ced rename clear() function to reduce camel case noise 2015-01-27 09:57:14 +01:00
Dennis Luxen ad4fb5afe3 revert previous commit that replace boost::array by std::array. not compatible with clang-3.5/boost1.54 2015-01-26 17:37:37 +01:00
Dennis Luxen dd6dd63798 rename iterator variable to be more telling 2015-01-26 16:35:16 +01:00
Dennis Luxen 7a3748b8f6 remove redundant c'tor call 2015-01-26 16:34:05 +01:00
Dennis Luxen 06a08a874f fix performance regression in output generation, use copy elision and return result char array 2015-01-26 13:49:07 +01:00
Dennis Luxen 37a9813482 replace boost::array by std::array 2015-01-26 13:26:21 +01:00
Dennis Luxen fe7b436a8c refactor request parser to use C++11 idioms, plus a couple of consts 2015-01-26 13:20:22 +01:00
Dennis Luxen 601eff1af6 initialize compression type to be no compression 2015-01-26 11:25:10 +01:00
Dennis Luxen 29949eae1b remove unneeded include to boost/tribool 2015-01-23 18:55:58 +01:00
Dennis Luxen 9dfe6d1e85 use std::tuple to return multiple return values, hope for copy elision. Also, removes two cases of parameter reassignment 2015-01-23 18:53:37 +01:00
Dennis Luxen fb3bc22c64 replace boost::tribool with enum based implementation 2015-01-23 18:18:29 +01:00
Dennis Luxen b89304a24b add enum class based tribool implementation 2015-01-23 17:46:23 +01:00
Dennis Luxen 69b3457e83 replace boost::tuple by std::tuple 2015-01-23 17:14:12 +01:00
Dennis Luxen cf21074f10 use enum as return code instead of boolean logic in extractor 2015-01-23 16:59:13 +01:00
Dennis Luxen dc7f21513a move initialization of extractor config into main method and out out extraction logic 2015-01-23 16:30:14 +01:00
Dennis Luxen a15450af91 manually revert previous change as g++ doesnt convert bitfields properly 2015-01-23 14:24:02 +01:00
Dennis Luxen efbcce0ffe use bitfields to reduce struct size of segment information. size goes down from 28->24 bytes 2015-01-23 13:53:02 +01:00
Dennis Luxen 1c2c87e03d fix boundary edge case 2015-01-23 13:52:44 +01:00
Dennis Luxen 93b33c0518 fix cast to be explicit 2015-01-23 13:52:28 +01:00
Dennis Luxen 53e01952be replace for loops with counters by range-based for loops 2015-01-23 12:19:01 +01:00
Dennis Luxen 1c12b468a8 replace for loop with hand-rolled pair-wise traverse of container with call to for_each_pair; fix target type of cast 2015-01-23 12:11:51 +01:00
Dennis Luxen ccd803416e fix unintended float/epsilon<double> comparison 2015-01-23 11:49:02 +01:00
Dennis Luxen 62f2a42f28 reduce cyclomatic complexity in double->string bearing conversion 2015-01-23 11:44:35 +01:00
Dennis Luxen d6e76fd1c0 add whitespace 2015-01-23 11:38:47 +01:00
Dennis Luxen 9135c56ac6 fix implicit float/double conversion, use casts 2015-01-23 11:26:47 +01:00
Dennis Luxen 0e7eff3963 rename short variable names in mercator to be more telling 2015-01-23 11:14:29 +01:00
Dennis Luxen bd1928e445 rename short variable names to be more telling 2015-01-23 09:47:44 +01:00
Dennis Luxen 8e105af232 remove redundant code from switch statement in restriction parser 2015-01-23 09:25:05 +01:00
Dennis Luxen 796cbafde4 add missing include in release build 2015-01-22 17:57:38 +01:00
Dennis Luxen 29354a1586 fix bearing computation 2015-01-22 17:07:04 +01:00
Dennis Luxen bcd73e604c reformat coordinate and rtree test code 2015-01-22 17:00:48 +01:00
Dennis Luxen e80ca6553d use new coordinate interface in unit tests 2015-01-22 16:58:45 +01:00
Dennis Luxen 90f17c2140 remove is_set() and reset() functions from coordinate 2015-01-22 16:55:34 +01:00
Dennis Luxen 2e5cc1e6ae remove redundant code and streamline coordinate interface 2015-01-22 16:48:53 +01:00
Dennis Luxen 0ea7fd9c3d remove more dead/unused functions 2015-01-22 16:41:04 +01:00
Dennis Luxen 814d9aa01b reformat code source file 2015-01-22 16:33:27 +01:00
Dennis Luxen 3fa12445a5 rename coordinate calculation functions, remove code clutter 2015-01-22 16:28:40 +01:00
Dennis Luxen 547a2aec09 remove dead/redundant code 2015-01-22 15:50:04 +01:00
Dennis Luxen 9175fb7da8 remove unused debug code 2015-01-22 15:19:43 +01:00
Dennis Luxen 887032881a use std::any_of() algorithm instead of hand-rolled logic 2015-01-22 15:09:24 +01:00
Dennis Luxen e67f82283f replace temporary variable with short name by atomic<>.load call 2015-01-22 13:47:31 +01:00
Dennis Luxen cfa83658dc Use early exit/continue to simplify code and reduce indentation 2015-01-22 12:39:41 +01:00
Dennis Luxen c881aa7b32 Use early exit/continue to simplify code and reduce indentation, move increase/decrease query count into functions 2015-01-22 12:38:48 +01:00
Dennis Luxen a8db29399f remove unneeded else block in if statement 2015-01-22 12:28:00 +01:00
Dennis Luxen baacd0e50c reformat source files 2015-01-22 12:24:54 +01:00
Dennis Luxen 0f8c3b1960 fix copyright year 2015-01-22 12:18:48 +01:00
Dennis Luxen cd523cc934 conflate collapsable if statements 2015-01-22 12:14:14 +01:00
Dennis Luxen 044271a55c specialize insert function to pass by reference for non-fundamental types by using type traits 2015-01-22 11:02:49 +01:00
Dennis Luxen f662b9a081 install libgdal-dev on Travis 2015-01-20 18:45:49 +01:00
Dennis Luxen ba10f97420 add third_party directory node to the include dirs 2015-01-20 18:23:10 +01:00
Dennis Luxen 50c460ebd5 install mapbox/variant headers from third_party directory 2015-01-20 18:07:45 +01:00
Dennis Luxen 501863a0eb move external dependence mapbox/variant into third_party directory 2015-01-20 18:06:26 +01:00
Dennis Luxen ec9b2dbe42 remove debug info from binaries 2015-01-20 17:57:47 +01:00
Dennis Luxen db2ba22bd6 fix tests to run with new header coordinate_calculations 2015-01-20 17:56:50 +01:00
Dennis Luxen 087f08dad2 also build tests on travis CI 2015-01-20 17:56:30 +01:00
Dennis Luxen bf7b146dfc Merge pull request #1350 from Project-OSRM/feature/prune_incremental_search
speed up nearest neighbor query by pruning
2015-01-20 17:36:23 +01:00
Dennis Luxen 01f3237416 speed up nearest neighbor query by pruning, move coordinate calculations away from library interface 2015-01-20 16:24:49 +01:00
Dennis Luxen 8f813fbc67 clear result nodes/way in parser for each parsed element 2015-01-20 11:25:21 +01:00
Dennis Luxen f4ff695080 replace conditional operator by explicit serialization 2015-01-20 10:50:33 +01:00
Dennis Luxen 08cc2bbd70 move thread local variables out of parsing scope 2015-01-16 18:22:37 +01:00
Dennis Luxen 46a7e46068 serialize lvalues as MSVC barfs out on serializing the return value of the conditional operator 2015-01-16 18:12:21 +01:00
Dennis Luxen 472a567f42 add cmath include to fix call to std::abs() on clang compiler, reorder includes 2015-01-16 17:23:29 +01:00
Dennis Luxen f3bc1ed3a9 make floating point number literal a float 2015-01-16 17:21:02 +01:00
Dennis Luxen 7ba9b97afc reorder members of internal extractor edge. 56->40 bytes 2015-01-16 17:11:30 +01:00
Dennis Luxen 061d281d2a serialize bitfields thru local member mockups 2015-01-16 17:10:31 +01:00
Dennis Luxen 2835508292 fixes #1346:
- use const_iterator where it makes sense
- fix renumbering of turn restriction members
- remove redundant code
- fix counting of usable turn restrictions
2015-01-16 15:56:49 +01:00
Dennis Luxen 959d9a3ad9 explicitly implement check if is_only turn is restricted 2015-01-16 15:52:41 +01:00
Dennis Luxen 7cf34a6d6f make debug output more verbose during renumbering of turn restriction members 2015-01-16 15:47:01 +01:00
Dennis Luxen 8d6d7d1f20 remove superflous inline keywords 2015-01-16 11:27:46 +01:00
Dennis Luxen b115764d9c Merge pull request #1347 from Project-OSRM/perpendicular-fix
Fix ComputePerpendicularDistance convinience function
2015-01-16 09:53:49 +01:00
Patrick Niklaus 1b5d332e93 Add regression test for FixedpointCoordinate 2015-01-16 00:49:43 +01:00
Patrick Niklaus 356dfc806d Fix ComputePerpendicularDistance convinience function
This function is used by StaticRTree and returns wrong results.
The other variation is correct. To reduce code duplication
the correct version is used instead, as the implementation is nearly
identical.
2015-01-16 00:34:07 +01:00
Dennis Luxen f2b556adfd umbenannt: UnitTests/* -> unit_tests/* 2015-01-15 18:39:26 +01:00
Dennis Luxen 1bbfced61a reorder includes 2015-01-15 18:10:22 +01:00
Dennis Luxen 800cb8c6dd renamed: ../UnitTests/data_structures/BinaryHeapTest.cpp -> ../UnitTests/data_structures/binary_heap.cpp
renamed:    ../UnitTests/data_structures/RangeTableTest.cpp -> ../UnitTests/data_structures/range_table.cpp
renamed:    ../UnitTests/data_structures/StaticGraphTest.cpp -> ../UnitTests/data_structures/static_graph.cpp
renamed:    ../UnitTests/data_structures/StaticRTreeTest.cpp -> ../UnitTests/data_structures/static_rtree.cpp
2015-01-15 18:07:47 +01:00
Dennis Luxen 6b1d672dc1 fix signed/unsigned comparison 2015-01-15 13:11:25 +01:00
Dennis Luxen 6e138bbf54 fixes data structure tests:
- MapStorage: fix returned index in peek_index() on fail
- UnorderedMapStorage: fix returned index in peek_index() on fail
- BinaryHeap: auto-deduce Index type
- ArrayStorage: replace raw array with std::vector
2015-01-15 12:59:08 +01:00
Dennis Luxen 6dabf4507a implement peek_index() functions for all binary heap storage classes 2015-01-15 11:15:48 +01:00
Dennis Luxen 527e6cbc72 xor fast hash storage: reorder initialization of elements, delete default c'tor, resetting of table may be expensive as it is rare 2015-01-14 18:14:55 +01:00
Dennis Luxen 39edbcbabd after profiling with intel vtune, mitigate some performance hotspots. may give a 10-20% performance boost during preprocessing 2015-01-14 17:26:59 +01:00
Dennis Luxen 0077856d2f Merge commit 'b65f1d7df0b997eac085da7f5a3344a86b812916' as 'Include/variant' 2015-01-14 09:36:20 +01:00
Dennis Luxen b65f1d7df0 Squashed 'Include/variant/' content from commit 00ab881
git-subtree-dir: Include/variant
git-subtree-split: 00ab88117ed25f78cdca2faa00beea0061271e85
2015-01-14 09:36:20 +01:00
Dennis Luxen 201afbbeec rm hard copy of variant. 2015-01-14 09:32:43 +01:00
Dennis Luxen f5caf96d2e add new include dir of libosmium 2015-01-13 17:14:54 +01:00
Dennis Luxen 73efcc6b0c Squashed 'third_party/libosmium/' content from commit 910f8f1
git-subtree-dir: third_party/libosmium
git-subtree-split: 910f8f1e992402e0f1acd0132eaffa7539ca83d2
2015-01-13 16:54:25 +01:00
Dennis Luxen d69510f997 Merge commit '73efcc6b0ccedf8c1b6d95abdba8340cc9adf100' as 'third_party/libosmium' 2015-01-13 16:54:25 +01:00
Dennis Luxen d6946a8aae remove copy of libosmium, to be replaced by a subtree 2015-01-13 16:50:31 +01:00
Dennis Luxen ebbc168f3f fix implicit integer cast, reorder includes 2015-01-13 16:46:44 +01:00
Dennis Luxen 347cbd37ca fix include guard naming in plugin base 2015-01-13 16:15:51 +01:00
Dennis Luxen d190e0b771 Merge pull request #1343 from Project-OSRM/feature/static_graph_components
use static graph for component exploration, closes #1288
2015-01-13 16:06:48 +01:00
Dennis Luxen 5f28a7db0d add some whitespace 2015-01-13 15:52:24 +01:00
Dennis Luxen d0c99f1999 fix linking of benchmarks and tests 2015-01-13 15:45:27 +01:00
Dennis Luxen bf71781ee9 new file: Util/mercator.cpp
renamed:    Util/MercatorUtil.h -> Util/mercator.hpp
2015-01-13 14:57:23 +01:00
Dennis Luxen fbce104f3b use static graph for component exploration, closes #1288 2015-01-13 14:24:56 +01:00
Dennis Luxen ef9074f8e4 renamed: Util/finger_print.* -> Util/fingerprint.*
thx @emiltin
2015-01-13 11:16:13 +01:00
Dennis Luxen 67f3111cc0 renamed: Util/FingerPrint.h -> Util/finger_print.hpp 2015-01-13 11:05:22 +01:00
Dennis Luxen 56d2101b1a Merge pull request #1339 from Project-OSRM/test_appveyor_default_os
remove explicit appveyor os spec to get scheduled on hyper-v
2015-01-12 16:28:27 +01:00
Emil Tin a28395b116 remove accidentally added files 2015-01-12 13:58:32 +01:00
Emil Tin eebf3a54e2 cuke: abort if bins are missing, closes #1341 2015-01-12 13:56:43 +01:00
Dennis Luxen 7e70fa63d7 Merge pull request #1338 from frodrigo/develop
Black list access=psv for car profile
2015-01-09 23:39:49 +01:00
Dennis Luxen bea4b520c0 Revert "Revert "fix #1255 assume lift gates are passable""
This reverts commit cec3d1488a.

*sigh*
2015-01-09 19:15:00 +01:00
Dennis Luxen 64c17c4ecd remove explicit appveyor os spec to get scheduled on hyper-v 2015-01-09 18:53:15 +01:00
Frederic Rodrigo 26f7ac9ca1 Black list access=psv for car profile 2015-01-09 17:14:16 +00:00
Dennis Luxen b1a12768e1 fix parameter name for maximum number of location in distance table plugin 2015-01-08 17:41:19 +01:00
Dennis Luxen 0e5a448d04 Merge pull request #1335 from Project-OSRM/feature/frodrigo-max_locations_distance_table
Feature/frodrigo max locations distance table
2015-01-08 16:07:17 +01:00
Dennis Luxen 91a89399f8 fix copyright year 2015-01-08 15:07:01 +01:00
Dennis Luxen c6bb7c5993 renamed: Include/osrm/ServerConfig.h -> Include/osrm/libosrm_config.hpp
pass lib config object by reference
2015-01-08 15:05:54 +01:00
Dennis Luxen 48b131eb5c Merge branch 'max_locations_distance_table' of https://github.com/frodrigo/osrm-backend into frodrigo-max_locations_distance_table
Conflicts:
	Library/OSRM.h
	Library/OSRM_impl.cpp
	Library/OSRM_impl.h
2015-01-08 14:49:10 +01:00
Dennis Luxen 1328be2b61 move structs into anon namespace, move containers in function scope 2015-01-07 12:30:01 +01:00
Dennis Luxen 88c1e622dd fix copyright year 2015-01-07 12:29:13 +01:00
Dennis Luxen 10672786a1 fix copyright year and include guard 2015-01-07 12:28:26 +01:00
Dennis Luxen d896a9efec remove superflous inline keywords as this DeallocatingVector is header-defined, also remove ignored const keywords 2015-01-07 12:26:49 +01:00
Dennis Luxen 0ccdd4b6ad fix implicit conversion that _may_ lose integer precision 2015-01-07 12:26:09 +01:00
Dennis Luxen 66fc676858 remove unused parameter, move previously templated function into compile unit 2015-01-06 20:05:33 +01:00
Frederic Rodrigo 12f2acc9ff Order ServerPaths members by memory size, pass ServerPaths by ref 2015-01-06 15:33:57 +00:00
Dennis Luxen b53e8bf501 remove implicit conversion 2015-01-06 15:31:55 +01:00
Dennis Luxen e296264ea6 Merge pull request #1292 from Project-OSRM/feature/json_lib_interface
Feature/json lib interface
2015-01-06 15:27:40 +01:00
Frédéric Rodrigo 598f5519d1 Remove setters from structures server_config 2015-01-06 14:11:09 +00:00
Frédéric Rodrigo ced64d7a09 Move server configuration from method parameter to a struct 2015-01-06 14:11:09 +00:00
Frédéric Rodrigo 7075a8a8ef Fix tests for new option --max_locations_distance_table 2015-01-06 14:11:09 +00:00
Frédéric Rodrigo e2605c2838 Add a commande line option to osrm-routed for max locations supported in distance table query 2015-01-06 14:11:09 +00:00
Dennis Luxen be63939441 fix includes 2015-01-06 13:35:36 +01:00
Dennis Luxen dea9c37d99 fix bad request error message 2015-01-06 13:27:51 +01:00
Dennis Luxen 4d27366ead fix compilation of benchmark tests 2015-01-06 13:27:51 +01:00
Dennis Luxen a11a8429bb remove unneeded header file 2015-01-06 13:27:51 +01:00
Dennis Luxen 6da33cafe5 rebase branch onto latest develop, report changes. hurt a little 2015-01-06 13:27:50 +01:00
Dennis Luxen 06f82d5e8a install variant by default 2015-01-06 13:22:12 +01:00
Dennis Luxen 89dd0c4a40 install headers with .hpp suffix 2015-01-06 13:22:12 +01:00
Dennis Luxen 1b10f53eff DataStructures/RawRouteData.h -> DataStructures/internal_route_result.hpp, implements #1238 2015-01-06 13:22:12 +01:00
Dennis Luxen 8bd7d57dd8 fixed compilation of simple client
- adapted to new lib interface
- fixed return codes of command line parsing
- reformatted code
2015-01-06 13:20:56 +01:00
Dennis Luxen 4a6325696e change library interface to expose json container as structure to exchange data 2015-01-06 13:19:21 +01:00
Dennis Luxen b50a907ca3 fix changed include paths 2015-01-06 13:17:12 +01:00
Dennis Luxen 59e9a67abd rename and remove include header files for stabilized lib API 2015-01-06 13:09:44 +01:00
Liu Jiaming 1d2f06df6d Fix std::list splice usage error 2015-01-06 13:02:05 +01:00
662 changed files with 75672 additions and 15725 deletions
+4
View File
@@ -0,0 +1,4 @@
---
Checks: '-clang-analyzer-*,google-*,llvm-*,misc-*,readability-*,-google-build-explicit-make-pair,-google-explicit-constructor,-google-readability-braces-around-statements,-google-readability-casting,-google-readability-namespace-comments,-google-readability-function,-google-readability-todo,-google-runtime-int,-llvm-namespace-comment,-llvm-header-guard,-llvm-twine-local,-misc-argument-comment,-readability-braces-around-statements,-readability-identifier-naming'
...
+5 -20
View File
@@ -1,3 +1,7 @@
# pre compiled dependencies #
#############################
osrm-deps
# Compiled source #
###################
*.com
@@ -36,8 +40,6 @@ Thumbs.db
# build related files #
#######################
/build/
/Util/finger_print.cpp
/Util/git_sha.cpp
/cmake/postinst
# Eclipse related files #
@@ -53,25 +55,8 @@ Thumbs.db
stxxl.log
stxxl.errlog
# compiled protobuffers #
#########################
/DataStructures/pbf-proto/*.pb.h
/DataStructures/pbf-proto/*.pb.cc
# External Libs #
#################
/lib/
/win/lib
# Visual Studio Temp + build Files #
# Compiled Binary Files #
####################################
/win/*.user
/win/*.ncb
/win/*.suo
/win/Debug/
/win/Release/
/win/bin/
/win/bin-debug/
/osrm-extract
/osrm-io-benchmark
/osrm-components
+140 -54
View File
@@ -1,60 +1,146 @@
language: cpp
compiler:
- gcc
# - clang
# Make sure CMake is installed
install:
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
- sudo add-apt-repository -y ppa:boost-latest/ppa
- sudo apt-get update >/dev/null
- sudo apt-get -q install protobuf-compiler libprotoc-dev libprotobuf7 libprotobuf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
- sudo apt-get -q install g++-4.8
- sudo apt-get install libboost1.54-all-dev
# luabind
- curl https://gist.githubusercontent.com/DennisOSRM/f2eb7b948e6fe1ae319e/raw/install-luabind.sh | sudo bash
# osmosis
- curl -s https://gist.githubusercontent.com/DennisOSRM/803a64a9178ec375069f/raw/ | sudo bash
# cmake
- curl -s https://gist.githubusercontent.com/DennisOSRM/5fad9bee5c7f09fd7fc9/raw/ | sudo bash
# osmpbf library
- curl -s https://gist.githubusercontent.com/DennisOSRM/13b1b4fe38a57ead850e/raw/install_osmpbf.sh | sudo bash
before_script:
- rvm use 1.9.3
- gem install bundler
- bundle install
- mkdir build
- cd build
- cmake .. $CMAKEOPTIONS
script:
- make -j 2
- make -j 2 tests
- ./datastructure-tests
- cd ..
- cucumber -p verify
after_script:
# - cd ..
# - cucumber -p verify
sudo: required
dist: trusty
notifications:
email: false
branches:
only:
- master
- develop
cache:
- bundler
- apt
env:
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5000 OSRM_TIMEOUT=60
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5010 OSRM_TIMEOUT=60
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
matrix:
include:
# 1/ Linux Clang Builds
- os: linux
compiler: clang
addons: &clang38
apt:
sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test']
packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'rubygems-integration', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
env: COMPILER='clang++-3.8' BUILD_TYPE='Release'
- os: linux
compiler: clang
addons: &clang38
apt:
sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test']
packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'rubygems-integration', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
env: COMPILER='clang++-3.8' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
- os: linux
compiler: clang
addons: *clang38
env: COMPILER='clang++-3.8' BUILD_TYPE='Debug'
# 2/ Linux GCC Builds
- os: linux
compiler: gcc
addons: &gcc48
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'rubygems-integration', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
env: COMPILER='g++-4.8' BUILD_TYPE='Release'
- os: linux
compiler: gcc
addons: *gcc48
env: COMPILER='g++-4.8' BUILD_TYPE='Debug'
- os: linux
compiler: gcc
addons: &gcc5
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'rubygems-integration', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
env: COMPILER='g++-5' BUILD_TYPE='Release'
- os: linux
compiler: gcc
addons: &gcc5
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'rubygems-integration', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
env: COMPILER='g++-5' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
- os: linux
compiler: gcc
addons: *gcc5
env: COMPILER='g++-5' BUILD_TYPE='Debug'
# Disabled until tests all pass on OSX:
#
# 3/ OSX Clang Builds
#- os: osx
# osx_image: xcode6.4
# compiler: clang
# env: COMPILER='clang++' BUILD_TYPE='Debug'
#- os: osx
# osx_image: xcode6.4
# compiler: clang
# env: COMPILER='clang++' BUILD_TYPE='Release'
#- os: osx
# osx_image: xcode6.4
# compiler: clang
# env: COMPILER='clang++' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
#- os: osx
# osx_image: xcode7
# compiler: clang
# env: COMPILER='clang++' BUILD_TYPE='Debug'
#- os: osx
# osx_image: xcode7
# compiler: clang
# env: COMPILER='clang++' BUILD_TYPE='Release'
#- os: osx
# osx_image: xcode7
# compiler: clang
# env: COMPILER='clang++' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
install:
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
- |
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz"
mkdir cmake && travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
OSMOSIS_URL="http://bretth.dev.openstreetmap.org/osmosis-build/osmosis-latest.tgz"
mkdir osmosis && travis_retry wget --quiet -O - ${OSMOSIS_URL} | tar -xz -C osmosis
export PATH=${DEPS_DIR}/osmosis/bin:${PATH}
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
brew install cmake boost libzip libstxxl libxml2 lua51 luabind tbb GDAL osmosis
fi
before_script:
- cd ${TRAVIS_BUILD_DIR}
- rvm use 1.9.3
- gem install bundler
- bundle install
- mkdir build && cd build
- export CXX=${COMPILER}
- export OSRM_PORT=5000 OSRM_TIMEOUT=60
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} -DBUILD_TOOLS=1
script:
- make --jobs=2
- make tests --jobs=2
- make benchmarks
- ./algorithm-tests
- ./datastructure-tests
- ./util-tests
- cd ..
- cucumber -p verify
+197 -110
View File
@@ -1,19 +1,21 @@
cmake_minimum_required(VERSION 2.8.8)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE)
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR AND NOT MSVC_IDE)
message(FATAL_ERROR "In-source builds are not allowed.
Please create a directory and run cmake from there, passing the path to this source directory as the last argument.
This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them.")
endif()
project(OSRM)
project(OSRM C CXX)
set(OSRM_VERSION_MAJOR 4)
set(OSRM_VERSION_MINOR 9)
set(OSRM_VERSION_PATCH 0)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CheckCXXCompilerFlag)
include(FindPackageHandleStandardArgs)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(GetGitRevisionDescription)
git_describe(GIT_DESCRIPTION)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(bitness 32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
@@ -23,85 +25,95 @@ else()
message(WARNING "Building on a 32 bit system is unsupported")
endif()
if (WIN32 AND MSVC_VERSION LESS 1800)
if(WIN32 AND MSVC_VERSION LESS 1800)
message(FATAL_ERROR "Building with Microsoft compiler needs Visual Studio 2013 or later (Express version works too)")
endif()
OPTION(WITH_TOOLS "Build OSRM tools" OFF)
OPTION(BUILD_TOOLS "Build OSRM tools" OFF)
option(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF)
option(DEBUG_GEOMETRY "Enables an option to dump GeoJSON of the final routing graph" OFF)
option(BUILD_TOOLS "Build OSRM tools" OFF)
include_directories(${CMAKE_SOURCE_DIR}/Include/)
include_directories(${CMAKE_SOURCE_DIR}/third_party/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include/)
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/finger_print.cpp finger_print.cpp.alwaysbuild
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FingerPrint-Config.cmake
DEPENDS
${CMAKE_SOURCE_DIR}/Util/finger_print.cpp.in
COMMENT "Configuring finger_print.cpp"
add_custom_target(FingerPrintConfigure ALL ${CMAKE_COMMAND}
"-DOUTPUT_DIR=${CMAKE_CURRENT_BINARY_DIR}"
"-DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}"
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FingerPrint-Config.cmake"
COMMENT "Configuring revision fingerprint"
VERBATIM)
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/finger_print.cpp)
add_custom_target(tests DEPENDS datastructure-tests algorithm-tests)
add_custom_target(tests DEPENDS datastructure-tests algorithm-tests util-tests)
add_custom_target(benchmarks DEPENDS rtree-bench)
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread unit_test_framework)
configure_file(
${CMAKE_SOURCE_DIR}/Util/git_sha.cpp.in
${CMAKE_SOURCE_DIR}/Util/git_sha.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/version.hpp.in
${CMAKE_CURRENT_BINARY_DIR}/util/version.hpp
)
file(GLOB ExtractorGlob extractor/*.cpp)
file(GLOB ImporterGlob data_structures/import_edge.cpp data_structures/external_memory_node.cpp)
file(GLOB ExtractorGlob extractor/*.cpp data_structures/hilbert_value.cpp)
file(GLOB ImporterGlob data_structures/import_edge.cpp data_structures/external_memory_node.cpp data_structures/raster_source.cpp)
add_library(IMPORT OBJECT ${ImporterGlob})
add_library(LOGGER OBJECT Util/simple_logger.cpp)
add_library(LOGGER OBJECT util/simple_logger.cpp)
add_library(PHANTOMNODE OBJECT data_structures/phantom_node.cpp)
add_library(EXCEPTION OBJECT Util/osrm_exception.cpp)
add_library(RASTERSOURCE OBJECT data_structures/raster_source.cpp)
add_library(EXCEPTION OBJECT util/osrm_exception.cpp)
add_library(MERCATOR OBJECT util/mercator.cpp)
add_library(ANGLE OBJECT util/compute_angle.cpp)
set(ExtractorSources extract.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
add_executable(osrm-extract ${ExtractorSources} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR> $<TARGET_OBJECTS:COMPRESSEDEDGE> $<TARGET_OBJECTS:GRAPHCOMPRESSOR> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:ANGLE>)
add_library(RESTRICTION OBJECT data_structures/restriction_map.cpp)
add_library(COMPRESSEDEDGE OBJECT data_structures/compressed_edge_container.cpp)
add_library(GRAPHCOMPRESSOR OBJECT algorithms/graph_compressor.cpp)
file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp Util/compute_angle.cpp {RestrictionMapGlob})
file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp {RestrictionMapGlob})
set(PrepareSources prepare.cpp ${PrepareGlob})
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION>)
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:ANGLE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR> $<TARGET_OBJECTS:COMPRESSEDEDGE> $<TARGET_OBJECTS:GRAPHCOMPRESSOR>)
file(GLOB ServerGlob Server/*.cpp)
file(GLOB ServerGlob server/*.cpp)
file(GLOB DescriptorGlob descriptors/*.cpp)
file(GLOB DatastructureGlob data_structures/search_engine_data.cpp data_structures/route_parameters.cpp Util/bearing.cpp)
list(REMOVE_ITEM DatastructureGlob data_structures/Coordinate.cpp)
file(GLOB CoordinateGlob data_structures/Coordinate.cpp)
file(GLOB AlgorithmGlob algorithms/*.cpp)
file(GLOB HttpGlob Server/Http/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp)
file(GLOB DataStructureTestsGlob UnitTests/data_structures/*.cpp data_structures/hilbert_value.cpp)
file(GLOB AlgorithmTestsGlob UnitTests/Algorithms/*.cpp)
file(GLOB DatastructureGlob data_structures/search_engine_data.cpp data_structures/route_parameters.cpp util/bearing.cpp)
file(GLOB CoordinateGlob data_structures/coordinate.cpp algorithms/coordinate_calculation.cpp)
file(GLOB AlgorithmGlob algorithms/polyline_compressor.cpp algorithms/polyline_formatter.cpp algorithms/douglas_peucker.cpp)
file(GLOB HttpGlob server/http/*.cpp)
file(GLOB LibOSRMGlob library/*.cpp)
file(GLOB DataStructureTestsGlob unit_tests/data_structures/*.cpp data_structures/hilbert_value.cpp)
file(GLOB AlgorithmTestsGlob unit_tests/algorithms/*.cpp algorithms/graph_compressor.cpp)
file(GLOB UtilTestsGlob unit_tests/util/*.cpp)
set(
OSRMSources
${LibOSRMGlob}
${DescriptorGlob}
${DatastructureGlob}
${CoordinateGlob}
${AlgorithmGlob}
${HttpGlob}
)
add_library(COORDINATE OBJECT ${CoordinateGlob})
add_library(FINGERPRINT OBJECT Util/finger_print.cpp)
add_library(GITDESCRIPTION OBJECT Util/git_sha.cpp)
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION>)
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:ANGLE> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR> $<TARGET_OBJECTS:IMPORT>)
add_library(FINGERPRINT OBJECT util/fingerprint.cpp)
add_dependencies(FINGERPRINT FingerPrintConfigure)
add_dependencies(OSRM FingerPrintConfigure)
set_target_properties(FINGERPRINT PROPERTIES LINKER_LANGUAGE CXX)
add_executable(osrm-routed routed.cpp ${ServerGlob} $<TARGET_OBJECTS:EXCEPTION>)
add_executable(osrm-datastore datastore.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
add_executable(osrm-datastore datastore.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
# Unit tests
add_executable(datastructure-tests EXCLUDE_FROM_ALL UnitTests/datastructure_tests.cpp ${DataStructureTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION>)
add_executable(algorithm-tests EXCLUDE_FROM_ALL UnitTests/algorithm_tests.cpp ${AlgorithmTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION>)
add_executable(datastructure-tests EXCLUDE_FROM_ALL unit_tests/datastructure_tests.cpp ${DataStructureTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR> $<TARGET_OBJECTS:COMPRESSEDEDGE> $<TARGET_OBJECTS:GRAPHCOMPRESSOR> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:RASTERSOURCE>)
add_executable(algorithm-tests EXCLUDE_FROM_ALL unit_tests/algorithm_tests.cpp ${AlgorithmTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:COMPRESSEDEDGE>)
add_executable(util-tests EXCLUDE_FROM_ALL unit_tests/util_tests.cpp ${UtilTestsGlob})
# Benchmarks
add_executable(rtree-bench EXCLUDE_FROM_ALL benchmarks/static_rtree.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION>)
add_executable(rtree-bench EXCLUDE_FROM_ALL benchmarks/static_rtree.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
# Check the release mode
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
@@ -109,56 +121,78 @@ if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
endif()
if(CMAKE_BUILD_TYPE MATCHES Debug)
message(STATUS "Configuring OSRM in debug mode")
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
message(STATUS "adding profiling flags")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
set(CMAKE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-inline -fno-omit-frame-pointer")
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Og -ggdb")
endif()
endif()
endif()
if(CMAKE_BUILD_TYPE MATCHES Release)
message(STATUS "Configuring OSRM in release mode")
# Check if LTO is available
set(LTO_FLAGS "")
CHECK_CXX_COMPILER_FLAG("-flto" HAS_LTO_FLAG)
if (HAS_LTO_FLAG)
set(LTO_FLAGS "${LTO_FLAGS} -flto")
check_cxx_compiler_flag("-flto" LTO_AVAILABLE)
if(LTO_AVAILABLE)
set(OLD_CXX_FLAGS ${CMAKE_CXX_FLAGS})
# GCC in addition allows parallelizing LTO
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
include(ProcessorCount)
ProcessorCount(NPROC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto=${NPROC}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
endif()
set(CHECK_LTO_SRC "int main(){return 0;}")
check_cxx_source_compiles("${CHECK_LTO_SRC}" LTO_WORKS)
if(LTO_WORKS)
message(STATUS "LTO working")
else()
message(STATUS "LTO broken")
set(CMAKE_CXX_FLAGS "${OLD_CXX_FLAGS}")
endif()
# Since gcc 4.9 the LTO format is non-standart ('slim'), so we need to use the build-in tools
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND
NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.9.0" AND NOT MINGW)
message(STATUS "Using gcc specific binutils for LTO.")
set(CMAKE_AR "/usr/bin/gcc-ar")
set(CMAKE_RANLIB "/usr/bin/gcc-ranlib")
endif()
endif (HAS_LTO_FLAG)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.9.0")
message(STATUS "Disabling LTO on GCC < 4.9.0 since it is broken, see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57038")
set(CMAKE_CXX_FLAGS "${OLD_CXX_FLAGS}")
endif()
endif()
endif()
if (NOT WIN32)
add_definitions(-DBOOST_TEST_DYN_LINK)
if(NOT WIN32)
add_definitions(-DBOOST_TEST_DYN_LINK)
endif()
# Configuring compilers
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang
# -Weverything -Wno-c++98-compat -Wno-shadow -Wno-exit-time-destructors
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunreachable-code -pedantic -fPIC")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wuninitialized -Wunreachable-code -Wstrict-overflow=2 -D_FORTIFY_SOURCE=2 -fPIC")
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
set(COLOR_FLAG "-fdiagnostics-color=auto")
CHECK_CXX_COMPILER_FLAG("-fdiagnostics-color=auto" HAS_COLOR_FLAG)
check_cxx_compiler_flag("-fdiagnostics-color=auto" HAS_COLOR_FLAG)
if(NOT HAS_COLOR_FLAG)
set(COLOR_FLAG "")
endif()
# using GCC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC ${COLOR_FLAG}")
if (WIN32) # using mingw
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wuninitialized -Wunreachable-code -Wstrict-overflow=1 -D_FORTIFY_SOURCE=2 ${COLOR_FLAG} -fPIC")
if(WIN32) # using mingw
add_definitions(-D_USE_MATH_DEFINES) # define M_PI, M_1_PI etc.
add_definitions(-DWIN32)
SET(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
set(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
endif()
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
# using Intel C++
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -wd10237 -Wall -ipo -fPIC")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
# using Visual Studio C++
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time chrono zlib)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
@@ -170,9 +204,29 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
target_link_libraries(osrm-extract wsock32 ws2_32)
endif()
# Configuring linker
execute_process(COMMAND ${CMAKE_CXX_COMPILER} "-Wl,--version" ERROR_QUIET OUTPUT_VARIABLE LINKER_VERSION)
# For ld.gold and ld.bfs (the GNU linkers) we optimize hard
if("${LINKER_VERSION}" MATCHES "GNU gold" OR "${LINKER_VERSION}" MATCHES "GNU ld")
message(STATUS "Setting linker optimizations")
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
# Tell compiler to put every function in separate section, linker can then match sections and functions
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections")
# Tell linker to do dead code and data eminination during link time discarding sections
set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,--gc-sections")
endif()
# Default linker optimization flags
set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,-O1 -Wl,--hash-style=gnu -Wl,--sort-common")
else()
message(STATUS "Using unknown linker, not setting linker optimizations")
endif ()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}")
# Activate C++11
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
ADD_DEFINITIONS(-std=c++11)
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ")
endif()
# Configuring other platform dependencies
@@ -197,12 +251,11 @@ if(UNIX AND NOT APPLE)
endif()
#Check Boost
set(BOOST_MIN_VERSION "1.49.0")
find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
find_package(Boost 1.49.0 COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
if(NOT Boost_FOUND)
message(FATAL_ERROR "Fatal error: Boost (version >= 1.49.0) required.\n")
endif()
include_directories(${Boost_INCLUDE_DIRS})
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
target_link_libraries(OSRM ${Boost_LIBRARIES})
target_link_libraries(osrm-extract ${Boost_LIBRARIES})
@@ -211,6 +264,7 @@ target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSR
target_link_libraries(osrm-datastore ${Boost_LIBRARIES})
target_link_libraries(datastructure-tests ${Boost_LIBRARIES})
target_link_libraries(algorithm-tests ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
target_link_libraries(util-tests ${Boost_LIBRARIES})
target_link_libraries(rtree-bench ${Boost_LIBRARIES})
find_package(Threads REQUIRED)
@@ -233,85 +287,86 @@ target_link_libraries(osrm-routed ${TBB_LIBRARIES})
target_link_libraries(datastructure-tests ${TBB_LIBRARIES})
target_link_libraries(algorithm-tests ${TBB_LIBRARIES})
target_link_libraries(rtree-bench ${TBB_LIBRARIES})
include_directories(${TBB_INCLUDE_DIR})
include_directories(SYSTEM ${TBB_INCLUDE_DIR})
find_package( Luabind REQUIRED )
include(check_luabind)
include_directories(${LUABIND_INCLUDE_DIR})
include_directories(SYSTEM ${LUABIND_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LUABIND_LIBRARY})
target_link_libraries(osrm-prepare ${LUABIND_LIBRARY})
if( LUAJIT_FOUND )
if(LUAJIT_FOUND)
target_link_libraries(osrm-extract ${LUAJIT_LIBRARIES})
target_link_libraries(osrm-prepare ${LUAJIT_LIBRARIES})
else()
target_link_libraries(osrm-extract ${LUA_LIBRARY})
target_link_libraries(osrm-prepare ${LUA_LIBRARY})
endif()
include_directories(${LUA_INCLUDE_DIR})
include_directories(SYSTEM ${LUA_INCLUDE_DIR})
find_package(EXPAT REQUIRED)
include_directories(${EXPAT_INCLUDE_DIRS})
include_directories(SYSTEM ${EXPAT_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${EXPAT_LIBRARIES})
find_package( STXXL REQUIRED )
include_directories(${STXXL_INCLUDE_DIR})
find_package(STXXL REQUIRED)
include_directories(SYSTEM ${STXXL_INCLUDE_DIR})
target_link_libraries(OSRM ${STXXL_LIBRARY})
target_link_libraries(osrm-extract ${STXXL_LIBRARY})
target_link_libraries(osrm-prepare ${STXXL_LIBRARY})
target_link_libraries(datastructure-tests ${STXXL_LIBRARY})
if(MINGW)
# STXXL needs OpenMP library
target_link_libraries(osrm-extract gomp)
set(OpenMP_FIND_QUIETLY ON)
find_package(OpenMP)
if(OPENMP_FOUND)
message(STATUS "OpenMP support found. Linking just in case for stxxl")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
find_package( OSMPBF REQUIRED )
include_directories(${OSMPBF_INCLUDE_DIR})
target_link_libraries(osrm-extract ${OSMPBF_LIBRARY})
target_link_libraries(osrm-prepare ${OSMPBF_LIBRARY})
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${PROTOBUF_LIBRARY})
target_link_libraries(osrm-prepare ${PROTOBUF_LIBRARY})
find_package(BZip2 REQUIRED)
include_directories(${BZIP_INCLUDE_DIRS})
include_directories(SYSTEM ${BZIP_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${BZIP2_LIBRARIES})
find_package(ZLIB REQUIRED)
include_directories(${ZLIB_INCLUDE_DIRS})
include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS})
target_link_libraries(osrm-extract ${ZLIB_LIBRARY})
target_link_libraries(osrm-routed ${ZLIB_LIBRARY})
if(WITH_TOOLS OR BUILD_TOOLS)
if (ENABLE_JSON_LOGGING)
message(STATUS "Enabling json logging")
add_definitions(-DENABLE_JSON_LOGGING)
endif()
if (DEBUG_GEOMETRY)
message(STATUS "Enabling final edge weight GeoJSON output option")
add_definitions(-DDEBUG_GEOMETRY)
endif()
if(BUILD_TOOLS)
message(STATUS "Activating OSRM internal tools")
find_package(GDAL)
if(GDAL_FOUND)
add_executable(osrm-components tools/components.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION>)
add_executable(osrm-components tools/components.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
target_link_libraries(osrm-components ${TBB_LIBRARIES})
include_directories(${GDAL_INCLUDE_DIR})
target_link_libraries(
osrm-components
${GDAL_LIBRARIES} ${Boost_LIBRARIES})
include_directories(SYSTEM ${GDAL_INCLUDE_DIR})
target_link_libraries(osrm-components ${GDAL_LIBRARIES} ${Boost_LIBRARIES})
install(TARGETS osrm-components DESTINATION bin)
else()
message(FATAL_ERROR "libgdal and/or development headers not found")
endif()
add_executable(osrm-cli tools/simpleclient.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-cli tools/simpleclient.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:COORDINATE>)
target_link_libraries(osrm-cli ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
target_link_libraries(osrm-cli ${TBB_LIBRARIES})
add_executable(osrm-io-benchmark tools/io-benchmark.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
add_executable(osrm-io-benchmark tools/io-benchmark.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-io-benchmark ${Boost_LIBRARIES})
add_executable(osrm-unlock-all tools/unlock_all_mutexes.cpp $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
add_executable(osrm-unlock-all tools/unlock_all_mutexes.cpp $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
target_link_libraries(osrm-unlock-all ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
if(UNIX AND NOT APPLE)
target_link_libraries(osrm-unlock-all rt)
endif()
add_executable(osrm-check-hsgr tools/check-hsgr.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER>)
target_link_libraries(osrm-check-hsgr ${Boost_LIBRARIES})
add_executable(osrm-springclean tools/springclean.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:EXCEPTION>)
add_executable(osrm-check-hsgr tools/check-hsgr.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:IMPORT>)
target_link_libraries(osrm-check-hsgr ${Boost_LIBRARIES} ${TBB_LIBRARIES})
add_executable(osrm-springclean tools/springclean.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
target_link_libraries(osrm-springclean ${Boost_LIBRARIES})
install(TARGETS osrm-cli DESTINATION bin)
@@ -321,7 +376,8 @@ if(WITH_TOOLS OR BUILD_TOOLS)
install(TARGETS osrm-springclean DESTINATION bin)
endif()
file(GLOB InstallGlob Include/osrm/*.h Library/OSRM.h)
file(GLOB InstallGlob include/osrm/*.hpp)
file(GLOB VariantGlob third_party/variant/*.hpp)
# Add RPATH info to executables so that when they are run after being installed
# (i.e., from /usr/local/bin/) the linker can find library dependencies. For
@@ -332,24 +388,55 @@ set_property(TARGET osrm-datastore PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
install(FILES ${InstallGlob} DESTINATION include/osrm)
install(FILES ${VariantGlob} DESTINATION include/variant)
install(TARGETS osrm-extract DESTINATION bin)
install(TARGETS osrm-prepare DESTINATION bin)
install(TARGETS osrm-datastore DESTINATION bin)
install(TARGETS osrm-routed DESTINATION bin)
install(TARGETS OSRM DESTINATION lib)
list(GET Boost_LIBRARIES 1 BOOST_LIBRARY_FIRST)
get_filename_component(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_FIRST}" PATH)
set(BOOST_LIBRARY_LISTING "-L${BOOST_LIBRARY_LISTING}")
foreach (lib ${Boost_LIBRARIES})
foreach(lib ${Boost_LIBRARIES})
get_filename_component(BOOST_LIBRARY_NAME "${lib}" NAME_WE)
string(REPLACE "lib" "" BOOST_LIBRARY_NAME ${BOOST_LIBRARY_NAME})
set(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_LISTING} -l${BOOST_LIBRARY_NAME}")
endforeach ()
endforeach()
list(GET TBB_LIBRARIES 1 TBB_LIBRARY_FIRST)
get_filename_component(TBB_LIBRARY_LISTING "${TBB_LIBRARY_FIRST}" PATH)
set(TBB_LIBRARY_LISTING "-L${TBB_LIBRARY_LISTING}")
foreach(lib ${TBB_LIBRARIES})
get_filename_component(TBB_LIBRARY_NAME "${lib}" NAME_WE)
string(REPLACE "lib" "" TBB_LIBRARY_NAME ${TBB_LIBRARY_NAME})
set(TBB_LIBRARY_LISTING "${TBB_LIBRARY_LISTING} -l${TBB_LIBRARY_NAME}")
endforeach()
configure_file(${CMAKE_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
if(BUILD_DEBIAN_PACKAGE)
include(CPackDebianConfig)
include(CPack)
endif()
# add a target to generate API documentation with Doxygen
find_package(Doxygen)
if(DOXYGEN_FOUND)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
add_custom_target(doc
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen" VERBATIM
)
endif()
# prefix compilation with ccache by default if available and on clang or gcc
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
set(ENV{CCACHE_CPP2} "true")
endif()
endif()
+43
View File
@@ -0,0 +1,43 @@
PROJECT_NAME = "Project OSRM"
PROJECT_BRIEF = "Open Source Routing Machine"
BUILTIN_STL_SUPPORT = YES
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_PACKAGE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_ANON_NSPACES = YES
QUIET = YES
INPUT = @CMAKE_CURRENT_SOURCE_DIR@
USE_MDFILE_AS_MAINPAGE = @CMAKE_CURRENT_SOURCE_DIR@/README.md
FILE_PATTERNS = *.h *.hpp *.c *.cc *.cpp *.md
RECURSIVE = YES
EXCLUDE = @CMAKE_CURRENT_SOURCE_DIR@/third_party \
@CMAKE_CURRENT_SOURCE_DIR@/build \
@CMAKE_CURRENT_SOURCE_DIR@/unit_tests \
@CMAKE_CURRENT_SOURCE_DIR@/benchmarks \
@CMAKE_CURRENT_SOURCE_DIR@/features
SOURCE_BROWSER = YES
CLANG_ASSISTED_PARSING = NO
HTML_COLORSTYLE_HUE = 217
HTML_COLORSTYLE_SAT = 71
HTML_COLORSTYLE_GAMMA = 50
GENERATE_TREEVIEW = YES
HAVE_DOT = @DOXYGEN_DOT_FOUND@
CALL_GRAPH = YES
CALLER_GRAPH = YES
DOT_IMAGE_FORMAT = svg
INTERACTIVE_SVG = YES
DOT_GRAPH_MAX_NODES = 500
DOT_TRANSPARENT = YES
DOT_MULTI_TARGETS = YES
+1 -1
View File
@@ -4,4 +4,4 @@ gem "cucumber"
gem "rake"
gem "osmlib-base"
gem "sys-proctable"
gem "rspec-expectations"
gem "rspec-expectations"
+16 -11
View File
@@ -2,22 +2,27 @@ GEM
remote: http://rubygems.org/
specs:
builder (3.2.2)
cucumber (1.3.8)
cucumber (2.0.0)
builder (>= 2.1.2)
cucumber-core (~> 1.1.3)
diff-lcs (>= 1.1.3)
gherkin (~> 2.12.1)
gherkin (~> 2.12)
multi_json (>= 1.7.5, < 2.0)
multi_test (>= 0.0.2)
diff-lcs (1.2.4)
gherkin (2.12.1)
multi_test (>= 0.1.2)
cucumber-core (1.1.3)
gherkin (~> 2.12.0)
diff-lcs (1.2.5)
gherkin (2.12.2)
multi_json (~> 1.3)
multi_json (1.8.0)
multi_test (0.0.2)
multi_json (1.11.0)
multi_test (0.1.2)
osmlib-base (0.1.4)
rake (10.1.0)
rspec-expectations (2.14.3)
diff-lcs (>= 1.1.3, < 2.0)
sys-proctable (0.9.3)
rake (10.4.2)
rspec-expectations (3.2.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-support (3.2.2)
sys-proctable (0.9.8)
PLATFORMS
ruby
-113
View File
@@ -1,113 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FIXED_POINT_COORDINATE_H_
#define FIXED_POINT_COORDINATE_H_
#include <iosfwd> //for std::ostream
#include <string>
#include <type_traits>
namespace
{
constexpr float COORDINATE_PRECISION = 1000000.f;
}
struct FixedPointCoordinate
{
int lat;
int lon;
FixedPointCoordinate();
FixedPointCoordinate(int lat, int lon);
template<class T>
FixedPointCoordinate(const T &coordinate) : lat(coordinate.lat), lon(coordinate.lon)
{
static_assert(std::is_same<decltype(lat), decltype(coordinate.lat)>::value, "coordinate types incompatible");
static_assert(std::is_same<decltype(lon), decltype(coordinate.lon)>::value, "coordinate types incompatible");
}
void Reset();
bool isSet() const;
bool is_valid() const;
bool operator==(const FixedPointCoordinate &other) const;
static double
ApproximateDistance(const int lat1, const int lon1, const int lat2, const int lon2);
static double ApproximateDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static float ApproximateEuclideanDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static float
ApproximateEuclideanDistance(const int lat1, const int lon1, const int lat2, const int lon2);
static float ApproximateSquaredEuclideanDistance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
static void convertInternalLatLonToString(const int value, std::string &output);
static void convertInternalCoordinateToString(const FixedPointCoordinate &coordinate,
std::string &output);
static void convertInternalReversedCoordinateToString(const FixedPointCoordinate &coordinate,
std::string &output);
static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location);
static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio);
static int
OrderedPerpendicularDistanceApproximation(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location);
static float GetBearing(const FixedPointCoordinate &A, const FixedPointCoordinate &B);
float GetBearing(const FixedPointCoordinate &other) const;
void Output(std::ostream &out) const;
static float DegreeToRadian(const float degree);
static float RadianToDegree(const float radian);
};
inline std::ostream &operator<<(std::ostream &out_stream, FixedPointCoordinate const &coordinate)
{
coordinate.Output(out_stream);
return out_stream;
}
#endif /* FIXED_POINT_COORDINATE_H_ */
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
-165
View File
@@ -1,165 +0,0 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
namespace boost { namespace interprocess { class named_mutex; } }
#include "OSRM_impl.h"
#include "OSRM.h"
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <osrm/ServerPaths.h>
#include "../plugins/distance_table.hpp"
#include "../plugins/hello_world.hpp"
#include "../plugins/locate.hpp"
#include "../plugins/nearest.hpp"
#include "../plugins/timestamp.hpp"
#include "../plugins/viaroute.hpp"
#include "../Server/DataStructures/BaseDataFacade.h"
#include "../Server/DataStructures/InternalDataFacade.h"
#include "../Server/DataStructures/SharedBarriers.h"
#include "../Server/DataStructures/SharedDataFacade.h"
#include "../Util/make_unique.hpp"
#include "../Util/ProgramOptions.h"
#include "../Util/simple_logger.hpp"
#include <boost/assert.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <algorithm>
#include <fstream>
#include <utility>
#include <vector>
OSRM_impl::OSRM_impl(ServerPaths server_paths, const bool use_shared_memory)
{
if (use_shared_memory)
{
barrier = osrm::make_unique<SharedBarriers>();
query_data_facade = new SharedDataFacade<QueryEdge::EdgeData>();
}
else
{
// populate base path
populate_base_path(server_paths);
query_data_facade = new InternalDataFacade<QueryEdge::EdgeData>(server_paths);
}
// The following plugins handle all requests.
RegisterPlugin(new DistanceTablePlugin<BaseDataFacade<QueryEdge::EdgeData>>(query_data_facade));
RegisterPlugin(new HelloWorldPlugin());
RegisterPlugin(new LocatePlugin<BaseDataFacade<QueryEdge::EdgeData>>(query_data_facade));
RegisterPlugin(new NearestPlugin<BaseDataFacade<QueryEdge::EdgeData>>(query_data_facade));
RegisterPlugin(new TimestampPlugin<BaseDataFacade<QueryEdge::EdgeData>>(query_data_facade));
RegisterPlugin(new ViaRoutePlugin<BaseDataFacade<QueryEdge::EdgeData>>(query_data_facade));
}
OSRM_impl::~OSRM_impl()
{
delete query_data_facade;
for (PluginMap::value_type &plugin_pointer : plugin_map)
{
delete plugin_pointer.second;
}
}
void OSRM_impl::RegisterPlugin(BasePlugin *plugin)
{
SimpleLogger().Write() << "loaded plugin: " << plugin->GetDescriptor();
if (plugin_map.find(plugin->GetDescriptor()) != plugin_map.end())
{
delete plugin_map.find(plugin->GetDescriptor())->second;
}
plugin_map.emplace(plugin->GetDescriptor(), plugin);
}
void OSRM_impl::RunQuery(RouteParameters &route_parameters, http::Reply &reply)
{
const PluginMap::const_iterator &iter = plugin_map.find(route_parameters.service);
if (plugin_map.end() != iter)
{
reply.status = http::Reply::ok;
if (barrier)
{
// lock update pending
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> pending_lock(
barrier->pending_update_mutex);
// lock query
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> query_lock(
barrier->query_mutex);
// unlock update pending
pending_lock.unlock();
// increment query count
++(barrier->number_of_queries);
(static_cast<SharedDataFacade<QueryEdge::EdgeData> *>(query_data_facade))
->CheckAndReloadFacade();
}
iter->second->HandleRequest(route_parameters, reply);
if (barrier)
{
// lock query
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> query_lock(
barrier->query_mutex);
// decrement query count
--(barrier->number_of_queries);
BOOST_ASSERT_MSG(0 <= barrier->number_of_queries, "invalid number of queries");
// notify all processes that were waiting for this condition
if (0 == barrier->number_of_queries)
{
barrier->no_running_queries_condition.notify_all();
}
}
}
else
{
reply = http::Reply::StockReply(http::Reply::badRequest);
}
}
// proxy code for compilation firewall
OSRM::OSRM(ServerPaths paths, const bool use_shared_memory)
: OSRM_pimpl_(osrm::make_unique<OSRM_impl>(paths, use_shared_memory))
{
}
OSRM::~OSRM() { OSRM_pimpl_.reset(); }
void OSRM::RunQuery(RouteParameters &route_parameters, http::Reply &reply)
{
OSRM_pimpl_->RunQuery(route_parameters, reply);
}
+18 -13
View File
@@ -1,12 +1,25 @@
# Readme
## About
For instructions on how to compile and run OSRM, please consult the Wiki at
The Open Source Routing Machine is a high performance routing engine written in C++11 designed to run on OpenStreetMap data.
https://github.com/Project-OSRM/osrm-backend/wiki
## Current build status
or use our free and daily updated online service at
| build config | branch | status |
|:-------------|:--------|:------------|
| Linux | master | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=master)](https://travis-ci.org/Project-OSRM/osrm-backend) |
| Linux | develop | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=develop)](https://travis-ci.org/Project-OSRM/osrm-backend) |
| Windows | master/develop | [![Build status](https://ci.appveyor.com/api/projects/status/4iuo3s9gxprmcjjh)](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
| LUAbind fork | master | [![Build Status](https://travis-ci.org/DennisOSRM/luabind.png?branch=master)](https://travis-ci.org/DennisOSRM/luabind) |
http://map.project-osrm.org
## Building
For instructions on how to [build](https://github.com/Project-OSRM/osrm-backend/wiki/Building-OSRM) and [run OSRM](https://github.com/Project-OSRM/osrm-backend/wiki/Running-OSRM), please consult [the Wiki](https://github.com/Project-OSRM/osrm-backend/wiki).
To quickly try OSRM use our [free and daily updated online service](http://map.project-osrm.org)
## Documentation
See the Wiki's [server API documentation](https://github.com/Project-OSRM/osrm-backend/wiki/Server-api) as well as the [library API documentation](https://github.com/Project-OSRM/osrm-backend/wiki/Library-api)
## References in publications
@@ -31,11 +44,3 @@ When using the code in a (scientific) publication, please cite
}
```
## Current build status
| build config | branch | status |
|:-------------|:--------|:------------|
| Linux | master | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=master)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| Linux | develop | [![Build Status](https://travis-ci.org/Project-OSRM/osrm-backend.png?branch=develop)](https://travis-ci.org/DennisOSRM/Project-OSRM) |
| Windows | master/develop | [![Build status](https://ci.appveyor.com/api/projects/status/4iuo3s9gxprmcjjh)](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
| LUAbind fork | master | [![Build Status](https://travis-ci.org/DennisOSRM/luabind.png?branch=master)](https://travis-ci.org/DennisOSRM/luabind) |
-74
View File
@@ -1,74 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef APIGRAMMAR_H_
#define APIGRAMMAR_H_
#include <boost/bind.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>
namespace qi = boost::spirit::qi;
template <typename Iterator, class HandlerT>
struct APIGrammar : qi::grammar<Iterator>
{
explicit APIGrammar(HandlerT * h) : APIGrammar::base_type(api_call), handler(h)
{
api_call = qi::lit('/') >> string[boost::bind(&HandlerT::setService, handler, ::_1)] >> *(query) >> -(uturns);
query = ('?') >> (+(zoom | output | jsonp | checksum | location | hint | u | cmp | language | instruction | geometry | alt_route | old_API | num_results) ) ;
zoom = (-qi::lit('&')) >> qi::lit('z') >> '=' >> qi::short_[boost::bind(&HandlerT::setZoomLevel, handler, ::_1)];
output = (-qi::lit('&')) >> qi::lit("output") >> '=' >> string[boost::bind(&HandlerT::setOutputFormat, handler, ::_1)];
jsonp = (-qi::lit('&')) >> qi::lit("jsonp") >> '=' >> stringwithPercent[boost::bind(&HandlerT::setJSONpParameter, handler, ::_1)];
checksum = (-qi::lit('&')) >> qi::lit("checksum") >> '=' >> qi::uint_[boost::bind(&HandlerT::setChecksum, handler, ::_1)];
instruction = (-qi::lit('&')) >> qi::lit("instructions") >> '=' >> qi::bool_[boost::bind(&HandlerT::setInstructionFlag, handler, ::_1)];
geometry = (-qi::lit('&')) >> qi::lit("geometry") >> '=' >> qi::bool_[boost::bind(&HandlerT::setGeometryFlag, handler, ::_1)];
cmp = (-qi::lit('&')) >> qi::lit("compression") >> '=' >> qi::bool_[boost::bind(&HandlerT::setCompressionFlag, handler, ::_1)];
location = (-qi::lit('&')) >> qi::lit("loc") >> '=' >> (qi::double_ >> qi::lit(',') >> qi::double_)[boost::bind(&HandlerT::addCoordinate, handler, ::_1)];
hint = (-qi::lit('&')) >> qi::lit("hint") >> '=' >> stringwithDot[boost::bind(&HandlerT::addHint, handler, ::_1)];
u = (-qi::lit('&')) >> qi::lit("u") >> '=' >> qi::bool_[boost::bind(&HandlerT::setUTurn, handler, ::_1)];
uturns = (-qi::lit('&')) >> qi::lit("uturns") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAllUTurns, handler, ::_1)];
language = (-qi::lit('&')) >> qi::lit("hl") >> '=' >> string[boost::bind(&HandlerT::setLanguage, handler, ::_1)];
alt_route = (-qi::lit('&')) >> qi::lit("alt") >> '=' >> qi::bool_[boost::bind(&HandlerT::setAlternateRouteFlag, handler, ::_1)];
old_API = (-qi::lit('&')) >> qi::lit("geomformat") >> '=' >> string[boost::bind(&HandlerT::setDeprecatedAPIFlag, handler, ::_1)];
num_results = (-qi::lit('&')) >> qi::lit("num_results") >> '=' >> qi::short_[boost::bind(&HandlerT::setNumberOfResults, handler, ::_1)];
string = +(qi::char_("a-zA-Z"));
stringwithDot = +(qi::char_("a-zA-Z0-9_.-"));
stringwithPercent = +(qi::char_("a-zA-Z0-9_.-") | qi::char_('[') | qi::char_(']') | (qi::char_('%') >> qi::char_("0-9A-Z") >> qi::char_("0-9A-Z") ));
}
qi::rule<Iterator> api_call, query;
qi::rule<Iterator, std::string()> service, zoom, output, string, jsonp, checksum, location, hint,
stringwithDot, stringwithPercent, language, instruction, geometry,
cmp, alt_route, u, uturns, old_API, num_results;
HandlerT * handler;
};
#endif /* APIGRAMMAR_H_ */
-143
View File
@@ -1,143 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "RequestHandler.h"
#include "APIGrammar.h"
#include "Http/Request.h"
#include "../data_structures/json_container.hpp"
#include "../Library/OSRM.h"
#include "../Util/json_renderer.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/string_util.hpp"
#include "../typedefs.h"
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <ctime>
#include <algorithm>
#include <iostream>
RequestHandler::RequestHandler() : routing_machine(nullptr) {}
void RequestHandler::handle_request(const http::Request &req, http::Reply &reply)
{
// parse command
try
{
std::string request;
URIDecode(req.uri, request);
// deactivated as GCC apparently does not implement that, not even in 4.9
// std::time_t t = std::time(nullptr);
// SimpleLogger().Write() << std::put_time(std::localtime(&t), "%m-%d-%Y %H:%M:%S") <<
// " " << req.endpoint.to_string() << " " <<
// req.referrer << ( 0 == req.referrer.length() ? "- " :" ") <<
// req.agent << ( 0 == req.agent.length() ? "- " :" ") << request;
time_t ltime;
struct tm *time_stamp;
ltime = time(nullptr);
time_stamp = localtime(&ltime);
// log timestamp
SimpleLogger().Write() << (time_stamp->tm_mday < 10 ? "0" : "") << time_stamp->tm_mday << "-"
<< (time_stamp->tm_mon + 1 < 10 ? "0" : "") << (time_stamp->tm_mon + 1) << "-"
<< 1900 + time_stamp->tm_year << " " << (time_stamp->tm_hour < 10 ? "0" : "")
<< time_stamp->tm_hour << ":" << (time_stamp->tm_min < 10 ? "0" : "") << time_stamp->tm_min
<< ":" << (time_stamp->tm_sec < 10 ? "0" : "") << time_stamp->tm_sec << " "
<< req.endpoint.to_string() << " " << req.referrer
<< (0 == req.referrer.length() ? "- " : " ") << req.agent
<< (0 == req.agent.length() ? "- " : " ") << request;
RouteParameters route_parameters;
APIGrammarParser api_parser(&route_parameters);
auto iter = request.begin();
const bool result = boost::spirit::qi::parse(iter, request.end(), api_parser);
// check if the was an error with the request
if (!result || (iter != request.end()))
{
reply = http::Reply::StockReply(http::Reply::badRequest);
reply.content.clear();
const auto position = std::distance(request.begin(), iter);
JSON::Object json_result;
json_result.values["status"] = 400;
std::string message = "Query string malformed close to position ";
message += cast::integral_to_string(position);
json_result.values["status_message"] = message;
JSON::render(reply.content, json_result);
return;
}
// parsing done, lets call the right plugin to handle the request
BOOST_ASSERT_MSG(routing_machine != nullptr, "pointer not init'ed");
if (!route_parameters.jsonp_parameter.empty())
{ // prepend response with jsonp parameter
const std::string json_p = (route_parameters.jsonp_parameter + "(");
reply.content.insert(reply.content.end(), json_p.begin(), json_p.end());
}
routing_machine->RunQuery(route_parameters, reply);
if (!route_parameters.jsonp_parameter.empty())
{ // append brace to jsonp response
reply.content.push_back(')');
}
// set headers
reply.headers.emplace_back("Content-Length", cast::integral_to_string(reply.content.size()));
if ("gpx" == route_parameters.output_format)
{ // gpx file
reply.headers.emplace_back("Content-Type", "application/gpx+xml; charset=UTF-8");
reply.headers.emplace_back("Content-Disposition", "attachment; filename=\"route.gpx\"");
}
else if (route_parameters.jsonp_parameter.empty())
{ // json file
reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8");
reply.headers.emplace_back("Content-Disposition", "inline; filename=\"response.json\"");
}
else
{ // jsonp
reply.headers.emplace_back("Content-Type", "text/javascript; charset=UTF-8");
reply.headers.emplace_back("Content-Disposition", "inline; filename=\"response.js\"");
}
}
catch (const std::exception &e)
{
reply = http::Reply::StockReply(http::Reply::internalServerError);
SimpleLogger().Write(logWARNING) << "[server error] code: " << e.what()
<< ", uri: " << req.uri;
return;
}
}
void RequestHandler::RegisterRoutingMachine(OSRM *osrm) { routing_machine = osrm; }
-310
View File
@@ -1,310 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "RequestParser.h"
#include "Http/Request.h"
namespace http
{
RequestParser::RequestParser() : state_(method_start), header({"", ""}) {}
void RequestParser::Reset() { state_ = method_start; }
boost::tuple<boost::tribool, char *>
RequestParser::Parse(Request &req, char *begin, char *end, http::CompressionType &compression_type)
{
while (begin != end)
{
boost::tribool result = consume(req, *begin++, compression_type);
if (result || !result)
{
return boost::make_tuple(result, begin);
}
}
boost::tribool result = boost::indeterminate;
return boost::make_tuple(result, begin);
}
boost::tribool
RequestParser::consume(Request &req, char input, http::CompressionType &compression_type)
{
switch (state_)
{
case method_start:
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
}
state_ = method;
return boost::indeterminate;
case method:
if (input == ' ')
{
state_ = uri;
return boost::indeterminate;
}
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
}
return boost::indeterminate;
case uri_start:
if (isCTL(input))
{
return false;
}
state_ = uri;
req.uri.push_back(input);
return boost::indeterminate;
case uri:
if (input == ' ')
{
state_ = http_version_h;
return boost::indeterminate;
}
if (isCTL(input))
{
return false;
}
req.uri.push_back(input);
return boost::indeterminate;
case http_version_h:
if (input == 'H')
{
state_ = http_version_t_1;
return boost::indeterminate;
}
return false;
case http_version_t_1:
if (input == 'T')
{
state_ = http_version_t_2;
return boost::indeterminate;
}
return false;
case http_version_t_2:
if (input == 'T')
{
state_ = http_version_p;
return boost::indeterminate;
}
return false;
case http_version_p:
if (input == 'P')
{
state_ = http_version_slash;
return boost::indeterminate;
}
return false;
case http_version_slash:
if (input == '/')
{
state_ = http_version_major_start;
return boost::indeterminate;
}
return false;
case http_version_major_start:
if (isDigit(input))
{
state_ = http_version_major;
return boost::indeterminate;
}
return false;
case http_version_major:
if (input == '.')
{
state_ = http_version_minor_start;
return boost::indeterminate;
}
if (isDigit(input))
{
return boost::indeterminate;
}
return false;
case http_version_minor_start:
if (isDigit(input))
{
state_ = http_version_minor;
return boost::indeterminate;
}
return false;
case http_version_minor:
if (input == '\r')
{
state_ = expecting_newline_1;
return boost::indeterminate;
}
if (isDigit(input))
{
return boost::indeterminate;
}
return false;
case expecting_newline_1:
if (input == '\n')
{
state_ = header_line_start;
return boost::indeterminate;
}
return false;
case header_line_start:
if (header.name == "Accept-Encoding")
{
/* giving gzip precedence over deflate */
if (header.value.find("deflate") != std::string::npos)
{
compression_type = deflateRFC1951;
}
if (header.value.find("gzip") != std::string::npos)
{
compression_type = gzipRFC1952;
}
}
if ("Referer" == header.name)
{
req.referrer = header.value;
}
if ("User-Agent" == header.name)
{
req.agent = header.value;
}
if (input == '\r')
{
state_ = expecting_newline_3;
return boost::indeterminate;
}
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
}
state_ = header_name;
header.Clear();
header.name.push_back(input);
return boost::indeterminate;
case header_lws:
if (input == '\r')
{
state_ = expecting_newline_2;
return boost::indeterminate;
}
if (input == ' ' || input == '\t')
{
return boost::indeterminate;
}
if (isCTL(input))
{
return false;
}
state_ = header_value;
return boost::indeterminate;
case header_name:
if (input == ':')
{
state_ = space_before_header_value;
return boost::indeterminate;
}
if (!isChar(input) || isCTL(input) || isTSpecial(input))
{
return false;
}
header.name.push_back(input);
return boost::indeterminate;
case space_before_header_value:
if (input == ' ')
{
state_ = header_value;
return boost::indeterminate;
}
return false;
case header_value:
if (input == '\r')
{
state_ = expecting_newline_2;
return boost::indeterminate;
}
if (isCTL(input))
{
return false;
}
header.value.push_back(input);
return boost::indeterminate;
case expecting_newline_2:
if (input == '\n')
{
state_ = header_line_start;
return boost::indeterminate;
}
return false;
default: // expecting_newline_3:
return (input == '\n');
// default:
// return false;
}
}
inline bool RequestParser::isChar(int character) { return character >= 0 && character <= 127; }
inline bool RequestParser::isCTL(int character)
{
return (character >= 0 && character <= 31) || (character == 127);
}
inline bool RequestParser::isTSpecial(int character)
{
switch (character)
{
case '(':
case ')':
case '<':
case '>':
case '@':
case ',':
case ';':
case ':':
case '\\':
case '"':
case '/':
case '[':
case ']':
case '?':
case '=':
case '{':
case '}':
case ' ':
case '\t':
return true;
default:
return false;
}
}
inline bool RequestParser::isDigit(int character) { return character >= '0' && character <= '9'; }
}
-90
View File
@@ -1,90 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef REQUEST_PARSER_H
#define REQUEST_PARSER_H
#include "Http/CompressionType.h"
#include <osrm/Header.h>
#include <boost/logic/tribool.hpp>
#include <boost/tuple/tuple.hpp>
namespace http
{
struct Request;
class RequestParser
{
public:
RequestParser();
void Reset();
boost::tuple<boost::tribool, char *>
Parse(Request &req, char *begin, char *end, CompressionType &compression_type);
private:
boost::tribool consume(Request &req, char input, CompressionType &compression_type);
inline bool isChar(int c);
inline bool isCTL(int c);
inline bool isTSpecial(int c);
inline bool isDigit(int c);
enum state
{ method_start,
method,
uri_start,
uri,
http_version_h,
http_version_t_1,
http_version_t_2,
http_version_p,
http_version_slash,
http_version_major_start,
http_version_major,
http_version_minor_start,
http_version_minor,
expecting_newline_1,
header_line_start,
header_lws,
header_name,
space_before_header_value,
header_value,
expecting_newline_2,
expecting_newline_3 } state_;
Header header;
};
} // namespace http
#endif // REQUEST_PARSER_H
-144
View File
@@ -1,144 +0,0 @@
/*
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BOOST_FILE_SYSTEM_FIX_H
#define BOOST_FILE_SYSTEM_FIX_H
#include "osrm_exception.hpp"
// #include <boost/any.hpp>
#include <boost/filesystem.hpp>
// #include <boost/program_options.hpp>
// This is one big workaround for latest boost renaming woes.
#if BOOST_FILESYSTEM_VERSION < 3
#warning Boost Installation with Filesystem3 missing, activating workaround
#include <cstdio>
#endif
namespace boost
{
namespace filesystem
{
// Validator for boost::filesystem::path, that verifies that the file
// exists. The validate() function must be defined in the same namespace
// as the target type, (boost::filesystem::path in this case), otherwise
// it is not called
// inline void validate(
// boost::any & v,
// const std::vector<std::string> & values,
// boost::filesystem::path *,
// int
// ) {
// boost::program_options::validators::check_first_occurrence(v);
// const std::string & input_string =
// boost::program_options::validators::get_single_string(values);
// if(boost::filesystem::is_regular_file(input_string)) {
// v = boost::any(boost::filesystem::path(input_string));
// } else {
// throw osrm::exception(input_string + " not found");
// }
// }
// adapted from:
// http://stackoverflow.com/questions/1746136/how-do-i-normalize-a-pathname-using-boostfilesystem
inline boost::filesystem::path
portable_canonical(const boost::filesystem::path &relative_path,
const boost::filesystem::path &current_path = boost::filesystem::current_path())
{
const boost::filesystem::path absolute_path =
boost::filesystem::absolute(relative_path, current_path);
boost::filesystem::path canonical_path;
for (auto path_iterator = absolute_path.begin(); path_iterator != absolute_path.end();
++path_iterator)
{
if (".." == path_iterator->string())
{
// /a/b/.. is not necessarily /a if b is a symbolic link
if (boost::filesystem::is_symlink(canonical_path))
{
canonical_path /= *path_iterator;
}
else if (".." == canonical_path.filename())
{
// /a/b/../.. is not /a/b/.. under most circumstances
// We can end up with ..s in our result because of symbolic links
canonical_path /= *path_iterator;
}
else
{
// Otherwise it should be safe to resolve the parent
canonical_path = canonical_path.parent_path();
}
}
else if ("." == path_iterator->string())
{
// Ignore
}
else
{
// Just cat other path entries
canonical_path /= *path_iterator;
}
}
BOOST_ASSERT(canonical_path.is_absolute());
BOOST_ASSERT(boost::filesystem::exists(canonical_path));
return canonical_path;
}
#if BOOST_FILESYSTEM_VERSION < 3
inline path temp_directory_path()
{
char *buffer;
buffer = tmpnam(nullptr);
return path(buffer);
}
inline path unique_path(const path &) { return temp_directory_path(); }
#endif
}
}
#ifndef BOOST_FILESYSTEM_VERSION
#define BOOST_FILESYSTEM_VERSION 3
#endif
inline void AssertPathExists(const boost::filesystem::path &path)
{
if (!boost::filesystem::is_regular_file(path))
{
throw osrm::exception(path.string() + " not found.");
}
}
#endif /* BOOST_FILE_SYSTEM_FIX_H */
-790
View File
@@ -1,790 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TRIGONOMETRY_TABLES_H
#define TRIGONOMETRY_TABLES_H
#include "../typedefs.h"
#include <cmath>
#include <limits>
constexpr unsigned short atan_table[4096] = {
0x0000, 0x0014, 0x0028, 0x003d, 0x0051, 0x0065,
0x007a, 0x008e, 0x00a3, 0x00b7, 0x00cb, 0x00e0,
0x00f4, 0x0108, 0x011d, 0x0131, 0x0146, 0x015a,
0x016e, 0x0183, 0x0197, 0x01ab, 0x01c0, 0x01d4,
0x01e9, 0x01fd, 0x0211, 0x0226, 0x023a, 0x024e,
0x0263, 0x0277, 0x028c, 0x02a0, 0x02b4, 0x02c9,
0x02dd, 0x02f1, 0x0306, 0x031a, 0x032f, 0x0343,
0x0357, 0x036c, 0x0380, 0x0394, 0x03a9, 0x03bd,
0x03d2, 0x03e6, 0x03fa, 0x040f, 0x0423, 0x0437,
0x044c, 0x0460, 0x0475, 0x0489, 0x049d, 0x04b2,
0x04c6, 0x04da, 0x04ef, 0x0503, 0x0517, 0x052c,
0x0540, 0x0555, 0x0569, 0x057d, 0x0592, 0x05a6,
0x05ba, 0x05cf, 0x05e3, 0x05f8, 0x060c, 0x0620,
0x0635, 0x0649, 0x065d, 0x0672, 0x0686, 0x069b,
0x06af, 0x06c3, 0x06d8, 0x06ec, 0x0700, 0x0715,
0x0729, 0x073d, 0x0752, 0x0766, 0x077b, 0x078f,
0x07a3, 0x07b8, 0x07cc, 0x07e0, 0x07f5, 0x0809,
0x081d, 0x0832, 0x0846, 0x085b, 0x086f, 0x0883,
0x0898, 0x08ac, 0x08c0, 0x08d5, 0x08e9, 0x08fd,
0x0912, 0x0926, 0x093b, 0x094f, 0x0963, 0x0978,
0x098c, 0x09a0, 0x09b5, 0x09c9, 0x09dd, 0x09f2,
0x0a06, 0x0a1a, 0x0a2f, 0x0a43, 0x0a58, 0x0a6c,
0x0a80, 0x0a95, 0x0aa9, 0x0abd, 0x0ad2, 0x0ae6,
0x0afa, 0x0b0f, 0x0b23, 0x0b37, 0x0b4c, 0x0b60,
0x0b75, 0x0b89, 0x0b9d, 0x0bb2, 0x0bc6, 0x0bda,
0x0bef, 0x0c03, 0x0c17, 0x0c2c, 0x0c40, 0x0c54,
0x0c69, 0x0c7d, 0x0c91, 0x0ca6, 0x0cba, 0x0cce,
0x0ce3, 0x0cf7, 0x0d0b, 0x0d20, 0x0d34, 0x0d48,
0x0d5d, 0x0d71, 0x0d86, 0x0d9a, 0x0dae, 0x0dc3,
0x0dd7, 0x0deb, 0x0e00, 0x0e14, 0x0e28, 0x0e3d,
0x0e51, 0x0e65, 0x0e7a, 0x0e8e, 0x0ea2, 0x0eb7,
0x0ecb, 0x0edf, 0x0ef4, 0x0f08, 0x0f1c, 0x0f31,
0x0f45, 0x0f59, 0x0f6e, 0x0f82, 0x0f96, 0x0fab,
0x0fbf, 0x0fd3, 0x0fe8, 0x0ffc, 0x1010, 0x1025,
0x1039, 0x104d, 0x1062, 0x1076, 0x108a, 0x109e,
0x10b3, 0x10c7, 0x10db, 0x10f0, 0x1104, 0x1118,
0x112d, 0x1141, 0x1155, 0x116a, 0x117e, 0x1192,
0x11a7, 0x11bb, 0x11cf, 0x11e4, 0x11f8, 0x120c,
0x1221, 0x1235, 0x1249, 0x125d, 0x1272, 0x1286,
0x129a, 0x12af, 0x12c3, 0x12d7, 0x12ec, 0x1300,
0x1314, 0x1329, 0x133d, 0x1351, 0x1365, 0x137a,
0x138e, 0x13a2, 0x13b7, 0x13cb, 0x13df, 0x13f4,
0x1408, 0x141c, 0x1431, 0x1445, 0x1459, 0x146d,
0x1482, 0x1496, 0x14aa, 0x14bf, 0x14d3, 0x14e7,
0x14fb, 0x1510, 0x1524, 0x1538, 0x154d, 0x1561,
0x1575, 0x1589, 0x159e, 0x15b2, 0x15c6, 0x15db,
0x15ef, 0x1603, 0x1617, 0x162c, 0x1640, 0x1654,
0x1669, 0x167d, 0x1691, 0x16a5, 0x16ba, 0x16ce,
0x16e2, 0x16f7, 0x170b, 0x171f, 0x1733, 0x1748,
0x175c, 0x1770, 0x1784, 0x1799, 0x17ad, 0x17c1,
0x17d6, 0x17ea, 0x17fe, 0x1812, 0x1827, 0x183b,
0x184f, 0x1863, 0x1878, 0x188c, 0x18a0, 0x18b4,
0x18c9, 0x18dd, 0x18f1, 0x1905, 0x191a, 0x192e,
0x1942, 0x1957, 0x196b, 0x197f, 0x1993, 0x19a8,
0x19bc, 0x19d0, 0x19e4, 0x19f9, 0x1a0d, 0x1a21,
0x1a35, 0x1a49, 0x1a5e, 0x1a72, 0x1a86, 0x1a9a,
0x1aaf, 0x1ac3, 0x1ad7, 0x1aeb, 0x1b00, 0x1b14,
0x1b28, 0x1b3c, 0x1b51, 0x1b65, 0x1b79, 0x1b8d,
0x1ba2, 0x1bb6, 0x1bca, 0x1bde, 0x1bf2, 0x1c07,
0x1c1b, 0x1c2f, 0x1c43, 0x1c58, 0x1c6c, 0x1c80,
0x1c94, 0x1ca8, 0x1cbd, 0x1cd1, 0x1ce5, 0x1cf9,
0x1d0e, 0x1d22, 0x1d36, 0x1d4a, 0x1d5e, 0x1d73,
0x1d87, 0x1d9b, 0x1daf, 0x1dc3, 0x1dd8, 0x1dec,
0x1e00, 0x1e14, 0x1e28, 0x1e3d, 0x1e51, 0x1e65,
0x1e79, 0x1e8d, 0x1ea2, 0x1eb6, 0x1eca, 0x1ede,
0x1ef2, 0x1f07, 0x1f1b, 0x1f2f, 0x1f43, 0x1f57,
0x1f6c, 0x1f80, 0x1f94, 0x1fa8, 0x1fbc, 0x1fd1,
0x1fe5, 0x1ff9, 0x200d, 0x2021, 0x2035, 0x204a,
0x205e, 0x2072, 0x2086, 0x209a, 0x20ae, 0x20c3,
0x20d7, 0x20eb, 0x20ff, 0x2113, 0x2127, 0x213c,
0x2150, 0x2164, 0x2178, 0x218c, 0x21a0, 0x21b5,
0x21c9, 0x21dd, 0x21f1, 0x2205, 0x2219, 0x222e,
0x2242, 0x2256, 0x226a, 0x227e, 0x2292, 0x22a6,
0x22bb, 0x22cf, 0x22e3, 0x22f7, 0x230b, 0x231f,
0x2333, 0x2348, 0x235c, 0x2370, 0x2384, 0x2398,
0x23ac, 0x23c0, 0x23d5, 0x23e9, 0x23fd, 0x2411,
0x2425, 0x2439, 0x244d, 0x2461, 0x2476, 0x248a,
0x249e, 0x24b2, 0x24c6, 0x24da, 0x24ee, 0x2502,
0x2517, 0x252b, 0x253f, 0x2553, 0x2567, 0x257b,
0x258f, 0x25a3, 0x25b7, 0x25cb, 0x25e0, 0x25f4,
0x2608, 0x261c, 0x2630, 0x2644, 0x2658, 0x266c,
0x2680, 0x2694, 0x26a9, 0x26bd, 0x26d1, 0x26e5,
0x26f9, 0x270d, 0x2721, 0x2735, 0x2749, 0x275d,
0x2771, 0x2785, 0x279a, 0x27ae, 0x27c2, 0x27d6,
0x27ea, 0x27fe, 0x2812, 0x2826, 0x283a, 0x284e,
0x2862, 0x2876, 0x288a, 0x289e, 0x28b3, 0x28c7,
0x28db, 0x28ef, 0x2903, 0x2917, 0x292b, 0x293f,
0x2953, 0x2967, 0x297b, 0x298f, 0x29a3, 0x29b7,
0x29cb, 0x29df, 0x29f3, 0x2a07, 0x2a1b, 0x2a2f,
0x2a43, 0x2a58, 0x2a6c, 0x2a80, 0x2a94, 0x2aa8,
0x2abc, 0x2ad0, 0x2ae4, 0x2af8, 0x2b0c, 0x2b20,
0x2b34, 0x2b48, 0x2b5c, 0x2b70, 0x2b84, 0x2b98,
0x2bac, 0x2bc0, 0x2bd4, 0x2be8, 0x2bfc, 0x2c10,
0x2c24, 0x2c38, 0x2c4c, 0x2c60, 0x2c74, 0x2c88,
0x2c9c, 0x2cb0, 0x2cc4, 0x2cd8, 0x2cec, 0x2d00,
0x2d14, 0x2d28, 0x2d3c, 0x2d50, 0x2d64, 0x2d78,
0x2d8c, 0x2da0, 0x2db4, 0x2dc8, 0x2ddc, 0x2df0,
0x2e04, 0x2e18, 0x2e2c, 0x2e40, 0x2e54, 0x2e68,
0x2e7c, 0x2e90, 0x2ea3, 0x2eb7, 0x2ecb, 0x2edf,
0x2ef3, 0x2f07, 0x2f1b, 0x2f2f, 0x2f43, 0x2f57,
0x2f6b, 0x2f7f, 0x2f93, 0x2fa7, 0x2fbb, 0x2fcf,
0x2fe3, 0x2ff7, 0x300b, 0x301e, 0x3032, 0x3046,
0x305a, 0x306e, 0x3082, 0x3096, 0x30aa, 0x30be,
0x30d2, 0x30e6, 0x30fa, 0x310e, 0x3122, 0x3135,
0x3149, 0x315d, 0x3171, 0x3185, 0x3199, 0x31ad,
0x31c1, 0x31d5, 0x31e9, 0x31fd, 0x3210, 0x3224,
0x3238, 0x324c, 0x3260, 0x3274, 0x3288, 0x329c,
0x32b0, 0x32c3, 0x32d7, 0x32eb, 0x32ff, 0x3313,
0x3327, 0x333b, 0x334f, 0x3363, 0x3376, 0x338a,
0x339e, 0x33b2, 0x33c6, 0x33da, 0x33ee, 0x3401,
0x3415, 0x3429, 0x343d, 0x3451, 0x3465, 0x3479,
0x348c, 0x34a0, 0x34b4, 0x34c8, 0x34dc, 0x34f0,
0x3504, 0x3517, 0x352b, 0x353f, 0x3553, 0x3567,
0x357b, 0x358e, 0x35a2, 0x35b6, 0x35ca, 0x35de,
0x35f2, 0x3605, 0x3619, 0x362d, 0x3641, 0x3655,
0x3668, 0x367c, 0x3690, 0x36a4, 0x36b8, 0x36cb,
0x36df, 0x36f3, 0x3707, 0x371b, 0x372f, 0x3742,
0x3756, 0x376a, 0x377e, 0x3791, 0x37a5, 0x37b9,
0x37cd, 0x37e1, 0x37f4, 0x3808, 0x381c, 0x3830,
0x3844, 0x3857, 0x386b, 0x387f, 0x3893, 0x38a6,
0x38ba, 0x38ce, 0x38e2, 0x38f5, 0x3909, 0x391d,
0x3931, 0x3944, 0x3958, 0x396c, 0x3980, 0x3993,
0x39a7, 0x39bb, 0x39cf, 0x39e2, 0x39f6, 0x3a0a,
0x3a1e, 0x3a31, 0x3a45, 0x3a59, 0x3a6d, 0x3a80,
0x3a94, 0x3aa8, 0x3abb, 0x3acf, 0x3ae3, 0x3af7,
0x3b0a, 0x3b1e, 0x3b32, 0x3b45, 0x3b59, 0x3b6d,
0x3b81, 0x3b94, 0x3ba8, 0x3bbc, 0x3bcf, 0x3be3,
0x3bf7, 0x3c0b, 0x3c1e, 0x3c32, 0x3c46, 0x3c59,
0x3c6d, 0x3c81, 0x3c94, 0x3ca8, 0x3cbc, 0x3ccf,
0x3ce3, 0x3cf7, 0x3d0a, 0x3d1e, 0x3d32, 0x3d45,
0x3d59, 0x3d6d, 0x3d80, 0x3d94, 0x3da8, 0x3dbb,
0x3dcf, 0x3de3, 0x3df6, 0x3e0a, 0x3e1e, 0x3e31,
0x3e45, 0x3e59, 0x3e6c, 0x3e80, 0x3e93, 0x3ea7,
0x3ebb, 0x3ece, 0x3ee2, 0x3ef6, 0x3f09, 0x3f1d,
0x3f30, 0x3f44, 0x3f58, 0x3f6b, 0x3f7f, 0x3f93,
0x3fa6, 0x3fba, 0x3fcd, 0x3fe1, 0x3ff5, 0x4008,
0x401c, 0x402f, 0x4043, 0x4057, 0x406a, 0x407e,
0x4091, 0x40a5, 0x40b8, 0x40cc, 0x40e0, 0x40f3,
0x4107, 0x411a, 0x412e, 0x4142, 0x4155, 0x4169,
0x417c, 0x4190, 0x41a3, 0x41b7, 0x41ca, 0x41de,
0x41f2, 0x4205, 0x4219, 0x422c, 0x4240, 0x4253,
0x4267, 0x427a, 0x428e, 0x42a1, 0x42b5, 0x42c9,
0x42dc, 0x42f0, 0x4303, 0x4317, 0x432a, 0x433e,
0x4351, 0x4365, 0x4378, 0x438c, 0x439f, 0x43b3,
0x43c6, 0x43da, 0x43ed, 0x4401, 0x4414, 0x4428,
0x443b, 0x444f, 0x4462, 0x4476, 0x4489, 0x449d,
0x44b0, 0x44c4, 0x44d7, 0x44eb, 0x44fe, 0x4512,
0x4525, 0x4539, 0x454c, 0x4560, 0x4573, 0x4586,
0x459a, 0x45ad, 0x45c1, 0x45d4, 0x45e8, 0x45fb,
0x460f, 0x4622, 0x4636, 0x4649, 0x465c, 0x4670,
0x4683, 0x4697, 0x46aa, 0x46be, 0x46d1, 0x46e5,
0x46f8, 0x470b, 0x471f, 0x4732, 0x4746, 0x4759,
0x476c, 0x4780, 0x4793, 0x47a7, 0x47ba, 0x47cd,
0x47e1, 0x47f4, 0x4808, 0x481b, 0x482e, 0x4842,
0x4855, 0x4869, 0x487c, 0x488f, 0x48a3, 0x48b6,
0x48ca, 0x48dd, 0x48f0, 0x4904, 0x4917, 0x492a,
0x493e, 0x4951, 0x4965, 0x4978, 0x498b, 0x499f,
0x49b2, 0x49c5, 0x49d9, 0x49ec, 0x49ff, 0x4a13,
0x4a26, 0x4a39, 0x4a4d, 0x4a60, 0x4a73, 0x4a87,
0x4a9a, 0x4aad, 0x4ac1, 0x4ad4, 0x4ae7, 0x4afb,
0x4b0e, 0x4b21, 0x4b35, 0x4b48, 0x4b5b, 0x4b6f,
0x4b82, 0x4b95, 0x4ba8, 0x4bbc, 0x4bcf, 0x4be2,
0x4bf6, 0x4c09, 0x4c1c, 0x4c2f, 0x4c43, 0x4c56,
0x4c69, 0x4c7d, 0x4c90, 0x4ca3, 0x4cb6, 0x4cca,
0x4cdd, 0x4cf0, 0x4d03, 0x4d17, 0x4d2a, 0x4d3d,
0x4d50, 0x4d64, 0x4d77, 0x4d8a, 0x4d9d, 0x4db1,
0x4dc4, 0x4dd7, 0x4dea, 0x4dfe, 0x4e11, 0x4e24,
0x4e37, 0x4e4b, 0x4e5e, 0x4e71, 0x4e84, 0x4e97,
0x4eab, 0x4ebe, 0x4ed1, 0x4ee4, 0x4ef7, 0x4f0b,
0x4f1e, 0x4f31, 0x4f44, 0x4f57, 0x4f6b, 0x4f7e,
0x4f91, 0x4fa4, 0x4fb7, 0x4fcb, 0x4fde, 0x4ff1,
0x5004, 0x5017, 0x502a, 0x503e, 0x5051, 0x5064,
0x5077, 0x508a, 0x509d, 0x50b1, 0x50c4, 0x50d7,
0x50ea, 0x50fd, 0x5110, 0x5123, 0x5137, 0x514a,
0x515d, 0x5170, 0x5183, 0x5196, 0x51a9, 0x51bc,
0x51d0, 0x51e3, 0x51f6, 0x5209, 0x521c, 0x522f,
0x5242, 0x5255, 0x5268, 0x527c, 0x528f, 0x52a2,
0x52b5, 0x52c8, 0x52db, 0x52ee, 0x5301, 0x5314,
0x5327, 0x533a, 0x534e, 0x5361, 0x5374, 0x5387,
0x539a, 0x53ad, 0x53c0, 0x53d3, 0x53e6, 0x53f9,
0x540c, 0x541f, 0x5432, 0x5445, 0x5458, 0x546b,
0x547e, 0x5491, 0x54a5, 0x54b8, 0x54cb, 0x54de,
0x54f1, 0x5504, 0x5517, 0x552a, 0x553d, 0x5550,
0x5563, 0x5576, 0x5589, 0x559c, 0x55af, 0x55c2,
0x55d5, 0x55e8, 0x55fb, 0x560e, 0x5621, 0x5634,
0x5647, 0x565a, 0x566d, 0x5680, 0x5693, 0x56a6,
0x56b9, 0x56cb, 0x56de, 0x56f1, 0x5704, 0x5717,
0x572a, 0x573d, 0x5750, 0x5763, 0x5776, 0x5789,
0x579c, 0x57af, 0x57c2, 0x57d5, 0x57e8, 0x57fb,
0x580e, 0x5820, 0x5833, 0x5846, 0x5859, 0x586c,
0x587f, 0x5892, 0x58a5, 0x58b8, 0x58cb, 0x58de,
0x58f0, 0x5903, 0x5916, 0x5929, 0x593c, 0x594f,
0x5962, 0x5975, 0x5988, 0x599a, 0x59ad, 0x59c0,
0x59d3, 0x59e6, 0x59f9, 0x5a0c, 0x5a1f, 0x5a31,
0x5a44, 0x5a57, 0x5a6a, 0x5a7d, 0x5a90, 0x5aa2,
0x5ab5, 0x5ac8, 0x5adb, 0x5aee, 0x5b01, 0x5b13,
0x5b26, 0x5b39, 0x5b4c, 0x5b5f, 0x5b72, 0x5b84,
0x5b97, 0x5baa, 0x5bbd, 0x5bd0, 0x5be2, 0x5bf5,
0x5c08, 0x5c1b, 0x5c2e, 0x5c40, 0x5c53, 0x5c66,
0x5c79, 0x5c8c, 0x5c9e, 0x5cb1, 0x5cc4, 0x5cd7,
0x5ce9, 0x5cfc, 0x5d0f, 0x5d22, 0x5d34, 0x5d47,
0x5d5a, 0x5d6d, 0x5d7f, 0x5d92, 0x5da5, 0x5db8,
0x5dca, 0x5ddd, 0x5df0, 0x5e03, 0x5e15, 0x5e28,
0x5e3b, 0x5e4d, 0x5e60, 0x5e73, 0x5e86, 0x5e98,
0x5eab, 0x5ebe, 0x5ed0, 0x5ee3, 0x5ef6, 0x5f09,
0x5f1b, 0x5f2e, 0x5f41, 0x5f53, 0x5f66, 0x5f79,
0x5f8b, 0x5f9e, 0x5fb1, 0x5fc3, 0x5fd6, 0x5fe9,
0x5ffb, 0x600e, 0x6021, 0x6033, 0x6046, 0x6059,
0x606b, 0x607e, 0x6091, 0x60a3, 0x60b6, 0x60c8,
0x60db, 0x60ee, 0x6100, 0x6113, 0x6126, 0x6138,
0x614b, 0x615d, 0x6170, 0x6183, 0x6195, 0x61a8,
0x61ba, 0x61cd, 0x61e0, 0x61f2, 0x6205, 0x6217,
0x622a, 0x623d, 0x624f, 0x6262, 0x6274, 0x6287,
0x6299, 0x62ac, 0x62bf, 0x62d1, 0x62e4, 0x62f6,
0x6309, 0x631b, 0x632e, 0x6340, 0x6353, 0x6366,
0x6378, 0x638b, 0x639d, 0x63b0, 0x63c2, 0x63d5,
0x63e7, 0x63fa, 0x640c, 0x641f, 0x6431, 0x6444,
0x6456, 0x6469, 0x647b, 0x648e, 0x64a0, 0x64b3,
0x64c5, 0x64d8, 0x64ea, 0x64fd, 0x650f, 0x6522,
0x6534, 0x6547, 0x6559, 0x656c, 0x657e, 0x6591,
0x65a3, 0x65b5, 0x65c8, 0x65da, 0x65ed, 0x65ff,
0x6612, 0x6624, 0x6637, 0x6649, 0x665b, 0x666e,
0x6680, 0x6693, 0x66a5, 0x66b8, 0x66ca, 0x66dc,
0x66ef, 0x6701, 0x6714, 0x6726, 0x6738, 0x674b,
0x675d, 0x6770, 0x6782, 0x6794, 0x67a7, 0x67b9,
0x67cc, 0x67de, 0x67f0, 0x6803, 0x6815, 0x6827,
0x683a, 0x684c, 0x685e, 0x6871, 0x6883, 0x6896,
0x68a8, 0x68ba, 0x68cd, 0x68df, 0x68f1, 0x6904,
0x6916, 0x6928, 0x693b, 0x694d, 0x695f, 0x6972,
0x6984, 0x6996, 0x69a8, 0x69bb, 0x69cd, 0x69df,
0x69f2, 0x6a04, 0x6a16, 0x6a29, 0x6a3b, 0x6a4d,
0x6a5f, 0x6a72, 0x6a84, 0x6a96, 0x6aa9, 0x6abb,
0x6acd, 0x6adf, 0x6af2, 0x6b04, 0x6b16, 0x6b28,
0x6b3b, 0x6b4d, 0x6b5f, 0x6b71, 0x6b84, 0x6b96,
0x6ba8, 0x6bba, 0x6bcd, 0x6bdf, 0x6bf1, 0x6c03,
0x6c15, 0x6c28, 0x6c3a, 0x6c4c, 0x6c5e, 0x6c70,
0x6c83, 0x6c95, 0x6ca7, 0x6cb9, 0x6ccb, 0x6cde,
0x6cf0, 0x6d02, 0x6d14, 0x6d26, 0x6d39, 0x6d4b,
0x6d5d, 0x6d6f, 0x6d81, 0x6d93, 0x6da6, 0x6db8,
0x6dca, 0x6ddc, 0x6dee, 0x6e00, 0x6e12, 0x6e25,
0x6e37, 0x6e49, 0x6e5b, 0x6e6d, 0x6e7f, 0x6e91,
0x6ea3, 0x6eb6, 0x6ec8, 0x6eda, 0x6eec, 0x6efe,
0x6f10, 0x6f22, 0x6f34, 0x6f46, 0x6f58, 0x6f6b,
0x6f7d, 0x6f8f, 0x6fa1, 0x6fb3, 0x6fc5, 0x6fd7,
0x6fe9, 0x6ffb, 0x700d, 0x701f, 0x7031, 0x7043,
0x7055, 0x7068, 0x707a, 0x708c, 0x709e, 0x70b0,
0x70c2, 0x70d4, 0x70e6, 0x70f8, 0x710a, 0x711c,
0x712e, 0x7140, 0x7152, 0x7164, 0x7176, 0x7188,
0x719a, 0x71ac, 0x71be, 0x71d0, 0x71e2, 0x71f4,
0x7206, 0x7218, 0x722a, 0x723c, 0x724e, 0x7260,
0x7272, 0x7284, 0x7296, 0x72a8, 0x72ba, 0x72cc,
0x72dd, 0x72ef, 0x7301, 0x7313, 0x7325, 0x7337,
0x7349, 0x735b, 0x736d, 0x737f, 0x7391, 0x73a3,
0x73b5, 0x73c7, 0x73d8, 0x73ea, 0x73fc, 0x740e,
0x7420, 0x7432, 0x7444, 0x7456, 0x7468, 0x747a,
0x748b, 0x749d, 0x74af, 0x74c1, 0x74d3, 0x74e5,
0x74f7, 0x7509, 0x751a, 0x752c, 0x753e, 0x7550,
0x7562, 0x7574, 0x7585, 0x7597, 0x75a9, 0x75bb,
0x75cd, 0x75df, 0x75f0, 0x7602, 0x7614, 0x7626,
0x7638, 0x764a, 0x765b, 0x766d, 0x767f, 0x7691,
0x76a3, 0x76b4, 0x76c6, 0x76d8, 0x76ea, 0x76fb,
0x770d, 0x771f, 0x7731, 0x7743, 0x7754, 0x7766,
0x7778, 0x778a, 0x779b, 0x77ad, 0x77bf, 0x77d1,
0x77e2, 0x77f4, 0x7806, 0x7818, 0x7829, 0x783b,
0x784d, 0x785e, 0x7870, 0x7882, 0x7894, 0x78a5,
0x78b7, 0x78c9, 0x78da, 0x78ec, 0x78fe, 0x7910,
0x7921, 0x7933, 0x7945, 0x7956, 0x7968, 0x797a,
0x798b, 0x799d, 0x79af, 0x79c0, 0x79d2, 0x79e4,
0x79f5, 0x7a07, 0x7a19, 0x7a2a, 0x7a3c, 0x7a4e,
0x7a5f, 0x7a71, 0x7a82, 0x7a94, 0x7aa6, 0x7ab7,
0x7ac9, 0x7adb, 0x7aec, 0x7afe, 0x7b0f, 0x7b21,
0x7b33, 0x7b44, 0x7b56, 0x7b67, 0x7b79, 0x7b8b,
0x7b9c, 0x7bae, 0x7bbf, 0x7bd1, 0x7be2, 0x7bf4,
0x7c06, 0x7c17, 0x7c29, 0x7c3a, 0x7c4c, 0x7c5d,
0x7c6f, 0x7c81, 0x7c92, 0x7ca4, 0x7cb5, 0x7cc7,
0x7cd8, 0x7cea, 0x7cfb, 0x7d0d, 0x7d1e, 0x7d30,
0x7d41, 0x7d53, 0x7d64, 0x7d76, 0x7d87, 0x7d99,
0x7daa, 0x7dbc, 0x7dcd, 0x7ddf, 0x7df0, 0x7e02,
0x7e13, 0x7e25, 0x7e36, 0x7e48, 0x7e59, 0x7e6b,
0x7e7c, 0x7e8e, 0x7e9f, 0x7eb0, 0x7ec2, 0x7ed3,
0x7ee5, 0x7ef6, 0x7f08, 0x7f19, 0x7f2b, 0x7f3c,
0x7f4d, 0x7f5f, 0x7f70, 0x7f82, 0x7f93, 0x7fa4,
0x7fb6, 0x7fc7, 0x7fd9, 0x7fea, 0x7ffb, 0x800d,
0x801e, 0x8030, 0x8041, 0x8052, 0x8064, 0x8075,
0x8086, 0x8098, 0x80a9, 0x80bb, 0x80cc, 0x80dd,
0x80ef, 0x8100, 0x8111, 0x8123, 0x8134, 0x8145,
0x8157, 0x8168, 0x8179, 0x818b, 0x819c, 0x81ad,
0x81bf, 0x81d0, 0x81e1, 0x81f3, 0x8204, 0x8215,
0x8226, 0x8238, 0x8249, 0x825a, 0x826c, 0x827d,
0x828e, 0x829f, 0x82b1, 0x82c2, 0x82d3, 0x82e5,
0x82f6, 0x8307, 0x8318, 0x832a, 0x833b, 0x834c,
0x835d, 0x836f, 0x8380, 0x8391, 0x83a2, 0x83b3,
0x83c5, 0x83d6, 0x83e7, 0x83f8, 0x840a, 0x841b,
0x842c, 0x843d, 0x844e, 0x8460, 0x8471, 0x8482,
0x8493, 0x84a4, 0x84b6, 0x84c7, 0x84d8, 0x84e9,
0x84fa, 0x850b, 0x851d, 0x852e, 0x853f, 0x8550,
0x8561, 0x8572, 0x8584, 0x8595, 0x85a6, 0x85b7,
0x85c8, 0x85d9, 0x85ea, 0x85fb, 0x860d, 0x861e,
0x862f, 0x8640, 0x8651, 0x8662, 0x8673, 0x8684,
0x8695, 0x86a7, 0x86b8, 0x86c9, 0x86da, 0x86eb,
0x86fc, 0x870d, 0x871e, 0x872f, 0x8740, 0x8751,
0x8762, 0x8773, 0x8784, 0x8796, 0x87a7, 0x87b8,
0x87c9, 0x87da, 0x87eb, 0x87fc, 0x880d, 0x881e,
0x882f, 0x8840, 0x8851, 0x8862, 0x8873, 0x8884,
0x8895, 0x88a6, 0x88b7, 0x88c8, 0x88d9, 0x88ea,
0x88fb, 0x890c, 0x891d, 0x892e, 0x893f, 0x8950,
0x8961, 0x8972, 0x8983, 0x8994, 0x89a5, 0x89b6,
0x89c6, 0x89d7, 0x89e8, 0x89f9, 0x8a0a, 0x8a1b,
0x8a2c, 0x8a3d, 0x8a4e, 0x8a5f, 0x8a70, 0x8a81,
0x8a92, 0x8aa3, 0x8ab3, 0x8ac4, 0x8ad5, 0x8ae6,
0x8af7, 0x8b08, 0x8b19, 0x8b2a, 0x8b3b, 0x8b4b,
0x8b5c, 0x8b6d, 0x8b7e, 0x8b8f, 0x8ba0, 0x8bb1,
0x8bc1, 0x8bd2, 0x8be3, 0x8bf4, 0x8c05, 0x8c16,
0x8c27, 0x8c37, 0x8c48, 0x8c59, 0x8c6a, 0x8c7b,
0x8c8c, 0x8c9c, 0x8cad, 0x8cbe, 0x8ccf, 0x8ce0,
0x8cf0, 0x8d01, 0x8d12, 0x8d23, 0x8d34, 0x8d44,
0x8d55, 0x8d66, 0x8d77, 0x8d87, 0x8d98, 0x8da9,
0x8dba, 0x8dca, 0x8ddb, 0x8dec, 0x8dfd, 0x8e0d,
0x8e1e, 0x8e2f, 0x8e40, 0x8e50, 0x8e61, 0x8e72,
0x8e83, 0x8e93, 0x8ea4, 0x8eb5, 0x8ec5, 0x8ed6,
0x8ee7, 0x8ef8, 0x8f08, 0x8f19, 0x8f2a, 0x8f3a,
0x8f4b, 0x8f5c, 0x8f6c, 0x8f7d, 0x8f8e, 0x8f9e,
0x8faf, 0x8fc0, 0x8fd0, 0x8fe1, 0x8ff2, 0x9002,
0x9013, 0x9024, 0x9034, 0x9045, 0x9056, 0x9066,
0x9077, 0x9088, 0x9098, 0x90a9, 0x90b9, 0x90ca,
0x90db, 0x90eb, 0x90fc, 0x910c, 0x911d, 0x912e,
0x913e, 0x914f, 0x915f, 0x9170, 0x9181, 0x9191,
0x91a2, 0x91b2, 0x91c3, 0x91d3, 0x91e4, 0x91f5,
0x9205, 0x9216, 0x9226, 0x9237, 0x9247, 0x9258,
0x9268, 0x9279, 0x9289, 0x929a, 0x92aa, 0x92bb,
0x92cc, 0x92dc, 0x92ed, 0x92fd, 0x930e, 0x931e,
0x932f, 0x933f, 0x9350, 0x9360, 0x9370, 0x9381,
0x9391, 0x93a2, 0x93b2, 0x93c3, 0x93d3, 0x93e4,
0x93f4, 0x9405, 0x9415, 0x9426, 0x9436, 0x9447,
0x9457, 0x9467, 0x9478, 0x9488, 0x9499, 0x94a9,
0x94ba, 0x94ca, 0x94da, 0x94eb, 0x94fb, 0x950c,
0x951c, 0x952c, 0x953d, 0x954d, 0x955e, 0x956e,
0x957e, 0x958f, 0x959f, 0x95af, 0x95c0, 0x95d0,
0x95e1, 0x95f1, 0x9601, 0x9612, 0x9622, 0x9632,
0x9643, 0x9653, 0x9663, 0x9674, 0x9684, 0x9694,
0x96a5, 0x96b5, 0x96c5, 0x96d6, 0x96e6, 0x96f6,
0x9707, 0x9717, 0x9727, 0x9738, 0x9748, 0x9758,
0x9768, 0x9779, 0x9789, 0x9799, 0x97aa, 0x97ba,
0x97ca, 0x97da, 0x97eb, 0x97fb, 0x980b, 0x981b,
0x982c, 0x983c, 0x984c, 0x985c, 0x986d, 0x987d,
0x988d, 0x989d, 0x98ad, 0x98be, 0x98ce, 0x98de,
0x98ee, 0x98ff, 0x990f, 0x991f, 0x992f, 0x993f,
0x9950, 0x9960, 0x9970, 0x9980, 0x9990, 0x99a0,
0x99b1, 0x99c1, 0x99d1, 0x99e1, 0x99f1, 0x9a01,
0x9a12, 0x9a22, 0x9a32, 0x9a42, 0x9a52, 0x9a62,
0x9a72, 0x9a83, 0x9a93, 0x9aa3, 0x9ab3, 0x9ac3,
0x9ad3, 0x9ae3, 0x9af3, 0x9b04, 0x9b14, 0x9b24,
0x9b34, 0x9b44, 0x9b54, 0x9b64, 0x9b74, 0x9b84,
0x9b94, 0x9ba4, 0x9bb5, 0x9bc5, 0x9bd5, 0x9be5,
0x9bf5, 0x9c05, 0x9c15, 0x9c25, 0x9c35, 0x9c45,
0x9c55, 0x9c65, 0x9c75, 0x9c85, 0x9c95, 0x9ca5,
0x9cb5, 0x9cc5, 0x9cd5, 0x9ce5, 0x9cf5, 0x9d05,
0x9d15, 0x9d25, 0x9d35, 0x9d45, 0x9d55, 0x9d65,
0x9d75, 0x9d85, 0x9d95, 0x9da5, 0x9db5, 0x9dc5,
0x9dd5, 0x9de5, 0x9df5, 0x9e05, 0x9e15, 0x9e25,
0x9e35, 0x9e45, 0x9e55, 0x9e65, 0x9e74, 0x9e84,
0x9e94, 0x9ea4, 0x9eb4, 0x9ec4, 0x9ed4, 0x9ee4,
0x9ef4, 0x9f04, 0x9f14, 0x9f23, 0x9f33, 0x9f43,
0x9f53, 0x9f63, 0x9f73, 0x9f83, 0x9f93, 0x9fa3,
0x9fb2, 0x9fc2, 0x9fd2, 0x9fe2, 0x9ff2, 0xa002,
0xa012, 0xa021, 0xa031, 0xa041, 0xa051, 0xa061,
0xa071, 0xa080, 0xa090, 0xa0a0, 0xa0b0, 0xa0c0,
0xa0cf, 0xa0df, 0xa0ef, 0xa0ff, 0xa10f, 0xa11e,
0xa12e, 0xa13e, 0xa14e, 0xa15e, 0xa16d, 0xa17d,
0xa18d, 0xa19d, 0xa1ac, 0xa1bc, 0xa1cc, 0xa1dc,
0xa1eb, 0xa1fb, 0xa20b, 0xa21b, 0xa22a, 0xa23a,
0xa24a, 0xa25a, 0xa269, 0xa279, 0xa289, 0xa298,
0xa2a8, 0xa2b8, 0xa2c8, 0xa2d7, 0xa2e7, 0xa2f7,
0xa306, 0xa316, 0xa326, 0xa335, 0xa345, 0xa355,
0xa364, 0xa374, 0xa384, 0xa393, 0xa3a3, 0xa3b3,
0xa3c2, 0xa3d2, 0xa3e2, 0xa3f1, 0xa401, 0xa411,
0xa420, 0xa430, 0xa440, 0xa44f, 0xa45f, 0xa46e,
0xa47e, 0xa48e, 0xa49d, 0xa4ad, 0xa4bc, 0xa4cc,
0xa4dc, 0xa4eb, 0xa4fb, 0xa50a, 0xa51a, 0xa52a,
0xa539, 0xa549, 0xa558, 0xa568, 0xa577, 0xa587,
0xa597, 0xa5a6, 0xa5b6, 0xa5c5, 0xa5d5, 0xa5e4,
0xa5f4, 0xa603, 0xa613, 0xa622, 0xa632, 0xa641,
0xa651, 0xa660, 0xa670, 0xa67f, 0xa68f, 0xa69e,
0xa6ae, 0xa6bd, 0xa6cd, 0xa6dc, 0xa6ec, 0xa6fb,
0xa70b, 0xa71a, 0xa72a, 0xa739, 0xa749, 0xa758,
0xa768, 0xa777, 0xa787, 0xa796, 0xa7a5, 0xa7b5,
0xa7c4, 0xa7d4, 0xa7e3, 0xa7f3, 0xa802, 0xa812,
0xa821, 0xa830, 0xa840, 0xa84f, 0xa85f, 0xa86e,
0xa87d, 0xa88d, 0xa89c, 0xa8ac, 0xa8bb, 0xa8ca,
0xa8da, 0xa8e9, 0xa8f8, 0xa908, 0xa917, 0xa927,
0xa936, 0xa945, 0xa955, 0xa964, 0xa973, 0xa983,
0xa992, 0xa9a1, 0xa9b1, 0xa9c0, 0xa9cf, 0xa9df,
0xa9ee, 0xa9fd, 0xaa0d, 0xaa1c, 0xaa2b, 0xaa3b,
0xaa4a, 0xaa59, 0xaa69, 0xaa78, 0xaa87, 0xaa96,
0xaaa6, 0xaab5, 0xaac4, 0xaad4, 0xaae3, 0xaaf2,
0xab01, 0xab11, 0xab20, 0xab2f, 0xab3e, 0xab4e,
0xab5d, 0xab6c, 0xab7b, 0xab8b, 0xab9a, 0xaba9,
0xabb8, 0xabc7, 0xabd7, 0xabe6, 0xabf5, 0xac04,
0xac14, 0xac23, 0xac32, 0xac41, 0xac50, 0xac60,
0xac6f, 0xac7e, 0xac8d, 0xac9c, 0xacab, 0xacbb,
0xacca, 0xacd9, 0xace8, 0xacf7, 0xad06, 0xad16,
0xad25, 0xad34, 0xad43, 0xad52, 0xad61, 0xad70,
0xad80, 0xad8f, 0xad9e, 0xadad, 0xadbc, 0xadcb,
0xadda, 0xade9, 0xadf8, 0xae08, 0xae17, 0xae26,
0xae35, 0xae44, 0xae53, 0xae62, 0xae71, 0xae80,
0xae8f, 0xae9e, 0xaead, 0xaebd, 0xaecc, 0xaedb,
0xaeea, 0xaef9, 0xaf08, 0xaf17, 0xaf26, 0xaf35,
0xaf44, 0xaf53, 0xaf62, 0xaf71, 0xaf80, 0xaf8f,
0xaf9e, 0xafad, 0xafbc, 0xafcb, 0xafda, 0xafe9,
0xaff8, 0xb007, 0xb016, 0xb025, 0xb034, 0xb043,
0xb052, 0xb061, 0xb070, 0xb07f, 0xb08e, 0xb09d,
0xb0ac, 0xb0bb, 0xb0ca, 0xb0d9, 0xb0e8, 0xb0f6,
0xb105, 0xb114, 0xb123, 0xb132, 0xb141, 0xb150,
0xb15f, 0xb16e, 0xb17d, 0xb18c, 0xb19b, 0xb1aa,
0xb1b8, 0xb1c7, 0xb1d6, 0xb1e5, 0xb1f4, 0xb203,
0xb212, 0xb221, 0xb22f, 0xb23e, 0xb24d, 0xb25c,
0xb26b, 0xb27a, 0xb289, 0xb297, 0xb2a6, 0xb2b5,
0xb2c4, 0xb2d3, 0xb2e2, 0xb2f1, 0xb2ff, 0xb30e,
0xb31d, 0xb32c, 0xb33b, 0xb349, 0xb358, 0xb367,
0xb376, 0xb385, 0xb393, 0xb3a2, 0xb3b1, 0xb3c0,
0xb3cf, 0xb3dd, 0xb3ec, 0xb3fb, 0xb40a, 0xb418,
0xb427, 0xb436, 0xb445, 0xb453, 0xb462, 0xb471,
0xb480, 0xb48e, 0xb49d, 0xb4ac, 0xb4bb, 0xb4c9,
0xb4d8, 0xb4e7, 0xb4f6, 0xb504, 0xb513, 0xb522,
0xb530, 0xb53f, 0xb54e, 0xb55c, 0xb56b, 0xb57a,
0xb588, 0xb597, 0xb5a6, 0xb5b5, 0xb5c3, 0xb5d2,
0xb5e1, 0xb5ef, 0xb5fe, 0xb60d, 0xb61b, 0xb62a,
0xb638, 0xb647, 0xb656, 0xb664, 0xb673, 0xb682,
0xb690, 0xb69f, 0xb6ae, 0xb6bc, 0xb6cb, 0xb6d9,
0xb6e8, 0xb6f7, 0xb705, 0xb714, 0xb722, 0xb731,
0xb740, 0xb74e, 0xb75d, 0xb76b, 0xb77a, 0xb788,
0xb797, 0xb7a6, 0xb7b4, 0xb7c3, 0xb7d1, 0xb7e0,
0xb7ee, 0xb7fd, 0xb80b, 0xb81a, 0xb829, 0xb837,
0xb846, 0xb854, 0xb863, 0xb871, 0xb880, 0xb88e,
0xb89d, 0xb8ab, 0xb8ba, 0xb8c8, 0xb8d7, 0xb8e5,
0xb8f4, 0xb902, 0xb911, 0xb91f, 0xb92e, 0xb93c,
0xb94b, 0xb959, 0xb968, 0xb976, 0xb984, 0xb993,
0xb9a1, 0xb9b0, 0xb9be, 0xb9cd, 0xb9db, 0xb9ea,
0xb9f8, 0xba06, 0xba15, 0xba23, 0xba32, 0xba40,
0xba4f, 0xba5d, 0xba6b, 0xba7a, 0xba88, 0xba97,
0xbaa5, 0xbab3, 0xbac2, 0xbad0, 0xbade, 0xbaed,
0xbafb, 0xbb0a, 0xbb18, 0xbb26, 0xbb35, 0xbb43,
0xbb51, 0xbb60, 0xbb6e, 0xbb7c, 0xbb8b, 0xbb99,
0xbba8, 0xbbb6, 0xbbc4, 0xbbd3, 0xbbe1, 0xbbef,
0xbbfd, 0xbc0c, 0xbc1a, 0xbc28, 0xbc37, 0xbc45,
0xbc53, 0xbc62, 0xbc70, 0xbc7e, 0xbc8c, 0xbc9b,
0xbca9, 0xbcb7, 0xbcc6, 0xbcd4, 0xbce2, 0xbcf0,
0xbcff, 0xbd0d, 0xbd1b, 0xbd29, 0xbd38, 0xbd46,
0xbd54, 0xbd62, 0xbd71, 0xbd7f, 0xbd8d, 0xbd9b,
0xbdaa, 0xbdb8, 0xbdc6, 0xbdd4, 0xbde2, 0xbdf1,
0xbdff, 0xbe0d, 0xbe1b, 0xbe29, 0xbe38, 0xbe46,
0xbe54, 0xbe62, 0xbe70, 0xbe7f, 0xbe8d, 0xbe9b,
0xbea9, 0xbeb7, 0xbec5, 0xbed4, 0xbee2, 0xbef0,
0xbefe, 0xbf0c, 0xbf1a, 0xbf28, 0xbf37, 0xbf45,
0xbf53, 0xbf61, 0xbf6f, 0xbf7d, 0xbf8b, 0xbf99,
0xbfa7, 0xbfb6, 0xbfc4, 0xbfd2, 0xbfe0, 0xbfee,
0xbffc, 0xc00a, 0xc018, 0xc026, 0xc034, 0xc042,
0xc051, 0xc05f, 0xc06d, 0xc07b, 0xc089, 0xc097,
0xc0a5, 0xc0b3, 0xc0c1, 0xc0cf, 0xc0dd, 0xc0eb,
0xc0f9, 0xc107, 0xc115, 0xc123, 0xc131, 0xc13f,
0xc14d, 0xc15b, 0xc169, 0xc177, 0xc185, 0xc193,
0xc1a1, 0xc1af, 0xc1bd, 0xc1cb, 0xc1d9, 0xc1e7,
0xc1f5, 0xc203, 0xc211, 0xc21f, 0xc22d, 0xc23b,
0xc249, 0xc257, 0xc265, 0xc273, 0xc281, 0xc28f,
0xc29d, 0xc2ab, 0xc2b8, 0xc2c6, 0xc2d4, 0xc2e2,
0xc2f0, 0xc2fe, 0xc30c, 0xc31a, 0xc328, 0xc336,
0xc344, 0xc352, 0xc35f, 0xc36d, 0xc37b, 0xc389,
0xc397, 0xc3a5, 0xc3b3, 0xc3c1, 0xc3ce, 0xc3dc,
0xc3ea, 0xc3f8, 0xc406, 0xc414, 0xc422, 0xc42f,
0xc43d, 0xc44b, 0xc459, 0xc467, 0xc475, 0xc482,
0xc490, 0xc49e, 0xc4ac, 0xc4ba, 0xc4c7, 0xc4d5,
0xc4e3, 0xc4f1, 0xc4ff, 0xc50d, 0xc51a, 0xc528,
0xc536, 0xc544, 0xc551, 0xc55f, 0xc56d, 0xc57b,
0xc589, 0xc596, 0xc5a4, 0xc5b2, 0xc5c0, 0xc5cd,
0xc5db, 0xc5e9, 0xc5f7, 0xc604, 0xc612, 0xc620,
0xc62d, 0xc63b, 0xc649, 0xc657, 0xc664, 0xc672,
0xc680, 0xc68d, 0xc69b, 0xc6a9, 0xc6b7, 0xc6c4,
0xc6d2, 0xc6e0, 0xc6ed, 0xc6fb, 0xc709, 0xc716,
0xc724, 0xc732, 0xc73f, 0xc74d, 0xc75b, 0xc768,
0xc776, 0xc784, 0xc791, 0xc79f, 0xc7ad, 0xc7ba,
0xc7c8, 0xc7d6, 0xc7e3, 0xc7f1, 0xc7fe, 0xc80c,
0xc81a, 0xc827, 0xc835, 0xc842, 0xc850, 0xc85e,
0xc86b, 0xc879, 0xc886, 0xc894, 0xc8a2, 0xc8af,
0xc8bd, 0xc8ca, 0xc8d8, 0xc8e5, 0xc8f3, 0xc901,
0xc90e, 0xc91c, 0xc929, 0xc937, 0xc944, 0xc952,
0xc95f, 0xc96d, 0xc97b, 0xc988, 0xc996, 0xc9a3,
0xc9b1, 0xc9be, 0xc9cc, 0xc9d9, 0xc9e7, 0xc9f4,
0xca02, 0xca0f, 0xca1d, 0xca2a, 0xca38, 0xca45,
0xca53, 0xca60, 0xca6e, 0xca7b, 0xca89, 0xca96,
0xcaa4, 0xcab1, 0xcabe, 0xcacc, 0xcad9, 0xcae7,
0xcaf4, 0xcb02, 0xcb0f, 0xcb1d, 0xcb2a, 0xcb37,
0xcb45, 0xcb52, 0xcb60, 0xcb6d, 0xcb7b, 0xcb88,
0xcb95, 0xcba3, 0xcbb0, 0xcbbe, 0xcbcb, 0xcbd8,
0xcbe6, 0xcbf3, 0xcc01, 0xcc0e, 0xcc1b, 0xcc29,
0xcc36, 0xcc43, 0xcc51, 0xcc5e, 0xcc6c, 0xcc79,
0xcc86, 0xcc94, 0xcca1, 0xccae, 0xccbc, 0xccc9,
0xccd6, 0xcce4, 0xccf1, 0xccfe, 0xcd0c, 0xcd19,
0xcd26, 0xcd34, 0xcd41, 0xcd4e, 0xcd5b, 0xcd69,
0xcd76, 0xcd83, 0xcd91, 0xcd9e, 0xcdab, 0xcdb9,
0xcdc6, 0xcdd3, 0xcde0, 0xcdee, 0xcdfb, 0xce08,
0xce15, 0xce23, 0xce30, 0xce3d, 0xce4a, 0xce58,
0xce65, 0xce72, 0xce7f, 0xce8d, 0xce9a, 0xcea7,
0xceb4, 0xcec2, 0xcecf, 0xcedc, 0xcee9, 0xcef6,
0xcf04, 0xcf11, 0xcf1e, 0xcf2b, 0xcf38, 0xcf46,
0xcf53, 0xcf60, 0xcf6d, 0xcf7a, 0xcf87, 0xcf95,
0xcfa2, 0xcfaf, 0xcfbc, 0xcfc9, 0xcfd6, 0xcfe4,
0xcff1, 0xcffe, 0xd00b, 0xd018, 0xd025, 0xd032,
0xd040, 0xd04d, 0xd05a, 0xd067, 0xd074, 0xd081,
0xd08e, 0xd09b, 0xd0a9, 0xd0b6, 0xd0c3, 0xd0d0,
0xd0dd, 0xd0ea, 0xd0f7, 0xd104, 0xd111, 0xd11e,
0xd12b, 0xd139, 0xd146, 0xd153, 0xd160, 0xd16d,
0xd17a, 0xd187, 0xd194, 0xd1a1, 0xd1ae, 0xd1bb,
0xd1c8, 0xd1d5, 0xd1e2, 0xd1ef, 0xd1fc, 0xd209,
0xd216, 0xd223, 0xd230, 0xd23d, 0xd24a, 0xd257,
0xd264, 0xd271, 0xd27e, 0xd28b, 0xd298, 0xd2a5,
0xd2b2, 0xd2bf, 0xd2cc, 0xd2d9, 0xd2e6, 0xd2f3,
0xd300, 0xd30d, 0xd31a, 0xd327, 0xd334, 0xd341,
0xd34e, 0xd35b, 0xd368, 0xd375, 0xd382, 0xd38f,
0xd39c, 0xd3a8, 0xd3b5, 0xd3c2, 0xd3cf, 0xd3dc,
0xd3e9, 0xd3f6, 0xd403, 0xd410, 0xd41d, 0xd42a,
0xd436, 0xd443, 0xd450, 0xd45d, 0xd46a, 0xd477,
0xd484, 0xd491, 0xd49e, 0xd4aa, 0xd4b7, 0xd4c4,
0xd4d1, 0xd4de, 0xd4eb, 0xd4f8, 0xd504, 0xd511,
0xd51e, 0xd52b, 0xd538, 0xd545, 0xd551, 0xd55e,
0xd56b, 0xd578, 0xd585, 0xd591, 0xd59e, 0xd5ab,
0xd5b8, 0xd5c5, 0xd5d1, 0xd5de, 0xd5eb, 0xd5f8,
0xd605, 0xd611, 0xd61e, 0xd62b, 0xd638, 0xd645,
0xd651, 0xd65e, 0xd66b, 0xd678, 0xd684, 0xd691,
0xd69e, 0xd6ab, 0xd6b7, 0xd6c4, 0xd6d1, 0xd6de,
0xd6ea, 0xd6f7, 0xd704, 0xd710, 0xd71d, 0xd72a,
0xd737, 0xd743, 0xd750, 0xd75d, 0xd769, 0xd776,
0xd783, 0xd78f, 0xd79c, 0xd7a9, 0xd7b6, 0xd7c2,
0xd7cf, 0xd7dc, 0xd7e8, 0xd7f5, 0xd802, 0xd80e,
0xd81b, 0xd828, 0xd834, 0xd841, 0xd84e, 0xd85a,
0xd867, 0xd873, 0xd880, 0xd88d, 0xd899, 0xd8a6,
0xd8b3, 0xd8bf, 0xd8cc, 0xd8d8, 0xd8e5, 0xd8f2,
0xd8fe, 0xd90b, 0xd917, 0xd924, 0xd931, 0xd93d,
0xd94a, 0xd956, 0xd963, 0xd970, 0xd97c, 0xd989,
0xd995, 0xd9a2, 0xd9ae, 0xd9bb, 0xd9c8, 0xd9d4,
0xd9e1, 0xd9ed, 0xd9fa, 0xda06, 0xda13, 0xda1f,
0xda2c, 0xda38, 0xda45, 0xda51, 0xda5e, 0xda6a,
0xda77, 0xda84, 0xda90, 0xda9d, 0xdaa9, 0xdab6,
0xdac2, 0xdacf, 0xdadb, 0xdae7, 0xdaf4, 0xdb00,
0xdb0d, 0xdb19, 0xdb26, 0xdb32, 0xdb3f, 0xdb4b,
0xdb58, 0xdb64, 0xdb71, 0xdb7d, 0xdb8a, 0xdb96,
0xdba2, 0xdbaf, 0xdbbb, 0xdbc8, 0xdbd4, 0xdbe1,
0xdbed, 0xdbf9, 0xdc06, 0xdc12, 0xdc1f, 0xdc2b,
0xdc38, 0xdc44, 0xdc50, 0xdc5d, 0xdc69, 0xdc76,
0xdc82, 0xdc8e, 0xdc9b, 0xdca7, 0xdcb3, 0xdcc0,
0xdccc, 0xdcd9, 0xdce5, 0xdcf1, 0xdcfe, 0xdd0a,
0xdd16, 0xdd23, 0xdd2f, 0xdd3b, 0xdd48, 0xdd54,
0xdd60, 0xdd6d, 0xdd79, 0xdd85, 0xdd92, 0xdd9e,
0xddaa, 0xddb7, 0xddc3, 0xddcf, 0xdddc, 0xdde8,
0xddf4, 0xde01, 0xde0d, 0xde19, 0xde25, 0xde32,
0xde3e, 0xde4a, 0xde57, 0xde63, 0xde6f, 0xde7b,
0xde88, 0xde94, 0xdea0, 0xdeac, 0xdeb9, 0xdec5,
0xded1, 0xdedd, 0xdeea, 0xdef6, 0xdf02, 0xdf0e,
0xdf1b, 0xdf27, 0xdf33, 0xdf3f, 0xdf4c, 0xdf58,
0xdf64, 0xdf70, 0xdf7c, 0xdf89, 0xdf95, 0xdfa1,
0xdfad, 0xdfb9, 0xdfc6, 0xdfd2, 0xdfde, 0xdfea,
0xdff6, 0xe003, 0xe00f, 0xe01b, 0xe027, 0xe033,
0xe03f, 0xe04c, 0xe058, 0xe064, 0xe070, 0xe07c,
0xe088, 0xe094, 0xe0a1, 0xe0ad, 0xe0b9, 0xe0c5,
0xe0d1, 0xe0dd, 0xe0e9, 0xe0f5, 0xe102, 0xe10e,
0xe11a, 0xe126, 0xe132, 0xe13e, 0xe14a, 0xe156,
0xe162, 0xe16e, 0xe17b, 0xe187, 0xe193, 0xe19f,
0xe1ab, 0xe1b7, 0xe1c3, 0xe1cf, 0xe1db, 0xe1e7,
0xe1f3, 0xe1ff, 0xe20b, 0xe217, 0xe223, 0xe22f,
0xe23c, 0xe248, 0xe254, 0xe260, 0xe26c, 0xe278,
0xe284, 0xe290, 0xe29c, 0xe2a8, 0xe2b4, 0xe2c0,
0xe2cc, 0xe2d8, 0xe2e4, 0xe2f0, 0xe2fc, 0xe308,
0xe314, 0xe320, 0xe32c, 0xe338, 0xe344, 0xe350,
0xe35c, 0xe368, 0xe374, 0xe380, 0xe38b, 0xe397,
0xe3a3, 0xe3af, 0xe3bb, 0xe3c7, 0xe3d3, 0xe3df,
0xe3eb, 0xe3f7, 0xe403, 0xe40f, 0xe41b, 0xe427,
0xe433, 0xe43f, 0xe44a, 0xe456, 0xe462, 0xe46e,
0xe47a, 0xe486, 0xe492, 0xe49e, 0xe4aa, 0xe4b6,
0xe4c1, 0xe4cd, 0xe4d9, 0xe4e5, 0xe4f1, 0xe4fd,
0xe509, 0xe515, 0xe520, 0xe52c, 0xe538, 0xe544,
0xe550, 0xe55c, 0xe567, 0xe573, 0xe57f, 0xe58b,
0xe597, 0xe5a3, 0xe5af, 0xe5ba, 0xe5c6, 0xe5d2,
0xe5de, 0xe5ea, 0xe5f5, 0xe601, 0xe60d, 0xe619,
0xe625, 0xe630, 0xe63c, 0xe648, 0xe654, 0xe660,
0xe66b, 0xe677, 0xe683, 0xe68f, 0xe69a, 0xe6a6,
0xe6b2, 0xe6be, 0xe6ca, 0xe6d5, 0xe6e1, 0xe6ed,
0xe6f9, 0xe704, 0xe710, 0xe71c, 0xe727, 0xe733,
0xe73f, 0xe74b, 0xe756, 0xe762, 0xe76e, 0xe77a,
0xe785, 0xe791, 0xe79d, 0xe7a8, 0xe7b4, 0xe7c0,
0xe7cb, 0xe7d7, 0xe7e3, 0xe7ef, 0xe7fa, 0xe806,
0xe812, 0xe81d, 0xe829, 0xe835, 0xe840, 0xe84c,
0xe858, 0xe863, 0xe86f, 0xe87b, 0xe886, 0xe892,
0xe89e, 0xe8a9, 0xe8b5, 0xe8c0, 0xe8cc, 0xe8d8,
0xe8e3, 0xe8ef, 0xe8fb, 0xe906, 0xe912, 0xe91d,
0xe929, 0xe935, 0xe940, 0xe94c, 0xe958, 0xe963,
0xe96f, 0xe97a, 0xe986, 0xe991, 0xe99d, 0xe9a9,
0xe9b4, 0xe9c0, 0xe9cb, 0xe9d7, 0xe9e3, 0xe9ee,
0xe9fa, 0xea05, 0xea11, 0xea1c, 0xea28, 0xea33,
0xea3f, 0xea4a, 0xea56, 0xea62, 0xea6d, 0xea79,
0xea84, 0xea90, 0xea9b, 0xeaa7, 0xeab2, 0xeabe,
0xeac9, 0xead5, 0xeae0, 0xeaec, 0xeaf7, 0xeb03,
0xeb0e, 0xeb1a, 0xeb25, 0xeb31, 0xeb3c, 0xeb48,
0xeb53, 0xeb5f, 0xeb6a, 0xeb76, 0xeb81, 0xeb8d,
0xeb98, 0xeba3, 0xebaf, 0xebba, 0xebc6, 0xebd1,
0xebdd, 0xebe8, 0xebf4, 0xebff, 0xec0a, 0xec16,
0xec21, 0xec2d, 0xec38, 0xec44, 0xec4f, 0xec5a,
0xec66, 0xec71, 0xec7d, 0xec88, 0xec93, 0xec9f,
0xecaa, 0xecb6, 0xecc1, 0xeccc, 0xecd8, 0xece3,
0xecef, 0xecfa, 0xed05, 0xed11, 0xed1c, 0xed27,
0xed33, 0xed3e, 0xed4a, 0xed55, 0xed60, 0xed6c,
0xed77, 0xed82, 0xed8e, 0xed99, 0xeda4, 0xedb0,
0xedbb, 0xedc6, 0xedd2, 0xeddd, 0xede8, 0xedf4,
0xedff, 0xee0a, 0xee15, 0xee21, 0xee2c, 0xee37,
0xee43, 0xee4e, 0xee59, 0xee65, 0xee70, 0xee7b,
0xee86, 0xee92, 0xee9d, 0xeea8, 0xeeb3, 0xeebf,
0xeeca, 0xeed5, 0xeee1, 0xeeec, 0xeef7, 0xef02,
0xef0e, 0xef19, 0xef24, 0xef2f, 0xef3a, 0xef46,
0xef51, 0xef5c, 0xef67, 0xef73, 0xef7e, 0xef89,
0xef94, 0xef9f, 0xefab, 0xefb6, 0xefc1, 0xefcc,
0xefd7, 0xefe3, 0xefee, 0xeff9, 0xf004, 0xf00f,
0xf01b, 0xf026, 0xf031, 0xf03c, 0xf047, 0xf052,
0xf05e, 0xf069, 0xf074, 0xf07f, 0xf08a, 0xf095,
0xf0a1, 0xf0ac, 0xf0b7, 0xf0c2, 0xf0cd, 0xf0d8,
0xf0e3, 0xf0ef, 0xf0fa, 0xf105, 0xf110, 0xf11b,
0xf126, 0xf131, 0xf13c, 0xf147, 0xf153, 0xf15e,
0xf169, 0xf174, 0xf17f, 0xf18a, 0xf195, 0xf1a0,
0xf1ab, 0xf1b6, 0xf1c2, 0xf1cd, 0xf1d8, 0xf1e3,
0xf1ee, 0xf1f9, 0xf204, 0xf20f, 0xf21a, 0xf225,
0xf230, 0xf23b, 0xf246, 0xf251, 0xf25c, 0xf267,
0xf272, 0xf27d, 0xf288, 0xf293, 0xf29f, 0xf2aa,
0xf2b5, 0xf2c0, 0xf2cb, 0xf2d6, 0xf2e1, 0xf2ec,
0xf2f7, 0xf302, 0xf30d, 0xf318, 0xf323, 0xf32e,
0xf339, 0xf344, 0xf34f, 0xf35a, 0xf364, 0xf36f,
0xf37a, 0xf385, 0xf390, 0xf39b, 0xf3a6, 0xf3b1,
0xf3bc, 0xf3c7, 0xf3d2, 0xf3dd, 0xf3e8, 0xf3f3,
0xf3fe, 0xf409, 0xf414, 0xf41f, 0xf42a, 0xf435,
0xf43f, 0xf44a, 0xf455, 0xf460, 0xf46b, 0xf476,
0xf481, 0xf48c, 0xf497, 0xf4a2, 0xf4ad, 0xf4b7,
0xf4c2, 0xf4cd, 0xf4d8, 0xf4e3, 0xf4ee, 0xf4f9,
0xf504, 0xf50f, 0xf519, 0xf524, 0xf52f, 0xf53a,
0xf545, 0xf550, 0xf55b, 0xf565, 0xf570, 0xf57b,
0xf586, 0xf591, 0xf59c, 0xf5a6, 0xf5b1, 0xf5bc,
0xf5c7, 0xf5d2, 0xf5dd, 0xf5e7, 0xf5f2, 0xf5fd,
0xf608, 0xf613, 0xf61d, 0xf628, 0xf633, 0xf63e,
0xf649, 0xf653, 0xf65e, 0xf669, 0xf674, 0xf67f,
0xf689, 0xf694, 0xf69f, 0xf6aa, 0xf6b4, 0xf6bf,
0xf6ca, 0xf6d5, 0xf6e0, 0xf6ea, 0xf6f5, 0xf700,
0xf70b, 0xf715, 0xf720, 0xf72b, 0xf736, 0xf740,
0xf74b, 0xf756, 0xf760, 0xf76b, 0xf776, 0xf781,
0xf78b, 0xf796, 0xf7a1, 0xf7ab, 0xf7b6, 0xf7c1,
0xf7cc, 0xf7d6, 0xf7e1, 0xf7ec, 0xf7f6, 0xf801,
0xf80c, 0xf816, 0xf821, 0xf82c, 0xf836, 0xf841,
0xf84c, 0xf856, 0xf861, 0xf86c, 0xf876, 0xf881,
0xf88c, 0xf896, 0xf8a1, 0xf8ac, 0xf8b6, 0xf8c1,
0xf8cc, 0xf8d6, 0xf8e1, 0xf8ec, 0xf8f6, 0xf901,
0xf90b, 0xf916, 0xf921, 0xf92b, 0xf936, 0xf941,
0xf94b, 0xf956, 0xf960, 0xf96b, 0xf976, 0xf980,
0xf98b, 0xf995, 0xf9a0, 0xf9aa, 0xf9b5, 0xf9c0,
0xf9ca, 0xf9d5, 0xf9df, 0xf9ea, 0xf9f4, 0xf9ff,
0xfa0a, 0xfa14, 0xfa1f, 0xfa29, 0xfa34, 0xfa3e,
0xfa49, 0xfa53, 0xfa5e, 0xfa69, 0xfa73, 0xfa7e,
0xfa88, 0xfa93, 0xfa9d, 0xfaa8, 0xfab2, 0xfabd,
0xfac7, 0xfad2, 0xfadc, 0xfae7, 0xfaf1, 0xfafc,
0xfb06, 0xfb11, 0xfb1b, 0xfb26, 0xfb30, 0xfb3b,
0xfb45, 0xfb50, 0xfb5a, 0xfb65, 0xfb6f, 0xfb7a,
0xfb84, 0xfb8f, 0xfb99, 0xfba4, 0xfbae, 0xfbb8,
0xfbc3, 0xfbcd, 0xfbd8, 0xfbe2, 0xfbed, 0xfbf7,
0xfc02, 0xfc0c, 0xfc16, 0xfc21, 0xfc2b, 0xfc36,
0xfc40, 0xfc4b, 0xfc55, 0xfc5f, 0xfc6a, 0xfc74,
0xfc7f, 0xfc89, 0xfc93, 0xfc9e, 0xfca8, 0xfcb3,
0xfcbd, 0xfcc7, 0xfcd2, 0xfcdc, 0xfce7, 0xfcf1,
0xfcfb, 0xfd06, 0xfd10, 0xfd1a, 0xfd25, 0xfd2f,
0xfd3a, 0xfd44, 0xfd4e, 0xfd59, 0xfd63, 0xfd6d,
0xfd78, 0xfd82, 0xfd8c, 0xfd97, 0xfda1, 0xfdab,
0xfdb6, 0xfdc0, 0xfdca, 0xfdd5, 0xfddf, 0xfde9,
0xfdf4, 0xfdfe, 0xfe08, 0xfe13, 0xfe1d, 0xfe27,
0xfe32, 0xfe3c, 0xfe46, 0xfe50, 0xfe5b, 0xfe65,
0xfe6f, 0xfe7a, 0xfe84, 0xfe8e, 0xfe98, 0xfea3,
0xfead, 0xfeb7, 0xfec1, 0xfecc, 0xfed6, 0xfee0,
0xfeeb, 0xfef5, 0xfeff, 0xff09, 0xff14, 0xff1e,
0xff28, 0xff32, 0xff3c, 0xff47, 0xff51, 0xff5b,
0xff65, 0xff70, 0xff7a, 0xff84, 0xff8e, 0xff98,
0xffa3, 0xffad, 0xffb7, 0xffc1, 0xffcc, 0xffd6,
0xffe0, 0xffea, 0xfff4, 0xffff
};
// max value is pi/4
constexpr double SCALING_FACTOR = 4. / M_PI * 0xFFFF;
inline double atan2_lookup(double y, double x)
{
if (std::abs(x) < std::numeric_limits<double>::epsilon())
{
if (y >= 0.)
{
return M_PI / 2.;
}
else
{
return -M_PI / 2.;
}
}
unsigned octant = 0;
if (x < 0.)
{
octant = 1;
x = -x;
}
if (y < 0.)
{
octant |= 2;
y = -y;
}
double t = y / x;
if (t > 1.0)
{
octant |= 4;
t = 1.0 / t;
}
double angle = atan_table[(unsigned)(t * 4095)] / SCALING_FACTOR;
switch (octant)
{
case 0:
break;
case 1:
angle = M_PI - angle;
break;
case 2:
angle = -angle;
break;
case 3:
angle = -M_PI + angle;
break;
case 4:
angle = M_PI / 2.0 - angle;
break;
case 5:
angle = M_PI / 2.0 + angle;
break;
case 6:
angle = -M_PI / 2.0 + angle;
break;
case 7:
angle = -M_PI / 2.0 - angle;
break;
}
return angle;
}
#endif // TRIGONOMETRY_TABLES_H
-188
View File
@@ -1,188 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CAST_HPP
#define CAST_HPP
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/qi.hpp>
#include <string>
#include <type_traits>
struct cast
{
// convert scoped enums to integers
template <typename Enumeration>
static auto enum_to_underlying(Enumeration const value) -> typename std::underlying_type<Enumeration>::type
{
return static_cast<typename std::underlying_type<Enumeration>::type>(value);
}
template <typename Number>
static typename std::enable_if<std::is_integral<Number>::value, std::string>::type
integral_to_string(const Number value)
{
std::string output;
std::back_insert_iterator<std::string> sink(output);
if (8 == sizeof(Number))
{
boost::spirit::karma::generate(sink, boost::spirit::karma::long_long, value);
}
else
{
if (std::is_signed<Number>::value)
{
boost::spirit::karma::generate(sink, boost::spirit::karma::int_, value);
}
else
{
boost::spirit::karma::generate(sink, boost::spirit::karma::uint_, value);
}
}
return output;
}
static int string_to_int(const std::string &input)
{
auto 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::int_, value);
return value;
}
static unsigned string_to_uint(const std::string &input)
{
auto first_digit = input.begin();
// Delete any trailing white-spaces
while (first_digit != input.end() && (std::isspace(*first_digit) || '-' == *first_digit))
{
++first_digit;
}
unsigned value = 0;
boost::spirit::qi::parse(first_digit, input.end(), boost::spirit::uint_, value);
return value;
}
static uint64_t string_to_uint64(const std::string &input)
{
auto 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;
}
// source: http://tinodidriksen.com/2011/05/28/cpp-convert-string-to-double-speed/
static double string_to_double(const char *p)
{
double r = 0.0;
bool neg = false;
if (*p == '-')
{
neg = true;
++p;
}
while (*p >= '0' && *p <= '9')
{
r = (r * 10.0) + (*p - '0');
++p;
}
if (*p == '.')
{
double f = 0.0;
int n = 0;
++p;
while (*p >= '0' && *p <= '9')
{
f = (f * 10.0) + (*p - '0');
++p;
++n;
}
r += f / std::pow(10.0, n);
}
if (neg)
{
r = -r;
}
return r;
}
template <typename T> struct scientific_policy : boost::spirit::karma::real_policies<T>
{
// we want the numbers always to be in fixed format
static int floatfield(T)
{
return boost::spirit::karma::real_policies<T>::fmtflags::fixed;
}
static unsigned int precision(T) { return 6; }
};
typedef boost::spirit::karma::real_generator<double, scientific_policy<double>> science_type;
static std::string double_fixed_to_string(const double value)
{
std::string output;
std::back_insert_iterator<std::string> sink(output);
boost::spirit::karma::generate(sink, science_type(), value);
if (output.size() >= 2 && output[output.size() - 2] == '.' &&
output[output.size() - 1] == '0')
{
output.resize(output.size() - 2);
}
return output;
}
static std::string double_to_string(const double value)
{
std::string output;
std::back_insert_iterator<std::string> sink(output);
boost::spirit::karma::generate(sink, value);
return output;
}
static void double_with_two_digits_to_string(const double 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
char buffer[12];
sprintf(buffer, "%g", value);
output = buffer;
}
};
#endif // CAST_HPP
-325
View File
@@ -1,325 +0,0 @@
/*
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GRAPHLOADER_H
#define GRAPHLOADER_H
#include "osrm_exception.hpp"
#include "../data_structures/external_memory_node.hpp"
#include "../data_structures/import_edge.hpp"
#include "../data_structures/query_node.hpp"
#include "../data_structures/restriction.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/FingerPrint.h"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <tbb/parallel_sort.h>
#include <cmath>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <unordered_map>
#include <vector>
template <typename EdgeT>
NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
std::vector<EdgeT> &edge_list,
std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list,
std::vector<QueryNode> *int_to_ext_node_id_map,
std::vector<TurnRestriction> &restriction_list)
{
const FingerPrint fingerprint_orig;
FingerPrint fingerprint_loaded;
input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << ".osrm was prepared with different build.\n"
"Reprocess to get rid of this warning.";
}
std::unordered_map<NodeID, NodeID> ext_to_int_id_map;
NodeID n;
input_stream.read((char *)&n, sizeof(NodeID));
SimpleLogger().Write() << "Importing n = " << n << " nodes ";
ExternalMemoryNode current_node;
for (NodeID i = 0; i < n; ++i)
{
input_stream.read((char *)&current_node, sizeof(ExternalMemoryNode));
int_to_ext_node_id_map->emplace_back(current_node.lat, current_node.lon, current_node.node_id);
ext_to_int_id_map.emplace(current_node.node_id, i);
if (current_node.barrier)
{
barrier_node_list.emplace_back(i);
}
if (current_node.traffic_lights)
{
traffic_light_node_list.emplace_back(i);
}
}
// tighten vector sizes
barrier_node_list.shrink_to_fit();
traffic_light_node_list.shrink_to_fit();
// renumber nodes in turn restrictions
for (TurnRestriction &current_restriction : restriction_list)
{
auto internal_id_iter = ext_to_int_id_map.find(current_restriction.from.node);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction";
continue;
}
current_restriction.from.node = internal_id_iter->second;
internal_id_iter = ext_to_int_id_map.find(current_restriction.via.node);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction";
continue;
}
current_restriction.via.node = internal_id_iter->second;
internal_id_iter = ext_to_int_id_map.find(current_restriction.to.node);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction";
continue;
}
current_restriction.to.node = internal_id_iter->second;
}
EdgeWeight weight;
NodeID source, target;
unsigned nameID;
int length;
short dir; // direction (0 = open, 1 = forward, 2+ = open)
bool is_roundabout, ignore_in_grid, is_access_restricted, is_split;
TravelMode travel_mode;
EdgeID m;
input_stream.read((char *)&m, sizeof(unsigned));
edge_list.reserve(m);
SimpleLogger().Write() << " and " << m << " edges ";
for (EdgeID i = 0; i < m; ++i)
{
input_stream.read((char *)&source, sizeof(unsigned));
input_stream.read((char *)&target, sizeof(unsigned));
input_stream.read((char *)&length, sizeof(int));
input_stream.read((char *)&dir, sizeof(short));
input_stream.read((char *)&weight, sizeof(int));
input_stream.read((char *)&nameID, sizeof(unsigned));
input_stream.read((char *)&is_roundabout, sizeof(bool));
input_stream.read((char *)&ignore_in_grid, sizeof(bool));
input_stream.read((char *)&is_access_restricted, sizeof(bool));
input_stream.read((char *)&travel_mode, sizeof(TravelMode));
input_stream.read((char *)&is_split, sizeof(bool));
BOOST_ASSERT_MSG(length > 0, "loaded null length edge");
BOOST_ASSERT_MSG(weight > 0, "loaded null weight");
BOOST_ASSERT_MSG(0 <= dir && dir <= 2, "loaded bogus direction");
bool forward = true;
bool backward = true;
if (1 == dir)
{
backward = false;
}
if (2 == dir)
{
forward = false;
}
// translate the external NodeIDs to internal IDs
auto internal_id_iter = ext_to_int_id_map.find(source);
if (ext_to_int_id_map.find(source) == ext_to_int_id_map.end())
{
#ifndef NDEBUG
SimpleLogger().Write(logWARNING) << " unresolved source NodeID: " << source;
#endif
continue;
}
source = internal_id_iter->second;
internal_id_iter = ext_to_int_id_map.find(target);
if (ext_to_int_id_map.find(target) == ext_to_int_id_map.end())
{
#ifndef NDEBUG
SimpleLogger().Write(logWARNING) << "unresolved target NodeID : " << target;
#endif
continue;
}
target = internal_id_iter->second;
BOOST_ASSERT_MSG(source != SPECIAL_NODEID && target != SPECIAL_NODEID,
"nonexisting source or target");
if (source > target)
{
std::swap(source, target);
std::swap(forward, backward);
}
edge_list.emplace_back(source,
target,
nameID,
weight,
forward,
backward,
is_roundabout,
ignore_in_grid,
is_access_restricted,
travel_mode,
is_split);
}
ext_to_int_id_map.clear();
tbb::parallel_sort(edge_list.begin(), edge_list.end());
for (unsigned i = 1; i < edge_list.size(); ++i)
{
if ((edge_list[i - 1].target == edge_list[i].target) &&
(edge_list[i - 1].source == edge_list[i].source))
{
const bool edge_flags_equivalent =
(edge_list[i - 1].forward == edge_list[i].forward) &&
(edge_list[i - 1].backward == edge_list[i].backward);
const bool edge_flags_are_superset1 =
(edge_list[i - 1].forward && edge_list[i - 1].backward) &&
(edge_list[i].forward != edge_list[i].backward);
const bool edge_flags_are_superset_2 =
(edge_list[i].forward && edge_list[i].backward) &&
(edge_list[i - 1].forward != edge_list[i - 1].backward);
if (edge_flags_equivalent)
{
edge_list[i].weight = std::min(edge_list[i - 1].weight, edge_list[i].weight);
edge_list[i - 1].source = SPECIAL_NODEID;
}
else if (edge_flags_are_superset1)
{
if (edge_list[i - 1].weight <= edge_list[i].weight)
{
// edge i-1 is smaller and goes in both directions. Throw away the other edge
edge_list[i].source = SPECIAL_NODEID;
}
else
{
// edge i-1 is open in both directions, but edge i is smaller in one direction.
// Close edge i-1 in this direction
edge_list[i - 1].forward = !edge_list[i].forward;
edge_list[i - 1].backward = !edge_list[i].backward;
}
}
else if (edge_flags_are_superset_2)
{
if (edge_list[i - 1].weight <= edge_list[i].weight)
{
// edge i-1 is smaller for one direction. edge i is open in both. close edge i
// in the other direction
edge_list[i].forward = !edge_list[i - 1].forward;
edge_list[i].backward = !edge_list[i - 1].backward;
}
else
{
// edge i is smaller and goes in both direction. Throw away edge i-1
edge_list[i - 1].source = SPECIAL_NODEID;
}
}
}
}
const auto new_end_iter = std::remove_if(edge_list.begin(), edge_list.end(), [] (const EdgeT &edge)
{
return edge.source == SPECIAL_NODEID ||
edge.target == SPECIAL_NODEID;
});
edge_list.erase(new_end_iter, edge_list.end()); // remove excess candidates.
edge_list.shrink_to_fit();
SimpleLogger().Write() << "Graph loaded ok and has " << edge_list.size() << " edges";
return n;
}
template <typename NodeT, typename EdgeT>
unsigned readHSGRFromStream(const boost::filesystem::path &hsgr_file,
std::vector<NodeT> &node_list,
std::vector<EdgeT> &edge_list,
unsigned *check_sum)
{
if (!boost::filesystem::exists(hsgr_file))
{
throw osrm::exception("hsgr file does not exist");
}
if (0 == boost::filesystem::file_size(hsgr_file))
{
throw osrm::exception("hsgr file is empty");
}
boost::filesystem::ifstream hsgr_input_stream(hsgr_file, std::ios::binary);
FingerPrint fingerprint_loaded, fingerprint_orig;
hsgr_input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << ".hsgr was prepared with different build.\n"
"Reprocess to get rid of this warning.";
}
unsigned number_of_nodes = 0;
unsigned number_of_edges = 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");
hsgr_input_stream.read((char *)&number_of_edges, sizeof(unsigned));
SimpleLogger().Write() << "number_of_nodes: " << number_of_nodes
<< ", number_of_edges: " << number_of_edges;
// BOOST_ASSERT_MSG( 0 != number_of_edges, "number of edges is zero");
node_list.resize(number_of_nodes);
hsgr_input_stream.read((char *)&(node_list[0]), number_of_nodes * sizeof(NodeT));
edge_list.resize(number_of_edges);
if (number_of_edges > 0)
{
hsgr_input_stream.read((char *)&(edge_list[0]), number_of_edges * sizeof(EdgeT));
}
hsgr_input_stream.close();
return number_of_nodes;
}
#endif // GRAPHLOADER_H
-42
View File
@@ -1,42 +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 RANGE_ALGORITHMS_HPP
#define RANGE_ALGORITHMS_HPP
#include <algorithm>
namespace osrm {
template<class Container>
auto max_element(const Container & c) -> decltype(std::max_element(c.begin(), c.end()))
{
return std::max_element(c.begin(), c.end());
}
template<class Container>
auto max_element(const Container & c) -> decltype(std::max_element(c.cbegin(), c.cend()))
{
return std::max_element(c.cbegin(), c.cend());
}
}
#endif // RANGE_ALGORITHMS_HPP
+118
View File
@@ -0,0 +1,118 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BAYES_CLASSIFIER_HPP
#define BAYES_CLASSIFIER_HPP
#include <cmath>
#include <vector>
#include <utility>
struct NormalDistribution
{
NormalDistribution(const double mean, const double standard_deviation)
: mean(mean), standard_deviation(standard_deviation)
{
}
// FIXME implement log-probability version since its faster
double density_function(const double val) const
{
const double x = val - mean;
return 1.0 / (std::sqrt(2. * M_PI) * standard_deviation) *
std::exp(-x * x / (standard_deviation * standard_deviation));
}
double mean;
double standard_deviation;
};
struct LaplaceDistribution
{
LaplaceDistribution(const double location, const double scale)
: location(location), scale(scale)
{
}
// FIXME implement log-probability version since its faster
double density_function(const double val) const
{
const double x = std::abs(val - location);
return 1.0 / (2. * scale) * std::exp(-x / scale);
}
double location;
double scale;
};
template <typename PositiveDistributionT, typename NegativeDistributionT, typename ValueT>
class BayesClassifier
{
public:
enum class ClassLabel : unsigned
{
NEGATIVE,
POSITIVE
};
using ClassificationT = std::pair<ClassLabel, double>;
BayesClassifier(PositiveDistributionT positive_distribution,
NegativeDistributionT negative_distribution,
const double positive_apriori_probability)
: positive_distribution(std::move(positive_distribution)),
negative_distribution(std::move(negative_distribution)),
positive_apriori_probability(positive_apriori_probability),
negative_apriori_probability(1. - positive_apriori_probability)
{
}
// Returns label and the probability of the label.
ClassificationT classify(const ValueT &v) const
{
const double positive_postpriori =
positive_apriori_probability * positive_distribution.density_function(v);
const double negative_postpriori =
negative_apriori_probability * negative_distribution.density_function(v);
const double norm = positive_postpriori + negative_postpriori;
if (positive_postpriori > negative_postpriori)
{
return std::make_pair(ClassLabel::POSITIVE, positive_postpriori / norm);
}
return std::make_pair(ClassLabel::NEGATIVE, negative_postpriori / norm);
}
private:
PositiveDistributionT positive_distribution;
NegativeDistributionT negative_distribution;
double positive_apriori_probability;
double negative_apriori_probability;
};
#endif // BAYES_CLASSIFIER_HPP
+4 -4
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -95,8 +95,8 @@ template <typename GraphT> class BFSComponentExplorer
* Explores the current component that starts at node using BFS.
*/
unsigned ExploreComponent(std::queue<std::pair<NodeID, NodeID>> &bfs_queue,
NodeID node,
unsigned current_component)
NodeID node,
unsigned current_component)
{
/*
Graphical representation of variables:
@@ -118,7 +118,7 @@ template <typename GraphT> class BFSComponentExplorer
std::pair<NodeID, NodeID> current_queue_item = bfs_queue.front();
bfs_queue.pop();
const NodeID v = current_queue_item.first; // current node
const NodeID v = current_queue_item.first; // current node
const NodeID u = current_queue_item.second; // parent
// increment size counter of current component
++current_component_size;
+273
View File
@@ -0,0 +1,273 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "coordinate_calculation.hpp"
#include "../util/mercator.hpp"
#include "../util/string_util.hpp"
#include <boost/assert.hpp>
#include <osrm/coordinate.hpp>
#include <cmath>
#include <limits>
namespace
{
constexpr static const float RAD = 0.017453292519943295769236907684886f;
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
constexpr static const float earth_radius = 6372797.560856f;
}
namespace coordinate_calculation
{
double haversine_distance(const int lat1,
const int lon1,
const int lat2,
const int lon2)
{
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
const double lt1 = lat1 / COORDINATE_PRECISION;
const double ln1 = lon1 / COORDINATE_PRECISION;
const double lt2 = lat2 / COORDINATE_PRECISION;
const double ln2 = lon2 / COORDINATE_PRECISION;
const double dlat1 = lt1 * (RAD);
const double dlong1 = ln1 * (RAD);
const double dlat2 = lt2 * (RAD);
const double dlong2 = ln2 * (RAD);
const double dLong = dlong1 - dlong2;
const double dLat = dlat1 - dlat2;
const double aHarv = std::pow(std::sin(dLat / 2.0), 2.0) +
std::cos(dlat1) * std::cos(dlat2) * std::pow(std::sin(dLong / 2.), 2);
const double cHarv = 2. * std::atan2(std::sqrt(aHarv), std::sqrt(1.0 - aHarv));
return earth_radius * cHarv;
}
double haversine_distance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return haversine_distance(coordinate_1.lat, coordinate_1.lon, coordinate_2.lat,
coordinate_2.lon);
}
float great_circle_distance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return great_circle_distance(coordinate_1.lat, coordinate_1.lon, coordinate_2.lat,
coordinate_2.lon);
}
float great_circle_distance(const int lat1,
const int lon1,
const int lat2,
const int lon2)
{
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
const float float_lat1 = (lat1 / COORDINATE_PRECISION) * RAD;
const float float_lon1 = (lon1 / COORDINATE_PRECISION) * RAD;
const float float_lat2 = (lat2 / COORDINATE_PRECISION) * RAD;
const float float_lon2 = (lon2 / COORDINATE_PRECISION) * RAD;
const float x_value = (float_lon2 - float_lon1) * std::cos((float_lat1 + float_lat2) / 2.f);
const float y_value = float_lat2 - float_lat1;
return std::hypot(x_value, y_value) * earth_radius;
}
float perpendicular_distance(const FixedPointCoordinate &source_coordinate,
const FixedPointCoordinate &target_coordinate,
const FixedPointCoordinate &query_location)
{
float ratio;
FixedPointCoordinate nearest_location;
return perpendicular_distance(source_coordinate, target_coordinate, query_location,
nearest_location, ratio);
}
float perpendicular_distance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio)
{
return perpendicular_distance_from_projected_coordinate(
segment_source, segment_target, query_location,
{mercator::lat2y(query_location.lat / COORDINATE_PRECISION),
query_location.lon / COORDINATE_PRECISION},
nearest_location, ratio);
}
float perpendicular_distance_from_projected_coordinate(
const FixedPointCoordinate &source_coordinate,
const FixedPointCoordinate &target_coordinate,
const FixedPointCoordinate &query_location,
const std::pair<double, double> &projected_coordinate)
{
float ratio;
FixedPointCoordinate nearest_location;
return perpendicular_distance_from_projected_coordinate(source_coordinate, target_coordinate,
query_location, projected_coordinate,
nearest_location, ratio);
}
float perpendicular_distance_from_projected_coordinate(
const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
const std::pair<double, double> &projected_coordinate,
FixedPointCoordinate &nearest_location,
float &ratio)
{
BOOST_ASSERT(query_location.is_valid());
// initialize values
const double x = projected_coordinate.first;
const double y = projected_coordinate.second;
const double a = mercator::lat2y(segment_source.lat / COORDINATE_PRECISION);
const double b = segment_source.lon / COORDINATE_PRECISION;
const double c = mercator::lat2y(segment_target.lat / COORDINATE_PRECISION);
const double d = segment_target.lon / COORDINATE_PRECISION;
double p, q /*,mX*/, nY;
if (std::abs(a - c) > std::numeric_limits<double>::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.f + m * m);
q = b + m * (p - a);
}
else
{
p = c;
q = y;
}
nY = (d * p - c * q) / (a * d - b * c);
// discretize the result to coordinate precision. it's a hack!
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
{
nY = 0.f;
}
// compute ratio
ratio =
static_cast<float>((p - nY * a) / c); // These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if (std::isnan(ratio))
{
ratio = (segment_target == query_location ? 1.f : 0.f);
}
else if (std::abs(ratio) <= std::numeric_limits<float>::epsilon())
{
ratio = 0.f;
}
else if (std::abs(ratio - 1.f) <= std::numeric_limits<float>::epsilon())
{
ratio = 1.f;
}
// compute nearest location
BOOST_ASSERT(!std::isnan(ratio));
if (ratio <= 0.f)
{
nearest_location = segment_source;
}
else if (ratio >= 1.f)
{
nearest_location = segment_target;
}
else
{
// point lies in between
nearest_location.lat = static_cast<int>(mercator::y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.is_valid());
const float approximate_distance =
great_circle_distance(query_location, nearest_location);
BOOST_ASSERT(0.f <= approximate_distance);
return approximate_distance;
}
void lat_or_lon_to_string(const int value, std::string &output)
{
char buffer[12];
buffer[11] = 0; // zero termination
output = printInt<11, 6>(buffer, value);
}
float deg_to_rad(const float degree)
{
return degree * (static_cast<float>(M_PI) / 180.f);
}
float rad_to_deg(const float radian)
{
return radian * (180.f * static_cast<float>(M_1_PI));
}
float bearing(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate)
{
const float lon_diff =
second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION;
const float lon_delta = deg_to_rad(lon_diff);
const float lat1 = deg_to_rad(first_coordinate.lat / COORDINATE_PRECISION);
const float lat2 = deg_to_rad(second_coordinate.lat / COORDINATE_PRECISION);
const float y = std::sin(lon_delta) * std::cos(lat2);
const float x =
std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(lon_delta);
float result = rad_to_deg(std::atan2(y, x));
while (result < 0.f)
{
result += 360.f;
}
while (result >= 360.f)
{
result -= 360.f;
}
return result;
}
}
+82
View File
@@ -0,0 +1,82 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef COORDINATE_CALCULATION
#define COORDINATE_CALCULATION
struct FixedPointCoordinate;
#include <string>
#include <utility>
namespace coordinate_calculation
{
double
haversine_distance(const int lat1, const int lon1, const int lat2, const int lon2);
double haversine_distance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
float great_circle_distance(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
float great_circle_distance(const int lat1, const int lon1, const int lat2, const int lon2);
void lat_or_lon_to_string(const int value, std::string &output);
float perpendicular_distance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location);
float perpendicular_distance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio);
float perpendicular_distance_from_projected_coordinate(
const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
const std::pair<double, double> &projected_coordinate);
float perpendicular_distance_from_projected_coordinate(
const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
const std::pair<double, double> &projected_coordinate,
FixedPointCoordinate &nearest_location,
float &ratio);
float deg_to_rad(const float degree);
float rad_to_deg(const float radian);
float bearing(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate);
}
#endif // COORDINATE_CALCULATION
+7 -8
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -49,7 +49,7 @@ class IteratorbasedCRC32
while (iter != end)
{
using value_type = typename std::iterator_traits<Iterator>::value_type;
char *data = (char *)(&(*iter));
const char *data = reinterpret_cast<const char *>(&(*iter));
if (use_hardware_implementation)
{
@@ -73,14 +73,14 @@ class IteratorbasedCRC32
return sse42_found;
}
unsigned compute_in_software(char *str, unsigned len)
unsigned compute_in_software(const char *str, unsigned len)
{
crc_processor.process_bytes(str, len);
return crc_processor.checksum();
}
// adapted from http://byteworm.com/2010/10/13/crc32/
unsigned compute_in_hardware(char *str, unsigned len)
unsigned compute_in_hardware(const char *str, unsigned len)
{
#if defined(__x86_64__)
unsigned q = len / sizeof(unsigned);
@@ -96,7 +96,7 @@ class IteratorbasedCRC32
++p;
}
str = (char *)p;
str = reinterpret_cast<char *>(p);
while (r--)
{
__asm__ __volatile__(".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
@@ -116,7 +116,7 @@ class IteratorbasedCRC32
return ecx;
}
#if defined(__MINGW64__) || defined(_MSC_VER)
#if defined(__MINGW64__) || defined(_MSC_VER) || !defined(__x86_64__)
inline void
__get_cpuid(int param, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) const
{
@@ -131,8 +131,7 @@ class IteratorbasedCRC32
struct RangebasedCRC32
{
template<typename Iteratable>
unsigned operator()(const Iteratable &iterable)
template <typename Iteratable> unsigned operator()(const Iteratable &iterable)
{
return crc32(std::begin(iterable), std::end(iterable));
}
+8 -10
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,15 +28,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "douglas_peucker.hpp"
#include "../data_structures/segment_information.hpp"
#include "../Util/integer_range.hpp"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <osrm/coordinate.hpp>
#include <cmath>
#include <algorithm>
#include <iterator>
namespace
{
@@ -65,12 +63,12 @@ struct CoordinatePairCalculator
// compute distance (a,c)
const float x_value_1 = (first_lon - float_lon1) * cos((float_lat1 + first_lat) / 2.f);
const float y_value_1 = first_lat - float_lat1;
const float dist1 = sqrt(std::pow(x_value_1, 2) + std::pow(y_value_1, 2)) * earth_radius;
const float dist1 = std::hypot(x_value_1, y_value_1) * earth_radius;
// compute distance (b,c)
const float x_value_2 = (second_lon - float_lon1) * cos((float_lat1 + second_lat) / 2.f);
const float y_value_2 = second_lat - float_lat1;
const float dist2 = sqrt(std::pow(x_value_2, 2) + std::pow(y_value_2, 2)) * earth_radius;
const float dist2 = std::hypot(x_value_2, y_value_2) * earth_radius;
// return the minimum
return static_cast<int>(std::min(dist1, dist2));
@@ -90,7 +88,7 @@ void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const
void DouglasPeucker::Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level)
{
unsigned size = std::distance(begin, end);
const auto size = std::distance(begin, end);
if (size < 2)
{
return;
@@ -101,8 +99,8 @@ void DouglasPeucker::Run(RandomAccessIt begin, RandomAccessIt end, const unsigne
{
BOOST_ASSERT_MSG(zoom_level < DOUGLAS_PEUCKER_THRESHOLDS.size(), "unsupported zoom level");
RandomAccessIt left_border = begin;
RandomAccessIt right_border = std::next(begin);
auto left_border = begin;
auto right_border = std::next(begin);
// Sweep over array and identify those ranges that need to be checked
do
{
+7 -6
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,9 +28,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef DOUGLAS_PEUCKER_HPP_
#define DOUGLAS_PEUCKER_HPP_
#include <stack>
#include <vector>
#include "../data_structures/segment_information.hpp"
#include <array>
#include <stack>
#include <utility>
#include <vector>
/* This class object computes the bitvector of indicating generalized input
* points according to the (Ramer-)Douglas-Peucker algorithm.
@@ -39,9 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* bit indicating if the points is present in the generalization.
* Note: points may also be pre-selected*/
struct SegmentInformation;
static const std::array<int, 19> DOUGLAS_PEUCKER_THRESHOLDS {{
static const std::array<int, 19> DOUGLAS_PEUCKER_THRESHOLDS{{
512440, // z0
256720, // z1
122560, // z2
+180
View File
@@ -0,0 +1,180 @@
#ifndef GEOSPATIAL_QUERY_HPP
#define GEOSPATIAL_QUERY_HPP
#include "coordinate_calculation.hpp"
#include "../typedefs.h"
#include "../data_structures/phantom_node.hpp"
#include "../util/bearing.hpp"
#include <osrm/coordinate.hpp>
#include <vector>
#include <memory>
#include <algorithm>
// Implements complex queries on top of an RTree and builds PhantomNodes from it.
//
// Only holds a weak reference on the RTree!
template <typename RTreeT> class GeospatialQuery
{
using EdgeData = typename RTreeT::EdgeData;
using CoordinateList = typename RTreeT::CoordinateList;
public:
GeospatialQuery(RTreeT &rtree_, std::shared_ptr<CoordinateList> coordinates_)
: rtree(rtree_), coordinates(coordinates_)
{
}
// Returns nearest PhantomNodes in the given bearing range within max_distance.
// Does not filter by small/big component!
std::vector<PhantomNodeWithDistance>
NearestPhantomNodesInRange(const FixedPointCoordinate &input_coordinate,
const float max_distance,
const int bearing = 0,
const int bearing_range = 180)
{
auto results =
rtree.Nearest(input_coordinate,
[this, bearing, bearing_range, max_distance](const EdgeData &data)
{
return checkSegmentBearing(data, bearing, bearing_range);
},
[max_distance](const std::size_t, const float min_dist)
{
return min_dist > max_distance;
});
return MakePhantomNodes(input_coordinate, results);
}
// Returns max_results nearest PhantomNodes in the given bearing range.
// Does not filter by small/big component!
std::vector<PhantomNodeWithDistance>
NearestPhantomNodes(const FixedPointCoordinate &input_coordinate,
const unsigned max_results,
const int bearing = 0,
const int bearing_range = 180)
{
auto results = rtree.Nearest(input_coordinate,
[this, bearing, bearing_range](const EdgeData &data)
{
return checkSegmentBearing(data, bearing, bearing_range);
},
[max_results](const std::size_t num_results, const float)
{
return num_results >= max_results;
});
return MakePhantomNodes(input_coordinate, results);
}
// Returns the nearest phantom node. If this phantom node is not from a big component
// a second phantom node is return that is the nearest coordinate in a big component.
std::pair<PhantomNode, PhantomNode>
NearestPhantomNodeWithAlternativeFromBigComponent(const FixedPointCoordinate &input_coordinate,
const int bearing = 0,
const int bearing_range = 180)
{
bool has_small_component = false;
bool has_big_component = false;
auto results = rtree.Nearest(
input_coordinate,
[this, bearing, bearing_range, &has_big_component,
&has_small_component](const EdgeData &data)
{
auto use_segment =
(!has_small_component || (!has_big_component && !data.component.is_tiny));
auto use_directions = std::make_pair(use_segment, use_segment);
if (use_segment)
{
use_directions = checkSegmentBearing(data, bearing, bearing_range);
if (use_directions.first || use_directions.second)
{
has_big_component = has_big_component || !data.component.is_tiny;
has_small_component = has_small_component || data.component.is_tiny;
}
}
return use_directions;
},
[&has_big_component](const std::size_t num_results, const float)
{
return num_results > 0 && has_big_component;
});
if (results.size() == 0)
{
return std::make_pair(PhantomNode{}, PhantomNode{});
}
BOOST_ASSERT(results.size() > 0);
return std::make_pair(MakePhantomNode(input_coordinate, results.front()).phantom_node,
MakePhantomNode(input_coordinate, results.back()).phantom_node);
}
private:
std::vector<PhantomNodeWithDistance>
MakePhantomNodes(const FixedPointCoordinate &input_coordinate,
const std::vector<EdgeData> &results) const
{
std::vector<PhantomNodeWithDistance> distance_and_phantoms(results.size());
std::transform(results.begin(), results.end(), distance_and_phantoms.begin(),
[this, &input_coordinate](const EdgeData &data)
{
return MakePhantomNode(input_coordinate, data);
});
return distance_and_phantoms;
}
PhantomNodeWithDistance MakePhantomNode(const FixedPointCoordinate &input_coordinate,
const EdgeData &data) const
{
FixedPointCoordinate point_on_segment;
float ratio;
const auto current_perpendicular_distance = coordinate_calculation::perpendicular_distance(
coordinates->at(data.u), coordinates->at(data.v), input_coordinate, point_on_segment,
ratio);
auto transformed =
PhantomNodeWithDistance { PhantomNode{data, point_on_segment}, current_perpendicular_distance };
ratio = std::min(1.f, std::max(0.f, ratio));
if (SPECIAL_NODEID != transformed.phantom_node.forward_node_id)
{
transformed.phantom_node.forward_weight *= ratio;
}
if (SPECIAL_NODEID != transformed.phantom_node.reverse_node_id)
{
transformed.phantom_node.reverse_weight *= 1.f - ratio;
}
return transformed;
}
std::pair<bool, bool> checkSegmentBearing(const EdgeData &segment,
const float filter_bearing,
const float filter_bearing_range)
{
const float forward_edge_bearing =
coordinate_calculation::bearing(coordinates->at(segment.u), coordinates->at(segment.v));
const float backward_edge_bearing = (forward_edge_bearing + 180) > 360
? (forward_edge_bearing - 180)
: (forward_edge_bearing + 180);
const bool forward_bearing_valid =
bearing::CheckInBounds(forward_edge_bearing, filter_bearing, filter_bearing_range) &&
segment.forward_edge_based_node_id != SPECIAL_NODEID;
const bool backward_bearing_valid =
bearing::CheckInBounds(backward_edge_bearing, filter_bearing, filter_bearing_range) &&
segment.reverse_edge_based_node_id != SPECIAL_NODEID;
return std::make_pair(forward_bearing_valid, backward_bearing_valid);
}
RTreeT &rtree;
const std::shared_ptr<CoordinateList> coordinates;
};
#endif
+188
View File
@@ -0,0 +1,188 @@
#include "graph_compressor.hpp"
#include "../data_structures/compressed_edge_container.hpp"
#include "../data_structures/dynamic_graph.hpp"
#include "../data_structures/node_based_graph.hpp"
#include "../data_structures/restriction_map.hpp"
#include "../data_structures/percent.hpp"
#include "../util/simple_logger.hpp"
GraphCompressor::GraphCompressor(SpeedProfileProperties speed_profile)
: speed_profile(std::move(speed_profile))
{
}
void GraphCompressor::Compress(const std::unordered_set<NodeID>& barrier_nodes,
const std::unordered_set<NodeID>& traffic_lights,
RestrictionMap& restriction_map,
NodeBasedDynamicGraph& graph,
CompressedEdgeContainer& geometry_compressor)
{
const unsigned original_number_of_nodes = graph.GetNumberOfNodes();
const unsigned original_number_of_edges = graph.GetNumberOfEdges();
Percent progress(original_number_of_nodes);
for (const NodeID node_v : osrm::irange(0u, original_number_of_nodes))
{
progress.printStatus(node_v);
// only contract degree 2 vertices
if (2 != graph.GetOutDegree(node_v))
{
continue;
}
// don't contract barrier node
if (barrier_nodes.end() != barrier_nodes.find(node_v))
{
continue;
}
// check if v is a via node for a turn restriction, i.e. a 'directed' barrier node
if (restriction_map.IsViaNode(node_v))
{
continue;
}
// reverse_e2 forward_e2
// u <---------- v -----------> w
// ----------> <-----------
// forward_e1 reverse_e1
//
// Will be compressed to:
//
// reverse_e1
// u <---------- w
// ---------->
// forward_e1
//
// If the edges are compatible.
const bool reverse_edge_order = graph.GetEdgeData(graph.BeginEdges(node_v)).reversed;
const EdgeID forward_e2 = graph.BeginEdges(node_v) + reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != forward_e2);
BOOST_ASSERT(forward_e2 >= graph.BeginEdges(node_v) &&
forward_e2 < graph.EndEdges(node_v));
const EdgeID reverse_e2 = graph.BeginEdges(node_v) + 1 - reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e2);
BOOST_ASSERT(reverse_e2 >= graph.BeginEdges(node_v) &&
reverse_e2 < graph.EndEdges(node_v));
const EdgeData &fwd_edge_data2 = graph.GetEdgeData(forward_e2);
const EdgeData &rev_edge_data2 = graph.GetEdgeData(reverse_e2);
const NodeID node_w = graph.GetTarget(forward_e2);
BOOST_ASSERT(SPECIAL_NODEID != node_w);
BOOST_ASSERT(node_v != node_w);
const NodeID node_u = graph.GetTarget(reverse_e2);
BOOST_ASSERT(SPECIAL_NODEID != node_u);
BOOST_ASSERT(node_u != node_v);
const EdgeID forward_e1 = graph.FindEdge(node_u, node_v);
BOOST_ASSERT(SPECIAL_EDGEID != forward_e1);
BOOST_ASSERT(node_v == graph.GetTarget(forward_e1));
const EdgeID reverse_e1 = graph.FindEdge(node_w, node_v);
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e1);
BOOST_ASSERT(node_v == graph.GetTarget(reverse_e1));
const EdgeData &fwd_edge_data1 = graph.GetEdgeData(forward_e1);
const EdgeData &rev_edge_data1 = graph.GetEdgeData(reverse_e1);
if (graph.FindEdgeInEitherDirection(node_u, node_w) != SPECIAL_EDGEID)
{
continue;
}
// this case can happen if two ways with different names overlap
if (fwd_edge_data1.name_id != rev_edge_data1.name_id ||
fwd_edge_data2.name_id != rev_edge_data2.name_id)
{
continue;
}
if (fwd_edge_data1.IsCompatibleTo(fwd_edge_data2) && rev_edge_data1.IsCompatibleTo(rev_edge_data2))
{
BOOST_ASSERT(graph.GetEdgeData(forward_e1).name_id ==
graph.GetEdgeData(reverse_e1).name_id);
BOOST_ASSERT(graph.GetEdgeData(forward_e2).name_id ==
graph.GetEdgeData(reverse_e2).name_id);
// Get distances before graph is modified
const int forward_weight1 = graph.GetEdgeData(forward_e1).distance;
const int forward_weight2 = graph.GetEdgeData(forward_e2).distance;
BOOST_ASSERT(0 != forward_weight1);
BOOST_ASSERT(0 != forward_weight2);
const int reverse_weight1 = graph.GetEdgeData(reverse_e1).distance;
const int reverse_weight2 = graph.GetEdgeData(reverse_e2).distance;
BOOST_ASSERT(0 != reverse_weight1);
BOOST_ASSERT(0 != reverse_weight2);
const bool has_node_penalty = traffic_lights.find(node_v) != traffic_lights.end();
// add weight of e2's to e1
graph.GetEdgeData(forward_e1).distance += fwd_edge_data2.distance;
graph.GetEdgeData(reverse_e1).distance += rev_edge_data2.distance;
if (has_node_penalty)
{
graph.GetEdgeData(forward_e1).distance +=
speed_profile.traffic_signal_penalty;
graph.GetEdgeData(reverse_e1).distance +=
speed_profile.traffic_signal_penalty;
}
// extend e1's to targets of e2's
graph.SetTarget(forward_e1, node_w);
graph.SetTarget(reverse_e1, node_u);
// remove e2's (if bidir, otherwise only one)
graph.DeleteEdge(node_v, forward_e2);
graph.DeleteEdge(node_v, reverse_e2);
// update any involved turn restrictions
restriction_map.FixupStartingTurnRestriction(node_u, node_v, node_w);
restriction_map.FixupArrivingTurnRestriction(node_u, node_v, node_w, graph);
restriction_map.FixupStartingTurnRestriction(node_w, node_v, node_u);
restriction_map.FixupArrivingTurnRestriction(node_w, node_v, node_u, graph);
// store compressed geometry in container
geometry_compressor.CompressEdge(
forward_e1, forward_e2, node_v, node_w,
forward_weight1 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0),
forward_weight2);
geometry_compressor.CompressEdge(
reverse_e1, reverse_e2, node_v, node_u, reverse_weight1,
reverse_weight2 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0));
}
}
PrintStatistics(original_number_of_nodes, original_number_of_edges, graph);
}
void GraphCompressor::PrintStatistics(unsigned original_number_of_nodes,
unsigned original_number_of_edges,
const NodeBasedDynamicGraph& graph) const
{
unsigned new_node_count = 0;
unsigned new_edge_count = 0;
for (const auto i : osrm::irange(0u, graph.GetNumberOfNodes()))
{
if (graph.GetOutDegree(i) > 0)
{
++new_node_count;
new_edge_count += (graph.EndEdges(i) - graph.BeginEdges(i));
}
}
SimpleLogger().Write() << "Node compression ratio: "
<< new_node_count / (double)original_number_of_nodes;
SimpleLogger().Write() << "Edge compression ratio: "
<< new_edge_count / (double)original_number_of_edges;
}
+62
View File
@@ -0,0 +1,62 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GEOMETRY_COMPRESSOR_HPP
#define GEOMETRY_COMPRESSOR_HPP
#include "../typedefs.h"
#include "../extractor/speed_profile.hpp"
#include "../data_structures/node_based_graph.hpp"
#include <memory>
#include <unordered_set>
class CompressedEdgeContainer;
class RestrictionMap;
class GraphCompressor
{
using EdgeData = NodeBasedDynamicGraph::EdgeData;
public:
GraphCompressor(SpeedProfileProperties speed_profile);
void Compress(const std::unordered_set<NodeID>& barrier_nodes,
const std::unordered_set<NodeID>& traffic_lights,
RestrictionMap& restriction_map,
NodeBasedDynamicGraph& graph,
CompressedEdgeContainer& geometry_compressor);
private:
void PrintStatistics(unsigned original_number_of_nodes,
unsigned original_number_of_edges,
const NodeBasedDynamicGraph& graph) const;
SpeedProfileProperties speed_profile;
};
#endif
+11 -16
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,14 +28,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef OBJECT_ENCODER_HPP
#define OBJECT_ENCODER_HPP
#include "../Util/string_util.hpp"
#include <boost/assert.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
@@ -49,10 +48,9 @@ struct ObjectEncoder
8,
6>;
template <class ObjectT>
static void EncodeToBase64(const ObjectT &object, std::string &encoded)
template <class ObjectT> static void EncodeToBase64(const ObjectT &object, std::string &encoded)
{
const char *char_ptr_to_object = (const char *)&object;
const char *char_ptr_to_object = reinterpret_cast<const char *>(&object);
std::vector<unsigned char> data(sizeof(object));
std::copy(char_ptr_to_object, char_ptr_to_object + sizeof(ObjectT), data.begin());
@@ -67,23 +65,20 @@ struct ObjectEncoder
encoded.resize(sizeof(ObjectT));
encoded.assign(base64_t(&data[0]),
base64_t(&data[0] + (data.size() - number_of_padded_chars)));
replaceAll(encoded, "+", "-");
replaceAll(encoded, "/", "_");
std::replace(begin(encoded), end(encoded), '+', '-');
std::replace(begin(encoded), end(encoded), '/', '_');
}
template <class ObjectT>
static void DecodeFromBase64(const std::string &input, ObjectT &object)
template <class ObjectT> static void DecodeFromBase64(const std::string &input, ObjectT &object)
{
try
{
std::string encoded(input);
// replace "-" with "+" and "_" with "/"
replaceAll(encoded, "-", "+");
replaceAll(encoded, "_", "/");
std::replace(begin(encoded), end(encoded), '-', '+');
std::replace(begin(encoded), end(encoded), '_', '/');
std::copy(binary_t(encoded.begin()),
binary_t(encoded.begin() + encoded.length() - 1),
(char *)&object);
std::copy(binary_t(encoded.begin()), binary_t(encoded.begin() + encoded.length()),
reinterpret_cast<char *>(&object));
}
catch (...)
{
+40 -10
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,7 +28,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "polyline_compressor.hpp"
#include "../data_structures/segment_information.hpp"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
std::string PolylineCompressor::encode_vector(std::vector<int> &numbers) const
{
@@ -56,19 +56,11 @@ std::string PolylineCompressor::encode_number(int number_to_encode) const
{
const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63;
output += static_cast<char>(next_value);
if (92 == next_value)
{
output += static_cast<char>(next_value);
}
number_to_encode >>= 5;
}
number_to_encode += 63;
output += static_cast<char>(number_to_encode);
if (92 == number_to_encode)
{
output += static_cast<char>(number_to_encode);
}
return output;
}
@@ -96,3 +88,41 @@ PolylineCompressor::get_encoded_string(const std::vector<SegmentInformation> &po
}
return encode_vector(delta_numbers);
}
std::vector<FixedPointCoordinate> PolylineCompressor::decode_string(const std::string &geometry_string) const
{
std::vector<FixedPointCoordinate> new_coordinates;
int index = 0, len = geometry_string.size();
int lat = 0, lng = 0;
while (index < len)
{
int b, shift = 0, result = 0;
do
{
b = geometry_string.at(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do
{
b = geometry_string.at(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
FixedPointCoordinate p;
p.lat = COORDINATE_PRECISION * (((double) lat / 1E6));
p.lon = COORDINATE_PRECISION * (((double) lng / 1E6));
new_coordinates.push_back(p);
}
return new_coordinates;
}
+5 -1
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,6 +30,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct SegmentInformation;
#include <osrm/coordinate.hpp>
#include <string>
#include <vector>
@@ -42,6 +44,8 @@ class PolylineCompressor
public:
std::string get_encoded_string(const std::vector<SegmentInformation> &polyline) const;
std::vector<FixedPointCoordinate> decode_string(const std::string &geometry_string) const;
};
#endif /* POLYLINECOMPRESSOR_H_ */
+7 -7
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,23 +30,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "polyline_compressor.hpp"
#include "../data_structures/segment_information.hpp"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
JSON::String
osrm::json::String
PolylineFormatter::printEncodedString(const std::vector<SegmentInformation> &polyline) const
{
return JSON::String(PolylineCompressor().get_encoded_string(polyline));
return osrm::json::String(PolylineCompressor().get_encoded_string(polyline));
}
JSON::Array
osrm::json::Array
PolylineFormatter::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
{
JSON::Array json_geometry_array;
osrm::json::Array json_geometry_array;
for (const auto &segment : polyline)
{
if (segment.necessary)
{
JSON::Array json_coordinate;
osrm::json::Array json_coordinate;
json_coordinate.values.push_back(segment.location.lat / COORDINATE_PRECISION);
json_coordinate.values.push_back(segment.location.lon / COORDINATE_PRECISION);
json_geometry_array.values.push_back(json_coordinate);
+4 -4
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,16 +30,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct SegmentInformation;
#include "../data_structures/json_container.hpp"
#include <osrm/json_container.hpp>
#include <string>
#include <vector>
struct PolylineFormatter
{
JSON::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
osrm::json::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
JSON::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
osrm::json::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
};
#endif /* POLYLINE_FORMATTER_HPP */
+27 -34
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -54,7 +54,8 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
for (const SegmentT &segment : segment_list)
{
if (segment.name_id != blocked_name_id && segment.length > result_segment.length && segment.name_id != 0)
if (segment.name_id != blocked_name_id && segment.length > result_segment.length &&
segment.name_id != 0)
{
result_segment = segment;
}
@@ -73,9 +74,13 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
SegmentT alternative_segment_1, alternative_segment_2;
auto length_comperator = [](const SegmentT &a, const SegmentT &b)
{ return a.length > b.length; };
{
return a.length > b.length;
};
auto name_id_comperator = [](const SegmentT &a, const SegmentT &b)
{ return a.name_id < b.name_id; };
{
return a.name_id < b.name_id;
};
if (shortest_path_segments.empty())
{
@@ -87,8 +92,7 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
shortest_segment_1 = shortest_path_segments[0];
if (!alternative_path_segments.empty())
{
std::sort(alternative_path_segments.begin(),
alternative_path_segments.end(),
std::sort(alternative_path_segments.begin(), alternative_path_segments.end(),
length_comperator);
// also pick the longest segment for the alternative path
@@ -99,16 +103,13 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
// alternative
std::vector<SegmentT> shortest_path_set_difference(shortest_path_segments.size());
std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), name_id_comperator);
std::sort(alternative_path_segments.begin(), alternative_path_segments.end(), name_id_comperator);
std::set_difference(shortest_path_segments.begin(),
shortest_path_segments.end(),
alternative_path_segments.begin(),
alternative_path_segments.end(),
shortest_path_set_difference.begin(),
name_id_comperator);
std::sort(alternative_path_segments.begin(), alternative_path_segments.end(),
name_id_comperator);
std::set_difference(shortest_path_segments.begin(), shortest_path_segments.end(),
alternative_path_segments.begin(), alternative_path_segments.end(),
shortest_path_set_difference.begin(), name_id_comperator);
std::sort(shortest_path_set_difference.begin(),
shortest_path_set_difference.end(),
std::sort(shortest_path_set_difference.begin(), shortest_path_set_difference.end(),
length_comperator);
shortest_segment_2 =
PickNextLongestSegment(shortest_path_set_difference, shortest_segment_1.name_id);
@@ -116,29 +117,23 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
// compute the set difference (for alternative path) depending on names between shortest and
// alternative
// vectors are still sorted, no need to do again
BOOST_ASSERT(std::is_sorted(shortest_path_segments.begin(),
shortest_path_segments.end(),
BOOST_ASSERT(std::is_sorted(shortest_path_segments.begin(), shortest_path_segments.end(),
name_id_comperator));
BOOST_ASSERT(std::is_sorted(alternative_path_segments.begin(),
alternative_path_segments.end(),
name_id_comperator));
alternative_path_segments.end(), name_id_comperator));
std::vector<SegmentT> alternative_path_set_difference(alternative_path_segments.size());
std::set_difference(alternative_path_segments.begin(),
alternative_path_segments.end(),
shortest_path_segments.begin(),
shortest_path_segments.end(),
alternative_path_set_difference.begin(),
name_id_comperator);
std::set_difference(alternative_path_segments.begin(), alternative_path_segments.end(),
shortest_path_segments.begin(), shortest_path_segments.end(),
alternative_path_set_difference.begin(), name_id_comperator);
std::sort(alternative_path_set_difference.begin(),
alternative_path_set_difference.end(),
std::sort(alternative_path_set_difference.begin(), alternative_path_set_difference.end(),
length_comperator);
if (!alternative_path_segments.empty())
{
alternative_segment_2 = PickNextLongestSegment(alternative_path_set_difference,
alternative_segment_1.name_id);
alternative_segment_1.name_id);
}
// move the segments into the order in which they occur.
@@ -152,15 +147,13 @@ template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
}
// fetching names for the selected segments
route_names.shortest_path_name_1 =
facade->GetEscapedNameForNameID(shortest_segment_1.name_id);
route_names.shortest_path_name_2 =
facade->GetEscapedNameForNameID(shortest_segment_2.name_id);
route_names.shortest_path_name_1 = facade->get_name_for_id(shortest_segment_1.name_id);
route_names.shortest_path_name_2 = facade->get_name_for_id(shortest_segment_2.name_id);
route_names.alternative_path_name_1 =
facade->GetEscapedNameForNameID(alternative_segment_1.name_id);
facade->get_name_for_id(alternative_segment_1.name_id);
route_names.alternative_path_name_2 =
facade->GetEscapedNameForNameID(alternative_segment_2.name_id);
facade->get_name_for_id(alternative_segment_2.name_id);
return route_names;
}
@@ -1,6 +1,6 @@
/*
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,40 +25,31 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TINY_COMPONENTS_HPP
#define TINY_COMPONENTS_HPP
#ifndef TARJAN_SCC_HPP
#define TARJAN_SCC_HPP
#include "../typedefs.h"
#include "../data_structures/deallocating_vector.hpp"
#include "../data_structures/import_edge.hpp"
#include "../data_structures/query_node.hpp"
#include "../data_structures/percent.hpp"
#include "../data_structures/restriction.hpp"
#include "../data_structures/restriction_map.hpp"
#include "../data_structures/turn_instructions.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/std_hash.hpp"
#include "../Util/timing_util.hpp"
#include <osrm/Coordinate.h>
#include "../util/integer_range.hpp"
#include "../util/simple_logger.hpp"
#include "../util/std_hash.hpp"
#include "../util/timing_util.hpp"
#include <osrm/coordinate.hpp>
#include <boost/assert.hpp>
#include <tbb/parallel_sort.h>
#include <cstdint>
#include <memory>
#include <algorithm>
#include <climits>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
template <typename GraphT>
class TarjanSCC
template <typename GraphT> class TarjanSCC
{
struct TarjanStackFrame
{
@@ -77,38 +68,32 @@ class TarjanSCC
std::vector<unsigned> components_index;
std::vector<NodeID> component_size_vector;
std::shared_ptr<GraphT> m_node_based_graph;
std::unordered_set<NodeID> barrier_node_set;
RestrictionMap m_restriction_map;
unsigned size_one_counter;
std::shared_ptr<const GraphT> m_graph;
std::size_t size_one_counter;
public:
template<class ContainerT>
TarjanSCC(std::shared_ptr<GraphT> graph,
const RestrictionMap &restrictions,
const ContainerT &barrier_node_list)
: components_index(graph->GetNumberOfNodes(), SPECIAL_NODEID),
m_node_based_graph(graph), m_restriction_map(restrictions),
TarjanSCC(std::shared_ptr<const GraphT> graph)
: components_index(graph->GetNumberOfNodes(), SPECIAL_NODEID), m_graph(graph),
size_one_counter(0)
{
barrier_node_set.insert(std::begin(barrier_node_list), std::end(barrier_node_list));
BOOST_ASSERT(m_node_based_graph->GetNumberOfNodes() > 0);
BOOST_ASSERT(m_graph->GetNumberOfNodes() > 0);
}
void run()
{
TIMER_START(SCC_RUN);
const NodeID max_node_id = m_graph->GetNumberOfNodes();
// The following is a hack to distinguish between stuff that happens
// before the recursive call and stuff that happens after
std::stack<TarjanStackFrame> recursion_stack;
// true = stuff before, false = stuff after call
std::stack<NodeID> tarjan_stack;
std::vector<TarjanNode> tarjan_node_list(m_node_based_graph->GetNumberOfNodes());
std::vector<TarjanNode> tarjan_node_list(max_node_id);
unsigned component_index = 0, size_of_current_component = 0;
int index = 0;
const NodeID last_node = m_node_based_graph->GetNumberOfNodes();
std::vector<bool> processing_node_before_recursion(m_node_based_graph->GetNumberOfNodes(), true);
for(const NodeID node : osrm::irange(0u, last_node))
unsigned index = 0;
std::vector<bool> processing_node_before_recursion(max_node_id, true);
for (const NodeID node : osrm::irange(0u, max_node_id))
{
if (SPECIAL_NODEID == components_index[node])
{
@@ -142,32 +127,9 @@ class TarjanSCC
tarjan_node_list[v].on_stack = true;
++index;
const NodeID to_node_of_only_restriction =
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(v))
for (const auto current_edge : m_graph->GetAdjacentEdgeRange(v))
{
const auto vprime = m_node_based_graph->GetTarget(current_edge);
// Traverse outgoing edges
if (barrier_node_set.find(v) != barrier_node_set.end() &&
u != vprime)
{
// continue;
}
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
vprime == to_node_of_only_restriction)
{
// At an only_-restriction but not at the right turn
// continue;
}
if (m_restriction_map.CheckIfTurnIsRestricted(u, v, vprime))
{
// continue;
}
const auto vprime = m_graph->GetTarget(current_edge);
if (SPECIAL_NODEID == tarjan_node_list[vprime].index)
{
@@ -186,9 +148,8 @@ class TarjanSCC
else
{
processing_node_before_recursion[v] = true;
tarjan_node_list[currentFrame.parent].low_link =
std::min(tarjan_node_list[currentFrame.parent].low_link,
tarjan_node_list[v].low_link);
tarjan_node_list[u].low_link =
std::min(tarjan_node_list[u].low_link, tarjan_node_list[v].low_link);
// after recursion, lets do cycle checking
// Check if we found a cycle. This is the bottom part of the recursion
if (tarjan_node_list[v].low_link == tarjan_node_list[v].index)
@@ -219,35 +180,25 @@ class TarjanSCC
}
TIMER_STOP(SCC_RUN);
SimpleLogger().Write() << "SCC run took: " << TIMER_MSEC(SCC_RUN)/1000. << "s";
SimpleLogger().Write() << "SCC run took: " << TIMER_MSEC(SCC_RUN) / 1000. << "s";
size_one_counter = std::count_if(component_size_vector.begin(),
component_size_vector.end(),
size_one_counter = std::count_if(component_size_vector.begin(), component_size_vector.end(),
[](unsigned value)
{
return 1 == value;
});
return 1 == value;
});
}
std::size_t get_number_of_components() const
std::size_t get_number_of_components() const { return component_size_vector.size(); }
std::size_t get_size_one_count() const { return size_one_counter; }
unsigned get_component_size(const unsigned component_id) const
{
return component_size_vector.size();
return component_size_vector[component_id];
}
unsigned get_size_one_count() const
{
return size_one_counter;
}
unsigned get_component_size(const NodeID node) const
{
return component_size_vector[components_index[node]];
}
unsigned get_component_id(const NodeID node) const
{
return components_index[node];
}
unsigned get_component_id(const NodeID node) const { return components_index[node]; }
};
#endif /* TINY_COMPONENTS_HPP */
#endif /* TARJAN_SCC_HPP */
+108
View File
@@ -0,0 +1,108 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TRIP_BRUTE_FORCE_HPP
#define TRIP_BRUTE_FORCE_HPP
#include "../data_structures/search_engine.hpp"
#include "../util/dist_table_wrapper.hpp"
#include "../util/simple_logger.hpp"
#include <osrm/json_container.hpp>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <iterator>
#include <vector>
#include <limits>
namespace osrm
{
namespace trip
{
// computes the distance of a given permutation
EdgeWeight ReturnDistance(const DistTableWrapper<EdgeWeight> &dist_table,
const std::vector<NodeID> &location_order,
const EdgeWeight min_route_dist,
const std::size_t component_size)
{
EdgeWeight route_dist = 0;
std::size_t i = 0;
while (i < location_order.size() && (route_dist < min_route_dist))
{
route_dist += dist_table(location_order[i], location_order[(i + 1) % component_size]);
BOOST_ASSERT_MSG(dist_table(location_order[i], location_order[(i + 1) % component_size]) !=
INVALID_EDGE_WEIGHT,
"invalid route found");
++i;
}
return route_dist;
}
// computes the route by computing all permutations and selecting the shortest
template <typename NodeIDIterator>
std::vector<NodeID> BruteForceTrip(const NodeIDIterator start,
const NodeIDIterator end,
const std::size_t number_of_locations,
const DistTableWrapper<EdgeWeight> &dist_table)
{
(void)number_of_locations; // unused
const auto component_size = std::distance(start, end);
std::vector<NodeID> perm(start, end);
std::vector<NodeID> route;
route.reserve(component_size);
EdgeWeight min_route_dist = INVALID_EDGE_WEIGHT;
// check length of all possible permutation of the component ids
BOOST_ASSERT_MSG(perm.size() > 0, "no permutation given");
BOOST_ASSERT_MSG(*(std::max_element(std::begin(perm), std::end(perm))) < number_of_locations,
"invalid node id");
BOOST_ASSERT_MSG(*(std::min_element(std::begin(perm), std::end(perm))) >= 0, "invalid node id");
do
{
const auto new_distance = ReturnDistance(dist_table, perm, min_route_dist, component_size);
if (new_distance <= min_route_dist)
{
min_route_dist = new_distance;
route = perm;
}
} while (std::next_permutation(std::begin(perm), std::end(perm)));
return route;
}
} // end namespace trip
} // end namespace osrm
#endif // TRIP_BRUTE_FORCE_HPP
+222
View File
@@ -0,0 +1,222 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TRIP_FARTHEST_INSERTION_HPP
#define TRIP_FARTHEST_INSERTION_HPP
#include "../data_structures/search_engine.hpp"
#include "../util/dist_table_wrapper.hpp"
#include <osrm/json_container.hpp>
#include <boost/assert.hpp>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <vector>
#include <limits>
namespace osrm
{
namespace trip
{
// given a route and a new location, find the best place of insertion and
// check the distance of roundtrip when the new location is additionally visited
using NodeIDIter = std::vector<NodeID>::iterator;
std::pair<EdgeWeight, NodeIDIter>
GetShortestRoundTrip(const NodeID new_loc,
const DistTableWrapper<EdgeWeight> &dist_table,
const std::size_t number_of_locations,
std::vector<NodeID> &route)
{
(void)number_of_locations; // unused
auto min_trip_distance = INVALID_EDGE_WEIGHT;
NodeIDIter next_insert_point_candidate;
// for all nodes in the current trip find the best insertion resulting in the shortest path
// assert min 2 nodes in route
const auto start = std::begin(route);
const auto end = std::end(route);
for (auto from_node = start; from_node != end; ++from_node)
{
auto to_node = std::next(from_node);
if (to_node == end)
{
to_node = start;
}
const auto dist_from = dist_table(*from_node, new_loc);
const auto dist_to = dist_table(new_loc, *to_node);
const auto trip_dist = dist_from + dist_to - dist_table(*from_node, *to_node);
BOOST_ASSERT_MSG(dist_from != INVALID_EDGE_WEIGHT, "distance has invalid edge weight");
BOOST_ASSERT_MSG(dist_to != INVALID_EDGE_WEIGHT, "distance has invalid edge weight");
// This is not neccessarily true:
// Lets say you have an edge (u, v) with duration 100. If you place a coordinate exactly in
// the middle of the segment yielding (u, v'), the adjusted duration will be 100 * 0.5 = 50.
// Now imagine two coordinates. One placed at 0.99 and one at 0.999. This means (u, v') now
// has a duration of 100 * 0.99 = 99, but (u, v'') also has a duration of 100 * 0.995 = 99.
// In which case (v', v'') has a duration of 0.
// BOOST_ASSERT_MSG(trip_dist >= 0, "previous trip was not minimal. something's wrong");
// from all possible insertions to the current trip, choose the shortest of all insertions
if (trip_dist < min_trip_distance)
{
min_trip_distance = trip_dist;
next_insert_point_candidate = to_node;
}
}
BOOST_ASSERT_MSG(min_trip_distance != INVALID_EDGE_WEIGHT, "trip has invalid edge weight");
return std::make_pair(min_trip_distance, next_insert_point_candidate);
}
template <typename NodeIDIterator>
// given two initial start nodes, find a roundtrip route using the farthest insertion algorithm
std::vector<NodeID> FindRoute(const std::size_t &number_of_locations,
const std::size_t &component_size,
const NodeIDIterator &start,
const NodeIDIterator &end,
const DistTableWrapper<EdgeWeight> &dist_table,
const NodeID &start1,
const NodeID &start2)
{
BOOST_ASSERT_MSG(number_of_locations >= component_size,
"component size bigger than total number of locations");
std::vector<NodeID> route;
route.reserve(number_of_locations);
// tracks which nodes have been already visited
std::vector<bool> visited(number_of_locations, false);
visited[start1] = true;
visited[start2] = true;
route.push_back(start1);
route.push_back(start2);
// add all other nodes missing (two nodes are already in the initial start trip)
for (std::size_t j = 2; j < component_size; ++j)
{
auto farthest_distance = std::numeric_limits<int>::min();
auto next_node = -1;
NodeIDIter next_insert_point;
// find unvisited loc i that is the farthest away from all other visited locs
for (auto i = start; i != end; ++i)
{
// find the shortest distance from i to all visited nodes
if (!visited[*i])
{
const auto insert_candidate =
GetShortestRoundTrip(*i, dist_table, number_of_locations, route);
BOOST_ASSERT_MSG(insert_candidate.first != INVALID_EDGE_WEIGHT,
"shortest round trip is invalid");
// add the location to the current trip such that it results in the shortest total
// tour
if (insert_candidate.first >= farthest_distance)
{
farthest_distance = insert_candidate.first;
next_node = *i;
next_insert_point = insert_candidate.second;
}
}
}
BOOST_ASSERT_MSG(next_node >= 0, "next node to visit is invalid");
// mark as visited and insert node
visited[next_node] = true;
route.insert(next_insert_point, next_node);
}
return route;
}
template <typename NodeIDIterator>
std::vector<NodeID> FarthestInsertionTrip(const NodeIDIterator &start,
const NodeIDIterator &end,
const std::size_t number_of_locations,
const DistTableWrapper<EdgeWeight> &dist_table)
{
//////////////////////////////////////////////////////////////////////////////////////////////////
// START FARTHEST INSERTION HERE
// 1. start at a random round trip of 2 locations
// 2. find the location that is the farthest away from the visited locations and whose insertion
// will make the round trip the longest
// 3. add the found location to the current round trip such that round trip is the shortest
// 4. repeat 2-3 until all locations are visited
// 5. DONE!
//////////////////////////////////////////////////////////////////////////////////////////////////
const auto component_size = std::distance(start, end);
BOOST_ASSERT(component_size >= 0);
auto max_from = -1;
auto max_to = -1;
if (static_cast<std::size_t>(component_size) == number_of_locations)
{
// find the pair of location with the biggest distance and make the pair the initial start
// trip
const auto index = std::distance(
std::begin(dist_table), std::max_element(std::begin(dist_table), std::end(dist_table)));
max_from = index / number_of_locations;
max_to = index % number_of_locations;
}
else
{
auto max_dist = 0;
for (auto x = start; x != end; ++x)
{
for (auto y = start; y != end; ++y)
{
const auto xy_dist = dist_table(*x, *y);
if (xy_dist > max_dist)
{
max_dist = xy_dist;
max_from = *x;
max_to = *y;
}
}
}
}
BOOST_ASSERT(max_from >= 0);
BOOST_ASSERT(max_to >= 0);
BOOST_ASSERT_MSG(static_cast<std::size_t>(max_from) < number_of_locations, "start node");
BOOST_ASSERT_MSG(static_cast<std::size_t>(max_to) < number_of_locations, "start node");
return FindRoute(number_of_locations, component_size, start, end, dist_table, max_from, max_to);
}
} // end namespace trip
} // end namespace osrm
#endif // TRIP_FARTHEST_INSERTION_HPP
+122
View File
@@ -0,0 +1,122 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TRIP_NEAREST_NEIGHBOUR_HPP
#define TRIP_NEAREST_NEIGHBOUR_HPP
#include "../data_structures/search_engine.hpp"
#include "../util/simple_logger.hpp"
#include "../util/dist_table_wrapper.hpp"
#include <osrm/json_container.hpp>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <vector>
#include <limits>
namespace osrm
{
namespace trip
{
template <typename NodeIDIterator>
std::vector<NodeID> NearestNeighbourTrip(const NodeIDIterator &start,
const NodeIDIterator &end,
const std::size_t number_of_locations,
const DistTableWrapper<EdgeWeight> &dist_table)
{
//////////////////////////////////////////////////////////////////////////////////////////////////
// START GREEDY NEAREST NEIGHBOUR HERE
// 1. grab a random location and mark as starting point
// 2. find the nearest unvisited neighbour, set it as the current location and mark as visited
// 3. repeat 2 until there is no unvisited location
// 4. return route back to starting point
// 5. compute route
// 6. repeat 1-5 with different starting points and choose iteration with shortest trip
// 7. DONE!
//////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<NodeID> route;
route.reserve(number_of_locations);
const auto component_size = std::distance(start, end);
auto shortest_trip_distance = INVALID_EDGE_WEIGHT;
// ALWAYS START AT ANOTHER STARTING POINT
for (auto start_node = start; start_node != end; ++start_node)
{
NodeID curr_node = *start_node;
std::vector<NodeID> curr_route;
curr_route.reserve(component_size);
curr_route.push_back(*start_node);
// visited[i] indicates whether node i was already visited by the salesman
std::vector<bool> visited(number_of_locations, false);
visited[*start_node] = true;
// 3. REPEAT FOR EVERY UNVISITED NODE
EdgeWeight trip_dist = 0;
for (std::size_t via_point = 1; via_point < component_size; ++via_point)
{
EdgeWeight min_dist = INVALID_EDGE_WEIGHT;
NodeID min_id = SPECIAL_NODEID;
// 2. FIND NEAREST NEIGHBOUR
for (auto next = start; next != end; ++next)
{
const auto curr_dist = dist_table(curr_node, *next);
BOOST_ASSERT_MSG(curr_dist != INVALID_EDGE_WEIGHT, "invalid distance found");
if (!visited[*next] && curr_dist < min_dist)
{
min_dist = curr_dist;
min_id = *next;
}
}
BOOST_ASSERT_MSG(min_id != SPECIAL_NODEID, "no next node found");
visited[min_id] = true;
curr_route.push_back(min_id);
trip_dist += min_dist;
curr_node = min_id;
}
// check round trip with this starting point is shorter than the shortest round trip found
// till now
if (trip_dist < shortest_trip_distance)
{
shortest_trip_distance = trip_dist;
route = std::move(curr_route);
}
}
return route;
}
} // end namespace trip
} // end namespace osrm
#endif // TRIP_NEAREST_NEIGHBOUR_HPP
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,33 +25,40 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MAKE_UNIQUE_H_
#define MAKE_UNIQUE_H_
#ifndef TRIP_BRUTE_FORCE_HPP
#define TRIP_BRUTE_FORCE_HPP
#include "../data_structures/search_engine.hpp"
#include "../util/simple_logger.hpp"
#include <osrm/json_container.hpp>
#include <cstdlib>
#include <memory>
#include <type_traits>
#include <algorithm>
#include <string>
#include <vector>
#include <limits>
namespace osrm
{
// Taken from http://msdn.microsoft.com/en-us/library/dn439780.asp
// Note, that the snippet was broken there and needed minor massaging
// make_unique<T>
template <class T, class... Types> std::unique_ptr<T> make_unique(Types &&... Args)
namespace trip
{
return (std::unique_ptr<T>(new T(std::forward<Types>(Args)...)));
}
// make_unique<T[]>
template <class T> std::unique_ptr<T[]> make_unique(std::size_t Size)
// todo: yet to be implemented
void TabuSearchTrip(std::vector<unsigned> &location,
const PhantomNodeArray &phantom_node_vector,
const std::vector<EdgeWeight> &dist_table,
InternalRouteResult &min_route,
std::vector<int> &min_loc_permutation)
{
return (std::unique_ptr<T>(new T[Size]()));
}
// make_unique<T[N]> disallowed
template <class T, class... Types>
typename std::enable_if<std::extent<T>::value != 0, void>::type make_unique(Types &&...) = delete;
void TabuSearchTrip(const PhantomNodeArray &phantom_node_vector,
const std::vector<EdgeWeight> &dist_table,
InternalRouteResult &min_route,
std::vector<int> &min_loc_permutation)
{
}
#endif //MAKE_UNIQUE_H_
}
}
#endif // TRIP_BRUTE_FORCE_HPP
+122
View File
@@ -0,0 +1,122 @@
@ECHO OFF
SETLOCAL
SET EL=0
ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET PROJECT_DIR=%CD%
ECHO PROJECT_DIR^: %PROJECT_DIR%
ECHO NUMBER_OF_PROCESSORS^: %NUMBER_OF_PROCESSORS%
ECHO cmake^: && cmake --version
ECHO activating VS command prompt ...
SET PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
ECHO platform^: %platform%
:: HARDCODE "x64" as it is uppercase on AppVeyor and download from S3 is case sensitive
SET DEPSPKG=osrm-deps-win-x64-14.0.7z
:: local development
ECHO LOCAL_DEV^: %LOCAL_DEV%
IF NOT DEFINED LOCAL_DEV SET LOCAL_DEV=0
IF DEFINED LOCAL_DEV IF %LOCAL_DEV% EQU 1 IF EXIST %DEPSPKG% ECHO skipping deps download && GOTO SKIPDL
IF EXIST %DEPSPKG% DEL %DEPSPKG%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO downloading %DEPSPKG%
powershell Invoke-WebRequest https://mapbox.s3.amazonaws.com/windows-builds/windows-build-deps/$env:DEPSPKG -OutFile $env:PROJECT_DIR\$env:DEPSPKG
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
:SKIPDL
IF EXIST osrm-deps ECHO deleting osrm-deps... && RD /S /Q osrm-deps
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
IF EXIST build ECHO deletings build dir... && RD /S /Q build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
7z -y x %DEPSPKG% | %windir%\system32\FIND "ing archive"
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
MKDIR build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
cd build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET OSRMDEPSDIR=%PROJECT_DIR%\osrm-deps
set PREFIX=%OSRMDEPSDIR%/libs
set BOOST_ROOT=%OSRMDEPSDIR%/boost
set TBB_INSTALL_DIR=%OSRMDEPSDIR%/tbb
set TBB_ARCH_PLATFORM=intel64/vc14
ECHO calling cmake ....
cmake .. ^
-G "Visual Studio 14 2015 Win64" ^
-DBOOST_ROOT=%BOOST_ROOT% ^
-DBoost_ADDITIONAL_VERSIONS=1.58 ^
-DBoost_USE_MULTITHREADED=ON ^
-DBoost_USE_STATIC_LIBS=ON ^
-DCMAKE_BUILD_TYPE=%CONFIGURATION% ^
-DCMAKE_INSTALL_PREFIX=%PREFIX%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO building ...
msbuild OSRM.sln ^
/p:Configuration=%Configuration% ^
/p:Platform=x64 ^
/t:rebuild ^
/p:BuildInParallel=true ^
/m:%NUMBER_OF_PROCESSORS% ^
/toolsversion:14.0 ^
/p:PlatformToolset=v140 ^
/clp:Verbosity=normal ^
/nologo ^
/flp1:logfile=build_errors.txt;errorsonly ^
/flp2:logfile=build_warnings.txt;warningsonly
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
CD %PROJECT_DIR%\build
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET PATH=%PROJECT_DIR%\osrm-deps\libs\bin;%PATH%
ECHO running datastructure-tests.exe ...
%Configuration%\datastructure-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO running algorithm-tests.exe ...
%Configuration%\algorithm-tests.exe
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
IF NOT "%APPVEYOR_REPO_BRANCH%"=="develop" GOTO DONE
ECHO ========= CREATING PACKAGES ==========
CD %PROJECT_DIR%\build\%Configuration%
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
SET P=%PROJECT_DIR%
SET ZIP= %P%\osrm_%Configuration%.zip
IF EXIST %ZIP% ECHO deleting %ZIP% && DEL /F /Q %ZIP%
IF %ERRORLEVEL% NEQ 0 ECHO deleting %ZIP% FAILED && GOTO ERROR
7z a %ZIP% *.lib *.exe *.pdb %P%/osrm-deps/libs/bin/*.dll -tzip -mx9 | %windir%\system32\FIND "ing archive"
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
CD ..\..\profiles
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
ECHO disk=c:\temp\stxxl,10000,wincall > .stxxl.txt
7z a %ZIP% * -tzip -mx9 | %windir%\system32\FIND "ing archive"
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
GOTO DONE
:ERROR
ECHO ~~~~~~~~~~~~~~~~~~~~~~ ERROR %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ECHO ERRORLEVEL^: %ERRORLEVEL%
SET EL=%ERRORLEVEL%
:DONE
ECHO ~~~~~~~~~~~~~~~~~~~~~~ DONE %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EXIT /b %EL%
+6 -40
View File
@@ -1,63 +1,29 @@
environment:
matrix:
- configuration: Debug
- configuration: Release
# branches to build
branches:
# whitelist
only:
- develop
# Operating system (build VM template)
os: Windows Server 2012 R2
# - configuration: Debug
# scripts that are called at very beginning, before repo cloning
init:
- git config --global core.autocrlf input
os: Visual Studio 2015
# clone directory
clone_folder: c:\projects\osrm
platform: x64
install:
# by default, all script lines are interpreted as batch
- nuget install protobuf
- cd c:\projects\osrm
- curl -O http://build.project-osrm.org/libs_osrm_%Configuration%.7z
- 7z x libs_osrm_%Configuration%.7z | find ":"
build_script:
- cd c:/projects/osrm
- mkdir build
- cd build
- echo Running cmake...
- call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
- SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH%
- SET P=c:/projects/osrm
- set TBB_INSTALL_DIR=%P%/tbb
- set TBB_ARCH_PLATFORM=intel64/vc12
- cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_ADDITIONAL_VERSIONS=1.57 -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013
- msbuild /clp:Verbosity=minimal /nologo OSRM.sln
- msbuild /clp:Verbosity=minimal /nologo tests.vcxproj
- cd %Configuration%
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip)
- cd ..\..\profiles
- echo disk=c:\temp\stxxl,10000,wincall > .stxxl.txt
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip * -tzip)
- set PATH=%PATH%;c:/projects/osrm/libs/bin
- cd c:/projects/osrm/build/%Configuration%
- datastructure-tests.exe
- algorithm-tests.exe
- CALL appveyor-build.bat
test: off
artifacts:
- path: osrm_Debug.zip
name: osrm_Debug.zip
- path: osrm_Release.zip
name: osrm_Release.zip
# - path: osrm_Debug.zip
# name: osrm_Debug.zip
deploy:
provider: FTP
+57 -94
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,16 +25,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../data_structures/original_edge_data.hpp"
#include "../data_structures/query_node.hpp"
#include "../data_structures/shared_memory_vector_wrapper.hpp"
#include "../data_structures/static_rtree.hpp"
#include "../data_structures/edge_based_node.hpp"
#include "../Util/BoostFileSystemFix.h"
#include "../algorithms/geospatial_query.hpp"
#include "../util/timing_util.hpp"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
#include <random>
#include <iostream>
// Choosen by a fair W20 dice roll (this value is completely arbitrary)
constexpr unsigned RANDOM_SEED = 13;
@@ -46,6 +46,7 @@ constexpr int32_t WORLD_MAX_LON = 180 * COORDINATE_PRECISION;
using RTreeLeaf = EdgeBasedNode;
using FixedPointCoordinateListPtr = std::shared_ptr<std::vector<FixedPointCoordinate>>;
using BenchStaticRTree = StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, false>::vector, false>;
using BenchQuery = GeospatialQuery<BenchStaticRTree>;
FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes_file)
{
@@ -66,7 +67,28 @@ FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes
return coords;
}
void Benchmark(BenchStaticRTree &rtree, unsigned num_queries)
template <typename QueryT>
void BenchmarkQuery(const std::vector<FixedPointCoordinate> &queries,
const std::string& name,
QueryT query)
{
std::cout << "Running " << name << " with " << queries.size() << " coordinates: " << std::flush;
TIMER_START(query);
for (const auto &q : queries)
{
auto result = query(q);
}
TIMER_STOP(query);
std::cout << "Took " << TIMER_SEC(query) << " seconds "
<< "(" << TIMER_MSEC(query) << "ms"
<< ") -> " << TIMER_MSEC(query) / queries.size() << " ms/query "
<< "(" << TIMER_MSEC(query) << "ms"
<< ")" << std::endl;
}
void Benchmark(BenchStaticRTree &rtree, BenchQuery &geo_query, unsigned num_queries)
{
std::mt19937 mt_rand(RANDOM_SEED);
std::uniform_int_distribution<> lat_udist(WORLD_MIN_LAT, WORLD_MAX_LAT);
@@ -74,96 +96,36 @@ void Benchmark(BenchStaticRTree &rtree, unsigned num_queries)
std::vector<FixedPointCoordinate> queries;
for (unsigned i = 0; i < num_queries; i++)
{
queries.emplace_back(FixedPointCoordinate(lat_udist(mt_rand), lon_udist(mt_rand)));
queries.emplace_back(lat_udist(mt_rand), lon_udist(mt_rand));
}
{
const unsigned num_results = 5;
std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results
<< " phantom nodes"
<< "\n";
BenchmarkQuery(queries, "raw RTree queries (1 result)", [&rtree](const FixedPointCoordinate &q)
{
return rtree.Nearest(q, 1);
});
BenchmarkQuery(queries, "raw RTree queries (10 results)",
[&rtree](const FixedPointCoordinate &q)
{
return rtree.Nearest(q, 10);
});
TIMER_START(query_phantom);
std::vector<PhantomNode> phantom_node_vector;
for (const auto &q : queries)
{
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, phantom_node_vector, 3, num_results);
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, phantom_node_vector, 17, num_results);
}
TIMER_STOP(query_phantom);
std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries
<< " queries."
<< "\n";
std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query."
<< "\n";
std::cout << "#### LocateClosestEndPointForCoordinate"
<< "\n";
}
TIMER_START(query_endpoint);
FixedPointCoordinate result;
for (const auto &q : queries)
{
rtree.LocateClosestEndPointForCoordinate(q, result, 3);
}
TIMER_STOP(query_endpoint);
std::cout << "Took " << TIMER_MSEC(query_endpoint) << " msec for " << num_queries << " queries."
<< "\n";
std::cout << TIMER_MSEC(query_endpoint) / ((double)num_queries) << " msec/query."
<< "\n";
std::cout << "#### FindPhantomNodeForCoordinate"
<< "\n";
TIMER_START(query_node);
for (const auto &q : queries)
{
PhantomNode phantom;
rtree.FindPhantomNodeForCoordinate(q, phantom, 3);
}
TIMER_STOP(query_node);
std::cout << "Took " << TIMER_MSEC(query_node) << " msec for " << num_queries
<< " queries."
<< "\n";
std::cout << TIMER_MSEC(query_node) / ((double)num_queries) << " msec/query."
<< "\n";
{
const unsigned num_results = 1;
std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results
<< " phantom nodes"
<< "\n";
TIMER_START(query_phantom);
std::vector<PhantomNode> phantom_node_vector;
for (const auto &q : queries)
{
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, phantom_node_vector, 3, num_results);
phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, phantom_node_vector, 17, num_results);
}
TIMER_STOP(query_phantom);
std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries
<< " queries."
<< "\n";
std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query."
<< "\n";
std::cout << "#### LocateClosestEndPointForCoordinate"
<< "\n";
}
BenchmarkQuery(queries, "big component alternative queries",
[&geo_query](const FixedPointCoordinate &q)
{
return geo_query.NearestPhantomNodeWithAlternativeFromBigComponent(q);
});
BenchmarkQuery(queries, "max distance 1000", [&geo_query](const FixedPointCoordinate &q)
{
return geo_query.NearestPhantomNodesInRange(q, 1000);
});
BenchmarkQuery(queries, "PhantomNode query (1 result)", [&geo_query](const FixedPointCoordinate &q)
{
return geo_query.NearestPhantomNodes(q, 1);
});
BenchmarkQuery(queries, "PhantomNode query (10 result)", [&geo_query](const FixedPointCoordinate &q)
{
return geo_query.NearestPhantomNodes(q, 10);
});
}
int main(int argc, char **argv)
@@ -182,8 +144,9 @@ int main(int argc, char **argv)
auto coords = LoadCoordinates(nodesPath);
BenchStaticRTree rtree(ramPath, filePath, coords);
BenchQuery query(rtree, coords);
Benchmark(rtree, 10000);
Benchmark(rtree, query, 10000);
return 0;
}
+33
View File
@@ -0,0 +1,33 @@
@ECHO OFF
SETLOCAL
SET EL=0
ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET PLATFORM=x64
SET CONFIGURATION=Release
::SET LOCAL_DEV=1
FOR /F "tokens=*" %%i in ('git rev-parse --abbrev-ref HEAD') do SET APPVEYOR_REPO_BRANCH=%%i
ECHO APPVEYOR_REPO_BRANCH^: %APPVEYOR_REPO_BRANCH%
SET PATH=C:\mb\windows-builds-64\tmp-bin\cmake-3.4.0-win32-x86\bin;%PATH%
SET PATH=C:\Program Files\7-Zip;%PATH%
powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
CALL appveyor-build.bat
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
GOTO DONE
:ERROR
ECHO ~~~~~~~~~~~~~~~~~~~~~~ ERROR %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ECHO ERRORLEVEL^: %ERRORLEVEL%
SET EL=%ERRORLEVEL%
:DONE
ECHO ~~~~~~~~~~~~~~~~~~~~~~ DONE %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EXIT /b %EL%
+1 -1
View File
@@ -34,7 +34,7 @@ SET(CPACK_DEBIAN_PACKAGE_SECTION "devel")
SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Open Source Routing Machine (OSRM) is a high-performance routing engine.
It combines sophisticated routing algorithms with the open and free data of the OpenStreetMap."
)
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6-dev, libprotobuf-dev, libosmpbf-dev, libbz2-1.0, libstxxl1, libxml2, libzip2, liblua5.1-0, libtbb2, libboost-all-dev")
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6-dev, libbz2-1.0, libstxxl1, libxml2, libzip2, liblua5.1-0, libtbb2, libboost-all-dev")
file(GLOB_RECURSE ProfileGlob ${CMAKE_SOURCE_DIR}/profiles/*)
install(FILES ${ProfileGlob} DESTINATION "share/doc/${LOWER_PROJECT_NAME}/profiles")
-54
View File
@@ -1,54 +0,0 @@
# Locate OSMPBF library
# This module defines
# OSMPBF_FOUND, if false, do not try to link to OSMPBF
# OSMPBF_LIBRARIES
# OSMPBF_INCLUDE_DIR, where to find OSMPBF.hpp
#
# Note that the expected include convention is
# #include <osmpbf/osmpbf.h>
# and not
# #include <osmpbf.h>
IF( NOT OSMPBF_FIND_QUIETLY )
MESSAGE(STATUS "Looking for OSMPBF...")
ENDIF()
FIND_PATH(OSMPBF_INCLUDE_DIR osmpbf.h
HINTS
$ENV{OSMPBF_DIR}
PATH_SUFFIXES OSMPBF include/osmpbf include
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt/local # DarwinPorts
/opt
)
FIND_LIBRARY(OSMPBF_LIBRARY
NAMES osmpbf
HINTS
$ENV{OSMPBF_DIR}
PATH_SUFFIXES lib64 lib
PATHS
~/Library/Frameworks
/Library/Frameworks
/usr/local
/usr
/opt/local
/opt
)
INCLUDE(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set OSMPBF_FOUND to TRUE if
# all listed variables are TRUE
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OSMPBF DEFAULT_MSG OSMPBF_LIBRARY OSMPBF_INCLUDE_DIR)
IF( NOT OSMPBF_FIND_QUIETLY )
IF( OSMPBF_FOUND )
MESSAGE(STATUS "Found OSMPBF: ${OSMPBF_LIBRARY}" )
ENDIF()
ENDIF()
#MARK_AS_ADVANCED(OSMPBF_INCLUDE_DIR OSMPBF_LIBRARIES OSMPBF_LIBRARY OSMPBF_LIBRARY_DBG)
+21 -7
View File
@@ -1,10 +1,24 @@
set(OLDFILE ${SOURCE_DIR}/Util/FingerPrint.cpp)
if (EXISTS ${OLDFILE})
file(REMOVE_RECURSE ${OLDFILE})
endif()
set(OLDFILE ${OUTPUT_DIR}/util/fingerprint_impl.hpp)
set(NEWFILE ${OLDFILE}.tmp)
set(INFILE ${SOURCE_DIR}/util/fingerprint_impl.hpp.in)
file(MD5 ${SOURCE_DIR}/prepare.cpp MD5PREPARE)
file(MD5 ${SOURCE_DIR}/data_structures/static_rtree.hpp MD5RTREE)
file(MD5 ${SOURCE_DIR}/Util/graph_loader.hpp MD5GRAPH)
file(MD5 ${SOURCE_DIR}/Server/DataStructures/InternalDataFacade.h MD5OBJECTS)
file(MD5 ${SOURCE_DIR}/util/graph_loader.hpp MD5GRAPH)
file(MD5 ${SOURCE_DIR}/server/data_structures/internal_datafacade.hpp MD5OBJECTS)
CONFIGURE_FILE( ${SOURCE_DIR}/Util/finger_print.cpp.in ${SOURCE_DIR}/Util/finger_print.cpp )
CONFIGURE_FILE(${INFILE} ${NEWFILE})
file(MD5 ${NEWFILE} MD5NEW)
if (EXISTS ${OLDFILE})
file(MD5 ${OLDFILE} MD5OLD)
if(NOT ${MD5NEW} STREQUAL ${MD5OLD})
file(REMOVE_RECURSE ${OLDFILE})
file(RENAME ${NEWFILE} ${OLDFILE})
else()
file(REMOVE_RECURSE ${NEWFILE})
message(STATUS "Fingerprint unchanged, not regenerating")
endif()
else()
file(RENAME ${NEWFILE} ${OLDFILE})
endif()
-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()
-38
View File
@@ -1,38 +0,0 @@
#
# Internal file for GetGitRevisionDescription.cmake
#
# 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)
set(HEAD_HASH)
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
if(HEAD_CONTENTS MATCHES "ref")
# named branch
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}")
configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
set(HEAD_HASH "${HEAD_REF}")
endif()
else()
# detached HEAD
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
endif()
if(NOT HEAD_HASH)
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
string(STRIP "${HEAD_HASH}" HEAD_HASH)
endif()
+1 -1
View File
@@ -1,7 +1,7 @@
INCLUDE (CheckCXXSourceCompiles)
unset(LUABIND_WORKS CACHE)
unset(LUABIND51_WORKS CACHE)
set (LUABIND_CHECK_SRC "#include \"lua.h\"\n#include <luabind/luabind.hpp>\n int main() { lua_State *myLuaState = luaL_newstate(); luabind::open(myLuaState); return 0;}")
set (LUABIND_CHECK_SRC "extern \"C\" {\n#include \"lua.h\"\n#include \"lauxlib.h\"\n}\n#include <luabind/open.hpp>\nint main() { lua_State *x = luaL_newstate(); luabind::open(x); }")
set (CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})
set (CMAKE_REQUIRED_INCLUDES "${Boost_INCLUDE_DIR};${LUABIND_INCLUDE_DIR};${LUA_INCLUDE_DIR}")
set (CMAKE_REQUIRED_LIBRARIES "${LUABIND_LIBRARY};${LUA_LIBRARY}")
+3 -3
View File
@@ -1,11 +1,11 @@
prefix=@CMAKE_INSTALL_PREFIX@
includedir=${prefix}/include/osrm
includedir=${prefix}/include
libdir=${prefix}/lib
Name: libOSRM
Description: Project OSRM library
Version: @GIT_DESCRIPTION@
Version: v@OSRM_VERSION_MAJOR@.@OSRM_VERSION_MINOR@.@OSRM_VERSION_PATCH@
Requires:
Libs: -L${libdir} -lOSRM
Libs.private: @BOOST_LIBRARY_LISTING@
Libs.private: @BOOST_LIBRARY_LISTING@ @TBB_LIBRARY_LISTING@
Cflags: -I${includedir}
+266 -155
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -35,9 +35,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../data_structures/query_edge.hpp"
#include "../data_structures/xor_fast_hash.hpp"
#include "../data_structures/xor_fast_hash_storage.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/timing_util.hpp"
#include "../util/integer_range.hpp"
#include "../util/simple_logger.hpp"
#include "../util/timing_util.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
@@ -50,6 +50,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm>
#include <limits>
#include <memory>
#include <vector>
class Contractor
@@ -92,9 +93,11 @@ class Contractor
};
using ContractorGraph = DynamicGraph<ContractorEdgeData>;
// using ContractorHeap = BinaryHeap<NodeID, NodeID, int, ContractorHeapData, ArrayStorage<NodeID, NodeID>
// using ContractorHeap = BinaryHeap<NodeID, NodeID, int, ContractorHeapData,
// ArrayStorage<NodeID, NodeID>
// >;
using ContractorHeap = BinaryHeap<NodeID, NodeID, int, ContractorHeapData, XORFastHashStorage<NodeID, NodeID>>;
using ContractorHeap =
BinaryHeap<NodeID, NodeID, int, ContractorHeapData, XORFastHashStorage<NodeID, NodeID>>;
using ContractorEdge = ContractorGraph::InputEdge;
struct ContractorThreadData
@@ -131,15 +134,14 @@ class Contractor
bool is_independent : 1;
};
struct ThreadDataContainer
{
explicit ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {}
explicit ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {}
inline ContractorThreadData* getThreadData()
inline ContractorThreadData *getThreadData()
{
bool exists = false;
auto& ref = data.local(exists);
auto &ref = data.local(exists);
if (!exists)
{
ref = std::make_shared<ContractorThreadData>(number_of_nodes);
@@ -149,12 +151,22 @@ class Contractor
}
int number_of_nodes;
using EnumerableThreadData = tbb::enumerable_thread_specific<std::shared_ptr<ContractorThreadData>>;
using EnumerableThreadData =
tbb::enumerable_thread_specific<std::shared_ptr<ContractorThreadData>>;
EnumerableThreadData data;
};
public:
template <class ContainerT> Contractor(int nodes, ContainerT &input_edge_list)
: Contractor(nodes, input_edge_list, {}, {})
{
}
template <class ContainerT>
Contractor(int nodes,
ContainerT &input_edge_list,
std::vector<float> &&node_levels_)
: node_levels(std::move(node_levels_))
{
std::vector<ContractorEdge> edges;
edges.reserve(input_edge_list.size() * 2);
@@ -162,32 +174,31 @@ class Contractor
const auto dend = input_edge_list.dend();
for (auto diter = input_edge_list.dbegin(); diter != dend; ++diter)
{
BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(diter->weight, 1)) > 0, "edge distance < 1");
BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(diter->weight, 1)) > 0,
"edge distance < 1");
#ifndef NDEBUG
if (static_cast<unsigned int>(std::max(diter->weight, 1)) > 24 * 60 * 60 * 10)
{
SimpleLogger().Write(logWARNING) << "Edge weight large -> "
<< static_cast<unsigned int>(std::max(diter->weight, 1));
SimpleLogger().Write(logWARNING)
<< "Edge weight large -> "
<< static_cast<unsigned int>(std::max(diter->weight, 1)) << " : "
<< static_cast<unsigned int>(diter->source) << " -> "
<< static_cast<unsigned int>(diter->target);
}
#endif
edges.emplace_back(diter->source, diter->target,
static_cast<unsigned int>(std::max(diter->weight, 1)),
1,
diter->edge_id,
false,
diter->forward ? true : false,
diter->backward ? true : false);
static_cast<unsigned int>(std::max(diter->weight, 1)), 1,
diter->edge_id, false, diter->forward ? true : false,
diter->backward ? true : false);
edges.emplace_back(diter->target, diter->source,
static_cast<unsigned int>(std::max(diter->weight, 1)),
1,
diter->edge_id,
false,
diter->backward ? true : false,
diter->forward ? true : false);
static_cast<unsigned int>(std::max(diter->weight, 1)), 1,
diter->edge_id, false, diter->backward ? true : false,
diter->forward ? true : false);
}
// clear input vector
input_edge_list.clear();
// FIXME not sure if we need this
edges.shrink_to_fit();
tbb::parallel_sort(edges.begin(), edges.end());
@@ -282,20 +293,20 @@ class Contractor
std::cout << "contractor finished initalization" << std::endl;
}
~Contractor() { }
~Contractor() {}
void Run()
void Run(double core_factor = 1.0)
{
// for the preperation we can use a big grain size, which is much faster (probably cache)
constexpr size_t InitGrainSize = 100000;
constexpr size_t PQGrainSize = 100000;
constexpr size_t InitGrainSize = 100000;
constexpr size_t PQGrainSize = 100000;
// auto_partitioner will automatically increase the blocksize if we have
// a lot of data. It is *important* for the last loop iterations
// (which have a very small dataset) that it is devisible.
constexpr size_t IndependentGrainSize = 1;
constexpr size_t ContractGrainSize = 1;
constexpr size_t NeighboursGrainSize = 1;
constexpr size_t DeleteGrainSize = 1;
constexpr size_t ContractGrainSize = 1;
constexpr size_t NeighboursGrainSize = 1;
constexpr size_t DeleteGrainSize = 1;
const NodeID number_of_nodes = contractor_graph->GetNumberOfNodes();
Percent p(number_of_nodes);
@@ -303,41 +314,59 @@ class Contractor
ThreadDataContainer thread_data_list(number_of_nodes);
NodeID number_of_contracted_nodes = 0;
std::vector<NodePriorityData> node_data;
std::vector<float> node_priorities;
is_core_node.resize(number_of_nodes, false);
std::vector<RemainingNodeData> remaining_nodes(number_of_nodes);
std::vector<float> node_priorities(number_of_nodes);
std::vector<NodePriorityData> node_data(number_of_nodes);
// initialize priorities in parallel
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, InitGrainSize),
[&remaining_nodes](const tbb::blocked_range<int>& range)
{
for (int x = range.begin(); x != range.end(); ++x)
{
remaining_nodes[x].id = x;
}
}
);
[this, &remaining_nodes](const tbb::blocked_range<int> &range)
{
for (int x = range.begin(), end = range.end(); x != end; ++x)
{
remaining_nodes[x].id = x;
}
});
std::cout << "initializing elimination PQ ..." << std::flush;
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, PQGrainSize),
[this, &node_priorities, &node_data, &thread_data_list](const tbb::blocked_range<int>& range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
for (int x = range.begin(); x != range.end(); ++x)
{
node_priorities[x] = this->EvaluateNodePriority(data, &node_data[x], x);
}
}
);
std::cout << "ok" << std::endl << "preprocessing " << number_of_nodes << " nodes ..."
<< std::flush;
bool flushed_contractor = false;
while (number_of_nodes > 2 && number_of_contracted_nodes < number_of_nodes)
bool use_cached_node_priorities = !node_levels.empty();
if (use_cached_node_priorities)
{
if (!flushed_contractor && (number_of_contracted_nodes > (number_of_nodes * 0.65)))
std::cout << "using cached node priorities ..." << std::flush;
node_priorities.swap(node_levels);
std::cout << "ok" << std::endl;
}
else
{
node_data.resize(number_of_nodes);
node_priorities.resize(number_of_nodes);
node_levels.resize(number_of_nodes);
std::cout << "initializing elimination PQ ..." << std::flush;
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, PQGrainSize),
[this, &node_priorities, &node_data, &thread_data_list](
const tbb::blocked_range<int> &range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
for (int x = range.begin(), end = range.end(); x != end; ++x)
{
node_priorities[x] =
this->EvaluateNodePriority(data, &node_data[x], x);
}
});
std::cout << "ok" << std::endl;
}
BOOST_ASSERT(node_priorities.size() == number_of_nodes);
std::cout << "preprocessing " << number_of_nodes << " nodes ..." << std::flush;
unsigned current_level = 0;
bool flushed_contractor = false;
while (number_of_nodes > 2 &&
number_of_contracted_nodes < static_cast<NodeID>(number_of_nodes * core_factor))
{
if (!flushed_contractor && (number_of_contracted_nodes >
static_cast<NodeID>(number_of_nodes * 0.65 * core_factor)))
{
DeallocatingVector<ContractorEdge> new_edge_set; // this one is not explicitely
// cleared since it goes out of
@@ -351,32 +380,37 @@ class Contractor
std::vector<float> new_node_priority(remaining_nodes.size());
// this map gives the old IDs from the new ones, necessary to get a consistent graph
// at the end of contraction
orig_node_id_to_new_id_map.resize(remaining_nodes.size());
orig_node_id_from_new_node_id_map.resize(remaining_nodes.size());
// this map gives the new IDs from the old ones, necessary to remap targets from the
// remaining graph
std::vector<NodeID> new_node_id_from_orig_id_map(number_of_nodes, UINT_MAX);
// build forward and backward renumbering map and remap ids in remaining_nodes and
// Priorities.
for (const auto new_node_id : osrm::irange<std::size_t>(0, remaining_nodes.size()))
{
auto& node = remaining_nodes[new_node_id];
BOOST_ASSERT(node_priorities.size() > node.id);
new_node_priority[new_node_id] = node_priorities[node.id];
}
// build forward and backward renumbering map and remap ids in remaining_nodes
for (const auto new_node_id : osrm::irange<std::size_t>(0, remaining_nodes.size()))
{
auto& node = remaining_nodes[new_node_id];
// create renumbering maps in both directions
orig_node_id_to_new_id_map[new_node_id] = remaining_nodes[new_node_id].id;
new_node_id_from_orig_id_map[remaining_nodes[new_node_id].id] = new_node_id;
new_node_priority[new_node_id] =
node_priorities[remaining_nodes[new_node_id].id];
remaining_nodes[new_node_id].id = new_node_id;
orig_node_id_from_new_node_id_map[new_node_id] = node.id;
new_node_id_from_orig_id_map[node.id] = new_node_id;
node.id = new_node_id;
}
// walk over all nodes
for (const auto i : osrm::irange<std::size_t>(0, contractor_graph->GetNumberOfNodes()))
for (const auto source :
osrm::irange<NodeID>(0, contractor_graph->GetNumberOfNodes()))
{
const NodeID source = i;
for (auto current_edge : contractor_graph->GetAdjacentEdgeRange(source))
{
ContractorGraph::EdgeData &data =
contractor_graph->GetEdgeData(current_edge);
const NodeID target = contractor_graph->GetTarget(current_edge);
if (SPECIAL_NODEID == new_node_id_from_orig_id_map[i])
if (SPECIAL_NODEID == new_node_id_from_orig_id_map[source])
{
external_edge_list.push_back({source, target, data});
}
@@ -384,11 +418,9 @@ class Contractor
{
// node is not yet contracted.
// add (renumbered) outgoing edges to new DynamicGraph.
ContractorEdge new_edge = {
new_node_id_from_orig_id_map[source],
new_node_id_from_orig_id_map[target],
data
};
ContractorEdge new_edge = {new_node_id_from_orig_id_map[source],
new_node_id_from_orig_id_map[target],
data};
new_edge.data.is_original_via_node_ID = true;
BOOST_ASSERT_MSG(UINT_MAX != new_node_id_from_orig_id_map[source],
@@ -413,7 +445,7 @@ class Contractor
contractor_graph.reset();
// create new graph
std::sort(new_edge_set.begin(), new_edge_set.end());
tbb::parallel_sort(new_edge_set.begin(), new_edge_set.end());
contractor_graph =
std::make_shared<ContractorGraph>(remaining_nodes.size(), new_edge_set);
@@ -425,66 +457,97 @@ class Contractor
thread_data_list.number_of_nodes = contractor_graph->GetNumberOfNodes();
}
const int last = (int)remaining_nodes.size();
tbb::parallel_for(tbb::blocked_range<int>(0, last, IndependentGrainSize),
[this, &node_priorities, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
// determine independent node set
for (int i = range.begin(); i != range.end(); ++i)
{
const NodeID node = remaining_nodes[i].id;
remaining_nodes[i].is_independent =
this->IsNodeIndependent(node_priorities, data, node);
}
}
);
tbb::parallel_for(tbb::blocked_range<std::size_t>(0, remaining_nodes.size(), IndependentGrainSize),
[this, &node_priorities, &remaining_nodes, &thread_data_list](
const tbb::blocked_range<std::size_t> &range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
// determine independent node set
for (auto i = range.begin(), end = range.end(); i != end; ++i)
{
const NodeID node = remaining_nodes[i].id;
remaining_nodes[i].is_independent =
this->IsNodeIndependent(node_priorities, data, node);
}
});
const auto first = stable_partition(remaining_nodes.begin(),
remaining_nodes.end(),
// sort all remaining nodes to the beginning of the sequence
const auto begin_independent_nodes = stable_partition(remaining_nodes.begin(), remaining_nodes.end(),
[](RemainingNodeData node_data)
{ return !node_data.is_independent; });
const int first_independent_node = static_cast<int>(first - remaining_nodes.begin());
{
return !node_data.is_independent;
});
auto begin_independent_nodes_idx = std::distance(remaining_nodes.begin(), begin_independent_nodes);
auto end_independent_nodes_idx = remaining_nodes.size();
if (!use_cached_node_priorities)
{
// write out contraction level
tbb::parallel_for(
tbb::blocked_range<std::size_t>(begin_independent_nodes_idx, end_independent_nodes_idx, ContractGrainSize),
[this, remaining_nodes, flushed_contractor, current_level](const tbb::blocked_range<std::size_t> &range)
{
if (flushed_contractor)
{
for (int position = range.begin(), end = range.end(); position != end; ++position)
{
const NodeID x = remaining_nodes[position].id;
node_levels[orig_node_id_from_new_node_id_map[x]] = current_level;
}
}
else
{
for (int position = range.begin(), end = range.end(); position != end; ++position)
{
const NodeID x = remaining_nodes[position].id;
node_levels[x] = current_level;
}
}
});
}
// contract independent nodes
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, ContractGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
tbb::parallel_for(
tbb::blocked_range<std::size_t>(begin_independent_nodes_idx, end_independent_nodes_idx, ContractGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<std::size_t> &range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(); position != range.end(); ++position)
for (int position = range.begin(), end = range.end(); position != end; ++position)
{
const NodeID x = remaining_nodes[position].id;
this->ContractNode<false>(data, x);
}
}
);
// make sure we really sort each block
tbb::parallel_for(thread_data_list.data.range(),
[&](const ThreadDataContainer::EnumerableThreadData::range_type& range)
{
for (auto& data : range)
std::sort(data->inserted_edges.begin(),
data->inserted_edges.end());
}
);
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, DeleteGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int>& range)
});
tbb::parallel_for(
tbb::blocked_range<int>(begin_independent_nodes_idx, end_independent_nodes_idx, DeleteGrainSize),
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int> &range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(); position != range.end(); ++position)
for (int position = range.begin(), end = range.end(); position != end; ++position)
{
const NodeID x = remaining_nodes[position].id;
this->DeleteIncomingEdges(data, x);
}
}
);
});
// make sure we really sort each block
tbb::parallel_for(
thread_data_list.data.range(),
[&](const ThreadDataContainer::EnumerableThreadData::range_type &range)
{
for (auto &data : range)
tbb::parallel_sort(data->inserted_edges.begin(),
data->inserted_edges.end());
});
// insert new edges
for (auto& data : thread_data_list.data)
for (auto &data : thread_data_list.data)
{
for (const ContractorEdge &edge : data->inserted_edges)
{
const EdgeID current_edge_ID = contractor_graph->FindEdge(edge.source, edge.target);
const EdgeID current_edge_ID =
contractor_graph->FindEdge(edge.source, edge.target);
if (current_edge_ID < contractor_graph->EndEdges(edge.source))
{
ContractorGraph::EdgeData &current_data =
@@ -503,29 +566,32 @@ class Contractor
data->inserted_edges.clear();
}
tbb::parallel_for(tbb::blocked_range<int>(first_independent_node, last, NeighboursGrainSize),
[this, &remaining_nodes, &node_priorities, &node_data, &thread_data_list](const tbb::blocked_range<int>& range)
{
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(); position != range.end(); ++position)
if (!use_cached_node_priorities)
{
tbb::parallel_for(
tbb::blocked_range<int>(begin_independent_nodes_idx, end_independent_nodes_idx, NeighboursGrainSize),
[this, &node_priorities, &remaining_nodes, &node_data, &thread_data_list](
const tbb::blocked_range<int> &range)
{
NodeID x = remaining_nodes[position].id;
this->UpdateNodeNeighbours(node_priorities, node_data, data, x);
}
}
);
ContractorThreadData *data = thread_data_list.getThreadData();
for (int position = range.begin(), end = range.end(); position != end; ++position)
{
NodeID x = remaining_nodes[position].id;
this->UpdateNodeNeighbours(node_priorities, node_data, data, x);
}
});
}
// remove contracted nodes from the pool
number_of_contracted_nodes += last - first_independent_node;
remaining_nodes.resize(first_independent_node);
remaining_nodes.shrink_to_fit();
number_of_contracted_nodes += end_independent_nodes_idx - begin_independent_nodes_idx;
remaining_nodes.resize(begin_independent_nodes_idx);
// unsigned maxdegree = 0;
// unsigned avgdegree = 0;
// unsigned mindegree = UINT_MAX;
// unsigned quaddegree = 0;
//
// for(unsigned i = 0; i < remaining_nodes.size(); ++i) {
// unsigned degree = contractor_graph->EndEdges(remaining_nodes[i].first)
// unsigned degree = contractor_graph->EndEdges(remaining_nodes[i].id)
// -
// contractor_graph->BeginEdges(remaining_nodes[i].first);
// if(degree > maxdegree)
@@ -545,11 +611,61 @@ class Contractor
// quad: " << quaddegree;
p.printStatus(number_of_contracted_nodes);
++current_level;
}
if (remaining_nodes.size() > 2)
{
if (orig_node_id_from_new_node_id_map.size() > 0)
{
tbb::parallel_for(
tbb::blocked_range<int>(0, remaining_nodes.size(), InitGrainSize),
[this, &remaining_nodes](const tbb::blocked_range<int> &range)
{
for (int x = range.begin(), end = range.end(); x != end; ++x)
{
const auto orig_id = remaining_nodes[x].id;
is_core_node[orig_node_id_from_new_node_id_map[orig_id]] = true;
}
});
}
else
{
tbb::parallel_for(
tbb::blocked_range<int>(0, remaining_nodes.size(), InitGrainSize),
[this, &remaining_nodes](const tbb::blocked_range<int> &range)
{
for (int x = range.begin(), end = range.end(); x != end; ++x)
{
const auto orig_id = remaining_nodes[x].id;
is_core_node[orig_id] = true;
}
});
}
}
else
{
// in this case we don't need core markers since we fully contracted
// the graph
is_core_node.clear();
}
SimpleLogger().Write() << "[core] " << remaining_nodes.size() << " nodes "
<< contractor_graph->GetNumberOfEdges() << " edges." << std::endl;
thread_data_list.data.clear();
}
inline void GetCoreMarker(std::vector<bool> &out_is_core_node)
{
out_is_core_node.swap(is_core_node);
}
inline void GetNodeLevels(std::vector<float> &out_node_levels)
{
out_node_levels.swap(node_levels);
}
template <class Edge> inline void GetEdges(DeallocatingVector<Edge> &edges)
{
Percent p(contractor_graph->GetNumberOfNodes());
@@ -565,10 +681,10 @@ class Contractor
{
const NodeID target = contractor_graph->GetTarget(edge);
const ContractorGraph::EdgeData &data = contractor_graph->GetEdgeData(edge);
if (!orig_node_id_to_new_id_map.empty())
if (!orig_node_id_from_new_node_id_map.empty())
{
new_edge.source = orig_node_id_to_new_id_map[node];
new_edge.target = orig_node_id_to_new_id_map[target];
new_edge.source = orig_node_id_from_new_node_id_map[node];
new_edge.target = orig_node_id_from_new_node_id_map[target];
}
else
{
@@ -579,9 +695,10 @@ class Contractor
BOOST_ASSERT_MSG(UINT_MAX != new_edge.target, "Target id invalid");
new_edge.data.distance = data.distance;
new_edge.data.shortcut = data.shortcut;
if (!data.is_original_via_node_ID && !orig_node_id_to_new_id_map.empty())
if (!data.is_original_via_node_ID && !orig_node_id_from_new_node_id_map.empty())
{
new_edge.data.id = orig_node_id_to_new_id_map[data.id];
// tranlate the _node id_ of the shortcutted node
new_edge.data.id = orig_node_id_from_new_node_id_map[data.id];
}
else
{
@@ -596,10 +713,10 @@ class Contractor
}
}
contractor_graph.reset();
orig_node_id_to_new_id_map.clear();
orig_node_id_to_new_id_map.shrink_to_fit();
orig_node_id_from_new_node_id_map.clear();
orig_node_id_from_new_node_id_map.shrink_to_fit();
BOOST_ASSERT(0 == orig_node_id_to_new_id_map.capacity());
BOOST_ASSERT(0 == orig_node_id_from_new_node_id_map.capacity());
edges.append(external_edge_list.begin(), external_edge_list.end());
external_edge_list.clear();
@@ -774,17 +891,11 @@ class Contractor
{
inserted_edges.emplace_back(source, target, path_distance,
out_data.originalEdges + in_data.originalEdges,
node,
true,
true,
false);
node, true, true, false);
inserted_edges.emplace_back(target, source, path_distance,
out_data.originalEdges + in_data.originalEdges,
node,
true,
false,
true);
node, true, false, true);
}
}
}
@@ -883,10 +994,9 @@ class Contractor
return true;
}
inline bool IsNodeIndependent(
const std::vector<float> &priorities,
ContractorThreadData *const data,
NodeID node) const
inline bool IsNodeIndependent(const std::vector<float> &priorities,
ContractorThreadData *const data,
NodeID node) const
{
const float priority = priorities[node];
@@ -963,9 +1073,10 @@ class Contractor
}
std::shared_ptr<ContractorGraph> contractor_graph;
std::vector<ContractorGraph::InputEdge> contracted_edge_list;
stxxl::vector<QueryEdge> external_edge_list;
std::vector<NodeID> orig_node_id_to_new_id_map;
std::vector<NodeID> orig_node_id_from_new_node_id_map;
std::vector<float> node_levels;
std::vector<bool> is_core_node;
XORFastHash fast_hash;
};
+142
View File
@@ -0,0 +1,142 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "contractor_options.hpp"
#include "util/version.hpp"
#include "../util/simple_logger.hpp"
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <tbb/task_scheduler_init.h>
return_code
ContractorOptions::ParseArguments(int argc, char *argv[], ContractorConfig &contractor_config)
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
"config,c", boost::program_options::value<boost::filesystem::path>(&contractor_config.config_file_path)
->default_value("contractor.ini"),
"Path to a configuration file.");
// declare a group of options that will be allowed both on command line and in config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()(
"profile,p",
boost::program_options::value<boost::filesystem::path>(&contractor_config.profile_path)
->default_value("profile.lua"),
"Path to LUA routing profile")(
"threads,t",
boost::program_options::value<unsigned int>(&contractor_config.requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use")(
"core,k", boost::program_options::value<double>(&contractor_config.core_factor)
->default_value(1.0),"Percentage of the graph (in vertices) to contract [0..1]")(
"segment-speed-file", boost::program_options::value<std::string>(&contractor_config.segment_speed_lookup_path),
"Lookup file containing nodeA,nodeB,speed data to adjust edge weights")(
"level-cache,o",
boost::program_options::value<bool>(&contractor_config.use_cached_priority)->default_value(false),
"Use .level file to retain the contaction level for each node from the last run.");
#ifdef DEBUG_GEOMETRY
config_options.add_options()(
"debug-geometry", boost::program_options::value<std::string>(&contractor_config.debug_geometry_path)
,"Write out edge-weight debugging geometry data in GeoJSON format to this file");
#endif
// hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"input,i", boost::program_options::value<boost::filesystem::path>(&contractor_config.osrm_input_path),
"Input file in .osm, .osm.bz2 or .osm.pbf format");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("input", 1);
// combine above options for parsing
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
boost::program_options::options_description config_file_options;
config_file_options.add(config_options).add(hidden_options);
boost::program_options::options_description visible_options(
"Usage: " + boost::filesystem::basename(argv[0]) + " <input.osrm> [options]");
visible_options.add(generic_options).add(config_options);
// parse command line options
boost::program_options::variables_map option_variables;
boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
.options(cmdline_options)
.positional(positional_options)
.run(),
option_variables);
const auto &temp_config_path = option_variables["config"].as<boost::filesystem::path>();
if (boost::filesystem::is_regular_file(temp_config_path))
{
boost::program_options::store(boost::program_options::parse_config_file<char>(
temp_config_path.string().c_str(), cmdline_options, true),
option_variables);
}
if (option_variables.count("version"))
{
SimpleLogger().Write() << OSRM_VERSION;
return return_code::exit;
}
if (option_variables.count("help"))
{
SimpleLogger().Write() << "\n" << visible_options;
return return_code::exit;
}
boost::program_options::notify(option_variables);
if (!option_variables.count("input"))
{
SimpleLogger().Write() << "\n" << visible_options;
return return_code::fail;
}
return return_code::ok;
}
void ContractorOptions::GenerateOutputFilesNames(ContractorConfig &contractor_config)
{
contractor_config.level_output_path = contractor_config.osrm_input_path.string() + ".level";
contractor_config.core_output_path = contractor_config.osrm_input_path.string() + ".core";
contractor_config.graph_output_path = contractor_config.osrm_input_path.string() + ".hsgr";
contractor_config.edge_based_graph_path = contractor_config.osrm_input_path.string() + ".ebg";
contractor_config.edge_segment_lookup_path = contractor_config.osrm_input_path.string() + ".edge_segment_lookup";
contractor_config.edge_penalty_path = contractor_config.osrm_input_path.string() + ".edge_penalties";
}
+81
View File
@@ -0,0 +1,81 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CONTRACTOR_OPTIONS_HPP
#define CONTRACTOR_OPTIONS_HPP
#include <boost/filesystem/path.hpp>
#include <string>
enum class return_code : unsigned
{
ok,
fail,
exit
};
struct ContractorConfig
{
ContractorConfig() noexcept : requested_num_threads(0) {}
boost::filesystem::path config_file_path;
boost::filesystem::path osrm_input_path;
boost::filesystem::path profile_path;
std::string level_output_path;
std::string core_output_path;
std::string graph_output_path;
std::string edge_based_graph_path;
std::string edge_segment_lookup_path;
std::string edge_penalty_path;
bool use_cached_priority;
unsigned requested_num_threads;
//A percentage of vertices that will be contracted for the hierarchy.
//Offers a trade-off between preprocessing and query time.
//The remaining vertices form the core of the hierarchy
//(e.g. 0.8 contracts 80 percent of the hierarchy, leaving a core of 20%)
double core_factor;
std::string segment_speed_lookup_path;
#ifdef DEBUG_GEOMETRY
std::string debug_geometry_path;
#endif
};
struct ContractorOptions
{
static return_code ParseArguments(int argc, char *argv[], ContractorConfig &extractor_config);
static void GenerateOutputFilesNames(ContractorConfig &extractor_config);
};
#endif // EXTRACTOR_OPTIONS_HPP
-796
View File
@@ -1,796 +0,0 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "edge_based_graph_factory.hpp"
#include "../algorithms/tiny_components.hpp"
#include "../data_structures/percent.hpp"
#include "../Util/compute_angle.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/lua_util.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/timing_util.hpp"
#include <boost/assert.hpp>
#include <fstream>
#include <iomanip>
#include <limits>
EdgeBasedGraphFactory::EdgeBasedGraphFactory(
const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
std::unique_ptr<RestrictionMap> restriction_map,
std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list,
std::vector<QueryNode> &node_info_list,
SpeedProfileProperties &speed_profile)
: speed_profile(speed_profile),
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
m_node_info_list(node_info_list), m_node_based_graph(node_based_graph),
m_restriction_map(std::move(restriction_map)), max_id(0), removed_node_count(0)
{
// insert into unordered sets for fast lookup
m_barrier_nodes.insert(barrier_node_list.begin(), barrier_node_list.end());
m_traffic_lights.insert(traffic_light_node_list.begin(), traffic_light_node_list.end());
}
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &output_edge_list)
{
BOOST_ASSERT_MSG(0 == output_edge_list.size(), "Vector is not empty");
m_edge_based_edge_list.swap(output_edge_list);
}
void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes)
{
#ifndef NDEBUG
for (const EdgeBasedNode &node : m_edge_based_node_list)
{
BOOST_ASSERT(m_node_info_list.at(node.u).lat != INT_MAX);
BOOST_ASSERT(m_node_info_list.at(node.u).lon != INT_MAX);
BOOST_ASSERT(m_node_info_list.at(node.v).lon != INT_MAX);
BOOST_ASSERT(m_node_info_list.at(node.v).lat != INT_MAX);
}
#endif
nodes.swap(m_edge_based_node_list);
}
void
EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u,
const NodeID node_v,
const unsigned component_id)
{
// merge edges together into one EdgeBasedNode
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
// find forward edge id and
const EdgeID e1 = m_node_based_graph->FindEdge(node_u, node_v);
BOOST_ASSERT(e1 != SPECIAL_EDGEID);
const EdgeData &forward_data = m_node_based_graph->GetEdgeData(e1);
// find reverse edge id and
const EdgeID e2 = m_node_based_graph->FindEdge(node_v, node_u);
#ifndef NDEBUG
if (e2 == m_node_based_graph->EndEdges(node_v))
{
SimpleLogger().Write(logWARNING) << "Did not find edge (" << node_v << "," << node_u << ")";
}
#endif
BOOST_ASSERT(e2 != SPECIAL_EDGEID);
BOOST_ASSERT(e2 < m_node_based_graph->EndEdges(node_v));
const EdgeData &reverse_data = m_node_based_graph->GetEdgeData(e2);
if (forward_data.edgeBasedNodeID == SPECIAL_NODEID &&
reverse_data.edgeBasedNodeID == SPECIAL_NODEID)
{
return;
}
BOOST_ASSERT(m_geometry_compressor.HasEntryForID(e1) ==
m_geometry_compressor.HasEntryForID(e2));
if (m_geometry_compressor.HasEntryForID(e1))
{
BOOST_ASSERT(m_geometry_compressor.HasEntryForID(e2));
// reconstruct geometry and put in each individual edge with its offset
const std::vector<GeometryCompressor::CompressedNode> &forward_geometry =
m_geometry_compressor.GetBucketReference(e1);
const std::vector<GeometryCompressor::CompressedNode> &reverse_geometry =
m_geometry_compressor.GetBucketReference(e2);
BOOST_ASSERT(forward_geometry.size() == reverse_geometry.size());
BOOST_ASSERT(0 != forward_geometry.size());
const unsigned geometry_size = static_cast<unsigned>(forward_geometry.size());
BOOST_ASSERT(geometry_size > 1);
// reconstruct bidirectional edge with individual weights and put each into the NN index
std::vector<int> forward_dist_prefix_sum(forward_geometry.size(), 0);
std::vector<int> reverse_dist_prefix_sum(reverse_geometry.size(), 0);
// quick'n'dirty prefix sum as std::partial_sum needs addtional casts
// TODO: move to lambda function with C++11
int temp_sum = 0;
for (const auto i : osrm::irange(0u, geometry_size))
{
forward_dist_prefix_sum[i] = temp_sum;
temp_sum += forward_geometry[i].second;
BOOST_ASSERT(forward_data.distance >= temp_sum);
}
temp_sum = 0;
for (const auto i : osrm::irange(0u, geometry_size))
{
temp_sum += reverse_geometry[reverse_geometry.size() - 1 - i].second;
reverse_dist_prefix_sum[i] = reverse_data.distance - temp_sum;
// BOOST_ASSERT(reverse_data.distance >= temp_sum);
}
NodeID current_edge_source_coordinate_id = node_u;
if (SPECIAL_NODEID != forward_data.edgeBasedNodeID)
{
max_id = std::max(forward_data.edgeBasedNodeID, max_id);
}
if (SPECIAL_NODEID != reverse_data.edgeBasedNodeID)
{
max_id = std::max(reverse_data.edgeBasedNodeID, max_id);
}
// traverse arrays from start and end respectively
for (const auto i : osrm::irange(0u, geometry_size))
{
BOOST_ASSERT(current_edge_source_coordinate_id ==
reverse_geometry[geometry_size - 1 - i].first);
const NodeID current_edge_target_coordinate_id = forward_geometry[i].first;
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
// build edges
m_edge_based_node_list.emplace_back(forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID,
current_edge_source_coordinate_id,
current_edge_target_coordinate_id,
forward_data.nameID,
forward_geometry[i].second,
reverse_geometry[geometry_size - 1 - i].second,
forward_dist_prefix_sum[i],
reverse_dist_prefix_sum[i],
m_geometry_compressor.GetPositionForID(e1),
component_id,
i,
forward_data.travel_mode,
reverse_data.travel_mode);
current_edge_source_coordinate_id = current_edge_target_coordinate_id;
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
BOOST_ASSERT(node_u != m_edge_based_node_list.back().u ||
node_v != m_edge_based_node_list.back().v);
BOOST_ASSERT(node_u != m_edge_based_node_list.back().v ||
node_v != m_edge_based_node_list.back().u);
}
BOOST_ASSERT(current_edge_source_coordinate_id == node_v);
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
}
else
{
BOOST_ASSERT(!m_geometry_compressor.HasEntryForID(e2));
if (forward_data.edgeBasedNodeID != SPECIAL_NODEID)
{
BOOST_ASSERT(forward_data.forward);
}
if (reverse_data.edgeBasedNodeID != SPECIAL_NODEID)
{
BOOST_ASSERT(reverse_data.forward);
}
if (forward_data.edgeBasedNodeID == SPECIAL_NODEID)
{
BOOST_ASSERT(!forward_data.forward);
}
if (reverse_data.edgeBasedNodeID == SPECIAL_NODEID)
{
BOOST_ASSERT(!reverse_data.forward);
}
BOOST_ASSERT(forward_data.edgeBasedNodeID != SPECIAL_NODEID ||
reverse_data.edgeBasedNodeID != SPECIAL_NODEID);
m_edge_based_node_list.emplace_back(forward_data.edgeBasedNodeID,
reverse_data.edgeBasedNodeID,
node_u,
node_v,
forward_data.nameID,
forward_data.distance,
reverse_data.distance,
0,
0,
SPECIAL_EDGEID,
component_id,
0,
forward_data.travel_mode,
reverse_data.travel_mode);
BOOST_ASSERT(!m_edge_based_node_list.back().IsCompressed());
}
}
void EdgeBasedGraphFactory::FlushVectorToStream(
std::ofstream &edge_data_file, std::vector<OriginalEdgeData> &original_edge_data_vector) const
{
if (original_edge_data_vector.empty()) {
return;
}
edge_data_file.write((char *)&(original_edge_data_vector[0]),
original_edge_data_vector.size() * sizeof(OriginalEdgeData));
original_edge_data_vector.clear();
}
void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
const std::string &geometry_filename,
lua_State *lua_state)
{
TIMER_START(geometry);
CompressGeometry();
TIMER_STOP(geometry);
TIMER_START(renumber);
RenumberEdges();
TIMER_STOP(renumber);
TIMER_START(generate_nodes);
GenerateEdgeExpandedNodes();
TIMER_STOP(generate_nodes);
TIMER_START(generate_edges);
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state);
TIMER_STOP(generate_edges);
m_geometry_compressor.SerializeInternalVector(geometry_filename);
SimpleLogger().Write() << "Timing statistics for edge-expanded graph:";
SimpleLogger().Write() << "Geometry compression: " << TIMER_SEC(geometry) << "s";
SimpleLogger().Write() << "Renumbering edges: " << TIMER_SEC(renumber) << "s";
SimpleLogger().Write() << "Generating nodes: " << TIMER_SEC(generate_nodes) << "s";
SimpleLogger().Write() << "Generating edges: " << TIMER_SEC(generate_edges) << "s";
}
void EdgeBasedGraphFactory::CompressGeometry()
{
SimpleLogger().Write() << "Removing graph geometry while preserving topology";
const unsigned original_number_of_nodes = m_node_based_graph->GetNumberOfNodes();
const unsigned original_number_of_edges = m_node_based_graph->GetNumberOfEdges();
Percent progress(original_number_of_nodes);
for (const NodeID node_v : osrm::irange(0u, original_number_of_nodes))
{
progress.printStatus(node_v);
// only contract degree 2 vertices
if (2 != m_node_based_graph->GetOutDegree(node_v))
{
continue;
}
// don't contract barrier node
if (m_barrier_nodes.end() != m_barrier_nodes.find(node_v))
{
continue;
}
// check if v is a via node for a turn restriction, i.e. a 'directed' barrier node
if (m_restriction_map->IsViaNode(node_v))
{
continue;
}
const bool reverse_edge_order =
!(m_node_based_graph->GetEdgeData(m_node_based_graph->BeginEdges(node_v)).forward);
const EdgeID forward_e2 = m_node_based_graph->BeginEdges(node_v) + reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != forward_e2);
const EdgeID reverse_e2 = m_node_based_graph->BeginEdges(node_v) + 1 - reverse_edge_order;
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e2);
const EdgeData &fwd_edge_data2 = m_node_based_graph->GetEdgeData(forward_e2);
const EdgeData &rev_edge_data2 = m_node_based_graph->GetEdgeData(reverse_e2);
const NodeID node_w = m_node_based_graph->GetTarget(forward_e2);
BOOST_ASSERT(SPECIAL_NODEID != node_w);
BOOST_ASSERT(node_v != node_w);
const NodeID node_u = m_node_based_graph->GetTarget(reverse_e2);
BOOST_ASSERT(SPECIAL_NODEID != node_u);
BOOST_ASSERT(node_u != node_v);
const EdgeID forward_e1 = m_node_based_graph->FindEdge(node_u, node_v);
BOOST_ASSERT(m_node_based_graph->EndEdges(node_u) != forward_e1);
BOOST_ASSERT(SPECIAL_EDGEID != forward_e1);
BOOST_ASSERT(node_v == m_node_based_graph->GetTarget(forward_e1));
const EdgeID reverse_e1 = m_node_based_graph->FindEdge(node_w, node_v);
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e1);
BOOST_ASSERT(node_v == m_node_based_graph->GetTarget(reverse_e1));
const EdgeData &fwd_edge_data1 = m_node_based_graph->GetEdgeData(forward_e1);
const EdgeData &rev_edge_data1 = m_node_based_graph->GetEdgeData(reverse_e1);
if ((m_node_based_graph->FindEdge(node_u, node_w) != m_node_based_graph->EndEdges(node_u)) ||
(m_node_based_graph->FindEdge(node_w, node_u) != m_node_based_graph->EndEdges(node_w)))
{
continue;
}
if ( // TODO: rename to IsCompatibleTo
fwd_edge_data1.IsEqualTo(fwd_edge_data2) &&
rev_edge_data1.IsEqualTo(rev_edge_data2))
{
// Get distances before graph is modified
const int forward_weight1 = m_node_based_graph->GetEdgeData(forward_e1).distance;
const int forward_weight2 = m_node_based_graph->GetEdgeData(forward_e2).distance;
BOOST_ASSERT(0 != forward_weight1);
BOOST_ASSERT(0 != forward_weight2);
const int reverse_weight1 = m_node_based_graph->GetEdgeData(reverse_e1).distance;
const int reverse_weight2 = m_node_based_graph->GetEdgeData(reverse_e2).distance;
BOOST_ASSERT(0 != reverse_weight1);
BOOST_ASSERT(0 != forward_weight2);
const bool add_traffic_signal_penalty =
(m_traffic_lights.find(node_v) != m_traffic_lights.end());
// add weight of e2's to e1
m_node_based_graph->GetEdgeData(forward_e1).distance += fwd_edge_data2.distance;
m_node_based_graph->GetEdgeData(reverse_e1).distance += rev_edge_data2.distance;
if (add_traffic_signal_penalty)
{
m_node_based_graph->GetEdgeData(forward_e1).distance +=
speed_profile.traffic_signal_penalty;
m_node_based_graph->GetEdgeData(reverse_e1).distance +=
speed_profile.traffic_signal_penalty;
}
// extend e1's to targets of e2's
m_node_based_graph->SetTarget(forward_e1, node_w);
m_node_based_graph->SetTarget(reverse_e1, node_u);
// remove e2's (if bidir, otherwise only one)
m_node_based_graph->DeleteEdge(node_v, forward_e2);
m_node_based_graph->DeleteEdge(node_v, reverse_e2);
// update any involved turn restrictions
m_restriction_map->FixupStartingTurnRestriction(node_u, node_v, node_w);
m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v,
node_w,
m_node_based_graph);
m_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u);
m_restriction_map->FixupArrivingTurnRestriction(node_w,
node_v,
node_u, m_node_based_graph);
// store compressed geometry in container
m_geometry_compressor.CompressEdge(
forward_e1,
forward_e2,
node_v,
node_w,
forward_weight1 +
(add_traffic_signal_penalty ? speed_profile.traffic_signal_penalty : 0),
forward_weight2);
m_geometry_compressor.CompressEdge(
reverse_e1,
reverse_e2,
node_v,
node_u,
reverse_weight1,
reverse_weight2 +
(add_traffic_signal_penalty ? speed_profile.traffic_signal_penalty : 0));
++removed_node_count;
BOOST_ASSERT(m_node_based_graph->GetEdgeData(forward_e1).nameID ==
m_node_based_graph->GetEdgeData(reverse_e1).nameID);
}
}
SimpleLogger().Write() << "removed " << removed_node_count << " nodes";
m_geometry_compressor.PrintStatistics();
unsigned new_node_count = 0;
unsigned new_edge_count = 0;
for(const auto i : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
if (m_node_based_graph->GetOutDegree(i) > 0)
{
++new_node_count;
new_edge_count += (m_node_based_graph->EndEdges(i) - m_node_based_graph->BeginEdges(i));
}
}
SimpleLogger().Write() << "new nodes: " << new_node_count << ", edges " << new_edge_count;
SimpleLogger().Write() << "Node compression ratio: " << new_node_count /
(double)original_number_of_nodes;
SimpleLogger().Write() << "Edge compression ratio: " << new_edge_count /
(double)original_number_of_edges;
}
/**
* Writes the id of the edge in the edge expanded graph (into the edge in the node based graph)
*/
void EdgeBasedGraphFactory::RenumberEdges()
{
// renumber edge based node IDs
unsigned numbered_edges_count = 0;
for (const auto current_node : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(current_node))
{
EdgeData &edge_data = m_node_based_graph->GetEdgeData(current_edge);
if (!edge_data.forward)
{
continue;
}
BOOST_ASSERT(numbered_edges_count < m_node_based_graph->GetNumberOfEdges());
edge_data.edgeBasedNodeID = numbered_edges_count;
++numbered_edges_count;
BOOST_ASSERT(SPECIAL_NODEID != edge_data.edgeBasedNodeID);
}
}
m_number_of_edge_based_nodes = numbered_edges_count;
}
/**
* Creates the nodes in the edge expanded graph from edges in the node-based graph.
*/
void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
{
SimpleLogger().Write() << "Identifying components of the (compressed) road network";
// Run a BFS on the undirected graph and identify small components
TarjanSCC<NodeBasedDynamicGraph> component_explorer(
m_node_based_graph, *m_restriction_map, m_barrier_nodes);
component_explorer.run();
SimpleLogger().Write() << "identified: " << component_explorer.get_number_of_components() - removed_node_count
<< " (compressed) components";
SimpleLogger().Write() << "identified " << component_explorer.get_size_one_count() - removed_node_count
<< " (compressed) SCCs of size 1";
SimpleLogger().Write() << "generating edge-expanded nodes";
Percent progress(m_node_based_graph->GetNumberOfNodes());
// loop over all edges and generate new set of nodes
for (const auto u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
BOOST_ASSERT(u != SPECIAL_NODEID);
BOOST_ASSERT(u < m_node_based_graph->GetNumberOfNodes());
progress.printStatus(u);
for (EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(u))
{
const EdgeData &edge_data = m_node_based_graph->GetEdgeData(e1);
BOOST_ASSERT(e1 != SPECIAL_EDGEID);
const NodeID v = m_node_based_graph->GetTarget(e1);
BOOST_ASSERT(SPECIAL_NODEID != v);
// pick only every other edge
if (u > v)
{
continue;
}
BOOST_ASSERT(u < v);
// Note: edges that end on barrier nodes or on a turn restriction
// may actually be in two distinct components. We choose the smallest
const unsigned size_of_component = std::min(component_explorer.get_component_size(u),
component_explorer.get_component_size(v));
const unsigned id_of_smaller_component = [u,v,&component_explorer] {
if (component_explorer.get_component_size(u) < component_explorer.get_component_size(v))
{
return component_explorer.get_component_id(u);
}
return component_explorer.get_component_id(v);
}();
const bool component_is_tiny = (size_of_component < 1000);
if (edge_data.edgeBasedNodeID == SPECIAL_NODEID)
{
InsertEdgeBasedNode(v, u, (component_is_tiny ? id_of_smaller_component + 1 : 0));
}
else
{
InsertEdgeBasedNode(u, v, (component_is_tiny ? id_of_smaller_component + 1 : 0));
}
}
}
SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size()
<< " nodes in edge-expanded graph";
}
/**
* Actually it also generates OriginalEdgeData and serializes them...
*/
void
EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
lua_State *lua_state)
{
SimpleLogger().Write() << "generating edge-expanded edges";
unsigned node_based_edge_counter = 0;
unsigned original_edges_counter = 0;
std::ofstream edge_data_file(original_edge_data_filename.c_str(), std::ios::binary);
// writes a dummy value that is updated later
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
std::vector<OriginalEdgeData> original_edge_data_vector;
original_edge_data_vector.reserve(1024 * 1024);
// Loop over all turns and generate new set of edges.
// Three nested loop look super-linear, but we are dealing with a (kind of)
// linear number of turns only.
unsigned restricted_turns_counter = 0;
unsigned skipped_uturns_counter = 0;
unsigned skipped_barrier_turns_counter = 0;
unsigned compressed = 0;
Percent progress(m_node_based_graph->GetNumberOfNodes());
for (const auto u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
{
progress.printStatus(u);
for (const EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(u))
{
if (!m_node_based_graph->GetEdgeData(e1).forward)
{
continue;
}
++node_based_edge_counter;
const NodeID v = m_node_based_graph->GetTarget(e1);
const NodeID to_node_of_only_restriction =
m_restriction_map->CheckForEmanatingIsOnlyTurn(u, v);
const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
for (const EdgeID e2 : m_node_based_graph->GetAdjacentEdgeRange(v))
{
if (!m_node_based_graph->GetEdgeData(e2).forward)
{
continue;
}
const NodeID w = m_node_based_graph->GetTarget(e2);
if ((to_node_of_only_restriction != SPECIAL_NODEID) &&
(w != to_node_of_only_restriction))
{
// We are at an only_-restriction but not at the right turn.
++restricted_turns_counter;
continue;
}
if (is_barrier_node)
{
if (u != w)
{
++skipped_barrier_turns_counter;
continue;
}
}
else
{
if ((u == w) && (m_node_based_graph->GetOutDegree(v) > 1))
{
++skipped_uturns_counter;
continue;
}
}
// only add an edge if turn is not a U-turn except when it is
// at the end of a dead-end street
if (m_restriction_map->CheckIfTurnIsRestricted(u, v, w) &&
(to_node_of_only_restriction == SPECIAL_NODEID) &&
(w != to_node_of_only_restriction))
{
// We are at an only_-restriction but not at the right turn.
++restricted_turns_counter;
continue;
}
// 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);
BOOST_ASSERT(edge_data1.edgeBasedNodeID != edge_data2.edgeBasedNodeID);
BOOST_ASSERT(edge_data1.forward);
BOOST_ASSERT(edge_data2.forward);
// the following is the core of the loop.
unsigned distance = edge_data1.distance;
if (m_traffic_lights.find(v) != m_traffic_lights.end())
{
distance += speed_profile.traffic_signal_penalty;
}
// unpack last node of first segment if packed
const auto first_coordinate = m_node_info_list[(m_geometry_compressor.HasEntryForID(e1) ?
m_geometry_compressor.GetLastNodeIDOfBucket(e1) :
u)];
// unpack first node of second segment if packed
const auto third_coordinate = m_node_info_list[(m_geometry_compressor.HasEntryForID(e2) ?
m_geometry_compressor.GetFirstNodeIDOfBucket(e2) :
w)];
const double turn_angle = ComputeAngle::OfThreeFixedPointCoordinates(
first_coordinate, m_node_info_list[v], third_coordinate);
const int turn_penalty = GetTurnPenalty(turn_angle, lua_state);
TurnInstruction turn_instruction = AnalyzeTurn(u, v, w, turn_angle);
if (turn_instruction == TurnInstruction::UTurn)
{
distance += speed_profile.u_turn_penalty;
}
distance += turn_penalty;
const bool edge_is_compressed = m_geometry_compressor.HasEntryForID(e1);
if (edge_is_compressed)
{
++compressed;
}
original_edge_data_vector.emplace_back(
(edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : v),
edge_data1.nameID,
turn_instruction,
edge_is_compressed,
edge_data2.travel_mode);
++original_edges_counter;
if (original_edge_data_vector.size() > 1024 * 1024 * 10)
{
FlushVectorToStream(edge_data_file, original_edge_data_vector);
}
BOOST_ASSERT(SPECIAL_NODEID != edge_data1.edgeBasedNodeID);
BOOST_ASSERT(SPECIAL_NODEID != edge_data2.edgeBasedNodeID);
m_edge_based_edge_list.emplace_back(EdgeBasedEdge(edge_data1.edgeBasedNodeID,
edge_data2.edgeBasedNodeID,
m_edge_based_edge_list.size(),
distance,
true,
false));
}
}
}
FlushVectorToStream(edge_data_file, original_edge_data_vector);
edge_data_file.seekp(std::ios::beg);
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
edge_data_file.close();
SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size() << " edge based nodes";
SimpleLogger().Write() << "Node-based graph contains " << node_based_edge_counter << " edges";
SimpleLogger().Write() << "Edge-expanded graph ...";
SimpleLogger().Write() << " contains " << m_edge_based_edge_list.size() << " edges";
SimpleLogger().Write() << " skips " << restricted_turns_counter << " turns, "
"defined by "
<< m_restriction_map->size() << " restrictions";
SimpleLogger().Write() << " skips " << skipped_uturns_counter << " U turns";
SimpleLogger().Write() << " skips " << skipped_barrier_turns_counter << " turns over barriers";
}
int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) const
{
if (speed_profile.has_turn_penalty_function)
{
try
{
// call lua profile to compute turn penalty
return luabind::call_function<int>(lua_state, "turn_function", 180. - angle);
}
catch (const luabind::error &er) { SimpleLogger().Write(logWARNING) << er.what(); }
}
return 0;
}
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID node_u,
const NodeID node_v,
const NodeID node_w,
const double angle)
const
{
if (node_u == node_w)
{
return TurnInstruction::UTurn;
}
const EdgeID edge1 = m_node_based_graph->FindEdge(node_u, node_v);
const EdgeID edge2 = m_node_based_graph->FindEdge(node_v, node_w);
const EdgeData &data1 = m_node_based_graph->GetEdgeData(edge1);
const EdgeData &data2 = m_node_based_graph->GetEdgeData(edge2);
// roundabouts need to be handled explicitely
if (data1.roundabout && data2.roundabout)
{
// Is a turn possible? If yes, we stay on the roundabout!
if (1 == m_node_based_graph->GetDirectedOutDegree(node_v))
{
// No turn possible.
return TurnInstruction::NoTurn;
}
return TurnInstruction::StayOnRoundAbout;
}
// Does turn start or end on roundabout?
if (data1.roundabout || data2.roundabout)
{
// We are entering the roundabout
if ((!data1.roundabout) && data2.roundabout)
{
return TurnInstruction::EnterRoundAbout;
}
// We are leaving the roundabout
if (data1.roundabout && (!data2.roundabout))
{
return TurnInstruction::LeaveRoundAbout;
}
}
// If street names stay the same and if we are certain that it is not a
// a segment of a roundabout, we skip it.
if (data1.nameID == data2.nameID)
{
// TODO: Here we should also do a small graph exploration to check for
// more complex situations
if (0 != data1.nameID || m_node_based_graph->GetOutDegree(node_v) <= 2)
{
return TurnInstruction::NoTurn;
}
}
return TurnInstructionsClass::GetTurnDirectionOfInstruction(angle);
}
unsigned EdgeBasedGraphFactory::GetNumberOfEdgeBasedNodes() const
{
return m_number_of_edge_based_nodes;
}
+277 -417
View File
@@ -26,29 +26,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "processing_chain.hpp"
#include "contractor.hpp"
#include "contractor.hpp"
#include "../algorithms/crc32_processor.hpp"
#include "../data_structures/deallocating_vector.hpp"
#include "../data_structures/static_rtree.hpp"
#include "../data_structures/restriction_map.hpp"
#include "../Util/git_sha.hpp"
#include "../Util/graph_loader.hpp"
#include "../Util/integer_range.hpp"
#include "../Util/lua_util.hpp"
#include "../Util/make_unique.hpp"
#include "../Util/osrm_exception.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/string_util.hpp"
#include "../Util/timing_util.hpp"
#include "../algorithms/crc32_processor.hpp"
#include "../util/graph_loader.hpp"
#include "../util/integer_range.hpp"
#include "../util/lua_util.hpp"
#include "../util/osrm_exception.hpp"
#include "../util/simple_logger.hpp"
#include "../util/string_util.hpp"
#include "../util/timing_util.hpp"
#include "../typedefs.h"
#include <fast-cpp-csv-parser/csv.h>
#include <boost/filesystem/fstream.hpp>
#include <boost/program_options.hpp>
#include <tbb/task_scheduler_init.h>
#include <tbb/parallel_sort.h>
#include <chrono>
@@ -57,169 +55,272 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <thread>
#include <vector>
Prepare::Prepare() : requested_num_threads(1) {}
#include "../util/debug_geometry.hpp"
Prepare::~Prepare() {}
int Prepare::Process(int argc, char *argv[])
int Prepare::Run()
{
LogPolicy::GetInstance().Unmute();
TIMER_START(preparing);
TIMER_START(expansion);
if (!ParseArguments(argc, argv))
{
return 0;
}
if (!boost::filesystem::is_regular_file(input_path))
{
SimpleLogger().Write(logWARNING) << "Input file " << input_path.string() << " not found!";
return 1;
}
if (!boost::filesystem::is_regular_file(profile_path))
{
SimpleLogger().Write(logWARNING) << "Profile " << profile_path.string() << " not found!";
return 1;
}
if (1 > requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return 1;
}
const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads();
SimpleLogger().Write() << "Input file: " << input_path.filename().string();
SimpleLogger().Write() << "Restrictions file: " << restrictions_path.filename().string();
SimpleLogger().Write() << "Profile: " << profile_path.filename().string();
SimpleLogger().Write() << "Threads: " << requested_num_threads;
if (recommended_num_threads != requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "The recommended number of threads is "
<< recommended_num_threads
<< "! This setting may have performance side-effects.";
}
tbb::task_scheduler_init init(requested_num_threads);
LogPolicy::GetInstance().Unmute();
FingerPrint fingerprint_orig;
CheckRestrictionsFile(fingerprint_orig);
boost::filesystem::ifstream input_stream(input_path, std::ios::in | std::ios::binary);
node_filename = input_path.string() + ".nodes";
edge_out = input_path.string() + ".edges";
geometry_filename = input_path.string() + ".geometry";
graph_out = input_path.string() + ".hsgr";
rtree_nodes_path = input_path.string() + ".ramIndex";
rtree_leafs_path = input_path.string() + ".fileIndex";
/*** Setup Scripting Environment ***/
// Create a new lua state
lua_State *lua_state = luaL_newstate();
// Connect LuaBind to this lua state
luabind::open(lua_state);
EdgeBasedGraphFactory::SpeedProfileProperties speed_profile;
if (!SetupScriptingEnvironment(lua_state, speed_profile))
{
return 1;
}
#ifdef WIN32
#pragma message("Memory consumption on Windows can be higher due to different bit packing")
#else
static_assert(sizeof(ImportEdge) == 20,
"changing ImportEdge type has influence on memory consumption!");
static_assert(sizeof(NodeBasedEdge) == 20,
"changing NodeBasedEdge type has influence on memory consumption!");
static_assert(sizeof(EdgeBasedEdge) == 16,
"changing EdgeBasedEdge type has influence on memory consumption!");
#endif
NodeID number_of_node_based_nodes =
readBinaryOSRMGraphFromStream(input_stream,
edge_list,
barrier_node_list,
traffic_light_list,
&internal_to_external_node_map,
restriction_list);
input_stream.close();
if (edge_list.empty())
if (config.core_factor > 1.0 || config.core_factor < 0)
{
SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
return 1;
throw osrm::exception("Core factor must be between 0.0 to 1.0 (inclusive)");
}
SimpleLogger().Write() << restriction_list.size() << " restrictions, "
<< barrier_node_list.size() << " bollard nodes, "
<< traffic_light_list.size() << " traffic lights";
TIMER_START(preparing);
// Create a new lua state
SimpleLogger().Write() << "Loading edge-expanded graph representation";
std::vector<EdgeBasedNode> node_based_edge_list;
unsigned number_of_edge_based_nodes = 0;
DeallocatingVector<EdgeBasedEdge> edge_based_edge_list;
// init node_based_edge_list, edge_based_edge_list by edgeList
number_of_edge_based_nodes = BuildEdgeExpandedGraph(lua_state,
number_of_node_based_nodes,
node_based_edge_list,
edge_based_edge_list,
speed_profile);
lua_close(lua_state);
size_t max_edge_id = LoadEdgeExpandedGraph(
config.edge_based_graph_path, edge_based_edge_list, config.edge_segment_lookup_path,
config.edge_penalty_path, config.segment_speed_lookup_path);
TIMER_STOP(expansion);
BuildRTree(node_based_edge_list);
RangebasedCRC32 crc32;
if (crc32.using_hardware())
{
SimpleLogger().Write() << "using hardware based CRC32 computation";
}
else
{
SimpleLogger().Write() << "using software based CRC32 computation";
}
const unsigned crc32_value = crc32(node_based_edge_list);
node_based_edge_list.clear();
node_based_edge_list.shrink_to_fit();
SimpleLogger().Write() << "CRC32: " << crc32_value;
WriteNodeMapping();
/***
* Contracting the edge-expanded graph
*/
SimpleLogger().Write() << "initializing contractor";
auto contractor =
osrm::make_unique<Contractor>(number_of_edge_based_nodes, edge_based_edge_list);
// Contracting the edge-expanded graph
TIMER_START(contraction);
contractor->Run();
std::vector<bool> is_core_node;
std::vector<float> node_levels;
if (config.use_cached_priority)
{
ReadNodeLevels(node_levels);
}
DeallocatingVector<QueryEdge> contracted_edge_list;
ContractGraph(max_edge_id, edge_based_edge_list, contracted_edge_list, is_core_node,
node_levels);
TIMER_STOP(contraction);
SimpleLogger().Write() << "Contraction took " << TIMER_SEC(contraction) << " sec";
DeallocatingVector<QueryEdge> contracted_edge_list;
contractor->GetEdges(contracted_edge_list);
contractor.reset();
std::size_t number_of_used_edges = WriteContractedGraph(max_edge_id, contracted_edge_list);
WriteCoreNodeMarker(std::move(is_core_node));
if (!config.use_cached_priority)
{
WriteNodeLevels(std::move(node_levels));
}
/***
* Sorting contracted edges in a way that the static query graph can read some in in-place.
*/
TIMER_STOP(preparing);
SimpleLogger().Write() << "Preprocessing : " << TIMER_SEC(preparing) << " seconds";
SimpleLogger().Write() << "Contraction: " << ((max_edge_id + 1) / TIMER_SEC(contraction))
<< " nodes/sec and " << number_of_used_edges / TIMER_SEC(contraction)
<< " edges/sec";
SimpleLogger().Write() << "finished preprocessing";
return 0;
}
namespace std
{
template <> struct hash<std::pair<OSMNodeID, OSMNodeID>>
{
std::size_t operator()(const std::pair<OSMNodeID, OSMNodeID> &k) const
{
return OSMNodeID_to_uint64_t(k.first) ^ (OSMNodeID_to_uint64_t(k.second) << 12);
}
};
}
std::size_t Prepare::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
const std::string &edge_segment_lookup_filename,
const std::string &edge_penalty_filename,
const std::string &segment_speed_filename)
{
SimpleLogger().Write() << "Opening " << edge_based_graph_filename;
boost::filesystem::ifstream input_stream(edge_based_graph_filename, std::ios::binary);
const bool update_edge_weights = segment_speed_filename != "";
boost::filesystem::ifstream edge_segment_input_stream;
boost::filesystem::ifstream edge_fixed_penalties_input_stream;
if (update_edge_weights)
{
edge_segment_input_stream.open(edge_segment_lookup_filename, std::ios::binary);
edge_fixed_penalties_input_stream.open(edge_penalty_filename, std::ios::binary);
if (!edge_segment_input_stream || !edge_fixed_penalties_input_stream)
{
throw osrm::exception("Could not load .edge_segment_lookup or .edge_penalties, did you "
"run osrm-extract with '--generate-edge-lookup'?");
}
}
const FingerPrint fingerprint_valid = FingerPrint::GetValid();
FingerPrint fingerprint_loaded;
input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
fingerprint_loaded.TestPrepare(fingerprint_valid);
size_t number_of_edges = 0;
size_t max_edge_id = SPECIAL_EDGEID;
input_stream.read((char *)&number_of_edges, sizeof(size_t));
input_stream.read((char *)&max_edge_id, sizeof(size_t));
edge_based_edge_list.resize(number_of_edges);
SimpleLogger().Write() << "Reading " << number_of_edges << " edges from the edge based graph";
std::unordered_map<std::pair<OSMNodeID, OSMNodeID>, unsigned> segment_speed_lookup;
if (update_edge_weights)
{
SimpleLogger().Write() << "Segment speed data supplied, will update edge weights from "
<< segment_speed_filename;
io::CSVReader<3> csv_in(segment_speed_filename);
csv_in.set_header("from_node", "to_node", "speed");
uint64_t from_node_id;
uint64_t to_node_id;
unsigned speed;
while (csv_in.read_row(from_node_id, to_node_id, speed))
{
segment_speed_lookup[std::make_pair(OSMNodeID(from_node_id), OSMNodeID(to_node_id))] = speed;
}
}
DEBUG_GEOMETRY_START(config);
// TODO: can we read this in bulk? DeallocatingVector isn't necessarily
// all stored contiguously
for (; number_of_edges > 0; --number_of_edges)
{
EdgeBasedEdge inbuffer;
input_stream.read((char *) &inbuffer, sizeof(EdgeBasedEdge));
if (update_edge_weights)
{
// Processing-time edge updates
unsigned fixed_penalty;
edge_fixed_penalties_input_stream.read(reinterpret_cast<char *>(&fixed_penalty),
sizeof(fixed_penalty));
int new_weight = 0;
unsigned num_osm_nodes = 0;
edge_segment_input_stream.read(reinterpret_cast<char *>(&num_osm_nodes),
sizeof(num_osm_nodes));
OSMNodeID previous_osm_node_id;
edge_segment_input_stream.read(reinterpret_cast<char *>(&previous_osm_node_id),
sizeof(previous_osm_node_id));
OSMNodeID this_osm_node_id;
double segment_length;
int segment_weight;
--num_osm_nodes;
for (; num_osm_nodes != 0; --num_osm_nodes)
{
edge_segment_input_stream.read(reinterpret_cast<char *>(&this_osm_node_id),
sizeof(this_osm_node_id));
edge_segment_input_stream.read(reinterpret_cast<char *>(&segment_length),
sizeof(segment_length));
edge_segment_input_stream.read(reinterpret_cast<char *>(&segment_weight),
sizeof(segment_weight));
auto speed_iter = segment_speed_lookup.find(
std::make_pair(previous_osm_node_id, this_osm_node_id));
if (speed_iter != segment_speed_lookup.end())
{
// This sets the segment weight using the same formula as the
// EdgeBasedGraphFactory for consistency. The *why* of this formula
// is lost in the annals of time.
int new_segment_weight =
std::max(1, static_cast<int>(std::floor(
(segment_length * 10.) / (speed_iter->second / 3.6) + .5)));
new_weight += new_segment_weight;
DEBUG_GEOMETRY_EDGE(
new_segment_weight,
segment_length,
previous_osm_node_id,
this_osm_node_id);
}
else
{
// If no lookup found, use the original weight value for this segment
new_weight += segment_weight;
DEBUG_GEOMETRY_EDGE(
segment_weight,
segment_length,
previous_osm_node_id,
this_osm_node_id);
}
previous_osm_node_id = this_osm_node_id;
}
inbuffer.weight = fixed_penalty + new_weight;
}
edge_based_edge_list.emplace_back(std::move(inbuffer));
}
DEBUG_GEOMETRY_STOP();
SimpleLogger().Write() << "Done reading edges";
return max_edge_id;
}
void Prepare::ReadNodeLevels(std::vector<float> &node_levels) const
{
boost::filesystem::ifstream order_input_stream(config.level_output_path, std::ios::binary);
unsigned level_size;
order_input_stream.read((char *)&level_size, sizeof(unsigned));
node_levels.resize(level_size);
order_input_stream.read((char *)node_levels.data(), sizeof(float) * node_levels.size());
}
void Prepare::WriteNodeLevels(std::vector<float> &&in_node_levels) const
{
std::vector<float> node_levels(std::move(in_node_levels));
boost::filesystem::ofstream order_output_stream(config.level_output_path, std::ios::binary);
unsigned level_size = node_levels.size();
order_output_stream.write((char *)&level_size, sizeof(unsigned));
order_output_stream.write((char *)node_levels.data(), sizeof(float) * node_levels.size());
}
void Prepare::WriteCoreNodeMarker(std::vector<bool> &&in_is_core_node) const
{
std::vector<bool> is_core_node(std::move(in_is_core_node));
std::vector<char> unpacked_bool_flags(std::move(is_core_node.size()));
for (auto i = 0u; i < is_core_node.size(); ++i)
{
unpacked_bool_flags[i] = is_core_node[i] ? 1 : 0;
}
boost::filesystem::ofstream core_marker_output_stream(config.core_output_path,
std::ios::binary);
unsigned size = unpacked_bool_flags.size();
core_marker_output_stream.write((char *)&size, sizeof(unsigned));
core_marker_output_stream.write((char *)unpacked_bool_flags.data(),
sizeof(char) * unpacked_bool_flags.size());
}
std::size_t Prepare::WriteContractedGraph(unsigned max_node_id,
const DeallocatingVector<QueryEdge> &contracted_edge_list)
{
// Sorting contracted edges in a way that the static query graph can read some in in-place.
tbb::parallel_sort(contracted_edge_list.begin(), contracted_edge_list.end());
const unsigned contracted_edge_count = contracted_edge_list.size();
SimpleLogger().Write() << "Serializing compacted graph of " << contracted_edge_count
<< " edges";
boost::filesystem::ofstream hsgr_output_stream(graph_out, std::ios::binary);
hsgr_output_stream.write((char *)&fingerprint_orig, sizeof(FingerPrint));
const unsigned max_used_node_id = 1 + [&contracted_edge_list]
const FingerPrint fingerprint = FingerPrint::GetValid();
boost::filesystem::ofstream hsgr_output_stream(config.graph_output_path, std::ios::binary);
hsgr_output_stream.write((char *)&fingerprint, sizeof(FingerPrint));
const unsigned max_used_node_id = [&contracted_edge_list]
{
unsigned tmp_max = 0;
for (const QueryEdge &edge : contracted_edge_list)
@@ -232,19 +333,20 @@ int Prepare::Process(int argc, char *argv[])
return tmp_max;
}();
SimpleLogger().Write(logDEBUG) << "input graph has " << number_of_edge_based_nodes << " nodes";
SimpleLogger().Write(logDEBUG) << "contracted graph has " << max_used_node_id << " nodes";
SimpleLogger().Write(logDEBUG) << "input graph has " << (max_node_id + 1) << " nodes";
SimpleLogger().Write(logDEBUG) << "contracted graph has " << (max_used_node_id + 1) << " nodes";
std::vector<StaticGraph<EdgeData>::NodeArrayEntry> node_array;
node_array.resize(number_of_edge_based_nodes + 1);
// make sure we have at least one sentinel
node_array.resize(max_node_id + 2);
SimpleLogger().Write() << "Building node array";
StaticGraph<EdgeData>::EdgeIterator edge = 0;
StaticGraph<EdgeData>::EdgeIterator position = 0;
StaticGraph<EdgeData>::EdgeIterator last_edge = edge;
StaticGraph<EdgeData>::EdgeIterator last_edge;
// initializing 'first_edge'-field of nodes:
for (const auto node : osrm::irange(0u, max_used_node_id))
for (const auto node : osrm::irange(0u, max_used_node_id + 1))
{
last_edge = edge;
while ((edge < contracted_edge_count) && (contracted_edge_list[edge].source == node))
@@ -255,7 +357,8 @@ int Prepare::Process(int argc, char *argv[])
position += edge - last_edge; // remove
}
for (const auto sentinel_counter : osrm::irange<unsigned>(max_used_node_id, node_array.size()))
for (const auto sentinel_counter :
osrm::irange<unsigned>(max_used_node_id + 1, node_array.size()))
{
// sentinel element, guarded against underflow
node_array[sentinel_counter].first_edge = contracted_edge_count;
@@ -263,9 +366,13 @@ int Prepare::Process(int argc, char *argv[])
SimpleLogger().Write() << "Serializing node array";
RangebasedCRC32 crc32_calculator;
const unsigned edges_crc32 = crc32_calculator(contracted_edge_list);
SimpleLogger().Write() << "Writing CRC32: " << edges_crc32;
const unsigned node_array_size = node_array.size();
// serialize crc32, aka checksum
hsgr_output_stream.write((char *)&crc32_value, sizeof(unsigned));
hsgr_output_stream.write((char *)&edges_crc32, sizeof(unsigned));
// serialize number of nodes
hsgr_output_stream.write((char *)&node_array_size, sizeof(unsigned));
// serialize number of edges
@@ -276,10 +383,9 @@ int Prepare::Process(int argc, char *argv[])
hsgr_output_stream.write((char *)&node_array[0],
sizeof(StaticGraph<EdgeData>::NodeArrayEntry) * node_array_size);
}
// serialize all edges
// serialize all edges
SimpleLogger().Write() << "Building edge array";
edge = 0;
int number_of_used_edges = 0;
StaticGraph<EdgeData>::EdgeArrayEntry current_edge;
@@ -291,7 +397,7 @@ int Prepare::Process(int argc, char *argv[])
current_edge.data = contracted_edge_list[edge].data;
// every target needs to be valid
BOOST_ASSERT(current_edge.target < max_used_node_id);
BOOST_ASSERT(current_edge.target <= max_used_node_id);
#ifndef NDEBUG
if (current_edge.data.distance <= 0)
{
@@ -311,271 +417,25 @@ int Prepare::Process(int argc, char *argv[])
++number_of_used_edges;
}
hsgr_output_stream.close();
TIMER_STOP(preparing);
SimpleLogger().Write() << "Preprocessing : " << TIMER_SEC(preparing) << " seconds";
SimpleLogger().Write() << "Expansion : " << (number_of_node_based_nodes / TIMER_SEC(expansion))
<< " nodes/sec and "
<< (number_of_edge_based_nodes / TIMER_SEC(expansion)) << " edges/sec";
SimpleLogger().Write() << "Contraction: "
<< (number_of_edge_based_nodes / TIMER_SEC(contraction))
<< " nodes/sec and " << number_of_used_edges / TIMER_SEC(contraction)
<< " edges/sec";
node_array.clear();
SimpleLogger().Write() << "finished preprocessing";
return 0;
return number_of_used_edges;
}
/**
\brief Parses command line arguments
\param argc count of arguments
\param argv array of arguments
\param result [out] value for exit return value
\return true if everything is ok, false if need to terminate execution
*/
bool Prepare::ParseArguments(int argc, char *argv[])
{
// declare a group of options that will be allowed only on command line
boost::program_options::options_description generic_options("Options");
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
"config,c",
boost::program_options::value<boost::filesystem::path>(&config_file_path)
->default_value("contractor.ini"),
"Path to a configuration file.");
// declare a group of options that will be allowed both on command line and in config file
boost::program_options::options_description config_options("Configuration");
config_options.add_options()(
"restrictions,r",
boost::program_options::value<boost::filesystem::path>(&restrictions_path),
"Restrictions file in .osrm.restrictions format")(
"profile,p",
boost::program_options::value<boost::filesystem::path>(&profile_path)
->default_value("profile.lua"),
"Path to LUA routing profile")(
"threads,t",
boost::program_options::value<unsigned int>(&requested_num_threads)
->default_value(tbb::task_scheduler_init::default_num_threads()),
"Number of threads to use");
// hidden options, will be allowed both on command line and in config file, but will not be
// shown to the user
boost::program_options::options_description hidden_options("Hidden options");
hidden_options.add_options()(
"input,i",
boost::program_options::value<boost::filesystem::path>(&input_path),
"Input file in .osm, .osm.bz2 or .osm.pbf format");
// positional option
boost::program_options::positional_options_description positional_options;
positional_options.add("input", 1);
// combine above options for parsing
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
boost::program_options::options_description config_file_options;
config_file_options.add(config_options).add(hidden_options);
boost::program_options::options_description visible_options(
"Usage: " + boost::filesystem::basename(argv[0]) + " <input.osrm> [options]");
visible_options.add(generic_options).add(config_options);
// parse command line options
boost::program_options::variables_map option_variables;
boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
.options(cmdline_options)
.positional(positional_options)
.run(),
option_variables);
const auto& temp_config_path = option_variables["config"].as<boost::filesystem::path>();
if (boost::filesystem::is_regular_file(temp_config_path))
{
boost::program_options::store(boost::program_options::parse_config_file<char>(temp_config_path.string().c_str(), cmdline_options, true),
option_variables);
}
if (option_variables.count("version"))
{
SimpleLogger().Write() << g_GIT_DESCRIPTION;
return false;
}
if (option_variables.count("help"))
{
SimpleLogger().Write() << "\n" << visible_options;
return false;
}
boost::program_options::notify(option_variables);
if (!option_variables.count("restrictions"))
{
restrictions_path = std::string(input_path.string() + ".restrictions");
}
if (!option_variables.count("input"))
{
SimpleLogger().Write() << "\n" << visible_options;
return false;
}
return true;
}
/**
\brief Loads and checks file UUIDs
*/
void Prepare::CheckRestrictionsFile(FingerPrint &fingerprint_orig)
{
boost::filesystem::ifstream restriction_stream(restrictions_path, std::ios::binary);
FingerPrint fingerprint_loaded;
unsigned number_of_usable_restrictions = 0;
restriction_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
if (!fingerprint_loaded.TestPrepare(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << ".restrictions was prepared with different build.\n"
"Reprocess to get rid of this warning.";
}
restriction_stream.read((char *)&number_of_usable_restrictions, sizeof(unsigned));
restriction_list.resize(number_of_usable_restrictions);
if (number_of_usable_restrictions > 0)
{
restriction_stream.read((char *)&(restriction_list[0]),
number_of_usable_restrictions * sizeof(TurnRestriction));
}
restriction_stream.close();
}
/**
\brief Setups scripting environment (lua-scripting)
Also initializes speed profile.
*/
bool
Prepare::SetupScriptingEnvironment(lua_State *lua_state,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
{
// open utility libraries string library;
luaL_openlibs(lua_state);
// adjust lua load path
luaAddScriptFolderToLoadPath(lua_state, profile_path.string().c_str());
// Now call our function in a lua script
if (0 != luaL_dofile(lua_state, profile_path.string().c_str()))
{
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
return false;
}
if (0 != luaL_dostring(lua_state, "return traffic_signal_penalty\n"))
{
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
return false;
}
speed_profile.traffic_signal_penalty = 10 * lua_tointeger(lua_state, -1);
SimpleLogger().Write(logDEBUG)
<< "traffic_signal_penalty: " << speed_profile.traffic_signal_penalty;
if (0 != luaL_dostring(lua_state, "return u_turn_penalty\n"))
{
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
return false;
}
speed_profile.u_turn_penalty = 10 * lua_tointeger(lua_state, -1);
speed_profile.has_turn_penalty_function = lua_function_exists(lua_state, "turn_function");
return true;
}
/**
\brief Building an edge-expanded graph from node-based input and turn restrictions
*/
std::size_t
Prepare::BuildEdgeExpandedGraph(lua_State *lua_state,
NodeID number_of_node_based_nodes,
std::vector<EdgeBasedNode> &node_based_edge_list,
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
{
SimpleLogger().Write() << "Generating edge-expanded graph representation";
std::shared_ptr<NodeBasedDynamicGraph> node_based_graph =
NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
std::unique_ptr<RestrictionMap> restriction_map = osrm::make_unique<RestrictionMap>(restriction_list);
std::shared_ptr<EdgeBasedGraphFactory> edge_based_graph_factory =
std::make_shared<EdgeBasedGraphFactory>(node_based_graph,
std::move(restriction_map),
barrier_node_list,
traffic_light_list,
internal_to_external_node_map,
speed_profile);
edge_list.clear();
edge_list.shrink_to_fit();
edge_based_graph_factory->Run(edge_out, geometry_filename, lua_state);
restriction_list.clear();
restriction_list.shrink_to_fit();
barrier_node_list.clear();
barrier_node_list.shrink_to_fit();
traffic_light_list.clear();
traffic_light_list.shrink_to_fit();
const std::size_t number_of_edge_based_nodes =
edge_based_graph_factory->GetNumberOfEdgeBasedNodes();
BOOST_ASSERT(number_of_edge_based_nodes != std::numeric_limits<unsigned>::max());
#ifndef WIN32
static_assert(sizeof(EdgeBasedEdge) == 16,
"changing ImportEdge type has influence on memory consumption!");
#endif
edge_based_graph_factory->GetEdgeBasedEdges(edge_based_edge_list);
edge_based_graph_factory->GetEdgeBasedNodes(node_based_edge_list);
edge_based_graph_factory.reset();
node_based_graph.reset();
return number_of_edge_based_nodes;
}
/**
\brief Writing info on original (node-based) nodes
\brief Build contracted graph.
*/
void Prepare::WriteNodeMapping()
void Prepare::ContractGraph(const unsigned max_edge_id,
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
DeallocatingVector<QueryEdge> &contracted_edge_list,
std::vector<bool> &is_core_node,
std::vector<float> &inout_node_levels) const
{
SimpleLogger().Write() << "writing node map ...";
boost::filesystem::ofstream node_stream(node_filename, std::ios::binary);
const unsigned size_of_mapping = internal_to_external_node_map.size();
node_stream.write((char *)&size_of_mapping, sizeof(unsigned));
if (size_of_mapping > 0)
{
node_stream.write((char *)&(internal_to_external_node_map[0]),
size_of_mapping * sizeof(QueryNode));
}
node_stream.close();
internal_to_external_node_map.clear();
internal_to_external_node_map.shrink_to_fit();
}
std::vector<float> node_levels;
node_levels.swap(inout_node_levels);
/**
\brief Building rtree-based nearest-neighbor data structure
Saves info to files: '.ramIndex' and '.fileIndex'.
*/
void Prepare::BuildRTree(std::vector<EdgeBasedNode> &node_based_edge_list)
{
SimpleLogger().Write() << "building r-tree ...";
StaticRTree<EdgeBasedNode>(node_based_edge_list,
rtree_nodes_path.c_str(),
rtree_leafs_path.c_str(),
internal_to_external_node_map);
Contractor contractor(max_edge_id + 1, edge_based_edge_list, std::move(node_levels));
contractor.Run(config.core_factor);
contractor.GetEdges(contracted_edge_list);
contractor.GetCoreMarker(is_core_node);
contractor.GetNodeLevels(inout_node_levels);
}
+26 -37
View File
@@ -28,11 +28,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PROCESSING_CHAIN_HPP
#define PROCESSING_CHAIN_HPP
#include "edge_based_graph_factory.hpp"
#include "contractor.hpp"
#include "contractor_options.hpp"
#include "../data_structures/query_edge.hpp"
#include "../data_structures/static_graph.hpp"
#include "../data_structures/deallocating_vector.hpp"
#include "../data_structures/node_based_graph.hpp"
class FingerPrint;
struct SpeedProfileProperties;
struct EdgeBasedNode;
struct lua_State;
@@ -47,49 +50,35 @@ class Prepare
{
public:
using EdgeData = QueryEdge::EdgeData;
using InputEdge = DynamicGraph<EdgeData>::InputEdge;
using StaticEdge = StaticGraph<EdgeData>::InputEdge;
explicit Prepare();
explicit Prepare(ContractorConfig contractor_config) : config(std::move(contractor_config)) {}
Prepare(const Prepare &) = delete;
~Prepare();
int Process(int argc, char *argv[]);
int Run();
protected:
bool ParseArguments(int argc, char *argv[]);
void CheckRestrictionsFile(FingerPrint &fingerprint_orig);
bool SetupScriptingEnvironment(lua_State *myLuaState,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile);
std::size_t BuildEdgeExpandedGraph(lua_State *myLuaState,
NodeID nodeBasedNodeNumber,
std::vector<EdgeBasedNode> &nodeBasedEdgeList,
DeallocatingVector<EdgeBasedEdge> &edgeBasedEdgeList,
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile);
void WriteNodeMapping();
void BuildRTree(std::vector<EdgeBasedNode> &node_based_edge_list);
void ContractGraph(const unsigned max_edge_id,
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
DeallocatingVector<QueryEdge> &contracted_edge_list,
std::vector<bool> &is_core_node,
std::vector<float> &node_levels) const;
void WriteCoreNodeMarker(std::vector<bool> &&is_core_node) const;
void WriteNodeLevels(std::vector<float> &&node_levels) const;
void ReadNodeLevels(std::vector<float> &contraction_order) const;
std::size_t WriteContractedGraph(unsigned number_of_edge_based_nodes,
const DeallocatingVector<QueryEdge> &contracted_edge_list);
void FindComponents(unsigned max_edge_id,
const DeallocatingVector<EdgeBasedEdge> &edges,
std::vector<EdgeBasedNode> &nodes) const;
private:
std::vector<QueryNode> internal_to_external_node_map;
std::vector<TurnRestriction> restriction_list;
std::vector<NodeID> barrier_node_list;
std::vector<NodeID> traffic_light_list;
std::vector<ImportEdge> edge_list;
unsigned requested_num_threads;
boost::filesystem::path config_file_path;
boost::filesystem::path input_path;
boost::filesystem::path restrictions_path;
boost::filesystem::path preinfo_path;
boost::filesystem::path profile_path;
std::string node_filename;
std::string edge_out;
std::string info_out;
std::string geometry_filename;
std::string graph_out;
std::string rtree_nodes_path;
std::string rtree_leafs_path;
ContractorConfig config;
std::size_t LoadEdgeExpandedGraph(const std::string &edge_based_graph_path,
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
const std::string &edge_segment_lookup_path,
const std::string &edge_penalty_path,
const std::string &segment_speed_path);
};
#endif // PROCESSING_CHAIN_HPP
-483
View File
@@ -1,483 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osrm/Coordinate.h>
#include "../Util/MercatorUtil.h"
#ifndef NDEBUG
#include "../Util/simple_logger.hpp"
#endif
#include "../Util/string_util.hpp"
#include <boost/assert.hpp>
#ifndef NDEBUG
#include <bitset>
#endif
#include <iostream>
#include <limits>
FixedPointCoordinate::FixedPointCoordinate()
: lat(std::numeric_limits<int>::min()), lon(std::numeric_limits<int>::min())
{
}
FixedPointCoordinate::FixedPointCoordinate(int lat, int lon) : lat(lat), lon(lon)
{
#ifndef NDEBUG
if (0 != (std::abs(lat) >> 30))
{
std::bitset<32> y_coordinate_vector(lat);
SimpleLogger().Write(logDEBUG) << "broken lat: " << lat
<< ", bits: " << y_coordinate_vector;
}
if (0 != (std::abs(lon) >> 30))
{
std::bitset<32> x_coordinate_vector(lon);
SimpleLogger().Write(logDEBUG) << "broken lon: " << lon
<< ", bits: " << x_coordinate_vector;
}
#endif
}
void FixedPointCoordinate::Reset()
{
lat = std::numeric_limits<int>::min();
lon = std::numeric_limits<int>::min();
}
bool FixedPointCoordinate::isSet() const
{
return (std::numeric_limits<int>::min() != lat) && (std::numeric_limits<int>::min() != lon);
}
bool FixedPointCoordinate::is_valid() const
{
if (lat > 90 * COORDINATE_PRECISION || lat < -90 * COORDINATE_PRECISION ||
lon > 180 * COORDINATE_PRECISION || lon < -180 * COORDINATE_PRECISION)
{
return false;
}
return true;
}
bool FixedPointCoordinate::operator==(const FixedPointCoordinate &other) const
{
return lat == other.lat && lon == other.lon;
}
double FixedPointCoordinate::ApproximateDistance(const int lat1,
const int lon1,
const int lat2,
const int lon2)
{
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
double RAD = 0.017453292519943295769236907684886;
double lt1 = lat1 / COORDINATE_PRECISION;
double ln1 = lon1 / COORDINATE_PRECISION;
double lt2 = lat2 / COORDINATE_PRECISION;
double ln2 = lon2 / COORDINATE_PRECISION;
double dlat1 = lt1 * (RAD);
double dlong1 = ln1 * (RAD);
double dlat2 = lt2 * (RAD);
double dlong2 = ln2 * (RAD);
double dLong = dlong1 - dlong2;
double dLat = dlat1 - dlat2;
double aHarv = pow(sin(dLat / 2.0), 2.0) + cos(dlat1) * cos(dlat2) * pow(sin(dLong / 2.), 2);
double cHarv = 2. * atan2(sqrt(aHarv), sqrt(1.0 - aHarv));
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
const double earth = 6372797.560856;
return earth * cHarv;
}
double FixedPointCoordinate::ApproximateDistance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return ApproximateDistance(
coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon);
}
float FixedPointCoordinate::ApproximateEuclideanDistance(const FixedPointCoordinate &coordinate_1,
const FixedPointCoordinate &coordinate_2)
{
return ApproximateEuclideanDistance(
coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon);
}
float FixedPointCoordinate::ApproximateEuclideanDistance(const int lat1,
const int lon1,
const int lat2,
const int lon2)
{
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
const float RAD = 0.017453292519943295769236907684886f;
const float float_lat1 = (lat1 / COORDINATE_PRECISION) * RAD;
const float float_lon1 = (lon1 / COORDINATE_PRECISION) * RAD;
const float float_lat2 = (lat2 / COORDINATE_PRECISION) * RAD;
const float float_lon2 = (lon2 / COORDINATE_PRECISION) * RAD;
const float x_value = (float_lon2 - float_lon1) * cos((float_lat1 + float_lat2) / 2.f);
const float y_value = float_lat2 - float_lat1;
const float earth_radius = 6372797.560856f;
return sqrt(x_value * x_value + y_value * y_value) * earth_radius;
}
float
FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &source_coordinate,
const FixedPointCoordinate &target_coordinate,
const FixedPointCoordinate &point)
{
// initialize values
const float x_value = static_cast<float>(lat2y(point.lat / COORDINATE_PRECISION));
const float y_value = point.lon / COORDINATE_PRECISION;
float a = static_cast<float>(lat2y(source_coordinate.lat / COORDINATE_PRECISION));
float b = source_coordinate.lon / COORDINATE_PRECISION;
float c = static_cast<float>(lat2y(target_coordinate.lat / COORDINATE_PRECISION));
float d = target_coordinate.lon / COORDINATE_PRECISION;
float p, q;
if (std::abs(a - c) > std::numeric_limits<float>::epsilon())
{
const float slope = (d - b) / (c - a); // slope
// Projection of (x,y) on line joining (a,b) and (c,d)
p = ((x_value + (slope * y_value)) + (slope * slope * a - slope * b)) /
(1.f + slope * slope);
q = b + slope * (p - a);
}
else
{
p = c;
q = y_value;
}
float ratio;
bool inverse_ratio = false;
// straight line segment on equator
if (std::abs(c) < std::numeric_limits<float>::epsilon() &&
std::abs(a) < std::numeric_limits<float>::epsilon())
{
ratio = (q - b) / (d - b);
}
else
{
if (std::abs(c) < std::numeric_limits<float>::epsilon())
{
// swap start/end
std::swap(a, c);
std::swap(b, d);
inverse_ratio = true;
}
float nY = (d * p - c * q) / (a * d - b * c);
// discretize the result to coordinate precision. it's a hack!
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
{
nY = 0.f;
}
// compute ratio
ratio = (p - nY * a) / c;
}
if (std::isnan(ratio))
{
ratio = (target_coordinate == point ? 1.f : 0.f);
}
else if (std::abs(ratio) <= std::numeric_limits<float>::epsilon())
{
ratio = 0.f;
}
else if (std::abs(ratio - 1.f) <= std::numeric_limits<float>::epsilon())
{
ratio = 1.f;
}
// we need to do this, if we switched start/end coordinates
if (inverse_ratio)
{
ratio = 1.0f - ratio;
}
// compute the nearest location
FixedPointCoordinate nearest_location;
BOOST_ASSERT(!std::isnan(ratio));
if (ratio <= 0.f)
{ // point is "left" of edge
nearest_location = source_coordinate;
}
else if (ratio >= 1.f)
{ // point is "right" of edge
nearest_location = target_coordinate;
}
else
{ // point lies in between
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.is_valid());
return FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location);
}
float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target,
const FixedPointCoordinate &query_location,
FixedPointCoordinate &nearest_location,
float &ratio)
{
BOOST_ASSERT(query_location.is_valid());
// initialize values
const double x = lat2y(query_location.lat / COORDINATE_PRECISION);
const double y = query_location.lon / COORDINATE_PRECISION;
const double a = lat2y(segment_source.lat / COORDINATE_PRECISION);
const double b = segment_source.lon / COORDINATE_PRECISION;
const double c = lat2y(segment_target.lat / COORDINATE_PRECISION);
const double d = segment_target.lon / COORDINATE_PRECISION;
double p, q /*,mX*/, nY;
if (std::abs(a - c) > std::numeric_limits<double>::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.f + m * m);
q = b + m * (p - a);
}
else
{
p = c;
q = y;
}
nY = (d * p - c * q) / (a * d - b * c);
// discretize the result to coordinate precision. it's a hack!
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
{
nY = 0.f;
}
// compute ratio
ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if (std::isnan(ratio))
{
ratio = (segment_target == query_location ? 1.f : 0.f);
}
else if (std::abs(ratio) <= std::numeric_limits<double>::epsilon())
{
ratio = 0.f;
}
else if (std::abs(ratio - 1.f) <= std::numeric_limits<double>::epsilon())
{
ratio = 1.f;
}
// compute nearest location
BOOST_ASSERT(!std::isnan(ratio));
if (ratio <= 0.f)
{
nearest_location = segment_source;
}
else if (ratio >= 1.f)
{
nearest_location = segment_target;
}
else
{
// point lies in between
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
}
BOOST_ASSERT(nearest_location.is_valid());
const float approximate_distance =
FixedPointCoordinate::ApproximateEuclideanDistance(query_location, nearest_location);
BOOST_ASSERT(0. <= approximate_distance);
return approximate_distance;
}
void FixedPointCoordinate::convertInternalLatLonToString(const int value, std::string &output)
{
char buffer[12];
buffer[11] = 0; // zero termination
output = printInt<11, 6>(buffer, value);
}
void FixedPointCoordinate::convertInternalCoordinateToString(const FixedPointCoordinate &coord,
std::string &output)
{
std::string tmp;
tmp.reserve(23);
convertInternalLatLonToString(coord.lon, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lat, tmp);
output += tmp;
}
void
FixedPointCoordinate::convertInternalReversedCoordinateToString(const FixedPointCoordinate &coord,
std::string &output)
{
std::string tmp;
tmp.reserve(23);
convertInternalLatLonToString(coord.lat, tmp);
output = tmp;
output += ",";
convertInternalLatLonToString(coord.lon, tmp);
output += tmp;
}
void FixedPointCoordinate::Output(std::ostream &out) const
{
out << "(" << lat / COORDINATE_PRECISION << "," << lon / COORDINATE_PRECISION << ")";
}
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &first_coordinate,
const FixedPointCoordinate &second_coordinate)
{
const float lon_diff =
second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION;
const float lon_delta = DegreeToRadian(lon_diff);
const float lat1 = DegreeToRadian(first_coordinate.lat / COORDINATE_PRECISION);
const float lat2 = DegreeToRadian(second_coordinate.lat / COORDINATE_PRECISION);
const float y = sin(lon_delta) * cos(lat2);
const float x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon_delta);
float result = RadianToDegree(std::atan2(y, x));
while (result < 0.f)
{
result += 360.f;
}
while (result >= 360.f)
{
result -= 360.f;
}
return result;
}
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &other) const
{
const float lon_delta =
DegreeToRadian(lon / COORDINATE_PRECISION - other.lon / COORDINATE_PRECISION);
const float lat1 = DegreeToRadian(other.lat / COORDINATE_PRECISION);
const float lat2 = DegreeToRadian(lat / COORDINATE_PRECISION);
const float y_value = std::sin(lon_delta) * std::cos(lat2);
const float x_value =
std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(lon_delta);
float result = RadianToDegree(std::atan2(y_value, x_value));
while (result < 0.f)
{
result += 360.f;
}
while (result >= 360.f)
{
result -= 360.f;
}
return result;
}
float FixedPointCoordinate::DegreeToRadian(const float degree)
{
return degree * (static_cast<float>(M_PI) / 180.f);
}
float FixedPointCoordinate::RadianToDegree(const float radian)
{
return radian * (180.f * static_cast<float>(M_1_PI));
}
// This distance computation does integer arithmetic only and is a lot faster than
// the other distance function which are numerically correct('ish).
// It preserves some order among the elements that make it useful for certain purposes
int FixedPointCoordinate::OrderedPerpendicularDistanceApproximation(
const FixedPointCoordinate &input_point,
const FixedPointCoordinate &segment_source,
const FixedPointCoordinate &segment_target)
{
// initialize values
const float x = static_cast<float>(lat2y(input_point.lat / COORDINATE_PRECISION));
const float y = input_point.lon / COORDINATE_PRECISION;
const float a = static_cast<float>(lat2y(segment_source.lat / COORDINATE_PRECISION));
const float b = segment_source.lon / COORDINATE_PRECISION;
const float c = static_cast<float>(lat2y(segment_target.lat / COORDINATE_PRECISION));
const float d = segment_target.lon / COORDINATE_PRECISION;
float p, q;
if (a == c)
{
p = c;
q = y;
}
else
{
const float 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.f + m * m);
q = b + m * (p - a);
}
const float nY = (d * p - c * q) / (a * d - b * c);
float ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need
// not calculate the explicit values of m an n as we
// are just interested in the ratio
if (std::isnan(ratio))
{
ratio = (segment_target == input_point) ? 1.f : 0.f;
}
// compute target quasi-location
int dx, dy;
if (ratio < 0.f)
{
dx = input_point.lon - segment_source.lon;
dy = input_point.lat - segment_source.lat;
}
else if (ratio > 1.f)
{
dx = input_point.lon - segment_target.lon;
dy = input_point.lat - segment_target.lat;
}
else
{
// point lies in between
dx = input_point.lon - static_cast<int>(q * COORDINATE_PRECISION);
dy = input_point.lat - static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
}
// return an approximation in the plane
return static_cast<int>(sqrt(dx * dx + dy * dy));
}
-123
View File
@@ -1,123 +0,0 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef INPUT_READER_FACTORY_H
#define INPUT_READER_FACTORY_H
#include <boost/assert.hpp>
#include <bzlib.h>
#include <libxml/xmlreader.h>
struct BZ2Context
{
FILE *file;
BZFILE *bz2;
int error;
int nUnused;
char unused[BZ_MAX_UNUSED];
};
int readFromBz2Stream(void *pointer, char *buffer, int len)
{
void *unusedTmpVoid = nullptr;
char *unusedTmp = nullptr;
BZ2Context *context = (BZ2Context *)pointer;
int read = 0;
while (0 == read &&
!(BZ_STREAM_END == context->error && 0 == context->nUnused && feof(context->file)))
{
read = BZ2_bzRead(&context->error, context->bz2, buffer, len);
if (BZ_OK == context->error)
{
return read;
}
else if (BZ_STREAM_END == context->error)
{
BZ2_bzReadGetUnused(&context->error, context->bz2, &unusedTmpVoid, &context->nUnused);
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadGetUnused");
unusedTmp = (char *)unusedTmpVoid;
for (int i = 0; i < context->nUnused; i++)
{
context->unused[i] = unusedTmp[i];
}
BZ2_bzReadClose(&context->error, context->bz2);
BOOST_ASSERT_MSG(BZ_OK == context->error, "Could not BZ2_bzReadClose");
context->error = BZ_STREAM_END; // set to the stream end for next call to this function
if (0 == context->nUnused && feof(context->file))
{
return read;
}
else
{
context->bz2 = BZ2_bzReadOpen(
&context->error, context->file, 0, 0, context->unused, context->nUnused);
BOOST_ASSERT_MSG(nullptr != context->bz2, "Could not open file");
}
}
else
{
BOOST_ASSERT_MSG(false, "Could not read bz2 file");
}
}
return read;
}
int closeBz2Stream(void *pointer)
{
BZ2Context *context = (BZ2Context *)pointer;
fclose(context->file);
delete context;
return 0;
}
xmlTextReaderPtr inputReaderFactory(const char *name)
{
std::string inputName(name);
if (inputName.find(".osm.bz2") != std::string::npos)
{
BZ2Context *context = new BZ2Context();
context->error = false;
context->file = fopen(name, "r");
int error;
context->bz2 =
BZ2_bzReadOpen(&error, context->file, 0, 0, context->unused, context->nUnused);
if (context->bz2 == nullptr || context->file == nullptr)
{
delete context;
return nullptr;
}
return xmlReaderForIO(readFromBz2Stream, closeBz2Stream, (void *)context, nullptr, nullptr, 0);
}
else
{
return xmlNewTextReaderFilename(name);
}
}
#endif // INPUT_READER_FACTORY_H
+47 -22
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -36,24 +36,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <type_traits>
#include <unordered_map>
#include <vector>
#include <cstring>
template <typename NodeID, typename Key> class ArrayStorage
{
public:
explicit ArrayStorage(size_t size) : positions(new Key[size])
{
memset(positions, 0, size * sizeof(Key));
}
explicit ArrayStorage(size_t size) : positions(size, 0) {}
~ArrayStorage() { delete[] positions; }
~ArrayStorage() {}
Key &operator[](NodeID node) { return positions[node]; }
Key peek_index(const NodeID node) const { return positions[node]; }
void Clear() {}
private:
Key *positions;
std::vector<Key> positions;
};
template <typename NodeID, typename Key> class MapStorage
@@ -65,6 +63,16 @@ template <typename NodeID, typename Key> class MapStorage
void Clear() { nodes.clear(); }
Key peek_index(const NodeID node) const
{
const auto iter = nodes.find(node);
if (nodes.end() != iter)
{
return iter->second;
}
return std::numeric_limits<Key>::max();
}
private:
std::map<NodeID, Key> nodes;
};
@@ -76,6 +84,16 @@ template <typename NodeID, typename Key> class UnorderedMapStorage
Key &operator[](const NodeID node) { return nodes[node]; }
Key peek_index(const NodeID node) const
{
const auto iter = nodes.find(node);
if (std::end(nodes) != iter)
{
return iter->second;
}
return std::numeric_limits<Key>::max();
}
Key const &operator[](const NodeID node) const
{
auto iter = nodes.find(node);
@@ -132,13 +150,13 @@ class BinaryHeap
Data &GetData(NodeID node)
{
const Key index = node_index[node];
const Key index = node_index.peek_index(node);
return inserted_nodes[index].data;
}
Data const &GetData(NodeID node) const
{
const Key index = node_index[node];
const Key index = node_index.peek_index(node);
return inserted_nodes[index].data;
}
@@ -148,17 +166,17 @@ class BinaryHeap
return inserted_nodes[index].weight;
}
bool WasRemoved(const NodeID node)
bool WasRemoved(const NodeID node) const
{
BOOST_ASSERT(WasInserted(node));
const Key index = node_index[node];
const Key index = node_index.peek_index(node);
return inserted_nodes[index].key == 0;
}
bool WasInserted(const NodeID node)
bool WasInserted(const NodeID node) const
{
const Key index = node_index[node];
if (index >= static_cast<Key>(inserted_nodes.size()))
const auto index = node_index.peek_index(node);
if (index >= static_cast<decltype(index)>(inserted_nodes.size()))
{
return false;
}
@@ -171,6 +189,11 @@ class BinaryHeap
return inserted_nodes[heap[1].index].node;
}
Weight MinKey() const {
BOOST_ASSERT(heap.size() > 1);
return heap[1].weight;
}
NodeID DeleteMin()
{
BOOST_ASSERT(heap.size() > 1);
@@ -189,7 +212,7 @@ class BinaryHeap
void DeleteAll()
{
auto iend = heap.end();
for (typename std::vector<HeapElement>::iterator i = heap.begin() + 1; i != iend; ++i)
for (auto i = heap.begin() + 1; i != iend; ++i)
{
inserted_nodes[i->index].key = 0;
}
@@ -200,7 +223,7 @@ class BinaryHeap
void DecreaseKey(NodeID node, Weight weight)
{
BOOST_ASSERT(std::numeric_limits<NodeID>::max() != node);
const Key &index = node_index[node];
const Key &index = node_index.peek_index(node);
Key &key = inserted_nodes[index].key;
BOOST_ASSERT(key >= 0);
@@ -214,7 +237,9 @@ class BinaryHeap
class HeapNode
{
public:
HeapNode(NodeID n, Key k, Weight w, Data d) : node(n), key(k), weight(w), data(d) {}
HeapNode(NodeID n, Key k, Weight w, Data d) : node(n), key(k), weight(w), data(std::move(d))
{
}
NodeID node;
Key key;
@@ -235,12 +260,12 @@ class BinaryHeap
{
const Key droppingIndex = heap[key].index;
const Weight weight = heap[key].weight;
const Key heap_size = static_cast<Key>(heap.size());
Key nextKey = key << 1;
while (nextKey < static_cast<Key>(heap.size()))
while (nextKey < heap_size)
{
const Key nextKeyOther = nextKey + 1;
if ((nextKeyOther < static_cast<Key>(heap.size())) &&
(heap[nextKey].weight > heap[nextKeyOther].weight))
if ((nextKeyOther < heap_size) && (heap[nextKey].weight > heap[nextKeyOther].weight))
{
nextKey = nextKeyOther;
}
@@ -279,7 +304,7 @@ class BinaryHeap
void CheckHeap()
{
#ifndef NDEBUG
for (Key i = 2; i < (Key)heap.size(); ++i)
for (std::size_t i = 2; i < heap.size(); ++i)
{
BOOST_ASSERT(heap[i].weight >= heap[i >> 1].weight);
}
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,8 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "geometry_compressor.hpp"
#include "../Util/simple_logger.hpp"
#include "compressed_edge_container.hpp"
#include "../util/simple_logger.hpp"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
@@ -35,16 +35,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits>
#include <string>
int free_list_maximum = 0;
int UniqueNumber() { return ++free_list_maximum; }
#include <iostream>
GeometryCompressor::GeometryCompressor()
CompressedEdgeContainer::CompressedEdgeContainer()
{
m_free_list.reserve(100);
IncreaseFreeList();
}
void GeometryCompressor::IncreaseFreeList()
void CompressedEdgeContainer::IncreaseFreeList()
{
m_compressed_geometries.resize(m_compressed_geometries.size() + 100);
for (unsigned i = 100; i > 0; --i)
@@ -54,13 +53,13 @@ void GeometryCompressor::IncreaseFreeList()
}
}
bool GeometryCompressor::HasEntryForID(const EdgeID edge_id) const
bool CompressedEdgeContainer::HasEntryForID(const EdgeID edge_id) const
{
auto iter = m_edge_id_to_list_index_map.find(edge_id);
return iter != m_edge_id_to_list_index_map.end();
}
unsigned GeometryCompressor::GetPositionForID(const EdgeID edge_id) const
unsigned CompressedEdgeContainer::GetPositionForID(const EdgeID edge_id) const
{
auto map_iterator = m_edge_id_to_list_index_map.find(edge_id);
BOOST_ASSERT(map_iterator != m_edge_id_to_list_index_map.end());
@@ -68,7 +67,7 @@ unsigned GeometryCompressor::GetPositionForID(const EdgeID edge_id) const
return map_iterator->second;
}
void GeometryCompressor::SerializeInternalVector(const std::string &path) const
void CompressedEdgeContainer::SerializeInternalVector(const std::string &path) const
{
boost::filesystem::fstream geometry_out_stream(path, std::ios::binary | std::ios::out);
@@ -111,7 +110,7 @@ void GeometryCompressor::SerializeInternalVector(const std::string &path) const
geometry_out_stream.close();
}
void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
void CompressedEdgeContainer::CompressEdge(const EdgeID edge_id_1,
const EdgeID edge_id_2,
const NodeID via_node_id,
const NodeID target_node_id,
@@ -156,6 +155,8 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
std::vector<CompressedNode> &edge_bucket_list1 = m_compressed_geometries[edge_bucket_id1];
// note we don't save the start coordinate: it is implicitly given by edge 1
// weight1 is the distance to the (currently) last coordinate in the bucket
if (edge_bucket_list1.empty())
{
edge_bucket_list1.emplace_back(via_node_id, weight1);
@@ -174,8 +175,8 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
m_compressed_geometries[list_to_remove_index];
// found an existing list, append it to the list of edge_id_1
edge_bucket_list1.insert(
edge_bucket_list1.end(), edge_bucket_list2.begin(), edge_bucket_list2.end());
edge_bucket_list1.insert(edge_bucket_list1.end(), edge_bucket_list2.begin(),
edge_bucket_list2.end());
// remove the list of edge_id_2
m_edge_id_to_list_index_map.erase(edge_id_2);
@@ -193,7 +194,7 @@ void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
}
}
void GeometryCompressor::PrintStatistics() const
void CompressedEdgeContainer::PrintStatistics() const
{
const uint64_t compressed_edges = m_compressed_geometries.size();
BOOST_ASSERT(0 == compressed_edges % 2);
@@ -211,31 +212,29 @@ void GeometryCompressor::PrintStatistics() const
"\n compressed edges: " << compressed_edges
<< "\n compressed geometries: " << compressed_geometries
<< "\n longest chain length: " << longest_chain_length
<< "\n cmpr ratio: "
<< ((float)compressed_edges /
std::max(compressed_geometries, (uint64_t)1))
<< "\n cmpr ratio: " << ((float)compressed_edges /
std::max(compressed_geometries, (uint64_t)1))
<< "\n avg chain length: "
<< (float)compressed_geometries /
std::max((uint64_t)1, compressed_edges);
}
const std::vector<GeometryCompressor::CompressedNode> &
GeometryCompressor::GetBucketReference(const EdgeID edge_id) const
const CompressedEdgeContainer::EdgeBucket&
CompressedEdgeContainer::GetBucketReference(const EdgeID edge_id) const
{
const unsigned index = m_edge_id_to_list_index_map.at(edge_id);
return m_compressed_geometries.at(index);
}
NodeID GeometryCompressor::GetFirstNodeIDOfBucket(const EdgeID edge_id) const
{
const auto &bucket = GetBucketReference(edge_id);
BOOST_ASSERT(bucket.size() >= 2);
return bucket[1].first;
}
NodeID GeometryCompressor::GetLastNodeIDOfBucket(const EdgeID edge_id) const
{
const auto &bucket = GetBucketReference(edge_id);
BOOST_ASSERT(bucket.size() >= 2);
return bucket[bucket.size()-2].first;
}
NodeID CompressedEdgeContainer::GetFirstEdgeTargetID(const EdgeID edge_id) const
{
const auto &bucket = GetBucketReference(edge_id);
BOOST_ASSERT(bucket.size() >= 2);
return bucket.front().first;
}
NodeID CompressedEdgeContainer::GetLastEdgeSourceID(const EdgeID edge_id) const
{
const auto &bucket = GetBucketReference(edge_id);
BOOST_ASSERT(bucket.size() >= 2);
return bucket[bucket.size() - 2].first;
}
@@ -35,12 +35,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
class GeometryCompressor
class CompressedEdgeContainer
{
public:
using CompressedNode = std::pair<NodeID, EdgeWeight>;
using EdgeBucket = std::vector<CompressedNode>;
GeometryCompressor();
CompressedEdgeContainer();
void CompressEdge(const EdgeID surviving_edge_id,
const EdgeID removed_edge_id,
const NodeID via_node_id,
@@ -52,14 +53,15 @@ class GeometryCompressor
void PrintStatistics() const;
void SerializeInternalVector(const std::string &path) const;
unsigned GetPositionForID(const EdgeID edge_id) const;
const std::vector<GeometryCompressor::CompressedNode> &
GetBucketReference(const EdgeID edge_id) const;
NodeID GetFirstNodeIDOfBucket(const EdgeID edge_id) const;
NodeID GetLastNodeIDOfBucket(const EdgeID edge_id) const;
const EdgeBucket& GetBucketReference(const EdgeID edge_id) const;
NodeID GetFirstEdgeTargetID(const EdgeID edge_id) const;
NodeID GetLastEdgeSourceID(const EdgeID edge_id) const;
private:
int free_list_maximum = 0;
void IncreaseFreeList();
std::vector<std::vector<CompressedNode>> m_compressed_geometries;
std::vector<EdgeBucket> m_compressed_geometries;
std::vector<unsigned> m_free_list;
std::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
};
-83
View File
@@ -1,83 +0,0 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CONCURRENT_QUEUE_HPP
#define CONCURRENT_QUEUE_HPP
#include <boost/circular_buffer.hpp>
#include <condition_variable>
#include <mutex>
template <typename Data> class ConcurrentQueue
{
public:
explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) {}
inline void push(const Data &data)
{
std::unique_lock<std::mutex> lock(m_mutex);
m_not_full.wait(lock,
[this]
{ return m_internal_queue.size() < m_internal_queue.capacity(); });
m_internal_queue.push_back(data);
m_not_empty.notify_one();
}
inline bool empty() const { return m_internal_queue.empty(); }
inline void wait_and_pop(Data &popped_value)
{
std::unique_lock<std::mutex> lock(m_mutex);
m_not_empty.wait(lock,
[this]
{ return !m_internal_queue.empty(); });
popped_value = m_internal_queue.front();
m_internal_queue.pop_front();
m_not_full.notify_one();
}
inline bool try_pop(Data &popped_value)
{
std::unique_lock<std::mutex> lock(m_mutex);
if (m_internal_queue.empty())
{
return false;
}
popped_value = m_internal_queue.front();
m_internal_queue.pop_front();
m_not_full.notify_one();
return true;
}
private:
boost::circular_buffer<Data> m_internal_queue;
std::mutex m_mutex;
std::condition_variable m_not_empty;
std::condition_variable m_not_full;
};
#endif // CONCURRENT_QUEUE_HPP
+87
View File
@@ -0,0 +1,87 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "../algorithms/coordinate_calculation.hpp"
#ifndef NDEBUG
#include "../util/simple_logger.hpp"
#endif
#include <osrm/coordinate.hpp>
#ifndef NDEBUG
#include <bitset>
#endif
#include <iostream>
#include <limits>
FixedPointCoordinate::FixedPointCoordinate()
: lat(std::numeric_limits<int>::min()), lon(std::numeric_limits<int>::min())
{
}
FixedPointCoordinate::FixedPointCoordinate(int lat, int lon) : lat(lat), lon(lon)
{
#ifndef NDEBUG
if (0 != (std::abs(lat) >> 30))
{
std::bitset<32> y_coordinate_vector(lat);
SimpleLogger().Write(logDEBUG) << "broken lat: " << lat
<< ", bits: " << y_coordinate_vector;
}
if (0 != (std::abs(lon) >> 30))
{
std::bitset<32> x_coordinate_vector(lon);
SimpleLogger().Write(logDEBUG) << "broken lon: " << lon
<< ", bits: " << x_coordinate_vector;
}
#endif
}
bool FixedPointCoordinate::is_valid() const
{
if (lat > 90 * COORDINATE_PRECISION || lat < -90 * COORDINATE_PRECISION ||
lon > 180 * COORDINATE_PRECISION || lon < -180 * COORDINATE_PRECISION)
{
return false;
}
return true;
}
bool FixedPointCoordinate::operator==(const FixedPointCoordinate &other) const
{
return lat == other.lat && lon == other.lon;
}
void FixedPointCoordinate::output(std::ostream &out) const
{
out << "(" << lat / COORDINATE_PRECISION << "," << lon / COORDINATE_PRECISION << ")";
}
float FixedPointCoordinate::bearing(const FixedPointCoordinate &other) const
{
return coordinate_calculation::bearing(other, *this);
}
+128 -38
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,19 +25,49 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DEALLOCATINGVECTOR_H_
#define DEALLOCATINGVECTOR_H_
#ifndef DEALLOCATING_VECTOR_HPP
#define DEALLOCATING_VECTOR_HPP
#include "../Util/integer_range.hpp"
#include "../util/integer_range.hpp"
#include <boost/iterator/iterator_facade.hpp>
#include <limits>
#include <utility>
#include <vector>
template <typename ElementT> struct ConstDeallocatingVectorIteratorState
{
ConstDeallocatingVectorIteratorState()
: index(std::numeric_limits<std::size_t>::max()), bucket_list(nullptr)
{
}
explicit ConstDeallocatingVectorIteratorState(const ConstDeallocatingVectorIteratorState &r)
: index(r.index), bucket_list(r.bucket_list)
{
}
explicit ConstDeallocatingVectorIteratorState(const std::size_t idx,
const std::vector<ElementT *> *input_list)
: index(idx), bucket_list(input_list)
{
}
std::size_t index;
const std::vector<ElementT *> *bucket_list;
ConstDeallocatingVectorIteratorState &operator=(const ConstDeallocatingVectorIteratorState &other)
{
index = other.index;
bucket_list = other.bucket_list;
return *this;
}
};
template <typename ElementT> struct DeallocatingVectorIteratorState
{
DeallocatingVectorIteratorState() : index(-1), bucket_list(nullptr) {}
DeallocatingVectorIteratorState()
: index(std::numeric_limits<std::size_t>::max()), bucket_list(nullptr)
{
}
explicit DeallocatingVectorIteratorState(const DeallocatingVectorIteratorState &r)
: index(r.index), bucket_list(r.bucket_list)
{
@@ -50,7 +80,7 @@ template <typename ElementT> struct DeallocatingVectorIteratorState
std::size_t index;
std::vector<ElementT *> *bucket_list;
inline DeallocatingVectorIteratorState &operator=(const DeallocatingVectorIteratorState &other)
DeallocatingVectorIteratorState &operator=(const DeallocatingVectorIteratorState &other)
{
index = other.index;
bucket_list = other.bucket_list;
@@ -58,6 +88,55 @@ template <typename ElementT> struct DeallocatingVectorIteratorState
}
};
template <typename ElementT, std::size_t ELEMENTS_PER_BLOCK>
class ConstDeallocatingVectorIterator
: public boost::iterator_facade<ConstDeallocatingVectorIterator<ElementT, ELEMENTS_PER_BLOCK>,
ElementT,
std::random_access_iterator_tag>
{
ConstDeallocatingVectorIteratorState<ElementT> current_state;
public:
ConstDeallocatingVectorIterator() {}
ConstDeallocatingVectorIterator(std::size_t idx, const std::vector<ElementT *> *input_list)
: current_state(idx, input_list)
{
}
friend class boost::iterator_core_access;
void advance(std::size_t n) { current_state.index += n; }
void increment() { advance(1); }
void decrement() { advance(-1); }
bool equal(ConstDeallocatingVectorIterator const &other) const
{
return current_state.index == other.current_state.index;
}
std::ptrdiff_t distance_to(ConstDeallocatingVectorIterator const &other) const
{
// it is important to implement it 'other minus this'. otherwise sorting breaks
return other.current_state.index - current_state.index;
}
ElementT &dereference() const
{
const std::size_t current_bucket = current_state.index / ELEMENTS_PER_BLOCK;
const std::size_t current_index = current_state.index % ELEMENTS_PER_BLOCK;
return (current_state.bucket_list->at(current_bucket)[current_index]);
}
ElementT &operator[](const std::size_t index) const
{
const std::size_t current_bucket = (index + current_state.index) / ELEMENTS_PER_BLOCK;
const std::size_t current_index = (index + current_state.index) % ELEMENTS_PER_BLOCK;
return (current_state.bucket_list->at(current_bucket)[current_index]);
}
};
template <typename ElementT, std::size_t ELEMENTS_PER_BLOCK>
class DeallocatingVectorIterator
: public boost::iterator_facade<DeallocatingVectorIterator<ElementT, ELEMENTS_PER_BLOCK>,
@@ -158,6 +237,12 @@ class DeallocatingVectorRemoveIterator
}
};
template <typename ElementT, std::size_t ELEMENTS_PER_BLOCK>
class DeallocatingVector;
template<typename T, std::size_t S>
void swap(DeallocatingVector<T, S>& lhs, DeallocatingVector<T, S>& rhs);
template <typename ElementT, std::size_t ELEMENTS_PER_BLOCK = 8388608 / sizeof(ElementT)>
class DeallocatingVector
{
@@ -166,22 +251,27 @@ class DeallocatingVector
public:
using iterator = DeallocatingVectorIterator<ElementT, ELEMENTS_PER_BLOCK>;
using const_iterator = DeallocatingVectorIterator<ElementT, ELEMENTS_PER_BLOCK>;
using const_iterator = ConstDeallocatingVectorIterator<ElementT, ELEMENTS_PER_BLOCK>;
// this forward-only iterator deallocates all buckets that have been visited
using deallocation_iterator = DeallocatingVectorRemoveIterator<ElementT, ELEMENTS_PER_BLOCK>;
DeallocatingVector() : current_size(0) { bucket_list.emplace_back(new ElementT[ELEMENTS_PER_BLOCK]); }
DeallocatingVector() : current_size(0)
{
bucket_list.emplace_back(new ElementT[ELEMENTS_PER_BLOCK]);
}
~DeallocatingVector() { clear(); }
inline void swap(DeallocatingVector<ElementT, ELEMENTS_PER_BLOCK> &other)
friend void swap<>(DeallocatingVector<ElementT, ELEMENTS_PER_BLOCK>& lhs, DeallocatingVector<ElementT, ELEMENTS_PER_BLOCK>& rhs);
void swap(DeallocatingVector<ElementT, ELEMENTS_PER_BLOCK> &other)
{
std::swap(current_size, other.current_size);
bucket_list.swap(other.bucket_list);
}
inline void clear()
void clear()
{
// Delete[]'ing ptr's to all Buckets
for (auto bucket : bucket_list)
@@ -192,11 +282,12 @@ class DeallocatingVector
bucket = nullptr;
}
}
bucket_list.clear(); bucket_list.shrink_to_fit();
bucket_list.clear();
bucket_list.shrink_to_fit();
current_size = 0;
}
inline void push_back(const ElementT &element)
void push_back(const ElementT &element)
{
const std::size_t current_capacity = capacity();
if (current_size == current_capacity)
@@ -209,7 +300,7 @@ class DeallocatingVector
++current_size;
}
template <typename... Ts> inline void emplace_back(Ts &&... element)
template <typename... Ts> void emplace_back(Ts &&... element)
{
const std::size_t current_capacity = capacity();
if (current_size == current_capacity)
@@ -222,9 +313,9 @@ class DeallocatingVector
++current_size;
}
inline void reserve(const std::size_t) const { /* don't do anything */ }
void reserve(const std::size_t) const { /* don't do anything */}
inline void resize(const std::size_t new_size)
void resize(const std::size_t new_size)
{
if (new_size >= current_size)
{
@@ -234,9 +325,10 @@ class DeallocatingVector
}
}
else
{ // down-size
{ // down-size
const std::size_t number_of_necessary_buckets = 1 + (new_size / ELEMENTS_PER_BLOCK);
for (const auto bucket_index : osrm::irange(number_of_necessary_buckets, bucket_list.size()))
for (const auto bucket_index :
osrm::irange(number_of_necessary_buckets, bucket_list.size()))
{
if (nullptr != bucket_list[bucket_index])
{
@@ -248,58 +340,50 @@ class DeallocatingVector
current_size = new_size;
}
inline std::size_t size() const { return current_size; }
std::size_t size() const { return current_size; }
inline std::size_t capacity() const { return bucket_list.size() * ELEMENTS_PER_BLOCK; }
std::size_t capacity() const { return bucket_list.size() * ELEMENTS_PER_BLOCK; }
inline iterator begin() { return iterator(static_cast<std::size_t>(0), &bucket_list); }
iterator begin() { return iterator(static_cast<std::size_t>(0), &bucket_list); }
inline iterator end() { return iterator(size(), &bucket_list); }
iterator end() { return iterator(size(), &bucket_list); }
inline deallocation_iterator dbegin()
deallocation_iterator dbegin()
{
return deallocation_iterator(static_cast<std::size_t>(0), &bucket_list);
}
inline deallocation_iterator dend() { return deallocation_iterator(size(), &bucket_list); }
deallocation_iterator dend() { return deallocation_iterator(size(), &bucket_list); }
inline const_iterator begin() const
const_iterator begin() const
{
return const_iterator(static_cast<std::size_t>(0), &bucket_list);
}
inline const_iterator end() const { return const_iterator(size(), &bucket_list); }
const_iterator end() const { return const_iterator(size(), &bucket_list); }
inline ElementT &operator[](const std::size_t index)
ElementT &operator[](const std::size_t index)
{
const std::size_t _bucket = index / ELEMENTS_PER_BLOCK;
const std::size_t _index = index % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
const inline ElementT &operator[](const std::size_t index) const
ElementT &operator[](const std::size_t index) const
{
const std::size_t _bucket = index / ELEMENTS_PER_BLOCK;
const std::size_t _index = index % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
inline ElementT &back()
ElementT &back() const
{
const std::size_t _bucket = current_size / ELEMENTS_PER_BLOCK;
const std::size_t _index = current_size % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
const inline ElementT &back() const
{
const std::size_t _bucket = current_size / ELEMENTS_PER_BLOCK;
const std::size_t _index = current_size % ELEMENTS_PER_BLOCK;
return (bucket_list[_bucket][_index]);
}
template<class InputIterator>
const inline void append(InputIterator first, const InputIterator last)
template <class InputIterator> void append(InputIterator first, const InputIterator last)
{
InputIterator position = first;
while (position != last)
@@ -310,4 +394,10 @@ class DeallocatingVector
}
};
#endif /* DEALLOCATINGVECTOR_H_ */
template<typename T, std::size_t S>
void swap(DeallocatingVector<T, S>& lhs, DeallocatingVector<T, S>& rhs)
{
lhs.swap(rhs);
}
#endif /* DEALLOCATING_VECTOR_HPP */
+98 -48
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -29,16 +29,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define DYNAMICGRAPH_HPP
#include "deallocating_vector.hpp"
#include "../Util/integer_range.hpp"
#include "../util/integer_range.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <cstdint>
#include <algorithm>
#include <limits>
#include <vector>
#include <atomic>
#include <limits>
#include <tuple>
#include <vector>
template <typename EdgeDataT> class DynamicGraph
{
@@ -55,60 +57,69 @@ template <typename EdgeDataT> class DynamicGraph
NodeIterator target;
EdgeDataT data;
InputEdge() : source(std::numeric_limits<NodeIterator>::max()), target(std::numeric_limits<NodeIterator>::max()) { }
template<typename... Ts>
InputEdge(NodeIterator source, NodeIterator target, Ts &&...data) : source(source), target(target), data(std::forward<Ts>(data)...) { }
bool operator<(const InputEdge &right) const
InputEdge()
: source(std::numeric_limits<NodeIterator>::max()),
target(std::numeric_limits<NodeIterator>::max())
{
if (source != right.source)
{
return source < right.source;
}
return target < right.target;
}
template <typename... Ts>
InputEdge(NodeIterator source, NodeIterator target, Ts &&... data)
: source(source), target(target), data(std::forward<Ts>(data)...)
{
}
bool operator<(const InputEdge &rhs) const
{
return std::tie(source, target) < std::tie(rhs.source, rhs.target);
}
};
// Constructs an empty graph with a given number of nodes.
explicit DynamicGraph(NodeIterator nodes) : number_of_nodes(nodes), number_of_edges(0)
{
node_list.reserve(number_of_nodes);
node_list.resize(number_of_nodes);
node_array.reserve(number_of_nodes);
node_array.resize(number_of_nodes);
edge_list.reserve(number_of_nodes * 1.1);
edge_list.resize(number_of_nodes);
}
/**
* Constructs a DynamicGraph from a list of edges sorted by source node id.
*/
template <class ContainerT> DynamicGraph(const NodeIterator nodes, const ContainerT &graph)
{
// we need to cast here because DeallocatingVector does not have a valid const iterator
BOOST_ASSERT(std::is_sorted(const_cast<ContainerT&>(graph).begin(), const_cast<ContainerT&>(graph).end()));
number_of_nodes = nodes;
number_of_edges = (EdgeIterator)graph.size();
node_list.reserve(number_of_nodes + 1);
node_list.resize(number_of_nodes + 1);
number_of_edges = static_cast<EdgeIterator>(graph.size());
node_array.resize(number_of_nodes + 1);
EdgeIterator edge = 0;
EdgeIterator position = 0;
for (const auto node : osrm::irange(0u, number_of_nodes))
{
EdgeIterator lastEdge = edge;
EdgeIterator last_edge = edge;
while (edge < number_of_edges && graph[edge].source == node)
{
++edge;
}
node_list[node].firstEdge = position;
node_list[node].edges = edge - lastEdge;
position += node_list[node].edges;
node_array[node].first_edge = position;
node_array[node].edges = edge - last_edge;
position += node_array[node].edges;
}
node_list.back().firstEdge = position;
node_array.back().first_edge = position;
edge_list.reserve(static_cast<std::size_t>(edge_list.size() * 1.1));
edge_list.resize(position);
edge = 0;
for (const auto node : osrm::irange(0u, number_of_nodes))
{
for (const auto i : osrm::irange(node_list[node].firstEdge,
node_list[node].firstEdge + node_list[node].edges))
for (const auto i : osrm::irange(node_array[node].first_edge,
node_array[node].first_edge + node_array[node].edges))
{
edge_list[i].target = graph[edge].target;
BOOST_ASSERT(edge_list[i].target < number_of_nodes);
edge_list[i].data = graph[edge].data;
++edge;
}
@@ -121,14 +132,14 @@ template <typename EdgeDataT> class DynamicGraph
unsigned GetNumberOfEdges() const { return number_of_edges; }
unsigned GetOutDegree(const NodeIterator n) const { return node_list[n].edges; }
unsigned GetOutDegree(const NodeIterator n) const { return node_array[n].edges; }
unsigned GetDirectedOutDegree(const NodeIterator n) const
{
unsigned degree = 0;
for (const auto edge : osrm::irange(BeginEdges(n), EndEdges(n)))
{
if (GetEdgeData(edge).forward)
if (!GetEdgeData(edge).reversed)
{
++degree;
}
@@ -146,12 +157,12 @@ template <typename EdgeDataT> class DynamicGraph
EdgeIterator BeginEdges(const NodeIterator n) const
{
return EdgeIterator(node_list[n].firstEdge);
return EdgeIterator(node_array[n].first_edge);
}
EdgeIterator EndEdges(const NodeIterator n) const
{
return EdgeIterator(node_list[n].firstEdge + node_list[n].edges);
return EdgeIterator(node_array[n].first_edge + node_array[n].edges);
}
EdgeRange GetAdjacentEdgeRange(const NodeIterator node) const
@@ -161,7 +172,7 @@ template <typename EdgeDataT> class DynamicGraph
NodeIterator InsertNode()
{
node_list.emplace_back(node_list.back());
node_array.emplace_back(node_array.back());
number_of_nodes += 1;
return number_of_nodes;
@@ -170,14 +181,14 @@ template <typename EdgeDataT> class DynamicGraph
// adds an edge. Invalidates edge iterators for the source node
EdgeIterator InsertEdge(const NodeIterator from, const NodeIterator to, const EdgeDataT &data)
{
Node &node = node_list[from];
EdgeIterator newFirstEdge = node.edges + node.firstEdge;
Node &node = node_array[from];
EdgeIterator newFirstEdge = node.edges + node.first_edge;
if (newFirstEdge >= edge_list.size() || !isDummy(newFirstEdge))
{
if (node.firstEdge != 0 && isDummy(node.firstEdge - 1))
if (node.first_edge != 0 && isDummy(node.first_edge - 1))
{
node.firstEdge--;
edge_list[node.firstEdge] = edge_list[node.firstEdge + node.edges];
node.first_edge--;
edge_list[node.first_edge] = edge_list[node.first_edge + node.edges];
}
else
{
@@ -192,32 +203,32 @@ template <typename EdgeDataT> class DynamicGraph
edge_list.resize(edge_list.size() + newSize);
for (const auto i : osrm::irange(0u, node.edges))
{
edge_list[newFirstEdge + i] = edge_list[node.firstEdge + i];
makeDummy(node.firstEdge + i);
edge_list[newFirstEdge + i] = edge_list[node.first_edge + i];
makeDummy(node.first_edge + i);
}
for (const auto i : osrm::irange(node.edges + 1, newSize))
{
makeDummy(newFirstEdge + i);
}
node.firstEdge = newFirstEdge;
node.first_edge = newFirstEdge;
}
}
Edge &edge = edge_list[node.firstEdge + node.edges];
Edge &edge = edge_list[node.first_edge + node.edges];
edge.target = to;
edge.data = data;
++number_of_edges;
++node.edges;
return EdgeIterator(node.firstEdge + node.edges);
return EdgeIterator(node.first_edge + node.edges);
}
// removes an edge. Invalidates edge iterators for the source node
void DeleteEdge(const NodeIterator source, const EdgeIterator e)
{
Node &node = node_list[source];
Node &node = node_array[source];
--number_of_edges;
--node.edges;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != node.edges);
const unsigned last = node.firstEdge + node.edges;
const unsigned last = node.first_edge + node.edges;
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != last);
// swap with last edge
edge_list[e] = edge_list[last];
@@ -242,7 +253,7 @@ template <typename EdgeDataT> class DynamicGraph
}
number_of_edges -= deleted;
node_list[source].edges -= deleted;
node_array[source].edges -= deleted;
return deleted;
}
@@ -257,7 +268,46 @@ template <typename EdgeDataT> class DynamicGraph
return i;
}
}
return EndEdges(from);
return SPECIAL_EDGEID;
}
// searches for a specific edge
EdgeIterator FindSmallestEdge(const NodeIterator from, const NodeIterator to) const
{
EdgeIterator smallest_edge = SPECIAL_EDGEID;
EdgeWeight smallest_weight = INVALID_EDGE_WEIGHT;
for (auto edge : GetAdjacentEdgeRange(from))
{
const NodeID target = GetTarget(edge);
const EdgeWeight weight = GetEdgeData(edge).distance;
if (target == to && weight < smallest_weight)
{
smallest_edge = edge;
smallest_weight = weight;
}
}
return smallest_edge;
}
EdgeIterator FindEdgeInEitherDirection(const NodeIterator from, const NodeIterator to) const
{
EdgeIterator tmp = FindEdge(from, to);
return (SPECIAL_NODEID != tmp ? tmp : FindEdge(to, from));
}
EdgeIterator
FindEdgeIndicateIfReverse(const NodeIterator from, const NodeIterator to, bool &result) const
{
EdgeIterator current_iterator = FindEdge(from, to);
if (SPECIAL_NODEID == current_iterator)
{
current_iterator = FindEdge(to, from);
if (SPECIAL_NODEID != current_iterator)
{
result = true;
}
}
return current_iterator;
}
protected:
@@ -274,7 +324,7 @@ template <typename EdgeDataT> class DynamicGraph
struct Node
{
// index of the first edge
EdgeIterator firstEdge;
EdgeIterator first_edge;
// amount of edges
unsigned edges;
};
@@ -288,7 +338,7 @@ template <typename EdgeDataT> class DynamicGraph
NodeIterator number_of_nodes;
std::atomic_uint number_of_edges;
std::vector<Node> node_list;
std::vector<Node> node_array;
DeallocatingVector<Edge> edge_list;
};
+55 -71
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -31,99 +31,83 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../data_structures/travel_mode.hpp"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <osrm/coordinate.hpp>
#include <limits>
/// This is what StaticRTree serialized and stores on disk
/// It is generated in EdgeBasedGraphFactory.
struct EdgeBasedNode
{
EdgeBasedNode() :
forward_edge_based_node_id(SPECIAL_NODEID),
reverse_edge_based_node_id(SPECIAL_NODEID),
u(SPECIAL_NODEID),
v(SPECIAL_NODEID),
name_id(0),
forward_weight(INVALID_EDGE_WEIGHT >> 1),
reverse_weight(INVALID_EDGE_WEIGHT >> 1),
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
component_id(-1),
fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ }
EdgeBasedNode()
: forward_edge_based_node_id(SPECIAL_NODEID), reverse_edge_based_node_id(SPECIAL_NODEID),
u(SPECIAL_NODEID), v(SPECIAL_NODEID), name_id(0),
forward_weight(INVALID_EDGE_WEIGHT >> 1), reverse_weight(INVALID_EDGE_WEIGHT >> 1),
forward_offset(0), reverse_offset(0), packed_geometry_id(SPECIAL_EDGEID),
component{INVALID_COMPONENTID, false}, fwd_segment_position(std::numeric_limits<unsigned short>::max()),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
explicit EdgeBasedNode(
NodeID forward_edge_based_node_id,
NodeID reverse_edge_based_node_id,
NodeID u,
NodeID v,
unsigned name_id,
int forward_weight,
int reverse_weight,
int forward_offset,
int reverse_offset,
unsigned packed_geometry_id,
unsigned component_id,
unsigned short fwd_segment_position,
TravelMode forward_travel_mode,
TravelMode backward_travel_mode
) :
forward_edge_based_node_id(forward_edge_based_node_id),
reverse_edge_based_node_id(reverse_edge_based_node_id),
u(u),
v(v),
name_id(name_id),
forward_weight(forward_weight),
reverse_weight(reverse_weight),
forward_offset(forward_offset),
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
component_id(component_id),
fwd_segment_position(fwd_segment_position),
forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
explicit EdgeBasedNode(NodeID forward_edge_based_node_id,
NodeID reverse_edge_based_node_id,
NodeID u,
NodeID v,
unsigned name_id,
int forward_weight,
int reverse_weight,
int forward_offset,
int reverse_offset,
unsigned packed_geometry_id,
bool is_tiny_component,
unsigned component_id,
unsigned short fwd_segment_position,
TravelMode forward_travel_mode,
TravelMode backward_travel_mode)
: forward_edge_based_node_id(forward_edge_based_node_id),
reverse_edge_based_node_id(reverse_edge_based_node_id), u(u), v(v), name_id(name_id),
forward_weight(forward_weight), reverse_weight(reverse_weight),
forward_offset(forward_offset), reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id), component{component_id, is_tiny_component},
fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{
BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) ||
(reverse_edge_based_node_id != SPECIAL_NODEID));
}
static inline FixedPointCoordinate Centroid(const FixedPointCoordinate & a, const FixedPointCoordinate & b)
static inline FixedPointCoordinate Centroid(const FixedPointCoordinate &a,
const FixedPointCoordinate &b)
{
FixedPointCoordinate centroid;
//The coordinates of the midpoint are given by:
centroid.lat = (a.lat + b.lat)/2;
centroid.lon = (a.lon + b.lon)/2;
// The coordinates of the midpoint are given by:
centroid.lat = (a.lat + b.lat) / 2;
centroid.lon = (a.lon + b.lon) / 2;
return centroid;
}
bool IsCompressed() const
{
return packed_geometry_id != SPECIAL_EDGEID;
}
bool is_in_tiny_cc() const
{
return 0 != component_id;
}
bool IsCompressed() const { return packed_geometry_id != SPECIAL_EDGEID; }
NodeID forward_edge_based_node_id; // needed for edge-expanded graph
NodeID reverse_edge_based_node_id; // needed for edge-expanded graph
NodeID u; // indices into the coordinates array
NodeID v; // indices into the coordinates array
unsigned name_id; // id of the edge name
int forward_weight; // weight of the edge
int reverse_weight; // weight in the other direction (may be different)
int forward_offset; // prefix sum of the weight up the edge TODO: short must suffice
int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice
NodeID u; // indices into the coordinates array
NodeID v; // indices into the coordinates array
unsigned name_id; // id of the edge name
int forward_weight; // weight of the edge
int reverse_weight; // weight in the other direction (may be different)
int forward_offset; // prefix sum of the weight up the edge TODO: short must suffice
int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice
unsigned packed_geometry_id; // if set, then the edge represents a packed geometry
unsigned component_id;
struct {
unsigned id : 31;
bool is_tiny : 1;
} component;
unsigned short fwd_segment_position; // segment id in a compressed geometry
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
};
#endif //EDGE_BASED_NODE_HPP
#endif // EDGE_BASED_NODE_HPP
+6 -8
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -26,11 +26,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "external_memory_node.hpp"
#include "query_node.hpp"
#include <limits>
ExternalMemoryNode::ExternalMemoryNode(
int lat, int lon, unsigned int node_id, bool barrier, bool traffic_lights)
int lat, int lon, OSMNodeID node_id, bool barrier, bool traffic_lights)
: QueryNode(lat, lon, node_id), barrier(barrier), traffic_lights(traffic_lights)
{
}
@@ -39,16 +40,13 @@ ExternalMemoryNode::ExternalMemoryNode() : barrier(false), traffic_lights(false)
ExternalMemoryNode ExternalMemoryNode::min_value()
{
return ExternalMemoryNode(0, 0, 0, false, false);
return ExternalMemoryNode(0, 0, MIN_OSM_NODEID, false, false);
}
ExternalMemoryNode ExternalMemoryNode::max_value()
{
return ExternalMemoryNode(std::numeric_limits<int>::max(),
std::numeric_limits<int>::max(),
std::numeric_limits<unsigned>::max(),
false,
false);
return ExternalMemoryNode(std::numeric_limits<int>::max(), std::numeric_limits<int>::max(),
MAX_OSM_NODEID, false, false);
}
bool ExternalMemoryNodeSTXXLCompare::operator()(const ExternalMemoryNode &left,
+3 -3
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,11 +30,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "query_node.hpp"
#include <string>
#include "../typedefs.h"
struct ExternalMemoryNode : QueryNode
{
ExternalMemoryNode(int lat, int lon, NodeID id, bool barrier, bool traffic_light);
ExternalMemoryNode(int lat, int lon, OSMNodeID id, bool barrier, bool traffic_light);
ExternalMemoryNode();
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
+170
View File
@@ -0,0 +1,170 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef HIDDEN_MARKOV_MODEL
#define HIDDEN_MARKOV_MODEL
#include "../util/integer_range.hpp"
#include <boost/assert.hpp>
#include <cmath>
#include <limits>
#include <vector>
namespace osrm
{
namespace matching
{
static const double log_2_pi = std::log(2. * M_PI);
static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits<double>::infinity();
static const double MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest();
static const std::size_t INVALID_STATE = std::numeric_limits<std::size_t>::max();
} // namespace matching
} // namespace osrm
// closures to precompute log -> only simple floating point operations
struct EmissionLogProbability
{
double sigma_z;
double log_sigma_z;
EmissionLogProbability(const double sigma_z) : sigma_z(sigma_z), log_sigma_z(std::log(sigma_z))
{
}
double operator()(const double distance) const
{
return -0.5 * (osrm::matching::log_2_pi + (distance / sigma_z) * (distance / sigma_z)) -
log_sigma_z;
}
};
struct TransitionLogProbability
{
double beta;
double log_beta;
TransitionLogProbability(const double beta) : beta(beta), log_beta(std::log(beta)) {}
double operator()(const double d_t) const { return -log_beta - d_t / beta; }
};
template <class CandidateLists> struct HiddenMarkovModel
{
std::vector<std::vector<double>> viterbi;
std::vector<std::vector<std::pair<unsigned, unsigned>>> parents;
std::vector<std::vector<float>> path_lengths;
std::vector<std::vector<bool>> pruned;
std::vector<std::vector<bool>> suspicious;
std::vector<bool> breakage;
const CandidateLists &candidates_list;
const EmissionLogProbability &emission_log_probability;
HiddenMarkovModel(const CandidateLists &candidates_list,
const EmissionLogProbability &emission_log_probability)
: breakage(candidates_list.size()), candidates_list(candidates_list),
emission_log_probability(emission_log_probability)
{
viterbi.resize(candidates_list.size());
parents.resize(candidates_list.size());
path_lengths.resize(candidates_list.size());
suspicious.resize(candidates_list.size());
pruned.resize(candidates_list.size());
breakage.resize(candidates_list.size());
for (const auto i : osrm::irange<std::size_t>(0u, candidates_list.size()))
{
const auto& num_candidates = candidates_list[i].size();
// add empty vectors
if (num_candidates > 0)
{
viterbi[i].resize(num_candidates);
parents[i].resize(num_candidates);
path_lengths[i].resize(num_candidates);
suspicious[i].resize(num_candidates);
pruned[i].resize(num_candidates);
}
}
clear(0);
}
void clear(std::size_t initial_timestamp)
{
BOOST_ASSERT(viterbi.size() == parents.size() && parents.size() == path_lengths.size() &&
path_lengths.size() == pruned.size() && pruned.size() == breakage.size());
for (const auto t : osrm::irange(initial_timestamp, viterbi.size()))
{
std::fill(viterbi[t].begin(), viterbi[t].end(), osrm::matching::IMPOSSIBLE_LOG_PROB);
std::fill(parents[t].begin(), parents[t].end(), std::make_pair(0u, 0u));
std::fill(path_lengths[t].begin(), path_lengths[t].end(), 0);
std::fill(suspicious[t].begin(), suspicious[t].end(), true);
std::fill(pruned[t].begin(), pruned[t].end(), true);
}
std::fill(breakage.begin() + initial_timestamp, breakage.end(), true);
}
std::size_t initialize(std::size_t initial_timestamp)
{
auto num_points = candidates_list.size();
do
{
BOOST_ASSERT(initial_timestamp < num_points);
for (const auto s : osrm::irange<std::size_t>(0u, viterbi[initial_timestamp].size()))
{
viterbi[initial_timestamp][s] =
emission_log_probability(candidates_list[initial_timestamp][s].distance);
parents[initial_timestamp][s] = std::make_pair(initial_timestamp, s);
pruned[initial_timestamp][s] =
viterbi[initial_timestamp][s] < osrm::matching::MINIMAL_LOG_PROB;
suspicious[initial_timestamp][s] = false;
breakage[initial_timestamp] =
breakage[initial_timestamp] && pruned[initial_timestamp][s];
}
++initial_timestamp;
} while (initial_timestamp < num_points && breakage[initial_timestamp - 1]);
if (initial_timestamp >= num_points)
{
return osrm::matching::INVALID_STATE;
}
BOOST_ASSERT(initial_timestamp > 0);
--initial_timestamp;
BOOST_ASSERT(breakage[initial_timestamp] == false);
return initial_timestamp;
}
};
#endif // HIDDEN_MARKOV_MODEL
+3 -3
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "hilbert_value.hpp"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
uint64_t HilbertCode::operator()(const FixedPointCoordinate &current_coordinate) const
{
@@ -57,7 +57,7 @@ uint64_t HilbertCode::BitInterleaving(const uint32_t latitude, const uint32_t lo
void HilbertCode::TransposeCoordinate(uint32_t *X) const
{
uint32_t M = 1 << (32 - 1), P, Q, t;
uint32_t M = 1u << (32 - 1), P, Q, t;
int i;
// Inverse undo
for (Q = M; Q > 1; Q >>= 1)
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
+14 -6
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -27,7 +27,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "import_edge.hpp"
#include <boost/assert.hpp>
#include "travel_mode.hpp"
#include "../typedefs.h"
bool NodeBasedEdge::operator<(const NodeBasedEdge &other) const
{
@@ -46,6 +47,13 @@ bool NodeBasedEdge::operator<(const NodeBasedEdge &other) const
return source < other.source;
}
NodeBasedEdge::NodeBasedEdge()
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), forward(false),
backward(false), roundabout(false),
access_restricted(false), startpoint(true), is_split(false), travel_mode(false)
{
}
NodeBasedEdge::NodeBasedEdge(NodeID source,
NodeID target,
NodeID name_id,
@@ -53,13 +61,13 @@ NodeBasedEdge::NodeBasedEdge(NodeID source,
bool forward,
bool backward,
bool roundabout,
bool in_tiny_cc,
bool access_restricted,
bool startpoint,
TravelMode travel_mode,
bool is_split)
: source(source), target(target), name_id(name_id), weight(weight),
forward(forward), backward(backward), roundabout(roundabout), in_tiny_cc(in_tiny_cc),
access_restricted(access_restricted), is_split(is_split), travel_mode(travel_mode)
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
backward(backward), roundabout(roundabout),
access_restricted(access_restricted), startpoint(startpoint), is_split(is_split), travel_mode(travel_mode)
{
}
+23 -6
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -35,6 +35,7 @@ struct NodeBasedEdge
{
bool operator<(const NodeBasedEdge &e) const;
NodeBasedEdge();
explicit NodeBasedEdge(NodeID source,
NodeID target,
NodeID name_id,
@@ -42,8 +43,8 @@ struct NodeBasedEdge
bool forward,
bool backward,
bool roundabout,
bool in_tiny_cc,
bool access_restricted,
bool startpoint,
TravelMode travel_mode,
bool is_split);
@@ -54,12 +55,30 @@ struct NodeBasedEdge
bool forward : 1;
bool backward : 1;
bool roundabout : 1;
bool in_tiny_cc : 1;
bool access_restricted : 1;
bool startpoint : 1;
bool is_split : 1;
TravelMode travel_mode : 4;
};
NodeBasedEdge() = delete;
struct NodeBasedEdgeWithOSM : NodeBasedEdge
{
explicit NodeBasedEdgeWithOSM(OSMNodeID source,
OSMNodeID target,
NodeID name_id,
EdgeWeight weight,
bool forward,
bool backward,
bool roundabout,
bool access_restricted,
bool startpoint,
TravelMode travel_mode,
bool is_split)
: NodeBasedEdge(SPECIAL_NODEID, SPECIAL_NODEID, name_id, weight, forward, backward, roundabout, access_restricted, startpoint, travel_mode, is_split),
osm_source_id(source), osm_target_id(target) {}
OSMNodeID osm_source_id;
OSMNodeID osm_target_id;
};
struct EdgeBasedEdge
@@ -86,6 +105,4 @@ struct EdgeBasedEdge
bool backward : 1;
};
using ImportEdge = NodeBasedEdge;
#endif /* IMPORT_EDGE_HPP */
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,25 +25,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RAW_ROUTE_DATA_HPP
#define RAW_ROUTE_DATA_HPP
#ifndef RAW_ROUTE_DATA_H
#define RAW_ROUTE_DATA_H
#include "../data_structures/phantom_node.hpp"
#include "../data_structures/travel_mode.hpp"
#include "../data_structures/turn_instructions.hpp"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
#include <vector>
struct PathData
{
PathData()
: node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT),
segment_duration(INVALID_EDGE_WEIGHT),
turn_instruction(TurnInstruction::NoTurn),
travel_mode(TRAVEL_MODE_INACCESSIBLE)
: node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT), segment_duration(INVALID_EDGE_WEIGHT),
turn_instruction(TurnInstruction::NoTurn), travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
@@ -52,8 +50,8 @@ struct PathData
TurnInstruction turn_instruction,
EdgeWeight segment_duration,
TravelMode travel_mode)
: node(node), name_id(name_id), segment_duration(segment_duration), turn_instruction(turn_instruction),
travel_mode(travel_mode)
: node(node), name_id(name_id), segment_duration(segment_duration),
turn_instruction(turn_instruction), travel_mode(travel_mode)
{
}
NodeID node;
@@ -63,7 +61,7 @@ struct PathData
TravelMode travel_mode : 4;
};
struct RawRouteData
struct InternalRouteResult
{
std::vector<std::vector<PathData>> unpacked_path_segments;
std::vector<PathData> unpacked_alternative;
@@ -80,11 +78,10 @@ struct RawRouteData
return (leg != unpacked_path_segments.size() - 1);
}
RawRouteData() :
shortest_path_length(INVALID_EDGE_WEIGHT),
alternative_path_length(INVALID_EDGE_WEIGHT)
InternalRouteResult()
: shortest_path_length(INVALID_EDGE_WEIGHT), alternative_path_length(INVALID_EDGE_WEIGHT)
{
}
};
#endif // RAW_ROUTE_DATA_HPP
#endif // RAW_ROUTE_DATA_H
+2 -2
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -86,7 +86,7 @@ template <typename KeyT, typename ValueT> class LRUCache
result = e.value;
// move to front
itemsInCache.splice(positionMap.find(key)->second, itemsInCache, itemsInCache.begin());
itemsInCache.splice(itemsInCache.begin(), itemsInCache, positionMap.find(key)->second);
positionMap.find(key)->second = itemsInCache.begin();
return true;
}
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,50 +25,46 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef REPLY_H
#define REPLY_H
#include "Header.h"
#include <boost/asio.hpp>
#ifndef MATRIX_GRAPH_WRAPPER_H
#define MATRIX_GRAPH_WRAPPER_H
#include <vector>
#include <cstddef>
#include <iterator>
namespace http
{
#include "../typedefs.h"
const char okHTML[] = "";
const char badRequestHTML[] = "{\"status\": 400,\"status_message\":\"Bad Request\"}";
const char internalServerErrorHTML[] =
"{\"status\": 500,\"status_message\":\"Internal Server Error\"}";
const char seperators[] = {':', ' '};
const char crlf[] = {'\r', '\n'};
const std::string okString = "HTTP/1.0 200 OK\r\n";
const std::string badRequestString = "HTTP/1.0 400 Bad Request\r\n";
const std::string internalServerErrorString = "HTTP/1.0 500 Internal Server Error\r\n";
// This Wrapper provides all methods that are needed for TarjanSCC, when the graph is given in a
// matrix representation (e.g. as output from a distance table call)
class Reply
template <typename T> class MatrixGraphWrapper
{
public:
enum status_type
{ ok = 200,
badRequest = 400,
internalServerError = 500 } status;
MatrixGraphWrapper(std::vector<T> table, const std::size_t number_of_nodes)
: table_(std::move(table)), number_of_nodes_(number_of_nodes){};
std::vector<Header> headers;
std::vector<boost::asio::const_buffer> ToBuffers();
std::vector<boost::asio::const_buffer> HeaderstoBuffers();
std::vector<char> content;
static Reply StockReply(status_type status);
void SetSize(const unsigned size);
void SetUncompressedSize();
std::size_t GetNumberOfNodes() const { return number_of_nodes_; }
Reply();
std::vector<T> GetAdjacentEdgeRange(const NodeID node) const
{
std::vector<T> edges;
// find all valid adjacent edges and move to vector `edges`
for (std::size_t i = 0; i < number_of_nodes_; ++i)
{
if (*(std::begin(table_) + node * number_of_nodes_ + i) != INVALID_EDGE_WEIGHT)
{
edges.push_back(i);
}
}
return edges;
}
EdgeWeight GetTarget(const EdgeWeight edge) const { return edge; }
private:
std::string ToString(Reply::status_type status);
boost::asio::const_buffer ToBuffer(Reply::status_type status);
const std::vector<T> table_;
const std::size_t number_of_nodes_;
};
}
#endif // REPLY_H
#endif // MATRIX_GRAPH_WRAPPER_H
+38 -206
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,7 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "dynamic_graph.hpp"
#include "import_edge.hpp"
#include "../Util/simple_logger.hpp"
#include "../util/graph_utils.hpp"
#include <tbb/parallel_sort.h>
@@ -39,232 +39,64 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct NodeBasedEdgeData
{
NodeBasedEdgeData()
: distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID),
nameID(std::numeric_limits<unsigned>::max()),
isAccessRestricted(false), shortcut(false), forward(false), backward(false),
roundabout(false), ignore_in_grid(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
: distance(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
name_id(std::numeric_limits<unsigned>::max()), access_restricted(false),
reversed(false), roundabout(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
NodeBasedEdgeData(int distance, unsigned edge_id, unsigned name_id,
bool access_restricted, bool reversed,
bool roundabout, bool startpoint, TravelMode travel_mode)
: distance(distance), edge_id(edge_id), name_id(name_id),
access_restricted(access_restricted), reversed(reversed),
roundabout(roundabout), startpoint(startpoint), travel_mode(travel_mode)
{
}
int distance;
unsigned edgeBasedNodeID;
unsigned nameID;
bool isAccessRestricted : 1;
bool shortcut : 1;
bool forward : 1;
bool backward : 1;
unsigned edge_id;
unsigned name_id;
bool access_restricted : 1;
bool reversed : 1;
bool roundabout : 1;
bool ignore_in_grid : 1;
bool startpoint : 1;
TravelMode travel_mode : 4;
void SwapDirectionFlags()
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
{
bool temp_flag = forward;
forward = backward;
backward = temp_flag;
}
bool IsEqualTo(const NodeBasedEdgeData &other) const
{
return (forward == other.forward) && (backward == other.backward) &&
(nameID == other.nameID) && (ignore_in_grid == other.ignore_in_grid) &&
return (reversed == other.reversed) && (name_id == other.name_id) &&
(travel_mode == other.travel_mode);
}
};
struct SimpleEdgeData
{
SimpleEdgeData() : capacity(0) {}
EdgeWeight capacity;
};
using NodeBasedDynamicGraph = DynamicGraph<NodeBasedEdgeData>;
using SimpleNodeBasedDynamicGraph = DynamicGraph<SimpleEdgeData>;
// Factory method to create NodeBasedDynamicGraph from ImportEdges
/// Factory method to create NodeBasedDynamicGraph from NodeBasedEdges
/// Since DynamicGraph expects directed edges, we need to insert
/// two edges for undirected edges.
inline std::shared_ptr<NodeBasedDynamicGraph>
NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge> &input_edge_list)
NodeBasedDynamicGraphFromEdges(std::size_t number_of_nodes, const std::vector<NodeBasedEdge> &input_edge_list)
{
static_assert(sizeof(NodeBasedEdgeData) == 16, "changing node based edge data size changes memory consumption");
DeallocatingVector<NodeBasedDynamicGraph::InputEdge> edges_list;
NodeBasedDynamicGraph::InputEdge edge;
for (const ImportEdge &import_edge : input_edge_list)
{
if (import_edge.forward)
auto edges_list = directedEdgesFromCompressed<NodeBasedDynamicGraph::InputEdge>(input_edge_list,
[](NodeBasedDynamicGraph::InputEdge& output_edge, const NodeBasedEdge& input_edge)
{
edge.source = import_edge.source;
edge.target = import_edge.target;
edge.data.forward = import_edge.forward;
edge.data.backward = import_edge.backward;
}
else
{
edge.source = import_edge.target;
edge.target = import_edge.source;
edge.data.backward = import_edge.forward;
edge.data.forward = import_edge.backward;
output_edge.data.distance = static_cast<int>(input_edge.weight);
BOOST_ASSERT(output_edge.data.distance > 0);
output_edge.data.roundabout = input_edge.roundabout;
output_edge.data.name_id = input_edge.name_id;
output_edge.data.access_restricted = input_edge.access_restricted;
output_edge.data.travel_mode = input_edge.travel_mode;
output_edge.data.startpoint = input_edge.startpoint;
}
);
if (edge.source == edge.target)
{
continue;
}
edge.data.distance = (std::max)((int)import_edge.weight, 1);
BOOST_ASSERT(edge.data.distance > 0);
edge.data.shortcut = false;
edge.data.roundabout = import_edge.roundabout;
edge.data.ignore_in_grid = import_edge.in_tiny_cc;
edge.data.nameID = import_edge.name_id;
edge.data.isAccessRestricted = import_edge.access_restricted;
edge.data.travel_mode = import_edge.travel_mode;
edges_list.push_back(edge);
if (!import_edge.is_split)
{
using std::swap; // enable ADL
swap(edge.source, edge.target);
edge.data.SwapDirectionFlags();
edges_list.push_back(edge);
}
}
// remove duplicate edges
tbb::parallel_sort(edges_list.begin(), edges_list.end());
NodeID edge_count = 0;
for (NodeID i = 0; i < edges_list.size(); )
{
const NodeID source = edges_list[i].source;
const NodeID target = edges_list[i].target;
// remove eigenloops
if (source == target)
{
i++;
continue;
}
NodeBasedDynamicGraph::InputEdge forward_edge;
NodeBasedDynamicGraph::InputEdge reverse_edge;
forward_edge = reverse_edge = edges_list[i];
forward_edge.data.forward = reverse_edge.data.backward = true;
forward_edge.data.backward = reverse_edge.data.forward = false;
forward_edge.data.shortcut = reverse_edge.data.shortcut = false;
forward_edge.data.distance = reverse_edge.data.distance =
std::numeric_limits<int>::max();
// remove parallel edges
while (i < edges_list.size() && edges_list[i].source == source && edges_list[i].target == target)
{
if (edges_list[i].data.forward)
{
forward_edge.data.distance =
std::min(edges_list[i].data.distance, forward_edge.data.distance);
}
if (edges_list[i].data.backward)
{
reverse_edge.data.distance =
std::min(edges_list[i].data.distance, reverse_edge.data.distance);
}
++i;
}
// merge edges (s,t) and (t,s) into bidirectional edge
if (forward_edge.data.distance == reverse_edge.data.distance)
{
if ((int)forward_edge.data.distance != std::numeric_limits<int>::max())
{
forward_edge.data.backward = true;
edges_list[edge_count++] = forward_edge;
}
}
else
{ // insert seperate edges
if (((int)forward_edge.data.distance) != std::numeric_limits<int>::max())
{
edges_list[edge_count++] = forward_edge;
}
if ((int)reverse_edge.data.distance != std::numeric_limits<int>::max())
{
edges_list[edge_count++] = reverse_edge;
}
}
}
edges_list.resize(edge_count);
SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " << edges_list.size();
auto graph = std::make_shared<NodeBasedDynamicGraph>(static_cast<NodeBasedDynamicGraph::NodeIterator>(number_of_nodes), edges_list);
return graph;
}
auto graph = std::make_shared<NodeBasedDynamicGraph>(
static_cast<NodeBasedDynamicGraph::NodeIterator>(number_of_nodes), edges_list);
template<class SimpleEdgeT>
inline std::shared_ptr<SimpleNodeBasedDynamicGraph>
SimpleNodeBasedDynamicGraphFromEdges(int number_of_nodes, std::vector<SimpleEdgeT> &input_edge_list)
{
static_assert(sizeof(NodeBasedEdgeData) == 16, "changing node based edge data size changes memory consumption");
tbb::parallel_sort(input_edge_list.begin(), input_edge_list.end());
DeallocatingVector<SimpleNodeBasedDynamicGraph::InputEdge> edges_list;
SimpleNodeBasedDynamicGraph::InputEdge edge;
edge.data.capacity = 1;
for (const SimpleEdgeT &import_edge : input_edge_list)
{
if (import_edge.source == import_edge.target)
{
continue;
}
edge.source = import_edge.source;
edge.target = import_edge.target;
edges_list.push_back(edge);
std::swap(edge.source, edge.target);
edges_list.push_back(edge);
}
// remove duplicate edges
tbb::parallel_sort(edges_list.begin(), edges_list.end());
NodeID edge_count = 0;
for (NodeID i = 0; i < edges_list.size(); )
{
const NodeID source = edges_list[i].source;
const NodeID target = edges_list[i].target;
// remove eigenloops
if (source == target)
{
i++;
continue;
}
SimpleNodeBasedDynamicGraph::InputEdge forward_edge;
SimpleNodeBasedDynamicGraph::InputEdge reverse_edge;
forward_edge = reverse_edge = edges_list[i];
forward_edge.data.capacity = reverse_edge.data.capacity = INVALID_EDGE_WEIGHT;
// remove parallel edges
while (i < edges_list.size() && edges_list[i].source == source && edges_list[i].target == target)
{
forward_edge.data.capacity = std::min(edges_list[i].data.capacity, forward_edge.data.capacity);
reverse_edge.data.capacity = std::min(edges_list[i].data.capacity, reverse_edge.data.capacity);
++i;
}
// merge edges (s,t) and (t,s) into bidirectional edge
if (forward_edge.data.capacity == reverse_edge.data.capacity)
{
if ((int)forward_edge.data.capacity != INVALID_EDGE_WEIGHT)
{
edges_list[edge_count++] = forward_edge;
}
}
else
{ // insert seperate edges
if (((int)forward_edge.data.capacity) != INVALID_EDGE_WEIGHT)
{
edges_list[edge_count++] = forward_edge;
}
if ((int)reverse_edge.data.capacity != INVALID_EDGE_WEIGHT)
{
edges_list[edge_count++] = reverse_edge;
}
}
}
SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of " << edges_list.size();
auto graph = std::make_shared<SimpleNodeBasedDynamicGraph>(number_of_nodes, edges_list);
return graph;
}
+5 -5
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -32,10 +32,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct Cmp
{
using value_type = NodeID;
bool operator()(const NodeID left, const NodeID right) const { return left < right; }
value_type max_value() { return 0xffffffff; }
value_type min_value() { return 0x0; }
using value_type = OSMNodeID;
bool operator()(const value_type left, const value_type right) const { return left < right; }
value_type max_value() { return MAX_OSM_NODEID; }
value_type min_value() { return MIN_OSM_NODEID; }
};
#endif // NODE_ID_HPP
+3 -4
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -48,9 +48,8 @@ struct OriginalEdgeData
OriginalEdgeData()
: via_node(std::numeric_limits<unsigned>::max()),
name_id(std::numeric_limits<unsigned>::max()),
turn_instruction(TurnInstruction::NoTurn), compressed_geometry(false),
travel_mode(TRAVEL_MODE_INACCESSIBLE)
name_id(std::numeric_limits<unsigned>::max()), turn_instruction(TurnInstruction::NoTurn),
compressed_geometry(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
+2 -2
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -36,7 +36,7 @@ class Percent
public:
explicit Percent(unsigned max_value, unsigned step = 5) { reinit(max_value, step); }
// Reinitializes
// Reinitializes
void reinit(unsigned max_value, unsigned step = 5)
{
m_max_value = max_value;
+47 -66
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -27,40 +27,45 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "phantom_node.hpp"
PhantomNode::PhantomNode(NodeID forward_node_id, NodeID reverse_node_id, unsigned name_id,
int forward_weight, int reverse_weight, int forward_offset, int reverse_offset,
unsigned packed_geometry_id, unsigned component_id, FixedPointCoordinate &location,
unsigned short fwd_segment_position,
TravelMode forward_travel_mode, TravelMode backward_travel_mode) :
forward_node_id(forward_node_id),
reverse_node_id(reverse_node_id),
name_id(name_id),
forward_weight(forward_weight),
reverse_weight(reverse_weight),
forward_offset(forward_offset),
reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id),
component_id(component_id),
location(location),
fwd_segment_position(fwd_segment_position),
forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{ }
#include "../typedefs.h"
#include "travel_mode.hpp"
PhantomNode::PhantomNode() :
forward_node_id(SPECIAL_NODEID),
reverse_node_id(SPECIAL_NODEID),
name_id(std::numeric_limits<unsigned>::max()),
forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT),
forward_offset(0),
reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID),
component_id(-1),
fwd_segment_position(0),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ }
#include <osrm/coordinate.hpp>
#include <limits>
PhantomNode::PhantomNode(NodeID forward_node_id,
NodeID reverse_node_id,
unsigned name_id,
int forward_weight,
int reverse_weight,
int forward_offset,
int reverse_offset,
unsigned packed_geometry_id,
bool is_tiny_component,
unsigned component_id,
FixedPointCoordinate &location,
unsigned short fwd_segment_position,
TravelMode forward_travel_mode,
TravelMode backward_travel_mode)
: forward_node_id(forward_node_id), reverse_node_id(reverse_node_id), name_id(name_id),
forward_weight(forward_weight), reverse_weight(reverse_weight),
forward_offset(forward_offset), reverse_offset(reverse_offset),
packed_geometry_id(packed_geometry_id), component{component_id, is_tiny_component}, location(location),
fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{
}
PhantomNode::PhantomNode()
: forward_node_id(SPECIAL_NODEID), reverse_node_id(SPECIAL_NODEID),
name_id(std::numeric_limits<unsigned>::max()), forward_weight(INVALID_EDGE_WEIGHT),
reverse_weight(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0),
packed_geometry_id(SPECIAL_EDGEID), component{INVALID_COMPONENTID, false},
fwd_segment_position(0), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{
}
int PhantomNode::GetForwardWeightPlusOffset() const
{
@@ -82,43 +87,19 @@ int PhantomNode::GetReverseWeightPlusOffset() const
bool PhantomNode::is_bidirected() const
{
return (forward_node_id != SPECIAL_NODEID) &&
(reverse_node_id != SPECIAL_NODEID);
return (forward_node_id != SPECIAL_NODEID) && (reverse_node_id != SPECIAL_NODEID);
}
bool PhantomNode::is_compressed() const
{
return (forward_offset != 0) || (reverse_offset != 0);
}
bool PhantomNode::is_compressed() const { return (forward_offset != 0) || (reverse_offset != 0); }
bool PhantomNode::is_valid(const unsigned number_of_nodes) const
{
return
location.is_valid() &&
(
(forward_node_id < number_of_nodes) ||
(reverse_node_id < number_of_nodes)
) &&
(
(forward_weight != INVALID_EDGE_WEIGHT) ||
(reverse_weight != INVALID_EDGE_WEIGHT)
) &&
(name_id != INVALID_NAMEID
);
}
bool PhantomNode::is_in_tiny_component() const
{
return component_id != 0;
}
bool PhantomNode::is_valid() const
{
return location.is_valid() &&
(name_id != INVALID_NAMEID);
((forward_node_id < number_of_nodes) || (reverse_node_id < number_of_nodes)) &&
((forward_weight != INVALID_EDGE_WEIGHT) || (reverse_weight != INVALID_EDGE_WEIGHT)) &&
(component.id != INVALID_COMPONENTID) && (name_id != INVALID_NAMEID);
}
bool PhantomNode::operator==(const PhantomNode & other) const
{
return location == other.location;
}
bool PhantomNode::is_valid() const { return location.is_valid() && (name_id != INVALID_NAMEID); }
bool PhantomNode::operator==(const PhantomNode &other) const { return location == other.location; }
+64 -31
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,11 +28,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef PHANTOM_NODES_H
#define PHANTOM_NODES_H
#include <osrm/Coordinate.h>
#include "../data_structures/travel_mode.hpp"
#include "travel_mode.hpp"
#include "../typedefs.h"
#include <osrm/coordinate.hpp>
#include <iostream>
#include <utility>
#include <vector>
struct PhantomNode
@@ -45,6 +47,7 @@ struct PhantomNode
int forward_offset,
int reverse_offset,
unsigned packed_geometry_id,
bool is_tiny_component,
unsigned component_id,
FixedPointCoordinate &location,
unsigned short fwd_segment_position,
@@ -53,6 +56,30 @@ struct PhantomNode
PhantomNode();
template <class OtherT> PhantomNode(const OtherT &other, const FixedPointCoordinate &foot_point)
{
forward_node_id = other.forward_edge_based_node_id;
reverse_node_id = other.reverse_edge_based_node_id;
name_id = other.name_id;
forward_weight = other.forward_weight;
reverse_weight = other.reverse_weight;
forward_offset = other.forward_offset;
reverse_offset = other.reverse_offset;
packed_geometry_id = other.packed_geometry_id;
component.id = other.component.id;
component.is_tiny = other.component.is_tiny;
location = foot_point;
fwd_segment_position = other.fwd_segment_position;
forward_travel_mode = other.forward_travel_mode;
backward_travel_mode = other.backward_travel_mode;
}
NodeID forward_node_id;
NodeID reverse_node_id;
unsigned name_id;
@@ -61,11 +88,20 @@ struct PhantomNode
int forward_offset;
int reverse_offset;
unsigned packed_geometry_id;
unsigned component_id;
struct ComponentType {
uint32_t id : 31;
bool is_tiny : 1;
} component;
// bit-fields are broken on Windows
#ifndef _MSC_VER
static_assert(sizeof(ComponentType) == 4, "ComponentType needs to 4 bytes big");
#endif
FixedPointCoordinate location;
unsigned short fwd_segment_position;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
// note 4 bits would suffice for each,
// but the saved byte would be padding anyway
TravelMode forward_travel_mode;
TravelMode backward_travel_mode;
int GetForwardWeightPlusOffset() const;
@@ -79,22 +115,19 @@ struct PhantomNode
bool is_valid() const;
bool is_in_tiny_component() const;
bool operator==(const PhantomNode & other) const;
bool operator==(const PhantomNode &other) const;
};
using PhantomNodeArray = std::vector<std::vector<PhantomNode>>;
#ifndef _MSC_VER
static_assert(sizeof(PhantomNode) == 48, "PhantomNode has more padding then expected");
#endif
class phantom_node_pair : public std::pair<PhantomNode, PhantomNode>
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
struct PhantomNodeWithDistance
{
};
struct PhantomNodeLists
{
std::vector<PhantomNode> source_phantom_list;
std::vector<PhantomNode> target_phantom_list;
PhantomNode phantom_node;
double distance;
};
struct PhantomNodes
@@ -103,26 +136,26 @@ struct PhantomNodes
PhantomNode target_phantom;
};
inline std::ostream& operator<<(std::ostream &out, const PhantomNodes & pn)
inline std::ostream &operator<<(std::ostream &out, const PhantomNodes &pn)
{
out << "source_coord: " << pn.source_phantom.location << "\n";
out << "target_coord: " << pn.target_phantom.location << std::endl;
return out;
}
inline std::ostream& operator<<(std::ostream &out, const PhantomNode & pn)
inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
{
out << "node1: " << pn.forward_node_id << ", " <<
"node2: " << pn.reverse_node_id << ", " <<
"name: " << pn.name_id << ", " <<
"fwd-w: " << pn.forward_weight << ", " <<
"rev-w: " << pn.reverse_weight << ", " <<
"fwd-o: " << pn.forward_offset << ", " <<
"rev-o: " << pn.reverse_offset << ", " <<
"geom: " << pn.packed_geometry_id << ", " <<
"comp: " << pn.component_id << ", " <<
"pos: " << pn.fwd_segment_position << ", " <<
"loc: " << pn.location;
out << "node1: " << pn.forward_node_id << ", "
<< "node2: " << pn.reverse_node_id << ", "
<< "name: " << pn.name_id << ", "
<< "fwd-w: " << pn.forward_weight << ", "
<< "rev-w: " << pn.reverse_weight << ", "
<< "fwd-o: " << pn.forward_offset << ", "
<< "rev-o: " << pn.reverse_offset << ", "
<< "geom: " << pn.packed_geometry_id << ", "
<< "comp: " << pn.component.is_tiny << " / " << pn.component.id << ", "
<< "pos: " << pn.fwd_segment_position << ", "
<< "loc: " << pn.location;
return out;
}
+9 -11
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,11 +25,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef QUERYEDGE_HPP_
#define QUERYEDGE_HPP_
#ifndef QUERYEDGE_HPP
#define QUERYEDGE_HPP
#include "../typedefs.h"
#include <tuple>
struct QueryEdge
{
NodeID source;
@@ -56,17 +58,13 @@ struct QueryEdge
QueryEdge() : source(SPECIAL_NODEID), target(SPECIAL_NODEID) {}
QueryEdge(NodeID source, NodeID target, EdgeData data)
: source(source), target(target), data(data)
: source(source), target(target), data(std::move(data))
{
}
bool operator<(const QueryEdge &right) const
bool operator<(const QueryEdge &rhs) const
{
if (source != right.source)
{
return source < right.source;
}
return target < right.target;
return std::tie(source, target) < std::tie(rhs.source, rhs.target);
}
bool operator==(const QueryEdge &right) const
@@ -78,4 +76,4 @@ struct QueryEdge
}
};
#endif /* QUERYEDGE_HPP_ */
#endif // QUERYEDGE_HPP
+10 -10
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -30,40 +30,40 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <osrm/coordinate.hpp>
#include <limits>
struct QueryNode
{
using key_type = NodeID; // type of NodeID
using value_type = int; // type of lat,lons
using key_type = OSMNodeID; // type of NodeID
using value_type = int; // type of lat,lons
explicit QueryNode(int lat, int lon, NodeID node_id) : lat(lat), lon(lon), node_id(node_id) {}
explicit QueryNode(int lat, int lon, OSMNodeID node_id) : lat(lat), lon(lon), node_id(node_id) {}
QueryNode()
: lat(std::numeric_limits<int>::max()), lon(std::numeric_limits<int>::max()),
node_id(std::numeric_limits<unsigned>::max())
node_id(SPECIAL_OSM_NODEID)
{
}
int lat;
int lon;
NodeID node_id;
OSMNodeID node_id;
static QueryNode min_value()
{
return QueryNode(static_cast<int>(-90 * COORDINATE_PRECISION),
static_cast<int>(-180 * COORDINATE_PRECISION),
std::numeric_limits<NodeID>::min());
MIN_OSM_NODEID);
}
static QueryNode max_value()
{
return QueryNode(static_cast<int>(90 * COORDINATE_PRECISION),
static_cast<int>(180 * COORDINATE_PRECISION),
std::numeric_limits<NodeID>::max());
MAX_OSM_NODEID);
}
value_type operator[](const std::size_t n) const
+43 -41
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,26 +28,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef RANGE_TABLE_HPP
#define RANGE_TABLE_HPP
#include "../Util/integer_range.hpp"
#include "../util/integer_range.hpp"
#include "shared_memory_factory.hpp"
#include "shared_memory_vector_wrapper.hpp"
#include <fstream>
#include <vector>
#include <array>
/*
* These pre-declarations are needed because parsing C++ is hard
* and otherwise the compiler gets confused.
*/
template<unsigned BLOCK_SIZE=16, bool USE_SHARED_MEMORY = false> class RangeTable;
template <unsigned BLOCK_SIZE = 16, bool USE_SHARED_MEMORY = false> class RangeTable;
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream& operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream &operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream& operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream &operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table);
/**
* Stores adjacent ranges in a compressed format.
@@ -58,33 +56,35 @@ std::istream& operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEM
* But each block consists of an absolute value and BLOCK_SIZE differential values.
* So the effective block size is sizeof(unsigned) + BLOCK_SIZE.
*/
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
class RangeTable
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY> class RangeTable
{
public:
public:
using BlockT = std::array<unsigned char, BLOCK_SIZE>;
using BlockContainerT = typename ShM<BlockT, USE_SHARED_MEMORY>::vector;
using OffsetContainerT = typename ShM<unsigned, USE_SHARED_MEMORY>::vector;
using RangeT = osrm::range<unsigned>;
friend std::ostream& operator<< <>(std::ostream &out, const RangeTable &table);
friend std::istream& operator>> <>(std::istream &in, RangeTable &table);
friend std::ostream &operator<<<>(std::ostream &out, const RangeTable &table);
friend std::istream &operator>><>(std::istream &in, RangeTable &table);
RangeTable() : sum_lengths(0) {}
// for loading from shared memory
explicit RangeTable(OffsetContainerT& external_offsets, BlockContainerT& external_blocks, const unsigned sum_lengths)
: sum_lengths(sum_lengths)
explicit RangeTable(OffsetContainerT &external_offsets,
BlockContainerT &external_blocks,
const unsigned sum_lengths)
: sum_lengths(sum_lengths)
{
block_offsets.swap(external_offsets);
diff_blocks.swap(external_blocks);
}
// construct table from length vector
explicit RangeTable(const std::vector<unsigned>& lengths)
template<typename VectorT>
explicit RangeTable(const VectorT &lengths)
{
const unsigned number_of_blocks = [&lengths]() {
const unsigned number_of_blocks = [&lengths]()
{
unsigned num = (lengths.size() + 1) / (BLOCK_SIZE + 1);
if ((lengths.size() + 1) % (BLOCK_SIZE + 1) != 0)
{
@@ -116,8 +116,8 @@ public:
block_sum += last_length;
}
BOOST_ASSERT((block_idx == 0 && block_offsets[block_counter] == lengths_prefix_sum)
|| lengths_prefix_sum == (block_offsets[block_counter]+block_sum));
BOOST_ASSERT((block_idx == 0 && block_offsets[block_counter] == lengths_prefix_sum) ||
lengths_prefix_sum == (block_offsets[block_counter] + block_sum));
// block is full
if (BLOCK_SIZE == block_idx)
@@ -136,7 +136,7 @@ public:
}
// Last block can't be finished because we didn't add the sentinel
BOOST_ASSERT (block_counter == (number_of_blocks - 1));
BOOST_ASSERT(block_counter == (number_of_blocks - 1));
// one block missing: starts with guard value
if (0 == block_idx)
@@ -155,7 +155,8 @@ public:
}
diff_blocks.push_back(block);
BOOST_ASSERT(diff_blocks.size() == number_of_blocks && block_offsets.size() == number_of_blocks);
BOOST_ASSERT(diff_blocks.size() == number_of_blocks &&
block_offsets.size() == number_of_blocks);
sum_lengths = lengths_prefix_sum;
}
@@ -172,7 +173,7 @@ public:
unsigned begin_idx = 0;
unsigned end_idx = 0;
begin_idx = block_offsets[block_idx];
const BlockT& block = diff_blocks[block_idx];
const BlockT &block = diff_blocks[block_idx];
if (internal_idx > 0)
{
begin_idx += PrefixSumAtIndex(internal_idx - 1, block);
@@ -195,9 +196,9 @@ public:
return osrm::irange(begin_idx, end_idx);
}
private:
inline unsigned PrefixSumAtIndex(int index, const BlockT& block) const;
private:
inline unsigned PrefixSumAtIndex(int index, const BlockT &block) const;
// contains offset for each differential block
OffsetContainerT block_offsets;
@@ -206,8 +207,9 @@ private:
unsigned sum_lengths;
};
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
unsigned RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY>::PrefixSumAtIndex(int index, const BlockT& block) const
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
unsigned RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY>::PrefixSumAtIndex(int index,
const BlockT &block) const
{
// this loop looks inefficent, but a modern compiler
// will emit nice SIMD here, at least for sensible block sizes. (I checked.)
@@ -220,39 +222,39 @@ unsigned RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY>::PrefixSumAtIndex(int index,
return sum;
}
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream& operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::ostream &operator<<(std::ostream &out, const RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
{
// write number of block
const unsigned number_of_blocks = table.diff_blocks.size();
out.write((char *) &number_of_blocks, sizeof(unsigned));
out.write((char *)&number_of_blocks, sizeof(unsigned));
// write total length
out.write((char *) &table.sum_lengths, sizeof(unsigned));
out.write((char *)&table.sum_lengths, sizeof(unsigned));
// write block offsets
out.write((char *) table.block_offsets.data(), sizeof(unsigned) * table.block_offsets.size());
out.write((char *)table.block_offsets.data(), sizeof(unsigned) * table.block_offsets.size());
// write blocks
out.write((char *) table.diff_blocks.data(), BLOCK_SIZE * table.diff_blocks.size());
out.write((char *)table.diff_blocks.data(), BLOCK_SIZE * table.diff_blocks.size());
return out;
}
template<unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream& operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
template <unsigned BLOCK_SIZE, bool USE_SHARED_MEMORY>
std::istream &operator>>(std::istream &in, RangeTable<BLOCK_SIZE, USE_SHARED_MEMORY> &table)
{
// read number of block
unsigned number_of_blocks;
in.read((char *) &number_of_blocks, sizeof(unsigned));
in.read((char *)&number_of_blocks, sizeof(unsigned));
// read total length
in.read((char *) &table.sum_lengths, sizeof(unsigned));
in.read((char *)&table.sum_lengths, sizeof(unsigned));
table.block_offsets.resize(number_of_blocks);
table.diff_blocks.resize(number_of_blocks);
// read block offsets
in.read((char *) table.block_offsets.data(), sizeof(unsigned) * number_of_blocks);
in.read((char *)table.block_offsets.data(), sizeof(unsigned) * number_of_blocks);
// read blocks
in.read((char *) table.diff_blocks.data(), BLOCK_SIZE * number_of_blocks);
in.read((char *)table.diff_blocks.data(), BLOCK_SIZE * number_of_blocks);
return in;
}
#endif //RANGE_TABLE_HPP
#endif // RANGE_TABLE_HPP
+178
View File
@@ -0,0 +1,178 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "raster_source.hpp"
#include "../util/simple_logger.hpp"
#include "../util/timing_util.hpp"
#include <osrm/coordinate.hpp>
#include <cmath>
RasterSource::RasterSource(RasterGrid _raster_data,
std::size_t _width,
std::size_t _height,
int _xmin,
int _xmax,
int _ymin,
int _ymax)
: xstep(calcSize(_xmin, _xmax, _width)), ystep(calcSize(_ymin, _ymax, _height)),
raster_data(std::move(_raster_data)), width(_width), height(_height), xmin(_xmin),
xmax(_xmax), ymin(_ymin), ymax(_ymax)
{
BOOST_ASSERT(xstep != 0);
BOOST_ASSERT(ystep != 0);
}
float RasterSource::calcSize(int min, int max, std::size_t count) const
{
BOOST_ASSERT(count > 0);
return (max - min) / (static_cast<float>(count) - 1);
}
// Query raster source for nearest data point
RasterDatum RasterSource::getRasterData(const int lon, const int lat) const
{
if (lon < xmin || lon > xmax || lat < ymin || lat > ymax)
{
return {};
}
const std::size_t xth = static_cast<std::size_t>(round((lon - xmin) / xstep));
const std::size_t yth = static_cast<std::size_t>(round((ymax - lat) / ystep));
return {raster_data(xth, yth)};
}
// Query raster source using bilinear interpolation
RasterDatum RasterSource::getRasterInterpolate(const int lon, const int lat) const
{
if (lon < xmin || lon > xmax || lat < ymin || lat > ymax)
{
return {};
}
const auto xthP = (lon - xmin) / xstep;
const auto ythP = (ymax - lat) / ystep;
const std::size_t top = static_cast<std::size_t>(fmax(floor(ythP), 0));
const std::size_t bottom = static_cast<std::size_t>(fmin(ceil(ythP), height - 1));
const std::size_t left = static_cast<std::size_t>(fmax(floor(xthP), 0));
const std::size_t right = static_cast<std::size_t>(fmin(ceil(xthP), width - 1));
// Calculate distances from corners for bilinear interpolation
const float fromLeft = (lon - left * xstep + xmin) / xstep;
const float fromTop = (ymax - top * ystep - lat) / ystep;
const float fromRight = 1 - fromLeft;
const float fromBottom = 1 - fromTop;
return {static_cast<std::int32_t>(raster_data(left, top) * (fromRight * fromBottom) +
raster_data(right, top) * (fromLeft * fromBottom) +
raster_data(left, bottom) * (fromRight * fromTop) +
raster_data(right, bottom) * (fromLeft * fromTop))};
}
// Load raster source into memory
int SourceContainer::loadRasterSource(const std::string &path_string,
double xmin,
double xmax,
double ymin,
double ymax,
std::size_t nrows,
std::size_t ncols)
{
const auto _xmin = static_cast<int>(xmin * COORDINATE_PRECISION);
const auto _xmax = static_cast<int>(xmax * COORDINATE_PRECISION);
const auto _ymin = static_cast<int>(ymin * COORDINATE_PRECISION);
const auto _ymax = static_cast<int>(ymax * COORDINATE_PRECISION);
const auto itr = LoadedSourcePaths.find(path_string);
if (itr != LoadedSourcePaths.end())
{
SimpleLogger().Write() << "[source loader] Already loaded source '" << path_string
<< "' at source_id " << itr->second;
return itr->second;
}
int source_id = static_cast<int>(LoadedSources.size());
SimpleLogger().Write() << "[source loader] Loading from " << path_string << " ... ";
TIMER_START(loading_source);
boost::filesystem::path filepath(path_string);
if (!boost::filesystem::exists(filepath))
{
throw osrm::exception("error reading: no such path");
}
RasterGrid rasterData{filepath, ncols, nrows};
RasterSource source{std::move(rasterData), ncols, nrows, _xmin, _xmax, _ymin, _ymax};
TIMER_STOP(loading_source);
LoadedSourcePaths.emplace(path_string, source_id);
LoadedSources.push_back(std::move(source));
SimpleLogger().Write() << "[source loader] ok, after " << TIMER_SEC(loading_source) << "s";
return source_id;
}
// External function for looking up nearest data point from a specified source
RasterDatum SourceContainer::getRasterDataFromSource(unsigned int source_id, int lon, int lat)
{
if (LoadedSources.size() < source_id + 1)
{
throw osrm::exception("error reading: no such loaded source");
}
BOOST_ASSERT(lat < (90 * COORDINATE_PRECISION));
BOOST_ASSERT(lat > (-90 * COORDINATE_PRECISION));
BOOST_ASSERT(lon < (180 * COORDINATE_PRECISION));
BOOST_ASSERT(lon > (-180 * COORDINATE_PRECISION));
const auto &found = LoadedSources[source_id];
return found.getRasterData(lon, lat);
}
// External function for looking up interpolated data from a specified source
RasterDatum
SourceContainer::getRasterInterpolateFromSource(unsigned int source_id, int lon, int lat)
{
if (LoadedSources.size() < source_id + 1)
{
throw osrm::exception("error reading: no such loaded source");
}
BOOST_ASSERT(lat < (90 * COORDINATE_PRECISION));
BOOST_ASSERT(lat > (-90 * COORDINATE_PRECISION));
BOOST_ASSERT(lon < (180 * COORDINATE_PRECISION));
BOOST_ASSERT(lon > (-180 * COORDINATE_PRECISION));
const auto &found = LoadedSources[source_id];
return found.getRasterInterpolate(lon, lat);
}
+175
View File
@@ -0,0 +1,175 @@
/*
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RASTER_SOURCE_HPP
#define RASTER_SOURCE_HPP
#include "../util/osrm_exception.hpp"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/spirit/include/qi_int.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/assert.hpp>
#include <unordered_map>
#include <iterator>
/**
\brief Small wrapper around raster source queries to optionally provide results
gracefully, depending on source bounds
*/
struct RasterDatum
{
static std::int32_t get_invalid() { return std::numeric_limits<std::int32_t>::max(); }
std::int32_t datum = get_invalid();
RasterDatum() = default;
RasterDatum(std::int32_t _datum) : datum(_datum) {}
};
class RasterGrid
{
public:
RasterGrid(const boost::filesystem::path &filepath, std::size_t _xdim, std::size_t _ydim)
{
xdim = _xdim;
ydim = _ydim;
_data.reserve(ydim * xdim);
boost::filesystem::ifstream stream(filepath);
if (!stream)
{
throw osrm::exception("Unable to open raster file.");
}
stream.seekg(0, std::ios_base::end);
std::string buffer;
buffer.resize(static_cast<std::size_t>(stream.tellg()));
stream.seekg(0, std::ios_base::beg);
BOOST_ASSERT(buffer.size() > 1);
stream.read(&buffer[0], static_cast<std::streamsize>(buffer.size()));
boost::algorithm::trim(buffer);
auto itr = buffer.begin();
auto end = buffer.end();
bool r = false;
try
{
r = boost::spirit::qi::parse(
itr, end, +boost::spirit::qi::int_ % +boost::spirit::qi::space, _data);
}
catch (std::exception const &ex)
{
throw osrm::exception(
std::string("Failed to read from raster source with exception: ") + ex.what());
}
if (!r || itr != end)
{
throw osrm::exception("Failed to parse raster source correctly.");
}
}
RasterGrid(const RasterGrid &) = default;
RasterGrid &operator=(const RasterGrid &) = default;
RasterGrid(RasterGrid &&) = default;
RasterGrid &operator=(RasterGrid &&) = default;
std::int32_t operator()(std::size_t x, std::size_t y) { return _data[y * xdim + x]; }
std::int32_t operator()(std::size_t x, std::size_t y) const { return _data[(y)*xdim + (x)]; }
private:
std::vector<std::int32_t> _data;
std::size_t xdim, ydim;
};
/**
\brief Stores raster source data in memory and provides lookup functions.
*/
class RasterSource
{
private:
const float xstep;
const float ystep;
float calcSize(int min, int max, std::size_t count) const;
public:
RasterGrid raster_data;
const std::size_t width;
const std::size_t height;
const int xmin;
const int xmax;
const int ymin;
const int ymax;
RasterDatum getRasterData(const int lon, const int lat) const;
RasterDatum getRasterInterpolate(const int lon, const int lat) const;
RasterSource(RasterGrid _raster_data,
std::size_t width,
std::size_t height,
int _xmin,
int _xmax,
int _ymin,
int _ymax);
};
class SourceContainer
{
public:
SourceContainer() = default;
int loadRasterSource(const std::string &path_string,
double xmin,
double xmax,
double ymin,
double ymax,
std::size_t nrows,
std::size_t ncols);
RasterDatum getRasterDataFromSource(unsigned int source_id, int lon, int lat);
RasterDatum getRasterInterpolateFromSource(unsigned int source_id, int lon, int lat);
private:
std::vector<RasterSource> LoadedSources;
std::unordered_map<std::string, int> LoadedSourcePaths;
};
#endif /* RASTER_SOURCE_HPP */
+73 -69
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,8 +28,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef RECTANGLE_HPP
#define RECTANGLE_HPP
#include "../algorithms/coordinate_calculation.hpp"
#include <boost/assert.hpp>
#include <osrm/coordinate.hpp>
#include <algorithm>
#include <cstdint>
#include <limits>
@@ -37,15 +41,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// TODO: Make template type, add tests
struct RectangleInt2D
{
RectangleInt2D() : min_lon(std::numeric_limits<int32_t>::max()),
max_lon(std::numeric_limits<int32_t>::min()),
min_lat(std::numeric_limits<int32_t>::max()),
max_lat(std::numeric_limits<int32_t>::min()) {}
RectangleInt2D()
: min_lon(std::numeric_limits<int32_t>::max()),
max_lon(std::numeric_limits<int32_t>::min()),
min_lat(std::numeric_limits<int32_t>::max()), max_lat(std::numeric_limits<int32_t>::min())
{
}
int32_t min_lon, max_lon;
int32_t min_lat, max_lat;
inline void MergeBoundingBoxes(const RectangleInt2D &other)
void MergeBoundingBoxes(const RectangleInt2D &other)
{
min_lon = std::min(min_lon, other.min_lon);
max_lon = std::max(max_lon, other.max_lon);
@@ -57,7 +63,7 @@ struct RectangleInt2D
BOOST_ASSERT(max_lon != std::numeric_limits<int32_t>::min());
}
inline FixedPointCoordinate Centroid() const
FixedPointCoordinate Centroid() const
{
FixedPointCoordinate centroid;
// The coordinates of the midpoints are given by:
@@ -67,7 +73,7 @@ struct RectangleInt2D
return centroid;
}
inline bool Intersects(const RectangleInt2D &other) const
bool Intersects(const RectangleInt2D &other) const
{
FixedPointCoordinate upper_left(other.max_lat, other.min_lon);
FixedPointCoordinate upper_right(other.max_lat, other.max_lon);
@@ -78,7 +84,7 @@ struct RectangleInt2D
Contains(lower_left));
}
inline float GetMinDist(const FixedPointCoordinate &location) const
float GetMinDist(const FixedPointCoordinate &location) const
{
const bool is_contained = Contains(location);
if (is_contained)
@@ -88,66 +94,74 @@ struct RectangleInt2D
enum Direction
{
INVALID = 0,
NORTH = 1,
SOUTH = 2,
EAST = 4,
INVALID = 0,
NORTH = 1,
SOUTH = 2,
EAST = 4,
NORTH_EAST = 5,
SOUTH_EAST = 6,
WEST = 8,
WEST = 8,
NORTH_WEST = 9,
SOUTH_WEST = 10
};
Direction d = INVALID;
if (location.lat > max_lat)
d = (Direction) (d | NORTH);
d = (Direction)(d | NORTH);
else if (location.lat < min_lat)
d = (Direction) (d | SOUTH);
d = (Direction)(d | SOUTH);
if (location.lon > max_lon)
d = (Direction) (d | EAST);
d = (Direction)(d | EAST);
else if (location.lon < min_lon)
d = (Direction) (d | WEST);
d = (Direction)(d | WEST);
BOOST_ASSERT(d != INVALID);
float min_dist = std::numeric_limits<float>::max();
switch (d)
{
case NORTH:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, location.lon));
break;
case SOUTH:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, location.lon));
break;
case WEST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, min_lon));
break;
case EAST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(location.lat, max_lon));
break;
case NORTH_EAST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, max_lon));
break;
case NORTH_WEST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(max_lat, min_lon));
break;
case SOUTH_EAST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, max_lon));
break;
case SOUTH_WEST:
min_dist = FixedPointCoordinate::ApproximateEuclideanDistance(location, FixedPointCoordinate(min_lat, min_lon));
break;
default:
break;
case NORTH:
min_dist = coordinate_calculation::great_circle_distance(
location, FixedPointCoordinate(max_lat, location.lon));
break;
case SOUTH:
min_dist = coordinate_calculation::great_circle_distance(
location, FixedPointCoordinate(min_lat, location.lon));
break;
case WEST:
min_dist = coordinate_calculation::great_circle_distance(
location, FixedPointCoordinate(location.lat, min_lon));
break;
case EAST:
min_dist = coordinate_calculation::great_circle_distance(
location, FixedPointCoordinate(location.lat, max_lon));
break;
case NORTH_EAST:
min_dist = coordinate_calculation::great_circle_distance(
location, FixedPointCoordinate(max_lat, max_lon));
break;
case NORTH_WEST:
min_dist = coordinate_calculation::great_circle_distance(
location, FixedPointCoordinate(max_lat, min_lon));
break;
case SOUTH_EAST:
min_dist = coordinate_calculation::great_circle_distance(
location, FixedPointCoordinate(min_lat, max_lon));
break;
case SOUTH_WEST:
min_dist = coordinate_calculation::great_circle_distance(
location, FixedPointCoordinate(min_lat, min_lon));
break;
default:
break;
}
BOOST_ASSERT(min_dist != std::numeric_limits<float>::max());
BOOST_ASSERT(min_dist < std::numeric_limits<float>::max());
return min_dist;
}
inline float GetMinMaxDist(const FixedPointCoordinate &location) const
float GetMinMaxDist(const FixedPointCoordinate &location) const
{
float min_max_dist = std::numeric_limits<float>::max();
// Get minmax distance to each of the four sides
@@ -158,42 +172,32 @@ struct RectangleInt2D
min_max_dist = std::min(
min_max_dist,
std::max(
FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_left),
FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_right)));
std::max(coordinate_calculation::great_circle_distance(location, upper_left),
coordinate_calculation::great_circle_distance(location, upper_right)));
min_max_dist = std::min(
min_max_dist,
std::max(
FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_right),
FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_right)));
std::max(coordinate_calculation::great_circle_distance(location, upper_right),
coordinate_calculation::great_circle_distance(location, lower_right)));
min_max_dist = std::min(
min_max_dist,
std::max(FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_right),
FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_left)));
min_max_dist =
std::min(min_max_dist,
std::max(coordinate_calculation::great_circle_distance(location, lower_right),
coordinate_calculation::great_circle_distance(location, lower_left)));
min_max_dist = std::min(
min_max_dist,
std::max(FixedPointCoordinate::ApproximateEuclideanDistance(location, lower_left),
FixedPointCoordinate::ApproximateEuclideanDistance(location, upper_left)));
min_max_dist =
std::min(min_max_dist,
std::max(coordinate_calculation::great_circle_distance(location, lower_left),
coordinate_calculation::great_circle_distance(location, upper_left)));
return min_max_dist;
}
inline bool Contains(const FixedPointCoordinate &location) const
bool Contains(const FixedPointCoordinate &location) const
{
const bool lats_contained = (location.lat >= min_lat) && (location.lat <= max_lat);
const bool lons_contained = (location.lon >= min_lon) && (location.lon <= max_lon);
return lats_contained && lons_contained;
}
inline friend std::ostream &operator<<(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;
}
};
#endif
+16 -14
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -36,8 +36,8 @@ struct TurnRestriction
{
union WayOrNode
{
NodeID node;
EdgeID way;
OSMNodeID_weak node;
OSMEdgeID_weak way;
};
WayOrNode via;
WayOrNode from;
@@ -77,11 +77,15 @@ struct TurnRestriction
}
};
/**
* This is just a wrapper around TurnRestriction used in the extractor.
*
* Could be merged with TurnRestriction. For now the type-destiction makes sense
* as the format in which the restriction is presented in the extractor and in the
* preprocessing is different. (see restriction_parser.cpp)
*/
struct InputRestrictionContainer
{
// EdgeID fromWay;
// EdgeID toWay;
// NodeID via_node;
TurnRestriction restriction;
InputRestrictionContainer(EdgeID fromWay, EdgeID toWay, EdgeID vw)
@@ -107,21 +111,19 @@ struct InputRestrictionContainer
struct CmpRestrictionContainerByFrom
{
typedef InputRestrictionContainer value_type;
inline bool operator()(const InputRestrictionContainer &a,
const InputRestrictionContainer &b) const
using value_type = InputRestrictionContainer;
bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const
{
return a.restriction.from.way < b.restriction.from.way;
}
inline value_type max_value() const { return InputRestrictionContainer::max_value(); }
inline value_type min_value() const { return InputRestrictionContainer::min_value(); }
value_type max_value() const { return InputRestrictionContainer::max_value(); }
value_type min_value() const { return InputRestrictionContainer::min_value(); }
};
struct CmpRestrictionContainerByTo
{
typedef InputRestrictionContainer value_type;
inline bool operator()(const InputRestrictionContainer &a,
const InputRestrictionContainer &b) const
using value_type = InputRestrictionContainer;
bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const
{
return a.restriction.to.way < b.restriction.to.way;
}
+60 -49
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -27,54 +27,58 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "restriction_map.hpp"
RestrictionMap::RestrictionMap(const std::vector<TurnRestriction> &restriction_list)
: m_count(0)
RestrictionMap::RestrictionMap(const std::vector<TurnRestriction> &restriction_list) : m_count(0)
{
// decompose restriction consisting of a start, via and end node into a
// a pair of starting edge and a list of all end nodes
for (auto &restriction : restriction_list)
{
// decompose restriction consisting of a start, via and end node into a
// a pair of starting edge and a list of all end nodes
for (auto &restriction : restriction_list)
// This downcasting is OK because when this is called, the node IDs have been
// renumbered into internal values, which should be well under 2^32
// This will be a problem if we have more than 2^32 actual restrictions
BOOST_ASSERT(restriction.from.node < std::numeric_limits<NodeID>::max());
BOOST_ASSERT(restriction.via.node < std::numeric_limits<NodeID>::max());
m_restriction_start_nodes.insert(restriction.from.node);
m_no_turn_via_node_set.insert(restriction.via.node);
// This explicit downcasting is also OK for the same reason.
RestrictionSource restriction_source = {static_cast<NodeID>(restriction.from.node), static_cast<NodeID>(restriction.via.node)};
std::size_t index;
auto restriction_iter = m_restriction_map.find(restriction_source);
if (restriction_iter == m_restriction_map.end())
{
m_restriction_start_nodes.insert(restriction.from.node);
m_no_turn_via_node_set.insert(restriction.via.node);
RestrictionSource restriction_source = {restriction.from.node, restriction.via.node};
std::size_t index;
auto restriction_iter = m_restriction_map.find(restriction_source);
if (restriction_iter == m_restriction_map.end())
{
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index + 1);
m_restriction_map.emplace(restriction_source, index);
}
else
{
index = restriction_iter->second;
// Map already contains an is_only_*-restriction
if (m_restriction_bucket_list.at(index).begin()->is_only)
{
continue;
}
else if (restriction.flags.is_only)
{
// We are going to insert an is_only_*-restriction. There can be only one.
m_count -= m_restriction_bucket_list.at(index).size();
m_restriction_bucket_list.at(index).clear();
}
}
++m_count;
m_restriction_bucket_list.at(index)
.emplace_back(restriction.to.node, restriction.flags.is_only);
index = m_restriction_bucket_list.size();
m_restriction_bucket_list.resize(index + 1);
m_restriction_map.emplace(restriction_source, index);
}
else
{
index = restriction_iter->second;
// Map already contains an is_only_*-restriction
if (m_restriction_bucket_list.at(index).begin()->is_only)
{
continue;
}
else if (restriction.flags.is_only)
{
// We are going to insert an is_only_*-restriction. There can be only one.
m_count -= m_restriction_bucket_list.at(index).size();
m_restriction_bucket_list.at(index).clear();
}
}
++m_count;
BOOST_ASSERT(restriction.to.node < std::numeric_limits<NodeID>::max());
m_restriction_bucket_list.at(index)
.emplace_back(restriction.to.node, restriction.flags.is_only);
}
}
bool RestrictionMap::IsViaNode(const NodeID node) const
{
return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end();
}
// Replaces start edge (v, w) with (u, w). Only start node changes.
void RestrictionMap::FixupStartingTurnRestriction(const NodeID node_u,
const NodeID node_v,
@@ -145,18 +149,25 @@ bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID node_u,
}
const auto restriction_iter = m_restriction_map.find({node_u, node_v});
if (restriction_iter != m_restriction_map.end())
if (restriction_iter == m_restriction_map.end())
{
const unsigned index = restriction_iter->second;
const auto &bucket = m_restriction_bucket_list.at(index);
for (const RestrictionTarget &restriction_target : bucket)
return false;
}
const unsigned index = restriction_iter->second;
const auto &bucket = m_restriction_bucket_list.at(index);
for (const RestrictionTarget &restriction_target : bucket)
{
if (node_w == restriction_target.target_node && // target found
!restriction_target.is_only) // and not an only_-restr.
{
if ((node_w == restriction_target.target_node) && // target found
(!restriction_target.is_only) // and not an only_-restr.
)
{
return true;
}
return true;
}
if (node_w != restriction_target.target_node && // target not found
restriction_target.is_only) // and is an only restriction
{
return true;
}
}
return false;
+17 -26
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,14 +28,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef RESTRICTION_MAP_HPP
#define RESTRICTION_MAP_HPP
#include <memory>
#include "restriction.hpp"
#include "../Util/std_hash.hpp"
#include "../util/std_hash.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>
@@ -45,9 +44,7 @@ struct RestrictionSource
NodeID start_node;
NodeID via_node;
RestrictionSource(NodeID start, NodeID via) : start_node(start), via_node(via)
{
}
RestrictionSource(NodeID start, NodeID via) : start_node(start), via_node(via) {}
friend inline bool operator==(const RestrictionSource &lhs, const RestrictionSource &rhs)
{
@@ -60,9 +57,7 @@ struct RestrictionTarget
NodeID target_node;
bool is_only;
explicit RestrictionTarget(NodeID target, bool only) : target_node(target), is_only(only)
{
}
explicit RestrictionTarget(NodeID target, bool only) : target_node(target), is_only(only) {}
friend inline bool operator==(const RestrictionTarget &lhs, const RestrictionTarget &rhs)
{
@@ -96,14 +91,15 @@ template <> struct hash<RestrictionTarget>
class RestrictionMap
{
public:
RestrictionMap() : m_count(0) {};
RestrictionMap(const std::vector<TurnRestriction> &restriction_list);
// Replace end v with w in each turn restriction containing u as via node
template<class GraphT>
template <class GraphT>
void FixupArrivingTurnRestriction(const NodeID node_u,
const NodeID node_v,
const NodeID node_w,
const std::shared_ptr<GraphT> &graph)
const GraphT &graph)
{
BOOST_ASSERT(node_u != SPECIAL_NODEID);
BOOST_ASSERT(node_v != SPECIAL_NODEID);
@@ -117,9 +113,9 @@ class RestrictionMap
// find all potential start edges. It is more efficent to get a (small) list
// of potential start edges than iterating over all buckets
std::vector<NodeID> predecessors;
for (const EdgeID current_edge_id : graph->GetAdjacentEdgeRange(node_u))
for (const EdgeID current_edge_id : graph.GetAdjacentEdgeRange(node_u))
{
const NodeID target = graph->GetTarget(current_edge_id);
const NodeID target = graph.GetTarget(current_edge_id);
if (node_v != target)
{
predecessors.push_back(target);
@@ -136,6 +132,7 @@ class RestrictionMap
const unsigned index = restriction_iterator->second;
auto &bucket = m_restriction_bucket_list.at(index);
for (RestrictionTarget &restriction_target : bucket)
{
if (node_v == restriction_target.target_node)
@@ -148,24 +145,18 @@ class RestrictionMap
bool IsViaNode(const NodeID node) const;
// Replaces start edge (v, w) with (u, w). Only start node changes.
void FixupStartingTurnRestriction(const NodeID node_u,
const NodeID node_v,
const NodeID node_w);
void
FixupStartingTurnRestriction(const NodeID node_u, const NodeID node_v, const NodeID node_w);
// Check if edge (u, v) is the start of any turn restriction.
// If so returns id of first target node.
NodeID CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const;
// Checks if turn <u,v,w> is actually a turn restriction.
bool CheckIfTurnIsRestricted(const NodeID node_u,
const NodeID node_v,
const NodeID node_w) const;
bool
CheckIfTurnIsRestricted(const NodeID node_u, const NodeID node_v, const NodeID node_w) const;
std::size_t size()
{
return m_count;
}
std::size_t size() const { return m_count; }
private:
// check of node is the start of any restriction
@@ -182,4 +173,4 @@ class RestrictionMap
std::unordered_set<NodeID> m_no_turn_via_node_set;
};
#endif //RESTRICTION_MAP_HPP
#endif // RESTRICTION_MAP_HPP
+75 -13
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,15 +25,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <osrm/RouteParameters.h>
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/intrinsic.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/spirit/include/qi.hpp>
#include <osrm/route_parameters.hpp>
#include "../algorithms/polyline_compressor.hpp"
RouteParameters::RouteParameters()
: zoom_level(18), print_instructions(false), alternate_route(true), geometry(true),
compression(true), deprecatedAPI(false), uturn_default(false), check_sum(-1), num_results(1)
compression(true), deprecatedAPI(false), uturn_default(false), classify(false),
matching_beta(5), gps_precision(5), check_sum(-1), num_results(1)
{
}
@@ -57,11 +61,9 @@ void RouteParameters::setAlternateRouteFlag(const bool flag) { alternate_route =
void RouteParameters::setUTurn(const bool flag)
{
uturns.resize(coordinates.size(), uturn_default);
if (!uturns.empty())
{
uturns.back() = flag;
}
// the API grammar should make sure this never happens
BOOST_ASSERT(!uturns.empty());
uturns.back() = flag;
}
void RouteParameters::setAllUTurns(const bool flag)
@@ -83,6 +85,12 @@ void RouteParameters::setInstructionFlag(const bool flag) { print_instructions =
void RouteParameters::setService(const std::string &service_string) { service = service_string; }
void RouteParameters::setClassify(const bool flag) { classify = flag; }
void RouteParameters::setMatchingBeta(const double beta) { matching_beta = beta; }
void RouteParameters::setGPSPrecision(const double precision) { gps_precision = precision; }
void RouteParameters::setOutputFormat(const std::string &format) { output_format = format; }
void RouteParameters::setJSONpParameter(const std::string &parameter)
@@ -99,6 +107,28 @@ void RouteParameters::addHint(const std::string &hint)
}
}
void RouteParameters::addTimestamp(const unsigned timestamp)
{
timestamps.resize(coordinates.size());
if (!timestamps.empty())
{
timestamps.back() = timestamp;
}
}
void RouteParameters::addBearing(
const boost::fusion::vector<int, boost::optional<int>> &received_bearing,
boost::spirit::qi::unused_type /* unused */, bool& pass)
{
pass = false;
const int bearing = boost::fusion::at_c<0>(received_bearing);
const boost::optional<int> range = boost::fusion::at_c<1>(received_bearing);
if (bearing < 0 || bearing > 359) return;
if (range && (*range < 0 || *range > 180)) return;
bearings.emplace_back(std::make_pair(bearing,range));
pass = true;
}
void RouteParameters::setLanguage(const std::string &language_string)
{
language = language_string;
@@ -108,10 +138,42 @@ void RouteParameters::setGeometryFlag(const bool flag) { geometry = flag; }
void RouteParameters::setCompressionFlag(const bool flag) { compression = flag; }
void
RouteParameters::addCoordinate(const boost::fusion::vector<double, double> &transmitted_coordinates)
void RouteParameters::addCoordinate(
const boost::fusion::vector<double, double> &received_coordinates)
{
coordinates.emplace_back(
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(transmitted_coordinates)),
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(transmitted_coordinates)));
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
is_source.push_back(true);
is_destination.push_back(true);
uturns.push_back(uturn_default);
}
void RouteParameters::addDestination(
const boost::fusion::vector<double, double> &received_coordinates)
{
coordinates.emplace_back(
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
is_source.push_back(false);
is_destination.push_back(true);
uturns.push_back(uturn_default);
}
void RouteParameters::addSource(
const boost::fusion::vector<double, double> &received_coordinates)
{
coordinates.emplace_back(
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
is_source.push_back(true);
is_destination.push_back(false);
uturns.push_back(uturn_default);
}
void RouteParameters::getCoordinatesFromGeometry(const std::string &geometry_string)
{
PolylineCompressor pc;
coordinates = pc.decode_string(geometry_string);
}
+13 -4
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2014, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -31,7 +31,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "search_engine_data.hpp"
#include "../routing_algorithms/alternative_path.hpp"
#include "../routing_algorithms/many_to_many.hpp"
#include "../routing_algorithms/map_matching.hpp"
#include "../routing_algorithms/shortest_path.hpp"
#include "../routing_algorithms/direct_shortest_path.hpp"
#include <type_traits>
@@ -43,15 +45,22 @@ template <class DataFacadeT> class SearchEngine
public:
ShortestPathRouting<DataFacadeT> shortest_path;
DirectShortestPathRouting<DataFacadeT> direct_shortest_path;
AlternativeRouting<DataFacadeT> alternative_path;
ManyToManyRouting<DataFacadeT> distance_table;
MapMatching<DataFacadeT> map_matching;
explicit SearchEngine(DataFacadeT *facade)
: facade(facade), shortest_path(facade, engine_working_data),
alternative_path(facade, engine_working_data), distance_table(facade, engine_working_data)
: facade(facade),
shortest_path(facade, engine_working_data),
direct_shortest_path(facade, engine_working_data),
alternative_path(facade, engine_working_data),
distance_table(facade, engine_working_data),
map_matching(facade, engine_working_data)
{
static_assert(!std::is_pointer<DataFacadeT>::value, "don't instantiate with ptr type");
static_assert(std::is_object<DataFacadeT>::value, "don't instantiate with void, function, or reference");
static_assert(std::is_object<DataFacadeT>::value,
"don't instantiate with void, function, or reference");
}
~SearchEngine() {}
+19 -19
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
Copyright (c) 2013, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -31,63 +31,63 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
void SearchEngineData::InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap.get())
if (forward_heap_1.get())
{
forwardHeap->Clear();
forward_heap_1->Clear();
}
else
{
forwardHeap.reset(new QueryHeap(number_of_nodes));
forward_heap_1.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap.get())
if (reverse_heap_1.get())
{
backwardHeap->Clear();
reverse_heap_1->Clear();
}
else
{
backwardHeap.reset(new QueryHeap(number_of_nodes));
reverse_heap_1.reset(new QueryHeap(number_of_nodes));
}
}
void SearchEngineData::InitializeOrClearSecondThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap2.get())
if (forward_heap_2.get())
{
forwardHeap2->Clear();
forward_heap_2->Clear();
}
else
{
forwardHeap2.reset(new QueryHeap(number_of_nodes));
forward_heap_2.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap2.get())
if (reverse_heap_2.get())
{
backwardHeap2->Clear();
reverse_heap_2->Clear();
}
else
{
backwardHeap2.reset(new QueryHeap(number_of_nodes));
reverse_heap_2.reset(new QueryHeap(number_of_nodes));
}
}
void SearchEngineData::InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes)
{
if (forwardHeap3.get())
if (forward_heap_3.get())
{
forwardHeap3->Clear();
forward_heap_3->Clear();
}
else
{
forwardHeap3.reset(new QueryHeap(number_of_nodes));
forward_heap_3.reset(new QueryHeap(number_of_nodes));
}
if (backwardHeap3.get())
if (reverse_heap_3.get())
{
backwardHeap3->Clear();
reverse_heap_3->Clear();
}
else
{
backwardHeap3.reset(new QueryHeap(number_of_nodes));
reverse_heap_3.reset(new QueryHeap(number_of_nodes));
}
}
+7 -7
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -44,12 +44,12 @@ struct SearchEngineData
using QueryHeap = BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>>;
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
static SearchEngineHeapPtr forwardHeap;
static SearchEngineHeapPtr backwardHeap;
static SearchEngineHeapPtr forwardHeap2;
static SearchEngineHeapPtr backwardHeap2;
static SearchEngineHeapPtr forwardHeap3;
static SearchEngineHeapPtr backwardHeap3;
static SearchEngineHeapPtr forward_heap_1;
static SearchEngineHeapPtr reverse_heap_1;
static SearchEngineHeapPtr forward_heap_2;
static SearchEngineHeapPtr reverse_heap_2;
static SearchEngineHeapPtr forward_heap_3;
static SearchEngineHeapPtr reverse_heap_3;
void InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes);
+15 -13
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -25,15 +25,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SEGMENT_INFORMATION_H
#define SEGMENT_INFORMATION_H
#ifndef SEGMENT_INFORMATION_HPP
#define SEGMENT_INFORMATION_HPP
#include "turn_instructions.hpp"
#include "../data_structures/travel_mode.hpp"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <osrm/coordinate.hpp>
#include <utility>
// Struct fits everything in one cache line
struct SegmentInformation
@@ -42,13 +43,14 @@ struct SegmentInformation
NodeID name_id;
EdgeWeight duration;
float length;
short bearing; // more than enough [0..3600] fits into 12 bits
short pre_turn_bearing; // more than enough [0..3600] fits into 12 bits
short post_turn_bearing;
TurnInstruction turn_instruction;
TravelMode travel_mode;
bool necessary;
bool is_via_location;
explicit SegmentInformation(const FixedPointCoordinate &location,
explicit SegmentInformation(FixedPointCoordinate location,
const NodeID name_id,
const EdgeWeight duration,
const float length,
@@ -56,23 +58,23 @@ struct SegmentInformation
const bool necessary,
const bool is_via_location,
const TravelMode travel_mode)
: location(location), name_id(name_id), duration(duration), length(length), bearing(0),
turn_instruction(turn_instruction), travel_mode(travel_mode), necessary(necessary),
is_via_location(is_via_location)
: location(std::move(location)), name_id(name_id), duration(duration), length(length),
pre_turn_bearing(0), post_turn_bearing(0), turn_instruction(turn_instruction), travel_mode(travel_mode),
necessary(necessary), is_via_location(is_via_location)
{
}
explicit SegmentInformation(const FixedPointCoordinate &location,
explicit SegmentInformation(FixedPointCoordinate location,
const NodeID name_id,
const EdgeWeight duration,
const float length,
const TurnInstruction turn_instruction,
const TravelMode travel_mode)
: location(location), name_id(name_id), duration(duration), length(length), bearing(0),
turn_instruction(turn_instruction), travel_mode(travel_mode),
: location(std::move(location)), name_id(name_id), duration(duration), length(length),
pre_turn_bearing(0), post_turn_bearing(0), turn_instruction(turn_instruction), travel_mode(travel_mode),
necessary(turn_instruction != TurnInstruction::NoTurn), is_via_location(false)
{
}
};
#endif /* SEGMENT_INFORMATION_H */
#endif /* SEGMENT_INFORMATION_HPP */
+38 -23
View File
@@ -1,6 +1,6 @@
/*
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
Copyright (c) 2015, Project OSRM contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
@@ -28,8 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SHARED_MEMORY_FACTORY_HPP
#define SHARED_MEMORY_FACTORY_HPP
#include "../Util/osrm_exception.hpp"
#include "../Util/simple_logger.hpp"
#include "../util/osrm_exception.hpp"
#include "../util/simple_logger.hpp"
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
@@ -99,6 +99,7 @@ class SharedMemory
SharedMemory() = delete;
SharedMemory(const SharedMemory &) = delete;
SharedMemory &operator=(const SharedMemory &) = delete;
template <typename IdentifierT>
SharedMemory(const boost::filesystem::path &lock_file,
@@ -123,10 +124,10 @@ class SharedMemory
{
Remove(key);
}
shm = boost::interprocess::xsi_shared_memory(
boost::interprocess::open_or_create, key, size);
shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_or_create, key,
size);
#ifdef __linux__
if (-1 == shmctl(shm.get_shmid(), SHM_LOCK, 0))
if (-1 == shmctl(shm.get_shmid(), SHM_LOCK, nullptr))
{
if (ENOMEM == errno)
{
@@ -150,7 +151,10 @@ class SharedMemory
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
result = RegionExists(key);
}
catch (...) { result = false; }
catch (...)
{
result = false;
}
return result;
}
@@ -165,8 +169,14 @@ class SharedMemory
static bool RegionExists(const boost::interprocess::xsi_key &key)
{
bool result = true;
try { boost::interprocess::xsi_shared_memory shm(boost::interprocess::open_only, key); }
catch (...) { result = false; }
try
{
boost::interprocess::xsi_shared_memory shm(boost::interprocess::open_only, key);
}
catch (...)
{
result = false;
}
return result;
}
@@ -198,12 +208,14 @@ class SharedMemory
// Windows - specific code
class SharedMemory
{
SharedMemory(const SharedMemory&) = delete;
SharedMemory(const SharedMemory &) = delete;
SharedMemory &operator=(const SharedMemory &) = delete;
// Remove shared memory on destruction
class shm_remove
{
private:
shm_remove(const shm_remove&) = delete;
shm_remove(const shm_remove &) = delete;
shm_remove &operator=(const shm_remove &) = delete;
char *m_shmid;
bool m_initialized;
@@ -242,8 +254,7 @@ class SharedMemory
if (0 == size)
{ // read_only
shm = boost::interprocess::shared_memory_object(
boost::interprocess::open_only,
key,
boost::interprocess::open_only, key,
read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
region = boost::interprocess::mapped_region(
shm, read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
@@ -255,8 +266,8 @@ class SharedMemory
{
Remove(key);
}
shm = boost::interprocess::shared_memory_object(
boost::interprocess::open_or_create, key, boost::interprocess::read_write);
shm = boost::interprocess::shared_memory_object(boost::interprocess::open_or_create,
key, boost::interprocess::read_write);
shm.truncate(size);
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_write);
@@ -274,7 +285,10 @@ class SharedMemory
build_key(id, k);
result = RegionExists(k);
}
catch (...) { result = false; }
catch (...)
{
result = false;
}
return result;
}
@@ -286,20 +300,20 @@ class SharedMemory
}
private:
static void build_key(int id, char *key)
{
sprintf(key, "%s.%d", "osrm.lock", id);
}
static void build_key(int id, char *key) { sprintf(key, "%s.%d", "osrm.lock", id); }
static bool RegionExists(const char *key)
{
bool result = true;
try
{
boost::interprocess::shared_memory_object shm(
boost::interprocess::open_only, key, boost::interprocess::read_write);
boost::interprocess::shared_memory_object shm(boost::interprocess::open_only, key,
boost::interprocess::read_write);
}
catch (...)
{
result = false;
}
catch (...) { result = false; }
return result;
}
@@ -364,6 +378,7 @@ template <class LockFileT = OSRMLockFile> class SharedMemoryFactory_tmpl
SharedMemoryFactory_tmpl() = delete;
SharedMemoryFactory_tmpl(const SharedMemoryFactory_tmpl &) = delete;
SharedMemoryFactory_tmpl &operator=(const SharedMemoryFactory_tmpl &) = delete;
};
using SharedMemoryFactory = SharedMemoryFactory_tmpl<>;

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