Compare commits
1724 Commits
v0.4.4
...
v5.1.0-rc.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 96127c289c | |||
| cfed65f7ea | |||
| c2263fec9b | |||
| 497720d060 | |||
| 238366e71f | |||
| 2c8cf26e74 | |||
| c87ae5612a | |||
| a2d83753bc | |||
| eedf75d951 | |||
| 3f51a1ae2e | |||
| a000f80705 | |||
| 7030bff7f7 | |||
| bb0b7fd2d1 | |||
| 71e1f3679e | |||
| b33517b099 | |||
| f3d5336892 | |||
| d81f25d54e | |||
| 44ebdfeb2d | |||
| a5a7a03fa0 | |||
| 363d2145bd | |||
| c7e19396a4 | |||
| 445e5bed49 | |||
| 4cf94319df | |||
| 1bb88b374e | |||
| 35fac07581 | |||
| 9287475b2a | |||
| b4976f89f2 | |||
| 93c8674a40 | |||
| d5f21fd13a | |||
| 04eef0463a | |||
| 82c3bc7b0e | |||
| 1d33cb96f5 | |||
| 648646068c | |||
| f251f93a11 | |||
| aab1aad8f4 | |||
| 65a6dc704e | |||
| 6018fcf490 | |||
| 1e6888c0d3 | |||
| c7303be33b | |||
| d8acf76f2d | |||
| 08248e3853 | |||
| 78acc6f215 | |||
| a4f1dc536d | |||
| 57a30dd375 | |||
| 5517ee334f | |||
| 30af544919 | |||
| f0069d3dcc | |||
| 206bdff9e7 | |||
| c32270b2b8 | |||
| cc03402570 | |||
| 21a76f1867 | |||
| 212ad94c90 | |||
| 378d9f4112 | |||
| e341d367d8 | |||
| 98937b187f | |||
| 59168e21b4 | |||
| d12a95b4ef | |||
| 83482afa02 | |||
| e470d1ae1c | |||
| e504128587 | |||
| 1ab6c07bad | |||
| 5ce465ce23 | |||
| a8b730576f | |||
| b796033473 | |||
| d078ed67ca | |||
| 346146d834 | |||
| 64307ea882 | |||
| 578eda7d28 | |||
| 505f4cb4a2 | |||
| bac6b729bf | |||
| d3a5cadb6c | |||
| 65351faf83 | |||
| 3aa1c5f13c | |||
| 8f3fe410b8 | |||
| ff3bf32b11 | |||
| 38cb01a30e | |||
| b8f7569e93 | |||
| cf17bd38eb | |||
| 930f6df2cb | |||
| e88106e990 | |||
| 21f64c75eb | |||
| 5186b9490d | |||
| e9e935303c | |||
| a154d71841 | |||
| fddb035539 | |||
| 1544a08ea2 | |||
| 8d68d4c050 | |||
| 62a1290043 | |||
| c5e1742150 | |||
| 754bc2d274 | |||
| 3ac061c546 | |||
| e59a7926a2 | |||
| be5b49e391 | |||
| 7b32d3184c | |||
| d770c35245 | |||
| e04baef3bb | |||
| 9d3ad22bc7 | |||
| cc35d15b2d | |||
| 15e3928906 | |||
| 4363fd64c4 | |||
| dac2f93383 | |||
| 82372bb2ab | |||
| b0c67c9019 | |||
| d83a34f72b | |||
| a16f156203 | |||
| 807aa71a7c | |||
| 14d9b67b58 | |||
| 82df0ca766 | |||
| a6c7529a4e | |||
| 202bb6d3e2 | |||
| bc514926bf | |||
| 9fc16b6a83 | |||
| 2125e0175d | |||
| 6b5982d389 | |||
| a4a8aa63d4 | |||
| bedf451952 | |||
| 93b8f1993c | |||
| c693f4806b | |||
| b07275694a | |||
| 82177c101b | |||
| da6dbd2159 | |||
| b3957d87b4 | |||
| 5f9ccadd6c | |||
| 6e04da9f8f | |||
| 58c13d2c07 | |||
| bca8593eef | |||
| 3e2e10a4c3 | |||
| 6979763292 | |||
| 324f1739e4 | |||
| 1489662f57 | |||
| 1c1f407f67 | |||
| 8fb631417b | |||
| ae45ad1ad2 | |||
| 6b89803534 | |||
| d01b34f501 | |||
| fcad2fa471 | |||
| 589767fe6d | |||
| d6407e5095 | |||
| 8ff8dc7200 | |||
| 2f7b02c96f | |||
| 669e2a767a | |||
| 2b4f9feeab | |||
| 1554916639 | |||
| 32a3651231 | |||
| dbd4ecf89b | |||
| 7416653874 | |||
| 621ed970da | |||
| 457ba9ac62 | |||
| f9da5f2c80 | |||
| b6a793a1e2 | |||
| bf2ab3d8af | |||
| 02f75236cb | |||
| 5dff83c6e9 | |||
| 43725bae89 | |||
| 59c12506cf | |||
| be15a3b739 | |||
| 9f515dad09 | |||
| 5052c4ae3a | |||
| 9a617f5d41 | |||
| 4886d46d91 | |||
| 67834def5f | |||
| c51ffeb65a | |||
| 68ee4eab61 | |||
| fa6d4ac0bc | |||
| 3fa533d91e | |||
| c0db144906 | |||
| ea2ec168b0 | |||
| cb18c1a54d | |||
| 45bcb22270 | |||
| 2539fd53dc | |||
| 8a2bd09fd0 | |||
| def89ac079 | |||
| fe08726387 | |||
| 9bb4a68599 | |||
| 996a27dbd1 | |||
| 58ebadd7b3 | |||
| cae06ba2c1 | |||
| 0274afa0f7 | |||
| 221f70ac7b | |||
| d3dbca374d | |||
| 6f0b6a8158 | |||
| b25cd6aaf2 | |||
| d27025003a | |||
| 66eb90d9d0 | |||
| 6a81a9d191 | |||
| 64cb134113 | |||
| 891ff7dd80 | |||
| 6643e7f499 | |||
| fcbf527ba5 | |||
| dfd180a292 | |||
| fa0a5040e5 | |||
| 56ba2cb251 | |||
| dea12779cf | |||
| 6033c05ff0 | |||
| 407da8bd15 | |||
| 43413ff980 | |||
| 4d864b8267 | |||
| a516245c94 | |||
| b1ed268d0e | |||
| 83b86bf092 | |||
| 954caa6804 | |||
| 8b6da4d2fe | |||
| f2d70d972d | |||
| b20de76037 | |||
| a33bd9dfe6 | |||
| f2443c64db | |||
| 278ec04f5e | |||
| 95787255a1 | |||
| eaf9993dd9 | |||
| 470d7600b8 | |||
| 849baea544 | |||
| 4f1ca20dda | |||
| 97401ad99a | |||
| 59f5e364c1 | |||
| 29c2a117c0 | |||
| c209e31ce1 | |||
| 12608889e2 | |||
| 3343882876 | |||
| 6e50b5fc60 | |||
| c540c85cf8 | |||
| b17491ebe5 | |||
| 76b410b2ca | |||
| 069388eae0 | |||
| c6c25e609b | |||
| 9b52dd8bf7 | |||
| 2cf19010e3 | |||
| 89d56e1cd1 | |||
| ef1fb08723 | |||
| e60ebee3f2 | |||
| 4c88fe0fb1 | |||
| 13338414db | |||
| 96f49f3b53 | |||
| 75979d7e1c | |||
| 29a2447906 | |||
| 2f702f61a4 | |||
| 5a71acbe3c | |||
| ca3e8ef09e | |||
| 8c44084af1 | |||
| d829a390fd | |||
| 6b6597e453 | |||
| 97c550d5f6 | |||
| acfd6ab141 | |||
| 7e790c1aa6 | |||
| d1e2aa57a8 | |||
| 2e6e3bf0b0 | |||
| e5025665fc | |||
| 1a8097f810 | |||
| f45daad6ca | |||
| e4e85e6f7e | |||
| 5beaf695ed | |||
| d09827b501 | |||
| 97722adbfa | |||
| 006a8833d3 | |||
| 8111baa8f9 | |||
| d6e4dc0aa2 | |||
| 497da1d29b | |||
| cbc8b64854 | |||
| c06f2a50f1 | |||
| 825a422721 | |||
| 2c4ba90abb | |||
| 6dda899a60 | |||
| 8725e2f40d | |||
| 35c501c203 | |||
| 30a9bc3179 | |||
| f9350a276c | |||
| cd9addf0e2 | |||
| 2219b6507c | |||
| 09931d7ad8 | |||
| 7ce0c0ef9a | |||
| 49e2cb6c36 | |||
| 4b60fc4747 | |||
| 164fb09f2c | |||
| 5647e6c199 | |||
| a4d6544764 | |||
| e942f6e420 | |||
| 7174baa91e | |||
| 5c8b7542d0 | |||
| e8035ced5a | |||
| 70a086a9e1 | |||
| 08cb6d1f63 | |||
| c7f3645fe2 | |||
| 4b6a85aae0 | |||
| c8a8859d2f | |||
| 8c0f47f06c | |||
| 926290dd9c | |||
| 6ae3315bb9 | |||
| 8621b1890e | |||
| c726001a0e | |||
| eba5f7d275 | |||
| 2f793473cc | |||
| 91567cad9e | |||
| d48ee84ae7 | |||
| fd000cad86 | |||
| 6244063073 | |||
| f34de8422e | |||
| a33edd15b4 | |||
| 6a65261765 | |||
| 07f3e2d457 | |||
| 958199ffef | |||
| e5ebf74d76 | |||
| 126d2f85ac | |||
| 908e3a2af6 | |||
| 25e40d723a | |||
| 7a764ce78b | |||
| 8947c789a9 | |||
| 8ac403abb9 | |||
| 9752cb8e4d | |||
| e9be9dd8d0 | |||
| 5e6d638c6f | |||
| c47f6e2ca5 | |||
| cc09df1961 | |||
| db26d2b2d7 | |||
| 5b33efeecc | |||
| fda4656630 | |||
| 5829bbe22d | |||
| f4cfde719d | |||
| 1fd66f55c1 | |||
| a964bec0f8 | |||
| b65ba5c394 | |||
| d51eefa1c4 | |||
| 4025cbd555 | |||
| 3da27c06c3 | |||
| bc7824812b | |||
| baf7822340 | |||
| 82ee08fcaf | |||
| 51d153a5f7 | |||
| df608e8b43 | |||
| 8e477437a6 | |||
| e70f0eea02 | |||
| 8be93a0202 | |||
| d4f7f19a22 | |||
| 4441381042 | |||
| 61c9c69718 | |||
| 5beaab97da | |||
| 843a4b8eae | |||
| 9ec46222e3 | |||
| 210da11fbb | |||
| ee61ae360d | |||
| 890e0f4995 | |||
| 224c66e0dc | |||
| 88052cd194 | |||
| c22453f24a | |||
| 099a805260 | |||
| 7ed474af8d | |||
| 9d893d6d4d | |||
| e55af0c274 | |||
| 803fbf2541 | |||
| 061b2b63e9 | |||
| 1486098065 | |||
| 0f0db4c823 | |||
| c3e7e96dce | |||
| 3c5f6bd8ac | |||
| b6b59e5c08 | |||
| a7aa27c87c | |||
| 735b325d74 | |||
| f948380fa2 | |||
| 79cf1880fc | |||
| ca130e1dc4 | |||
| d67ce81438 | |||
| ec1a84c57a | |||
| 59163cb2fc | |||
| 419cf9e2b0 | |||
| 95c78eac9c | |||
| 51a4cf5e46 | |||
| 2472c5d6a1 | |||
| 59fbb289b9 | |||
| e82bc20422 | |||
| 1e753e98ce | |||
| 39b3cab1da | |||
| 87fbfc6475 | |||
| cb8bfa027e | |||
| 1b1274fd56 | |||
| 38db495879 | |||
| a781c36876 | |||
| 71c336d9dd | |||
| e10e8910f3 | |||
| 253496c7ee | |||
| 30a3ab68c0 | |||
| 663a7c52c7 | |||
| 4e8ccd6f7d | |||
| 879ccfc8c2 | |||
| a77574b3d7 | |||
| 50738f8ce0 | |||
| 5c01878542 | |||
| ea93f6f560 | |||
| 7bab34eeda | |||
| 0cc23dec6f | |||
| 71c0d5253d | |||
| a674028c37 | |||
| 29fff4f51b | |||
| 4309ccfa02 | |||
| 4e8fe89faa | |||
| 8218d5a47e | |||
| 4bbb587280 | |||
| 0f04fe75bd | |||
| 11b356e55f | |||
| 80f008684d | |||
| c9c2d8133c | |||
| ac9a4d1e0d | |||
| d7dd6acd9d | |||
| b5739cb3d8 | |||
| ea93d56ca8 | |||
| 10097a946f | |||
| c439594403 | |||
| 29cf9e05db | |||
| 298f68c966 | |||
| 0b3289ea37 | |||
| 5f457bff12 | |||
| 6c00ccca9a | |||
| 7e679ab252 | |||
| 0ca21dbc91 | |||
| d2590f1078 | |||
| eb3f550e26 | |||
| 06aa6dedab | |||
| f769478abe | |||
| ba5f0af5a4 | |||
| 5e5f72ae57 | |||
| f36037ebf2 | |||
| 0c276ac71e | |||
| 9e95d1f1fd | |||
| e00bda37a5 | |||
| e7ea5f500d | |||
| a8fc95d4e4 | |||
| 3f598a5121 | |||
| 81c5ec0777 | |||
| 32bb58b272 | |||
| aa4b786ab3 | |||
| 3f5968b60c | |||
| 251eeb534a | |||
| 90add9f840 | |||
| 770624d492 | |||
| c59758ef65 | |||
| 15752335f4 | |||
| 3e4b48e206 | |||
| 25c685527a | |||
| fbabd137c2 | |||
| 6e7cf68164 | |||
| b47a532eb4 | |||
| 7c30ea32bf | |||
| bb06e044f5 | |||
| 01318a08b4 | |||
| 119487f1aa | |||
| 911427a361 | |||
| 58628a4bfc | |||
| b08b360f38 | |||
| adb8d0e845 | |||
| e0f009b3b9 | |||
| f1aa03c360 | |||
| 2ba417cf9f | |||
| d8af074ff6 | |||
| daf2bbf991 | |||
| 6605f293b4 | |||
| 482e18ccdb | |||
| ef1e0e14ec | |||
| 33f083b213 | |||
| bcfbc0cf6c | |||
| 00d75ece64 | |||
| dc1b5d3424 | |||
| 58fb633df3 | |||
| 36f9366f3f | |||
| 712f1ca02a | |||
| 285b238f26 | |||
| 70fb12b10e | |||
| 6380a6be05 | |||
| 548fd92c15 | |||
| 86de53eb9a | |||
| e1616953db | |||
| c1dbab50fe | |||
| b6bb6a92a9 | |||
| 0ab80ad0a7 | |||
| 61744764da | |||
| 8eb98982f3 | |||
| 1090339331 | |||
| 804816f014 | |||
| 51e8318224 | |||
| 0d38a50dba | |||
| 72094acf74 | |||
| 1bd67943bb | |||
| 30101e129f | |||
| 9bb31678a6 | |||
| 5e5c52ff0a | |||
| d9d4742130 | |||
| 0fab6b7cab | |||
| f10286de8c | |||
| a0e0465704 | |||
| c8457a2619 | |||
| 14c36bc405 | |||
| 81319228bd | |||
| fcd7b05900 | |||
| 8378d95588 | |||
| b34f9b1795 | |||
| 35b098e656 | |||
| e05a45b080 | |||
| 715ee66b03 | |||
| 3d6e9da115 | |||
| 54410988eb | |||
| dded2c2463 | |||
| fcf5838019 | |||
| beafa18708 | |||
| bd371a11ad | |||
| 1895fee1c9 | |||
| 2200d0b678 | |||
| f3c4a7dd16 | |||
| 25834b89dd | |||
| 4d20dea271 | |||
| c59647ad2f | |||
| e466cbe0ce | |||
| a24de2d22a | |||
| f452a3025d | |||
| 3c58eaf49f | |||
| c75b497b2e | |||
| d572d77b48 | |||
| a4074332cc | |||
| c31ceb6a5b | |||
| b0863d8628 | |||
| c38a6d74dd | |||
| 7bec75b709 | |||
| 56ea24b03b | |||
| 277829c280 | |||
| c127aaae6b | |||
| c895848061 | |||
| 64e5ebb55f | |||
| 83addd6bba | |||
| d87a19b2f9 | |||
| b58edc980c | |||
| f3e72623e9 | |||
| 54ee76bcef | |||
| efe6faabfd | |||
| 3ee8b655ea | |||
| c70d138eb9 | |||
| af2a327310 | |||
| b27e0e2807 | |||
| 8267ed53f0 | |||
| aa90d7b4b7 | |||
| 6b69946b9e | |||
| a1b87b5236 | |||
| 3044c5ea52 | |||
| d0636a9f6d | |||
| 0d291cb68e | |||
| c8bb50497b | |||
| ea027a7cc1 | |||
| 62e8601919 | |||
| be2cc7aed9 | |||
| 17babb22e2 | |||
| 21245273b4 | |||
| 8d7821c84e | |||
| c78dff9a15 | |||
| 25fea558ba | |||
| b1c84b598f | |||
| a6aa0a4cb0 | |||
| 8640129835 | |||
| 655dd2277c | |||
| 40f95191a0 | |||
| a013da860e | |||
| 4150c804df | |||
| 0446847278 | |||
| 2cf8309987 | |||
| 5b30f92677 | |||
| 88fac0ad2b | |||
| 45a9a6c4df | |||
| af554e7ed0 | |||
| 8912928581 | |||
| c2e49bd152 | |||
| ac0279aa83 | |||
| ae4161b780 | |||
| adc3bacea9 | |||
| e125f3a897 | |||
| f86b5a44bc | |||
| 0c5899b2a2 | |||
| a7d83b701f | |||
| d0b591307a | |||
| 13378a4b55 | |||
| ac6218eef2 | |||
| a98cc51ac2 | |||
| 92a06c9a28 | |||
| e595bdb20a | |||
| 9bd2446901 | |||
| 27babfec3d | |||
| 017ff53702 | |||
| 49441fe204 | |||
| 03d360b7bf | |||
| 53542abbb7 | |||
| fc908d4687 | |||
| e90b1bbead | |||
| ce1ca1b625 | |||
| 0eaa393065 | |||
| 6d749777fc | |||
| 6c20a4a874 | |||
| 79e8d1aac3 | |||
| becae46296 | |||
| 2ce553d661 | |||
| 66cadac6b6 | |||
| c237c5353b | |||
| c27a7e087f | |||
| 0894590a96 | |||
| 2efef91f1c | |||
| 3feba9a581 | |||
| afae896d05 | |||
| bcbaa21739 | |||
| d60bc61d13 | |||
| aeee565115 | |||
| 8126793b18 | |||
| 6a2592421c | |||
| 36adeec220 | |||
| 22bf0ead18 | |||
| b9dd6369d4 | |||
| 3d6c0ac512 | |||
| 95bf81f528 | |||
| 56e35e8ef2 | |||
| ae802a8a83 | |||
| ee71d2fe5f | |||
| 8dd2447cc5 | |||
| 3869ab6345 | |||
| 26453af1b9 | |||
| 5dc7b79bb6 | |||
| 33403efc8e | |||
| a0b4fcc05a | |||
| 82f7ab2ba5 | |||
| 505833a534 | |||
| 2557fb4f4d | |||
| 8511256779 | |||
| ae85d86d8f | |||
| 042740877c | |||
| b787b993b6 | |||
| 51ae14ec23 | |||
| 152f739527 | |||
| da88cb6a43 | |||
| 52a8bb414c | |||
| a27902205b | |||
| 7fb5b9886e | |||
| 8feb300d15 | |||
| 085bab749f | |||
| 96a5e594b3 | |||
| 04765d82ba | |||
| 47a9981571 | |||
| 0b45678ccc | |||
| 19ac465fa4 | |||
| 69bc8a8b22 | |||
| d0644bace9 | |||
| aae02cd1be | |||
| 47d56676f1 | |||
| efbaaf2f84 | |||
| d38575a011 | |||
| 908a9e9fa1 | |||
| 0ebabfad73 | |||
| 6ac3d902c9 | |||
| 3beb8c825b | |||
| b80e96547e | |||
| 2679c1cf0a | |||
| 65183e94c6 | |||
| 6b0fe683c9 | |||
| f14352f494 | |||
| ab9426e260 | |||
| 27fe85ac8b | |||
| eb6f01e65a | |||
| a6d406d2c3 | |||
| 4b8c0ac143 | |||
| c9f0158fdb | |||
| aac21f932b | |||
| ec01c2a119 | |||
| fbef77a942 | |||
| f207d988f4 | |||
| 60fc486cea | |||
| 978b70c998 | |||
| ef171f3acd | |||
| 64b36807d3 | |||
| 5de8f1803c | |||
| d1c4a26791 | |||
| a647cb9836 | |||
| 7398bed974 | |||
| 6077708831 | |||
| 6eebb1c089 | |||
| 6cd55e535c | |||
| 7d0955c0f4 | |||
| 8c9d24bd9f | |||
| c40375a424 | |||
| 2949a52a11 | |||
| 2e762d05f9 | |||
| bb06bfbbd7 | |||
| b8d20dfe99 | |||
| fa8529949b | |||
| 7b37c847bd | |||
| 3075f6cea7 | |||
| ff966490bb | |||
| 46993b43fe | |||
| 5e15bceaae | |||
| fefe5e241a | |||
| 8804330d83 | |||
| f5c12ec433 | |||
| 262cdd7bc0 | |||
| efee07e20b | |||
| 603b83e1c3 | |||
| a48f02e0da | |||
| d189339495 | |||
| 0802804677 | |||
| d9c281cd7c | |||
| 46185fe9e8 | |||
| 38e8a90f4e | |||
| 7a115e93c0 | |||
| d391df52ba | |||
| 46fc6f8da4 | |||
| 0fcca04150 | |||
| 54a9173107 | |||
| bf455c8d20 | |||
| c05d23a586 | |||
| 2a882aa58d | |||
| 04e26ba6b8 | |||
| 2211731c80 | |||
| 0fbdd57835 | |||
| 312b414d8f | |||
| a6e7954128 | |||
| 1417d43430 | |||
| 60ef6070b0 | |||
| 2f42196fca | |||
| f8b5e7e2c9 | |||
| 2c0547bb0e | |||
| 0f9eec887f | |||
| 234cf2d847 | |||
| 9304ad125c | |||
| 752c15c230 | |||
| 4f792c40b7 | |||
| 0245184c18 | |||
| 7ddf0226c6 | |||
| 17c3c1d66a | |||
| 40a3008318 | |||
| b48022be22 | |||
| 502aedb33e | |||
| 17f8e65808 | |||
| 439eb9da3d | |||
| f6116db957 | |||
| b36145e3c4 | |||
| 1c1bfd7541 | |||
| c824429458 | |||
| 238e77d959 | |||
| 23b2154d98 | |||
| 25c8711aad | |||
| cf30628d4e | |||
| e21eaa4b9e | |||
| 80b897d8cf | |||
| 1ed7bcfb2c | |||
| e20f92bbbb | |||
| 6e717bfd30 | |||
| 5d743bb0a3 | |||
| 7675c730b6 | |||
| 42942bb1e0 | |||
| 9d12de9bce | |||
| 790520e335 | |||
| 4b0e1a4b19 | |||
| a877f8abf0 | |||
| 491b1d9c96 | |||
| 2ce74c05e1 | |||
| 88e6558da3 | |||
| f1140ec903 | |||
| 8a745ecdfd | |||
| b8e29f5ae3 | |||
| 22e83013e3 | |||
| cc4713d878 | |||
| 490e838c60 | |||
| 6b15f29d7c | |||
| e7d9e42a16 | |||
| bd91727f49 | |||
| 328faf3744 | |||
| 1157cb9b95 | |||
| 7c8626d144 | |||
| 03faf2665b | |||
| 9959fd26bb | |||
| 43dcdb21ec | |||
| 3727637145 | |||
| 466251287f | |||
| f46706843b | |||
| c93ca02fb8 | |||
| 4813488f84 | |||
| fc292cc2d8 | |||
| f875e26fbf | |||
| 05658aeb3b | |||
| a14cb1fc06 | |||
| f68247673a | |||
| f65dd63210 | |||
| 03f64a6c20 | |||
| 0627c3443d | |||
| c65dd16460 | |||
| c590596dbe | |||
| 23cd4d5ed2 | |||
| 4dc6ff9fb8 | |||
| 8638cbf8b2 | |||
| a2555983e6 | |||
| 21804aecdb | |||
| 6991a38703 | |||
| 6b18e4f7e9 | |||
| efc9007cbf | |||
| efd33b295a | |||
| fa4ba42f15 | |||
| d3ef520915 | |||
| 811e29ff1b | |||
| 95d1efb7f8 | |||
| 5341cb5ff9 | |||
| cb37c0d135 | |||
| 73d40ce02a | |||
| c1709da6bf | |||
| dcfa81f983 | |||
| 42b1eaa240 | |||
| 1da1fa5a31 | |||
| 707931125e | |||
| f4e82a879b | |||
| 4f7369ed02 | |||
| 4312013552 | |||
| e8bc69aa01 | |||
| befb667759 | |||
| b35254ec78 | |||
| 9956988938 | |||
| 5b0e2e487a | |||
| ccd3872bf1 | |||
| b209952ce0 | |||
| 3568de2c6c | |||
| a8957d75b9 | |||
| 028ca5c9d9 | |||
| d516e1c736 | |||
| afdf8e7b21 | |||
| 9852b147f8 | |||
| 552cdbfe20 | |||
| 4ca29dd18e | |||
| 0d971a70cc | |||
| 0dda98384b | |||
| 685d330ee2 | |||
| 2d455018ae | |||
| fce486735b | |||
| 45073ce9eb | |||
| 4ba732c886 | |||
| a6cb786718 | |||
| 93a2e66704 | |||
| facbe2c012 | |||
| 02a49c8a68 | |||
| 97585bb26a | |||
| b618a1241f | |||
| d936009ea1 | |||
| 078f71c144 | |||
| bfc6c9b89d | |||
| 758d402305 | |||
| e6789fab6c | |||
| a2e114e852 | |||
| 0baf90a218 | |||
| f9f3d43152 | |||
| 326f2d2743 | |||
| 57f257dce5 | |||
| c27fc4e4d8 | |||
| a37192c102 | |||
| 68bd6a29b6 | |||
| da11113bf1 | |||
| 70f4cdd0ca | |||
| 78ac3cffde | |||
| 7eb2af6cd3 | |||
| 0b1c9d33a5 | |||
| 648a62112e | |||
| ff7cb91d9c | |||
| fd5881670d | |||
| fc8768b79b | |||
| 914570b053 | |||
| 1a8783cfa0 | |||
| 28bfefcac6 | |||
| bec56522e3 | |||
| 0ddd473477 | |||
| 2defc8e826 | |||
| c3756f6b58 | |||
| 66af3d260c | |||
| 5c3398c280 | |||
| 63a59325f5 | |||
| f1091f97fc | |||
| fe9bdfef79 | |||
| a8f11981e3 | |||
| 94651744af | |||
| 24e7d00af5 | |||
| f85a35b5fc | |||
| a27aad0061 | |||
| 9a332d2f86 | |||
| 1264983688 | |||
| 4d4a3d02ed | |||
| 53cee90933 | |||
| 6daa3290d4 | |||
| 5a9bee0527 | |||
| 6914d26187 | |||
| 68c01d09bb | |||
| 4bf1ad2566 | |||
| 00ed526fb0 | |||
| 9bdc58069b | |||
| 4ddbd2efb6 | |||
| f3f153cb38 | |||
| 9414a8085d | |||
| 33b18df1a0 | |||
| da91d342f7 | |||
| 4950e044ba | |||
| b41af5f580 | |||
| 24090d4642 | |||
| cdb1918973 | |||
| a8e8f04fa3 | |||
| 4ec3102df2 | |||
| 7e722db3ee | |||
| 20c45be3b3 | |||
| f2ee0aad20 | |||
| 478d4a571a | |||
| 4253ebf243 | |||
| 5b782a783a | |||
| c38183423f | |||
| 019e26dd8e | |||
| 6d2a65b4ea | |||
| 4206d98b55 | |||
| 9005fe2f61 | |||
| f87f18a291 | |||
| c0fdcb381a | |||
| aeaf0e7ba8 | |||
| 6dada4e347 | |||
| 61f015eef6 | |||
| d843521839 | |||
| 420369fe13 | |||
| 71bf1edc5e | |||
| d06ac519ab | |||
| 50512b52e1 | |||
| 543e77b9be | |||
| 783d455bd7 | |||
| 6c35272fe2 | |||
| 6955978a62 | |||
| 27d87dff79 | |||
| d8ca58a04e | |||
| ce34798685 | |||
| 16fd5249dd | |||
| b9a4c322a7 | |||
| 673bf356e4 | |||
| 6228412e61 | |||
| 578d947e2d | |||
| 72629d0081 | |||
| d7989f19cf | |||
| 8b11cdbf61 | |||
| 5c1f76e3cf | |||
| 63ba6018f3 | |||
| 8f3482561b | |||
| 13ceeb191c | |||
| 1536d1c044 | |||
| 16b6c26d6e | |||
| c7e30e2266 | |||
| d5e4495f89 | |||
| 963960a44c | |||
| a62c10321c | |||
| bb49e03435 | |||
| 38e7b1a262 | |||
| a00d3dfc00 | |||
| cd458e7a44 | |||
| 3f82570469 | |||
| a8642bd208 | |||
| b404c79ca4 | |||
| 29c75337f2 | |||
| fca4aeb50b | |||
| 1dfa2d6e91 | |||
| 79650ca3fd | |||
| fd84827e51 | |||
| 78283a0e0e | |||
| 993321e971 | |||
| f7a1e2f652 | |||
| e75be68466 | |||
| 74ac283c52 | |||
| 9ef1f8cba3 | |||
| e45656e5bf | |||
| cdc4fb45f2 | |||
| 5379a555db | |||
| d07c0bde80 | |||
| 7015ed203a | |||
| 1ead4cbb14 | |||
| 84ebca0dd2 | |||
| cf45b2cddb | |||
| 8f8bd05f83 | |||
| b1155a202c | |||
| d4aaaf16f8 | |||
| 119fb63576 | |||
| 3f7afd47d2 | |||
| ca0f8ed653 | |||
| 809bdb7c1f | |||
| 0424ff0818 | |||
| 9b952ff48c | |||
| c5064710a8 | |||
| 57e522065a | |||
| 7143daf500 | |||
| 71a00fc01b | |||
| 941483c14d | |||
| 17d8e65c64 | |||
| 72c0feb048 | |||
| 9e20dbe226 | |||
| 06f2738c03 | |||
| 5a257416ca | |||
| f9f0ffb64d | |||
| 31cf8a8813 | |||
| 98b7e0a407 | |||
| 7ed63d2ab5 | |||
| 6e6b38e8e9 | |||
| 829b9d96e4 | |||
| 85cef7e37c | |||
| c526bec798 | |||
| 9231335eef | |||
| dfac34beac | |||
| 82dd5d8ccf | |||
| be506f7121 | |||
| 2470494009 | |||
| f95a4b9b46 | |||
| 6b444a0877 | |||
| 5c4a845b55 | |||
| 468c01056f | |||
| 397078758e | |||
| c9af06c9e0 | |||
| 5a7e663b1d | |||
| e0550cd20b | |||
| 5844231a37 | |||
| 8d435638e1 | |||
| 55cad1b3ac | |||
| 9deadc1371 | |||
| 998abf05ba | |||
| aab5092da3 | |||
| 65ee5c4bbb | |||
| 42ab938a19 | |||
| 2891de2fcd | |||
| ed3758874d | |||
| 895d8179a2 | |||
| 8f6fc0146b | |||
| e1ac1c4fdc | |||
| a6b44a1470 | |||
| e8834a68f3 | |||
| 6ad1cd3fb5 | |||
| 3279cbac24 | |||
| 5094bad838 | |||
| 94af9b7f13 | |||
| 8e02263084 | |||
| fe0fe1873a | |||
| de29574314 | |||
| 5ac024788e | |||
| a1e273e983 | |||
| a95bf64ccf | |||
| 4fa9022932 | |||
| f10fb77a81 | |||
| db092c828e | |||
| bed0598530 | |||
| b734d4bbc1 | |||
| d2080808db | |||
| 345d5e8d9e | |||
| bcc41bf3d1 | |||
| b2d444d782 | |||
| bac6703f8e | |||
| 6cbbd1e5a1 | |||
| b6ef558c86 | |||
| 70bb082973 | |||
| 8b8a19c75d | |||
| 0b53242564 | |||
| f11bd509b0 | |||
| 57608628a4 | |||
| f167c3e12e | |||
| 262b380280 | |||
| ee0c20ae44 | |||
| c30c144120 | |||
| a5ee82b0d1 | |||
| a4f558181d | |||
| 120303e6e3 | |||
| b3822d5802 | |||
| 980e4ee89a | |||
| bb1428eeb1 | |||
| f6a90e9b42 | |||
| a71159667d | |||
| 74e00cf652 | |||
| e773a80b06 | |||
| e6eea67eeb | |||
| 8429a1e792 | |||
| 47fbd2a2b5 | |||
| 93835b9b94 | |||
| 2de3fc9f6f | |||
| 78a8cf6982 | |||
| 99cf3219d4 | |||
| 7587e97d46 | |||
| 3061c8b854 | |||
| 77e9e95067 | |||
| 6191b6bee2 | |||
| b15f8f68e4 | |||
| 84c12793e8 | |||
| 6eeadddd4d | |||
| a40b3a98dc | |||
| f0d66ff0fb | |||
| d3ebd360b2 | |||
| ebbe1692c8 | |||
| ca7d406787 | |||
| a2dc8378f5 | |||
| b570e89dbd | |||
| 108f87678a | |||
| 00146ae87c | |||
| e3757fbbfa | |||
| ac64e8b15e | |||
| c39ca7189b | |||
| 03c8fdd30a | |||
| 788bc67faa | |||
| 048be2da2c | |||
| 8e1f70865e | |||
| 6143f1ff5b | |||
| db30836b53 | |||
| 3e8ef5e462 | |||
| 0a53dccd4c | |||
| 2b5aa142fb | |||
| 40443d1e25 | |||
| cb4e7614ee | |||
| 3d84dbc73f | |||
| beb2ab9ad5 | |||
| 9a0877379c | |||
| bbd0239ece | |||
| 92956f2b45 | |||
| 48d1a5ec5d | |||
| 2ff2ce460c | |||
| 7cc875b8db | |||
| 9387f583fa | |||
| 707dd700b0 | |||
| ddff9b612f | |||
| 338ac5d4a3 | |||
| ca7abd727a | |||
| 62b20769ee | |||
| 4ec323c5cc | |||
| 84e72ede72 | |||
| bd37c48596 | |||
| e30f0e8e11 | |||
| c43a2513a8 | |||
| 4b4bc0dde2 | |||
| 49adf2192a | |||
| a7eabeb73f | |||
| f838f3427b | |||
| 1cc75ca636 | |||
| d4356b0453 | |||
| 35542e5823 | |||
| c80c2233c5 | |||
| c2f0e4f683 | |||
| 2621f4a2fa | |||
| 3c055642d5 | |||
| 43b881d0cd | |||
| 8b7b32e225 | |||
| 00b0ff50f3 | |||
| 1acde593b5 | |||
| c43c043521 | |||
| b526cadebd | |||
| 94f44e1d5d | |||
| 0352d9c99e | |||
| 0cd3f37e1b | |||
| 486d7b6d62 | |||
| 8f4e332409 | |||
| f0389c0b2f | |||
| 922e8a4912 | |||
| 021a1c7a39 | |||
| 4a7451682b | |||
| faa880d60a | |||
| fd30e82836 | |||
| 3ef34fbb56 | |||
| 7345dc6861 | |||
| 9958937fd1 | |||
| f19c57200d | |||
| 8a2652f53d | |||
| dddde4ddab | |||
| 300d901618 | |||
| 1cb72acd27 | |||
| a17776cb5f | |||
| 94b749ab00 | |||
| 5fc0d284cb | |||
| bbe1211451 | |||
| ce152b205f | |||
| a5fd7cf4e9 | |||
| da38a1367a | |||
| 1445f11c19 | |||
| 86df55f5cc | |||
| cf294c938e | |||
| ebff45f803 | |||
| 7b8021a36e | |||
| 5c77bb7c67 | |||
| 8ade26b4a4 | |||
| bdbc60b4f7 | |||
| 373fa7a7d9 | |||
| eec4f173a7 | |||
| d726ce6340 | |||
| b406844c96 | |||
| 153d38f10c | |||
| dce917eb74 | |||
| eb711787ae | |||
| 9967dbbaa9 | |||
| 71dc10ebea | |||
| 782fba2ce7 | |||
| 4d73f98050 | |||
| 79d2083a00 | |||
| ee3b296a99 | |||
| 8b62d04453 | |||
| 9b0d3dfaeb | |||
| b1ef4cfee9 | |||
| f12f6a56ba | |||
| 2777d53a12 | |||
| aba3ec692f | |||
| b7c8fcd062 | |||
| 3065de63dd | |||
| a57fb4f1ab | |||
| c493a22765 | |||
| d85e5def5d | |||
| 0aba499c8e | |||
| 4146695f34 | |||
| 4e57e10ba8 | |||
| daa6d02887 | |||
| a87d89302f | |||
| 2a9b1311d3 | |||
| 7d73501b87 | |||
| 039d6acd3e | |||
| 405fcdc483 | |||
| f52abc1a62 | |||
| e763953562 | |||
| 4cab617c25 | |||
| 0190b5e5af | |||
| abc0952247 | |||
| 6ce2726a87 | |||
| 17a4463f59 | |||
| e76d8df246 | |||
| a46bcf45d5 | |||
| 1f985d04a2 | |||
| d64e6e6c1f | |||
| 1164a65df8 | |||
| d57f07d57e | |||
| 5c0a964321 | |||
| cf3b8d09d9 | |||
| 1c7397fb21 | |||
| 6a08d93e2c | |||
| 4c03ace9eb | |||
| 2cd616dd30 | |||
| eab87c0827 | |||
| 8b8188710e | |||
| fd9bb3ac43 | |||
| 6d9c3bca33 | |||
| dd33a45644 | |||
| 074c7a9c40 | |||
| de2f06970d | |||
| 6166d946f7 | |||
| c778ab9622 | |||
| aad846b968 | |||
| f04a3e3d2e | |||
| 7ad52de2b1 | |||
| 0706ba9bec | |||
| ed53888fce | |||
| fd76fba235 | |||
| 95088a785a | |||
| f46b600ec0 | |||
| 566ab993df | |||
| 407036e215 | |||
| 7b1a5566fb | |||
| 1b0d8739c1 | |||
| 266feea397 | |||
| c4c6ab2494 | |||
| 079eea3f2b | |||
| a457d69034 | |||
| d0175798bf | |||
| 80e07943ee | |||
| e2954211ec | |||
| 337bed8176 | |||
| 71197e1c89 | |||
| e1a13f5ce8 | |||
| 1ed2c16a51 | |||
| 12e1bd80b3 | |||
| fd6daa580a | |||
| d2a19ec8ec | |||
| 8f3feac916 | |||
| c0e066440c | |||
| fbb4e9078a | |||
| d96e90c6f4 | |||
| 3b435d8956 | |||
| 345dd2481b | |||
| 006bcc0fc8 | |||
| c25d14e454 | |||
| 5ff95dc32d | |||
| 34031aab1b | |||
| 3035219212 | |||
| 8a608eb930 | |||
| c2fc47df34 | |||
| d4065774ce | |||
| 6d43d9f2b6 | |||
| 94d7fd9112 | |||
| 04b5833e98 | |||
| 52592b84fd | |||
| f2cd68e3ec | |||
| aff590a44d | |||
| 0d432f6377 | |||
| 59bceee258 | |||
| 4a0a0bac1d | |||
| c7bd96ea8b | |||
| 0eb2106067 | |||
| c03aec364c | |||
| f2cdb97867 | |||
| 727e284ed0 | |||
| 3248977e02 | |||
| 7ee8776165 | |||
| f89f4bd20b | |||
| a372ade7ce | |||
| 61dca4a35e | |||
| c0402345f7 | |||
| 9cc68b26e2 | |||
| 27c9230a82 | |||
| e985c9714b | |||
| 6c5015811e | |||
| 86e7de4d62 | |||
| 147d35e40d | |||
| b76fc724fd | |||
| 1bfab4e279 | |||
| 11bdfba37e | |||
| 405f08b807 | |||
| 592211cecd | |||
| a4f31001e8 | |||
| c2deedac8b | |||
| 9a61f8b894 | |||
| 3a291f5c8e | |||
| 559a2dcec7 | |||
| b7f003c4aa | |||
| d11c0bbd5c | |||
| c2f775fcaa | |||
| 19ac831c2e | |||
| 23b413a398 | |||
| 098de196e2 | |||
| 27d2c31f28 | |||
| c9c9edeb23 | |||
| 5adf792fad | |||
| 81af7d73a6 | |||
| 23e4e0786d | |||
| 0640ce9632 | |||
| 3e49bf4f42 | |||
| 66b038a010 | |||
| 9bbbebf31d | |||
| 19765cfa14 | |||
| d6badca610 | |||
| 6933804aa4 | |||
| 5bed7f292f | |||
| f553896e2d | |||
| 60663b5433 | |||
| 1851a31e66 | |||
| d853310bee | |||
| 11c671354b | |||
| b15599f01e | |||
| 4b957abc0c | |||
| 8ee82d1e03 | |||
| 5565662d87 | |||
| 78735fae6b | |||
| d3b9911445 | |||
| 7813dafc96 | |||
| 02b561edd2 | |||
| 272a1fda54 | |||
| bc8666df83 | |||
| 028fad94af | |||
| 0c735953c9 | |||
| 736bc87480 | |||
| dd94a64048 | |||
| cf9f88f8ce | |||
| 5694aeda5f | |||
| 7829e3c132 | |||
| 2ce0d60db1 | |||
| 68e66dad06 | |||
| 80db907857 | |||
| 76674a3594 | |||
| 98dba11c5e | |||
| de261d28ef | |||
| d43716612b | |||
| cfaacf7cb2 | |||
| b9922bc90b | |||
| 31cae8f05f | |||
| 133e382aae | |||
| e02c721c2b | |||
| 5af0ceb2d2 | |||
| 6460fdc62b | |||
| 402ca780bf | |||
| 643ab92cd2 | |||
| a9c3b343fc | |||
| 592bebaf29 | |||
| 4df215e674 | |||
| 91792f45ea | |||
| 20091e94c8 | |||
| 76aa494be4 | |||
| 6fb8fdc2bd | |||
| 0d879ed290 | |||
| d8d46e0f3e | |||
| e5830b0116 | |||
| d89b171f49 | |||
| a760aec791 | |||
| 34d5d353af | |||
| e8e637c4f2 | |||
| adbca39fef | |||
| a2c88b607f | |||
| 2115a67d24 | |||
| dec73b02e9 | |||
| 0e6ed53cee | |||
| fd6c70afe1 | |||
| c4f193b13e | |||
| 70703c39f3 | |||
| d429485f0c | |||
| 89460dd39c | |||
| f46b259384 | |||
| fb0ce48f2f | |||
| cb4a81008c | |||
| d620da365e | |||
| 0c3102721c | |||
| b3fa03043d | |||
| 38d7db49c8 | |||
| 1a8c832039 | |||
| 6e54f8cfa6 | |||
| 4838ffb82d | |||
| 1bcf41d382 | |||
| e381566494 | |||
| 66d7a073d3 | |||
| 0637215b85 | |||
| dc1405ffa8 | |||
| 0fce20c503 | |||
| 1b16dd126b | |||
| fe07f9208c | |||
| f092fc3fc6 | |||
| b5228dcda0 | |||
| a5db3ea25b | |||
| 173fad2362 | |||
| 496338d84d | |||
| 59727a6967 | |||
| 3a5e41ed91 | |||
| 2259bce05f | |||
| 7e00a86bb4 | |||
| 73a2a938b4 | |||
| c2098938f5 | |||
| 773ff182ee | |||
| 878c49e4e1 | |||
| 023dd3e880 | |||
| 6b88856c16 | |||
| dd5f926077 | |||
| 845020b0e2 | |||
| 7cf363eb06 | |||
| f67e670621 | |||
| 645e3ccbb3 | |||
| ab385f2bf5 | |||
| 5080b9a82b | |||
| 51e42ded44 | |||
| 37fb89c691 | |||
| 440eda3807 | |||
| bad2576397 | |||
| fdf2e5934d | |||
| 3da1e8598b | |||
| 0296c767bf | |||
| c215c42289 | |||
| 8adab95973 | |||
| b89c7580e6 | |||
| a85fe2cb08 | |||
| 4c4c126361 | |||
| e9e12b88f8 | |||
| dc08c516bf | |||
| 9b1f108051 | |||
| b0f9a0feb4 | |||
| 3bd27ae8c5 | |||
| 79b9bdf7ce | |||
| 9e09168597 | |||
| e5f12347bd | |||
| 86d3556c6d | |||
| 45838b33b7 | |||
| a1d4798ded | |||
| 25c52b7482 | |||
| fcf9f266ad | |||
| fa638ae3a0 | |||
| 6d9cd504a0 | |||
| f9e9bb8870 | |||
| 85ab2425a8 | |||
| 9931155c68 | |||
| 56b6d928b6 | |||
| b865bea482 | |||
| b6314e0c73 | |||
| 2c773750c7 | |||
| 539b9be1d3 | |||
| 00e8caa0e3 | |||
| 1ff8b62bf5 | |||
| 25fb985af8 | |||
| 858245db7d | |||
| 09bea2ad5b | |||
| adb520ec2a | |||
| 5a1ff4b50d | |||
| e0f8acf733 | |||
| a81542eeee | |||
| f67eeb66aa | |||
| 884c998622 | |||
| 88c8d73a94 | |||
| 86576768d1 | |||
| 3327c32b20 | |||
| 97ed6a3a4e | |||
| 85d8e0ac2c | |||
| 2a68f9f532 | |||
| b55d35c7bb | |||
| 98f85d7728 | |||
| 328a7caf61 | |||
| 275ea9b0bb | |||
| bb78bc8fe3 | |||
| 10224a692b | |||
| 3eb83d0737 | |||
| f35fa0049c | |||
| d77a88c21e | |||
| 3d55622237 | |||
| bf76465029 | |||
| 129a6ed99e | |||
| 9f5fc4ab0c | |||
| 97f6468663 | |||
| a883b73981 | |||
| 36aadc21a7 | |||
| da469911d3 | |||
| 4195b0d0e6 | |||
| d241aef502 | |||
| 8b2ca6b13d | |||
| ade94c87b5 | |||
| 46f3426c35 | |||
| 3503cd9b71 | |||
| 73cc040792 | |||
| 6c6029618a | |||
| 2a8084b6c6 | |||
| 86ca9bd0f9 | |||
| b192678abf | |||
| 9a998d7b41 | |||
| 64a6859753 | |||
| b20b7e65bf | |||
| 203e3ef077 | |||
| 7be5502a12 | |||
| 0de6e4ccbb | |||
| c8041bacd6 | |||
| 1187f83ffd | |||
| dd3b8469dd | |||
| 34bbd7dcaa | |||
| 8318b3ba83 | |||
| 6768ecc3fc | |||
| 9672f00ec3 | |||
| 0c1101739d | |||
| 872cb2d9c8 | |||
| 3e47fe54fa | |||
| f0d3d23b5f | |||
| 69e59b0ced | |||
| ad4fb5afe3 | |||
| dd6dd63798 | |||
| 7a3748b8f6 | |||
| 06a08a874f | |||
| 37a9813482 | |||
| fe7b436a8c | |||
| 601eff1af6 | |||
| 29949eae1b | |||
| 9dfe6d1e85 | |||
| fb3bc22c64 | |||
| b89304a24b | |||
| 69b3457e83 | |||
| cf21074f10 | |||
| dc7f21513a | |||
| a15450af91 | |||
| efbcce0ffe | |||
| 1c2c87e03d | |||
| 93b33c0518 | |||
| 53e01952be | |||
| 1c12b468a8 | |||
| ccd803416e | |||
| 62f2a42f28 | |||
| d6e76fd1c0 | |||
| 9135c56ac6 | |||
| 0e7eff3963 | |||
| bd1928e445 | |||
| 8e105af232 | |||
| 796cbafde4 | |||
| 29354a1586 | |||
| bcd73e604c | |||
| e80ca6553d | |||
| 90f17c2140 | |||
| 2e5cc1e6ae | |||
| 0ea7fd9c3d | |||
| 814d9aa01b | |||
| 3fa12445a5 | |||
| 547a2aec09 | |||
| 9175fb7da8 | |||
| 887032881a | |||
| e67f82283f | |||
| cfa83658dc | |||
| c881aa7b32 | |||
| a8db29399f | |||
| baacd0e50c | |||
| 0f8c3b1960 | |||
| cd523cc934 | |||
| 044271a55c | |||
| f662b9a081 | |||
| ba10f97420 | |||
| 50c460ebd5 | |||
| 501863a0eb | |||
| ec9b2dbe42 | |||
| db2ba22bd6 | |||
| 087f08dad2 | |||
| bf7b146dfc | |||
| 01f3237416 | |||
| 8f813fbc67 | |||
| f4ff695080 | |||
| 08cc2bbd70 | |||
| 46a7e46068 | |||
| 472a567f42 | |||
| f3bc1ed3a9 | |||
| 7ba9b97afc | |||
| 061d281d2a | |||
| 2835508292 | |||
| 959d9a3ad9 | |||
| 7cf34a6d6f | |||
| 8d6d7d1f20 | |||
| b115764d9c | |||
| 1b5d332e93 | |||
| 356dfc806d | |||
| f2b556adfd | |||
| 1bbfced61a | |||
| 800cb8c6dd | |||
| 6b1d672dc1 | |||
| 6e138bbf54 | |||
| 6dabf4507a | |||
| 527e6cbc72 | |||
| 39edbcbabd | |||
| 0077856d2f | |||
| b65f1d7df0 | |||
| 201afbbeec | |||
| f5caf96d2e | |||
| 73efcc6b0c | |||
| d69510f997 | |||
| d6946a8aae | |||
| ebbc168f3f | |||
| 347cbd37ca | |||
| d190e0b771 | |||
| 5f28a7db0d | |||
| d0c99f1999 | |||
| bf71781ee9 | |||
| fbce104f3b | |||
| ef9074f8e4 | |||
| 67f3111cc0 | |||
| 56d2101b1a | |||
| a28395b116 | |||
| eebf3a54e2 | |||
| 7e70fa63d7 | |||
| bea4b520c0 | |||
| 64c17c4ecd | |||
| 26f7ac9ca1 | |||
| b1a12768e1 | |||
| 0e5a448d04 | |||
| 91a89399f8 | |||
| c6bb7c5993 | |||
| 48b131eb5c | |||
| 1328be2b61 | |||
| 88c1e622dd | |||
| 10672786a1 | |||
| d896a9efec | |||
| 0ccdd4b6ad | |||
| 66fc676858 | |||
| 12f2acc9ff | |||
| b53e8bf501 | |||
| e296264ea6 | |||
| 598f5519d1 | |||
| ced64d7a09 | |||
| 7075a8a8ef | |||
| e2605c2838 | |||
| be63939441 | |||
| dea9c37d99 | |||
| 4d27366ead | |||
| a11a8429bb | |||
| 6da33cafe5 | |||
| 06f82d5e8a | |||
| 89dd0c4a40 | |||
| 1b10f53eff | |||
| 8bd7d57dd8 | |||
| 4a6325696e | |||
| b50a907ca3 | |||
| 59e9a67abd | |||
| 1d2f06df6d | |||
| 725b93a961 | |||
| a21e4c5a0b | |||
| 433db17083 | |||
| f8753fb9f1 | |||
| 25d5653f66 | |||
| 703a88a639 | |||
| 25326b571b | |||
| 5e2f4c9d2d | |||
| f43d380fe2 | |||
| 2240d3d0d1 | |||
| b6eea9a880 | |||
| 6bbd7c0c0b | |||
| 2caeb4008c | |||
| a4919ffb45 | |||
| b384340cbb | |||
| 061f46306f | |||
| fe1f11b071 | |||
| d3f5db576a | |||
| 0ca586e1c8 | |||
| a0b55f9df3 | |||
| 24943ccee6 | |||
| bcaaf34fa7 | |||
| ea17d1f6c7 | |||
| 3be734010c | |||
| e79787cc77 | |||
| 7de428233e | |||
| 9722f56be8 | |||
| e766d206f1 | |||
| 1fa9091239 | |||
| 04e1e5e3a2 | |||
| fa5c0560fa | |||
| 55d47b3e31 | |||
| 5bb96fd477 | |||
| 22b404a1b4 | |||
| 03dcf82602 | |||
| 95d1e8a4f1 | |||
| 67f68b47db | |||
| 593808f24d | |||
| 0a884cc64a | |||
| a54d4b98b1 | |||
| 23132e5292 | |||
| d741b624be | |||
| 00bc394bdb | |||
| d7215ad185 | |||
| 2b63eb8243 | |||
| 1bb3da0332 | |||
| c7d3d635f6 | |||
| f4c8db6105 | |||
| b2637b9a43 | |||
| 09d0ac3838 | |||
| f42cc848d5 | |||
| 4b1224f874 | |||
| 10bb2cce8e | |||
| 8174b3b85a | |||
| 71e2f2ed61 | |||
| 8d8724b3e1 | |||
| 47f65ccba6 | |||
| df0c1106ce | |||
| 47a2271e27 | |||
| ea367a7f37 | |||
| f4b192e33c | |||
| a5c824f694 | |||
| 75f9c08445 | |||
| cec3d1488a | |||
| ebec082da2 |
@@ -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'
|
||||
...
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
# Kind-specific patterns to check AST nodes against. Both python-clang and
|
||||
# libclang docs explain CursorKind, with differences in detail. See also:
|
||||
# - https://github.com/llvm-mirror/clang/blob/aca4fe314a55cacae29e1548cb7bfd2119c6df4c/bindings/python/clang/cindex.py#L599
|
||||
# - http://clang.llvm.org/doxygen/group__CINDEX.html#gaaccc432245b4cd9f2d470913f9ef0013
|
||||
# - https://docs.python.org/2/library/re.html#regular-expression-syntax
|
||||
|
||||
class_decl: '^([A-Z]+[a-z]+)+$'
|
||||
struct_decl: '^([A-Z]+[a-z]+)+$'
|
||||
field_decl: '^[a-z_]+$'
|
||||
var_decl: '^[a-z]+[a-z0-9_]*$'
|
||||
parm_decl: '^[a-z]*[a-z0-9_]*$'
|
||||
namespace: '^[a-z_]*$'
|
||||
cxx_method: '^([A-Z]+[a-z]+)+$'
|
||||
function_decl: '^[a-z]+([A-Z]+[a-z]+)*$'
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"rules": {
|
||||
"indent": [
|
||||
2,
|
||||
4
|
||||
],
|
||||
"quotes": [
|
||||
1,
|
||||
"single"
|
||||
],
|
||||
"linebreak-style": [
|
||||
2,
|
||||
"unix"
|
||||
],
|
||||
"semi": [
|
||||
2,
|
||||
"always"
|
||||
],
|
||||
"no-console": [
|
||||
1
|
||||
]
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "eslint:recommended"
|
||||
}
|
||||
+16
-20
@@ -1,3 +1,7 @@
|
||||
# pre compiled dependencies #
|
||||
#############################
|
||||
osrm-deps
|
||||
|
||||
# Compiled source #
|
||||
###################
|
||||
*.com
|
||||
@@ -36,8 +40,8 @@ Thumbs.db
|
||||
# build related files #
|
||||
#######################
|
||||
/build/
|
||||
/Util/finger_print.cpp
|
||||
/Util/GitDescription.cpp
|
||||
/example/build/
|
||||
/test/data/monaco*
|
||||
/cmake/postinst
|
||||
|
||||
# Eclipse related files #
|
||||
@@ -53,25 +57,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
|
||||
@@ -88,8 +75,17 @@ stxxl.errlog
|
||||
###################
|
||||
/sandbox/
|
||||
|
||||
# Test related files #
|
||||
######################
|
||||
/test/profile.lua
|
||||
/test/cache
|
||||
/test/speeds.csv
|
||||
/test/penalties.csv
|
||||
/test/data/monaco.*
|
||||
node_modules
|
||||
|
||||
# Deprecated config file #
|
||||
##########################
|
||||
/server.ini
|
||||
|
||||
*.swp
|
||||
|
||||
+173
-55
@@ -1,60 +1,178 @@
|
||||
language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
# - clang
|
||||
# Make sure CMake is installed
|
||||
install:
|
||||
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
|
||||
- sudo add-apt-repository -y ppa:boost-latest/ppa
|
||||
- sudo apt-get update >/dev/null
|
||||
- sudo apt-get -q install protobuf-compiler libprotoc-dev libprotobuf7 libprotobuf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
|
||||
- sudo apt-get -q install g++-4.8
|
||||
- sudo apt-get install libboost1.54-all-dev
|
||||
# luabind
|
||||
- curl https://gist.githubusercontent.com/DennisOSRM/f2eb7b948e6fe1ae319e/raw/install-luabind.sh | sudo bash
|
||||
# osmosis
|
||||
- curl -s https://gist.githubusercontent.com/DennisOSRM/803a64a9178ec375069f/raw/ | sudo bash
|
||||
# cmake
|
||||
- curl -s https://gist.githubusercontent.com/DennisOSRM/5fad9bee5c7f09fd7fc9/raw/ | sudo bash
|
||||
# osmpbf library
|
||||
- curl -s https://gist.githubusercontent.com/DennisOSRM/13b1b4fe38a57ead850e/raw/install_osmpbf.sh | sudo bash
|
||||
before_script:
|
||||
- rvm use 1.9.3
|
||||
- gem install bundler
|
||||
- bundle install
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake .. $CMAKEOPTIONS
|
||||
script:
|
||||
- make -j 2
|
||||
- make -j 2 tests
|
||||
- ./datastructure-tests
|
||||
- cd ..
|
||||
- cucumber -p verify
|
||||
after_script:
|
||||
# - cd ..
|
||||
# - cucumber -p verify
|
||||
|
||||
git:
|
||||
depth: 10
|
||||
|
||||
# sudo:required is needed for trusty images
|
||||
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
|
||||
cache:
|
||||
ccache: true
|
||||
apt: true
|
||||
|
||||
env:
|
||||
global:
|
||||
- CCACHE_TEMPDIR=/tmp/.ccache-temp
|
||||
- CCACHE_COMPRESS=1
|
||||
- JOBS=4
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
# We override the compiler names here to yield better ccache behavior, which uses this as key
|
||||
include:
|
||||
|
||||
# Debug Builds
|
||||
- os: linux
|
||||
compiler: "gcc-5-debug"
|
||||
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', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Debug'
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-4.8-debug"
|
||||
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', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-4.8' CXXCOMPILER='g++-4.8' BUILD_TYPE='Debug'
|
||||
|
||||
- os: linux
|
||||
compiler: "clang-3.8-debug"
|
||||
addons: &clang38
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Debug' RUN_CLANG_FORMAT=ON
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: CCOMPILER='clang' CXXCOMPILER='clang++' BUILD_TYPE='Debug' JOBS=1 CUCUMBER_TIMEOUT=60000
|
||||
|
||||
# Release Builds
|
||||
- os: linux
|
||||
compiler: "gcc-5-release"
|
||||
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', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release'
|
||||
|
||||
# Disabled because of CI slowness
|
||||
#- 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', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
|
||||
#- env: CCOMPILER='gcc-4.8' CXXCOMPILER='g++-4.8' BUILD_TYPE='Release'
|
||||
|
||||
# Disabled because of CI slowness
|
||||
#- os: linux
|
||||
#- compiler: clang
|
||||
#- addons: &clang38
|
||||
#- apt:
|
||||
#- sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
|
||||
#- packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
|
||||
#- env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Release'
|
||||
|
||||
# Disabled because of CI slowness
|
||||
#- os: osx
|
||||
#- osx_image: xcode7.3
|
||||
#- compiler: clang
|
||||
#- env: CCOMPILER='clang' CXXCOMPILER='clang++' BUILD_TYPE='Release'
|
||||
|
||||
# Shared Library
|
||||
- os: linux
|
||||
compiler: "gcc-5-release-shared"
|
||||
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', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev', 'ccache']
|
||||
env: CCOMPILER='gcc-5' CXXCOMPILER='g++-5' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
# Disabled because CI slowness
|
||||
#- os: linux
|
||||
#- compiler: clang
|
||||
#- addons: &clang38
|
||||
#- apt:
|
||||
#- sources: ['llvm-toolchain-precise-3.8', 'ubuntu-toolchain-r-test']
|
||||
#- packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
|
||||
#- env: CCOMPILER='clang-3.8' CXXCOMPILER='clang++-3.8' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
before_install:
|
||||
- source ./scripts/install_node.sh 4
|
||||
- npm 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.5/cmake-3.5.1-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}
|
||||
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||
# implicit deps, but seem to be installed by default with recent images: libxml2 GDAL boost
|
||||
brew install cmake libzip libstxxl lua51 luabind tbb md5sha1sum ccache
|
||||
fi
|
||||
|
||||
install:
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- |
|
||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||
./scripts/check_taginfo.py taginfo.json profiles/car.lua
|
||||
fi
|
||||
- mkdir build && pushd build
|
||||
- export CC=${CCOMPILER} CXX=${CXXCOMPILER}
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} -DCOVERAGE=${COVERAGE:-OFF} -DBUILD_TOOLS=1 -DENABLE_CCACHE=ON
|
||||
- echo "travis_fold:start:MAKE"
|
||||
- make --jobs=${JOBS}
|
||||
- make tests --jobs=${JOBS}
|
||||
- make benchmarks --jobs=${JOBS}
|
||||
- echo "travis_fold:end:MAKE"
|
||||
- ccache -s
|
||||
- sudo make install
|
||||
- |
|
||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||
sudo ldconfig
|
||||
fi
|
||||
- popd
|
||||
- mkdir example/build && pushd example/build
|
||||
- cmake ..
|
||||
- make
|
||||
- popd
|
||||
|
||||
script:
|
||||
- echo "travis_fold:start:BENCHMARK"
|
||||
- make -C test/data benchmark
|
||||
- echo "travis_fold:end:BENCHMARK"
|
||||
- ./example/build/osrm-example test/data/monaco.osrm
|
||||
# All tests assume to be run from the build directory
|
||||
- pushd build
|
||||
- ./unit_tests/library-tests ../test/data/monaco.osrm
|
||||
- ./unit_tests/extractor-tests
|
||||
- ./unit_tests/engine-tests
|
||||
- ./unit_tests/util-tests
|
||||
- ./unit_tests/server-tests
|
||||
- popd
|
||||
- npm test
|
||||
|
||||
after_success:
|
||||
- |
|
||||
if [ -n "${RUN_CLANG_FORMAT}" ]; then
|
||||
./scripts/format.sh || true # we don't want to fail just yet
|
||||
fi
|
||||
- |
|
||||
if [ -n "${COVERAGE}" ]; then
|
||||
coveralls --build-root build --exclude unit_tests --exclude third_party --exclude node_modules --gcov-options '\-lp'
|
||||
fi
|
||||
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
# 5.1.0
|
||||
Changes with regard to 5.0.0
|
||||
|
||||
- API:
|
||||
- added StepManeuver type `roundabout turn`. The type indicates a small roundabout that is treated as an intersection
|
||||
(turn right at the roundabout for first exit, go straight at the roundabout...)
|
||||
- added StepManeuver type `on ramp` and `off ramp` to distinguish between ramps that enter and exit a highway.
|
||||
- reduced new name instructions for trivial changes
|
||||
- combined multiple turns into a single instruction at segregated roads`
|
||||
|
||||
- Profile Changes:
|
||||
- introduced a suffix_list / get_name_suffix_list to specify name suffices to be suppressed in name change announcements
|
||||
- street names are now consistently assembled for the car, bike and walk profile as: "Name (Ref)" as in "Berlin (A5)"
|
||||
- new `car.lua` dependency `lib/destination.lua`
|
||||
- register a way's .nodes() function for use in the profile's way_function.
|
||||
|
||||
- Infrastructure
|
||||
- BREAKING: reordered internal instruction types. This breaks the **data format**
|
||||
|
||||
- Fixes:
|
||||
- Issue #2310: post-processing for local paths, fixes #2310
|
||||
- Issue #2309: local path looping, fixes #2309
|
||||
- Issue #2356: Make hint values optional
|
||||
- Issue #2349: Segmentation fault in some requests
|
||||
- Issue #2335: map matching was using shortest path with uturns disabled
|
||||
- Issue #2193: Fix syntax error position indicators in parameters queries
|
||||
- Fix search with u-turn
|
||||
- PhantomNode packing in MSVC now the same on other platforms
|
||||
- Summary is now not malformed when including unnamed roads
|
||||
- Emit new-name on when changing fron unanmed road to named road
|
||||
|
||||
# 5.0.0
|
||||
Changes with regard 5.0.0 RC2:
|
||||
- API:
|
||||
- if `geometry=geojson` is passed the resulting geometry can be a LineString or Point
|
||||
depending on how many coordinates are present.
|
||||
- the removal of the summary field was revered. for `steps=flase` the field will always be an empty string.
|
||||
|
||||
Changes with regard to 4.9.1:
|
||||
- API:
|
||||
- BREAKING: Complete rewrite of the HTTP and library API. See detailed documentation in the wiki.
|
||||
- BREAKING: The default coordinate order is now `longitude, latidue`. Exception: Polyline geometry
|
||||
which follow the original Google specification of `latitdue, longitude`.
|
||||
- BREAKING: Polyline geometries now use precision 5, instead of previously 6
|
||||
- BREAKING: Removed GPX support
|
||||
- New service `tile` which serves debug vector tiles of the road network
|
||||
- Completely new engine for guidance generation:
|
||||
- Support for highway ramps
|
||||
- Support for different intersection types (end of street, forks, merges)
|
||||
- Instruction post-processing to merge unimportant instructions
|
||||
- Improved handling of roundabouts
|
||||
|
||||
- Tools:
|
||||
- BREAKING: Renamed osrm-prepare to osrm-contract
|
||||
- BREAKING: Removes profiles from osrm-contract, only needed in osrm-extract.
|
||||
- Abort processing in osrm-extract if there are no snappable edges remaining.
|
||||
- Added .properties file to osrm-extract ouput.
|
||||
- Enables the use of multiple segment-speed-files on the osrm-contract command line
|
||||
|
||||
- Profile changes:
|
||||
- Remove movable bridge mode
|
||||
- Add `maxspeed=none` tag to car profile.
|
||||
- A `side_road` tag support for the OSRM car profile.
|
||||
|
||||
- Fixes:
|
||||
- Issue #2150: Prevents routing over delivery ways and nodes
|
||||
- Issue #1972: Provide uninstall target
|
||||
- Issue #2072: Disable alternatives by default and if core factor < 1.0
|
||||
- Issue #1999: Fix unpacking for self-loop nodes not in core.
|
||||
|
||||
- Infrastructure:
|
||||
- Cucumber test suit is now based on cucumber-js, removes Ruby as dependency
|
||||
- Updated to mapbox/variant v1.1
|
||||
- Updated to libosmium v2.6.1
|
||||
- Remove GeoJSON based debugging output, replaced by debug tiles
|
||||
|
||||
|
||||
# 5.0.0 RC2
|
||||
- Profiles:
|
||||
- `properties.allow_uturns_at_via` -> `properties.continue_straight_at_waypoint` (value is inverted!)
|
||||
- API:
|
||||
- Removed summary from legs property
|
||||
- Disable steps and alternatives by default
|
||||
- Fix `code` field: 'ok' -> 'Ok'
|
||||
- Allow 4.json and 4.3.json format
|
||||
- Conform to v5 spec and support "unlimited" as radiuses value.
|
||||
- `uturns` parameter was replaced by `continue_straight` (value is inverted!)
|
||||
- Features:
|
||||
- Report progress for gennerating edge expanded edges in the edge based graph factory
|
||||
- Add maxspeed=none tag to car profile.
|
||||
- Optimize StaticRTree code: speedup 2x (to RC1)
|
||||
- Optimize DouglasPeucker code: speedup 10x (to RC1)
|
||||
- Optimize WebMercator projection: speedup 2x (to RC1)
|
||||
- Bugs:
|
||||
- #2195: Resolves issues with multiple includedirs in pkg-config file
|
||||
- #2219: Internal server error when using the match plugin
|
||||
- #2027: basename -> filename
|
||||
- #2168: Report correct position where parsing failed
|
||||
- #2036: Add license to storage and storage config exposed in public API
|
||||
- Fix uturn detection in match plugin
|
||||
- Add missing -lz to fix linking of server-tests
|
||||
|
||||
# 5.0.0 RC1
|
||||
- Renamed osrm-prepare into osrm-contract
|
||||
- osrm-contract does not need a profile parameter anymore
|
||||
- New public HTTP API, find documentation [here](https://github.com/Project-OSRM/osrm-backend/wiki/New-Server-api)
|
||||
- POST support is discontinued, please use library bindings for more complex requests
|
||||
- Removed timestamp plugin
|
||||
- Coordinate order is now Longitude,Latitude
|
||||
- Cucumber tests now based on Javascript (run with `npm test`)
|
||||
- Profile API changed:
|
||||
- `forward_mode` and `backward_mode` now need to be selected from a pre-defined list
|
||||
- Global profile properties are now stored in a global `properties` element. This includes:
|
||||
- `properties.traffic_signal_penalty`
|
||||
- `properties.use_turn_restrictions`
|
||||
- `properties.u_turn_penalty`
|
||||
- `properties.allow_u_turn_at_via`
|
||||
|
||||
|
||||
+309
-198
@@ -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 5)
|
||||
set(OSRM_VERSION_MINOR 1)
|
||||
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,82 +25,60 @@ else()
|
||||
message(WARNING "Building on a 32 bit system is unsupported")
|
||||
endif()
|
||||
|
||||
if (WIN32 AND MSVC_VERSION LESS 1800)
|
||||
message(FATAL_ERROR "Building with Microsoft compiler needs Visual Studio 2013 or later (Express version works too)")
|
||||
if(WIN32 AND MSVC_VERSION LESS 1900)
|
||||
message(FATAL_ERROR "Building with Microsoft compiler needs Latest Visual Studio 2015 (Community or better)")
|
||||
endif()
|
||||
|
||||
OPTION(WITH_TOOLS "Build OSRM tools" OFF)
|
||||
OPTION(BUILD_TOOLS "Build OSRM tools" OFF)
|
||||
option(ENABLE_CCACHE "Speed up incremental rebuilds via ccache" ON)
|
||||
option(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF)
|
||||
option(BUILD_TOOLS "Build OSRM tools" OFF)
|
||||
option(BUILD_COMPONENTS "Build osrm-components" ON)
|
||||
option(ENABLE_ASSERTIONS OFF)
|
||||
option(COVERAGE OFF)
|
||||
option(SANITIZER OFF)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}/Include/)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/third_party/)
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
||||
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/Util/finger_print.cpp finger_print.cpp.alwaysbuild
|
||||
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_SOURCE_DIR}
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FingerPrint-Config.cmake
|
||||
DEPENDS
|
||||
${CMAKE_SOURCE_DIR}/Util/finger_print.cpp.in
|
||||
COMMENT "Configuring finger_print.cpp"
|
||||
add_custom_target(FingerPrintConfigure ALL ${CMAKE_COMMAND}
|
||||
"-DOUTPUT_DIR=${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"-DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/FingerPrint-Config.cmake"
|
||||
COMMENT "Configuring revision fingerprint"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(FingerPrintConfigure DEPENDS ${CMAKE_SOURCE_DIR}/Util/finger_print.cpp)
|
||||
add_custom_target(tests DEPENDS datastructure-tests algorithm-tests)
|
||||
add_custom_target(benchmarks DEPENDS rtree-bench)
|
||||
|
||||
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread unit_test_framework)
|
||||
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp.in
|
||||
${CMAKE_SOURCE_DIR}/Util/GitDescription.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/util/version.hpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/util/version.hpp
|
||||
)
|
||||
file(GLOB ExtractorGlob extractor/*.cpp)
|
||||
file(GLOB ImporterGlob data_structures/import_edge.cpp data_structures/external_memory_node.cpp)
|
||||
add_library(IMPORT OBJECT ${ImporterGlob})
|
||||
add_library(LOGGER OBJECT Util/simple_logger.cpp)
|
||||
add_library(PHANTOMNODE OBJECT data_structures/phantom_node.cpp)
|
||||
file(GLOB UtilGlob src/util/*.cpp)
|
||||
file(GLOB ExtractorGlob src/extractor/*.cpp src/extractor/*/*.cpp)
|
||||
file(GLOB ContractorGlob src/contractor/*.cpp)
|
||||
file(GLOB StorageGlob src/storage/*.cpp)
|
||||
file(GLOB ServerGlob src/server/*.cpp src/server/**/*.cpp)
|
||||
file(GLOB EngineGlob src/engine/*.cpp src/engine/**/*.cpp)
|
||||
|
||||
set(ExtractorSources extract.cpp ${ExtractorGlob})
|
||||
add_executable(osrm-extract ${ExtractorSources} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER>)
|
||||
add_library(UTIL OBJECT ${UtilGlob})
|
||||
add_library(EXTRACTOR OBJECT ${ExtractorGlob})
|
||||
add_library(CONTRACTOR OBJECT ${ContractorGlob})
|
||||
add_library(STORAGE OBJECT ${StorageGlob})
|
||||
add_library(ENGINE OBJECT ${EngineGlob})
|
||||
add_library(SERVER OBJECT ${ServerGlob})
|
||||
|
||||
file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp data_structures/restriction_map.cpp Util/compute_angle.cpp)
|
||||
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_dependencies(UTIL FingerPrintConfigure)
|
||||
set_target_properties(UTIL PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
||||
file(GLOB ServerGlob Server/*.cpp)
|
||||
file(GLOB DescriptorGlob descriptors/*.cpp)
|
||||
file(GLOB DatastructureGlob data_structures/search_engine_data.cpp data_structures/route_parameters.cpp Util/bearing.cpp)
|
||||
list(REMOVE_ITEM DatastructureGlob data_structures/Coordinate.cpp)
|
||||
file(GLOB CoordinateGlob data_structures/Coordinate.cpp)
|
||||
file(GLOB AlgorithmGlob algorithms/*.cpp)
|
||||
file(GLOB HttpGlob Server/Http/*.cpp)
|
||||
file(GLOB LibOSRMGlob Library/*.cpp)
|
||||
file(GLOB DataStructureTestsGlob UnitTests/data_structures/*.cpp data_structures/hilbert_value.cpp)
|
||||
file(GLOB AlgorithmTestsGlob UnitTests/Algorithms/*.cpp)
|
||||
|
||||
set(
|
||||
OSRMSources
|
||||
${LibOSRMGlob}
|
||||
${DescriptorGlob}
|
||||
${DatastructureGlob}
|
||||
${CoordinateGlob}
|
||||
${AlgorithmGlob}
|
||||
${HttpGlob}
|
||||
)
|
||||
add_library(COORDINATE OBJECT ${CoordinateGlob})
|
||||
add_library(FINGERPRINT OBJECT Util/finger_print.cpp)
|
||||
add_library(GITDESCRIPTION OBJECT Util/GitDescription.cpp)
|
||||
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE>)
|
||||
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>)
|
||||
|
||||
# Unit tests
|
||||
add_executable(datastructure-tests EXCLUDE_FROM_ALL UnitTests/datastructure_tests.cpp ${DataStructureTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE>)
|
||||
add_executable(algorithm-tests EXCLUDE_FROM_ALL UnitTests/algorithm_tests.cpp ${AlgorithmTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE>)
|
||||
|
||||
# Benchmarks
|
||||
add_executable(rtree-bench EXCLUDE_FROM_ALL benchmarks/static_rtree.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE>)
|
||||
add_executable(osrm-extract src/tools/extract.cpp)
|
||||
add_executable(osrm-contract src/tools/contract.cpp)
|
||||
add_executable(osrm-routed src/tools/routed.cpp $<TARGET_OBJECTS:SERVER> $<TARGET_OBJECTS:UTIL>)
|
||||
add_executable(osrm-datastore src/tools/store.cpp $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm src/osrm/osrm.cpp $<TARGET_OBJECTS:ENGINE> $<TARGET_OBJECTS:UTIL> $<TARGET_OBJECTS:STORAGE>)
|
||||
add_library(osrm_extract $<TARGET_OBJECTS:EXTRACTOR> $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm_contract $<TARGET_OBJECTS:CONTRACTOR> $<TARGET_OBJECTS:UTIL>)
|
||||
add_library(osrm_store $<TARGET_OBJECTS:STORAGE> $<TARGET_OBJECTS:UTIL>)
|
||||
|
||||
# Check the release mode
|
||||
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
@@ -106,64 +86,125 @@ 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")
|
||||
set(ENABLE_ASSERTIONS ON)
|
||||
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)
|
||||
set(MAYBE_COVERAGE_LIBRARIES "")
|
||||
if (COVERAGE)
|
||||
if (NOT CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
message(ERROR "COVERAGE=ON only make sense with a Debug build")
|
||||
endif()
|
||||
message(INFO "Enabling coverage")
|
||||
set(MAYBE_COVERAGE_LIBRARIES "gcov")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs")
|
||||
endif()
|
||||
if (SANITIZER)
|
||||
if (NOT CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
message(ERROR "SANITIZER=ON only make sense with a Debug build")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
||||
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")
|
||||
# using GCC
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -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)
|
||||
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 -fcolor-diagnostics")
|
||||
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()
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
|
||||
# using GCC
|
||||
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(-DWIN32)
|
||||
set(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
|
||||
endif()
|
||||
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(-DBOOST_LIB_DIAGNOSTIC)
|
||||
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_USE_MATH_DEFINES) #needed for M_PI with cmath.h
|
||||
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
|
||||
@@ -182,165 +223,235 @@ if(APPLE)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(osrm-prepare rt)
|
||||
target_link_libraries(osrm-datastore rt)
|
||||
target_link_libraries(OSRM rt)
|
||||
set(MAYBE_RT_LIBRARY rt)
|
||||
endif()
|
||||
|
||||
#Check Boost
|
||||
set(BOOST_MIN_VERSION "1.49.0")
|
||||
find_package(Boost ${BOOST_MIN_VERSION} 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})
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/cmake")
|
||||
set(OSMIUM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include")
|
||||
find_package(Osmium REQUIRED COMPONENTS io)
|
||||
include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS})
|
||||
|
||||
target_link_libraries(OSRM ${Boost_LIBRARIES})
|
||||
target_link_libraries(osrm-extract ${Boost_LIBRARIES})
|
||||
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(rtree-bench ${Boost_LIBRARIES})
|
||||
|
||||
find_package(Boost 1.49.0 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
if(NOT WIN32)
|
||||
add_definitions(-DBOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
add_definitions(-DBOOST_SPIRIT_USE_PHOENIX_V3)
|
||||
add_definitions(-DBOOST_RESULT_OF_USE_DECLTYPE)
|
||||
add_definitions(-DBOOST_FILESYSTEM_NO_DEPRECATED)
|
||||
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
|
||||
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)
|
||||
include_directories(SYSTEM ${TBB_INCLUDE_DIR})
|
||||
if(WIN32 AND CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(TBB_LIBRARIES ${TBB_DEBUG_LIBRARIES})
|
||||
endif()
|
||||
target_link_libraries(osrm-datastore ${TBB_LIBRARIES})
|
||||
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})
|
||||
|
||||
find_package( Luabind REQUIRED )
|
||||
find_package(Luabind REQUIRED)
|
||||
include(check_luabind)
|
||||
include_directories(SYSTEM ${LUABIND_INCLUDE_DIR})
|
||||
|
||||
include_directories(${LUABIND_INCLUDE_DIR})
|
||||
target_link_libraries(osrm-extract ${LUABIND_LIBRARY})
|
||||
target_link_libraries(osrm-prepare ${LUABIND_LIBRARY})
|
||||
|
||||
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})
|
||||
set(USED_LUA_LIBRARIES ${LUA_LIBRARY})
|
||||
if(LUAJIT_FOUND)
|
||||
set(USED_LUA_LIBRARIES, LUAJIT_LIBRARIES)
|
||||
endif()
|
||||
include_directories(${LUA_INCLUDE_DIR})
|
||||
include_directories(SYSTEM ${LUA_INCLUDE_DIR})
|
||||
|
||||
find_package(EXPAT REQUIRED)
|
||||
include_directories(${EXPAT_INCLUDE_DIRS})
|
||||
target_link_libraries(osrm-extract ${EXPAT_LIBRARIES})
|
||||
include_directories(SYSTEM ${EXPAT_INCLUDE_DIRS})
|
||||
|
||||
find_package( STXXL REQUIRED )
|
||||
include_directories(${STXXL_INCLUDE_DIR})
|
||||
target_link_libraries(OSRM ${STXXL_LIBRARY})
|
||||
target_link_libraries(osrm-extract ${STXXL_LIBRARY})
|
||||
target_link_libraries(osrm-prepare ${STXXL_LIBRARY})
|
||||
find_package(STXXL REQUIRED)
|
||||
include_directories(SYSTEM ${STXXL_INCLUDE_DIR})
|
||||
|
||||
if(MINGW)
|
||||
# STXXL needs OpenMP library
|
||||
target_link_libraries(osrm-extract gomp)
|
||||
set(OpenMP_FIND_QUIETLY ON)
|
||||
find_package(OpenMP)
|
||||
if(OPENMP_FOUND)
|
||||
message(STATUS "OpenMP support found. Linking just in case for stxxl")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
find_package( OSMPBF REQUIRED )
|
||||
include_directories(${OSMPBF_INCLUDE_DIR})
|
||||
target_link_libraries(osrm-extract ${OSMPBF_LIBRARY})
|
||||
target_link_libraries(osrm-prepare ${OSMPBF_LIBRARY})
|
||||
|
||||
find_package(Protobuf REQUIRED)
|
||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||
target_link_libraries(osrm-extract ${PROTOBUF_LIBRARY})
|
||||
target_link_libraries(osrm-prepare ${PROTOBUF_LIBRARY})
|
||||
|
||||
find_package(BZip2 REQUIRED)
|
||||
include_directories(${BZIP_INCLUDE_DIRS})
|
||||
target_link_libraries(osrm-extract ${BZIP2_LIBRARIES})
|
||||
include_directories(SYSTEM ${BZIP_INCLUDE_DIRS})
|
||||
|
||||
find_package(ZLIB REQUIRED)
|
||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
target_link_libraries(osrm-extract ${ZLIB_LIBRARY})
|
||||
target_link_libraries(osrm-routed ${ZLIB_LIBRARY})
|
||||
include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
if(WITH_TOOLS OR BUILD_TOOLS)
|
||||
message(STATUS "Activating OSRM internal tools")
|
||||
if (ENABLE_JSON_LOGGING)
|
||||
message(STATUS "Enabling json logging")
|
||||
add_definitions(-DENABLE_JSON_LOGGING)
|
||||
endif()
|
||||
|
||||
# Binaries
|
||||
target_link_libraries(osrm-datastore osrm_store ${Boost_LIBRARIES})
|
||||
target_link_libraries(osrm-extract osrm_extract ${Boost_LIBRARIES})
|
||||
target_link_libraries(osrm-contract osrm_contract ${Boost_LIBRARIES})
|
||||
target_link_libraries(osrm-routed osrm ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} ${ZLIB_LIBRARY})
|
||||
|
||||
set(EXTRACTOR_LIBRARIES
|
||||
${BZIP2_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${EXPAT_LIBRARIES}
|
||||
${LUABIND_LIBRARY}
|
||||
${USED_LUA_LIBRARIES}
|
||||
${OSMIUM_LIBRARIES}
|
||||
${STXXL_LIBRARY}
|
||||
${TBB_LIBRARIES}
|
||||
${ZLIB_LIBRARY}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
set(CONTRACTOR_LIBRARIES
|
||||
${Boost_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${LUABIND_LIBRARY}
|
||||
${USED_LUA_LIBRARIES}
|
||||
${STXXL_LIBRARY}
|
||||
${TBB_LIBRARIES}
|
||||
${MAYBE_RT_LIBRARY}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
set(ENGINE_LIBRARIES
|
||||
${Boost_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${STXXL_LIBRARY}
|
||||
${TBB_LIBRARIES}
|
||||
${MAYBE_RT_LIBRARY}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
set(STORAGE_LIBRARIES
|
||||
${Boost_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${TBB_LIBRARIES}
|
||||
${MAYBE_RT_LIBRARY}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
set(UTIL_LIBRARIES
|
||||
${Boost_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${STXXL_LIBRARY}
|
||||
${TBB_LIBRARIES}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
# Libraries
|
||||
target_link_libraries(osrm ${ENGINE_LIBRARIES})
|
||||
target_link_libraries(osrm_contract ${CONTRACTOR_LIBRARIES})
|
||||
target_link_libraries(osrm_extract ${EXTRACTOR_LIBRARIES})
|
||||
target_link_libraries(osrm_store ${STORAGE_LIBRARIES})
|
||||
|
||||
if(BUILD_COMPONENTS)
|
||||
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 src/tools/components.cpp $<TARGET_OBJECTS:UTIL>)
|
||||
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")
|
||||
message(WARNING "libgdal and/or development headers not found")
|
||||
endif()
|
||||
add_executable(osrm-cli tools/simpleclient.cpp $<TARGET_OBJECTS:LOGGER>)
|
||||
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>)
|
||||
endif()
|
||||
|
||||
if(BUILD_TOOLS)
|
||||
message(STATUS "Activating OSRM internal tools")
|
||||
add_executable(osrm-io-benchmark src/tools/io-benchmark.cpp $<TARGET_OBJECTS:UTIL>)
|
||||
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 src/tools/unlock_all_mutexes.cpp $<TARGET_OBJECTS:UTIL>)
|
||||
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-springclean src/tools/springclean.cpp $<TARGET_OBJECTS:UTIL>)
|
||||
target_link_libraries(osrm-springclean ${Boost_LIBRARIES})
|
||||
|
||||
install(TARGETS osrm-cli DESTINATION bin)
|
||||
install(TARGETS osrm-io-benchmark DESTINATION bin)
|
||||
install(TARGETS osrm-unlock-all DESTINATION bin)
|
||||
install(TARGETS osrm-check-hsgr DESTINATION bin)
|
||||
install(TARGETS osrm-springclean DESTINATION bin)
|
||||
endif()
|
||||
|
||||
file(GLOB InstallGlob Include/osrm/*.h Library/OSRM.h)
|
||||
if (ENABLE_ASSERTIONS)
|
||||
message(STATUS "Enabling assertions")
|
||||
add_definitions(-DBOOST_ENABLE_ASSERT_HANDLER)
|
||||
endif()
|
||||
|
||||
# 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
|
||||
# more info see http://www.cmake.org/Wiki/CMake_RPATH_handling
|
||||
set_property(TARGET osrm-extract PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
set_property(TARGET osrm-prepare PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
set_property(TARGET osrm-contract PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
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)
|
||||
file(GLOB VariantGlob third_party/variant/*.hpp)
|
||||
file(GLOB LibraryGlob include/osrm/*.hpp)
|
||||
file(GLOB ParametersGlob include/engine/api/*_parameters.hpp)
|
||||
set(EngineHeader include/engine/status.hpp include/engine/engine_config.hpp include/engine/hint.hpp include/engine/bearing.hpp include/engine/phantom_node.hpp)
|
||||
set(UtilHeader include/util/coordinate.hpp include/util/json_container.hpp include/util/typedefs.hpp include/util/strong_typedef.hpp)
|
||||
set(ExtractorHeader include/extractor/extractor.hpp include/extractor/extractor_config.hpp include/extractor/travel_mode.hpp)
|
||||
set(ContractorHeader include/contractor/contractor.hpp include/contractor/contractor_config.hpp)
|
||||
set(StorageHeader include/storage/storage.hpp include/storage/storage_config.hpp)
|
||||
install(FILES ${EngineHeader} DESTINATION include/osrm/engine)
|
||||
install(FILES ${UtilHeader} DESTINATION include/osrm/util)
|
||||
install(FILES ${StorageHeader} DESTINATION include/osrm/storage)
|
||||
install(FILES ${ExtractorHeader} DESTINATION include/osrm/extractor)
|
||||
install(FILES ${ContractorHeader} DESTINATION include/osrm/contractor)
|
||||
install(FILES ${LibraryGlob} DESTINATION include/osrm)
|
||||
install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api)
|
||||
install(FILES ${VariantGlob} DESTINATION include/variant)
|
||||
install(TARGETS osrm-extract DESTINATION bin)
|
||||
install(TARGETS osrm-prepare DESTINATION bin)
|
||||
install(TARGETS osrm-contract 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})
|
||||
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 ()
|
||||
install(TARGETS osrm DESTINATION lib)
|
||||
install(TARGETS osrm_extract DESTINATION lib)
|
||||
install(TARGETS osrm_contract DESTINATION lib)
|
||||
install(TARGETS osrm_store DESTINATION lib)
|
||||
|
||||
configure_file(${CMAKE_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
|
||||
list(GET ENGINE_LIBRARIES 1 ENGINE_LIBRARY_FIRST)
|
||||
foreach(lib ${ENGINE_LIBRARIES})
|
||||
get_filename_component(ENGINE_LIBRARY_PATH "${ENGINE_LIBRARY_FIRST}" PATH)
|
||||
get_filename_component(ENGINE_LIBRARY_NAME "${lib}" NAME_WE)
|
||||
string(REPLACE "lib" "" ENGINE_LIBRARY_NAME ${ENGINE_LIBRARY_NAME})
|
||||
string(REPLACE "-l" "" ENGINE_LIBRARY_NAME ${ENGINE_LIBRARY_NAME})
|
||||
set(ENGINE_LIBRARY_LISTING "${ENGINE_LIBRARY_LISTING} -L${ENGINE_LIBRARY_PATH} -l${ENGINE_LIBRARY_NAME}")
|
||||
endforeach()
|
||||
|
||||
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(ENABLE_CCACHE AND (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU"))
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND)
|
||||
message(STATUS "Using ccache to speed up incremental builds")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
|
||||
set(ENV{CCACHE_CPP2} "true")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# uninstall target
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake)
|
||||
|
||||
|
||||
# Modular build system: each directory registered here provides its own CMakeLists.txt
|
||||
add_subdirectory(unit_tests)
|
||||
add_subdirectory(src/benchmarks)
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
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@/node_modules \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/unit_tests \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/benchmarks \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/features
|
||||
|
||||
SOURCE_BROWSER = YES
|
||||
|
||||
CLANG_ASSISTED_PARSING = NO
|
||||
|
||||
HTML_COLORSTYLE_HUE = 217
|
||||
HTML_COLORSTYLE_SAT = 71
|
||||
HTML_COLORSTYLE_GAMMA = 50
|
||||
|
||||
GENERATE_TREEVIEW = YES
|
||||
|
||||
HAVE_DOT = @DOXYGEN_DOT_FOUND@
|
||||
CALL_GRAPH = YES
|
||||
CALLER_GRAPH = YES
|
||||
|
||||
DOT_IMAGE_FORMAT = svg
|
||||
INTERACTIVE_SVG = YES
|
||||
DOT_GRAPH_MAX_NODES = 500
|
||||
DOT_TRANSPARENT = YES
|
||||
DOT_MULTI_TARGETS = YES
|
||||
@@ -1,7 +0,0 @@
|
||||
source "http://rubygems.org"
|
||||
|
||||
gem "cucumber"
|
||||
gem "rake"
|
||||
gem "osmlib-base"
|
||||
gem "sys-proctable"
|
||||
gem "rspec-expectations"
|
||||
@@ -1,30 +0,0 @@
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
builder (3.2.2)
|
||||
cucumber (1.3.8)
|
||||
builder (>= 2.1.2)
|
||||
diff-lcs (>= 1.1.3)
|
||||
gherkin (~> 2.12.1)
|
||||
multi_json (>= 1.7.5, < 2.0)
|
||||
multi_test (>= 0.0.2)
|
||||
diff-lcs (1.2.4)
|
||||
gherkin (2.12.1)
|
||||
multi_json (~> 1.3)
|
||||
multi_json (1.8.0)
|
||||
multi_test (0.0.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)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cucumber
|
||||
osmlib-base
|
||||
rake
|
||||
rspec-expectations
|
||||
sys-proctable
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef FIXED_POINT_COORDINATE_H_
|
||||
#define FIXED_POINT_COORDINATE_H_
|
||||
|
||||
#include <iosfwd> //for std::ostream
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr float COORDINATE_PRECISION = 1000000.f;
|
||||
}
|
||||
struct FixedPointCoordinate
|
||||
{
|
||||
int lat;
|
||||
int lon;
|
||||
|
||||
FixedPointCoordinate();
|
||||
FixedPointCoordinate(int lat, int lon);
|
||||
|
||||
template<class T>
|
||||
FixedPointCoordinate(const T &coordinate) : lat(coordinate.lat), lon(coordinate.lon)
|
||||
{
|
||||
static_assert(std::is_same<decltype(lat), decltype(coordinate.lat)>::value, "coordinate types incompatible");
|
||||
static_assert(std::is_same<decltype(lon), decltype(coordinate.lon)>::value, "coordinate types incompatible");
|
||||
}
|
||||
|
||||
void Reset();
|
||||
bool isSet() const;
|
||||
bool is_valid() const;
|
||||
bool operator==(const FixedPointCoordinate &other) const;
|
||||
|
||||
static double
|
||||
ApproximateDistance(const int lat1, const int lon1, const int lat2, const int lon2);
|
||||
|
||||
static double ApproximateDistance(const FixedPointCoordinate &first_coordinate,
|
||||
const FixedPointCoordinate &second_coordinate);
|
||||
|
||||
static float ApproximateEuclideanDistance(const FixedPointCoordinate &first_coordinate,
|
||||
const FixedPointCoordinate &second_coordinate);
|
||||
|
||||
static float
|
||||
ApproximateEuclideanDistance(const int lat1, const int lon1, const int lat2, const int lon2);
|
||||
|
||||
static float ApproximateSquaredEuclideanDistance(const FixedPointCoordinate &first_coordinate,
|
||||
const FixedPointCoordinate &second_coordinate);
|
||||
|
||||
static void convertInternalLatLonToString(const int value, std::string &output);
|
||||
|
||||
static void convertInternalCoordinateToString(const FixedPointCoordinate &coordinate,
|
||||
std::string &output);
|
||||
|
||||
static void convertInternalReversedCoordinateToString(const FixedPointCoordinate &coordinate,
|
||||
std::string &output);
|
||||
|
||||
static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
|
||||
const FixedPointCoordinate &segment_target,
|
||||
const FixedPointCoordinate &query_location);
|
||||
|
||||
static float ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
|
||||
const FixedPointCoordinate &segment_target,
|
||||
const FixedPointCoordinate &query_location,
|
||||
FixedPointCoordinate &nearest_location,
|
||||
float &ratio);
|
||||
|
||||
static int
|
||||
OrderedPerpendicularDistanceApproximation(const FixedPointCoordinate &segment_source,
|
||||
const FixedPointCoordinate &segment_target,
|
||||
const FixedPointCoordinate &query_location);
|
||||
|
||||
static float GetBearing(const FixedPointCoordinate &A, const FixedPointCoordinate &B);
|
||||
|
||||
float GetBearing(const FixedPointCoordinate &other) const;
|
||||
|
||||
void Output(std::ostream &out) const;
|
||||
|
||||
static float DegreeToRadian(const float degree);
|
||||
static float RadianToDegree(const float radian);
|
||||
};
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &out_stream, FixedPointCoordinate const &coordinate)
|
||||
{
|
||||
coordinate.Output(out_stream);
|
||||
return out_stream;
|
||||
}
|
||||
|
||||
#endif /* FIXED_POINT_COORDINATE_H_ */
|
||||
@@ -1,53 +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 HTTP_HEADER_H
|
||||
#define HTTP_HEADER_H
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
namespace http
|
||||
{
|
||||
struct Header
|
||||
{
|
||||
Header& operator=(const Header& other) = default;
|
||||
Header(const std::string & name, const std::string & value) : name(name), value(value) {}
|
||||
Header(Header && other) : name(std::move(other.name)), value(std::move(other.value)) {}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
name.clear();
|
||||
value.clear();
|
||||
}
|
||||
|
||||
std::string name;
|
||||
std::string value;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // HTTP_HEADER_H
|
||||
@@ -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,92 +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 ROUTE_PARAMETERS_H
|
||||
#define ROUTE_PARAMETERS_H
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
|
||||
#include <boost/fusion/container/vector/vector_fwd.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct RouteParameters
|
||||
{
|
||||
RouteParameters();
|
||||
|
||||
void setZoomLevel(const short level);
|
||||
|
||||
void setNumberOfResults(const short number);
|
||||
|
||||
void setAlternateRouteFlag(const bool flag);
|
||||
|
||||
void setUTurn(const bool flag);
|
||||
|
||||
void setAllUTurns(const bool flag);
|
||||
|
||||
void setDeprecatedAPIFlag(const std::string &);
|
||||
|
||||
void setChecksum(const unsigned check_sum);
|
||||
|
||||
void setInstructionFlag(const bool flag);
|
||||
|
||||
void setService(const std::string &service);
|
||||
|
||||
void setOutputFormat(const std::string &format);
|
||||
|
||||
void setJSONpParameter(const std::string ¶meter);
|
||||
|
||||
void addHint(const std::string &hint);
|
||||
|
||||
void setLanguage(const std::string &language);
|
||||
|
||||
void setGeometryFlag(const bool flag);
|
||||
|
||||
void setCompressionFlag(const bool flag);
|
||||
|
||||
void addCoordinate(const boost::fusion::vector<double, double> &coordinates);
|
||||
|
||||
short zoom_level;
|
||||
bool print_instructions;
|
||||
bool alternate_route;
|
||||
bool geometry;
|
||||
bool compression;
|
||||
bool deprecatedAPI;
|
||||
bool uturn_default;
|
||||
unsigned check_sum;
|
||||
short num_results;
|
||||
std::string service;
|
||||
std::string output_format;
|
||||
std::string jsonp_parameter;
|
||||
std::string language;
|
||||
std::vector<std::string> hints;
|
||||
std::vector<bool> uturns;
|
||||
std::vector<FixedPointCoordinate> coordinates;
|
||||
};
|
||||
|
||||
#endif // ROUTE_PARAMETERS_H
|
||||
@@ -1,38 +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 SERVER_PATH_H
|
||||
#define SERVER_PATH_H
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
typedef std::unordered_map<std::string, boost::filesystem::path> ServerPaths;
|
||||
|
||||
#endif // SERVER_PATH_H
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
|
||||
Copyright (c) 2016, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
namespace boost { namespace interprocess { class named_mutex; } }
|
||||
|
||||
#include "OSRM_impl.h"
|
||||
#include "OSRM.h"
|
||||
|
||||
#include <osrm/Reply.h>
|
||||
#include <osrm/RouteParameters.h>
|
||||
#include <osrm/ServerPaths.h>
|
||||
|
||||
#include "../plugins/distance_table.hpp"
|
||||
#include "../plugins/hello_world.hpp"
|
||||
#include "../plugins/locate.hpp"
|
||||
#include "../plugins/nearest.hpp"
|
||||
#include "../plugins/timestamp.hpp"
|
||||
#include "../plugins/viaroute.hpp"
|
||||
#include "../Server/DataStructures/BaseDataFacade.h"
|
||||
#include "../Server/DataStructures/InternalDataFacade.h"
|
||||
#include "../Server/DataStructures/SharedBarriers.h"
|
||||
#include "../Server/DataStructures/SharedDataFacade.h"
|
||||
#include "../Util/make_unique.hpp"
|
||||
#include "../Util/ProgramOptions.h"
|
||||
#include "../Util/simple_logger.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/interprocess/sync/named_condition.hpp>
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
OSRM_impl::OSRM_impl(ServerPaths server_paths, const bool use_shared_memory)
|
||||
{
|
||||
if (use_shared_memory)
|
||||
{
|
||||
barrier = osrm::make_unique<SharedBarriers>();
|
||||
query_data_facade = new SharedDataFacade<QueryEdge::EdgeData>();
|
||||
}
|
||||
else
|
||||
{
|
||||
// populate base path
|
||||
populate_base_path(server_paths);
|
||||
query_data_facade = new InternalDataFacade<QueryEdge::EdgeData>(server_paths);
|
||||
}
|
||||
|
||||
// The following plugins handle all requests.
|
||||
RegisterPlugin(new DistanceTablePlugin<BaseDataFacade<QueryEdge::EdgeData>>(query_data_facade));
|
||||
RegisterPlugin(new HelloWorldPlugin());
|
||||
RegisterPlugin(new LocatePlugin<BaseDataFacade<QueryEdge::EdgeData>>(query_data_facade));
|
||||
RegisterPlugin(new NearestPlugin<BaseDataFacade<QueryEdge::EdgeData>>(query_data_facade));
|
||||
RegisterPlugin(new TimestampPlugin<BaseDataFacade<QueryEdge::EdgeData>>(query_data_facade));
|
||||
RegisterPlugin(new ViaRoutePlugin<BaseDataFacade<QueryEdge::EdgeData>>(query_data_facade));
|
||||
}
|
||||
|
||||
OSRM_impl::~OSRM_impl()
|
||||
{
|
||||
delete query_data_facade;
|
||||
for (PluginMap::value_type &plugin_pointer : plugin_map)
|
||||
{
|
||||
delete plugin_pointer.second;
|
||||
}
|
||||
}
|
||||
|
||||
void OSRM_impl::RegisterPlugin(BasePlugin *plugin)
|
||||
{
|
||||
SimpleLogger().Write() << "loaded plugin: " << plugin->GetDescriptor();
|
||||
if (plugin_map.find(plugin->GetDescriptor()) != plugin_map.end())
|
||||
{
|
||||
delete plugin_map.find(plugin->GetDescriptor())->second;
|
||||
}
|
||||
plugin_map.emplace(plugin->GetDescriptor(), plugin);
|
||||
}
|
||||
|
||||
void OSRM_impl::RunQuery(RouteParameters &route_parameters, http::Reply &reply)
|
||||
{
|
||||
const PluginMap::const_iterator &iter = plugin_map.find(route_parameters.service);
|
||||
|
||||
if (plugin_map.end() != iter)
|
||||
{
|
||||
reply.status = http::Reply::ok;
|
||||
if (barrier)
|
||||
{
|
||||
// lock update pending
|
||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> pending_lock(
|
||||
barrier->pending_update_mutex);
|
||||
|
||||
// lock query
|
||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> query_lock(
|
||||
barrier->query_mutex);
|
||||
|
||||
// unlock update pending
|
||||
pending_lock.unlock();
|
||||
|
||||
// increment query count
|
||||
++(barrier->number_of_queries);
|
||||
|
||||
(static_cast<SharedDataFacade<QueryEdge::EdgeData> *>(query_data_facade))
|
||||
->CheckAndReloadFacade();
|
||||
}
|
||||
|
||||
iter->second->HandleRequest(route_parameters, reply);
|
||||
if (barrier)
|
||||
{
|
||||
// lock query
|
||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> query_lock(
|
||||
barrier->query_mutex);
|
||||
|
||||
// decrement query count
|
||||
--(barrier->number_of_queries);
|
||||
BOOST_ASSERT_MSG(0 <= barrier->number_of_queries, "invalid number of queries");
|
||||
|
||||
// notify all processes that were waiting for this condition
|
||||
if (0 == barrier->number_of_queries)
|
||||
{
|
||||
barrier->no_running_queries_condition.notify_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reply = http::Reply::StockReply(http::Reply::badRequest);
|
||||
}
|
||||
}
|
||||
|
||||
// proxy code for compilation firewall
|
||||
|
||||
OSRM::OSRM(ServerPaths paths, const bool use_shared_memory)
|
||||
: OSRM_pimpl_(osrm::make_unique<OSRM_impl>(paths, use_shared_memory))
|
||||
{
|
||||
}
|
||||
|
||||
OSRM::~OSRM() { OSRM_pimpl_.reset(); }
|
||||
|
||||
void OSRM::RunQuery(RouteParameters &route_parameters, http::Reply &reply)
|
||||
{
|
||||
OSRM_pimpl_->RunQuery(route_parameters, reply);
|
||||
}
|
||||
@@ -1,66 +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 OSRM_IMPL_H
|
||||
#define OSRM_IMPL_H
|
||||
|
||||
class BasePlugin;
|
||||
namespace http { class Reply; }
|
||||
struct RouteParameters;
|
||||
|
||||
#include <osrm/ServerPaths.h>
|
||||
|
||||
#include "../data_structures/query_edge.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
struct SharedBarriers;
|
||||
template <class EdgeDataT> class BaseDataFacade;
|
||||
|
||||
class OSRM_impl
|
||||
{
|
||||
private:
|
||||
using PluginMap = std::unordered_map<std::string, BasePlugin *>;
|
||||
|
||||
public:
|
||||
OSRM_impl(ServerPaths paths, const bool use_shared_memory);
|
||||
OSRM_impl(const OSRM_impl &) = delete;
|
||||
virtual ~OSRM_impl();
|
||||
void RunQuery(RouteParameters &route_parameters, http::Reply &reply);
|
||||
|
||||
private:
|
||||
void RegisterPlugin(BasePlugin *plugin);
|
||||
PluginMap plugin_map;
|
||||
// will only be initialized if shared memory is used
|
||||
std::unique_ptr<SharedBarriers> barrier;
|
||||
// base class pointer to the objects
|
||||
BaseDataFacade<QueryEdge::EdgeData> *query_data_facade;
|
||||
};
|
||||
|
||||
#endif // OSRM_IMPL_H
|
||||
@@ -1,12 +1,63 @@
|
||||
# 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 | status |
|
||||
|:-------------|:-------|
|
||||
| Linux | [](https://travis-ci.org/Project-OSRM/osrm-backend) |
|
||||
| Windows | [](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
|
||||
| Coverage | [](https://coveralls.io/github/Project-OSRM/osrm-backend?branch=master) |
|
||||
|
||||
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
|
||||
|
||||
### Full documentation
|
||||
|
||||
- [osrm-routed HTTP API documentation](docs/http.md)
|
||||
- [libosrm API documentation](docs/libosrm.md)
|
||||
|
||||
### Quick start
|
||||
|
||||
Building OSRM assuming all dependencies are installed:
|
||||
|
||||
```
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build .
|
||||
sudo cmake --build . --target install
|
||||
```
|
||||
|
||||
Loading preparing a dataset and starting the server:
|
||||
|
||||
```
|
||||
osrm-extract data.osm.pbf -p profiles/car.lua
|
||||
osrm-contract data.osrm
|
||||
osrm-routed data.osrm
|
||||
```
|
||||
|
||||
Running a query on your local server:
|
||||
|
||||
```
|
||||
curl http://127.0.0.1:5000/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
|
||||
```
|
||||
|
||||
### Running a request against the Demo Server
|
||||
|
||||
First read the [API usage policy](https://github.com/Project-OSRM/osrm-backend/wiki/Api-usage-policy).
|
||||
|
||||
Then run simple query with instructions and alternatives on Berlin:
|
||||
|
||||
```
|
||||
curl https://router.project-osrm.org/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
|
||||
```
|
||||
|
||||
## References in publications
|
||||
|
||||
@@ -31,11 +82,3 @@ When using the code in a (scientific) publication, please cite
|
||||
}
|
||||
```
|
||||
|
||||
## Current build status
|
||||
|
||||
| build config | branch | status |
|
||||
|:-------------|:--------|:------------|
|
||||
| Linux | master | [](https://travis-ci.org/DennisOSRM/Project-OSRM) |
|
||||
| Linux | develop | [](https://travis-ci.org/DennisOSRM/Project-OSRM) |
|
||||
| Windows | master/develop | [](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
|
||||
| LUAbind fork | master | [](https://travis-ci.org/DennisOSRM/luabind) |
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
require 'OSM/StreamParser'
|
||||
require 'socket'
|
||||
require 'digest/sha1'
|
||||
require 'cucumber/rake/task'
|
||||
require 'sys/proctable'
|
||||
|
||||
BUILD_FOLDER = 'build'
|
||||
DATA_FOLDER = 'sandbox'
|
||||
PROFILE = 'bicycle'
|
||||
OSRM_PORT = 5000
|
||||
PROFILES_FOLDER = '../profiles'
|
||||
|
||||
Cucumber::Rake::Task.new do |t|
|
||||
t.cucumber_opts = %w{--format pretty}
|
||||
end
|
||||
|
||||
areas = {
|
||||
:kbh => { :country => 'denmark', :bbox => 'top=55.6972 left=12.5222 right=12.624 bottom=55.6376' },
|
||||
:frd => { :country => 'denmark', :bbox => 'top=55.7007 left=12.4765 bottom=55.6576 right=12.5698' },
|
||||
:regh => { :country => 'denmark', :bbox => 'top=56.164 left=11.792 bottom=55.403 right=12.731' },
|
||||
:denmark => { :country => 'denmark', :bbox => nil },
|
||||
:skaane => { :country => 'sweden', :bbox => 'top=56.55 left=12.4 bottom=55.3 right=14.6' }
|
||||
}
|
||||
|
||||
|
||||
|
||||
osm_data_area_name = ARGV[1] ? ARGV[1].to_s.to_sym : :kbh
|
||||
raise "Unknown data area." unless areas[osm_data_area_name]
|
||||
osm_data_country = areas[osm_data_area_name][:country]
|
||||
osm_data_area_bbox = areas[osm_data_area_name][:bbox]
|
||||
|
||||
|
||||
task osm_data_area_name.to_sym {} #define empty task to prevent rake from whining. will break if area has same name as a task
|
||||
|
||||
|
||||
def each_process name, &block
|
||||
Sys::ProcTable.ps do |process|
|
||||
if process.comm.strip == name.strip && process.state != 'zombie'
|
||||
yield process.pid.to_i, process.state.strip
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def up?
|
||||
find_pid('osrm-routed') != nil
|
||||
end
|
||||
|
||||
def find_pid name
|
||||
each_process(name) { |pid,state| return pid.to_i }
|
||||
return nil
|
||||
end
|
||||
|
||||
def wait_for_shutdown name
|
||||
timeout = 10
|
||||
(timeout*10).times do
|
||||
return if find_pid(name) == nil
|
||||
sleep 0.1
|
||||
end
|
||||
raise "*** Could not terminate #{name}."
|
||||
end
|
||||
|
||||
|
||||
desc "Rebuild and run tests."
|
||||
task :default => [:build]
|
||||
|
||||
desc "Build using CMake."
|
||||
task :build do
|
||||
if Dir.exists? BUILD_FOLDER
|
||||
Dir.chdir BUILD_FOLDER do
|
||||
system "make"
|
||||
end
|
||||
else
|
||||
system "mkdir build; cd build; cmake ..; make"
|
||||
end
|
||||
end
|
||||
|
||||
desc "Setup config files."
|
||||
task :setup do
|
||||
end
|
||||
|
||||
desc "Download OSM data."
|
||||
task :download do
|
||||
Dir.mkdir "#{DATA_FOLDER}" unless File.exist? "#{DATA_FOLDER}"
|
||||
puts "Downloading..."
|
||||
puts "curl http://download.geofabrik.de/europe/#{osm_data_country}-latest.osm.pbf -o #{DATA_FOLDER}/#{osm_data_country}.osm.pbf"
|
||||
raise "Error while downloading data." unless system "curl http://download.geofabrik.de/europe/#{osm_data_country}-latest.osm.pbf -o #{DATA_FOLDER}/#{osm_data_country}.osm.pbf"
|
||||
if osm_data_area_bbox
|
||||
puts "Cropping and converting to protobuffer..."
|
||||
raise "Error while cropping data." unless system "osmosis --read-pbf file=#{DATA_FOLDER}/#{osm_data_country}.osm.pbf --bounding-box #{osm_data_area_bbox} --write-pbf file=#{DATA_FOLDER}/#{osm_data_area_name}.osm.pbf omitmetadata=true"
|
||||
end
|
||||
end
|
||||
|
||||
desc "Crop OSM data"
|
||||
task :crop do
|
||||
if osm_data_area_bbox
|
||||
raise "Error while cropping data." unless system "osmosis --read-pbf file=#{DATA_FOLDER}/#{osm_data_country}.osm.pbf --bounding-box #{osm_data_area_bbox} --write-pbf file=#{DATA_FOLDER}/#{osm_data_area_name}.osm.pbf omitmetadata=true"
|
||||
end
|
||||
end
|
||||
|
||||
desc "Reprocess OSM data."
|
||||
task :process => [:extract,:prepare] do
|
||||
end
|
||||
|
||||
desc "Extract OSM data."
|
||||
task :extract do
|
||||
Dir.chdir DATA_FOLDER do
|
||||
raise "Error while extracting data." unless system "../#{BUILD_FOLDER}/osrm-extract #{osm_data_area_name}.osm.pbf --profile ../profiles/#{PROFILE}.lua"
|
||||
end
|
||||
end
|
||||
|
||||
desc "Prepare OSM data."
|
||||
task :prepare do
|
||||
Dir.chdir DATA_FOLDER do
|
||||
raise "Error while preparing data." unless system "../#{BUILD_FOLDER}/osrm-prepare #{osm_data_area_name}.osrm --profile ../profiles/#{PROFILE}.lua"
|
||||
end
|
||||
end
|
||||
|
||||
desc "Delete preprocessing files."
|
||||
task :clean do
|
||||
File.delete *Dir.glob("#{DATA_FOLDER}/*.osrm")
|
||||
File.delete *Dir.glob("#{DATA_FOLDER}/*.osrm.*")
|
||||
end
|
||||
|
||||
desc "Run all cucumber test"
|
||||
task :test do
|
||||
system "cucumber"
|
||||
puts
|
||||
end
|
||||
|
||||
desc "Run the routing server in the terminal. Press Ctrl-C to stop."
|
||||
task :run do
|
||||
Dir.chdir DATA_FOLDER do
|
||||
system "../#{BUILD_FOLDER}/osrm-routed #{osm_data_area_name}.osrm --port #{OSRM_PORT}"
|
||||
end
|
||||
end
|
||||
|
||||
desc "Launch the routing server in the background. Use rake:down to stop it."
|
||||
task :up do
|
||||
Dir.chdir DATA_FOLDER do
|
||||
abort("Already up.") if up?
|
||||
pipe = IO.popen("../#{BUILD_FOLDER}/osrm-routed #{osm_data_area_name}.osrm --port #{OSRM_PORT} 1>>osrm-routed.log 2>>osrm-routed.log")
|
||||
timeout = 5
|
||||
(timeout*10).times do
|
||||
begin
|
||||
socket = TCPSocket.new('localhost', OSRM_PORT)
|
||||
socket.puts 'ping'
|
||||
rescue Errno::ECONNREFUSED
|
||||
sleep 0.1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Stop the routing server."
|
||||
task :down do
|
||||
pid = find_pid 'osrm-routed'
|
||||
if pid
|
||||
Process.kill 'TERM', pid
|
||||
else
|
||||
puts "Already down."
|
||||
end
|
||||
end
|
||||
|
||||
desc "Kill all osrm-extract, osrm-prepare and osrm-routed processes."
|
||||
task :kill do
|
||||
each_process('osrm-routed') { |pid,state| Process.kill 'KILL', pid }
|
||||
each_process('osrm-prepare') { |pid,state| Process.kill 'KILL', pid }
|
||||
each_process('osrm-extract') { |pid,state| Process.kill 'KILL', pid }
|
||||
wait_for_shutdown 'osrm-routed'
|
||||
wait_for_shutdown 'osrm-prepare'
|
||||
wait_for_shutdown 'osrm-extract'
|
||||
end
|
||||
|
||||
desc "Get PIDs of all osrm-extract, osrm-prepare and osrm-routed processes."
|
||||
task :pid do
|
||||
each_process 'osrm-routed' do |pid,state|
|
||||
puts "#{pid}\t#{state}"
|
||||
end
|
||||
end
|
||||
|
||||
desc "Stop, reprocess and restart."
|
||||
task :update => [:down,:process,:up] do
|
||||
end
|
||||
|
||||
|
||||
desc "Remove test cache files."
|
||||
task :sweep do
|
||||
system "rm test/cache/*"
|
||||
end
|
||||
|
||||
@@ -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_ */
|
||||
@@ -1,174 +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 "Connection.h"
|
||||
#include "RequestHandler.h"
|
||||
#include "RequestParser.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/iostreams/filtering_stream.hpp>
|
||||
#include <boost/iostreams/filter/gzip.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace http
|
||||
{
|
||||
|
||||
Connection::Connection(boost::asio::io_service &io_service, RequestHandler &handler)
|
||||
: strand(io_service), TCP_socket(io_service), request_handler(handler)
|
||||
{
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::socket &Connection::socket() { return TCP_socket; }
|
||||
|
||||
/// Start the first asynchronous operation for the connection.
|
||||
void Connection::start()
|
||||
{
|
||||
TCP_socket.async_read_some(
|
||||
boost::asio::buffer(incoming_data_buffer),
|
||||
strand.wrap(boost::bind(&Connection::handle_read,
|
||||
this->shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred)));
|
||||
}
|
||||
|
||||
void Connection::handle_read(const boost::system::error_code &error, std::size_t bytes_transferred)
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// no error detected, let's parse the request
|
||||
CompressionType compression_type(noCompression);
|
||||
boost::tribool result;
|
||||
boost::tie(result, boost::tuples::ignore) =
|
||||
RequestParser().Parse(request,
|
||||
incoming_data_buffer.data(),
|
||||
incoming_data_buffer.data() + bytes_transferred,
|
||||
compression_type);
|
||||
|
||||
// the request has been parsed
|
||||
if (result)
|
||||
{
|
||||
request.endpoint = TCP_socket.remote_endpoint().address();
|
||||
request_handler.handle_request(request, reply);
|
||||
|
||||
// Header compression_header;
|
||||
std::vector<char> compressed_output;
|
||||
std::vector<boost::asio::const_buffer> output_buffer;
|
||||
|
||||
// compress the result w/ gzip/deflate if requested
|
||||
switch (compression_type)
|
||||
{
|
||||
case deflateRFC1951:
|
||||
// use deflate for compression
|
||||
reply.headers.insert(reply.headers.begin(), {"Content-Encoding", "deflate"});
|
||||
CompressBufferCollection(reply.content, compression_type, compressed_output);
|
||||
reply.SetSize(static_cast<unsigned>(compressed_output.size()));
|
||||
output_buffer = reply.HeaderstoBuffers();
|
||||
output_buffer.push_back(boost::asio::buffer(compressed_output));
|
||||
break;
|
||||
case gzipRFC1952:
|
||||
// use gzip for compression
|
||||
reply.headers.insert(reply.headers.begin(), {"Content-Encoding", "gzip"});
|
||||
CompressBufferCollection(reply.content, compression_type, compressed_output);
|
||||
reply.SetSize(static_cast<unsigned>(compressed_output.size()));
|
||||
output_buffer = reply.HeaderstoBuffers();
|
||||
output_buffer.push_back(boost::asio::buffer(compressed_output));
|
||||
break;
|
||||
case noCompression:
|
||||
// don't use any compression
|
||||
reply.SetUncompressedSize();
|
||||
output_buffer = reply.ToBuffers();
|
||||
break;
|
||||
}
|
||||
// write result to stream
|
||||
boost::asio::async_write(TCP_socket,
|
||||
output_buffer,
|
||||
strand.wrap(boost::bind(&Connection::handle_write,
|
||||
this->shared_from_this(),
|
||||
boost::asio::placeholders::error)));
|
||||
}
|
||||
else if (!result)
|
||||
{ // request is not parseable
|
||||
reply = Reply::StockReply(Reply::badRequest);
|
||||
|
||||
boost::asio::async_write(TCP_socket,
|
||||
reply.ToBuffers(),
|
||||
strand.wrap(boost::bind(&Connection::handle_write,
|
||||
this->shared_from_this(),
|
||||
boost::asio::placeholders::error)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// we don't have a result yet, so continue reading
|
||||
TCP_socket.async_read_some(
|
||||
boost::asio::buffer(incoming_data_buffer),
|
||||
strand.wrap(boost::bind(&Connection::handle_read,
|
||||
this->shared_from_this(),
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred)));
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle completion of a write operation.
|
||||
void Connection::handle_write(const boost::system::error_code &error)
|
||||
{
|
||||
if (!error)
|
||||
{
|
||||
// Initiate graceful connection closure.
|
||||
boost::system::error_code ignore_error;
|
||||
TCP_socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ignore_error);
|
||||
}
|
||||
}
|
||||
|
||||
void Connection::CompressBufferCollection(std::vector<char> uncompressed_data,
|
||||
CompressionType compression_type,
|
||||
std::vector<char> &compressed_data)
|
||||
{
|
||||
boost::iostreams::gzip_params compression_parameters;
|
||||
|
||||
// there's a trade-off between speed and size. speed wins
|
||||
compression_parameters.level = boost::iostreams::zlib::best_speed;
|
||||
// check which compression flavor is used
|
||||
if (deflateRFC1951 == compression_type)
|
||||
{
|
||||
compression_parameters.noheader = true;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(compressed_data.empty());
|
||||
// plug data into boost's compression stream
|
||||
boost::iostreams::filtering_ostream gzip_stream;
|
||||
gzip_stream.push(boost::iostreams::gzip_compressor(compression_parameters));
|
||||
gzip_stream.push(boost::iostreams::back_inserter(compressed_data));
|
||||
gzip_stream.write(&uncompressed_data[0], uncompressed_data.size());
|
||||
boost::iostreams::close(gzip_stream);
|
||||
}
|
||||
}
|
||||
@@ -1,104 +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 CONNECTION_H
|
||||
#define CONNECTION_H
|
||||
|
||||
// #include "RequestParser.h"
|
||||
#include "Http/CompressionType.h"
|
||||
#include "Http/Request.h"
|
||||
|
||||
#include <osrm/Reply.h>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
//workaround for incomplete std::shared_ptr compatibility in old boost versions
|
||||
#if BOOST_VERSION < 105300 || defined BOOST_NO_CXX11_SMART_PTR
|
||||
|
||||
namespace boost {
|
||||
template<class T>
|
||||
const T* get_pointer(std::shared_ptr<T> const& p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T* get_pointer(std::shared_ptr<T>& p)
|
||||
{
|
||||
return p.get();
|
||||
}
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
class RequestHandler;
|
||||
|
||||
namespace http
|
||||
{
|
||||
|
||||
/// Represents a single connection from a client.
|
||||
class Connection : public std::enable_shared_from_this<Connection>
|
||||
{
|
||||
public:
|
||||
explicit Connection(boost::asio::io_service &io_service, RequestHandler &handler);
|
||||
Connection(const Connection &) = delete;
|
||||
Connection() = delete;
|
||||
|
||||
boost::asio::ip::tcp::socket &socket();
|
||||
|
||||
/// Start the first asynchronous operation for the connection.
|
||||
void start();
|
||||
|
||||
private:
|
||||
void handle_read(const boost::system::error_code &e, std::size_t bytes_transferred);
|
||||
|
||||
/// Handle completion of a write operation.
|
||||
void handle_write(const boost::system::error_code &e);
|
||||
|
||||
void CompressBufferCollection(std::vector<char> uncompressed_data,
|
||||
CompressionType compression_type,
|
||||
std::vector<char> &compressed_data);
|
||||
|
||||
boost::asio::io_service::strand strand;
|
||||
boost::asio::ip::tcp::socket TCP_socket;
|
||||
RequestHandler &request_handler;
|
||||
boost::array<char, 8192> incoming_data_buffer;
|
||||
Request request;
|
||||
Reply reply;
|
||||
};
|
||||
|
||||
} // namespace http
|
||||
|
||||
#endif // CONNECTION_H
|
||||
@@ -1,132 +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 BASE_DATA_FACADE_H
|
||||
#define BASE_DATA_FACADE_H
|
||||
|
||||
// Exposes all data access interfaces to the algorithms via base class ptr
|
||||
|
||||
#include "../../data_structures/edge_based_node.hpp"
|
||||
#include "../../data_structures/external_memory_node.hpp"
|
||||
#include "../../data_structures/phantom_node.hpp"
|
||||
#include "../../data_structures/turn_instructions.hpp"
|
||||
#include "../../Util/integer_range.hpp"
|
||||
#include "../../Util/OSRMException.h"
|
||||
#include "../../Util/StringUtil.h"
|
||||
#include "../../typedefs.h"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
typedef osrm::range<EdgeID> EdgeRange;
|
||||
|
||||
template <class EdgeDataT> class BaseDataFacade
|
||||
{
|
||||
public:
|
||||
typedef EdgeBasedNode RTreeLeaf;
|
||||
typedef EdgeDataT EdgeData;
|
||||
BaseDataFacade() {}
|
||||
virtual ~BaseDataFacade() {}
|
||||
|
||||
// search graph access
|
||||
virtual unsigned GetNumberOfNodes() const = 0;
|
||||
|
||||
virtual unsigned GetNumberOfEdges() const = 0;
|
||||
|
||||
virtual unsigned GetOutDegree(const NodeID n) const = 0;
|
||||
|
||||
virtual NodeID GetTarget(const EdgeID e) const = 0;
|
||||
|
||||
// virtual EdgeDataT &GetEdgeData(const EdgeID e) = 0;
|
||||
|
||||
virtual const EdgeDataT &GetEdgeData(const EdgeID e) const = 0;
|
||||
|
||||
virtual EdgeID BeginEdges(const NodeID n) const = 0;
|
||||
|
||||
virtual EdgeID EndEdges(const NodeID n) const = 0;
|
||||
|
||||
virtual EdgeRange GetAdjacentEdgeRange(const NodeID node) const = 0;
|
||||
|
||||
// searches for a specific edge
|
||||
virtual EdgeID FindEdge(const NodeID from, const NodeID to) const = 0;
|
||||
|
||||
virtual EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const = 0;
|
||||
|
||||
virtual EdgeID
|
||||
FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const = 0;
|
||||
|
||||
// node and edge information access
|
||||
virtual FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const = 0;
|
||||
|
||||
virtual bool EdgeIsCompressed(const unsigned id) const = 0;
|
||||
|
||||
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const = 0;
|
||||
|
||||
virtual void GetUncompressedGeometry(const unsigned id,
|
||||
std::vector<unsigned> &result_nodes) const = 0;
|
||||
|
||||
virtual TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const = 0;
|
||||
|
||||
virtual TravelMode GetTravelModeForEdgeID(const unsigned id) const = 0;
|
||||
|
||||
virtual bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
FixedPointCoordinate &result,
|
||||
const unsigned zoom_level = 18) = 0;
|
||||
|
||||
virtual bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
PhantomNode &resulting_phantom_node,
|
||||
const unsigned zoom_level) = 0;
|
||||
|
||||
virtual bool
|
||||
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
std::vector<PhantomNode> &resulting_phantom_node_vector,
|
||||
const unsigned zoom_level,
|
||||
const unsigned number_of_results) = 0;
|
||||
|
||||
virtual bool
|
||||
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
PhantomNode &resulting_phantom_node,
|
||||
const unsigned zoom_leve) = 0;
|
||||
|
||||
virtual unsigned GetCheckSum() const = 0;
|
||||
|
||||
virtual unsigned GetNameIndexFromEdgeID(const unsigned id) const = 0;
|
||||
|
||||
virtual void GetName(const unsigned name_id, std::string &result) const = 0;
|
||||
|
||||
std::string GetEscapedNameForNameID(const unsigned name_id) const
|
||||
{
|
||||
std::string temporary_string;
|
||||
GetName(name_id, temporary_string);
|
||||
return EscapeJSONString(temporary_string);
|
||||
}
|
||||
|
||||
virtual std::string GetTimestamp() const = 0;
|
||||
};
|
||||
|
||||
#endif // BASE_DATA_FACADE_H
|
||||
@@ -1,471 +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_DATA_FACADE
|
||||
#define INTERNAL_DATA_FACADE
|
||||
|
||||
// implements all data storage when shared memory is _NOT_ used
|
||||
|
||||
#include "BaseDataFacade.h"
|
||||
|
||||
#include "../../data_structures/original_edge_data.hpp"
|
||||
#include "../../data_structures/query_node.hpp"
|
||||
#include "../../data_structures/query_edge.hpp"
|
||||
#include "../../data_structures/shared_memory_vector_wrapper.hpp"
|
||||
#include "../../data_structures/static_graph.hpp"
|
||||
#include "../../data_structures/static_rtree.hpp"
|
||||
#include "../../data_structures/range_table.hpp"
|
||||
#include "../../Util/BoostFileSystemFix.h"
|
||||
#include "../../Util/graph_loader.hpp"
|
||||
#include "../../Util/simple_logger.hpp"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
#include <osrm/ServerPaths.h>
|
||||
|
||||
template <class EdgeDataT> class InternalDataFacade : public BaseDataFacade<EdgeDataT>
|
||||
{
|
||||
|
||||
private:
|
||||
typedef BaseDataFacade<EdgeDataT> super;
|
||||
typedef StaticGraph<typename super::EdgeData> QueryGraph;
|
||||
typedef typename QueryGraph::InputEdge InputEdge;
|
||||
typedef typename super::RTreeLeaf RTreeLeaf;
|
||||
|
||||
InternalDataFacade() {}
|
||||
|
||||
unsigned m_check_sum;
|
||||
unsigned m_number_of_nodes;
|
||||
QueryGraph *m_query_graph;
|
||||
std::string m_timestamp;
|
||||
|
||||
std::shared_ptr<ShM<FixedPointCoordinate, false>::vector> m_coordinate_list;
|
||||
ShM<NodeID, false>::vector m_via_node_list;
|
||||
ShM<unsigned, false>::vector m_name_ID_list;
|
||||
ShM<TurnInstruction, false>::vector m_turn_instruction_list;
|
||||
ShM<TravelMode, false>::vector m_travel_mode_list;
|
||||
ShM<char, false>::vector m_names_char_list;
|
||||
ShM<bool, false>::vector m_edge_is_compressed;
|
||||
ShM<unsigned, false>::vector m_geometry_indices;
|
||||
ShM<unsigned, false>::vector m_geometry_list;
|
||||
|
||||
boost::thread_specific_ptr<
|
||||
StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, false>::vector, false>> m_static_rtree;
|
||||
boost::filesystem::path ram_index_path;
|
||||
boost::filesystem::path file_index_path;
|
||||
RangeTable<16, false> m_name_table;
|
||||
|
||||
void LoadTimestamp(const boost::filesystem::path ×tamp_path)
|
||||
{
|
||||
if (boost::filesystem::exists(timestamp_path))
|
||||
{
|
||||
SimpleLogger().Write() << "Loading Timestamp";
|
||||
boost::filesystem::ifstream timestamp_stream(timestamp_path);
|
||||
if (!timestamp_stream)
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << timestamp_path << " not found";
|
||||
}
|
||||
getline(timestamp_stream, m_timestamp);
|
||||
timestamp_stream.close();
|
||||
}
|
||||
if (m_timestamp.empty())
|
||||
{
|
||||
m_timestamp = "n/a";
|
||||
}
|
||||
if (25 < m_timestamp.length())
|
||||
{
|
||||
m_timestamp.resize(25);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadGraph(const boost::filesystem::path &hsgr_path)
|
||||
{
|
||||
typename ShM<typename QueryGraph::NodeArrayEntry, false>::vector node_list;
|
||||
typename ShM<typename QueryGraph::EdgeArrayEntry, false>::vector edge_list;
|
||||
|
||||
SimpleLogger().Write() << "loading graph from " << hsgr_path.string();
|
||||
|
||||
m_number_of_nodes = readHSGRFromStream(hsgr_path, node_list, edge_list, &m_check_sum);
|
||||
|
||||
BOOST_ASSERT_MSG(0 != node_list.size(), "node list empty");
|
||||
// BOOST_ASSERT_MSG(0 != edge_list.size(), "edge list empty");
|
||||
SimpleLogger().Write() << "loaded " << node_list.size() << " nodes and " << edge_list.size()
|
||||
<< " edges";
|
||||
m_query_graph = new QueryGraph(node_list, edge_list);
|
||||
|
||||
BOOST_ASSERT_MSG(0 == node_list.size(), "node list not flushed");
|
||||
BOOST_ASSERT_MSG(0 == edge_list.size(), "edge list not flushed");
|
||||
SimpleLogger().Write() << "Data checksum is " << m_check_sum;
|
||||
}
|
||||
|
||||
void LoadNodeAndEdgeInformation(const boost::filesystem::path &nodes_file,
|
||||
const boost::filesystem::path &edges_file)
|
||||
{
|
||||
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
|
||||
|
||||
QueryNode current_node;
|
||||
unsigned number_of_coordinates = 0;
|
||||
nodes_input_stream.read((char *)&number_of_coordinates, sizeof(unsigned));
|
||||
m_coordinate_list =
|
||||
std::make_shared<std::vector<FixedPointCoordinate>>(number_of_coordinates);
|
||||
for (unsigned i = 0; i < number_of_coordinates; ++i)
|
||||
{
|
||||
nodes_input_stream.read((char *)¤t_node, sizeof(QueryNode));
|
||||
m_coordinate_list->at(i) = FixedPointCoordinate(current_node.lat, current_node.lon);
|
||||
BOOST_ASSERT((std::abs(m_coordinate_list->at(i).lat) >> 30) == 0);
|
||||
BOOST_ASSERT((std::abs(m_coordinate_list->at(i).lon) >> 30) == 0);
|
||||
}
|
||||
nodes_input_stream.close();
|
||||
|
||||
boost::filesystem::ifstream edges_input_stream(edges_file, std::ios::binary);
|
||||
unsigned number_of_edges = 0;
|
||||
edges_input_stream.read((char *)&number_of_edges, sizeof(unsigned));
|
||||
m_via_node_list.resize(number_of_edges);
|
||||
m_name_ID_list.resize(number_of_edges);
|
||||
m_turn_instruction_list.resize(number_of_edges);
|
||||
m_travel_mode_list.resize(number_of_edges);
|
||||
m_edge_is_compressed.resize(number_of_edges);
|
||||
|
||||
unsigned compressed = 0;
|
||||
|
||||
OriginalEdgeData current_edge_data;
|
||||
for (unsigned i = 0; i < number_of_edges; ++i)
|
||||
{
|
||||
edges_input_stream.read((char *)&(current_edge_data), sizeof(OriginalEdgeData));
|
||||
m_via_node_list[i] = current_edge_data.via_node;
|
||||
m_name_ID_list[i] = current_edge_data.name_id;
|
||||
m_turn_instruction_list[i] = current_edge_data.turn_instruction;
|
||||
m_travel_mode_list[i] = current_edge_data.travel_mode;
|
||||
m_edge_is_compressed[i] = current_edge_data.compressed_geometry;
|
||||
if (m_edge_is_compressed[i])
|
||||
{
|
||||
++compressed;
|
||||
}
|
||||
}
|
||||
|
||||
edges_input_stream.close();
|
||||
}
|
||||
|
||||
void LoadGeometries(const boost::filesystem::path &geometry_file)
|
||||
{
|
||||
std::ifstream geometry_stream(geometry_file.string().c_str(), std::ios::binary);
|
||||
unsigned number_of_indices = 0;
|
||||
unsigned number_of_compressed_geometries = 0;
|
||||
|
||||
geometry_stream.read((char *)&number_of_indices, sizeof(unsigned));
|
||||
|
||||
m_geometry_indices.resize(number_of_indices);
|
||||
if (number_of_indices > 0)
|
||||
{
|
||||
geometry_stream.read((char *)&(m_geometry_indices[0]),
|
||||
number_of_indices * sizeof(unsigned));
|
||||
}
|
||||
|
||||
geometry_stream.read((char *)&number_of_compressed_geometries, sizeof(unsigned));
|
||||
|
||||
BOOST_ASSERT(m_geometry_indices.back() == number_of_compressed_geometries);
|
||||
m_geometry_list.resize(number_of_compressed_geometries);
|
||||
|
||||
if (number_of_compressed_geometries > 0)
|
||||
{
|
||||
geometry_stream.read((char *)&(m_geometry_list[0]),
|
||||
number_of_compressed_geometries * sizeof(unsigned));
|
||||
}
|
||||
geometry_stream.close();
|
||||
}
|
||||
|
||||
void LoadRTree()
|
||||
{
|
||||
BOOST_ASSERT_MSG(!m_coordinate_list->empty(), "coordinates must be loaded before r-tree");
|
||||
|
||||
m_static_rtree.reset(
|
||||
new StaticRTree<RTreeLeaf>(ram_index_path, file_index_path, m_coordinate_list));
|
||||
}
|
||||
|
||||
void LoadStreetNames(const boost::filesystem::path &names_file)
|
||||
{
|
||||
boost::filesystem::ifstream name_stream(names_file, std::ios::binary);
|
||||
|
||||
name_stream >> m_name_table;
|
||||
|
||||
unsigned number_of_chars = 0;
|
||||
name_stream.read((char *)&number_of_chars, sizeof(unsigned));
|
||||
BOOST_ASSERT_MSG(0 != number_of_chars, "name file broken");
|
||||
m_names_char_list.resize(number_of_chars + 1); //+1 gives sentinel element
|
||||
name_stream.read((char *)&m_names_char_list[0], number_of_chars * sizeof(char));
|
||||
if (0 == m_names_char_list.size())
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << "list of street names is empty";
|
||||
}
|
||||
name_stream.close();
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~InternalDataFacade()
|
||||
{
|
||||
delete m_query_graph;
|
||||
m_static_rtree.reset();
|
||||
}
|
||||
|
||||
explicit InternalDataFacade(const ServerPaths &server_paths)
|
||||
{
|
||||
// generate paths of data files
|
||||
if (server_paths.find("hsgrdata") == server_paths.end())
|
||||
{
|
||||
throw OSRMException("no hsgr file given in ini file");
|
||||
}
|
||||
if (server_paths.find("ramindex") == server_paths.end())
|
||||
{
|
||||
throw OSRMException("no ram index file given in ini file");
|
||||
}
|
||||
if (server_paths.find("fileindex") == server_paths.end())
|
||||
{
|
||||
throw OSRMException("no leaf index file given in ini file");
|
||||
}
|
||||
if (server_paths.find("geometries") == server_paths.end())
|
||||
{
|
||||
throw OSRMException("no geometries file given in ini file");
|
||||
}
|
||||
if (server_paths.find("nodesdata") == server_paths.end())
|
||||
{
|
||||
throw OSRMException("no nodes file given in ini file");
|
||||
}
|
||||
if (server_paths.find("edgesdata") == server_paths.end())
|
||||
{
|
||||
throw OSRMException("no edges file given in ini file");
|
||||
}
|
||||
if (server_paths.find("namesdata") == server_paths.end())
|
||||
{
|
||||
throw OSRMException("no names file given in ini file");
|
||||
}
|
||||
|
||||
ServerPaths::const_iterator paths_iterator = server_paths.find("hsgrdata");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
const boost::filesystem::path &hsgr_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("timestamp");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
const boost::filesystem::path ×tamp_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("ramindex");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
ram_index_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("fileindex");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
file_index_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("nodesdata");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
const boost::filesystem::path &nodes_data_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("edgesdata");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
const boost::filesystem::path &edges_data_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("namesdata");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
const boost::filesystem::path &names_data_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("geometries");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
const boost::filesystem::path &geometries_path = paths_iterator->second;
|
||||
|
||||
// load data
|
||||
SimpleLogger().Write() << "loading graph data";
|
||||
AssertPathExists(hsgr_path);
|
||||
LoadGraph(hsgr_path);
|
||||
SimpleLogger().Write() << "loading edge information";
|
||||
AssertPathExists(nodes_data_path);
|
||||
AssertPathExists(edges_data_path);
|
||||
LoadNodeAndEdgeInformation(nodes_data_path, edges_data_path);
|
||||
SimpleLogger().Write() << "loading geometries";
|
||||
AssertPathExists(geometries_path);
|
||||
LoadGeometries(geometries_path);
|
||||
SimpleLogger().Write() << "loading r-tree";
|
||||
AssertPathExists(ram_index_path);
|
||||
AssertPathExists(file_index_path);
|
||||
SimpleLogger().Write() << "loading timestamp";
|
||||
LoadTimestamp(timestamp_path);
|
||||
SimpleLogger().Write() << "loading street names";
|
||||
AssertPathExists(names_data_path);
|
||||
LoadStreetNames(names_data_path);
|
||||
}
|
||||
|
||||
// search graph access
|
||||
unsigned GetNumberOfNodes() const final { return m_query_graph->GetNumberOfNodes(); }
|
||||
|
||||
unsigned GetNumberOfEdges() const final { return m_query_graph->GetNumberOfEdges(); }
|
||||
|
||||
unsigned GetOutDegree(const NodeID n) const final { return m_query_graph->GetOutDegree(n); }
|
||||
|
||||
NodeID GetTarget(const EdgeID e) const final { return m_query_graph->GetTarget(e); }
|
||||
|
||||
// EdgeDataT &GetEdgeData(const EdgeID e) final { return m_query_graph->GetEdgeData(e); }
|
||||
|
||||
EdgeDataT &GetEdgeData(const EdgeID e) const final { return m_query_graph->GetEdgeData(e); }
|
||||
|
||||
EdgeID BeginEdges(const NodeID n) const final { return m_query_graph->BeginEdges(n); }
|
||||
|
||||
EdgeID EndEdges(const NodeID n) const final { return m_query_graph->EndEdges(n); }
|
||||
|
||||
EdgeRange GetAdjacentEdgeRange(const NodeID node) const final
|
||||
{
|
||||
return m_query_graph->GetAdjacentEdgeRange(node);
|
||||
};
|
||||
|
||||
// searches for a specific edge
|
||||
EdgeID FindEdge(const NodeID from, const NodeID to) const final
|
||||
{
|
||||
return m_query_graph->FindEdge(from, to);
|
||||
}
|
||||
|
||||
EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const final
|
||||
{
|
||||
return m_query_graph->FindEdgeInEitherDirection(from, to);
|
||||
}
|
||||
|
||||
EdgeID FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const final
|
||||
{
|
||||
return m_query_graph->FindEdgeIndicateIfReverse(from, to, result);
|
||||
}
|
||||
|
||||
// node and edge information access
|
||||
FixedPointCoordinate GetCoordinateOfNode(const unsigned id) const final
|
||||
{
|
||||
return m_coordinate_list->at(id);
|
||||
};
|
||||
|
||||
bool EdgeIsCompressed(const unsigned id) const { return m_edge_is_compressed.at(id); }
|
||||
|
||||
TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const final
|
||||
{
|
||||
return m_turn_instruction_list.at(id);
|
||||
}
|
||||
|
||||
TravelMode GetTravelModeForEdgeID(const unsigned id) const
|
||||
{
|
||||
return m_travel_mode_list.at(id);
|
||||
}
|
||||
|
||||
bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
FixedPointCoordinate &result,
|
||||
const unsigned zoom_level = 18) final
|
||||
{
|
||||
if (!m_static_rtree.get())
|
||||
{
|
||||
LoadRTree();
|
||||
}
|
||||
|
||||
return m_static_rtree->LocateClosestEndPointForCoordinate(
|
||||
input_coordinate, result, zoom_level);
|
||||
}
|
||||
|
||||
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
PhantomNode &resulting_phantom_node,
|
||||
const unsigned zoom_level) final
|
||||
{
|
||||
if (!m_static_rtree.get())
|
||||
{
|
||||
LoadRTree();
|
||||
}
|
||||
|
||||
return m_static_rtree->FindPhantomNodeForCoordinate(
|
||||
input_coordinate, resulting_phantom_node, zoom_level);
|
||||
}
|
||||
|
||||
bool
|
||||
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
PhantomNode &resulting_phantom_node,
|
||||
const unsigned zoom_level) final
|
||||
{
|
||||
std::vector<PhantomNode> resulting_phantom_node_vector;
|
||||
auto result = IncrementalFindPhantomNodeForCoordinate(input_coordinate,
|
||||
resulting_phantom_node_vector,
|
||||
zoom_level,
|
||||
1);
|
||||
if (result)
|
||||
{
|
||||
BOOST_ASSERT(!resulting_phantom_node_vector.empty());
|
||||
resulting_phantom_node = resulting_phantom_node_vector.front();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
std::vector<PhantomNode> &resulting_phantom_node_vector,
|
||||
const unsigned zoom_level,
|
||||
const unsigned number_of_results) final
|
||||
{
|
||||
if (!m_static_rtree.get())
|
||||
{
|
||||
LoadRTree();
|
||||
}
|
||||
|
||||
return m_static_rtree->IncrementalFindPhantomNodeForCoordinate(
|
||||
input_coordinate, resulting_phantom_node_vector, zoom_level, number_of_results);
|
||||
}
|
||||
|
||||
unsigned GetCheckSum() const final { return m_check_sum; }
|
||||
|
||||
unsigned GetNameIndexFromEdgeID(const unsigned id) const final
|
||||
{
|
||||
return m_name_ID_list.at(id);
|
||||
};
|
||||
|
||||
void GetName(const unsigned name_id, std::string &result) const final
|
||||
{
|
||||
if (UINT_MAX == name_id)
|
||||
{
|
||||
result = "";
|
||||
return;
|
||||
}
|
||||
auto range = m_name_table.GetRange(name_id);
|
||||
|
||||
result.clear();
|
||||
if (range.begin() != range.end())
|
||||
{
|
||||
result.resize(range.back() - range.front() + 1);
|
||||
std::copy(m_names_char_list.begin() + range.front(),
|
||||
m_names_char_list.begin() + range.back() + 1,
|
||||
result.begin());
|
||||
}
|
||||
}
|
||||
|
||||
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const final
|
||||
{
|
||||
return m_via_node_list.at(id);
|
||||
}
|
||||
|
||||
virtual void GetUncompressedGeometry(const unsigned id,
|
||||
std::vector<unsigned> &result_nodes) const final
|
||||
{
|
||||
const unsigned begin = m_geometry_indices.at(id);
|
||||
const unsigned end = m_geometry_indices.at(id + 1);
|
||||
|
||||
result_nodes.clear();
|
||||
result_nodes.insert(
|
||||
result_nodes.begin(), m_geometry_list.begin() + begin, m_geometry_list.begin() + end);
|
||||
}
|
||||
|
||||
std::string GetTimestamp() const final { return m_timestamp; }
|
||||
};
|
||||
|
||||
#endif // INTERNAL_DATA_FACADE
|
||||
@@ -1,60 +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 SHARED_BARRIER_H
|
||||
#define SHARED_BARRIER_H
|
||||
|
||||
#include <boost/interprocess/sync/named_mutex.hpp>
|
||||
#include <boost/interprocess/sync/named_condition.hpp>
|
||||
|
||||
struct SharedBarriers
|
||||
{
|
||||
|
||||
SharedBarriers()
|
||||
: pending_update_mutex(boost::interprocess::open_or_create, "pending_update"),
|
||||
update_mutex(boost::interprocess::open_or_create, "update"),
|
||||
query_mutex(boost::interprocess::open_or_create, "query"),
|
||||
no_running_queries_condition(boost::interprocess::open_or_create, "no_running_queries"),
|
||||
update_ongoing(false), number_of_queries(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Mutex to protect access to the boolean variable
|
||||
boost::interprocess::named_mutex pending_update_mutex;
|
||||
boost::interprocess::named_mutex update_mutex;
|
||||
boost::interprocess::named_mutex query_mutex;
|
||||
|
||||
// Condition that no update is running
|
||||
boost::interprocess::named_condition no_running_queries_condition;
|
||||
|
||||
// Is there an ongoing update?
|
||||
bool update_ongoing;
|
||||
// Is there any query?
|
||||
int number_of_queries;
|
||||
};
|
||||
|
||||
#endif // SHARED_BARRIER_H
|
||||
@@ -1,447 +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 SHARED_DATA_FACADE_H
|
||||
#define SHARED_DATA_FACADE_H
|
||||
|
||||
// implements all data storage when shared memory _IS_ used
|
||||
|
||||
#include "BaseDataFacade.h"
|
||||
#include "SharedDataType.h"
|
||||
|
||||
#include "../../data_structures/range_table.hpp"
|
||||
#include "../../data_structures/static_graph.hpp"
|
||||
#include "../../data_structures/static_rtree.hpp"
|
||||
#include "../../Util/BoostFileSystemFix.h"
|
||||
#include "../../Util/make_unique.hpp"
|
||||
#include "../../Util/simple_logger.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
template <class EdgeDataT> class SharedDataFacade : public BaseDataFacade<EdgeDataT>
|
||||
{
|
||||
|
||||
private:
|
||||
typedef EdgeDataT EdgeData;
|
||||
typedef BaseDataFacade<EdgeData> super;
|
||||
typedef StaticGraph<EdgeData, true> QueryGraph;
|
||||
typedef typename StaticGraph<EdgeData, true>::NodeArrayEntry GraphNode;
|
||||
typedef typename StaticGraph<EdgeData, true>::EdgeArrayEntry GraphEdge;
|
||||
typedef typename RangeTable<16, true>::BlockT NameIndexBlock;
|
||||
typedef typename QueryGraph::InputEdge InputEdge;
|
||||
typedef typename super::RTreeLeaf RTreeLeaf;
|
||||
using SharedRTree = StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>;
|
||||
using TimeStampedRTreePair = std::pair<unsigned, std::shared_ptr<SharedRTree>>;
|
||||
using RTreeNode = typename SharedRTree::TreeNode;
|
||||
|
||||
SharedDataLayout *data_layout;
|
||||
char *shared_memory;
|
||||
SharedDataTimestamp *data_timestamp_ptr;
|
||||
|
||||
SharedDataType CURRENT_LAYOUT;
|
||||
SharedDataType CURRENT_DATA;
|
||||
unsigned CURRENT_TIMESTAMP;
|
||||
|
||||
unsigned m_check_sum;
|
||||
std::unique_ptr<QueryGraph> m_query_graph;
|
||||
std::unique_ptr<SharedMemory> m_layout_memory;
|
||||
std::unique_ptr<SharedMemory> m_large_memory;
|
||||
std::string m_timestamp;
|
||||
|
||||
std::shared_ptr<ShM<FixedPointCoordinate, true>::vector> m_coordinate_list;
|
||||
ShM<NodeID, true>::vector m_via_node_list;
|
||||
ShM<unsigned, true>::vector m_name_ID_list;
|
||||
ShM<TurnInstruction, true>::vector m_turn_instruction_list;
|
||||
ShM<TravelMode, true>::vector m_travel_mode_list;
|
||||
ShM<char, true>::vector m_names_char_list;
|
||||
ShM<unsigned, true>::vector m_name_begin_indices;
|
||||
ShM<bool, true>::vector m_edge_is_compressed;
|
||||
ShM<unsigned, true>::vector m_geometry_indices;
|
||||
ShM<unsigned, true>::vector m_geometry_list;
|
||||
|
||||
boost::thread_specific_ptr<std::pair<unsigned, std::shared_ptr<SharedRTree>>> m_static_rtree;
|
||||
boost::filesystem::path file_index_path;
|
||||
|
||||
std::shared_ptr<RangeTable<16, true>> m_name_table;
|
||||
|
||||
void LoadChecksum()
|
||||
{
|
||||
m_check_sum =
|
||||
*data_layout->GetBlockPtr<unsigned>(shared_memory, SharedDataLayout::HSGR_CHECKSUM);
|
||||
SimpleLogger().Write() << "set checksum: " << m_check_sum;
|
||||
}
|
||||
|
||||
void LoadTimestamp()
|
||||
{
|
||||
char *timestamp_ptr =
|
||||
data_layout->GetBlockPtr<char>(shared_memory, SharedDataLayout::TIMESTAMP);
|
||||
m_timestamp.resize(data_layout->GetBlockSize(SharedDataLayout::TIMESTAMP));
|
||||
std::copy(timestamp_ptr,
|
||||
timestamp_ptr + data_layout->GetBlockSize(SharedDataLayout::TIMESTAMP),
|
||||
m_timestamp.begin());
|
||||
}
|
||||
|
||||
void LoadRTree()
|
||||
{
|
||||
BOOST_ASSERT_MSG(!m_coordinate_list->empty(), "coordinates must be loaded before r-tree");
|
||||
|
||||
RTreeNode *tree_ptr =
|
||||
data_layout->GetBlockPtr<RTreeNode>(shared_memory, SharedDataLayout::R_SEARCH_TREE);
|
||||
m_static_rtree.reset(new TimeStampedRTreePair(CURRENT_TIMESTAMP,
|
||||
osrm::make_unique<SharedRTree>(
|
||||
tree_ptr,
|
||||
data_layout->num_entries[SharedDataLayout::R_SEARCH_TREE],
|
||||
file_index_path,
|
||||
m_coordinate_list)));
|
||||
}
|
||||
|
||||
void LoadGraph()
|
||||
{
|
||||
GraphNode *graph_nodes_ptr =
|
||||
data_layout->GetBlockPtr<GraphNode>(shared_memory, SharedDataLayout::GRAPH_NODE_LIST);
|
||||
|
||||
GraphEdge *graph_edges_ptr =
|
||||
data_layout->GetBlockPtr<GraphEdge>(shared_memory, SharedDataLayout::GRAPH_EDGE_LIST);
|
||||
|
||||
typename ShM<GraphNode, true>::vector node_list(
|
||||
graph_nodes_ptr, data_layout->num_entries[SharedDataLayout::GRAPH_NODE_LIST]);
|
||||
typename ShM<GraphEdge, true>::vector edge_list(
|
||||
graph_edges_ptr, data_layout->num_entries[SharedDataLayout::GRAPH_EDGE_LIST]);
|
||||
m_query_graph.reset(new QueryGraph(node_list, edge_list));
|
||||
}
|
||||
|
||||
void LoadNodeAndEdgeInformation()
|
||||
{
|
||||
|
||||
FixedPointCoordinate *coordinate_list_ptr = data_layout->GetBlockPtr<FixedPointCoordinate>(
|
||||
shared_memory, SharedDataLayout::COORDINATE_LIST);
|
||||
m_coordinate_list = osrm::make_unique<ShM<FixedPointCoordinate, true>::vector>(
|
||||
coordinate_list_ptr, data_layout->num_entries[SharedDataLayout::COORDINATE_LIST]);
|
||||
|
||||
TravelMode *travel_mode_list_ptr = data_layout->GetBlockPtr<TravelMode>(
|
||||
shared_memory, SharedDataLayout::TRAVEL_MODE);
|
||||
typename ShM<TravelMode, true>::vector travel_mode_list(
|
||||
travel_mode_list_ptr,
|
||||
data_layout->num_entries[SharedDataLayout::TRAVEL_MODE]);
|
||||
m_travel_mode_list.swap(travel_mode_list);
|
||||
|
||||
TurnInstruction *turn_instruction_list_ptr = data_layout->GetBlockPtr<TurnInstruction>(
|
||||
shared_memory, SharedDataLayout::TURN_INSTRUCTION);
|
||||
typename ShM<TurnInstruction, true>::vector turn_instruction_list(
|
||||
turn_instruction_list_ptr,
|
||||
data_layout->num_entries[SharedDataLayout::TURN_INSTRUCTION]);
|
||||
m_turn_instruction_list.swap(turn_instruction_list);
|
||||
|
||||
unsigned *name_id_list_ptr =
|
||||
data_layout->GetBlockPtr<unsigned>(shared_memory, SharedDataLayout::NAME_ID_LIST);
|
||||
typename ShM<unsigned, true>::vector name_id_list(
|
||||
name_id_list_ptr, data_layout->num_entries[SharedDataLayout::NAME_ID_LIST]);
|
||||
m_name_ID_list.swap(name_id_list);
|
||||
}
|
||||
|
||||
void LoadViaNodeList()
|
||||
{
|
||||
NodeID *via_node_list_ptr =
|
||||
data_layout->GetBlockPtr<NodeID>(shared_memory, SharedDataLayout::VIA_NODE_LIST);
|
||||
typename ShM<NodeID, true>::vector via_node_list(
|
||||
via_node_list_ptr, data_layout->num_entries[SharedDataLayout::VIA_NODE_LIST]);
|
||||
m_via_node_list.swap(via_node_list);
|
||||
}
|
||||
|
||||
void LoadNames()
|
||||
{
|
||||
unsigned *offsets_ptr =
|
||||
data_layout->GetBlockPtr<unsigned>(shared_memory, SharedDataLayout::NAME_OFFSETS);
|
||||
NameIndexBlock *blocks_ptr =
|
||||
data_layout->GetBlockPtr<NameIndexBlock>(shared_memory, SharedDataLayout::NAME_BLOCKS);
|
||||
typename ShM<unsigned, true>::vector name_offsets(
|
||||
offsets_ptr, data_layout->num_entries[SharedDataLayout::NAME_OFFSETS]);
|
||||
typename ShM<NameIndexBlock, true>::vector name_blocks(
|
||||
blocks_ptr, data_layout->num_entries[SharedDataLayout::NAME_BLOCKS]);
|
||||
|
||||
char *names_list_ptr =
|
||||
data_layout->GetBlockPtr<char>(shared_memory, SharedDataLayout::NAME_CHAR_LIST);
|
||||
typename ShM<char, true>::vector names_char_list(
|
||||
names_list_ptr, data_layout->num_entries[SharedDataLayout::NAME_CHAR_LIST]);
|
||||
m_name_table = osrm::make_unique<RangeTable<16, true>>(
|
||||
name_offsets, name_blocks, static_cast<unsigned>(names_char_list.size()));
|
||||
|
||||
m_names_char_list.swap(names_char_list);
|
||||
}
|
||||
|
||||
void LoadGeometries()
|
||||
{
|
||||
unsigned *geometries_compressed_ptr = data_layout->GetBlockPtr<unsigned>(
|
||||
shared_memory, SharedDataLayout::GEOMETRIES_INDICATORS);
|
||||
typename ShM<bool, true>::vector edge_is_compressed(
|
||||
geometries_compressed_ptr,
|
||||
data_layout->num_entries[SharedDataLayout::GEOMETRIES_INDICATORS]);
|
||||
m_edge_is_compressed.swap(edge_is_compressed);
|
||||
|
||||
unsigned *geometries_index_ptr =
|
||||
data_layout->GetBlockPtr<unsigned>(shared_memory, SharedDataLayout::GEOMETRIES_INDEX);
|
||||
typename ShM<unsigned, true>::vector geometry_begin_indices(
|
||||
geometries_index_ptr, data_layout->num_entries[SharedDataLayout::GEOMETRIES_INDEX]);
|
||||
m_geometry_indices.swap(geometry_begin_indices);
|
||||
|
||||
unsigned *geometries_list_ptr =
|
||||
data_layout->GetBlockPtr<unsigned>(shared_memory, SharedDataLayout::GEOMETRIES_LIST);
|
||||
typename ShM<unsigned, true>::vector geometry_list(
|
||||
geometries_list_ptr, data_layout->num_entries[SharedDataLayout::GEOMETRIES_LIST]);
|
||||
m_geometry_list.swap(geometry_list);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~SharedDataFacade() {}
|
||||
|
||||
SharedDataFacade()
|
||||
{
|
||||
data_timestamp_ptr = (SharedDataTimestamp *)SharedMemoryFactory::Get(
|
||||
CURRENT_REGIONS, sizeof(SharedDataTimestamp), false, false)->Ptr();
|
||||
CURRENT_LAYOUT = LAYOUT_NONE;
|
||||
CURRENT_DATA = DATA_NONE;
|
||||
CURRENT_TIMESTAMP = 0;
|
||||
|
||||
// load data
|
||||
CheckAndReloadFacade();
|
||||
}
|
||||
|
||||
void CheckAndReloadFacade()
|
||||
{
|
||||
if (CURRENT_LAYOUT != data_timestamp_ptr->layout ||
|
||||
CURRENT_DATA != data_timestamp_ptr->data ||
|
||||
CURRENT_TIMESTAMP != data_timestamp_ptr->timestamp)
|
||||
{
|
||||
// release the previous shared memory segments
|
||||
SharedMemory::Remove(CURRENT_LAYOUT);
|
||||
SharedMemory::Remove(CURRENT_DATA);
|
||||
|
||||
CURRENT_LAYOUT = data_timestamp_ptr->layout;
|
||||
CURRENT_DATA = data_timestamp_ptr->data;
|
||||
CURRENT_TIMESTAMP = data_timestamp_ptr->timestamp;
|
||||
|
||||
m_layout_memory.reset(SharedMemoryFactory::Get(CURRENT_LAYOUT));
|
||||
|
||||
data_layout = (SharedDataLayout *)(m_layout_memory->Ptr());
|
||||
|
||||
m_large_memory.reset(SharedMemoryFactory::Get(CURRENT_DATA));
|
||||
shared_memory = (char *)(m_large_memory->Ptr());
|
||||
|
||||
const char *file_index_ptr =
|
||||
data_layout->GetBlockPtr<char>(shared_memory, SharedDataLayout::FILE_INDEX_PATH);
|
||||
file_index_path = boost::filesystem::path(file_index_ptr);
|
||||
if (!boost::filesystem::exists(file_index_path))
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "Leaf file name " << file_index_path.string();
|
||||
throw OSRMException("Could not load leaf index file."
|
||||
"Is any data loaded into shared memory?");
|
||||
}
|
||||
|
||||
LoadGraph();
|
||||
LoadChecksum();
|
||||
LoadNodeAndEdgeInformation();
|
||||
LoadGeometries();
|
||||
LoadTimestamp();
|
||||
LoadViaNodeList();
|
||||
LoadNames();
|
||||
|
||||
data_layout->PrintInformation();
|
||||
|
||||
SimpleLogger().Write() << "number of geometries: " << m_coordinate_list->size();
|
||||
for (unsigned i = 0; i < m_coordinate_list->size(); ++i)
|
||||
{
|
||||
if (!GetCoordinateOfNode(i).is_valid())
|
||||
{
|
||||
SimpleLogger().Write() << "coordinate " << i << " not valid";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// search graph access
|
||||
unsigned GetNumberOfNodes() const final { return m_query_graph->GetNumberOfNodes(); }
|
||||
|
||||
unsigned GetNumberOfEdges() const final { return m_query_graph->GetNumberOfEdges(); }
|
||||
|
||||
unsigned GetOutDegree(const NodeID n) const final { return m_query_graph->GetOutDegree(n); }
|
||||
|
||||
NodeID GetTarget(const EdgeID e) const final { return m_query_graph->GetTarget(e); }
|
||||
|
||||
EdgeDataT &GetEdgeData(const EdgeID e) const final { return m_query_graph->GetEdgeData(e); }
|
||||
|
||||
EdgeID BeginEdges(const NodeID n) const final { return m_query_graph->BeginEdges(n); }
|
||||
|
||||
EdgeID EndEdges(const NodeID n) const final { return m_query_graph->EndEdges(n); }
|
||||
|
||||
EdgeRange GetAdjacentEdgeRange(const NodeID node) const final
|
||||
{
|
||||
return m_query_graph->GetAdjacentEdgeRange(node);
|
||||
};
|
||||
|
||||
// searches for a specific edge
|
||||
EdgeID FindEdge(const NodeID from, const NodeID to) const final
|
||||
{
|
||||
return m_query_graph->FindEdge(from, to);
|
||||
}
|
||||
|
||||
EdgeID FindEdgeInEitherDirection(const NodeID from, const NodeID to) const final
|
||||
{
|
||||
return m_query_graph->FindEdgeInEitherDirection(from, to);
|
||||
}
|
||||
|
||||
EdgeID FindEdgeIndicateIfReverse(const NodeID from, const NodeID to, bool &result) const final
|
||||
{
|
||||
return m_query_graph->FindEdgeIndicateIfReverse(from, to, result);
|
||||
}
|
||||
|
||||
// node and edge information access
|
||||
FixedPointCoordinate GetCoordinateOfNode(const NodeID id) const final
|
||||
{
|
||||
return m_coordinate_list->at(id);
|
||||
};
|
||||
|
||||
virtual bool EdgeIsCompressed(const unsigned id) const final
|
||||
{
|
||||
return m_edge_is_compressed.at(id);
|
||||
}
|
||||
|
||||
virtual void GetUncompressedGeometry(const unsigned id,
|
||||
std::vector<unsigned> &result_nodes) const final
|
||||
{
|
||||
const unsigned begin = m_geometry_indices.at(id);
|
||||
const unsigned end = m_geometry_indices.at(id + 1);
|
||||
|
||||
result_nodes.clear();
|
||||
result_nodes.insert(
|
||||
result_nodes.begin(), m_geometry_list.begin() + begin, m_geometry_list.begin() + end);
|
||||
}
|
||||
|
||||
virtual unsigned GetGeometryIndexForEdgeID(const unsigned id) const final
|
||||
{
|
||||
return m_via_node_list.at(id);
|
||||
}
|
||||
|
||||
TurnInstruction GetTurnInstructionForEdgeID(const unsigned id) const final
|
||||
{
|
||||
return m_turn_instruction_list.at(id);
|
||||
}
|
||||
|
||||
TravelMode GetTravelModeForEdgeID(const unsigned id) const
|
||||
{
|
||||
return m_travel_mode_list.at(id);
|
||||
}
|
||||
|
||||
bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
FixedPointCoordinate &result,
|
||||
const unsigned zoom_level = 18) final
|
||||
{
|
||||
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
|
||||
{
|
||||
LoadRTree();
|
||||
}
|
||||
|
||||
return m_static_rtree->second->LocateClosestEndPointForCoordinate(
|
||||
input_coordinate, result, zoom_level);
|
||||
}
|
||||
|
||||
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
PhantomNode &resulting_phantom_node,
|
||||
const unsigned zoom_level) final
|
||||
{
|
||||
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
|
||||
{
|
||||
LoadRTree();
|
||||
}
|
||||
|
||||
return m_static_rtree->second->FindPhantomNodeForCoordinate(
|
||||
input_coordinate, resulting_phantom_node, zoom_level);
|
||||
}
|
||||
|
||||
bool
|
||||
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
PhantomNode &resulting_phantom_node,
|
||||
const unsigned zoom_level) final
|
||||
{
|
||||
std::vector<PhantomNode> resulting_phantom_node_vector;
|
||||
auto result = IncrementalFindPhantomNodeForCoordinate(input_coordinate,
|
||||
resulting_phantom_node_vector,
|
||||
zoom_level,
|
||||
1);
|
||||
if (result)
|
||||
{
|
||||
BOOST_ASSERT(!resulting_phantom_node_vector.empty());
|
||||
resulting_phantom_node = resulting_phantom_node_vector.front();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
IncrementalFindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
std::vector<PhantomNode> &resulting_phantom_node_vector,
|
||||
const unsigned zoom_level,
|
||||
const unsigned number_of_results) final
|
||||
{
|
||||
if (!m_static_rtree.get() || CURRENT_TIMESTAMP != m_static_rtree->first)
|
||||
{
|
||||
LoadRTree();
|
||||
}
|
||||
|
||||
return m_static_rtree->second->IncrementalFindPhantomNodeForCoordinate(
|
||||
input_coordinate, resulting_phantom_node_vector, zoom_level, number_of_results);
|
||||
}
|
||||
|
||||
unsigned GetCheckSum() const final { return m_check_sum; }
|
||||
|
||||
unsigned GetNameIndexFromEdgeID(const unsigned id) const final
|
||||
{
|
||||
return m_name_ID_list.at(id);
|
||||
};
|
||||
|
||||
void GetName(const unsigned name_id, std::string &result) const final
|
||||
{
|
||||
if (UINT_MAX == name_id)
|
||||
{
|
||||
result = "";
|
||||
return;
|
||||
}
|
||||
auto range = m_name_table->GetRange(name_id);
|
||||
|
||||
result.clear();
|
||||
if (range.begin() != range.end())
|
||||
{
|
||||
result.resize(range.back() - range.front() + 1);
|
||||
std::copy(m_names_char_list.begin() + range.front(),
|
||||
m_names_char_list.begin() + range.back() + 1,
|
||||
result.begin());
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetTimestamp() const final { return m_timestamp; }
|
||||
};
|
||||
|
||||
#endif // SHARED_DATA_FACADE_H
|
||||
@@ -1,193 +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 SHARED_DATA_TYPE_H_
|
||||
#define SHARED_DATA_TYPE_H_
|
||||
|
||||
#include "../../Util/OSRMException.h"
|
||||
#include "../../Util/simple_logger.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <array>
|
||||
|
||||
// Added at the start and end of each block as sanity check
|
||||
static const char CANARY[] = "OSRM";
|
||||
|
||||
struct SharedDataLayout
|
||||
{
|
||||
enum BlockID {
|
||||
NAME_OFFSETS = 0,
|
||||
NAME_BLOCKS,
|
||||
NAME_CHAR_LIST,
|
||||
NAME_ID_LIST,
|
||||
VIA_NODE_LIST,
|
||||
GRAPH_NODE_LIST,
|
||||
GRAPH_EDGE_LIST,
|
||||
COORDINATE_LIST,
|
||||
TURN_INSTRUCTION,
|
||||
TRAVEL_MODE,
|
||||
R_SEARCH_TREE,
|
||||
GEOMETRIES_INDEX,
|
||||
GEOMETRIES_LIST,
|
||||
GEOMETRIES_INDICATORS,
|
||||
HSGR_CHECKSUM,
|
||||
TIMESTAMP,
|
||||
FILE_INDEX_PATH,
|
||||
NUM_BLOCKS
|
||||
};
|
||||
|
||||
std::array<uint64_t, NUM_BLOCKS> num_entries;
|
||||
std::array<uint64_t, NUM_BLOCKS> entry_size;
|
||||
|
||||
SharedDataLayout()
|
||||
: num_entries()
|
||||
, entry_size()
|
||||
{
|
||||
}
|
||||
|
||||
void PrintInformation() const
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "-";
|
||||
SimpleLogger().Write(logDEBUG) << "name_offsets_size: " << num_entries[NAME_OFFSETS];
|
||||
SimpleLogger().Write(logDEBUG) << "name_blocks_size: " << num_entries[NAME_BLOCKS];
|
||||
SimpleLogger().Write(logDEBUG) << "name_char_list_size: " << num_entries[NAME_CHAR_LIST];
|
||||
SimpleLogger().Write(logDEBUG) << "name_id_list_size: " << num_entries[NAME_ID_LIST];
|
||||
SimpleLogger().Write(logDEBUG) << "via_node_list_size: " << num_entries[VIA_NODE_LIST];
|
||||
SimpleLogger().Write(logDEBUG) << "graph_node_list_size: " << num_entries[GRAPH_NODE_LIST];
|
||||
SimpleLogger().Write(logDEBUG) << "graph_edge_list_size: " << num_entries[GRAPH_EDGE_LIST];
|
||||
SimpleLogger().Write(logDEBUG) << "timestamp_length: " << num_entries[TIMESTAMP];
|
||||
SimpleLogger().Write(logDEBUG) << "coordinate_list_size: " << num_entries[COORDINATE_LIST];
|
||||
SimpleLogger().Write(logDEBUG) << "turn_instruction_list_size: " << num_entries[TURN_INSTRUCTION];
|
||||
SimpleLogger().Write(logDEBUG) << "travel_mode_list_size: " << num_entries[TRAVEL_MODE];
|
||||
SimpleLogger().Write(logDEBUG) << "r_search_tree_size: " << num_entries[R_SEARCH_TREE];
|
||||
SimpleLogger().Write(logDEBUG) << "geometries_indicators: " << num_entries[GEOMETRIES_INDICATORS]
|
||||
<< "/" << ((num_entries[GEOMETRIES_INDICATORS] / 8) + 1);
|
||||
SimpleLogger().Write(logDEBUG) << "geometries_index_list_size: " << num_entries[GEOMETRIES_INDEX];
|
||||
SimpleLogger().Write(logDEBUG) << "geometries_list_size: " << num_entries[GEOMETRIES_LIST];
|
||||
SimpleLogger().Write(logDEBUG) << "sizeof(checksum): " << entry_size[HSGR_CHECKSUM];
|
||||
|
||||
SimpleLogger().Write(logDEBUG) << "NAME_OFFSETS " << ": " << GetBlockSize(NAME_OFFSETS );
|
||||
SimpleLogger().Write(logDEBUG) << "NAME_BLOCKS " << ": " << GetBlockSize(NAME_BLOCKS );
|
||||
SimpleLogger().Write(logDEBUG) << "NAME_CHAR_LIST " << ": " << GetBlockSize(NAME_CHAR_LIST );
|
||||
SimpleLogger().Write(logDEBUG) << "NAME_ID_LIST " << ": " << GetBlockSize(NAME_ID_LIST );
|
||||
SimpleLogger().Write(logDEBUG) << "VIA_NODE_LIST " << ": " << GetBlockSize(VIA_NODE_LIST );
|
||||
SimpleLogger().Write(logDEBUG) << "GRAPH_NODE_LIST " << ": " << GetBlockSize(GRAPH_NODE_LIST );
|
||||
SimpleLogger().Write(logDEBUG) << "GRAPH_EDGE_LIST " << ": " << GetBlockSize(GRAPH_EDGE_LIST );
|
||||
SimpleLogger().Write(logDEBUG) << "COORDINATE_LIST " << ": " << GetBlockSize(COORDINATE_LIST );
|
||||
SimpleLogger().Write(logDEBUG) << "TURN_INSTRUCTION " << ": " << GetBlockSize(TURN_INSTRUCTION );
|
||||
SimpleLogger().Write(logDEBUG) << "TRAVEL_MODE " << ": " << GetBlockSize(TRAVEL_MODE );
|
||||
SimpleLogger().Write(logDEBUG) << "R_SEARCH_TREE " << ": " << GetBlockSize(R_SEARCH_TREE );
|
||||
SimpleLogger().Write(logDEBUG) << "GEOMETRIES_INDEX " << ": " << GetBlockSize(GEOMETRIES_INDEX );
|
||||
SimpleLogger().Write(logDEBUG) << "GEOMETRIES_LIST " << ": " << GetBlockSize(GEOMETRIES_LIST );
|
||||
SimpleLogger().Write(logDEBUG) << "GEOMETRIES_INDICATORS" << ": " << GetBlockSize(GEOMETRIES_INDICATORS);
|
||||
SimpleLogger().Write(logDEBUG) << "HSGR_CHECKSUM " << ": " << GetBlockSize(HSGR_CHECKSUM );
|
||||
SimpleLogger().Write(logDEBUG) << "TIMESTAMP " << ": " << GetBlockSize(TIMESTAMP );
|
||||
SimpleLogger().Write(logDEBUG) << "FILE_INDEX_PATH " << ": " << GetBlockSize(FILE_INDEX_PATH );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void SetBlockSize(BlockID bid, uint64_t entries)
|
||||
{
|
||||
num_entries[bid] = entries;
|
||||
entry_size[bid] = sizeof(T);
|
||||
}
|
||||
|
||||
inline uint64_t GetBlockSize(BlockID bid) const
|
||||
{
|
||||
// special encoding
|
||||
if (bid == GEOMETRIES_INDICATORS)
|
||||
{
|
||||
return (num_entries[GEOMETRIES_INDICATORS]/32 + 1) * entry_size[GEOMETRIES_INDICATORS];
|
||||
}
|
||||
|
||||
return num_entries[bid] * entry_size[bid];
|
||||
}
|
||||
|
||||
inline uint64_t GetSizeOfLayout() const
|
||||
{
|
||||
return GetBlockOffset(NUM_BLOCKS) + NUM_BLOCKS*2*sizeof(CANARY);
|
||||
}
|
||||
|
||||
inline uint64_t GetBlockOffset(BlockID bid) const
|
||||
{
|
||||
uint64_t result = sizeof(CANARY);
|
||||
for (auto i = 0; i < bid; i++)
|
||||
{
|
||||
result += GetBlockSize((BlockID) i) + 2*sizeof(CANARY);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T, bool WRITE_CANARY=false>
|
||||
inline T* GetBlockPtr(char* shared_memory, BlockID bid)
|
||||
{
|
||||
T* ptr = (T*)(shared_memory + GetBlockOffset(bid));
|
||||
if (WRITE_CANARY)
|
||||
{
|
||||
char* start_canary_ptr = shared_memory + GetBlockOffset(bid) - sizeof(CANARY);
|
||||
char* end_canary_ptr = shared_memory + GetBlockOffset(bid) + GetBlockSize(bid);
|
||||
std::copy(CANARY, CANARY + sizeof(CANARY), start_canary_ptr);
|
||||
std::copy(CANARY, CANARY + sizeof(CANARY), end_canary_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
char* start_canary_ptr = shared_memory + GetBlockOffset(bid) - sizeof(CANARY);
|
||||
char* end_canary_ptr = shared_memory + GetBlockOffset(bid) + GetBlockSize(bid);
|
||||
bool start_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), start_canary_ptr);
|
||||
bool end_canary_alive = std::equal(CANARY, CANARY + sizeof(CANARY), end_canary_ptr);
|
||||
if (!start_canary_alive)
|
||||
{
|
||||
throw OSRMException("Start canary of block corrupted.");
|
||||
}
|
||||
if (!end_canary_alive)
|
||||
{
|
||||
throw OSRMException("End canary of block corrupted.");
|
||||
}
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
};
|
||||
|
||||
enum SharedDataType
|
||||
{ CURRENT_REGIONS,
|
||||
LAYOUT_1,
|
||||
DATA_1,
|
||||
LAYOUT_2,
|
||||
DATA_2,
|
||||
LAYOUT_NONE,
|
||||
DATA_NONE };
|
||||
|
||||
struct SharedDataTimestamp
|
||||
{
|
||||
SharedDataType layout;
|
||||
SharedDataType data;
|
||||
unsigned timestamp;
|
||||
};
|
||||
|
||||
#endif /* SHARED_DATA_TYPE_H_ */
|
||||
@@ -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 <osrm/Reply.h>
|
||||
|
||||
#include "../../Util/cast.hpp"
|
||||
|
||||
namespace http
|
||||
{
|
||||
|
||||
void Reply::SetSize(const unsigned size)
|
||||
{
|
||||
for (Header &h : headers)
|
||||
{
|
||||
if ("Content-Length" == h.name)
|
||||
{
|
||||
h.value = cast::integral_to_string(size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the size of the uncompressed output.
|
||||
void Reply::SetUncompressedSize() { SetSize(static_cast<unsigned>(content.size())); }
|
||||
|
||||
std::vector<boost::asio::const_buffer> Reply::ToBuffers()
|
||||
{
|
||||
std::vector<boost::asio::const_buffer> buffers;
|
||||
buffers.push_back(ToBuffer(status));
|
||||
for (const Header &h : headers)
|
||||
{
|
||||
buffers.push_back(boost::asio::buffer(h.name));
|
||||
buffers.push_back(boost::asio::buffer(seperators));
|
||||
buffers.push_back(boost::asio::buffer(h.value));
|
||||
buffers.push_back(boost::asio::buffer(crlf));
|
||||
}
|
||||
buffers.push_back(boost::asio::buffer(crlf));
|
||||
buffers.push_back(boost::asio::buffer(content));
|
||||
return buffers;
|
||||
}
|
||||
|
||||
std::vector<boost::asio::const_buffer> Reply::HeaderstoBuffers()
|
||||
{
|
||||
std::vector<boost::asio::const_buffer> buffers;
|
||||
buffers.push_back(ToBuffer(status));
|
||||
for (std::size_t i = 0; i < headers.size(); ++i)
|
||||
{
|
||||
Header ¤t_header = headers[i];
|
||||
buffers.push_back(boost::asio::buffer(current_header.name));
|
||||
buffers.push_back(boost::asio::buffer(seperators));
|
||||
buffers.push_back(boost::asio::buffer(current_header.value));
|
||||
buffers.push_back(boost::asio::buffer(crlf));
|
||||
}
|
||||
buffers.push_back(boost::asio::buffer(crlf));
|
||||
return buffers;
|
||||
}
|
||||
|
||||
Reply Reply::StockReply(Reply::status_type status)
|
||||
{
|
||||
Reply reply;
|
||||
reply.status = status;
|
||||
reply.content.clear();
|
||||
|
||||
const std::string status_string = reply.ToString(status);
|
||||
reply.content.insert(reply.content.end(), status_string.begin(), status_string.end());
|
||||
reply.headers.emplace_back("Access-Control-Allow-Origin", "*");
|
||||
reply.headers.emplace_back("Content-Length", cast::integral_to_string(reply.content.size()));
|
||||
reply.headers.emplace_back("Content-Type", "text/html");
|
||||
return reply;
|
||||
}
|
||||
|
||||
std::string Reply::ToString(Reply::status_type status)
|
||||
{
|
||||
if (Reply::ok == status)
|
||||
{
|
||||
return okHTML;
|
||||
}
|
||||
if (Reply::badRequest == status)
|
||||
{
|
||||
return badRequestHTML;
|
||||
}
|
||||
return internalServerErrorHTML;
|
||||
}
|
||||
|
||||
boost::asio::const_buffer Reply::ToBuffer(Reply::status_type status)
|
||||
{
|
||||
if (Reply::ok == status)
|
||||
{
|
||||
return boost::asio::buffer(okString);
|
||||
}
|
||||
if (Reply::internalServerError == status)
|
||||
{
|
||||
return boost::asio::buffer(internalServerErrorString);
|
||||
}
|
||||
return boost::asio::buffer(badRequestString);
|
||||
}
|
||||
|
||||
Reply::Reply() : status(ok) {}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "RequestHandler.h"
|
||||
|
||||
#include "APIGrammar.h"
|
||||
#include "Http/Request.h"
|
||||
|
||||
#include "../data_structures/json_container.hpp"
|
||||
#include "../Library/OSRM.h"
|
||||
#include "../Util/json_renderer.hpp"
|
||||
#include "../Util/simple_logger.hpp"
|
||||
#include "../Util/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(<ime);
|
||||
|
||||
// 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; }
|
||||
@@ -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'; }
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef REQUEST_PARSER_H
|
||||
#define REQUEST_PARSER_H
|
||||
|
||||
#include "Http/CompressionType.h"
|
||||
#include <osrm/Header.h>
|
||||
|
||||
#include <boost/logic/tribool.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
namespace http
|
||||
{
|
||||
|
||||
struct Request;
|
||||
|
||||
class RequestParser
|
||||
{
|
||||
public:
|
||||
RequestParser();
|
||||
void Reset();
|
||||
|
||||
boost::tuple<boost::tribool, char *>
|
||||
Parse(Request &req, char *begin, char *end, CompressionType &compression_type);
|
||||
|
||||
private:
|
||||
boost::tribool consume(Request &req, char input, CompressionType &compression_type);
|
||||
|
||||
inline bool isChar(int c);
|
||||
|
||||
inline bool isCTL(int c);
|
||||
|
||||
inline bool isTSpecial(int c);
|
||||
|
||||
inline bool isDigit(int c);
|
||||
|
||||
enum state
|
||||
{ method_start,
|
||||
method,
|
||||
uri_start,
|
||||
uri,
|
||||
http_version_h,
|
||||
http_version_t_1,
|
||||
http_version_t_2,
|
||||
http_version_p,
|
||||
http_version_slash,
|
||||
http_version_major_start,
|
||||
http_version_major,
|
||||
http_version_minor_start,
|
||||
http_version_minor,
|
||||
expecting_newline_1,
|
||||
header_line_start,
|
||||
header_lws,
|
||||
header_name,
|
||||
space_before_header_value,
|
||||
header_value,
|
||||
expecting_newline_2,
|
||||
expecting_newline_3 } state_;
|
||||
|
||||
Header header;
|
||||
};
|
||||
|
||||
} // namespace http
|
||||
|
||||
#endif // REQUEST_PARSER_H
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "../../algorithms/douglas_peucker.hpp"
|
||||
#include "../../data_structures/segment_information.hpp"
|
||||
#include "../../Include/osrm/Coordinate.h"
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_case_template.hpp>
|
||||
#include <boost/mpl/list.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(douglas_peucker)
|
||||
|
||||
SegmentInformation getTestInfo(int lat, int lon, bool necessary)
|
||||
{
|
||||
return SegmentInformation(FixedPointCoordinate(lat, lon),
|
||||
0, 0, 0, TurnInstruction::HeadOn, necessary, false, 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(all_necessary_test)
|
||||
{
|
||||
/*
|
||||
* x
|
||||
* / \
|
||||
* x \
|
||||
* / \
|
||||
* x x
|
||||
*/
|
||||
std::vector<SegmentInformation> info = {
|
||||
getTestInfo(5, 5, true),
|
||||
getTestInfo(6, 6, true),
|
||||
getTestInfo(10, 10, true),
|
||||
getTestInfo(5, 15, true)
|
||||
};
|
||||
DouglasPeucker dp;
|
||||
for (unsigned z = 0; z < DOUGLAS_PEUCKER_THRESHOLDS.size(); z++)
|
||||
{
|
||||
dp.Run(info, z);
|
||||
for (const auto& i : info)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(i.necessary, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(remove_second_node_test)
|
||||
{
|
||||
DouglasPeucker dp;
|
||||
for (unsigned z = 0; z < DOUGLAS_PEUCKER_THRESHOLDS.size(); z++)
|
||||
{
|
||||
/*
|
||||
* x--x
|
||||
* | \
|
||||
* x-x x
|
||||
* |
|
||||
* x
|
||||
*/
|
||||
std::vector<SegmentInformation> info = {
|
||||
getTestInfo(5 * COORDINATE_PRECISION,
|
||||
5 * COORDINATE_PRECISION, true),
|
||||
getTestInfo(5 * COORDINATE_PRECISION,
|
||||
5 * COORDINATE_PRECISION + DOUGLAS_PEUCKER_THRESHOLDS[z], false),
|
||||
getTestInfo(10 * COORDINATE_PRECISION,
|
||||
10 * COORDINATE_PRECISION, false),
|
||||
getTestInfo(10 * COORDINATE_PRECISION,
|
||||
10 + COORDINATE_PRECISION + DOUGLAS_PEUCKER_THRESHOLDS[z] * 2, false),
|
||||
getTestInfo(5 * COORDINATE_PRECISION,
|
||||
15 * COORDINATE_PRECISION, false),
|
||||
getTestInfo(5 * COORDINATE_PRECISION + DOUGLAS_PEUCKER_THRESHOLDS[z],
|
||||
15 * COORDINATE_PRECISION, true),
|
||||
};
|
||||
BOOST_TEST_MESSAGE("Threshold (" << z << "): " << DOUGLAS_PEUCKER_THRESHOLDS[z]);
|
||||
dp.Run(info, z);
|
||||
BOOST_CHECK_EQUAL(info[0].necessary, true);
|
||||
BOOST_CHECK_EQUAL(info[1].necessary, false);
|
||||
BOOST_CHECK_EQUAL(info[2].necessary, true);
|
||||
BOOST_CHECK_EQUAL(info[3].necessary, true);
|
||||
BOOST_CHECK_EQUAL(info[4].necessary, false);
|
||||
BOOST_CHECK_EQUAL(info[5].necessary, true);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -1,494 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "../../data_structures/static_rtree.hpp"
|
||||
#include "../../data_structures/query_node.hpp"
|
||||
#include "../../data_structures/edge_based_node.hpp"
|
||||
#include "../../Util/floating_point.hpp"
|
||||
#include "../../typedefs.h"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/test_case_template.hpp>
|
||||
#include <boost/mpl/list.hpp>
|
||||
|
||||
#include <random>
|
||||
#include <unordered_set>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(static_rtree)
|
||||
|
||||
constexpr uint32_t TEST_BRANCHING_FACTOR = 8;
|
||||
constexpr uint32_t TEST_LEAF_NODE_SIZE = 64;
|
||||
|
||||
typedef EdgeBasedNode TestData;
|
||||
typedef StaticRTree<TestData,
|
||||
std::vector<FixedPointCoordinate>,
|
||||
false,
|
||||
TEST_BRANCHING_FACTOR,
|
||||
TEST_LEAF_NODE_SIZE> TestStaticRTree;
|
||||
|
||||
// Choosen by a fair W20 dice roll (this value is completely arbitrary)
|
||||
constexpr unsigned RANDOM_SEED = 42;
|
||||
static const int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION;
|
||||
static const int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION;
|
||||
static const int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION;
|
||||
static const int32_t WORLD_MAX_LON = 180 * COORDINATE_PRECISION;
|
||||
|
||||
class LinearSearchNN
|
||||
{
|
||||
public:
|
||||
LinearSearchNN(const std::shared_ptr<std::vector<FixedPointCoordinate>> &coords,
|
||||
const std::vector<TestData> &edges)
|
||||
: coords(coords), edges(edges)
|
||||
{
|
||||
}
|
||||
|
||||
bool LocateClosestEndPointForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
FixedPointCoordinate &result_coordinate,
|
||||
const unsigned zoom_level)
|
||||
{
|
||||
bool ignore_tiny_components = (zoom_level <= 14);
|
||||
|
||||
float min_dist = std::numeric_limits<float>::max();
|
||||
FixedPointCoordinate min_coord;
|
||||
for (const TestData &e : edges)
|
||||
{
|
||||
if (ignore_tiny_components && e.is_in_tiny_cc)
|
||||
continue;
|
||||
|
||||
const FixedPointCoordinate &start = coords->at(e.u);
|
||||
const FixedPointCoordinate &end = coords->at(e.v);
|
||||
float distance = FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
input_coordinate.lat, input_coordinate.lon, start.lat, start.lon);
|
||||
if (distance < min_dist)
|
||||
{
|
||||
min_coord = start;
|
||||
min_dist = distance;
|
||||
}
|
||||
|
||||
distance = FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
input_coordinate.lat, input_coordinate.lon, end.lat, end.lon);
|
||||
if (distance < min_dist)
|
||||
{
|
||||
min_coord = end;
|
||||
min_dist = distance;
|
||||
}
|
||||
}
|
||||
|
||||
result_coordinate = min_coord;
|
||||
return result_coordinate.is_valid();
|
||||
}
|
||||
|
||||
bool FindPhantomNodeForCoordinate(const FixedPointCoordinate &input_coordinate,
|
||||
PhantomNode &result_phantom_node,
|
||||
const unsigned zoom_level)
|
||||
{
|
||||
bool ignore_tiny_components = (zoom_level <= 14);
|
||||
|
||||
float min_dist = std::numeric_limits<float>::max();
|
||||
TestData nearest_edge;
|
||||
for (const TestData &e : edges)
|
||||
{
|
||||
if (ignore_tiny_components && e.is_in_tiny_cc)
|
||||
continue;
|
||||
|
||||
float current_ratio = 0.;
|
||||
FixedPointCoordinate nearest;
|
||||
const float current_perpendicular_distance =
|
||||
FixedPointCoordinate::ComputePerpendicularDistance(
|
||||
coords->at(e.u), coords->at(e.v), input_coordinate, nearest, current_ratio);
|
||||
|
||||
if ((current_perpendicular_distance < min_dist) &&
|
||||
!osrm::epsilon_compare(current_perpendicular_distance, min_dist))
|
||||
{ // found a new minimum
|
||||
min_dist = current_perpendicular_distance;
|
||||
result_phantom_node = {e.forward_edge_based_node_id,
|
||||
e.reverse_edge_based_node_id,
|
||||
e.name_id,
|
||||
e.forward_weight,
|
||||
e.reverse_weight,
|
||||
e.forward_offset,
|
||||
e.reverse_offset,
|
||||
e.packed_geometry_id,
|
||||
nearest,
|
||||
e.fwd_segment_position,
|
||||
e.forward_travel_mode,
|
||||
e.backward_travel_mode};
|
||||
nearest_edge = e;
|
||||
}
|
||||
}
|
||||
|
||||
if (result_phantom_node.location.is_valid())
|
||||
{
|
||||
// Hack to fix rounding errors and wandering via nodes.
|
||||
if (1 == std::abs(input_coordinate.lon - result_phantom_node.location.lon))
|
||||
{
|
||||
result_phantom_node.location.lon = input_coordinate.lon;
|
||||
}
|
||||
if (1 == std::abs(input_coordinate.lat - result_phantom_node.location.lat))
|
||||
{
|
||||
result_phantom_node.location.lat = input_coordinate.lat;
|
||||
}
|
||||
|
||||
const float distance_1 = FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
coords->at(nearest_edge.u), result_phantom_node.location);
|
||||
const float distance_2 = FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
coords->at(nearest_edge.u), coords->at(nearest_edge.v));
|
||||
const float ratio = std::min(1.f, distance_1 / distance_2);
|
||||
|
||||
if (SPECIAL_NODEID != result_phantom_node.forward_node_id)
|
||||
{
|
||||
result_phantom_node.forward_weight *= ratio;
|
||||
}
|
||||
if (SPECIAL_NODEID != result_phantom_node.reverse_node_id)
|
||||
{
|
||||
result_phantom_node.reverse_weight *= (1. - ratio);
|
||||
}
|
||||
}
|
||||
|
||||
return result_phantom_node.location.is_valid();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::shared_ptr<std::vector<FixedPointCoordinate>> &coords;
|
||||
const std::vector<TestData> &edges;
|
||||
};
|
||||
|
||||
template <unsigned NUM_NODES, unsigned NUM_EDGES> struct RandomGraphFixture
|
||||
{
|
||||
struct TupleHash
|
||||
{
|
||||
typedef std::pair<unsigned, unsigned> argument_type;
|
||||
typedef std::size_t result_type;
|
||||
|
||||
result_type operator()(const argument_type &t) const
|
||||
{
|
||||
std::size_t val{0};
|
||||
boost::hash_combine(val, t.first);
|
||||
boost::hash_combine(val, t.second);
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
RandomGraphFixture() : coords(std::make_shared<std::vector<FixedPointCoordinate>>())
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Constructing " << NUM_NODES << " nodes and " << NUM_EDGES << " edges.");
|
||||
|
||||
std::mt19937 g(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);
|
||||
|
||||
for (unsigned i = 0; i < NUM_NODES; i++)
|
||||
{
|
||||
int lat = lat_udist(g);
|
||||
int lon = lon_udist(g);
|
||||
nodes.emplace_back(QueryNode(lat, lon, i));
|
||||
coords->emplace_back(FixedPointCoordinate(lat, lon));
|
||||
}
|
||||
|
||||
std::uniform_int_distribution<> edge_udist(0, nodes.size() - 1);
|
||||
|
||||
std::unordered_set<std::pair<unsigned, unsigned>, TupleHash> used_edges;
|
||||
|
||||
while (edges.size() < NUM_EDGES)
|
||||
{
|
||||
TestData data;
|
||||
data.u = edge_udist(g);
|
||||
data.v = edge_udist(g);
|
||||
if (used_edges.find(std::pair<unsigned, unsigned>(
|
||||
std::min(data.u, data.v), std::max(data.u, data.v))) == used_edges.end())
|
||||
{
|
||||
data.is_in_tiny_cc = false;
|
||||
edges.emplace_back(data);
|
||||
used_edges.emplace(std::min(data.u, data.v), std::max(data.u, data.v));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<QueryNode> nodes;
|
||||
std::shared_ptr<std::vector<FixedPointCoordinate>> coords;
|
||||
std::vector<TestData> edges;
|
||||
};
|
||||
|
||||
struct GraphFixture
|
||||
{
|
||||
GraphFixture(const std::vector<std::pair<float, float>> &input_coords,
|
||||
const std::vector<std::pair<unsigned, unsigned>> &input_edges)
|
||||
: coords(std::make_shared<std::vector<FixedPointCoordinate>>())
|
||||
{
|
||||
|
||||
for (unsigned i = 0; i < input_coords.size(); i++)
|
||||
{
|
||||
FixedPointCoordinate c(input_coords[i].first * COORDINATE_PRECISION,
|
||||
input_coords[i].second * COORDINATE_PRECISION);
|
||||
coords->emplace_back(c);
|
||||
nodes.emplace_back(QueryNode(c.lat, c.lon, i));
|
||||
}
|
||||
|
||||
for (const auto &pair : input_edges)
|
||||
{
|
||||
TestData d;
|
||||
d.u = pair.first;
|
||||
d.v = pair.second;
|
||||
edges.emplace_back(d);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<QueryNode> nodes;
|
||||
std::shared_ptr<std::vector<FixedPointCoordinate>> coords;
|
||||
std::vector<TestData> edges;
|
||||
};
|
||||
|
||||
typedef RandomGraphFixture<TEST_LEAF_NODE_SIZE * 3, TEST_LEAF_NODE_SIZE / 2>
|
||||
TestRandomGraphFixture_LeafHalfFull;
|
||||
typedef RandomGraphFixture<TEST_LEAF_NODE_SIZE * 5, TEST_LEAF_NODE_SIZE>
|
||||
TestRandomGraphFixture_LeafFull;
|
||||
typedef RandomGraphFixture<TEST_LEAF_NODE_SIZE * 10, TEST_LEAF_NODE_SIZE * 2>
|
||||
TestRandomGraphFixture_TwoLeaves;
|
||||
typedef RandomGraphFixture<TEST_LEAF_NODE_SIZE * TEST_BRANCHING_FACTOR * 3,
|
||||
TEST_LEAF_NODE_SIZE * TEST_BRANCHING_FACTOR>
|
||||
TestRandomGraphFixture_Branch;
|
||||
typedef RandomGraphFixture<TEST_LEAF_NODE_SIZE * TEST_BRANCHING_FACTOR * 3,
|
||||
TEST_LEAF_NODE_SIZE * TEST_BRANCHING_FACTOR * 2>
|
||||
TestRandomGraphFixture_MultipleLevels;
|
||||
|
||||
template <typename RTreeT>
|
||||
void simple_verify_rtree(RTreeT &rtree,
|
||||
const std::shared_ptr<std::vector<FixedPointCoordinate>> &coords,
|
||||
const std::vector<TestData> &edges)
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Verify end points");
|
||||
for (const auto &e : edges)
|
||||
{
|
||||
FixedPointCoordinate result_u, result_v;
|
||||
const FixedPointCoordinate &pu = coords->at(e.u);
|
||||
const FixedPointCoordinate &pv = coords->at(e.v);
|
||||
bool found_u = rtree.LocateClosestEndPointForCoordinate(pu, result_u, 1);
|
||||
bool found_v = rtree.LocateClosestEndPointForCoordinate(pv, result_v, 1);
|
||||
BOOST_CHECK(found_u && found_v);
|
||||
float dist_u = FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
result_u.lat, result_u.lon, pu.lat, pu.lon);
|
||||
BOOST_CHECK_LE(dist_u, std::numeric_limits<float>::epsilon());
|
||||
float dist_v = FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
result_v.lat, result_v.lon, pv.lat, pv.lon);
|
||||
BOOST_CHECK_LE(dist_v, std::numeric_limits<float>::epsilon());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RTreeT>
|
||||
void sampling_verify_rtree(RTreeT &rtree, LinearSearchNN &lsnn, unsigned num_samples)
|
||||
{
|
||||
std::mt19937 g(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_samples; i++)
|
||||
{
|
||||
queries.emplace_back(FixedPointCoordinate(lat_udist(g), lon_udist(g)));
|
||||
}
|
||||
|
||||
BOOST_TEST_MESSAGE("Sampling queries");
|
||||
for (const auto &q : queries)
|
||||
{
|
||||
FixedPointCoordinate result_rtree;
|
||||
rtree.LocateClosestEndPointForCoordinate(q, result_rtree, 1);
|
||||
FixedPointCoordinate result_ln;
|
||||
lsnn.LocateClosestEndPointForCoordinate(q, result_ln, 1);
|
||||
BOOST_CHECK_EQUAL(result_ln, result_rtree);
|
||||
|
||||
PhantomNode phantom_rtree;
|
||||
rtree.FindPhantomNodeForCoordinate(q, phantom_rtree, 1);
|
||||
PhantomNode phantom_ln;
|
||||
lsnn.FindPhantomNodeForCoordinate(q, phantom_ln, 1);
|
||||
BOOST_CHECK_EQUAL(phantom_rtree, phantom_ln);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FixtureT, typename RTreeT = TestStaticRTree>
|
||||
void build_rtree(const std::string &prefix,
|
||||
FixtureT *fixture,
|
||||
std::string &leaves_path,
|
||||
std::string &nodes_path)
|
||||
{
|
||||
nodes_path = prefix + ".ramIndex";
|
||||
leaves_path = prefix + ".fileIndex";
|
||||
const std::string coords_path = prefix + ".nodes";
|
||||
|
||||
boost::filesystem::ofstream node_stream(coords_path, std::ios::binary);
|
||||
const unsigned num_nodes = fixture->nodes.size();
|
||||
node_stream.write((char *)&num_nodes, sizeof(unsigned));
|
||||
node_stream.write((char *)&(fixture->nodes[0]), num_nodes * sizeof(QueryNode));
|
||||
node_stream.close();
|
||||
|
||||
RTreeT r(fixture->edges, nodes_path, leaves_path, fixture->nodes);
|
||||
}
|
||||
|
||||
template <typename FixtureT, typename RTreeT = TestStaticRTree>
|
||||
void construction_test(const std::string &prefix, FixtureT *fixture)
|
||||
{
|
||||
std::string leaves_path;
|
||||
std::string nodes_path;
|
||||
build_rtree<FixtureT, RTreeT>(prefix, fixture, leaves_path, nodes_path);
|
||||
RTreeT rtree(nodes_path, leaves_path, fixture->coords);
|
||||
LinearSearchNN lsnn(fixture->coords, fixture->edges);
|
||||
|
||||
simple_verify_rtree(rtree, fixture->coords, fixture->edges);
|
||||
sampling_verify_rtree(rtree, lsnn, 100);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(construct_half_leaf_test, TestRandomGraphFixture_LeafHalfFull)
|
||||
{
|
||||
construction_test("test_1", this);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(construct_full_leaf_test, TestRandomGraphFixture_LeafFull)
|
||||
{
|
||||
construction_test("test_2", this);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(construct_two_leaves_test, TestRandomGraphFixture_TwoLeaves)
|
||||
{
|
||||
construction_test("test_3", this);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(construct_branch_test, TestRandomGraphFixture_Branch)
|
||||
{
|
||||
construction_test("test_4", this);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(construct_multiple_levels_test, TestRandomGraphFixture_MultipleLevels)
|
||||
{
|
||||
construction_test("test_5", this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Bug: If you querry a point that lies between two BBs that have a gap,
|
||||
* one BB will be pruned, even if it could contain a nearer match.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(regression_test)
|
||||
{
|
||||
typedef std::pair<float, float> Coord;
|
||||
typedef std::pair<unsigned, unsigned> Edge;
|
||||
GraphFixture fixture({
|
||||
Coord(40.0, 0.0),
|
||||
Coord(35.0, 5.0),
|
||||
|
||||
Coord(5.0, 5.0),
|
||||
Coord(0.0, 10.0),
|
||||
|
||||
Coord(20.0, 10.0),
|
||||
Coord(20.0, 5.0),
|
||||
|
||||
Coord(40.0, 100.0),
|
||||
Coord(35.0, 105.0),
|
||||
|
||||
Coord(5.0, 105.0),
|
||||
Coord(0.0, 110.0),
|
||||
},
|
||||
{Edge(0, 1), Edge(2, 3), Edge(4, 5), Edge(6, 7), Edge(8, 9)});
|
||||
|
||||
typedef StaticRTree<TestData, std::vector<FixedPointCoordinate>, false, 2, 3> MiniStaticRTree;
|
||||
|
||||
std::string leaves_path;
|
||||
std::string nodes_path;
|
||||
build_rtree<GraphFixture, MiniStaticRTree>(
|
||||
"test_regression", &fixture, leaves_path, nodes_path);
|
||||
MiniStaticRTree rtree(nodes_path, leaves_path, fixture.coords);
|
||||
|
||||
// query a node just right of the center of the gap
|
||||
FixedPointCoordinate input(20.0 * COORDINATE_PRECISION, 55.1 * COORDINATE_PRECISION);
|
||||
FixedPointCoordinate result;
|
||||
rtree.LocateClosestEndPointForCoordinate(input, result, 1);
|
||||
FixedPointCoordinate result_ln;
|
||||
LinearSearchNN lsnn(fixture.coords, fixture.edges);
|
||||
lsnn.LocateClosestEndPointForCoordinate(input, result_ln, 1);
|
||||
|
||||
BOOST_CHECK_EQUAL(result_ln, result);
|
||||
}
|
||||
|
||||
void TestRectangle(double width, double height, double center_lat, double center_lon)
|
||||
{
|
||||
FixedPointCoordinate center(center_lat * COORDINATE_PRECISION,
|
||||
center_lon * COORDINATE_PRECISION);
|
||||
|
||||
TestStaticRTree::RectangleT rect;
|
||||
rect.min_lat = center.lat - height / 2.0 * COORDINATE_PRECISION;
|
||||
rect.max_lat = center.lat + height / 2.0 * COORDINATE_PRECISION;
|
||||
rect.min_lon = center.lon - width / 2.0 * COORDINATE_PRECISION;
|
||||
rect.max_lon = center.lon + width / 2.0 * COORDINATE_PRECISION;
|
||||
|
||||
unsigned offset = 5 * COORDINATE_PRECISION;
|
||||
FixedPointCoordinate north(rect.max_lat + offset, center.lon);
|
||||
FixedPointCoordinate south(rect.min_lat - offset, center.lon);
|
||||
FixedPointCoordinate west(center.lat, rect.min_lon - offset);
|
||||
FixedPointCoordinate east(center.lat, rect.max_lon + offset);
|
||||
FixedPointCoordinate north_east(rect.max_lat + offset, rect.max_lon + offset);
|
||||
FixedPointCoordinate north_west(rect.max_lat + offset, rect.min_lon - offset);
|
||||
FixedPointCoordinate south_east(rect.min_lat - offset, rect.max_lon + offset);
|
||||
FixedPointCoordinate south_west(rect.min_lat - offset, rect.min_lon - offset);
|
||||
|
||||
/* Distance to line segments of rectangle */
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(north),
|
||||
FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
north, FixedPointCoordinate(rect.max_lat, north.lon)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(south),
|
||||
FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
south, FixedPointCoordinate(rect.min_lat, south.lon)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(west),
|
||||
FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
west, FixedPointCoordinate(west.lat, rect.min_lon)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(east),
|
||||
FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
east, FixedPointCoordinate(east.lat, rect.max_lon)));
|
||||
|
||||
/* Distance to corner points */
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(north_east),
|
||||
FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
north_east, FixedPointCoordinate(rect.max_lat, rect.max_lon)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(north_west),
|
||||
FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
north_west, FixedPointCoordinate(rect.max_lat, rect.min_lon)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(south_east),
|
||||
FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
south_east, FixedPointCoordinate(rect.min_lat, rect.max_lon)));
|
||||
BOOST_CHECK_EQUAL(rect.GetMinDist(south_west),
|
||||
FixedPointCoordinate::ApproximateEuclideanDistance(
|
||||
south_west, FixedPointCoordinate(rect.min_lat, rect.min_lon)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(rectangle_test)
|
||||
{
|
||||
TestRectangle(10, 10, 5, 5);
|
||||
TestRectangle(10, 10, -5, 5);
|
||||
TestRectangle(10, 10, 5, -5);
|
||||
TestRectangle(10, 10, -5, -5);
|
||||
TestRectangle(10, 10, 0, 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -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
|
||||
// inline void validate(
|
||||
// boost::any & v,
|
||||
// const std::vector<std::string> & values,
|
||||
// boost::filesystem::path *,
|
||||
// int
|
||||
// ) {
|
||||
// boost::program_options::validators::check_first_occurrence(v);
|
||||
// const std::string & input_string =
|
||||
// boost::program_options::validators::get_single_string(values);
|
||||
// if(boost::filesystem::is_regular_file(input_string)) {
|
||||
// v = boost::any(boost::filesystem::path(input_string));
|
||||
// } else {
|
||||
// throw OSRMException(input_string + " not found");
|
||||
// }
|
||||
// }
|
||||
|
||||
// adapted from:
|
||||
// http://stackoverflow.com/questions/1746136/how-do-i-normalize-a-pathname-using-boostfilesystem
|
||||
inline boost::filesystem::path
|
||||
portable_canonical(const boost::filesystem::path &relative_path,
|
||||
const boost::filesystem::path ¤t_path = boost::filesystem::current_path())
|
||||
{
|
||||
const boost::filesystem::path absolute_path =
|
||||
boost::filesystem::absolute(relative_path, current_path);
|
||||
|
||||
boost::filesystem::path canonical_path;
|
||||
for (auto path_iterator = absolute_path.begin(); path_iterator != absolute_path.end();
|
||||
++path_iterator)
|
||||
{
|
||||
if (".." == path_iterator->string())
|
||||
{
|
||||
// /a/b/.. is not necessarily /a if b is a symbolic link
|
||||
if (boost::filesystem::is_symlink(canonical_path))
|
||||
{
|
||||
canonical_path /= *path_iterator;
|
||||
}
|
||||
else if (".." == canonical_path.filename())
|
||||
{
|
||||
// /a/b/../.. is not /a/b/.. under most circumstances
|
||||
// We can end up with ..s in our result because of symbolic links
|
||||
canonical_path /= *path_iterator;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise it should be safe to resolve the parent
|
||||
canonical_path = canonical_path.parent_path();
|
||||
}
|
||||
}
|
||||
else if ("." == path_iterator->string())
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just cat other path entries
|
||||
canonical_path /= *path_iterator;
|
||||
}
|
||||
}
|
||||
BOOST_ASSERT(canonical_path.is_absolute());
|
||||
BOOST_ASSERT(boost::filesystem::exists(canonical_path));
|
||||
return canonical_path;
|
||||
}
|
||||
|
||||
#if BOOST_FILESYSTEM_VERSION < 3
|
||||
|
||||
inline path temp_directory_path()
|
||||
{
|
||||
char *buffer;
|
||||
buffer = tmpnam(nullptr);
|
||||
|
||||
return path(buffer);
|
||||
}
|
||||
|
||||
inline path unique_path(const path &) { return temp_directory_path(); }
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOOST_FILESYSTEM_VERSION
|
||||
#define BOOST_FILESYSTEM_VERSION 3
|
||||
#endif
|
||||
|
||||
inline void AssertPathExists(const boost::filesystem::path &path)
|
||||
{
|
||||
if (!boost::filesystem::is_regular_file(path))
|
||||
{
|
||||
throw OSRMException(path.string() + " not found.");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BOOST_FILE_SYSTEM_FIX_H */
|
||||
@@ -1,279 +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 DATA_STORE_OPTIONS_H
|
||||
#define DATA_STORE_OPTIONS_H
|
||||
|
||||
#include "BoostFileSystemFix.h"
|
||||
#include "GitDescription.h"
|
||||
#include "IniFileUtil.h"
|
||||
#include "OSRMException.h"
|
||||
#include "simple_logger.hpp"
|
||||
|
||||
#include <osrm/ServerPaths.h>
|
||||
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
// generate boost::program_options object for the routing part
|
||||
bool GenerateDataStoreOptions(const int argc, const char *argv[], ServerPaths &paths)
|
||||
{
|
||||
// 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")
|
||||
("springclean,s", "Remove all regions in shared memory")("config,c",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["config"])
|
||||
->default_value("server.ini"),
|
||||
"Path to a configuration file");
|
||||
|
||||
// declare a group of options that will be allowed both on command line
|
||||
// as well as in a config file
|
||||
boost::program_options::options_description config_options("Configuration");
|
||||
config_options.add_options()(
|
||||
"hsgrdata",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["hsgrdata"]),
|
||||
".hsgr file")("nodesdata",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["nodesdata"]),
|
||||
".nodes file")(
|
||||
"edgesdata",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["edgesdata"]),
|
||||
".edges file")("geometry",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["geometry"]),
|
||||
".geometry file")(
|
||||
"ramindex",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["ramindex"]),
|
||||
".ramIndex file")(
|
||||
"fileindex",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["fileindex"]),
|
||||
".fileIndex file")(
|
||||
"namesdata",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["namesdata"]),
|
||||
".names file")("timestamp",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["timestamp"]),
|
||||
".timestamp file");
|
||||
|
||||
// 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()(
|
||||
"base,b",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["base"]),
|
||||
"base path to .osrm file");
|
||||
|
||||
// positional option
|
||||
boost::program_options::positional_options_description positional_options;
|
||||
positional_options.add("base", 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]) + " [<options>] <configuration>");
|
||||
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);
|
||||
|
||||
const bool parameter_present = (paths.find("hsgrdata") != paths.end() &&
|
||||
!paths.find("hsgrdata")->second.string().empty()) ||
|
||||
(paths.find("nodesdata") != paths.end() &&
|
||||
!paths.find("nodesdata")->second.string().empty()) ||
|
||||
(paths.find("edgesdata") != paths.end() &&
|
||||
!paths.find("edgesdata")->second.string().empty()) ||
|
||||
(paths.find("geometry") != paths.end() &&
|
||||
!paths.find("geometry")->second.string().empty()) ||
|
||||
(paths.find("ramindex") != paths.end() &&
|
||||
!paths.find("ramindex")->second.string().empty()) ||
|
||||
(paths.find("fileindex") != paths.end() &&
|
||||
!paths.find("fileindex")->second.string().empty()) ||
|
||||
(paths.find("timestamp") != paths.end() &&
|
||||
!paths.find("timestamp")->second.string().empty());
|
||||
|
||||
if (parameter_present)
|
||||
{
|
||||
if ((paths.find("config") != paths.end() &&
|
||||
boost::filesystem::is_regular_file(paths.find("config")->second)) ||
|
||||
option_variables.count("base"))
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << "conflicting parameters";
|
||||
SimpleLogger().Write() << visible_options;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// parse config file
|
||||
ServerPaths::iterator path_iterator = paths.find("config");
|
||||
if (path_iterator != paths.end() && boost::filesystem::is_regular_file(path_iterator->second) &&
|
||||
!option_variables.count("base"))
|
||||
{
|
||||
SimpleLogger().Write() << "Reading options from: " << path_iterator->second.string();
|
||||
std::string ini_file_contents = ReadIniFileAndLowerContents(path_iterator->second);
|
||||
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);
|
||||
}
|
||||
else if (option_variables.count("base"))
|
||||
{
|
||||
path_iterator = paths.find("base");
|
||||
BOOST_ASSERT(paths.end() != path_iterator);
|
||||
std::string base_string = path_iterator->second.string();
|
||||
|
||||
path_iterator = paths.find("hsgrdata");
|
||||
if (path_iterator != paths.end())
|
||||
{
|
||||
path_iterator->second = base_string + ".hsgr";
|
||||
}
|
||||
|
||||
path_iterator = paths.find("nodesdata");
|
||||
if (path_iterator != paths.end())
|
||||
{
|
||||
path_iterator->second = base_string + ".nodes";
|
||||
}
|
||||
|
||||
path_iterator = paths.find("edgesdata");
|
||||
if (path_iterator != paths.end())
|
||||
{
|
||||
path_iterator->second = base_string + ".edges";
|
||||
}
|
||||
|
||||
path_iterator = paths.find("geometry");
|
||||
if (path_iterator != paths.end())
|
||||
{
|
||||
path_iterator->second = base_string + ".geometry";
|
||||
}
|
||||
|
||||
path_iterator = paths.find("ramindex");
|
||||
if (path_iterator != paths.end())
|
||||
{
|
||||
path_iterator->second = base_string + ".ramIndex";
|
||||
}
|
||||
|
||||
path_iterator = paths.find("fileindex");
|
||||
if (path_iterator != paths.end())
|
||||
{
|
||||
path_iterator->second = base_string + ".fileIndex";
|
||||
}
|
||||
|
||||
path_iterator = paths.find("namesdata");
|
||||
if (path_iterator != paths.end())
|
||||
{
|
||||
path_iterator->second = base_string + ".names";
|
||||
}
|
||||
|
||||
path_iterator = paths.find("timestamp");
|
||||
if (path_iterator != paths.end())
|
||||
{
|
||||
path_iterator->second = base_string + ".timestamp";
|
||||
}
|
||||
}
|
||||
|
||||
path_iterator = paths.find("hsgrdata");
|
||||
if (path_iterator == paths.end() || path_iterator->second.string().empty())
|
||||
{
|
||||
throw OSRMException(".hsgr file must be specified");
|
||||
}
|
||||
AssertPathExists(path_iterator->second);
|
||||
|
||||
path_iterator = paths.find("nodesdata");
|
||||
if (path_iterator == paths.end() || path_iterator->second.string().empty())
|
||||
{
|
||||
throw OSRMException(".nodes file must be specified");
|
||||
}
|
||||
AssertPathExists(path_iterator->second);
|
||||
|
||||
path_iterator = paths.find("edgesdata");
|
||||
if (path_iterator == paths.end() || path_iterator->second.string().empty())
|
||||
{
|
||||
throw OSRMException(".edges file must be specified");
|
||||
}
|
||||
AssertPathExists(path_iterator->second);
|
||||
|
||||
path_iterator = paths.find("geometry");
|
||||
if (path_iterator == paths.end() || path_iterator->second.string().empty())
|
||||
{
|
||||
throw OSRMException(".geometry file must be specified");
|
||||
}
|
||||
AssertPathExists(path_iterator->second);
|
||||
|
||||
path_iterator = paths.find("ramindex");
|
||||
if (path_iterator == paths.end() || path_iterator->second.string().empty())
|
||||
{
|
||||
throw OSRMException(".ramindex file must be specified");
|
||||
}
|
||||
AssertPathExists(path_iterator->second);
|
||||
|
||||
path_iterator = paths.find("fileindex");
|
||||
if (path_iterator == paths.end() || path_iterator->second.string().empty())
|
||||
{
|
||||
throw OSRMException(".fileindex file must be specified");
|
||||
}
|
||||
AssertPathExists(path_iterator->second);
|
||||
|
||||
path_iterator = paths.find("namesdata");
|
||||
if (path_iterator == paths.end() || path_iterator->second.string().empty())
|
||||
{
|
||||
throw OSRMException(".names file must be specified");
|
||||
}
|
||||
AssertPathExists(path_iterator->second);
|
||||
|
||||
path_iterator = paths.find("timestamp");
|
||||
if (path_iterator == paths.end() || path_iterator->second.string().empty())
|
||||
{
|
||||
throw OSRMException(".timestamp file must be specified");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* DATA_STORE_OPTIONS_H */
|
||||
@@ -1,59 +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 FINGERPRINT_H
|
||||
#define FINGERPRINT_H
|
||||
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
|
||||
// implements a singleton, i.e. there is one and only one conviguration object
|
||||
class FingerPrint
|
||||
{
|
||||
public:
|
||||
FingerPrint();
|
||||
FingerPrint(const FingerPrint&) = delete;
|
||||
~FingerPrint();
|
||||
const boost::uuids::uuid &GetFingerPrint() const;
|
||||
bool IsMagicNumberOK() const;
|
||||
bool TestGraphUtil(const FingerPrint &other) const;
|
||||
bool TestPrepare(const FingerPrint &other) const;
|
||||
bool TestRTree(const FingerPrint &other) const;
|
||||
bool TestQueryObjects(const FingerPrint &other) const;
|
||||
|
||||
private:
|
||||
const unsigned magic_number;
|
||||
char md5_prepare[33];
|
||||
char md5_tree[33];
|
||||
char md5_graph[33];
|
||||
char md5_objects[33];
|
||||
|
||||
// initialize to {6ba7b810-9dad-11d1-80b4-00c04fd430c8}
|
||||
boost::uuids::uuid named_uuid;
|
||||
bool has_64_bits;
|
||||
};
|
||||
|
||||
#endif /* FingerPrint_H */
|
||||
@@ -1,49 +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 INI_FILE_UTIL_H
|
||||
#define INI_FILE_UTIL_H
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
#include <regex>
|
||||
#include <string>
|
||||
|
||||
// support old capitalized option names by down-casing them with a regex replace
|
||||
inline std::string ReadIniFileAndLowerContents(const boost::filesystem::path &path)
|
||||
{
|
||||
boost::filesystem::fstream config_stream(path);
|
||||
std::string ini_file_content((std::istreambuf_iterator<char>(config_stream)),
|
||||
std::istreambuf_iterator<char>());
|
||||
boost::regex regex( "^([^=]*)" ); //match from start of line to '='
|
||||
std::string format( "\\L$1\\E" ); //replace with downcased substring
|
||||
return boost::regex_replace( ini_file_content, regex, format );
|
||||
}
|
||||
|
||||
#endif // INI_FILE_UTIL_H
|
||||
@@ -1,43 +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 MERCATOR_UTIL_H
|
||||
#define MERCATOR_UTIL_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
inline double y2lat(const double a)
|
||||
{
|
||||
return 180. * M_1_PI * (2. * std::atan(std::exp(a * M_PI / 180.)) - M_PI_2);
|
||||
}
|
||||
|
||||
inline double lat2y(const double a)
|
||||
{
|
||||
return 180. * M_1_PI * std::log(std::tan(M_PI_4 + a * (M_PI / 180.) / 2.));
|
||||
}
|
||||
|
||||
#endif // MERCATOR_UTIL_H
|
||||
@@ -1,46 +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 OSRM_EXCEPTION_H
|
||||
#define OSRM_EXCEPTION_H
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
class OSRMException : public std::exception
|
||||
{
|
||||
public:
|
||||
explicit OSRMException(const char *message) : message(message) {}
|
||||
explicit OSRMException(const std::string &message) : message(message) {}
|
||||
virtual ~OSRMException() throw() {}
|
||||
|
||||
private:
|
||||
virtual const char *what() const throw() { return message.c_str(); }
|
||||
const std::string message;
|
||||
};
|
||||
|
||||
#endif /* OSRM_EXCEPTION_H */
|
||||
@@ -1,279 +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 PROGAM_OPTIONS_H
|
||||
#define PROGAM_OPTIONS_H
|
||||
|
||||
#include "GitDescription.h"
|
||||
#include "IniFileUtil.h"
|
||||
#include "OSRMException.h"
|
||||
#include "simple_logger.hpp"
|
||||
|
||||
#include <osrm/ServerPaths.h>
|
||||
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
const static unsigned INIT_OK_START_ENGINE = 0;
|
||||
const static unsigned INIT_OK_DO_NOT_START_ENGINE = 1;
|
||||
const static unsigned INIT_FAILED = -1;
|
||||
|
||||
inline void populate_base_path(ServerPaths &server_paths)
|
||||
{
|
||||
// populate the server_path object
|
||||
auto path_iterator = server_paths.find("base");
|
||||
|
||||
// if a base path has been set, we populate it.
|
||||
if (path_iterator != server_paths.end())
|
||||
{
|
||||
const std::string base_string = path_iterator->second.string();
|
||||
SimpleLogger().Write() << "populating base path: " << base_string;
|
||||
|
||||
server_paths["hsgrdata"] = base_string + ".hsgr";
|
||||
BOOST_ASSERT(server_paths.find("hsgrdata") != server_paths.end());
|
||||
server_paths["nodesdata"] = base_string + ".nodes";
|
||||
BOOST_ASSERT(server_paths.find("nodesdata") != server_paths.end());
|
||||
server_paths["edgesdata"] = base_string + ".edges";
|
||||
BOOST_ASSERT(server_paths.find("edgesdata") != server_paths.end());
|
||||
server_paths["geometries"] = base_string + ".geometry";
|
||||
BOOST_ASSERT(server_paths.find("geometries") != server_paths.end());
|
||||
server_paths["ramindex"] = base_string + ".ramIndex";
|
||||
BOOST_ASSERT(server_paths.find("ramindex") != server_paths.end());
|
||||
server_paths["fileindex"] = base_string + ".fileIndex";
|
||||
BOOST_ASSERT(server_paths.find("fileindex") != server_paths.end());
|
||||
server_paths["namesdata"] = base_string + ".names";
|
||||
BOOST_ASSERT(server_paths.find("namesdata") != server_paths.end());
|
||||
server_paths["timestamp"] = base_string + ".timestamp";
|
||||
BOOST_ASSERT(server_paths.find("timestamp") != server_paths.end());
|
||||
}
|
||||
|
||||
// check if files are give and whether they exist at all
|
||||
path_iterator = server_paths.find("hsgrdata");
|
||||
if (path_iterator == server_paths.end() ||
|
||||
!boost::filesystem::is_regular_file(path_iterator->second))
|
||||
{
|
||||
if (path_iterator == server_paths.end())
|
||||
{
|
||||
SimpleLogger().Write() << "hsgrdata unset";
|
||||
}
|
||||
if (!boost::filesystem::is_regular_file(path_iterator->second))
|
||||
{
|
||||
SimpleLogger().Write() << "not a regular file";
|
||||
}
|
||||
|
||||
throw OSRMException(".hsgr not found: " + path_iterator->second.string());
|
||||
}
|
||||
|
||||
path_iterator = server_paths.find("nodesdata");
|
||||
if (path_iterator == server_paths.end() ||
|
||||
!boost::filesystem::is_regular_file(path_iterator->second))
|
||||
{
|
||||
throw OSRMException(".nodes not found");
|
||||
}
|
||||
|
||||
path_iterator = server_paths.find("edgesdata");
|
||||
if (path_iterator == server_paths.end() ||
|
||||
!boost::filesystem::is_regular_file(path_iterator->second))
|
||||
{
|
||||
throw OSRMException(".edges not found");
|
||||
}
|
||||
|
||||
path_iterator = server_paths.find("geometries");
|
||||
if (path_iterator == server_paths.end() ||
|
||||
!boost::filesystem::is_regular_file(path_iterator->second))
|
||||
{
|
||||
throw OSRMException(".geometry not found");
|
||||
}
|
||||
|
||||
path_iterator = server_paths.find("ramindex");
|
||||
if (path_iterator == server_paths.end() ||
|
||||
!boost::filesystem::is_regular_file(path_iterator->second))
|
||||
{
|
||||
throw OSRMException(".ramIndex not found");
|
||||
}
|
||||
|
||||
path_iterator = server_paths.find("fileindex");
|
||||
if (path_iterator == server_paths.end() ||
|
||||
!boost::filesystem::is_regular_file(path_iterator->second))
|
||||
{
|
||||
throw OSRMException(".fileIndex not found");
|
||||
}
|
||||
|
||||
path_iterator = server_paths.find("namesdata");
|
||||
if (path_iterator == server_paths.end() ||
|
||||
!boost::filesystem::is_regular_file(path_iterator->second))
|
||||
{
|
||||
throw OSRMException(".namesIndex not found");
|
||||
}
|
||||
|
||||
SimpleLogger().Write() << "HSGR file:\t" << server_paths["hsgrdata"];
|
||||
SimpleLogger().Write(logDEBUG) << "Nodes file:\t" << server_paths["nodesdata"];
|
||||
SimpleLogger().Write(logDEBUG) << "Edges file:\t" << server_paths["edgesdata"];
|
||||
SimpleLogger().Write(logDEBUG) << "Geometry file:\t" << server_paths["geometries"];
|
||||
SimpleLogger().Write(logDEBUG) << "RAM file:\t" << server_paths["ramindex"];
|
||||
SimpleLogger().Write(logDEBUG) << "Index file:\t" << server_paths["fileindex"];
|
||||
SimpleLogger().Write(logDEBUG) << "Names file:\t" << server_paths["namesdata"];
|
||||
SimpleLogger().Write(logDEBUG) << "Timestamp file:\t" << server_paths["timestamp"];
|
||||
}
|
||||
|
||||
// generate boost::program_options object for the routing part
|
||||
inline unsigned GenerateServerProgramOptions(const int argc,
|
||||
const char *argv[],
|
||||
ServerPaths &paths,
|
||||
std::string &ip_address,
|
||||
int &ip_port,
|
||||
int &requested_num_threads,
|
||||
bool &use_shared_memory,
|
||||
bool &trial)
|
||||
{
|
||||
// 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>(&paths["config"])
|
||||
->default_value("server.ini"),
|
||||
"Path to a configuration file")(
|
||||
"trial",
|
||||
boost::program_options::value<bool>(&trial)->implicit_value(true),
|
||||
"Quit after initialization");
|
||||
|
||||
// declare a group of options that will be allowed both on command line
|
||||
// as well as in a config file
|
||||
boost::program_options::options_description config_options("Configuration");
|
||||
config_options.add_options()(
|
||||
"hsgrdata",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["hsgrdata"]),
|
||||
".hsgr file")("nodesdata",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["nodesdata"]),
|
||||
".nodes file")(
|
||||
"edgesdata",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["edgesdata"]),
|
||||
".edges file")("geometry",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["geometries"]),
|
||||
".geometry file")(
|
||||
"ramindex",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["ramindex"]),
|
||||
".ramIndex file")(
|
||||
"fileindex",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["fileindex"]),
|
||||
"File index file")(
|
||||
"namesdata",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["namesdata"]),
|
||||
".names file")("timestamp",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["timestamp"]),
|
||||
".timestamp file")(
|
||||
"ip,i",
|
||||
boost::program_options::value<std::string>(&ip_address)->default_value("0.0.0.0"),
|
||||
"IP address")(
|
||||
"port,p", boost::program_options::value<int>(&ip_port)->default_value(5000), "TCP/IP port")(
|
||||
"threads,t",
|
||||
boost::program_options::value<int>(&requested_num_threads)->default_value(8),
|
||||
"Number of threads to use")(
|
||||
"sharedmemory,s",
|
||||
boost::program_options::value<bool>(&use_shared_memory)->implicit_value(true),
|
||||
"Load data from shared memory");
|
||||
|
||||
// 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()(
|
||||
"base,b",
|
||||
boost::program_options::value<boost::filesystem::path>(&paths["base"]),
|
||||
"base path to .osrm file");
|
||||
|
||||
// positional option
|
||||
boost::program_options::positional_options_description positional_options;
|
||||
positional_options.add("base", 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]) + " <base.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 INIT_OK_DO_NOT_START_ENGINE;
|
||||
}
|
||||
|
||||
if (option_variables.count("help"))
|
||||
{
|
||||
SimpleLogger().Write() << visible_options;
|
||||
return INIT_OK_DO_NOT_START_ENGINE;
|
||||
}
|
||||
|
||||
boost::program_options::notify(option_variables);
|
||||
|
||||
// parse config file
|
||||
ServerPaths::iterator path_iterator = paths.find("config");
|
||||
if (path_iterator != paths.end() && boost::filesystem::is_regular_file(path_iterator->second) &&
|
||||
!option_variables.count("base"))
|
||||
{
|
||||
SimpleLogger().Write() << "Reading options from: " << path_iterator->second.string();
|
||||
std::string ini_file_contents = ReadIniFileAndLowerContents(path_iterator->second);
|
||||
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);
|
||||
return INIT_OK_START_ENGINE;
|
||||
}
|
||||
|
||||
if (1 > requested_num_threads)
|
||||
{
|
||||
throw OSRMException("Number of threads must be a positive number");
|
||||
}
|
||||
|
||||
if (!use_shared_memory && option_variables.count("base"))
|
||||
{
|
||||
return INIT_OK_START_ENGINE;
|
||||
}
|
||||
if (use_shared_memory && !option_variables.count("base"))
|
||||
{
|
||||
return INIT_OK_START_ENGINE;
|
||||
}
|
||||
SimpleLogger().Write() << visible_options;
|
||||
return INIT_OK_DO_NOT_START_ENGINE;
|
||||
}
|
||||
|
||||
#endif /* PROGRAM_OPTIONS_H */
|
||||
@@ -1,165 +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 STRINGUTIL_H
|
||||
#define STRINGUTIL_H
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// precision: position after decimal point
|
||||
// length: maximum number of digits including comma and decimals
|
||||
// work with negative values to prevent overflowing when taking -value
|
||||
template <int length, int precision> static inline char *printInt(char *buffer, int value)
|
||||
{
|
||||
bool minus = true;
|
||||
if (value > 0)
|
||||
{
|
||||
minus = false;
|
||||
value = -value;
|
||||
}
|
||||
buffer += length - 1;
|
||||
for (int i = 0; i < precision; i++)
|
||||
{
|
||||
*buffer = '0' - (value % 10);
|
||||
value /= 10;
|
||||
buffer--;
|
||||
}
|
||||
*buffer = '.';
|
||||
buffer--;
|
||||
for (int i = precision + 1; i < length; i++)
|
||||
{
|
||||
*buffer = '0' - (value % 10);
|
||||
value /= 10;
|
||||
if (value == 0)
|
||||
break;
|
||||
buffer--;
|
||||
}
|
||||
if (minus)
|
||||
{
|
||||
buffer--;
|
||||
*buffer = '-';
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
inline void replaceAll(std::string &s, const std::string &sub, const std::string &other)
|
||||
{
|
||||
boost::replace_all(s, sub, other);
|
||||
}
|
||||
|
||||
inline std::string EscapeJSONString(const std::string &input)
|
||||
{
|
||||
std::string output;
|
||||
output.reserve(input.size());
|
||||
for (auto iter = input.begin(); iter != input.end(); ++iter)
|
||||
{
|
||||
switch (iter[0])
|
||||
{
|
||||
case '\\':
|
||||
output += "\\\\";
|
||||
break;
|
||||
case '"':
|
||||
output += "\\\"";
|
||||
break;
|
||||
case '/':
|
||||
output += "\\/";
|
||||
break;
|
||||
case '\b':
|
||||
output += "\\b";
|
||||
break;
|
||||
case '\f':
|
||||
output += "\\f";
|
||||
break;
|
||||
case '\n':
|
||||
output += "\\n";
|
||||
break;
|
||||
case '\r':
|
||||
output += "\\r";
|
||||
break;
|
||||
case '\t':
|
||||
output += "\\t";
|
||||
break;
|
||||
default:
|
||||
output += *iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
static std::string originals[] = {"&", "\"", "<", ">", "'", "[", "]", "\\"};
|
||||
static std::string entities[] = {
|
||||
"&", """, "<", ">", "'", "&91;", "&93;", " \"};
|
||||
|
||||
inline std::size_t URIDecode(const std::string &input, std::string &output)
|
||||
{
|
||||
auto src_iter = input.begin();
|
||||
output.resize(input.size() + 1);
|
||||
std::size_t decoded_length = 0;
|
||||
for (decoded_length = 0; src_iter != input.end(); ++decoded_length)
|
||||
{
|
||||
if (src_iter[0] == '%' && src_iter[1] && src_iter[2] && isxdigit(src_iter[1]) &&
|
||||
isxdigit(src_iter[2]))
|
||||
{
|
||||
std::string::value_type a = src_iter[1];
|
||||
std::string::value_type b = src_iter[2];
|
||||
a -= src_iter[1] < 58 ? 48 : src_iter[1] < 71 ? 55 : 87;
|
||||
b -= src_iter[2] < 58 ? 48 : src_iter[2] < 71 ? 55 : 87;
|
||||
output[decoded_length] = 16 * a + b;
|
||||
src_iter += 3;
|
||||
continue;
|
||||
}
|
||||
output[decoded_length] = *src_iter++;
|
||||
}
|
||||
output.resize(decoded_length);
|
||||
return decoded_length;
|
||||
}
|
||||
|
||||
inline std::size_t URIDecodeInPlace(std::string &URI) { return URIDecode(URI, URI); }
|
||||
|
||||
inline std::string GetRandomString()
|
||||
{
|
||||
std::string s;
|
||||
s.resize(128);
|
||||
static const char alphanum[] = "0123456789"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
for (int i = 0; i < 127; ++i)
|
||||
{
|
||||
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
|
||||
}
|
||||
s[127] = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
#endif // STRINGUTIL_H
|
||||
@@ -1,790 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TRIGONOMETRY_TABLES_H
|
||||
#define TRIGONOMETRY_TABLES_H
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include <cmath>
|
||||
|
||||
#include <limits>
|
||||
|
||||
constexpr unsigned short atan_table[4096] = {
|
||||
0x0000, 0x0014, 0x0028, 0x003d, 0x0051, 0x0065,
|
||||
0x007a, 0x008e, 0x00a3, 0x00b7, 0x00cb, 0x00e0,
|
||||
0x00f4, 0x0108, 0x011d, 0x0131, 0x0146, 0x015a,
|
||||
0x016e, 0x0183, 0x0197, 0x01ab, 0x01c0, 0x01d4,
|
||||
0x01e9, 0x01fd, 0x0211, 0x0226, 0x023a, 0x024e,
|
||||
0x0263, 0x0277, 0x028c, 0x02a0, 0x02b4, 0x02c9,
|
||||
0x02dd, 0x02f1, 0x0306, 0x031a, 0x032f, 0x0343,
|
||||
0x0357, 0x036c, 0x0380, 0x0394, 0x03a9, 0x03bd,
|
||||
0x03d2, 0x03e6, 0x03fa, 0x040f, 0x0423, 0x0437,
|
||||
0x044c, 0x0460, 0x0475, 0x0489, 0x049d, 0x04b2,
|
||||
0x04c6, 0x04da, 0x04ef, 0x0503, 0x0517, 0x052c,
|
||||
0x0540, 0x0555, 0x0569, 0x057d, 0x0592, 0x05a6,
|
||||
0x05ba, 0x05cf, 0x05e3, 0x05f8, 0x060c, 0x0620,
|
||||
0x0635, 0x0649, 0x065d, 0x0672, 0x0686, 0x069b,
|
||||
0x06af, 0x06c3, 0x06d8, 0x06ec, 0x0700, 0x0715,
|
||||
0x0729, 0x073d, 0x0752, 0x0766, 0x077b, 0x078f,
|
||||
0x07a3, 0x07b8, 0x07cc, 0x07e0, 0x07f5, 0x0809,
|
||||
0x081d, 0x0832, 0x0846, 0x085b, 0x086f, 0x0883,
|
||||
0x0898, 0x08ac, 0x08c0, 0x08d5, 0x08e9, 0x08fd,
|
||||
0x0912, 0x0926, 0x093b, 0x094f, 0x0963, 0x0978,
|
||||
0x098c, 0x09a0, 0x09b5, 0x09c9, 0x09dd, 0x09f2,
|
||||
0x0a06, 0x0a1a, 0x0a2f, 0x0a43, 0x0a58, 0x0a6c,
|
||||
0x0a80, 0x0a95, 0x0aa9, 0x0abd, 0x0ad2, 0x0ae6,
|
||||
0x0afa, 0x0b0f, 0x0b23, 0x0b37, 0x0b4c, 0x0b60,
|
||||
0x0b75, 0x0b89, 0x0b9d, 0x0bb2, 0x0bc6, 0x0bda,
|
||||
0x0bef, 0x0c03, 0x0c17, 0x0c2c, 0x0c40, 0x0c54,
|
||||
0x0c69, 0x0c7d, 0x0c91, 0x0ca6, 0x0cba, 0x0cce,
|
||||
0x0ce3, 0x0cf7, 0x0d0b, 0x0d20, 0x0d34, 0x0d48,
|
||||
0x0d5d, 0x0d71, 0x0d86, 0x0d9a, 0x0dae, 0x0dc3,
|
||||
0x0dd7, 0x0deb, 0x0e00, 0x0e14, 0x0e28, 0x0e3d,
|
||||
0x0e51, 0x0e65, 0x0e7a, 0x0e8e, 0x0ea2, 0x0eb7,
|
||||
0x0ecb, 0x0edf, 0x0ef4, 0x0f08, 0x0f1c, 0x0f31,
|
||||
0x0f45, 0x0f59, 0x0f6e, 0x0f82, 0x0f96, 0x0fab,
|
||||
0x0fbf, 0x0fd3, 0x0fe8, 0x0ffc, 0x1010, 0x1025,
|
||||
0x1039, 0x104d, 0x1062, 0x1076, 0x108a, 0x109e,
|
||||
0x10b3, 0x10c7, 0x10db, 0x10f0, 0x1104, 0x1118,
|
||||
0x112d, 0x1141, 0x1155, 0x116a, 0x117e, 0x1192,
|
||||
0x11a7, 0x11bb, 0x11cf, 0x11e4, 0x11f8, 0x120c,
|
||||
0x1221, 0x1235, 0x1249, 0x125d, 0x1272, 0x1286,
|
||||
0x129a, 0x12af, 0x12c3, 0x12d7, 0x12ec, 0x1300,
|
||||
0x1314, 0x1329, 0x133d, 0x1351, 0x1365, 0x137a,
|
||||
0x138e, 0x13a2, 0x13b7, 0x13cb, 0x13df, 0x13f4,
|
||||
0x1408, 0x141c, 0x1431, 0x1445, 0x1459, 0x146d,
|
||||
0x1482, 0x1496, 0x14aa, 0x14bf, 0x14d3, 0x14e7,
|
||||
0x14fb, 0x1510, 0x1524, 0x1538, 0x154d, 0x1561,
|
||||
0x1575, 0x1589, 0x159e, 0x15b2, 0x15c6, 0x15db,
|
||||
0x15ef, 0x1603, 0x1617, 0x162c, 0x1640, 0x1654,
|
||||
0x1669, 0x167d, 0x1691, 0x16a5, 0x16ba, 0x16ce,
|
||||
0x16e2, 0x16f7, 0x170b, 0x171f, 0x1733, 0x1748,
|
||||
0x175c, 0x1770, 0x1784, 0x1799, 0x17ad, 0x17c1,
|
||||
0x17d6, 0x17ea, 0x17fe, 0x1812, 0x1827, 0x183b,
|
||||
0x184f, 0x1863, 0x1878, 0x188c, 0x18a0, 0x18b4,
|
||||
0x18c9, 0x18dd, 0x18f1, 0x1905, 0x191a, 0x192e,
|
||||
0x1942, 0x1957, 0x196b, 0x197f, 0x1993, 0x19a8,
|
||||
0x19bc, 0x19d0, 0x19e4, 0x19f9, 0x1a0d, 0x1a21,
|
||||
0x1a35, 0x1a49, 0x1a5e, 0x1a72, 0x1a86, 0x1a9a,
|
||||
0x1aaf, 0x1ac3, 0x1ad7, 0x1aeb, 0x1b00, 0x1b14,
|
||||
0x1b28, 0x1b3c, 0x1b51, 0x1b65, 0x1b79, 0x1b8d,
|
||||
0x1ba2, 0x1bb6, 0x1bca, 0x1bde, 0x1bf2, 0x1c07,
|
||||
0x1c1b, 0x1c2f, 0x1c43, 0x1c58, 0x1c6c, 0x1c80,
|
||||
0x1c94, 0x1ca8, 0x1cbd, 0x1cd1, 0x1ce5, 0x1cf9,
|
||||
0x1d0e, 0x1d22, 0x1d36, 0x1d4a, 0x1d5e, 0x1d73,
|
||||
0x1d87, 0x1d9b, 0x1daf, 0x1dc3, 0x1dd8, 0x1dec,
|
||||
0x1e00, 0x1e14, 0x1e28, 0x1e3d, 0x1e51, 0x1e65,
|
||||
0x1e79, 0x1e8d, 0x1ea2, 0x1eb6, 0x1eca, 0x1ede,
|
||||
0x1ef2, 0x1f07, 0x1f1b, 0x1f2f, 0x1f43, 0x1f57,
|
||||
0x1f6c, 0x1f80, 0x1f94, 0x1fa8, 0x1fbc, 0x1fd1,
|
||||
0x1fe5, 0x1ff9, 0x200d, 0x2021, 0x2035, 0x204a,
|
||||
0x205e, 0x2072, 0x2086, 0x209a, 0x20ae, 0x20c3,
|
||||
0x20d7, 0x20eb, 0x20ff, 0x2113, 0x2127, 0x213c,
|
||||
0x2150, 0x2164, 0x2178, 0x218c, 0x21a0, 0x21b5,
|
||||
0x21c9, 0x21dd, 0x21f1, 0x2205, 0x2219, 0x222e,
|
||||
0x2242, 0x2256, 0x226a, 0x227e, 0x2292, 0x22a6,
|
||||
0x22bb, 0x22cf, 0x22e3, 0x22f7, 0x230b, 0x231f,
|
||||
0x2333, 0x2348, 0x235c, 0x2370, 0x2384, 0x2398,
|
||||
0x23ac, 0x23c0, 0x23d5, 0x23e9, 0x23fd, 0x2411,
|
||||
0x2425, 0x2439, 0x244d, 0x2461, 0x2476, 0x248a,
|
||||
0x249e, 0x24b2, 0x24c6, 0x24da, 0x24ee, 0x2502,
|
||||
0x2517, 0x252b, 0x253f, 0x2553, 0x2567, 0x257b,
|
||||
0x258f, 0x25a3, 0x25b7, 0x25cb, 0x25e0, 0x25f4,
|
||||
0x2608, 0x261c, 0x2630, 0x2644, 0x2658, 0x266c,
|
||||
0x2680, 0x2694, 0x26a9, 0x26bd, 0x26d1, 0x26e5,
|
||||
0x26f9, 0x270d, 0x2721, 0x2735, 0x2749, 0x275d,
|
||||
0x2771, 0x2785, 0x279a, 0x27ae, 0x27c2, 0x27d6,
|
||||
0x27ea, 0x27fe, 0x2812, 0x2826, 0x283a, 0x284e,
|
||||
0x2862, 0x2876, 0x288a, 0x289e, 0x28b3, 0x28c7,
|
||||
0x28db, 0x28ef, 0x2903, 0x2917, 0x292b, 0x293f,
|
||||
0x2953, 0x2967, 0x297b, 0x298f, 0x29a3, 0x29b7,
|
||||
0x29cb, 0x29df, 0x29f3, 0x2a07, 0x2a1b, 0x2a2f,
|
||||
0x2a43, 0x2a58, 0x2a6c, 0x2a80, 0x2a94, 0x2aa8,
|
||||
0x2abc, 0x2ad0, 0x2ae4, 0x2af8, 0x2b0c, 0x2b20,
|
||||
0x2b34, 0x2b48, 0x2b5c, 0x2b70, 0x2b84, 0x2b98,
|
||||
0x2bac, 0x2bc0, 0x2bd4, 0x2be8, 0x2bfc, 0x2c10,
|
||||
0x2c24, 0x2c38, 0x2c4c, 0x2c60, 0x2c74, 0x2c88,
|
||||
0x2c9c, 0x2cb0, 0x2cc4, 0x2cd8, 0x2cec, 0x2d00,
|
||||
0x2d14, 0x2d28, 0x2d3c, 0x2d50, 0x2d64, 0x2d78,
|
||||
0x2d8c, 0x2da0, 0x2db4, 0x2dc8, 0x2ddc, 0x2df0,
|
||||
0x2e04, 0x2e18, 0x2e2c, 0x2e40, 0x2e54, 0x2e68,
|
||||
0x2e7c, 0x2e90, 0x2ea3, 0x2eb7, 0x2ecb, 0x2edf,
|
||||
0x2ef3, 0x2f07, 0x2f1b, 0x2f2f, 0x2f43, 0x2f57,
|
||||
0x2f6b, 0x2f7f, 0x2f93, 0x2fa7, 0x2fbb, 0x2fcf,
|
||||
0x2fe3, 0x2ff7, 0x300b, 0x301e, 0x3032, 0x3046,
|
||||
0x305a, 0x306e, 0x3082, 0x3096, 0x30aa, 0x30be,
|
||||
0x30d2, 0x30e6, 0x30fa, 0x310e, 0x3122, 0x3135,
|
||||
0x3149, 0x315d, 0x3171, 0x3185, 0x3199, 0x31ad,
|
||||
0x31c1, 0x31d5, 0x31e9, 0x31fd, 0x3210, 0x3224,
|
||||
0x3238, 0x324c, 0x3260, 0x3274, 0x3288, 0x329c,
|
||||
0x32b0, 0x32c3, 0x32d7, 0x32eb, 0x32ff, 0x3313,
|
||||
0x3327, 0x333b, 0x334f, 0x3363, 0x3376, 0x338a,
|
||||
0x339e, 0x33b2, 0x33c6, 0x33da, 0x33ee, 0x3401,
|
||||
0x3415, 0x3429, 0x343d, 0x3451, 0x3465, 0x3479,
|
||||
0x348c, 0x34a0, 0x34b4, 0x34c8, 0x34dc, 0x34f0,
|
||||
0x3504, 0x3517, 0x352b, 0x353f, 0x3553, 0x3567,
|
||||
0x357b, 0x358e, 0x35a2, 0x35b6, 0x35ca, 0x35de,
|
||||
0x35f2, 0x3605, 0x3619, 0x362d, 0x3641, 0x3655,
|
||||
0x3668, 0x367c, 0x3690, 0x36a4, 0x36b8, 0x36cb,
|
||||
0x36df, 0x36f3, 0x3707, 0x371b, 0x372f, 0x3742,
|
||||
0x3756, 0x376a, 0x377e, 0x3791, 0x37a5, 0x37b9,
|
||||
0x37cd, 0x37e1, 0x37f4, 0x3808, 0x381c, 0x3830,
|
||||
0x3844, 0x3857, 0x386b, 0x387f, 0x3893, 0x38a6,
|
||||
0x38ba, 0x38ce, 0x38e2, 0x38f5, 0x3909, 0x391d,
|
||||
0x3931, 0x3944, 0x3958, 0x396c, 0x3980, 0x3993,
|
||||
0x39a7, 0x39bb, 0x39cf, 0x39e2, 0x39f6, 0x3a0a,
|
||||
0x3a1e, 0x3a31, 0x3a45, 0x3a59, 0x3a6d, 0x3a80,
|
||||
0x3a94, 0x3aa8, 0x3abb, 0x3acf, 0x3ae3, 0x3af7,
|
||||
0x3b0a, 0x3b1e, 0x3b32, 0x3b45, 0x3b59, 0x3b6d,
|
||||
0x3b81, 0x3b94, 0x3ba8, 0x3bbc, 0x3bcf, 0x3be3,
|
||||
0x3bf7, 0x3c0b, 0x3c1e, 0x3c32, 0x3c46, 0x3c59,
|
||||
0x3c6d, 0x3c81, 0x3c94, 0x3ca8, 0x3cbc, 0x3ccf,
|
||||
0x3ce3, 0x3cf7, 0x3d0a, 0x3d1e, 0x3d32, 0x3d45,
|
||||
0x3d59, 0x3d6d, 0x3d80, 0x3d94, 0x3da8, 0x3dbb,
|
||||
0x3dcf, 0x3de3, 0x3df6, 0x3e0a, 0x3e1e, 0x3e31,
|
||||
0x3e45, 0x3e59, 0x3e6c, 0x3e80, 0x3e93, 0x3ea7,
|
||||
0x3ebb, 0x3ece, 0x3ee2, 0x3ef6, 0x3f09, 0x3f1d,
|
||||
0x3f30, 0x3f44, 0x3f58, 0x3f6b, 0x3f7f, 0x3f93,
|
||||
0x3fa6, 0x3fba, 0x3fcd, 0x3fe1, 0x3ff5, 0x4008,
|
||||
0x401c, 0x402f, 0x4043, 0x4057, 0x406a, 0x407e,
|
||||
0x4091, 0x40a5, 0x40b8, 0x40cc, 0x40e0, 0x40f3,
|
||||
0x4107, 0x411a, 0x412e, 0x4142, 0x4155, 0x4169,
|
||||
0x417c, 0x4190, 0x41a3, 0x41b7, 0x41ca, 0x41de,
|
||||
0x41f2, 0x4205, 0x4219, 0x422c, 0x4240, 0x4253,
|
||||
0x4267, 0x427a, 0x428e, 0x42a1, 0x42b5, 0x42c9,
|
||||
0x42dc, 0x42f0, 0x4303, 0x4317, 0x432a, 0x433e,
|
||||
0x4351, 0x4365, 0x4378, 0x438c, 0x439f, 0x43b3,
|
||||
0x43c6, 0x43da, 0x43ed, 0x4401, 0x4414, 0x4428,
|
||||
0x443b, 0x444f, 0x4462, 0x4476, 0x4489, 0x449d,
|
||||
0x44b0, 0x44c4, 0x44d7, 0x44eb, 0x44fe, 0x4512,
|
||||
0x4525, 0x4539, 0x454c, 0x4560, 0x4573, 0x4586,
|
||||
0x459a, 0x45ad, 0x45c1, 0x45d4, 0x45e8, 0x45fb,
|
||||
0x460f, 0x4622, 0x4636, 0x4649, 0x465c, 0x4670,
|
||||
0x4683, 0x4697, 0x46aa, 0x46be, 0x46d1, 0x46e5,
|
||||
0x46f8, 0x470b, 0x471f, 0x4732, 0x4746, 0x4759,
|
||||
0x476c, 0x4780, 0x4793, 0x47a7, 0x47ba, 0x47cd,
|
||||
0x47e1, 0x47f4, 0x4808, 0x481b, 0x482e, 0x4842,
|
||||
0x4855, 0x4869, 0x487c, 0x488f, 0x48a3, 0x48b6,
|
||||
0x48ca, 0x48dd, 0x48f0, 0x4904, 0x4917, 0x492a,
|
||||
0x493e, 0x4951, 0x4965, 0x4978, 0x498b, 0x499f,
|
||||
0x49b2, 0x49c5, 0x49d9, 0x49ec, 0x49ff, 0x4a13,
|
||||
0x4a26, 0x4a39, 0x4a4d, 0x4a60, 0x4a73, 0x4a87,
|
||||
0x4a9a, 0x4aad, 0x4ac1, 0x4ad4, 0x4ae7, 0x4afb,
|
||||
0x4b0e, 0x4b21, 0x4b35, 0x4b48, 0x4b5b, 0x4b6f,
|
||||
0x4b82, 0x4b95, 0x4ba8, 0x4bbc, 0x4bcf, 0x4be2,
|
||||
0x4bf6, 0x4c09, 0x4c1c, 0x4c2f, 0x4c43, 0x4c56,
|
||||
0x4c69, 0x4c7d, 0x4c90, 0x4ca3, 0x4cb6, 0x4cca,
|
||||
0x4cdd, 0x4cf0, 0x4d03, 0x4d17, 0x4d2a, 0x4d3d,
|
||||
0x4d50, 0x4d64, 0x4d77, 0x4d8a, 0x4d9d, 0x4db1,
|
||||
0x4dc4, 0x4dd7, 0x4dea, 0x4dfe, 0x4e11, 0x4e24,
|
||||
0x4e37, 0x4e4b, 0x4e5e, 0x4e71, 0x4e84, 0x4e97,
|
||||
0x4eab, 0x4ebe, 0x4ed1, 0x4ee4, 0x4ef7, 0x4f0b,
|
||||
0x4f1e, 0x4f31, 0x4f44, 0x4f57, 0x4f6b, 0x4f7e,
|
||||
0x4f91, 0x4fa4, 0x4fb7, 0x4fcb, 0x4fde, 0x4ff1,
|
||||
0x5004, 0x5017, 0x502a, 0x503e, 0x5051, 0x5064,
|
||||
0x5077, 0x508a, 0x509d, 0x50b1, 0x50c4, 0x50d7,
|
||||
0x50ea, 0x50fd, 0x5110, 0x5123, 0x5137, 0x514a,
|
||||
0x515d, 0x5170, 0x5183, 0x5196, 0x51a9, 0x51bc,
|
||||
0x51d0, 0x51e3, 0x51f6, 0x5209, 0x521c, 0x522f,
|
||||
0x5242, 0x5255, 0x5268, 0x527c, 0x528f, 0x52a2,
|
||||
0x52b5, 0x52c8, 0x52db, 0x52ee, 0x5301, 0x5314,
|
||||
0x5327, 0x533a, 0x534e, 0x5361, 0x5374, 0x5387,
|
||||
0x539a, 0x53ad, 0x53c0, 0x53d3, 0x53e6, 0x53f9,
|
||||
0x540c, 0x541f, 0x5432, 0x5445, 0x5458, 0x546b,
|
||||
0x547e, 0x5491, 0x54a5, 0x54b8, 0x54cb, 0x54de,
|
||||
0x54f1, 0x5504, 0x5517, 0x552a, 0x553d, 0x5550,
|
||||
0x5563, 0x5576, 0x5589, 0x559c, 0x55af, 0x55c2,
|
||||
0x55d5, 0x55e8, 0x55fb, 0x560e, 0x5621, 0x5634,
|
||||
0x5647, 0x565a, 0x566d, 0x5680, 0x5693, 0x56a6,
|
||||
0x56b9, 0x56cb, 0x56de, 0x56f1, 0x5704, 0x5717,
|
||||
0x572a, 0x573d, 0x5750, 0x5763, 0x5776, 0x5789,
|
||||
0x579c, 0x57af, 0x57c2, 0x57d5, 0x57e8, 0x57fb,
|
||||
0x580e, 0x5820, 0x5833, 0x5846, 0x5859, 0x586c,
|
||||
0x587f, 0x5892, 0x58a5, 0x58b8, 0x58cb, 0x58de,
|
||||
0x58f0, 0x5903, 0x5916, 0x5929, 0x593c, 0x594f,
|
||||
0x5962, 0x5975, 0x5988, 0x599a, 0x59ad, 0x59c0,
|
||||
0x59d3, 0x59e6, 0x59f9, 0x5a0c, 0x5a1f, 0x5a31,
|
||||
0x5a44, 0x5a57, 0x5a6a, 0x5a7d, 0x5a90, 0x5aa2,
|
||||
0x5ab5, 0x5ac8, 0x5adb, 0x5aee, 0x5b01, 0x5b13,
|
||||
0x5b26, 0x5b39, 0x5b4c, 0x5b5f, 0x5b72, 0x5b84,
|
||||
0x5b97, 0x5baa, 0x5bbd, 0x5bd0, 0x5be2, 0x5bf5,
|
||||
0x5c08, 0x5c1b, 0x5c2e, 0x5c40, 0x5c53, 0x5c66,
|
||||
0x5c79, 0x5c8c, 0x5c9e, 0x5cb1, 0x5cc4, 0x5cd7,
|
||||
0x5ce9, 0x5cfc, 0x5d0f, 0x5d22, 0x5d34, 0x5d47,
|
||||
0x5d5a, 0x5d6d, 0x5d7f, 0x5d92, 0x5da5, 0x5db8,
|
||||
0x5dca, 0x5ddd, 0x5df0, 0x5e03, 0x5e15, 0x5e28,
|
||||
0x5e3b, 0x5e4d, 0x5e60, 0x5e73, 0x5e86, 0x5e98,
|
||||
0x5eab, 0x5ebe, 0x5ed0, 0x5ee3, 0x5ef6, 0x5f09,
|
||||
0x5f1b, 0x5f2e, 0x5f41, 0x5f53, 0x5f66, 0x5f79,
|
||||
0x5f8b, 0x5f9e, 0x5fb1, 0x5fc3, 0x5fd6, 0x5fe9,
|
||||
0x5ffb, 0x600e, 0x6021, 0x6033, 0x6046, 0x6059,
|
||||
0x606b, 0x607e, 0x6091, 0x60a3, 0x60b6, 0x60c8,
|
||||
0x60db, 0x60ee, 0x6100, 0x6113, 0x6126, 0x6138,
|
||||
0x614b, 0x615d, 0x6170, 0x6183, 0x6195, 0x61a8,
|
||||
0x61ba, 0x61cd, 0x61e0, 0x61f2, 0x6205, 0x6217,
|
||||
0x622a, 0x623d, 0x624f, 0x6262, 0x6274, 0x6287,
|
||||
0x6299, 0x62ac, 0x62bf, 0x62d1, 0x62e4, 0x62f6,
|
||||
0x6309, 0x631b, 0x632e, 0x6340, 0x6353, 0x6366,
|
||||
0x6378, 0x638b, 0x639d, 0x63b0, 0x63c2, 0x63d5,
|
||||
0x63e7, 0x63fa, 0x640c, 0x641f, 0x6431, 0x6444,
|
||||
0x6456, 0x6469, 0x647b, 0x648e, 0x64a0, 0x64b3,
|
||||
0x64c5, 0x64d8, 0x64ea, 0x64fd, 0x650f, 0x6522,
|
||||
0x6534, 0x6547, 0x6559, 0x656c, 0x657e, 0x6591,
|
||||
0x65a3, 0x65b5, 0x65c8, 0x65da, 0x65ed, 0x65ff,
|
||||
0x6612, 0x6624, 0x6637, 0x6649, 0x665b, 0x666e,
|
||||
0x6680, 0x6693, 0x66a5, 0x66b8, 0x66ca, 0x66dc,
|
||||
0x66ef, 0x6701, 0x6714, 0x6726, 0x6738, 0x674b,
|
||||
0x675d, 0x6770, 0x6782, 0x6794, 0x67a7, 0x67b9,
|
||||
0x67cc, 0x67de, 0x67f0, 0x6803, 0x6815, 0x6827,
|
||||
0x683a, 0x684c, 0x685e, 0x6871, 0x6883, 0x6896,
|
||||
0x68a8, 0x68ba, 0x68cd, 0x68df, 0x68f1, 0x6904,
|
||||
0x6916, 0x6928, 0x693b, 0x694d, 0x695f, 0x6972,
|
||||
0x6984, 0x6996, 0x69a8, 0x69bb, 0x69cd, 0x69df,
|
||||
0x69f2, 0x6a04, 0x6a16, 0x6a29, 0x6a3b, 0x6a4d,
|
||||
0x6a5f, 0x6a72, 0x6a84, 0x6a96, 0x6aa9, 0x6abb,
|
||||
0x6acd, 0x6adf, 0x6af2, 0x6b04, 0x6b16, 0x6b28,
|
||||
0x6b3b, 0x6b4d, 0x6b5f, 0x6b71, 0x6b84, 0x6b96,
|
||||
0x6ba8, 0x6bba, 0x6bcd, 0x6bdf, 0x6bf1, 0x6c03,
|
||||
0x6c15, 0x6c28, 0x6c3a, 0x6c4c, 0x6c5e, 0x6c70,
|
||||
0x6c83, 0x6c95, 0x6ca7, 0x6cb9, 0x6ccb, 0x6cde,
|
||||
0x6cf0, 0x6d02, 0x6d14, 0x6d26, 0x6d39, 0x6d4b,
|
||||
0x6d5d, 0x6d6f, 0x6d81, 0x6d93, 0x6da6, 0x6db8,
|
||||
0x6dca, 0x6ddc, 0x6dee, 0x6e00, 0x6e12, 0x6e25,
|
||||
0x6e37, 0x6e49, 0x6e5b, 0x6e6d, 0x6e7f, 0x6e91,
|
||||
0x6ea3, 0x6eb6, 0x6ec8, 0x6eda, 0x6eec, 0x6efe,
|
||||
0x6f10, 0x6f22, 0x6f34, 0x6f46, 0x6f58, 0x6f6b,
|
||||
0x6f7d, 0x6f8f, 0x6fa1, 0x6fb3, 0x6fc5, 0x6fd7,
|
||||
0x6fe9, 0x6ffb, 0x700d, 0x701f, 0x7031, 0x7043,
|
||||
0x7055, 0x7068, 0x707a, 0x708c, 0x709e, 0x70b0,
|
||||
0x70c2, 0x70d4, 0x70e6, 0x70f8, 0x710a, 0x711c,
|
||||
0x712e, 0x7140, 0x7152, 0x7164, 0x7176, 0x7188,
|
||||
0x719a, 0x71ac, 0x71be, 0x71d0, 0x71e2, 0x71f4,
|
||||
0x7206, 0x7218, 0x722a, 0x723c, 0x724e, 0x7260,
|
||||
0x7272, 0x7284, 0x7296, 0x72a8, 0x72ba, 0x72cc,
|
||||
0x72dd, 0x72ef, 0x7301, 0x7313, 0x7325, 0x7337,
|
||||
0x7349, 0x735b, 0x736d, 0x737f, 0x7391, 0x73a3,
|
||||
0x73b5, 0x73c7, 0x73d8, 0x73ea, 0x73fc, 0x740e,
|
||||
0x7420, 0x7432, 0x7444, 0x7456, 0x7468, 0x747a,
|
||||
0x748b, 0x749d, 0x74af, 0x74c1, 0x74d3, 0x74e5,
|
||||
0x74f7, 0x7509, 0x751a, 0x752c, 0x753e, 0x7550,
|
||||
0x7562, 0x7574, 0x7585, 0x7597, 0x75a9, 0x75bb,
|
||||
0x75cd, 0x75df, 0x75f0, 0x7602, 0x7614, 0x7626,
|
||||
0x7638, 0x764a, 0x765b, 0x766d, 0x767f, 0x7691,
|
||||
0x76a3, 0x76b4, 0x76c6, 0x76d8, 0x76ea, 0x76fb,
|
||||
0x770d, 0x771f, 0x7731, 0x7743, 0x7754, 0x7766,
|
||||
0x7778, 0x778a, 0x779b, 0x77ad, 0x77bf, 0x77d1,
|
||||
0x77e2, 0x77f4, 0x7806, 0x7818, 0x7829, 0x783b,
|
||||
0x784d, 0x785e, 0x7870, 0x7882, 0x7894, 0x78a5,
|
||||
0x78b7, 0x78c9, 0x78da, 0x78ec, 0x78fe, 0x7910,
|
||||
0x7921, 0x7933, 0x7945, 0x7956, 0x7968, 0x797a,
|
||||
0x798b, 0x799d, 0x79af, 0x79c0, 0x79d2, 0x79e4,
|
||||
0x79f5, 0x7a07, 0x7a19, 0x7a2a, 0x7a3c, 0x7a4e,
|
||||
0x7a5f, 0x7a71, 0x7a82, 0x7a94, 0x7aa6, 0x7ab7,
|
||||
0x7ac9, 0x7adb, 0x7aec, 0x7afe, 0x7b0f, 0x7b21,
|
||||
0x7b33, 0x7b44, 0x7b56, 0x7b67, 0x7b79, 0x7b8b,
|
||||
0x7b9c, 0x7bae, 0x7bbf, 0x7bd1, 0x7be2, 0x7bf4,
|
||||
0x7c06, 0x7c17, 0x7c29, 0x7c3a, 0x7c4c, 0x7c5d,
|
||||
0x7c6f, 0x7c81, 0x7c92, 0x7ca4, 0x7cb5, 0x7cc7,
|
||||
0x7cd8, 0x7cea, 0x7cfb, 0x7d0d, 0x7d1e, 0x7d30,
|
||||
0x7d41, 0x7d53, 0x7d64, 0x7d76, 0x7d87, 0x7d99,
|
||||
0x7daa, 0x7dbc, 0x7dcd, 0x7ddf, 0x7df0, 0x7e02,
|
||||
0x7e13, 0x7e25, 0x7e36, 0x7e48, 0x7e59, 0x7e6b,
|
||||
0x7e7c, 0x7e8e, 0x7e9f, 0x7eb0, 0x7ec2, 0x7ed3,
|
||||
0x7ee5, 0x7ef6, 0x7f08, 0x7f19, 0x7f2b, 0x7f3c,
|
||||
0x7f4d, 0x7f5f, 0x7f70, 0x7f82, 0x7f93, 0x7fa4,
|
||||
0x7fb6, 0x7fc7, 0x7fd9, 0x7fea, 0x7ffb, 0x800d,
|
||||
0x801e, 0x8030, 0x8041, 0x8052, 0x8064, 0x8075,
|
||||
0x8086, 0x8098, 0x80a9, 0x80bb, 0x80cc, 0x80dd,
|
||||
0x80ef, 0x8100, 0x8111, 0x8123, 0x8134, 0x8145,
|
||||
0x8157, 0x8168, 0x8179, 0x818b, 0x819c, 0x81ad,
|
||||
0x81bf, 0x81d0, 0x81e1, 0x81f3, 0x8204, 0x8215,
|
||||
0x8226, 0x8238, 0x8249, 0x825a, 0x826c, 0x827d,
|
||||
0x828e, 0x829f, 0x82b1, 0x82c2, 0x82d3, 0x82e5,
|
||||
0x82f6, 0x8307, 0x8318, 0x832a, 0x833b, 0x834c,
|
||||
0x835d, 0x836f, 0x8380, 0x8391, 0x83a2, 0x83b3,
|
||||
0x83c5, 0x83d6, 0x83e7, 0x83f8, 0x840a, 0x841b,
|
||||
0x842c, 0x843d, 0x844e, 0x8460, 0x8471, 0x8482,
|
||||
0x8493, 0x84a4, 0x84b6, 0x84c7, 0x84d8, 0x84e9,
|
||||
0x84fa, 0x850b, 0x851d, 0x852e, 0x853f, 0x8550,
|
||||
0x8561, 0x8572, 0x8584, 0x8595, 0x85a6, 0x85b7,
|
||||
0x85c8, 0x85d9, 0x85ea, 0x85fb, 0x860d, 0x861e,
|
||||
0x862f, 0x8640, 0x8651, 0x8662, 0x8673, 0x8684,
|
||||
0x8695, 0x86a7, 0x86b8, 0x86c9, 0x86da, 0x86eb,
|
||||
0x86fc, 0x870d, 0x871e, 0x872f, 0x8740, 0x8751,
|
||||
0x8762, 0x8773, 0x8784, 0x8796, 0x87a7, 0x87b8,
|
||||
0x87c9, 0x87da, 0x87eb, 0x87fc, 0x880d, 0x881e,
|
||||
0x882f, 0x8840, 0x8851, 0x8862, 0x8873, 0x8884,
|
||||
0x8895, 0x88a6, 0x88b7, 0x88c8, 0x88d9, 0x88ea,
|
||||
0x88fb, 0x890c, 0x891d, 0x892e, 0x893f, 0x8950,
|
||||
0x8961, 0x8972, 0x8983, 0x8994, 0x89a5, 0x89b6,
|
||||
0x89c6, 0x89d7, 0x89e8, 0x89f9, 0x8a0a, 0x8a1b,
|
||||
0x8a2c, 0x8a3d, 0x8a4e, 0x8a5f, 0x8a70, 0x8a81,
|
||||
0x8a92, 0x8aa3, 0x8ab3, 0x8ac4, 0x8ad5, 0x8ae6,
|
||||
0x8af7, 0x8b08, 0x8b19, 0x8b2a, 0x8b3b, 0x8b4b,
|
||||
0x8b5c, 0x8b6d, 0x8b7e, 0x8b8f, 0x8ba0, 0x8bb1,
|
||||
0x8bc1, 0x8bd2, 0x8be3, 0x8bf4, 0x8c05, 0x8c16,
|
||||
0x8c27, 0x8c37, 0x8c48, 0x8c59, 0x8c6a, 0x8c7b,
|
||||
0x8c8c, 0x8c9c, 0x8cad, 0x8cbe, 0x8ccf, 0x8ce0,
|
||||
0x8cf0, 0x8d01, 0x8d12, 0x8d23, 0x8d34, 0x8d44,
|
||||
0x8d55, 0x8d66, 0x8d77, 0x8d87, 0x8d98, 0x8da9,
|
||||
0x8dba, 0x8dca, 0x8ddb, 0x8dec, 0x8dfd, 0x8e0d,
|
||||
0x8e1e, 0x8e2f, 0x8e40, 0x8e50, 0x8e61, 0x8e72,
|
||||
0x8e83, 0x8e93, 0x8ea4, 0x8eb5, 0x8ec5, 0x8ed6,
|
||||
0x8ee7, 0x8ef8, 0x8f08, 0x8f19, 0x8f2a, 0x8f3a,
|
||||
0x8f4b, 0x8f5c, 0x8f6c, 0x8f7d, 0x8f8e, 0x8f9e,
|
||||
0x8faf, 0x8fc0, 0x8fd0, 0x8fe1, 0x8ff2, 0x9002,
|
||||
0x9013, 0x9024, 0x9034, 0x9045, 0x9056, 0x9066,
|
||||
0x9077, 0x9088, 0x9098, 0x90a9, 0x90b9, 0x90ca,
|
||||
0x90db, 0x90eb, 0x90fc, 0x910c, 0x911d, 0x912e,
|
||||
0x913e, 0x914f, 0x915f, 0x9170, 0x9181, 0x9191,
|
||||
0x91a2, 0x91b2, 0x91c3, 0x91d3, 0x91e4, 0x91f5,
|
||||
0x9205, 0x9216, 0x9226, 0x9237, 0x9247, 0x9258,
|
||||
0x9268, 0x9279, 0x9289, 0x929a, 0x92aa, 0x92bb,
|
||||
0x92cc, 0x92dc, 0x92ed, 0x92fd, 0x930e, 0x931e,
|
||||
0x932f, 0x933f, 0x9350, 0x9360, 0x9370, 0x9381,
|
||||
0x9391, 0x93a2, 0x93b2, 0x93c3, 0x93d3, 0x93e4,
|
||||
0x93f4, 0x9405, 0x9415, 0x9426, 0x9436, 0x9447,
|
||||
0x9457, 0x9467, 0x9478, 0x9488, 0x9499, 0x94a9,
|
||||
0x94ba, 0x94ca, 0x94da, 0x94eb, 0x94fb, 0x950c,
|
||||
0x951c, 0x952c, 0x953d, 0x954d, 0x955e, 0x956e,
|
||||
0x957e, 0x958f, 0x959f, 0x95af, 0x95c0, 0x95d0,
|
||||
0x95e1, 0x95f1, 0x9601, 0x9612, 0x9622, 0x9632,
|
||||
0x9643, 0x9653, 0x9663, 0x9674, 0x9684, 0x9694,
|
||||
0x96a5, 0x96b5, 0x96c5, 0x96d6, 0x96e6, 0x96f6,
|
||||
0x9707, 0x9717, 0x9727, 0x9738, 0x9748, 0x9758,
|
||||
0x9768, 0x9779, 0x9789, 0x9799, 0x97aa, 0x97ba,
|
||||
0x97ca, 0x97da, 0x97eb, 0x97fb, 0x980b, 0x981b,
|
||||
0x982c, 0x983c, 0x984c, 0x985c, 0x986d, 0x987d,
|
||||
0x988d, 0x989d, 0x98ad, 0x98be, 0x98ce, 0x98de,
|
||||
0x98ee, 0x98ff, 0x990f, 0x991f, 0x992f, 0x993f,
|
||||
0x9950, 0x9960, 0x9970, 0x9980, 0x9990, 0x99a0,
|
||||
0x99b1, 0x99c1, 0x99d1, 0x99e1, 0x99f1, 0x9a01,
|
||||
0x9a12, 0x9a22, 0x9a32, 0x9a42, 0x9a52, 0x9a62,
|
||||
0x9a72, 0x9a83, 0x9a93, 0x9aa3, 0x9ab3, 0x9ac3,
|
||||
0x9ad3, 0x9ae3, 0x9af3, 0x9b04, 0x9b14, 0x9b24,
|
||||
0x9b34, 0x9b44, 0x9b54, 0x9b64, 0x9b74, 0x9b84,
|
||||
0x9b94, 0x9ba4, 0x9bb5, 0x9bc5, 0x9bd5, 0x9be5,
|
||||
0x9bf5, 0x9c05, 0x9c15, 0x9c25, 0x9c35, 0x9c45,
|
||||
0x9c55, 0x9c65, 0x9c75, 0x9c85, 0x9c95, 0x9ca5,
|
||||
0x9cb5, 0x9cc5, 0x9cd5, 0x9ce5, 0x9cf5, 0x9d05,
|
||||
0x9d15, 0x9d25, 0x9d35, 0x9d45, 0x9d55, 0x9d65,
|
||||
0x9d75, 0x9d85, 0x9d95, 0x9da5, 0x9db5, 0x9dc5,
|
||||
0x9dd5, 0x9de5, 0x9df5, 0x9e05, 0x9e15, 0x9e25,
|
||||
0x9e35, 0x9e45, 0x9e55, 0x9e65, 0x9e74, 0x9e84,
|
||||
0x9e94, 0x9ea4, 0x9eb4, 0x9ec4, 0x9ed4, 0x9ee4,
|
||||
0x9ef4, 0x9f04, 0x9f14, 0x9f23, 0x9f33, 0x9f43,
|
||||
0x9f53, 0x9f63, 0x9f73, 0x9f83, 0x9f93, 0x9fa3,
|
||||
0x9fb2, 0x9fc2, 0x9fd2, 0x9fe2, 0x9ff2, 0xa002,
|
||||
0xa012, 0xa021, 0xa031, 0xa041, 0xa051, 0xa061,
|
||||
0xa071, 0xa080, 0xa090, 0xa0a0, 0xa0b0, 0xa0c0,
|
||||
0xa0cf, 0xa0df, 0xa0ef, 0xa0ff, 0xa10f, 0xa11e,
|
||||
0xa12e, 0xa13e, 0xa14e, 0xa15e, 0xa16d, 0xa17d,
|
||||
0xa18d, 0xa19d, 0xa1ac, 0xa1bc, 0xa1cc, 0xa1dc,
|
||||
0xa1eb, 0xa1fb, 0xa20b, 0xa21b, 0xa22a, 0xa23a,
|
||||
0xa24a, 0xa25a, 0xa269, 0xa279, 0xa289, 0xa298,
|
||||
0xa2a8, 0xa2b8, 0xa2c8, 0xa2d7, 0xa2e7, 0xa2f7,
|
||||
0xa306, 0xa316, 0xa326, 0xa335, 0xa345, 0xa355,
|
||||
0xa364, 0xa374, 0xa384, 0xa393, 0xa3a3, 0xa3b3,
|
||||
0xa3c2, 0xa3d2, 0xa3e2, 0xa3f1, 0xa401, 0xa411,
|
||||
0xa420, 0xa430, 0xa440, 0xa44f, 0xa45f, 0xa46e,
|
||||
0xa47e, 0xa48e, 0xa49d, 0xa4ad, 0xa4bc, 0xa4cc,
|
||||
0xa4dc, 0xa4eb, 0xa4fb, 0xa50a, 0xa51a, 0xa52a,
|
||||
0xa539, 0xa549, 0xa558, 0xa568, 0xa577, 0xa587,
|
||||
0xa597, 0xa5a6, 0xa5b6, 0xa5c5, 0xa5d5, 0xa5e4,
|
||||
0xa5f4, 0xa603, 0xa613, 0xa622, 0xa632, 0xa641,
|
||||
0xa651, 0xa660, 0xa670, 0xa67f, 0xa68f, 0xa69e,
|
||||
0xa6ae, 0xa6bd, 0xa6cd, 0xa6dc, 0xa6ec, 0xa6fb,
|
||||
0xa70b, 0xa71a, 0xa72a, 0xa739, 0xa749, 0xa758,
|
||||
0xa768, 0xa777, 0xa787, 0xa796, 0xa7a5, 0xa7b5,
|
||||
0xa7c4, 0xa7d4, 0xa7e3, 0xa7f3, 0xa802, 0xa812,
|
||||
0xa821, 0xa830, 0xa840, 0xa84f, 0xa85f, 0xa86e,
|
||||
0xa87d, 0xa88d, 0xa89c, 0xa8ac, 0xa8bb, 0xa8ca,
|
||||
0xa8da, 0xa8e9, 0xa8f8, 0xa908, 0xa917, 0xa927,
|
||||
0xa936, 0xa945, 0xa955, 0xa964, 0xa973, 0xa983,
|
||||
0xa992, 0xa9a1, 0xa9b1, 0xa9c0, 0xa9cf, 0xa9df,
|
||||
0xa9ee, 0xa9fd, 0xaa0d, 0xaa1c, 0xaa2b, 0xaa3b,
|
||||
0xaa4a, 0xaa59, 0xaa69, 0xaa78, 0xaa87, 0xaa96,
|
||||
0xaaa6, 0xaab5, 0xaac4, 0xaad4, 0xaae3, 0xaaf2,
|
||||
0xab01, 0xab11, 0xab20, 0xab2f, 0xab3e, 0xab4e,
|
||||
0xab5d, 0xab6c, 0xab7b, 0xab8b, 0xab9a, 0xaba9,
|
||||
0xabb8, 0xabc7, 0xabd7, 0xabe6, 0xabf5, 0xac04,
|
||||
0xac14, 0xac23, 0xac32, 0xac41, 0xac50, 0xac60,
|
||||
0xac6f, 0xac7e, 0xac8d, 0xac9c, 0xacab, 0xacbb,
|
||||
0xacca, 0xacd9, 0xace8, 0xacf7, 0xad06, 0xad16,
|
||||
0xad25, 0xad34, 0xad43, 0xad52, 0xad61, 0xad70,
|
||||
0xad80, 0xad8f, 0xad9e, 0xadad, 0xadbc, 0xadcb,
|
||||
0xadda, 0xade9, 0xadf8, 0xae08, 0xae17, 0xae26,
|
||||
0xae35, 0xae44, 0xae53, 0xae62, 0xae71, 0xae80,
|
||||
0xae8f, 0xae9e, 0xaead, 0xaebd, 0xaecc, 0xaedb,
|
||||
0xaeea, 0xaef9, 0xaf08, 0xaf17, 0xaf26, 0xaf35,
|
||||
0xaf44, 0xaf53, 0xaf62, 0xaf71, 0xaf80, 0xaf8f,
|
||||
0xaf9e, 0xafad, 0xafbc, 0xafcb, 0xafda, 0xafe9,
|
||||
0xaff8, 0xb007, 0xb016, 0xb025, 0xb034, 0xb043,
|
||||
0xb052, 0xb061, 0xb070, 0xb07f, 0xb08e, 0xb09d,
|
||||
0xb0ac, 0xb0bb, 0xb0ca, 0xb0d9, 0xb0e8, 0xb0f6,
|
||||
0xb105, 0xb114, 0xb123, 0xb132, 0xb141, 0xb150,
|
||||
0xb15f, 0xb16e, 0xb17d, 0xb18c, 0xb19b, 0xb1aa,
|
||||
0xb1b8, 0xb1c7, 0xb1d6, 0xb1e5, 0xb1f4, 0xb203,
|
||||
0xb212, 0xb221, 0xb22f, 0xb23e, 0xb24d, 0xb25c,
|
||||
0xb26b, 0xb27a, 0xb289, 0xb297, 0xb2a6, 0xb2b5,
|
||||
0xb2c4, 0xb2d3, 0xb2e2, 0xb2f1, 0xb2ff, 0xb30e,
|
||||
0xb31d, 0xb32c, 0xb33b, 0xb349, 0xb358, 0xb367,
|
||||
0xb376, 0xb385, 0xb393, 0xb3a2, 0xb3b1, 0xb3c0,
|
||||
0xb3cf, 0xb3dd, 0xb3ec, 0xb3fb, 0xb40a, 0xb418,
|
||||
0xb427, 0xb436, 0xb445, 0xb453, 0xb462, 0xb471,
|
||||
0xb480, 0xb48e, 0xb49d, 0xb4ac, 0xb4bb, 0xb4c9,
|
||||
0xb4d8, 0xb4e7, 0xb4f6, 0xb504, 0xb513, 0xb522,
|
||||
0xb530, 0xb53f, 0xb54e, 0xb55c, 0xb56b, 0xb57a,
|
||||
0xb588, 0xb597, 0xb5a6, 0xb5b5, 0xb5c3, 0xb5d2,
|
||||
0xb5e1, 0xb5ef, 0xb5fe, 0xb60d, 0xb61b, 0xb62a,
|
||||
0xb638, 0xb647, 0xb656, 0xb664, 0xb673, 0xb682,
|
||||
0xb690, 0xb69f, 0xb6ae, 0xb6bc, 0xb6cb, 0xb6d9,
|
||||
0xb6e8, 0xb6f7, 0xb705, 0xb714, 0xb722, 0xb731,
|
||||
0xb740, 0xb74e, 0xb75d, 0xb76b, 0xb77a, 0xb788,
|
||||
0xb797, 0xb7a6, 0xb7b4, 0xb7c3, 0xb7d1, 0xb7e0,
|
||||
0xb7ee, 0xb7fd, 0xb80b, 0xb81a, 0xb829, 0xb837,
|
||||
0xb846, 0xb854, 0xb863, 0xb871, 0xb880, 0xb88e,
|
||||
0xb89d, 0xb8ab, 0xb8ba, 0xb8c8, 0xb8d7, 0xb8e5,
|
||||
0xb8f4, 0xb902, 0xb911, 0xb91f, 0xb92e, 0xb93c,
|
||||
0xb94b, 0xb959, 0xb968, 0xb976, 0xb984, 0xb993,
|
||||
0xb9a1, 0xb9b0, 0xb9be, 0xb9cd, 0xb9db, 0xb9ea,
|
||||
0xb9f8, 0xba06, 0xba15, 0xba23, 0xba32, 0xba40,
|
||||
0xba4f, 0xba5d, 0xba6b, 0xba7a, 0xba88, 0xba97,
|
||||
0xbaa5, 0xbab3, 0xbac2, 0xbad0, 0xbade, 0xbaed,
|
||||
0xbafb, 0xbb0a, 0xbb18, 0xbb26, 0xbb35, 0xbb43,
|
||||
0xbb51, 0xbb60, 0xbb6e, 0xbb7c, 0xbb8b, 0xbb99,
|
||||
0xbba8, 0xbbb6, 0xbbc4, 0xbbd3, 0xbbe1, 0xbbef,
|
||||
0xbbfd, 0xbc0c, 0xbc1a, 0xbc28, 0xbc37, 0xbc45,
|
||||
0xbc53, 0xbc62, 0xbc70, 0xbc7e, 0xbc8c, 0xbc9b,
|
||||
0xbca9, 0xbcb7, 0xbcc6, 0xbcd4, 0xbce2, 0xbcf0,
|
||||
0xbcff, 0xbd0d, 0xbd1b, 0xbd29, 0xbd38, 0xbd46,
|
||||
0xbd54, 0xbd62, 0xbd71, 0xbd7f, 0xbd8d, 0xbd9b,
|
||||
0xbdaa, 0xbdb8, 0xbdc6, 0xbdd4, 0xbde2, 0xbdf1,
|
||||
0xbdff, 0xbe0d, 0xbe1b, 0xbe29, 0xbe38, 0xbe46,
|
||||
0xbe54, 0xbe62, 0xbe70, 0xbe7f, 0xbe8d, 0xbe9b,
|
||||
0xbea9, 0xbeb7, 0xbec5, 0xbed4, 0xbee2, 0xbef0,
|
||||
0xbefe, 0xbf0c, 0xbf1a, 0xbf28, 0xbf37, 0xbf45,
|
||||
0xbf53, 0xbf61, 0xbf6f, 0xbf7d, 0xbf8b, 0xbf99,
|
||||
0xbfa7, 0xbfb6, 0xbfc4, 0xbfd2, 0xbfe0, 0xbfee,
|
||||
0xbffc, 0xc00a, 0xc018, 0xc026, 0xc034, 0xc042,
|
||||
0xc051, 0xc05f, 0xc06d, 0xc07b, 0xc089, 0xc097,
|
||||
0xc0a5, 0xc0b3, 0xc0c1, 0xc0cf, 0xc0dd, 0xc0eb,
|
||||
0xc0f9, 0xc107, 0xc115, 0xc123, 0xc131, 0xc13f,
|
||||
0xc14d, 0xc15b, 0xc169, 0xc177, 0xc185, 0xc193,
|
||||
0xc1a1, 0xc1af, 0xc1bd, 0xc1cb, 0xc1d9, 0xc1e7,
|
||||
0xc1f5, 0xc203, 0xc211, 0xc21f, 0xc22d, 0xc23b,
|
||||
0xc249, 0xc257, 0xc265, 0xc273, 0xc281, 0xc28f,
|
||||
0xc29d, 0xc2ab, 0xc2b8, 0xc2c6, 0xc2d4, 0xc2e2,
|
||||
0xc2f0, 0xc2fe, 0xc30c, 0xc31a, 0xc328, 0xc336,
|
||||
0xc344, 0xc352, 0xc35f, 0xc36d, 0xc37b, 0xc389,
|
||||
0xc397, 0xc3a5, 0xc3b3, 0xc3c1, 0xc3ce, 0xc3dc,
|
||||
0xc3ea, 0xc3f8, 0xc406, 0xc414, 0xc422, 0xc42f,
|
||||
0xc43d, 0xc44b, 0xc459, 0xc467, 0xc475, 0xc482,
|
||||
0xc490, 0xc49e, 0xc4ac, 0xc4ba, 0xc4c7, 0xc4d5,
|
||||
0xc4e3, 0xc4f1, 0xc4ff, 0xc50d, 0xc51a, 0xc528,
|
||||
0xc536, 0xc544, 0xc551, 0xc55f, 0xc56d, 0xc57b,
|
||||
0xc589, 0xc596, 0xc5a4, 0xc5b2, 0xc5c0, 0xc5cd,
|
||||
0xc5db, 0xc5e9, 0xc5f7, 0xc604, 0xc612, 0xc620,
|
||||
0xc62d, 0xc63b, 0xc649, 0xc657, 0xc664, 0xc672,
|
||||
0xc680, 0xc68d, 0xc69b, 0xc6a9, 0xc6b7, 0xc6c4,
|
||||
0xc6d2, 0xc6e0, 0xc6ed, 0xc6fb, 0xc709, 0xc716,
|
||||
0xc724, 0xc732, 0xc73f, 0xc74d, 0xc75b, 0xc768,
|
||||
0xc776, 0xc784, 0xc791, 0xc79f, 0xc7ad, 0xc7ba,
|
||||
0xc7c8, 0xc7d6, 0xc7e3, 0xc7f1, 0xc7fe, 0xc80c,
|
||||
0xc81a, 0xc827, 0xc835, 0xc842, 0xc850, 0xc85e,
|
||||
0xc86b, 0xc879, 0xc886, 0xc894, 0xc8a2, 0xc8af,
|
||||
0xc8bd, 0xc8ca, 0xc8d8, 0xc8e5, 0xc8f3, 0xc901,
|
||||
0xc90e, 0xc91c, 0xc929, 0xc937, 0xc944, 0xc952,
|
||||
0xc95f, 0xc96d, 0xc97b, 0xc988, 0xc996, 0xc9a3,
|
||||
0xc9b1, 0xc9be, 0xc9cc, 0xc9d9, 0xc9e7, 0xc9f4,
|
||||
0xca02, 0xca0f, 0xca1d, 0xca2a, 0xca38, 0xca45,
|
||||
0xca53, 0xca60, 0xca6e, 0xca7b, 0xca89, 0xca96,
|
||||
0xcaa4, 0xcab1, 0xcabe, 0xcacc, 0xcad9, 0xcae7,
|
||||
0xcaf4, 0xcb02, 0xcb0f, 0xcb1d, 0xcb2a, 0xcb37,
|
||||
0xcb45, 0xcb52, 0xcb60, 0xcb6d, 0xcb7b, 0xcb88,
|
||||
0xcb95, 0xcba3, 0xcbb0, 0xcbbe, 0xcbcb, 0xcbd8,
|
||||
0xcbe6, 0xcbf3, 0xcc01, 0xcc0e, 0xcc1b, 0xcc29,
|
||||
0xcc36, 0xcc43, 0xcc51, 0xcc5e, 0xcc6c, 0xcc79,
|
||||
0xcc86, 0xcc94, 0xcca1, 0xccae, 0xccbc, 0xccc9,
|
||||
0xccd6, 0xcce4, 0xccf1, 0xccfe, 0xcd0c, 0xcd19,
|
||||
0xcd26, 0xcd34, 0xcd41, 0xcd4e, 0xcd5b, 0xcd69,
|
||||
0xcd76, 0xcd83, 0xcd91, 0xcd9e, 0xcdab, 0xcdb9,
|
||||
0xcdc6, 0xcdd3, 0xcde0, 0xcdee, 0xcdfb, 0xce08,
|
||||
0xce15, 0xce23, 0xce30, 0xce3d, 0xce4a, 0xce58,
|
||||
0xce65, 0xce72, 0xce7f, 0xce8d, 0xce9a, 0xcea7,
|
||||
0xceb4, 0xcec2, 0xcecf, 0xcedc, 0xcee9, 0xcef6,
|
||||
0xcf04, 0xcf11, 0xcf1e, 0xcf2b, 0xcf38, 0xcf46,
|
||||
0xcf53, 0xcf60, 0xcf6d, 0xcf7a, 0xcf87, 0xcf95,
|
||||
0xcfa2, 0xcfaf, 0xcfbc, 0xcfc9, 0xcfd6, 0xcfe4,
|
||||
0xcff1, 0xcffe, 0xd00b, 0xd018, 0xd025, 0xd032,
|
||||
0xd040, 0xd04d, 0xd05a, 0xd067, 0xd074, 0xd081,
|
||||
0xd08e, 0xd09b, 0xd0a9, 0xd0b6, 0xd0c3, 0xd0d0,
|
||||
0xd0dd, 0xd0ea, 0xd0f7, 0xd104, 0xd111, 0xd11e,
|
||||
0xd12b, 0xd139, 0xd146, 0xd153, 0xd160, 0xd16d,
|
||||
0xd17a, 0xd187, 0xd194, 0xd1a1, 0xd1ae, 0xd1bb,
|
||||
0xd1c8, 0xd1d5, 0xd1e2, 0xd1ef, 0xd1fc, 0xd209,
|
||||
0xd216, 0xd223, 0xd230, 0xd23d, 0xd24a, 0xd257,
|
||||
0xd264, 0xd271, 0xd27e, 0xd28b, 0xd298, 0xd2a5,
|
||||
0xd2b2, 0xd2bf, 0xd2cc, 0xd2d9, 0xd2e6, 0xd2f3,
|
||||
0xd300, 0xd30d, 0xd31a, 0xd327, 0xd334, 0xd341,
|
||||
0xd34e, 0xd35b, 0xd368, 0xd375, 0xd382, 0xd38f,
|
||||
0xd39c, 0xd3a8, 0xd3b5, 0xd3c2, 0xd3cf, 0xd3dc,
|
||||
0xd3e9, 0xd3f6, 0xd403, 0xd410, 0xd41d, 0xd42a,
|
||||
0xd436, 0xd443, 0xd450, 0xd45d, 0xd46a, 0xd477,
|
||||
0xd484, 0xd491, 0xd49e, 0xd4aa, 0xd4b7, 0xd4c4,
|
||||
0xd4d1, 0xd4de, 0xd4eb, 0xd4f8, 0xd504, 0xd511,
|
||||
0xd51e, 0xd52b, 0xd538, 0xd545, 0xd551, 0xd55e,
|
||||
0xd56b, 0xd578, 0xd585, 0xd591, 0xd59e, 0xd5ab,
|
||||
0xd5b8, 0xd5c5, 0xd5d1, 0xd5de, 0xd5eb, 0xd5f8,
|
||||
0xd605, 0xd611, 0xd61e, 0xd62b, 0xd638, 0xd645,
|
||||
0xd651, 0xd65e, 0xd66b, 0xd678, 0xd684, 0xd691,
|
||||
0xd69e, 0xd6ab, 0xd6b7, 0xd6c4, 0xd6d1, 0xd6de,
|
||||
0xd6ea, 0xd6f7, 0xd704, 0xd710, 0xd71d, 0xd72a,
|
||||
0xd737, 0xd743, 0xd750, 0xd75d, 0xd769, 0xd776,
|
||||
0xd783, 0xd78f, 0xd79c, 0xd7a9, 0xd7b6, 0xd7c2,
|
||||
0xd7cf, 0xd7dc, 0xd7e8, 0xd7f5, 0xd802, 0xd80e,
|
||||
0xd81b, 0xd828, 0xd834, 0xd841, 0xd84e, 0xd85a,
|
||||
0xd867, 0xd873, 0xd880, 0xd88d, 0xd899, 0xd8a6,
|
||||
0xd8b3, 0xd8bf, 0xd8cc, 0xd8d8, 0xd8e5, 0xd8f2,
|
||||
0xd8fe, 0xd90b, 0xd917, 0xd924, 0xd931, 0xd93d,
|
||||
0xd94a, 0xd956, 0xd963, 0xd970, 0xd97c, 0xd989,
|
||||
0xd995, 0xd9a2, 0xd9ae, 0xd9bb, 0xd9c8, 0xd9d4,
|
||||
0xd9e1, 0xd9ed, 0xd9fa, 0xda06, 0xda13, 0xda1f,
|
||||
0xda2c, 0xda38, 0xda45, 0xda51, 0xda5e, 0xda6a,
|
||||
0xda77, 0xda84, 0xda90, 0xda9d, 0xdaa9, 0xdab6,
|
||||
0xdac2, 0xdacf, 0xdadb, 0xdae7, 0xdaf4, 0xdb00,
|
||||
0xdb0d, 0xdb19, 0xdb26, 0xdb32, 0xdb3f, 0xdb4b,
|
||||
0xdb58, 0xdb64, 0xdb71, 0xdb7d, 0xdb8a, 0xdb96,
|
||||
0xdba2, 0xdbaf, 0xdbbb, 0xdbc8, 0xdbd4, 0xdbe1,
|
||||
0xdbed, 0xdbf9, 0xdc06, 0xdc12, 0xdc1f, 0xdc2b,
|
||||
0xdc38, 0xdc44, 0xdc50, 0xdc5d, 0xdc69, 0xdc76,
|
||||
0xdc82, 0xdc8e, 0xdc9b, 0xdca7, 0xdcb3, 0xdcc0,
|
||||
0xdccc, 0xdcd9, 0xdce5, 0xdcf1, 0xdcfe, 0xdd0a,
|
||||
0xdd16, 0xdd23, 0xdd2f, 0xdd3b, 0xdd48, 0xdd54,
|
||||
0xdd60, 0xdd6d, 0xdd79, 0xdd85, 0xdd92, 0xdd9e,
|
||||
0xddaa, 0xddb7, 0xddc3, 0xddcf, 0xdddc, 0xdde8,
|
||||
0xddf4, 0xde01, 0xde0d, 0xde19, 0xde25, 0xde32,
|
||||
0xde3e, 0xde4a, 0xde57, 0xde63, 0xde6f, 0xde7b,
|
||||
0xde88, 0xde94, 0xdea0, 0xdeac, 0xdeb9, 0xdec5,
|
||||
0xded1, 0xdedd, 0xdeea, 0xdef6, 0xdf02, 0xdf0e,
|
||||
0xdf1b, 0xdf27, 0xdf33, 0xdf3f, 0xdf4c, 0xdf58,
|
||||
0xdf64, 0xdf70, 0xdf7c, 0xdf89, 0xdf95, 0xdfa1,
|
||||
0xdfad, 0xdfb9, 0xdfc6, 0xdfd2, 0xdfde, 0xdfea,
|
||||
0xdff6, 0xe003, 0xe00f, 0xe01b, 0xe027, 0xe033,
|
||||
0xe03f, 0xe04c, 0xe058, 0xe064, 0xe070, 0xe07c,
|
||||
0xe088, 0xe094, 0xe0a1, 0xe0ad, 0xe0b9, 0xe0c5,
|
||||
0xe0d1, 0xe0dd, 0xe0e9, 0xe0f5, 0xe102, 0xe10e,
|
||||
0xe11a, 0xe126, 0xe132, 0xe13e, 0xe14a, 0xe156,
|
||||
0xe162, 0xe16e, 0xe17b, 0xe187, 0xe193, 0xe19f,
|
||||
0xe1ab, 0xe1b7, 0xe1c3, 0xe1cf, 0xe1db, 0xe1e7,
|
||||
0xe1f3, 0xe1ff, 0xe20b, 0xe217, 0xe223, 0xe22f,
|
||||
0xe23c, 0xe248, 0xe254, 0xe260, 0xe26c, 0xe278,
|
||||
0xe284, 0xe290, 0xe29c, 0xe2a8, 0xe2b4, 0xe2c0,
|
||||
0xe2cc, 0xe2d8, 0xe2e4, 0xe2f0, 0xe2fc, 0xe308,
|
||||
0xe314, 0xe320, 0xe32c, 0xe338, 0xe344, 0xe350,
|
||||
0xe35c, 0xe368, 0xe374, 0xe380, 0xe38b, 0xe397,
|
||||
0xe3a3, 0xe3af, 0xe3bb, 0xe3c7, 0xe3d3, 0xe3df,
|
||||
0xe3eb, 0xe3f7, 0xe403, 0xe40f, 0xe41b, 0xe427,
|
||||
0xe433, 0xe43f, 0xe44a, 0xe456, 0xe462, 0xe46e,
|
||||
0xe47a, 0xe486, 0xe492, 0xe49e, 0xe4aa, 0xe4b6,
|
||||
0xe4c1, 0xe4cd, 0xe4d9, 0xe4e5, 0xe4f1, 0xe4fd,
|
||||
0xe509, 0xe515, 0xe520, 0xe52c, 0xe538, 0xe544,
|
||||
0xe550, 0xe55c, 0xe567, 0xe573, 0xe57f, 0xe58b,
|
||||
0xe597, 0xe5a3, 0xe5af, 0xe5ba, 0xe5c6, 0xe5d2,
|
||||
0xe5de, 0xe5ea, 0xe5f5, 0xe601, 0xe60d, 0xe619,
|
||||
0xe625, 0xe630, 0xe63c, 0xe648, 0xe654, 0xe660,
|
||||
0xe66b, 0xe677, 0xe683, 0xe68f, 0xe69a, 0xe6a6,
|
||||
0xe6b2, 0xe6be, 0xe6ca, 0xe6d5, 0xe6e1, 0xe6ed,
|
||||
0xe6f9, 0xe704, 0xe710, 0xe71c, 0xe727, 0xe733,
|
||||
0xe73f, 0xe74b, 0xe756, 0xe762, 0xe76e, 0xe77a,
|
||||
0xe785, 0xe791, 0xe79d, 0xe7a8, 0xe7b4, 0xe7c0,
|
||||
0xe7cb, 0xe7d7, 0xe7e3, 0xe7ef, 0xe7fa, 0xe806,
|
||||
0xe812, 0xe81d, 0xe829, 0xe835, 0xe840, 0xe84c,
|
||||
0xe858, 0xe863, 0xe86f, 0xe87b, 0xe886, 0xe892,
|
||||
0xe89e, 0xe8a9, 0xe8b5, 0xe8c0, 0xe8cc, 0xe8d8,
|
||||
0xe8e3, 0xe8ef, 0xe8fb, 0xe906, 0xe912, 0xe91d,
|
||||
0xe929, 0xe935, 0xe940, 0xe94c, 0xe958, 0xe963,
|
||||
0xe96f, 0xe97a, 0xe986, 0xe991, 0xe99d, 0xe9a9,
|
||||
0xe9b4, 0xe9c0, 0xe9cb, 0xe9d7, 0xe9e3, 0xe9ee,
|
||||
0xe9fa, 0xea05, 0xea11, 0xea1c, 0xea28, 0xea33,
|
||||
0xea3f, 0xea4a, 0xea56, 0xea62, 0xea6d, 0xea79,
|
||||
0xea84, 0xea90, 0xea9b, 0xeaa7, 0xeab2, 0xeabe,
|
||||
0xeac9, 0xead5, 0xeae0, 0xeaec, 0xeaf7, 0xeb03,
|
||||
0xeb0e, 0xeb1a, 0xeb25, 0xeb31, 0xeb3c, 0xeb48,
|
||||
0xeb53, 0xeb5f, 0xeb6a, 0xeb76, 0xeb81, 0xeb8d,
|
||||
0xeb98, 0xeba3, 0xebaf, 0xebba, 0xebc6, 0xebd1,
|
||||
0xebdd, 0xebe8, 0xebf4, 0xebff, 0xec0a, 0xec16,
|
||||
0xec21, 0xec2d, 0xec38, 0xec44, 0xec4f, 0xec5a,
|
||||
0xec66, 0xec71, 0xec7d, 0xec88, 0xec93, 0xec9f,
|
||||
0xecaa, 0xecb6, 0xecc1, 0xeccc, 0xecd8, 0xece3,
|
||||
0xecef, 0xecfa, 0xed05, 0xed11, 0xed1c, 0xed27,
|
||||
0xed33, 0xed3e, 0xed4a, 0xed55, 0xed60, 0xed6c,
|
||||
0xed77, 0xed82, 0xed8e, 0xed99, 0xeda4, 0xedb0,
|
||||
0xedbb, 0xedc6, 0xedd2, 0xeddd, 0xede8, 0xedf4,
|
||||
0xedff, 0xee0a, 0xee15, 0xee21, 0xee2c, 0xee37,
|
||||
0xee43, 0xee4e, 0xee59, 0xee65, 0xee70, 0xee7b,
|
||||
0xee86, 0xee92, 0xee9d, 0xeea8, 0xeeb3, 0xeebf,
|
||||
0xeeca, 0xeed5, 0xeee1, 0xeeec, 0xeef7, 0xef02,
|
||||
0xef0e, 0xef19, 0xef24, 0xef2f, 0xef3a, 0xef46,
|
||||
0xef51, 0xef5c, 0xef67, 0xef73, 0xef7e, 0xef89,
|
||||
0xef94, 0xef9f, 0xefab, 0xefb6, 0xefc1, 0xefcc,
|
||||
0xefd7, 0xefe3, 0xefee, 0xeff9, 0xf004, 0xf00f,
|
||||
0xf01b, 0xf026, 0xf031, 0xf03c, 0xf047, 0xf052,
|
||||
0xf05e, 0xf069, 0xf074, 0xf07f, 0xf08a, 0xf095,
|
||||
0xf0a1, 0xf0ac, 0xf0b7, 0xf0c2, 0xf0cd, 0xf0d8,
|
||||
0xf0e3, 0xf0ef, 0xf0fa, 0xf105, 0xf110, 0xf11b,
|
||||
0xf126, 0xf131, 0xf13c, 0xf147, 0xf153, 0xf15e,
|
||||
0xf169, 0xf174, 0xf17f, 0xf18a, 0xf195, 0xf1a0,
|
||||
0xf1ab, 0xf1b6, 0xf1c2, 0xf1cd, 0xf1d8, 0xf1e3,
|
||||
0xf1ee, 0xf1f9, 0xf204, 0xf20f, 0xf21a, 0xf225,
|
||||
0xf230, 0xf23b, 0xf246, 0xf251, 0xf25c, 0xf267,
|
||||
0xf272, 0xf27d, 0xf288, 0xf293, 0xf29f, 0xf2aa,
|
||||
0xf2b5, 0xf2c0, 0xf2cb, 0xf2d6, 0xf2e1, 0xf2ec,
|
||||
0xf2f7, 0xf302, 0xf30d, 0xf318, 0xf323, 0xf32e,
|
||||
0xf339, 0xf344, 0xf34f, 0xf35a, 0xf364, 0xf36f,
|
||||
0xf37a, 0xf385, 0xf390, 0xf39b, 0xf3a6, 0xf3b1,
|
||||
0xf3bc, 0xf3c7, 0xf3d2, 0xf3dd, 0xf3e8, 0xf3f3,
|
||||
0xf3fe, 0xf409, 0xf414, 0xf41f, 0xf42a, 0xf435,
|
||||
0xf43f, 0xf44a, 0xf455, 0xf460, 0xf46b, 0xf476,
|
||||
0xf481, 0xf48c, 0xf497, 0xf4a2, 0xf4ad, 0xf4b7,
|
||||
0xf4c2, 0xf4cd, 0xf4d8, 0xf4e3, 0xf4ee, 0xf4f9,
|
||||
0xf504, 0xf50f, 0xf519, 0xf524, 0xf52f, 0xf53a,
|
||||
0xf545, 0xf550, 0xf55b, 0xf565, 0xf570, 0xf57b,
|
||||
0xf586, 0xf591, 0xf59c, 0xf5a6, 0xf5b1, 0xf5bc,
|
||||
0xf5c7, 0xf5d2, 0xf5dd, 0xf5e7, 0xf5f2, 0xf5fd,
|
||||
0xf608, 0xf613, 0xf61d, 0xf628, 0xf633, 0xf63e,
|
||||
0xf649, 0xf653, 0xf65e, 0xf669, 0xf674, 0xf67f,
|
||||
0xf689, 0xf694, 0xf69f, 0xf6aa, 0xf6b4, 0xf6bf,
|
||||
0xf6ca, 0xf6d5, 0xf6e0, 0xf6ea, 0xf6f5, 0xf700,
|
||||
0xf70b, 0xf715, 0xf720, 0xf72b, 0xf736, 0xf740,
|
||||
0xf74b, 0xf756, 0xf760, 0xf76b, 0xf776, 0xf781,
|
||||
0xf78b, 0xf796, 0xf7a1, 0xf7ab, 0xf7b6, 0xf7c1,
|
||||
0xf7cc, 0xf7d6, 0xf7e1, 0xf7ec, 0xf7f6, 0xf801,
|
||||
0xf80c, 0xf816, 0xf821, 0xf82c, 0xf836, 0xf841,
|
||||
0xf84c, 0xf856, 0xf861, 0xf86c, 0xf876, 0xf881,
|
||||
0xf88c, 0xf896, 0xf8a1, 0xf8ac, 0xf8b6, 0xf8c1,
|
||||
0xf8cc, 0xf8d6, 0xf8e1, 0xf8ec, 0xf8f6, 0xf901,
|
||||
0xf90b, 0xf916, 0xf921, 0xf92b, 0xf936, 0xf941,
|
||||
0xf94b, 0xf956, 0xf960, 0xf96b, 0xf976, 0xf980,
|
||||
0xf98b, 0xf995, 0xf9a0, 0xf9aa, 0xf9b5, 0xf9c0,
|
||||
0xf9ca, 0xf9d5, 0xf9df, 0xf9ea, 0xf9f4, 0xf9ff,
|
||||
0xfa0a, 0xfa14, 0xfa1f, 0xfa29, 0xfa34, 0xfa3e,
|
||||
0xfa49, 0xfa53, 0xfa5e, 0xfa69, 0xfa73, 0xfa7e,
|
||||
0xfa88, 0xfa93, 0xfa9d, 0xfaa8, 0xfab2, 0xfabd,
|
||||
0xfac7, 0xfad2, 0xfadc, 0xfae7, 0xfaf1, 0xfafc,
|
||||
0xfb06, 0xfb11, 0xfb1b, 0xfb26, 0xfb30, 0xfb3b,
|
||||
0xfb45, 0xfb50, 0xfb5a, 0xfb65, 0xfb6f, 0xfb7a,
|
||||
0xfb84, 0xfb8f, 0xfb99, 0xfba4, 0xfbae, 0xfbb8,
|
||||
0xfbc3, 0xfbcd, 0xfbd8, 0xfbe2, 0xfbed, 0xfbf7,
|
||||
0xfc02, 0xfc0c, 0xfc16, 0xfc21, 0xfc2b, 0xfc36,
|
||||
0xfc40, 0xfc4b, 0xfc55, 0xfc5f, 0xfc6a, 0xfc74,
|
||||
0xfc7f, 0xfc89, 0xfc93, 0xfc9e, 0xfca8, 0xfcb3,
|
||||
0xfcbd, 0xfcc7, 0xfcd2, 0xfcdc, 0xfce7, 0xfcf1,
|
||||
0xfcfb, 0xfd06, 0xfd10, 0xfd1a, 0xfd25, 0xfd2f,
|
||||
0xfd3a, 0xfd44, 0xfd4e, 0xfd59, 0xfd63, 0xfd6d,
|
||||
0xfd78, 0xfd82, 0xfd8c, 0xfd97, 0xfda1, 0xfdab,
|
||||
0xfdb6, 0xfdc0, 0xfdca, 0xfdd5, 0xfddf, 0xfde9,
|
||||
0xfdf4, 0xfdfe, 0xfe08, 0xfe13, 0xfe1d, 0xfe27,
|
||||
0xfe32, 0xfe3c, 0xfe46, 0xfe50, 0xfe5b, 0xfe65,
|
||||
0xfe6f, 0xfe7a, 0xfe84, 0xfe8e, 0xfe98, 0xfea3,
|
||||
0xfead, 0xfeb7, 0xfec1, 0xfecc, 0xfed6, 0xfee0,
|
||||
0xfeeb, 0xfef5, 0xfeff, 0xff09, 0xff14, 0xff1e,
|
||||
0xff28, 0xff32, 0xff3c, 0xff47, 0xff51, 0xff5b,
|
||||
0xff65, 0xff70, 0xff7a, 0xff84, 0xff8e, 0xff98,
|
||||
0xffa3, 0xffad, 0xffb7, 0xffc1, 0xffcc, 0xffd6,
|
||||
0xffe0, 0xffea, 0xfff4, 0xffff
|
||||
};
|
||||
|
||||
// max value is pi/4
|
||||
constexpr double SCALING_FACTOR = 4. / M_PI * 0xFFFF;
|
||||
|
||||
inline double atan2_lookup(double y, double x)
|
||||
{
|
||||
if (std::abs(x) < std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
if (y >= 0.)
|
||||
{
|
||||
return M_PI / 2.;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -M_PI / 2.;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned octant = 0;
|
||||
|
||||
if (x < 0.)
|
||||
{
|
||||
octant = 1;
|
||||
x = -x;
|
||||
}
|
||||
if (y < 0.)
|
||||
{
|
||||
octant |= 2;
|
||||
y = -y;
|
||||
}
|
||||
|
||||
double t = y / x;
|
||||
if (t > 1.0)
|
||||
{
|
||||
octant |= 4;
|
||||
t = 1.0 / t;
|
||||
}
|
||||
|
||||
double angle = atan_table[(unsigned)(t * 4095)] / SCALING_FACTOR;
|
||||
|
||||
switch (octant)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
angle = M_PI - angle;
|
||||
break;
|
||||
case 2:
|
||||
angle = -angle;
|
||||
break;
|
||||
case 3:
|
||||
angle = -M_PI + angle;
|
||||
break;
|
||||
case 4:
|
||||
angle = M_PI / 2.0 - angle;
|
||||
break;
|
||||
case 5:
|
||||
angle = M_PI / 2.0 + angle;
|
||||
break;
|
||||
case 6:
|
||||
angle = -M_PI / 2.0 + angle;
|
||||
break;
|
||||
case 7:
|
||||
angle = -M_PI / 2.0 - angle;
|
||||
break;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
|
||||
#endif // TRIGONOMETRY_TABLES_H
|
||||
@@ -1,65 +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 "bearing.hpp"
|
||||
|
||||
std::string Bearing::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";
|
||||
}
|
||||
-188
@@ -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
|
||||
@@ -1,51 +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 "compute_angle.hpp"
|
||||
|
||||
#include "TrigonometryTables.h"
|
||||
#include "../Util/MercatorUtil.h"
|
||||
#include <osrm/Coordinate.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
double ComputeAngle::OfThreeFixedPointCoordinates(const FixedPointCoordinate &A,
|
||||
const FixedPointCoordinate &C,
|
||||
const FixedPointCoordinate &B)
|
||||
{
|
||||
const double v1x = (A.lon - C.lon) / COORDINATE_PRECISION;
|
||||
const double v1y = lat2y(A.lat / COORDINATE_PRECISION) - lat2y(C.lat / COORDINATE_PRECISION);
|
||||
const double v2x = (B.lon - C.lon) / COORDINATE_PRECISION;
|
||||
const double v2y = lat2y(B.lat / COORDINATE_PRECISION) - lat2y(C.lat / COORDINATE_PRECISION);
|
||||
|
||||
double angle = (atan2_lookup(v2y, v2x) - atan2_lookup(v1y, v1x)) * 180. / M_PI;
|
||||
while (angle < 0.)
|
||||
{
|
||||
angle += 360.;
|
||||
}
|
||||
return angle;
|
||||
}
|
||||
@@ -1,41 +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 COMPUTE_ANGLE_HPP
|
||||
#define COMPUTE_ANGLE_HPP
|
||||
|
||||
struct FixedPointCoordinate;
|
||||
struct NodeInfo;
|
||||
|
||||
struct ComputeAngle
|
||||
{
|
||||
/* Get angle of line segment (A,C)->(C,B), atan2 magic, formerly cosine theorem*/
|
||||
static double OfThreeFixedPointCoordinates(const FixedPointCoordinate &A,
|
||||
const FixedPointCoordinate &C,
|
||||
const FixedPointCoordinate &B);
|
||||
};
|
||||
#endif // COMPUTE_ANGLE_HPP
|
||||
@@ -1,82 +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 CONTAINER_HPP_
|
||||
#define CONTAINER_HPP_
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
template <typename T> void sort_unique_resize(std::vector<T> &vector)
|
||||
{
|
||||
std::sort(vector.begin(), vector.end());
|
||||
const auto number_of_unique_elements = std::unique(vector.begin(), vector.end()) - vector.begin();
|
||||
vector.resize(number_of_unique_elements);
|
||||
}
|
||||
|
||||
// template <typename T> inline void sort_unique_resize_shrink_vector(std::vector<T> &vector)
|
||||
// {
|
||||
// sort_unique_resize(vector);
|
||||
// vector.shrink_to_fit();
|
||||
// }
|
||||
|
||||
// template <typename T> inline void remove_consecutive_duplicates_from_vector(std::vector<T> &vector)
|
||||
// {
|
||||
// const auto number_of_unique_elements = std::unique(vector.begin(), vector.end()) - vector.begin();
|
||||
// vector.resize(number_of_unique_elements);
|
||||
// }
|
||||
|
||||
template <typename ForwardIterator, typename Function>
|
||||
Function for_each_pair(ForwardIterator begin, ForwardIterator end, Function function)
|
||||
{
|
||||
if (begin == end)
|
||||
{
|
||||
return function;
|
||||
}
|
||||
|
||||
auto next = begin;
|
||||
next = std::next(next);
|
||||
|
||||
while (next != end)
|
||||
{
|
||||
function(*begin, *next);
|
||||
begin = std::next(begin); next = std::next(next);
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
template <class ContainerT, typename Function>
|
||||
Function for_each_pair(ContainerT &container, Function function)
|
||||
{
|
||||
return for_each_pair(std::begin(container), std::end(container), function);
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* CONTAINER_HPP_ */
|
||||
@@ -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.
|
||||
|
||||
*/
|
||||
|
||||
#include "FingerPrint.h"
|
||||
|
||||
#include "OSRMException.h"
|
||||
|
||||
#include <boost/uuid/name_generator.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#cmakedefine01 HAS64BITS
|
||||
#cmakedefine MD5PREPARE "${MD5PREPARE}"
|
||||
#cmakedefine MD5RTREE "${MD5RTREE}"
|
||||
#cmakedefine MD5GRAPH "${MD5GRAPH}"
|
||||
#cmakedefine MD5OBJECTS "${MD5OBJECTS}"
|
||||
|
||||
FingerPrint::FingerPrint() : magic_number(1297240911)
|
||||
{
|
||||
md5_prepare[32] = md5_tree[32] = md5_graph[32] = md5_objects[32] = '\0';
|
||||
|
||||
boost::uuids::name_generator gen(named_uuid);
|
||||
std::string temp_string;
|
||||
|
||||
std::memcpy(md5_prepare, MD5PREPARE, strlen(MD5PREPARE));
|
||||
temp_string += md5_prepare;
|
||||
std::memcpy(md5_tree, MD5RTREE, 32);
|
||||
temp_string += md5_tree;
|
||||
std::memcpy(md5_graph, MD5GRAPH, 32);
|
||||
temp_string += md5_graph;
|
||||
std::memcpy(md5_objects, MD5OBJECTS, 32);
|
||||
temp_string += md5_objects;
|
||||
|
||||
named_uuid = gen(temp_string);
|
||||
has_64_bits = HAS64BITS;
|
||||
}
|
||||
|
||||
FingerPrint::~FingerPrint() {}
|
||||
|
||||
const boost::uuids::uuid &FingerPrint::GetFingerPrint() const { return named_uuid; }
|
||||
|
||||
bool FingerPrint::IsMagicNumberOK() const { return 1297240911 == magic_number; }
|
||||
|
||||
bool FingerPrint::TestGraphUtil(const FingerPrint &other) const
|
||||
{
|
||||
if (!other.IsMagicNumberOK())
|
||||
{
|
||||
throw OSRMException("hsgr input file misses magic number. Check or reprocess the file");
|
||||
}
|
||||
return std::equal(md5_graph, md5_graph + 32, other.md5_graph);
|
||||
}
|
||||
|
||||
bool FingerPrint::TestPrepare(const FingerPrint &other) const
|
||||
{
|
||||
if (!other.IsMagicNumberOK())
|
||||
{
|
||||
throw OSRMException("osrm input file misses magic number. Check or reprocess the file");
|
||||
}
|
||||
return std::equal(md5_prepare, md5_prepare + 32, other.md5_prepare);
|
||||
}
|
||||
|
||||
bool FingerPrint::TestRTree(const FingerPrint &other) const
|
||||
{
|
||||
if (!other.IsMagicNumberOK())
|
||||
{
|
||||
throw OSRMException("r-tree input file misses magic number. Check or reprocess the file");
|
||||
}
|
||||
return std::equal(md5_tree, md5_tree + 32, other.md5_tree);
|
||||
}
|
||||
|
||||
bool FingerPrint::TestQueryObjects(const FingerPrint &other) const
|
||||
{
|
||||
if (!other.IsMagicNumberOK())
|
||||
{
|
||||
throw OSRMException("missing magic number. Check or reprocess the file");
|
||||
}
|
||||
return std::equal(md5_objects, md5_objects + 32, other.md5_objects);
|
||||
}
|
||||
@@ -1,325 +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 GRAPHLOADER_H
|
||||
#define GRAPHLOADER_H
|
||||
|
||||
#include "OSRMException.h"
|
||||
#include "../data_structures/external_memory_node.hpp"
|
||||
#include "../data_structures/import_edge.hpp"
|
||||
#include "../data_structures/query_node.hpp"
|
||||
#include "../data_structures/restriction.hpp"
|
||||
#include "../Util/simple_logger.hpp"
|
||||
#include "../Util/FingerPrint.h"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
template <typename EdgeT>
|
||||
NodeID readBinaryOSRMGraphFromStream(std::istream &input_stream,
|
||||
std::vector<EdgeT> &edge_list,
|
||||
std::vector<NodeID> &barrier_node_list,
|
||||
std::vector<NodeID> &traffic_light_node_list,
|
||||
std::vector<QueryNode> *int_to_ext_node_id_map,
|
||||
std::vector<TurnRestriction> &restriction_list)
|
||||
{
|
||||
const FingerPrint fingerprint_orig;
|
||||
FingerPrint fingerprint_loaded;
|
||||
input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
|
||||
|
||||
if (!fingerprint_loaded.TestGraphUtil(fingerprint_orig))
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << ".osrm was prepared with different build.\n"
|
||||
"Reprocess to get rid of this warning.";
|
||||
}
|
||||
|
||||
std::unordered_map<NodeID, NodeID> ext_to_int_id_map;
|
||||
|
||||
NodeID n;
|
||||
input_stream.read((char *)&n, sizeof(NodeID));
|
||||
SimpleLogger().Write() << "Importing n = " << n << " nodes ";
|
||||
|
||||
ExternalMemoryNode current_node;
|
||||
for (NodeID i = 0; i < n; ++i)
|
||||
{
|
||||
input_stream.read((char *)¤t_node, sizeof(ExternalMemoryNode));
|
||||
int_to_ext_node_id_map->emplace_back(current_node.lat, current_node.lon, current_node.node_id);
|
||||
ext_to_int_id_map.emplace(current_node.node_id, i);
|
||||
if (current_node.barrier)
|
||||
{
|
||||
barrier_node_list.emplace_back(i);
|
||||
}
|
||||
if (current_node.traffic_lights)
|
||||
{
|
||||
traffic_light_node_list.emplace_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
// tighten vector sizes
|
||||
barrier_node_list.shrink_to_fit();
|
||||
traffic_light_node_list.shrink_to_fit();
|
||||
|
||||
// renumber nodes in turn restrictions
|
||||
for (TurnRestriction ¤t_restriction : restriction_list)
|
||||
{
|
||||
auto internal_id_iter = ext_to_int_id_map.find(current_restriction.from.node);
|
||||
if (internal_id_iter == ext_to_int_id_map.end())
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "Unmapped from Node of restriction";
|
||||
continue;
|
||||
}
|
||||
current_restriction.from.node = internal_id_iter->second;
|
||||
|
||||
internal_id_iter = ext_to_int_id_map.find(current_restriction.via.node);
|
||||
if (internal_id_iter == ext_to_int_id_map.end())
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "Unmapped via node of restriction";
|
||||
continue;
|
||||
}
|
||||
current_restriction.via.node = internal_id_iter->second;
|
||||
|
||||
internal_id_iter = ext_to_int_id_map.find(current_restriction.to.node);
|
||||
if (internal_id_iter == ext_to_int_id_map.end())
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "Unmapped to node of restriction";
|
||||
continue;
|
||||
}
|
||||
current_restriction.to.node = internal_id_iter->second;
|
||||
}
|
||||
|
||||
EdgeWeight weight;
|
||||
NodeID source, target;
|
||||
unsigned nameID;
|
||||
int length;
|
||||
short dir; // direction (0 = open, 1 = forward, 2+ = open)
|
||||
bool is_roundabout, ignore_in_grid, is_access_restricted, is_split;
|
||||
TravelMode travel_mode;
|
||||
|
||||
EdgeID m;
|
||||
input_stream.read((char *)&m, sizeof(unsigned));
|
||||
edge_list.reserve(m);
|
||||
SimpleLogger().Write() << " and " << m << " edges ";
|
||||
|
||||
for (EdgeID i = 0; i < m; ++i)
|
||||
{
|
||||
input_stream.read((char *)&source, sizeof(unsigned));
|
||||
input_stream.read((char *)&target, sizeof(unsigned));
|
||||
input_stream.read((char *)&length, sizeof(int));
|
||||
input_stream.read((char *)&dir, sizeof(short));
|
||||
input_stream.read((char *)&weight, sizeof(int));
|
||||
input_stream.read((char *)&nameID, sizeof(unsigned));
|
||||
input_stream.read((char *)&is_roundabout, sizeof(bool));
|
||||
input_stream.read((char *)&ignore_in_grid, sizeof(bool));
|
||||
input_stream.read((char *)&is_access_restricted, sizeof(bool));
|
||||
input_stream.read((char *)&travel_mode, sizeof(TravelMode));
|
||||
input_stream.read((char *)&is_split, sizeof(bool));
|
||||
|
||||
BOOST_ASSERT_MSG(length > 0, "loaded null length edge");
|
||||
BOOST_ASSERT_MSG(weight > 0, "loaded null weight");
|
||||
BOOST_ASSERT_MSG(0 <= dir && dir <= 2, "loaded bogus direction");
|
||||
|
||||
bool forward = true;
|
||||
bool backward = true;
|
||||
if (1 == dir)
|
||||
{
|
||||
backward = false;
|
||||
}
|
||||
if (2 == dir)
|
||||
{
|
||||
forward = false;
|
||||
}
|
||||
|
||||
// translate the external NodeIDs to internal IDs
|
||||
auto internal_id_iter = ext_to_int_id_map.find(source);
|
||||
if (ext_to_int_id_map.find(source) == ext_to_int_id_map.end())
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
SimpleLogger().Write(logWARNING) << " unresolved source NodeID: " << source;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
source = internal_id_iter->second;
|
||||
internal_id_iter = ext_to_int_id_map.find(target);
|
||||
if (ext_to_int_id_map.find(target) == ext_to_int_id_map.end())
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
SimpleLogger().Write(logWARNING) << "unresolved target NodeID : " << target;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
target = internal_id_iter->second;
|
||||
BOOST_ASSERT_MSG(source != SPECIAL_NODEID && target != SPECIAL_NODEID,
|
||||
"nonexisting source or target");
|
||||
|
||||
if (source > target)
|
||||
{
|
||||
std::swap(source, target);
|
||||
std::swap(forward, backward);
|
||||
}
|
||||
|
||||
edge_list.emplace_back(source,
|
||||
target,
|
||||
nameID,
|
||||
weight,
|
||||
forward,
|
||||
backward,
|
||||
is_roundabout,
|
||||
ignore_in_grid,
|
||||
is_access_restricted,
|
||||
travel_mode,
|
||||
is_split);
|
||||
}
|
||||
ext_to_int_id_map.clear();
|
||||
|
||||
tbb::parallel_sort(edge_list.begin(), edge_list.end());
|
||||
|
||||
for (unsigned i = 1; i < edge_list.size(); ++i)
|
||||
{
|
||||
if ((edge_list[i - 1].target == edge_list[i].target) &&
|
||||
(edge_list[i - 1].source == edge_list[i].source))
|
||||
{
|
||||
const bool edge_flags_equivalent =
|
||||
(edge_list[i - 1].forward == edge_list[i].forward) &&
|
||||
(edge_list[i - 1].backward == edge_list[i].backward);
|
||||
const bool edge_flags_are_superset1 =
|
||||
(edge_list[i - 1].forward && edge_list[i - 1].backward) &&
|
||||
(edge_list[i].forward != edge_list[i].backward);
|
||||
const bool edge_flags_are_superset_2 =
|
||||
(edge_list[i].forward && edge_list[i].backward) &&
|
||||
(edge_list[i - 1].forward != edge_list[i - 1].backward);
|
||||
|
||||
if (edge_flags_equivalent)
|
||||
{
|
||||
edge_list[i].weight = std::min(edge_list[i - 1].weight, edge_list[i].weight);
|
||||
edge_list[i - 1].source = SPECIAL_NODEID;
|
||||
}
|
||||
else if (edge_flags_are_superset1)
|
||||
{
|
||||
if (edge_list[i - 1].weight <= edge_list[i].weight)
|
||||
{
|
||||
// edge i-1 is smaller and goes in both directions. Throw away the other edge
|
||||
edge_list[i].source = SPECIAL_NODEID;
|
||||
}
|
||||
else
|
||||
{
|
||||
// edge i-1 is open in both directions, but edge i is smaller in one direction.
|
||||
// Close edge i-1 in this direction
|
||||
edge_list[i - 1].forward = !edge_list[i].forward;
|
||||
edge_list[i - 1].backward = !edge_list[i].backward;
|
||||
}
|
||||
}
|
||||
else if (edge_flags_are_superset_2)
|
||||
{
|
||||
if (edge_list[i - 1].weight <= edge_list[i].weight)
|
||||
{
|
||||
// edge i-1 is smaller for one direction. edge i is open in both. close edge i
|
||||
// in the other direction
|
||||
edge_list[i].forward = !edge_list[i - 1].forward;
|
||||
edge_list[i].backward = !edge_list[i - 1].backward;
|
||||
}
|
||||
else
|
||||
{
|
||||
// edge i is smaller and goes in both direction. Throw away edge i-1
|
||||
edge_list[i - 1].source = SPECIAL_NODEID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto new_end_iter = std::remove_if(edge_list.begin(), edge_list.end(), [] (const EdgeT &edge)
|
||||
{
|
||||
return edge.source == SPECIAL_NODEID ||
|
||||
edge.target == SPECIAL_NODEID;
|
||||
});
|
||||
edge_list.erase(new_end_iter, edge_list.end()); // remove excess candidates.
|
||||
edge_list.shrink_to_fit();
|
||||
SimpleLogger().Write() << "Graph loaded ok and has " << edge_list.size() << " edges";
|
||||
return n;
|
||||
}
|
||||
|
||||
template <typename NodeT, typename EdgeT>
|
||||
unsigned readHSGRFromStream(const boost::filesystem::path &hsgr_file,
|
||||
std::vector<NodeT> &node_list,
|
||||
std::vector<EdgeT> &edge_list,
|
||||
unsigned *check_sum)
|
||||
{
|
||||
if (!boost::filesystem::exists(hsgr_file))
|
||||
{
|
||||
throw 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
|
||||
@@ -1,182 +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.
|
||||
|
||||
*/
|
||||
|
||||
// based on
|
||||
// https://svn.apache.org/repos/asf/mesos/tags/release-0.9.0-incubating-RC0/src/common/json.hpp
|
||||
|
||||
#ifndef JSON_RENDERER_HPP
|
||||
#define JSON_RENDERER_HPP
|
||||
|
||||
#include "../data_structures/json_container.hpp"
|
||||
#include "cast.hpp"
|
||||
|
||||
namespace JSON {
|
||||
|
||||
struct Renderer : mapbox::util::static_visitor<>
|
||||
{
|
||||
explicit Renderer(std::ostream &_out) : out(_out) {}
|
||||
|
||||
void operator()(const String &string) const { out << "\"" << string.value << "\""; }
|
||||
|
||||
void operator()(const Number &number) const
|
||||
{
|
||||
out.precision(10);
|
||||
out << number.value;
|
||||
}
|
||||
|
||||
void operator()(const Object &object) const
|
||||
{
|
||||
out << "{";
|
||||
auto iterator = object.values.begin();
|
||||
while (iterator != object.values.end())
|
||||
{
|
||||
out << "\"" << (*iterator).first << "\":";
|
||||
mapbox::util::apply_visitor(Renderer(out), (*iterator).second);
|
||||
if (++iterator != object.values.end())
|
||||
{
|
||||
out << ",";
|
||||
}
|
||||
}
|
||||
out << "}";
|
||||
}
|
||||
|
||||
void operator()(const Array &array) const
|
||||
{
|
||||
out << "[";
|
||||
std::vector<Value>::const_iterator iterator;
|
||||
iterator = array.values.begin();
|
||||
while (iterator != array.values.end())
|
||||
{
|
||||
mapbox::util::apply_visitor(Renderer(out), *iterator);
|
||||
if (++iterator != array.values.end())
|
||||
{
|
||||
out << ",";
|
||||
}
|
||||
}
|
||||
out << "]";
|
||||
}
|
||||
|
||||
void operator()(const True &) const { out << "true"; }
|
||||
|
||||
void operator()(const False &) const { out << "false"; }
|
||||
|
||||
void operator()(const Null &) const { out << "null"; }
|
||||
|
||||
private:
|
||||
std::ostream &out;
|
||||
};
|
||||
|
||||
struct ArrayRenderer : mapbox::util::static_visitor<>
|
||||
{
|
||||
explicit ArrayRenderer(std::vector<char> &_out) : out(_out) {}
|
||||
|
||||
void operator()(const String &string) const
|
||||
{
|
||||
out.push_back('\"');
|
||||
out.insert(out.end(), string.value.begin(), string.value.end());
|
||||
out.push_back('\"');
|
||||
}
|
||||
|
||||
void operator()(const Number &number) const
|
||||
{
|
||||
const std::string number_string = cast::double_fixed_to_string(number.value);
|
||||
out.insert(out.end(), number_string.begin(), number_string.end());
|
||||
}
|
||||
|
||||
void operator()(const Object &object) const
|
||||
{
|
||||
out.push_back('{');
|
||||
auto iterator = object.values.begin();
|
||||
while (iterator != object.values.end())
|
||||
{
|
||||
out.push_back('\"');
|
||||
out.insert(out.end(), (*iterator).first.begin(), (*iterator).first.end());
|
||||
out.push_back('\"');
|
||||
out.push_back(':');
|
||||
|
||||
mapbox::util::apply_visitor(ArrayRenderer(out), (*iterator).second);
|
||||
if (++iterator != object.values.end())
|
||||
{
|
||||
out.push_back(',');
|
||||
}
|
||||
}
|
||||
out.push_back('}');
|
||||
}
|
||||
|
||||
void operator()(const Array &array) const
|
||||
{
|
||||
out.push_back('[');
|
||||
std::vector<Value>::const_iterator iterator;
|
||||
iterator = array.values.begin();
|
||||
while (iterator != array.values.end())
|
||||
{
|
||||
mapbox::util::apply_visitor(ArrayRenderer(out), *iterator);
|
||||
if (++iterator != array.values.end())
|
||||
{
|
||||
out.push_back(',');
|
||||
}
|
||||
}
|
||||
out.push_back(']');
|
||||
}
|
||||
|
||||
void operator()(const True &) const
|
||||
{
|
||||
const std::string temp("true");
|
||||
out.insert(out.end(), temp.begin(), temp.end());
|
||||
}
|
||||
|
||||
void operator()(const False &) const
|
||||
{
|
||||
const std::string temp("false");
|
||||
out.insert(out.end(), temp.begin(), temp.end());
|
||||
}
|
||||
|
||||
void operator()(const Null &) const
|
||||
{
|
||||
const std::string temp("null");
|
||||
out.insert(out.end(), temp.begin(), temp.end());
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<char> &out;
|
||||
};
|
||||
|
||||
inline void render(std::ostream &out, const Object &object)
|
||||
{
|
||||
Value value = object;
|
||||
mapbox::util::apply_visitor(Renderer(out), value);
|
||||
}
|
||||
|
||||
inline void render(std::vector<char> &out, const Object &object)
|
||||
{
|
||||
Value value = object;
|
||||
mapbox::util::apply_visitor(ArrayRenderer(out), value);
|
||||
}
|
||||
|
||||
} // namespace JSON
|
||||
|
||||
#endif // JSON_RENDERER_HPP
|
||||
@@ -1,66 +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 LUA_UTIL_HPP
|
||||
#define LUA_UTIL_HPP
|
||||
|
||||
extern "C" {
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
}
|
||||
|
||||
#include <boost/filesystem/convenience.hpp>
|
||||
#include <luabind/luabind.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
template <typename T> void LUA_print(T output) { std::cout << "[LUA] " << output << std::endl; }
|
||||
|
||||
// Check if the lua function <name> is defined
|
||||
inline bool lua_function_exists(lua_State *lua_state, const char *name)
|
||||
{
|
||||
luabind::object globals_table = luabind::globals(lua_state);
|
||||
luabind::object lua_function = globals_table[name];
|
||||
return lua_function && (luabind::type(lua_function) == LUA_TFUNCTION);
|
||||
}
|
||||
|
||||
// Add the folder contain the script to the lua load path, so script can easily require() other lua
|
||||
// scripts inside that folder, or subfolders.
|
||||
// See http://lua-users.org/wiki/PackagePath for details on the package.path syntax.
|
||||
inline void luaAddScriptFolderToLoadPath(lua_State *lua_state, const char *file_name)
|
||||
{
|
||||
const boost::filesystem::path profile_path(file_name);
|
||||
std::string folder = profile_path.parent_path().string();
|
||||
// TODO: This code is most probably not Windows safe since it uses UNIX'ish path delimiters
|
||||
const std::string lua_code =
|
||||
"package.path = \"" + folder + "/?.lua;profiles/?.lua;\" .. package.path";
|
||||
luaL_dostring(lua_state, lua_code.c_str());
|
||||
}
|
||||
|
||||
#endif // LUA_UTIL_HPP
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
open source routing machine
|
||||
Copyright (C) Dennis Luxen, others 2010
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU AFFERO General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
or see http://www.gnu.org/licenses/agpl.txt.
|
||||
*/
|
||||
|
||||
#ifndef RANGE_ALGORITHMS_HPP
|
||||
#define RANGE_ALGORITHMS_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace osrm {
|
||||
|
||||
template<class Container>
|
||||
auto max_element(const Container & c) -> decltype(std::max_element(c.begin(), c.end()))
|
||||
{
|
||||
return std::max_element(c.begin(), c.end());
|
||||
}
|
||||
|
||||
template<class Container>
|
||||
auto max_element(const Container & c) -> decltype(std::max_element(c.cbegin(), c.cend()))
|
||||
{
|
||||
return std::max_element(c.cbegin(), c.cend());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // RANGE_ALGORITHMS_HPP
|
||||
@@ -1,135 +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 "simple_logger.hpp"
|
||||
|
||||
#include "OSRMException.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#define isatty _isatty
|
||||
#define fileno _fileno
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <ostream>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
|
||||
namespace
|
||||
{
|
||||
static const char COL_RESET[] { "\x1b[0m"};
|
||||
static const char RED[] { "\x1b[31m"};
|
||||
#ifndef NDEBUG
|
||||
static const char YELLOW[] { "\x1b[33m"};
|
||||
#endif
|
||||
// static const char GREEN[] { "\x1b[32m"};
|
||||
// static const char BLUE[] { "\x1b[34m"};
|
||||
// static const char MAGENTA[] { "\x1b[35m"};
|
||||
// static const char CYAN[] { "\x1b[36m"};
|
||||
}
|
||||
|
||||
void LogPolicy::Unmute() { m_is_mute = false; }
|
||||
|
||||
void LogPolicy::Mute() { m_is_mute = true; }
|
||||
|
||||
bool LogPolicy::IsMute() const { return m_is_mute; }
|
||||
|
||||
LogPolicy &LogPolicy::GetInstance()
|
||||
{
|
||||
static LogPolicy runningInstance;
|
||||
return runningInstance;
|
||||
}
|
||||
|
||||
SimpleLogger::SimpleLogger() : level(logINFO) {}
|
||||
|
||||
std::mutex &SimpleLogger::get_mutex()
|
||||
{
|
||||
static std::mutex mtx;
|
||||
return mtx;
|
||||
}
|
||||
|
||||
std::ostringstream &SimpleLogger::Write(LogLevel lvl)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(get_mutex());
|
||||
try
|
||||
{
|
||||
level = lvl;
|
||||
os << "[";
|
||||
switch (level)
|
||||
{
|
||||
case logWARNING:
|
||||
os << "warn";
|
||||
break;
|
||||
case logDEBUG:
|
||||
#ifndef NDEBUG
|
||||
os << "debug";
|
||||
#endif
|
||||
break;
|
||||
default: //logINFO:
|
||||
os << "info";
|
||||
break;
|
||||
}
|
||||
os << "] ";
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
// encapsulate in OSRMException
|
||||
throw OSRMException(std::string(e.what()) + ", getting ostringstream");
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
SimpleLogger::~SimpleLogger()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(get_mutex());
|
||||
if (!LogPolicy::GetInstance().IsMute())
|
||||
{
|
||||
const bool is_terminal = static_cast<bool>(isatty(fileno(stdout)));
|
||||
switch (level)
|
||||
{
|
||||
case logWARNING:
|
||||
std::cerr << (is_terminal ? RED : "") << os.str() << (is_terminal ? COL_RESET : "")
|
||||
<< std::endl;
|
||||
break;
|
||||
case logDEBUG:
|
||||
#ifndef NDEBUG
|
||||
std::cout << (is_terminal ? YELLOW : "") << os.str() << (is_terminal ? COL_RESET : "")
|
||||
<< std::endl;
|
||||
#endif
|
||||
break;
|
||||
default: //logINFO:
|
||||
std::cout << os.str() << (is_terminal ? COL_RESET : "") << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 SIMPLE_LOGGER_HPP
|
||||
#define SIMPLE_LOGGER_HPP
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
|
||||
enum LogLevel
|
||||
{
|
||||
logINFO,
|
||||
logWARNING,
|
||||
logDEBUG
|
||||
};
|
||||
|
||||
class LogPolicy
|
||||
{
|
||||
public:
|
||||
void Unmute();
|
||||
|
||||
void Mute();
|
||||
|
||||
bool IsMute() const;
|
||||
|
||||
static LogPolicy &GetInstance();
|
||||
|
||||
LogPolicy(const LogPolicy &) = delete;
|
||||
|
||||
private:
|
||||
LogPolicy() : m_is_mute(true) {}
|
||||
std::atomic<bool> m_is_mute;
|
||||
};
|
||||
|
||||
class SimpleLogger
|
||||
{
|
||||
public:
|
||||
SimpleLogger();
|
||||
|
||||
virtual ~SimpleLogger();
|
||||
std::mutex &get_mutex();
|
||||
std::ostringstream &Write(LogLevel l = logINFO);
|
||||
|
||||
private:
|
||||
LogLevel level;
|
||||
std::ostringstream os;
|
||||
};
|
||||
|
||||
#endif /* SIMPLE_LOGGER_HPP */
|
||||
@@ -1,77 +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 STD_HASH_HPP
|
||||
#define STD_HASH_HPP
|
||||
|
||||
#include <functional>
|
||||
|
||||
// this is largely inspired by boost's hash combine as can be found in
|
||||
// "The C++ Standard Library" 2nd Edition. Nicolai M. Josuttis. 2012.
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T>
|
||||
void hash_combine(std::size_t &seed, const T& val)
|
||||
{
|
||||
seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void hash_val(std::size_t &seed, const T& val)
|
||||
{
|
||||
hash_combine(seed, val);
|
||||
}
|
||||
|
||||
template<typename T, typename ... Types>
|
||||
void hash_val(std::size_t &seed, const T& val, const Types& ... args)
|
||||
{
|
||||
hash_combine(seed, val);
|
||||
hash_val(seed, args ...);
|
||||
}
|
||||
|
||||
template<typename ... Types>
|
||||
std::size_t hash_val(const Types&... args)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
hash_val(seed, args...);
|
||||
return seed;
|
||||
}
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <typename T1, typename T2> struct hash<std::pair<T1, T2>>
|
||||
{
|
||||
size_t operator()(const std::pair<T1, T2> &pair) const
|
||||
{
|
||||
return hash_val(pair.first, pair.second);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // STD_HASH_HPP
|
||||
@@ -1,80 +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 TIMING_UTIL_HPP
|
||||
#define TIMING_UTIL_HPP
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
struct GlobalTimer
|
||||
{
|
||||
GlobalTimer() : time(0) {}
|
||||
std::atomic<uint64_t> time;
|
||||
};
|
||||
|
||||
class GlobalTimerFactory
|
||||
{
|
||||
public:
|
||||
static GlobalTimerFactory& get()
|
||||
{
|
||||
static GlobalTimerFactory instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
GlobalTimer& getGlobalTimer(const std::string& name)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(map_mutex);
|
||||
return timer_map[name];
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex map_mutex;
|
||||
std::unordered_map<std::string, GlobalTimer> timer_map;
|
||||
};
|
||||
|
||||
#define GLOBAL_TIMER_AQUIRE(_X) auto& _X##_global_timer = GlobalTimerFactory::get().getGlobalTimer(#_X)
|
||||
#define GLOBAL_TIMER_RESET(_X) _X##_global_timer.time = 0
|
||||
#define GLOBAL_TIMER_START(_X) TIMER_START(_X)
|
||||
#define GLOBAL_TIMER_STOP(_X) TIMER_STOP(_X); _X##_global_timer.time += TIMER_NSEC(_X)
|
||||
#define GLOBAL_TIMER_NSEC(_X) static_cast<double>(_X##_global_timer.time)
|
||||
#define GLOBAL_TIMER_USEC(_X) (_X##_global_timer.time / 1000.0)
|
||||
#define GLOBAL_TIMER_MSEC(_X) (_X##_global_timer.time / 1000.0 / 1000.0)
|
||||
#define GLOBAL_TIMER_SEC(_X) (_X##_global_timer.time / 1000.0 / 1000.0 / 1000.0)
|
||||
|
||||
#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_NSEC(_X) std::chrono::duration_cast<std::chrono::nanoseconds>(_X##_stop - _X##_start).count()
|
||||
#define TIMER_USEC(_X) std::chrono::duration_cast<std::chrono::microseconds>(_X##_stop - _X##_start).count()
|
||||
#define TIMER_MSEC(_X) (0.000001*std::chrono::duration_cast<std::chrono::nanoseconds>(_X##_stop - _X##_start).count())
|
||||
#define TIMER_SEC(_X) (0.000001*std::chrono::duration_cast<std::chrono::microseconds>(_X##_stop - _X##_start).count())
|
||||
#define TIMER_MIN(_X) std::chrono::duration_cast<std::chrono::minutes>(_X##_stop - _X##_start).count()
|
||||
|
||||
#endif // TIMING_UTIL_HPP
|
||||
@@ -1,140 +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 XML_RENDERER_HPP
|
||||
#define XML_RENDERER_HPP
|
||||
|
||||
#include "../data_structures/json_container.hpp"
|
||||
#include "cast.hpp"
|
||||
|
||||
namespace JSON {
|
||||
|
||||
struct XMLToArrayRenderer : mapbox::util::static_visitor<>
|
||||
{
|
||||
explicit XMLToArrayRenderer(std::vector<char> &_out) : out(_out) {}
|
||||
|
||||
void operator()(const String &string) const
|
||||
{
|
||||
out.push_back('\"');
|
||||
out.insert(out.end(), string.value.begin(), string.value.end());
|
||||
out.push_back('\"');
|
||||
}
|
||||
|
||||
void operator()(const Number &number) const
|
||||
{
|
||||
const std::string number_string = cast::double_fixed_to_string(number.value);
|
||||
out.insert(out.end(), number_string.begin(), number_string.end());
|
||||
}
|
||||
|
||||
void operator()(const Object &object) const
|
||||
{
|
||||
auto iterator = object.values.begin();
|
||||
while (iterator != object.values.end())
|
||||
{
|
||||
if (iterator->first.at(0) != '_')
|
||||
{
|
||||
out.push_back('<');
|
||||
out.insert(out.end(), (*iterator).first.begin(), (*iterator).first.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
out.push_back(' ');
|
||||
out.insert(out.end(), ++(*iterator).first.begin(), (*iterator).first.end());
|
||||
out.push_back('=');
|
||||
|
||||
}
|
||||
mapbox::util::apply_visitor(XMLToArrayRenderer(out), (*iterator).second);
|
||||
if (iterator->first.at(0) != '_')
|
||||
{
|
||||
out.push_back('/');
|
||||
out.push_back('>');
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const Array &array) const
|
||||
{
|
||||
std::vector<Value>::const_iterator iterator;
|
||||
iterator = array.values.begin();
|
||||
while (iterator != array.values.end())
|
||||
{
|
||||
mapbox::util::apply_visitor(XMLToArrayRenderer(out), *iterator);
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const True &) const
|
||||
{
|
||||
const std::string temp("true");
|
||||
out.insert(out.end(), temp.begin(), temp.end());
|
||||
}
|
||||
|
||||
void operator()(const False &) const
|
||||
{
|
||||
const std::string temp("false");
|
||||
out.insert(out.end(), temp.begin(), temp.end());
|
||||
}
|
||||
|
||||
void operator()(const Null &) const
|
||||
{
|
||||
const std::string temp("null");
|
||||
out.insert(out.end(), temp.begin(), temp.end());
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<char> &out;
|
||||
};
|
||||
|
||||
template<class JSONObject>
|
||||
inline void xml_render(std::vector<char> &out, const JSONObject &object)
|
||||
{
|
||||
Value value = object;
|
||||
mapbox::util::apply_visitor(XMLToArrayRenderer(out), value);
|
||||
}
|
||||
|
||||
template<class JSONObject>
|
||||
inline void gpx_render(std::vector<char> &out, const JSONObject &object)
|
||||
{
|
||||
// add header
|
||||
|
||||
const 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.topogr"
|
||||
"afix.com/GPX/1/1 gpx.xsd\"><metadata><copyright author=\"Project OSRM\"><lice"
|
||||
"nse>Data (c) OpenStreetMap contributors (ODbL)</license></copyright></metadat"
|
||||
"a><rte>"};
|
||||
out.insert(out.end(), header.begin(), header.end());
|
||||
|
||||
xml_render(out, object);
|
||||
|
||||
const std::string footer {"</rte></gpx>"};
|
||||
out.insert(out.end(), footer.begin(), footer.end());
|
||||
}
|
||||
} // namespace JSON
|
||||
|
||||
#endif // XML_RENDERER_HPP
|
||||
@@ -1,174 +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 BFS_COMPONENTS_HPP_
|
||||
#define BFS_COMPONENTS_HPP_
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "../data_structures/restriction_map.hpp"
|
||||
|
||||
#include <queue>
|
||||
#include <unordered_set>
|
||||
|
||||
// Explores the components of the given graph while respecting turn restrictions
|
||||
// and barriers.
|
||||
template <typename GraphT> class BFSComponentExplorer
|
||||
{
|
||||
public:
|
||||
BFSComponentExplorer(const GraphT &dynamic_graph,
|
||||
const RestrictionMap &restrictions,
|
||||
const std::unordered_set<NodeID> &barrier_nodes)
|
||||
: m_graph(dynamic_graph), m_restriction_map(restrictions), m_barrier_nodes(barrier_nodes)
|
||||
{
|
||||
BOOST_ASSERT(m_graph.GetNumberOfNodes() > 0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the size of the component that the node belongs to.
|
||||
*/
|
||||
unsigned int GetComponentSize(const NodeID node) const
|
||||
{
|
||||
BOOST_ASSERT(node < m_component_index_list.size());
|
||||
|
||||
return m_component_index_size[m_component_index_list[node]];
|
||||
}
|
||||
|
||||
unsigned int GetNumberOfComponents() { return m_component_index_size.size(); }
|
||||
|
||||
/*!
|
||||
* Computes the component sizes.
|
||||
*/
|
||||
void run()
|
||||
{
|
||||
std::queue<std::pair<NodeID, NodeID>> bfs_queue;
|
||||
unsigned current_component = 0;
|
||||
|
||||
BOOST_ASSERT(m_component_index_list.empty());
|
||||
BOOST_ASSERT(m_component_index_size.empty());
|
||||
|
||||
unsigned num_nodes = m_graph.GetNumberOfNodes();
|
||||
|
||||
m_component_index_list.resize(num_nodes, std::numeric_limits<unsigned>::max());
|
||||
|
||||
BOOST_ASSERT(num_nodes > 0);
|
||||
|
||||
// put unexplorered node with parent pointer into queue
|
||||
for (NodeID node = 0; node < num_nodes; ++node)
|
||||
{
|
||||
if (std::numeric_limits<unsigned>::max() == m_component_index_list[node])
|
||||
{
|
||||
unsigned size = ExploreComponent(bfs_queue, node, current_component);
|
||||
|
||||
// push size into vector
|
||||
m_component_index_size.emplace_back(size);
|
||||
++current_component;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/*!
|
||||
* 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)
|
||||
{
|
||||
/*
|
||||
Graphical representation of variables:
|
||||
|
||||
u v w
|
||||
*---------->*---------->*
|
||||
e2
|
||||
*/
|
||||
|
||||
bfs_queue.emplace(node, node);
|
||||
// mark node as read
|
||||
m_component_index_list[node] = current_component;
|
||||
|
||||
unsigned current_component_size = 1;
|
||||
|
||||
while (!bfs_queue.empty())
|
||||
{
|
||||
// fetch element from BFS queue
|
||||
std::pair<NodeID, NodeID> current_queue_item = bfs_queue.front();
|
||||
bfs_queue.pop();
|
||||
|
||||
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)
|
||||
{
|
||||
const NodeID to_node_of_only_restriction =
|
||||
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, 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)
|
||||
{
|
||||
// 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])
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return current_component_size;
|
||||
}
|
||||
|
||||
std::vector<unsigned> m_component_index_list;
|
||||
std::vector<NodeID> m_component_index_size;
|
||||
|
||||
const GraphT &m_graph;
|
||||
const RestrictionMap &m_restriction_map;
|
||||
const std::unordered_set<NodeID> &m_barrier_nodes;
|
||||
};
|
||||
|
||||
#endif // BFS_COMPONENTS_HPP_
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "douglas_peucker.hpp"
|
||||
|
||||
#include "../data_structures/segment_information.hpp"
|
||||
#include "../Util/integer_range.hpp"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct CoordinatePairCalculator
|
||||
{
|
||||
CoordinatePairCalculator() = delete;
|
||||
CoordinatePairCalculator(const FixedPointCoordinate &coordinate_a,
|
||||
const FixedPointCoordinate &coordinate_b)
|
||||
{
|
||||
// initialize distance calculator with two fixed coordinates a, b
|
||||
const float RAD = 0.017453292519943295769236907684886f;
|
||||
first_lat = (coordinate_a.lat / COORDINATE_PRECISION) * RAD;
|
||||
first_lon = (coordinate_a.lon / COORDINATE_PRECISION) * RAD;
|
||||
second_lat = (coordinate_b.lat / COORDINATE_PRECISION) * RAD;
|
||||
second_lon = (coordinate_b.lon / COORDINATE_PRECISION) * RAD;
|
||||
}
|
||||
|
||||
int operator()(FixedPointCoordinate &other) const
|
||||
{
|
||||
// set third coordinate c
|
||||
const float RAD = 0.017453292519943295769236907684886f;
|
||||
const float earth_radius = 6372797.560856f;
|
||||
const float float_lat1 = (other.lat / COORDINATE_PRECISION) * RAD;
|
||||
const float float_lon1 = (other.lon / COORDINATE_PRECISION) * RAD;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
|
||||
// return the minimum
|
||||
return static_cast<int>(std::min(dist1, dist2));
|
||||
}
|
||||
|
||||
float first_lat;
|
||||
float first_lon;
|
||||
float second_lat;
|
||||
float second_lon;
|
||||
};
|
||||
}
|
||||
|
||||
void DouglasPeucker::Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level)
|
||||
{
|
||||
Run(std::begin(input_geometry), std::end(input_geometry), zoom_level);
|
||||
}
|
||||
|
||||
void DouglasPeucker::Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level)
|
||||
{
|
||||
unsigned size = std::distance(begin, end);
|
||||
if (size < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
begin->necessary = true;
|
||||
std::prev(end)->necessary = true;
|
||||
|
||||
{
|
||||
BOOST_ASSERT_MSG(zoom_level < DOUGLAS_PEUCKER_THRESHOLDS.size(), "unsupported zoom level");
|
||||
RandomAccessIt left_border = begin;
|
||||
RandomAccessIt 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 (right_border->necessary)
|
||||
{
|
||||
// sanity checks
|
||||
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 != end);
|
||||
}
|
||||
|
||||
// mark locations as 'necessary' by divide-and-conquer
|
||||
while (!recursion_stack.empty())
|
||||
{
|
||||
// pop next element
|
||||
const GeometryRange pair = recursion_stack.top();
|
||||
recursion_stack.pop();
|
||||
// sanity checks
|
||||
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;
|
||||
auto farthest_entry_it = pair.second;
|
||||
const CoordinatePairCalculator dist_calc(pair.first->location, pair.second->location);
|
||||
|
||||
// sweep over range to find the maximum
|
||||
for (auto it = std::next(pair.first); it != pair.second; ++it)
|
||||
{
|
||||
const int distance = dist_calc(it->location);
|
||||
// found new feasible maximum?
|
||||
if (distance > max_int_distance && distance > DOUGLAS_PEUCKER_THRESHOLDS[zoom_level])
|
||||
{
|
||||
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])
|
||||
{
|
||||
// mark idx as necessary
|
||||
farthest_entry_it->necessary = true;
|
||||
if (1 < std::distance(pair.first, farthest_entry_it))
|
||||
{
|
||||
recursion_stack.emplace(pair.first, farthest_entry_it);
|
||||
}
|
||||
if (1 < std::distance(farthest_entry_it, pair.second))
|
||||
{
|
||||
recursion_stack.emplace(farthest_entry_it, pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,80 +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 DOUGLAS_PEUCKER_HPP_
|
||||
#define DOUGLAS_PEUCKER_HPP_
|
||||
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
/* This class object computes the bitvector of indicating generalized input
|
||||
* points according to the (Ramer-)Douglas-Peucker algorithm.
|
||||
*
|
||||
* Input is vector of pairs. Each pair consists of the point information and a
|
||||
* 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
|
||||
{
|
||||
public:
|
||||
using RandomAccessIt = std::vector<SegmentInformation>::iterator;
|
||||
|
||||
using GeometryRange = std::pair<RandomAccessIt, RandomAccessIt>;
|
||||
// Stack to simulate the recursion
|
||||
std::stack<GeometryRange> recursion_stack;
|
||||
|
||||
public:
|
||||
void Run(RandomAccessIt begin, RandomAccessIt end, const unsigned zoom_level);
|
||||
void Run(std::vector<SegmentInformation> &input_geometry, const unsigned zoom_level);
|
||||
};
|
||||
|
||||
#endif /* DOUGLAS_PEUCKER_HPP_ */
|
||||
@@ -1,94 +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 OBJECT_ENCODER_HPP
|
||||
#define OBJECT_ENCODER_HPP
|
||||
|
||||
#include "../Util/StringUtil.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/archive/iterators/base64_from_binary.hpp>
|
||||
#include <boost/archive/iterators/binary_from_base64.hpp>
|
||||
#include <boost/archive/iterators/transform_width.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct ObjectEncoder
|
||||
{
|
||||
using base64_t = boost::archive::iterators::base64_from_binary<
|
||||
boost::archive::iterators::transform_width<const char *, 6, 8>>;
|
||||
|
||||
using binary_t = boost::archive::iterators::transform_width<
|
||||
boost::archive::iterators::binary_from_base64<std::string::const_iterator>,
|
||||
8,
|
||||
6>;
|
||||
|
||||
template <class ObjectT>
|
||||
static void EncodeToBase64(const ObjectT &object, std::string &encoded)
|
||||
{
|
||||
const char *char_ptr_to_object = (const char *)&object;
|
||||
std::vector<unsigned char> data(sizeof(object));
|
||||
std::copy(char_ptr_to_object, char_ptr_to_object + sizeof(ObjectT), data.begin());
|
||||
|
||||
unsigned char number_of_padded_chars = 0; // is in {0,1,2};
|
||||
while (data.size() % 3 != 0)
|
||||
{
|
||||
++number_of_padded_chars;
|
||||
data.push_back(0x00);
|
||||
}
|
||||
|
||||
BOOST_ASSERT_MSG(0 == data.size() % 3, "base64 input data size is not a multiple of 3!");
|
||||
encoded.resize(sizeof(ObjectT));
|
||||
encoded.assign(base64_t(&data[0]),
|
||||
base64_t(&data[0] + (data.size() - number_of_padded_chars)));
|
||||
replaceAll(encoded, "+", "-");
|
||||
replaceAll(encoded, "/", "_");
|
||||
}
|
||||
|
||||
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::copy(binary_t(encoded.begin()),
|
||||
binary_t(encoded.begin() + encoded.length() - 1),
|
||||
(char *)&object);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* OBJECT_ENCODER_HPP */
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "polyline_compressor.hpp"
|
||||
#include "../data_structures/segment_information.hpp"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
|
||||
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);
|
||||
if (92 == next_value)
|
||||
{
|
||||
output += static_cast<char>(next_value);
|
||||
}
|
||||
number_to_encode >>= 5;
|
||||
}
|
||||
|
||||
number_to_encode += 63;
|
||||
output += static_cast<char>(number_to_encode);
|
||||
if (92 == number_to_encode)
|
||||
{
|
||||
output += static_cast<char>(number_to_encode);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,47 +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 POLYLINECOMPRESSOR_H_
|
||||
#define POLYLINECOMPRESSOR_H_
|
||||
|
||||
struct SegmentInformation;
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class PolylineCompressor
|
||||
{
|
||||
private:
|
||||
std::string encode_vector(std::vector<int> &numbers) const;
|
||||
|
||||
std::string encode_number(const int number_to_encode) const;
|
||||
|
||||
public:
|
||||
std::string get_encoded_string(const std::vector<SegmentInformation> &polyline) const;
|
||||
};
|
||||
|
||||
#endif /* POLYLINECOMPRESSOR_H_ */
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "polyline_formatter.hpp"
|
||||
|
||||
#include "polyline_compressor.hpp"
|
||||
#include "../data_structures/segment_information.hpp"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
|
||||
JSON::String
|
||||
PolylineFormatter::printEncodedString(const std::vector<SegmentInformation> &polyline) const
|
||||
{
|
||||
return JSON::String(PolylineCompressor().get_encoded_string(polyline));
|
||||
}
|
||||
|
||||
JSON::Array
|
||||
PolylineFormatter::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;
|
||||
}
|
||||
@@ -1,169 +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 EXTRACT_ROUTE_NAMES_H
|
||||
#define EXTRACT_ROUTE_NAMES_H
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct RouteNames
|
||||
{
|
||||
std::string shortest_path_name_1;
|
||||
std::string shortest_path_name_2;
|
||||
std::string alternative_path_name_1;
|
||||
std::string alternative_path_name_2;
|
||||
};
|
||||
|
||||
// construct routes names
|
||||
template <class DataFacadeT, class SegmentT> struct ExtractRouteNames
|
||||
{
|
||||
private:
|
||||
SegmentT PickNextLongestSegment(const std::vector<SegmentT> &segment_list,
|
||||
const unsigned blocked_name_id) const
|
||||
{
|
||||
SegmentT result_segment;
|
||||
result_segment.length = 0;
|
||||
|
||||
for (const SegmentT &segment : segment_list)
|
||||
{
|
||||
if (segment.name_id != blocked_name_id && segment.length > result_segment.length && segment.name_id != 0)
|
||||
{
|
||||
result_segment = segment;
|
||||
}
|
||||
}
|
||||
return result_segment;
|
||||
}
|
||||
|
||||
public:
|
||||
RouteNames operator()(std::vector<SegmentT> &shortest_path_segments,
|
||||
std::vector<SegmentT> &alternative_path_segments,
|
||||
const DataFacadeT *facade) const
|
||||
{
|
||||
RouteNames route_names;
|
||||
|
||||
SegmentT shortest_segment_1, shortest_segment_2;
|
||||
SegmentT alternative_segment_1, alternative_segment_2;
|
||||
|
||||
auto length_comperator = [](const SegmentT &a, const SegmentT &b)
|
||||
{ return a.length > b.length; };
|
||||
auto name_id_comperator = [](const SegmentT &a, const SegmentT &b)
|
||||
{ return a.name_id < b.name_id; };
|
||||
|
||||
if (shortest_path_segments.empty())
|
||||
{
|
||||
return route_names;
|
||||
}
|
||||
|
||||
// pick the longest segment for the shortest path.
|
||||
std::sort(shortest_path_segments.begin(), shortest_path_segments.end(), length_comperator);
|
||||
shortest_segment_1 = shortest_path_segments[0];
|
||||
if (!alternative_path_segments.empty())
|
||||
{
|
||||
std::sort(alternative_path_segments.begin(),
|
||||
alternative_path_segments.end(),
|
||||
length_comperator);
|
||||
|
||||
// also pick the longest segment for the alternative path
|
||||
alternative_segment_1 = alternative_path_segments[0];
|
||||
}
|
||||
|
||||
// compute the set difference (for shortest path) depending on names between shortest and
|
||||
// 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(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);
|
||||
|
||||
// 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(),
|
||||
name_id_comperator));
|
||||
BOOST_ASSERT(std::is_sorted(alternative_path_segments.begin(),
|
||||
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::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);
|
||||
}
|
||||
|
||||
// move the segments into the order in which they occur.
|
||||
if (shortest_segment_1.position > shortest_segment_2.position)
|
||||
{
|
||||
std::swap(shortest_segment_1, shortest_segment_2);
|
||||
}
|
||||
if (alternative_segment_1.position > alternative_segment_2.position)
|
||||
{
|
||||
std::swap(alternative_segment_1, alternative_segment_2);
|
||||
}
|
||||
|
||||
// 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.alternative_path_name_1 =
|
||||
facade->GetEscapedNameForNameID(alternative_segment_1.name_id);
|
||||
route_names.alternative_path_name_2 =
|
||||
facade->GetEscapedNameForNameID(alternative_segment_2.name_id);
|
||||
|
||||
return route_names;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // EXTRACT_ROUTE_NAMES_H
|
||||
@@ -1,296 +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 TINY_COMPONENTS_HPP
|
||||
#define TINY_COMPONENTS_HPP
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "../data_structures/deallocating_vector.hpp"
|
||||
#include "../data_structures/import_edge.hpp"
|
||||
#include "../data_structures/query_node.hpp"
|
||||
#include "../data_structures/percent.hpp"
|
||||
#include "../data_structures/restriction.hpp"
|
||||
#include "../data_structures/turn_instructions.hpp"
|
||||
|
||||
#include "../Util/integer_range.hpp"
|
||||
#include "../Util/OSRMException.h"
|
||||
#include "../Util/simple_logger.hpp"
|
||||
#include "../Util/std_hash.hpp"
|
||||
#include "../Util/timing_util.hpp"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#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;
|
||||
};
|
||||
|
||||
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<EmanatingRestrictionsVector> m_restriction_bucket_list;
|
||||
std::vector<unsigned> components_index;
|
||||
std::vector<NodeID> component_size_vector;
|
||||
std::shared_ptr<GraphT> m_node_based_graph;
|
||||
std::unordered_set<NodeID> barrier_node_list;
|
||||
unsigned size_one_counter;
|
||||
RestrictionMap m_restriction_map;
|
||||
|
||||
public:
|
||||
TarjanSCC(std::shared_ptr<GraphT> graph,
|
||||
std::vector<NodeID> &bn,
|
||||
std::vector<TurnRestriction> &irs)
|
||||
: components_index(graph->GetNumberOfNodes(), SPECIAL_NODEID),
|
||||
m_node_based_graph(graph),
|
||||
size_one_counter(0)
|
||||
{
|
||||
|
||||
TIMER_START(SCC_LOAD);
|
||||
for (const TurnRestriction &restriction : irs)
|
||||
{
|
||||
std::pair<NodeID, NodeID> restriction_source = {restriction.from.node,
|
||||
restriction.via.node};
|
||||
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.is_only)
|
||||
{
|
||||
// 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.to.node, restriction.flags.is_only);
|
||||
}
|
||||
|
||||
barrier_node_list.insert(bn.begin(), bn.end());
|
||||
|
||||
TIMER_STOP(SCC_LOAD);
|
||||
SimpleLogger().Write() << "Loading data into SCC took " << TIMER_MSEC(SCC_LOAD)/1000. << "s";
|
||||
}
|
||||
|
||||
void Run()
|
||||
{
|
||||
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<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 auto 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";
|
||||
|
||||
|
||||
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";
|
||||
|
||||
}
|
||||
|
||||
unsigned get_component_size(const NodeID node) const
|
||||
{
|
||||
return component_size_vector[components_index[node]];
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* TINY_COMPONENTS_HPP */
|
||||
@@ -0,0 +1,163 @@
|
||||
@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
|
||||
IF %ERRORLEVEL% NEQ 0 ECHO CMAKE not found GOTO ERROR
|
||||
|
||||
FOR /F %%G IN ("--version") DO cmake %%G 2>&1 | findstr /C:"3.5.0" > nul && goto CMAKE_NOT_OK
|
||||
GOTO CMAKE_OK
|
||||
|
||||
:CMAKE_NOT_OK
|
||||
ECHO CMAKE NOT OK - downloading new CMake
|
||||
IF NOT EXIST cm.zip powershell Invoke-WebRequest https://cmake.org/files/v3.5/cmake-3.5.1-win32-x86.zip -OutFile $env:PROJECT_DIR\cm.zip
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
IF NOT EXIST cmake-3.5.1-win32-x86 7z -y x cm.zip | %windir%\system32\FIND "ing archive"
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
SET PATH=%PROJECT_DIR%\cmake-3.5.1-win32-x86\bin;%PATH%
|
||||
|
||||
:CMAKE_OK
|
||||
ECHO CMAKE_OK
|
||||
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%
|
||||
|
||||
ECHO cl.exe version
|
||||
cl
|
||||
ECHO msbuild version
|
||||
msbuild /version
|
||||
|
||||
:: 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.
|
||||
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 deleting 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
|
||||
|
||||
::tree osrm-deps
|
||||
|
||||
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 BOOST_LIBRARYDIR=%BOOST_ROOT%/lib
|
||||
set TBB_INSTALL_DIR=%OSRMDEPSDIR%/tbb
|
||||
set TBB_ARCH_PLATFORM=intel64/vc14
|
||||
|
||||
ECHO OSRMDEPSDIR ^: %OSRMDEPSDIR%
|
||||
ECHO PREFIX ^: %PREFIX%
|
||||
ECHO BOOST_ROOT ^: %BOOST_ROOT%
|
||||
ECHO BOOST_LIBRARYDIR ^: %BOOST_LIBRARYDIR%
|
||||
ECHO TBB_INSTALL_DIR ^: %TBB_INSTALL_DIR%
|
||||
ECHO TBB_ARCH_PLATFORM ^: %TBB_ARCH_PLATFORM%
|
||||
|
||||
|
||||
ECHO calling cmake ....
|
||||
cmake .. ^
|
||||
-G "Visual Studio 14 2015 Win64" ^
|
||||
-DBOOST_ROOT=%BOOST_ROOT% ^
|
||||
-DBOOST_LIBRARYDIR=%BOOST_LIBRARYDIR% ^
|
||||
-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 extractor-tests.exe ...
|
||||
unit_tests\%Configuration%\extractor-tests.exe
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
ECHO running engine-tests.exe ...
|
||||
unit_tests\%Configuration%\engine-tests.exe
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
ECHO running util-tests.exe ...
|
||||
unit_tests\%Configuration%\util-tests.exe
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
ECHO running server-tests.exe ...
|
||||
unit_tests\%Configuration%\server-tests.exe
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
|
||||
IF NOT "%APPVEYOR_REPO_BRANCH%"=="master" 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%
|
||||
+10
-46
@@ -1,63 +1,33 @@
|
||||
environment:
|
||||
matrix:
|
||||
- configuration: Debug
|
||||
- configuration: Release
|
||||
|
||||
# branches to build
|
||||
branches:
|
||||
# whitelist
|
||||
only:
|
||||
- develop
|
||||
|
||||
# Operating system (build VM template)
|
||||
os: Windows Server 2012 R2
|
||||
# - configuration: Debug
|
||||
|
||||
# scripts that are called at very beginning, before repo cloning
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
|
||||
os: Visual Studio 2015
|
||||
|
||||
# clone directory
|
||||
clone_folder: c:\projects\osrm
|
||||
|
||||
platform: x64
|
||||
|
||||
install:
|
||||
# by default, all script lines are interpreted as batch
|
||||
- nuget install protobuf
|
||||
- cd c:\projects\osrm
|
||||
- curl -O http://build.project-osrm.org/libs_osrm_%Configuration%.7z
|
||||
- 7z x libs_osrm_%Configuration%.7z | find ":"
|
||||
|
||||
build_script:
|
||||
- cd c:/projects/osrm
|
||||
- mkdir build
|
||||
- cd build
|
||||
- echo Running cmake...
|
||||
- call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
|
||||
- SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH%
|
||||
- SET P=c:/projects/osrm
|
||||
- set TBB_INSTALL_DIR=%P%/tbb
|
||||
- set TBB_ARCH_PLATFORM=intel64/vc12
|
||||
- cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_ADDITIONAL_VERSIONS=1.57 -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013
|
||||
- msbuild /clp:Verbosity=minimal /nologo OSRM.sln
|
||||
- msbuild /clp:Verbosity=minimal /nologo tests.vcxproj
|
||||
- cd %Configuration%
|
||||
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip)
|
||||
- cd ..\..\profiles
|
||||
- echo disk=c:\temp\stxxl,10000,wincall > .stxxl.txt
|
||||
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip * -tzip)
|
||||
- set PATH=%PATH%;c:/projects/osrm/libs/bin
|
||||
- cd c:/projects/osrm/build/%Configuration%
|
||||
- datastructure-tests.exe
|
||||
- algorithm-tests.exe
|
||||
- CALL appveyor-build.bat
|
||||
|
||||
test: off
|
||||
|
||||
artifacts:
|
||||
- path: osrm_Debug.zip
|
||||
name: osrm_Debug.zip
|
||||
- path: osrm_Release.zip
|
||||
name: osrm_Release.zip
|
||||
# - path: osrm_Debug.zip
|
||||
# name: osrm_Debug.zip
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
deploy:
|
||||
provider: FTP
|
||||
@@ -70,9 +40,3 @@ deploy:
|
||||
folder: /
|
||||
enable_ssl: true
|
||||
active_mode: false
|
||||
|
||||
# notifications:
|
||||
# - provider: HipChat
|
||||
# auth_token:
|
||||
# secure: boLE7BjcahdIUxv9jkN7U3F8iOASF+MkhtctlVoWJoo=
|
||||
# room: Directions
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "../data_structures/original_edge_data.hpp"
|
||||
#include "../data_structures/query_node.hpp"
|
||||
#include "../data_structures/shared_memory_vector_wrapper.hpp"
|
||||
#include "../data_structures/static_rtree.hpp"
|
||||
#include "../data_structures/edge_based_node.hpp"
|
||||
#include "../Util/BoostFileSystemFix.h"
|
||||
|
||||
#include <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);
|
||||
|
||||
QueryNode 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 *)¤t_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;
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
{
|
||||
const unsigned num_results = 1;
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
@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.5.0-win32-x86\bin;%PATH%
|
||||
SET PATH=C:\mb\windows-builds-64\tmp-bin\cmake-3.5.1-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%
|
||||
@@ -7,15 +7,13 @@ INCLUDE(FindDebArch)
|
||||
SET(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENCE.TXT")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CPACK_RESOURCE_FILE_README}")
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR "0")
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR "4")
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH "3")
|
||||
|
||||
SET(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
SET(CPACK_PACKAGE_UPSTREAM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
|
||||
SET(CPACK_PACKAGE_DEBIAN_REVISION "1")
|
||||
SET(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_UPSTREAM_VERSION}-${CPACK_PACKAGE_DEBIAN_REVISION}")
|
||||
|
||||
string(TOLOWER "${CMAKE_PROJECT_NAME}" LOWER_PROJECT_NAME)
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${LOWER_PROJECT_NAME}_${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
|
||||
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${LOWER_PROJECT_NAME}_${CPACK_PACKAGE_VERSION}_orig")
|
||||
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${LOWER_PROJECT_NAME}_${CPACK_PACKAGE_UPSTREAM_VERSION}_orig")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Open Source Routing Machine (OSRM).")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION "Open Source Routing Machine (OSRM) is a routing engine.")
|
||||
|
||||
@@ -27,18 +25,17 @@ SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY "FALSE")
|
||||
SET(CPACK_GENERATOR "DEB")
|
||||
|
||||
SET(CPACK_DEBIAN_PACKAGE_NAME "${CPACK_PACKAGE_NAME}${VERSION_SUFFIX}")
|
||||
SET(CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}${CPACK_PACKAGE_REVISION}")
|
||||
SET(CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}")
|
||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Dennis Luxen <info@project-osrm.org>")
|
||||
SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||
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")
|
||||
CONFIGURE_FILE (${CMAKE_SOURCE_DIR}/cmake/postinst.in postinst)
|
||||
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_BINARY_DIR}/postinst;${CMAKE_CURRENT_BINARY_DIR}/copyright;")
|
||||
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_BINARY_DIR}/copyright;")
|
||||
|
||||
MESSAGE(STATUS "Debian Package: ${CPACK_DEBIAN_PACKAGE_NAME} (${CPACK_DEBIAN_PACKAGE_VERSION}) [${CPACK_PACKAGE_FILE_NAME}.deb]")
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2007-2009 Kitware, Inc.
|
||||
# Copyright 2013 for Project-OSRM, Lua5.1 => Lua5.2
|
||||
# Copyright 2016 for Project-OSRM, Lua5.1 => Lua5.2
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
|
||||
@@ -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)
|
||||
@@ -24,7 +24,7 @@ FIND_PATH(STXXL_INCLUDE_DIR stxxl.h
|
||||
)
|
||||
|
||||
FIND_LIBRARY(STXXL_LIBRARY
|
||||
NAMES stxxl
|
||||
NAMES stxxl stxxl_debug
|
||||
HINTS
|
||||
$ENV{STXXL_DIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
|
||||
@@ -1,10 +1,24 @@
|
||||
set(OLDFILE ${SOURCE_DIR}/Util/FingerPrint.cpp)
|
||||
if (EXISTS ${OLDFILE})
|
||||
file(REMOVE_RECURSE ${OLDFILE})
|
||||
endif()
|
||||
file(MD5 ${SOURCE_DIR}/prepare.cpp MD5PREPARE)
|
||||
file(MD5 ${SOURCE_DIR}/data_structures/static_rtree.hpp MD5RTREE)
|
||||
file(MD5 ${SOURCE_DIR}/Util/graph_loader.hpp MD5GRAPH)
|
||||
file(MD5 ${SOURCE_DIR}/Server/DataStructures/InternalDataFacade.h MD5OBJECTS)
|
||||
set(OLDFILE ${OUTPUT_DIR}/include/util/fingerprint_impl.hpp)
|
||||
set(NEWFILE ${OLDFILE}.tmp)
|
||||
set(INFILE ${SOURCE_DIR}/include/util/fingerprint_impl.hpp.in)
|
||||
file(MD5 ${SOURCE_DIR}/src/tools/contract.cpp MD5PREPARE)
|
||||
file(MD5 ${SOURCE_DIR}/include/util/static_rtree.hpp MD5RTREE)
|
||||
file(MD5 ${SOURCE_DIR}/include/util/graph_loader.hpp MD5GRAPH)
|
||||
file(MD5 ${SOURCE_DIR}/include/engine/datafacade/internal_datafacade.hpp MD5OBJECTS)
|
||||
|
||||
CONFIGURE_FILE( ${SOURCE_DIR}/Util/finger_print.cpp.in ${SOURCE_DIR}/Util/finger_print.cpp )
|
||||
CONFIGURE_FILE(${INFILE} ${NEWFILE})
|
||||
|
||||
file(MD5 ${NEWFILE} MD5NEW)
|
||||
|
||||
if (EXISTS ${OLDFILE})
|
||||
file(MD5 ${OLDFILE} MD5OLD)
|
||||
if(NOT ${MD5NEW} STREQUAL ${MD5OLD})
|
||||
file(REMOVE_RECURSE ${OLDFILE})
|
||||
file(RENAME ${NEWFILE} ${OLDFILE})
|
||||
else()
|
||||
file(REMOVE_RECURSE ${NEWFILE})
|
||||
message(STATUS "Fingerprint unchanged, not regenerating")
|
||||
endif()
|
||||
else()
|
||||
file(RENAME ${NEWFILE} ${OLDFILE})
|
||||
endif()
|
||||
|
||||
@@ -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()
|
||||
@@ -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,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}")
|
||||
|
||||
@@ -32,13 +32,11 @@ cache_file = "%s/cached_options.txt" % (scriptpath)
|
||||
db = None
|
||||
if os.access(cache_file, os.R_OK) == 0:
|
||||
db = load_db(sys.argv[1])
|
||||
f = open(cache_file, "wb")
|
||||
pickle.dump(db, f)
|
||||
f.close()
|
||||
with open(cache_file, "wb") as f:
|
||||
pickle.dump(db, f)
|
||||
else:
|
||||
f = open(cache_file)
|
||||
db = pickle.load(f)
|
||||
f.close()
|
||||
with open(cache_file) as f:
|
||||
db = pickle.load(f)
|
||||
|
||||
if db and sys.argv[2] in db:
|
||||
for option in db[sys.argv[2]]:
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif(NOT "${rm_retval}" STREQUAL 0)
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
endforeach(file)
|
||||
+5
-5
@@ -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@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -losrm
|
||||
Libs.private: @ENGINE_LIBRARY_LISTING@
|
||||
Cflags: -I${includedir} -I${includedir}/osrm
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
#/usr/bin/env bash
|
||||
ln -s /usr/share/doc/@CMAKE_PROJECT_NAME@/profiles/car.lua @CMAKE_INSTALL_PREFIX@/profile.lua
|
||||
@@ -1,9 +0,0 @@
|
||||
# config/cucumber.yml
|
||||
##YAML Template
|
||||
---
|
||||
default: --require features --tags ~@todo --tags ~@bug --tag ~@stress
|
||||
verify: --require features --tags ~@todo --tags ~@bug --tags ~@stress -f progress
|
||||
jenkins: --require features --tags ~@todo --tags ~@bug --tags ~@stress --tags ~@options -f progress
|
||||
bugs: --require features --tags @bug
|
||||
todo: --require features --tags @todo
|
||||
all: --require features
|
||||
@@ -1,782 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "edge_based_graph_factory.hpp"
|
||||
#include "../algorithms/bfs_components.hpp"
|
||||
#include "../data_structures/percent.hpp"
|
||||
#include "../Util/compute_angle.hpp"
|
||||
#include "../Util/integer_range.hpp"
|
||||
#include "../Util/lua_util.hpp"
|
||||
#include "../Util/simple_logger.hpp"
|
||||
#include "../Util/timing_util.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
|
||||
EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
||||
const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
|
||||
std::unique_ptr<RestrictionMap> restriction_map,
|
||||
std::vector<NodeID> &barrier_node_list,
|
||||
std::vector<NodeID> &traffic_light_node_list,
|
||||
std::vector<QueryNode> &node_info_list,
|
||||
SpeedProfileProperties &speed_profile)
|
||||
: speed_profile(speed_profile),
|
||||
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
|
||||
m_node_info_list(node_info_list), m_node_based_graph(node_based_graph),
|
||||
m_restriction_map(std::move(restriction_map)), max_id(0)
|
||||
{
|
||||
|
||||
// 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 = static_cast<unsigned>(forward_geometry.size());
|
||||
BOOST_ASSERT(geometry_size > 1);
|
||||
|
||||
// reconstruct bidirectional edge with individual weights and put each into the NN index
|
||||
|
||||
std::vector<int> forward_dist_prefix_sum(forward_geometry.size(), 0);
|
||||
std::vector<int> reverse_dist_prefix_sum(reverse_geometry.size(), 0);
|
||||
|
||||
// quick'n'dirty prefix sum as std::partial_sum needs addtional casts
|
||||
// TODO: move to lambda function with C++11
|
||||
int temp_sum = 0;
|
||||
|
||||
for (const auto i : osrm::irange(0u, geometry_size))
|
||||
{
|
||||
forward_dist_prefix_sum[i] = temp_sum;
|
||||
temp_sum += forward_geometry[i].second;
|
||||
|
||||
BOOST_ASSERT(forward_data.distance >= temp_sum);
|
||||
}
|
||||
|
||||
temp_sum = 0;
|
||||
for (const auto i : osrm::irange(0u, geometry_size))
|
||||
{
|
||||
temp_sum += reverse_geometry[reverse_geometry.size() - 1 - i].second;
|
||||
reverse_dist_prefix_sum[i] = reverse_data.distance - temp_sum;
|
||||
// BOOST_ASSERT(reverse_data.distance >= temp_sum);
|
||||
}
|
||||
|
||||
NodeID current_edge_source_coordinate_id = node_u;
|
||||
|
||||
if (SPECIAL_NODEID != forward_data.edgeBasedNodeID)
|
||||
{
|
||||
max_id = std::max(forward_data.edgeBasedNodeID, max_id);
|
||||
}
|
||||
if (SPECIAL_NODEID != reverse_data.edgeBasedNodeID)
|
||||
{
|
||||
max_id = std::max(reverse_data.edgeBasedNodeID, max_id);
|
||||
}
|
||||
|
||||
// traverse arrays from start and end respectively
|
||||
for (const auto i : osrm::irange(0u, geometry_size))
|
||||
{
|
||||
BOOST_ASSERT(current_edge_source_coordinate_id ==
|
||||
reverse_geometry[geometry_size - 1 - i].first);
|
||||
const NodeID current_edge_target_coordinate_id = forward_geometry[i].first;
|
||||
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
|
||||
|
||||
// build edges
|
||||
m_edge_based_node_list.emplace_back(forward_data.edgeBasedNodeID,
|
||||
reverse_data.edgeBasedNodeID,
|
||||
current_edge_source_coordinate_id,
|
||||
current_edge_target_coordinate_id,
|
||||
forward_data.nameID,
|
||||
forward_geometry[i].second,
|
||||
reverse_geometry[geometry_size - 1 - i].second,
|
||||
forward_dist_prefix_sum[i],
|
||||
reverse_dist_prefix_sum[i],
|
||||
m_geometry_compressor.GetPositionForID(e1),
|
||||
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_node_based_graph);
|
||||
|
||||
m_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u);
|
||||
m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u, m_node_based_graph);
|
||||
|
||||
// store compressed geometry in container
|
||||
m_geometry_compressor.CompressEdge(
|
||||
forward_e1,
|
||||
forward_e2,
|
||||
node_v,
|
||||
node_w,
|
||||
forward_weight1 +
|
||||
(add_traffic_signal_penalty ? speed_profile.traffic_signal_penalty : 0),
|
||||
forward_weight2);
|
||||
m_geometry_compressor.CompressEdge(
|
||||
reverse_e1,
|
||||
reverse_e2,
|
||||
node_v,
|
||||
node_u,
|
||||
reverse_weight1,
|
||||
reverse_weight2 +
|
||||
(add_traffic_signal_penalty ? speed_profile.traffic_signal_penalty : 0));
|
||||
++removed_node_count;
|
||||
|
||||
BOOST_ASSERT(m_node_based_graph->GetEdgeData(forward_e1).nameID ==
|
||||
m_node_based_graph->GetEdgeData(reverse_e1).nameID);
|
||||
}
|
||||
}
|
||||
SimpleLogger().Write() << "removed " << removed_node_count << " nodes";
|
||||
m_geometry_compressor.PrintStatistics();
|
||||
|
||||
unsigned new_node_count = 0;
|
||||
unsigned new_edge_count = 0;
|
||||
|
||||
for(const auto i : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
||||
{
|
||||
if (m_node_based_graph->GetOutDegree(i) > 0)
|
||||
{
|
||||
++new_node_count;
|
||||
new_edge_count += (m_node_based_graph->EndEdges(i) - m_node_based_graph->BeginEdges(i));
|
||||
}
|
||||
}
|
||||
SimpleLogger().Write() << "new nodes: " << new_node_count << ", edges " << new_edge_count;
|
||||
SimpleLogger().Write() << "Node compression ratio: " << new_node_count /
|
||||
(double)original_number_of_nodes;
|
||||
SimpleLogger().Write() << "Edge compression ratio: " << new_edge_count /
|
||||
(double)original_number_of_edges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the id of the edge in the edge expanded graph (into the edge in the node based graph)
|
||||
*/
|
||||
void EdgeBasedGraphFactory::RenumberEdges()
|
||||
{
|
||||
// renumber edge based node IDs
|
||||
unsigned numbered_edges_count = 0;
|
||||
for (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;
|
||||
}
|
||||
@@ -1,126 +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.
|
||||
|
||||
*/
|
||||
|
||||
// This class constructs the edge-expanded routing graph
|
||||
|
||||
#ifndef EDGE_BASED_GRAPH_FACTORY_HPP_
|
||||
#define EDGE_BASED_GRAPH_FACTORY_HPP_
|
||||
|
||||
#include "geometry_compressor.hpp"
|
||||
#include "../typedefs.h"
|
||||
#include "../data_structures/deallocating_vector.hpp"
|
||||
#include "../data_structures/edge_based_node.hpp"
|
||||
#include "../data_structures/original_edge_data.hpp"
|
||||
#include "../data_structures/query_node.hpp"
|
||||
#include "../data_structures/turn_instructions.hpp"
|
||||
#include "../data_structures/node_based_graph.hpp"
|
||||
#include "../data_structures/restriction_map.hpp"
|
||||
|
||||
#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<QueryNode> &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<QueryNode> 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 /* EDGE_BASED_GRAPH_FACTORY_HPP_ */
|
||||
@@ -1,241 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "geometry_compressor.hpp"
|
||||
#include "../Util/simple_logger.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
int free_list_maximum = 0;
|
||||
int UniqueNumber() { return ++free_list_maximum; }
|
||||
|
||||
GeometryCompressor::GeometryCompressor()
|
||||
{
|
||||
m_free_list.reserve(100);
|
||||
IncreaseFreeList();
|
||||
}
|
||||
|
||||
void GeometryCompressor::IncreaseFreeList()
|
||||
{
|
||||
m_compressed_geometries.resize(m_compressed_geometries.size() + 100);
|
||||
for (unsigned i = 100; i > 0; --i)
|
||||
{
|
||||
m_free_list.emplace_back(free_list_maximum);
|
||||
++free_list_maximum;
|
||||
}
|
||||
}
|
||||
|
||||
bool GeometryCompressor::HasEntryForID(const EdgeID edge_id) const
|
||||
{
|
||||
auto iter = m_edge_id_to_list_index_map.find(edge_id);
|
||||
return iter != m_edge_id_to_list_index_map.end();
|
||||
}
|
||||
|
||||
unsigned GeometryCompressor::GetPositionForID(const EdgeID edge_id) const
|
||||
{
|
||||
auto map_iterator = m_edge_id_to_list_index_map.find(edge_id);
|
||||
BOOST_ASSERT(map_iterator != m_edge_id_to_list_index_map.end());
|
||||
BOOST_ASSERT(map_iterator->second < m_compressed_geometries.size());
|
||||
return map_iterator->second;
|
||||
}
|
||||
|
||||
void GeometryCompressor::SerializeInternalVector(const std::string &path) const
|
||||
{
|
||||
|
||||
boost::filesystem::fstream geometry_out_stream(path, std::ios::binary | std::ios::out);
|
||||
const unsigned compressed_geometries = m_compressed_geometries.size() + 1;
|
||||
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != compressed_geometries);
|
||||
geometry_out_stream.write((char *)&compressed_geometries, sizeof(unsigned));
|
||||
|
||||
// write indices array
|
||||
unsigned prefix_sum_of_list_indices = 0;
|
||||
for (const auto &elem : m_compressed_geometries)
|
||||
{
|
||||
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
|
||||
|
||||
const std::vector<CompressedNode> ¤t_vector = elem;
|
||||
const unsigned unpacked_size = current_vector.size();
|
||||
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != unpacked_size);
|
||||
prefix_sum_of_list_indices += unpacked_size;
|
||||
}
|
||||
// sentinel element
|
||||
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
|
||||
|
||||
// number of geometry entries to follow, it is the (inclusive) prefix sum
|
||||
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
|
||||
|
||||
unsigned control_sum = 0;
|
||||
// write compressed geometries
|
||||
for (auto &elem : m_compressed_geometries)
|
||||
{
|
||||
const std::vector<CompressedNode> ¤t_vector = elem;
|
||||
const unsigned unpacked_size = current_vector.size();
|
||||
control_sum += unpacked_size;
|
||||
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != unpacked_size);
|
||||
for (const CompressedNode current_node : current_vector)
|
||||
{
|
||||
geometry_out_stream.write((char *)&(current_node.first), sizeof(NodeID));
|
||||
}
|
||||
}
|
||||
BOOST_ASSERT(control_sum == prefix_sum_of_list_indices);
|
||||
// all done, let's close the resource
|
||||
geometry_out_stream.close();
|
||||
}
|
||||
|
||||
void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
|
||||
const EdgeID edge_id_2,
|
||||
const NodeID via_node_id,
|
||||
const NodeID target_node_id,
|
||||
const EdgeWeight weight1,
|
||||
const EdgeWeight weight2)
|
||||
{
|
||||
// remove super-trivial geometries
|
||||
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_1);
|
||||
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_2);
|
||||
BOOST_ASSERT(SPECIAL_NODEID != via_node_id);
|
||||
BOOST_ASSERT(SPECIAL_NODEID != target_node_id);
|
||||
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight1);
|
||||
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight2);
|
||||
|
||||
// append list of removed edge_id plus via node to surviving edge id:
|
||||
// <surv_1, .. , surv_n, via_node_id, rem_1, .. rem_n
|
||||
//
|
||||
// General scheme:
|
||||
// 1. append via node id to list of edge_id_1
|
||||
// 2. find list for edge_id_2, if yes add all elements and delete it
|
||||
|
||||
// Add via node id. List is created if it does not exist
|
||||
if (!HasEntryForID(edge_id_1))
|
||||
{
|
||||
// create a new entry in the map
|
||||
if (0 == m_free_list.size())
|
||||
{
|
||||
// make sure there is a place to put the entries
|
||||
IncreaseFreeList();
|
||||
}
|
||||
BOOST_ASSERT(!m_free_list.empty());
|
||||
m_edge_id_to_list_index_map[edge_id_1] = m_free_list.back();
|
||||
m_free_list.pop_back();
|
||||
}
|
||||
|
||||
// find bucket index
|
||||
const auto iter = m_edge_id_to_list_index_map.find(edge_id_1);
|
||||
BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end());
|
||||
const unsigned edge_bucket_id1 = iter->second;
|
||||
BOOST_ASSERT(edge_bucket_id1 == GetPositionForID(edge_id_1));
|
||||
BOOST_ASSERT(edge_bucket_id1 < m_compressed_geometries.size());
|
||||
|
||||
std::vector<CompressedNode> &edge_bucket_list1 = m_compressed_geometries[edge_bucket_id1];
|
||||
|
||||
if (edge_bucket_list1.empty())
|
||||
{
|
||||
edge_bucket_list1.emplace_back(via_node_id, weight1);
|
||||
}
|
||||
|
||||
BOOST_ASSERT(0 < edge_bucket_list1.size());
|
||||
BOOST_ASSERT(!edge_bucket_list1.empty());
|
||||
|
||||
if (HasEntryForID(edge_id_2))
|
||||
{
|
||||
// second edge is not atomic anymore
|
||||
const unsigned list_to_remove_index = GetPositionForID(edge_id_2);
|
||||
BOOST_ASSERT(list_to_remove_index < m_compressed_geometries.size());
|
||||
|
||||
std::vector<CompressedNode> &edge_bucket_list2 =
|
||||
m_compressed_geometries[list_to_remove_index];
|
||||
|
||||
// found an existing list, append it to the list of edge_id_1
|
||||
edge_bucket_list1.insert(
|
||||
edge_bucket_list1.end(), edge_bucket_list2.begin(), edge_bucket_list2.end());
|
||||
|
||||
// remove the list of edge_id_2
|
||||
m_edge_id_to_list_index_map.erase(edge_id_2);
|
||||
BOOST_ASSERT(m_edge_id_to_list_index_map.end() ==
|
||||
m_edge_id_to_list_index_map.find(edge_id_2));
|
||||
edge_bucket_list2.clear();
|
||||
BOOST_ASSERT(0 == edge_bucket_list2.size());
|
||||
m_free_list.emplace_back(list_to_remove_index);
|
||||
BOOST_ASSERT(list_to_remove_index == m_free_list.back());
|
||||
}
|
||||
else
|
||||
{
|
||||
// we are certain that the second edge is atomic.
|
||||
edge_bucket_list1.emplace_back(target_node_id, weight2);
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryCompressor::PrintStatistics() const
|
||||
{
|
||||
const uint64_t compressed_edges = m_compressed_geometries.size();
|
||||
BOOST_ASSERT(0 == compressed_edges % 2);
|
||||
BOOST_ASSERT(m_compressed_geometries.size() + m_free_list.size() > 0);
|
||||
|
||||
uint64_t compressed_geometries = 0;
|
||||
uint64_t longest_chain_length = 0;
|
||||
for (const std::vector<CompressedNode> ¤t_vector : m_compressed_geometries)
|
||||
{
|
||||
compressed_geometries += current_vector.size();
|
||||
longest_chain_length = std::max(longest_chain_length, (uint64_t)current_vector.size());
|
||||
}
|
||||
|
||||
SimpleLogger().Write() << "Geometry successfully removed:"
|
||||
"\n compressed edges: " << compressed_edges
|
||||
<< "\n compressed geometries: " << compressed_geometries
|
||||
<< "\n longest chain length: " << longest_chain_length
|
||||
<< "\n cmpr ratio: "
|
||||
<< ((float)compressed_edges /
|
||||
std::max(compressed_geometries, (uint64_t)1))
|
||||
<< "\n avg chain length: "
|
||||
<< (float)compressed_geometries /
|
||||
std::max((uint64_t)1, compressed_edges);
|
||||
}
|
||||
|
||||
const std::vector<GeometryCompressor::CompressedNode> &
|
||||
GeometryCompressor::GetBucketReference(const EdgeID edge_id) const
|
||||
{
|
||||
const unsigned index = m_edge_id_to_list_index_map.at(edge_id);
|
||||
return m_compressed_geometries.at(index);
|
||||
}
|
||||
|
||||
NodeID GeometryCompressor::GetFirstNodeIDOfBucket(const EdgeID edge_id) const
|
||||
{
|
||||
const auto &bucket = GetBucketReference(edge_id);
|
||||
BOOST_ASSERT(bucket.size() >= 2);
|
||||
return bucket[1].first;
|
||||
}
|
||||
NodeID GeometryCompressor::GetLastNodeIDOfBucket(const EdgeID edge_id) const
|
||||
{
|
||||
const auto &bucket = GetBucketReference(edge_id);
|
||||
BOOST_ASSERT(bucket.size() >= 2);
|
||||
return bucket[bucket.size()-2].first;
|
||||
}
|
||||
|
||||
@@ -1,67 +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 GEOMETRY_COMPRESSOR_HPP_
|
||||
#define GEOMETRY_COMPRESSOR_HPP_
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class GeometryCompressor
|
||||
{
|
||||
public:
|
||||
using CompressedNode = std::pair<NodeID, EdgeWeight>;
|
||||
|
||||
GeometryCompressor();
|
||||
void CompressEdge(const EdgeID surviving_edge_id,
|
||||
const EdgeID removed_edge_id,
|
||||
const NodeID via_node_id,
|
||||
const NodeID target_node,
|
||||
const EdgeWeight weight1,
|
||||
const EdgeWeight weight2);
|
||||
|
||||
bool HasEntryForID(const EdgeID edge_id) const;
|
||||
void PrintStatistics() const;
|
||||
void SerializeInternalVector(const std::string &path) const;
|
||||
unsigned GetPositionForID(const EdgeID edge_id) const;
|
||||
const std::vector<GeometryCompressor::CompressedNode> &
|
||||
GetBucketReference(const EdgeID edge_id) const;
|
||||
NodeID GetFirstNodeIDOfBucket(const EdgeID edge_id) const;
|
||||
NodeID GetLastNodeIDOfBucket(const EdgeID edge_id) const;
|
||||
|
||||
private:
|
||||
void IncreaseFreeList();
|
||||
std::vector<std::vector<CompressedNode>> m_compressed_geometries;
|
||||
std::vector<unsigned> m_free_list;
|
||||
std::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
|
||||
};
|
||||
|
||||
#endif // GEOMETRY_COMPRESSOR_HPP_
|
||||
@@ -1,581 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "processing_chain.hpp"
|
||||
|
||||
#include "contractor.hpp"
|
||||
|
||||
#include "../algorithms/crc32_processor.hpp"
|
||||
#include "../data_structures/deallocating_vector.hpp"
|
||||
#include "../data_structures/static_rtree.hpp"
|
||||
#include "../data_structures/restriction_map.hpp"
|
||||
|
||||
#include "../Util/GitDescription.h"
|
||||
#include "../Util/graph_loader.hpp"
|
||||
#include "../Util/integer_range.hpp"
|
||||
#include "../Util/lua_util.hpp"
|
||||
#include "../Util/make_unique.hpp"
|
||||
#include "../Util/OSRMException.h"
|
||||
#include "../Util/simple_logger.hpp"
|
||||
#include "../Util/StringUtil.h"
|
||||
#include "../Util/timing_util.hpp"
|
||||
#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 *)¤t_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);
|
||||
|
||||
const auto& temp_config_path = option_variables["config"].as<boost::filesystem::path>();
|
||||
if (boost::filesystem::is_regular_file(temp_config_path))
|
||||
{
|
||||
boost::program_options::store(boost::program_options::parse_config_file<char>(temp_config_path.string().c_str(), cmdline_options, true),
|
||||
option_variables);
|
||||
}
|
||||
|
||||
if (option_variables.count("version"))
|
||||
{
|
||||
SimpleLogger().Write() << g_GIT_DESCRIPTION;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (option_variables.count("help"))
|
||||
{
|
||||
SimpleLogger().Write() << "\n" << visible_options;
|
||||
return false;
|
||||
}
|
||||
|
||||
boost::program_options::notify(option_variables);
|
||||
|
||||
if (!option_variables.count("restrictions"))
|
||||
{
|
||||
restrictions_path = std::string(input_path.string() + ".restrictions");
|
||||
}
|
||||
|
||||
if (!option_variables.count("input"))
|
||||
{
|
||||
SimpleLogger().Write() << "\n" << visible_options;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Loads and checks file UUIDs
|
||||
*/
|
||||
void Prepare::CheckRestrictionsFile(FingerPrint &fingerprint_orig)
|
||||
{
|
||||
boost::filesystem::ifstream restriction_stream(restrictions_path, std::ios::binary);
|
||||
FingerPrint fingerprint_loaded;
|
||||
unsigned number_of_usable_restrictions = 0;
|
||||
restriction_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
|
||||
if (!fingerprint_loaded.TestPrepare(fingerprint_orig))
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << ".restrictions was prepared with different build.\n"
|
||||
"Reprocess to get rid of this warning.";
|
||||
}
|
||||
|
||||
restriction_stream.read((char *)&number_of_usable_restrictions, sizeof(unsigned));
|
||||
restriction_list.resize(number_of_usable_restrictions);
|
||||
if (number_of_usable_restrictions > 0)
|
||||
{
|
||||
restriction_stream.read((char *)&(restriction_list[0]),
|
||||
number_of_usable_restrictions * sizeof(TurnRestriction));
|
||||
}
|
||||
restriction_stream.close();
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Setups scripting environment (lua-scripting)
|
||||
Also initializes speed profile.
|
||||
*/
|
||||
bool
|
||||
Prepare::SetupScriptingEnvironment(lua_State *lua_state,
|
||||
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
|
||||
{
|
||||
// open utility libraries string library;
|
||||
luaL_openlibs(lua_state);
|
||||
|
||||
// adjust lua load path
|
||||
luaAddScriptFolderToLoadPath(lua_state, profile_path.string().c_str());
|
||||
|
||||
// Now call our function in a lua script
|
||||
if (0 != luaL_dofile(lua_state, profile_path.string().c_str()))
|
||||
{
|
||||
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 != luaL_dostring(lua_state, "return traffic_signal_penalty\n"))
|
||||
{
|
||||
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
|
||||
return false;
|
||||
}
|
||||
speed_profile.traffic_signal_penalty = 10 * lua_tointeger(lua_state, -1);
|
||||
SimpleLogger().Write(logDEBUG)
|
||||
<< "traffic_signal_penalty: " << speed_profile.traffic_signal_penalty;
|
||||
|
||||
if (0 != luaL_dostring(lua_state, "return u_turn_penalty\n"))
|
||||
{
|
||||
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
speed_profile.u_turn_penalty = 10 * lua_tointeger(lua_state, -1);
|
||||
speed_profile.has_turn_penalty_function = lua_function_exists(lua_state, "turn_function");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Building an edge-expanded graph from node-based input and turn restrictions
|
||||
*/
|
||||
std::size_t
|
||||
Prepare::BuildEdgeExpandedGraph(lua_State *lua_state,
|
||||
NodeID number_of_node_based_nodes,
|
||||
std::vector<EdgeBasedNode> &node_based_edge_list,
|
||||
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
||||
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
|
||||
{
|
||||
SimpleLogger().Write() << "Generating edge-expanded graph representation";
|
||||
std::shared_ptr<NodeBasedDynamicGraph> node_based_graph =
|
||||
NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
|
||||
std::unique_ptr<RestrictionMap> restriction_map = osrm::make_unique<RestrictionMap>(restriction_list);
|
||||
std::shared_ptr<EdgeBasedGraphFactory> edge_based_graph_factory =
|
||||
std::make_shared<EdgeBasedGraphFactory>(node_based_graph,
|
||||
std::move(restriction_map),
|
||||
barrier_node_list,
|
||||
traffic_light_list,
|
||||
internal_to_external_node_map,
|
||||
speed_profile);
|
||||
edge_list.clear();
|
||||
edge_list.shrink_to_fit();
|
||||
|
||||
edge_based_graph_factory->Run(edge_out, geometry_filename, lua_state);
|
||||
|
||||
restriction_list.clear();
|
||||
restriction_list.shrink_to_fit();
|
||||
barrier_node_list.clear();
|
||||
barrier_node_list.shrink_to_fit();
|
||||
traffic_light_list.clear();
|
||||
traffic_light_list.shrink_to_fit();
|
||||
|
||||
const std::size_t number_of_edge_based_nodes =
|
||||
edge_based_graph_factory->GetNumberOfEdgeBasedNodes();
|
||||
|
||||
BOOST_ASSERT(number_of_edge_based_nodes != std::numeric_limits<unsigned>::max());
|
||||
#ifndef WIN32
|
||||
static_assert(sizeof(EdgeBasedEdge) == 16,
|
||||
"changing ImportEdge type has influence on memory consumption!");
|
||||
#endif
|
||||
|
||||
edge_based_graph_factory->GetEdgeBasedEdges(edge_based_edge_list);
|
||||
edge_based_graph_factory->GetEdgeBasedNodes(node_based_edge_list);
|
||||
|
||||
edge_based_graph_factory.reset();
|
||||
node_based_graph.reset();
|
||||
|
||||
return number_of_edge_based_nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Writing info on original (node-based) nodes
|
||||
*/
|
||||
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(QueryNode));
|
||||
}
|
||||
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);
|
||||
}
|
||||
@@ -1,95 +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 PROCESSING_CHAIN_HPP
|
||||
#define PROCESSING_CHAIN_HPP
|
||||
|
||||
#include "edge_based_graph_factory.hpp"
|
||||
#include "../data_structures/query_edge.hpp"
|
||||
#include "../data_structures/static_graph.hpp"
|
||||
|
||||
class FingerPrint;
|
||||
struct EdgeBasedNode;
|
||||
struct lua_State;
|
||||
|
||||
#include <boost/filesystem.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<QueryNode> internal_to_external_node_map;
|
||||
std::vector<TurnRestriction> restriction_list;
|
||||
std::vector<NodeID> barrier_node_list;
|
||||
std::vector<NodeID> traffic_light_list;
|
||||
std::vector<ImportEdge> edge_list;
|
||||
|
||||
unsigned requested_num_threads;
|
||||
boost::filesystem::path config_file_path;
|
||||
boost::filesystem::path input_path;
|
||||
boost::filesystem::path restrictions_path;
|
||||
boost::filesystem::path preinfo_path;
|
||||
boost::filesystem::path profile_path;
|
||||
|
||||
std::string node_filename;
|
||||
std::string edge_out;
|
||||
std::string info_out;
|
||||
std::string geometry_filename;
|
||||
std::string graph_out;
|
||||
std::string rtree_nodes_path;
|
||||
std::string rtree_leafs_path;
|
||||
};
|
||||
|
||||
#endif // PROCESSING_CHAIN_HPP
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
default: '--require features --tags ~@stress --tags ~@todo',
|
||||
verify: '--require features --tags ~@todo --tags ~@bug --tags ~@stress -f progress',
|
||||
jenkins: '--require features --tags ~@todo --tags ~@bug --tags ~@stress --tags ~@options -f progress',
|
||||
bugs: '--require features --tags @bug',
|
||||
todo: '--require features --tags @todo',
|
||||
all: '--require features'
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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::is_valid() const
|
||||
{
|
||||
if (lat > 90 * COORDINATE_PRECISION || lat < -90 * COORDINATE_PRECISION ||
|
||||
lon > 180 * COORDINATE_PRECISION || lon < -180 * COORDINATE_PRECISION)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool FixedPointCoordinate::operator==(const FixedPointCoordinate &other) const
|
||||
{
|
||||
return lat == other.lat && lon == other.lon;
|
||||
}
|
||||
|
||||
double FixedPointCoordinate::ApproximateDistance(const int lat1,
|
||||
const int lon1,
|
||||
const int lat2,
|
||||
const int lon2)
|
||||
{
|
||||
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
|
||||
double RAD = 0.017453292519943295769236907684886;
|
||||
double lt1 = lat1 / COORDINATE_PRECISION;
|
||||
double ln1 = lon1 / COORDINATE_PRECISION;
|
||||
double lt2 = lat2 / COORDINATE_PRECISION;
|
||||
double ln2 = lon2 / COORDINATE_PRECISION;
|
||||
double dlat1 = lt1 * (RAD);
|
||||
|
||||
double dlong1 = ln1 * (RAD);
|
||||
double dlat2 = lt2 * (RAD);
|
||||
double dlong2 = ln2 * (RAD);
|
||||
|
||||
double dLong = dlong1 - dlong2;
|
||||
double dLat = dlat1 - dlat2;
|
||||
|
||||
double aHarv = pow(sin(dLat / 2.0), 2.0) + cos(dlat1) * cos(dlat2) * pow(sin(dLong / 2.), 2);
|
||||
double cHarv = 2. * atan2(sqrt(aHarv), sqrt(1.0 - aHarv));
|
||||
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
|
||||
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
|
||||
const double earth = 6372797.560856;
|
||||
return earth * cHarv;
|
||||
}
|
||||
|
||||
double FixedPointCoordinate::ApproximateDistance(const FixedPointCoordinate &coordinate_1,
|
||||
const FixedPointCoordinate &coordinate_2)
|
||||
{
|
||||
return ApproximateDistance(
|
||||
coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon);
|
||||
}
|
||||
|
||||
float FixedPointCoordinate::ApproximateEuclideanDistance(const FixedPointCoordinate &coordinate_1,
|
||||
const FixedPointCoordinate &coordinate_2)
|
||||
{
|
||||
return ApproximateEuclideanDistance(
|
||||
coordinate_1.lat, coordinate_1.lon, coordinate_2.lat, coordinate_2.lon);
|
||||
}
|
||||
|
||||
float FixedPointCoordinate::ApproximateEuclideanDistance(const int lat1,
|
||||
const int lon1,
|
||||
const int lat2,
|
||||
const int lon2)
|
||||
{
|
||||
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
|
||||
|
||||
const float RAD = 0.017453292519943295769236907684886f;
|
||||
const float float_lat1 = (lat1 / COORDINATE_PRECISION) * RAD;
|
||||
const float float_lon1 = (lon1 / COORDINATE_PRECISION) * RAD;
|
||||
const float float_lat2 = (lat2 / COORDINATE_PRECISION) * RAD;
|
||||
const float float_lon2 = (lon2 / COORDINATE_PRECISION) * RAD;
|
||||
|
||||
const float x_value = (float_lon2 - float_lon1) * cos((float_lat1 + float_lat2) / 2.f);
|
||||
const float y_value = float_lat2 - float_lat1;
|
||||
const float earth_radius = 6372797.560856f;
|
||||
return sqrt(x_value * x_value + y_value * y_value) * earth_radius;
|
||||
}
|
||||
|
||||
float
|
||||
FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &source_coordinate,
|
||||
const FixedPointCoordinate &target_coordinate,
|
||||
const FixedPointCoordinate &point)
|
||||
{
|
||||
// initialize values
|
||||
const float x_value = static_cast<float>(lat2y(point.lat / COORDINATE_PRECISION));
|
||||
const float y_value = point.lon / COORDINATE_PRECISION;
|
||||
float a = static_cast<float>(lat2y(source_coordinate.lat / COORDINATE_PRECISION));
|
||||
float b = source_coordinate.lon / COORDINATE_PRECISION;
|
||||
float c = static_cast<float>(lat2y(target_coordinate.lat / COORDINATE_PRECISION));
|
||||
float d = target_coordinate.lon / COORDINATE_PRECISION;
|
||||
float p, q;
|
||||
if (std::abs(a - c) > std::numeric_limits<float>::epsilon())
|
||||
{
|
||||
const float slope = (d - b) / (c - a); // slope
|
||||
// Projection of (x,y) on line joining (a,b) and (c,d)
|
||||
p = ((x_value + (slope * y_value)) + (slope * slope * a - slope * b)) /
|
||||
(1.f + slope * slope);
|
||||
q = b + slope * (p - a);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = c;
|
||||
q = y_value;
|
||||
}
|
||||
|
||||
float ratio;
|
||||
bool inverse_ratio = false;
|
||||
|
||||
// straight line segment on equator
|
||||
if (std::abs(c) < std::numeric_limits<float>::epsilon() &&
|
||||
std::abs(a) < std::numeric_limits<float>::epsilon())
|
||||
{
|
||||
ratio = (q - b) / (d - b);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (std::abs(c) < std::numeric_limits<float>::epsilon())
|
||||
{
|
||||
// swap start/end
|
||||
std::swap(a, c);
|
||||
std::swap(b, d);
|
||||
inverse_ratio = true;
|
||||
}
|
||||
|
||||
float nY = (d * p - c * q) / (a * d - b * c);
|
||||
// discretize the result to coordinate precision. it's a hack!
|
||||
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
|
||||
{
|
||||
nY = 0.f;
|
||||
}
|
||||
|
||||
// compute ratio
|
||||
ratio = (p - nY * a) / c;
|
||||
}
|
||||
|
||||
if (std::isnan(ratio))
|
||||
{
|
||||
ratio = (target_coordinate == point ? 1.f : 0.f);
|
||||
}
|
||||
else if (std::abs(ratio) <= std::numeric_limits<float>::epsilon())
|
||||
{
|
||||
ratio = 0.f;
|
||||
}
|
||||
else if (std::abs(ratio - 1.f) <= std::numeric_limits<float>::epsilon())
|
||||
{
|
||||
ratio = 1.f;
|
||||
}
|
||||
|
||||
// we need to do this, if we switched start/end coordinates
|
||||
if (inverse_ratio)
|
||||
{
|
||||
ratio = 1.0f - ratio;
|
||||
}
|
||||
|
||||
// compute the nearest location
|
||||
FixedPointCoordinate nearest_location;
|
||||
BOOST_ASSERT(!std::isnan(ratio));
|
||||
if (ratio <= 0.f)
|
||||
{ // point is "left" of edge
|
||||
nearest_location = source_coordinate;
|
||||
}
|
||||
else if (ratio >= 1.f)
|
||||
{ // point is "right" of edge
|
||||
nearest_location = target_coordinate;
|
||||
}
|
||||
else
|
||||
{ // point lies in between
|
||||
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
|
||||
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
|
||||
}
|
||||
|
||||
BOOST_ASSERT(nearest_location.is_valid());
|
||||
return FixedPointCoordinate::ApproximateEuclideanDistance(point, nearest_location);
|
||||
}
|
||||
|
||||
float FixedPointCoordinate::ComputePerpendicularDistance(const FixedPointCoordinate &segment_source,
|
||||
const FixedPointCoordinate &segment_target,
|
||||
const FixedPointCoordinate &query_location,
|
||||
FixedPointCoordinate &nearest_location,
|
||||
float &ratio)
|
||||
{
|
||||
BOOST_ASSERT(query_location.is_valid());
|
||||
|
||||
// initialize values
|
||||
const double x = lat2y(query_location.lat / COORDINATE_PRECISION);
|
||||
const double y = query_location.lon / COORDINATE_PRECISION;
|
||||
const double a = lat2y(segment_source.lat / COORDINATE_PRECISION);
|
||||
const double b = segment_source.lon / COORDINATE_PRECISION;
|
||||
const double c = lat2y(segment_target.lat / COORDINATE_PRECISION);
|
||||
const double d = segment_target.lon / COORDINATE_PRECISION;
|
||||
double p, q /*,mX*/, nY;
|
||||
if (std::abs(a - c) > std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
const double m = (d - b) / (c - a); // slope
|
||||
// Projection of (x,y) on line joining (a,b) and (c,d)
|
||||
p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m);
|
||||
q = b + m * (p - a);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = c;
|
||||
q = y;
|
||||
}
|
||||
nY = (d * p - c * q) / (a * d - b * c);
|
||||
|
||||
// discretize the result to coordinate precision. it's a hack!
|
||||
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
|
||||
{
|
||||
nY = 0.f;
|
||||
}
|
||||
|
||||
// compute ratio
|
||||
ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need
|
||||
// not calculate the explicit values of m an n as we
|
||||
// are just interested in the ratio
|
||||
if (std::isnan(ratio))
|
||||
{
|
||||
ratio = (segment_target == query_location ? 1.f : 0.f);
|
||||
}
|
||||
else if (std::abs(ratio) <= std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
ratio = 0.f;
|
||||
}
|
||||
else if (std::abs(ratio - 1.f) <= std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
ratio = 1.f;
|
||||
}
|
||||
|
||||
// compute nearest location
|
||||
BOOST_ASSERT(!std::isnan(ratio));
|
||||
if (ratio <= 0.f)
|
||||
{
|
||||
nearest_location = segment_source;
|
||||
}
|
||||
else if (ratio >= 1.f)
|
||||
{
|
||||
nearest_location = segment_target;
|
||||
}
|
||||
else
|
||||
{
|
||||
// point lies in between
|
||||
nearest_location.lat = static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
|
||||
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
|
||||
}
|
||||
BOOST_ASSERT(nearest_location.is_valid());
|
||||
|
||||
const float approximate_distance =
|
||||
FixedPointCoordinate::ApproximateEuclideanDistance(query_location, nearest_location);
|
||||
BOOST_ASSERT(0. <= approximate_distance);
|
||||
return approximate_distance;
|
||||
}
|
||||
|
||||
void FixedPointCoordinate::convertInternalLatLonToString(const int value, std::string &output)
|
||||
{
|
||||
char buffer[12];
|
||||
buffer[11] = 0; // zero termination
|
||||
output = printInt<11, 6>(buffer, value);
|
||||
}
|
||||
|
||||
void FixedPointCoordinate::convertInternalCoordinateToString(const FixedPointCoordinate &coord,
|
||||
std::string &output)
|
||||
{
|
||||
std::string tmp;
|
||||
tmp.reserve(23);
|
||||
convertInternalLatLonToString(coord.lon, tmp);
|
||||
output = tmp;
|
||||
output += ",";
|
||||
convertInternalLatLonToString(coord.lat, tmp);
|
||||
output += tmp;
|
||||
}
|
||||
|
||||
void
|
||||
FixedPointCoordinate::convertInternalReversedCoordinateToString(const FixedPointCoordinate &coord,
|
||||
std::string &output)
|
||||
{
|
||||
std::string tmp;
|
||||
tmp.reserve(23);
|
||||
convertInternalLatLonToString(coord.lat, tmp);
|
||||
output = tmp;
|
||||
output += ",";
|
||||
convertInternalLatLonToString(coord.lon, tmp);
|
||||
output += tmp;
|
||||
}
|
||||
|
||||
void FixedPointCoordinate::Output(std::ostream &out) const
|
||||
{
|
||||
out << "(" << lat / COORDINATE_PRECISION << "," << lon / COORDINATE_PRECISION << ")";
|
||||
}
|
||||
|
||||
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &first_coordinate,
|
||||
const FixedPointCoordinate &second_coordinate)
|
||||
{
|
||||
const float lon_diff =
|
||||
second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION;
|
||||
const float lon_delta = DegreeToRadian(lon_diff);
|
||||
const float lat1 = DegreeToRadian(first_coordinate.lat / COORDINATE_PRECISION);
|
||||
const float lat2 = DegreeToRadian(second_coordinate.lat / COORDINATE_PRECISION);
|
||||
const float y = sin(lon_delta) * cos(lat2);
|
||||
const float x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon_delta);
|
||||
float result = RadianToDegree(std::atan2(y, x));
|
||||
while (result < 0.f)
|
||||
{
|
||||
result += 360.f;
|
||||
}
|
||||
|
||||
while (result >= 360.f)
|
||||
{
|
||||
result -= 360.f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
float FixedPointCoordinate::GetBearing(const FixedPointCoordinate &other) const
|
||||
{
|
||||
const float lon_delta =
|
||||
DegreeToRadian(lon / COORDINATE_PRECISION - other.lon / COORDINATE_PRECISION);
|
||||
const float lat1 = DegreeToRadian(other.lat / COORDINATE_PRECISION);
|
||||
const float lat2 = DegreeToRadian(lat / COORDINATE_PRECISION);
|
||||
const float y_value = std::sin(lon_delta) * std::cos(lat2);
|
||||
const float x_value =
|
||||
std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(lon_delta);
|
||||
float result = RadianToDegree(std::atan2(y_value, x_value));
|
||||
|
||||
while (result < 0.f)
|
||||
{
|
||||
result += 360.f;
|
||||
}
|
||||
|
||||
while (result >= 360.f)
|
||||
{
|
||||
result -= 360.f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
float FixedPointCoordinate::DegreeToRadian(const float degree)
|
||||
{
|
||||
return degree * (static_cast<float>(M_PI) / 180.f);
|
||||
}
|
||||
|
||||
float FixedPointCoordinate::RadianToDegree(const float radian)
|
||||
{
|
||||
return radian * (180.f * static_cast<float>(M_1_PI));
|
||||
}
|
||||
|
||||
// This distance computation does integer arithmetic only and is a lot faster than
|
||||
// the other distance function which are numerically correct('ish).
|
||||
// It preserves some order among the elements that make it useful for certain purposes
|
||||
int FixedPointCoordinate::OrderedPerpendicularDistanceApproximation(
|
||||
const FixedPointCoordinate &input_point,
|
||||
const FixedPointCoordinate &segment_source,
|
||||
const FixedPointCoordinate &segment_target)
|
||||
{
|
||||
// initialize values
|
||||
const float x = static_cast<float>(lat2y(input_point.lat / COORDINATE_PRECISION));
|
||||
const float y = input_point.lon / COORDINATE_PRECISION;
|
||||
const float a = static_cast<float>(lat2y(segment_source.lat / COORDINATE_PRECISION));
|
||||
const float b = segment_source.lon / COORDINATE_PRECISION;
|
||||
const float c = static_cast<float>(lat2y(segment_target.lat / COORDINATE_PRECISION));
|
||||
const float d = segment_target.lon / COORDINATE_PRECISION;
|
||||
|
||||
float p, q;
|
||||
if (a == c)
|
||||
{
|
||||
p = c;
|
||||
q = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
const float m = (d - b) / (c - a); // slope
|
||||
// Projection of (x,y) on line joining (a,b) and (c,d)
|
||||
p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m);
|
||||
q = b + m * (p - a);
|
||||
}
|
||||
|
||||
const float nY = (d * p - c * q) / (a * d - b * c);
|
||||
float ratio = (p - nY * a) / c; // These values are actually n/m+n and m/m+n , we need
|
||||
// not calculate the explicit values of m an n as we
|
||||
// are just interested in the ratio
|
||||
if (std::isnan(ratio))
|
||||
{
|
||||
ratio = (segment_target == input_point) ? 1.f : 0.f;
|
||||
}
|
||||
|
||||
// compute target quasi-location
|
||||
int dx, dy;
|
||||
if (ratio < 0.f)
|
||||
{
|
||||
dx = input_point.lon - segment_source.lon;
|
||||
dy = input_point.lat - segment_source.lat;
|
||||
}
|
||||
else if (ratio > 1.f)
|
||||
{
|
||||
dx = input_point.lon - segment_target.lon;
|
||||
dy = input_point.lat - segment_target.lat;
|
||||
}
|
||||
else
|
||||
{
|
||||
// point lies in between
|
||||
dx = input_point.lon - static_cast<int>(q * COORDINATE_PRECISION);
|
||||
dy = input_point.lat - static_cast<int>(y2lat(p) * COORDINATE_PRECISION);
|
||||
}
|
||||
|
||||
// return an approximation in the plane
|
||||
return static_cast<int>(sqrt(dx * dx + dy * dy));
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CONCURRENT_QUEUE_HPP
|
||||
#define CONCURRENT_QUEUE_HPP
|
||||
|
||||
#include <boost/circular_buffer.hpp>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
template <typename Data> class ConcurrentQueue
|
||||
{
|
||||
public:
|
||||
explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) {}
|
||||
|
||||
inline void push(const Data &data)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_not_full.wait(lock,
|
||||
[this]
|
||||
{ return m_internal_queue.size() < m_internal_queue.capacity(); });
|
||||
m_internal_queue.push_back(data);
|
||||
m_not_empty.notify_one();
|
||||
}
|
||||
|
||||
inline bool empty() const { return m_internal_queue.empty(); }
|
||||
|
||||
inline void wait_and_pop(Data &popped_value)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_not_empty.wait(lock,
|
||||
[this]
|
||||
{ return !m_internal_queue.empty(); });
|
||||
popped_value = m_internal_queue.front();
|
||||
m_internal_queue.pop_front();
|
||||
m_not_full.notify_one();
|
||||
}
|
||||
|
||||
inline bool try_pop(Data &popped_value)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
if (m_internal_queue.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
popped_value = m_internal_queue.front();
|
||||
m_internal_queue.pop_front();
|
||||
m_not_full.notify_one();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::circular_buffer<Data> m_internal_queue;
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_not_empty;
|
||||
std::condition_variable m_not_full;
|
||||
};
|
||||
|
||||
#endif // CONCURRENT_QUEUE_HPP
|
||||
@@ -1,125 +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 EDGE_BASED_NODE_HPP
|
||||
#define EDGE_BASED_NODE_HPP
|
||||
|
||||
#include "../data_structures/travel_mode.hpp"
|
||||
#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_HPP
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "external_memory_node.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
ExternalMemoryNode::ExternalMemoryNode(
|
||||
int lat, int lon, unsigned int node_id, bool barrier, bool traffic_lights)
|
||||
: QueryNode(lat, lon, node_id), barrier(barrier), traffic_lights(traffic_lights)
|
||||
{
|
||||
}
|
||||
|
||||
ExternalMemoryNode::ExternalMemoryNode() : barrier(false), traffic_lights(false) {}
|
||||
|
||||
ExternalMemoryNode ExternalMemoryNode::min_value()
|
||||
{
|
||||
return ExternalMemoryNode(0, 0, 0, false, false);
|
||||
}
|
||||
|
||||
ExternalMemoryNode ExternalMemoryNode::max_value()
|
||||
{
|
||||
return ExternalMemoryNode(std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<int>::max(),
|
||||
std::numeric_limits<unsigned>::max(),
|
||||
false,
|
||||
false);
|
||||
}
|
||||
|
||||
bool ExternalMemoryNodeSTXXLCompare::operator()(const ExternalMemoryNode &left,
|
||||
const ExternalMemoryNode &right) const
|
||||
{
|
||||
return left.node_id < right.node_id;
|
||||
}
|
||||
|
||||
ExternalMemoryNodeSTXXLCompare::value_type ExternalMemoryNodeSTXXLCompare::max_value()
|
||||
{
|
||||
return ExternalMemoryNode::max_value();
|
||||
}
|
||||
|
||||
ExternalMemoryNodeSTXXLCompare::value_type ExternalMemoryNodeSTXXLCompare::min_value()
|
||||
{
|
||||
return ExternalMemoryNode::min_value();
|
||||
}
|
||||
@@ -1,216 +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 FIXED_POINT_NUMBER_HPP
|
||||
#define FIXED_POINT_NUMBER_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
|
||||
// implements an binary based fixed point number type
|
||||
template <unsigned FractionalBitSize,
|
||||
bool use_64_bits = false,
|
||||
bool is_unsigned = false,
|
||||
bool truncate_results = false>
|
||||
class FixedPointNumber
|
||||
{
|
||||
static_assert(FractionalBitSize > 0, "FractionalBitSize must be greater than 0");
|
||||
static_assert(FractionalBitSize <= 32, "FractionalBitSize must at most 32");
|
||||
|
||||
typename std::conditional<use_64_bits, int64_t, int32_t>::type m_fixed_point_state;
|
||||
constexpr static const decltype(m_fixed_point_state) PRECISION = 1 << FractionalBitSize;
|
||||
|
||||
// state signage encapsulates whether the state should either represent a
|
||||
// signed or an unsigned floating point number
|
||||
using state_signage =
|
||||
typename std::conditional<is_unsigned,
|
||||
typename std::make_unsigned<decltype(m_fixed_point_state)>::type,
|
||||
decltype(m_fixed_point_state)>::type;
|
||||
|
||||
public:
|
||||
FixedPointNumber() : m_fixed_point_state(0) {}
|
||||
|
||||
// the type is either initialized with a floating point value or an
|
||||
// integral state. Anything else will throw at compile-time.
|
||||
template <class T>
|
||||
constexpr FixedPointNumber(const T &&input) noexcept
|
||||
: m_fixed_point_state(static_cast<decltype(m_fixed_point_state)>(
|
||||
std::round(std::forward<const T>(input) * PRECISION)))
|
||||
{
|
||||
static_assert(
|
||||
std::is_floating_point<T>::value || std::is_integral<T>::value,
|
||||
"FixedPointNumber needs to be initialized with floating point or integral value");
|
||||
}
|
||||
|
||||
// get max value
|
||||
template <typename T,
|
||||
typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
|
||||
constexpr static auto max() noexcept -> T
|
||||
{
|
||||
return static_cast<T>(std::numeric_limits<state_signage>::max()) / PRECISION;
|
||||
}
|
||||
|
||||
// get min value
|
||||
template <typename T,
|
||||
typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
|
||||
constexpr static auto min() noexcept -> T
|
||||
{
|
||||
return static_cast<T>(1) / PRECISION;
|
||||
}
|
||||
|
||||
// get lowest value
|
||||
template <typename T,
|
||||
typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
|
||||
constexpr static auto lowest() noexcept -> T
|
||||
{
|
||||
return static_cast<T>(std::numeric_limits<state_signage>::min()) / PRECISION;
|
||||
}
|
||||
|
||||
// cast to floating point type T, return value
|
||||
template <typename T,
|
||||
typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
|
||||
explicit operator const T() const noexcept
|
||||
{
|
||||
// casts to external type (signed or unsigned) and then to float
|
||||
return static_cast<T>(static_cast<state_signage>(m_fixed_point_state)) / PRECISION;
|
||||
}
|
||||
|
||||
// warn about cast to integral type T, its disabled for good reason
|
||||
template <typename T, typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
|
||||
explicit operator T() const
|
||||
{
|
||||
static_assert(std::is_integral<T>::value,
|
||||
"casts to integral types have been disabled on purpose");
|
||||
}
|
||||
|
||||
// compare, ie. sort fixed-point numbers
|
||||
bool operator<(const FixedPointNumber &other) const noexcept
|
||||
{
|
||||
return m_fixed_point_state < other.m_fixed_point_state;
|
||||
}
|
||||
|
||||
// equality, ie. sort fixed-point numbers
|
||||
bool operator==(const FixedPointNumber &other) const noexcept
|
||||
{
|
||||
return m_fixed_point_state == other.m_fixed_point_state;
|
||||
}
|
||||
|
||||
bool operator!=(const FixedPointNumber &other) const { return !(*this == other); }
|
||||
bool operator>(const FixedPointNumber &other) const { return other < *this; }
|
||||
bool operator<=(const FixedPointNumber &other) const { return !(other < *this); }
|
||||
bool operator>=(const FixedPointNumber &other) const { return !(*this < other); }
|
||||
|
||||
// arithmetic operators
|
||||
FixedPointNumber operator+(const FixedPointNumber &other) const noexcept
|
||||
{
|
||||
FixedPointNumber tmp = *this;
|
||||
tmp.m_fixed_point_state += other.m_fixed_point_state;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
FixedPointNumber &operator+=(const FixedPointNumber &other) noexcept
|
||||
{
|
||||
this->m_fixed_point_state += other.m_fixed_point_state;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FixedPointNumber operator-(const FixedPointNumber &other) const noexcept
|
||||
{
|
||||
FixedPointNumber tmp = *this;
|
||||
tmp.m_fixed_point_state -= other.m_fixed_point_state;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
FixedPointNumber &operator-=(const FixedPointNumber &other) noexcept
|
||||
{
|
||||
this->m_fixed_point_state -= other.m_fixed_point_state;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FixedPointNumber operator*(const FixedPointNumber &other) const noexcept
|
||||
{
|
||||
int64_t temp = this->m_fixed_point_state;
|
||||
temp *= other.m_fixed_point_state;
|
||||
|
||||
// rounding!
|
||||
if (!truncate_results)
|
||||
{
|
||||
temp = temp + ((temp & 1 << (FractionalBitSize - 1)) << 1);
|
||||
}
|
||||
temp >>= FractionalBitSize;
|
||||
FixedPointNumber tmp;
|
||||
tmp.m_fixed_point_state = static_cast<decltype(m_fixed_point_state)>(temp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
FixedPointNumber &operator*=(const FixedPointNumber &other) noexcept
|
||||
{
|
||||
int64_t temp = this->m_fixed_point_state;
|
||||
temp *= other.m_fixed_point_state;
|
||||
|
||||
// rounding!
|
||||
if (!truncate_results)
|
||||
{
|
||||
temp = temp + ((temp & 1 << (FractionalBitSize - 1)) << 1);
|
||||
}
|
||||
temp >>= FractionalBitSize;
|
||||
this->m_fixed_point_state = static_cast<decltype(m_fixed_point_state)>(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FixedPointNumber operator/(const FixedPointNumber &other) const noexcept
|
||||
{
|
||||
int64_t temp = this->m_fixed_point_state;
|
||||
temp <<= FractionalBitSize;
|
||||
temp /= static_cast<int64_t>(other.m_fixed_point_state);
|
||||
FixedPointNumber tmp;
|
||||
tmp.m_fixed_point_state = static_cast<decltype(m_fixed_point_state)>(temp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
FixedPointNumber &operator/=(const FixedPointNumber &other) noexcept
|
||||
{
|
||||
int64_t temp = this->m_fixed_point_state;
|
||||
temp <<= FractionalBitSize;
|
||||
temp /= static_cast<int64_t>(other.m_fixed_point_state);
|
||||
FixedPointNumber tmp;
|
||||
this->m_fixed_point_state = static_cast<decltype(m_fixed_point_state)>(temp);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(4 == sizeof(FixedPointNumber<1>), "FP19 has wrong size != 4");
|
||||
}
|
||||
#endif // FIXED_POINT_NUMBER_HPP
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "hilbert_value.hpp"
|
||||
|
||||
#include <osrm/Coordinate.h>
|
||||
|
||||
uint64_t HilbertCode::operator()(const FixedPointCoordinate ¤t_coordinate) const
|
||||
{
|
||||
unsigned location[2];
|
||||
location[0] = current_coordinate.lat + static_cast<int>(90 * COORDINATE_PRECISION);
|
||||
location[1] = current_coordinate.lon + static_cast<int>(180 * COORDINATE_PRECISION);
|
||||
|
||||
TransposeCoordinate(location);
|
||||
return BitInterleaving(location[0], location[1]);
|
||||
}
|
||||
|
||||
uint64_t HilbertCode::BitInterleaving(const uint32_t latitude, const uint32_t longitude) const
|
||||
{
|
||||
uint64_t result = 0;
|
||||
for (int8_t index = 31; index >= 0; --index)
|
||||
{
|
||||
result |= (latitude >> index) & 1;
|
||||
result <<= 1;
|
||||
result |= (longitude >> index) & 1;
|
||||
if (0 != index)
|
||||
{
|
||||
result <<= 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void HilbertCode::TransposeCoordinate(uint32_t *X) const
|
||||
{
|
||||
uint32_t M = 1 << (32 - 1), P, Q, t;
|
||||
int i;
|
||||
// Inverse undo
|
||||
for (Q = M; Q > 1; Q >>= 1)
|
||||
{
|
||||
P = Q - 1;
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
|
||||
const bool condition = (X[i] & Q);
|
||||
if (condition)
|
||||
{
|
||||
X[0] ^= P; // invert
|
||||
}
|
||||
else
|
||||
{
|
||||
t = (X[0] ^ X[i]) & P;
|
||||
X[0] ^= t;
|
||||
X[i] ^= t;
|
||||
}
|
||||
} // exchange
|
||||
}
|
||||
// Gray encode
|
||||
for (i = 1; i < 2; ++i)
|
||||
{
|
||||
X[i] ^= X[i - 1];
|
||||
}
|
||||
t = 0;
|
||||
for (Q = M; Q > 1; Q >>= 1)
|
||||
{
|
||||
const bool condition = (X[2 - 1] & Q);
|
||||
if (condition)
|
||||
{
|
||||
t ^= Q - 1;
|
||||
}
|
||||
} // check if this for loop is wrong
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
X[i] ^= t;
|
||||
}
|
||||
}
|
||||
@@ -1,49 +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 HILBERT_VALUE_HPP
|
||||
#define HILBERT_VALUE_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// computes a 64 bit value that corresponds to the hilbert space filling curve
|
||||
|
||||
struct FixedPointCoordinate;
|
||||
|
||||
class HilbertCode
|
||||
{
|
||||
public:
|
||||
uint64_t operator()(const FixedPointCoordinate ¤t_coordinate) const;
|
||||
HilbertCode() {}
|
||||
HilbertCode(const HilbertCode &) = delete;
|
||||
|
||||
private:
|
||||
inline uint64_t BitInterleaving(const uint32_t a, const uint32_t b) const;
|
||||
inline void TransposeCoordinate(uint32_t *X) const;
|
||||
};
|
||||
|
||||
#endif /* HILBERT_VALUE_HPP */
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "import_edge.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
bool NodeBasedEdge::operator<(const NodeBasedEdge &other) const
|
||||
{
|
||||
if (source == other.source)
|
||||
{
|
||||
if (target == other.target)
|
||||
{
|
||||
if (weight == other.weight)
|
||||
{
|
||||
return forward && backward && ((!other.forward) || (!other.backward));
|
||||
}
|
||||
return weight < other.weight;
|
||||
}
|
||||
return target < other.target;
|
||||
}
|
||||
return source < other.source;
|
||||
}
|
||||
|
||||
NodeBasedEdge::NodeBasedEdge(NodeID source,
|
||||
NodeID target,
|
||||
NodeID name_id,
|
||||
EdgeWeight weight,
|
||||
bool forward,
|
||||
bool backward,
|
||||
bool roundabout,
|
||||
bool in_tiny_cc,
|
||||
bool access_restricted,
|
||||
TravelMode travel_mode,
|
||||
bool is_split)
|
||||
: source(source), target(target), name_id(name_id), weight(weight),
|
||||
forward(forward), backward(backward), roundabout(roundabout), in_tiny_cc(in_tiny_cc),
|
||||
access_restricted(access_restricted), is_split(is_split), travel_mode(travel_mode)
|
||||
{
|
||||
}
|
||||
|
||||
bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const
|
||||
{
|
||||
if (source == other.source)
|
||||
{
|
||||
if (target == other.target)
|
||||
{
|
||||
if (weight == other.weight)
|
||||
{
|
||||
return forward && backward && ((!other.forward) || (!other.backward));
|
||||
}
|
||||
return weight < other.weight;
|
||||
}
|
||||
return target < other.target;
|
||||
}
|
||||
return source < other.source;
|
||||
}
|
||||
|
||||
template <class EdgeT>
|
||||
EdgeBasedEdge::EdgeBasedEdge(const EdgeT &other)
|
||||
: source(other.source), target(other.target), edge_id(other.data.via),
|
||||
weight(other.data.distance), forward(other.data.forward), backward(other.data.backward)
|
||||
{
|
||||
}
|
||||
|
||||
/** Default constructor. target and weight are set to 0.*/
|
||||
EdgeBasedEdge::EdgeBasedEdge()
|
||||
: source(0), target(0), edge_id(0), weight(0), forward(false), backward(false)
|
||||
{
|
||||
}
|
||||
|
||||
EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
|
||||
const NodeID target,
|
||||
const NodeID edge_id,
|
||||
const EdgeWeight weight,
|
||||
const bool forward,
|
||||
const bool backward)
|
||||
: source(source), target(target), edge_id(edge_id), weight(weight), forward(forward),
|
||||
backward(backward)
|
||||
{
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user