Compare commits

..

1104 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
Dennis Luxen 725b93a961 Merge branch 'develop' 2015-01-06 11:03:29 +01:00
Dennis Luxen a21e4c5a0b link library against exception lib 2015-01-06 11:00:44 +01:00
Dennis Luxen 433db17083 fix initialization of simple client 2015-01-05 18:14:49 +01:00
Dennis Luxen f8753fb9f1 fix overly long line 2015-01-05 16:32:11 +01:00
Dennis Luxen 25d5653f66 rename a number of overly long variable names 2015-01-05 16:29:33 +01:00
Dennis Luxen 703a88a639 remove empty d'tor from osrm::exception 2015-01-05 15:53:28 +01:00
Dennis Luxen 25326b571b renamed: Util/OSRMException.h -> Util/osrm_exception.hpp 2015-01-05 15:40:05 +01:00
Dennis Luxen 5e2f4c9d2d fix header include 2015-01-05 14:47:05 +01:00
Dennis Luxen f43d380fe2 remove unneeded method 2015-01-05 14:46:38 +01:00
Dennis Luxen 2240d3d0d1 add new header file 2015-01-05 14:39:17 +01:00
Dennis Luxen b6eea9a880 fix unintended implicit cast from unsigned to signed 2015-01-05 14:38:24 +01:00
Dennis Luxen 6bbd7c0c0b update ignore list in git 2015-01-05 14:37:35 +01:00
Dennis Luxen 2caeb4008c renamed: Util/GitDescription.cpp.in -> Util/git_sha.cpp.in
renamed:    Util/GitDescription.h -> Util/git_sha.h
2015-01-05 14:32:04 +01:00
Dennis Luxen a4919ffb45 re-enable hintin mechanism 2015-01-05 12:59:29 +01:00
Dennis Luxen b384340cbb Revert "remove remnants of hinting mechanism"
This reverts commit 7de428233e.
2015-01-05 12:57:34 +01:00
Dennis Luxen 061f46306f remove unneeded lvalue parameter 2015-01-05 12:00:11 +01:00
Dennis Luxen fe1f11b071 renamed: Util/StringUtil.h -> Util/string_util.hpp 2015-01-05 10:22:11 +01:00
Patrick Niklaus d3f5db576a Enable gcc color output when available 2015-01-04 23:13:15 +01:00
Emil Tin 0ca586e1c8 cuke: remove unneeded @x tag 2015-01-03 16:53:01 +01:00
Emil Tin a0b55f9df3 table tests: use empty string to mean no route 2015-01-03 11:12:47 +01:00
Dennis Luxen 24943ccee6 fix use of old-style cast 2015-01-02 17:43:46 +01:00
Dennis Luxen bcaaf34fa7 implicit conversion loses integer precision 2015-01-02 17:41:11 +01:00
Dennis Luxen ea17d1f6c7 dynamic exception specifications are deprecated, use 'noexcept' instead 2015-01-02 17:39:11 +01:00
Dennis Luxen 3be734010c fix warning: 'const' type qualifier on return type has no effect 2015-01-02 17:34:21 +01:00
Dennis Luxen e79787cc77 reorder members to avoid padding class 'SimpleLogger' with 4 bytes to align 'os' 2015-01-02 17:32:52 +01:00
Dennis Luxen 7de428233e remove remnants of hinting mechanism 2015-01-02 17:10:47 +01:00
Dennis Luxen 9722f56be8 remove more debug code 2015-01-02 16:41:36 +01:00
Dennis Luxen e766d206f1 remove debug code 2015-01-02 16:06:09 +01:00
Dennis Luxen 1fa9091239 retire json hinting mechanism 2015-01-02 15:46:43 +01:00
Dennis Luxen 04e1e5e3a2 reformat code 2015-01-02 15:17:15 +01:00
Dennis Luxen fa5c0560fa use tiny cc id if all phantoms have such an id, and if and only if all ids are equal 2015-01-02 09:36:27 +01:00
Dennis Luxen 55d47b3e31 reimplement incremental nearest neighbor query 2015-01-02 09:36:27 +01:00
Dennis Luxen 5bb96fd477 reformat code of phantom node c'tor for legibility 2015-01-02 09:36:27 +01:00
Dennis Luxen 22b404a1b4 add is_in_tiny_cc() util function 2015-01-02 09:36:27 +01:00
Dennis Luxen 03dcf82602 use first phantom node of second pair 2015-01-02 09:36:26 +01:00
Dennis Luxen 95d1e8a4f1 adapt viaroute plugin to query NN search for vector of phantom nodes 2015-01-02 09:36:26 +01:00
Emil Tin 67f68b47db add fuzzy match to table tests, add more tests 2015-01-01 20:19:41 +01:00
Emil Tin 593808f24d initial support for testing distance matrices 2015-01-01 15:12:45 +01:00
Dennis Luxen 0a884cc64a don't stop traversing at bollard node 2014-12-31 16:04:53 +01:00
Dennis Luxen a54d4b98b1 add const keyword in range based for loop 2014-12-31 16:04:53 +01:00
Patrick Niklaus 23132e5292 Use >= 0 to include routes where start/end is the same 2014-12-31 15:59:42 +01:00
Dennis Luxen d741b624be pass component class by ref (not value) in edge-based graph factory 2014-12-30 11:44:11 +01:00
Patrick Niklaus 00bc394bdb Fix off-by-one in distance table plugin.
Should fix #1320.
2014-12-28 17:45:55 +01:00
Dennis Luxen d7215ad185 fix tests, temporarily disable one test case 2014-12-24 13:03:05 +01:00
Dennis Luxen 2b63eb8243 remove zoom level from nearest neighbor calls 2014-12-24 10:40:03 +01:00
Dennis Luxen 1bb3da0332 expose component_id in phantom node 2014-12-24 10:25:27 +01:00
Dennis Luxen c7d3d635f6 fix test compile 2014-12-23 17:18:32 +01:00
Dennis Luxen f4c8db6105 - serialize component_id
- remove calls to deprecated NN function in facades
2014-12-23 16:14:28 +01:00
Dennis Luxen b2637b9a43 compute component id for each SCC 2014-12-23 15:26:06 +01:00
Dennis Luxen 09d0ac3838 add aux. function to get component id for a given node 2014-12-23 15:17:38 +01:00
Dennis Luxen f42cc848d5 - correct number of components in compressed graph by number of removed nodes
- replace integer for loops by integer range-based loop
2014-12-23 14:51:25 +01:00
Dennis Luxen 4b1224f874 fix copyright year 2014-12-23 14:38:04 +01:00
Dennis Luxen 10bb2cce8e count number of removed nodes as a private member variable in EdgeBasedGraphFactory 2014-12-23 14:37:01 +01:00
Dennis Luxen 8174b3b85a output total number of compoments and those of size one 2014-12-23 14:33:38 +01:00
Dennis Luxen 71e2f2ed61 move SCC stats output out of algo implementation 2014-12-23 14:31:55 +01:00
Dennis Luxen 8d8724b3e1 use SCC code for exploration of components 2014-12-23 12:27:04 +01:00
Dennis Luxen 47f65ccba6 use restriction map in tiny components 2014-12-23 11:47:19 +01:00
Dennis Luxen df0c1106ce compile and link restriction map object to components and routes 2014-12-23 11:46:25 +01:00
Dennis Luxen 47a2271e27 copy edits: 2014-12-23 11:30:45 +01:00
Dennis Luxen ea367a7f37 add better checks for forbidden routes 2014-12-22 18:12:47 +01:00
Dennis Luxen f4b192e33c simplify code 2014-12-22 18:12:18 +01:00
Dennis Luxen a5c824f694 adapt tiny_components.hpp to have the same interface as bfs_components.hpp 2014-12-22 16:43:57 +01:00
Dennis Luxen ccc4607d6d renamed: Util/GraphLoader.h -> Util/graph_loader.hpp 2014-12-22 16:09:01 +01:00
Dennis Luxen 4ec41392f7 code cleanup in graph loading function 2014-12-22 16:03:22 +01:00
Dennis Luxen 5f2b2cd0f7 remove dead code 2014-12-22 15:53:11 +01:00
Dennis Luxen 361e3ca356 fix a copy&paste oversight, fixes #1319
remove UINT_MAX
2014-12-22 15:11:37 +01:00
Dennis Luxen 13bf4fab32 make implementation of restriction map independent of graph type 2014-12-19 16:46:12 +01:00
Dennis Luxen 4b583e8ce9 replace insecure std::rand by C++11's random number generation
fixes coverity issue 1248916 Don't call
2014-12-19 10:59:12 +01:00
Dennis Luxen d31c6fe286 fix coverity issue 1258907 Division or modulo by float zero 2014-12-19 10:49:33 +01:00
Dennis Luxen 79de97d814 move application logic, i.e. shape file generation, from SCC traversal class to calling tool code 2014-12-18 18:14:14 +01:00
Dennis Luxen 1c5d093b59 Revert "catch uncaught exception"
This reverts commit ecff2beafa.
2014-12-18 16:42:14 +01:00
Dennis Luxen ecff2beafa catch uncaught exception 2014-12-18 16:11:49 +01:00
Dennis Luxen 7e0b19c43d renamed Util/StdHashExtensions.h -> Util/std_hash.hpp 2014-12-18 10:09:31 +01:00
Dennis Luxen 2ebe2faa74 renamed Util/TimingUtil.h -> Util/timing_util.hpp 2014-12-17 17:33:31 +01:00
Dennis Luxen aec1451168 add workaround for Windows build issues. 2014-12-17 16:24:43 +01:00
Dennis Luxen 38251aa513 construct RequestParser object on demand
pass CompressionType refs instead of ptrs to parser
2014-12-17 15:48:33 +01:00
Dennis Luxen d92e8ca8d2 remove unneeded function 2014-12-17 15:09:07 +01:00
Dennis Luxen 2e5876d488 add lock_guard to protect against data races in initialization of scripting environment
rename function names to reduce camel case noise
2014-12-17 14:34:23 +01:00
Dennis Luxen 3dddd16ec7 bump osmium version 2014-12-17 11:19:08 +01:00
Dennis Luxen 40ff7ad999 update speed profile from external calibration data 2014-12-17 11:02:04 +01:00
Dennis Luxen cb79f769c9 Merge pull request #1312 from joto/const
Some cleanups in the extractor code.
2014-12-12 17:10:47 -08:00
Jochen Topf e95feff016 Use 'const' where possible in extractor and simplify iterator loop. 2014-12-13 00:23:41 +01:00
Jochen Topf f65b32c1af Use atomics for counters. 2014-12-13 00:16:32 +01:00
Dennis Luxen 46dd9b9887 remove duplicated paths 2014-12-13 00:09:25 +01:00
Dennis Luxen 4445f21e8a renamed: Tools/* -> tools/* 2014-11-28 15:36:40 +01:00
Dennis Luxen 00d3676a20 renamed: RoutingAlgorithms/* routing_algorithms/ 2014-11-28 15:33:41 +01:00
Dennis Luxen 0f7cb12e97 renamed: ThirdParty/* -> third_party/* 2014-11-28 15:22:26 +01:00
Dennis Luxen 8485e02c00 renamed: Plugins/* -> plugins/* 2014-11-28 15:14:13 +01:00
Dennis Luxen ae7300f9b4 renamed: extractor.cpp -> extract.cpp
renamed:    Extractor/* -> extractor/
2014-11-28 15:00:48 +01:00
Dennis Luxen fc796539e8 deleted: Docs/webclient.txt 2014-11-28 14:39:28 +01:00
Dennis Luxen 1d8c43b445 renamed: Descriptors/* -> descriptors/* 2014-11-28 14:36:38 +01:00
Dennis Luxen 58de37e822 renamed: DataStructures/* -> data_structures/* 2014-11-28 12:15:31 +01:00
Dennis Luxen 7b3a0c5105 renamed: Contractor/* -> contractor/* 2014-11-28 10:30:21 +01:00
Dennis Luxen 592034653c renamed: Benchmarks/* -> benchmarks/*s 2014-11-28 10:15:27 +01:00
Dennis Luxen 8d9f830c53 change includes to lower case algorithms/ 2014-11-28 10:12:08 +01:00
Dennis Luxen d8eea0ce0e renamed: Algorithms/* -> algorithms/* 2014-11-28 10:07:06 +01:00
Dennis Luxen c28c441e77 renamed: Contractor.h -> contractor.hpp 2014-11-27 19:07:59 +01:00
Dennis Luxen 1391420699 renamed: ../Benchmarks/StaticRTreeBench.cpp -> ../Benchmarks/static_rtree.cpp 2014-11-27 19:04:30 +01:00
Dennis Luxen c0be751ef4 renamed: DataStructures/SegmentInformation.h -> DataStructures/segment_information.hpp 2014-11-27 18:54:20 +01:00
Dennis Luxen 5e2462e061 renamed: DataStructures/RestrictionMap.cpp -> DataStructures/restriction_map.cpp
renamed:    DataStructures/RestrictionMap.h -> DataStructures/restriction_map.hpp
2014-11-27 18:38:21 +01:00
Dennis Luxen 5c0eb4772d renamed: Util/LuaUtil.h -> Util/lua_util.hpp 2014-11-27 18:31:01 +01:00
Dennis Luxen ef8706b4e1 fix inconsistencies with integer and iterator range header files, closes #1296 2014-11-27 09:54:57 +01:00
Dennis Luxen acd1919e8d renamed: Util/Azimuth.h -> Util/bearing.hpp 2014-11-26 16:55:18 +01:00
Dennis Luxen 459e2a322b cast computed way in a proper way, add a static assertion to check for file types via traits 2014-11-26 12:05:55 +01:00
Dennis Luxen e62caf33aa Merge pull request #1294 from alex85k/appveyor
update appveyor.yml (newer libraries, algorithm-tests)
2014-11-26 09:46:05 +01:00
alex85k 72fd0f3d41 update appveyor.yml (newer libraries, algorithm-tests) 2014-11-26 12:38:04 +03:00
Dennis Luxen 032c21c545 fix mixed up include header <numeric> <-> <cmath> 2014-11-25 14:52:21 +01:00
Dennis Luxen b391daac6d use C++11's std::round from <numeric> instead of C-style round from cstdlib 2014-11-25 14:49:33 +01:00
Dennis Luxen 8cb6959e3f untangle includes 2014-11-24 15:51:52 +01:00
Dennis Luxen 49c817a60e remove redundant clear() calls in Extractor.cpp 2014-11-24 15:42:55 +01:00
Dennis Luxen 6859b53155 use JSON container to hold all intermediate results:
- no hand-rolled GPX generation anymore
- render gpx thru a JSONContainer visitor pattern
- precursor to expose JSON containter as result from OSRM lib interface, cf. #1261
2014-11-24 15:15:57 +01:00
Dennis Luxen c581563230 fix setting of restriction end nodes, fixes #1286, and potentially #1287 2014-11-24 11:29:25 +01:00
Patrick Niklaus fc1db35f27 Add missing json dependency to cucumber 2014-11-23 13:29:22 +01:00
Patrick Niklaus 2734a4aee4 Merge pull request #1284 from Project-OSRM/algo-test-fix
Fix DP unit test
2014-11-22 16:22:07 +01:00
Patrick Niklaus 172f65969c Fix DP unit test 2014-11-22 13:47:20 +01:00
Dennis Luxen f0dbe0deb9 fix compilation 2014-11-21 09:35:20 +01:00
Dennis Luxen 8f8d81f90c renamed: Algorithms/StronglyConnectedComponents.h -> Algorithms/tiny_components.hpp 2014-11-20 17:21:35 +01:00
Dennis Luxen 665523bc7e add springclean tool to ignore list 2014-11-20 17:05:55 +01:00
Dennis Luxen 99e8fa70ba renamed: Algorithms/DouglasPeucker.cpp -> Algorithms/douglas_peucker.cpp
renamed:    Algorithms/DouglasPeucker.h -> Algorithms/douglas_peucker.hpp
2014-11-20 17:04:52 +01:00
Dennis Luxen 4c1d7c9d73 renamed: Algorithms/ExtractRouteNames.h -> Algorithms/route_name_extraction.hpp 2014-11-20 17:01:36 +01:00
Dennis Luxen d1cc8e7ad7 renamed: Algorithms/BFSComponentExplorer.h -> Algorithms/bfs_components.hpp 2014-11-20 16:58:35 +01:00
Dennis Luxen 7629e44e4c renamed: Algorithms/IteratorBasedCRC32.h -> Algorithms/crc32_processor.hpp 2014-11-20 16:17:49 +01:00
Dennis Luxen b62f6a6141 renamed: Algorithms/ObjectToBase64.h -> Algorithms/object_encoder.hpp 2014-11-20 16:10:11 +01:00
Dennis Luxen 10d7a2396c move JSON rendering code out of container header file. prerequesite to #1261 2014-11-20 15:26:30 +01:00
Dennis Luxen 007eced326 fix variant include 2014-11-20 15:14:19 +01:00
Dennis Luxen 1128270d4b fix short variable names 2014-11-20 15:06:48 +01:00
Dennis Luxen c7d889bf9e add missing break 2014-11-20 15:02:02 +01:00
Dennis Luxen 7cb585c1a1 remove constant conditional operator 2014-11-20 15:00:49 +01:00
Dennis Luxen 75157221b2 commit another if statement 2014-11-20 14:59:27 +01:00
Dennis Luxen 9807520ef0 collapse if statement 2014-11-20 14:58:32 +01:00
Dennis Luxen c658ee5c78 fix OCLint warning: short variable name, unused parameter 2014-11-20 14:55:43 +01:00
Dennis Luxen cbfbcdcff5 reformat RestrictionParser 2014-11-20 10:46:14 +01:00
Dennis Luxen 9a0581ea7f Merge pull request #1159 from Project-OSRM/feature/libosmium
parallelizing profile calls and porting lib osmium to Windows
2014-11-20 10:20:09 +01:00
Dennis Luxen 60c268ddd6 reorder some of the code 2014-11-19 11:02:38 +01:00
Dennis Luxen 0361e0204a rename Clear() method to clear() 2014-11-19 10:53:28 +01:00
Dennis Luxen 2da427134b use push_back to insert into tbb::concurrent_vector as emplace_back is not generally available 2014-11-19 10:12:08 +01:00
Dennis Luxen 4fce0dadcf remove further debug output from profiles 2014-11-19 09:58:41 +01:00
Dennis Luxen 288c241fb4 move initialization of Lua error callback into scripting environment 2014-11-19 09:49:39 +01:00
Dennis Luxen f3e3eda69e remove debug output from bike profile 2014-11-19 09:47:23 +01:00
Dennis Luxen 0f4dd8103d add cast.hpp from osmium 2014-11-19 09:44:02 +01:00
Dennis Luxen 86ee05ee5e add missing include 2014-11-19 09:22:31 +01:00
Dennis Luxen 3b9c6a6465 reformat Extractor 2014-11-18 19:03:44 +01:00
Dennis Luxen 8e73a4a19d enable relation parsing with libosmium 2014-11-18 18:53:19 +01:00
Dennis Luxen 428bb36ec6 parallelize with a vector of iterators 2014-11-18 16:54:48 +01:00
Dennis Luxen 0a24df6bd0 Merge pull request #1279 from Project-OSRM/config-parsing-fix
Fix ignored config file. Fixes issue #1276.
2014-11-18 14:09:03 +01:00
Patrick Niklaus d3ca080729 Fix windows build. 2014-11-18 11:52:39 +01:00
Patrick Niklaus 7658031784 Fix ignored config file. Fixes issue #1276. 2014-11-18 00:43:38 +01:00
Dennis Luxen 710e74219a libosmium version bump 2014-11-17 14:58:39 +01:00
Dennis Luxen 0249bed53a bump variant dependency 2014-11-17 14:58:39 +01:00
Dennis Luxen 9d14f81b79 set default timestamp for tests 2014-11-17 14:58:39 +01:00
Dennis Luxen a7c683a83c forward way ID information properly in turn restrictions parsing 2014-11-17 14:58:38 +01:00
Dennis Luxen 16631bf454 port track smoothness to new parsing 2014-11-17 14:58:38 +01:00
Dennis Luxen 3c563f7073 rebase branch onto most recent changes from develop branch 2014-11-17 14:58:38 +01:00
Dennis Luxen 344bdbb707 basic parallelization infrastructure 2014-11-17 14:58:38 +01:00
Dennis Luxen a0256dfc60 add error callback when calling get_exceptions 2014-11-17 14:58:38 +01:00
Dennis Luxen b131f27eb9 use_turn_restrictions as global in car profile 2014-11-17 14:58:38 +01:00
Dennis Luxen 0d9b70552e refactor FirstAndLastSegmentOfWay 2014-11-17 14:58:38 +01:00
Dennis Luxen ea1a89290a uncouple configuration of Extractor into compile unit 2014-11-17 14:58:38 +01:00
Dennis Luxen 59f1679d37 move LUA error callback function into anonymous namespace 2014-11-17 14:58:37 +01:00
Dennis Luxen 5121983218 Rename NodeInfo -> QueryNode 2014-11-17 14:58:37 +01:00
Dennis Luxen 0d7141ce5b Rename NodeInfo -> QueryNode 2014-11-17 14:58:37 +01:00
Dennis Luxen b4b753ce2e rename variables in ExternalMemoryNode to be more telling and consistent 2014-11-17 14:58:37 +01:00
Dennis Luxen 4f666e4d53 remove dead code 2014-11-17 14:58:37 +01:00
Dennis Luxen 874a988527 add dummy NodeID.h (to move into include) 2014-11-17 14:58:37 +01:00
Dennis Luxen 51c79f9784 rename ExtractorStructs into a more telling name 2014-11-17 14:58:37 +01:00
Dennis Luxen 4d19811026 apply reformatting 2014-11-17 14:58:37 +01:00
Dennis Luxen d1454075ab untangle function object code for stxxl comperators 2014-11-17 14:58:37 +01:00
Dennis Luxen becb6cf5bf compile renamed object file 2014-11-17 14:58:36 +01:00
Dennis Luxen a6f34d2044 rename ImportNode.h/cpp -> ExternalMemoryNode.h/cpp 2014-11-17 14:58:36 +01:00
Dennis Luxen 7300024e13 remove unneeded code: HashTable 2014-11-17 14:58:36 +01:00
Dennis Luxen 282800e6b1 replace boost::optional with mapbox::util::optional 2014-11-17 14:58:36 +01:00
Dennis Luxen e938bd3481 Revert "remove implicitly defined inline keywords from header-implemented functions in Util/ headers"
This reverts commit dc35e97ae002bdfda4bc3a68507749c464cfe371.
2014-11-17 14:58:36 +01:00
Dennis Luxen 9b501276fb upgrade variant dependency 2014-11-17 14:58:36 +01:00
Dennis Luxen 90d191f5f8 remove implicitly defined inline keywords from header-implemented functions in Extractor/ExtractionHelperFunctions.h 2014-11-17 14:58:36 +01:00
Dennis Luxen f452e7f9d2 remove implicitly defined inline keywords from header-implemented functions in Util/ headers 2014-11-17 14:58:36 +01:00
Dennis Luxen 1d25f41122 remove unused code 2014-11-17 14:58:36 +01:00
Dennis Luxen 5556785804 remove implicitly defined inline keywords from header-implemented functions in ExtractionWay 2014-11-17 14:58:35 +01:00
Dennis Luxen 22ce4c24fb move key/value wrapper function into anonymous namespace in ScriptingEnvironment 2014-11-17 14:58:35 +01:00
Dennis Luxen d4d2d127d1 pass an rvalue of a parsed node into the external memory storage 2014-11-17 14:58:35 +01:00
Dennis Luxen 3c28932862 remove errenous define in AppVeyor cmake call 2014-11-17 14:58:35 +01:00
Dennis Luxen 7e9177cb3c link against expat.lib 2014-11-17 14:58:35 +01:00
Dennis Luxen f692103c81 fix build on windows by linking against the right libs 2014-11-17 14:58:35 +01:00
Dennis Luxen 5a1dfe9b89 include variant library from a relative path 2014-11-17 14:58:35 +01:00
Dennis Luxen 7175180dc9 remove deprecated code 2014-11-17 14:58:34 +01:00
Dennis Luxen f95d1fa8ba add expat to cmake call on AppVeyor 2014-11-17 14:58:34 +01:00
Dennis Luxen 7b57068f6f manually install osmpbf, the one on Travis is outdated 2014-11-17 14:58:34 +01:00
Dennis Luxen d79eac3e26 port foot profile 2014-11-17 14:58:34 +01:00
Dennis Luxen 27c255c874 port bicycle profile 2014-11-17 14:58:34 +01:00
Dennis Luxen bdc611b23a port timestamp test to libosmium 2014-11-17 14:58:34 +01:00
Dennis Luxen 4cddf0bf5d replace explicit value fetching with wrapper call 2014-11-17 14:58:34 +01:00
Dennis Luxen 462d4c99cc port testbot profile 2014-11-17 14:58:34 +01:00
Dennis Luxen 94a2188090 explicitly specify optional parameter 2014-11-17 14:58:33 +01:00
Dennis Luxen ebcdcb5f00 port car profile 2014-11-17 14:58:33 +01:00
Dennis Luxen f9e780ed67 add a wrapper function to work around binding a function with default parameters against LuaBind 2014-11-17 14:58:33 +01:00
Dennis Luxen 18f8ce69cd remove default c'tor in ScriptingEnvironment 2014-11-17 14:58:33 +01:00
Dennis Luxen dce665f14e reformat ExtractorCallbacks 2014-11-17 14:58:33 +01:00
Dennis Luxen 80046b646b actually parse the data that flowing thru osmium 2014-11-17 14:58:33 +01:00
Dennis Luxen 06ddceeac0 reset travel modes on ExtractionWay::clear() 2014-11-17 14:58:33 +01:00
Dennis Luxen b7ea1dfcd0 fix generation of file names 2014-11-17 14:58:33 +01:00
Dennis Luxen 6d9598cd4c link against expat not libxml2, good riddance 2014-11-17 14:58:33 +01:00
Dennis Luxen 60c9701c3f reduce white space noise 2014-11-17 14:58:32 +01:00
Dennis Luxen 2a8644b72c expose libosmium types to LUA 2014-11-17 14:58:32 +01:00
Dennis Luxen b6e469abd1 implement parsing thru libosmium 2014-11-17 14:58:32 +01:00
Dennis Luxen 004c237085 implement restriction type interface in RestrictionMap 2014-11-17 14:58:32 +01:00
Dennis Luxen 398e3bdf82 implement new restriction type interface in PrepareData 2014-11-17 14:58:32 +01:00
Dennis Luxen 958350af82 add InputRestrictionContainer implementation 2014-11-17 14:58:32 +01:00
Dennis Luxen 2d677a8af9 support new restriction type in component analysis 2014-11-17 14:58:32 +01:00
Dennis Luxen 05a79f5b55 implement loader routines for new restriction type 2014-11-17 14:58:31 +01:00
Dennis Luxen ac9566d3d7 add include dir to libosmium 2014-11-17 14:58:31 +01:00
Dennis Luxen 8b7bf94aae implement new Restriction type 2014-11-17 14:58:31 +01:00
Dennis Luxen c4e785e523 remove explicit keyword from WayIDStartAndEndEdge ctor 2014-11-17 14:58:31 +01:00
Dennis Luxen 2f6f883f7f implement ExtractionWay and -Node 2014-11-17 14:58:31 +01:00
Dennis Luxen d071e92a1c implement restriction parsing 2014-11-17 14:58:31 +01:00
Dennis Luxen b18b4072e1 implement restriction parsing 2014-11-17 14:58:31 +01:00
Dennis Luxen 0a2898da17 remove legacy extrators 2014-11-17 14:58:30 +01:00
Dennis Luxen 73fb596973 add libosmium 2014-11-17 14:58:30 +01:00
Dennis Luxen c3f9dc7400 Merge pull request #1271 from alex85k/mingw-full
Support building tools on Windows, more MinGW
2014-11-17 09:18:40 +01:00
alex85k c75ce210ea support building tools on Windows 2014-11-16 21:33:41 +05:00
Dennis Luxen ffca6d8ba5 Merge pull request #1268 from alex85k/develop
fix appveyor packaging - 2
2014-11-14 09:25:01 +01:00
alex85k 1ec35befc8 package .exe, .pdb and lua profiles on AppVeyor 2014-11-14 00:37:07 +05:00
Dennis Luxen 6080eaebbd Merge pull request #1267 from alex85k/develop
fix appveyor packaging
2014-11-13 17:26:48 +01:00
alex85k 41ea339053 fix appveyor packaging 2014-11-13 20:16:40 +03:00
Dennis Luxen 75f9c08445 Merge pull request #1266 from Project-OSRM/revert-1256-patch-1
Revert "fix #1255 assume lift gates are passable"
2014-11-13 14:24:09 +01:00
Dennis Luxen cec3d1488a Revert "fix #1255 assume lift gates are passable" 2014-11-13 14:23:54 +01:00
Dennis Luxen ebec082da2 Merge pull request #1256 from AlanBell/patch-1
fix #1255 assume lift gates are passable
2014-11-13 14:23:42 +01:00
Dennis Luxen bec585e382 update distance table entries only if larger than 0. 2014-11-13 13:45:21 +01:00
Dennis Luxen 2cc8ae875a Merge pull request #1259 from Steffaan/develop
Update NearestPlugin.h to return correct names on mulitple results.
2014-11-11 10:33:49 -08:00
Dennis Luxen db8252e650 Merge branch 'AlanBell-patch-1' into develop 2014-11-11 09:47:53 -08:00
Dennis Luxen e3cb26a1c4 Merge branch 'patch-1' of https://github.com/AlanBell/osrm-backend into AlanBell-patch-1 2014-11-11 09:47:16 -08:00
Stefan 44036ae26d Update NearestPlugin.h to return correct names on mulitple results. 2014-11-11 18:22:32 +01:00
AlanBell 5b5f871a6e Merge pull request #1 from AlanBell/master
test case for lift gate access
2014-11-11 09:26:54 +00:00
AlanBell 9a8f9cae6d test case for lift gate access 2014-11-11 09:16:57 +00:00
AlanBell 8f804581c0 fix #1255 assume lift gates are passable
lift gates are commonly found on industrial parks or businesses, delivery drivers need to route to these, most gates are permissive and open in daytime, this patch won't route through gates where access is specifically no.
2014-11-07 10:29:25 +00:00
Dennis Luxen e26ef17545 reserve delta vector beforehand to avoid realocations. 2014-11-01 17:32:49 -04:00
Dennis Luxen 800bb223b5 remove unused variable 2014-11-01 17:15:20 -04:00
Dennis Luxen 75606f2100 reformatting 2014-10-31 12:15:09 -04:00
Dennis Luxen a28928e6ca use double braces for array initialization as brace elision is implemented/supported differently in GCC and Clang 2014-10-29 10:39:23 -04:00
Dennis Luxen 8700007025 Merge branch 'revert-1240-revert-1217-sketch-upstream' into develop 2014-10-29 10:18:44 -04:00
Patrick Niklaus 520f7fa2de Add UnitTest for DP
Conflicts:
	CMakeLists.txt
2014-10-29 00:40:34 +01:00
Patrick Niklaus 096208a154 Move DP thresholds back to header, since they are needed for testing
Conflicts:
	Algorithms/DouglasPeucker.cpp
2014-10-29 00:38:52 +01:00
Patrick Niklaus 27caab69ec Fix broken DP 2014-10-29 00:37:45 +01:00
Patrick Niklaus 3fe2b587cb Revert "Revert "Bring general sketch commits upstream"" 2014-10-29 00:33:43 +01:00
Dennis Luxen c791188811 separate logic between polyline compression algorithm and JSON formatting.
fixes and closes #1245
2014-10-28 17:31:51 -04:00
Dennis Luxen b227c90c18 remove redundant local variable 2014-10-28 11:11:06 -04:00
Dennis Luxen 8a5538356b remove redundant local variable 2014-10-28 10:39:29 -04:00
Dennis Luxen b257c881b5 explicit casts help mitigate MSVC warnery 2014-10-28 10:36:09 -04:00
Dennis Luxen 0f5dffb1c3 add some specific casts to avoid MSVC warnery 2014-10-28 10:36:02 -04:00
Dennis Luxen d2bd238274 Merge pull request #1244 from Project-OSRM/run_unittests_on_travis
Run unittests on travis
2014-10-28 10:35:22 -04:00
Dennis Luxen fed700440d pick different random seed to avoid edge case 2014-10-28 09:49:55 -04:00
Dennis Luxen 32a9d42412 run datastructure unit tests on travis 2014-10-28 09:14:43 -04:00
Dennis Luxen efc938d870 fix building of tests/benchmark 2014-10-28 09:11:14 -04:00
Dennis Luxen 369f669227 break out PhantomNode.h into a header/impl combo, rename to new naming scheme. 2014-10-27 17:56:06 -04:00
Dennis Luxen 1c56671f01 reformat to break overly long lines 2014-10-27 17:34:50 -04:00
Dennis Luxen 4dbc1e0e96 reformat to fix OCLint long line warning 2014-10-27 13:20:33 -04:00
Dennis Luxen 94288843f1 make entire_length variable a private member that cannot be set from the outside and only accessed thru a const getter. 2014-10-27 12:21:29 -04:00
Dennis Luxen b12decc865 Merge pull request #1240 from Project-OSRM/revert-1217-sketch-upstream
Revert "Bring general sketch commits upstream"
2014-10-27 10:08:17 -04:00
Dennis Luxen 0fc944abf3 Revert "Bring general sketch commits upstream" 2014-10-27 10:07:07 -04:00
Dennis Luxen 9f96c98f02 Merge pull request #1217 from TheMarex/sketch-upstream
Bring general sketch commits upstream
2014-10-26 10:19:24 -04:00
Patrick Niklaus 9805b05738 Reorder include and use correct datatypes 2014-10-25 10:14:31 +02:00
Patrick Niklaus 13ed186469 Fix include order in staticrtree 2014-10-25 10:14:31 +02:00
Patrick Niklaus 00a43221ac Use numeric_limits 2014-10-25 10:14:31 +02:00
Patrick Niklaus edc39112e2 Add wrapper function to DouglasPlucker for backwards-compability 2014-10-23 16:23:54 +02:00
Patrick Niklaus 3b727dea99 Make atan2_lookup inline since it is header-declared 2014-10-23 16:23:54 +02:00
Patrick Niklaus f16b2adec7 Allow empty ranges in DP 2014-10-23 16:23:54 +02:00
Patrick Niklaus 7d425aa76f Use iterators for DouglasPeucker 2014-10-23 16:23:54 +02:00
Patrick Niklaus 651c07c724 Add global timer utils
Global timers can be used to accumulate timings of the same context
in a thread-safe way.
2014-10-23 16:23:54 +02:00
Patrick Niklaus 4d27b75897 Move Rectangle2DInt to own header 2014-10-23 16:23:54 +02:00
Dennis Luxen 6f75d68d07 untangle includes 2014-10-23 16:11:54 +02:00
Dennis Luxen ae269e12bb disable debug code in rtree 2014-10-23 16:11:35 +02:00
Dennis Luxen 3a48929fe6 add benchmark for a single coordinate incremental lookup 2014-10-23 16:11:01 +02:00
Dennis Luxen be970326b6 remove superflous include from library 2014-10-22 19:28:15 +02:00
Dennis Luxen 463511871f Refactor routing plugins:
- remove superflous members from RawRouteData, partially implements #1238
- DescriptorTable moved to BaseDescriptor.h
- added templated assignment c'tor to DescriptorConfig
- refactored check for valid input coordinates, moved to BasePlugin.h
- replaced shared_ptr's to descriptors in ViaRoutePlugin.h with unique_ptr
- implemented FindIncrementalPhantomNode in facades for a single, i.e. first result
- untangled a few includes
2014-10-22 19:02:19 +02:00
Dennis Luxen 002da1e02d add range-based for_each_pair 2014-10-22 18:56:14 +02:00
Dennis Luxen b095aae5ce some minor include untangling 2014-10-21 19:05:56 +02:00
Dennis Luxen 511c21029e To arrive at a later point in time: Revert "remove inline keywords"
This reverts commit 81b0447024.
2014-10-21 18:34:50 +02:00
Dennis Luxen 81b0447024 remove inline keywords 2014-10-21 18:06:58 +02:00
700 changed files with 101177 additions and 17706 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'
...
+6 -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/FingerPrint.cpp
/Util/GitDescription.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
@@ -81,6 +66,7 @@ stxxl.errlog
/osrm-unlock-all
/osrm-cli
/osrm-check-hsgr
/osrm-springclean
/nohup.out
# Sandbox folder #
+140 -51
View File
@@ -1,57 +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 libosmpbf-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
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
- 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
-112
View File
@@ -1,112 +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 "PolylineCompressor.h"
#include "../DataStructures/SegmentInformation.h"
#include <osrm/Coordinate.h>
void PolylineCompressor::encodeVectorSignedNumber(std::vector<int> &numbers,
std::string &output) const
{
const unsigned end = static_cast<unsigned>(numbers.size());
for (unsigned i = 0; i < end; ++i)
{
numbers[i] <<= 1;
if (numbers[i] < 0)
{
numbers[i] = ~(numbers[i]);
}
}
for (const int number : numbers)
{
encodeNumber(number, output);
}
}
void PolylineCompressor::encodeNumber(int number_to_encode, std::string &output) const
{
while (number_to_encode >= 0x20)
{
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);
}
}
JSON::String
PolylineCompressor::printEncodedString(const std::vector<SegmentInformation> &polyline) const
{
std::string output;
std::vector<int> delta_numbers;
if (!polyline.empty())
{
FixedPointCoordinate last_coordinate = {0, 0};
for (const auto &segment : polyline)
{
if (segment.necessary)
{
const int lat_diff = segment.location.lat - last_coordinate.lat;
const int lon_diff = segment.location.lon - last_coordinate.lon;
delta_numbers.emplace_back(lat_diff);
delta_numbers.emplace_back(lon_diff);
last_coordinate = segment.location;
}
}
encodeVectorSignedNumber(delta_numbers, output);
}
JSON::String return_value(output);
return return_value;
}
JSON::Array
PolylineCompressor::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
{
JSON::Array json_geometry_array;
for (const auto &segment : polyline)
{
if (segment.necessary)
{
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);
}
}
return json_geometry_array;
}
-459
View File
@@ -1,459 +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 STRONGLYCONNECTEDCOMPONENTS_H_
#define STRONGLYCONNECTEDCOMPONENTS_H_
#include "../typedefs.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/ImportEdge.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/TurnInstructions.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/StdHashExtensions.h"
#include "../Util/TimingUtil.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <tbb/parallel_sort.h>
#ifdef __APPLE__
#include <gdal.h>
#include <ogrsf_frmts.h>
#else
#include <gdal/gdal.h>
#include <gdal/ogrsf_frmts.h>
#endif
#include <cstdint>
#include <memory>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
class TarjanSCC
{
private:
struct TarjanNode
{
TarjanNode() : index(SPECIAL_NODEID), low_link(SPECIAL_NODEID), on_stack(false) {}
unsigned index;
unsigned low_link;
bool on_stack;
};
struct TarjanEdgeData
{
TarjanEdgeData() : distance(INVALID_EDGE_WEIGHT), name_id(INVALID_NAMEID) {}
TarjanEdgeData(int distance, unsigned name_id) : distance(distance), name_id(name_id) {}
int distance;
unsigned name_id;
};
struct TarjanStackFrame
{
explicit TarjanStackFrame(NodeID v, NodeID parent) : v(v), parent(parent) {}
NodeID v;
NodeID parent;
};
using TarjanDynamicGraph = DynamicGraph<TarjanEdgeData>;
using TarjanEdge = TarjanDynamicGraph::InputEdge;
using RestrictionSource = std::pair<NodeID, NodeID>;
using RestrictionTarget = std::pair<NodeID, bool>;
using EmanatingRestrictionsVector = std::vector<RestrictionTarget>;
using RestrictionMap = std::unordered_map<RestrictionSource, unsigned>;
std::vector<NodeInfo> m_coordinate_list;
std::vector<EmanatingRestrictionsVector> m_restriction_bucket_list;
std::shared_ptr<TarjanDynamicGraph> m_node_based_graph;
std::unordered_set<NodeID> barrier_node_list;
std::unordered_set<NodeID> traffic_light_list;
unsigned m_restriction_counter;
RestrictionMap m_restriction_map;
public:
TarjanSCC(int number_of_nodes,
std::vector<NodeBasedEdge> &input_edges,
std::vector<NodeID> &bn,
std::vector<NodeID> &tl,
std::vector<TurnRestriction> &irs,
std::vector<NodeInfo> &nI)
: m_coordinate_list(nI), m_restriction_counter(irs.size())
{
TIMER_START(SCC_LOAD);
for (const TurnRestriction &restriction : irs)
{
std::pair<NodeID, NodeID> restriction_source = {restriction.fromNode,
restriction.viaNode};
unsigned index = 0;
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator == 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_iterator->second;
// Map already contains an is_only_*-restriction
if (m_restriction_bucket_list.at(index).begin()->second)
{
continue;
}
else if (restriction.flags.isOnly)
{
// We are going to insert an is_only_*-restriction. There can be only one.
m_restriction_bucket_list.at(index).clear();
}
}
m_restriction_bucket_list.at(index)
.emplace_back(restriction.toNode, restriction.flags.isOnly);
}
barrier_node_list.insert(bn.begin(), bn.end());
traffic_light_list.insert(tl.begin(), tl.end());
DeallocatingVector<TarjanEdge> edge_list;
for (const NodeBasedEdge &input_edge : input_edges)
{
if (input_edge.source == input_edge.target)
{
continue;
}
if (input_edge.forward)
{
edge_list.emplace_back(input_edge.source,
input_edge.target,
(std::max)((int)input_edge.weight, 1),
input_edge.name_id);
}
if (input_edge.backward)
{
edge_list.emplace_back(input_edge.target,
input_edge.source,
(std::max)((int)input_edge.weight, 1),
input_edge.name_id);
}
}
input_edges.clear();
input_edges.shrink_to_fit();
BOOST_ASSERT_MSG(0 == input_edges.size() && 0 == input_edges.capacity(),
"input edge vector not properly deallocated");
tbb::parallel_sort(edge_list.begin(), edge_list.end());
m_node_based_graph = std::make_shared<TarjanDynamicGraph>(number_of_nodes, edge_list);
TIMER_STOP(SCC_LOAD);
SimpleLogger().Write() << "Loading data into SCC took " << TIMER_MSEC(SCC_LOAD)/1000. << "s";
}
~TarjanSCC() { m_node_based_graph.reset(); }
void Run()
{
TIMER_START(SCC_RUN_SETUP);
// remove files from previous run if exist
DeleteFileIfExists("component.dbf");
DeleteFileIfExists("component.shx");
DeleteFileIfExists("component.shp");
Percent p(m_node_based_graph->GetNumberOfNodes());
OGRRegisterAll();
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver *poDriver =
OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName);
if (nullptr == poDriver)
{
throw OSRMException("ESRI Shapefile driver not available");
}
OGRDataSource *poDS = poDriver->CreateDataSource("component.shp", nullptr);
if (nullptr == poDS)
{
throw OSRMException("Creation of output file failed");
}
OGRSpatialReference *poSRS = new OGRSpatialReference();
poSRS->importFromEPSG(4326);
OGRLayer *poLayer = poDS->CreateLayer("component", poSRS, wkbLineString, nullptr);
if (nullptr == poLayer)
{
throw OSRMException("Layer creation failed.");
}
TIMER_STOP(SCC_RUN_SETUP);
SimpleLogger().Write() << "shapefile setup took " << TIMER_MSEC(SCC_RUN_SETUP)/1000. << "s";
TIMER_START(SCC_RUN);
// 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<unsigned> components_index(m_node_based_graph->GetNumberOfNodes(),
SPECIAL_NODEID);
std::vector<NodeID> component_size_vector;
std::vector<TarjanNode> tarjan_node_list(m_node_based_graph->GetNumberOfNodes());
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))
{
if (SPECIAL_NODEID == components_index[node])
{
recursion_stack.emplace(TarjanStackFrame(node, node));
}
while (!recursion_stack.empty())
{
TarjanStackFrame currentFrame = recursion_stack.top();
const NodeID v = currentFrame.v;
recursion_stack.pop();
const bool before_recursion = processing_node_before_recursion[v];
if (before_recursion && tarjan_node_list[v].index != UINT_MAX)
{
continue;
}
if (before_recursion)
{
// Mark frame to handle tail of recursion
recursion_stack.emplace(currentFrame);
processing_node_before_recursion[v] = false;
// Mark essential information for SCC
tarjan_node_list[v].index = index;
tarjan_node_list[v].low_link = index;
tarjan_stack.push(v);
tarjan_node_list[v].on_stack = true;
++index;
// Traverse outgoing edges
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(v))
{
const TarjanDynamicGraph::NodeIterator vprime =
m_node_based_graph->GetTarget(current_edge);
if (SPECIAL_NODEID == tarjan_node_list[vprime].index)
{
recursion_stack.emplace(TarjanStackFrame(vprime, v));
}
else
{
if (tarjan_node_list[vprime].on_stack &&
tarjan_node_list[vprime].index < tarjan_node_list[v].low_link)
{
tarjan_node_list[v].low_link = tarjan_node_list[vprime].index;
}
}
}
}
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);
// 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)
{
NodeID vprime;
do
{
vprime = tarjan_stack.top();
tarjan_stack.pop();
tarjan_node_list[vprime].on_stack = false;
components_index[vprime] = component_index;
++size_of_current_component;
} while (v != vprime);
component_size_vector.emplace_back(size_of_current_component);
if (size_of_current_component > 1000)
{
SimpleLogger().Write() << "large component [" << component_index
<< "]=" << size_of_current_component;
}
++component_index;
size_of_current_component = 0;
}
}
}
}
TIMER_STOP(SCC_RUN);
SimpleLogger().Write() << "SCC run took: " << TIMER_MSEC(SCC_RUN)/1000. << "s";
SimpleLogger().Write() << "identified: " << component_size_vector.size()
<< " many components, marking small components";
TIMER_START(SCC_OUTPUT);
const unsigned size_one_counter = std::count_if(component_size_vector.begin(),
component_size_vector.end(),
[](unsigned value)
{
return 1 == value;
});
SimpleLogger().Write() << "identified " << size_one_counter << " SCCs of size 1";
uint64_t total_network_distance = 0;
p.reinit(m_node_based_graph->GetNumberOfNodes());
// const NodeID last_u_node = m_node_based_graph->GetNumberOfNodes();
for (const NodeID source : osrm::irange(0u, last_node))
{
p.printIncrement();
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(source))
{
const TarjanDynamicGraph::NodeIterator target =
m_node_based_graph->GetTarget(current_edge);
if (source < target ||
m_node_based_graph->EndEdges(target) ==
m_node_based_graph->FindEdge(target, source))
{
total_network_distance +=
100 * FixedPointCoordinate::ApproximateEuclideanDistance(
m_coordinate_list[source].lat,
m_coordinate_list[source].lon,
m_coordinate_list[target].lat,
m_coordinate_list[target].lon);
BOOST_ASSERT(current_edge != SPECIAL_EDGEID);
BOOST_ASSERT(source != SPECIAL_NODEID);
BOOST_ASSERT(target != SPECIAL_NODEID);
const unsigned size_of_containing_component =
std::min(component_size_vector[components_index[source]],
component_size_vector[components_index[target]]);
// edges that end on bollard nodes may actually be in two distinct components
if (size_of_containing_component < 10)
{
OGRLineString lineString;
lineString.addPoint(m_coordinate_list[source].lon / COORDINATE_PRECISION,
m_coordinate_list[source].lat / COORDINATE_PRECISION);
lineString.addPoint(m_coordinate_list[target].lon / COORDINATE_PRECISION,
m_coordinate_list[target].lat / COORDINATE_PRECISION);
OGRFeature *poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());
poFeature->SetGeometry(&lineString);
if (OGRERR_NONE != poLayer->CreateFeature(poFeature))
{
throw OSRMException("Failed to create feature in shapefile.");
}
OGRFeature::DestroyFeature(poFeature);
}
}
}
}
OGRDataSource::DestroyDataSource(poDS);
component_size_vector.clear();
component_size_vector.shrink_to_fit();
BOOST_ASSERT_MSG(0 == component_size_vector.size() && 0 == component_size_vector.capacity(),
"component_size_vector not properly deallocated");
components_index.clear();
components_index.shrink_to_fit();
BOOST_ASSERT_MSG(0 == components_index.size() && 0 == components_index.capacity(),
"components_index not properly deallocated");
TIMER_STOP(SCC_OUTPUT);
SimpleLogger().Write() << "generating output took: " << TIMER_MSEC(SCC_OUTPUT)/1000. << "s";
SimpleLogger().Write() << "total network distance: "
<< (uint64_t)total_network_distance / 100 / 1000. << " km";
}
private:
unsigned CheckForEmanatingIsOnlyTurn(const NodeID u, const NodeID v) const
{
std::pair<NodeID, NodeID> restriction_source = {u, v};
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
for (const RestrictionSource &restriction_target : m_restriction_bucket_list.at(index))
{
if (restriction_target.second)
{
return restriction_target.first;
}
}
}
return SPECIAL_NODEID;
}
bool CheckIfTurnIsRestricted(const NodeID u, const NodeID v, const NodeID w) const
{
// only add an edge if turn is not a U-turn except it is the end of dead-end street.
std::pair<NodeID, NodeID> restriction_source = {u, v};
const auto restriction_iterator = m_restriction_map.find(restriction_source);
if (restriction_iterator != m_restriction_map.end())
{
const unsigned index = restriction_iterator->second;
for (const RestrictionTarget &restriction_target : m_restriction_bucket_list.at(index))
{
if (w == restriction_target.first)
{
return true;
}
}
}
return false;
}
void DeleteFileIfExists(const std::string &file_name) const
{
if (boost::filesystem::exists(file_name))
{
boost::filesystem::remove(file_name);
}
}
};
#endif /* STRONGLYCONNECTEDCOMPONENTS_H_ */
-130
View File
@@ -1,130 +0,0 @@
#include "../DataStructures/OriginalEdgeData.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/SharedMemoryVectorWrapper.h"
#include "../DataStructures/StaticRTree.h"
#include "../Util/BoostFileSystemFix.h"
#include "../DataStructures/EdgeBasedNode.h"
#include <osrm/Coordinate.h>
#include <random>
// Choosen by a fair W20 dice roll (this value is completely arbitrary)
constexpr unsigned RANDOM_SEED = 13;
constexpr int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION;
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>;
FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes_file)
{
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
NodeInfo current_node;
unsigned number_of_coordinates = 0;
nodes_input_stream.read((char *)&number_of_coordinates, sizeof(unsigned));
auto coords = std::make_shared<std::vector<FixedPointCoordinate>>(number_of_coordinates);
for (unsigned i = 0; i < number_of_coordinates; ++i)
{
nodes_input_stream.read((char *)&current_node, sizeof(NodeInfo));
coords->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon);
BOOST_ASSERT((std::abs(coords->at(i).lat) >> 30) == 0);
BOOST_ASSERT((std::abs(coords->at(i).lon) >> 30) == 0);
}
nodes_input_stream.close();
return coords;
}
void Benchmark(BenchStaticRTree &rtree, unsigned num_queries)
{
std::mt19937 mt_rand(RANDOM_SEED);
std::uniform_int_distribution<> lat_udist(WORLD_MIN_LAT, WORLD_MAX_LAT);
std::uniform_int_distribution<> lon_udist(WORLD_MIN_LON, WORLD_MAX_LON);
std::vector<FixedPointCoordinate> queries;
for (unsigned i = 0; i < num_queries; i++)
{
queries.emplace_back(FixedPointCoordinate(lat_udist(mt_rand), lon_udist(mt_rand)));
}
const unsigned num_results = 5;
std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results
<< " phantom nodes"
<< "\n";
TIMER_START(query_phantom);
std::vector<PhantomNode> resulting_phantom_node_vector;
for (const auto &q : queries)
{
resulting_phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, resulting_phantom_node_vector, 3, num_results);
resulting_phantom_node_vector.clear();
rtree.IncrementalFindPhantomNodeForCoordinate(
q, resulting_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_phantomnode);
for (const auto &q : queries)
{
PhantomNode phantom;
rtree.FindPhantomNodeForCoordinate(q, phantom, 3);
}
TIMER_STOP(query_phantomnode);
std::cout << "Took " << TIMER_MSEC(query_phantomnode) << " msec for " << num_queries
<< " queries."
<< "\n";
std::cout << TIMER_MSEC(query_phantomnode) / ((double)num_queries) << " msec/query."
<< "\n";
}
int main(int argc, char **argv)
{
if (argc < 4)
{
std::cout << "./rtree-bench file.ramIndex file.fileIndx file.nodes"
<< "\n";
return 1;
}
const char *ramPath = argv[1];
const char *filePath = argv[2];
const char *nodesPath = argv[3];
auto coords = LoadCoordinates(nodesPath);
BenchStaticRTree rtree(ramPath, filePath, coords);
Benchmark(rtree, 10000);
return 0;
}
+218 -107
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,78 +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_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/FingerPrint.cpp FingerPrint.cpp.alwaysbuild
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FingerPrint-Config.cmake
DEPENDS
${CMAKE_SOURCE_DIR}/Util/FingerPrint.cpp.in
COMMENT "Configuring FingerPrint.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/FingerPrint.cpp)
add_custom_target(tests DEPENDS datastructure-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/GitDescription.cpp.in
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util/version.hpp.in
${CMAKE_CURRENT_BINARY_DIR}/util/version.hpp
)
file(GLOB ExtractorGlob Extractor/*.cpp)
file(GLOB ImporterGlob DataStructures/Import*.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(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 extractor.cpp ${ExtractorGlob})
add_executable(osrm-extract ${ExtractorSources} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER>)
set(ExtractorSources extract.cpp ${ExtractorGlob})
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>)
file(GLOB PrepareGlob Contractor/*.cpp DataStructures/HilbertValue.cpp DataStructures/RestrictionMap.cpp Util/compute_angle.cpp)
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 {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>)
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 DescriptorGlob Descriptors/*.cpp)
file(GLOB DatastructureGlob DataStructures/SearchEngineData.cpp DataStructures/RouteParameters.cpp)
list(REMOVE_ITEM DatastructureGlob DataStructures/Coordinate.cpp)
file(GLOB CoordinateGlob DataStructures/Coordinate.cpp)
file(GLOB AlgorithmGlob Algorithms/*.cpp)
file(GLOB HttpGlob Server/Http/*.cpp)
file(GLOB LibOSRMGlob Library/*.cpp)
file(GLOB DataStructureTestsGlob UnitTests/DataStructures/*.cpp DataStructures/HilbertValue.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)
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/FingerPrint.cpp)
add_library(GITDESCRIPTION OBJECT Util/GitDescription.cpp)
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
add_dependencies(FINGERPRINT FingerPrintConfigure)
add_executable(osrm-routed routed.cpp ${ServerGlob})
add_executable(osrm-datastore datastore.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
add_library(COORDINATE OBJECT ${CoordinateGlob})
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: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>)
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/StaticRTreeBench.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER>)
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)
@@ -102,61 +121,112 @@ 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
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)
if(NOT HAS_COLOR_FLAG)
set(COLOR_FLAG "")
endif()
# using GCC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC")
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)
add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation
add_definitions(-D_USE_MATH_DEFINES) # define M_PI
add_definitions(-D_WIN32_WINNT=0x0501)
add_definitions(-DXML_STATIC)
find_library(ws2_32_LIBRARY_PATH ws2_32)
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
@@ -181,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})
@@ -194,6 +263,8 @@ target_link_libraries(osrm-prepare ${Boost_LIBRARIES})
target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
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)
@@ -202,6 +273,7 @@ target_link_libraries(osrm-datastore ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(osrm-prepare ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(OSRM ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(datastructure-tests ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(algorithm-tests ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(rtree-bench ${CMAKE_THREAD_LIBS_INIT})
find_package(TBB REQUIRED)
@@ -213,81 +285,88 @@ target_link_libraries(osrm-extract ${TBB_LIBRARIES})
target_link_libraries(osrm-prepare ${TBB_LIBRARIES})
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(LibXml2 REQUIRED)
include_directories(${LIBXML2_INCLUDE_DIR})
target_link_libraries(osrm-extract ${LIBXML2_LIBRARIES})
find_package(EXPAT REQUIRED)
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})
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})
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(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>)
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: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: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>)
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: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>)
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)
@@ -297,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
@@ -308,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()
-782
View File
@@ -1,782 +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 "EdgeBasedGraphFactory.h"
#include "../Algorithms/BFSComponentExplorer.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/Range.h"
#include "../Util/compute_angle.hpp"
#include "../Util/LuaUtil.h"
#include "../Util/simple_logger.hpp"
#include "../Util/TimingUtil.h"
#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<NodeInfo> &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)
{
// 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 bool belongs_to_tiny_cc)
{
// 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 = 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),
i,
belongs_to_tiny_cc,
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,
0,
belongs_to_tiny_cc,
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);
unsigned removed_node_count = 0;
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_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u);
m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u);
// 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 (NodeID current_node = 0; current_node < m_node_based_graph->GetNumberOfNodes();
++current_node)
{
for (EdgeID 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 road network";
// Run a BFS on the undirected graph and identify small components
BFSComponentExplorer<NodeBasedDynamicGraph> component_explorer(
*m_node_based_graph, *m_restriction_map, m_barrier_nodes);
component_explorer.run();
SimpleLogger().Write() << "identified: " << component_explorer.GetNumberOfComponents()
<< " many components";
SimpleLogger().Write() << "generating edge-expanded nodes";
Percent progress(m_node_based_graph->GetNumberOfNodes());
// loop over all edges and generate new set of nodes
for (NodeID u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u)
{
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.GetComponentSize(u),
component_explorer.GetComponentSize(v));
const bool component_is_tiny = (size_of_component < 1000);
if (edge_data.edgeBasedNodeID == SPECIAL_NODEID)
{
InsertEdgeBasedNode(v, u, component_is_tiny);
}
else
{
InsertEdgeBasedNode(u, v, component_is_tiny);
}
}
}
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 (NodeID u = 0, end = m_node_based_graph->GetNumberOfNodes(); u < end; ++u)
{
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 (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;
}
-126
View File
@@ -1,126 +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.
*/
// This class constructs the edge-expanded routing graph
#ifndef EDGEBASEDGRAPHFACTORY_H_
#define EDGEBASEDGRAPHFACTORY_H_
#include "../typedefs.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/EdgeBasedNode.h"
#include "../DataStructures/OriginalEdgeData.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/TurnInstructions.h"
#include "../DataStructures/NodeBasedGraph.h"
#include "../DataStructures/RestrictionMap.h"
#include "GeometryCompressor.h"
#include <algorithm>
#include <iosfwd>
#include <memory>
#include <queue>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
struct lua_State;
class EdgeBasedGraphFactory
{
public:
EdgeBasedGraphFactory() = delete;
EdgeBasedGraphFactory(const EdgeBasedGraphFactory &) = delete;
struct SpeedProfileProperties;
explicit EdgeBasedGraphFactory(const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
std::unique_ptr<RestrictionMap> restricion_map,
std::vector<NodeID> &barrier_node_list,
std::vector<NodeID> &traffic_light_node_list,
std::vector<NodeInfo> &m_node_info_list,
SpeedProfileProperties &speed_profile);
void Run(const std::string &original_edge_data_filename,
const std::string &geometry_filename,
lua_State *lua_state);
void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges);
void GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes);
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, const double angle) const;
int GetTurnPenalty(double angle, lua_State *lua_state) const;
unsigned GetNumberOfEdgeBasedNodes() const;
struct SpeedProfileProperties
{
SpeedProfileProperties()
: traffic_signal_penalty(0), u_turn_penalty(0), has_turn_penalty_function(false)
{
}
int traffic_signal_penalty;
int u_turn_penalty;
bool has_turn_penalty_function;
} speed_profile;
private:
using EdgeData = NodeBasedDynamicGraph::EdgeData;
unsigned m_number_of_edge_based_nodes;
std::vector<NodeInfo> m_node_info_list;
std::vector<EdgeBasedNode> m_edge_based_node_list;
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
std::unordered_set<NodeID> m_barrier_nodes;
std::unordered_set<NodeID> m_traffic_lights;
std::unique_ptr<RestrictionMap> m_restriction_map;
GeometryCompressor m_geometry_compressor;
void CompressGeometry();
void RenumberEdges();
void GenerateEdgeExpandedNodes();
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
lua_State *lua_state);
void InsertEdgeBasedNode(const NodeID u, const NodeID v, const bool belongsToTinyComponent);
void FlushVectorToStream(std::ofstream &edge_data_file,
std::vector<OriginalEdgeData> &original_edge_data_vector) const;
NodeID max_id;
};
#endif /* EDGEBASEDGRAPHFACTORY_H_ */
-575
View File
@@ -1,575 +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 "Prepare.h"
#include "Contractor.h"
#include "../Algorithms/IteratorBasedCRC32.h"
#include "../DataStructures/BinaryHeap.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/StaticRTree.h"
#include "../DataStructures/RestrictionMap.h"
#include "../Util/GitDescription.h"
#include "../Util/LuaUtil.h"
#include "../Util/make_unique.hpp"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include "../typedefs.h"
#include <boost/filesystem/fstream.hpp>
#include <boost/program_options.hpp>
#include <tbb/task_scheduler_init.h>
#include <tbb/parallel_sort.h>
#include <chrono>
#include <memory>
#include <string>
#include <thread>
#include <vector>
Prepare::Prepare() : requested_num_threads(1) {}
Prepare::~Prepare() {}
int Prepare::Process(int argc, char *argv[])
{
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!");
#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())
{
SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
return 1;
}
SimpleLogger().Write() << restriction_list.size() << " restrictions, "
<< barrier_node_list.size() << " bollard nodes, "
<< traffic_light_list.size() << " traffic lights";
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);
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);
TIMER_START(contraction);
contractor->Run();
TIMER_STOP(contraction);
SimpleLogger().Write() << "Contraction took " << TIMER_SEC(contraction) << " sec";
DeallocatingVector<QueryEdge> contracted_edge_list;
contractor->GetEdges(contracted_edge_list);
contractor.reset();
/***
* 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]
{
unsigned tmp_max = 0;
for (const QueryEdge &edge : contracted_edge_list)
{
BOOST_ASSERT(SPECIAL_NODEID != edge.source);
BOOST_ASSERT(SPECIAL_NODEID != edge.target);
tmp_max = std::max(tmp_max, edge.source);
tmp_max = std::max(tmp_max, edge.target);
}
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";
std::vector<StaticGraph<EdgeData>::NodeArrayEntry> node_array;
node_array.resize(number_of_edge_based_nodes + 1);
SimpleLogger().Write() << "Building node array";
StaticGraph<EdgeData>::EdgeIterator edge = 0;
StaticGraph<EdgeData>::EdgeIterator position = 0;
StaticGraph<EdgeData>::EdgeIterator last_edge = edge;
// initializing 'first_edge'-field of nodes:
for (const auto node : osrm::irange(0u, max_used_node_id))
{
last_edge = edge;
while ((edge < contracted_edge_count) && (contracted_edge_list[edge].source == node))
{
++edge;
}
node_array[node].first_edge = position; //=edge
position += edge - last_edge; // remove
}
for (const auto sentinel_counter : osrm::irange<unsigned>(max_used_node_id, node_array.size()))
{
// sentinel element, guarded against underflow
node_array[sentinel_counter].first_edge = contracted_edge_count;
}
SimpleLogger().Write() << "Serializing node array";
const unsigned node_array_size = node_array.size();
// serialize crc32, aka checksum
hsgr_output_stream.write((char *)&crc32_value, sizeof(unsigned));
// serialize number of nodes
hsgr_output_stream.write((char *)&node_array_size, sizeof(unsigned));
// serialize number of edges
hsgr_output_stream.write((char *)&contracted_edge_count, sizeof(unsigned));
// serialize all nodes
if (node_array_size > 0)
{
hsgr_output_stream.write((char *)&node_array[0],
sizeof(StaticGraph<EdgeData>::NodeArrayEntry) * node_array_size);
}
// serialize all edges
SimpleLogger().Write() << "Building edge array";
edge = 0;
int number_of_used_edges = 0;
StaticGraph<EdgeData>::EdgeArrayEntry current_edge;
for (const auto edge : osrm::irange<std::size_t>(0, contracted_edge_list.size()))
{
// no eigen loops
BOOST_ASSERT(contracted_edge_list[edge].source != contracted_edge_list[edge].target);
current_edge.target = contracted_edge_list[edge].target;
current_edge.data = contracted_edge_list[edge].data;
// every target needs to be valid
BOOST_ASSERT(current_edge.target < max_used_node_id);
#ifndef NDEBUG
if (current_edge.data.distance <= 0)
{
SimpleLogger().Write(logWARNING) << "Edge: " << edge
<< ",source: " << contracted_edge_list[edge].source
<< ", target: " << contracted_edge_list[edge].target
<< ", dist: " << current_edge.data.distance;
SimpleLogger().Write(logWARNING) << "Failed at adjacency list of node "
<< contracted_edge_list[edge].source << "/"
<< node_array.size() - 1;
return 1;
}
#endif
hsgr_output_stream.write((char *)&current_edge,
sizeof(StaticGraph<EdgeData>::EdgeArrayEntry));
++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;
}
/**
\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);
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 =
std::unique_ptr<RestrictionMap>(new RestrictionMap(node_based_graph, 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
*/
void Prepare::WriteNodeMapping()
{
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(NodeInfo));
}
node_stream.close();
internal_to_external_node_map.clear();
internal_to_external_node_map.shrink_to_fit();
}
/**
\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);
}
-67
View File
@@ -1,67 +0,0 @@
#ifndef PREPARE_H
#define PREPARE_H
#include "EdgeBasedGraphFactory.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/StaticGraph.h"
#include "../Util/GraphLoader.h"
#include <boost/filesystem.hpp>
#include <luabind/luabind.hpp>
#include <vector>
/**
\brief class of 'prepare' utility.
*/
class Prepare
{
public:
using EdgeData = QueryEdge::EdgeData;
using InputEdge = DynamicGraph<EdgeData>::InputEdge;
using StaticEdge = StaticGraph<EdgeData>::InputEdge;
explicit Prepare();
Prepare(const Prepare &) = delete;
~Prepare();
int Process(int argc, char *argv[]);
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);
private:
std::vector<NodeInfo> 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;
};
#endif // PREPARE_H
-83
View File
@@ -1,83 +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 CONCURRENT_QUEUE_H
#define CONCURRENT_QUEUE_H
#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_H
-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/StringUtil.h"
#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::isValid() 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.isValid());
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.isValid());
// 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.isValid());
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));
}
-98
View File
@@ -1,98 +0,0 @@
#ifndef EDGE_BASED_NODE_H
#define EDGE_BASED_NODE_H
#include "../DataStructures/TravelMode.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
#include <limits>
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),
fwd_segment_position( std::numeric_limits<unsigned short>::max() ),
is_in_tiny_cc(false),
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 short fwd_segment_position,
bool belongs_to_tiny_component,
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),
fwd_segment_position(fwd_segment_position),
is_in_tiny_cc(belongs_to_tiny_component),
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)
{
FixedPointCoordinate centroid;
//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;
}
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
unsigned packed_geometry_id; // if set, then the edge represents a packed geometry
unsigned short fwd_segment_position; // segment id in a compressed geometry
bool is_in_tiny_cc;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
};
#endif //EDGE_BASED_NODE_H
-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
-244
View File
@@ -1,244 +0,0 @@
#ifndef NODE_BASED_GRAPH_H_
#define NODE_BASED_GRAPH_H_
#include "DynamicGraph.h"
#include "ImportEdge.h"
#include "../Util/simple_logger.hpp"
#include <tbb/parallel_sort.h>
#include <memory>
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)
{
}
int distance;
unsigned edgeBasedNodeID;
unsigned nameID;
bool isAccessRestricted : 1;
bool shortcut : 1;
bool forward : 1;
bool backward : 1;
bool roundabout : 1;
bool ignore_in_grid : 1;
TravelMode travel_mode : 4;
void SwapDirectionFlags()
{
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) &&
(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
inline std::shared_ptr<NodeBasedDynamicGraph>
NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge> &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)
{
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;
}
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;
}
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;
}
#endif // NODE_BASED_GRAPH_H_
-181
View File
@@ -1,181 +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 PHANTOM_NODES_H
#define PHANTOM_NODES_H
#include <osrm/Coordinate.h>
#include "../DataStructures/TravelMode.h"
#include "../Util/simple_logger.hpp"
#include "../typedefs.h"
#include <vector>
struct 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, 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),
location(location),
fwd_segment_position(fwd_segment_position),
forward_travel_mode(forward_travel_mode),
backward_travel_mode(backward_travel_mode)
{ }
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),
fwd_segment_position(0),
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
{ }
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;
FixedPointCoordinate location;
unsigned short fwd_segment_position;
TravelMode forward_travel_mode : 4;
TravelMode backward_travel_mode : 4;
int GetForwardWeightPlusOffset() const
{
if (SPECIAL_NODEID == forward_node_id)
{
return 0;
}
const int result = (forward_offset + forward_weight);
return result;
}
int GetReverseWeightPlusOffset() const
{
if (SPECIAL_NODEID == reverse_node_id)
{
return 0;
}
const int result = (reverse_offset + reverse_weight);
return result;
}
bool isBidirected() const
{
return (forward_node_id != SPECIAL_NODEID) &&
(reverse_node_id != SPECIAL_NODEID);
}
bool IsCompressed() const
{
return (forward_offset != 0) || (reverse_offset != 0);
}
bool isValid(const unsigned numberOfNodes) const
{
return
location.isValid() &&
(
(forward_node_id < numberOfNodes) ||
(reverse_node_id < numberOfNodes)
) &&
(
(forward_weight != INVALID_EDGE_WEIGHT) ||
(reverse_weight != INVALID_EDGE_WEIGHT)
) &&
(name_id != std::numeric_limits<unsigned>::max()
);
}
bool isValid() const
{
return location.isValid() &&
(name_id != std::numeric_limits<unsigned>::max());
}
bool operator==(const PhantomNode & other) const
{
return location == other.location;
}
};
using PhantomNodeArray = std::vector<std::vector<PhantomNode>>;
struct PhantomNodeLists
{
std::vector<PhantomNode> source_phantom_list;
std::vector<PhantomNode> target_phantom_list;
};
struct PhantomNodes
{
PhantomNode source_phantom;
PhantomNode target_phantom;
};
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)
{
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 << ", " <<
"pos: " << pn.fwd_segment_position << ", " <<
"loc: " << pn.location;
return out;
}
#endif // PHANTOM_NODES_H
File diff suppressed because it is too large Load Diff
-126
View File
@@ -1,126 +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 "DescriptionFactory.h"
#include <osrm/Coordinate.h>
#include "../typedefs.h"
#include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
DescriptionFactory::DescriptionFactory() : entireLength(0) { via_indices.push_back(0); }
std::vector<unsigned> const &DescriptionFactory::GetViaIndices() const { return via_indices; }
void DescriptionFactory::SetStartSegment(const PhantomNode &source, const bool traversed_in_reverse)
{
start_phantom = source;
const EdgeWeight segment_duration =
(traversed_in_reverse ? source.reverse_weight : source.forward_weight);
const TravelMode travel_mode =
(traversed_in_reverse ? source.backward_travel_mode : source.forward_travel_mode);
AppendSegment(
source.location,
PathData(0, source.name_id, TurnInstruction::HeadOn, segment_duration, travel_mode));
BOOST_ASSERT(path_description.back().duration == segment_duration);
}
void DescriptionFactory::SetEndSegment(const PhantomNode &target,
const bool traversed_in_reverse,
const bool is_via_location)
{
target_phantom = target;
const EdgeWeight segment_duration =
(traversed_in_reverse ? target.reverse_weight : target.forward_weight);
const TravelMode travel_mode =
(traversed_in_reverse ? target.backward_travel_mode : target.forward_travel_mode);
path_description.emplace_back(target.location,
target.name_id,
segment_duration,
0.f,
is_via_location ? TurnInstruction::ReachViaLocation
: TurnInstruction::NoTurn,
true,
true,
travel_mode);
BOOST_ASSERT(path_description.back().duration == segment_duration);
}
void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
const PathData &path_point)
{
// if the start location is on top of a node, the first movement might be zero-length,
// in which case we dont' add a new description, but instead update the existing one
if ((1 == path_description.size()) && (path_description.front().location == coordinate))
{
if (path_point.segment_duration > 0)
{
path_description.front().name_id = path_point.name_id;
path_description.front().travel_mode = path_point.travel_mode;
}
return;
}
// make sure mode changes are announced, even when there otherwise is no turn
const TurnInstruction turn = [&]() -> TurnInstruction
{
if (TurnInstruction::NoTurn == path_point.turn_instruction &&
path_description.front().travel_mode != path_point.travel_mode &&
path_point.segment_duration > 0)
{
return TurnInstruction::GoStraight;
}
return path_point.turn_instruction;
}();
path_description.emplace_back(coordinate,
path_point.name_id,
path_point.segment_duration,
0.f,
turn,
path_point.travel_mode);
}
JSON::Value DescriptionFactory::AppendGeometryString(const bool return_encoded)
{
if (return_encoded)
{
return polyline_compressor.printEncodedString(path_description);
}
return polyline_compressor.printUnencodedString(path_description);
}
void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time)
{
summary.source_name_id = start_phantom.name_id;
summary.target_name_id = target_phantom.name_id;
summary.BuildDurationAndLengthStrings(distance, time);
}
-218
View File
@@ -1,218 +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 DESCRIPTIONFACTORY_H_
#define DESCRIPTIONFACTORY_H_
#include "../Algorithms/DouglasPeucker.h"
#include "../Algorithms/PolylineCompressor.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/SegmentInformation.h"
#include "../DataStructures/TurnInstructions.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
#include <limits>
#include <vector>
struct PathData;
/* This class is fed with all way segments in consecutive order
* and produces the description plus the encoded polyline */
class DescriptionFactory
{
DouglasPeucker polyline_generalizer;
PolylineCompressor polyline_compressor;
PhantomNode start_phantom, target_phantom;
double DegreeToRadian(const double degree) const;
double RadianToDegree(const double degree) const;
std::vector<unsigned> via_indices;
public:
struct RouteSummary
{
unsigned distance;
EdgeWeight duration;
unsigned source_name_id;
unsigned target_name_id;
RouteSummary() : distance(0), duration(0), source_name_id(0), target_name_id(0) {}
void BuildDurationAndLengthStrings(const double raw_distance, const unsigned raw_duration)
{
// compute distance/duration for route summary
distance = static_cast<unsigned>(round(raw_distance));
duration = static_cast<unsigned>(round(raw_duration / 10.));
}
} summary;
double entireLength;
// I know, declaring this public is considered bad. I'm lazy
std::vector<SegmentInformation> path_description;
DescriptionFactory();
void AppendSegment(const FixedPointCoordinate &coordinate, const PathData &data);
void BuildRouteSummary(const double distance, const unsigned time);
void SetStartSegment(const PhantomNode &start_phantom, const bool traversed_in_reverse);
void SetEndSegment(const PhantomNode &start_phantom,
const bool traversed_in_reverse,
const bool is_via_location = false);
JSON::Value AppendGeometryString(const bool return_encoded);
std::vector<unsigned> const &GetViaIndices() const;
template <class DataFacadeT> void Run(const DataFacadeT *facade, const unsigned zoomLevel)
{
if (path_description.empty())
{
return;
}
/** starts at index 1 */
path_description[0].length = 0;
for (unsigned i = 1; i < path_description.size(); ++i)
{
// move down names by one, q&d hack
path_description[i - 1].name_id = path_description[i].name_id;
path_description[i].length = FixedPointCoordinate::ApproximateEuclideanDistance(
path_description[i - 1].location, path_description[i].location);
}
/*Simplify turn instructions
Input :
10. Turn left on B 36 for 20 km
11. Continue on B 35; B 36 for 2 km
12. Continue on B 36 for 13 km
becomes:
10. Turn left on B 36 for 35 km
*/
// TODO: rework to check only end and start of string.
// stl string is way to expensive
// unsigned lastTurn = 0;
// for(unsigned i = 1; i < path_description.size(); ++i) {
// string1 = sEngine.GetEscapedNameForNameID(path_description[i].name_id);
// if(TurnInstruction::GoStraight == path_description[i].turn_instruction) {
// if(std::string::npos != string0.find(string1+";")
// || std::string::npos != string0.find(";"+string1)
// || std::string::npos != string0.find(string1+" ;")
// || std::string::npos != string0.find("; "+string1)
// ){
// SimpleLogger().Write() << "->next correct: " << string0 << " contains " <<
// string1;
// for(; lastTurn != i; ++lastTurn)
// path_description[lastTurn].name_id = path_description[i].name_id;
// path_description[i].turn_instruction = TurnInstruction::NoTurn;
// } else if(std::string::npos != string1.find(string0+";")
// || std::string::npos != string1.find(";"+string0)
// || std::string::npos != string1.find(string0+" ;")
// || std::string::npos != string1.find("; "+string0)
// ){
// SimpleLogger().Write() << "->prev correct: " << string1 << " contains " <<
// string0;
// path_description[i].name_id = path_description[i-1].name_id;
// path_description[i].turn_instruction = TurnInstruction::NoTurn;
// }
// }
// if (TurnInstruction::NoTurn != path_description[i].turn_instruction) {
// lastTurn = i;
// }
// string0 = string1;
// }
float segment_length = 0.;
unsigned segment_duration = 0;
unsigned segment_start_index = 0;
for (unsigned i = 1; i < path_description.size(); ++i)
{
entireLength += path_description[i].length;
segment_length += path_description[i].length;
segment_duration += path_description[i].duration;
path_description[segment_start_index].length = segment_length;
path_description[segment_start_index].duration = segment_duration;
if (TurnInstruction::NoTurn != path_description[i].turn_instruction)
{
BOOST_ASSERT(path_description[i].necessary);
segment_length = 0;
segment_duration = 0;
segment_start_index = i;
}
}
// Post-processing to remove empty or nearly empty path segments
if (std::numeric_limits<double>::epsilon() > path_description.back().length)
{
if (path_description.size() > 2)
{
path_description.pop_back();
path_description.back().necessary = true;
path_description.back().turn_instruction = TurnInstruction::NoTurn;
target_phantom.name_id = (path_description.end() - 2)->name_id;
}
}
if (std::numeric_limits<double>::epsilon() > path_description.front().length)
{
if (path_description.size() > 2)
{
path_description.erase(path_description.begin());
path_description.front().turn_instruction = TurnInstruction::HeadOn;
path_description.front().necessary = true;
start_phantom.name_id = path_description.front().name_id;
}
}
// Generalize poly line
polyline_generalizer.Run(path_description, zoomLevel);
// fix what needs to be fixed else
unsigned necessary_pieces = 0; // a running index that counts the necessary pieces
for (unsigned i = 0; i < path_description.size() - 1 && path_description.size() >= 2; ++i)
{
if (path_description[i].necessary)
{
++necessary_pieces;
if (path_description[i].is_via_location)
{ // mark the end of a leg
via_indices.push_back(necessary_pieces);
}
const double angle =
path_description[i + 1].location.GetBearing(path_description[i].location);
path_description[i].bearing = static_cast<unsigned>(angle * 10);
}
}
via_indices.push_back(necessary_pieces + 1);
BOOST_ASSERT(via_indices.size() >= 2);
// BOOST_ASSERT(0 != necessary_pieces || path_description.empty());
return;
}
};
#endif /* DESCRIPTIONFACTORY_H_ */
-101
View File
@@ -1,101 +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 GPX_DESCRIPTOR_H
#define GPX_DESCRIPTOR_H
#include "BaseDescriptor.h"
template <class DataFacadeT> class GPXDescriptor final : public BaseDescriptor<DataFacadeT>
{
private:
DescriptorConfig config;
FixedPointCoordinate current;
DataFacadeT *facade;
void AddRoutePoint(const FixedPointCoordinate &coordinate, std::vector<char> &output)
{
const std::string route_point_head = "<rtept lat=\"";
const std::string route_point_middle = " lon=\"";
const std::string route_point_tail = "\"></rtept>";
std::string tmp;
FixedPointCoordinate::convertInternalLatLonToString(coordinate.lat, tmp);
output.insert(output.end(), route_point_head.begin(), route_point_head.end());
output.insert(output.end(), tmp.begin(), tmp.end());
output.push_back('\"');
FixedPointCoordinate::convertInternalLatLonToString(coordinate.lon, tmp);
output.insert(output.end(), route_point_middle.begin(), route_point_middle.end());
output.insert(output.end(), tmp.begin(), tmp.end());
output.insert(output.end(), route_point_tail.begin(), route_point_tail.end());
}
public:
explicit GPXDescriptor(DataFacadeT *facade) : facade(facade) {}
void SetConfig(const DescriptorConfig &c) final { config = c; }
// TODO: reorder parameters
void Run(const RawRouteData &raw_route, http::Reply &reply) final
{
std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<gpx creator=\"OSRM Routing Engine\" version=\"1.1\" "
"xmlns=\"http://www.topografix.com/GPX/1/1\" "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 gpx.xsd"
"\">"
"<metadata><copyright author=\"Project OSRM\"><license>Data (c)"
" OpenStreetMap contributors (ODbL)</license></copyright>"
"</metadata>"
"<rte>");
reply.content.insert(reply.content.end(), header.begin(), header.end());
const bool found_route = (raw_route.shortest_path_length != INVALID_EDGE_WEIGHT) &&
(!raw_route.unpacked_path_segments.front().empty());
if (found_route)
{
AddRoutePoint(raw_route.segment_end_coordinates.front().source_phantom.location,
reply.content);
for (const std::vector<PathData> &path_data_vector : raw_route.unpacked_path_segments)
{
for (const PathData &path_data : path_data_vector)
{
const FixedPointCoordinate current_coordinate =
facade->GetCoordinateOfNode(path_data.node);
AddRoutePoint(current_coordinate, reply.content);
}
}
AddRoutePoint(raw_route.segment_end_coordinates.back().target_phantom.location,
reply.content);
}
std::string footer("</rte></gpx>");
reply.content.insert(reply.content.end(), footer.begin(), footer.end());
}
};
#endif // GPX_DESCRIPTOR_H
-3
View File
@@ -1,3 +0,0 @@
The javascript based web client is a seperate project available at
https://github.com/DennisSchiefer/Project-OSRM-Web
+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
-140
View File
@@ -1,140 +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 "BaseParser.h"
#include "ExtractionWay.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/ref.hpp>
#include <boost/regex.hpp>
BaseParser::BaseParser(ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment)
: extractor_callbacks(extractor_callbacks),
lua_state(scripting_environment.getLuaState()),
scripting_environment(scripting_environment), use_turn_restrictions(true)
{
ReadUseRestrictionsSetting();
ReadRestrictionExceptions();
}
void BaseParser::ReadUseRestrictionsSetting()
{
if (0 != luaL_dostring(lua_state, "return use_turn_restrictions\n"))
{
use_turn_restrictions = false;
}
else if (lua_isboolean(lua_state, -1))
{
use_turn_restrictions = lua_toboolean(lua_state, -1);
}
if (use_turn_restrictions)
{
SimpleLogger().Write() << "Using turn restrictions";
}
else
{
SimpleLogger().Write() << "Ignoring turn restrictions";
}
}
void BaseParser::ReadRestrictionExceptions()
{
if (lua_function_exists(lua_state, "get_exceptions"))
{
// get list of turn restriction exceptions
luabind::call_function<void>(
lua_state, "get_exceptions", boost::ref(restriction_exceptions));
const unsigned exception_count = restriction_exceptions.size();
SimpleLogger().Write() << "Found " << exception_count
<< " exceptions to turn restrictions:";
for (const std::string &str : restriction_exceptions)
{
SimpleLogger().Write() << " " << str;
}
}
else
{
SimpleLogger().Write() << "Found no exceptions to turn restrictions";
}
}
void BaseParser::report_errors(lua_State *lua_state, const int status) const
{
if (0 != status)
{
std::cerr << "-- " << lua_tostring(lua_state, -1) << std::endl;
lua_pop(lua_state, 1); // remove error message
}
}
void BaseParser::ParseNodeInLua(ImportNode &node, lua_State *local_lua_state)
{
luabind::call_function<void>(local_lua_state, "node_function", boost::ref(node));
}
void BaseParser::ParseWayInLua(ExtractionWay &way, lua_State *local_lua_state)
{
luabind::call_function<void>(local_lua_state, "way_function", boost::ref(way));
}
bool BaseParser::ShouldIgnoreRestriction(const std::string &except_tag_string) const
{
// should this restriction be ignored? yes if there's an overlap between:
// a) the list of modes in the except tag of the restriction
// (except_tag_string), eg: except=bus;bicycle
// b) the lua profile defines a hierachy of modes,
// eg: [access, vehicle, bicycle]
if (except_tag_string.empty())
{
return false;
}
// Be warned, this is quadratic work here, but we assume that
// only a few exceptions are actually defined.
std::vector<std::string> exceptions;
boost::algorithm::split_regex(exceptions, except_tag_string, boost::regex("[;][ ]*"));
for (std::string &current_string : exceptions)
{
const auto string_iterator =
std::find(restriction_exceptions.begin(), restriction_exceptions.end(), current_string);
if (restriction_exceptions.end() != string_iterator)
{
return true;
}
}
return false;
}
-67
View File
@@ -1,67 +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 BASEPARSER_H_
#define BASEPARSER_H_
#include <string>
#include <vector>
struct lua_State;
class ExtractorCallbacks;
class ScriptingEnvironment;
struct ExtractionWay;
struct ImportNode;
class BaseParser
{
public:
BaseParser() = delete;
BaseParser(const BaseParser &) = delete;
BaseParser(ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment);
virtual ~BaseParser() {}
virtual bool ReadHeader() = 0;
virtual bool Parse() = 0;
virtual void ParseNodeInLua(ImportNode &node, lua_State *lua_state);
virtual void ParseWayInLua(ExtractionWay &way, lua_State *lua_state);
virtual void report_errors(lua_State *lua_state, const int status) const;
protected:
virtual void ReadUseRestrictionsSetting();
virtual void ReadRestrictionExceptions();
virtual bool ShouldIgnoreRestriction(const std::string &except_tag_string) const;
ExtractorCallbacks *extractor_callbacks;
lua_State *lua_state;
ScriptingEnvironment &scripting_environment;
std::vector<std::string> restriction_exceptions;
bool use_turn_restrictions;
};
#endif /* BASEPARSER_H_ */
-430
View File
@@ -1,430 +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 "ExtractionContainers.h"
#include "ExtractionWay.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/TimingUtil.h"
#include "../DataStructures/RangeTable.h"
#include <boost/assert.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <stxxl/sort>
#include <chrono>
#include <limits>
ExtractionContainers::ExtractionContainers()
{
// Check if stxxl can be instantiated
stxxl::vector<unsigned> dummy_vector;
name_list.push_back("");
}
ExtractionContainers::~ExtractionContainers()
{
used_node_id_list.clear();
all_nodes_list.clear();
all_edges_list.clear();
name_list.clear();
restrictions_list.clear();
way_start_end_id_list.clear();
}
void ExtractionContainers::PrepareData(const std::string &output_file_name,
const std::string &restrictions_file_name)
{
try
{
unsigned number_of_used_nodes = 0;
unsigned number_of_used_edges = 0;
std::cout << "[extractor] Sorting used nodes ... " << std::flush;
TIMER_START(sorting_used_nodes);
stxxl::sort(used_node_id_list.begin(), used_node_id_list.end(), Cmp(), stxxl_memory);
TIMER_STOP(sorting_used_nodes);
std::cout << "ok, after " << TIMER_SEC(sorting_used_nodes) << "s" << std::endl;
std::cout << "[extractor] Erasing duplicate nodes ... " << std::flush;
TIMER_START(erasing_dups);
auto new_end = std::unique(used_node_id_list.begin(), used_node_id_list.end());
used_node_id_list.resize(new_end - used_node_id_list.begin());
TIMER_STOP(erasing_dups);
std::cout << "ok, after " << TIMER_SEC(erasing_dups) << "s" << std::endl;
std::cout << "[extractor] Sorting all nodes ... " << std::flush;
TIMER_START(sorting_nodes);
stxxl::sort(all_nodes_list.begin(), all_nodes_list.end(), CmpNodeByID(), stxxl_memory);
TIMER_STOP(sorting_nodes);
std::cout << "ok, after " << TIMER_SEC(sorting_nodes) << "s" << std::endl;
std::cout << "[extractor] Sorting used ways ... " << std::flush;
TIMER_START(sort_ways);
stxxl::sort(
way_start_end_id_list.begin(), way_start_end_id_list.end(), CmpWayByID(), stxxl_memory);
TIMER_STOP(sort_ways);
std::cout << "ok, after " << TIMER_SEC(sort_ways) << "s" << std::endl;
std::cout << "[extractor] Sorting restrictions. by from... " << std::flush;
TIMER_START(sort_restrictions);
stxxl::sort(restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByFrom(),
stxxl_memory);
TIMER_STOP(sort_restrictions);
std::cout << "ok, after " << TIMER_SEC(sort_restrictions) << "s" << std::endl;
std::cout << "[extractor] Fixing restriction starts ... " << std::flush;
TIMER_START(fix_restriction_starts);
auto restrictions_iterator = restrictions_list.begin();
auto way_start_and_end_iterator = way_start_end_id_list.begin();
while (way_start_and_end_iterator != way_start_end_id_list.end() &&
restrictions_iterator != restrictions_list.end())
{
if (way_start_and_end_iterator->wayID < restrictions_iterator->fromWay)
{
++way_start_and_end_iterator;
continue;
}
if (way_start_and_end_iterator->wayID > restrictions_iterator->fromWay)
{
++restrictions_iterator;
continue;
}
BOOST_ASSERT(way_start_and_end_iterator->wayID == restrictions_iterator->fromWay);
const NodeID via_node_id = restrictions_iterator->restriction.viaNode;
if (way_start_and_end_iterator->firstStart == via_node_id)
{
restrictions_iterator->restriction.fromNode =
way_start_and_end_iterator->firstTarget;
}
else if (way_start_and_end_iterator->firstTarget == via_node_id)
{
restrictions_iterator->restriction.fromNode =
way_start_and_end_iterator->firstStart;
}
else if (way_start_and_end_iterator->lastStart == via_node_id)
{
restrictions_iterator->restriction.fromNode =
way_start_and_end_iterator->lastTarget;
}
else if (way_start_and_end_iterator->lastTarget == via_node_id)
{
restrictions_iterator->restriction.fromNode = way_start_and_end_iterator->lastStart;
}
++restrictions_iterator;
}
TIMER_STOP(fix_restriction_starts);
std::cout << "ok, after " << TIMER_SEC(fix_restriction_starts) << "s" << std::endl;
std::cout << "[extractor] Sorting restrictions. by to ... " << std::flush;
TIMER_START(sort_restrictions_to);
stxxl::sort(restrictions_list.begin(),
restrictions_list.end(),
CmpRestrictionContainerByTo(),
stxxl_memory);
TIMER_STOP(sort_restrictions_to);
std::cout << "ok, after " << TIMER_SEC(sort_restrictions_to) << "s" << std::endl;
unsigned number_of_useable_restrictions = 0;
std::cout << "[extractor] Fixing restriction ends ... " << std::flush;
TIMER_START(fix_restriction_ends);
restrictions_iterator = restrictions_list.begin();
way_start_and_end_iterator = way_start_end_id_list.begin();
while (way_start_and_end_iterator != way_start_end_id_list.end() &&
restrictions_iterator != restrictions_list.end())
{
if (way_start_and_end_iterator->wayID < restrictions_iterator->toWay)
{
++way_start_and_end_iterator;
continue;
}
if (way_start_and_end_iterator->wayID > restrictions_iterator->toWay)
{
++restrictions_iterator;
continue;
}
NodeID via_node_id = restrictions_iterator->restriction.viaNode;
if (way_start_and_end_iterator->lastStart == via_node_id)
{
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->lastTarget;
}
else if (way_start_and_end_iterator->lastTarget == via_node_id)
{
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->lastStart;
}
else if (way_start_and_end_iterator->firstStart == via_node_id)
{
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->firstTarget;
}
else if (way_start_and_end_iterator->firstTarget == via_node_id)
{
restrictions_iterator->restriction.toNode = way_start_and_end_iterator->firstStart;
}
if (std::numeric_limits<unsigned>::max() != restrictions_iterator->restriction.fromNode &&
std::numeric_limits<unsigned>::max() != restrictions_iterator->restriction.toNode)
{
++number_of_useable_restrictions;
}
++restrictions_iterator;
}
TIMER_STOP(fix_restriction_ends);
std::cout << "ok, after " << TIMER_SEC(fix_restriction_ends) << "s" << std::endl;
SimpleLogger().Write() << "usable restrictions: " << number_of_useable_restrictions;
// serialize restrictions
std::ofstream restrictions_out_stream;
restrictions_out_stream.open(restrictions_file_name.c_str(), std::ios::binary);
restrictions_out_stream.write((char *)&fingerprint, sizeof(FingerPrint));
restrictions_out_stream.write((char *)&number_of_useable_restrictions, sizeof(unsigned));
for(const auto & restriction_container : restrictions_list)
{
if (std::numeric_limits<unsigned>::max() != restriction_container.restriction.fromNode &&
std::numeric_limits<unsigned>::max() != restriction_container.restriction.toNode)
{
restrictions_out_stream.write((char *)&(restriction_container.restriction),
sizeof(TurnRestriction));
}
}
restrictions_out_stream.close();
std::ofstream file_out_stream;
file_out_stream.open(output_file_name.c_str(), std::ios::binary);
file_out_stream.write((char *)&fingerprint, sizeof(FingerPrint));
file_out_stream.write((char *)&number_of_used_nodes, sizeof(unsigned));
std::cout << "[extractor] Confirming/Writing used nodes ... " << std::flush;
TIMER_START(write_nodes);
// identify all used nodes by a merging step of two sorted lists
auto node_iterator = all_nodes_list.begin();
auto node_id_iterator = used_node_id_list.begin();
while (node_id_iterator != used_node_id_list.end() && node_iterator != all_nodes_list.end())
{
if (*node_id_iterator < node_iterator->node_id)
{
++node_id_iterator;
continue;
}
if (*node_id_iterator > node_iterator->node_id)
{
++node_iterator;
continue;
}
BOOST_ASSERT(*node_id_iterator == node_iterator->node_id);
file_out_stream.write((char *)&(*node_iterator), sizeof(ExternalMemoryNode));
++number_of_used_nodes;
++node_id_iterator;
++node_iterator;
}
TIMER_STOP(write_nodes);
std::cout << "ok, after " << TIMER_SEC(write_nodes) << "s" << std::endl;
std::cout << "[extractor] setting number of nodes ... " << std::flush;
std::ios::pos_type previous_file_position = file_out_stream.tellp();
file_out_stream.seekp(std::ios::beg + sizeof(FingerPrint));
file_out_stream.write((char *)&number_of_used_nodes, sizeof(unsigned));
file_out_stream.seekp(previous_file_position);
std::cout << "ok" << std::endl;
// Sort edges by start.
std::cout << "[extractor] Sorting edges by start ... " << std::flush;
TIMER_START(sort_edges_by_start);
stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByStartID(), stxxl_memory);
TIMER_STOP(sort_edges_by_start);
std::cout << "ok, after " << TIMER_SEC(sort_edges_by_start) << "s" << std::endl;
std::cout << "[extractor] Setting start coords ... " << std::flush;
TIMER_START(set_start_coords);
file_out_stream.write((char *)&number_of_used_edges, sizeof(unsigned));
// Traverse list of edges and nodes in parallel and set start coord
node_iterator = all_nodes_list.begin();
auto edge_iterator = all_edges_list.begin();
while (edge_iterator != all_edges_list.end() && node_iterator != all_nodes_list.end())
{
if (edge_iterator->start < node_iterator->node_id)
{
++edge_iterator;
continue;
}
if (edge_iterator->start > node_iterator->node_id)
{
node_iterator++;
continue;
}
BOOST_ASSERT(edge_iterator->start == node_iterator->node_id);
edge_iterator->source_coordinate.lat = node_iterator->lat;
edge_iterator->source_coordinate.lon = node_iterator->lon;
++edge_iterator;
}
TIMER_STOP(set_start_coords);
std::cout << "ok, after " << TIMER_SEC(set_start_coords) << "s" << std::endl;
// Sort Edges by target
std::cout << "[extractor] Sorting edges by target ... " << std::flush;
TIMER_START(sort_edges_by_target);
stxxl::sort(all_edges_list.begin(), all_edges_list.end(), CmpEdgeByTargetID(), stxxl_memory);
TIMER_STOP(sort_edges_by_target);
std::cout << "ok, after " << TIMER_SEC(sort_edges_by_target) << "s" << std::endl;
std::cout << "[extractor] Setting target coords ... " << std::flush;
TIMER_START(set_target_coords);
// Traverse list of edges and nodes in parallel and set target coord
node_iterator = all_nodes_list.begin();
edge_iterator = all_edges_list.begin();
while (edge_iterator != all_edges_list.end() && node_iterator != all_nodes_list.end())
{
if (edge_iterator->target < node_iterator->node_id)
{
++edge_iterator;
continue;
}
if (edge_iterator->target > node_iterator->node_id)
{
++node_iterator;
continue;
}
BOOST_ASSERT(edge_iterator->target == node_iterator->node_id);
if (edge_iterator->source_coordinate.lat != std::numeric_limits<int>::min() &&
edge_iterator->source_coordinate.lon != std::numeric_limits<int>::min())
{
BOOST_ASSERT(edge_iterator->speed != -1);
edge_iterator->target_coordinate.lat = node_iterator->lat;
edge_iterator->target_coordinate.lon = node_iterator->lon;
const double distance = FixedPointCoordinate::ApproximateEuclideanDistance(
edge_iterator->source_coordinate.lat,
edge_iterator->source_coordinate.lon,
node_iterator->lat,
node_iterator->lon);
const double weight = (distance * 10.) / (edge_iterator->speed / 3.6);
int integer_weight = std::max(
1,
(int)std::floor(
(edge_iterator->is_duration_set ? edge_iterator->speed : weight) + .5));
int integer_distance = std::max(1, (int)distance);
short zero = 0;
short one = 1;
file_out_stream.write((char *)&edge_iterator->start, sizeof(unsigned));
file_out_stream.write((char *)&edge_iterator->target, sizeof(unsigned));
file_out_stream.write((char *)&integer_distance, sizeof(int));
switch (edge_iterator->direction)
{
case ExtractionWay::notSure:
file_out_stream.write((char *)&zero, sizeof(short));
break;
case ExtractionWay::oneway:
file_out_stream.write((char *)&one, sizeof(short));
break;
case ExtractionWay::bidirectional:
file_out_stream.write((char *)&zero, sizeof(short));
break;
case ExtractionWay::opposite:
file_out_stream.write((char *)&one, sizeof(short));
break;
default:
throw OSRMException("edge has broken direction");
}
file_out_stream.write((char *)&integer_weight, sizeof(int));
file_out_stream.write((char *)&edge_iterator->name_id, sizeof(unsigned));
file_out_stream.write((char *)&edge_iterator->is_roundabout, sizeof(bool));
file_out_stream.write((char *)&edge_iterator->is_in_tiny_cc, sizeof(bool));
file_out_stream.write((char *)&edge_iterator->is_access_restricted, sizeof(bool));
// cannot take adress of bit field, so use local
const TravelMode travel_mode = edge_iterator->travel_mode;
file_out_stream.write((char *)&travel_mode, sizeof(TravelMode));
file_out_stream.write((char *)&edge_iterator->is_split, sizeof(bool));
++number_of_used_edges;
}
++edge_iterator;
}
TIMER_STOP(set_target_coords);
std::cout << "ok, after " << TIMER_SEC(set_target_coords) << "s" << std::endl;
std::cout << "[extractor] setting number of edges ... " << std::flush;
file_out_stream.seekp(previous_file_position);
file_out_stream.write((char *)&number_of_used_edges, sizeof(unsigned));
file_out_stream.close();
std::cout << "ok" << std::endl;
std::cout << "[extractor] writing street name index ... " << std::flush;
TIMER_START(write_name_index);
std::string name_file_streamName = (output_file_name + ".names");
boost::filesystem::ofstream name_file_stream(name_file_streamName, std::ios::binary);
unsigned total_length = 0;
std::vector<unsigned> name_lengths;
for (const std::string &temp_string : name_list)
{
const unsigned string_length = std::min(static_cast<unsigned>(temp_string.length()), 255u);
name_lengths.push_back(string_length);
total_length += string_length;
}
RangeTable<> table(name_lengths);
name_file_stream << table;
name_file_stream.write((char*) &total_length, sizeof(unsigned));
// write all chars consecutively
for (const std::string &temp_string : name_list)
{
const unsigned string_length = std::min(static_cast<unsigned>(temp_string.length()), 255u);
name_file_stream.write(temp_string.c_str(), string_length);
}
name_file_stream.close();
TIMER_STOP(write_name_index);
std::cout << "ok, after " << TIMER_SEC(write_name_index) << "s" << std::endl;
SimpleLogger().Write() << "Processed " << number_of_used_nodes << " nodes and "
<< number_of_used_edges << " edges";
}
catch (const std::exception &e) { std::cerr << "Caught Execption:" << e.what() << std::endl; }
}
-69
View File
@@ -1,69 +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 EXTRACTIONCONTAINERS_H_
#define EXTRACTIONCONTAINERS_H_
#include "InternalExtractorEdge.h"
#include "ExtractorStructs.h"
#include "../DataStructures/Restriction.h"
#include "../Util/FingerPrint.h"
#include <stxxl/vector>
class ExtractionContainers
{
#ifndef _MSC_VER
constexpr static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? std::numeric_limits<int>::max() : std::numeric_limits<unsigned>::max());
#else
const static unsigned stxxl_memory = ((sizeof(std::size_t) == 4) ? INT_MAX : UINT_MAX);
#endif
public:
using STXXLNodeIDVector = stxxl::vector<NodeID>;
using STXXLNodeVector = stxxl::vector<ExternalMemoryNode>;
using STXXLEdgeVector = stxxl::vector<InternalExtractorEdge>;
using STXXLStringVector = stxxl::vector<std::string>;
using STXXLRestrictionsVector = stxxl::vector<InputRestrictionContainer>;
using STXXLWayIDStartEndVector = stxxl::vector<WayIDStartAndEndEdge>;
STXXLNodeIDVector used_node_id_list;
STXXLNodeVector all_nodes_list;
STXXLEdgeVector all_edges_list;
STXXLStringVector name_list;
STXXLRestrictionsVector restrictions_list;
STXXLWayIDStartEndVector way_start_end_id_list;
const FingerPrint fingerprint;
ExtractionContainers();
~ExtractionContainers();
void PrepareData(const std::string &output_file_name,
const std::string &restrictions_file_name);
};
#endif /* EXTRACTIONCONTAINERS_H_ */
-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 EXTRACTION_HELPER_FUNCTIONS_H
#define EXTRACTION_HELPER_FUNCTIONS_H
#include "../Util/cast.hpp"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string_regex.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/regex.hpp>
#include <limits>
namespace qi = boost::spirit::qi;
// TODO: Move into LUA
inline bool durationIsValid(const std::string &s)
{
boost::regex e(
"((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)",
boost::regex_constants::icase | boost::regex_constants::perl);
std::vector<std::string> result;
boost::algorithm::split_regex(result, s, boost::regex(":"));
const bool matched = regex_match(s, e);
return matched;
}
inline unsigned parseDuration(const std::string &s)
{
unsigned hours = 0;
unsigned minutes = 0;
unsigned seconds = 0;
boost::regex e(
"((\\d|\\d\\d):(\\d|\\d\\d):(\\d|\\d\\d))|((\\d|\\d\\d):(\\d|\\d\\d))|(\\d|\\d\\d)",
boost::regex_constants::icase | boost::regex_constants::perl);
std::vector<std::string> result;
boost::algorithm::split_regex(result, s, boost::regex(":"));
const bool matched = regex_match(s, e);
if (matched)
{
if (1 == result.size())
{
minutes = cast::string_to_int(result[0]);
}
if (2 == result.size())
{
minutes = cast::string_to_int(result[1]);
hours = cast::string_to_int(result[0]);
}
if (3 == result.size())
{
seconds = cast::string_to_int(result[2]);
minutes = cast::string_to_int(result[1]);
hours = cast::string_to_int(result[0]);
}
return 10 * (3600 * hours + 60 * minutes + seconds);
}
return std::numeric_limits<unsigned>::max();
}
#endif // EXTRACTION_HELPER_FUNCTIONS_H_
-302
View File
@@ -1,302 +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 "Extractor.h"
#include "ExtractorCallbacks.h"
#include "ExtractionContainers.h"
#include "PBFParser.h"
#include "ScriptingEnvironment.h"
#include "XMLParser.h"
#include "../Util/GitDescription.h"
#include "../Util/IniFileUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/TimingUtil.h"
#include "../typedefs.h"
#include <boost/program_options.hpp>
#include <tbb/task_scheduler_init.h>
#include <cstdlib>
#include <chrono>
#include <fstream>
#include <iostream>
#include <thread>
#include <unordered_map>
Extractor::Extractor() : requested_num_threads(0), file_has_pbf_format(false)
{
}
Extractor::~Extractor() {}
bool Extractor::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("extractor.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>(
&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(
boost::filesystem::basename(argv[0]) + " <input.osm/.osm.bz2/.osm.pbf> [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);
if (option_variables.count("version"))
{
SimpleLogger().Write() << g_GIT_DESCRIPTION;
return false;
}
if (option_variables.count("help"))
{
SimpleLogger().Write() << visible_options;
return false;
}
boost::program_options::notify(option_variables);
// parse config file
if (boost::filesystem::is_regular_file(config_file_path))
{
SimpleLogger().Write() << "Reading options from: " << config_file_path.string();
std::string ini_file_contents = ReadIniFileAndLowerContents(config_file_path);
std::stringstream config_stream(ini_file_contents);
boost::program_options::store(parse_config_file(config_stream, config_file_options),
option_variables);
boost::program_options::notify(option_variables);
}
if (!option_variables.count("input"))
{
SimpleLogger().Write() << visible_options;
return false;
}
return true;
}
void Extractor::GenerateOutputFilesNames()
{
output_file_name = input_path.string();
restriction_file_name = input_path.string();
std::string::size_type pos = output_file_name.find(".osm.bz2");
if (pos == std::string::npos)
{
pos = output_file_name.find(".osm.pbf");
if (pos != std::string::npos)
{
file_has_pbf_format = true;
}
else
{
pos = output_file_name.find(".osm.xml");
}
}
if (pos == std::string::npos)
{
pos = output_file_name.find(".pbf");
if (pos != std::string::npos)
{
file_has_pbf_format = true;
}
}
if (pos == std::string::npos)
{
pos = output_file_name.find(".osm");
if (pos == std::string::npos)
{
output_file_name.append(".osrm");
restriction_file_name.append(".osrm.restrictions");
}
else
{
output_file_name.replace(pos, 5, ".osrm");
restriction_file_name.replace(pos, 5, ".osrm.restrictions");
}
}
else
{
output_file_name.replace(pos, 8, ".osrm");
restriction_file_name.replace(pos, 8, ".osrm.restrictions");
}
}
int Extractor::Run(int argc, char *argv[])
{
try
{
LogPolicy::GetInstance().Unmute();
TIMER_START(extracting);
if (!ParseArguments(argc, argv))
return 0;
if (1 > requested_num_threads)
{
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
return 1;
}
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;
}
const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads();
SimpleLogger().Write() << "Input file: " << input_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);
/*** Setup Scripting Environment ***/
ScriptingEnvironment scripting_environment(profile_path.string().c_str());
GenerateOutputFilesNames();
std::unordered_map<std::string, NodeID> string_map;
ExtractionContainers extraction_containers;
string_map[""] = 0;
auto extractor_callbacks = new ExtractorCallbacks(extraction_containers, string_map);
BaseParser *parser;
if (file_has_pbf_format)
{
parser = new PBFParser(input_path.string().c_str(),
extractor_callbacks,
scripting_environment,
requested_num_threads);
}
else
{
parser = new XMLParser(input_path.string().c_str(),
extractor_callbacks,
scripting_environment);
}
if (!parser->ReadHeader())
{
throw OSRMException("Parser not initialized!");
}
SimpleLogger().Write() << "Parsing in progress..";
TIMER_START(parsing);
parser->Parse();
delete parser;
delete extractor_callbacks;
TIMER_STOP(parsing);
SimpleLogger().Write() << "Parsing finished after " << TIMER_SEC(parsing) << " seconds";
if (extraction_containers.all_edges_list.empty())
{
SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
return 1;
}
extraction_containers.PrepareData(output_file_name, restriction_file_name);
TIMER_STOP(extracting);
SimpleLogger().Write() << "extraction finished after " << TIMER_SEC(extracting) << "s";
SimpleLogger().Write() << "To prepare the data for routing, run: "
<< "./osrm-prepare " << output_file_name << std::endl;
}
catch (boost::program_options::too_many_positional_options_error &)
{
SimpleLogger().Write(logWARNING) << "Only one input file can be specified";
return 1;
}
catch (std::exception &e)
{
SimpleLogger().Write(logWARNING) << e.what();
return 1;
}
return 0;
}
-36
View File
@@ -1,36 +0,0 @@
#ifndef EXTRACTOR_H_
#define EXTRACTOR_H_
#include <boost/filesystem.hpp>
#include <string>
class ExtractorCallbacks;
/** \brief Class of 'extract' utility. */
class Extractor
{
protected:
unsigned requested_num_threads;
boost::filesystem::path config_file_path;
boost::filesystem::path input_path;
boost::filesystem::path profile_path;
std::string output_file_name;
std::string restriction_file_name;
bool file_has_pbf_format;
/** \brief Parses "extractor's" command line arguments */
bool ParseArguments(int argc, char *argv[]);
/** \brief Parses config file, if present in options */
void GenerateOutputFilesNames();
public:
explicit Extractor();
Extractor(const Extractor &) = delete;
virtual ~Extractor();
int Run(int argc, char *argv[]);
};
#endif /* EXTRACTOR_H_ */
-182
View File
@@ -1,182 +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 "ExtractorCallbacks.h"
#include "ExtractionContainers.h"
#include "ExtractionWay.h"
#include "../DataStructures/Restriction.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/simple_logger.hpp"
#include <osrm/Coordinate.h>
#include <limits>
#include <string>
#include <vector>
ExtractorCallbacks::ExtractorCallbacks(ExtractionContainers &extraction_containers,
std::unordered_map<std::string, NodeID> &string_map)
: string_map(string_map), external_memory(extraction_containers)
{
}
/** warning: caller needs to take care of synchronization! */
void ExtractorCallbacks::ProcessNode(const ExternalMemoryNode &n)
{
if (n.lat <= 85 * COORDINATE_PRECISION && n.lat >= -85 * COORDINATE_PRECISION)
{
external_memory.all_nodes_list.push_back(n);
}
}
bool ExtractorCallbacks::ProcessRestriction(const InputRestrictionContainer &restriction)
{
external_memory.restrictions_list.push_back(restriction);
return true;
}
/** warning: caller needs to take care of synchronization! */
void ExtractorCallbacks::ProcessWay(ExtractionWay &parsed_way)
{
if (((0 >= parsed_way.forward_speed) ||
(TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode)) &&
((0 >= parsed_way.backward_speed) ||
(TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode)) &&
(0 >= parsed_way.duration))
{ // Only true if the way is specified by the speed profile
return;
}
if (parsed_way.path.size() <= 1)
{ // safe-guard against broken data
return;
}
if (std::numeric_limits<unsigned>::max() == parsed_way.id)
{
SimpleLogger().Write(logDEBUG) << "found bogus way with id: " << parsed_way.id
<< " of size " << parsed_way.path.size();
return;
}
if (0 < parsed_way.duration)
{
// TODO: iterate all way segments and set duration corresponding to the length of each
// segment
parsed_way.forward_speed = parsed_way.duration / (parsed_way.path.size() - 1);
parsed_way.backward_speed = parsed_way.duration / (parsed_way.path.size() - 1);
}
if (std::numeric_limits<double>::epsilon() >= std::abs(-1. - parsed_way.forward_speed))
{
SimpleLogger().Write(logDEBUG) << "found way with bogus speed, id: " << parsed_way.id;
return;
}
// Get the unique identifier for the street name
const auto &string_map_iterator = string_map.find(parsed_way.name);
if (string_map.end() == string_map_iterator)
{
parsed_way.nameID = external_memory.name_list.size();
external_memory.name_list.push_back(parsed_way.name);
string_map.insert(std::make_pair(parsed_way.name, parsed_way.nameID));
}
else
{
parsed_way.nameID = string_map_iterator->second;
}
if (TRAVEL_MODE_INACCESSIBLE == parsed_way.forward_travel_mode)
{
std::reverse(parsed_way.path.begin(), parsed_way.path.end());
parsed_way.forward_travel_mode = parsed_way.backward_travel_mode;
parsed_way.backward_travel_mode = TRAVEL_MODE_INACCESSIBLE;
}
const bool split_edge =
(parsed_way.forward_speed>0) && (TRAVEL_MODE_INACCESSIBLE != parsed_way.forward_travel_mode) &&
(parsed_way.backward_speed>0) && (TRAVEL_MODE_INACCESSIBLE != parsed_way.backward_travel_mode) &&
((parsed_way.forward_speed != parsed_way.backward_speed) ||
(parsed_way.forward_travel_mode != parsed_way.backward_travel_mode));
BOOST_ASSERT(parsed_way.forward_travel_mode>0);
for (unsigned n = 0; n < (parsed_way.path.size() - 1); ++n)
{
external_memory.all_edges_list.push_back(InternalExtractorEdge(
parsed_way.path[n],
parsed_way.path[n + 1],
((split_edge || TRAVEL_MODE_INACCESSIBLE == parsed_way.backward_travel_mode) ? ExtractionWay::oneway
: ExtractionWay::bidirectional),
parsed_way.forward_speed,
parsed_way.nameID,
parsed_way.roundabout,
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
parsed_way.forward_travel_mode,
split_edge));
external_memory.used_node_id_list.push_back(parsed_way.path[n]);
}
external_memory.used_node_id_list.push_back(parsed_way.path.back());
// The following information is needed to identify start and end segments of restrictions
external_memory.way_start_end_id_list.push_back(
WayIDStartAndEndEdge(parsed_way.id,
parsed_way.path[0],
parsed_way.path[1],
parsed_way.path[parsed_way.path.size() - 2],
parsed_way.path.back()));
if (split_edge)
{ // Only true if the way should be split
BOOST_ASSERT(parsed_way.backward_travel_mode>0);
std::reverse(parsed_way.path.begin(), parsed_way.path.end());
for (std::vector<NodeID>::size_type n = 0; n < parsed_way.path.size() - 1; ++n)
{
external_memory.all_edges_list.push_back(
InternalExtractorEdge(parsed_way.path[n],
parsed_way.path[n + 1],
ExtractionWay::oneway,
parsed_way.backward_speed,
parsed_way.nameID,
parsed_way.roundabout,
parsed_way.ignoreInGrid,
(0 < parsed_way.duration),
parsed_way.isAccessRestricted,
parsed_way.backward_travel_mode,
split_edge));
}
external_memory.way_start_end_id_list.push_back(
WayIDStartAndEndEdge(parsed_way.id,
parsed_way.path[0],
parsed_way.path[1],
parsed_way.path[parsed_way.path.size() - 2],
parsed_way.path.back()));
}
}
-114
View File
@@ -1,114 +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 EXTRACTORSTRUCTS_H_
#define EXTRACTORSTRUCTS_H_
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../typedefs.h"
#include <limits>
#include <string>
struct ExtractorRelation
{
ExtractorRelation() : type(unknown) {}
enum
{ unknown = 0,
ferry,
turnRestriction } type;
HashTable<std::string, std::string> keyVals;
};
struct WayIDStartAndEndEdge
{
unsigned wayID;
NodeID firstStart;
NodeID firstTarget;
NodeID lastStart;
NodeID lastTarget;
WayIDStartAndEndEdge()
: wayID(std::numeric_limits<unsigned>::max()), firstStart(std::numeric_limits<unsigned>::max()), firstTarget(std::numeric_limits<unsigned>::max()), lastStart(std::numeric_limits<unsigned>::max()),
lastTarget(std::numeric_limits<unsigned>::max())
{
}
explicit WayIDStartAndEndEdge(unsigned w, NodeID fs, NodeID ft, NodeID ls, NodeID lt)
: wayID(w), firstStart(fs), firstTarget(ft), lastStart(ls), lastTarget(lt)
{
}
static WayIDStartAndEndEdge min_value()
{
return WayIDStartAndEndEdge((std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)(),
(std::numeric_limits<unsigned>::min)());
}
static WayIDStartAndEndEdge max_value()
{
return WayIDStartAndEndEdge((std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)(),
(std::numeric_limits<unsigned>::max)());
}
};
struct CmpWayByID
{
using value_type = WayIDStartAndEndEdge;
bool operator()(const WayIDStartAndEndEdge &a, const WayIDStartAndEndEdge &b) const
{
return a.wayID < b.wayID;
}
value_type max_value() { return WayIDStartAndEndEdge::max_value(); }
value_type min_value() { return WayIDStartAndEndEdge::min_value(); }
};
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; }
};
struct CmpNodeByID
{
using value_type = ExternalMemoryNode;
bool operator()(const ExternalMemoryNode &left, const ExternalMemoryNode &right) const
{
return left.node_id < right.node_id;
}
value_type max_value() { return ExternalMemoryNode::max_value(); }
value_type min_value() { return ExternalMemoryNode::min_value(); }
};
#endif /* EXTRACTORSTRUCTS_H_ */
-118
View File
@@ -1,118 +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 INTERNAL_EXTRACTOR_EDGE_H
#define INTERNAL_EXTRACTOR_EDGE_H
#include "../typedefs.h"
#include "../DataStructures/TravelMode.h"
#include <osrm/Coordinate.h>
#include <boost/assert.hpp>
struct InternalExtractorEdge
{
InternalExtractorEdge()
: start(0), target(0), direction(0), speed(0), name_id(0), is_roundabout(false),
is_in_tiny_cc(false), is_duration_set(false), is_access_restricted(false),
travel_mode(TRAVEL_MODE_INACCESSIBLE), is_split(false)
{
}
explicit InternalExtractorEdge(NodeID start,
NodeID target,
short direction,
double speed,
unsigned name_id,
bool is_roundabout,
bool is_in_tiny_cc,
bool is_duration_set,
bool is_access_restricted,
TravelMode travel_mode,
bool is_split)
: start(start), target(target), direction(direction), speed(speed),
name_id(name_id), is_roundabout(is_roundabout), is_in_tiny_cc(is_in_tiny_cc),
is_duration_set(is_duration_set), is_access_restricted(is_access_restricted),
travel_mode(travel_mode), is_split(is_split)
{
}
// necessary static util functions for stxxl's sorting
static InternalExtractorEdge min_value()
{
return InternalExtractorEdge(0, 0, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false);
}
static InternalExtractorEdge max_value()
{
return InternalExtractorEdge(
SPECIAL_NODEID, SPECIAL_NODEID, 0, 0, 0, false, false, false, false, TRAVEL_MODE_INACCESSIBLE, false);
}
NodeID start;
NodeID target;
short direction;
double speed;
unsigned name_id;
bool is_roundabout;
bool is_in_tiny_cc;
bool is_duration_set;
bool is_access_restricted;
TravelMode travel_mode : 4;
bool is_split;
FixedPointCoordinate source_coordinate;
FixedPointCoordinate target_coordinate;
};
struct CmpEdgeByStartID
{
using value_type = InternalExtractorEdge;
bool operator()(const InternalExtractorEdge &a, const InternalExtractorEdge &b) const
{
return a.start < b.start;
}
value_type max_value() { return InternalExtractorEdge::max_value(); }
value_type min_value() { return InternalExtractorEdge::min_value(); }
};
struct CmpEdgeByTargetID
{
using value_type = InternalExtractorEdge;
bool operator()(const InternalExtractorEdge &a, const InternalExtractorEdge &b) const
{
return a.target < b.target;
}
value_type max_value() { return InternalExtractorEdge::max_value(); }
value_type min_value() { return InternalExtractorEdge::min_value(); }
};
#endif // INTERNAL_EXTRACTOR_EDGE_H
-665
View File
@@ -1,665 +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 "PBFParser.h"
#include "ExtractionWay.h"
#include "ExtractorCallbacks.h"
#include "ScriptingEnvironment.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/Restriction.h"
#include "../Util/MachineInfo.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../typedefs.h"
#include <boost/assert.hpp>
#include <tbb/parallel_for.h>
#include <tbb/task_scheduler_init.h>
#include <osrm/Coordinate.h>
#include <zlib.h>
#include <functional>
#include <iostream>
#include <limits>
#include <thread>
PBFParser::PBFParser(const char *fileName,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment,
unsigned num_threads)
: BaseParser(extractor_callbacks, scripting_environment)
{
if (0 == num_threads)
{
num_parser_threads = tbb::task_scheduler_init::default_num_threads();
}
else
{
num_parser_threads = num_threads;
}
GOOGLE_PROTOBUF_VERIFY_VERSION;
// TODO: What is the bottleneck here? Filling the queue or reading the stuff from disk?
// NOTE: With Lua scripting, it is parsing the stuff. I/O is virtually for free.
// Max 2500 items in queue, hardcoded.
thread_data_queue = std::make_shared<ConcurrentQueue<ParserThreadData *>>(2500);
input.open(fileName, std::ios::in | std::ios::binary);
if (!input)
{
throw OSRMException("pbf file not found.");
}
block_count = 0;
group_count = 0;
}
PBFParser::~PBFParser()
{
if (input.is_open())
{
input.close();
}
// Clean up any leftover ThreadData objects in the queue
ParserThreadData *thread_data;
while (thread_data_queue->try_pop(thread_data))
{
delete thread_data;
}
google::protobuf::ShutdownProtobufLibrary();
SimpleLogger().Write(logDEBUG) << "parsed " << block_count << " blocks from pbf with "
<< group_count << " groups";
}
inline bool PBFParser::ReadHeader()
{
ParserThreadData init_data;
/** read Header */
if (!readPBFBlobHeader(input, &init_data))
{
return false;
}
if (readBlob(input, &init_data))
{
if (!init_data.PBFHeaderBlock.ParseFromArray(&(init_data.charBuffer[0]),
static_cast<int>(init_data.charBuffer.size())))
{
std::cerr << "[error] Header not parseable!" << std::endl;
return false;
}
const auto feature_size = init_data.PBFHeaderBlock.required_features_size();
for (int i = 0; i < feature_size; ++i)
{
const std::string &feature = init_data.PBFHeaderBlock.required_features(i);
bool supported = false;
if ("OsmSchema-V0.6" == feature)
{
supported = true;
}
else if ("DenseNodes" == feature)
{
supported = true;
}
if (!supported)
{
std::cerr << "[error] required feature not supported: " << feature.data()
<< std::endl;
return false;
}
}
}
else
{
std::cerr << "[error] blob not loaded!" << std::endl;
}
return true;
}
inline void PBFParser::ReadData()
{
bool keep_running = true;
do
{
ParserThreadData *thread_data = new ParserThreadData();
keep_running = readNextBlock(input, thread_data);
if (keep_running)
{
thread_data_queue->push(thread_data);
}
else
{
// No more data to read, parse stops when nullptr encountered
thread_data_queue->push(nullptr);
delete thread_data;
}
} while (keep_running);
}
inline void PBFParser::ParseData()
{
tbb::task_scheduler_init init(num_parser_threads);
while (true)
{
ParserThreadData *thread_data;
thread_data_queue->wait_and_pop(thread_data);
if (nullptr == thread_data)
{
thread_data_queue->push(nullptr); // Signal end of data for other threads
break;
}
loadBlock(thread_data);
int group_size = thread_data->PBFprimitiveBlock.primitivegroup_size();
for (int i = 0; i < group_size; ++i)
{
thread_data->currentGroupID = i;
loadGroup(thread_data);
if (thread_data->entityTypeIndicator == TypeNode)
{
parseNode(thread_data);
}
if (thread_data->entityTypeIndicator == TypeWay)
{
parseWay(thread_data);
}
if (thread_data->entityTypeIndicator == TypeRelation)
{
parseRelation(thread_data);
}
if (thread_data->entityTypeIndicator == TypeDenseNode)
{
parseDenseNode(thread_data);
}
}
delete thread_data;
thread_data = nullptr;
}
}
inline bool PBFParser::Parse()
{
// Start the read and parse threads
std::thread read_thread(std::bind(&PBFParser::ReadData, this));
// Open several parse threads that are synchronized before call to
std::thread parse_thread(std::bind(&PBFParser::ParseData, this));
// Wait for the threads to finish
read_thread.join();
parse_thread.join();
return true;
}
inline void PBFParser::parseDenseNode(ParserThreadData *thread_data)
{
const OSMPBF::DenseNodes &dense =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).dense();
int denseTagIndex = 0;
int64_t m_lastDenseID = 0;
int64_t m_lastDenseLatitude = 0;
int64_t m_lastDenseLongitude = 0;
const int number_of_nodes = dense.id_size();
std::vector<ImportNode> extracted_nodes_vector(number_of_nodes);
for (int i = 0; i < number_of_nodes; ++i)
{
m_lastDenseID += dense.id(i);
m_lastDenseLatitude += dense.lat(i);
m_lastDenseLongitude += dense.lon(i);
extracted_nodes_vector[i].node_id = static_cast<NodeID>(m_lastDenseID);
extracted_nodes_vector[i].lat = static_cast<int>(
COORDINATE_PRECISION *
((double)m_lastDenseLatitude * thread_data->PBFprimitiveBlock.granularity() +
thread_data->PBFprimitiveBlock.lat_offset()) /
NANO);
extracted_nodes_vector[i].lon = static_cast<int>(
COORDINATE_PRECISION *
((double)m_lastDenseLongitude * thread_data->PBFprimitiveBlock.granularity() +
thread_data->PBFprimitiveBlock.lon_offset()) /
NANO);
while (denseTagIndex < dense.keys_vals_size())
{
const int tagValue = dense.keys_vals(denseTagIndex);
if (0 == tagValue)
{
++denseTagIndex;
break;
}
const int keyValue = dense.keys_vals(denseTagIndex + 1);
const std::string &key = thread_data->PBFprimitiveBlock.stringtable().s(tagValue);
const std::string &value = thread_data->PBFprimitiveBlock.stringtable().s(keyValue);
extracted_nodes_vector[i].keyVals.Add(std::move(key), std::move(value));
denseTagIndex += 2;
}
}
tbb::parallel_for(tbb::blocked_range<size_t>(0, extracted_nodes_vector.size()),
[this, &extracted_nodes_vector](const tbb::blocked_range<size_t> &range)
{
lua_State *lua_state = this->scripting_environment.getLuaState();
for (size_t i = range.begin(); i != range.end(); ++i)
{
ImportNode &import_node = extracted_nodes_vector[i];
ParseNodeInLua(import_node, lua_state);
}
});
for (const ImportNode &import_node : extracted_nodes_vector)
{
extractor_callbacks->ProcessNode(import_node);
}
}
inline void PBFParser::parseNode(ParserThreadData *)
{
throw OSRMException("Parsing of simple nodes not supported. PBF should use dense nodes");
}
inline void PBFParser::parseRelation(ParserThreadData *thread_data)
{
// TODO: leave early, if relation is not a restriction
// TODO: reuse rawRestriction container
if (!use_turn_restrictions)
{
return;
}
const OSMPBF::PrimitiveGroup &group =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID);
for (int i = 0, relation_size = group.relations_size(); i < relation_size; ++i)
{
std::string except_tag_string;
const OSMPBF::Relation &inputRelation =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).relations(i);
bool is_restriction = false;
bool is_only_restriction = false;
for (int k = 0, endOfKeys = inputRelation.keys_size(); k < endOfKeys; ++k)
{
const std::string &key =
thread_data->PBFprimitiveBlock.stringtable().s(inputRelation.keys(k));
const std::string &val =
thread_data->PBFprimitiveBlock.stringtable().s(inputRelation.vals(k));
if ("type" == key)
{
if ("restriction" == val)
{
is_restriction = true;
}
else
{
break;
}
}
if (("restriction" == key) && (val.find("only_") == 0))
{
is_only_restriction = true;
}
if ("except" == key)
{
except_tag_string = val;
}
}
if (is_restriction && ShouldIgnoreRestriction(except_tag_string))
{
continue;
}
if (is_restriction)
{
int64_t last_ref = 0;
InputRestrictionContainer current_restriction_container(is_only_restriction);
for (int rolesIndex = 0, last_role = inputRelation.roles_sid_size();
rolesIndex < last_role;
++rolesIndex)
{
const std::string &role = thread_data->PBFprimitiveBlock.stringtable().s(
inputRelation.roles_sid(rolesIndex));
last_ref += inputRelation.memids(rolesIndex);
if (!("from" == role || "to" == role || "via" == role))
{
continue;
}
switch (inputRelation.types(rolesIndex))
{
case 0: // node
if ("from" == role || "to" == role)
{ // Only via should be a node
continue;
}
BOOST_ASSERT("via" == role);
if (std::numeric_limits<unsigned>::max() !=
current_restriction_container.viaNode)
{
current_restriction_container.viaNode =
std::numeric_limits<unsigned>::max();
}
BOOST_ASSERT(std::numeric_limits<unsigned>::max() ==
current_restriction_container.viaNode);
current_restriction_container.restriction.viaNode =
static_cast<NodeID>(last_ref);
break;
case 1: // way
BOOST_ASSERT("from" == role || "to" == role || "via" == role);
if ("from" == role)
{
current_restriction_container.fromWay = static_cast<EdgeID>(last_ref);
}
if ("to" == role)
{
current_restriction_container.toWay = static_cast<EdgeID>(last_ref);
}
if ("via" == role)
{
BOOST_ASSERT(current_restriction_container.restriction.toNode ==
std::numeric_limits<unsigned>::max());
current_restriction_container.viaNode = static_cast<NodeID>(last_ref);
}
break;
case 2: // relation, not used. relations relating to relations are evil.
continue;
BOOST_ASSERT(false);
break;
default: // should not happen
BOOST_ASSERT(false);
break;
}
}
if (!extractor_callbacks->ProcessRestriction(current_restriction_container))
{
std::cerr << "[PBFParser] relation not parsed" << std::endl;
}
}
}
}
inline void PBFParser::parseWay(ParserThreadData *thread_data)
{
const int number_of_ways =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).ways_size();
std::vector<ExtractionWay> parsed_way_vector(number_of_ways);
for (int i = 0; i < number_of_ways; ++i)
{
const OSMPBF::Way &input_way =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID).ways(i);
parsed_way_vector[i].id = static_cast<EdgeID>(input_way.id());
unsigned node_id_in_path = 0;
const auto number_of_referenced_nodes = input_way.refs_size();
for (auto j = 0; j < number_of_referenced_nodes; ++j)
{
node_id_in_path += static_cast<NodeID>(input_way.refs(j));
parsed_way_vector[i].path.push_back(node_id_in_path);
}
BOOST_ASSERT(input_way.keys_size() == input_way.vals_size());
const auto number_of_keys = input_way.keys_size();
for (auto j = 0; j < number_of_keys; ++j)
{
const std::string &key =
thread_data->PBFprimitiveBlock.stringtable().s(input_way.keys(j));
const std::string &val =
thread_data->PBFprimitiveBlock.stringtable().s(input_way.vals(j));
parsed_way_vector[i].keyVals.Add(std::move(key), std::move(val));
}
}
// TODO: investigate if schedule guided will be handled by tbb automatically
tbb::parallel_for(tbb::blocked_range<size_t>(0, parsed_way_vector.size()),
[this, &parsed_way_vector](const tbb::blocked_range<size_t> &range)
{
lua_State *lua_state = this->scripting_environment.getLuaState();
for (size_t i = range.begin(); i != range.end(); i++)
{
ExtractionWay &extraction_way = parsed_way_vector[i];
if (2 <= extraction_way.path.size())
{
ParseWayInLua(extraction_way, lua_state);
}
}
});
for (ExtractionWay &extraction_way : parsed_way_vector)
{
if (2 <= extraction_way.path.size())
{
extractor_callbacks->ProcessWay(extraction_way);
}
}
}
inline void PBFParser::loadGroup(ParserThreadData *thread_data)
{
#ifndef NDEBUG
++group_count;
#endif
const OSMPBF::PrimitiveGroup &group =
thread_data->PBFprimitiveBlock.primitivegroup(thread_data->currentGroupID);
thread_data->entityTypeIndicator = TypeDummy;
if (0 != group.nodes_size())
{
thread_data->entityTypeIndicator = TypeNode;
}
if (0 != group.ways_size())
{
thread_data->entityTypeIndicator = TypeWay;
}
if (0 != group.relations_size())
{
thread_data->entityTypeIndicator = TypeRelation;
}
if (group.has_dense())
{
thread_data->entityTypeIndicator = TypeDenseNode;
BOOST_ASSERT(0 != group.dense().id_size());
}
BOOST_ASSERT(thread_data->entityTypeIndicator != TypeDummy);
}
inline void PBFParser::loadBlock(ParserThreadData *thread_data)
{
++block_count;
thread_data->currentGroupID = 0;
thread_data->currentEntityID = 0;
}
inline bool PBFParser::readPBFBlobHeader(std::fstream &stream, ParserThreadData *thread_data)
{
int size(0);
stream.read((char *)&size, sizeof(int));
size = SwapEndian(size);
if (stream.eof())
{
return false;
}
if (size > MAX_BLOB_HEADER_SIZE || size < 0)
{
return false;
}
char *data = new char[size];
stream.read(data, size * sizeof(data[0]));
bool dataSuccessfullyParsed = (thread_data->PBFBlobHeader).ParseFromArray(data, size);
delete[] data;
return dataSuccessfullyParsed;
}
inline bool PBFParser::unpackZLIB(ParserThreadData *thread_data)
{
auto raw_size = thread_data->PBFBlob.raw_size();
char *unpacked_data_array = new char[raw_size];
z_stream compressed_data_stream;
compressed_data_stream.next_in = (unsigned char *)thread_data->PBFBlob.zlib_data().data();
compressed_data_stream.avail_in = thread_data->PBFBlob.zlib_data().size();
compressed_data_stream.next_out = (unsigned char *)unpacked_data_array;
compressed_data_stream.avail_out = raw_size;
compressed_data_stream.zalloc = Z_NULL;
compressed_data_stream.zfree = Z_NULL;
compressed_data_stream.opaque = Z_NULL;
int return_code = inflateInit(&compressed_data_stream);
if (return_code != Z_OK)
{
std::cerr << "[error] failed to init zlib stream" << std::endl;
delete[] unpacked_data_array;
return false;
}
return_code = inflate(&compressed_data_stream, Z_FINISH);
if (return_code != Z_STREAM_END)
{
std::cerr << "[error] failed to inflate zlib stream" << std::endl;
std::cerr << "[error] Error type: " << return_code << std::endl;
delete[] unpacked_data_array;
return false;
}
return_code = inflateEnd(&compressed_data_stream);
if (return_code != Z_OK)
{
std::cerr << "[error] failed to deinit zlib stream" << std::endl;
delete[] unpacked_data_array;
return false;
}
thread_data->charBuffer.clear();
thread_data->charBuffer.resize(raw_size);
std::copy(unpacked_data_array, unpacked_data_array + raw_size, thread_data->charBuffer.begin());
delete[] unpacked_data_array;
return true;
}
inline bool PBFParser::unpackLZMA(ParserThreadData *) { return false; }
inline bool PBFParser::readBlob(std::fstream &stream, ParserThreadData *thread_data)
{
if (stream.eof())
{
return false;
}
const int size = thread_data->PBFBlobHeader.datasize();
if (size < 0 || size > MAX_BLOB_SIZE)
{
std::cerr << "[error] invalid Blob size:" << size << std::endl;
return false;
}
char *data = new char[size];
stream.read(data, sizeof(data[0]) * size);
if (!thread_data->PBFBlob.ParseFromArray(data, size))
{
std::cerr << "[error] failed to parse blob" << std::endl;
delete[] data;
return false;
}
if (thread_data->PBFBlob.has_raw())
{
const std::string &data = thread_data->PBFBlob.raw();
thread_data->charBuffer.clear();
thread_data->charBuffer.resize(data.size());
std::copy(data.begin(), data.end(), thread_data->charBuffer.begin());
}
else if (thread_data->PBFBlob.has_zlib_data())
{
if (!unpackZLIB(thread_data))
{
std::cerr << "[error] zlib data encountered that could not be unpacked" << std::endl;
delete[] data;
return false;
}
}
else if (thread_data->PBFBlob.has_lzma_data())
{
if (!unpackLZMA(thread_data))
{
std::cerr << "[error] lzma data encountered that could not be unpacked" << std::endl;
}
delete[] data;
return false;
}
else
{
std::cerr << "[error] Blob contains no data" << std::endl;
delete[] data;
return false;
}
delete[] data;
return true;
}
bool PBFParser::readNextBlock(std::fstream &stream, ParserThreadData *thread_data)
{
if (stream.eof())
{
return false;
}
if (!readPBFBlobHeader(stream, thread_data))
{
return false;
}
if (thread_data->PBFBlobHeader.type() != "OSMData")
{
return false;
}
if (!readBlob(stream, thread_data))
{
return false;
}
if (!thread_data->PBFprimitiveBlock.ParseFromArray(&(thread_data->charBuffer[0]),
thread_data->charBuffer.size()))
{
std::cerr << "failed to parse PrimitiveBlock" << std::endl;
return false;
}
return true;
}
-103
View File
@@ -1,103 +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 PBFPARSER_H_
#define PBFPARSER_H_
#include "BaseParser.h"
#include "../DataStructures/ConcurrentQueue.h"
#include <osmpbf/fileformat.pb.h>
#include <osmpbf/osmformat.pb.h>
#include <fstream>
#include <memory>
class PBFParser : public BaseParser
{
enum EntityType
{ TypeDummy = 0,
TypeNode = 1,
TypeWay = 2,
TypeRelation = 4,
TypeDenseNode = 8 };
struct ParserThreadData
{
int currentGroupID;
int currentEntityID;
EntityType entityTypeIndicator;
OSMPBF::BlobHeader PBFBlobHeader;
OSMPBF::Blob PBFBlob;
OSMPBF::HeaderBlock PBFHeaderBlock;
OSMPBF::PrimitiveBlock PBFprimitiveBlock;
std::vector<char> charBuffer;
};
public:
PBFParser(const char *file_name,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment,
unsigned num_parser_threads = 0);
virtual ~PBFParser();
inline bool ReadHeader();
inline bool Parse();
private:
inline void ReadData();
inline void ParseData();
inline void parseDenseNode(ParserThreadData *thread_data);
inline void parseNode(ParserThreadData *thread_data);
inline void parseRelation(ParserThreadData *thread_data);
inline void parseWay(ParserThreadData *thread_data);
inline void loadGroup(ParserThreadData *thread_data);
inline void loadBlock(ParserThreadData *thread_data);
inline bool readPBFBlobHeader(std::fstream &stream, ParserThreadData *thread_data);
inline bool unpackZLIB(ParserThreadData *thread_data);
inline bool unpackLZMA(ParserThreadData *thread_data);
inline bool readBlob(std::fstream &stream, ParserThreadData *thread_data);
inline bool readNextBlock(std::fstream &stream, ParserThreadData *thread_data);
static const int NANO = 1000 * 1000 * 1000;
static const int MAX_BLOB_HEADER_SIZE = 64 * 1024;
static const int MAX_BLOB_SIZE = 32 * 1024 * 1024;
unsigned group_count;
unsigned block_count;
std::fstream input; // the input stream to parse
std::shared_ptr<ConcurrentQueue<ParserThreadData *>> thread_data_queue;
unsigned num_parser_threads;
};
#endif /* PBFPARSER_H_ */
-122
View File
@@ -1,122 +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 "ScriptingEnvironment.h"
#include "ExtractionHelperFunctions.h"
#include "ExtractionWay.h"
#include "../DataStructures/ImportNode.h"
#include "../Util/LuaUtil.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../typedefs.h"
#include <sstream>
ScriptingEnvironment::ScriptingEnvironment() {}
ScriptingEnvironment::ScriptingEnvironment(const char *file_name)
: file_name(file_name)
{
SimpleLogger().Write() << "Using script " << file_name;
}
void ScriptingEnvironment::initLuaState(lua_State* lua_state)
{
luabind::open(lua_state);
// open utility libraries string library;
luaL_openlibs(lua_state);
luaAddScriptFolderToLoadPath(lua_state, file_name.c_str());
// Add our function to the state's global scope
luabind::module(lua_state)[
luabind::def("print", LUA_print<std::string>),
luabind::def("durationIsValid", durationIsValid),
luabind::def("parseDuration", parseDuration),
luabind::class_<HashTable<std::string, std::string>>("keyVals")
.def("Add", &HashTable<std::string, std::string>::Add)
.def("Find", &HashTable<std::string, std::string>::Find)
.def("Holds", &HashTable<std::string, std::string>::Holds),
luabind::class_<ImportNode>("Node")
// .def(luabind::constructor<>())
.def_readwrite("lat", &ImportNode::lat)
.def_readwrite("lon", &ImportNode::lon)
.def_readonly("id", &ImportNode::node_id)
.def_readwrite("bollard", &ImportNode::bollard)
.def_readwrite("traffic_light", &ImportNode::trafficLight)
.def_readwrite("tags", &ImportNode::keyVals),
luabind::class_<ExtractionWay>("Way")
// .def(luabind::constructor<>())
.def_readonly("id", &ExtractionWay::id)
.def_readwrite("name", &ExtractionWay::name)
.def_readwrite("forward_speed", &ExtractionWay::forward_speed)
.def_readwrite("backward_speed", &ExtractionWay::backward_speed)
.def_readwrite("duration", &ExtractionWay::duration)
.def_readwrite("access", &ExtractionWay::access)
.def_readwrite("roundabout", &ExtractionWay::roundabout)
.def_readwrite("is_access_restricted", &ExtractionWay::isAccessRestricted)
.def_readwrite("ignore_in_grid", &ExtractionWay::ignoreInGrid)
.def_readwrite("tags", &ExtractionWay::keyVals)
.property("direction", &ExtractionWay::get_direction, &ExtractionWay::set_direction)
.property("forward_mode", &ExtractionWay::get_forward_mode, &ExtractionWay::set_forward_mode)
.property("backward_mode", &ExtractionWay::get_backward_mode, &ExtractionWay::set_backward_mode)
.enum_("constants")[
luabind::value("notSure", 0),
luabind::value("oneway", 1),
luabind::value("bidirectional", 2),
luabind::value("opposite", 3)
],
luabind::class_<std::vector<std::string>>("vector")
.def("Add", static_cast<void (std::vector<std::string>::*)(const std::string &)>(&std::vector<std::string>::push_back))
];
if (0 != luaL_dofile(lua_state, file_name.c_str()))
{
luabind::object error_msg(luabind::from_stack(lua_state, -1));
std::ostringstream error_stream;
error_stream << error_msg;
throw OSRMException("ERROR occured in profile script:\n" + error_stream.str());
}
}
lua_State *ScriptingEnvironment::getLuaState()
{
bool initialized = false;
auto& ref = script_contexts.local(initialized);
if (!initialized)
{
std::shared_ptr<lua_State> state(luaL_newstate(), lua_close);
ref = state;
initLuaState(ref.get());
}
return ref.get();
}
-354
View File
@@ -1,354 +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 "XMLParser.h"
#include "ExtractionWay.h"
#include "ExtractorCallbacks.h"
#include "../DataStructures/HashTable.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/InputReaderFactory.h"
#include "../DataStructures/Restriction.h"
#include "../Util/cast.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../typedefs.h"
#include <osrm/Coordinate.h>
XMLParser::XMLParser(const char *filename,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment)
: BaseParser(extractor_callbacks, scripting_environment)
{
inputReader = inputReaderFactory(filename);
}
bool XMLParser::ReadHeader() { return xmlTextReaderRead(inputReader) == 1; }
bool XMLParser::Parse()
{
while (xmlTextReaderRead(inputReader) == 1)
{
const int type = xmlTextReaderNodeType(inputReader);
// 1 is Element
if (type != 1)
{
continue;
}
xmlChar *currentName = xmlTextReaderName(inputReader);
if (currentName == nullptr)
{
continue;
}
if (xmlStrEqual(currentName, (const xmlChar *)"node") == 1)
{
ImportNode current_node = ReadXMLNode();
ParseNodeInLua(current_node, lua_state);
extractor_callbacks->ProcessNode(current_node);
}
if (xmlStrEqual(currentName, (const xmlChar *)"way") == 1)
{
ExtractionWay way = ReadXMLWay();
ParseWayInLua(way, lua_state);
extractor_callbacks->ProcessWay(way);
}
if (use_turn_restrictions && xmlStrEqual(currentName, (const xmlChar *)"relation") == 1)
{
InputRestrictionContainer current_restriction = ReadXMLRestriction();
if ((UINT_MAX != current_restriction.fromWay) &&
!extractor_callbacks->ProcessRestriction(current_restriction))
{
std::cerr << "[XMLParser] restriction not parsed" << std::endl;
}
}
xmlFree(currentName);
}
return true;
}
InputRestrictionContainer XMLParser::ReadXMLRestriction()
{
InputRestrictionContainer restriction;
if (xmlTextReaderIsEmptyElement(inputReader) == 1)
{
return restriction;
}
std::string except_tag_string;
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int child_type = xmlTextReaderNodeType(inputReader);
if (child_type != 1 && child_type != 15)
{
continue;
}
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"relation") == 1)
{
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(child_name);
continue;
}
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (key != nullptr && value != nullptr)
{
if (xmlStrEqual(key, (const xmlChar *)"restriction") &&
StringStartsWith((const char *)value, "only_"))
{
restriction.restriction.flags.isOnly = true;
}
if (xmlStrEqual(key, (const xmlChar *)"except"))
{
except_tag_string = (const char *)value;
}
}
if (key != nullptr)
{
xmlFree(key);
}
if (value != nullptr)
{
xmlFree(value);
}
}
else if (xmlStrEqual(child_name, (const xmlChar *)"member") == 1)
{
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != nullptr)
{
xmlChar *role = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"role");
xmlChar *type = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"type");
if (xmlStrEqual(role, (const xmlChar *)"to") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.toWay = cast::string_to_uint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"from") &&
xmlStrEqual(type, (const xmlChar *)"way"))
{
restriction.fromWay = cast::string_to_uint((const char *)ref);
}
if (xmlStrEqual(role, (const xmlChar *)"via") &&
xmlStrEqual(type, (const xmlChar *)"node"))
{
restriction.restriction.viaNode = cast::string_to_uint((const char *)ref);
}
if (nullptr != type)
{
xmlFree(type);
}
if (nullptr != role)
{
xmlFree(role);
}
if (nullptr != ref)
{
xmlFree(ref);
}
}
}
xmlFree(child_name);
}
if (ShouldIgnoreRestriction(except_tag_string))
{
restriction.fromWay = UINT_MAX; // workaround to ignore the restriction
}
return restriction;
}
ExtractionWay XMLParser::ReadXMLWay()
{
ExtractionWay way;
if (xmlTextReaderIsEmptyElement(inputReader) == 1)
{
return way;
}
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int child_type = xmlTextReaderNodeType(inputReader);
if (child_type != 1 && child_type != 15)
{
continue;
}
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"way") == 1)
{
xmlChar *way_id = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
way.id = cast::string_to_uint((char *)way_id);
xmlFree(way_id);
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(child_name);
continue;
}
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (key != nullptr && value != nullptr)
{
way.keyVals.Add(std::string((char *)key), std::string((char *)value));
}
if (key != nullptr)
{
xmlFree(key);
}
if (value != nullptr)
{
xmlFree(value);
}
}
else if (xmlStrEqual(child_name, (const xmlChar *)"nd") == 1)
{
xmlChar *ref = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"ref");
if (ref != nullptr)
{
way.path.push_back(cast::string_to_uint((const char *)ref));
xmlFree(ref);
}
}
xmlFree(child_name);
}
return way;
}
ImportNode XMLParser::ReadXMLNode()
{
ImportNode node;
xmlChar *attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lat");
if (attribute != nullptr)
{
node.lat = static_cast<int>(COORDINATE_PRECISION * cast::string_to_double((const char *)attribute));
xmlFree(attribute);
}
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"lon");
if (attribute != nullptr)
{
node.lon = static_cast<int>(COORDINATE_PRECISION * cast::string_to_double((const char *)attribute));
xmlFree(attribute);
}
attribute = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"id");
if (attribute != nullptr)
{
node.node_id = cast::string_to_uint((const char *)attribute);
xmlFree(attribute);
}
if (xmlTextReaderIsEmptyElement(inputReader) == 1)
{
return node;
}
const int depth = xmlTextReaderDepth(inputReader);
while (xmlTextReaderRead(inputReader) == 1)
{
const int child_type = xmlTextReaderNodeType(inputReader);
// 1 = Element, 15 = EndElement
if (child_type != 1 && child_type != 15)
{
continue;
}
const int child_depth = xmlTextReaderDepth(inputReader);
xmlChar *child_name = xmlTextReaderName(inputReader);
if (child_name == nullptr)
{
continue;
}
if (depth == child_depth && child_type == 15 &&
xmlStrEqual(child_name, (const xmlChar *)"node") == 1)
{
xmlFree(child_name);
break;
}
if (child_type != 1)
{
xmlFree(child_name);
continue;
}
if (xmlStrEqual(child_name, (const xmlChar *)"tag") == 1)
{
xmlChar *key = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"k");
xmlChar *value = xmlTextReaderGetAttribute(inputReader, (const xmlChar *)"v");
if (key != nullptr && value != nullptr)
{
node.keyVals.Add(std::string((char *)(key)), std::string((char *)(value)));
}
if (key != nullptr)
{
xmlFree(key);
}
if (value != nullptr)
{
xmlFree(value);
}
}
xmlFree(child_name);
}
return node;
}
-54
View File
@@ -1,54 +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 XMLPARSER_H_
#define XMLPARSER_H_
#include "BaseParser.h"
#include "../DataStructures/Restriction.h"
#include <libxml/xmlreader.h>
class ExtractorCallbacks;
class XMLParser : public BaseParser
{
public:
XMLParser(const char *filename,
ExtractorCallbacks *extractor_callbacks,
ScriptingEnvironment &scripting_environment);
bool ReadHeader();
bool Parse();
private:
InputRestrictionContainer ReadXMLRestriction();
ExtractionWay ReadXMLWay();
ImportNode ReadXMLNode();
xmlTextReaderPtr inputReader;
};
#endif /* XMLPARSER_H_ */
+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
-111
View File
@@ -1,111 +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>
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 isValid() 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_ */
-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 REPLY_H
#define REPLY_H
#include "Header.h"
#include <boost/asio.hpp>
#include <vector>
namespace http
{
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";
class Reply
{
public:
enum status_type
{ ok = 200,
badRequest = 400,
internalServerError = 500 } status;
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();
Reply();
private:
std::string ToString(Reply::status_type status);
boost::asio::const_buffer ToBuffer(Reply::status_type status);
};
}
#endif // REPLY_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,
-166
View File
@@ -1,166 +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.
*/
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/BasePlugin.h"
#include "../Plugins/DistanceTablePlugin.h"
#include "../Plugins/HelloWorldPlugin.h"
#include "../Plugins/LocatePlugin.h"
#include "../Plugins/NearestPlugin.h"
#include "../Plugins/TimestampPlugin.h"
#include "../Plugins/ViaRoutePlugin.h"
#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);
}
-50
View File
@@ -1,50 +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 BASEPLUGIN_H_
#define BASEPLUGIN_H_
#include "../Util/StringUtil.h"
#include <osrm/Coordinate.h>
#include <osrm/Reply.h>
#include <osrm/RouteParameters.h>
#include <string>
#include <vector>
class BasePlugin
{
public:
BasePlugin() {}
// Maybe someone can explain the pure virtual destructor thing to me (dennis)
virtual ~BasePlugin() {}
virtual const std::string GetDescriptor() const = 0;
virtual void HandleRequest(const RouteParameters &routeParameters, http::Reply &reply) = 0;
};
#endif /* BASEPLUGIN_H_ */
-148
View File
@@ -1,148 +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 DISTANCE_TABLE_PLUGIN_H
#define DISTANCE_TABLE_PLUGIN_H
#include "BasePlugin.h"
#include "../Algorithms/ObjectToBase64.h"
#include "../DataStructures/JSONContainer.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/SearchEngine.h"
#include "../Descriptors/BaseDescriptor.h"
#include "../Util/make_unique.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include <cstdlib>
#include <algorithm>
#include <memory>
#include <unordered_map>
#include <string>
#include <vector>
template <class DataFacadeT> class DistanceTablePlugin final : public BasePlugin
{
private:
std::unique_ptr<SearchEngine<DataFacadeT>> search_engine_ptr;
public:
explicit DistanceTablePlugin(DataFacadeT *facade) : descriptor_string("table"), facade(facade)
{
search_engine_ptr = osrm::make_unique<SearchEngine<DataFacadeT>>(facade);
}
virtual ~DistanceTablePlugin() {}
const std::string GetDescriptor() const final { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
// check number of parameters
if (2 > route_parameters.coordinates.size())
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
RawRouteData raw_route;
raw_route.check_sum = facade->GetCheckSum();
if (std::any_of(begin(route_parameters.coordinates),
end(route_parameters.coordinates),
[&](FixedPointCoordinate coordinate)
{
return !coordinate.isValid();
}))
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
for (const FixedPointCoordinate &coordinate : route_parameters.coordinates)
{
raw_route.raw_via_node_coordinates.emplace_back(std::move(coordinate));
}
const bool checksum_OK = (route_parameters.check_sum == raw_route.check_sum);
unsigned max_locations =
std::min(100u, static_cast<unsigned>(raw_route.raw_via_node_coordinates.size()));
PhantomNodeArray phantom_node_vector(max_locations);
for (unsigned i = 0; i < max_locations; ++i)
{
if (checksum_OK && i < route_parameters.hints.size() &&
!route_parameters.hints[i].empty())
{
PhantomNode current_phantom_node;
ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], current_phantom_node);
if (current_phantom_node.isValid(facade->GetNumberOfNodes()))
{
phantom_node_vector[i].emplace_back(std::move(current_phantom_node));
continue;
}
}
facade->IncrementalFindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i],
phantom_node_vector[i],
route_parameters.zoom_level,
1);
BOOST_ASSERT(phantom_node_vector[i].front().isValid(facade->GetNumberOfNodes()));
}
// TIMER_START(distance_table);
std::shared_ptr<std::vector<EdgeWeight>> result_table =
search_engine_ptr->distance_table(phantom_node_vector);
// TIMER_STOP(distance_table);
if (!result_table)
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
JSON::Object json_object;
JSON::Array json_array;
const unsigned number_of_locations = static_cast<unsigned>(phantom_node_vector.size());
for (unsigned row = 0; row < number_of_locations; ++row)
{
JSON::Array json_row;
auto row_begin_iterator = result_table->begin() + (row * number_of_locations);
auto row_end_iterator = result_table->begin() + ((row + 1) * number_of_locations);
json_row.values.insert(json_row.values.end(), row_begin_iterator, row_end_iterator);
json_array.values.push_back(json_row);
}
json_object.values["distance_table"] = json_array;
JSON::render(reply.content, json_object);
}
private:
std::string descriptor_string;
DataFacadeT *facade;
};
#endif // DISTANCE_TABLE_PLUGIN_H
-78
View File
@@ -1,78 +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 LOCATE_PLUGIN_H
#define LOCATE_PLUGIN_H
#include "BasePlugin.h"
#include "../DataStructures/JSONContainer.h"
#include "../Util/StringUtil.h"
#include <string>
// locates the nearest node in the road network for a given coordinate.
template <class DataFacadeT> class LocatePlugin final : public BasePlugin
{
public:
explicit LocatePlugin(DataFacadeT *facade) : descriptor_string("locate"), facade(facade) {}
const std::string GetDescriptor() const final { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
// check number of parameters
if (route_parameters.coordinates.empty() || !route_parameters.coordinates.front().isValid())
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
JSON::Object json_result;
FixedPointCoordinate result;
if (!facade->LocateClosestEndPointForCoordinate(route_parameters.coordinates.front(),
result))
{
json_result.values["status"] = 207;
}
else
{
reply.status = http::Reply::ok;
json_result.values["status"] = 0;
JSON::Array json_coordinate;
json_coordinate.values.push_back(result.lat / COORDINATE_PRECISION);
json_coordinate.values.push_back(result.lon / COORDINATE_PRECISION);
json_result.values["mapped_coordinate"] = json_coordinate;
}
JSON::render(reply.content, json_result);
}
private:
std::string descriptor_string;
DataFacadeT *facade;
};
#endif /* LOCATE_PLUGIN_H */
-116
View File
@@ -1,116 +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 NEAREST_PLUGIN_H
#define NEAREST_PLUGIN_H
#include "BasePlugin.h"
#include "../DataStructures/JSONContainer.h"
#include "../DataStructures/PhantomNodes.h"
#include "../DataStructures/Range.h"
#include <string>
/*
* This Plugin locates the nearest point on a street in the road network for a given coordinate.
*/
template <class DataFacadeT> class NearestPlugin final : public BasePlugin
{
public:
explicit NearestPlugin(DataFacadeT *facade) : facade(facade), descriptor_string("nearest") {}
const std::string GetDescriptor() const final { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
// check number of parameters
if (route_parameters.coordinates.empty() || !route_parameters.coordinates.front().isValid())
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
auto number_of_results = static_cast<std::size_t>(route_parameters.num_results);
std::vector<PhantomNode> phantom_node_vector;
facade->IncrementalFindPhantomNodeForCoordinate(route_parameters.coordinates.front(),
phantom_node_vector,
route_parameters.zoom_level,
static_cast<int>(number_of_results));
JSON::Object json_result;
if (phantom_node_vector.empty() || !phantom_node_vector.front().isValid())
{
json_result.values["status"] = 207;
}
else
{
reply.status = http::Reply::ok;
json_result.values["status"] = 0;
if (number_of_results > 1)
{
JSON::Array results;
auto vector_length = phantom_node_vector.size();
for (const auto i : osrm::irange<std::size_t>(0, std::min(number_of_results, vector_length)))
{
JSON::Array json_coordinate;
JSON::Object result;
json_coordinate.values.push_back(phantom_node_vector.at(i).location.lat /
COORDINATE_PRECISION);
json_coordinate.values.push_back(phantom_node_vector.at(i).location.lon /
COORDINATE_PRECISION);
result.values["mapped coordinate"] = json_coordinate;
std::string temp_string;
facade->GetName(phantom_node_vector.front().name_id, temp_string);
result.values["name"] = temp_string;
results.values.push_back(result);
}
json_result.values["results"] = results;
}
else
{
JSON::Array json_coordinate;
json_coordinate.values.push_back(phantom_node_vector.front().location.lat /
COORDINATE_PRECISION);
json_coordinate.values.push_back(phantom_node_vector.front().location.lon /
COORDINATE_PRECISION);
json_result.values["mapped_coordinate"] = json_coordinate;
std::string temp_string;
facade->GetName(phantom_node_vector.front().name_id, temp_string);
json_result.values["name"] = temp_string;
}
}
JSON::render(reply.content, json_result);
}
private:
DataFacadeT *facade;
std::string descriptor_string;
};
#endif /* NEAREST_PLUGIN_H */
-176
View File
@@ -1,176 +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 VIA_ROUTE_PLUGIN_H
#define VIA_ROUTE_PLUGIN_H
#include "BasePlugin.h"
#include "../Algorithms/ObjectToBase64.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/SearchEngine.h"
#include "../Descriptors/BaseDescriptor.h"
#include "../Descriptors/GPXDescriptor.h"
#include "../Descriptors/JSONDescriptor.h"
#include "../Util/make_unique.hpp"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include <cstdlib>
#include <algorithm>
#include <memory>
#include <unordered_map>
#include <string>
#include <vector>
template <class DataFacadeT> class ViaRoutePlugin final : public BasePlugin
{
private:
std::unordered_map<std::string, unsigned> descriptor_table;
std::unique_ptr<SearchEngine<DataFacadeT>> search_engine_ptr;
public:
explicit ViaRoutePlugin(DataFacadeT *facade) : descriptor_string("viaroute"), facade(facade)
{
search_engine_ptr = osrm::make_unique<SearchEngine<DataFacadeT>>(facade);
descriptor_table.emplace("json", 0);
descriptor_table.emplace("gpx", 1);
// descriptor_table.emplace("geojson", 2);
}
virtual ~ViaRoutePlugin() {}
const std::string GetDescriptor() const final { return descriptor_string; }
void HandleRequest(const RouteParameters &route_parameters, http::Reply &reply) final
{
// check number of parameters
if (2 > route_parameters.coordinates.size() ||
std::any_of(begin(route_parameters.coordinates),
end(route_parameters.coordinates),
[&](FixedPointCoordinate coordinate)
{
return !coordinate.isValid();
}))
{
reply = http::Reply::StockReply(http::Reply::badRequest);
return;
}
RawRouteData raw_route;
raw_route.check_sum = facade->GetCheckSum();
for (const FixedPointCoordinate &coordinate : route_parameters.coordinates)
{
raw_route.raw_via_node_coordinates.emplace_back(coordinate);
}
std::vector<PhantomNode> phantom_node_vector(raw_route.raw_via_node_coordinates.size());
const bool checksum_OK = (route_parameters.check_sum == raw_route.check_sum);
for (unsigned i = 0; i < raw_route.raw_via_node_coordinates.size(); ++i)
{
if (checksum_OK && i < route_parameters.hints.size() &&
!route_parameters.hints[i].empty())
{
ObjectEncoder::DecodeFromBase64(route_parameters.hints[i], phantom_node_vector[i]);
if (phantom_node_vector[i].isValid(facade->GetNumberOfNodes()))
{
continue;
}
}
facade->FindPhantomNodeForCoordinate(raw_route.raw_via_node_coordinates[i],
phantom_node_vector[i],
route_parameters.zoom_level);
}
PhantomNodes current_phantom_node_pair;
for (unsigned i = 0; i < phantom_node_vector.size() - 1; ++i)
{
current_phantom_node_pair.source_phantom = phantom_node_vector[i];
current_phantom_node_pair.target_phantom = phantom_node_vector[i + 1];
raw_route.segment_end_coordinates.emplace_back(current_phantom_node_pair);
}
const bool is_alternate_requested = route_parameters.alternate_route;
const bool is_only_one_segment = (1 == raw_route.segment_end_coordinates.size());
if (is_alternate_requested && is_only_one_segment)
{
search_engine_ptr->alternative_path(raw_route.segment_end_coordinates.front(),
raw_route);
}
else
{
search_engine_ptr->shortest_path(
raw_route.segment_end_coordinates, route_parameters.uturns, raw_route);
}
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
{
SimpleLogger().Write(logDEBUG) << "Error occurred, single path not found";
}
reply.status = http::Reply::ok;
DescriptorConfig descriptor_config;
auto iter = descriptor_table.find(route_parameters.output_format);
unsigned descriptor_type = (iter != descriptor_table.end() ? iter->second : 0);
descriptor_config.zoom_level = route_parameters.zoom_level;
descriptor_config.instructions = route_parameters.print_instructions;
descriptor_config.geometry = route_parameters.geometry;
descriptor_config.encode_geometry = route_parameters.compression;
std::shared_ptr<BaseDescriptor<DataFacadeT>> descriptor;
switch (descriptor_type)
{
// case 0:
// descriptor = std::make_shared<JSONDescriptor<DataFacadeT>>();
// break;
case 1:
descriptor = std::make_shared<GPXDescriptor<DataFacadeT>>(facade);
break;
// case 2:
// descriptor = std::make_shared<GEOJSONDescriptor<DataFacadeT>>();
// break;
default:
descriptor = std::make_shared<JSONDescriptor<DataFacadeT>>(facade);
break;
}
descriptor->SetConfig(descriptor_config);
descriptor->Run(raw_route, reply);
}
private:
std::string descriptor_string;
DataFacadeT *facade;
};
#endif // VIA_ROUTE_PLUGIN_H
+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) |
-413
View File
@@ -1,413 +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 BASIC_ROUTING_INTERFACE_H
#define BASIC_ROUTING_INTERFACE_H
#include "../DataStructures/RawRouteData.h"
#include "../DataStructures/SearchEngineData.h"
#include "../DataStructures/TurnInstructions.h"
// #include "../Util/simple_logger.hpp.h"
#include <boost/assert.hpp>
#include <stack>
SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap2;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap2;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::forwardHeap3;
SearchEngineData::SearchEngineHeapPtr SearchEngineData::backwardHeap3;
template <class DataFacadeT> class BasicRoutingInterface
{
private:
typedef typename DataFacadeT::EdgeData EdgeData;
protected:
DataFacadeT *facade;
public:
BasicRoutingInterface() = delete;
BasicRoutingInterface(const BasicRoutingInterface &) = delete;
explicit BasicRoutingInterface(DataFacadeT *facade) : facade(facade) {}
virtual ~BasicRoutingInterface() {};
inline void RoutingStep(SearchEngineData::QueryHeap &forward_heap,
SearchEngineData::QueryHeap &reverse_heap,
NodeID *middle_node_id,
int *upper_bound,
const int min_edge_offset,
const bool forward_direction) const
{
const NodeID node = forward_heap.DeleteMin();
const int distance = forward_heap.GetKey(node);
// const NodeID parentnode = forward_heap.GetData(node).parent;
// SimpleLogger().Write() << (forward_direction ? "[fwd] " : "[rev] ") << "settled edge (" << parentnode << "," << node << "), dist: " << distance;
if (reverse_heap.WasInserted(node))
{
const int new_distance = reverse_heap.GetKey(node) + distance;
if (new_distance < *upper_bound)
{
if (new_distance >= 0)
{
*middle_node_id = node;
*upper_bound = new_distance;
// SimpleLogger().Write() << "accepted middle node " << node << " at distance " << new_distance;
// } else {
// SimpleLogger().Write() << "discared middle node " << node << " at distance " << new_distance;
}
}
}
if (distance + min_edge_offset > *upper_bound)
{
// SimpleLogger().Write() << "min_edge_offset: " << min_edge_offset;
forward_heap.DeleteAll();
return;
}
// Stalling
for (const auto edge : facade->GetAdjacentEdgeRange(node))
{
const EdgeData &data = facade->GetEdgeData(edge);
const bool reverse_flag = ((!forward_direction) ? data.forward : data.backward);
if (reverse_flag)
{
const NodeID to = facade->GetTarget(edge);
const int edge_weight = data.distance;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
if (forward_heap.WasInserted(to))
{
if (forward_heap.GetKey(to) + edge_weight < distance)
{
return;
}
}
}
}
for (const auto edge : facade->GetAdjacentEdgeRange(node))
{
const EdgeData &data = facade->GetEdgeData(edge);
bool forward_directionFlag = (forward_direction ? data.forward : data.backward);
if (forward_directionFlag)
{
const NodeID to = facade->GetTarget(edge);
const int edge_weight = data.distance;
BOOST_ASSERT_MSG(edge_weight > 0, "edge_weight invalid");
const int to_distance = distance + edge_weight;
// New Node discovered -> Add to Heap + Node Info Storage
if (!forward_heap.WasInserted(to))
{
forward_heap.Insert(to, to_distance, node);
}
// Found a shorter Path -> Update distance
else if (to_distance < forward_heap.GetKey(to))
{
// new parent
forward_heap.GetData(to).parent = node;
forward_heap.DecreaseKey(to, to_distance);
}
}
}
}
inline void UnpackPath(const std::vector<NodeID> &packed_path,
const PhantomNodes &phantom_node_pair,
std::vector<PathData> &unpacked_path) const
{
const bool start_traversed_in_reverse =
(packed_path.front() != phantom_node_pair.source_phantom.forward_node_id);
const bool target_traversed_in_reverse =
(packed_path.back() != phantom_node_pair.target_phantom.forward_node_id);
const unsigned packed_path_size = static_cast<unsigned>(packed_path.size());
std::stack<std::pair<NodeID, NodeID>> recursion_stack;
// We have to push the path in reverse order onto the stack because it's LIFO.
for (unsigned i = packed_path_size - 1; i > 0; --i)
{
recursion_stack.emplace(packed_path[i - 1], packed_path[i]);
}
std::pair<NodeID, NodeID> edge;
while (!recursion_stack.empty())
{
/*
Graphical representation of variables:
edge.first edge.second
*------------------>*
edge_id
*/
edge = recursion_stack.top();
recursion_stack.pop();
// facade->FindEdge does not suffice here in case of shortcuts.
// The above explanation unclear? Think!
EdgeID smaller_edge_id = SPECIAL_EDGEID;
int edge_weight = std::numeric_limits<EdgeWeight>::max();
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.first))
{
const int weight = facade->GetEdgeData(edge_id).distance;
if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) &&
facade->GetEdgeData(edge_id).forward)
{
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
/*
Graphical representation of variables:
edge.first edge.second
*<------------------*
edge_id
*/
if (SPECIAL_EDGEID == smaller_edge_id)
{
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.second))
{
const int weight = facade->GetEdgeData(edge_id).distance;
if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) &&
facade->GetEdgeData(edge_id).backward)
{
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
}
BOOST_ASSERT_MSG(edge_weight != INVALID_EDGE_WEIGHT, "edge id invalid");
const EdgeData &ed = facade->GetEdgeData(smaller_edge_id);
if (ed.shortcut)
{ // unpack
const NodeID middle_node_id = ed.id;
// again, we need to this in reversed order
recursion_stack.emplace(middle_node_id, edge.second);
recursion_stack.emplace(edge.first, middle_node_id);
}
else
{
BOOST_ASSERT_MSG(!ed.shortcut, "original edge flagged as shortcut");
unsigned name_index = facade->GetNameIndexFromEdgeID(ed.id);
const TurnInstruction turn_instruction = facade->GetTurnInstructionForEdgeID(ed.id);
const TravelMode travel_mode = facade->GetTravelModeForEdgeID(ed.id);
if (!facade->EdgeIsCompressed(ed.id))
{
BOOST_ASSERT(!facade->EdgeIsCompressed(ed.id));
unpacked_path.emplace_back(facade->GetGeometryIndexForEdgeID(ed.id),
name_index,
turn_instruction,
ed.distance,
travel_mode);
}
else
{
std::vector<unsigned> id_vector;
facade->GetUncompressedGeometry(facade->GetGeometryIndexForEdgeID(ed.id),
id_vector);
const std::size_t start_index =
(unpacked_path.empty()
? ((start_traversed_in_reverse)
? id_vector.size() -
phantom_node_pair.source_phantom.fwd_segment_position - 1
: phantom_node_pair.source_phantom.fwd_segment_position)
: 0);
const std::size_t end_index = id_vector.size();
BOOST_ASSERT(start_index >= 0);
BOOST_ASSERT(start_index <= end_index);
for (std::size_t i = start_index; i < end_index; ++i)
{
unpacked_path.emplace_back(id_vector[i], name_index, TurnInstruction::NoTurn, 0, travel_mode);
}
unpacked_path.back().turn_instruction = turn_instruction;
unpacked_path.back().segment_duration = ed.distance;
}
}
}
if (SPECIAL_EDGEID != phantom_node_pair.target_phantom.packed_geometry_id)
{
std::vector<unsigned> id_vector;
facade->GetUncompressedGeometry(phantom_node_pair.target_phantom.packed_geometry_id,
id_vector);
const bool is_local_path = (phantom_node_pair.source_phantom.packed_geometry_id ==
phantom_node_pair.target_phantom.packed_geometry_id) &&
unpacked_path.empty();
std::size_t start_index = 0;
if (is_local_path)
{
start_index = phantom_node_pair.source_phantom.fwd_segment_position;
if (target_traversed_in_reverse)
{
start_index =
id_vector.size() - phantom_node_pair.source_phantom.fwd_segment_position;
}
}
std::size_t end_index = phantom_node_pair.target_phantom.fwd_segment_position;
if (target_traversed_in_reverse)
{
std::reverse(id_vector.begin(), id_vector.end());
end_index =
id_vector.size() - phantom_node_pair.target_phantom.fwd_segment_position;
}
if (start_index > end_index)
{
start_index = std::min(start_index, id_vector.size()-1);
}
for (std::size_t i = start_index; i != end_index; (start_index < end_index ? ++i : --i))
{
BOOST_ASSERT(i < id_vector.size());
BOOST_ASSERT(phantom_node_pair.target_phantom.forward_travel_mode>0 );
unpacked_path.emplace_back(PathData{id_vector[i],
phantom_node_pair.target_phantom.name_id,
TurnInstruction::NoTurn,
0,
phantom_node_pair.target_phantom.forward_travel_mode});
}
}
// there is no equivalent to a node-based node in an edge-expanded graph.
// two equivalent routes may start (or end) at different node-based edges
// as they are added with the offset how much "distance" on the edge
// has already been traversed. Depending on offset one needs to remove
// the last node.
if (unpacked_path.size() > 1)
{
const std::size_t last_index = unpacked_path.size() - 1;
const std::size_t second_to_last_index = last_index - 1;
// looks like a trivially true check but tests for underflow
BOOST_ASSERT(last_index > second_to_last_index);
if (unpacked_path[last_index].node == unpacked_path[second_to_last_index].node)
{
unpacked_path.pop_back();
}
BOOST_ASSERT(!unpacked_path.empty());
}
}
inline void UnpackEdge(const NodeID s, const NodeID t, std::vector<NodeID> &unpacked_path) const
{
std::stack<std::pair<NodeID, NodeID>> recursion_stack;
recursion_stack.emplace(s, t);
std::pair<NodeID, NodeID> edge;
while (!recursion_stack.empty())
{
edge = recursion_stack.top();
recursion_stack.pop();
EdgeID smaller_edge_id = SPECIAL_EDGEID;
int edge_weight = std::numeric_limits<EdgeWeight>::max();
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.first))
{
const int weight = facade->GetEdgeData(edge_id).distance;
if ((facade->GetTarget(edge_id) == edge.second) && (weight < edge_weight) &&
facade->GetEdgeData(edge_id).forward)
{
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
if (SPECIAL_EDGEID == smaller_edge_id)
{
for (const auto edge_id : facade->GetAdjacentEdgeRange(edge.second))
{
const int weight = facade->GetEdgeData(edge_id).distance;
if ((facade->GetTarget(edge_id) == edge.first) && (weight < edge_weight) &&
facade->GetEdgeData(edge_id).backward)
{
smaller_edge_id = edge_id;
edge_weight = weight;
}
}
}
BOOST_ASSERT_MSG(edge_weight != std::numeric_limits<EdgeWeight>::max(), "edge weight invalid");
const EdgeData &ed = facade->GetEdgeData(smaller_edge_id);
if (ed.shortcut)
{ // unpack
const NodeID middle_node_id = ed.id;
// again, we need to this in reversed order
recursion_stack.emplace(middle_node_id, edge.second);
recursion_stack.emplace(edge.first, middle_node_id);
}
else
{
BOOST_ASSERT_MSG(!ed.shortcut, "edge must be shortcut");
unpacked_path.emplace_back(edge.first);
}
}
unpacked_path.emplace_back(t);
}
inline void RetrievePackedPathFromHeap(const SearchEngineData::QueryHeap &forward_heap,
const SearchEngineData::QueryHeap &reverse_heap,
const NodeID middle_node_id,
std::vector<NodeID> &packed_path) const
{
RetrievePackedPathFromSingleHeap(forward_heap, middle_node_id, packed_path);
std::reverse(packed_path.begin(), packed_path.end());
packed_path.emplace_back(middle_node_id);
RetrievePackedPathFromSingleHeap(reverse_heap, middle_node_id, packed_path);
}
inline void RetrievePackedPathFromSingleHeap(const SearchEngineData::QueryHeap &search_heap,
const NodeID middle_node_id,
std::vector<NodeID> &packed_path) const
{
NodeID current_node_id = middle_node_id;
while (current_node_id != search_heap.GetData(current_node_id).parent)
{
current_node_id = search_heap.GetData(current_node_id).parent;
packed_path.emplace_back(current_node_id);
}
}
};
#endif // BASIC_ROUTING_INTERFACE_H
-335
View File
@@ -1,335 +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 SHORTEST_PATH_ROUTING_H
#define SHORTEST_PATH_ROUTING_H
#include <boost/assert.hpp>
#include "BasicRoutingInterface.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/SearchEngineData.h"
#include "../typedefs.h"
template <class DataFacadeT> class ShortestPathRouting final : public BasicRoutingInterface<DataFacadeT>
{
using super = BasicRoutingInterface<DataFacadeT>;
using QueryHeap = SearchEngineData::QueryHeap;
SearchEngineData &engine_working_data;
public:
ShortestPathRouting(DataFacadeT *facade, SearchEngineData &engine_working_data)
: super(facade), engine_working_data(engine_working_data)
{
}
~ShortestPathRouting() {}
void operator()(const std::vector<PhantomNodes> &phantom_nodes_vector,
const std::vector<bool> &uturn_indicators,
RawRouteData &raw_route_data) const
{
int distance1 = 0;
int distance2 = 0;
bool search_from_1st_node = true;
bool search_from_2nd_node = true;
NodeID middle1 = SPECIAL_NODEID;
NodeID middle2 = SPECIAL_NODEID;
std::vector<std::vector<NodeID>> packed_legs1(phantom_nodes_vector.size());
std::vector<std::vector<NodeID>> packed_legs2(phantom_nodes_vector.size());
engine_working_data.InitializeOrClearFirstThreadLocalStorage(
super::facade->GetNumberOfNodes());
engine_working_data.InitializeOrClearSecondThreadLocalStorage(
super::facade->GetNumberOfNodes());
engine_working_data.InitializeOrClearThirdThreadLocalStorage(
super::facade->GetNumberOfNodes());
QueryHeap &forward_heap1 = *(engine_working_data.forwardHeap);
QueryHeap &reverse_heap1 = *(engine_working_data.backwardHeap);
QueryHeap &forward_heap2 = *(engine_working_data.forwardHeap2);
QueryHeap &reverse_heap2 = *(engine_working_data.backwardHeap2);
std::size_t current_leg = 0;
// Get distance to next pair of target nodes.
for (const PhantomNodes &phantom_node_pair : phantom_nodes_vector)
{
forward_heap1.Clear();
forward_heap2.Clear();
reverse_heap1.Clear();
reverse_heap2.Clear();
int local_upper_bound1 = INVALID_EDGE_WEIGHT;
int local_upper_bound2 = INVALID_EDGE_WEIGHT;
middle1 = SPECIAL_NODEID;
middle2 = SPECIAL_NODEID;
const bool allow_u_turn = current_leg > 0 && uturn_indicators.size() > current_leg && uturn_indicators[current_leg-1];
EdgeWeight min_edge_offset = 0;
// insert new starting nodes into forward heap, adjusted by previous distances.
if ((allow_u_turn || search_from_1st_node) &&
phantom_node_pair.source_phantom.forward_node_id != SPECIAL_NODEID)
{
forward_heap1.Insert(
phantom_node_pair.source_phantom.forward_node_id,
(allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id);
min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
forward_heap2.Insert(
phantom_node_pair.source_phantom.forward_node_id,
(allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.source_phantom.forward_node_id);
min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.forward_node_id << ", w: " << (allow_u_turn ? 0 : distance1) - phantom_node_pair.source_phantom.GetForwardWeightPlusOffset();
}
if ((allow_u_turn || search_from_2nd_node) &&
phantom_node_pair.source_phantom.reverse_node_id != SPECIAL_NODEID)
{
forward_heap1.Insert(
phantom_node_pair.source_phantom.reverse_node_id,
(allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id);
min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-a2 insert: " << phantom_node_pair.source_phantom.reverse_node_id <<
// ", w: " << (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
forward_heap2.Insert(
phantom_node_pair.source_phantom.reverse_node_id,
(allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.source_phantom.reverse_node_id);
min_edge_offset = std::min(min_edge_offset, (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset());
// SimpleLogger().Write(logDEBUG) << "fwd-b2 insert: " << phantom_node_pair.source_phantom.reverse_node_id <<
// ", w: " << (allow_u_turn ? 0 : distance2) - phantom_node_pair.source_phantom.GetReverseWeightPlusOffset();
}
// insert new backward nodes into backward heap, unadjusted.
if (phantom_node_pair.target_phantom.forward_node_id != SPECIAL_NODEID)
{
reverse_heap1.Insert(phantom_node_pair.target_phantom.forward_node_id,
phantom_node_pair.target_phantom.GetForwardWeightPlusOffset(),
phantom_node_pair.target_phantom.forward_node_id);
// SimpleLogger().Write(logDEBUG) << "rev-a insert: " << phantom_node_pair.target_phantom.forward_node_id <<
// ", w: " << phantom_node_pair.target_phantom.GetForwardWeightPlusOffset();
}
if (phantom_node_pair.target_phantom.reverse_node_id != SPECIAL_NODEID)
{
reverse_heap2.Insert(phantom_node_pair.target_phantom.reverse_node_id,
phantom_node_pair.target_phantom.GetReverseWeightPlusOffset(),
phantom_node_pair.target_phantom.reverse_node_id);
// SimpleLogger().Write(logDEBUG) << "rev-a insert: " << phantom_node_pair.target_phantom.reverse_node_id <<
// ", w: " << phantom_node_pair.target_phantom.GetReverseWeightPlusOffset();
}
// run two-Target Dijkstra routing step.
while (0 < (forward_heap1.Size() + reverse_heap1.Size()))
{
if (!forward_heap1.Empty())
{
super::RoutingStep(
forward_heap1, reverse_heap1, &middle1, &local_upper_bound1, min_edge_offset, true);
}
if (!reverse_heap1.Empty())
{
super::RoutingStep(
reverse_heap1, forward_heap1, &middle1, &local_upper_bound1, min_edge_offset, false);
}
}
if (!reverse_heap2.Empty())
{
while (0 < (forward_heap2.Size() + reverse_heap2.Size()))
{
if (!forward_heap2.Empty())
{
super::RoutingStep(
forward_heap2, reverse_heap2, &middle2, &local_upper_bound2, min_edge_offset, true);
}
if (!reverse_heap2.Empty())
{
super::RoutingStep(
reverse_heap2, forward_heap2, &middle2, &local_upper_bound2, min_edge_offset, false);
}
}
}
// No path found for both target nodes?
if ((INVALID_EDGE_WEIGHT == local_upper_bound1) &&
(INVALID_EDGE_WEIGHT == local_upper_bound2))
{
raw_route_data.shortest_path_length = INVALID_EDGE_WEIGHT;
raw_route_data.alternative_path_length = INVALID_EDGE_WEIGHT;
return;
}
search_from_1st_node = true;
search_from_2nd_node = true;
if (SPECIAL_NODEID == middle1)
{
search_from_1st_node = false;
}
if (SPECIAL_NODEID == middle2)
{
search_from_2nd_node = false;
}
// Was at most one of the two paths not found?
BOOST_ASSERT_MSG((INVALID_EDGE_WEIGHT != distance1 || INVALID_EDGE_WEIGHT != distance2), "no path found");
// Unpack paths if they exist
std::vector<NodeID> temporary_packed_leg1;
std::vector<NodeID> temporary_packed_leg2;
BOOST_ASSERT((unsigned)current_leg < packed_legs1.size());
BOOST_ASSERT((unsigned)current_leg < packed_legs2.size());
if (INVALID_EDGE_WEIGHT != local_upper_bound1)
{
super::RetrievePackedPathFromHeap(
forward_heap1, reverse_heap1, middle1, temporary_packed_leg1);
}
if (INVALID_EDGE_WEIGHT != local_upper_bound2)
{
super::RetrievePackedPathFromHeap(
forward_heap2, reverse_heap2, middle2, temporary_packed_leg2);
}
// if one of the paths was not found, replace it with the other one.
if ((allow_u_turn && local_upper_bound1 > local_upper_bound2) || temporary_packed_leg1.empty())
{
temporary_packed_leg1.clear();
temporary_packed_leg1.insert(temporary_packed_leg1.end(),
temporary_packed_leg2.begin(),
temporary_packed_leg2.end());
local_upper_bound1 = local_upper_bound2;
}
if ((allow_u_turn && local_upper_bound2 > local_upper_bound1) || temporary_packed_leg2.empty())
{
temporary_packed_leg2.clear();
temporary_packed_leg2.insert(temporary_packed_leg2.end(),
temporary_packed_leg1.begin(),
temporary_packed_leg1.end());
local_upper_bound2 = local_upper_bound1;
}
BOOST_ASSERT_MSG(!temporary_packed_leg1.empty() || !temporary_packed_leg2.empty(),
"tempory packed paths empty");
BOOST_ASSERT((0 == current_leg) || !packed_legs1[current_leg - 1].empty());
BOOST_ASSERT((0 == current_leg) || !packed_legs2[current_leg - 1].empty());
if (!allow_u_turn && 0 < current_leg)
{
const NodeID end_id_of_segment1 = packed_legs1[current_leg - 1].back();
const NodeID end_id_of_segment2 = packed_legs2[current_leg - 1].back();
BOOST_ASSERT(!temporary_packed_leg1.empty());
const NodeID start_id_of_leg1 = temporary_packed_leg1.front();
const NodeID start_id_of_leg2 = temporary_packed_leg2.front();
if ((end_id_of_segment1 != start_id_of_leg1) &&
(end_id_of_segment2 != start_id_of_leg2))
{
std::swap(temporary_packed_leg1, temporary_packed_leg2);
std::swap(local_upper_bound1, local_upper_bound2);
}
// remove the shorter path if both legs end at the same segment
if (start_id_of_leg1 == start_id_of_leg2)
{
const NodeID last_id_of_packed_legs1 = packed_legs1[current_leg - 1].back();
const NodeID last_id_of_packed_legs2 = packed_legs2[current_leg - 1].back();
if (start_id_of_leg1 != last_id_of_packed_legs1)
{
packed_legs1 = packed_legs2;
BOOST_ASSERT(start_id_of_leg1 == temporary_packed_leg1.front());
}
else if (start_id_of_leg2 != last_id_of_packed_legs2)
{
packed_legs2 = packed_legs1;
BOOST_ASSERT(start_id_of_leg2 == temporary_packed_leg2.front());
}
}
}
BOOST_ASSERT(packed_legs1.size() == packed_legs2.size());
packed_legs1[current_leg].insert(packed_legs1[current_leg].end(),
temporary_packed_leg1.begin(),
temporary_packed_leg1.end());
BOOST_ASSERT(packed_legs1[current_leg].size() == temporary_packed_leg1.size());
packed_legs2[current_leg].insert(packed_legs2[current_leg].end(),
temporary_packed_leg2.begin(),
temporary_packed_leg2.end());
BOOST_ASSERT(packed_legs2[current_leg].size() == temporary_packed_leg2.size());
if (!allow_u_turn && (packed_legs1[current_leg].back() == packed_legs2[current_leg].back()) &&
phantom_node_pair.target_phantom.isBidirected())
{
const NodeID last_node_id = packed_legs2[current_leg].back();
search_from_1st_node &=
!(last_node_id == phantom_node_pair.target_phantom.reverse_node_id);
search_from_2nd_node &=
!(last_node_id == phantom_node_pair.target_phantom.forward_node_id);
BOOST_ASSERT(search_from_1st_node != search_from_2nd_node);
}
distance1 = local_upper_bound1;
distance2 = local_upper_bound2;
++current_leg;
}
if (distance1 > distance2)
{
std::swap(packed_legs1, packed_legs2);
}
raw_route_data.unpacked_path_segments.resize(packed_legs1.size());
for (const std::size_t index : osrm::irange<std::size_t>(0, packed_legs1.size()))
{
BOOST_ASSERT(!phantom_nodes_vector.empty());
BOOST_ASSERT(packed_legs1.size() == raw_route_data.unpacked_path_segments.size());
PhantomNodes unpack_phantom_node_pair = phantom_nodes_vector[index];
super::UnpackPath(
// -- packed input
packed_legs1[index],
// -- start and end of (sub-)route
unpack_phantom_node_pair,
// -- unpacked output
raw_route_data.unpacked_path_segments[index]);
raw_route_data.source_traversed_in_reverse.push_back(
(packed_legs1[index].front() != phantom_nodes_vector[index].source_phantom.forward_node_id));
raw_route_data.target_traversed_in_reverse.push_back(
(packed_legs1[index].back() != phantom_nodes_vector[index].target_phantom.forward_node_id));
}
raw_route_data.shortest_path_length = std::min(distance1, distance2);
}
};
#endif /* SHORTEST_PATH_ROUTING_H */
-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_ */
-142
View File
@@ -1,142 +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 "../DataStructures/JSONContainer.h"
#include "../Library/OSRM.h"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#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 *compressionType);
private:
boost::tribool consume(Request &req, char input, CompressionType *compressionType);
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
-130
View File
@@ -1,130 +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 "../typedefs.h"
#include "../Algorithms/StronglyConnectedComponents.h"
#include "../Util/GraphLoader.h"
#include "../Util/OSRMException.h"
#include "../Util/simple_logger.hpp"
#include "../Util/FingerPrint.h"
#include <fstream>
#include <memory>
#include <string>
#include <vector>
std::vector<NodeInfo> coordinate_list;
std::vector<TurnRestriction> restrictions_vector;
std::vector<NodeID> bollard_ID_list;
std::vector<NodeID> trafficlight_ID_list;
int main(int argc, char *argv[])
{
LogPolicy::GetInstance().Unmute();
try
{
// enable logging
if (argc < 3)
{
SimpleLogger().Write(logWARNING) << "usage:\n" << argv[0]
<< " <osrm> <osrm.restrictions>";
return -1;
}
SimpleLogger().Write() << "Using restrictions from file: " << argv[2];
std::ifstream restriction_ifstream(argv[2], std::ios::binary);
const FingerPrint fingerprint_orig;
FingerPrint fingerprint_loaded;
restriction_ifstream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
// check fingerprint and warn if necessary
if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
{
SimpleLogger().Write(logWARNING) << argv[2] << " was prepared with a different build. "
"Reprocess to get rid of this warning.";
}
if (!restriction_ifstream.good())
{
throw OSRMException("Could not access <osrm-restrictions> files");
}
uint32_t usable_restrictions = 0;
restriction_ifstream.read((char *)&usable_restrictions, sizeof(uint32_t));
restrictions_vector.resize(usable_restrictions);
// load restrictions
if (usable_restrictions > 0)
{
restriction_ifstream.read((char *)&(restrictions_vector[0]),
usable_restrictions * sizeof(TurnRestriction));
}
restriction_ifstream.close();
std::ifstream input_stream(argv[1], std::ifstream::in | std::ifstream::binary);
if (!input_stream.is_open())
{
throw OSRMException("Cannot open osrm file");
}
// load graph data
std::vector<ImportEdge> edge_list;
const NodeID number_of_nodes = readBinaryOSRMGraphFromStream(input_stream,
edge_list,
bollard_ID_list,
trafficlight_ID_list,
&coordinate_list,
restrictions_vector);
input_stream.close();
BOOST_ASSERT_MSG(restrictions_vector.size() == usable_restrictions,
"size of restrictions_vector changed");
SimpleLogger().Write() << restrictions_vector.size() << " restrictions, "
<< bollard_ID_list.size() << " bollard nodes, "
<< trafficlight_ID_list.size() << " traffic lights";
// Building an edge-expanded graph from node-based input an turn
// restrictions
SimpleLogger().Write() << "Starting SCC graph traversal";
std::shared_ptr<TarjanSCC> tarjan = std::make_shared<TarjanSCC>(number_of_nodes,
edge_list,
bollard_ID_list,
trafficlight_ID_list,
restrictions_vector,
coordinate_list);
edge_list.clear();
edge_list.shrink_to_fit();
tarjan->Run();
SimpleLogger().Write() << "finished component analysis";
}
catch (const std::exception &e)
{
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
}
return 0;
}
-7
View File
@@ -1,7 +0,0 @@
#define BOOST_TEST_MODULE datastructure tests
#include <boost/test/unit_test.hpp>
/*
* This file will contain an automatically generated main function.
*/
-144
View File
@@ -1,144 +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 BOOST_FILE_SYSTEM_FIX_H
#define BOOST_FILE_SYSTEM_FIX_H
#include "OSRMException.h"
// #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
// 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 OSRMException(input_string + " not found");
// }
// }
// adapted from:
// http://stackoverflow.com/questions/1746136/how-do-i-normalize-a-pathname-using-boostfilesystem
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
path temp_directory_path()
{
char *buffer;
buffer = tmpnam(nullptr);
return path(buffer);
}
path unique_path(const path &) { return temp_directory_path(); }
#endif
}
}
#ifndef BOOST_FILESYSTEM_VERSION
#define BOOST_FILESYSTEM_VERSION 3
#endif
void AssertPathExists(const boost::filesystem::path &path)
{
if (!boost::filesystem::is_regular_file(path))
{
throw OSRMException(path.string() + " not found.");
}
}
#endif /* BOOST_FILE_SYSTEM_FIX_H */
-425
View File
@@ -1,425 +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 GRAPHLOADER_H
#define GRAPHLOADER_H
#include "OSRMException.h"
#include "../DataStructures/ImportNode.h"
#include "../DataStructures/ImportEdge.h"
#include "../DataStructures/QueryNode.h"
#include "../DataStructures/Restriction.h"
#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<NodeInfo> *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.";
}
NodeID n, source, target;
EdgeID m;
short dir; // direction (0 = open, 1 = forward, 2+ = open)
std::unordered_map<NodeID, NodeID> ext_to_int_id_map;
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.bollard)
{
barrier_node_list.emplace_back(i);
}
if (current_node.trafficLight)
{
traffic_light_node_list.emplace_back(i);
}
}
// tighten vector sizes
barrier_node_list.shrink_to_fit();
traffic_light_node_list.shrink_to_fit();
input_stream.read((char *)&m, sizeof(unsigned));
SimpleLogger().Write() << " and " << m << " edges ";
for (TurnRestriction &current_restriction : restriction_list)
{
auto internal_id_iter = ext_to_int_id_map.find(current_restriction.fromNode);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction";
continue;
}
current_restriction.fromNode = internal_id_iter->second;
internal_id_iter = ext_to_int_id_map.find(current_restriction.viaNode);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction";
continue;
}
current_restriction.viaNode = internal_id_iter->second;
internal_id_iter = ext_to_int_id_map.find(current_restriction.toNode);
if (internal_id_iter == ext_to_int_id_map.end())
{
SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction";
continue;
}
current_restriction.toNode = internal_id_iter->second;
}
edge_list.reserve(m);
EdgeWeight weight;
NodeID nameID;
int length;
bool is_roundabout, ignore_in_grid, is_access_restricted, is_split;
TravelMode travel_mode;
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 != UINT_MAX && target != UINT_MAX, "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);
}
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].backward != edge_list[i].backward);
const bool edge_flags_are_superset_2 =
(edge_list[i].forward && edge_list[i].backward) &&
(edge_list[i - 1].backward != 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 = UINT_MAX;
}
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 = UINT_MAX;
}
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 = UINT_MAX;
}
}
}
}
const auto new_end_iter = std::remove_if(edge_list.begin(),
edge_list.end(),
[](const EdgeT &edge)
{ return edge.source == SPECIAL_NODEID; });
ext_to_int_id_map.clear();
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 EdgeT, typename CoordinateT>
NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
std::vector<EdgeT> &edge_list,
std::vector<CoordinateT> & coordinate_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.";
}
NodeID n, source, target;
EdgeID m;
short dir; // direction (0 = open, 1 = forward, 2+ = open)
std::unordered_map<NodeID, NodeID> ext_to_int_id_map;
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));
coordinate_list.emplace_back(current_node.lat, current_node.lon);
ext_to_int_id_map.emplace(current_node.node_id, i);
}
input_stream.read((char *)&m, sizeof(unsigned));
SimpleLogger().Write() << " and " << m << " edges ";
edge_list.reserve(m);
EdgeWeight weight;
NodeID nameID;
int length;
bool is_roundabout, ignore_in_grid, is_access_restricted, is_split;
TravelMode travel_mode;
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");
// 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 != UINT_MAX && target != UINT_MAX, "nonexisting source or target");
if (source > target)
{
std::swap(source, target);
}
edge_list.emplace_back(source,
target);
}
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))
{
edge_list[i].distance = std::min(edge_list[i - 1].distance, edge_list[i].distance);
edge_list[i - 1].source = UINT_MAX;
}
}
const auto new_end_iter = std::remove_if(edge_list.begin(),
edge_list.end(),
[](const EdgeT &edge)
{ return edge.source == SPECIAL_NODEID; });
ext_to_int_id_map.clear();
edge_list.erase(new_end_iter, edge_list.end()); // remove excess candidates.
edge_list.shrink_to_fit();
SimpleLogger().Write() << "Graph loaded ok and has " << n << " nodes and " << 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 OSRMException("hsgr file does not exist");
}
if (0 == boost::filesystem::file_size(hsgr_file))
{
throw OSRMException("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
-39
View File
@@ -1,39 +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 TIMINGUTIL_H
#define TIMINGUTIL_H
#include <chrono>
#define TIMER_START(_X) auto _X##_start = std::chrono::steady_clock::now(), _X##_stop = _X##_start
#define TIMER_STOP(_X) _X##_stop = std::chrono::steady_clock::now()
#define TIMER_MSEC(_X) std::chrono::duration_cast<std::chrono::milliseconds>(_X##_stop - _X##_start).count()
#define TIMER_SEC(_X) (0.001*std::chrono::duration_cast<std::chrono::milliseconds>(_X##_stop - _X##_start).count())
#define TIMER_MIN(_X) std::chrono::duration_cast<std::chrono::minutes>(_X##_stop - _X##_start).count()
#endif // TIMINGUTIL_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;
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 n)
{
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
+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
@@ -1,8 +1,35 @@
#ifndef BFS_COMPONENT_EXPLORER_H_
#define BFS_COMPONENT_EXPLORER_H_
/*
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 BFS_COMPONENTS_HPP_
#define BFS_COMPONENTS_HPP_
#include "../typedefs.h"
#include "../DataStructures/RestrictionMap.h"
#include "../data_structures/restriction_map.hpp"
#include <queue>
#include <unordered_set>
@@ -68,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:
@@ -91,42 +118,42 @@ 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;
const bool is_barrier_node = (m_barrier_nodes.find(v) != m_barrier_nodes.end());
if (!is_barrier_node)
if (m_barrier_nodes.find(v) != m_barrier_nodes.end())
{
const NodeID to_node_of_only_restriction =
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
continue;
}
const NodeID to_node_of_only_restriction =
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
for (auto e2 : m_graph.GetAdjacentEdgeRange(v))
for (auto e2 : m_graph.GetAdjacentEdgeRange(v))
{
const NodeID w = m_graph.GetTarget(e2);
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction)
{
const NodeID w = m_graph.GetTarget(e2);
// At an only_-restriction but not at the right turn
continue;
}
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
w != to_node_of_only_restriction)
if (u != w)
{
// 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))
{
// At an only_-restriction but not at the right turn
continue;
}
if (u != w)
{
// 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))
// only add an edge if turn is not prohibited
if (std::numeric_limits<unsigned>::max() == m_component_index_list[w])
{
// only add an edge if turn is not prohibited
if (std::numeric_limits<unsigned>::max() == m_component_index_list[w])
{
// insert next (node, parent) only if w has
// not yet been explored
// mark node as read
m_component_index_list[w] = current_component;
bfs_queue.emplace(w, v);
}
// insert next (node, parent) only if w has
// not yet been explored
// mark node as read
m_component_index_list[w] = current_component;
bfs_queue.emplace(w, v);
}
}
}
@@ -144,4 +171,4 @@ template <typename GraphT> class BFSComponentExplorer
const std::unordered_set<NodeID> &m_barrier_nodes;
};
#endif // BFS_COMPONENT_EXPLORER_H_
#endif // BFS_COMPONENTS_HPP_
+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
@@ -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));
}
@@ -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,20 +25,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "DouglasPeucker.h"
#include "douglas_peucker.hpp"
#include "../DataStructures/Range.h"
#include "../DataStructures/SegmentInformation.h"
#include <osrm/Coordinate.h>
#include "../data_structures/segment_information.hpp"
#include <boost/assert.hpp>
#include <osrm/coordinate.hpp>
#include <cmath>
#include <algorithm>
#include <iterator>
namespace {
namespace
{
struct CoordinatePairCalculator
{
CoordinatePairCalculator() = delete;
@@ -64,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));
@@ -82,61 +81,40 @@ struct CoordinatePairCalculator
};
}
DouglasPeucker::DouglasPeucker()
: douglas_peucker_thresholds({512440, // z0
256720, // z1
122560, // z2
56780, // z3
28800, // z4
14400, // z5
7200, // z6
3200, // z7
2400, // z8
1000, // z9
600, // z10
120, // z11
60, // z12
45, // z13
36, // z14
20, // z15
8, // z16
6, // z17
4 // z18
})
{
}
void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level)
{
// check if input data is invalid
BOOST_ASSERT_MSG(!input_geometry.empty(), "geometry invalid");
Run(std::begin(input_geometry), std::end(input_geometry), zoom_level);
}
if (input_geometry.size() < 2)
void DouglasPeucker::Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level)
{
const auto size = std::distance(begin, end);
if (size < 2)
{
return;
}
input_geometry.front().necessary = true;
input_geometry.back().necessary = true;
begin->necessary = true;
std::prev(end)->necessary = true;
{
BOOST_ASSERT_MSG(zoom_level < 19, "unsupported zoom level");
unsigned left_border = 0;
unsigned right_border = 1;
BOOST_ASSERT_MSG(zoom_level < DOUGLAS_PEUCKER_THRESHOLDS.size(), "unsupported zoom level");
auto left_border = begin;
auto right_border = std::next(begin);
// Sweep over array and identify those ranges that need to be checked
do
{
// traverse list until new border element found
if (input_geometry[right_border].necessary)
if (right_border->necessary)
{
// sanity checks
BOOST_ASSERT(input_geometry[left_border].necessary);
BOOST_ASSERT(input_geometry[right_border].necessary);
BOOST_ASSERT(left_border->necessary);
BOOST_ASSERT(right_border->necessary);
recursion_stack.emplace(left_border, right_border);
left_border = right_border;
}
++right_border;
} while (right_border < input_geometry.size());
} while (right_border != end);
}
// mark locations as 'necessary' by divide-and-conquer
@@ -146,40 +124,40 @@ void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const
const GeometryRange pair = recursion_stack.top();
recursion_stack.pop();
// sanity checks
BOOST_ASSERT_MSG(input_geometry[pair.first].necessary, "left border mus be necessary");
BOOST_ASSERT_MSG(input_geometry[pair.second].necessary, "right border must be necessary");
BOOST_ASSERT_MSG(pair.second < input_geometry.size(), "right border outside of geometry");
BOOST_ASSERT_MSG(pair.first < pair.second, "left border on the wrong side");
BOOST_ASSERT_MSG(pair.first->necessary, "left border must be necessary");
BOOST_ASSERT_MSG(pair.second->necessary, "right border must be necessary");
BOOST_ASSERT_MSG(std::distance(pair.second, end) > 0, "right border outside of geometry");
BOOST_ASSERT_MSG(std::distance(pair.first, pair.second) >= 0,
"left border on the wrong side");
int max_int_distance = 0;
unsigned farthest_entry_index = pair.second;
const CoordinatePairCalculator dist_calc(input_geometry[pair.first].location,
input_geometry[pair.second].location);
auto farthest_entry_it = pair.second;
const CoordinatePairCalculator dist_calc(pair.first->location, pair.second->location);
// sweep over range to find the maximum
for (const auto i : osrm::irange(pair.first + 1, pair.second))
for (auto it = std::next(pair.first); it != pair.second; ++it)
{
const int distance = dist_calc(input_geometry[i].location);
const int distance = dist_calc(it->location);
// found new feasible maximum?
if (distance > max_int_distance && distance > douglas_peucker_thresholds[zoom_level])
if (distance > max_int_distance && distance > DOUGLAS_PEUCKER_THRESHOLDS[zoom_level])
{
farthest_entry_index = i;
farthest_entry_it = it;
max_int_distance = distance;
}
}
// check if maximum violates a zoom level dependent threshold
if (max_int_distance > douglas_peucker_thresholds[zoom_level])
if (max_int_distance > DOUGLAS_PEUCKER_THRESHOLDS[zoom_level])
{
// mark idx as necessary
input_geometry[farthest_entry_index].necessary = true;
if (1 < (farthest_entry_index - pair.first))
farthest_entry_it->necessary = true;
if (1 < std::distance(pair.first, farthest_entry_it))
{
recursion_stack.emplace(pair.first, farthest_entry_index);
recursion_stack.emplace(pair.first, farthest_entry_it);
}
if (1 < (pair.second - farthest_entry_index))
if (1 < std::distance(farthest_entry_it, pair.second))
{
recursion_stack.emplace(farthest_entry_index, pair.second);
recursion_stack.emplace(farthest_entry_it, pair.second);
}
}
}
@@ -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,
@@ -25,9 +25,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DOUGLASPEUCKER_H_
#define DOUGLASPEUCKER_H_
#ifndef DOUGLAS_PEUCKER_HPP_
#define DOUGLAS_PEUCKER_HPP_
#include "../data_structures/segment_information.hpp"
#include <array>
#include <stack>
#include <utility>
#include <vector>
@@ -39,20 +42,40 @@ 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{{
512440, // z0
256720, // z1
122560, // z2
56780, // z3
28800, // z4
14400, // z5
7200, // z6
3200, // z7
2400, // z8
1000, // z9
600, // z10
120, // z11
60, // z12
45, // z13
36, // z14
20, // z15
8, // z16
6, // z17
4 // z18
}};
class DouglasPeucker
{
private:
std::vector<int> douglas_peucker_thresholds;
public:
using RandomAccessIt = std::vector<SegmentInformation>::iterator;
using GeometryRange = std::pair<unsigned, unsigned>;
using GeometryRange = std::pair<RandomAccessIt, RandomAccessIt>;
// Stack to simulate the recursion
std::stack<GeometryRange> recursion_stack;
public:
DouglasPeucker();
void Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level);
void Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level);
};
#endif /* DOUGLASPEUCKER_H_ */
#endif /* DOUGLAS_PEUCKER_HPP_ */
+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
@@ -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,10 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OBJECT_TO_BASE64_H_
#define OBJECT_TO_BASE64_H_
#include "../Util/StringUtil.h"
#ifndef OBJECT_ENCODER_HPP
#define OBJECT_ENCODER_HPP
#include <boost/assert.hpp>
#include <boost/archive/iterators/base64_from_binary.hpp>
@@ -36,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#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 (...)
{
@@ -91,4 +86,4 @@ struct ObjectEncoder
}
};
#endif /* OBJECT_TO_BASE64_H_ */
#endif /* OBJECT_ENCODER_HPP */
+128
View File
@@ -0,0 +1,128 @@
/*
Copyright (c) 2014, 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 "polyline_compressor.hpp"
#include "../data_structures/segment_information.hpp"
#include <osrm/coordinate.hpp>
std::string PolylineCompressor::encode_vector(std::vector<int> &numbers) const
{
std::string output;
const auto end = numbers.size();
for (std::size_t i = 0; i < end; ++i)
{
numbers[i] <<= 1;
if (numbers[i] < 0)
{
numbers[i] = ~(numbers[i]);
}
}
for (const int number : numbers)
{
output += encode_number(number);
}
return output;
}
std::string PolylineCompressor::encode_number(int number_to_encode) const
{
std::string output;
while (number_to_encode >= 0x20)
{
const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63;
output += static_cast<char>(next_value);
number_to_encode >>= 5;
}
number_to_encode += 63;
output += static_cast<char>(number_to_encode);
return output;
}
std::string
PolylineCompressor::get_encoded_string(const std::vector<SegmentInformation> &polyline) const
{
if (polyline.empty())
{
return {};
}
std::vector<int> delta_numbers;
delta_numbers.reserve((polyline.size() - 1) * 2);
FixedPointCoordinate previous_coordinate = {0, 0};
for (const auto &segment : polyline)
{
if (segment.necessary)
{
const int lat_diff = segment.location.lat - previous_coordinate.lat;
const int lon_diff = segment.location.lon - previous_coordinate.lon;
delta_numbers.emplace_back(lat_diff);
delta_numbers.emplace_back(lon_diff);
previous_coordinate = segment.location;
}
}
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;
}
@@ -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,7 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct SegmentInformation;
#include "../DataStructures/JSONContainer.h"
#include <osrm/coordinate.hpp>
#include <string>
#include <vector>
@@ -38,14 +38,14 @@ struct SegmentInformation;
class PolylineCompressor
{
private:
void encodeVectorSignedNumber(std::vector<int> &numbers, std::string &output) const;
std::string encode_vector(std::vector<int> &numbers) const;
void encodeNumber(int number_to_encode, std::string &output) const;
std::string encode_number(const int number_to_encode) const;
public:
JSON::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
JSON::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
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_ */
@@ -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,49 +25,32 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef AZIMUTH_H
#define AZIMUTH_H
#include "polyline_formatter.hpp"
#include <string>
#include "polyline_compressor.hpp"
#include "../data_structures/segment_information.hpp"
struct Azimuth
#include <osrm/coordinate.hpp>
osrm::json::String
PolylineFormatter::printEncodedString(const std::vector<SegmentInformation> &polyline) const
{
static std::string Get(const double heading)
{
if (heading <= 202.5)
{
if (heading >= 0 && heading <= 22.5)
{
return "N";
}
if (heading > 22.5 && heading <= 67.5)
{
return "NE";
}
if (heading > 67.5 && heading <= 112.5)
{
return "E";
}
if (heading > 112.5 && heading <= 157.5)
{
return "SE";
}
return "S";
}
if (heading > 202.5 && heading <= 247.5)
{
return "SW";
}
if (heading > 247.5 && heading <= 292.5)
{
return "W";
}
if (heading > 292.5 && heading <= 337.5)
{
return "NW";
}
return "N";
}
};
return osrm::json::String(PolylineCompressor().get_encoded_string(polyline));
}
#endif // AZIMUTH_H
osrm::json::Array
PolylineFormatter::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
{
osrm::json::Array json_geometry_array;
for (const auto &segment : polyline)
{
if (segment.necessary)
{
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);
}
}
return json_geometry_array;
}
+45
View File
@@ -0,0 +1,45 @@
/*
Copyright (c) 2014, 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 POLYLINE_FORMATTER_HPP
#define POLYLINE_FORMATTER_HPP
struct SegmentInformation;
#include <osrm/json_container.hpp>
#include <string>
#include <vector>
struct PolylineFormatter
{
osrm::json::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
osrm::json::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
};
#endif /* POLYLINE_FORMATTER_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,
@@ -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;
}
+204
View File
@@ -0,0 +1,204 @@
/*
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 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 "../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 <cstdint>
#include <memory>
#include <algorithm>
#include <climits>
#include <stack>
#include <vector>
template <typename GraphT> class TarjanSCC
{
struct TarjanStackFrame
{
explicit TarjanStackFrame(NodeID v, NodeID parent) : v(v), parent(parent) {}
NodeID v;
NodeID parent;
};
struct TarjanNode
{
TarjanNode() : index(SPECIAL_NODEID), low_link(SPECIAL_NODEID), on_stack(false) {}
unsigned index;
unsigned low_link;
bool on_stack;
};
std::vector<unsigned> components_index;
std::vector<NodeID> component_size_vector;
std::shared_ptr<const GraphT> m_graph;
std::size_t size_one_counter;
public:
TarjanSCC(std::shared_ptr<const GraphT> graph)
: components_index(graph->GetNumberOfNodes(), SPECIAL_NODEID), m_graph(graph),
size_one_counter(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(max_node_id);
unsigned component_index = 0, size_of_current_component = 0;
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])
{
recursion_stack.emplace(TarjanStackFrame(node, node));
}
while (!recursion_stack.empty())
{
TarjanStackFrame currentFrame = recursion_stack.top();
const NodeID u = currentFrame.parent;
const NodeID v = currentFrame.v;
recursion_stack.pop();
const bool before_recursion = processing_node_before_recursion[v];
if (before_recursion && tarjan_node_list[v].index != UINT_MAX)
{
continue;
}
if (before_recursion)
{
// Mark frame to handle tail of recursion
recursion_stack.emplace(currentFrame);
processing_node_before_recursion[v] = false;
// Mark essential information for SCC
tarjan_node_list[v].index = index;
tarjan_node_list[v].low_link = index;
tarjan_stack.push(v);
tarjan_node_list[v].on_stack = true;
++index;
for (const auto current_edge : m_graph->GetAdjacentEdgeRange(v))
{
const auto vprime = m_graph->GetTarget(current_edge);
if (SPECIAL_NODEID == tarjan_node_list[vprime].index)
{
recursion_stack.emplace(TarjanStackFrame(vprime, v));
}
else
{
if (tarjan_node_list[vprime].on_stack &&
tarjan_node_list[vprime].index < tarjan_node_list[v].low_link)
{
tarjan_node_list[v].low_link = tarjan_node_list[vprime].index;
}
}
}
}
else
{
processing_node_before_recursion[v] = true;
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)
{
NodeID vprime;
do
{
vprime = tarjan_stack.top();
tarjan_stack.pop();
tarjan_node_list[vprime].on_stack = false;
components_index[vprime] = component_index;
++size_of_current_component;
} while (v != vprime);
component_size_vector.emplace_back(size_of_current_component);
if (size_of_current_component > 1000)
{
SimpleLogger().Write() << "large component [" << component_index
<< "]=" << size_of_current_component;
}
++component_index;
size_of_current_component = 0;
}
}
}
}
TIMER_STOP(SCC_RUN);
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(),
[](unsigned value)
{
return 1 == value;
});
}
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[component_id];
}
unsigned get_component_id(const NodeID node) const { return components_index[node]; }
};
#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 -35
View File
@@ -1,58 +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% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013
- msbuild /clp:Verbosity=minimal /nologo OSRM.sln
- msbuild /clp:Verbosity=minimal /nologo tests.vcxproj
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip)
- set PATH=%PATH%;c:/projects/osrm/libs/bin
- cd c:/projects/osrm/build/%Configuration%
- datastructure-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
+152
View File
@@ -0,0 +1,152 @@
/*
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 "../data_structures/query_node.hpp"
#include "../data_structures/static_rtree.hpp"
#include "../data_structures/edge_based_node.hpp"
#include "../algorithms/geospatial_query.hpp"
#include "../util/timing_util.hpp"
#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;
constexpr int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION;
constexpr int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION;
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)
{
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
QueryNode current_node;
unsigned coordinate_count = 0;
nodes_input_stream.read((char *)&coordinate_count, sizeof(unsigned));
auto coords = std::make_shared<std::vector<FixedPointCoordinate>>(coordinate_count);
for (unsigned i = 0; i < coordinate_count; ++i)
{
nodes_input_stream.read((char *)&current_node, sizeof(QueryNode));
coords->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon);
BOOST_ASSERT((std::abs(coords->at(i).lat) >> 30) == 0);
BOOST_ASSERT((std::abs(coords->at(i).lon) >> 30) == 0);
}
nodes_input_stream.close();
return coords;
}
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);
std::uniform_int_distribution<> lon_udist(WORLD_MIN_LON, WORLD_MAX_LON);
std::vector<FixedPointCoordinate> queries;
for (unsigned i = 0; i < num_queries; i++)
{
queries.emplace_back(lat_udist(mt_rand), lon_udist(mt_rand));
}
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);
});
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)
{
if (argc < 4)
{
std::cout << "./rtree-bench file.ramIndex file.fileIndx file.nodes"
<< "\n";
return 1;
}
const char *ramPath = argv[1];
const char *filePath = argv[2];
const char *nodesPath = argv[3];
auto coords = LoadCoordinates(nodesPath);
BenchStaticRTree rtree(ramPath, filePath, coords);
BenchQuery query(rtree, coords);
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)
+22 -8
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}/DataStructures/StaticRTree.h MD5RTREE)
file(MD5 ${SOURCE_DIR}/Util/GraphLoader.h MD5GRAPH)
file(MD5 ${SOURCE_DIR}/Server/DataStructures/InternalDataFacade.h MD5OBJECTS)
file(MD5 ${SOURCE_DIR}/data_structures/static_rtree.hpp MD5RTREE)
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/FingerPrint.cpp.in ${SOURCE_DIR}/Util/FingerPrint.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}
@@ -1,6 +1,6 @@
/*
Copyright (c) 2013, 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,
@@ -25,20 +25,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CONTRACTOR_H
#define CONTRACTOR_H
#ifndef CONTRACTOR_HPP
#define CONTRACTOR_HPP
#include "../DataStructures/BinaryHeap.h"
#include "../DataStructures/DeallocatingVector.h"
#include "../DataStructures/DynamicGraph.h"
#include "../DataStructures/Percent.h"
#include "../DataStructures/QueryEdge.h"
#include "../DataStructures/Range.h"
#include "../DataStructures/XORFastHash.h"
#include "../DataStructures/XORFastHashStorage.h"
#include "../Util/simple_logger.hpp"
#include "../Util/StringUtil.h"
#include "../Util/TimingUtil.h"
#include "../data_structures/binary_heap.hpp"
#include "../data_structures/deallocating_vector.hpp"
#include "../data_structures/dynamic_graph.hpp"
#include "../data_structures/percent.hpp"
#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 "../typedefs.h"
#include <boost/assert.hpp>
@@ -51,6 +50,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <algorithm>
#include <limits>
#include <memory>
#include <vector>
class Contractor
@@ -93,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
@@ -132,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);
@@ -150,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);
@@ -163,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());
@@ -283,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);
@@ -304,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
@@ -352,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});
}
@@ -385,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],
@@ -414,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);
@@ -426,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 =
@@ -504,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)
@@ -546,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());
@@ -566,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
{
@@ -580,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
{
@@ -597,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();
@@ -775,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);
}
}
}
@@ -884,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];
@@ -964,10 +1073,11 @@ 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;
};
#endif // CONTRACTOR_H
#endif // CONTRACTOR_HPP
+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
+441
View File
@@ -0,0 +1,441 @@
/*
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.
*/
#include "processing_chain.hpp"
#include "contractor.hpp"
#include "contractor.hpp"
#include "../data_structures/deallocating_vector.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/parallel_sort.h>
#include <chrono>
#include <memory>
#include <string>
#include <thread>
#include <vector>
#include "../util/debug_geometry.hpp"
Prepare::~Prepare() {}
int Prepare::Run()
{
#ifdef WIN32
#pragma message("Memory consumption on Windows can be higher due to different bit packing")
#else
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
if (config.core_factor > 1.0 || config.core_factor < 0)
{
throw osrm::exception("Core factor must be between 0.0 to 1.0 (inclusive)");
}
TIMER_START(preparing);
// Create a new lua state
SimpleLogger().Write() << "Loading edge-expanded graph representation";
DeallocatingVector<EdgeBasedEdge> edge_based_edge_list;
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);
// Contracting the edge-expanded graph
TIMER_START(contraction);
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";
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));
}
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";
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)
{
BOOST_ASSERT(SPECIAL_NODEID != edge.source);
BOOST_ASSERT(SPECIAL_NODEID != edge.target);
tmp_max = std::max(tmp_max, edge.source);
tmp_max = std::max(tmp_max, edge.target);
}
return tmp_max;
}();
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;
// 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;
// initializing 'first_edge'-field of nodes:
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))
{
++edge;
}
node_array[node].first_edge = position; //=edge
position += edge - last_edge; // remove
}
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;
}
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 *)&edges_crc32, sizeof(unsigned));
// serialize number of nodes
hsgr_output_stream.write((char *)&node_array_size, sizeof(unsigned));
// serialize number of edges
hsgr_output_stream.write((char *)&contracted_edge_count, sizeof(unsigned));
// serialize all nodes
if (node_array_size > 0)
{
hsgr_output_stream.write((char *)&node_array[0],
sizeof(StaticGraph<EdgeData>::NodeArrayEntry) * node_array_size);
}
// serialize all edges
SimpleLogger().Write() << "Building edge array";
int number_of_used_edges = 0;
StaticGraph<EdgeData>::EdgeArrayEntry current_edge;
for (const auto edge : osrm::irange<std::size_t>(0, contracted_edge_list.size()))
{
// no eigen loops
BOOST_ASSERT(contracted_edge_list[edge].source != contracted_edge_list[edge].target);
current_edge.target = contracted_edge_list[edge].target;
current_edge.data = contracted_edge_list[edge].data;
// every target needs to be valid
BOOST_ASSERT(current_edge.target <= max_used_node_id);
#ifndef NDEBUG
if (current_edge.data.distance <= 0)
{
SimpleLogger().Write(logWARNING) << "Edge: " << edge
<< ",source: " << contracted_edge_list[edge].source
<< ", target: " << contracted_edge_list[edge].target
<< ", dist: " << current_edge.data.distance;
SimpleLogger().Write(logWARNING) << "Failed at adjacency list of node "
<< contracted_edge_list[edge].source << "/"
<< node_array.size() - 1;
return 1;
}
#endif
hsgr_output_stream.write((char *)&current_edge,
sizeof(StaticGraph<EdgeData>::EdgeArrayEntry));
++number_of_used_edges;
}
return number_of_used_edges;
}
/**
\brief Build contracted graph.
*/
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
{
std::vector<float> node_levels;
node_levels.swap(inout_node_levels);
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);
}
+84
View File
@@ -0,0 +1,84 @@
/*
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 PROCESSING_CHAIN_HPP
#define PROCESSING_CHAIN_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"
struct SpeedProfileProperties;
struct EdgeBasedNode;
struct lua_State;
#include <boost/filesystem.hpp>
#include <vector>
/**
\brief class of 'prepare' utility.
*/
class Prepare
{
public:
using EdgeData = QueryEdge::EdgeData;
explicit Prepare(ContractorConfig contractor_config) : config(std::move(contractor_config)) {}
Prepare(const Prepare &) = delete;
~Prepare();
int Run();
protected:
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:
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

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