Compare commits
1884 Commits
v4.9.1
...
v5.6.0-rc.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 57d93fc5dc | |||
| 3aba2bc2d0 | |||
| c42478f0ee | |||
| ea583a77ff | |||
| dd999e112e | |||
| 69c54bef72 | |||
| cfee0f1109 | |||
| c7ce758e1c | |||
| 3ac4fb5933 | |||
| 2afe5e971b | |||
| 519b744502 | |||
| d3c2ac671f | |||
| 07a1a907f8 | |||
| 062cae82a0 | |||
| 316c7781a3 | |||
| e11bcfece5 | |||
| cb8dee3e60 | |||
| a1abe71d9f | |||
| d54c837e51 | |||
| 106d17541d | |||
| ad29b237e3 | |||
| febefb4684 | |||
| d28713b845 | |||
| 2e6428e917 | |||
| 1f3a8d4538 | |||
| 140f1ad923 | |||
| 1c25070572 | |||
| 24fe881d03 | |||
| 25ab51f4f0 | |||
| 46f96af360 | |||
| ce685da92c | |||
| 2218658969 | |||
| 3e2db47cc8 | |||
| 28a8154cee | |||
| 005124fe1c | |||
| 1e4c8eeeb6 | |||
| 72455a2733 | |||
| 112cf55aae | |||
| aa3f208032 | |||
| 919386bdaf | |||
| ae835cc04f | |||
| ef4d32a492 | |||
| 2a5ebf84bc | |||
| 768dc8d817 | |||
| 0c04c6cafb | |||
| bf690df97a | |||
| 880b982eeb | |||
| 53011755a2 | |||
| ddb60c34e6 | |||
| 543f0e5e44 | |||
| 1e9e420d91 | |||
| c885d03830 | |||
| ab91a05680 | |||
| 84261fd214 | |||
| 734df348cb | |||
| 41064e2d7b | |||
| 8d7aae8687 | |||
| 7256b6d0d4 | |||
| 3106b5dd9e | |||
| f1427a834d | |||
| 04954de9c6 | |||
| a6cd0863bc | |||
| 9f28873cb1 | |||
| 10c5d76909 | |||
| d81ef3f4db | |||
| 3abab16bf3 | |||
| 6e1c4bfecd | |||
| cedeb15ade | |||
| f2663acfc6 | |||
| c48fc58eb2 | |||
| 5f1c7efd41 | |||
| 9e5d45d86a | |||
| 5fd6355829 | |||
| 6da4d918d0 | |||
| 1628ebb871 | |||
| eaed5c7a8e | |||
| 9d2628b74f | |||
| 11ee632cfe | |||
| 97c0a74c04 | |||
| b3ef27d104 | |||
| c22ce3ae1f | |||
| 36c944ef53 | |||
| 5b24758742 | |||
| a572719484 | |||
| ad594cb2e4 | |||
| 6b143c5e1d | |||
| 25baf51a2c | |||
| c059d15cb9 | |||
| 279f8aabfb | |||
| e463733138 | |||
| 7deff5837c | |||
| 46ac9d05d9 | |||
| c7640903c3 | |||
| 445225bf6d | |||
| 47b1a56b12 | |||
| b5e289adc3 | |||
| e0a1a43449 | |||
| 337ecefa45 | |||
| 7961fa8863 | |||
| 88eb9e5499 | |||
| df449d3b5c | |||
| d8c54fb815 | |||
| 6f27aae022 | |||
| 5c93609142 | |||
| c277b95f03 | |||
| b1f1c26703 | |||
| a5d0707dd0 | |||
| d129b0ef24 | |||
| f2c3b9859e | |||
| bb1f4a025a | |||
| 8c36012653 | |||
| 66cb75f4a3 | |||
| 0c6dee4bef | |||
| 49d3467ec7 | |||
| a48cf58468 | |||
| fbc7189cf8 | |||
| e8167b2e4e | |||
| c03aa8a273 | |||
| a40abacfca | |||
| b8beac2d00 | |||
| 75e0b5a5c4 | |||
| c03b230e84 | |||
| 6b06c5bd32 | |||
| 226ee62981 | |||
| fce3bb180c | |||
| 1ae69fe40d | |||
| e4dc2aa45c | |||
| d0f1347ff1 | |||
| 70e899378d | |||
| dbd70d4884 | |||
| 71044e88f3 | |||
| b8f631f6f6 | |||
| 3837f9d015 | |||
| 763ad0d047 | |||
| b6f9ec2a33 | |||
| 5d3a348b76 | |||
| 104e23abf3 | |||
| a7bb26f2d6 | |||
| 710ba20acc | |||
| fce8d72895 | |||
| 774b8688ca | |||
| fe2beb6f68 | |||
| 71e7d6d6b8 | |||
| 29f736f1c8 | |||
| bb4f13a47c | |||
| bb0b03bbce | |||
| 59ad7dddb2 | |||
| f12fdeb23e | |||
| f896aaf881 | |||
| a2a2cf84d1 | |||
| 4e897aad50 | |||
| 5e8bdbfa0c | |||
| fd57c5b48b | |||
| 1d4d3b80b5 | |||
| f82740ed93 | |||
| c1f833c80f | |||
| 813e16b9b4 | |||
| 06ef3053de | |||
| 9fa7e6c74f | |||
| a7d63283ab | |||
| 78a443bfb2 | |||
| 84b8d3cfb9 | |||
| b3483f95a7 | |||
| 32f63e5e0c | |||
| 185e9dc7f3 | |||
| 6794f52cb2 | |||
| 06e6b9ea6f | |||
| 93d89ad686 | |||
| 7c8176b077 | |||
| 7ef95e9918 | |||
| f313cb9913 | |||
| 15c8fd326f | |||
| f7e8581a1b | |||
| c01ea2ea3e | |||
| 1153b78c06 | |||
| b5d5f309a3 | |||
| 5100f2cc7b | |||
| f6fef5c166 | |||
| 559c88b36d | |||
| 7dea7476f1 | |||
| dc81f581a0 | |||
| 300283d572 | |||
| aad2124faa | |||
| aced058c4a | |||
| 24ab71a346 | |||
| 2640a319c1 | |||
| e6ff17ab2a | |||
| f7ad2e1e26 | |||
| 2ed6b181c8 | |||
| f48bbb78de | |||
| bd2a5ebe10 | |||
| f8499957fa | |||
| 5db134bbba | |||
| 8645d8c7fc | |||
| b8e13d9b1b | |||
| 421caa1856 | |||
| ed9d10e96c | |||
| 0f3a463854 | |||
| b9b52cb857 | |||
| 9af67c5a9f | |||
| 8ffe915395 | |||
| b376c97db8 | |||
| 7b11cd3a11 | |||
| 76de3b6ace | |||
| bc081b7132 | |||
| 3cbac0f012 | |||
| f40b34af9d | |||
| cc14fb8bff | |||
| c5e3fa916f | |||
| dff7fe214b | |||
| 3b2ca720a8 | |||
| df4231341f | |||
| 0a2f934c87 | |||
| 3721f8c887 | |||
| 1ba5ff44cc | |||
| 5ecd2e4c67 | |||
| b1f6797aab | |||
| f04d146ca3 | |||
| 8c50a42ec4 | |||
| c4b3cdfd80 | |||
| 37051e1583 | |||
| d3ef993d5f | |||
| 9832825abd | |||
| d584bcad11 | |||
| e48ca65af4 | |||
| f429e08851 | |||
| de062d4ca3 | |||
| d83ab9d905 | |||
| 4618b502ac | |||
| 94854b5c90 | |||
| f8dd965435 | |||
| 6e29f9889b | |||
| 48d4e91d98 | |||
| 708ac04562 | |||
| 38b2ad298d | |||
| a51ef67db8 | |||
| 67ce19cb14 | |||
| 1b51163b1d | |||
| 84b618ed1a | |||
| dc8e6bd8d9 | |||
| 68e38880df | |||
| d5904d5756 | |||
| 0f59b78c02 | |||
| 6e7fe5feb0 | |||
| 3dfbf42e61 | |||
| f88f51fd98 | |||
| 98659fb0a0 | |||
| 8a1afe456f | |||
| f1384f5e44 | |||
| 1cd5394a16 | |||
| 8c7f744b1a | |||
| 896445a337 | |||
| 8c21e1267e | |||
| ad3fd46da5 | |||
| 62f0e11bfa | |||
| 03d653c0bb | |||
| cbfb055f81 | |||
| 2288704bb5 | |||
| 97dcf4eef9 | |||
| 17e15033e1 | |||
| 875f482203 | |||
| df3c39cef5 | |||
| a28a20a1ba | |||
| 17a18b5c7c | |||
| 423c083038 | |||
| 468d8c0031 | |||
| 6f4c6e84ae | |||
| 4b1aae40af | |||
| 0e6863aec1 | |||
| 949d505783 | |||
| d11927046f | |||
| 9461c83511 | |||
| 532cbfce13 | |||
| 0fbd18b0dd | |||
| 3f07a830e6 | |||
| 24b01fae00 | |||
| 0817cd6dfd | |||
| 9d8b92f418 | |||
| 928a6f0c7d | |||
| 29b3caf529 | |||
| 20c8ac0272 | |||
| c99c8bccbc | |||
| 735191255d | |||
| da6ca640a7 | |||
| f6f7a9290f | |||
| 9687a9325c | |||
| 43566bfd14 | |||
| 110e6c3689 | |||
| 561b7cc58e | |||
| 5775679f64 | |||
| 560d8ffec0 | |||
| 2544c3f20e | |||
| 5a311012af | |||
| ef087f963d | |||
| a1127c3e09 | |||
| 01a57ff1d8 | |||
| 37824e2954 | |||
| 4489c8dfc2 | |||
| ee63e39ff5 | |||
| ce5bcc797b | |||
| fe5cc55b0e | |||
| 12d58ace10 | |||
| 4636aaabfe | |||
| 186cc8340a | |||
| e343f71541 | |||
| 0df0d31d83 | |||
| aaf42a1caf | |||
| d02dd67e95 | |||
| a49bd70985 | |||
| b2c27fbd25 | |||
| 9fe0e91d92 | |||
| 08b7270f5c | |||
| fc52dd85fe | |||
| 6d961d4a15 | |||
| 0bd08224bf | |||
| 2a383efbf6 | |||
| b84d70d305 | |||
| 3bade8625f | |||
| 844300b95a | |||
| dd811539a3 | |||
| 79c2ae46d8 | |||
| d023e7c581 | |||
| 4ccb08983f | |||
| 8c941d1344 | |||
| 841c032a0d | |||
| a764fd1f29 | |||
| 3687864cc1 | |||
| 4b5466629f | |||
| f19bf70b55 | |||
| 24fa94af59 | |||
| 95a584a30d | |||
| 6ba36a2bc7 | |||
| 039989a339 | |||
| a7559077a0 | |||
| bbe80192aa | |||
| 9b16b757a4 | |||
| 3680fc9d90 | |||
| 836e8bdff0 | |||
| 3d4b39be7d | |||
| 193dfd9d8b | |||
| 305e813489 | |||
| a5756fc764 | |||
| f5bf788814 | |||
| 00f7d7776d | |||
| dce685c780 | |||
| 173a39fd8b | |||
| 5d564ee510 | |||
| 24c2708d1e | |||
| d87a972c66 | |||
| f90736b6b3 | |||
| 9aeb3086cb | |||
| 9e361a8178 | |||
| c3aeef4e09 | |||
| 50090e6447 | |||
| b9e5d26e3a | |||
| 184cfab33b | |||
| fd95b2da76 | |||
| ce04a608b8 | |||
| cff69178e8 | |||
| 6c682b2258 | |||
| c1087eaecc | |||
| 8bb183bc8c | |||
| 15359befdc | |||
| 2c9e18d5a9 | |||
| 4f81e31d63 | |||
| b73c59088c | |||
| 44e4728bde | |||
| ba2629456f | |||
| 1b4779a58c | |||
| 1eaf9f3269 | |||
| 73e365d398 | |||
| d5bf508046 | |||
| 47b097038a | |||
| a4264c7849 | |||
| 463228d0bf | |||
| 6f885b5bdb | |||
| 1dde5d288d | |||
| 820feb3a04 | |||
| 46b00e1378 | |||
| eb12c16fd6 | |||
| 17c32f5ce7 | |||
| 53ef2e2955 | |||
| 7b1131b982 | |||
| 1fc969e6c8 | |||
| 49f960064c | |||
| 83a9d0590d | |||
| d8b016b92a | |||
| 608044305d | |||
| 4760b85930 | |||
| 9e2782d923 | |||
| 2dfeb0cabc | |||
| 2f9b5788d0 | |||
| be496eb4e3 | |||
| 97244557b1 | |||
| e2e5eb0169 | |||
| 6949d7ee5b | |||
| 02303904b8 | |||
| 4ad6d88888 | |||
| e226b52f21 | |||
| b1125b7f1f | |||
| 33ff92d27e | |||
| de4fd76d57 | |||
| bf6df74d44 | |||
| 8f6dd805e5 | |||
| 3235f30a98 | |||
| 7e4020c010 | |||
| 538bbd47d1 | |||
| 78583d2c8c | |||
| fa1a0a1325 | |||
| 6df1437cfc | |||
| 15ed53d4a7 | |||
| 63be191775 | |||
| 6ec505281e | |||
| 5a293e891b | |||
| b57169e221 | |||
| 045d25041f | |||
| 170923874b | |||
| 8137e95fbb | |||
| 0375af197d | |||
| babbda98a6 | |||
| 72bfbed1f1 | |||
| feeae05f1c | |||
| f88ac989ea | |||
| 41f083cded | |||
| 12ded539aa | |||
| 827a1fbd7a | |||
| e84a0ea37c | |||
| 88208bfa5d | |||
| 7073403f1b | |||
| 2501882adb | |||
| 4f2bb19b0f | |||
| de77befb23 | |||
| a5db3d72f1 | |||
| b8898ef410 | |||
| d0543e6c3b | |||
| cef53c4b56 | |||
| 481b03baeb | |||
| f96e61ee06 | |||
| d21c8e3800 | |||
| af7960a796 | |||
| 4c6d6aeaa7 | |||
| ef2261661c | |||
| 9c11f4231c | |||
| 837ab105ad | |||
| 6ac9617d49 | |||
| ccdebccde1 | |||
| c1651ccb12 | |||
| f33180f092 | |||
| 1b03b8df6d | |||
| 3eeb3cb6c6 | |||
| 3e18e31bc9 | |||
| 2fb40944bf | |||
| b108d8ea21 | |||
| 79917d2c8e | |||
| d2cd4fac2d | |||
| cd03877c90 | |||
| 388d84a89e | |||
| 9d24a4422a | |||
| 9693f9269b | |||
| 08a5648e3e | |||
| ccf5552406 | |||
| b749d9bd2f | |||
| d342a18324 | |||
| 8f00936790 | |||
| 8a3aec301a | |||
| faa5185440 | |||
| 4ba8ccfcce | |||
| c30f43b148 | |||
| 5da63998d6 | |||
| 6fc0609a62 | |||
| f02b7b0910 | |||
| 9435254661 | |||
| de14a72931 | |||
| 164f4ffc32 | |||
| b5c77de923 | |||
| 6067fdf27f | |||
| a34a885031 | |||
| f39eb999e5 | |||
| 87d09f78e6 | |||
| 83b7d75121 | |||
| 4598599f52 | |||
| da77edfc83 | |||
| 2917122287 | |||
| a22e0fa62e | |||
| dc7e61c25d | |||
| 8dc667f20d | |||
| 8ff4bc09ac | |||
| 88c3f4c481 | |||
| 01a2c66472 | |||
| cf35bbeb50 | |||
| fe94977c9b | |||
| 69a60686dc | |||
| 7b97e1035f | |||
| c4f010e363 | |||
| 51ebadfc45 | |||
| ceddfada3d | |||
| a933b5d949 | |||
| ba5871cfa1 | |||
| e8b947bca6 | |||
| 7753845f5c | |||
| 19eec48207 | |||
| 293856981f | |||
| 86b70f2632 | |||
| 1905a0f473 | |||
| d05b85c227 | |||
| 19f00589de | |||
| 7f28a14c76 | |||
| fead71da54 | |||
| c26e90cac0 | |||
| d4e5710928 | |||
| 5c2783310a | |||
| b8795c7341 | |||
| 1d994da12b | |||
| 46994e87be | |||
| 40bfe89d97 | |||
| e3c2d4dddc | |||
| 502d9e10c2 | |||
| 865c6590fa | |||
| c30784895d | |||
| fa1fc810ea | |||
| 052b0e831d | |||
| 42271d99b2 | |||
| ecee13bffa | |||
| 5e167b8745 | |||
| 1f8ca2879f | |||
| 2d13116487 | |||
| 316ef305de | |||
| ab1a9271c8 | |||
| 18bc02f087 | |||
| 2a2abe9e0f | |||
| b7ee38eca7 | |||
| ae157d0b4f | |||
| 769485cc2f | |||
| 983ad3513a | |||
| ca914b8b1f | |||
| ca21b8833a | |||
| 3f0f0e306b | |||
| f77a2474ea | |||
| 8205c34abe | |||
| ee4fb89336 | |||
| 81c5cba0e5 | |||
| caa7c994a0 | |||
| 847f530c8e | |||
| c69545c47a | |||
| 1557ff81bc | |||
| ebac9f586b | |||
| 2512cf386d | |||
| da04563e26 | |||
| ceaf362326 | |||
| 9af00b1925 | |||
| f540485cb0 | |||
| 5617d3886d | |||
| 06d13b6954 | |||
| d0c142b9c7 | |||
| ef1f14550f | |||
| 5839bf334b | |||
| 46c936b48e | |||
| 8ed6bb8a1b | |||
| b72dc8c0cf | |||
| 72fa35da10 | |||
| 17eb664597 | |||
| 77931ffe24 | |||
| 45df2c991f | |||
| 615e302b8c | |||
| 1ed8e7e98c | |||
| ee012ae2da | |||
| 32dcce88f7 | |||
| a13cf3f2be | |||
| 6cf99c886f | |||
| 7cbb1807e7 | |||
| d47d03c15b | |||
| 240a7696da | |||
| 14b024e4dc | |||
| 339ebe8f81 | |||
| 9eb7fc03ce | |||
| 036475afd0 | |||
| 378322f6e3 | |||
| d964b81308 | |||
| 49a28b478c | |||
| a75e16e26b | |||
| 73179641b1 | |||
| 58316c608d | |||
| 1c2ead8fb8 | |||
| 66f2cc5184 | |||
| dbd108df8c | |||
| ff1ab217ba | |||
| 49a9d7f57a | |||
| da15c014f5 | |||
| 9a85a50586 | |||
| 94ca782816 | |||
| d17eacc52b | |||
| d86bba3e24 | |||
| 7f7b47611d | |||
| 2d4c128ea2 | |||
| 5d9fc83db4 | |||
| 879f7eb042 | |||
| 5b4e2950d9 | |||
| 050585bbd9 | |||
| 89007ae669 | |||
| b821a1dd98 | |||
| d1f1358e48 | |||
| 805d93912d | |||
| 0b7b16abc0 | |||
| 3dd7732ffc | |||
| c8eb2b2d11 | |||
| 14e7460465 | |||
| 6290aeea93 | |||
| 10b93c6908 | |||
| e4d0d49300 | |||
| cbb96ce7f4 | |||
| 54aaf574d9 | |||
| a824e64682 | |||
| df6186f0f1 | |||
| 78d530ddae | |||
| da15e1fc5e | |||
| 7e2663f2ad | |||
| 1a96483f7b | |||
| 3d5a53566c | |||
| eafe3fa928 | |||
| 6cfb1d6a85 | |||
| 0abd32fca3 | |||
| d1f555dcef | |||
| 6cfd1c92e1 | |||
| bbbbacb073 | |||
| e7b2f85a20 | |||
| 75de7c8eaf | |||
| 3f3c85ba72 | |||
| 89264eb89b | |||
| fa5714ab82 | |||
| 8aa93f32cc | |||
| 60010dd998 | |||
| 7ffe832ff8 | |||
| a63b10972b | |||
| 3eac6effbb | |||
| 7d124ce54d | |||
| 8522cddd61 | |||
| bf2b1a64b9 | |||
| 70ee624e5c | |||
| 3a49635eb7 | |||
| aa5f8dce23 | |||
| c186e51a08 | |||
| 861314256e | |||
| 38f5adbe5c | |||
| 092e77e89b | |||
| 64a72f574d | |||
| 1b4a52e99c | |||
| 1d94eb88f6 | |||
| b3c5a9c010 | |||
| e3c1b133bf | |||
| e6fe9d0d67 | |||
| 05c1fe7f46 | |||
| e3a38a6b0d | |||
| 2b9cf742c5 | |||
| a289e1cd96 | |||
| c306a59854 | |||
| dcc1b5ab2b | |||
| 938dff011f | |||
| 9123c93a90 | |||
| a551286a8f | |||
| 86fd04e556 | |||
| b6dbf81206 | |||
| af47252efe | |||
| 3b81b39998 | |||
| 802b93fa9a | |||
| 7899444135 | |||
| 1ab2b87cc0 | |||
| 97c66c6c82 | |||
| 733207d4a1 | |||
| a0ed70f0a2 | |||
| d3a6b5a77e | |||
| 7a523713c7 | |||
| f7265892ed | |||
| be266c7c2b | |||
| b1b41435b6 | |||
| 8f32a80778 | |||
| 5d79e0ac2f | |||
| 47a6cd5462 | |||
| 7528b27f99 | |||
| a4f9499305 | |||
| bb244e28bb | |||
| 6fac14dbd8 | |||
| 8b144f22c9 | |||
| 146eb3a20e | |||
| d8e444e620 | |||
| da9d63a384 | |||
| c5e85f3d6d | |||
| e05750547c | |||
| 315823cce1 | |||
| 6ff07f4e82 | |||
| 41b54cf25d | |||
| 5ee15ee339 | |||
| 01b0bce2d5 | |||
| cb57ccacef | |||
| 7e0d14b113 | |||
| d06eec5e42 | |||
| 9648821a79 | |||
| 21fb18fe5e | |||
| 6a2518c0df | |||
| 7886d06839 | |||
| 5a9eb6ef72 | |||
| b6c3d1d5bf | |||
| 9b2f6585fb | |||
| 46fd17a9ff | |||
| da73bae9c6 | |||
| 766e2713ab | |||
| 9957254a5a | |||
| 9f6859561c | |||
| 88573a66cd | |||
| 3ccbe9842c | |||
| 5971822f82 | |||
| cdf6baba1d | |||
| 4b7ddb6826 | |||
| 06b74c1f08 | |||
| 3a0eed2ee5 | |||
| 2557bdcf39 | |||
| 12d478784b | |||
| 38fef77d70 | |||
| e8bae78749 | |||
| e14bc30428 | |||
| 9485c97738 | |||
| 11aed6c93e | |||
| d53c267129 | |||
| 2f6de614c1 | |||
| 087080a6c3 | |||
| 41b22916f3 | |||
| 89f1071947 | |||
| 464de785cb | |||
| 8986777c58 | |||
| 65def1a9e2 | |||
| 176c2244ad | |||
| b161e10b73 | |||
| 5bef5dcb04 | |||
| 46a4c27582 | |||
| acc6da86de | |||
| 4d84bc0f01 | |||
| c737635a3b | |||
| b7eeafb183 | |||
| 677306eeee | |||
| 2284ebaacb | |||
| 6b4975b2e4 | |||
| 94c38d115a | |||
| b1e309b4eb | |||
| e8ce119972 | |||
| 8b7cd2931b | |||
| 8bee57b0b0 | |||
| 6bfe3a2d41 | |||
| 7f71f0ed12 | |||
| 583aaff286 | |||
| b24f5c7c1a | |||
| 026f71934b | |||
| 1353d55880 | |||
| b09f637d02 | |||
| 979f9cab20 | |||
| eb6083daf5 | |||
| c4718495a0 | |||
| 0d36d472c9 | |||
| 35422a0fb5 | |||
| d012b44b7f | |||
| eda6d9dc7c | |||
| 63c86198a3 | |||
| 33bdfe9cf9 | |||
| a87c5998a1 | |||
| c918a7957b | |||
| 61e6afdef0 | |||
| 95dc36e908 | |||
| 951a4dc112 | |||
| c09b9b4c99 | |||
| b0873e2aa4 | |||
| 2bdb8fce63 | |||
| d8a692740a | |||
| 14797c421e | |||
| 280b000f07 | |||
| fb4834458e | |||
| c7a1576100 | |||
| aebf6fa0b1 | |||
| f76e3d4522 | |||
| eaf42ba437 | |||
| e83905b783 | |||
| 0b868969be | |||
| b4710633b1 | |||
| 7d076e9344 | |||
| 71d64e8cd9 | |||
| 748fd3efa9 | |||
| 1fc63e1e72 | |||
| fd6bb5ec1f | |||
| 261dbf3edd | |||
| 9e323d2d42 | |||
| 1309dd2a0f | |||
| 9b737230d6 | |||
| ecbd709535 | |||
| 060ec99678 | |||
| 3601d1d262 | |||
| 41ba20ca9a | |||
| 57e3f173d3 | |||
| 92c298c7cf | |||
| b25011ee60 | |||
| 0e017a6ce5 | |||
| 2431e15ffa | |||
| 396add1e9d | |||
| 86241a2793 | |||
| ee47afbe17 | |||
| 8831ca2f32 | |||
| abde215bc3 | |||
| 130d5298fc | |||
| 50cbba1620 | |||
| 2cc293ad16 | |||
| 6ac65a922f | |||
| 3d80f989d0 | |||
| 4fcb5d28a4 | |||
| 3ebdacf369 | |||
| 2ddc00c21e | |||
| e76e39a398 | |||
| 04667f1ed8 | |||
| 2091c3443b | |||
| 2b466b2fb2 | |||
| e17b306265 | |||
| b00b15ab98 | |||
| f4db79fe9b | |||
| 0e4061f858 | |||
| 043a1446e1 | |||
| 49221995e8 | |||
| 247a7488b8 | |||
| 1806198971 | |||
| 375331b80c | |||
| 8fdbe965cc | |||
| dc77d02e8a | |||
| 6265b8fa77 | |||
| 311b348d09 | |||
| ec02cdc4cc | |||
| 5905708111 | |||
| 5d91b759d1 | |||
| ec0a1a4ab1 | |||
| efa29edf09 | |||
| 2a05b70dfc | |||
| 8693e68271 | |||
| d21a9a514d | |||
| e03d132823 | |||
| 61ba985bc9 | |||
| 4629a20fe4 | |||
| a28125ee9a | |||
| df877aca1b | |||
| 05dc415aba | |||
| 6dedd9cb72 | |||
| 256d39b572 | |||
| d186ae1863 | |||
| fddc19e98d | |||
| 2592cd2e58 | |||
| 93b6438cea | |||
| f6746d88b7 | |||
| 34ace4dd4b | |||
| 41d0f42ddf | |||
| 2868f702a5 | |||
| ec4dcee8bd | |||
| 8c378191df | |||
| b98431e8e6 | |||
| 3c8781855e | |||
| 27a94f3ca6 | |||
| 04e334e3e2 | |||
| 12d4832037 | |||
| 6e4f6fec91 | |||
| 57c9525e5c | |||
| 543e4fb57d | |||
| 3881ead8e5 | |||
| 911d1e81b6 | |||
| ae06300c17 | |||
| 26879ca91a | |||
| 306744e5cb | |||
| 3ca32898a1 | |||
| 532fda267f | |||
| 494845b160 | |||
| 0fc823041e | |||
| 71eae4137d | |||
| 47b19f209b | |||
| 2b5355edca | |||
| e9a0beb4e8 | |||
| 6bdfe68897 | |||
| cf2d2b6763 | |||
| 95cd44f34f | |||
| d330e60d40 | |||
| 99004bbec8 | |||
| bbcc728a07 | |||
| 033dc0a72d | |||
| 1c140a112a | |||
| 312e86eb58 | |||
| 1dfdb38d4a | |||
| dfafe7dc5f | |||
| 6ecc123d15 | |||
| 6f322d2140 | |||
| dfa762bccc | |||
| 87f00d2c4c | |||
| 6f94e0dfb8 | |||
| ad70759f91 | |||
| 27c4e8ddd0 | |||
| 805d74b6ae | |||
| 4ad78309e2 | |||
| b78207ddd8 | |||
| b6834da9a4 | |||
| 801cc72691 | |||
| e198709643 | |||
| ed8d5e0b0a | |||
| e8fb312703 | |||
| 058b8c3b31 | |||
| ae3ccb009e | |||
| 0c60a2aef8 | |||
| 44fdf86702 | |||
| 1659bbf7b1 | |||
| 46b58fba83 | |||
| 84da86ba4a | |||
| 6777127497 | |||
| a4ac07866a | |||
| 448f8377fb | |||
| c490752ca7 | |||
| 6edc565c01 | |||
| bb0c2754d3 | |||
| 58d6e8f4d0 | |||
| bdc66049a5 | |||
| 0a53775fb3 | |||
| 9cdc9008aa | |||
| bd707b0cfc | |||
| a85f39c140 | |||
| ef7b36da32 | |||
| 14fdf861ca | |||
| 7641b12b08 | |||
| e7159adf59 | |||
| 51f08f2994 | |||
| a03eac8e48 | |||
| 503137221d | |||
| fb9205bf81 | |||
| bfbb313088 | |||
| 25d3c4b843 | |||
| 371c06d66d | |||
| 3e5c978719 | |||
| 843f1a6356 | |||
| a5c5faa21d | |||
| 6a1e17c6fa | |||
| cd30f370b8 | |||
| 4ae8abe6a3 | |||
| 82bfd4ee40 | |||
| e08c4cff13 | |||
| 6e16eab6ec | |||
| 21c47514da | |||
| d6de2ca71c | |||
| 451a0d9090 | |||
| 262354f733 | |||
| 498370330d | |||
| 6865853776 | |||
| 1418c0dbbc | |||
| bbc79dd49f | |||
| 8036320d94 | |||
| c30f69d6e9 | |||
| 2e2f34f241 | |||
| cbbeef5c46 | |||
| 823ee54f22 | |||
| 3d03797e53 | |||
| 089e60fa1e | |||
| baf8e4784b | |||
| d53350b263 | |||
| 824afdceca | |||
| a8230e976f | |||
| 6af7e6866c | |||
| aaa27333ba | |||
| 797f2a196b | |||
| 51066ff18f | |||
| 4de64a92cb | |||
| a21fd2ea18 | |||
| 0df0b4305d | |||
| a5ed53e7aa | |||
| 0587c5f5c4 | |||
| 57dbb18c4c | |||
| 4d92f08424 | |||
| 254ee07942 | |||
| 0bf8bd2230 | |||
| b5225f07cb | |||
| abed7690d0 | |||
| f96174ddbe | |||
| e5b713841a | |||
| 3b1b12069f | |||
| 1635f7351d | |||
| ce5ae411c1 | |||
| d1bc32fb31 | |||
| f9f87f25d4 | |||
| 89aa6b7881 | |||
| edf9e0c1ed | |||
| c2e520ad9d | |||
| 7649187095 | |||
| fe39d0fd10 | |||
| 98b83b7208 | |||
| 57321979ae | |||
| e3ce0c5887 | |||
| 95af72c70c | |||
| 3b37769624 | |||
| d150df1c5c | |||
| a322e27e05 | |||
| 98fe0badbe | |||
| 44b841a25d | |||
| 9c8bf820de | |||
| 4d9aa65e78 | |||
| 0f3942558f | |||
| ba074b0116 | |||
| 6aa97048df | |||
| d9a5c79ea6 | |||
| 9d7714c714 | |||
| 8291be375a | |||
| 0a73737f69 | |||
| 2fd1b6c913 | |||
| ea38a1d880 | |||
| f576e13c51 | |||
| ee7bb8731a | |||
| da0c3ff394 | |||
| 6ae559b42b | |||
| 95ca6ebdaa | |||
| 0d6964d9c8 | |||
| ba386d4b2c | |||
| b5ffb51e18 | |||
| a9f674497a | |||
| 1e8a92ccb4 | |||
| b9178bb8c7 | |||
| 520b29d0d5 | |||
| fe397e6953 | |||
| dcb741d827 | |||
| 508c205d35 | |||
| d5294bb5d0 | |||
| 6ed9be31ca | |||
| 3bbd3a8a65 | |||
| 73a608895a | |||
| 96c73baeb3 | |||
| 73113f5eb8 | |||
| 7b74b86891 | |||
| 0903b8227f | |||
| fa525ad610 | |||
| 0f2bb5dde5 | |||
| 84dc1b6845 | |||
| 4ce1a37772 | |||
| 8dd4cc5c40 | |||
| 6aed145dae | |||
| d15cc77b0b | |||
| 24a75d37fb | |||
| 7e80dae59b | |||
| 7316c48e9f | |||
| c520c7a24a | |||
| 7564633045 | |||
| 7174c5d036 | |||
| ddd128ce0e | |||
| f5aa5c0769 | |||
| 2acde49f0f | |||
| 8849015bbf | |||
| 70cd7a94ec | |||
| 3984dea34b | |||
| b11b471aa4 | |||
| 63754df4d4 | |||
| e644424508 | |||
| 4f6eef3d16 | |||
| e2e8104864 | |||
| 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 | |||
| 8511256779 | |||
| 2557fb4f4d | |||
| 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 | |||
| b36145e3c4 | |||
| 1c1bfd7541 | |||
| 238e77d959 | |||
| e21eaa4b9e | |||
| 80b897d8cf | |||
| 1ed7bcfb2c | |||
| e20f92bbbb | |||
| 6e717bfd30 | |||
| 5d743bb0a3 | |||
| 42942bb1e0 | |||
| 9d12de9bce | |||
| 790520e335 | |||
| 4b0e1a4b19 | |||
| a877f8abf0 | |||
| 491b1d9c96 | |||
| 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 | |||
| 4d4a3d02ed |
+59
-23
@@ -2,53 +2,89 @@
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: true
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: true
|
||||
BreakBeforeBinaryOperators: false
|
||||
BreakBeforeBraces: Allman
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BinPackParameters: false
|
||||
ColumnLimit: 100
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
DerivePointerBinding: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^<'
|
||||
Priority: 3
|
||||
- Regex: '^"(osrm|util|engine|extract|contract)/'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IndentCaseLabels: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyExcessCharacter: 1000
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerBindsToType: false
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
Cpp11BracedListStyle: true
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
IndentWidth: 4
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
BreakBeforeBraces: Allman
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInAngles: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
ContinuationIndentWidth: 4
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
SpaceBeforeParens: ControlStatements
|
||||
...
|
||||
|
||||
|
||||
+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"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# Issue
|
||||
|
||||
What issue is this PR targeting? If there is no issue that addresses the problem, please open a corresponding issue and link it here.
|
||||
|
||||
## Tasklist
|
||||
- [ ] ADD OWN TASKS HERE
|
||||
- [ ] update relevant [Wiki pages](https://github.com/Project-OSRM/osrm-backend/wiki)
|
||||
- [ ] add regression / cucumber cases (see docs/testing.md)
|
||||
- [ ] review
|
||||
- [ ] adjust for comments
|
||||
|
||||
## Requirements / Relations
|
||||
Link any requirements here. Other pull requests this PR is based on?
|
||||
+19
@@ -1,3 +1,8 @@
|
||||
# mason #
|
||||
#########
|
||||
/.mason
|
||||
/mason_packages
|
||||
|
||||
# pre compiled dependencies #
|
||||
#############################
|
||||
osrm-deps
|
||||
@@ -40,6 +45,8 @@ Thumbs.db
|
||||
# build related files #
|
||||
#######################
|
||||
/build/
|
||||
/example/build/
|
||||
/test/data/monaco*
|
||||
/cmake/postinst
|
||||
|
||||
# Eclipse related files #
|
||||
@@ -73,8 +80,20 @@ 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
|
||||
|
||||
# local lua debugging file
|
||||
debug.lua
|
||||
+163
-106
@@ -1,4 +1,9 @@
|
||||
language: cpp
|
||||
|
||||
git:
|
||||
depth: 10
|
||||
|
||||
# sudo:required is needed for trusty images
|
||||
sudo: required
|
||||
dist: trusty
|
||||
|
||||
@@ -8,139 +13,191 @@ notifications:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- "5.6"
|
||||
|
||||
cache:
|
||||
ccache: true
|
||||
apt: true
|
||||
directories:
|
||||
- test/cache
|
||||
|
||||
env:
|
||||
global:
|
||||
- CCACHE_TEMPDIR=/tmp/.ccache-temp
|
||||
- CCACHE_COMPRESS=1
|
||||
- CASHER_TIME_OUT=599 # one second less than 10m to avoid 10m timeout error: https://github.com/Project-OSRM/osrm-backend/issues/2742
|
||||
- CCACHE_VERSION=3.3.1
|
||||
- CMAKE_VERSION=3.6.2
|
||||
- MASON="$(pwd)/third_party/mason/mason"
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
# We override the compiler names here to yield better ccache behavior, which uses this as key
|
||||
include:
|
||||
|
||||
# 1/ Linux Clang Builds
|
||||
# Debug Builds
|
||||
- os: linux
|
||||
compiler: "gcc-6-debug"
|
||||
addons: &gcc6
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', '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-6' CXXCOMPILER='g++-6' BUILD_TYPE='Debug' TARGET_ARCH='x86_64-asan' ENABLE_COVERAGE=ON ENABLE_SANITIZER=ON BUILD_COMPONENTS=ON
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
compiler: "clang-3.9-debug"
|
||||
addons: &clang38
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'rubygems-integration', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Release'
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-5-dev', '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: CLANG_VERSION='3.9.1' BUILD_TYPE='Debug' BUILD_COMPONENTS=ON CUCUMBER_TIMEOUT=60000
|
||||
|
||||
- os: osx
|
||||
osx_image: xcode8.2
|
||||
compiler: "mason-osx-release"
|
||||
# we use the xcode provides clang and don't install our own
|
||||
env: ENABLE_MASON=ON BUILD_TYPE='Release' CUCUMBER_TIMEOUT=60000 CCOMPILER='clang' CXXCOMPILER='clang++' ENABLE_ASSERTIONS=ON
|
||||
|
||||
# Release Builds
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: &clang38
|
||||
apt:
|
||||
sources: ['llvm-toolchain-precise', 'ubuntu-toolchain-r-test']
|
||||
packages: ['clang-3.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'rubygems-integration', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
- os: linux
|
||||
compiler: clang
|
||||
addons: *clang38
|
||||
env: COMPILER='clang++-3.8' BUILD_TYPE='Debug'
|
||||
|
||||
|
||||
# 2/ Linux GCC Builds
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: &gcc48
|
||||
compiler: "mason-linux-release"
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.8', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'rubygems-integration', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
|
||||
env: COMPILER='g++-4.8' BUILD_TYPE='Release'
|
||||
packages: ['libstdc++-5-dev']
|
||||
env: CLANG_VERSION='3.9.1' BUILD_TYPE='Release' ENABLE_MASON=ON RUN_CLANG_FORMAT=ON
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc48
|
||||
env: COMPILER='g++-4.8' BUILD_TYPE='Debug'
|
||||
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: &gcc5
|
||||
compiler: "gcc-6-release"
|
||||
addons: &gcc6
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-5', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'rubygems-integration', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
|
||||
env: COMPILER='g++-5' BUILD_TYPE='Release'
|
||||
packages: ['g++-6', '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-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' BUILD_COMPONENTS=ON
|
||||
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: &gcc5
|
||||
compiler: "gcc-6-release-i686"
|
||||
env: >
|
||||
TARGET_ARCH='i686' CCOMPILER='gcc-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release'
|
||||
CFLAGS='-m32 -msse2 -mfpmath=sse' CXXFLAGS='-m32 -msse2 -mfpmath=sse' CHECK_HEADERS=yes
|
||||
|
||||
- os: linux
|
||||
compiler: "gcc-4.9-release"
|
||||
addons: &gcc49
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-5', 'libbz2-dev', 'libstxxl-dev', 'libstxxl1', 'libxml2-dev', 'libzip-dev', 'lua5.1', 'liblua5.1-0-dev', 'rubygems-integration', 'libtbb-dev', 'libgdal-dev', 'libluabind-dev', 'libboost-all-dev']
|
||||
env: COMPILER='g++-5' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
packages: ['g++-4.9', '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.9' CXXCOMPILER='g++-4.9' 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'
|
||||
|
||||
# Shared Library
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons: *gcc5
|
||||
env: COMPILER='g++-5' BUILD_TYPE='Debug'
|
||||
compiler: "gcc-6-release-shared"
|
||||
addons: &gcc6
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6', '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-6' CXXCOMPILER='g++-6' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON BUILD_COMPONENTS=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
|
||||
|
||||
# Disabled until tests all pass on OSX:
|
||||
#
|
||||
# 3/ OSX Clang Builds
|
||||
#- os: osx
|
||||
# osx_image: xcode6.4
|
||||
# compiler: clang
|
||||
# env: COMPILER='clang++' BUILD_TYPE='Debug'
|
||||
|
||||
#- os: osx
|
||||
# osx_image: xcode6.4
|
||||
# compiler: clang
|
||||
# env: COMPILER='clang++' BUILD_TYPE='Release'
|
||||
|
||||
#- os: osx
|
||||
# osx_image: xcode6.4
|
||||
# compiler: clang
|
||||
# env: COMPILER='clang++' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
#- os: osx
|
||||
# osx_image: xcode7
|
||||
# compiler: clang
|
||||
# env: COMPILER='clang++' BUILD_TYPE='Debug'
|
||||
|
||||
#- os: osx
|
||||
# osx_image: xcode7
|
||||
# compiler: clang
|
||||
# env: COMPILER='clang++' BUILD_TYPE='Release'
|
||||
|
||||
#- os: osx
|
||||
# osx_image: xcode7
|
||||
# compiler: clang
|
||||
# env: COMPILER='clang++' BUILD_TYPE='Release' BUILD_SHARED_LIBS=ON
|
||||
|
||||
|
||||
install:
|
||||
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
|
||||
- mkdir -p ${DEPS_DIR} && cd ${DEPS_DIR}
|
||||
before_install:
|
||||
- if [[ ! -z $TARGET_ARCH ]] ; then source ./scripts/travis/before_install.$TARGET_ARCH.sh ; fi
|
||||
- |
|
||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||
CMAKE_URL="http://www.cmake.org/files/v3.3/cmake-3.3.2-Linux-x86_64.tar.gz"
|
||||
mkdir cmake && travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
|
||||
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
|
||||
|
||||
OSMOSIS_URL="http://bretth.dev.openstreetmap.org/osmosis-build/osmosis-latest.tgz"
|
||||
mkdir osmosis && travis_retry wget --quiet -O - ${OSMOSIS_URL} | tar -xz -C osmosis
|
||||
export PATH=${DEPS_DIR}/osmosis/bin:${PATH}
|
||||
|
||||
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||
brew install cmake boost libzip libstxxl libxml2 lua51 luabind tbb GDAL osmosis
|
||||
export JOBS=$((`nproc` + 1))
|
||||
fi
|
||||
- |
|
||||
if [ -n "${RUN_CLANG_FORMAT}" ]; then
|
||||
${MASON} install clang-format 3.8.1 && PATH=$(${MASON} prefix clang-format 3.8.1)/bin:${PATH} ./scripts/format.sh
|
||||
fi
|
||||
- |
|
||||
if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then
|
||||
export JOBS=$((`sysctl -n hw.ncpu` + 1))
|
||||
sudo mdutil -i off /
|
||||
fi
|
||||
- echo "Using ${JOBS} jobs"
|
||||
- source ./scripts/install_node.sh 4
|
||||
- npm install -g "npm@>=3" # Upgrade to npm >v2 to reduce size of downloaded dependencies
|
||||
- npm install
|
||||
- ${MASON} install ccache ${CCACHE_VERSION} && export PATH=$(${MASON} prefix ccache ${CCACHE_VERSION})/bin:${PATH}
|
||||
- ${MASON} install cmake ${CMAKE_VERSION} && export PATH=$(${MASON} prefix cmake ${CMAKE_VERSION})/bin:${PATH}
|
||||
- |
|
||||
if [[ ! -z ${CLANG_VERSION} ]]; then
|
||||
export CCOMPILER='clang'
|
||||
export CXXCOMPILER='clang++'
|
||||
${MASON} install clang++ ${CLANG_VERSION} && export PATH=$(${MASON} prefix clang++ ${CLANG_VERSION})/bin:${PATH}
|
||||
# we only enable lto for release builds
|
||||
# and therefore don't need to us ld.gold or llvm tools for linking
|
||||
# for debug builds
|
||||
if [[ ${BUILD_TYPE} == 'Release' ]]; then
|
||||
${MASON} install binutils 2.27 && export PATH=$(${MASON} prefix binutils 2.27)/bin:${PATH}
|
||||
fi
|
||||
fi
|
||||
- ccache --max-size=256M # limiting the cache's size to roughly the previous job's object sizes
|
||||
|
||||
before_script:
|
||||
- cd ${TRAVIS_BUILD_DIR}
|
||||
- rvm use 1.9.3
|
||||
- gem install bundler
|
||||
- bundle install
|
||||
- mkdir build && cd build
|
||||
- export CXX=${COMPILER}
|
||||
- export OSRM_PORT=5000 OSRM_TIMEOUT=60
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} -DBUILD_TOOLS=1
|
||||
install:
|
||||
- |
|
||||
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||
./scripts/check_taginfo.py taginfo.json profiles/car.lua
|
||||
fi
|
||||
- export OSRM_BUILD_DIR="$(pwd)/build-osrm"
|
||||
- mkdir ${OSRM_BUILD_DIR} && pushd ${OSRM_BUILD_DIR}
|
||||
- export CC=${CCOMPILER} CXX=${CXXCOMPILER}
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_MASON=${ENABLE_MASON:-OFF} -DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS:-OFF} -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} -DENABLE_COVERAGE=${ENABLE_COVERAGE:-OFF} -DENABLE_SANITIZER=${ENABLE_SANITIZER:-OFF} -DBUILD_TOOLS=ON -DBUILD_COMPONENTS=${BUILD_COMPONENTS:-OFF} -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
|
||||
- if [[ ${CHECK_HEADERS} == yes ]] ; then make check-headers ; fi
|
||||
- popd
|
||||
- mkdir example/build && pushd example/build
|
||||
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
|
||||
- make --jobs=${JOBS}
|
||||
- popd
|
||||
- npm run build-api-docs
|
||||
|
||||
script:
|
||||
- make --jobs=2
|
||||
- make tests --jobs=2
|
||||
- make benchmarks
|
||||
- ./algorithm-tests
|
||||
- ./datastructure-tests
|
||||
- ./util-tests
|
||||
- cd ..
|
||||
- cucumber -p verify
|
||||
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
|
||||
- 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 ${OSRM_BUILD_DIR}
|
||||
- ./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 "${ENABLE_COVERAGE}" ]; then
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
fi
|
||||
|
||||
+422
@@ -0,0 +1,422 @@
|
||||
# 5.6.0
|
||||
- Changes from 5.5
|
||||
- Bugfixes
|
||||
- Fix #3475 removed an invalid `exit` field from the `arrive` maneuver
|
||||
- Fix #3515 adjusted number of `nodes` in `annotation`
|
||||
- Fix #3605 Fixed a bug that could lead to turns at the end of the road to be suppressed
|
||||
- Fix #2844 handle up to 16777215 code units in OSM names
|
||||
- Infrastructure
|
||||
- Support building rpm packages.
|
||||
- Guidance
|
||||
- No longer emitting turns on ferries, if a ferry should use multiple docking locations
|
||||
- Profiles
|
||||
- Removed the `./profile.lua -> ./profiles/car.lua` symlink. Use specific profiles from the `profiles` directory.
|
||||
- `properties` object has a new `weight_name` field, default value is "duration"
|
||||
- `properties` object has a new `weight_precision` field that specifies a decimal precision of edge weights, default value 1
|
||||
- In `way_function` the filed `forward_rate` and `backward_rate` of `ExtractionWay` can now be set.
|
||||
They have the same interpretation for the way weight as `forward_speed` and `backward_speed` for the edge duration.
|
||||
The unit of rate is meters per weight unit, so higher values will be prefered during routing.
|
||||
- `turn_function` now does not return an integer but takes in a `ExtractionTurn` object and can modify the `weight` and `duration` fields
|
||||
- `segment_function` now takes in a `ExtractionSegment` object and can modify `weight` and `duration` fields
|
||||
- `properties.uturn_penalty` is deprecated. Set it in the `turn_function`. The turn type is exposed as `ExtractionTurn::direction_modifier`.
|
||||
- `properties.traffic_light_penalty` is deprecated. Traffic light penalties now need to be set over in the turn function.
|
||||
Each turn with a traffic light is marked with `ExtractionTurn::has_traffic_light = true`.
|
||||
- Renamed the helper file `profiles/lib/directional.lua` to `profiles/lib/tags.lua` since it now provides more general tags parsing utility functions.
|
||||
- The car and foot profiles now depend on the helper file `profiles/lib/handlers.lua`.
|
||||
- Infrastructure
|
||||
- Disabled link-time optimized (LTO) builds by default. Enable by passing `-DENABLE_LTO=ON` to `cmake` if you need the performance and know what you are doing.
|
||||
- Datafile versioning is now based on OSRM semver values, rather than source code checksums.
|
||||
Datafiles are compatible between patch levels, but incompatible between minor version or higher bumps.
|
||||
- libOSRM now creates an own watcher thread then used in shared memory mode to listen for data updates
|
||||
- Tools:
|
||||
- Added osrm-extract-conditionals tool for checking conditional values in OSM data
|
||||
- Trip Plugin
|
||||
- Added a new feature that finds the optimal route given a list of waypoints, a source and a destination. This does not return a roundtrip and instead returns a one way optimal route from the fixed source to the destination points.
|
||||
|
||||
# 5.5.1
|
||||
- Changes from 5.5.0
|
||||
- API:
|
||||
- Adds `generate_hints=true` (`true` by default) which lets user disable `Hint` generating in the response. Use if you don't need `Hint`s!
|
||||
- Bugfixes
|
||||
- Fix #3418 and ensure we only return bearings in the range 0-359 in API responses
|
||||
- Fixed a bug that could lead to emitting false instructions for staying on a roundabout
|
||||
|
||||
# 5.5.0
|
||||
- Changes from 5.4.0
|
||||
- API:
|
||||
- `osrm-datastore` now accepts the parameter `--max-wait` that specifies how long it waits before aquiring a shared memory lock by force
|
||||
- Shared memory now allows for multiple clients (multiple instances of libosrm on the same segment)
|
||||
- Polyline geometries can now be requested with precision 5 as well as with precision 6
|
||||
- Profiles
|
||||
- the car profile has been refactored into smaller functions
|
||||
- get_value_by_key() is now guaranteed never to return empty strings, nil is returned instead.
|
||||
- debug.lua was added to make it easier to test/develop profile code.
|
||||
- `car.lua` now depends on lib/set.lua and lib/sequence.lua
|
||||
- `restrictions` is now used for namespaced restrictions and restriction exceptions (e.g. `restriction:motorcar=` as well as `except=motorcar`)
|
||||
- replaced lhs/rhs profiles by using test defined profiles
|
||||
- Handle `oneway=alternating` (routed over with penalty) separately from `oneway=reversible` (not routed over due to time dependence)
|
||||
- Handle `destination:forward`, `destination:backward`, `destination:ref:forward`, `destination:ref:backward` tags
|
||||
- Properly handle destinations on `oneway=-1` roads
|
||||
- Guidance
|
||||
- Notifications are now exposed more prominently, announcing turns onto a ferry/pushing your bike more prominently
|
||||
- Improved turn angle calculation, detecting offsets due to lanes / minor variations due to inaccuracies
|
||||
- Corrected the bearings returned for intermediate steps - requires reprocessing
|
||||
- Improved turn locations for collapsed turns
|
||||
- Sliproad classification refinements: the situations we detect as Sliproads now resemble more closely the reality
|
||||
- Trip Plugin
|
||||
- changed internal behaviour to prefer the smallest lexicographic result over the largest one
|
||||
- Bugfixes
|
||||
- fixed a bug where polyline decoding on a defective polyline could end up in out-of-bound access on a vector
|
||||
- fixed compile errors in tile unit-test framework
|
||||
- fixed a bug that could result in inconsistent behaviour when collapsing instructions
|
||||
- fixed a bug that could result in crashes when leaving a ferry directly onto a motorway ramp
|
||||
- fixed a bug in the tile plugin that resulted in discovering invalid edges for connections
|
||||
- improved error messages when missing files during traffic updates (#3114)
|
||||
- For single coordinate geometries the GeoJSON `Point` encoding was broken. We now always emit `LineString`s even in the one-coordinate-case (backwards compatible) (#3425)
|
||||
- Debug Tiles
|
||||
- Added support for turn penalties
|
||||
- Internals
|
||||
- Internal/Shared memory datafacades now share common memory layout and data loading code
|
||||
- File reading now has much better error handling
|
||||
- Misc
|
||||
- Progress indicators now print newlines when stdout is not a TTY
|
||||
- Prettier API documentation now generated via `npm run build-api-docs` output `build/docs`
|
||||
|
||||
# 5.4.3
|
||||
- Changes from 5.4.2
|
||||
- Bugfixes
|
||||
- #3254 Fixed a bug that could end up hiding roundabout instructions
|
||||
- #3260 fixed a bug that provided the wrong location in the arrival instruction
|
||||
|
||||
# 5.4.2
|
||||
- Changes from 5.4.1
|
||||
- Bugfixes
|
||||
- #3032 Fixed a bug that could result in emitting `invalid` as an instruction type on sliproads with mode changes
|
||||
- #3085 Fixed an outdated assertion that could throw without a cause for concern
|
||||
- #3179 Fixed a bug that could trigger an assertion in TurnInstruciton generation
|
||||
|
||||
# 5.4.1
|
||||
- Changes from 5.4.0
|
||||
- Bugfixes
|
||||
- #3016: Fixes shared memory updates while queries are running
|
||||
|
||||
# 5.4.0
|
||||
- Changes from 5.3.0
|
||||
- Profiles
|
||||
- includes library guidance.lua that offers preliminary configuration on guidance.
|
||||
- added left_hand_driving flag in global profile properties
|
||||
- modified turn penalty function for car profile - better fit to real data
|
||||
- return `ref` and `name` as separate fields. Do no use ref or destination as fallback for name value
|
||||
- the default profile for car now ignores HOV only roads
|
||||
- Guidance
|
||||
- Handle Access tags for lanes, only considering valid lanes in lane-guidance (think car | car | bike | car)
|
||||
- Improved the detection of non-noticeable name-changes
|
||||
- Summaries have been improved to consider references as well
|
||||
- API:
|
||||
- `annotations=true` now returns the data source id for each segment as `datasources`
|
||||
- Reduced semantic of merge to refer only to merges from a lane onto a motorway-like road
|
||||
- new `ref` field in the `RouteStep` object. It contains the reference code or name of a way. Previously merged into the `name` property like `name (ref)` and are now separate fields.
|
||||
- Bugfixes
|
||||
- Fixed an issue that would result in segfaults for viaroutes with an invalid intermediate segment when u-turns were allowed at the via-location
|
||||
- Invalid only_* restrictions could result in loss of connectivity. As a fallback, we assume all turns allowed when the restriction is not valid
|
||||
- Fixed a bug that could result in an infinite loop when finding information about an upcoming intersection
|
||||
- Fixed a bug that led to not discovering if a road simply looses a considered prefix
|
||||
- BREAKING: Fixed a bug that could crash postprocessing of instructions on invalid roundabout taggings. This change requires reprocessing datasets with osrm-extract and osrm-contract
|
||||
- Fixed an issue that could emit `invalid` as instruction when ending on a sliproad after a traffic-light
|
||||
- Fixed an issue that would detect turning circles as sliproads
|
||||
- Fixed a bug where post-processing instructions (e.g. left + left -> uturn) could result in false pronunciations
|
||||
- Fixes a bug where a bearing range of zero would cause exhaustive graph traversals
|
||||
- Fixes a bug where certain looped geometries could cause an infinite loop during extraction
|
||||
- Fixed a bug where some roads could be falsly identified as sliproads
|
||||
- Fixed a bug where roundabout intersections could result in breaking assertions when immediately exited
|
||||
- Infrastructure:
|
||||
- Adds a feature to limit results in nearest service with a default of 100 in `osrm-routed`
|
||||
|
||||
# 5.3.0
|
||||
- Changes from 5.3.0-rc.3
|
||||
- Guidance
|
||||
- Only announce `use lane` on required turns (not using all lanes to go straight)
|
||||
- Moved `lanes` to the intersection objects. This is BREAKING in relation to other Release Candidates but not with respect to other releases.
|
||||
- Bugfixes
|
||||
- Fix BREAKING: bug that could result in failure to load 'osrm.icd' files. This breaks the dataformat
|
||||
- Fix: bug that results in segfaults when `use lane` instructions are suppressed
|
||||
|
||||
- Changes form 5.2.7
|
||||
- API
|
||||
- Introduces new `TurnType` in the form of `use lane`. The type indicates that you have to stick to a lane without turning
|
||||
- Introduces `lanes` to the `Intersection` object. The lane data contains both the markings at the intersection and a flag indicating if they can be chosen for the next turn
|
||||
- Removed unused `-s` from `osrm-datastore`
|
||||
- Guidance
|
||||
- Only announce `use lane` on required turns (not using all lanes to go straight)
|
||||
- Improved detection of obvious turns
|
||||
- Improved turn lane detection
|
||||
- Reduce the number of end-of-road instructions in obvious cases
|
||||
- Profile:
|
||||
- bicycle.lua: Surface speeds never increase the actual speed
|
||||
- Infrastructure
|
||||
- Add 32bit support
|
||||
- Add ARM NEON/VFP support
|
||||
- Fix Windows builds
|
||||
- Optimize speed file updates using mmap
|
||||
- Add option to disable LTO for older compilers
|
||||
- BREAKING: The new turn type changes the turn-type order. This breaks the **data format**.
|
||||
- BREAKING: Turn lane data introduces two new files (osrm.tld,osrm.tls). This breaks the fileformat for older versions.
|
||||
- Bugfixes:
|
||||
- Fix devide by zero on updating speed data using osrm-contract
|
||||
|
||||
# 5.3.0 RC3
|
||||
- Changes from 5.3.0-rc.2
|
||||
- Guidance
|
||||
- Improved detection of obvious turns
|
||||
- Improved turn lane detection
|
||||
- Bugfixes
|
||||
- Fix bug that didn't chose minimal weights on overlapping edges
|
||||
|
||||
# 5.3.0 RC2
|
||||
- Changes from 5.3.0-rc.1
|
||||
- Bugfixes
|
||||
- Fixes invalid checks in the lane-extraction part of the car profile
|
||||
|
||||
# 5.3.0 RC1
|
||||
- API
|
||||
- Introduces new `TurnType` in the form of `use lane`. The type indicates that you have to stick to a lane without turning
|
||||
- Introduces lanes to the route response. The lane data contains both the markings at the intersection and a flag indicating their involvement in the turn
|
||||
|
||||
- Infrastructure
|
||||
- BREAKING: The new turn type changes the turn-type order. This breaks the **data format**.
|
||||
- BREAKING: Turn lane data introduces two new files (osrm.tld,osrm.tls). This breaks the fileformat for older versions.
|
||||
|
||||
# 5.2.5
|
||||
- Bugfixes
|
||||
- Fixes a segfault caused by incorrect trimming logic for very short steps.
|
||||
|
||||
# 5.2.4
|
||||
- Bugfixes:
|
||||
- Fixed in issue that arised on roundabouts in combination with intermediate intersections and sliproads
|
||||
|
||||
# 5.2.3
|
||||
- Bugfixes:
|
||||
- Fixed an issue with name changes in roundabouts that could result in crashes
|
||||
|
||||
# 5.2.2
|
||||
Changes from 5.2.1
|
||||
- Bugfixes:
|
||||
- Buffer overrun in tile plugin response handling
|
||||
|
||||
# 5.2.1
|
||||
Changes from 5.2.0
|
||||
- Bugfixes:
|
||||
- Removed debug statement that was spamming the console
|
||||
|
||||
# 5.2.0
|
||||
Changes from 5.2.0 RC2
|
||||
- Bugfixes:
|
||||
- Fixed crash when loading shared memory caused by invalid OSM IDs segment size.
|
||||
- Various small instructions handling fixes
|
||||
|
||||
Changes from 5.1.0
|
||||
- API:
|
||||
- new parameter `annotations` for `route`, `trip` and `match` requests. Returns additional data about each
|
||||
coordinate along the selected/matched route line per `RouteLeg`:
|
||||
- duration of each segment
|
||||
- distance of each segment
|
||||
- OSM node ids of all segment endpoints
|
||||
- Introducing Intersections for Route Steps. This changes the API format in multiple ways.
|
||||
- `bearing_before`/`bearing_after` of `StepManeuver` are now deprecated and will be removed in the next major release
|
||||
- `location` of `StepManeuvers` is now deprecated and will be removed in the next major release
|
||||
- every `RouteStep` now has property `intersections` containing a list of `Intersection` objects.
|
||||
- Support for destination signs. New member `destinations` in `RouteStep`, based on `destination` and `destination:ref`
|
||||
- Support for name pronunciations. New member `pronunciation` in `RouteStep`, based on `name:pronunciation`
|
||||
|
||||
- Profile changes:
|
||||
- duration parser now accepts P[n]DT[n]H[n]M[n]S, P[n]W, PTHHMMSS and PTHH:MM:SS ISO8601 formats.
|
||||
- `result.destinations` allows you to set a way's destinations
|
||||
- `result.pronunciation` allows you to set way name pronunciations
|
||||
- `highway=motorway_link` no longer implies `oneway` as per the OSM Wiki
|
||||
|
||||
- Infrastructure:
|
||||
- BREAKING: Changed the on-disk encoding of the StaticRTree to reduce ramIndex file size. This breaks the **data format**
|
||||
- BREAKING: Intersection Classification adds a new file to the mix (osrm.icd). This breaks the fileformat for older versions.
|
||||
- Better support for osrm-routed binary upgrade on the fly [UNIX specific]:
|
||||
- Open sockets with SO_REUSEPORT to allow multiple osrm-routed processes serving requests from the same port.
|
||||
- Add SIGNAL_PARENT_WHEN_READY environment variable to enable osrm-routed signal its parent with USR1 when it's running and waiting for requests.
|
||||
- Disable http access logging via DISABLE_ACCESS_LOGGING environment variable.
|
||||
|
||||
- Guidance:
|
||||
- BREAKING: modifies the file format with new internal identifiers
|
||||
- improved detection of turning streets, not reporting new-name in wrong situations
|
||||
- improved handling of sliproads (emit turns instead of 'take the ramp')
|
||||
- improved collapsing of instructions. Some 'new name' instructions will be suppressed if they are without alternative and the segment is short
|
||||
|
||||
- Bugfixes
|
||||
- fixed broken summaries for very short routes
|
||||
|
||||
# 5.2.0 RC2
|
||||
Changes from 5.2.0 RC1
|
||||
|
||||
- Guidance:
|
||||
- improved handling of sliproads (emit turns instead of 'take the ramp')
|
||||
- improved collapsing of instructions. Some 'new name' instructions will be suppressed if they are without alternative and the segment is short
|
||||
- BREAKING: modifies the file format with new internal identifiers
|
||||
|
||||
- API:
|
||||
- paramater `annotate` was renamed to `annotations`.
|
||||
- `annotation` as accidentally placed in `Route` instead of `RouteLeg`
|
||||
- Support for destination signs. New member `destinations` in `RouteStep`, based on `destination` and `destination:ref`
|
||||
- Support for name pronunciations. New member `pronunciation` in `RouteStep`, based on `name:pronunciation`
|
||||
- Add `nodes` property to `annotation` in `RouteLeg` containing the ids of nodes covered by the route
|
||||
|
||||
- Profile changes:
|
||||
- `result.destinations` allows you to set a way's destinations
|
||||
- `result.pronunciation` allows you to set way name pronunciations
|
||||
- `highway=motorway_link` no longer implies `oneway` as per the OSM Wiki
|
||||
|
||||
- Infrastructure
|
||||
- BREAKING: Changed the on-disk encoding of the StaticRTree to reduce ramIndex file size. This breaks the **data format**
|
||||
|
||||
- Bugfixes
|
||||
- fixed broken summaries for very short routes
|
||||
|
||||
# 5.2.0 RC1
|
||||
Changes from 5.1.0
|
||||
|
||||
- API:
|
||||
- new parameter `annotate` for `route` and `match` requests. Returns additional data about each
|
||||
coordinate along the selected/matched route line.
|
||||
- Introducing Intersections for Route Steps. This changes the API format in multiple ways.
|
||||
- `bearing_before`/`bearing_after` of `StepManeuver` are now deprecated and will be removed in the next major release
|
||||
- `location` of `StepManeuvers` is now deprecated and will be removed in the next major release
|
||||
- every `RouteStep` now has property `intersections` containing a list of `Intersection` objects.
|
||||
|
||||
- Profile changes:
|
||||
- duration parser now accepts P[n]DT[n]H[n]M[n]S, P[n]W, PTHHMMSS and PTHH:MM:SS ISO8601 formats.
|
||||
|
||||
- Infrastructure:
|
||||
- Better support for osrm-routed binary upgrade on the fly [UNIX specific]:
|
||||
- Open sockets with SO_REUSEPORT to allow multiple osrm-routed processes serving requests from the same port.
|
||||
- Add SIGNAL_PARENT_WHEN_READY environment variable to enable osrm-routed signal its parent with USR1 when it's running and waiting for requests.
|
||||
- BREAKING: Intersection Classification adds a new file to the mix (osrm.icd). This breaks the fileformat for older versions.
|
||||
- Disable http access logging via DISABLE_ACCESS_LOGGING environment
|
||||
variable.
|
||||
|
||||
- Guidance:
|
||||
- improved detection of turning streets, not reporting new-name in wrong situations
|
||||
|
||||
# 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**
|
||||
- BREAKING: Changed the on-disk encoding of the StaticRTree for better performance. 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`
|
||||
+581
-257
@@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 2.8.8)
|
||||
cmake_minimum_required(VERSION 2.8.11)
|
||||
# we depend on 2.8.11 introducing target_include_directories
|
||||
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR AND NOT MSVC_IDE)
|
||||
message(FATAL_ERROR "In-source builds are not allowed.
|
||||
@@ -6,14 +7,76 @@ Please create a directory and run cmake from there, passing the path to this sou
|
||||
This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them.")
|
||||
endif()
|
||||
|
||||
# detect if this is included as subproject and if so expose
|
||||
# some variables to its parent scope
|
||||
get_directory_property(BUILD_AS_SUBPROJECT PARENT_DIRECTORY)
|
||||
if(BUILD_AS_SUBPROJECT)
|
||||
message(STATUS "Building libosrm as subproject.")
|
||||
endif()
|
||||
|
||||
option(ENABLE_MASON "Use mason for dependencies" OFF)
|
||||
option(ENABLE_CCACHE "Speed up incremental rebuilds via ccache" ON)
|
||||
option(BUILD_TOOLS "Build OSRM tools" OFF)
|
||||
option(BUILD_PACKAGE "Build OSRM package" OFF)
|
||||
option(ENABLE_ASSERTIONS "Use assertions in release mode" OFF)
|
||||
option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF)
|
||||
option(ENABLE_SANITIZER "Use memory sanitizer for Debug build" OFF)
|
||||
option(ENABLE_LTO "Use LTO if available" OFF)
|
||||
option(ENABLE_FUZZING "Fuzz testing using LLVM's libFuzzer" OFF)
|
||||
option(ENABLE_GOLD_LINKER "Use GNU gold linker if available" ON)
|
||||
|
||||
if(ENABLE_MASON)
|
||||
# versions in use
|
||||
set(MASON_BOOST_VERSION "1.63.0")
|
||||
set(MASON_STXXL_VERSION "1.4.1")
|
||||
set(MASON_EXPAT_VERSION "2.2.0")
|
||||
set(MASON_LUA_VERSION "5.2.4")
|
||||
set(MASON_BZIP2_VERSION "1.0.6")
|
||||
set(MASON_TBB_VERSION "2017_20161128")
|
||||
|
||||
message(STATUS "Enabling mason")
|
||||
|
||||
find_program(CURL_FOUND curl)
|
||||
if(NOT CURL_FOUND)
|
||||
message(FATAL_ERROR "curl command required with -DENABLE_MASON")
|
||||
endif()
|
||||
|
||||
set(MASON_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/third_party/mason/mason)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/third_party/mason/mason.cmake)
|
||||
endif()
|
||||
|
||||
# be compatible with version handling before cmake 3.x
|
||||
if (POLICY CMP0048)
|
||||
cmake_policy(SET CMP0048 OLD)
|
||||
endif()
|
||||
project(OSRM C CXX)
|
||||
set(OSRM_VERSION_MAJOR 4)
|
||||
set(OSRM_VERSION_MINOR 9)
|
||||
set(OSRM_VERSION_MAJOR 5)
|
||||
set(OSRM_VERSION_MINOR 5)
|
||||
set(OSRM_VERSION_PATCH 0)
|
||||
set(OSRM_VERSION "${OSRM_VERSION_MAJOR}.${OSRM_VERSION_MINOR}.${OSRM_VERSION_PATCH}")
|
||||
|
||||
add_definitions(-DOSRM_PROJECT_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
# these two functions build up custom variables:
|
||||
# DEPENDENCIES_INCLUDE_DIRS and OSRM_DEFINES
|
||||
# These variables we want to pass to
|
||||
# include_directories and add_definitions for both
|
||||
# this build and for sharing externally via pkg-config
|
||||
|
||||
function(add_dependency_includes includes)
|
||||
list(APPEND DEPENDENCIES_INCLUDE_DIRS "${includes}")
|
||||
set(DEPENDENCIES_INCLUDE_DIRS "${DEPENDENCIES_INCLUDE_DIRS}" PARENT_SCOPE)
|
||||
endfunction(add_dependency_includes)
|
||||
|
||||
function(add_dependency_defines defines)
|
||||
list(APPEND OSRM_DEFINES "${defines}")
|
||||
set(OSRM_DEFINES "${OSRM_DEFINES}" PARENT_SCOPE)
|
||||
endfunction(add_dependency_defines)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
@@ -22,120 +85,123 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(bitness 64)
|
||||
message(STATUS "Building on a 64 bit system")
|
||||
else()
|
||||
message(WARNING "Building on a 32 bit system is unsupported")
|
||||
message(STATUS "Building on a 32 bit system")
|
||||
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(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF)
|
||||
option(DEBUG_GEOMETRY "Enables an option to dump GeoJSON of the final routing graph" OFF)
|
||||
option(BUILD_TOOLS "Build OSRM tools" OFF)
|
||||
# Strictly require GCC>=4.9 and Clang>=3.4 - GCC 4.8 is already too old for C++14.
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
|
||||
message(FATAL_ERROR "GCC>=4.9 required. In case you are on Ubuntu upgrade via ppa:ubuntu-toolchain-r/test")
|
||||
endif()
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
|
||||
message(FATAL_ERROR "Clang>=3.4 required. In case you are on Ubuntu upgrade via http://apt.llvm.org")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
||||
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/)
|
||||
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include/)
|
||||
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/sol2/)
|
||||
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/variant/include)
|
||||
|
||||
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(tests DEPENDS datastructure-tests algorithm-tests util-tests)
|
||||
add_custom_target(benchmarks DEPENDS rtree-bench)
|
||||
|
||||
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread unit_test_framework)
|
||||
set(BOOST_COMPONENTS date_time chrono filesystem iostreams program_options regex system thread unit_test_framework)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/util/version.hpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/util/version.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include/util/version.hpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/util/version.hpp
|
||||
)
|
||||
file(GLOB ExtractorGlob extractor/*.cpp data_structures/hilbert_value.cpp)
|
||||
file(GLOB ImporterGlob data_structures/import_edge.cpp data_structures/external_memory_node.cpp data_structures/raster_source.cpp)
|
||||
add_library(IMPORT OBJECT ${ImporterGlob})
|
||||
add_library(LOGGER OBJECT util/simple_logger.cpp)
|
||||
add_library(PHANTOMNODE OBJECT data_structures/phantom_node.cpp)
|
||||
add_library(RASTERSOURCE OBJECT data_structures/raster_source.cpp)
|
||||
add_library(EXCEPTION OBJECT util/osrm_exception.cpp)
|
||||
add_library(MERCATOR OBJECT util/mercator.cpp)
|
||||
add_library(ANGLE OBJECT util/compute_angle.cpp)
|
||||
file(GLOB UtilGlob src/util/*.cpp 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:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR> $<TARGET_OBJECTS:COMPRESSEDEDGE> $<TARGET_OBJECTS:GRAPHCOMPRESSOR> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:ANGLE>)
|
||||
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})
|
||||
|
||||
add_library(RESTRICTION OBJECT data_structures/restriction_map.cpp)
|
||||
add_library(COMPRESSEDEDGE OBJECT data_structures/compressed_edge_container.cpp)
|
||||
add_library(GRAPHCOMPRESSOR OBJECT algorithms/graph_compressor.cpp)
|
||||
set_target_properties(UTIL PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
||||
file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp {RestrictionMapGlob})
|
||||
set(PrepareSources prepare.cpp ${PrepareGlob})
|
||||
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:ANGLE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR> $<TARGET_OBJECTS:COMPRESSEDEDGE> $<TARGET_OBJECTS:GRAPHCOMPRESSOR>)
|
||||
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>)
|
||||
|
||||
file(GLOB ServerGlob server/*.cpp)
|
||||
file(GLOB DescriptorGlob descriptors/*.cpp)
|
||||
file(GLOB DatastructureGlob data_structures/search_engine_data.cpp data_structures/route_parameters.cpp util/bearing.cpp)
|
||||
file(GLOB CoordinateGlob data_structures/coordinate.cpp algorithms/coordinate_calculation.cpp)
|
||||
file(GLOB AlgorithmGlob algorithms/polyline_compressor.cpp algorithms/polyline_formatter.cpp algorithms/douglas_peucker.cpp)
|
||||
file(GLOB HttpGlob server/http/*.cpp)
|
||||
file(GLOB LibOSRMGlob library/*.cpp)
|
||||
file(GLOB DataStructureTestsGlob unit_tests/data_structures/*.cpp data_structures/hilbert_value.cpp)
|
||||
file(GLOB AlgorithmTestsGlob unit_tests/algorithms/*.cpp algorithms/graph_compressor.cpp)
|
||||
file(GLOB UtilTestsGlob unit_tests/util/*.cpp)
|
||||
if(ENABLE_GOLD_LINKER)
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||
if("${LD_VERSION}" MATCHES "GNU gold")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
|
||||
set(OSRM_LDFLAGS "${OSRM_LDFLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
|
||||
message(STATUS "Using GNU gold as linker.")
|
||||
|
||||
set(
|
||||
OSRMSources
|
||||
${LibOSRMGlob}
|
||||
${DescriptorGlob}
|
||||
${DatastructureGlob}
|
||||
${AlgorithmGlob}
|
||||
${HttpGlob}
|
||||
)
|
||||
# Issue 2785: check gold binutils version and don't use gc-sections for versions prior 2.25
|
||||
string(REGEX REPLACE ".*\\(GNU Binutils[^\\)0-9]+([0-9]+\\.[0-9]+)[^\\)]*\\).*" "\\1" GOLD_BINUTILS_VERSION "${LD_VERSION}")
|
||||
if ("${GOLD_BINUTILS_VERSION}" VERSION_LESS "2.26")
|
||||
message(STATUS "Disabling gc-sections on gold binutils < 2.26, see: https://sourceware.org/bugzilla/show_bug.cgi?id=17639")
|
||||
set(LD_AVOID_GC_SECTIONS TRUE)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "GNU gold linker isn't available.")
|
||||
set(ENABLE_GOLD_LINKER OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(COORDINATE OBJECT ${CoordinateGlob})
|
||||
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:ANGLE> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR> $<TARGET_OBJECTS:IMPORT>)
|
||||
|
||||
add_library(FINGERPRINT OBJECT util/fingerprint.cpp)
|
||||
add_dependencies(FINGERPRINT FingerPrintConfigure)
|
||||
add_dependencies(OSRM FingerPrintConfigure)
|
||||
set_target_properties(FINGERPRINT PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
||||
add_executable(osrm-routed routed.cpp ${ServerGlob} $<TARGET_OBJECTS:EXCEPTION>)
|
||||
add_executable(osrm-datastore datastore.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
|
||||
|
||||
# Unit tests
|
||||
add_executable(datastructure-tests EXCLUDE_FROM_ALL unit_tests/datastructure_tests.cpp ${DataStructureTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR> $<TARGET_OBJECTS:COMPRESSEDEDGE> $<TARGET_OBJECTS:GRAPHCOMPRESSOR> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:RASTERSOURCE>)
|
||||
add_executable(algorithm-tests EXCLUDE_FROM_ALL unit_tests/algorithm_tests.cpp ${AlgorithmTestsGlob} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:COMPRESSEDEDGE>)
|
||||
add_executable(util-tests EXCLUDE_FROM_ALL unit_tests/util_tests.cpp ${UtilTestsGlob})
|
||||
|
||||
# Benchmarks
|
||||
add_executable(rtree-bench EXCLUDE_FROM_ALL benchmarks/static_rtree.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
|
||||
|
||||
# Check the release mode
|
||||
if(NOT CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
# Explicitly set the build type to Release if no other type is specified
|
||||
# on the command line. Without this, cmake defaults to an unoptimized,
|
||||
# non-debug build, which almost nobody wants.
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
message(STATUS "No build type specified, defaulting to Release")
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
message(STATUS "Configuring OSRM in debug mode")
|
||||
elseif(CMAKE_BUILD_TYPE MATCHES Release)
|
||||
message(STATUS "Configuring OSRM in release mode")
|
||||
elseif(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
|
||||
message(STATUS "Configuring OSRM in release mode with debug flags")
|
||||
elseif(CMAKE_BUILD_TYPE MATCHES MinRelSize)
|
||||
message(STATUS "Configuring OSRM in release mode with minimized size")
|
||||
else()
|
||||
message(STATUS "Unrecognized build type - will use cmake defaults")
|
||||
endif()
|
||||
|
||||
# Additional logic for the different build types
|
||||
if(CMAKE_BUILD_TYPE MATCHES Debug OR CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
|
||||
message(STATUS "Configuring debug mode flags")
|
||||
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()
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-inline -fno-omit-frame-pointer")
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
if (CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Og -ggdb")
|
||||
else()
|
||||
# Don't override the -O parameter for RelWithDebInfo, we want an optimized build
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(CMAKE_BUILD_TYPE MATCHES Release)
|
||||
message(STATUS "Configuring OSRM in release mode")
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES Release OR CMAKE_BUILD_TYPE MATCHES MinRelSize OR CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
|
||||
message(STATUS "Configuring release mode optimizations")
|
||||
# Check if LTO is available
|
||||
check_cxx_compiler_flag("-flto" LTO_AVAILABLE)
|
||||
if(LTO_AVAILABLE)
|
||||
check_cxx_compiler_flag("-Wl,-flto" LTO_AVAILABLE)
|
||||
|
||||
if(ENABLE_LTO AND LTO_AVAILABLE)
|
||||
set(OLD_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
# GCC in addition allows parallelizing LTO
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
@@ -149,33 +215,78 @@ if(CMAKE_BUILD_TYPE MATCHES Release)
|
||||
check_cxx_source_compiles("${CHECK_LTO_SRC}" LTO_WORKS)
|
||||
if(LTO_WORKS)
|
||||
message(STATUS "LTO working")
|
||||
set(OSRM_CXXFLAGS "${OSRM_CXXFLAGS} -flto")
|
||||
set(OSRM_LDFLAGS "${OSRM_LDFLAGS} -flto")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -flto")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -flto")
|
||||
else()
|
||||
message(STATUS "LTO broken")
|
||||
set(CMAKE_CXX_FLAGS "${OLD_CXX_FLAGS}")
|
||||
set(ENABLE_LTO Off)
|
||||
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
|
||||
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")
|
||||
find_program(GCC_AR gcc-ar)
|
||||
find_program(GCC_RANLIB gcc-ranlib)
|
||||
if ("${GCC_AR}" STREQUAL "GCC_AR-NOTFOUND" OR "${GCC_RANLIB}" STREQUAL "GCC_RANLIB-NOTFOUND")
|
||||
message(WARNING "GCC specific binutils not found. In case of linker issues export env vars: AR=gcc-ar, NM=gcc-nm, RANLIB=gcc-ranlib")
|
||||
else()
|
||||
message(STATUS "Using GCC specific binutils for LTO:")
|
||||
message(STATUS " ${GCC_AR}")
|
||||
message(STATUS " ${GCC_RANLIB}")
|
||||
set(CMAKE_AR ${GCC_AR})
|
||||
set(CMAKE_RANLIB ${GCC_RANLIB})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Same for clang LTO requires their own toolchain
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
find_program(LLVM_AR llvm-ar)
|
||||
find_program(LLVM_RANLIB llvm-ranlib)
|
||||
if ("${LLVM_AR}" STREQUAL "LLVM_AR-NOTFOUND" OR "${LLVM_RANLIB}" STREQUAL "LLVM_RANLIB-NOTFOUND")
|
||||
message(WARNING "LLVM specific binutils not found.")
|
||||
else()
|
||||
message(STATUS "Using LLVM specific binutils for LTO:")
|
||||
message(STATUS " ${LLVM_AR}")
|
||||
message(STATUS " ${LLVM_RANLIB}")
|
||||
set(CMAKE_AR ${LLVM_AR})
|
||||
set(CMAKE_RANLIB ${LLVM_RANLIB})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
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}")
|
||||
set(ENABLE_LTO Off)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT WIN32)
|
||||
add_definitions(-DBOOST_TEST_DYN_LINK)
|
||||
if(UNIX AND NOT APPLE AND ENABLE_MASON AND (LTO_WORKS OR ENABLE_GOLD_LINKER))
|
||||
message(WARNING "ENABLE_MASON and ENABLE_LTO/ENABLE_GOLD_LINKER may not work on all linux systems currently")
|
||||
message(WARNING "For more details see: https://github.com/Project-OSRM/osrm-backend/issues/3202")
|
||||
endif()
|
||||
|
||||
set(MAYBE_COVERAGE_LIBRARIES "")
|
||||
if (ENABLE_COVERAGE)
|
||||
if (NOT CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
message(ERROR "ENABLE_COVERAGE=ON only make sense with a Debug build")
|
||||
endif()
|
||||
message(INFO "Enabling coverage")
|
||||
set(MAYBE_COVERAGE_LIBRARIES "-lgcov")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs")
|
||||
endif()
|
||||
if (ENABLE_SANITIZER)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
||||
set(OSRM_CXXFLAGS "${OSRM_CXXFLAGS} -fsanitize=address")
|
||||
endif()
|
||||
|
||||
# Configuring compilers
|
||||
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")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wuninitialized -Wunreachable-code -Wstrict-overflow=2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fPIC -fcolor-diagnostics -ftemplate-depth=1024")
|
||||
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
|
||||
set(COLOR_FLAG "-fdiagnostics-color=auto")
|
||||
check_cxx_compiler_flag("-fdiagnostics-color=auto" HAS_COLOR_FLAG)
|
||||
@@ -183,10 +294,9 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
|
||||
set(COLOR_FLAG "")
|
||||
endif()
|
||||
# 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")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wuninitialized -Wunreachable-code -Wstrict-overflow=1 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 ${COLOR_FLAG} -fPIC -ftemplate-depth=1024")
|
||||
if(WIN32) # using mingw
|
||||
add_definitions(-D_USE_MATH_DEFINES) # define M_PI, M_1_PI etc.
|
||||
add_definitions(-DWIN32)
|
||||
add_dependency_defines(-DWIN32)
|
||||
set(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
|
||||
endif()
|
||||
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
|
||||
@@ -194,12 +304,13 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -wd10237 -Wall -ipo -fPIC")
|
||||
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
|
||||
# using Visual Studio C++
|
||||
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time chrono zlib)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation
|
||||
add_definitions(-D_USE_MATH_DEFINES) # define M_PI
|
||||
add_definitions(-D_WIN32_WINNT=0x0501)
|
||||
add_definitions(-DXML_STATIC)
|
||||
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} zlib)
|
||||
add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC)
|
||||
add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS)
|
||||
add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation
|
||||
add_dependency_defines(-D_USE_MATH_DEFINES) #needed for M_PI with cmath.h
|
||||
add_dependency_defines(-D_WIN32_WINNT=0x0501)
|
||||
add_dependency_defines(-DXML_STATIC)
|
||||
find_library(ws2_32_LIBRARY_PATH ws2_32)
|
||||
target_link_libraries(osrm-extract wsock32 ws2_32)
|
||||
endif()
|
||||
@@ -209,7 +320,7 @@ execute_process(COMMAND ${CMAKE_CXX_COMPILER} "-Wl,--version" ERROR_QUIET OUTPUT
|
||||
# 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")
|
||||
if(NOT (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC" OR "${LD_AVOID_GC_SECTIONS}"))
|
||||
# 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
|
||||
@@ -217,20 +328,25 @@ if("${LINKER_VERSION}" MATCHES "GNU gold" OR "${LINKER_VERSION}" MATCHES "GNU ld
|
||||
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(OSRM_LDFLAGS "${OSRM_LDFLAGS} ${LINKER_FLAGS}")
|
||||
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
|
||||
# Activate C++1y
|
||||
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y")
|
||||
set(OSRM_CXXFLAGS "${OSRM_CXXFLAGS} -std=c++1y")
|
||||
endif()
|
||||
|
||||
# Configuring other platform dependencies
|
||||
if(APPLE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.10")
|
||||
execute_process(COMMAND xcrun --sdk macosx --show-sdk-path OUTPUT_VARIABLE CMAKE_OSX_SYSROOT OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||
message(STATUS "Set Architecture to x64 on OS X")
|
||||
exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION)
|
||||
@@ -245,76 +361,182 @@ 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 -lrt)
|
||||
endif()
|
||||
|
||||
#Check Boost
|
||||
find_package(Boost 1.49.0 COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
|
||||
if(NOT Boost_FOUND)
|
||||
message(FATAL_ERROR "Fatal error: Boost (version >= 1.49.0) required.\n")
|
||||
endif()
|
||||
include_directories(SYSTEM ${Boost_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(util-tests ${Boost_LIBRARIES})
|
||||
target_link_libraries(rtree-bench ${Boost_LIBRARIES})
|
||||
# Disallow deprecated protozero APIs
|
||||
add_definitions(-DPROTOZERO_STRICT_API)
|
||||
|
||||
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)
|
||||
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(SYSTEM ${TBB_INCLUDE_DIR})
|
||||
# if mason is enabled no find_package calls are made
|
||||
# to ensure that we are only compiling and linking against
|
||||
# fully portable mason packages
|
||||
if(ENABLE_MASON)
|
||||
message(STATUS "Installing dependencies via mason")
|
||||
|
||||
find_package( Luabind REQUIRED )
|
||||
include(check_luabind)
|
||||
set(Boost_USE_STATIC_LIBS ON)
|
||||
mason_use(boost VERSION ${MASON_BOOST_VERSION} HEADER_ONLY)
|
||||
add_dependency_includes(${MASON_PACKAGE_boost_INCLUDE_DIRS})
|
||||
mason_use(boost_libfilesystem VERSION ${MASON_BOOST_VERSION})
|
||||
set(Boost_FILESYSTEM_LIBRARY ${MASON_PACKAGE_boost_libfilesystem_STATIC_LIBS})
|
||||
mason_use(boost_libiostreams VERSION ${MASON_BOOST_VERSION})
|
||||
set(Boost_IOSTREAMS_LIBRARY ${MASON_PACKAGE_boost_libiostreams_STATIC_LIBS})
|
||||
mason_use(boost_libprogram_options VERSION ${MASON_BOOST_VERSION})
|
||||
set(Boost_PROGRAM_OPTIONS_LIBRARY ${MASON_PACKAGE_boost_libprogram_options_STATIC_LIBS})
|
||||
mason_use(boost_libregex VERSION ${MASON_BOOST_VERSION})
|
||||
set(Boost_REGEX_LIBRARY ${MASON_PACKAGE_boost_libregex_STATIC_LIBS})
|
||||
mason_use(boost_libtest VERSION ${MASON_BOOST_VERSION})
|
||||
set(Boost_UNIT_TEST_FRAMEWORK_LIBRARY ${MASON_PACKAGE_boost_libtest_STATIC_LIBS})
|
||||
mason_use(boost_libdate_time VERSION ${MASON_BOOST_VERSION})
|
||||
set(Boost_DATE_TIME_LIBRARY ${MASON_PACKAGE_boost_libdate_time_STATIC_LIBS})
|
||||
mason_use(boost_libthread VERSION ${MASON_BOOST_VERSION})
|
||||
set(Boost_THREAD_LIBRARY ${MASON_PACKAGE_boost_libthread_STATIC_LIBS})
|
||||
mason_use(boost_libsystem VERSION ${MASON_BOOST_VERSION})
|
||||
set(Boost_SYSTEM_LIBRARY ${MASON_PACKAGE_boost_libsystem_STATIC_LIBS})
|
||||
|
||||
include_directories(SYSTEM ${LUABIND_INCLUDE_DIR})
|
||||
target_link_libraries(osrm-extract ${LUABIND_LIBRARY})
|
||||
target_link_libraries(osrm-prepare ${LUABIND_LIBRARY})
|
||||
mason_use(stxxl VERSION ${MASON_STXXL_VERSION})
|
||||
add_dependency_includes(${MASON_PACKAGE_stxxl_INCLUDE_DIRS})
|
||||
set(STXXL_LIBRARY ${MASON_PACKAGE_stxxl_STATIC_LIBS})
|
||||
|
||||
mason_use(expat VERSION ${MASON_EXPAT_VERSION})
|
||||
add_dependency_includes(${MASON_PACKAGE_expat_INCLUDE_DIRS})
|
||||
set(EXPAT_LIBRARIES ${MASON_PACKAGE_expat_STATIC_LIBS})
|
||||
|
||||
mason_use(lua VERSION ${MASON_LUA_VERSION})
|
||||
add_dependency_includes(${MASON_PACKAGE_lua_INCLUDE_DIRS})
|
||||
set(USED_LUA_LIBRARIES ${MASON_PACKAGE_lua_STATIC_LIBS})
|
||||
|
||||
mason_use(bzip2 VERSION ${MASON_BZIP2_VERSION})
|
||||
add_dependency_includes(${MASON_PACKAGE_bzip2_INCLUDE_DIRS})
|
||||
set(BZIP2_LIBRARIES ${MASON_PACKAGE_bzip2_STATIC_LIBS})
|
||||
|
||||
mason_use(tbb VERSION ${MASON_TBB_VERSION})
|
||||
add_dependency_includes(${MASON_PACKAGE_tbb_INCLUDE_DIRS})
|
||||
set(TBB_LIBRARIES ${MASON_PACKAGE_tbb_LDFLAGS})
|
||||
|
||||
if(NOT MASON_PACKAGE_tbb_LIBRARY_DIRS)
|
||||
message(FATAL_ERROR "MASON_PACKAGE_tbb_LIBRARY_DIRS is empty, rpath will not work")
|
||||
endif()
|
||||
set(TBB_LINKER_RPATHS "")
|
||||
foreach(libpath ${MASON_PACKAGE_tbb_LIBRARY_DIRS})
|
||||
set(TBB_LINKER_RPATHS "${TBB_LINKER_RPATHS} -Wl,-rpath -Wl,${libpath}")
|
||||
file(GLOB TBBGlob ${libpath}/*.*)
|
||||
install(FILES ${TBBGlob} DESTINATION lib)
|
||||
endforeach()
|
||||
if(APPLE)
|
||||
set(LINKER_FLAGS "${TBB_LINKER_RPATHS} -Wl,-rpath -Wl,@executable_path")
|
||||
elseif(UNIX)
|
||||
set(LINKER_FLAGS "${TBB_LINKER_RPATHS} '-Wl,-rpath,$ORIGIN' -Wl,-z,origin")
|
||||
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}")
|
||||
|
||||
# current mason packages target -D_GLIBCXX_USE_CXX11_ABI=0
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
|
||||
|
||||
# note: we avoid calling find_package(Osmium ...) here to ensure that the
|
||||
# expat and bzip2 are used from mason rather than the system
|
||||
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/include)
|
||||
|
||||
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})
|
||||
|
||||
find_package(Boost 1.54 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||
add_dependency_includes(${Boost_INCLUDE_DIRS})
|
||||
if(WIN32 AND Boost_VERSION VERSION_LESS 106200)
|
||||
message(FATAL_ERROR "Building with MSVC needs Boost 1.62 with CXX11_CONSTEXPR support")
|
||||
endif()
|
||||
|
||||
find_package(TBB REQUIRED)
|
||||
add_dependency_includes(${TBB_INCLUDE_DIR})
|
||||
if(WIN32 AND CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(TBB_LIBRARIES ${TBB_DEBUG_LIBRARIES})
|
||||
endif()
|
||||
|
||||
find_package(EXPAT REQUIRED)
|
||||
add_dependency_includes(${EXPAT_INCLUDE_DIRS})
|
||||
|
||||
find_package(STXXL REQUIRED)
|
||||
add_dependency_includes(${STXXL_INCLUDE_DIR})
|
||||
|
||||
find_package(BZip2 REQUIRED)
|
||||
add_dependency_includes(${BZIP2_INCLUDE_DIR})
|
||||
|
||||
FIND_PACKAGE(Lua 5.2 EXACT)
|
||||
IF (LUA_FOUND)
|
||||
MESSAGE(STATUS "Using Lua ${LUA_VERSION_STRING}")
|
||||
ELSE()
|
||||
FIND_PACKAGE(Lua 5.1 EXACT)
|
||||
IF (LUA_FOUND)
|
||||
MESSAGE(STATUS "Using Lua ${LUA_VERSION_STRING}")
|
||||
ELSE()
|
||||
# Now fall back to a lua verison without exact
|
||||
# in case this cmake version also forces patch versions
|
||||
FIND_PACKAGE(Lua 5.2)
|
||||
IF (LUA_FOUND)
|
||||
MESSAGE(STATUS "Using Lua ${LUA_VERSION_STRING}")
|
||||
ELSE()
|
||||
FIND_PACKAGE(Lua 5.1)
|
||||
IF (LUA_FOUND)
|
||||
MESSAGE(STATUS "Using Lua ${LUA_VERSION_STRING}")
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "Lua 5.1 or 5.2 was not found.")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
set(USED_LUA_LIBRARIES ${LUA_LIBRARIES})
|
||||
add_dependency_includes(${LUA_INCLUDE_DIR})
|
||||
|
||||
# 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()
|
||||
|
||||
# note libosmium depends on expat and bzip2
|
||||
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_DIR})
|
||||
|
||||
endif()
|
||||
include_directories(SYSTEM ${LUA_INCLUDE_DIR})
|
||||
|
||||
find_package(EXPAT REQUIRED)
|
||||
include_directories(SYSTEM ${EXPAT_INCLUDE_DIRS})
|
||||
target_link_libraries(osrm-extract ${EXPAT_LIBRARIES})
|
||||
# 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()
|
||||
|
||||
find_package(STXXL REQUIRED)
|
||||
include_directories(SYSTEM ${STXXL_INCLUDE_DIR})
|
||||
target_link_libraries(OSRM ${STXXL_LIBRARY})
|
||||
target_link_libraries(osrm-extract ${STXXL_LIBRARY})
|
||||
target_link_libraries(osrm-prepare ${STXXL_LIBRARY})
|
||||
target_link_libraries(datastructure-tests ${STXXL_LIBRARY})
|
||||
# even with mason builds we want to link to system zlib
|
||||
# to ensure that osrm binaries play well with other binaries like nodejs
|
||||
find_package(ZLIB REQUIRED)
|
||||
add_dependency_includes(${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
if(NOT WIN32 AND NOT Boost_USE_STATIC_LIBS)
|
||||
add_dependency_defines(-DBOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
|
||||
if(NOT WIN32 AND NOT Boost_USE_STATIC_LIBS)
|
||||
add_dependency_defines(-DBOOST_TEST_DYN_LINK)
|
||||
endif()
|
||||
|
||||
add_dependency_defines(-DBOOST_SPIRIT_USE_PHOENIX_V3)
|
||||
add_dependency_defines(-DBOOST_RESULT_OF_USE_DECLTYPE)
|
||||
add_dependency_defines(-DBOOST_FILESYSTEM_NO_DEPRECATED)
|
||||
|
||||
set(OpenMP_FIND_QUIETLY ON)
|
||||
find_package(OpenMP)
|
||||
@@ -323,120 +545,222 @@ if(OPENMP_FOUND)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
find_package(BZip2 REQUIRED)
|
||||
include_directories(SYSTEM ${BZIP_INCLUDE_DIRS})
|
||||
target_link_libraries(osrm-extract ${BZIP2_LIBRARIES})
|
||||
add_definitions(${OSRM_DEFINES})
|
||||
include_directories(SYSTEM ${DEPENDENCIES_INCLUDE_DIRS})
|
||||
|
||||
find_package(ZLIB REQUIRED)
|
||||
include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS})
|
||||
target_link_libraries(osrm-extract ${ZLIB_LIBRARY})
|
||||
target_link_libraries(osrm-routed ${ZLIB_LIBRARY})
|
||||
set(BOOST_BASE_LIBRARIES
|
||||
${Boost_DATE_TIME_LIBRARY}
|
||||
${Boost_CHRONO_LIBRARY}
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
${Boost_IOSTREAMS_LIBRARY}
|
||||
${Boost_THREAD_LIBRARY}
|
||||
${Boost_SYSTEM_LIBRARY})
|
||||
|
||||
if (ENABLE_JSON_LOGGING)
|
||||
message(STATUS "Enabling json logging")
|
||||
add_definitions(-DENABLE_JSON_LOGGING)
|
||||
endif()
|
||||
set(BOOST_ENGINE_LIBRARIES
|
||||
${Boost_ZLIB_LIBRARY}
|
||||
${Boost_REGEX_LIBRARY}
|
||||
${BOOST_BASE_LIBRARIES})
|
||||
|
||||
if (DEBUG_GEOMETRY)
|
||||
message(STATUS "Enabling final edge weight GeoJSON output option")
|
||||
add_definitions(-DDEBUG_GEOMETRY)
|
||||
endif()
|
||||
# Binaries
|
||||
target_link_libraries(osrm-datastore osrm_store ${Boost_PROGRAM_OPTIONS_LIBRARY})
|
||||
target_link_libraries(osrm-extract osrm_extract ${Boost_PROGRAM_OPTIONS_LIBRARY})
|
||||
target_link_libraries(osrm-contract osrm_contract ${Boost_PROGRAM_OPTIONS_LIBRARY})
|
||||
target_link_libraries(osrm-routed osrm ${Boost_PROGRAM_OPTIONS_LIBRARY} ${OPTIONAL_SOCKET_LIBS} ${ZLIB_LIBRARY})
|
||||
|
||||
set(EXTRACTOR_LIBRARIES
|
||||
${BZIP2_LIBRARIES}
|
||||
${Boost_REGEX_LIBRARY}
|
||||
${BOOST_BASE_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${EXPAT_LIBRARIES}
|
||||
${USED_LUA_LIBRARIES}
|
||||
${OSMIUM_LIBRARIES}
|
||||
${STXXL_LIBRARY}
|
||||
${TBB_LIBRARIES}
|
||||
${ZLIB_LIBRARY}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
set(CONTRACTOR_LIBRARIES
|
||||
${BOOST_BASE_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${USED_LUA_LIBRARIES}
|
||||
${STXXL_LIBRARY}
|
||||
${TBB_LIBRARIES}
|
||||
${MAYBE_RT_LIBRARY}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
set(ENGINE_LIBRARIES
|
||||
${BOOST_ENGINE_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${TBB_LIBRARIES}
|
||||
${MAYBE_RT_LIBRARY}
|
||||
${MAYBE_COVERAGE_LIBRARIES}
|
||||
${ZLIB_LIBRARY})
|
||||
set(STORAGE_LIBRARIES
|
||||
${BOOST_BASE_LIBRARIES}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${TBB_LIBRARIES}
|
||||
${MAYBE_RT_LIBRARY}
|
||||
${MAYBE_COVERAGE_LIBRARIES})
|
||||
set(UTIL_LIBRARIES
|
||||
${BOOST_BASE_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})
|
||||
|
||||
# BUILD_COMPONENTS
|
||||
add_executable(osrm-components src/tools/components.cpp $<TARGET_OBJECTS:UTIL>)
|
||||
target_link_libraries(osrm-components ${TBB_LIBRARIES} ${BOOST_BASE_LIBRARIES})
|
||||
install(TARGETS osrm-components DESTINATION bin)
|
||||
|
||||
if(BUILD_TOOLS)
|
||||
message(STATUS "Activating OSRM internal tools")
|
||||
find_package(GDAL)
|
||||
if(GDAL_FOUND)
|
||||
add_executable(osrm-components tools/components.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
|
||||
target_link_libraries(osrm-components ${TBB_LIBRARIES})
|
||||
include_directories(SYSTEM ${GDAL_INCLUDE_DIR})
|
||||
target_link_libraries(osrm-components ${GDAL_LIBRARIES} ${Boost_LIBRARIES})
|
||||
install(TARGETS osrm-components DESTINATION bin)
|
||||
else()
|
||||
message(FATAL_ERROR "libgdal and/or development headers not found")
|
||||
endif()
|
||||
add_executable(osrm-cli tools/simpleclient.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:COORDINATE>)
|
||||
target_link_libraries(osrm-cli ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
|
||||
target_link_libraries(osrm-cli ${TBB_LIBRARIES})
|
||||
add_executable(osrm-io-benchmark tools/io-benchmark.cpp $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:LOGGER>)
|
||||
target_link_libraries(osrm-io-benchmark ${Boost_LIBRARIES})
|
||||
add_executable(osrm-unlock-all tools/unlock_all_mutexes.cpp $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
|
||||
target_link_libraries(osrm-unlock-all ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(osrm-unlock-all rt)
|
||||
endif()
|
||||
add_executable(osrm-check-hsgr tools/check-hsgr.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:IMPORT>)
|
||||
target_link_libraries(osrm-check-hsgr ${Boost_LIBRARIES} ${TBB_LIBRARIES})
|
||||
add_executable(osrm-springclean tools/springclean.cpp $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
|
||||
target_link_libraries(osrm-springclean ${Boost_LIBRARIES})
|
||||
add_executable(osrm-io-benchmark src/tools/io-benchmark.cpp $<TARGET_OBJECTS:UTIL>)
|
||||
target_link_libraries(osrm-io-benchmark ${BOOST_BASE_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)
|
||||
|
||||
find_package(Shapefile) # package libshp-dev
|
||||
if(Shapefile_FOUND)
|
||||
add_executable(osrm-extract-conditionals src/tools/extract-conditionals.cpp $<TARGET_OBJECTS:UTIL>)
|
||||
target_include_directories(osrm-extract-conditionals PRIVATE ${LIBSHAPEFILE_INCLUDE_DIR})
|
||||
target_link_libraries(osrm-extract-conditionals ${OSMIUM_LIBRARIES} ${BOOST_BASE_LIBRARIES} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${LIBSHAPEFILE_LIBRARY})
|
||||
install(TARGETS osrm-extract-conditionals DESTINATION bin)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
file(GLOB InstallGlob include/osrm/*.hpp)
|
||||
file(GLOB VariantGlob third_party/variant/*.hpp)
|
||||
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)
|
||||
install(FILES ${VariantGlob} DESTINATION include/variant)
|
||||
file(GLOB VariantGlob third_party/variant/include/mapbox/*.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 include/util/exception.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/mapbox)
|
||||
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)
|
||||
install(TARGETS osrm DESTINATION lib)
|
||||
install(TARGETS osrm_extract DESTINATION lib)
|
||||
install(TARGETS osrm_contract DESTINATION lib)
|
||||
install(TARGETS osrm_store 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()
|
||||
list(GET TBB_LIBRARIES 1 TBB_LIBRARY_FIRST)
|
||||
get_filename_component(TBB_LIBRARY_LISTING "${TBB_LIBRARY_FIRST}" PATH)
|
||||
set(TBB_LIBRARY_LISTING "-L${TBB_LIBRARY_LISTING}")
|
||||
foreach(lib ${TBB_LIBRARIES})
|
||||
get_filename_component(TBB_LIBRARY_NAME "${lib}" NAME_WE)
|
||||
string(REPLACE "lib" "" TBB_LIBRARY_NAME ${TBB_LIBRARY_NAME})
|
||||
set(TBB_LIBRARY_LISTING "${TBB_LIBRARY_LISTING} -l${TBB_LIBRARY_NAME}")
|
||||
endforeach()
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
|
||||
# Install profiles and support library to /usr/local/share/osrm/profiles by default
|
||||
set(DefaultProfilesDir profiles)
|
||||
install(DIRECTORY ${DefaultProfilesDir} DESTINATION share/osrm)
|
||||
|
||||
if(BUILD_DEBIAN_PACKAGE)
|
||||
include(CPackDebianConfig)
|
||||
# Setup exporting variables for pkgconfig and subproject
|
||||
#
|
||||
|
||||
if(BUILD_PACKAGE)
|
||||
include(CPackConfig)
|
||||
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
|
||||
)
|
||||
function(JOIN VALUES GLUE OUTPUT)
|
||||
string (REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}")
|
||||
set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
JOIN("${OSRM_DEFINES}" " " TMP_OSRM_DEFINES)
|
||||
set(LibOSRM_CXXFLAGS "${OSRM_CXXFLAGS} ${TMP_OSRM_DEFINES}")
|
||||
set(LibOSRM_LDFLAGS "${OSRM_LDFLAGS}")
|
||||
|
||||
if(BUILD_AS_SUBPROJECT)
|
||||
set(LibOSRM_CXXFLAGS "${LibOSRM_CXXFLAGS}" PARENT_SCOPE)
|
||||
set(LibOSRM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE)
|
||||
set(LibOSRM_LIBRARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE)
|
||||
set(LibOSRM_LIBRARIES "osrm" PARENT_SCOPE)
|
||||
set(LibOSRM_DEPENDENT_LIBRARIES "${ENGINE_LIBRARIES}" PARENT_SCOPE)
|
||||
set(LibOSRM_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/osrm"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party"
|
||||
"${DEPENDENCIES_INCLUDE_DIRS}" PARENT_SCOPE)
|
||||
set(LibOSRM_LIBRARY_DIRS "${LibOSRM_LIBRARY_DIR}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
# prefix compilation with ccache by default if available and on clang or gcc
|
||||
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if(CCACHE_FOUND)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
|
||||
set(ENV{CCACHE_CPP2} "true")
|
||||
# pkgconfig defines
|
||||
set(PKGCONFIG_OSRM_CXXFLAGS "${LibOSRM_CXXFLAGS}")
|
||||
set(PKGCONFIG_OSRM_LDFLAGS "${LibOSRM_LDFLAGS}")
|
||||
set(PKGCONFIG_LIBRARY_DIR "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
set(PKGCONFIG_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/include")
|
||||
|
||||
list(APPEND DEPENDENCIES_INCLUDE_DIRS "${PKGCONFIG_INCLUDE_DIR}")
|
||||
list(APPEND DEPENDENCIES_INCLUDE_DIRS "${PKGCONFIG_INCLUDE_DIR}/osrm")
|
||||
JOIN("-I${DEPENDENCIES_INCLUDE_DIRS}" " -I" PKGCONFIG_OSRM_INCLUDE_FLAGS)
|
||||
JOIN("${ENGINE_LIBRARIES}" " " PKGCONFIG_OSRM_DEPENDENT_LIBRARIES)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
|
||||
# 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)
|
||||
|
||||
if (ENABLE_FUZZING)
|
||||
# Requires libosrm being built with sanitizers; make configurable and default to ubsan
|
||||
set(FUZZ_SANITIZER "undefined" CACHE STRING "Sanitizer to be used for Fuzz testing")
|
||||
set_property(CACHE FUZZ_SANITIZER PROPERTY STRINGS "undefined" "integer" "address" "memory" "thread" "leak")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize-coverage=edge,indirect-calls,8bit-counters -fsanitize=address")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||
set(OSRM_LDFLAGS "${OSRM_LDFLAGS} -fsanitize=address")
|
||||
|
||||
message(STATUS "Using -fsanitize=${FUZZ_SANITIZER} for Fuzz testing")
|
||||
|
||||
add_subdirectory(fuzz)
|
||||
endif ()
|
||||
|
||||
|
||||
## add headers sanity check target that includes all headers independently
|
||||
set(check_headers_dir "${PROJECT_BINARY_DIR}/check-headers")
|
||||
file(GLOB_RECURSE headers_to_check
|
||||
${PROJECT_BINARY_DIR}/*.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/*.hpp)
|
||||
foreach(header ${headers_to_check})
|
||||
get_filename_component(filename ${header} NAME_WE)
|
||||
set(filename "${check_headers_dir}/${filename}.cpp")
|
||||
if (NOT EXISTS ${filename})
|
||||
file(WRITE ${filename} "#include \"${header}\"\n")
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND sources ${filename})
|
||||
endforeach()
|
||||
add_library(check-headers STATIC EXCLUDE_FROM_ALL ${sources})
|
||||
set_target_properties(check-headers PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${check_headers_dir})
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# User
|
||||
|
||||
Before you open a new issue, please search for older ones that cover the same issue.
|
||||
In general "me too" comments/issues are frowned upon.
|
||||
You can add a :+1: emoji to the issue if you want to express interest in this.
|
||||
|
||||
# Developer
|
||||
|
||||
We use `clang-format` version `3.8` to consistently format the code base. There is a helper script under `scripts/format.sh`.
|
||||
The format is automatically checked by the `mason-linux-release` job of a Travis CI build.
|
||||
To save development time a local hook `.git/hooks/pre-push`
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
remote="$1"
|
||||
if [ x"$remote" = xorigin ] ; then
|
||||
if [ $(git rev-parse --abbrev-ref HEAD) = master ] ; then
|
||||
echo "Rejected push to $remote/master" ; exit 1
|
||||
fi
|
||||
|
||||
./scripts/format.sh
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo "Unstaged format changes" ; exit 1
|
||||
fi
|
||||
fi
|
||||
```
|
||||
could check code format, modify a local repository and reject push due to unstaged formatting changes.
|
||||
Also `pre-push` hook rejects direct pushes to `origin/master`.
|
||||
|
||||
⚠️ `scripts/format.sh` checks all local files that match `*.cpp` or `*.hpp` patterns.
|
||||
|
||||
|
||||
In general changes that affect the API and/or increase the memory consumption need to be discussed first.
|
||||
Often we don't include changes that would increase the memory consumption a lot if they are not generally usable (e.g. elevation data is a good example).
|
||||
|
||||
## Pull Request
|
||||
|
||||
Every pull-request that changes the API needs to update the docs in `docs/http.md` and add an entry to `CHANGELOG.md`.
|
||||
Breaking changes need to have a BREAKING prefix. See the [releasing documentation](docs/releasing.md) on how this affects the version.
|
||||
|
||||
Early feedback is also important.
|
||||
You will see that a lot of the PR have tags like `[not ready]` or `[wip]`.
|
||||
We like to open PRs as soon as we are starting to work on something to make it visible to the rest of the team.
|
||||
If your work is going in entirely the wrong direction, there is a good chance someone will pick up on this before it is too late.
|
||||
Everyone is encouraged to read PRs of other people and give feedback.
|
||||
|
||||
For every significant code change we require a pull request review before it is merged.
|
||||
If your pull request modifies the API this need to be signed of by a team discussion.
|
||||
This means you will need to find another member of the team with commit access and request a review of your pull request.
|
||||
|
||||
Once your pull request is reviewed you can merge it! If you don't have commit access, ping someone that has commit access.
|
||||
If you do have commit access there are in general two accepted styles to merging:
|
||||
|
||||
1. Make sure the branch is up to date with `master`. Run `git rebase master` to find out.
|
||||
2. Once that is ensured you can either:
|
||||
- Click the nice green merge button (for a non-fast-forward merge)
|
||||
- Merge by hand using a fast-forward merge
|
||||
|
||||
Which merge you prefer is up to personal preference. In general it is recommended to use fast-forward merges because it creates a history that is sequential and easier to understand.
|
||||
|
||||
# Maintainer
|
||||
|
||||
## Doing a release
|
||||
|
||||
There is an in-depth guide around how to push out a release once it is ready [here](docs/releasing.md).
|
||||
|
||||
## The API
|
||||
|
||||
Changes to the API need to be discussed and signed off by the team. Breaking changes even more so than additive changes.
|
||||
|
||||
## Milestones
|
||||
|
||||
If a pull request or an issue is applicable for the current or next milestone, depends on the target version number.
|
||||
Since we use semantic versioning we restrict breaking changes to major releases.
|
||||
After a Release Candidate is released we usually don't change the API anymore if it is not critical.
|
||||
Bigger code changes after a RC was released should also be avoided.
|
||||
|
||||
@@ -18,6 +18,7 @@ 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
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
source "http://rubygems.org"
|
||||
|
||||
gem "cucumber"
|
||||
gem "rake"
|
||||
gem "osmlib-base"
|
||||
gem "sys-proctable"
|
||||
gem "rspec-expectations"
|
||||
@@ -1,35 +0,0 @@
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
builder (3.2.2)
|
||||
cucumber (2.0.0)
|
||||
builder (>= 2.1.2)
|
||||
cucumber-core (~> 1.1.3)
|
||||
diff-lcs (>= 1.1.3)
|
||||
gherkin (~> 2.12)
|
||||
multi_json (>= 1.7.5, < 2.0)
|
||||
multi_test (>= 0.1.2)
|
||||
cucumber-core (1.1.3)
|
||||
gherkin (~> 2.12.0)
|
||||
diff-lcs (1.2.5)
|
||||
gherkin (2.12.2)
|
||||
multi_json (~> 1.3)
|
||||
multi_json (1.11.0)
|
||||
multi_test (0.1.2)
|
||||
osmlib-base (0.1.4)
|
||||
rake (10.4.2)
|
||||
rspec-expectations (3.2.1)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.2.0)
|
||||
rspec-support (3.2.2)
|
||||
sys-proctable (0.9.8)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cucumber
|
||||
osmlib-base
|
||||
rake
|
||||
rspec-expectations
|
||||
sys-proctable
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
Copyright (c) 2016, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
|
||||
@@ -1,25 +1,91 @@
|
||||
## About
|
||||
## Open Source Routing Machine
|
||||
|
||||
The Open Source Routing Machine is a high performance routing engine written in C++11 designed to run on OpenStreetMap data.
|
||||
| Linux / macOS | Windows | Code Coverage |
|
||||
| ------------- | ------- | ------------- |
|
||||
| [](https://travis-ci.org/Project-OSRM/osrm-backend) | [](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) | [](https://codecov.io/gh/Project-OSRM/osrm-backend) |
|
||||
|
||||
## Current build status
|
||||
High performance routing engine written in C++14 designed to run on OpenStreetMap data.
|
||||
|
||||
| build config | branch | status |
|
||||
|:-------------|:--------|:------------|
|
||||
| Linux | master | [](https://travis-ci.org/Project-OSRM/osrm-backend) |
|
||||
| Linux | develop | [](https://travis-ci.org/Project-OSRM/osrm-backend) |
|
||||
| Windows | master/develop | [](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
|
||||
| LUAbind fork | master | [](https://travis-ci.org/DennisOSRM/luabind) |
|
||||
The following services are available via HTTP API, C++ library interface and NodeJs wrapper:
|
||||
- Nearest - Snaps coordinates to the street network and returns the nearest matches
|
||||
- Route - Finds the fastest route between coordinates
|
||||
- Table - Computes the duration of the fastest route between all pairs of supplied coordinates
|
||||
- Match - Snaps noisy GPS traces to the road network in the most plausible way
|
||||
- Trip - Solves the Traveling Salesman Problem using a greedy heuristic
|
||||
- Tile - Generates Mapbox Vector Tiles with internal routing metadata
|
||||
|
||||
## Building
|
||||
To quickly try OSRM use our [demo server](http://map.project-osrm.org) which comes with both the backend and a frontend on top.
|
||||
|
||||
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).
|
||||
Related [Project-OSRM](https://github.com/Project-OSRM) repositories:
|
||||
- [node-osrm](https://github.com/Project-OSRM/node-osrm) - Production-ready NodeJs bindings for the routing engine
|
||||
- [osrm-frontend](https://github.com/Project-OSRM/osrm-frontend) - User-facing frontend with map. The demo server runs this on top of the backend
|
||||
- [osrm-text-instructions](https://github.com/Project-OSRM/osrm-text-instructions) - Text instructions from OSRM route response
|
||||
|
||||
To quickly try OSRM use our [free and daily updated online service](http://map.project-osrm.org)
|
||||
## Contact
|
||||
|
||||
- IRC: `irc.oftc.net`, channel: `#osrm` ([Webchat](https://webchat.oftc.net))
|
||||
- Mailinglist: `https://lists.openstreetmap.org/listinfo/osrm-talk`
|
||||
|
||||
## Quick Start
|
||||
|
||||
The following targets Ubuntu 16.04.
|
||||
For instructions how to build on different distributions, macOS or Windows see our [Wiki](https://github.com/Project-OSRM/osrm-backend/wiki).
|
||||
|
||||
#### Install dependencies
|
||||
|
||||
```bash
|
||||
sudo apt install build-essential git cmake pkg-config \
|
||||
libbz2-dev libstxxl-dev libstxxl1v5 libxml2-dev \
|
||||
libzip-dev libboost-all-dev lua5.2 liblua5.2-dev libtbb-dev
|
||||
```
|
||||
|
||||
#### Compile and install OSRM binaries:
|
||||
|
||||
```bash
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake --build .
|
||||
sudo cmake --build . --target install
|
||||
```
|
||||
|
||||
#### Grab a `.osm.pbf` extract from [Geofabrik](http://download.geofabrik.de/index.html) or [Mapzen's Metro Extracts](https://mapzen.com/data/metro-extracts/)
|
||||
|
||||
```bash
|
||||
wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf
|
||||
```
|
||||
|
||||
#### Pre-process the extract and start the HTTP server
|
||||
|
||||
```
|
||||
osrm-extract berlin-latest.osm.pbf -p profiles/car.lua
|
||||
osrm-contract berlin-latest.osrm
|
||||
osrm-routed berlin-latest.osrm
|
||||
```
|
||||
|
||||
#### Running Queries
|
||||
|
||||
```
|
||||
curl http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
See the Wiki's [server API documentation](https://github.com/Project-OSRM/osrm-backend/wiki/Server-api) as well as the [library API documentation](https://github.com/Project-OSRM/osrm-backend/wiki/Library-api)
|
||||
### Full documentation
|
||||
|
||||
- [Hosted documentation](http://project-osrm.org)
|
||||
- [osrm-routed HTTP API documentation](docs/http.md)
|
||||
- [libosrm API documentation](docs/libosrm.md)
|
||||
|
||||
|
||||
### Running a request against the Demo Server
|
||||
|
||||
Read the [API usage policy](https://github.com/Project-OSRM/osrm-backend/wiki/Api-usage-policy).
|
||||
Simple query with instructions and alternatives on Berlin:
|
||||
|
||||
```
|
||||
curl https://router.project-osrm.org/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true&alternatives=true
|
||||
```
|
||||
|
||||
## References in publications
|
||||
|
||||
@@ -43,4 +109,3 @@ When using the code in a (scientific) publication, please cite
|
||||
address = {New York, NY, USA},
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -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,174 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef BFS_COMPONENTS_HPP_
|
||||
#define BFS_COMPONENTS_HPP_
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "../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;
|
||||
if (m_barrier_nodes.find(v) != m_barrier_nodes.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
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,273 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "coordinate_calculation.hpp"
|
||||
|
||||
#include "../util/mercator.hpp"
|
||||
#include "../util/string_util.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr static const float RAD = 0.017453292519943295769236907684886f;
|
||||
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
|
||||
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
|
||||
constexpr static const float earth_radius = 6372797.560856f;
|
||||
}
|
||||
|
||||
namespace coordinate_calculation
|
||||
{
|
||||
|
||||
double haversine_distance(const int lat1,
|
||||
const int lon1,
|
||||
const int lat2,
|
||||
const int lon2)
|
||||
{
|
||||
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
|
||||
const double lt1 = lat1 / COORDINATE_PRECISION;
|
||||
const double ln1 = lon1 / COORDINATE_PRECISION;
|
||||
const double lt2 = lat2 / COORDINATE_PRECISION;
|
||||
const double ln2 = lon2 / COORDINATE_PRECISION;
|
||||
const double dlat1 = lt1 * (RAD);
|
||||
|
||||
const double dlong1 = ln1 * (RAD);
|
||||
const double dlat2 = lt2 * (RAD);
|
||||
const double dlong2 = ln2 * (RAD);
|
||||
|
||||
const double dLong = dlong1 - dlong2;
|
||||
const double dLat = dlat1 - dlat2;
|
||||
|
||||
const double aHarv = std::pow(std::sin(dLat / 2.0), 2.0) +
|
||||
std::cos(dlat1) * std::cos(dlat2) * std::pow(std::sin(dLong / 2.), 2);
|
||||
const double cHarv = 2. * std::atan2(std::sqrt(aHarv), std::sqrt(1.0 - aHarv));
|
||||
return earth_radius * cHarv;
|
||||
}
|
||||
|
||||
double haversine_distance(const FixedPointCoordinate &coordinate_1,
|
||||
const FixedPointCoordinate &coordinate_2)
|
||||
{
|
||||
return haversine_distance(coordinate_1.lat, coordinate_1.lon, coordinate_2.lat,
|
||||
coordinate_2.lon);
|
||||
}
|
||||
|
||||
float great_circle_distance(const FixedPointCoordinate &coordinate_1,
|
||||
const FixedPointCoordinate &coordinate_2)
|
||||
{
|
||||
return great_circle_distance(coordinate_1.lat, coordinate_1.lon, coordinate_2.lat,
|
||||
coordinate_2.lon);
|
||||
}
|
||||
|
||||
float great_circle_distance(const int lat1,
|
||||
const int lon1,
|
||||
const int lat2,
|
||||
const int lon2)
|
||||
{
|
||||
BOOST_ASSERT(lat1 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lon1 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lat2 != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(lon2 != std::numeric_limits<int>::min());
|
||||
|
||||
const float float_lat1 = (lat1 / COORDINATE_PRECISION) * RAD;
|
||||
const float float_lon1 = (lon1 / COORDINATE_PRECISION) * RAD;
|
||||
const float float_lat2 = (lat2 / COORDINATE_PRECISION) * RAD;
|
||||
const float float_lon2 = (lon2 / COORDINATE_PRECISION) * RAD;
|
||||
|
||||
const float x_value = (float_lon2 - float_lon1) * std::cos((float_lat1 + float_lat2) / 2.f);
|
||||
const float y_value = float_lat2 - float_lat1;
|
||||
return std::hypot(x_value, y_value) * earth_radius;
|
||||
}
|
||||
|
||||
float perpendicular_distance(const FixedPointCoordinate &source_coordinate,
|
||||
const FixedPointCoordinate &target_coordinate,
|
||||
const FixedPointCoordinate &query_location)
|
||||
{
|
||||
float ratio;
|
||||
FixedPointCoordinate nearest_location;
|
||||
|
||||
return perpendicular_distance(source_coordinate, target_coordinate, query_location,
|
||||
nearest_location, ratio);
|
||||
}
|
||||
|
||||
float perpendicular_distance(const FixedPointCoordinate &segment_source,
|
||||
const FixedPointCoordinate &segment_target,
|
||||
const FixedPointCoordinate &query_location,
|
||||
FixedPointCoordinate &nearest_location,
|
||||
float &ratio)
|
||||
{
|
||||
return perpendicular_distance_from_projected_coordinate(
|
||||
segment_source, segment_target, query_location,
|
||||
{mercator::lat2y(query_location.lat / COORDINATE_PRECISION),
|
||||
query_location.lon / COORDINATE_PRECISION},
|
||||
nearest_location, ratio);
|
||||
}
|
||||
|
||||
float perpendicular_distance_from_projected_coordinate(
|
||||
const FixedPointCoordinate &source_coordinate,
|
||||
const FixedPointCoordinate &target_coordinate,
|
||||
const FixedPointCoordinate &query_location,
|
||||
const std::pair<double, double> &projected_coordinate)
|
||||
{
|
||||
float ratio;
|
||||
FixedPointCoordinate nearest_location;
|
||||
|
||||
return perpendicular_distance_from_projected_coordinate(source_coordinate, target_coordinate,
|
||||
query_location, projected_coordinate,
|
||||
nearest_location, ratio);
|
||||
}
|
||||
|
||||
float perpendicular_distance_from_projected_coordinate(
|
||||
const FixedPointCoordinate &segment_source,
|
||||
const FixedPointCoordinate &segment_target,
|
||||
const FixedPointCoordinate &query_location,
|
||||
const std::pair<double, double> &projected_coordinate,
|
||||
FixedPointCoordinate &nearest_location,
|
||||
float &ratio)
|
||||
{
|
||||
BOOST_ASSERT(query_location.is_valid());
|
||||
|
||||
// initialize values
|
||||
const double x = projected_coordinate.first;
|
||||
const double y = projected_coordinate.second;
|
||||
const double a = mercator::lat2y(segment_source.lat / COORDINATE_PRECISION);
|
||||
const double b = segment_source.lon / COORDINATE_PRECISION;
|
||||
const double c = mercator::lat2y(segment_target.lat / COORDINATE_PRECISION);
|
||||
const double d = segment_target.lon / COORDINATE_PRECISION;
|
||||
double p, q /*,mX*/, nY;
|
||||
if (std::abs(a - c) > std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
const double m = (d - b) / (c - a); // slope
|
||||
// Projection of (x,y) on line joining (a,b) and (c,d)
|
||||
p = ((x + (m * y)) + (m * m * a - m * b)) / (1.f + m * m);
|
||||
q = b + m * (p - a);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = c;
|
||||
q = y;
|
||||
}
|
||||
nY = (d * p - c * q) / (a * d - b * c);
|
||||
|
||||
// discretize the result to coordinate precision. it's a hack!
|
||||
if (std::abs(nY) < (1.f / COORDINATE_PRECISION))
|
||||
{
|
||||
nY = 0.f;
|
||||
}
|
||||
|
||||
// compute ratio
|
||||
ratio =
|
||||
static_cast<float>((p - nY * a) / c); // These values are actually n/m+n and m/m+n , we need
|
||||
// not calculate the explicit values of m an n as we
|
||||
// are just interested in the ratio
|
||||
if (std::isnan(ratio))
|
||||
{
|
||||
ratio = (segment_target == query_location ? 1.f : 0.f);
|
||||
}
|
||||
else if (std::abs(ratio) <= std::numeric_limits<float>::epsilon())
|
||||
{
|
||||
ratio = 0.f;
|
||||
}
|
||||
else if (std::abs(ratio - 1.f) <= std::numeric_limits<float>::epsilon())
|
||||
{
|
||||
ratio = 1.f;
|
||||
}
|
||||
|
||||
// compute nearest location
|
||||
BOOST_ASSERT(!std::isnan(ratio));
|
||||
if (ratio <= 0.f)
|
||||
{
|
||||
nearest_location = segment_source;
|
||||
}
|
||||
else if (ratio >= 1.f)
|
||||
{
|
||||
nearest_location = segment_target;
|
||||
}
|
||||
else
|
||||
{
|
||||
// point lies in between
|
||||
nearest_location.lat = static_cast<int>(mercator::y2lat(p) * COORDINATE_PRECISION);
|
||||
nearest_location.lon = static_cast<int>(q * COORDINATE_PRECISION);
|
||||
}
|
||||
BOOST_ASSERT(nearest_location.is_valid());
|
||||
|
||||
const float approximate_distance =
|
||||
great_circle_distance(query_location, nearest_location);
|
||||
BOOST_ASSERT(0.f <= approximate_distance);
|
||||
return approximate_distance;
|
||||
}
|
||||
|
||||
void lat_or_lon_to_string(const int value, std::string &output)
|
||||
{
|
||||
char buffer[12];
|
||||
buffer[11] = 0; // zero termination
|
||||
output = printInt<11, 6>(buffer, value);
|
||||
}
|
||||
|
||||
float deg_to_rad(const float degree)
|
||||
{
|
||||
return degree * (static_cast<float>(M_PI) / 180.f);
|
||||
}
|
||||
|
||||
float rad_to_deg(const float radian)
|
||||
{
|
||||
return radian * (180.f * static_cast<float>(M_1_PI));
|
||||
}
|
||||
|
||||
float bearing(const FixedPointCoordinate &first_coordinate,
|
||||
const FixedPointCoordinate &second_coordinate)
|
||||
{
|
||||
const float lon_diff =
|
||||
second_coordinate.lon / COORDINATE_PRECISION - first_coordinate.lon / COORDINATE_PRECISION;
|
||||
const float lon_delta = deg_to_rad(lon_diff);
|
||||
const float lat1 = deg_to_rad(first_coordinate.lat / COORDINATE_PRECISION);
|
||||
const float lat2 = deg_to_rad(second_coordinate.lat / COORDINATE_PRECISION);
|
||||
const float y = std::sin(lon_delta) * std::cos(lat2);
|
||||
const float x =
|
||||
std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(lon_delta);
|
||||
float result = rad_to_deg(std::atan2(y, x));
|
||||
while (result < 0.f)
|
||||
{
|
||||
result += 360.f;
|
||||
}
|
||||
|
||||
while (result >= 360.f)
|
||||
{
|
||||
result -= 360.f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef COORDINATE_CALCULATION
|
||||
#define COORDINATE_CALCULATION
|
||||
|
||||
struct FixedPointCoordinate;
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace coordinate_calculation
|
||||
{
|
||||
double
|
||||
haversine_distance(const int lat1, const int lon1, const int lat2, const int lon2);
|
||||
|
||||
double haversine_distance(const FixedPointCoordinate &first_coordinate,
|
||||
const FixedPointCoordinate &second_coordinate);
|
||||
|
||||
float great_circle_distance(const FixedPointCoordinate &first_coordinate,
|
||||
const FixedPointCoordinate &second_coordinate);
|
||||
|
||||
float great_circle_distance(const int lat1, const int lon1, const int lat2, const int lon2);
|
||||
|
||||
void lat_or_lon_to_string(const int value, std::string &output);
|
||||
|
||||
float perpendicular_distance(const FixedPointCoordinate &segment_source,
|
||||
const FixedPointCoordinate &segment_target,
|
||||
const FixedPointCoordinate &query_location);
|
||||
|
||||
float perpendicular_distance(const FixedPointCoordinate &segment_source,
|
||||
const FixedPointCoordinate &segment_target,
|
||||
const FixedPointCoordinate &query_location,
|
||||
FixedPointCoordinate &nearest_location,
|
||||
float &ratio);
|
||||
|
||||
float perpendicular_distance_from_projected_coordinate(
|
||||
const FixedPointCoordinate &segment_source,
|
||||
const FixedPointCoordinate &segment_target,
|
||||
const FixedPointCoordinate &query_location,
|
||||
const std::pair<double, double> &projected_coordinate);
|
||||
|
||||
float perpendicular_distance_from_projected_coordinate(
|
||||
const FixedPointCoordinate &segment_source,
|
||||
const FixedPointCoordinate &segment_target,
|
||||
const FixedPointCoordinate &query_location,
|
||||
const std::pair<double, double> &projected_coordinate,
|
||||
FixedPointCoordinate &nearest_location,
|
||||
float &ratio);
|
||||
|
||||
float deg_to_rad(const float degree);
|
||||
float rad_to_deg(const float radian);
|
||||
|
||||
float bearing(const FixedPointCoordinate &first_coordinate,
|
||||
const FixedPointCoordinate &second_coordinate);
|
||||
}
|
||||
|
||||
#endif // COORDINATE_CALCULATION
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "douglas_peucker.hpp"
|
||||
|
||||
#include "../data_structures/segment_information.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
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 = std::hypot(x_value_1, y_value_1) * earth_radius;
|
||||
|
||||
// compute distance (b,c)
|
||||
const float x_value_2 = (second_lon - float_lon1) * cos((float_lat1 + second_lat) / 2.f);
|
||||
const float y_value_2 = second_lat - float_lat1;
|
||||
const float dist2 = std::hypot(x_value_2, y_value_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)
|
||||
{
|
||||
const auto 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");
|
||||
auto left_border = begin;
|
||||
auto right_border = std::next(begin);
|
||||
// Sweep over array and identify those ranges that need to be checked
|
||||
do
|
||||
{
|
||||
// traverse list until new border element found
|
||||
if (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,81 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef DOUGLAS_PEUCKER_HPP_
|
||||
#define DOUGLAS_PEUCKER_HPP_
|
||||
|
||||
#include "../data_structures/segment_information.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <stack>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
/* This class object computes the bitvector of indicating generalized input
|
||||
* points according to the (Ramer-)Douglas-Peucker algorithm.
|
||||
*
|
||||
* 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*/
|
||||
|
||||
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,180 +0,0 @@
|
||||
#ifndef GEOSPATIAL_QUERY_HPP
|
||||
#define GEOSPATIAL_QUERY_HPP
|
||||
|
||||
#include "coordinate_calculation.hpp"
|
||||
#include "../typedefs.h"
|
||||
#include "../data_structures/phantom_node.hpp"
|
||||
#include "../util/bearing.hpp"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
// Implements complex queries on top of an RTree and builds PhantomNodes from it.
|
||||
//
|
||||
// Only holds a weak reference on the RTree!
|
||||
template <typename RTreeT> class GeospatialQuery
|
||||
{
|
||||
using EdgeData = typename RTreeT::EdgeData;
|
||||
using CoordinateList = typename RTreeT::CoordinateList;
|
||||
|
||||
public:
|
||||
GeospatialQuery(RTreeT &rtree_, std::shared_ptr<CoordinateList> coordinates_)
|
||||
: rtree(rtree_), coordinates(coordinates_)
|
||||
{
|
||||
}
|
||||
|
||||
// Returns nearest PhantomNodes in the given bearing range within max_distance.
|
||||
// Does not filter by small/big component!
|
||||
std::vector<PhantomNodeWithDistance>
|
||||
NearestPhantomNodesInRange(const FixedPointCoordinate &input_coordinate,
|
||||
const float max_distance,
|
||||
const int bearing = 0,
|
||||
const int bearing_range = 180)
|
||||
{
|
||||
auto results =
|
||||
rtree.Nearest(input_coordinate,
|
||||
[this, bearing, bearing_range, max_distance](const EdgeData &data)
|
||||
{
|
||||
return checkSegmentBearing(data, bearing, bearing_range);
|
||||
},
|
||||
[max_distance](const std::size_t, const float min_dist)
|
||||
{
|
||||
return min_dist > max_distance;
|
||||
});
|
||||
|
||||
return MakePhantomNodes(input_coordinate, results);
|
||||
}
|
||||
|
||||
// Returns max_results nearest PhantomNodes in the given bearing range.
|
||||
// Does not filter by small/big component!
|
||||
std::vector<PhantomNodeWithDistance>
|
||||
NearestPhantomNodes(const FixedPointCoordinate &input_coordinate,
|
||||
const unsigned max_results,
|
||||
const int bearing = 0,
|
||||
const int bearing_range = 180)
|
||||
{
|
||||
auto results = rtree.Nearest(input_coordinate,
|
||||
[this, bearing, bearing_range](const EdgeData &data)
|
||||
{
|
||||
return checkSegmentBearing(data, bearing, bearing_range);
|
||||
},
|
||||
[max_results](const std::size_t num_results, const float)
|
||||
{
|
||||
return num_results >= max_results;
|
||||
});
|
||||
|
||||
return MakePhantomNodes(input_coordinate, results);
|
||||
}
|
||||
|
||||
// Returns the nearest phantom node. If this phantom node is not from a big component
|
||||
// a second phantom node is return that is the nearest coordinate in a big component.
|
||||
std::pair<PhantomNode, PhantomNode>
|
||||
NearestPhantomNodeWithAlternativeFromBigComponent(const FixedPointCoordinate &input_coordinate,
|
||||
const int bearing = 0,
|
||||
const int bearing_range = 180)
|
||||
{
|
||||
bool has_small_component = false;
|
||||
bool has_big_component = false;
|
||||
auto results = rtree.Nearest(
|
||||
input_coordinate,
|
||||
[this, bearing, bearing_range, &has_big_component,
|
||||
&has_small_component](const EdgeData &data)
|
||||
{
|
||||
auto use_segment =
|
||||
(!has_small_component || (!has_big_component && !data.component.is_tiny));
|
||||
auto use_directions = std::make_pair(use_segment, use_segment);
|
||||
|
||||
if (use_segment)
|
||||
{
|
||||
use_directions = checkSegmentBearing(data, bearing, bearing_range);
|
||||
if (use_directions.first || use_directions.second)
|
||||
{
|
||||
has_big_component = has_big_component || !data.component.is_tiny;
|
||||
has_small_component = has_small_component || data.component.is_tiny;
|
||||
}
|
||||
}
|
||||
|
||||
return use_directions;
|
||||
},
|
||||
[&has_big_component](const std::size_t num_results, const float)
|
||||
{
|
||||
return num_results > 0 && has_big_component;
|
||||
});
|
||||
|
||||
if (results.size() == 0)
|
||||
{
|
||||
return std::make_pair(PhantomNode{}, PhantomNode{});
|
||||
}
|
||||
|
||||
BOOST_ASSERT(results.size() > 0);
|
||||
return std::make_pair(MakePhantomNode(input_coordinate, results.front()).phantom_node,
|
||||
MakePhantomNode(input_coordinate, results.back()).phantom_node);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<PhantomNodeWithDistance>
|
||||
MakePhantomNodes(const FixedPointCoordinate &input_coordinate,
|
||||
const std::vector<EdgeData> &results) const
|
||||
{
|
||||
std::vector<PhantomNodeWithDistance> distance_and_phantoms(results.size());
|
||||
std::transform(results.begin(), results.end(), distance_and_phantoms.begin(),
|
||||
[this, &input_coordinate](const EdgeData &data)
|
||||
{
|
||||
return MakePhantomNode(input_coordinate, data);
|
||||
});
|
||||
return distance_and_phantoms;
|
||||
}
|
||||
|
||||
PhantomNodeWithDistance MakePhantomNode(const FixedPointCoordinate &input_coordinate,
|
||||
const EdgeData &data) const
|
||||
{
|
||||
FixedPointCoordinate point_on_segment;
|
||||
float ratio;
|
||||
const auto current_perpendicular_distance = coordinate_calculation::perpendicular_distance(
|
||||
coordinates->at(data.u), coordinates->at(data.v), input_coordinate, point_on_segment,
|
||||
ratio);
|
||||
|
||||
auto transformed =
|
||||
PhantomNodeWithDistance { PhantomNode{data, point_on_segment}, current_perpendicular_distance };
|
||||
|
||||
ratio = std::min(1.f, std::max(0.f, ratio));
|
||||
|
||||
if (SPECIAL_NODEID != transformed.phantom_node.forward_node_id)
|
||||
{
|
||||
transformed.phantom_node.forward_weight *= ratio;
|
||||
}
|
||||
if (SPECIAL_NODEID != transformed.phantom_node.reverse_node_id)
|
||||
{
|
||||
transformed.phantom_node.reverse_weight *= 1.f - ratio;
|
||||
}
|
||||
return transformed;
|
||||
}
|
||||
|
||||
std::pair<bool, bool> checkSegmentBearing(const EdgeData &segment,
|
||||
const float filter_bearing,
|
||||
const float filter_bearing_range)
|
||||
{
|
||||
const float forward_edge_bearing =
|
||||
coordinate_calculation::bearing(coordinates->at(segment.u), coordinates->at(segment.v));
|
||||
|
||||
const float backward_edge_bearing = (forward_edge_bearing + 180) > 360
|
||||
? (forward_edge_bearing - 180)
|
||||
: (forward_edge_bearing + 180);
|
||||
|
||||
const bool forward_bearing_valid =
|
||||
bearing::CheckInBounds(forward_edge_bearing, filter_bearing, filter_bearing_range) &&
|
||||
segment.forward_edge_based_node_id != SPECIAL_NODEID;
|
||||
const bool backward_bearing_valid =
|
||||
bearing::CheckInBounds(backward_edge_bearing, filter_bearing, filter_bearing_range) &&
|
||||
segment.reverse_edge_based_node_id != SPECIAL_NODEID;
|
||||
return std::make_pair(forward_bearing_valid, backward_bearing_valid);
|
||||
}
|
||||
|
||||
RTreeT &rtree;
|
||||
const std::shared_ptr<CoordinateList> coordinates;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,188 +0,0 @@
|
||||
#include "graph_compressor.hpp"
|
||||
|
||||
#include "../data_structures/compressed_edge_container.hpp"
|
||||
#include "../data_structures/dynamic_graph.hpp"
|
||||
#include "../data_structures/node_based_graph.hpp"
|
||||
#include "../data_structures/restriction_map.hpp"
|
||||
#include "../data_structures/percent.hpp"
|
||||
|
||||
#include "../util/simple_logger.hpp"
|
||||
|
||||
GraphCompressor::GraphCompressor(SpeedProfileProperties speed_profile)
|
||||
: speed_profile(std::move(speed_profile))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void GraphCompressor::Compress(const std::unordered_set<NodeID>& barrier_nodes,
|
||||
const std::unordered_set<NodeID>& traffic_lights,
|
||||
RestrictionMap& restriction_map,
|
||||
NodeBasedDynamicGraph& graph,
|
||||
CompressedEdgeContainer& geometry_compressor)
|
||||
{
|
||||
const unsigned original_number_of_nodes = graph.GetNumberOfNodes();
|
||||
const unsigned original_number_of_edges = graph.GetNumberOfEdges();
|
||||
|
||||
Percent progress(original_number_of_nodes);
|
||||
|
||||
for (const NodeID node_v : osrm::irange(0u, original_number_of_nodes))
|
||||
{
|
||||
progress.printStatus(node_v);
|
||||
|
||||
// only contract degree 2 vertices
|
||||
if (2 != graph.GetOutDegree(node_v))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// don't contract barrier node
|
||||
if (barrier_nodes.end() != barrier_nodes.find(node_v))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if v is a via node for a turn restriction, i.e. a 'directed' barrier node
|
||||
if (restriction_map.IsViaNode(node_v))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// reverse_e2 forward_e2
|
||||
// u <---------- v -----------> w
|
||||
// ----------> <-----------
|
||||
// forward_e1 reverse_e1
|
||||
//
|
||||
// Will be compressed to:
|
||||
//
|
||||
// reverse_e1
|
||||
// u <---------- w
|
||||
// ---------->
|
||||
// forward_e1
|
||||
//
|
||||
// If the edges are compatible.
|
||||
|
||||
const bool reverse_edge_order = graph.GetEdgeData(graph.BeginEdges(node_v)).reversed;
|
||||
const EdgeID forward_e2 = graph.BeginEdges(node_v) + reverse_edge_order;
|
||||
BOOST_ASSERT(SPECIAL_EDGEID != forward_e2);
|
||||
BOOST_ASSERT(forward_e2 >= graph.BeginEdges(node_v) &&
|
||||
forward_e2 < graph.EndEdges(node_v));
|
||||
const EdgeID reverse_e2 = graph.BeginEdges(node_v) + 1 - reverse_edge_order;
|
||||
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e2);
|
||||
BOOST_ASSERT(reverse_e2 >= graph.BeginEdges(node_v) &&
|
||||
reverse_e2 < graph.EndEdges(node_v));
|
||||
|
||||
const EdgeData &fwd_edge_data2 = graph.GetEdgeData(forward_e2);
|
||||
const EdgeData &rev_edge_data2 = graph.GetEdgeData(reverse_e2);
|
||||
|
||||
const NodeID node_w = graph.GetTarget(forward_e2);
|
||||
BOOST_ASSERT(SPECIAL_NODEID != node_w);
|
||||
BOOST_ASSERT(node_v != node_w);
|
||||
const NodeID node_u = graph.GetTarget(reverse_e2);
|
||||
BOOST_ASSERT(SPECIAL_NODEID != node_u);
|
||||
BOOST_ASSERT(node_u != node_v);
|
||||
|
||||
const EdgeID forward_e1 = graph.FindEdge(node_u, node_v);
|
||||
BOOST_ASSERT(SPECIAL_EDGEID != forward_e1);
|
||||
BOOST_ASSERT(node_v == graph.GetTarget(forward_e1));
|
||||
const EdgeID reverse_e1 = graph.FindEdge(node_w, node_v);
|
||||
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e1);
|
||||
BOOST_ASSERT(node_v == graph.GetTarget(reverse_e1));
|
||||
|
||||
const EdgeData &fwd_edge_data1 = graph.GetEdgeData(forward_e1);
|
||||
const EdgeData &rev_edge_data1 = graph.GetEdgeData(reverse_e1);
|
||||
|
||||
if (graph.FindEdgeInEitherDirection(node_u, node_w) != SPECIAL_EDGEID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// this case can happen if two ways with different names overlap
|
||||
if (fwd_edge_data1.name_id != rev_edge_data1.name_id ||
|
||||
fwd_edge_data2.name_id != rev_edge_data2.name_id)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fwd_edge_data1.IsCompatibleTo(fwd_edge_data2) && rev_edge_data1.IsCompatibleTo(rev_edge_data2))
|
||||
{
|
||||
BOOST_ASSERT(graph.GetEdgeData(forward_e1).name_id ==
|
||||
graph.GetEdgeData(reverse_e1).name_id);
|
||||
BOOST_ASSERT(graph.GetEdgeData(forward_e2).name_id ==
|
||||
graph.GetEdgeData(reverse_e2).name_id);
|
||||
|
||||
// Get distances before graph is modified
|
||||
const int forward_weight1 = graph.GetEdgeData(forward_e1).distance;
|
||||
const int forward_weight2 = graph.GetEdgeData(forward_e2).distance;
|
||||
|
||||
BOOST_ASSERT(0 != forward_weight1);
|
||||
BOOST_ASSERT(0 != forward_weight2);
|
||||
|
||||
const int reverse_weight1 = graph.GetEdgeData(reverse_e1).distance;
|
||||
const int reverse_weight2 = graph.GetEdgeData(reverse_e2).distance;
|
||||
|
||||
BOOST_ASSERT(0 != reverse_weight1);
|
||||
BOOST_ASSERT(0 != reverse_weight2);
|
||||
|
||||
const bool has_node_penalty = traffic_lights.find(node_v) != traffic_lights.end();
|
||||
|
||||
// add weight of e2's to e1
|
||||
graph.GetEdgeData(forward_e1).distance += fwd_edge_data2.distance;
|
||||
graph.GetEdgeData(reverse_e1).distance += rev_edge_data2.distance;
|
||||
if (has_node_penalty)
|
||||
{
|
||||
graph.GetEdgeData(forward_e1).distance +=
|
||||
speed_profile.traffic_signal_penalty;
|
||||
graph.GetEdgeData(reverse_e1).distance +=
|
||||
speed_profile.traffic_signal_penalty;
|
||||
}
|
||||
|
||||
// extend e1's to targets of e2's
|
||||
graph.SetTarget(forward_e1, node_w);
|
||||
graph.SetTarget(reverse_e1, node_u);
|
||||
|
||||
// remove e2's (if bidir, otherwise only one)
|
||||
graph.DeleteEdge(node_v, forward_e2);
|
||||
graph.DeleteEdge(node_v, reverse_e2);
|
||||
|
||||
// update any involved turn restrictions
|
||||
restriction_map.FixupStartingTurnRestriction(node_u, node_v, node_w);
|
||||
restriction_map.FixupArrivingTurnRestriction(node_u, node_v, node_w, graph);
|
||||
|
||||
restriction_map.FixupStartingTurnRestriction(node_w, node_v, node_u);
|
||||
restriction_map.FixupArrivingTurnRestriction(node_w, node_v, node_u, graph);
|
||||
|
||||
// store compressed geometry in container
|
||||
geometry_compressor.CompressEdge(
|
||||
forward_e1, forward_e2, node_v, node_w,
|
||||
forward_weight1 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0),
|
||||
forward_weight2);
|
||||
geometry_compressor.CompressEdge(
|
||||
reverse_e1, reverse_e2, node_v, node_u, reverse_weight1,
|
||||
reverse_weight2 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0));
|
||||
}
|
||||
}
|
||||
|
||||
PrintStatistics(original_number_of_nodes, original_number_of_edges, graph);
|
||||
}
|
||||
|
||||
void GraphCompressor::PrintStatistics(unsigned original_number_of_nodes,
|
||||
unsigned original_number_of_edges,
|
||||
const NodeBasedDynamicGraph& graph) const
|
||||
{
|
||||
|
||||
unsigned new_node_count = 0;
|
||||
unsigned new_edge_count = 0;
|
||||
|
||||
for (const auto i : osrm::irange(0u, graph.GetNumberOfNodes()))
|
||||
{
|
||||
if (graph.GetOutDegree(i) > 0)
|
||||
{
|
||||
++new_node_count;
|
||||
new_edge_count += (graph.EndEdges(i) - graph.BeginEdges(i));
|
||||
}
|
||||
}
|
||||
SimpleLogger().Write() << "Node compression ratio: "
|
||||
<< new_node_count / (double)original_number_of_nodes;
|
||||
SimpleLogger().Write() << "Edge compression ratio: "
|
||||
<< new_edge_count / (double)original_number_of_edges;
|
||||
}
|
||||
@@ -1,62 +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 "../extractor/speed_profile.hpp"
|
||||
#include "../data_structures/node_based_graph.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
|
||||
class CompressedEdgeContainer;
|
||||
class RestrictionMap;
|
||||
|
||||
class GraphCompressor
|
||||
{
|
||||
using EdgeData = NodeBasedDynamicGraph::EdgeData;
|
||||
|
||||
public:
|
||||
GraphCompressor(SpeedProfileProperties speed_profile);
|
||||
|
||||
void Compress(const std::unordered_set<NodeID>& barrier_nodes,
|
||||
const std::unordered_set<NodeID>& traffic_lights,
|
||||
RestrictionMap& restriction_map,
|
||||
NodeBasedDynamicGraph& graph,
|
||||
CompressedEdgeContainer& geometry_compressor);
|
||||
private:
|
||||
|
||||
void PrintStatistics(unsigned original_number_of_nodes,
|
||||
unsigned original_number_of_edges,
|
||||
const NodeBasedDynamicGraph& graph) const;
|
||||
|
||||
SpeedProfileProperties speed_profile;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef OBJECT_ENCODER_HPP
|
||||
#define OBJECT_ENCODER_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/archive/iterators/base64_from_binary.hpp>
|
||||
#include <boost/archive/iterators/binary_from_base64.hpp>
|
||||
#include <boost/archive/iterators/transform_width.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
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 = reinterpret_cast<const char *>(&object);
|
||||
std::vector<unsigned char> data(sizeof(object));
|
||||
std::copy(char_ptr_to_object, char_ptr_to_object + sizeof(ObjectT), data.begin());
|
||||
|
||||
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)));
|
||||
std::replace(begin(encoded), end(encoded), '+', '-');
|
||||
std::replace(begin(encoded), end(encoded), '/', '_');
|
||||
}
|
||||
|
||||
template <class ObjectT> static void DecodeFromBase64(const std::string &input, ObjectT &object)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string encoded(input);
|
||||
std::replace(begin(encoded), end(encoded), '-', '+');
|
||||
std::replace(begin(encoded), end(encoded), '_', '/');
|
||||
|
||||
std::copy(binary_t(encoded.begin()), binary_t(encoded.begin() + encoded.length()),
|
||||
reinterpret_cast<char *>(&object));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* OBJECT_ENCODER_HPP */
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "polyline_compressor.hpp"
|
||||
#include "../data_structures/segment_information.hpp"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
std::string PolylineCompressor::encode_vector(std::vector<int> &numbers) const
|
||||
{
|
||||
std::string output;
|
||||
const auto end = numbers.size();
|
||||
for (std::size_t i = 0; i < end; ++i)
|
||||
{
|
||||
numbers[i] <<= 1;
|
||||
if (numbers[i] < 0)
|
||||
{
|
||||
numbers[i] = ~(numbers[i]);
|
||||
}
|
||||
}
|
||||
for (const int number : numbers)
|
||||
{
|
||||
output += encode_number(number);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string PolylineCompressor::encode_number(int number_to_encode) const
|
||||
{
|
||||
std::string output;
|
||||
while (number_to_encode >= 0x20)
|
||||
{
|
||||
const int next_value = (0x20 | (number_to_encode & 0x1f)) + 63;
|
||||
output += static_cast<char>(next_value);
|
||||
number_to_encode >>= 5;
|
||||
}
|
||||
|
||||
number_to_encode += 63;
|
||||
output += static_cast<char>(number_to_encode);
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string
|
||||
PolylineCompressor::get_encoded_string(const std::vector<SegmentInformation> &polyline) const
|
||||
{
|
||||
if (polyline.empty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<int> delta_numbers;
|
||||
delta_numbers.reserve((polyline.size() - 1) * 2);
|
||||
FixedPointCoordinate previous_coordinate = {0, 0};
|
||||
for (const auto &segment : polyline)
|
||||
{
|
||||
if (segment.necessary)
|
||||
{
|
||||
const int lat_diff = segment.location.lat - previous_coordinate.lat;
|
||||
const int lon_diff = segment.location.lon - previous_coordinate.lon;
|
||||
delta_numbers.emplace_back(lat_diff);
|
||||
delta_numbers.emplace_back(lon_diff);
|
||||
previous_coordinate = segment.location;
|
||||
}
|
||||
}
|
||||
return encode_vector(delta_numbers);
|
||||
}
|
||||
|
||||
std::vector<FixedPointCoordinate> PolylineCompressor::decode_string(const std::string &geometry_string) const
|
||||
{
|
||||
std::vector<FixedPointCoordinate> new_coordinates;
|
||||
int index = 0, len = geometry_string.size();
|
||||
int lat = 0, lng = 0;
|
||||
|
||||
while (index < len)
|
||||
{
|
||||
int b, shift = 0, result = 0;
|
||||
do
|
||||
{
|
||||
b = geometry_string.at(index++) - 63;
|
||||
result |= (b & 0x1f) << shift;
|
||||
shift += 5;
|
||||
} while (b >= 0x20);
|
||||
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
||||
lat += dlat;
|
||||
|
||||
shift = 0;
|
||||
result = 0;
|
||||
do
|
||||
{
|
||||
b = geometry_string.at(index++) - 63;
|
||||
result |= (b & 0x1f) << shift;
|
||||
shift += 5;
|
||||
} while (b >= 0x20);
|
||||
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
||||
lng += dlng;
|
||||
|
||||
FixedPointCoordinate p;
|
||||
p.lat = COORDINATE_PRECISION * (((double) lat / 1E6));
|
||||
p.lon = COORDINATE_PRECISION * (((double) lng / 1E6));
|
||||
new_coordinates.push_back(p);
|
||||
}
|
||||
|
||||
return new_coordinates;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef POLYLINECOMPRESSOR_H_
|
||||
#define POLYLINECOMPRESSOR_H_
|
||||
|
||||
struct SegmentInformation;
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#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;
|
||||
|
||||
std::vector<FixedPointCoordinate> decode_string(const std::string &geometry_string) const;
|
||||
};
|
||||
|
||||
#endif /* POLYLINECOMPRESSOR_H_ */
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "polyline_formatter.hpp"
|
||||
|
||||
#include "polyline_compressor.hpp"
|
||||
#include "../data_structures/segment_information.hpp"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
osrm::json::String
|
||||
PolylineFormatter::printEncodedString(const std::vector<SegmentInformation> &polyline) const
|
||||
{
|
||||
return osrm::json::String(PolylineCompressor().get_encoded_string(polyline));
|
||||
}
|
||||
|
||||
osrm::json::Array
|
||||
PolylineFormatter::printUnencodedString(const std::vector<SegmentInformation> &polyline) const
|
||||
{
|
||||
osrm::json::Array json_geometry_array;
|
||||
for (const auto &segment : polyline)
|
||||
{
|
||||
if (segment.necessary)
|
||||
{
|
||||
osrm::json::Array json_coordinate;
|
||||
json_coordinate.values.push_back(segment.location.lat / COORDINATE_PRECISION);
|
||||
json_coordinate.values.push_back(segment.location.lon / COORDINATE_PRECISION);
|
||||
json_geometry_array.values.push_back(json_coordinate);
|
||||
}
|
||||
}
|
||||
return json_geometry_array;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef POLYLINE_FORMATTER_HPP
|
||||
#define POLYLINE_FORMATTER_HPP
|
||||
|
||||
struct SegmentInformation;
|
||||
|
||||
#include <osrm/json_container.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct PolylineFormatter
|
||||
{
|
||||
osrm::json::String printEncodedString(const std::vector<SegmentInformation> &polyline) const;
|
||||
|
||||
osrm::json::Array printUnencodedString(const std::vector<SegmentInformation> &polyline) const;
|
||||
};
|
||||
|
||||
#endif /* POLYLINE_FORMATTER_HPP */
|
||||
@@ -1,162 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef 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->get_name_for_id(shortest_segment_1.name_id);
|
||||
route_names.shortest_path_name_2 = facade->get_name_for_id(shortest_segment_2.name_id);
|
||||
|
||||
route_names.alternative_path_name_1 =
|
||||
facade->get_name_for_id(alternative_segment_1.name_id);
|
||||
route_names.alternative_path_name_2 =
|
||||
facade->get_name_for_id(alternative_segment_2.name_id);
|
||||
|
||||
return route_names;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // EXTRACT_ROUTE_NAMES_H
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TRIP_BRUTE_FORCE_HPP
|
||||
#define TRIP_BRUTE_FORCE_HPP
|
||||
|
||||
#include "../data_structures/search_engine.hpp"
|
||||
#include "../util/dist_table_wrapper.hpp"
|
||||
#include "../util/simple_logger.hpp"
|
||||
|
||||
#include <osrm/json_container.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace trip
|
||||
{
|
||||
|
||||
// computes the distance of a given permutation
|
||||
EdgeWeight ReturnDistance(const DistTableWrapper<EdgeWeight> &dist_table,
|
||||
const std::vector<NodeID> &location_order,
|
||||
const EdgeWeight min_route_dist,
|
||||
const std::size_t component_size)
|
||||
{
|
||||
EdgeWeight route_dist = 0;
|
||||
std::size_t i = 0;
|
||||
while (i < location_order.size() && (route_dist < min_route_dist))
|
||||
{
|
||||
route_dist += dist_table(location_order[i], location_order[(i + 1) % component_size]);
|
||||
BOOST_ASSERT_MSG(dist_table(location_order[i], location_order[(i + 1) % component_size]) !=
|
||||
INVALID_EDGE_WEIGHT,
|
||||
"invalid route found");
|
||||
++i;
|
||||
}
|
||||
|
||||
return route_dist;
|
||||
}
|
||||
|
||||
// computes the route by computing all permutations and selecting the shortest
|
||||
template <typename NodeIDIterator>
|
||||
std::vector<NodeID> BruteForceTrip(const NodeIDIterator start,
|
||||
const NodeIDIterator end,
|
||||
const std::size_t number_of_locations,
|
||||
const DistTableWrapper<EdgeWeight> &dist_table)
|
||||
{
|
||||
(void)number_of_locations; // unused
|
||||
|
||||
const auto component_size = std::distance(start, end);
|
||||
|
||||
std::vector<NodeID> perm(start, end);
|
||||
std::vector<NodeID> route;
|
||||
route.reserve(component_size);
|
||||
|
||||
EdgeWeight min_route_dist = INVALID_EDGE_WEIGHT;
|
||||
|
||||
// check length of all possible permutation of the component ids
|
||||
|
||||
BOOST_ASSERT_MSG(perm.size() > 0, "no permutation given");
|
||||
BOOST_ASSERT_MSG(*(std::max_element(std::begin(perm), std::end(perm))) < number_of_locations,
|
||||
"invalid node id");
|
||||
BOOST_ASSERT_MSG(*(std::min_element(std::begin(perm), std::end(perm))) >= 0, "invalid node id");
|
||||
|
||||
do
|
||||
{
|
||||
const auto new_distance = ReturnDistance(dist_table, perm, min_route_dist, component_size);
|
||||
if (new_distance <= min_route_dist)
|
||||
{
|
||||
min_route_dist = new_distance;
|
||||
route = perm;
|
||||
}
|
||||
} while (std::next_permutation(std::begin(perm), std::end(perm)));
|
||||
|
||||
return route;
|
||||
}
|
||||
|
||||
} // end namespace trip
|
||||
} // end namespace osrm
|
||||
#endif // TRIP_BRUTE_FORCE_HPP
|
||||
+60
-8
@@ -8,16 +8,39 @@ 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 CMAKE_NOT_OK
|
||||
|
||||
cmake --version | findstr /C:"3.7.1" && GOTO CMAKE_OK
|
||||
|
||||
:CMAKE_NOT_OK
|
||||
SET CMAKE_VERSION=3.7.1
|
||||
ECHO CMAKE NOT OK - downloading new CMake %CMAKE_VERSION%
|
||||
IF NOT EXIST cm.zip powershell Invoke-WebRequest https://cmake.org/files/v3.7/cmake-%CMAKE_VERSION%-win32-x86.zip -OutFile $env:PROJECT_DIR\cm.zip
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
IF NOT EXIST cmake-%CMAKE_VERSION%-win32-x86 7z -y x cm.zip | %windir%\system32\FIND "ing archive"
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
SET PATH=%PROJECT_DIR%\cmake-%CMAKE_VERSION%-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
|
||||
@@ -33,27 +56,39 @@ IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
|
||||
IF EXIST osrm-deps ECHO deleting osrm-deps... && RD /S /Q osrm-deps
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
IF EXIST build ECHO deletings build dir... && RD /S /Q build
|
||||
IF 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 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 ^
|
||||
@@ -81,14 +116,31 @@ IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
|
||||
SET PATH=%PROJECT_DIR%\osrm-deps\libs\bin;%PATH%
|
||||
|
||||
ECHO running datastructure-tests.exe ...
|
||||
%Configuration%\datastructure-tests.exe
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
ECHO running algorithm-tests.exe ...
|
||||
%Configuration%\algorithm-tests.exe
|
||||
ECHO running extractor-tests.exe ...
|
||||
unit_tests\%Configuration%\extractor-tests.exe
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
|
||||
IF NOT "%APPVEYOR_REPO_BRANCH%"=="develop" GOTO DONE
|
||||
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
|
||||
|
||||
ECHO running library-tests.exe ...
|
||||
SET test_region=monaco
|
||||
SET test_osm=%test_region%.osm.pbf
|
||||
IF NOT EXIST %test_osm% powershell Invoke-WebRequest https://s3.amazonaws.com/mapbox/osrm/testing/monaco.osm.pbf -OutFile %test_osm%
|
||||
%Configuration%\osrm-extract.exe -p ../profiles/car.lua %test_osm%
|
||||
%Configuration%\osrm-contract.exe %test_region%.osrm
|
||||
unit_tests\%Configuration%\library-tests.exe %test_region%.osrm
|
||||
|
||||
IF NOT "%APPVEYOR_REPO_BRANCH%"=="master" GOTO DONE
|
||||
ECHO ========= CREATING PACKAGES ==========
|
||||
|
||||
CD %PROJECT_DIR%\build\%Configuration%
|
||||
|
||||
+15
-7
@@ -3,6 +3,9 @@ environment:
|
||||
- configuration: Release
|
||||
# - configuration: Debug
|
||||
|
||||
install:
|
||||
- ps: Install-Product node 6
|
||||
|
||||
# scripts that are called at very beginning, before repo cloning
|
||||
init:
|
||||
- git config --global core.autocrlf input
|
||||
@@ -17,7 +20,14 @@ platform: x64
|
||||
build_script:
|
||||
- CALL appveyor-build.bat
|
||||
|
||||
test: off
|
||||
before_test:
|
||||
- node --version
|
||||
- npm --version
|
||||
- npm install
|
||||
- npm link
|
||||
- SET PATH=%CD%\osrm-deps\libs\bin;%PATH%
|
||||
- SET OSRM_BUILD_DIR=build\%Configuration%
|
||||
- npm test
|
||||
|
||||
artifacts:
|
||||
- path: osrm_Release.zip
|
||||
@@ -25,6 +35,10 @@ artifacts:
|
||||
# - path: osrm_Debug.zip
|
||||
# name: osrm_Debug.zip
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
deploy:
|
||||
provider: FTP
|
||||
server:
|
||||
@@ -36,9 +50,3 @@ deploy:
|
||||
folder: /
|
||||
enable_ssl: true
|
||||
active_mode: false
|
||||
|
||||
# notifications:
|
||||
# - provider: HipChat
|
||||
# auth_token:
|
||||
# secure: boLE7BjcahdIUxv9jkN7U3F8iOASF+MkhtctlVoWJoo=
|
||||
# room: Directions
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "../data_structures/query_node.hpp"
|
||||
#include "../data_structures/static_rtree.hpp"
|
||||
#include "../data_structures/edge_based_node.hpp"
|
||||
#include "../algorithms/geospatial_query.hpp"
|
||||
#include "../util/timing_util.hpp"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
|
||||
// Choosen by a fair W20 dice roll (this value is completely arbitrary)
|
||||
constexpr unsigned RANDOM_SEED = 13;
|
||||
constexpr int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION;
|
||||
constexpr int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION;
|
||||
constexpr int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION;
|
||||
constexpr int32_t WORLD_MAX_LON = 180 * COORDINATE_PRECISION;
|
||||
|
||||
using RTreeLeaf = EdgeBasedNode;
|
||||
using FixedPointCoordinateListPtr = std::shared_ptr<std::vector<FixedPointCoordinate>>;
|
||||
using BenchStaticRTree = StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, false>::vector, false>;
|
||||
using BenchQuery = GeospatialQuery<BenchStaticRTree>;
|
||||
|
||||
FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes_file)
|
||||
{
|
||||
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
|
||||
|
||||
QueryNode current_node;
|
||||
unsigned coordinate_count = 0;
|
||||
nodes_input_stream.read((char *)&coordinate_count, sizeof(unsigned));
|
||||
auto coords = std::make_shared<std::vector<FixedPointCoordinate>>(coordinate_count);
|
||||
for (unsigned i = 0; i < coordinate_count; ++i)
|
||||
{
|
||||
nodes_input_stream.read((char *)¤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;
|
||||
}
|
||||
|
||||
template <typename QueryT>
|
||||
void BenchmarkQuery(const std::vector<FixedPointCoordinate> &queries,
|
||||
const std::string& name,
|
||||
QueryT query)
|
||||
{
|
||||
std::cout << "Running " << name << " with " << queries.size() << " coordinates: " << std::flush;
|
||||
|
||||
TIMER_START(query);
|
||||
for (const auto &q : queries)
|
||||
{
|
||||
auto result = query(q);
|
||||
}
|
||||
TIMER_STOP(query);
|
||||
|
||||
std::cout << "Took " << TIMER_SEC(query) << " seconds "
|
||||
<< "(" << TIMER_MSEC(query) << "ms"
|
||||
<< ") -> " << TIMER_MSEC(query) / queries.size() << " ms/query "
|
||||
<< "(" << TIMER_MSEC(query) << "ms"
|
||||
<< ")" << std::endl;
|
||||
}
|
||||
|
||||
void Benchmark(BenchStaticRTree &rtree, BenchQuery &geo_query, unsigned num_queries)
|
||||
{
|
||||
std::mt19937 mt_rand(RANDOM_SEED);
|
||||
std::uniform_int_distribution<> lat_udist(WORLD_MIN_LAT, WORLD_MAX_LAT);
|
||||
std::uniform_int_distribution<> lon_udist(WORLD_MIN_LON, WORLD_MAX_LON);
|
||||
std::vector<FixedPointCoordinate> queries;
|
||||
for (unsigned i = 0; i < num_queries; i++)
|
||||
{
|
||||
queries.emplace_back(lat_udist(mt_rand), lon_udist(mt_rand));
|
||||
}
|
||||
|
||||
BenchmarkQuery(queries, "raw RTree queries (1 result)", [&rtree](const FixedPointCoordinate &q)
|
||||
{
|
||||
return rtree.Nearest(q, 1);
|
||||
});
|
||||
BenchmarkQuery(queries, "raw RTree queries (10 results)",
|
||||
[&rtree](const FixedPointCoordinate &q)
|
||||
{
|
||||
return rtree.Nearest(q, 10);
|
||||
});
|
||||
|
||||
BenchmarkQuery(queries, "big component alternative queries",
|
||||
[&geo_query](const FixedPointCoordinate &q)
|
||||
{
|
||||
return geo_query.NearestPhantomNodeWithAlternativeFromBigComponent(q);
|
||||
});
|
||||
BenchmarkQuery(queries, "max distance 1000", [&geo_query](const FixedPointCoordinate &q)
|
||||
{
|
||||
return geo_query.NearestPhantomNodesInRange(q, 1000);
|
||||
});
|
||||
BenchmarkQuery(queries, "PhantomNode query (1 result)", [&geo_query](const FixedPointCoordinate &q)
|
||||
{
|
||||
return geo_query.NearestPhantomNodes(q, 1);
|
||||
});
|
||||
BenchmarkQuery(queries, "PhantomNode query (10 result)", [&geo_query](const FixedPointCoordinate &q)
|
||||
{
|
||||
return geo_query.NearestPhantomNodes(q, 10);
|
||||
});
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 4)
|
||||
{
|
||||
std::cout << "./rtree-bench file.ramIndex file.fileIndx file.nodes"
|
||||
<< "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *ramPath = argv[1];
|
||||
const char *filePath = argv[2];
|
||||
const char *nodesPath = argv[3];
|
||||
|
||||
auto coords = LoadCoordinates(nodesPath);
|
||||
|
||||
BenchStaticRTree rtree(ramPath, filePath, coords);
|
||||
BenchQuery query(rtree, coords);
|
||||
|
||||
Benchmark(rtree, query, 10000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+1
-1
@@ -11,7 +11,7 @@ SET CONFIGURATION=Release
|
||||
FOR /F "tokens=*" %%i in ('git rev-parse --abbrev-ref HEAD') do SET APPVEYOR_REPO_BRANCH=%%i
|
||||
ECHO APPVEYOR_REPO_BRANCH^: %APPVEYOR_REPO_BRANCH%
|
||||
|
||||
SET PATH=C:\mb\windows-builds-64\tmp-bin\cmake-3.4.0-win32-x86\bin;%PATH%
|
||||
SET PATH=C:\mb\windows-builds-64\tmp-bin\cmake-3.7.0-rc2-win32-x86\bin;%PATH%
|
||||
SET PATH=C:\Program Files\7-Zip;%PATH%
|
||||
|
||||
powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
IF(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
MESSAGE(FATAL_ERROR "Cannot configure CPack to generate Debian/RPM packages on non-linux systems.")
|
||||
ENDIF()
|
||||
string(TOLOWER "${CMAKE_PROJECT_NAME}" CPACK_PACKAGE_NAME)
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR ${OSRM_VERSION_MAJOR})
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR ${OSRM_VERSION_MINOR})
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH ${OSRM_VERSION_PATCH})
|
||||
SET(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
|
||||
|
||||
SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY "FALSE")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "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_PACKAGE_CONTACT "Project OSRM <info@project-osrm.org>")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENCE.TXT")
|
||||
|
||||
SET(CPACK_STRIP_FILES "TRUE")
|
||||
file(GLOB_RECURSE ProfileGlob ${CMAKE_SOURCE_DIR}/profiles/*)
|
||||
install(FILES ${ProfileGlob} DESTINATION "share/doc/${CPACK_PACKAGE_NAME}/profiles")
|
||||
|
||||
find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems")
|
||||
if(DPKG_PROGRAM)
|
||||
SET(CPACK_GENERATOR "DEB")
|
||||
execute_process(
|
||||
COMMAND ${DPKG_PROGRAM} --print-architecture
|
||||
OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
|
||||
SET(CPACK_DEBIAN_PACKAGE_SHLIBDEPS "ON")
|
||||
else(DPKG_PROGRAM)
|
||||
find_program(RPM_PROGRAM rpm DOC "rpm RPM-based systems")
|
||||
find_program(RPMBUILD_PROGRAM rpm DOC "rpm RPM-based systems")
|
||||
if(RPMBUILD_PROGRAM)
|
||||
SET(CPACK_GENERATOR "RPM")
|
||||
execute_process(
|
||||
COMMAND ${RPM_PROGRAM} --eval %{_arch}
|
||||
OUTPUT_VARIABLE CPACK_RPM_PACKAGE_ARCHITECTURE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}.${CPACK_RPM_PACKAGE_ARCHITECTURE}")
|
||||
# Exclude /usr/lib64/pkgconfig directory given that it is already owned by the pkg-config rpm package.
|
||||
SET(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/usr/${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
endif(RPMBUILD_PROGRAM)
|
||||
endif(DPKG_PROGRAM)
|
||||
@@ -1,44 +0,0 @@
|
||||
IF(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
MESSAGE(FATAL_ERROR "Cannot configure CPack to generate Debian packages on non-linux systems.")
|
||||
ENDIF()
|
||||
|
||||
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}")
|
||||
|
||||
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_PACKAGE_DESCRIPTION_SUMMARY "Open Source Routing Machine (OSRM).")
|
||||
SET(CPACK_PACKAGE_DESCRIPTION "Open Source Routing Machine (OSRM) is a routing engine.")
|
||||
|
||||
# To create a proper Debian/Ubuntu package, the following CMake
|
||||
# options should be used:
|
||||
|
||||
SET(CPACK_STRIP_FILES "TRUE")
|
||||
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_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, 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;")
|
||||
|
||||
MESSAGE(STATUS "Debian Package: ${CPACK_DEBIAN_PACKAGE_NAME} (${CPACK_DEBIAN_PACKAGE_VERSION}) [${CPACK_PACKAGE_FILE_NAME}.deb]")
|
||||
@@ -0,0 +1,194 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#.rst:
|
||||
# FindLua
|
||||
# -------
|
||||
#
|
||||
#
|
||||
#
|
||||
# Locate Lua library This module defines
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# LUA_FOUND - if false, do not try to link to Lua
|
||||
# LUA_LIBRARIES - both lua and lualib
|
||||
# LUA_INCLUDE_DIR - where to find lua.h
|
||||
# LUA_VERSION_STRING - the version of Lua found
|
||||
# LUA_VERSION_MAJOR - the major version of Lua
|
||||
# LUA_VERSION_MINOR - the minor version of Lua
|
||||
# LUA_VERSION_PATCH - the patch version of Lua
|
||||
#
|
||||
#
|
||||
#
|
||||
# Note that the expected include convention is
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# #include "lua.h"
|
||||
#
|
||||
# and not
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# #include <lua/lua.h>
|
||||
#
|
||||
# This is because, the lua location is not standardized and may exist in
|
||||
# locations other than lua/
|
||||
|
||||
unset(_lua_include_subdirs)
|
||||
unset(_lua_library_names)
|
||||
unset(_lua_append_versions)
|
||||
|
||||
# this is a function only to have all the variables inside go away automatically
|
||||
function(_lua_set_version_vars)
|
||||
set(LUA_VERSIONS5 5.3 5.2 5.1 5.0)
|
||||
|
||||
if (Lua_FIND_VERSION_EXACT)
|
||||
if (Lua_FIND_VERSION_COUNT GREATER 1)
|
||||
set(_lua_append_versions ${Lua_FIND_VERSION_MAJOR}.${Lua_FIND_VERSION_MINOR})
|
||||
endif ()
|
||||
elseif (Lua_FIND_VERSION)
|
||||
# once there is a different major version supported this should become a loop
|
||||
if (NOT Lua_FIND_VERSION_MAJOR GREATER 5)
|
||||
if (Lua_FIND_VERSION_COUNT EQUAL 1)
|
||||
set(_lua_append_versions ${LUA_VERSIONS5})
|
||||
else ()
|
||||
foreach (subver IN LISTS LUA_VERSIONS5)
|
||||
if (NOT subver VERSION_LESS ${Lua_FIND_VERSION})
|
||||
list(APPEND _lua_append_versions ${subver})
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
endif ()
|
||||
else ()
|
||||
# once there is a different major version supported this should become a loop
|
||||
set(_lua_append_versions ${LUA_VERSIONS5})
|
||||
endif ()
|
||||
|
||||
list(APPEND _lua_include_subdirs "include/lua" "include")
|
||||
|
||||
foreach (ver IN LISTS _lua_append_versions)
|
||||
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)$" _ver "${ver}")
|
||||
list(APPEND _lua_include_subdirs
|
||||
include/lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
|
||||
include/lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
||||
include/lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
||||
)
|
||||
list(APPEND _lua_library_names
|
||||
lua${CMAKE_MATCH_1}${CMAKE_MATCH_2}
|
||||
lua${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
||||
lua-${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
||||
lua.${CMAKE_MATCH_1}.${CMAKE_MATCH_2}
|
||||
)
|
||||
endforeach ()
|
||||
|
||||
set(_lua_include_subdirs "${_lua_include_subdirs}" PARENT_SCOPE)
|
||||
set(_lua_library_names "${_lua_library_names}" PARENT_SCOPE)
|
||||
set(_lua_append_versions "${_lua_append_versions}" PARENT_SCOPE)
|
||||
endfunction(_lua_set_version_vars)
|
||||
|
||||
function(_lua_check_header_version _hdr_file)
|
||||
# At least 5.[012] have different ways to express the version
|
||||
# so all of them need to be tested. Lua 5.2 defines LUA_VERSION
|
||||
# and LUA_RELEASE as joined by the C preprocessor, so avoid those.
|
||||
file(STRINGS "${_hdr_file}" lua_version_strings
|
||||
REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*")
|
||||
|
||||
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};")
|
||||
if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$")
|
||||
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};")
|
||||
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};")
|
||||
set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}")
|
||||
else ()
|
||||
string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
|
||||
if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$")
|
||||
string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};")
|
||||
endif ()
|
||||
string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}")
|
||||
string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}")
|
||||
endif ()
|
||||
foreach (ver IN LISTS _lua_append_versions)
|
||||
if (ver STREQUAL "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}")
|
||||
set(LUA_VERSION_MAJOR ${LUA_VERSION_MAJOR} PARENT_SCOPE)
|
||||
set(LUA_VERSION_MINOR ${LUA_VERSION_MINOR} PARENT_SCOPE)
|
||||
set(LUA_VERSION_PATCH ${LUA_VERSION_PATCH} PARENT_SCOPE)
|
||||
set(LUA_VERSION_STRING ${LUA_VERSION_STRING} PARENT_SCOPE)
|
||||
return()
|
||||
endif ()
|
||||
endforeach ()
|
||||
endfunction(_lua_check_header_version)
|
||||
|
||||
_lua_set_version_vars()
|
||||
|
||||
if (LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
|
||||
_lua_check_header_version("${LUA_INCLUDE_DIR}/lua.h")
|
||||
endif ()
|
||||
|
||||
if (NOT LUA_VERSION_STRING)
|
||||
foreach (subdir IN LISTS _lua_include_subdirs)
|
||||
unset(LUA_INCLUDE_PREFIX CACHE)
|
||||
find_path(LUA_INCLUDE_PREFIX ${subdir}/lua.h
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
if (LUA_INCLUDE_PREFIX)
|
||||
_lua_check_header_version("${LUA_INCLUDE_PREFIX}/${subdir}/lua.h")
|
||||
if (LUA_VERSION_STRING)
|
||||
set(LUA_INCLUDE_DIR "${LUA_INCLUDE_PREFIX}/${subdir}")
|
||||
break()
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
endif ()
|
||||
unset(_lua_include_subdirs)
|
||||
unset(_lua_append_versions)
|
||||
|
||||
find_library(LUA_LIBRARY
|
||||
NAMES ${_lua_library_names} lua
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATH_SUFFIXES lib
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
unset(_lua_library_names)
|
||||
|
||||
if (LUA_LIBRARY)
|
||||
# include the math library for Unix
|
||||
if (UNIX AND NOT APPLE AND NOT BEOS)
|
||||
find_library(LUA_MATH_LIBRARY m)
|
||||
set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}")
|
||||
|
||||
# include dl library for statically-linked Lua library
|
||||
get_filename_component(LUA_LIB_EXT ${LUA_LIBRARY} EXT)
|
||||
if(LUA_LIB_EXT STREQUAL CMAKE_STATIC_LIBRARY_SUFFIX)
|
||||
list(APPEND LUA_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
# For Windows and Mac, don't need to explicitly include the math library
|
||||
else ()
|
||||
set(LUA_LIBRARIES "${LUA_LIBRARY}")
|
||||
endif ()
|
||||
endif ()
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua
|
||||
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
|
||||
VERSION_VAR LUA_VERSION_STRING)
|
||||
|
||||
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY)
|
||||
@@ -1,82 +0,0 @@
|
||||
# Locate Lua library
|
||||
# This module defines
|
||||
# LUA52_FOUND, if false, do not try to link to Lua
|
||||
# LUA_LIBRARIES
|
||||
# LUA_INCLUDE_DIR, where to find lua.h
|
||||
# LUA_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
|
||||
#
|
||||
# Note that the expected include convention is
|
||||
# #include "lua.h"
|
||||
# and not
|
||||
# #include <lua/lua.h>
|
||||
# This is because, the lua location is not standardized and may exist
|
||||
# in locations other than lua/
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2007-2009 Kitware, Inc.
|
||||
# Copyright 2013 for Project-OSRM, Lua5.1 => Lua5.2
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
find_path(LUA_INCLUDE_DIR lua.h
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATH_SUFFIXES include/lua52 include/lua5.2 include/lua-5.2 include/lua include
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
|
||||
find_library(LUA_LIBRARY
|
||||
NAMES lua52 lua5.2 lua-5.2 lua
|
||||
HINTS
|
||||
ENV LUA_DIR
|
||||
PATH_SUFFIXES lib
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
|
||||
if(LUA_LIBRARY)
|
||||
# include the math library for Unix
|
||||
if(UNIX AND NOT APPLE AND NOT BEOS)
|
||||
find_library(LUA_MATH_LIBRARY m)
|
||||
set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
# For Windows and Mac, don't need to explicitly include the math library
|
||||
else()
|
||||
set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h")
|
||||
file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
|
||||
|
||||
string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}")
|
||||
unset(lua_version_str)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua52
|
||||
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
|
||||
VERSION_VAR LUA_VERSION_STRING)
|
||||
|
||||
mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
# Locate Lua library
|
||||
# This module defines
|
||||
# LUAJIT_FOUND, if false, do not try to link to Lua
|
||||
# LUAJIT_LIBRARIES
|
||||
# LUAJIT_INCLUDE_DIR, where to find lua.h
|
||||
#
|
||||
# Note that the expected include convention is
|
||||
# #include "lua.h"
|
||||
# and not
|
||||
# #include <lua/lua.h>
|
||||
# This is because, the lua location is not standardized and may exist
|
||||
# in locations other than lua/
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2007-2009 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distributed this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
#
|
||||
# ################
|
||||
# 2010 - modified for cronkite to find luajit instead of lua, as it was before.
|
||||
#
|
||||
|
||||
if ( NOT LuaJIT_FIND_VERSION )
|
||||
MESSAGE(FATAL_ERROR "You need to specify a version of libluajit to use")
|
||||
ENDIF()
|
||||
|
||||
IF( NOT LUAJIT_FIND_QUIETLY )
|
||||
MESSAGE(STATUS "Looking for LuaJIT ${LuaJIT_FIND_VERSION}")
|
||||
ENDIF()
|
||||
|
||||
FIND_PATH(LUAJIT_INCLUDE_DIR lua.h
|
||||
HINTS
|
||||
$ENV{LUAJIT_DIR}
|
||||
PATH_SUFFIXES include/luajit-2.0 include/luajit2.0 include/luajit include
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local
|
||||
/usr
|
||||
/sw # Fink
|
||||
/opt/local # DarwinPorts
|
||||
/opt/csw # Blastwave
|
||||
/opt
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LUAJIT_LIBRARY
|
||||
NAMES luajit-${LuaJIT_FIND_VERSION_MAJOR}${LuaJIT_FIND_VERSION_MINOR} luajit-${LuaJIT_FIND_VERSION}
|
||||
HINTS
|
||||
$ENV{LUAJIT_DIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local
|
||||
/usr
|
||||
/sw
|
||||
/opt/local
|
||||
/opt/csw
|
||||
/opt
|
||||
)
|
||||
|
||||
IF(LUAJIT_LIBRARY)
|
||||
# include the math library for Unix
|
||||
IF(UNIX AND NOT APPLE)
|
||||
FIND_LIBRARY(LUAJIT_MATH_LIBRARY m)
|
||||
SET( LUAJIT_LIBRARIES "${LUAJIT_LIBRARY};${LUAJIT_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
# For Windows and Mac, don't need to explicitly include the math library
|
||||
ELSE(UNIX AND NOT APPLE)
|
||||
SET( LUAJIT_LIBRARIES "${LUAJIT_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||
ENDIF(UNIX AND NOT APPLE)
|
||||
ENDIF(LUAJIT_LIBRARY)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LUAJIT DEFAULT_MSG LUAJIT_LIBRARIES LUAJIT_INCLUDE_DIR)
|
||||
|
||||
IF( NOT LUAJIT_FIND_QUIETLY )
|
||||
IF( LUAJIT_FOUND AND LUAJIT_LIBRARIES)
|
||||
MESSAGE(STATUS "Found LuaJIT: ${LUAJIT_LIBRARY}" )
|
||||
MARK_AS_ADVANCED(LUAJIT_INCLUDE_DIR LUAJIT_LIBRARIES LUAJIT_LIBRARY LUAJIT_MATH_LIBRARY)
|
||||
ELSE()
|
||||
SET ( LUAJIT_FOUND FALSE )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
@@ -1,75 +0,0 @@
|
||||
# Locate Luabind library
|
||||
# This module defines
|
||||
# LUABIND_FOUND, if false, do not try to link to Luabind
|
||||
# LUABIND_LIBRARIES
|
||||
# LUABIND_INCLUDE_DIR, where to find luabind.hpp
|
||||
#
|
||||
# Note that the expected include convention is
|
||||
# #include <luabind/luabind.hpp>
|
||||
# and not
|
||||
# #include <luabind.hpp>
|
||||
|
||||
IF( NOT LUABIND_FIND_QUIETLY )
|
||||
MESSAGE(STATUS "Looking for Luabind...")
|
||||
ENDIF()
|
||||
|
||||
FIND_PATH(LUABIND_INCLUDE_DIR luabind.hpp
|
||||
HINTS
|
||||
$ENV{LUABIND_DIR}
|
||||
PATH_SUFFIXES luabind include/luabind include
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local
|
||||
/usr
|
||||
/opt/local # DarwinPorts
|
||||
/opt
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LUABIND_LIBRARY
|
||||
NAMES luabind luabind09
|
||||
HINTS
|
||||
$ENV{LUABIND_DIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local
|
||||
/usr
|
||||
/opt/local
|
||||
/opt
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LUABIND_LIBRARY_DBG
|
||||
NAMES luabindd
|
||||
HINTS
|
||||
$ENV{LUABIND_DIR}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/usr/local
|
||||
/usr
|
||||
/opt/local
|
||||
/opt
|
||||
)
|
||||
|
||||
IF(LUABIND_LIBRARY)
|
||||
SET( LUABIND_LIBRARIES "${LUABIND_LIBRARY}" CACHE STRING "Luabind Libraries")
|
||||
ENDIF(LUABIND_LIBRARY)
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LUABIND_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Luabind DEFAULT_MSG LUABIND_LIBRARIES LUABIND_INCLUDE_DIR)
|
||||
|
||||
IF( NOT LUABIND_FIND_QUIETLY )
|
||||
IF( LUABIND_FOUND )
|
||||
MESSAGE(STATUS "Found Luabind: ${LUABIND_LIBRARY}" )
|
||||
ENDIF()
|
||||
IF( LUABIND_LIBRARY_DBG )
|
||||
MESSAGE(STATUS "Luabind debug library availible: ${LUABIND_LIBRARY_DBG}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(LUABIND_INCLUDE_DIR LUABIND_LIBRARIES LUABIND_LIBRARY LUABIND_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
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# - Try to find Shapefile C Library
|
||||
# http://shapelib.maptools.org/
|
||||
#
|
||||
# Exports:
|
||||
# Shapefile_FOUND
|
||||
# LIBSHAPEFILE_INCLUDE_DIR
|
||||
# LIBSHAPEFILE_LIBRARY
|
||||
# Hints:
|
||||
# LIBSHAPEFILE_LIBRARY_DIR
|
||||
|
||||
find_path(LIBSHAPEFILE_INCLUDE_DIR
|
||||
shapefil.h)
|
||||
|
||||
find_library(LIBSHAPEFILE_LIBRARY
|
||||
NAMES shp
|
||||
HINTS "${LIBSHAPEFILE_LIBRARY_DIR}")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Shapefile DEFAULT_MSG
|
||||
LIBSHAPEFILE_LIBRARY LIBSHAPEFILE_INCLUDE_DIR)
|
||||
mark_as_advanced(LIBSHAPEFILE_INCLUDE_DIR LIBSHAPEFILE_LIBRARY)
|
||||
@@ -280,4 +280,5 @@ if (TBB_FOUND)
|
||||
FILE(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS)
|
||||
STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}")
|
||||
set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}")
|
||||
message(STATUS "TBB interface version: ${TBB_INTERFACE_VERSION}")
|
||||
endif (TBB_FOUND)
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
set(OLDFILE ${OUTPUT_DIR}/util/fingerprint_impl.hpp)
|
||||
set(NEWFILE ${OLDFILE}.tmp)
|
||||
set(INFILE ${SOURCE_DIR}/util/fingerprint_impl.hpp.in)
|
||||
file(MD5 ${SOURCE_DIR}/prepare.cpp MD5PREPARE)
|
||||
file(MD5 ${SOURCE_DIR}/data_structures/static_rtree.hpp MD5RTREE)
|
||||
file(MD5 ${SOURCE_DIR}/util/graph_loader.hpp MD5GRAPH)
|
||||
file(MD5 ${SOURCE_DIR}/server/data_structures/internal_datafacade.hpp MD5OBJECTS)
|
||||
|
||||
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,40 +0,0 @@
|
||||
INCLUDE (CheckCXXSourceCompiles)
|
||||
unset(LUABIND_WORKS CACHE)
|
||||
unset(LUABIND51_WORKS CACHE)
|
||||
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}")
|
||||
|
||||
find_package(Lua52)
|
||||
if(NOT APPLE)
|
||||
find_package(LuaJIT 5.2)
|
||||
endif()
|
||||
if(LUA52_FOUND)
|
||||
set (CMAKE_REQUIRED_INCLUDES "${Boost_INCLUDE_DIR};${LUABIND_INCLUDE_DIR};${LUA_INCLUDE_DIR}")
|
||||
set (CMAKE_REQUIRED_LIBRARIES "${LUABIND_LIBRARY};${LUA_LIBRARY}")
|
||||
CHECK_CXX_SOURCE_COMPILES("${LUABIND_CHECK_SRC}" LUABIND_WORKS)
|
||||
endif()
|
||||
|
||||
if(LUABIND_WORKS)
|
||||
message(STATUS "Luabind/Lua5.2 combination working with ${LUA_LIBRARY}")
|
||||
else()
|
||||
message(STATUS "Luabind/Lua5.2 not feasible, falling back to Lua 5.1.")
|
||||
unset(LUA_FOUND CACHE)
|
||||
unset(LUA_INCLUDE_DIR CACHE)
|
||||
unset(LUA_LIBRARY CACHE)
|
||||
find_package(Lua51 REQUIRED)
|
||||
if(NOT APPLE)
|
||||
find_package(LuaJIT 5.1)
|
||||
endif()
|
||||
set (CMAKE_REQUIRED_INCLUDES "${Boost_INCLUDE_DIR};${LUABIND_INCLUDE_DIR};${LUA_INCLUDE_DIR}")
|
||||
set (CMAKE_REQUIRED_LIBRARIES "${LUABIND_LIBRARY};${LUA_LIBRARY}")
|
||||
|
||||
CHECK_CXX_SOURCE_COMPILES("${LUABIND_CHECK_SRC}" LUABIND51_WORKS)
|
||||
|
||||
if(LUABIND51_WORKS)
|
||||
message(STATUS "Luabind works with Lua 5.1 at ${LUA_LIBRARY}")
|
||||
else()
|
||||
message(FATAL_ERROR "Luabind does not work with Lua 5.1 at ${LUA_LIBRARY}, no working Luabind found")
|
||||
endif()
|
||||
endif()
|
||||
@@ -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)
|
||||
+6
-6
@@ -1,11 +1,11 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
includedir=${prefix}/include
|
||||
libdir=${prefix}/lib
|
||||
includedir=@PKGCONFIG_INCLUDE_DIR@
|
||||
libdir=@PKGCONFIG_LIBRARY_DIR@
|
||||
|
||||
Name: libOSRM
|
||||
Description: Project OSRM library
|
||||
Version: v@OSRM_VERSION_MAJOR@.@OSRM_VERSION_MINOR@.@OSRM_VERSION_PATCH@
|
||||
Version: v@OSRM_VERSION@
|
||||
Requires:
|
||||
Libs: -L${libdir} -lOSRM
|
||||
Libs.private: @BOOST_LIBRARY_LISTING@ @TBB_LIBRARY_LISTING@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -losrm @PKGCONFIG_OSRM_LDFLAGS@
|
||||
Libs.private: @PKGCONFIG_OSRM_DEPENDENT_LIBRARIES@
|
||||
Cflags: @PKGCONFIG_OSRM_INCLUDE_FLAGS@ @PKGCONFIG_OSRM_CXXFLAGS@
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
#/usr/bin/env bash
|
||||
ln -s /usr/share/doc/@CMAKE_PROJECT_NAME@/profiles/car.lua @CMAKE_INSTALL_PREFIX@/profile.lua
|
||||
@@ -0,0 +1,7 @@
|
||||
coverage:
|
||||
|
||||
ignore:
|
||||
- unit_tests/.*
|
||||
- third_party/.*
|
||||
|
||||
comment: off
|
||||
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "contractor_options.hpp"
|
||||
|
||||
#include "util/version.hpp"
|
||||
#include "../util/simple_logger.hpp"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <tbb/task_scheduler_init.h>
|
||||
|
||||
return_code
|
||||
ContractorOptions::ParseArguments(int argc, char *argv[], ContractorConfig &contractor_config)
|
||||
{
|
||||
// declare a group of options that will be allowed only on command line
|
||||
boost::program_options::options_description generic_options("Options");
|
||||
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
|
||||
"config,c", boost::program_options::value<boost::filesystem::path>(&contractor_config.config_file_path)
|
||||
->default_value("contractor.ini"),
|
||||
"Path to a configuration file.");
|
||||
|
||||
// declare a group of options that will be allowed both on command line and in config file
|
||||
boost::program_options::options_description config_options("Configuration");
|
||||
config_options.add_options()(
|
||||
"profile,p",
|
||||
boost::program_options::value<boost::filesystem::path>(&contractor_config.profile_path)
|
||||
->default_value("profile.lua"),
|
||||
"Path to LUA routing profile")(
|
||||
"threads,t",
|
||||
boost::program_options::value<unsigned int>(&contractor_config.requested_num_threads)
|
||||
->default_value(tbb::task_scheduler_init::default_num_threads()),
|
||||
"Number of threads to use")(
|
||||
"core,k", boost::program_options::value<double>(&contractor_config.core_factor)
|
||||
->default_value(1.0),"Percentage of the graph (in vertices) to contract [0..1]")(
|
||||
"segment-speed-file", boost::program_options::value<std::string>(&contractor_config.segment_speed_lookup_path),
|
||||
"Lookup file containing nodeA,nodeB,speed data to adjust edge weights")(
|
||||
"level-cache,o",
|
||||
boost::program_options::value<bool>(&contractor_config.use_cached_priority)->default_value(false),
|
||||
"Use .level file to retain the contaction level for each node from the last run.");
|
||||
|
||||
#ifdef DEBUG_GEOMETRY
|
||||
config_options.add_options()(
|
||||
"debug-geometry", boost::program_options::value<std::string>(&contractor_config.debug_geometry_path)
|
||||
,"Write out edge-weight debugging geometry data in GeoJSON format to this file");
|
||||
#endif
|
||||
|
||||
// hidden options, will be allowed both on command line and in config file, but will not be
|
||||
// shown to the user
|
||||
boost::program_options::options_description hidden_options("Hidden options");
|
||||
hidden_options.add_options()(
|
||||
"input,i", boost::program_options::value<boost::filesystem::path>(&contractor_config.osrm_input_path),
|
||||
"Input file in .osm, .osm.bz2 or .osm.pbf format");
|
||||
|
||||
// positional option
|
||||
boost::program_options::positional_options_description positional_options;
|
||||
positional_options.add("input", 1);
|
||||
|
||||
// combine above options for parsing
|
||||
boost::program_options::options_description cmdline_options;
|
||||
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
|
||||
|
||||
boost::program_options::options_description config_file_options;
|
||||
config_file_options.add(config_options).add(hidden_options);
|
||||
|
||||
boost::program_options::options_description visible_options(
|
||||
"Usage: " + boost::filesystem::basename(argv[0]) + " <input.osrm> [options]");
|
||||
visible_options.add(generic_options).add(config_options);
|
||||
|
||||
// parse command line options
|
||||
boost::program_options::variables_map option_variables;
|
||||
boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
|
||||
.options(cmdline_options)
|
||||
.positional(positional_options)
|
||||
.run(),
|
||||
option_variables);
|
||||
|
||||
const auto &temp_config_path = option_variables["config"].as<boost::filesystem::path>();
|
||||
if (boost::filesystem::is_regular_file(temp_config_path))
|
||||
{
|
||||
boost::program_options::store(boost::program_options::parse_config_file<char>(
|
||||
temp_config_path.string().c_str(), cmdline_options, true),
|
||||
option_variables);
|
||||
}
|
||||
|
||||
if (option_variables.count("version"))
|
||||
{
|
||||
SimpleLogger().Write() << OSRM_VERSION;
|
||||
return return_code::exit;
|
||||
}
|
||||
|
||||
if (option_variables.count("help"))
|
||||
{
|
||||
SimpleLogger().Write() << "\n" << visible_options;
|
||||
return return_code::exit;
|
||||
}
|
||||
|
||||
boost::program_options::notify(option_variables);
|
||||
|
||||
if (!option_variables.count("input"))
|
||||
{
|
||||
SimpleLogger().Write() << "\n" << visible_options;
|
||||
return return_code::fail;
|
||||
}
|
||||
|
||||
return return_code::ok;
|
||||
}
|
||||
|
||||
void ContractorOptions::GenerateOutputFilesNames(ContractorConfig &contractor_config)
|
||||
{
|
||||
contractor_config.level_output_path = contractor_config.osrm_input_path.string() + ".level";
|
||||
contractor_config.core_output_path = contractor_config.osrm_input_path.string() + ".core";
|
||||
contractor_config.graph_output_path = contractor_config.osrm_input_path.string() + ".hsgr";
|
||||
contractor_config.edge_based_graph_path = contractor_config.osrm_input_path.string() + ".ebg";
|
||||
contractor_config.edge_segment_lookup_path = contractor_config.osrm_input_path.string() + ".edge_segment_lookup";
|
||||
contractor_config.edge_penalty_path = contractor_config.osrm_input_path.string() + ".edge_penalties";
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CONTRACTOR_OPTIONS_HPP
|
||||
#define CONTRACTOR_OPTIONS_HPP
|
||||
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
enum class return_code : unsigned
|
||||
{
|
||||
ok,
|
||||
fail,
|
||||
exit
|
||||
};
|
||||
|
||||
struct ContractorConfig
|
||||
{
|
||||
ContractorConfig() noexcept : requested_num_threads(0) {}
|
||||
|
||||
boost::filesystem::path config_file_path;
|
||||
boost::filesystem::path osrm_input_path;
|
||||
boost::filesystem::path profile_path;
|
||||
|
||||
std::string level_output_path;
|
||||
std::string core_output_path;
|
||||
std::string graph_output_path;
|
||||
std::string edge_based_graph_path;
|
||||
|
||||
std::string edge_segment_lookup_path;
|
||||
std::string edge_penalty_path;
|
||||
bool use_cached_priority;
|
||||
|
||||
unsigned requested_num_threads;
|
||||
|
||||
//A percentage of vertices that will be contracted for the hierarchy.
|
||||
//Offers a trade-off between preprocessing and query time.
|
||||
//The remaining vertices form the core of the hierarchy
|
||||
//(e.g. 0.8 contracts 80 percent of the hierarchy, leaving a core of 20%)
|
||||
double core_factor;
|
||||
|
||||
std::string segment_speed_lookup_path;
|
||||
|
||||
#ifdef DEBUG_GEOMETRY
|
||||
std::string debug_geometry_path;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ContractorOptions
|
||||
{
|
||||
static return_code ParseArguments(int argc, char *argv[], ContractorConfig &extractor_config);
|
||||
|
||||
static void GenerateOutputFilesNames(ContractorConfig &extractor_config);
|
||||
};
|
||||
|
||||
#endif // EXTRACTOR_OPTIONS_HPP
|
||||
@@ -1,441 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "processing_chain.hpp"
|
||||
#include "contractor.hpp"
|
||||
|
||||
#include "contractor.hpp"
|
||||
|
||||
#include "../data_structures/deallocating_vector.hpp"
|
||||
|
||||
#include "../algorithms/crc32_processor.hpp"
|
||||
#include "../util/graph_loader.hpp"
|
||||
#include "../util/integer_range.hpp"
|
||||
#include "../util/lua_util.hpp"
|
||||
#include "../util/osrm_exception.hpp"
|
||||
#include "../util/simple_logger.hpp"
|
||||
#include "../util/string_util.hpp"
|
||||
#include "../util/timing_util.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <fast-cpp-csv-parser/csv.h>
|
||||
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "../util/debug_geometry.hpp"
|
||||
|
||||
Prepare::~Prepare() {}
|
||||
|
||||
int Prepare::Run()
|
||||
{
|
||||
#ifdef WIN32
|
||||
#pragma message("Memory consumption on Windows can be higher due to different bit packing")
|
||||
#else
|
||||
static_assert(sizeof(NodeBasedEdge) == 20,
|
||||
"changing NodeBasedEdge type has influence on memory consumption!");
|
||||
static_assert(sizeof(EdgeBasedEdge) == 16,
|
||||
"changing EdgeBasedEdge type has influence on memory consumption!");
|
||||
#endif
|
||||
|
||||
if (config.core_factor > 1.0 || config.core_factor < 0)
|
||||
{
|
||||
throw osrm::exception("Core factor must be between 0.0 to 1.0 (inclusive)");
|
||||
}
|
||||
|
||||
TIMER_START(preparing);
|
||||
|
||||
// Create a new lua state
|
||||
|
||||
SimpleLogger().Write() << "Loading edge-expanded graph representation";
|
||||
|
||||
DeallocatingVector<EdgeBasedEdge> edge_based_edge_list;
|
||||
|
||||
size_t max_edge_id = LoadEdgeExpandedGraph(
|
||||
config.edge_based_graph_path, edge_based_edge_list, config.edge_segment_lookup_path,
|
||||
config.edge_penalty_path, config.segment_speed_lookup_path);
|
||||
|
||||
// Contracting the edge-expanded graph
|
||||
|
||||
TIMER_START(contraction);
|
||||
std::vector<bool> is_core_node;
|
||||
std::vector<float> node_levels;
|
||||
if (config.use_cached_priority)
|
||||
{
|
||||
ReadNodeLevels(node_levels);
|
||||
}
|
||||
DeallocatingVector<QueryEdge> contracted_edge_list;
|
||||
ContractGraph(max_edge_id, edge_based_edge_list, contracted_edge_list, is_core_node,
|
||||
node_levels);
|
||||
TIMER_STOP(contraction);
|
||||
|
||||
SimpleLogger().Write() << "Contraction took " << TIMER_SEC(contraction) << " sec";
|
||||
|
||||
std::size_t number_of_used_edges = WriteContractedGraph(max_edge_id, contracted_edge_list);
|
||||
WriteCoreNodeMarker(std::move(is_core_node));
|
||||
if (!config.use_cached_priority)
|
||||
{
|
||||
WriteNodeLevels(std::move(node_levels));
|
||||
}
|
||||
|
||||
TIMER_STOP(preparing);
|
||||
|
||||
SimpleLogger().Write() << "Preprocessing : " << TIMER_SEC(preparing) << " seconds";
|
||||
SimpleLogger().Write() << "Contraction: " << ((max_edge_id + 1) / TIMER_SEC(contraction))
|
||||
<< " nodes/sec and " << number_of_used_edges / TIMER_SEC(contraction)
|
||||
<< " edges/sec";
|
||||
|
||||
SimpleLogger().Write() << "finished preprocessing";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
template <> struct hash<std::pair<OSMNodeID, OSMNodeID>>
|
||||
{
|
||||
std::size_t operator()(const std::pair<OSMNodeID, OSMNodeID> &k) const
|
||||
{
|
||||
return OSMNodeID_to_uint64_t(k.first) ^ (OSMNodeID_to_uint64_t(k.second) << 12);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
std::size_t Prepare::LoadEdgeExpandedGraph(std::string const &edge_based_graph_filename,
|
||||
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
||||
const std::string &edge_segment_lookup_filename,
|
||||
const std::string &edge_penalty_filename,
|
||||
const std::string &segment_speed_filename)
|
||||
{
|
||||
SimpleLogger().Write() << "Opening " << edge_based_graph_filename;
|
||||
boost::filesystem::ifstream input_stream(edge_based_graph_filename, std::ios::binary);
|
||||
|
||||
const bool update_edge_weights = segment_speed_filename != "";
|
||||
|
||||
boost::filesystem::ifstream edge_segment_input_stream;
|
||||
boost::filesystem::ifstream edge_fixed_penalties_input_stream;
|
||||
|
||||
if (update_edge_weights)
|
||||
{
|
||||
edge_segment_input_stream.open(edge_segment_lookup_filename, std::ios::binary);
|
||||
edge_fixed_penalties_input_stream.open(edge_penalty_filename, std::ios::binary);
|
||||
if (!edge_segment_input_stream || !edge_fixed_penalties_input_stream)
|
||||
{
|
||||
throw osrm::exception("Could not load .edge_segment_lookup or .edge_penalties, did you "
|
||||
"run osrm-extract with '--generate-edge-lookup'?");
|
||||
}
|
||||
}
|
||||
|
||||
const FingerPrint fingerprint_valid = FingerPrint::GetValid();
|
||||
FingerPrint fingerprint_loaded;
|
||||
input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
|
||||
fingerprint_loaded.TestPrepare(fingerprint_valid);
|
||||
|
||||
size_t number_of_edges = 0;
|
||||
size_t max_edge_id = SPECIAL_EDGEID;
|
||||
input_stream.read((char *)&number_of_edges, sizeof(size_t));
|
||||
input_stream.read((char *)&max_edge_id, sizeof(size_t));
|
||||
|
||||
edge_based_edge_list.resize(number_of_edges);
|
||||
SimpleLogger().Write() << "Reading " << number_of_edges << " edges from the edge based graph";
|
||||
|
||||
std::unordered_map<std::pair<OSMNodeID, OSMNodeID>, unsigned> segment_speed_lookup;
|
||||
|
||||
if (update_edge_weights)
|
||||
{
|
||||
SimpleLogger().Write() << "Segment speed data supplied, will update edge weights from "
|
||||
<< segment_speed_filename;
|
||||
io::CSVReader<3> csv_in(segment_speed_filename);
|
||||
csv_in.set_header("from_node", "to_node", "speed");
|
||||
uint64_t from_node_id;
|
||||
uint64_t to_node_id;
|
||||
unsigned speed;
|
||||
while (csv_in.read_row(from_node_id, to_node_id, speed))
|
||||
{
|
||||
segment_speed_lookup[std::make_pair(OSMNodeID(from_node_id), OSMNodeID(to_node_id))] = speed;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_GEOMETRY_START(config);
|
||||
|
||||
// TODO: can we read this in bulk? DeallocatingVector isn't necessarily
|
||||
// all stored contiguously
|
||||
for (; number_of_edges > 0; --number_of_edges)
|
||||
{
|
||||
EdgeBasedEdge inbuffer;
|
||||
input_stream.read((char *) &inbuffer, sizeof(EdgeBasedEdge));
|
||||
|
||||
if (update_edge_weights)
|
||||
{
|
||||
// Processing-time edge updates
|
||||
unsigned fixed_penalty;
|
||||
edge_fixed_penalties_input_stream.read(reinterpret_cast<char *>(&fixed_penalty),
|
||||
sizeof(fixed_penalty));
|
||||
|
||||
int new_weight = 0;
|
||||
|
||||
unsigned num_osm_nodes = 0;
|
||||
edge_segment_input_stream.read(reinterpret_cast<char *>(&num_osm_nodes),
|
||||
sizeof(num_osm_nodes));
|
||||
OSMNodeID previous_osm_node_id;
|
||||
edge_segment_input_stream.read(reinterpret_cast<char *>(&previous_osm_node_id),
|
||||
sizeof(previous_osm_node_id));
|
||||
OSMNodeID this_osm_node_id;
|
||||
double segment_length;
|
||||
int segment_weight;
|
||||
--num_osm_nodes;
|
||||
for (; num_osm_nodes != 0; --num_osm_nodes)
|
||||
{
|
||||
edge_segment_input_stream.read(reinterpret_cast<char *>(&this_osm_node_id),
|
||||
sizeof(this_osm_node_id));
|
||||
edge_segment_input_stream.read(reinterpret_cast<char *>(&segment_length),
|
||||
sizeof(segment_length));
|
||||
edge_segment_input_stream.read(reinterpret_cast<char *>(&segment_weight),
|
||||
sizeof(segment_weight));
|
||||
|
||||
auto speed_iter = segment_speed_lookup.find(
|
||||
std::make_pair(previous_osm_node_id, this_osm_node_id));
|
||||
if (speed_iter != segment_speed_lookup.end())
|
||||
{
|
||||
// This sets the segment weight using the same formula as the
|
||||
// EdgeBasedGraphFactory for consistency. The *why* of this formula
|
||||
// is lost in the annals of time.
|
||||
int new_segment_weight =
|
||||
std::max(1, static_cast<int>(std::floor(
|
||||
(segment_length * 10.) / (speed_iter->second / 3.6) + .5)));
|
||||
new_weight += new_segment_weight;
|
||||
|
||||
DEBUG_GEOMETRY_EDGE(
|
||||
new_segment_weight,
|
||||
segment_length,
|
||||
previous_osm_node_id,
|
||||
this_osm_node_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If no lookup found, use the original weight value for this segment
|
||||
new_weight += segment_weight;
|
||||
|
||||
DEBUG_GEOMETRY_EDGE(
|
||||
segment_weight,
|
||||
segment_length,
|
||||
previous_osm_node_id,
|
||||
this_osm_node_id);
|
||||
}
|
||||
|
||||
previous_osm_node_id = this_osm_node_id;
|
||||
}
|
||||
|
||||
inbuffer.weight = fixed_penalty + new_weight;
|
||||
}
|
||||
|
||||
edge_based_edge_list.emplace_back(std::move(inbuffer));
|
||||
}
|
||||
|
||||
DEBUG_GEOMETRY_STOP();
|
||||
SimpleLogger().Write() << "Done reading edges";
|
||||
return max_edge_id;
|
||||
}
|
||||
|
||||
void Prepare::ReadNodeLevels(std::vector<float> &node_levels) const
|
||||
{
|
||||
boost::filesystem::ifstream order_input_stream(config.level_output_path, std::ios::binary);
|
||||
|
||||
unsigned level_size;
|
||||
order_input_stream.read((char *)&level_size, sizeof(unsigned));
|
||||
node_levels.resize(level_size);
|
||||
order_input_stream.read((char *)node_levels.data(), sizeof(float) * node_levels.size());
|
||||
}
|
||||
|
||||
void Prepare::WriteNodeLevels(std::vector<float> &&in_node_levels) const
|
||||
{
|
||||
std::vector<float> node_levels(std::move(in_node_levels));
|
||||
|
||||
boost::filesystem::ofstream order_output_stream(config.level_output_path, std::ios::binary);
|
||||
|
||||
unsigned level_size = node_levels.size();
|
||||
order_output_stream.write((char *)&level_size, sizeof(unsigned));
|
||||
order_output_stream.write((char *)node_levels.data(), sizeof(float) * node_levels.size());
|
||||
}
|
||||
|
||||
void Prepare::WriteCoreNodeMarker(std::vector<bool> &&in_is_core_node) const
|
||||
{
|
||||
std::vector<bool> is_core_node(std::move(in_is_core_node));
|
||||
std::vector<char> unpacked_bool_flags(std::move(is_core_node.size()));
|
||||
for (auto i = 0u; i < is_core_node.size(); ++i)
|
||||
{
|
||||
unpacked_bool_flags[i] = is_core_node[i] ? 1 : 0;
|
||||
}
|
||||
|
||||
boost::filesystem::ofstream core_marker_output_stream(config.core_output_path,
|
||||
std::ios::binary);
|
||||
unsigned size = unpacked_bool_flags.size();
|
||||
core_marker_output_stream.write((char *)&size, sizeof(unsigned));
|
||||
core_marker_output_stream.write((char *)unpacked_bool_flags.data(),
|
||||
sizeof(char) * unpacked_bool_flags.size());
|
||||
}
|
||||
|
||||
std::size_t Prepare::WriteContractedGraph(unsigned max_node_id,
|
||||
const DeallocatingVector<QueryEdge> &contracted_edge_list)
|
||||
{
|
||||
// Sorting contracted edges in a way that the static query graph can read some in in-place.
|
||||
tbb::parallel_sort(contracted_edge_list.begin(), contracted_edge_list.end());
|
||||
const unsigned contracted_edge_count = contracted_edge_list.size();
|
||||
SimpleLogger().Write() << "Serializing compacted graph of " << contracted_edge_count
|
||||
<< " edges";
|
||||
|
||||
const FingerPrint fingerprint = FingerPrint::GetValid();
|
||||
boost::filesystem::ofstream hsgr_output_stream(config.graph_output_path, std::ios::binary);
|
||||
hsgr_output_stream.write((char *)&fingerprint, sizeof(FingerPrint));
|
||||
const unsigned max_used_node_id = [&contracted_edge_list]
|
||||
{
|
||||
unsigned tmp_max = 0;
|
||||
for (const QueryEdge &edge : contracted_edge_list)
|
||||
{
|
||||
BOOST_ASSERT(SPECIAL_NODEID != edge.source);
|
||||
BOOST_ASSERT(SPECIAL_NODEID != edge.target);
|
||||
tmp_max = std::max(tmp_max, edge.source);
|
||||
tmp_max = std::max(tmp_max, edge.target);
|
||||
}
|
||||
return tmp_max;
|
||||
}();
|
||||
|
||||
SimpleLogger().Write(logDEBUG) << "input graph has " << (max_node_id + 1) << " nodes";
|
||||
SimpleLogger().Write(logDEBUG) << "contracted graph has " << (max_used_node_id + 1) << " nodes";
|
||||
|
||||
std::vector<StaticGraph<EdgeData>::NodeArrayEntry> node_array;
|
||||
// make sure we have at least one sentinel
|
||||
node_array.resize(max_node_id + 2);
|
||||
|
||||
SimpleLogger().Write() << "Building node array";
|
||||
StaticGraph<EdgeData>::EdgeIterator edge = 0;
|
||||
StaticGraph<EdgeData>::EdgeIterator position = 0;
|
||||
StaticGraph<EdgeData>::EdgeIterator last_edge;
|
||||
|
||||
// initializing 'first_edge'-field of nodes:
|
||||
for (const auto node : osrm::irange(0u, max_used_node_id + 1))
|
||||
{
|
||||
last_edge = edge;
|
||||
while ((edge < contracted_edge_count) && (contracted_edge_list[edge].source == node))
|
||||
{
|
||||
++edge;
|
||||
}
|
||||
node_array[node].first_edge = position; //=edge
|
||||
position += edge - last_edge; // remove
|
||||
}
|
||||
|
||||
for (const auto sentinel_counter :
|
||||
osrm::irange<unsigned>(max_used_node_id + 1, node_array.size()))
|
||||
{
|
||||
// sentinel element, guarded against underflow
|
||||
node_array[sentinel_counter].first_edge = contracted_edge_count;
|
||||
}
|
||||
|
||||
SimpleLogger().Write() << "Serializing node array";
|
||||
|
||||
RangebasedCRC32 crc32_calculator;
|
||||
const unsigned edges_crc32 = crc32_calculator(contracted_edge_list);
|
||||
SimpleLogger().Write() << "Writing CRC32: " << edges_crc32;
|
||||
|
||||
const unsigned node_array_size = node_array.size();
|
||||
// serialize crc32, aka checksum
|
||||
hsgr_output_stream.write((char *)&edges_crc32, sizeof(unsigned));
|
||||
// serialize number of nodes
|
||||
hsgr_output_stream.write((char *)&node_array_size, sizeof(unsigned));
|
||||
// serialize number of edges
|
||||
hsgr_output_stream.write((char *)&contracted_edge_count, sizeof(unsigned));
|
||||
// serialize all nodes
|
||||
if (node_array_size > 0)
|
||||
{
|
||||
hsgr_output_stream.write((char *)&node_array[0],
|
||||
sizeof(StaticGraph<EdgeData>::NodeArrayEntry) * node_array_size);
|
||||
}
|
||||
|
||||
// serialize all edges
|
||||
SimpleLogger().Write() << "Building edge array";
|
||||
int number_of_used_edges = 0;
|
||||
|
||||
StaticGraph<EdgeData>::EdgeArrayEntry current_edge;
|
||||
for (const auto edge : osrm::irange<std::size_t>(0, contracted_edge_list.size()))
|
||||
{
|
||||
// no eigen loops
|
||||
BOOST_ASSERT(contracted_edge_list[edge].source != contracted_edge_list[edge].target);
|
||||
current_edge.target = contracted_edge_list[edge].target;
|
||||
current_edge.data = contracted_edge_list[edge].data;
|
||||
|
||||
// every target needs to be valid
|
||||
BOOST_ASSERT(current_edge.target <= max_used_node_id);
|
||||
#ifndef NDEBUG
|
||||
if (current_edge.data.distance <= 0)
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << "Edge: " << edge
|
||||
<< ",source: " << contracted_edge_list[edge].source
|
||||
<< ", target: " << contracted_edge_list[edge].target
|
||||
<< ", dist: " << current_edge.data.distance;
|
||||
|
||||
SimpleLogger().Write(logWARNING) << "Failed at adjacency list of node "
|
||||
<< contracted_edge_list[edge].source << "/"
|
||||
<< node_array.size() - 1;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
hsgr_output_stream.write((char *)¤t_edge,
|
||||
sizeof(StaticGraph<EdgeData>::EdgeArrayEntry));
|
||||
|
||||
++number_of_used_edges;
|
||||
}
|
||||
|
||||
return number_of_used_edges;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Build contracted graph.
|
||||
*/
|
||||
void Prepare::ContractGraph(const unsigned max_edge_id,
|
||||
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
||||
DeallocatingVector<QueryEdge> &contracted_edge_list,
|
||||
std::vector<bool> &is_core_node,
|
||||
std::vector<float> &inout_node_levels) const
|
||||
{
|
||||
std::vector<float> node_levels;
|
||||
node_levels.swap(inout_node_levels);
|
||||
|
||||
Contractor contractor(max_edge_id + 1, edge_based_edge_list, std::move(node_levels));
|
||||
contractor.Run(config.core_factor);
|
||||
contractor.GetEdges(contracted_edge_list);
|
||||
contractor.GetCoreMarker(is_core_node);
|
||||
contractor.GetNodeLevels(inout_node_levels);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
default: '--strict --tags ~@stress --tags ~@todo --require features/support --require features/step_definitions',
|
||||
verify: '--strict --tags ~@stress --tags ~@todo -f progress --require features/support --require features/step_definitions',
|
||||
todo: '--strict --tags @todo --require features/support --require features/step_definitions',
|
||||
all: '--strict --require features/support --require features/step_definitions'
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "compressed_edge_container.hpp"
|
||||
#include "../util/simple_logger.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
CompressedEdgeContainer::CompressedEdgeContainer()
|
||||
{
|
||||
m_free_list.reserve(100);
|
||||
IncreaseFreeList();
|
||||
}
|
||||
|
||||
void CompressedEdgeContainer::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 CompressedEdgeContainer::HasEntryForID(const EdgeID edge_id) const
|
||||
{
|
||||
auto iter = m_edge_id_to_list_index_map.find(edge_id);
|
||||
return iter != m_edge_id_to_list_index_map.end();
|
||||
}
|
||||
|
||||
unsigned CompressedEdgeContainer::GetPositionForID(const EdgeID edge_id) const
|
||||
{
|
||||
auto map_iterator = m_edge_id_to_list_index_map.find(edge_id);
|
||||
BOOST_ASSERT(map_iterator != m_edge_id_to_list_index_map.end());
|
||||
BOOST_ASSERT(map_iterator->second < m_compressed_geometries.size());
|
||||
return map_iterator->second;
|
||||
}
|
||||
|
||||
void CompressedEdgeContainer::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 CompressedEdgeContainer::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];
|
||||
|
||||
// note we don't save the start coordinate: it is implicitly given by edge 1
|
||||
// weight1 is the distance to the (currently) last coordinate in the bucket
|
||||
if (edge_bucket_list1.empty())
|
||||
{
|
||||
edge_bucket_list1.emplace_back(via_node_id, weight1);
|
||||
}
|
||||
|
||||
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 CompressedEdgeContainer::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 CompressedEdgeContainer::EdgeBucket&
|
||||
CompressedEdgeContainer::GetBucketReference(const EdgeID edge_id) const
|
||||
{
|
||||
const unsigned index = m_edge_id_to_list_index_map.at(edge_id);
|
||||
return m_compressed_geometries.at(index);
|
||||
}
|
||||
|
||||
NodeID CompressedEdgeContainer::GetFirstEdgeTargetID(const EdgeID edge_id) const
|
||||
{
|
||||
const auto &bucket = GetBucketReference(edge_id);
|
||||
BOOST_ASSERT(bucket.size() >= 2);
|
||||
return bucket.front().first;
|
||||
}
|
||||
NodeID CompressedEdgeContainer::GetLastEdgeSourceID(const EdgeID edge_id) const
|
||||
{
|
||||
const auto &bucket = GetBucketReference(edge_id);
|
||||
BOOST_ASSERT(bucket.size() >= 2);
|
||||
return bucket[bucket.size() - 2].first;
|
||||
}
|
||||
@@ -1,69 +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 CompressedEdgeContainer
|
||||
{
|
||||
public:
|
||||
using CompressedNode = std::pair<NodeID, EdgeWeight>;
|
||||
using EdgeBucket = std::vector<CompressedNode>;
|
||||
|
||||
CompressedEdgeContainer();
|
||||
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 EdgeBucket& GetBucketReference(const EdgeID edge_id) const;
|
||||
NodeID GetFirstEdgeTargetID(const EdgeID edge_id) const;
|
||||
NodeID GetLastEdgeSourceID(const EdgeID edge_id) const;
|
||||
|
||||
private:
|
||||
int free_list_maximum = 0;
|
||||
|
||||
void IncreaseFreeList();
|
||||
std::vector<EdgeBucket> 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,87 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "../algorithms/coordinate_calculation.hpp"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#include "../util/simple_logger.hpp"
|
||||
#endif
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#ifndef NDEBUG
|
||||
#include <bitset>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
|
||||
FixedPointCoordinate::FixedPointCoordinate()
|
||||
: lat(std::numeric_limits<int>::min()), lon(std::numeric_limits<int>::min())
|
||||
{
|
||||
}
|
||||
|
||||
FixedPointCoordinate::FixedPointCoordinate(int lat, int lon) : lat(lat), lon(lon)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (0 != (std::abs(lat) >> 30))
|
||||
{
|
||||
std::bitset<32> y_coordinate_vector(lat);
|
||||
SimpleLogger().Write(logDEBUG) << "broken lat: " << lat
|
||||
<< ", bits: " << y_coordinate_vector;
|
||||
}
|
||||
if (0 != (std::abs(lon) >> 30))
|
||||
{
|
||||
std::bitset<32> x_coordinate_vector(lon);
|
||||
SimpleLogger().Write(logDEBUG) << "broken lon: " << lon
|
||||
<< ", bits: " << x_coordinate_vector;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FixedPointCoordinate::is_valid() const
|
||||
{
|
||||
if (lat > 90 * COORDINATE_PRECISION || lat < -90 * COORDINATE_PRECISION ||
|
||||
lon > 180 * COORDINATE_PRECISION || lon < -180 * COORDINATE_PRECISION)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FixedPointCoordinate::operator==(const FixedPointCoordinate &other) const
|
||||
{
|
||||
return lat == other.lat && lon == other.lon;
|
||||
}
|
||||
|
||||
void FixedPointCoordinate::output(std::ostream &out) const
|
||||
{
|
||||
out << "(" << lat / COORDINATE_PRECISION << "," << lon / COORDINATE_PRECISION << ")";
|
||||
}
|
||||
|
||||
float FixedPointCoordinate::bearing(const FixedPointCoordinate &other) const
|
||||
{
|
||||
return coordinate_calculation::bearing(other, *this);
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef EDGE_BASED_NODE_HPP
|
||||
#define EDGE_BASED_NODE_HPP
|
||||
|
||||
#include "../data_structures/travel_mode.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <limits>
|
||||
|
||||
/// This is what StaticRTree serialized and stores on disk
|
||||
/// It is generated in EdgeBasedGraphFactory.
|
||||
struct EdgeBasedNode
|
||||
{
|
||||
EdgeBasedNode()
|
||||
: forward_edge_based_node_id(SPECIAL_NODEID), reverse_edge_based_node_id(SPECIAL_NODEID),
|
||||
u(SPECIAL_NODEID), v(SPECIAL_NODEID), name_id(0),
|
||||
forward_weight(INVALID_EDGE_WEIGHT >> 1), reverse_weight(INVALID_EDGE_WEIGHT >> 1),
|
||||
forward_offset(0), reverse_offset(0), packed_geometry_id(SPECIAL_EDGEID),
|
||||
component{INVALID_COMPONENTID, false}, fwd_segment_position(std::numeric_limits<unsigned short>::max()),
|
||||
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
||||
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
||||
{
|
||||
}
|
||||
|
||||
explicit EdgeBasedNode(NodeID forward_edge_based_node_id,
|
||||
NodeID reverse_edge_based_node_id,
|
||||
NodeID u,
|
||||
NodeID v,
|
||||
unsigned name_id,
|
||||
int forward_weight,
|
||||
int reverse_weight,
|
||||
int forward_offset,
|
||||
int reverse_offset,
|
||||
unsigned packed_geometry_id,
|
||||
bool is_tiny_component,
|
||||
unsigned component_id,
|
||||
unsigned short fwd_segment_position,
|
||||
TravelMode forward_travel_mode,
|
||||
TravelMode backward_travel_mode)
|
||||
: forward_edge_based_node_id(forward_edge_based_node_id),
|
||||
reverse_edge_based_node_id(reverse_edge_based_node_id), u(u), v(v), name_id(name_id),
|
||||
forward_weight(forward_weight), reverse_weight(reverse_weight),
|
||||
forward_offset(forward_offset), reverse_offset(reverse_offset),
|
||||
packed_geometry_id(packed_geometry_id), component{component_id, is_tiny_component},
|
||||
fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode),
|
||||
backward_travel_mode(backward_travel_mode)
|
||||
{
|
||||
BOOST_ASSERT((forward_edge_based_node_id != SPECIAL_NODEID) ||
|
||||
(reverse_edge_based_node_id != SPECIAL_NODEID));
|
||||
}
|
||||
|
||||
static inline FixedPointCoordinate Centroid(const FixedPointCoordinate &a,
|
||||
const FixedPointCoordinate &b)
|
||||
{
|
||||
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
|
||||
struct {
|
||||
unsigned id : 31;
|
||||
bool is_tiny : 1;
|
||||
} component;
|
||||
unsigned short fwd_segment_position; // segment id in a compressed geometry
|
||||
TravelMode forward_travel_mode : 4;
|
||||
TravelMode backward_travel_mode : 4;
|
||||
};
|
||||
|
||||
#endif // EDGE_BASED_NODE_HPP
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "external_memory_node.hpp"
|
||||
#include "query_node.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
ExternalMemoryNode::ExternalMemoryNode(
|
||||
int lat, int lon, OSMNodeID 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, MIN_OSM_NODEID, false, false);
|
||||
}
|
||||
|
||||
ExternalMemoryNode ExternalMemoryNode::max_value()
|
||||
{
|
||||
return ExternalMemoryNode(std::numeric_limits<int>::max(), std::numeric_limits<int>::max(),
|
||||
MAX_OSM_NODEID, 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,57 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef EXTERNAL_MEMORY_NODE_HPP_
|
||||
#define EXTERNAL_MEMORY_NODE_HPP_
|
||||
|
||||
#include "query_node.hpp"
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
struct ExternalMemoryNode : QueryNode
|
||||
{
|
||||
ExternalMemoryNode(int lat, int lon, OSMNodeID id, bool barrier, bool traffic_light);
|
||||
|
||||
ExternalMemoryNode();
|
||||
|
||||
static ExternalMemoryNode min_value();
|
||||
|
||||
static ExternalMemoryNode max_value();
|
||||
|
||||
bool barrier;
|
||||
bool traffic_lights;
|
||||
};
|
||||
|
||||
struct ExternalMemoryNodeSTXXLCompare
|
||||
{
|
||||
using value_type = ExternalMemoryNode;
|
||||
bool operator()(const ExternalMemoryNode &left, const ExternalMemoryNode &right) const;
|
||||
value_type max_value();
|
||||
value_type min_value();
|
||||
};
|
||||
|
||||
#endif /* EXTERNAL_MEMORY_NODE_HPP_ */
|
||||
@@ -1,216 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef 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,170 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HIDDEN_MARKOV_MODEL
|
||||
#define HIDDEN_MARKOV_MODEL
|
||||
|
||||
#include "../util/integer_range.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
namespace osrm
|
||||
{
|
||||
namespace matching
|
||||
{
|
||||
static const double log_2_pi = std::log(2. * M_PI);
|
||||
static const double IMPOSSIBLE_LOG_PROB = -std::numeric_limits<double>::infinity();
|
||||
static const double MINIMAL_LOG_PROB = std::numeric_limits<double>::lowest();
|
||||
static const std::size_t INVALID_STATE = std::numeric_limits<std::size_t>::max();
|
||||
} // namespace matching
|
||||
} // namespace osrm
|
||||
|
||||
// closures to precompute log -> only simple floating point operations
|
||||
struct EmissionLogProbability
|
||||
{
|
||||
double sigma_z;
|
||||
double log_sigma_z;
|
||||
|
||||
EmissionLogProbability(const double sigma_z) : sigma_z(sigma_z), log_sigma_z(std::log(sigma_z))
|
||||
{
|
||||
}
|
||||
|
||||
double operator()(const double distance) const
|
||||
{
|
||||
return -0.5 * (osrm::matching::log_2_pi + (distance / sigma_z) * (distance / sigma_z)) -
|
||||
log_sigma_z;
|
||||
}
|
||||
};
|
||||
|
||||
struct TransitionLogProbability
|
||||
{
|
||||
double beta;
|
||||
double log_beta;
|
||||
TransitionLogProbability(const double beta) : beta(beta), log_beta(std::log(beta)) {}
|
||||
|
||||
double operator()(const double d_t) const { return -log_beta - d_t / beta; }
|
||||
};
|
||||
|
||||
template <class CandidateLists> struct HiddenMarkovModel
|
||||
{
|
||||
std::vector<std::vector<double>> viterbi;
|
||||
std::vector<std::vector<std::pair<unsigned, unsigned>>> parents;
|
||||
std::vector<std::vector<float>> path_lengths;
|
||||
std::vector<std::vector<bool>> pruned;
|
||||
std::vector<std::vector<bool>> suspicious;
|
||||
std::vector<bool> breakage;
|
||||
|
||||
const CandidateLists &candidates_list;
|
||||
const EmissionLogProbability &emission_log_probability;
|
||||
|
||||
HiddenMarkovModel(const CandidateLists &candidates_list,
|
||||
const EmissionLogProbability &emission_log_probability)
|
||||
: breakage(candidates_list.size()), candidates_list(candidates_list),
|
||||
emission_log_probability(emission_log_probability)
|
||||
{
|
||||
viterbi.resize(candidates_list.size());
|
||||
parents.resize(candidates_list.size());
|
||||
path_lengths.resize(candidates_list.size());
|
||||
suspicious.resize(candidates_list.size());
|
||||
pruned.resize(candidates_list.size());
|
||||
breakage.resize(candidates_list.size());
|
||||
for (const auto i : osrm::irange<std::size_t>(0u, candidates_list.size()))
|
||||
{
|
||||
const auto& num_candidates = candidates_list[i].size();
|
||||
// add empty vectors
|
||||
if (num_candidates > 0)
|
||||
{
|
||||
viterbi[i].resize(num_candidates);
|
||||
parents[i].resize(num_candidates);
|
||||
path_lengths[i].resize(num_candidates);
|
||||
suspicious[i].resize(num_candidates);
|
||||
pruned[i].resize(num_candidates);
|
||||
}
|
||||
}
|
||||
|
||||
clear(0);
|
||||
}
|
||||
|
||||
void clear(std::size_t initial_timestamp)
|
||||
{
|
||||
BOOST_ASSERT(viterbi.size() == parents.size() && parents.size() == path_lengths.size() &&
|
||||
path_lengths.size() == pruned.size() && pruned.size() == breakage.size());
|
||||
|
||||
for (const auto t : osrm::irange(initial_timestamp, viterbi.size()))
|
||||
{
|
||||
std::fill(viterbi[t].begin(), viterbi[t].end(), osrm::matching::IMPOSSIBLE_LOG_PROB);
|
||||
std::fill(parents[t].begin(), parents[t].end(), std::make_pair(0u, 0u));
|
||||
std::fill(path_lengths[t].begin(), path_lengths[t].end(), 0);
|
||||
std::fill(suspicious[t].begin(), suspicious[t].end(), true);
|
||||
std::fill(pruned[t].begin(), pruned[t].end(), true);
|
||||
}
|
||||
std::fill(breakage.begin() + initial_timestamp, breakage.end(), true);
|
||||
}
|
||||
|
||||
std::size_t initialize(std::size_t initial_timestamp)
|
||||
{
|
||||
auto num_points = candidates_list.size();
|
||||
do
|
||||
{
|
||||
BOOST_ASSERT(initial_timestamp < num_points);
|
||||
|
||||
for (const auto s : osrm::irange<std::size_t>(0u, viterbi[initial_timestamp].size()))
|
||||
{
|
||||
viterbi[initial_timestamp][s] =
|
||||
emission_log_probability(candidates_list[initial_timestamp][s].distance);
|
||||
parents[initial_timestamp][s] = std::make_pair(initial_timestamp, s);
|
||||
pruned[initial_timestamp][s] =
|
||||
viterbi[initial_timestamp][s] < osrm::matching::MINIMAL_LOG_PROB;
|
||||
suspicious[initial_timestamp][s] = false;
|
||||
|
||||
breakage[initial_timestamp] =
|
||||
breakage[initial_timestamp] && pruned[initial_timestamp][s];
|
||||
}
|
||||
|
||||
++initial_timestamp;
|
||||
} while (initial_timestamp < num_points && breakage[initial_timestamp - 1]);
|
||||
|
||||
if (initial_timestamp >= num_points)
|
||||
{
|
||||
return osrm::matching::INVALID_STATE;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(initial_timestamp > 0);
|
||||
--initial_timestamp;
|
||||
|
||||
BOOST_ASSERT(breakage[initial_timestamp] == false);
|
||||
|
||||
return initial_timestamp;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // HIDDEN_MARKOV_MODEL
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "hilbert_value.hpp"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
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 = 1u << (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 contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef 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,113 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "import_edge.hpp"
|
||||
|
||||
#include "travel_mode.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
||||
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()
|
||||
: source(SPECIAL_NODEID), target(SPECIAL_NODEID), name_id(0), weight(0), forward(false),
|
||||
backward(false), roundabout(false),
|
||||
access_restricted(false), startpoint(true), is_split(false), travel_mode(false)
|
||||
{
|
||||
}
|
||||
|
||||
NodeBasedEdge::NodeBasedEdge(NodeID source,
|
||||
NodeID target,
|
||||
NodeID name_id,
|
||||
EdgeWeight weight,
|
||||
bool forward,
|
||||
bool backward,
|
||||
bool roundabout,
|
||||
bool access_restricted,
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool is_split)
|
||||
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
|
||||
backward(backward), roundabout(roundabout),
|
||||
access_restricted(access_restricted), startpoint(startpoint), 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)
|
||||
{
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef IMPORT_EDGE_HPP
|
||||
#define IMPORT_EDGE_HPP
|
||||
|
||||
#include "../data_structures/travel_mode.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
||||
struct NodeBasedEdge
|
||||
{
|
||||
bool operator<(const NodeBasedEdge &e) const;
|
||||
|
||||
NodeBasedEdge();
|
||||
explicit NodeBasedEdge(NodeID source,
|
||||
NodeID target,
|
||||
NodeID name_id,
|
||||
EdgeWeight weight,
|
||||
bool forward,
|
||||
bool backward,
|
||||
bool roundabout,
|
||||
bool access_restricted,
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool is_split);
|
||||
|
||||
NodeID source;
|
||||
NodeID target;
|
||||
NodeID name_id;
|
||||
EdgeWeight weight;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
bool roundabout : 1;
|
||||
bool access_restricted : 1;
|
||||
bool startpoint : 1;
|
||||
bool is_split : 1;
|
||||
TravelMode travel_mode : 4;
|
||||
};
|
||||
|
||||
struct NodeBasedEdgeWithOSM : NodeBasedEdge
|
||||
{
|
||||
explicit NodeBasedEdgeWithOSM(OSMNodeID source,
|
||||
OSMNodeID target,
|
||||
NodeID name_id,
|
||||
EdgeWeight weight,
|
||||
bool forward,
|
||||
bool backward,
|
||||
bool roundabout,
|
||||
bool access_restricted,
|
||||
bool startpoint,
|
||||
TravelMode travel_mode,
|
||||
bool is_split)
|
||||
: NodeBasedEdge(SPECIAL_NODEID, SPECIAL_NODEID, name_id, weight, forward, backward, roundabout, access_restricted, startpoint, travel_mode, is_split),
|
||||
osm_source_id(source), osm_target_id(target) {}
|
||||
|
||||
OSMNodeID osm_source_id;
|
||||
OSMNodeID osm_target_id;
|
||||
};
|
||||
|
||||
struct EdgeBasedEdge
|
||||
{
|
||||
|
||||
public:
|
||||
bool operator<(const EdgeBasedEdge &e) const;
|
||||
|
||||
template <class EdgeT> explicit EdgeBasedEdge(const EdgeT &myEdge);
|
||||
|
||||
EdgeBasedEdge();
|
||||
|
||||
explicit EdgeBasedEdge(const NodeID source,
|
||||
const NodeID target,
|
||||
const NodeID edge_id,
|
||||
const EdgeWeight weight,
|
||||
const bool forward,
|
||||
const bool backward);
|
||||
NodeID source;
|
||||
NodeID target;
|
||||
NodeID edge_id;
|
||||
EdgeWeight weight : 30;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
};
|
||||
|
||||
#endif /* IMPORT_EDGE_HPP */
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef RAW_ROUTE_DATA_H
|
||||
#define RAW_ROUTE_DATA_H
|
||||
|
||||
#include "../data_structures/phantom_node.hpp"
|
||||
#include "../data_structures/travel_mode.hpp"
|
||||
#include "../data_structures/turn_instructions.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct PathData
|
||||
{
|
||||
PathData()
|
||||
: node(SPECIAL_NODEID), name_id(INVALID_EDGE_WEIGHT), segment_duration(INVALID_EDGE_WEIGHT),
|
||||
turn_instruction(TurnInstruction::NoTurn), travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
||||
{
|
||||
}
|
||||
|
||||
PathData(NodeID node,
|
||||
unsigned name_id,
|
||||
TurnInstruction turn_instruction,
|
||||
EdgeWeight segment_duration,
|
||||
TravelMode travel_mode)
|
||||
: node(node), name_id(name_id), segment_duration(segment_duration),
|
||||
turn_instruction(turn_instruction), travel_mode(travel_mode)
|
||||
{
|
||||
}
|
||||
NodeID node;
|
||||
unsigned name_id;
|
||||
EdgeWeight segment_duration;
|
||||
TurnInstruction turn_instruction;
|
||||
TravelMode travel_mode : 4;
|
||||
};
|
||||
|
||||
struct InternalRouteResult
|
||||
{
|
||||
std::vector<std::vector<PathData>> unpacked_path_segments;
|
||||
std::vector<PathData> unpacked_alternative;
|
||||
std::vector<PhantomNodes> segment_end_coordinates;
|
||||
std::vector<bool> source_traversed_in_reverse;
|
||||
std::vector<bool> target_traversed_in_reverse;
|
||||
std::vector<bool> alt_source_traversed_in_reverse;
|
||||
std::vector<bool> alt_target_traversed_in_reverse;
|
||||
int shortest_path_length;
|
||||
int alternative_path_length;
|
||||
|
||||
bool is_via_leg(const std::size_t leg) const
|
||||
{
|
||||
return (leg != unpacked_path_segments.size() - 1);
|
||||
}
|
||||
|
||||
InternalRouteResult()
|
||||
: shortest_path_length(INVALID_EDGE_WEIGHT), alternative_path_length(INVALID_EDGE_WEIGHT)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // RAW_ROUTE_DATA_H
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LRUCACHE_HPP
|
||||
#define LRUCACHE_HPP
|
||||
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
|
||||
template <typename KeyT, typename ValueT> class LRUCache
|
||||
{
|
||||
private:
|
||||
struct CacheEntry
|
||||
{
|
||||
CacheEntry(KeyT k, ValueT v) : key(k), value(v) {}
|
||||
KeyT key;
|
||||
ValueT value;
|
||||
};
|
||||
unsigned capacity;
|
||||
std::list<CacheEntry> itemsInCache;
|
||||
std::unordered_map<KeyT, typename std::list<CacheEntry>::iterator> positionMap;
|
||||
|
||||
public:
|
||||
explicit LRUCache(unsigned c) : capacity(c) {}
|
||||
|
||||
bool Holds(KeyT key)
|
||||
{
|
||||
if (positionMap.find(key) != positionMap.end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Insert(const KeyT key, ValueT &value)
|
||||
{
|
||||
itemsInCache.push_front(CacheEntry(key, value));
|
||||
positionMap.insert(std::make_pair(key, itemsInCache.begin()));
|
||||
if (itemsInCache.size() > capacity)
|
||||
{
|
||||
positionMap.erase(itemsInCache.back().key);
|
||||
itemsInCache.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void Insert(const KeyT key, ValueT value)
|
||||
{
|
||||
itemsInCache.push_front(CacheEntry(key, value));
|
||||
positionMap.insert(std::make_pair(key, itemsInCache.begin()));
|
||||
if (itemsInCache.size() > capacity)
|
||||
{
|
||||
positionMap.erase(itemsInCache.back().key);
|
||||
itemsInCache.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
bool Fetch(const KeyT key, ValueT &result)
|
||||
{
|
||||
if (Holds(key))
|
||||
{
|
||||
CacheEntry e = *(positionMap.find(key)->second);
|
||||
result = e.value;
|
||||
|
||||
// move to front
|
||||
itemsInCache.splice(itemsInCache.begin(), itemsInCache, positionMap.find(key)->second);
|
||||
positionMap.find(key)->second = itemsInCache.begin();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
unsigned Size() const { return itemsInCache.size(); }
|
||||
};
|
||||
#endif // LRUCACHE_HPP
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef MATRIX_GRAPH_WRAPPER_H
|
||||
#define MATRIX_GRAPH_WRAPPER_H
|
||||
|
||||
#include <vector>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
// This Wrapper provides all methods that are needed for TarjanSCC, when the graph is given in a
|
||||
// matrix representation (e.g. as output from a distance table call)
|
||||
|
||||
template <typename T> class MatrixGraphWrapper
|
||||
{
|
||||
public:
|
||||
MatrixGraphWrapper(std::vector<T> table, const std::size_t number_of_nodes)
|
||||
: table_(std::move(table)), number_of_nodes_(number_of_nodes){};
|
||||
|
||||
std::size_t GetNumberOfNodes() const { return number_of_nodes_; }
|
||||
|
||||
std::vector<T> GetAdjacentEdgeRange(const NodeID node) const
|
||||
{
|
||||
|
||||
std::vector<T> edges;
|
||||
// find all valid adjacent edges and move to vector `edges`
|
||||
for (std::size_t i = 0; i < number_of_nodes_; ++i)
|
||||
{
|
||||
if (*(std::begin(table_) + node * number_of_nodes_ + i) != INVALID_EDGE_WEIGHT)
|
||||
{
|
||||
edges.push_back(i);
|
||||
}
|
||||
}
|
||||
return edges;
|
||||
}
|
||||
|
||||
EdgeWeight GetTarget(const EdgeWeight edge) const { return edge; }
|
||||
|
||||
private:
|
||||
const std::vector<T> table_;
|
||||
const std::size_t number_of_nodes_;
|
||||
};
|
||||
|
||||
#endif // MATRIX_GRAPH_WRAPPER_H
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NODE_BASED_GRAPH_HPP
|
||||
#define NODE_BASED_GRAPH_HPP
|
||||
|
||||
#include "dynamic_graph.hpp"
|
||||
#include "import_edge.hpp"
|
||||
#include "../util/graph_utils.hpp"
|
||||
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
struct NodeBasedEdgeData
|
||||
{
|
||||
NodeBasedEdgeData()
|
||||
: distance(INVALID_EDGE_WEIGHT), edge_id(SPECIAL_NODEID),
|
||||
name_id(std::numeric_limits<unsigned>::max()), access_restricted(false),
|
||||
reversed(false), roundabout(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
||||
{
|
||||
}
|
||||
|
||||
NodeBasedEdgeData(int distance, unsigned edge_id, unsigned name_id,
|
||||
bool access_restricted, bool reversed,
|
||||
bool roundabout, bool startpoint, TravelMode travel_mode)
|
||||
: distance(distance), edge_id(edge_id), name_id(name_id),
|
||||
access_restricted(access_restricted), reversed(reversed),
|
||||
roundabout(roundabout), startpoint(startpoint), travel_mode(travel_mode)
|
||||
{
|
||||
}
|
||||
|
||||
int distance;
|
||||
unsigned edge_id;
|
||||
unsigned name_id;
|
||||
bool access_restricted : 1;
|
||||
bool reversed : 1;
|
||||
bool roundabout : 1;
|
||||
bool startpoint : 1;
|
||||
TravelMode travel_mode : 4;
|
||||
|
||||
bool IsCompatibleTo(const NodeBasedEdgeData &other) const
|
||||
{
|
||||
return (reversed == other.reversed) && (name_id == other.name_id) &&
|
||||
(travel_mode == other.travel_mode);
|
||||
}
|
||||
};
|
||||
|
||||
using NodeBasedDynamicGraph = DynamicGraph<NodeBasedEdgeData>;
|
||||
|
||||
/// Factory method to create NodeBasedDynamicGraph from NodeBasedEdges
|
||||
/// Since DynamicGraph expects directed edges, we need to insert
|
||||
/// two edges for undirected edges.
|
||||
inline std::shared_ptr<NodeBasedDynamicGraph>
|
||||
NodeBasedDynamicGraphFromEdges(std::size_t number_of_nodes, const std::vector<NodeBasedEdge> &input_edge_list)
|
||||
{
|
||||
auto edges_list = directedEdgesFromCompressed<NodeBasedDynamicGraph::InputEdge>(input_edge_list,
|
||||
[](NodeBasedDynamicGraph::InputEdge& output_edge, const NodeBasedEdge& input_edge)
|
||||
{
|
||||
output_edge.data.distance = static_cast<int>(input_edge.weight);
|
||||
BOOST_ASSERT(output_edge.data.distance > 0);
|
||||
|
||||
output_edge.data.roundabout = input_edge.roundabout;
|
||||
output_edge.data.name_id = input_edge.name_id;
|
||||
output_edge.data.access_restricted = input_edge.access_restricted;
|
||||
output_edge.data.travel_mode = input_edge.travel_mode;
|
||||
output_edge.data.startpoint = input_edge.startpoint;
|
||||
}
|
||||
);
|
||||
|
||||
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
||||
|
||||
auto graph = std::make_shared<NodeBasedDynamicGraph>(
|
||||
static_cast<NodeBasedDynamicGraph::NodeIterator>(number_of_nodes), edges_list);
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
#endif // NODE_BASED_GRAPH_HPP
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NODE_ID_HPP
|
||||
#define NODE_ID_HPP
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
struct Cmp
|
||||
{
|
||||
using value_type = OSMNodeID;
|
||||
bool operator()(const value_type left, const value_type right) const { return left < right; }
|
||||
value_type max_value() { return MAX_OSM_NODEID; }
|
||||
value_type min_value() { return MIN_OSM_NODEID; }
|
||||
};
|
||||
|
||||
#endif // NODE_ID_HPP
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef ORIGINAL_EDGE_DATA_HPP
|
||||
#define ORIGINAL_EDGE_DATA_HPP
|
||||
|
||||
#include "travel_mode.hpp"
|
||||
#include "turn_instructions.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
struct OriginalEdgeData
|
||||
{
|
||||
explicit OriginalEdgeData(NodeID via_node,
|
||||
unsigned name_id,
|
||||
TurnInstruction turn_instruction,
|
||||
bool compressed_geometry,
|
||||
TravelMode travel_mode)
|
||||
: via_node(via_node), name_id(name_id), turn_instruction(turn_instruction),
|
||||
compressed_geometry(compressed_geometry), travel_mode(travel_mode)
|
||||
{
|
||||
}
|
||||
|
||||
OriginalEdgeData()
|
||||
: via_node(std::numeric_limits<unsigned>::max()),
|
||||
name_id(std::numeric_limits<unsigned>::max()), turn_instruction(TurnInstruction::NoTurn),
|
||||
compressed_geometry(false), travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
||||
{
|
||||
}
|
||||
|
||||
NodeID via_node;
|
||||
unsigned name_id;
|
||||
TurnInstruction turn_instruction;
|
||||
bool compressed_geometry;
|
||||
TravelMode travel_mode;
|
||||
};
|
||||
|
||||
#endif // ORIGINAL_EDGE_DATA_HPP
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef PERCENT_HPP
|
||||
#define PERCENT_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <atomic>
|
||||
|
||||
class Percent
|
||||
{
|
||||
public:
|
||||
explicit Percent(unsigned max_value, unsigned step = 5) { reinit(max_value, step); }
|
||||
|
||||
// Reinitializes
|
||||
void reinit(unsigned max_value, unsigned step = 5)
|
||||
{
|
||||
m_max_value = max_value;
|
||||
m_current_value = 0;
|
||||
m_percent_interval = m_max_value / 100;
|
||||
m_next_threshold = m_percent_interval;
|
||||
m_last_percent = 0;
|
||||
m_step = step;
|
||||
}
|
||||
|
||||
// If there has been significant progress, display it.
|
||||
void printStatus(unsigned current_value)
|
||||
{
|
||||
if (current_value >= m_next_threshold)
|
||||
{
|
||||
m_next_threshold += m_percent_interval;
|
||||
printPercent(current_value / static_cast<double>(m_max_value) * 100.);
|
||||
}
|
||||
if (current_value + 1 == m_max_value)
|
||||
std::cout << " 100%" << std::endl;
|
||||
}
|
||||
|
||||
void printIncrement()
|
||||
{
|
||||
++m_current_value;
|
||||
printStatus(m_current_value);
|
||||
}
|
||||
|
||||
void printAddition(const unsigned addition)
|
||||
{
|
||||
m_current_value += addition;
|
||||
printStatus(m_current_value);
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic_uint m_current_value;
|
||||
unsigned m_max_value;
|
||||
unsigned m_percent_interval;
|
||||
unsigned m_next_threshold;
|
||||
unsigned m_last_percent;
|
||||
unsigned m_step;
|
||||
|
||||
// Displays progress.
|
||||
void printPercent(double percent)
|
||||
{
|
||||
while (percent >= m_last_percent + m_step)
|
||||
{
|
||||
m_last_percent += m_step;
|
||||
if (m_last_percent % 10 == 0)
|
||||
{
|
||||
std::cout << " " << m_last_percent << "% ";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << ".";
|
||||
}
|
||||
std::cout.flush();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // PERCENT_HPP
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "phantom_node.hpp"
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "travel_mode.hpp"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <limits>
|
||||
|
||||
PhantomNode::PhantomNode(NodeID forward_node_id,
|
||||
NodeID reverse_node_id,
|
||||
unsigned name_id,
|
||||
int forward_weight,
|
||||
int reverse_weight,
|
||||
int forward_offset,
|
||||
int reverse_offset,
|
||||
unsigned packed_geometry_id,
|
||||
bool is_tiny_component,
|
||||
unsigned component_id,
|
||||
FixedPointCoordinate &location,
|
||||
unsigned short fwd_segment_position,
|
||||
TravelMode forward_travel_mode,
|
||||
TravelMode backward_travel_mode)
|
||||
: forward_node_id(forward_node_id), reverse_node_id(reverse_node_id), name_id(name_id),
|
||||
forward_weight(forward_weight), reverse_weight(reverse_weight),
|
||||
forward_offset(forward_offset), reverse_offset(reverse_offset),
|
||||
packed_geometry_id(packed_geometry_id), component{component_id, is_tiny_component}, location(location),
|
||||
fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode),
|
||||
backward_travel_mode(backward_travel_mode)
|
||||
{
|
||||
}
|
||||
|
||||
PhantomNode::PhantomNode()
|
||||
: forward_node_id(SPECIAL_NODEID), reverse_node_id(SPECIAL_NODEID),
|
||||
name_id(std::numeric_limits<unsigned>::max()), forward_weight(INVALID_EDGE_WEIGHT),
|
||||
reverse_weight(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0),
|
||||
packed_geometry_id(SPECIAL_EDGEID), component{INVALID_COMPONENTID, false},
|
||||
fwd_segment_position(0), forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
||||
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
||||
{
|
||||
}
|
||||
|
||||
int PhantomNode::GetForwardWeightPlusOffset() const
|
||||
{
|
||||
if (SPECIAL_NODEID == forward_node_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return forward_offset + forward_weight;
|
||||
}
|
||||
|
||||
int PhantomNode::GetReverseWeightPlusOffset() const
|
||||
{
|
||||
if (SPECIAL_NODEID == reverse_node_id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return reverse_offset + reverse_weight;
|
||||
}
|
||||
|
||||
bool PhantomNode::is_bidirected() const
|
||||
{
|
||||
return (forward_node_id != SPECIAL_NODEID) && (reverse_node_id != SPECIAL_NODEID);
|
||||
}
|
||||
|
||||
bool PhantomNode::is_compressed() const { return (forward_offset != 0) || (reverse_offset != 0); }
|
||||
|
||||
bool PhantomNode::is_valid(const unsigned number_of_nodes) const
|
||||
{
|
||||
return location.is_valid() &&
|
||||
((forward_node_id < number_of_nodes) || (reverse_node_id < number_of_nodes)) &&
|
||||
((forward_weight != INVALID_EDGE_WEIGHT) || (reverse_weight != INVALID_EDGE_WEIGHT)) &&
|
||||
(component.id != INVALID_COMPONENTID) && (name_id != INVALID_NAMEID);
|
||||
}
|
||||
|
||||
bool PhantomNode::is_valid() const { return location.is_valid() && (name_id != INVALID_NAMEID); }
|
||||
|
||||
bool PhantomNode::operator==(const PhantomNode &other) const { return location == other.location; }
|
||||
@@ -1,162 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef PHANTOM_NODES_H
|
||||
#define PHANTOM_NODES_H
|
||||
|
||||
#include "travel_mode.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
struct PhantomNode
|
||||
{
|
||||
PhantomNode(NodeID forward_node_id,
|
||||
NodeID reverse_node_id,
|
||||
unsigned name_id,
|
||||
int forward_weight,
|
||||
int reverse_weight,
|
||||
int forward_offset,
|
||||
int reverse_offset,
|
||||
unsigned packed_geometry_id,
|
||||
bool is_tiny_component,
|
||||
unsigned component_id,
|
||||
FixedPointCoordinate &location,
|
||||
unsigned short fwd_segment_position,
|
||||
TravelMode forward_travel_mode,
|
||||
TravelMode backward_travel_mode);
|
||||
|
||||
PhantomNode();
|
||||
|
||||
template <class OtherT> PhantomNode(const OtherT &other, const FixedPointCoordinate &foot_point)
|
||||
{
|
||||
forward_node_id = other.forward_edge_based_node_id;
|
||||
reverse_node_id = other.reverse_edge_based_node_id;
|
||||
name_id = other.name_id;
|
||||
|
||||
forward_weight = other.forward_weight;
|
||||
reverse_weight = other.reverse_weight;
|
||||
|
||||
forward_offset = other.forward_offset;
|
||||
reverse_offset = other.reverse_offset;
|
||||
|
||||
packed_geometry_id = other.packed_geometry_id;
|
||||
|
||||
component.id = other.component.id;
|
||||
component.is_tiny = other.component.is_tiny;
|
||||
|
||||
location = foot_point;
|
||||
fwd_segment_position = other.fwd_segment_position;
|
||||
|
||||
forward_travel_mode = other.forward_travel_mode;
|
||||
backward_travel_mode = other.backward_travel_mode;
|
||||
}
|
||||
|
||||
NodeID forward_node_id;
|
||||
NodeID reverse_node_id;
|
||||
unsigned name_id;
|
||||
int forward_weight;
|
||||
int reverse_weight;
|
||||
int forward_offset;
|
||||
int reverse_offset;
|
||||
unsigned packed_geometry_id;
|
||||
struct ComponentType {
|
||||
uint32_t id : 31;
|
||||
bool is_tiny : 1;
|
||||
} component;
|
||||
// bit-fields are broken on Windows
|
||||
#ifndef _MSC_VER
|
||||
static_assert(sizeof(ComponentType) == 4, "ComponentType needs to 4 bytes big");
|
||||
#endif
|
||||
FixedPointCoordinate location;
|
||||
unsigned short fwd_segment_position;
|
||||
// note 4 bits would suffice for each,
|
||||
// but the saved byte would be padding anyway
|
||||
TravelMode forward_travel_mode;
|
||||
TravelMode backward_travel_mode;
|
||||
|
||||
int GetForwardWeightPlusOffset() const;
|
||||
|
||||
int GetReverseWeightPlusOffset() const;
|
||||
|
||||
bool is_bidirected() const;
|
||||
|
||||
bool is_compressed() const;
|
||||
|
||||
bool is_valid(const unsigned numberOfNodes) const;
|
||||
|
||||
bool is_valid() const;
|
||||
|
||||
bool operator==(const PhantomNode &other) const;
|
||||
};
|
||||
|
||||
#ifndef _MSC_VER
|
||||
static_assert(sizeof(PhantomNode) == 48, "PhantomNode has more padding then expected");
|
||||
#endif
|
||||
|
||||
using PhantomNodePair = std::pair<PhantomNode, PhantomNode>;
|
||||
|
||||
struct PhantomNodeWithDistance
|
||||
{
|
||||
PhantomNode phantom_node;
|
||||
double distance;
|
||||
};
|
||||
|
||||
struct PhantomNodes
|
||||
{
|
||||
PhantomNode source_phantom;
|
||||
PhantomNode target_phantom;
|
||||
};
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &out, const PhantomNodes &pn)
|
||||
{
|
||||
out << "source_coord: " << pn.source_phantom.location << "\n";
|
||||
out << "target_coord: " << pn.target_phantom.location << std::endl;
|
||||
return out;
|
||||
}
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
|
||||
{
|
||||
out << "node1: " << pn.forward_node_id << ", "
|
||||
<< "node2: " << pn.reverse_node_id << ", "
|
||||
<< "name: " << pn.name_id << ", "
|
||||
<< "fwd-w: " << pn.forward_weight << ", "
|
||||
<< "rev-w: " << pn.reverse_weight << ", "
|
||||
<< "fwd-o: " << pn.forward_offset << ", "
|
||||
<< "rev-o: " << pn.reverse_offset << ", "
|
||||
<< "geom: " << pn.packed_geometry_id << ", "
|
||||
<< "comp: " << pn.component.is_tiny << " / " << pn.component.id << ", "
|
||||
<< "pos: " << pn.fwd_segment_position << ", "
|
||||
<< "loc: " << pn.location;
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif // PHANTOM_NODES_H
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef QUERYEDGE_HPP
|
||||
#define QUERYEDGE_HPP
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
struct QueryEdge
|
||||
{
|
||||
NodeID source;
|
||||
NodeID target;
|
||||
struct EdgeData
|
||||
{
|
||||
EdgeData() : id(0), shortcut(false), distance(0), forward(false), backward(false) {}
|
||||
|
||||
template <class OtherT> EdgeData(const OtherT &other)
|
||||
{
|
||||
distance = other.distance;
|
||||
shortcut = other.shortcut;
|
||||
id = other.id;
|
||||
forward = other.forward;
|
||||
backward = other.backward;
|
||||
}
|
||||
NodeID id : 31;
|
||||
bool shortcut : 1;
|
||||
int distance : 30;
|
||||
bool forward : 1;
|
||||
bool backward : 1;
|
||||
} data;
|
||||
|
||||
QueryEdge() : source(SPECIAL_NODEID), target(SPECIAL_NODEID) {}
|
||||
|
||||
QueryEdge(NodeID source, NodeID target, EdgeData data)
|
||||
: source(source), target(target), data(std::move(data))
|
||||
{
|
||||
}
|
||||
|
||||
bool operator<(const QueryEdge &rhs) const
|
||||
{
|
||||
return std::tie(source, target) < std::tie(rhs.source, rhs.target);
|
||||
}
|
||||
|
||||
bool operator==(const QueryEdge &right) const
|
||||
{
|
||||
return (source == right.source && target == right.target &&
|
||||
data.distance == right.data.distance && data.shortcut == right.data.shortcut &&
|
||||
data.forward == right.data.forward && data.backward == right.data.backward &&
|
||||
data.id == right.data.id);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // QUERYEDGE_HPP
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef QUERY_NODE_HPP
|
||||
#define QUERY_NODE_HPP
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <limits>
|
||||
|
||||
struct QueryNode
|
||||
{
|
||||
using key_type = OSMNodeID; // type of NodeID
|
||||
using value_type = int; // type of lat,lons
|
||||
|
||||
explicit QueryNode(int lat, int lon, OSMNodeID node_id) : lat(lat), lon(lon), node_id(node_id) {}
|
||||
QueryNode()
|
||||
: lat(std::numeric_limits<int>::max()), lon(std::numeric_limits<int>::max()),
|
||||
node_id(SPECIAL_OSM_NODEID)
|
||||
{
|
||||
}
|
||||
|
||||
int lat;
|
||||
int lon;
|
||||
OSMNodeID node_id;
|
||||
|
||||
static QueryNode min_value()
|
||||
{
|
||||
return QueryNode(static_cast<int>(-90 * COORDINATE_PRECISION),
|
||||
static_cast<int>(-180 * COORDINATE_PRECISION),
|
||||
MIN_OSM_NODEID);
|
||||
}
|
||||
|
||||
static QueryNode max_value()
|
||||
{
|
||||
return QueryNode(static_cast<int>(90 * COORDINATE_PRECISION),
|
||||
static_cast<int>(180 * COORDINATE_PRECISION),
|
||||
MAX_OSM_NODEID);
|
||||
}
|
||||
|
||||
value_type operator[](const std::size_t n) const
|
||||
{
|
||||
switch (n)
|
||||
{
|
||||
case 1:
|
||||
return lat;
|
||||
case 0:
|
||||
return lon;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
BOOST_ASSERT_MSG(false, "should not happen");
|
||||
return std::numeric_limits<int>::lowest();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // QUERY_NODE_HPP
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "raster_source.hpp"
|
||||
|
||||
#include "../util/simple_logger.hpp"
|
||||
#include "../util/timing_util.hpp"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
RasterSource::RasterSource(RasterGrid _raster_data,
|
||||
std::size_t _width,
|
||||
std::size_t _height,
|
||||
int _xmin,
|
||||
int _xmax,
|
||||
int _ymin,
|
||||
int _ymax)
|
||||
: xstep(calcSize(_xmin, _xmax, _width)), ystep(calcSize(_ymin, _ymax, _height)),
|
||||
raster_data(std::move(_raster_data)), width(_width), height(_height), xmin(_xmin),
|
||||
xmax(_xmax), ymin(_ymin), ymax(_ymax)
|
||||
{
|
||||
BOOST_ASSERT(xstep != 0);
|
||||
BOOST_ASSERT(ystep != 0);
|
||||
}
|
||||
|
||||
float RasterSource::calcSize(int min, int max, std::size_t count) const
|
||||
{
|
||||
BOOST_ASSERT(count > 0);
|
||||
return (max - min) / (static_cast<float>(count) - 1);
|
||||
}
|
||||
|
||||
// Query raster source for nearest data point
|
||||
RasterDatum RasterSource::getRasterData(const int lon, const int lat) const
|
||||
{
|
||||
if (lon < xmin || lon > xmax || lat < ymin || lat > ymax)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const std::size_t xth = static_cast<std::size_t>(round((lon - xmin) / xstep));
|
||||
const std::size_t yth = static_cast<std::size_t>(round((ymax - lat) / ystep));
|
||||
|
||||
return {raster_data(xth, yth)};
|
||||
}
|
||||
|
||||
// Query raster source using bilinear interpolation
|
||||
RasterDatum RasterSource::getRasterInterpolate(const int lon, const int lat) const
|
||||
{
|
||||
if (lon < xmin || lon > xmax || lat < ymin || lat > ymax)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto xthP = (lon - xmin) / xstep;
|
||||
const auto ythP = (ymax - lat) / ystep;
|
||||
|
||||
const std::size_t top = static_cast<std::size_t>(fmax(floor(ythP), 0));
|
||||
const std::size_t bottom = static_cast<std::size_t>(fmin(ceil(ythP), height - 1));
|
||||
const std::size_t left = static_cast<std::size_t>(fmax(floor(xthP), 0));
|
||||
const std::size_t right = static_cast<std::size_t>(fmin(ceil(xthP), width - 1));
|
||||
|
||||
// Calculate distances from corners for bilinear interpolation
|
||||
const float fromLeft = (lon - left * xstep + xmin) / xstep;
|
||||
const float fromTop = (ymax - top * ystep - lat) / ystep;
|
||||
const float fromRight = 1 - fromLeft;
|
||||
const float fromBottom = 1 - fromTop;
|
||||
|
||||
return {static_cast<std::int32_t>(raster_data(left, top) * (fromRight * fromBottom) +
|
||||
raster_data(right, top) * (fromLeft * fromBottom) +
|
||||
raster_data(left, bottom) * (fromRight * fromTop) +
|
||||
raster_data(right, bottom) * (fromLeft * fromTop))};
|
||||
}
|
||||
|
||||
// Load raster source into memory
|
||||
int SourceContainer::loadRasterSource(const std::string &path_string,
|
||||
double xmin,
|
||||
double xmax,
|
||||
double ymin,
|
||||
double ymax,
|
||||
std::size_t nrows,
|
||||
std::size_t ncols)
|
||||
{
|
||||
const auto _xmin = static_cast<int>(xmin * COORDINATE_PRECISION);
|
||||
const auto _xmax = static_cast<int>(xmax * COORDINATE_PRECISION);
|
||||
const auto _ymin = static_cast<int>(ymin * COORDINATE_PRECISION);
|
||||
const auto _ymax = static_cast<int>(ymax * COORDINATE_PRECISION);
|
||||
|
||||
const auto itr = LoadedSourcePaths.find(path_string);
|
||||
if (itr != LoadedSourcePaths.end())
|
||||
{
|
||||
SimpleLogger().Write() << "[source loader] Already loaded source '" << path_string
|
||||
<< "' at source_id " << itr->second;
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
int source_id = static_cast<int>(LoadedSources.size());
|
||||
|
||||
SimpleLogger().Write() << "[source loader] Loading from " << path_string << " ... ";
|
||||
TIMER_START(loading_source);
|
||||
|
||||
boost::filesystem::path filepath(path_string);
|
||||
if (!boost::filesystem::exists(filepath))
|
||||
{
|
||||
throw osrm::exception("error reading: no such path");
|
||||
}
|
||||
|
||||
RasterGrid rasterData{filepath, ncols, nrows};
|
||||
|
||||
RasterSource source{std::move(rasterData), ncols, nrows, _xmin, _xmax, _ymin, _ymax};
|
||||
TIMER_STOP(loading_source);
|
||||
LoadedSourcePaths.emplace(path_string, source_id);
|
||||
LoadedSources.push_back(std::move(source));
|
||||
|
||||
SimpleLogger().Write() << "[source loader] ok, after " << TIMER_SEC(loading_source) << "s";
|
||||
|
||||
return source_id;
|
||||
}
|
||||
|
||||
// External function for looking up nearest data point from a specified source
|
||||
RasterDatum SourceContainer::getRasterDataFromSource(unsigned int source_id, int lon, int lat)
|
||||
{
|
||||
if (LoadedSources.size() < source_id + 1)
|
||||
{
|
||||
throw osrm::exception("error reading: no such loaded source");
|
||||
}
|
||||
|
||||
BOOST_ASSERT(lat < (90 * COORDINATE_PRECISION));
|
||||
BOOST_ASSERT(lat > (-90 * COORDINATE_PRECISION));
|
||||
BOOST_ASSERT(lon < (180 * COORDINATE_PRECISION));
|
||||
BOOST_ASSERT(lon > (-180 * COORDINATE_PRECISION));
|
||||
|
||||
const auto &found = LoadedSources[source_id];
|
||||
return found.getRasterData(lon, lat);
|
||||
}
|
||||
|
||||
// External function for looking up interpolated data from a specified source
|
||||
RasterDatum
|
||||
SourceContainer::getRasterInterpolateFromSource(unsigned int source_id, int lon, int lat)
|
||||
{
|
||||
if (LoadedSources.size() < source_id + 1)
|
||||
{
|
||||
throw osrm::exception("error reading: no such loaded source");
|
||||
}
|
||||
|
||||
BOOST_ASSERT(lat < (90 * COORDINATE_PRECISION));
|
||||
BOOST_ASSERT(lat > (-90 * COORDINATE_PRECISION));
|
||||
BOOST_ASSERT(lon < (180 * COORDINATE_PRECISION));
|
||||
BOOST_ASSERT(lon > (-180 * COORDINATE_PRECISION));
|
||||
|
||||
const auto &found = LoadedSources[source_id];
|
||||
return found.getRasterInterpolate(lon, lat);
|
||||
}
|
||||
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef RECTANGLE_HPP
|
||||
#define RECTANGLE_HPP
|
||||
|
||||
#include "../algorithms/coordinate_calculation.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
// TODO: Make template type, add tests
|
||||
struct RectangleInt2D
|
||||
{
|
||||
RectangleInt2D()
|
||||
: min_lon(std::numeric_limits<int32_t>::max()),
|
||||
max_lon(std::numeric_limits<int32_t>::min()),
|
||||
min_lat(std::numeric_limits<int32_t>::max()), max_lat(std::numeric_limits<int32_t>::min())
|
||||
{
|
||||
}
|
||||
|
||||
int32_t min_lon, max_lon;
|
||||
int32_t min_lat, max_lat;
|
||||
|
||||
void MergeBoundingBoxes(const RectangleInt2D &other)
|
||||
{
|
||||
min_lon = std::min(min_lon, other.min_lon);
|
||||
max_lon = std::max(max_lon, other.max_lon);
|
||||
min_lat = std::min(min_lat, other.min_lat);
|
||||
max_lat = std::max(max_lat, other.max_lat);
|
||||
BOOST_ASSERT(min_lat != std::numeric_limits<int32_t>::min());
|
||||
BOOST_ASSERT(min_lon != std::numeric_limits<int32_t>::min());
|
||||
BOOST_ASSERT(max_lat != std::numeric_limits<int32_t>::min());
|
||||
BOOST_ASSERT(max_lon != std::numeric_limits<int32_t>::min());
|
||||
}
|
||||
|
||||
FixedPointCoordinate Centroid() const
|
||||
{
|
||||
FixedPointCoordinate centroid;
|
||||
// The coordinates of the midpoints are given by:
|
||||
// x = (x1 + x2) /2 and y = (y1 + y2) /2.
|
||||
centroid.lon = (min_lon + max_lon) / 2;
|
||||
centroid.lat = (min_lat + max_lat) / 2;
|
||||
return centroid;
|
||||
}
|
||||
|
||||
bool Intersects(const RectangleInt2D &other) const
|
||||
{
|
||||
FixedPointCoordinate upper_left(other.max_lat, other.min_lon);
|
||||
FixedPointCoordinate upper_right(other.max_lat, other.max_lon);
|
||||
FixedPointCoordinate lower_right(other.min_lat, other.max_lon);
|
||||
FixedPointCoordinate lower_left(other.min_lat, other.min_lon);
|
||||
|
||||
return (Contains(upper_left) || Contains(upper_right) || Contains(lower_right) ||
|
||||
Contains(lower_left));
|
||||
}
|
||||
|
||||
float GetMinDist(const FixedPointCoordinate &location) const
|
||||
{
|
||||
const bool is_contained = Contains(location);
|
||||
if (is_contained)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
enum Direction
|
||||
{
|
||||
INVALID = 0,
|
||||
NORTH = 1,
|
||||
SOUTH = 2,
|
||||
EAST = 4,
|
||||
NORTH_EAST = 5,
|
||||
SOUTH_EAST = 6,
|
||||
WEST = 8,
|
||||
NORTH_WEST = 9,
|
||||
SOUTH_WEST = 10
|
||||
};
|
||||
|
||||
Direction d = INVALID;
|
||||
if (location.lat > max_lat)
|
||||
d = (Direction)(d | NORTH);
|
||||
else if (location.lat < min_lat)
|
||||
d = (Direction)(d | SOUTH);
|
||||
if (location.lon > max_lon)
|
||||
d = (Direction)(d | EAST);
|
||||
else if (location.lon < min_lon)
|
||||
d = (Direction)(d | WEST);
|
||||
|
||||
BOOST_ASSERT(d != INVALID);
|
||||
|
||||
float min_dist = std::numeric_limits<float>::max();
|
||||
switch (d)
|
||||
{
|
||||
case NORTH:
|
||||
min_dist = coordinate_calculation::great_circle_distance(
|
||||
location, FixedPointCoordinate(max_lat, location.lon));
|
||||
break;
|
||||
case SOUTH:
|
||||
min_dist = coordinate_calculation::great_circle_distance(
|
||||
location, FixedPointCoordinate(min_lat, location.lon));
|
||||
break;
|
||||
case WEST:
|
||||
min_dist = coordinate_calculation::great_circle_distance(
|
||||
location, FixedPointCoordinate(location.lat, min_lon));
|
||||
break;
|
||||
case EAST:
|
||||
min_dist = coordinate_calculation::great_circle_distance(
|
||||
location, FixedPointCoordinate(location.lat, max_lon));
|
||||
break;
|
||||
case NORTH_EAST:
|
||||
min_dist = coordinate_calculation::great_circle_distance(
|
||||
location, FixedPointCoordinate(max_lat, max_lon));
|
||||
break;
|
||||
case NORTH_WEST:
|
||||
min_dist = coordinate_calculation::great_circle_distance(
|
||||
location, FixedPointCoordinate(max_lat, min_lon));
|
||||
break;
|
||||
case SOUTH_EAST:
|
||||
min_dist = coordinate_calculation::great_circle_distance(
|
||||
location, FixedPointCoordinate(min_lat, max_lon));
|
||||
break;
|
||||
case SOUTH_WEST:
|
||||
min_dist = coordinate_calculation::great_circle_distance(
|
||||
location, FixedPointCoordinate(min_lat, min_lon));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(min_dist < std::numeric_limits<float>::max());
|
||||
|
||||
return min_dist;
|
||||
}
|
||||
|
||||
float GetMinMaxDist(const FixedPointCoordinate &location) const
|
||||
{
|
||||
float min_max_dist = std::numeric_limits<float>::max();
|
||||
// Get minmax distance to each of the four sides
|
||||
const FixedPointCoordinate upper_left(max_lat, min_lon);
|
||||
const FixedPointCoordinate upper_right(max_lat, max_lon);
|
||||
const FixedPointCoordinate lower_right(min_lat, max_lon);
|
||||
const FixedPointCoordinate lower_left(min_lat, min_lon);
|
||||
|
||||
min_max_dist = std::min(
|
||||
min_max_dist,
|
||||
std::max(coordinate_calculation::great_circle_distance(location, upper_left),
|
||||
coordinate_calculation::great_circle_distance(location, upper_right)));
|
||||
|
||||
min_max_dist = std::min(
|
||||
min_max_dist,
|
||||
std::max(coordinate_calculation::great_circle_distance(location, upper_right),
|
||||
coordinate_calculation::great_circle_distance(location, lower_right)));
|
||||
|
||||
min_max_dist =
|
||||
std::min(min_max_dist,
|
||||
std::max(coordinate_calculation::great_circle_distance(location, lower_right),
|
||||
coordinate_calculation::great_circle_distance(location, lower_left)));
|
||||
|
||||
min_max_dist =
|
||||
std::min(min_max_dist,
|
||||
std::max(coordinate_calculation::great_circle_distance(location, lower_left),
|
||||
coordinate_calculation::great_circle_distance(location, upper_left)));
|
||||
return min_max_dist;
|
||||
}
|
||||
|
||||
bool Contains(const FixedPointCoordinate &location) const
|
||||
{
|
||||
const bool lats_contained = (location.lat >= min_lat) && (location.lat <= max_lat);
|
||||
const bool lons_contained = (location.lon >= min_lon) && (location.lon <= max_lon);
|
||||
return lats_contained && lons_contained;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <boost/fusion/container/vector.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic.hpp>
|
||||
#include <boost/fusion/include/at_c.hpp>
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
|
||||
#include <osrm/route_parameters.hpp>
|
||||
|
||||
#include "../algorithms/polyline_compressor.hpp"
|
||||
|
||||
RouteParameters::RouteParameters()
|
||||
: zoom_level(18), print_instructions(false), alternate_route(true), geometry(true),
|
||||
compression(true), deprecatedAPI(false), uturn_default(false), classify(false),
|
||||
matching_beta(5), gps_precision(5), check_sum(-1), num_results(1)
|
||||
{
|
||||
}
|
||||
|
||||
void RouteParameters::setZoomLevel(const short level)
|
||||
{
|
||||
if (18 >= level && 0 <= level)
|
||||
{
|
||||
zoom_level = level;
|
||||
}
|
||||
}
|
||||
|
||||
void RouteParameters::setNumberOfResults(const short number)
|
||||
{
|
||||
if (number > 0 && number <= 100)
|
||||
{
|
||||
num_results = number;
|
||||
}
|
||||
}
|
||||
|
||||
void RouteParameters::setAlternateRouteFlag(const bool flag) { alternate_route = flag; }
|
||||
|
||||
void RouteParameters::setUTurn(const bool flag)
|
||||
{
|
||||
// the API grammar should make sure this never happens
|
||||
BOOST_ASSERT(!uturns.empty());
|
||||
uturns.back() = flag;
|
||||
}
|
||||
|
||||
void RouteParameters::setAllUTurns(const bool flag)
|
||||
{
|
||||
// if the flag flips the default, then we erase everything.
|
||||
if (flag)
|
||||
{
|
||||
uturn_default = flag;
|
||||
uturns.clear();
|
||||
uturns.resize(coordinates.size(), uturn_default);
|
||||
}
|
||||
}
|
||||
|
||||
void RouteParameters::setDeprecatedAPIFlag(const std::string &) { deprecatedAPI = true; }
|
||||
|
||||
void RouteParameters::setChecksum(const unsigned sum) { check_sum = sum; }
|
||||
|
||||
void RouteParameters::setInstructionFlag(const bool flag) { print_instructions = flag; }
|
||||
|
||||
void RouteParameters::setService(const std::string &service_string) { service = service_string; }
|
||||
|
||||
void RouteParameters::setClassify(const bool flag) { classify = flag; }
|
||||
|
||||
void RouteParameters::setMatchingBeta(const double beta) { matching_beta = beta; }
|
||||
|
||||
void RouteParameters::setGPSPrecision(const double precision) { gps_precision = precision; }
|
||||
|
||||
void RouteParameters::setOutputFormat(const std::string &format) { output_format = format; }
|
||||
|
||||
void RouteParameters::setJSONpParameter(const std::string ¶meter)
|
||||
{
|
||||
jsonp_parameter = parameter;
|
||||
}
|
||||
|
||||
void RouteParameters::addHint(const std::string &hint)
|
||||
{
|
||||
hints.resize(coordinates.size());
|
||||
if (!hints.empty())
|
||||
{
|
||||
hints.back() = hint;
|
||||
}
|
||||
}
|
||||
|
||||
void RouteParameters::addTimestamp(const unsigned timestamp)
|
||||
{
|
||||
timestamps.resize(coordinates.size());
|
||||
if (!timestamps.empty())
|
||||
{
|
||||
timestamps.back() = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
void RouteParameters::addBearing(
|
||||
const boost::fusion::vector<int, boost::optional<int>> &received_bearing,
|
||||
boost::spirit::qi::unused_type /* unused */, bool& pass)
|
||||
{
|
||||
pass = false;
|
||||
const int bearing = boost::fusion::at_c<0>(received_bearing);
|
||||
const boost::optional<int> range = boost::fusion::at_c<1>(received_bearing);
|
||||
if (bearing < 0 || bearing > 359) return;
|
||||
if (range && (*range < 0 || *range > 180)) return;
|
||||
bearings.emplace_back(std::make_pair(bearing,range));
|
||||
pass = true;
|
||||
}
|
||||
|
||||
void RouteParameters::setLanguage(const std::string &language_string)
|
||||
{
|
||||
language = language_string;
|
||||
}
|
||||
|
||||
void RouteParameters::setGeometryFlag(const bool flag) { geometry = flag; }
|
||||
|
||||
void RouteParameters::setCompressionFlag(const bool flag) { compression = flag; }
|
||||
|
||||
void RouteParameters::addCoordinate(
|
||||
const boost::fusion::vector<double, double> &received_coordinates)
|
||||
{
|
||||
coordinates.emplace_back(
|
||||
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
|
||||
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
|
||||
is_source.push_back(true);
|
||||
is_destination.push_back(true);
|
||||
uturns.push_back(uturn_default);
|
||||
}
|
||||
|
||||
void RouteParameters::addDestination(
|
||||
const boost::fusion::vector<double, double> &received_coordinates)
|
||||
{
|
||||
coordinates.emplace_back(
|
||||
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
|
||||
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
|
||||
is_source.push_back(false);
|
||||
is_destination.push_back(true);
|
||||
uturns.push_back(uturn_default);
|
||||
}
|
||||
|
||||
void RouteParameters::addSource(
|
||||
const boost::fusion::vector<double, double> &received_coordinates)
|
||||
{
|
||||
coordinates.emplace_back(
|
||||
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<0>(received_coordinates)),
|
||||
static_cast<int>(COORDINATE_PRECISION * boost::fusion::at_c<1>(received_coordinates)));
|
||||
is_source.push_back(true);
|
||||
is_destination.push_back(false);
|
||||
uturns.push_back(uturn_default);
|
||||
}
|
||||
|
||||
void RouteParameters::getCoordinatesFromGeometry(const std::string &geometry_string)
|
||||
{
|
||||
PolylineCompressor pc;
|
||||
coordinates = pc.decode_string(geometry_string);
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SEARCH_ENGINE_HPP
|
||||
#define SEARCH_ENGINE_HPP
|
||||
|
||||
#include "search_engine_data.hpp"
|
||||
#include "../routing_algorithms/alternative_path.hpp"
|
||||
#include "../routing_algorithms/many_to_many.hpp"
|
||||
#include "../routing_algorithms/map_matching.hpp"
|
||||
#include "../routing_algorithms/shortest_path.hpp"
|
||||
#include "../routing_algorithms/direct_shortest_path.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
template <class DataFacadeT> class SearchEngine
|
||||
{
|
||||
private:
|
||||
DataFacadeT *facade;
|
||||
SearchEngineData engine_working_data;
|
||||
|
||||
public:
|
||||
ShortestPathRouting<DataFacadeT> shortest_path;
|
||||
DirectShortestPathRouting<DataFacadeT> direct_shortest_path;
|
||||
AlternativeRouting<DataFacadeT> alternative_path;
|
||||
ManyToManyRouting<DataFacadeT> distance_table;
|
||||
MapMatching<DataFacadeT> map_matching;
|
||||
|
||||
explicit SearchEngine(DataFacadeT *facade)
|
||||
: facade(facade),
|
||||
shortest_path(facade, engine_working_data),
|
||||
direct_shortest_path(facade, engine_working_data),
|
||||
alternative_path(facade, engine_working_data),
|
||||
distance_table(facade, engine_working_data),
|
||||
map_matching(facade, engine_working_data)
|
||||
{
|
||||
static_assert(!std::is_pointer<DataFacadeT>::value, "don't instantiate with ptr type");
|
||||
static_assert(std::is_object<DataFacadeT>::value,
|
||||
"don't instantiate with void, function, or reference");
|
||||
}
|
||||
|
||||
~SearchEngine() {}
|
||||
};
|
||||
|
||||
#endif // SEARCH_ENGINE_HPP
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SEARCH_ENGINE_DATA_HPP
|
||||
#define SEARCH_ENGINE_DATA_HPP
|
||||
|
||||
#include <boost/thread/tss.hpp>
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "binary_heap.hpp"
|
||||
|
||||
struct HeapData
|
||||
{
|
||||
NodeID parent;
|
||||
/* explicit */ HeapData(NodeID p) : parent(p) {}
|
||||
};
|
||||
|
||||
struct SearchEngineData
|
||||
{
|
||||
using QueryHeap = BinaryHeap<NodeID, NodeID, int, HeapData, UnorderedMapStorage<NodeID, int>>;
|
||||
using SearchEngineHeapPtr = boost::thread_specific_ptr<QueryHeap>;
|
||||
|
||||
static SearchEngineHeapPtr forward_heap_1;
|
||||
static SearchEngineHeapPtr reverse_heap_1;
|
||||
static SearchEngineHeapPtr forward_heap_2;
|
||||
static SearchEngineHeapPtr reverse_heap_2;
|
||||
static SearchEngineHeapPtr forward_heap_3;
|
||||
static SearchEngineHeapPtr reverse_heap_3;
|
||||
|
||||
void InitializeOrClearFirstThreadLocalStorage(const unsigned number_of_nodes);
|
||||
|
||||
void InitializeOrClearSecondThreadLocalStorage(const unsigned number_of_nodes);
|
||||
|
||||
void InitializeOrClearThirdThreadLocalStorage(const unsigned number_of_nodes);
|
||||
};
|
||||
|
||||
#endif // SEARCH_ENGINE_DATA_HPP
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SEGMENT_INFORMATION_HPP
|
||||
#define SEGMENT_INFORMATION_HPP
|
||||
|
||||
#include "turn_instructions.hpp"
|
||||
|
||||
#include "../data_structures/travel_mode.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
#include <utility>
|
||||
|
||||
// Struct fits everything in one cache line
|
||||
struct SegmentInformation
|
||||
{
|
||||
FixedPointCoordinate location;
|
||||
NodeID name_id;
|
||||
EdgeWeight duration;
|
||||
float length;
|
||||
short pre_turn_bearing; // more than enough [0..3600] fits into 12 bits
|
||||
short post_turn_bearing;
|
||||
TurnInstruction turn_instruction;
|
||||
TravelMode travel_mode;
|
||||
bool necessary;
|
||||
bool is_via_location;
|
||||
|
||||
explicit SegmentInformation(FixedPointCoordinate location,
|
||||
const NodeID name_id,
|
||||
const EdgeWeight duration,
|
||||
const float length,
|
||||
const TurnInstruction turn_instruction,
|
||||
const bool necessary,
|
||||
const bool is_via_location,
|
||||
const TravelMode travel_mode)
|
||||
: location(std::move(location)), name_id(name_id), duration(duration), length(length),
|
||||
pre_turn_bearing(0), post_turn_bearing(0), turn_instruction(turn_instruction), travel_mode(travel_mode),
|
||||
necessary(necessary), is_via_location(is_via_location)
|
||||
{
|
||||
}
|
||||
|
||||
explicit SegmentInformation(FixedPointCoordinate location,
|
||||
const NodeID name_id,
|
||||
const EdgeWeight duration,
|
||||
const float length,
|
||||
const TurnInstruction turn_instruction,
|
||||
const TravelMode travel_mode)
|
||||
: location(std::move(location)), name_id(name_id), duration(duration), length(length),
|
||||
pre_turn_bearing(0), post_turn_bearing(0), turn_instruction(turn_instruction), travel_mode(travel_mode),
|
||||
necessary(turn_instruction != TurnInstruction::NoTurn), is_via_location(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* SEGMENT_INFORMATION_HPP */
|
||||
@@ -1,386 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SHARED_MEMORY_FACTORY_HPP
|
||||
#define SHARED_MEMORY_FACTORY_HPP
|
||||
|
||||
#include "../util/osrm_exception.hpp"
|
||||
#include "../util/simple_logger.hpp"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/interprocess/mapped_region.hpp>
|
||||
#ifndef WIN32
|
||||
#include <boost/interprocess/xsi_shared_memory.hpp>
|
||||
#else
|
||||
#include <boost/interprocess/shared_memory_object.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#endif
|
||||
|
||||
// #include <cstring>
|
||||
#include <cstdint>
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
|
||||
struct OSRMLockFile
|
||||
{
|
||||
boost::filesystem::path operator()()
|
||||
{
|
||||
boost::filesystem::path temp_dir = boost::filesystem::temp_directory_path();
|
||||
boost::filesystem::path lock_file = temp_dir / "osrm.lock";
|
||||
return lock_file;
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef WIN32
|
||||
class SharedMemory
|
||||
{
|
||||
|
||||
// Remove shared memory on destruction
|
||||
class shm_remove
|
||||
{
|
||||
private:
|
||||
int m_shmid;
|
||||
bool m_initialized;
|
||||
|
||||
public:
|
||||
void SetID(int shmid)
|
||||
{
|
||||
m_shmid = shmid;
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
shm_remove() : m_shmid(INT_MIN), m_initialized(false) {}
|
||||
shm_remove(const shm_remove &) = delete;
|
||||
~shm_remove()
|
||||
{
|
||||
if (m_initialized)
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "automatic memory deallocation";
|
||||
if (!boost::interprocess::xsi_shared_memory::remove(m_shmid))
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "could not deallocate id " << m_shmid;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
void *Ptr() const { return region.get_address(); }
|
||||
|
||||
SharedMemory() = delete;
|
||||
SharedMemory(const SharedMemory &) = delete;
|
||||
SharedMemory &operator=(const SharedMemory &) = delete;
|
||||
|
||||
template <typename IdentifierT>
|
||||
SharedMemory(const boost::filesystem::path &lock_file,
|
||||
const IdentifierT id,
|
||||
const uint64_t size = 0,
|
||||
bool read_write = false,
|
||||
bool remove_prev = true)
|
||||
: key(lock_file.string().c_str(), id)
|
||||
{
|
||||
if (0 == size)
|
||||
{ // read_only
|
||||
shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_only, key);
|
||||
|
||||
region = boost::interprocess::mapped_region(
|
||||
shm,
|
||||
(read_write ? boost::interprocess::read_write : boost::interprocess::read_only));
|
||||
}
|
||||
else
|
||||
{ // writeable pointer
|
||||
// remove previously allocated mem
|
||||
if (remove_prev)
|
||||
{
|
||||
Remove(key);
|
||||
}
|
||||
shm = boost::interprocess::xsi_shared_memory(boost::interprocess::open_or_create, key,
|
||||
size);
|
||||
#ifdef __linux__
|
||||
if (-1 == shmctl(shm.get_shmid(), SHM_LOCK, nullptr))
|
||||
{
|
||||
if (ENOMEM == errno)
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << "could not lock shared memory to RAM";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_write);
|
||||
|
||||
remover.SetID(shm.get_shmid());
|
||||
SimpleLogger().Write(logDEBUG) << "writeable memory allocated " << size << " bytes";
|
||||
}
|
||||
}
|
||||
|
||||
template <typename IdentifierT> static bool RegionExists(const IdentifierT id)
|
||||
{
|
||||
bool result = true;
|
||||
try
|
||||
{
|
||||
OSRMLockFile lock_file;
|
||||
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
|
||||
result = RegionExists(key);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename IdentifierT> static bool Remove(const IdentifierT id)
|
||||
{
|
||||
OSRMLockFile lock_file;
|
||||
boost::interprocess::xsi_key key(lock_file().string().c_str(), id);
|
||||
return Remove(key);
|
||||
}
|
||||
|
||||
private:
|
||||
static bool RegionExists(const boost::interprocess::xsi_key &key)
|
||||
{
|
||||
bool result = true;
|
||||
try
|
||||
{
|
||||
boost::interprocess::xsi_shared_memory shm(boost::interprocess::open_only, key);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool Remove(const boost::interprocess::xsi_key &key)
|
||||
{
|
||||
bool ret = false;
|
||||
try
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "deallocating prev memory";
|
||||
boost::interprocess::xsi_shared_memory xsi(boost::interprocess::open_only, key);
|
||||
ret = boost::interprocess::xsi_shared_memory::remove(xsi.get_shmid());
|
||||
}
|
||||
catch (const boost::interprocess::interprocess_exception &e)
|
||||
{
|
||||
if (e.get_error_code() != boost::interprocess::not_found_error)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
boost::interprocess::xsi_key key;
|
||||
boost::interprocess::xsi_shared_memory shm;
|
||||
boost::interprocess::mapped_region region;
|
||||
shm_remove remover;
|
||||
};
|
||||
#else
|
||||
// Windows - specific code
|
||||
class SharedMemory
|
||||
{
|
||||
SharedMemory(const SharedMemory &) = delete;
|
||||
SharedMemory &operator=(const SharedMemory &) = delete;
|
||||
// Remove shared memory on destruction
|
||||
class shm_remove
|
||||
{
|
||||
private:
|
||||
shm_remove(const shm_remove &) = delete;
|
||||
shm_remove &operator=(const shm_remove &) = delete;
|
||||
char *m_shmid;
|
||||
bool m_initialized;
|
||||
|
||||
public:
|
||||
void SetID(char *shmid)
|
||||
{
|
||||
m_shmid = shmid;
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
shm_remove() : m_shmid("undefined"), m_initialized(false) {}
|
||||
|
||||
~shm_remove()
|
||||
{
|
||||
if (m_initialized)
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "automatic memory deallocation";
|
||||
if (!boost::interprocess::shared_memory_object::remove(m_shmid))
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "could not deallocate id " << m_shmid;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
void *Ptr() const { return region.get_address(); }
|
||||
|
||||
SharedMemory(const boost::filesystem::path &lock_file,
|
||||
const int id,
|
||||
const uint64_t size = 0,
|
||||
bool read_write = false,
|
||||
bool remove_prev = true)
|
||||
{
|
||||
sprintf(key, "%s.%d", "osrm.lock", id);
|
||||
if (0 == size)
|
||||
{ // read_only
|
||||
shm = boost::interprocess::shared_memory_object(
|
||||
boost::interprocess::open_only, key,
|
||||
read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
|
||||
region = boost::interprocess::mapped_region(
|
||||
shm, read_write ? boost::interprocess::read_write : boost::interprocess::read_only);
|
||||
}
|
||||
else
|
||||
{ // writeable pointer
|
||||
// remove previously allocated mem
|
||||
if (remove_prev)
|
||||
{
|
||||
Remove(key);
|
||||
}
|
||||
shm = boost::interprocess::shared_memory_object(boost::interprocess::open_or_create,
|
||||
key, boost::interprocess::read_write);
|
||||
shm.truncate(size);
|
||||
region = boost::interprocess::mapped_region(shm, boost::interprocess::read_write);
|
||||
|
||||
remover.SetID(key);
|
||||
SimpleLogger().Write(logDEBUG) << "writeable memory allocated " << size << " bytes";
|
||||
}
|
||||
}
|
||||
|
||||
static bool RegionExists(const int id)
|
||||
{
|
||||
bool result = true;
|
||||
try
|
||||
{
|
||||
char k[500];
|
||||
build_key(id, k);
|
||||
result = RegionExists(k);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool Remove(const int id)
|
||||
{
|
||||
char k[500];
|
||||
build_key(id, k);
|
||||
return Remove(k);
|
||||
}
|
||||
|
||||
private:
|
||||
static void build_key(int id, char *key) { sprintf(key, "%s.%d", "osrm.lock", id); }
|
||||
|
||||
static bool RegionExists(const char *key)
|
||||
{
|
||||
bool result = true;
|
||||
try
|
||||
{
|
||||
boost::interprocess::shared_memory_object shm(boost::interprocess::open_only, key,
|
||||
boost::interprocess::read_write);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool Remove(char *key)
|
||||
{
|
||||
bool ret = false;
|
||||
try
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "deallocating prev memory";
|
||||
ret = boost::interprocess::shared_memory_object::remove(key);
|
||||
}
|
||||
catch (const boost::interprocess::interprocess_exception &e)
|
||||
{
|
||||
if (e.get_error_code() != boost::interprocess::not_found_error)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char key[500];
|
||||
boost::interprocess::shared_memory_object shm;
|
||||
boost::interprocess::mapped_region region;
|
||||
shm_remove remover;
|
||||
};
|
||||
#endif
|
||||
|
||||
template <class LockFileT = OSRMLockFile> class SharedMemoryFactory_tmpl
|
||||
{
|
||||
public:
|
||||
template <typename IdentifierT>
|
||||
static SharedMemory *Get(const IdentifierT &id,
|
||||
const uint64_t size = 0,
|
||||
bool read_write = false,
|
||||
bool remove_prev = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
LockFileT lock_file;
|
||||
if (!boost::filesystem::exists(lock_file()))
|
||||
{
|
||||
if (0 == size)
|
||||
{
|
||||
throw osrm::exception("lock file does not exist, exiting");
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::filesystem::ofstream ofs(lock_file());
|
||||
ofs.close();
|
||||
}
|
||||
}
|
||||
return new SharedMemory(lock_file(), id, size, read_write, remove_prev);
|
||||
}
|
||||
catch (const boost::interprocess::interprocess_exception &e)
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what() << ", code "
|
||||
<< e.get_error_code();
|
||||
throw osrm::exception(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
SharedMemoryFactory_tmpl() = delete;
|
||||
SharedMemoryFactory_tmpl(const SharedMemoryFactory_tmpl &) = delete;
|
||||
SharedMemoryFactory_tmpl &operator=(const SharedMemoryFactory_tmpl &) = delete;
|
||||
};
|
||||
|
||||
using SharedMemoryFactory = SharedMemoryFactory_tmpl<>;
|
||||
|
||||
#endif // SHARED_MEMORY_FACTORY_HPP
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SHARED_MEMORY_VECTOR_WRAPPER_HPP
|
||||
#define SHARED_MEMORY_VECTOR_WRAPPER_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
template <typename DataT> class ShMemIterator : public std::iterator<std::input_iterator_tag, DataT>
|
||||
{
|
||||
DataT *p;
|
||||
|
||||
public:
|
||||
explicit ShMemIterator(DataT *x) : p(x) {}
|
||||
ShMemIterator(const ShMemIterator &mit) : p(mit.p) {}
|
||||
ShMemIterator &operator++()
|
||||
{
|
||||
++p;
|
||||
return *this;
|
||||
}
|
||||
ShMemIterator operator++(int)
|
||||
{
|
||||
ShMemIterator tmp(*this);
|
||||
operator++();
|
||||
return tmp;
|
||||
}
|
||||
ShMemIterator operator+(std::ptrdiff_t diff)
|
||||
{
|
||||
ShMemIterator tmp(p + diff);
|
||||
return tmp;
|
||||
}
|
||||
bool operator==(const ShMemIterator &rhs) { return p == rhs.p; }
|
||||
bool operator!=(const ShMemIterator &rhs) { return p != rhs.p; }
|
||||
DataT &operator*() { return *p; }
|
||||
};
|
||||
|
||||
template <typename DataT> class SharedMemoryWrapper
|
||||
{
|
||||
private:
|
||||
DataT *m_ptr;
|
||||
std::size_t m_size;
|
||||
|
||||
public:
|
||||
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
|
||||
|
||||
SharedMemoryWrapper(DataT *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
|
||||
|
||||
void swap(SharedMemoryWrapper<DataT> &other)
|
||||
{
|
||||
// BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
|
||||
std::swap(m_size, other.m_size);
|
||||
std::swap(m_ptr, other.m_ptr);
|
||||
}
|
||||
|
||||
DataT &at(const std::size_t index) { return m_ptr[index]; }
|
||||
|
||||
const DataT &at(const std::size_t index) const { return m_ptr[index]; }
|
||||
|
||||
ShMemIterator<DataT> begin() const { return ShMemIterator<DataT>(m_ptr); }
|
||||
|
||||
ShMemIterator<DataT> end() const { return ShMemIterator<DataT>(m_ptr + m_size); }
|
||||
|
||||
std::size_t size() const { return m_size; }
|
||||
|
||||
bool empty() const { return 0 == size(); }
|
||||
|
||||
DataT &operator[](const unsigned index)
|
||||
{
|
||||
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
||||
return m_ptr[index];
|
||||
}
|
||||
|
||||
const DataT &operator[](const unsigned index) const
|
||||
{
|
||||
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
||||
return m_ptr[index];
|
||||
}
|
||||
};
|
||||
|
||||
template <> class SharedMemoryWrapper<bool>
|
||||
{
|
||||
private:
|
||||
unsigned *m_ptr;
|
||||
std::size_t m_size;
|
||||
|
||||
public:
|
||||
SharedMemoryWrapper() : m_ptr(nullptr), m_size(0) {}
|
||||
|
||||
SharedMemoryWrapper(unsigned *ptr, std::size_t size) : m_ptr(ptr), m_size(size) {}
|
||||
|
||||
void swap(SharedMemoryWrapper<bool> &other)
|
||||
{
|
||||
// BOOST_ASSERT_MSG(m_size != 0 || other.size() != 0, "size invalid");
|
||||
std::swap(m_size, other.m_size);
|
||||
std::swap(m_ptr, other.m_ptr);
|
||||
}
|
||||
|
||||
bool at(const std::size_t index) const
|
||||
{
|
||||
const std::size_t bucket = index / 32;
|
||||
const unsigned offset = static_cast<unsigned>(index % 32);
|
||||
return m_ptr[bucket] & (1 << offset);
|
||||
}
|
||||
|
||||
std::size_t size() const { return m_size; }
|
||||
|
||||
bool empty() const { return 0 == size(); }
|
||||
|
||||
bool operator[](const unsigned index)
|
||||
{
|
||||
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
||||
const unsigned bucket = index / 32;
|
||||
const unsigned offset = index % 32;
|
||||
return m_ptr[bucket] & (1 << offset);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DataT, bool UseSharedMemory> struct ShM
|
||||
{
|
||||
using vector = typename std::conditional<UseSharedMemory,
|
||||
SharedMemoryWrapper<DataT>,
|
||||
std::vector<DataT>>::type;
|
||||
};
|
||||
|
||||
#endif // SHARED_MEMORY_VECTOR_WRAPPER_HPP
|
||||
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
// KD Tree coded by Christian Vetter, Monav Project
|
||||
|
||||
#ifndef STATICKDTREE_HPP
|
||||
#define STATICKDTREE_HPP
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stack>
|
||||
#include <limits>
|
||||
|
||||
namespace KDTree
|
||||
{
|
||||
|
||||
#define KDTREE_BASESIZE (8)
|
||||
|
||||
template <unsigned k, typename T> class BoundingBox
|
||||
{
|
||||
public:
|
||||
BoundingBox()
|
||||
{
|
||||
for (unsigned dim = 0; dim < k; ++dim)
|
||||
{
|
||||
min[dim] = std::numeric_limits<T>::min();
|
||||
max[dim] = std::numeric_limits<T>::max();
|
||||
}
|
||||
}
|
||||
|
||||
T min[k];
|
||||
T max[k];
|
||||
};
|
||||
|
||||
struct NoData
|
||||
{
|
||||
};
|
||||
|
||||
template <unsigned k, typename T> class EuclidianMetric
|
||||
{
|
||||
public:
|
||||
double operator()(const T left[k], const T right[k])
|
||||
{
|
||||
double result = 0;
|
||||
for (unsigned i = 0; i < k; ++i)
|
||||
{
|
||||
double temp = (double)left[i] - (double)right[i];
|
||||
result += temp * temp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double operator()(const BoundingBox<k, T> &box, const T point[k])
|
||||
{
|
||||
T nearest[k];
|
||||
for (unsigned dim = 0; dim < k; ++dim)
|
||||
{
|
||||
if (point[dim] < box.min[dim])
|
||||
nearest[dim] = box.min[dim];
|
||||
else if (point[dim] > box.max[dim])
|
||||
nearest[dim] = box.max[dim];
|
||||
else
|
||||
nearest[dim] = point[dim];
|
||||
}
|
||||
return operator()(point, nearest);
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned k, typename T, typename Data = NoData, typename Metric = EuclidianMetric<k, T>>
|
||||
class StaticKDTree
|
||||
{
|
||||
public:
|
||||
struct InputPoint
|
||||
{
|
||||
T coordinates[k];
|
||||
Data data;
|
||||
bool operator==(const InputPoint &right)
|
||||
{
|
||||
for (int i = 0; i < k; i++)
|
||||
{
|
||||
if (coordinates[i] != right.coordinates[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
explicit StaticKDTree(std::vector<InputPoint> *points)
|
||||
{
|
||||
BOOST_ASSERT(k > 0);
|
||||
BOOST_ASSERT(points->size() > 0);
|
||||
size = points->size();
|
||||
kdtree = new InputPoint[size];
|
||||
for (Iterator i = 0; i != size; ++i)
|
||||
{
|
||||
kdtree[i] = points->at(i);
|
||||
for (unsigned dim = 0; dim < k; ++dim)
|
||||
{
|
||||
if (kdtree[i].coordinates[dim] < boundingBox.min[dim])
|
||||
boundingBox.min[dim] = kdtree[i].coordinates[dim];
|
||||
if (kdtree[i].coordinates[dim] > boundingBox.max[dim])
|
||||
boundingBox.max[dim] = kdtree[i].coordinates[dim];
|
||||
}
|
||||
}
|
||||
std::stack<Tree> s;
|
||||
s.push(Tree(0, size, 0));
|
||||
while (!s.empty())
|
||||
{
|
||||
Tree tree = s.top();
|
||||
s.pop();
|
||||
|
||||
if (tree.right - tree.left < KDTREE_BASESIZE)
|
||||
continue;
|
||||
|
||||
Iterator middle = tree.left + (tree.right - tree.left) / 2;
|
||||
std::nth_element(kdtree + tree.left, kdtree + middle, kdtree + tree.right,
|
||||
Less(tree.dimension));
|
||||
s.push(Tree(tree.left, middle, (tree.dimension + 1) % k));
|
||||
s.push(Tree(middle + 1, tree.right, (tree.dimension + 1) % k));
|
||||
}
|
||||
}
|
||||
|
||||
~StaticKDTree() { delete[] kdtree; }
|
||||
|
||||
bool NearestNeighbor(InputPoint *result, const InputPoint &point)
|
||||
{
|
||||
Metric distance;
|
||||
bool found = false;
|
||||
double nearestDistance = std::numeric_limits<T>::max();
|
||||
std::stack<NNTree> s;
|
||||
s.push(NNTree(0, size, 0, boundingBox));
|
||||
while (!s.empty())
|
||||
{
|
||||
NNTree tree = s.top();
|
||||
s.pop();
|
||||
|
||||
if (distance(tree.box, point.coordinates) >= nearestDistance)
|
||||
continue;
|
||||
|
||||
if (tree.right - tree.left < KDTREE_BASESIZE)
|
||||
{
|
||||
for (unsigned i = tree.left; i < tree.right; i++)
|
||||
{
|
||||
double newDistance = distance(kdtree[i].coordinates, point.coordinates);
|
||||
if (newDistance < nearestDistance)
|
||||
{
|
||||
nearestDistance = newDistance;
|
||||
*result = kdtree[i];
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
Iterator middle = tree.left + (tree.right - tree.left) / 2;
|
||||
|
||||
double newDistance = distance(kdtree[middle].coordinates, point.coordinates);
|
||||
if (newDistance < nearestDistance)
|
||||
{
|
||||
nearestDistance = newDistance;
|
||||
*result = kdtree[middle];
|
||||
found = true;
|
||||
}
|
||||
|
||||
Less comperator(tree.dimension);
|
||||
if (!comperator(point, kdtree[middle]))
|
||||
{
|
||||
NNTree first(middle + 1, tree.right, (tree.dimension + 1) % k, tree.box);
|
||||
NNTree second(tree.left, middle, (tree.dimension + 1) % k, tree.box);
|
||||
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
||||
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
||||
s.push(second);
|
||||
s.push(first);
|
||||
}
|
||||
else
|
||||
{
|
||||
NNTree first(middle + 1, tree.right, (tree.dimension + 1) % k, tree.box);
|
||||
NNTree second(tree.left, middle, (tree.dimension + 1) % k, tree.box);
|
||||
first.box.min[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
||||
second.box.max[tree.dimension] = kdtree[middle].coordinates[tree.dimension];
|
||||
s.push(first);
|
||||
s.push(second);
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
private:
|
||||
using Iterator = unsigned;
|
||||
struct Tree
|
||||
{
|
||||
Iterator left;
|
||||
Iterator right;
|
||||
unsigned dimension;
|
||||
Tree() {}
|
||||
Tree(Iterator l, Iterator r, unsigned d) : left(l), right(r), dimension(d) {}
|
||||
};
|
||||
struct NNTree
|
||||
{
|
||||
Iterator left;
|
||||
Iterator right;
|
||||
unsigned dimension;
|
||||
BoundingBox<k, T> box;
|
||||
NNTree() {}
|
||||
NNTree(Iterator l, Iterator r, unsigned d, const BoundingBox<k, T> &b)
|
||||
: left(l), right(r), dimension(d), box(b)
|
||||
{
|
||||
}
|
||||
};
|
||||
class Less
|
||||
{
|
||||
public:
|
||||
explicit Less(unsigned d)
|
||||
{
|
||||
dimension = d;
|
||||
BOOST_ASSERT(dimension < k);
|
||||
}
|
||||
|
||||
bool operator()(const InputPoint &left, const InputPoint &right)
|
||||
{
|
||||
BOOST_ASSERT(dimension < k);
|
||||
return left.coordinates[dimension] < right.coordinates[dimension];
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned dimension;
|
||||
};
|
||||
|
||||
BoundingBox<k, T> boundingBox;
|
||||
InputPoint *kdtree;
|
||||
Iterator size;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // STATICKDTREE_HPP
|
||||
@@ -1,521 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef STATIC_RTREE_HPP
|
||||
#define STATIC_RTREE_HPP
|
||||
|
||||
#include "deallocating_vector.hpp"
|
||||
#include "hilbert_value.hpp"
|
||||
#include "rectangle.hpp"
|
||||
#include "shared_memory_factory.hpp"
|
||||
#include "shared_memory_vector_wrapper.hpp"
|
||||
|
||||
#include "../util/bearing.hpp"
|
||||
#include "../util/integer_range.hpp"
|
||||
#include "../util/mercator.hpp"
|
||||
#include "../util/osrm_exception.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <tbb/parallel_sort.h>
|
||||
|
||||
#include <variant/variant.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Static RTree for serving nearest neighbour queries
|
||||
template <class EdgeDataT,
|
||||
class CoordinateListT = std::vector<FixedPointCoordinate>,
|
||||
bool UseSharedMemory = false,
|
||||
uint32_t BRANCHING_FACTOR = 64,
|
||||
uint32_t LEAF_NODE_SIZE = 1024>
|
||||
class StaticRTree
|
||||
{
|
||||
public:
|
||||
using Rectangle = RectangleInt2D;
|
||||
using EdgeData = EdgeDataT;
|
||||
using CoordinateList = CoordinateListT;
|
||||
|
||||
static constexpr std::size_t MAX_CHECKED_ELEMENTS = 4 * LEAF_NODE_SIZE;
|
||||
|
||||
struct TreeNode
|
||||
{
|
||||
TreeNode() : child_count(0), child_is_on_disk(false) {}
|
||||
Rectangle minimum_bounding_rectangle;
|
||||
uint32_t child_count : 31;
|
||||
bool child_is_on_disk : 1;
|
||||
uint32_t children[BRANCHING_FACTOR];
|
||||
};
|
||||
|
||||
private:
|
||||
struct WrappedInputElement
|
||||
{
|
||||
explicit WrappedInputElement(const uint64_t _hilbert_value, const uint32_t _array_index)
|
||||
: m_hilbert_value(_hilbert_value), m_array_index(_array_index)
|
||||
{
|
||||
}
|
||||
|
||||
WrappedInputElement() : m_hilbert_value(0), m_array_index(UINT_MAX) {}
|
||||
|
||||
uint64_t m_hilbert_value;
|
||||
uint32_t m_array_index;
|
||||
|
||||
inline bool operator<(const WrappedInputElement &other) const
|
||||
{
|
||||
return m_hilbert_value < other.m_hilbert_value;
|
||||
}
|
||||
};
|
||||
|
||||
struct LeafNode
|
||||
{
|
||||
LeafNode() : object_count(0), objects() {}
|
||||
uint32_t object_count;
|
||||
std::array<EdgeDataT, LEAF_NODE_SIZE> objects;
|
||||
};
|
||||
|
||||
using QueryNodeType = mapbox::util::variant<TreeNode, EdgeDataT>;
|
||||
struct QueryCandidate
|
||||
{
|
||||
inline bool operator<(const QueryCandidate &other) const
|
||||
{
|
||||
// Attn: this is reversed order. std::pq is a max pq!
|
||||
return other.min_dist < min_dist;
|
||||
}
|
||||
|
||||
float min_dist;
|
||||
QueryNodeType node;
|
||||
};
|
||||
|
||||
typename ShM<TreeNode, UseSharedMemory>::vector m_search_tree;
|
||||
uint64_t m_element_count;
|
||||
const std::string m_leaf_node_filename;
|
||||
std::shared_ptr<CoordinateListT> m_coordinate_list;
|
||||
boost::filesystem::ifstream leaves_stream;
|
||||
|
||||
public:
|
||||
StaticRTree() = delete;
|
||||
StaticRTree(const StaticRTree &) = delete;
|
||||
|
||||
template <typename CoordinateT>
|
||||
// Construct a packed Hilbert-R-Tree with Kamel-Faloutsos algorithm [1]
|
||||
explicit StaticRTree(const std::vector<EdgeDataT> &input_data_vector,
|
||||
const std::string &tree_node_filename,
|
||||
const std::string &leaf_node_filename,
|
||||
const std::vector<CoordinateT> &coordinate_list)
|
||||
: m_element_count(input_data_vector.size()), m_leaf_node_filename(leaf_node_filename)
|
||||
{
|
||||
std::vector<WrappedInputElement> input_wrapper_vector(m_element_count);
|
||||
|
||||
HilbertCode get_hilbert_number;
|
||||
|
||||
// generate auxiliary vector of hilbert-values
|
||||
tbb::parallel_for(
|
||||
tbb::blocked_range<uint64_t>(0, m_element_count),
|
||||
[&input_data_vector, &input_wrapper_vector, &get_hilbert_number,
|
||||
&coordinate_list](const tbb::blocked_range<uint64_t> &range)
|
||||
{
|
||||
for (uint64_t element_counter = range.begin(), end = range.end();
|
||||
element_counter != end; ++element_counter)
|
||||
{
|
||||
WrappedInputElement ¤t_wrapper = input_wrapper_vector[element_counter];
|
||||
current_wrapper.m_array_index = element_counter;
|
||||
|
||||
EdgeDataT const ¤t_element = input_data_vector[element_counter];
|
||||
|
||||
// Get Hilbert-Value for centroid in mercartor projection
|
||||
FixedPointCoordinate current_centroid = EdgeDataT::Centroid(
|
||||
FixedPointCoordinate(coordinate_list.at(current_element.u).lat,
|
||||
coordinate_list.at(current_element.u).lon),
|
||||
FixedPointCoordinate(coordinate_list.at(current_element.v).lat,
|
||||
coordinate_list.at(current_element.v).lon));
|
||||
current_centroid.lat =
|
||||
COORDINATE_PRECISION *
|
||||
mercator::lat2y(current_centroid.lat / COORDINATE_PRECISION);
|
||||
|
||||
current_wrapper.m_hilbert_value = get_hilbert_number(current_centroid);
|
||||
}
|
||||
});
|
||||
|
||||
// open leaf file
|
||||
boost::filesystem::ofstream leaf_node_file(leaf_node_filename, std::ios::binary);
|
||||
leaf_node_file.write((char *)&m_element_count, sizeof(uint64_t));
|
||||
|
||||
// sort the hilbert-value representatives
|
||||
tbb::parallel_sort(input_wrapper_vector.begin(), input_wrapper_vector.end());
|
||||
std::vector<TreeNode> tree_nodes_in_level;
|
||||
|
||||
// pack M elements into leaf node and write to leaf file
|
||||
uint64_t processed_objects_count = 0;
|
||||
while (processed_objects_count < m_element_count)
|
||||
{
|
||||
|
||||
LeafNode current_leaf;
|
||||
TreeNode current_node;
|
||||
for (uint32_t current_element_index = 0; LEAF_NODE_SIZE > current_element_index;
|
||||
++current_element_index)
|
||||
{
|
||||
if (m_element_count > (processed_objects_count + current_element_index))
|
||||
{
|
||||
uint32_t index_of_next_object =
|
||||
input_wrapper_vector[processed_objects_count + current_element_index]
|
||||
.m_array_index;
|
||||
current_leaf.objects[current_element_index] =
|
||||
input_data_vector[index_of_next_object];
|
||||
++current_leaf.object_count;
|
||||
}
|
||||
}
|
||||
|
||||
// generate tree node that resemble the objects in leaf and store it for next level
|
||||
InitializeMBRectangle(current_node.minimum_bounding_rectangle, current_leaf.objects,
|
||||
current_leaf.object_count, coordinate_list);
|
||||
current_node.child_is_on_disk = true;
|
||||
current_node.children[0] = tree_nodes_in_level.size();
|
||||
tree_nodes_in_level.emplace_back(current_node);
|
||||
|
||||
// write leaf_node to leaf node file
|
||||
leaf_node_file.write((char *)¤t_leaf, sizeof(current_leaf));
|
||||
processed_objects_count += current_leaf.object_count;
|
||||
}
|
||||
|
||||
// close leaf file
|
||||
leaf_node_file.close();
|
||||
|
||||
uint32_t processing_level = 0;
|
||||
while (1 < tree_nodes_in_level.size())
|
||||
{
|
||||
std::vector<TreeNode> tree_nodes_in_next_level;
|
||||
uint32_t processed_tree_nodes_in_level = 0;
|
||||
while (processed_tree_nodes_in_level < tree_nodes_in_level.size())
|
||||
{
|
||||
TreeNode parent_node;
|
||||
// pack BRANCHING_FACTOR elements into tree_nodes each
|
||||
for (uint32_t current_child_node_index = 0;
|
||||
BRANCHING_FACTOR > current_child_node_index; ++current_child_node_index)
|
||||
{
|
||||
if (processed_tree_nodes_in_level < tree_nodes_in_level.size())
|
||||
{
|
||||
TreeNode ¤t_child_node =
|
||||
tree_nodes_in_level[processed_tree_nodes_in_level];
|
||||
// add tree node to parent entry
|
||||
parent_node.children[current_child_node_index] = m_search_tree.size();
|
||||
m_search_tree.emplace_back(current_child_node);
|
||||
// merge MBRs
|
||||
parent_node.minimum_bounding_rectangle.MergeBoundingBoxes(
|
||||
current_child_node.minimum_bounding_rectangle);
|
||||
// increase counters
|
||||
++parent_node.child_count;
|
||||
++processed_tree_nodes_in_level;
|
||||
}
|
||||
}
|
||||
tree_nodes_in_next_level.emplace_back(parent_node);
|
||||
}
|
||||
tree_nodes_in_level.swap(tree_nodes_in_next_level);
|
||||
++processing_level;
|
||||
}
|
||||
BOOST_ASSERT_MSG(1 == tree_nodes_in_level.size(), "tree broken, more than one root node");
|
||||
// last remaining entry is the root node, store it
|
||||
m_search_tree.emplace_back(tree_nodes_in_level[0]);
|
||||
|
||||
// reverse and renumber tree to have root at index 0
|
||||
std::reverse(m_search_tree.begin(), m_search_tree.end());
|
||||
|
||||
uint32_t search_tree_size = m_search_tree.size();
|
||||
tbb::parallel_for(tbb::blocked_range<uint32_t>(0, search_tree_size),
|
||||
[this, &search_tree_size](const tbb::blocked_range<uint32_t> &range)
|
||||
{
|
||||
for (uint32_t i = range.begin(), end = range.end(); i != end; ++i)
|
||||
{
|
||||
TreeNode ¤t_tree_node = this->m_search_tree[i];
|
||||
for (uint32_t j = 0; j < current_tree_node.child_count; ++j)
|
||||
{
|
||||
const uint32_t old_id = current_tree_node.children[j];
|
||||
const uint32_t new_id = search_tree_size - old_id - 1;
|
||||
current_tree_node.children[j] = new_id;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// open tree file
|
||||
boost::filesystem::ofstream tree_node_file(tree_node_filename, std::ios::binary);
|
||||
|
||||
uint32_t size_of_tree = m_search_tree.size();
|
||||
BOOST_ASSERT_MSG(0 < size_of_tree, "tree empty");
|
||||
tree_node_file.write((char *)&size_of_tree, sizeof(uint32_t));
|
||||
tree_node_file.write((char *)&m_search_tree[0], sizeof(TreeNode) * size_of_tree);
|
||||
// close tree node file.
|
||||
tree_node_file.close();
|
||||
}
|
||||
|
||||
explicit StaticRTree(const boost::filesystem::path &node_file,
|
||||
const boost::filesystem::path &leaf_file,
|
||||
const std::shared_ptr<CoordinateListT> coordinate_list)
|
||||
: m_leaf_node_filename(leaf_file.string())
|
||||
{
|
||||
// open tree node file and load into RAM.
|
||||
m_coordinate_list = coordinate_list;
|
||||
|
||||
if (!boost::filesystem::exists(node_file))
|
||||
{
|
||||
throw osrm::exception("ram index file does not exist");
|
||||
}
|
||||
if (0 == boost::filesystem::file_size(node_file))
|
||||
{
|
||||
throw osrm::exception("ram index file is empty");
|
||||
}
|
||||
boost::filesystem::ifstream tree_node_file(node_file, std::ios::binary);
|
||||
|
||||
uint32_t tree_size = 0;
|
||||
tree_node_file.read((char *)&tree_size, sizeof(uint32_t));
|
||||
|
||||
m_search_tree.resize(tree_size);
|
||||
if (tree_size > 0)
|
||||
{
|
||||
tree_node_file.read((char *)&m_search_tree[0], sizeof(TreeNode) * tree_size);
|
||||
}
|
||||
tree_node_file.close();
|
||||
// open leaf node file and store thread specific pointer
|
||||
if (!boost::filesystem::exists(leaf_file))
|
||||
{
|
||||
throw osrm::exception("mem index file does not exist");
|
||||
}
|
||||
if (0 == boost::filesystem::file_size(leaf_file))
|
||||
{
|
||||
throw osrm::exception("mem index file is empty");
|
||||
}
|
||||
|
||||
leaves_stream.open(leaf_file, std::ios::binary);
|
||||
leaves_stream.read((char *)&m_element_count, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
explicit StaticRTree(TreeNode *tree_node_ptr,
|
||||
const uint64_t number_of_nodes,
|
||||
const boost::filesystem::path &leaf_file,
|
||||
std::shared_ptr<CoordinateListT> coordinate_list)
|
||||
: m_search_tree(tree_node_ptr, number_of_nodes), m_leaf_node_filename(leaf_file.string()),
|
||||
m_coordinate_list(std::move(coordinate_list))
|
||||
{
|
||||
// open leaf node file and store thread specific pointer
|
||||
if (!boost::filesystem::exists(leaf_file))
|
||||
{
|
||||
throw osrm::exception("mem index file does not exist");
|
||||
}
|
||||
if (0 == boost::filesystem::file_size(leaf_file))
|
||||
{
|
||||
throw osrm::exception("mem index file is empty");
|
||||
}
|
||||
|
||||
leaves_stream.open(leaf_file, std::ios::binary);
|
||||
leaves_stream.read((char *)&m_element_count, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
// Override filter and terminator for the desired behaviour.
|
||||
std::vector<EdgeDataT> Nearest(const FixedPointCoordinate &input_coordinate,
|
||||
const std::size_t max_results)
|
||||
{
|
||||
return Nearest(input_coordinate,
|
||||
[](const EdgeDataT &)
|
||||
{
|
||||
return std::make_pair(true, true);
|
||||
},
|
||||
[max_results](const std::size_t num_results, const float)
|
||||
{
|
||||
return num_results >= max_results;
|
||||
});
|
||||
}
|
||||
|
||||
// Override filter and terminator for the desired behaviour.
|
||||
template <typename FilterT, typename TerminationT>
|
||||
std::vector<EdgeDataT> Nearest(const FixedPointCoordinate &input_coordinate,
|
||||
const FilterT filter,
|
||||
const TerminationT terminate)
|
||||
{
|
||||
std::vector<EdgeDataT> results;
|
||||
std::pair<double, double> projected_coordinate = {
|
||||
mercator::lat2y(input_coordinate.lat / COORDINATE_PRECISION),
|
||||
input_coordinate.lon / COORDINATE_PRECISION};
|
||||
|
||||
// initialize queue with root element
|
||||
std::priority_queue<QueryCandidate> traversal_queue;
|
||||
traversal_queue.push(QueryCandidate {0.f, m_search_tree[0]});
|
||||
|
||||
while (!traversal_queue.empty())
|
||||
{
|
||||
const QueryCandidate current_query_node = traversal_queue.top();
|
||||
if (terminate(results.size(), current_query_node.min_dist))
|
||||
{
|
||||
traversal_queue = std::priority_queue<QueryCandidate>{};
|
||||
break;
|
||||
}
|
||||
|
||||
traversal_queue.pop();
|
||||
|
||||
if (current_query_node.node.template is<TreeNode>())
|
||||
{ // current object is a tree node
|
||||
const TreeNode ¤t_tree_node =
|
||||
current_query_node.node.template get<TreeNode>();
|
||||
if (current_tree_node.child_is_on_disk)
|
||||
{
|
||||
ExploreLeafNode(current_tree_node.children[0], input_coordinate,
|
||||
projected_coordinate, traversal_queue);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExploreTreeNode(current_tree_node, input_coordinate, traversal_queue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// inspecting an actual road segment
|
||||
const auto ¤t_segment = current_query_node.node.template get<EdgeDataT>();
|
||||
|
||||
|
||||
auto use_segment = filter(current_segment);
|
||||
if (!use_segment.first && !use_segment.second)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// store phantom node in result vector
|
||||
results.push_back(std::move(current_segment));
|
||||
|
||||
if (!use_segment.first)
|
||||
{
|
||||
results.back().forward_edge_based_node_id = SPECIAL_NODEID;
|
||||
}
|
||||
else if (!use_segment.second)
|
||||
{
|
||||
results.back().reverse_edge_based_node_id = SPECIAL_NODEID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename QueueT>
|
||||
void ExploreLeafNode(const std::uint32_t leaf_id,
|
||||
const FixedPointCoordinate &input_coordinate,
|
||||
const std::pair<double, double> &projected_coordinate,
|
||||
QueueT &traversal_queue)
|
||||
{
|
||||
LeafNode current_leaf_node;
|
||||
LoadLeafFromDisk(leaf_id, current_leaf_node);
|
||||
|
||||
// current object represents a block on disk
|
||||
for (const auto i : osrm::irange(0u, current_leaf_node.object_count))
|
||||
{
|
||||
auto ¤t_edge = current_leaf_node.objects[i];
|
||||
const float current_perpendicular_distance =
|
||||
coordinate_calculation::perpendicular_distance_from_projected_coordinate(
|
||||
m_coordinate_list->at(current_edge.u), m_coordinate_list->at(current_edge.v),
|
||||
input_coordinate, projected_coordinate);
|
||||
// distance must be non-negative
|
||||
BOOST_ASSERT(0.f <= current_perpendicular_distance);
|
||||
|
||||
traversal_queue.push(QueryCandidate {current_perpendicular_distance, std::move(current_edge)});
|
||||
}
|
||||
}
|
||||
|
||||
template <class QueueT>
|
||||
void ExploreTreeNode(const TreeNode &parent,
|
||||
const FixedPointCoordinate &input_coordinate,
|
||||
QueueT &traversal_queue)
|
||||
{
|
||||
for (uint32_t i = 0; i < parent.child_count; ++i)
|
||||
{
|
||||
const int32_t child_id = parent.children[i];
|
||||
const auto &child_tree_node = m_search_tree[child_id];
|
||||
const auto &child_rectangle = child_tree_node.minimum_bounding_rectangle;
|
||||
const float lower_bound_to_element = child_rectangle.GetMinDist(input_coordinate);
|
||||
traversal_queue.push(QueryCandidate {lower_bound_to_element, m_search_tree[child_id]});
|
||||
}
|
||||
}
|
||||
|
||||
inline void LoadLeafFromDisk(const uint32_t leaf_id, LeafNode &result_node)
|
||||
{
|
||||
if (!leaves_stream.is_open())
|
||||
{
|
||||
leaves_stream.open(m_leaf_node_filename, std::ios::in | std::ios::binary);
|
||||
}
|
||||
if (!leaves_stream.good())
|
||||
{
|
||||
throw osrm::exception("Could not read from leaf file.");
|
||||
}
|
||||
const uint64_t seek_pos = sizeof(uint64_t) + leaf_id * sizeof(LeafNode);
|
||||
leaves_stream.seekg(seek_pos);
|
||||
BOOST_ASSERT_MSG(leaves_stream.good(), "Seeking to position in leaf file failed.");
|
||||
leaves_stream.read((char *)&result_node, sizeof(LeafNode));
|
||||
BOOST_ASSERT_MSG(leaves_stream.good(), "Reading from leaf file failed.");
|
||||
}
|
||||
|
||||
template <typename CoordinateT>
|
||||
void InitializeMBRectangle(Rectangle &rectangle,
|
||||
const std::array<EdgeDataT, LEAF_NODE_SIZE> &objects,
|
||||
const uint32_t element_count,
|
||||
const std::vector<CoordinateT> &coordinate_list)
|
||||
{
|
||||
for (uint32_t i = 0; i < element_count; ++i)
|
||||
{
|
||||
rectangle.min_lon =
|
||||
std::min(rectangle.min_lon, std::min(coordinate_list.at(objects[i].u).lon,
|
||||
coordinate_list.at(objects[i].v).lon));
|
||||
rectangle.max_lon =
|
||||
std::max(rectangle.max_lon, std::max(coordinate_list.at(objects[i].u).lon,
|
||||
coordinate_list.at(objects[i].v).lon));
|
||||
|
||||
rectangle.min_lat =
|
||||
std::min(rectangle.min_lat, std::min(coordinate_list.at(objects[i].u).lat,
|
||||
coordinate_list.at(objects[i].v).lat));
|
||||
rectangle.max_lat =
|
||||
std::max(rectangle.max_lat, std::max(coordinate_list.at(objects[i].u).lat,
|
||||
coordinate_list.at(objects[i].v).lat));
|
||||
}
|
||||
BOOST_ASSERT(rectangle.min_lat != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(rectangle.min_lon != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(rectangle.max_lat != std::numeric_limits<int>::min());
|
||||
BOOST_ASSERT(rectangle.max_lon != std::numeric_limits<int>::min());
|
||||
}
|
||||
};
|
||||
|
||||
//[1] "On Packing R-Trees"; I. Kamel, C. Faloutsos; 1993; DOI: 10.1145/170088.170403
|
||||
//[2] "Nearest Neighbor Queries", N. Roussopulos et al; 1995; DOI: 10.1145/223784.223794
|
||||
//[3] "Distance Browsing in Spatial Databases"; G. Hjaltason, H. Samet; 1999; ACM Trans. DB Sys
|
||||
// Vol.24 No.2, pp.265-318
|
||||
#endif // STATIC_RTREE_HPP
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2014, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TURN_INSTRUCTIONS_HPP
|
||||
#define TURN_INSTRUCTIONS_HPP
|
||||
|
||||
enum class TurnInstruction : unsigned char
|
||||
{
|
||||
NoTurn = 0,
|
||||
GoStraight,
|
||||
TurnSlightRight,
|
||||
TurnRight,
|
||||
TurnSharpRight,
|
||||
UTurn,
|
||||
TurnSharpLeft,
|
||||
TurnLeft,
|
||||
TurnSlightLeft,
|
||||
ReachViaLocation,
|
||||
HeadOn,
|
||||
EnterRoundAbout,
|
||||
LeaveRoundAbout,
|
||||
StayOnRoundAbout,
|
||||
StartAtEndOfStreet,
|
||||
ReachedYourDestination,
|
||||
EnterAgainstAllowedDirection,
|
||||
LeaveAgainstAllowedDirection,
|
||||
InverseAccessRestrictionFlag = 127,
|
||||
AccessRestrictionFlag = 128,
|
||||
AccessRestrictionPenalty = 129
|
||||
};
|
||||
|
||||
struct TurnInstructionsClass
|
||||
{
|
||||
TurnInstructionsClass() = delete;
|
||||
TurnInstructionsClass(const TurnInstructionsClass &) = delete;
|
||||
|
||||
static inline TurnInstruction GetTurnDirectionOfInstruction(const double angle)
|
||||
{
|
||||
if (angle >= 23 && angle < 67)
|
||||
{
|
||||
return TurnInstruction::TurnSharpRight;
|
||||
}
|
||||
if (angle >= 67 && angle < 113)
|
||||
{
|
||||
return TurnInstruction::TurnRight;
|
||||
}
|
||||
if (angle >= 113 && angle < 158)
|
||||
{
|
||||
return TurnInstruction::TurnSlightRight;
|
||||
}
|
||||
if (angle >= 158 && angle < 202)
|
||||
{
|
||||
return TurnInstruction::GoStraight;
|
||||
}
|
||||
if (angle >= 202 && angle < 248)
|
||||
{
|
||||
return TurnInstruction::TurnSlightLeft;
|
||||
}
|
||||
if (angle >= 248 && angle < 292)
|
||||
{
|
||||
return TurnInstruction::TurnLeft;
|
||||
}
|
||||
if (angle >= 292 && angle < 336)
|
||||
{
|
||||
return TurnInstruction::TurnSharpLeft;
|
||||
}
|
||||
return TurnInstruction::UTurn;
|
||||
}
|
||||
|
||||
static inline bool TurnIsNecessary(const TurnInstruction turn_instruction)
|
||||
{
|
||||
if (TurnInstruction::NoTurn == turn_instruction ||
|
||||
TurnInstruction::StayOnRoundAbout == turn_instruction)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* TURN_INSTRUCTIONS_HPP */
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LOWER_BOUND_HPP
|
||||
#define LOWER_BOUND_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <queue>
|
||||
#include <type_traits>
|
||||
|
||||
// max pq holds k elements
|
||||
// insert if key is smaller than max
|
||||
// if size > k then remove element
|
||||
// get() always yields a bound to the k smallest element in the stream
|
||||
|
||||
template <typename key_type> class upper_bound
|
||||
{
|
||||
private:
|
||||
using parameter_type =
|
||||
typename std::conditional<std::is_fundamental<key_type>::value, key_type, key_type &>::type;
|
||||
|
||||
public:
|
||||
upper_bound() = delete;
|
||||
upper_bound(std::size_t size) : size(size) {}
|
||||
|
||||
key_type get() const
|
||||
{
|
||||
if (queue.size() < size)
|
||||
{
|
||||
return std::numeric_limits<key_type>::max();
|
||||
}
|
||||
return queue.top();
|
||||
}
|
||||
|
||||
void insert(const parameter_type key)
|
||||
{
|
||||
if (key < get())
|
||||
{
|
||||
queue.emplace(key);
|
||||
while (queue.size() > size)
|
||||
{
|
||||
queue.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::priority_queue<key_type, std::vector<key_type>, std::less<key_type>> queue;
|
||||
const std::size_t size;
|
||||
};
|
||||
|
||||
#endif // LOWER_BOUND_HPP
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef XOR_FAST_HASH_HPP
|
||||
#define XOR_FAST_HASH_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
This is an implementation of Tabulation hashing, which has suprising properties like
|
||||
universality.
|
||||
The space requirement is 2*2^16 = 256 kb of memory, which fits into L2 cache.
|
||||
Evaluation boils down to 10 or less assembly instruction on any recent X86 CPU:
|
||||
|
||||
1: movq table2(%rip), %rdx
|
||||
2: movl %edi, %eax
|
||||
3: movzwl %di, %edi
|
||||
4: shrl $16, %eax
|
||||
5: movzwl %ax, %eax
|
||||
6: movzbl (%rdx,%rax), %eax
|
||||
7: movq table1(%rip), %rdx
|
||||
8: xorb (%rdx,%rdi), %al
|
||||
9: movzbl %al, %eax
|
||||
10: ret
|
||||
|
||||
*/
|
||||
class XORFastHash
|
||||
{ // 65k entries
|
||||
std::vector<unsigned short> table1;
|
||||
std::vector<unsigned short> table2;
|
||||
|
||||
public:
|
||||
XORFastHash()
|
||||
{
|
||||
table1.resize(2 << 16);
|
||||
table2.resize(2 << 16);
|
||||
for (unsigned i = 0; i < (2 << 16); ++i)
|
||||
{
|
||||
table1[i] = static_cast<unsigned short>(i);
|
||||
table2[i] = static_cast<unsigned short>(i);
|
||||
}
|
||||
std::random_shuffle(table1.begin(), table1.end());
|
||||
std::random_shuffle(table2.begin(), table2.end());
|
||||
}
|
||||
|
||||
inline unsigned short operator()(const unsigned originalValue) const
|
||||
{
|
||||
unsigned short lsb = ((originalValue)&0xffff);
|
||||
unsigned short msb = (((originalValue) >> 16) & 0xffff);
|
||||
return table1[lsb] ^ table2[msb];
|
||||
}
|
||||
};
|
||||
|
||||
class XORMiniHash
|
||||
{ // 256 entries
|
||||
std::vector<unsigned char> table1;
|
||||
std::vector<unsigned char> table2;
|
||||
std::vector<unsigned char> table3;
|
||||
std::vector<unsigned char> table4;
|
||||
|
||||
public:
|
||||
XORMiniHash()
|
||||
{
|
||||
table1.resize(1 << 8);
|
||||
table2.resize(1 << 8);
|
||||
table3.resize(1 << 8);
|
||||
table4.resize(1 << 8);
|
||||
for (unsigned i = 0; i < (1 << 8); ++i)
|
||||
{
|
||||
table1[i] = static_cast<unsigned char>(i);
|
||||
table2[i] = static_cast<unsigned char>(i);
|
||||
table3[i] = static_cast<unsigned char>(i);
|
||||
table4[i] = static_cast<unsigned char>(i);
|
||||
}
|
||||
std::random_shuffle(table1.begin(), table1.end());
|
||||
std::random_shuffle(table2.begin(), table2.end());
|
||||
std::random_shuffle(table3.begin(), table3.end());
|
||||
std::random_shuffle(table4.begin(), table4.end());
|
||||
}
|
||||
unsigned char operator()(const unsigned originalValue) const
|
||||
{
|
||||
unsigned char byte1 = ((originalValue)&0xff);
|
||||
unsigned char byte2 = ((originalValue >> 8) & 0xff);
|
||||
unsigned char byte3 = ((originalValue >> 16) & 0xff);
|
||||
unsigned char byte4 = ((originalValue >> 24) & 0xff);
|
||||
return table1[byte1] ^ table2[byte2] ^ table3[byte3] ^ table4[byte4];
|
||||
}
|
||||
};
|
||||
|
||||
#endif // XOR_FAST_HASH_HPP
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2013, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef XOR_FAST_HASH_STORAGE_HPP
|
||||
#define XOR_FAST_HASH_STORAGE_HPP
|
||||
|
||||
#include "xor_fast_hash.hpp"
|
||||
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
template <typename NodeID, typename Key> class XORFastHashStorage
|
||||
{
|
||||
public:
|
||||
struct HashCell
|
||||
{
|
||||
unsigned time;
|
||||
NodeID id;
|
||||
Key key;
|
||||
HashCell()
|
||||
: time(std::numeric_limits<unsigned>::max()), id(std::numeric_limits<unsigned>::max()),
|
||||
key(std::numeric_limits<unsigned>::max())
|
||||
{
|
||||
}
|
||||
|
||||
HashCell(const HashCell &other) : time(other.key), id(other.id), key(other.time) {}
|
||||
|
||||
operator Key() const { return key; }
|
||||
|
||||
void operator=(const Key key_to_insert) { key = key_to_insert; }
|
||||
};
|
||||
|
||||
XORFastHashStorage() = delete;
|
||||
|
||||
explicit XORFastHashStorage(size_t) : positions(2 << 16), current_timestamp(0) {}
|
||||
|
||||
HashCell &operator[](const NodeID node)
|
||||
{
|
||||
unsigned short position = fast_hasher(node);
|
||||
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
|
||||
{
|
||||
++position %= (2 << 16);
|
||||
}
|
||||
|
||||
positions[position].time = current_timestamp;
|
||||
positions[position].id = node;
|
||||
return positions[position];
|
||||
}
|
||||
|
||||
// peek into table, get key for node, think of it as a read-only operator[]
|
||||
Key peek_index(const NodeID node) const
|
||||
{
|
||||
unsigned short position = fast_hasher(node);
|
||||
while ((positions[position].time == current_timestamp) && (positions[position].id != node))
|
||||
{
|
||||
++position %= (2 << 16);
|
||||
}
|
||||
return positions[position].key;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
++current_timestamp;
|
||||
if (std::numeric_limits<unsigned>::max() == current_timestamp)
|
||||
{
|
||||
positions.clear();
|
||||
positions.resize(2 << 16);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<HashCell> positions;
|
||||
XORFastHash fast_hasher;
|
||||
unsigned current_timestamp;
|
||||
};
|
||||
|
||||
#endif // XOR_FAST_HASH_STORAGE_HPP
|
||||
-598
@@ -1,598 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "data_structures/original_edge_data.hpp"
|
||||
#include "data_structures/range_table.hpp"
|
||||
#include "data_structures/query_edge.hpp"
|
||||
#include "data_structures/query_node.hpp"
|
||||
#include "data_structures/shared_memory_factory.hpp"
|
||||
#include "data_structures/shared_memory_vector_wrapper.hpp"
|
||||
#include "data_structures/static_graph.hpp"
|
||||
#include "data_structures/static_rtree.hpp"
|
||||
#include "data_structures/travel_mode.hpp"
|
||||
#include "data_structures/turn_instructions.hpp"
|
||||
#include "server/data_structures/datafacade_base.hpp"
|
||||
#include "server/data_structures/shared_datatype.hpp"
|
||||
#include "server/data_structures/shared_barriers.hpp"
|
||||
#include "util/datastore_options.hpp"
|
||||
#include "util/simple_logger.hpp"
|
||||
#include "util/osrm_exception.hpp"
|
||||
#include "util/fingerprint.hpp"
|
||||
#include "typedefs.h"
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
|
||||
using RTreeLeaf = BaseDataFacade<QueryEdge::EdgeData>::RTreeLeaf;
|
||||
using RTreeNode = StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, true>::vector, true>::TreeNode;
|
||||
using QueryGraph = StaticGraph<QueryEdge::EdgeData>;
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/iostreams/seek.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <new>
|
||||
|
||||
// delete a shared memory region. report warning if it could not be deleted
|
||||
void delete_region(const SharedDataType region)
|
||||
{
|
||||
if (SharedMemory::RegionExists(region) && !SharedMemory::Remove(region))
|
||||
{
|
||||
const std::string name = [&]
|
||||
{
|
||||
switch (region)
|
||||
{
|
||||
case CURRENT_REGIONS:
|
||||
return "CURRENT_REGIONS";
|
||||
case LAYOUT_1:
|
||||
return "LAYOUT_1";
|
||||
case DATA_1:
|
||||
return "DATA_1";
|
||||
case LAYOUT_2:
|
||||
return "LAYOUT_2";
|
||||
case DATA_2:
|
||||
return "DATA_2";
|
||||
case LAYOUT_NONE:
|
||||
return "LAYOUT_NONE";
|
||||
default: // DATA_NONE:
|
||||
return "DATA_NONE";
|
||||
}
|
||||
}();
|
||||
|
||||
SimpleLogger().Write(logWARNING) << "could not delete shared memory region " << name;
|
||||
}
|
||||
}
|
||||
|
||||
int main(const int argc, const char *argv[]) try
|
||||
{
|
||||
LogPolicy::GetInstance().Unmute();
|
||||
SharedBarriers barrier;
|
||||
|
||||
#ifdef __linux__
|
||||
// try to disable swapping on Linux
|
||||
const bool lock_flags = MCL_CURRENT | MCL_FUTURE;
|
||||
if (-1 == mlockall(lock_flags))
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << "Process " << argv[0] << " could not request RAM lock";
|
||||
}
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> pending_lock(
|
||||
barrier.pending_update_mutex);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// hard unlock in case of any exception.
|
||||
barrier.pending_update_mutex.unlock();
|
||||
}
|
||||
|
||||
SimpleLogger().Write(logDEBUG) << "Checking input parameters";
|
||||
|
||||
std::unordered_map<std::string, boost::filesystem::path> server_paths;
|
||||
if (!GenerateDataStoreOptions(argc, argv, server_paths))
|
||||
{
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (server_paths.find("hsgrdata") == server_paths.end())
|
||||
{
|
||||
throw osrm::exception("no hsgr file found");
|
||||
}
|
||||
if (server_paths.find("ramindex") == server_paths.end())
|
||||
{
|
||||
throw osrm::exception("no ram index file found");
|
||||
}
|
||||
if (server_paths.find("fileindex") == server_paths.end())
|
||||
{
|
||||
throw osrm::exception("no leaf index file found");
|
||||
}
|
||||
if (server_paths.find("nodesdata") == server_paths.end())
|
||||
{
|
||||
throw osrm::exception("no nodes file found");
|
||||
}
|
||||
if (server_paths.find("edgesdata") == server_paths.end())
|
||||
{
|
||||
throw osrm::exception("no edges file found");
|
||||
}
|
||||
if (server_paths.find("namesdata") == server_paths.end())
|
||||
{
|
||||
throw osrm::exception("no names file found");
|
||||
}
|
||||
if (server_paths.find("geometry") == server_paths.end())
|
||||
{
|
||||
throw osrm::exception("no geometry file found");
|
||||
}
|
||||
if (server_paths.find("core") == server_paths.end())
|
||||
{
|
||||
throw osrm::exception("no core file found");
|
||||
}
|
||||
|
||||
auto paths_iterator = server_paths.find("hsgrdata");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
BOOST_ASSERT(!paths_iterator->second.empty());
|
||||
const boost::filesystem::path &hsgr_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("timestamp");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
BOOST_ASSERT(!paths_iterator->second.empty());
|
||||
const boost::filesystem::path ×tamp_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("ramindex");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
BOOST_ASSERT(!paths_iterator->second.empty());
|
||||
const boost::filesystem::path &ram_index_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("fileindex");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
BOOST_ASSERT(!paths_iterator->second.empty());
|
||||
const boost::filesystem::path index_file_path_absolute =
|
||||
boost::filesystem::canonical(paths_iterator->second);
|
||||
const std::string &file_index_path = index_file_path_absolute.string();
|
||||
paths_iterator = server_paths.find("nodesdata");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
BOOST_ASSERT(!paths_iterator->second.empty());
|
||||
const boost::filesystem::path &nodes_data_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("edgesdata");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
BOOST_ASSERT(!paths_iterator->second.empty());
|
||||
const boost::filesystem::path &edges_data_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("namesdata");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
BOOST_ASSERT(!paths_iterator->second.empty());
|
||||
const boost::filesystem::path &names_data_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("geometry");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
BOOST_ASSERT(!paths_iterator->second.empty());
|
||||
const boost::filesystem::path &geometries_data_path = paths_iterator->second;
|
||||
paths_iterator = server_paths.find("core");
|
||||
BOOST_ASSERT(server_paths.end() != paths_iterator);
|
||||
BOOST_ASSERT(!paths_iterator->second.empty());
|
||||
const boost::filesystem::path &core_marker_path = paths_iterator->second;
|
||||
|
||||
// determine segment to use
|
||||
bool segment2_in_use = SharedMemory::RegionExists(LAYOUT_2);
|
||||
const SharedDataType layout_region = [&]
|
||||
{
|
||||
return segment2_in_use ? LAYOUT_1 : LAYOUT_2;
|
||||
}();
|
||||
const SharedDataType data_region = [&]
|
||||
{
|
||||
return segment2_in_use ? DATA_1 : DATA_2;
|
||||
}();
|
||||
const SharedDataType previous_layout_region = [&]
|
||||
{
|
||||
return segment2_in_use ? LAYOUT_2 : LAYOUT_1;
|
||||
}();
|
||||
const SharedDataType previous_data_region = [&]
|
||||
{
|
||||
return segment2_in_use ? DATA_2 : DATA_1;
|
||||
}();
|
||||
|
||||
// Allocate a memory layout in shared memory, deallocate previous
|
||||
auto *layout_memory = SharedMemoryFactory::Get(layout_region, sizeof(SharedDataLayout));
|
||||
auto *shared_layout_ptr = new (layout_memory->Ptr()) SharedDataLayout();
|
||||
|
||||
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::FILE_INDEX_PATH,
|
||||
file_index_path.length() + 1);
|
||||
|
||||
// collect number of elements to store in shared memory object
|
||||
SimpleLogger().Write() << "load names from: " << names_data_path;
|
||||
// number of entries in name index
|
||||
boost::filesystem::ifstream name_stream(names_data_path, std::ios::binary);
|
||||
unsigned name_blocks = 0;
|
||||
name_stream.read((char *)&name_blocks, sizeof(unsigned));
|
||||
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::NAME_OFFSETS, name_blocks);
|
||||
shared_layout_ptr->SetBlockSize<typename RangeTable<16, true>::BlockT>(
|
||||
SharedDataLayout::NAME_BLOCKS, name_blocks);
|
||||
SimpleLogger().Write() << "name offsets size: " << name_blocks;
|
||||
BOOST_ASSERT_MSG(0 != name_blocks, "name file broken");
|
||||
|
||||
unsigned number_of_chars = 0;
|
||||
name_stream.read((char *)&number_of_chars, sizeof(unsigned));
|
||||
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::NAME_CHAR_LIST, number_of_chars);
|
||||
|
||||
// Loading information for original edges
|
||||
boost::filesystem::ifstream edges_input_stream(edges_data_path, std::ios::binary);
|
||||
unsigned number_of_original_edges = 0;
|
||||
edges_input_stream.read((char *)&number_of_original_edges, sizeof(unsigned));
|
||||
|
||||
// note: settings this all to the same size is correct, we extract them from the same struct
|
||||
shared_layout_ptr->SetBlockSize<NodeID>(SharedDataLayout::VIA_NODE_LIST,
|
||||
number_of_original_edges);
|
||||
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::NAME_ID_LIST,
|
||||
number_of_original_edges);
|
||||
shared_layout_ptr->SetBlockSize<TravelMode>(SharedDataLayout::TRAVEL_MODE,
|
||||
number_of_original_edges);
|
||||
shared_layout_ptr->SetBlockSize<TurnInstruction>(SharedDataLayout::TURN_INSTRUCTION,
|
||||
number_of_original_edges);
|
||||
// note: there are 32 geometry indicators in one unsigned block
|
||||
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::GEOMETRIES_INDICATORS,
|
||||
number_of_original_edges);
|
||||
|
||||
boost::filesystem::ifstream hsgr_input_stream(hsgr_path, std::ios::binary);
|
||||
|
||||
FingerPrint fingerprint_valid = FingerPrint::GetValid();
|
||||
FingerPrint fingerprint_loaded;
|
||||
hsgr_input_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
|
||||
if (fingerprint_loaded.TestGraphUtil(fingerprint_valid))
|
||||
{
|
||||
SimpleLogger().Write(logDEBUG) << "Fingerprint checked out ok";
|
||||
}
|
||||
else
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << ".hsgr was prepared with different build. "
|
||||
"Reprocess to get rid of this warning.";
|
||||
}
|
||||
|
||||
// load checksum
|
||||
unsigned checksum = 0;
|
||||
hsgr_input_stream.read((char *)&checksum, sizeof(unsigned));
|
||||
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::HSGR_CHECKSUM, 1);
|
||||
// load graph node size
|
||||
unsigned number_of_graph_nodes = 0;
|
||||
hsgr_input_stream.read((char *)&number_of_graph_nodes, sizeof(unsigned));
|
||||
|
||||
BOOST_ASSERT_MSG((0 != number_of_graph_nodes), "number of nodes is zero");
|
||||
shared_layout_ptr->SetBlockSize<QueryGraph::NodeArrayEntry>(SharedDataLayout::GRAPH_NODE_LIST,
|
||||
number_of_graph_nodes);
|
||||
|
||||
// load graph edge size
|
||||
unsigned number_of_graph_edges = 0;
|
||||
hsgr_input_stream.read((char *)&number_of_graph_edges, sizeof(unsigned));
|
||||
// BOOST_ASSERT_MSG(0 != number_of_graph_edges, "number of graph edges is zero");
|
||||
shared_layout_ptr->SetBlockSize<QueryGraph::EdgeArrayEntry>(SharedDataLayout::GRAPH_EDGE_LIST,
|
||||
number_of_graph_edges);
|
||||
|
||||
// load rsearch tree size
|
||||
boost::filesystem::ifstream tree_node_file(ram_index_path, std::ios::binary);
|
||||
|
||||
uint32_t tree_size = 0;
|
||||
tree_node_file.read((char *)&tree_size, sizeof(uint32_t));
|
||||
shared_layout_ptr->SetBlockSize<RTreeNode>(SharedDataLayout::R_SEARCH_TREE, tree_size);
|
||||
|
||||
// load timestamp size
|
||||
std::string m_timestamp;
|
||||
if (boost::filesystem::exists(timestamp_path))
|
||||
{
|
||||
boost::filesystem::ifstream timestamp_stream(timestamp_path);
|
||||
if (!timestamp_stream)
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << timestamp_path << " not found. setting to default";
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
shared_layout_ptr->SetBlockSize<char>(SharedDataLayout::TIMESTAMP, m_timestamp.length());
|
||||
|
||||
// load core marker size
|
||||
boost::filesystem::ifstream core_marker_file(core_marker_path, std::ios::binary);
|
||||
|
||||
uint32_t number_of_core_markers = 0;
|
||||
core_marker_file.read((char *)&number_of_core_markers, sizeof(uint32_t));
|
||||
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::CORE_MARKER,
|
||||
number_of_core_markers);
|
||||
|
||||
// load coordinate size
|
||||
boost::filesystem::ifstream nodes_input_stream(nodes_data_path, std::ios::binary);
|
||||
unsigned coordinate_list_size = 0;
|
||||
nodes_input_stream.read((char *)&coordinate_list_size, sizeof(unsigned));
|
||||
shared_layout_ptr->SetBlockSize<FixedPointCoordinate>(SharedDataLayout::COORDINATE_LIST,
|
||||
coordinate_list_size);
|
||||
|
||||
// load geometries sizes
|
||||
std::ifstream geometry_input_stream(geometries_data_path.string().c_str(), std::ios::binary);
|
||||
unsigned number_of_geometries_indices = 0;
|
||||
unsigned number_of_compressed_geometries = 0;
|
||||
|
||||
geometry_input_stream.read((char *)&number_of_geometries_indices, sizeof(unsigned));
|
||||
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::GEOMETRIES_INDEX,
|
||||
number_of_geometries_indices);
|
||||
boost::iostreams::seek(geometry_input_stream, number_of_geometries_indices * sizeof(unsigned),
|
||||
BOOST_IOS::cur);
|
||||
geometry_input_stream.read((char *)&number_of_compressed_geometries, sizeof(unsigned));
|
||||
shared_layout_ptr->SetBlockSize<unsigned>(SharedDataLayout::GEOMETRIES_LIST,
|
||||
number_of_compressed_geometries);
|
||||
// allocate shared memory block
|
||||
SimpleLogger().Write() << "allocating shared memory of " << shared_layout_ptr->GetSizeOfLayout()
|
||||
<< " bytes";
|
||||
SharedMemory *shared_memory =
|
||||
SharedMemoryFactory::Get(data_region, shared_layout_ptr->GetSizeOfLayout());
|
||||
char *shared_memory_ptr = static_cast<char *>(shared_memory->Ptr());
|
||||
|
||||
// read actual data into shared memory object //
|
||||
|
||||
// hsgr checksum
|
||||
unsigned *checksum_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
|
||||
shared_memory_ptr, SharedDataLayout::HSGR_CHECKSUM);
|
||||
*checksum_ptr = checksum;
|
||||
|
||||
// ram index file name
|
||||
char *file_index_path_ptr = shared_layout_ptr->GetBlockPtr<char, true>(
|
||||
shared_memory_ptr, SharedDataLayout::FILE_INDEX_PATH);
|
||||
// make sure we have 0 ending
|
||||
std::fill(file_index_path_ptr,
|
||||
file_index_path_ptr +
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::FILE_INDEX_PATH),
|
||||
0);
|
||||
std::copy(file_index_path.begin(), file_index_path.end(), file_index_path_ptr);
|
||||
|
||||
// Loading street names
|
||||
unsigned *name_offsets_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
|
||||
shared_memory_ptr, SharedDataLayout::NAME_OFFSETS);
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_OFFSETS) > 0)
|
||||
{
|
||||
name_stream.read((char *)name_offsets_ptr,
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_OFFSETS));
|
||||
}
|
||||
|
||||
unsigned *name_blocks_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
|
||||
shared_memory_ptr, SharedDataLayout::NAME_BLOCKS);
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_BLOCKS) > 0)
|
||||
{
|
||||
name_stream.read((char *)name_blocks_ptr,
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_BLOCKS));
|
||||
}
|
||||
|
||||
char *name_char_ptr = shared_layout_ptr->GetBlockPtr<char, true>(
|
||||
shared_memory_ptr, SharedDataLayout::NAME_CHAR_LIST);
|
||||
unsigned temp_length;
|
||||
name_stream.read((char *)&temp_length, sizeof(unsigned));
|
||||
|
||||
BOOST_ASSERT_MSG(temp_length ==
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_CHAR_LIST),
|
||||
"Name file corrupted!");
|
||||
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_CHAR_LIST) > 0)
|
||||
{
|
||||
name_stream.read(name_char_ptr,
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::NAME_CHAR_LIST));
|
||||
}
|
||||
|
||||
name_stream.close();
|
||||
|
||||
// load original edge information
|
||||
NodeID *via_node_ptr = shared_layout_ptr->GetBlockPtr<NodeID, true>(
|
||||
shared_memory_ptr, SharedDataLayout::VIA_NODE_LIST);
|
||||
|
||||
unsigned *name_id_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
|
||||
shared_memory_ptr, SharedDataLayout::NAME_ID_LIST);
|
||||
|
||||
TravelMode *travel_mode_ptr = shared_layout_ptr->GetBlockPtr<TravelMode, true>(
|
||||
shared_memory_ptr, SharedDataLayout::TRAVEL_MODE);
|
||||
|
||||
TurnInstruction *turn_instructions_ptr = shared_layout_ptr->GetBlockPtr<TurnInstruction, true>(
|
||||
shared_memory_ptr, SharedDataLayout::TURN_INSTRUCTION);
|
||||
|
||||
unsigned *geometries_indicator_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
|
||||
shared_memory_ptr, SharedDataLayout::GEOMETRIES_INDICATORS);
|
||||
|
||||
OriginalEdgeData current_edge_data;
|
||||
for (unsigned i = 0; i < number_of_original_edges; ++i)
|
||||
{
|
||||
edges_input_stream.read((char *)&(current_edge_data), sizeof(OriginalEdgeData));
|
||||
via_node_ptr[i] = current_edge_data.via_node;
|
||||
name_id_ptr[i] = current_edge_data.name_id;
|
||||
travel_mode_ptr[i] = current_edge_data.travel_mode;
|
||||
turn_instructions_ptr[i] = current_edge_data.turn_instruction;
|
||||
|
||||
const unsigned bucket = i / 32;
|
||||
const unsigned offset = i % 32;
|
||||
const unsigned value = [&]
|
||||
{
|
||||
unsigned return_value = 0;
|
||||
if (0 != offset)
|
||||
{
|
||||
return_value = geometries_indicator_ptr[bucket];
|
||||
}
|
||||
return return_value;
|
||||
}();
|
||||
if (current_edge_data.compressed_geometry)
|
||||
{
|
||||
geometries_indicator_ptr[bucket] = (value | (1 << offset));
|
||||
}
|
||||
}
|
||||
edges_input_stream.close();
|
||||
|
||||
// load compressed geometry
|
||||
unsigned temporary_value;
|
||||
unsigned *geometries_index_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
|
||||
shared_memory_ptr, SharedDataLayout::GEOMETRIES_INDEX);
|
||||
geometry_input_stream.seekg(0, geometry_input_stream.beg);
|
||||
geometry_input_stream.read((char *)&temporary_value, sizeof(unsigned));
|
||||
BOOST_ASSERT(temporary_value ==
|
||||
shared_layout_ptr->num_entries[SharedDataLayout::GEOMETRIES_INDEX]);
|
||||
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::GEOMETRIES_INDEX) > 0)
|
||||
{
|
||||
geometry_input_stream.read(
|
||||
(char *)geometries_index_ptr,
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::GEOMETRIES_INDEX));
|
||||
}
|
||||
unsigned *geometries_list_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
|
||||
shared_memory_ptr, SharedDataLayout::GEOMETRIES_LIST);
|
||||
|
||||
geometry_input_stream.read((char *)&temporary_value, sizeof(unsigned));
|
||||
BOOST_ASSERT(temporary_value ==
|
||||
shared_layout_ptr->num_entries[SharedDataLayout::GEOMETRIES_LIST]);
|
||||
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::GEOMETRIES_LIST) > 0)
|
||||
{
|
||||
geometry_input_stream.read(
|
||||
(char *)geometries_list_ptr,
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::GEOMETRIES_LIST));
|
||||
}
|
||||
|
||||
// Loading list of coordinates
|
||||
FixedPointCoordinate *coordinates_ptr =
|
||||
shared_layout_ptr->GetBlockPtr<FixedPointCoordinate, true>(
|
||||
shared_memory_ptr, SharedDataLayout::COORDINATE_LIST);
|
||||
|
||||
QueryNode current_node;
|
||||
for (unsigned i = 0; i < coordinate_list_size; ++i)
|
||||
{
|
||||
nodes_input_stream.read((char *)¤t_node, sizeof(QueryNode));
|
||||
coordinates_ptr[i] = FixedPointCoordinate(current_node.lat, current_node.lon);
|
||||
}
|
||||
nodes_input_stream.close();
|
||||
|
||||
// store timestamp
|
||||
char *timestamp_ptr =
|
||||
shared_layout_ptr->GetBlockPtr<char, true>(shared_memory_ptr, SharedDataLayout::TIMESTAMP);
|
||||
std::copy(m_timestamp.c_str(), m_timestamp.c_str() + m_timestamp.length(), timestamp_ptr);
|
||||
|
||||
// store search tree portion of rtree
|
||||
char *rtree_ptr = shared_layout_ptr->GetBlockPtr<char, true>(shared_memory_ptr,
|
||||
SharedDataLayout::R_SEARCH_TREE);
|
||||
|
||||
if (tree_size > 0)
|
||||
{
|
||||
tree_node_file.read(rtree_ptr, sizeof(RTreeNode) * tree_size);
|
||||
}
|
||||
tree_node_file.close();
|
||||
|
||||
// load core markers
|
||||
std::vector<char> unpacked_core_markers(number_of_core_markers);
|
||||
core_marker_file.read((char *)unpacked_core_markers.data(),
|
||||
sizeof(char) * number_of_core_markers);
|
||||
|
||||
unsigned *core_marker_ptr = shared_layout_ptr->GetBlockPtr<unsigned, true>(
|
||||
shared_memory_ptr, SharedDataLayout::CORE_MARKER);
|
||||
|
||||
for (auto i = 0u; i < number_of_core_markers; ++i)
|
||||
{
|
||||
BOOST_ASSERT(unpacked_core_markers[i] == 0 || unpacked_core_markers[i] == 1);
|
||||
|
||||
if (unpacked_core_markers[i] == 1)
|
||||
{
|
||||
const unsigned bucket = i / 32;
|
||||
const unsigned offset = i % 32;
|
||||
const unsigned value = [&]
|
||||
{
|
||||
unsigned return_value = 0;
|
||||
if (0 != offset)
|
||||
{
|
||||
return_value = core_marker_ptr[bucket];
|
||||
}
|
||||
return return_value;
|
||||
}();
|
||||
|
||||
core_marker_ptr[bucket] = (value | (1 << offset));
|
||||
}
|
||||
}
|
||||
|
||||
// load the nodes of the search graph
|
||||
QueryGraph::NodeArrayEntry *graph_node_list_ptr =
|
||||
shared_layout_ptr->GetBlockPtr<QueryGraph::NodeArrayEntry, true>(
|
||||
shared_memory_ptr, SharedDataLayout::GRAPH_NODE_LIST);
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::GRAPH_NODE_LIST) > 0)
|
||||
{
|
||||
hsgr_input_stream.read((char *)graph_node_list_ptr,
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::GRAPH_NODE_LIST));
|
||||
}
|
||||
|
||||
// load the edges of the search graph
|
||||
QueryGraph::EdgeArrayEntry *graph_edge_list_ptr =
|
||||
shared_layout_ptr->GetBlockPtr<QueryGraph::EdgeArrayEntry, true>(
|
||||
shared_memory_ptr, SharedDataLayout::GRAPH_EDGE_LIST);
|
||||
if (shared_layout_ptr->GetBlockSize(SharedDataLayout::GRAPH_EDGE_LIST) > 0)
|
||||
{
|
||||
hsgr_input_stream.read((char *)graph_edge_list_ptr,
|
||||
shared_layout_ptr->GetBlockSize(SharedDataLayout::GRAPH_EDGE_LIST));
|
||||
}
|
||||
hsgr_input_stream.close();
|
||||
|
||||
// acquire lock
|
||||
SharedMemory *data_type_memory =
|
||||
SharedMemoryFactory::Get(CURRENT_REGIONS, sizeof(SharedDataTimestamp), true, false);
|
||||
SharedDataTimestamp *data_timestamp_ptr =
|
||||
static_cast<SharedDataTimestamp *>(data_type_memory->Ptr());
|
||||
|
||||
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> query_lock(
|
||||
barrier.query_mutex);
|
||||
|
||||
// notify all processes that were waiting for this condition
|
||||
if (0 < barrier.number_of_queries)
|
||||
{
|
||||
barrier.no_running_queries_condition.wait(query_lock);
|
||||
}
|
||||
|
||||
data_timestamp_ptr->layout = layout_region;
|
||||
data_timestamp_ptr->data = data_region;
|
||||
data_timestamp_ptr->timestamp += 1;
|
||||
delete_region(previous_data_region);
|
||||
delete_region(previous_layout_region);
|
||||
SimpleLogger().Write() << "all data loaded";
|
||||
|
||||
shared_layout_ptr->PrintInformation();
|
||||
}
|
||||
catch (const std::bad_alloc &e)
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << "[exception] " << e.what();
|
||||
SimpleLogger().Write(logWARNING) << "Please provide more memory or disable locking the virtual "
|
||||
"address space (note: this makes OSRM swap, i.e. slow)";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
SimpleLogger().Write(logWARNING) << "caught exception: " << e.what();
|
||||
}
|
||||
@@ -1,249 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "description_factory.hpp"
|
||||
|
||||
#include "../algorithms/polyline_formatter.hpp"
|
||||
#include "../algorithms/coordinate_calculation.hpp"
|
||||
#include "../data_structures/internal_route_result.hpp"
|
||||
#include "../data_structures/turn_instructions.hpp"
|
||||
#include "../util/container.hpp"
|
||||
#include "../util/integer_range.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
||||
DescriptionFactory::DescriptionFactory() : entire_length(0) { via_indices.push_back(0); }
|
||||
|
||||
std::vector<unsigned> const &DescriptionFactory::GetViaIndices() const { return via_indices; }
|
||||
|
||||
void DescriptionFactory::SetStartSegment(const PhantomNode &source, const bool traversed_in_reverse)
|
||||
{
|
||||
start_phantom = source;
|
||||
const EdgeWeight segment_duration =
|
||||
(traversed_in_reverse ? source.reverse_weight : source.forward_weight);
|
||||
const TravelMode travel_mode =
|
||||
(traversed_in_reverse ? source.backward_travel_mode : source.forward_travel_mode);
|
||||
AppendSegment(source.location, PathData(0, source.name_id, TurnInstruction::HeadOn,
|
||||
segment_duration, travel_mode));
|
||||
BOOST_ASSERT(path_description.back().duration == segment_duration);
|
||||
}
|
||||
|
||||
void DescriptionFactory::SetEndSegment(const PhantomNode &target,
|
||||
const bool traversed_in_reverse,
|
||||
const bool is_via_location)
|
||||
{
|
||||
target_phantom = target;
|
||||
const EdgeWeight segment_duration =
|
||||
(traversed_in_reverse ? target.reverse_weight : target.forward_weight);
|
||||
const TravelMode travel_mode =
|
||||
(traversed_in_reverse ? target.backward_travel_mode : target.forward_travel_mode);
|
||||
path_description.emplace_back(target.location, target.name_id, segment_duration, 0.f,
|
||||
is_via_location ? TurnInstruction::ReachViaLocation
|
||||
: TurnInstruction::NoTurn,
|
||||
true, true, travel_mode);
|
||||
BOOST_ASSERT(path_description.back().duration == segment_duration);
|
||||
}
|
||||
|
||||
void DescriptionFactory::AppendSegment(const FixedPointCoordinate &coordinate,
|
||||
const PathData &path_point)
|
||||
{
|
||||
// if the start location is on top of a node, the first movement might be zero-length,
|
||||
// in which case we dont' add a new description, but instead update the existing one
|
||||
if ((1 == path_description.size()) && (path_description.front().location == coordinate))
|
||||
{
|
||||
if (path_point.segment_duration > 0)
|
||||
{
|
||||
path_description.front().name_id = path_point.name_id;
|
||||
path_description.front().travel_mode = path_point.travel_mode;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// make sure mode changes are announced, even when there otherwise is no turn
|
||||
const TurnInstruction turn = [&]() -> TurnInstruction
|
||||
{
|
||||
if (TurnInstruction::NoTurn == path_point.turn_instruction &&
|
||||
path_description.front().travel_mode != path_point.travel_mode &&
|
||||
path_point.segment_duration > 0)
|
||||
{
|
||||
return TurnInstruction::GoStraight;
|
||||
}
|
||||
return path_point.turn_instruction;
|
||||
}();
|
||||
|
||||
path_description.emplace_back(coordinate, path_point.name_id, path_point.segment_duration, 0.f,
|
||||
turn, path_point.travel_mode);
|
||||
}
|
||||
|
||||
osrm::json::Value DescriptionFactory::AppendGeometryString(const bool return_encoded)
|
||||
{
|
||||
if (return_encoded)
|
||||
{
|
||||
return PolylineFormatter().printEncodedString(path_description);
|
||||
}
|
||||
return PolylineFormatter().printUnencodedString(path_description);
|
||||
}
|
||||
|
||||
void DescriptionFactory::BuildRouteSummary(const double distance, const unsigned time)
|
||||
{
|
||||
summary.source_name_id = start_phantom.name_id;
|
||||
summary.target_name_id = target_phantom.name_id;
|
||||
summary.BuildDurationAndLengthStrings(distance, time);
|
||||
}
|
||||
|
||||
void DescriptionFactory::Run(const unsigned zoom_level)
|
||||
{
|
||||
if (path_description.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/** starts at index 1 */
|
||||
path_description[0].length = 0.f;
|
||||
for (const auto i : osrm::irange<std::size_t>(1, path_description.size()))
|
||||
{
|
||||
// move down names by one, q&d hack
|
||||
path_description[i - 1].name_id = path_description[i].name_id;
|
||||
path_description[i].length = coordinate_calculation::great_circle_distance(
|
||||
path_description[i - 1].location, path_description[i].location);
|
||||
}
|
||||
|
||||
/*Simplify turn instructions
|
||||
Input :
|
||||
10. Turn left on B 36 for 20 km
|
||||
11. Continue on B 35; B 36 for 2 km
|
||||
12. Continue on B 36 for 13 km
|
||||
|
||||
becomes:
|
||||
10. Turn left on B 36 for 35 km
|
||||
*/
|
||||
// TODO: rework to check only end and start of string.
|
||||
// stl string is way to expensive
|
||||
|
||||
// unsigned lastTurn = 0;
|
||||
// for(unsigned i = 1; i < path_description.size(); ++i) {
|
||||
// string1 = sEngine.GetEscapedNameForNameID(path_description[i].name_id);
|
||||
// if(TurnInstruction::GoStraight == path_description[i].turn_instruction) {
|
||||
// if(std::string::npos != string0.find(string1+";")
|
||||
// || std::string::npos != string0.find(";"+string1)
|
||||
// || std::string::npos != string0.find(string1+" ;")
|
||||
// || std::string::npos != string0.find("; "+string1)
|
||||
// ){
|
||||
// SimpleLogger().Write() << "->next correct: " << string0 << " contains " <<
|
||||
// string1;
|
||||
// for(; lastTurn != i; ++lastTurn)
|
||||
// path_description[lastTurn].name_id = path_description[i].name_id;
|
||||
// path_description[i].turn_instruction = TurnInstruction::NoTurn;
|
||||
// } else if(std::string::npos != string1.find(string0+";")
|
||||
// || std::string::npos != string1.find(";"+string0)
|
||||
// || std::string::npos != string1.find(string0+" ;")
|
||||
// || std::string::npos != string1.find("; "+string0)
|
||||
// ){
|
||||
// SimpleLogger().Write() << "->prev correct: " << string1 << " contains " <<
|
||||
// string0;
|
||||
// path_description[i].name_id = path_description[i-1].name_id;
|
||||
// path_description[i].turn_instruction = TurnInstruction::NoTurn;
|
||||
// }
|
||||
// }
|
||||
// if (TurnInstruction::NoTurn != path_description[i].turn_instruction) {
|
||||
// lastTurn = i;
|
||||
// }
|
||||
// string0 = string1;
|
||||
// }
|
||||
//
|
||||
|
||||
float segment_length = 0.;
|
||||
EdgeWeight segment_duration = 0;
|
||||
std::size_t segment_start_index = 0;
|
||||
|
||||
for (const auto i : osrm::irange<std::size_t>(1, path_description.size()))
|
||||
{
|
||||
entire_length += path_description[i].length;
|
||||
segment_length += path_description[i].length;
|
||||
segment_duration += path_description[i].duration;
|
||||
path_description[segment_start_index].length = segment_length;
|
||||
path_description[segment_start_index].duration = segment_duration;
|
||||
|
||||
if (TurnInstruction::NoTurn != path_description[i].turn_instruction)
|
||||
{
|
||||
BOOST_ASSERT(path_description[i].necessary);
|
||||
segment_length = 0;
|
||||
segment_duration = 0;
|
||||
segment_start_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Post-processing to remove empty or nearly empty path segments
|
||||
if (path_description.size() > 2 &&
|
||||
std::numeric_limits<float>::epsilon() > path_description.back().length &&
|
||||
!(path_description.end() - 2)->is_via_location)
|
||||
{
|
||||
path_description.pop_back();
|
||||
path_description.back().necessary = true;
|
||||
path_description.back().turn_instruction = TurnInstruction::NoTurn;
|
||||
target_phantom.name_id = (path_description.end() - 2)->name_id;
|
||||
}
|
||||
|
||||
if (path_description.size() > 2 &&
|
||||
std::numeric_limits<float>::epsilon() > path_description.front().length &&
|
||||
!(path_description.begin() + 1)->is_via_location)
|
||||
{
|
||||
path_description.erase(path_description.begin());
|
||||
path_description.front().turn_instruction = TurnInstruction::HeadOn;
|
||||
path_description.front().necessary = true;
|
||||
start_phantom.name_id = path_description.front().name_id;
|
||||
}
|
||||
|
||||
// Generalize poly line
|
||||
polyline_generalizer.Run(path_description.begin(), path_description.end(), zoom_level);
|
||||
|
||||
// fix what needs to be fixed else
|
||||
unsigned necessary_segments = 0; // a running index that counts the necessary pieces
|
||||
osrm::for_each_pair(
|
||||
path_description, [&](SegmentInformation &first, const SegmentInformation &second)
|
||||
{
|
||||
if (!first.necessary)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (first.is_via_location)
|
||||
{ // mark the end of a leg (of several segments)
|
||||
via_indices.push_back(necessary_segments);
|
||||
}
|
||||
|
||||
const double post_turn_bearing = coordinate_calculation::bearing(first.location, second.location);
|
||||
const double pre_turn_bearing = coordinate_calculation::bearing(second.location, first.location);
|
||||
first.post_turn_bearing = static_cast<short>(post_turn_bearing * 10);
|
||||
first.pre_turn_bearing = static_cast<short>(pre_turn_bearing * 10);
|
||||
|
||||
++necessary_segments;
|
||||
});
|
||||
|
||||
via_indices.push_back(necessary_segments);
|
||||
BOOST_ASSERT(via_indices.size() >= 2);
|
||||
return;
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef DESCRIPTION_FACTORY_HPP
|
||||
#define DESCRIPTION_FACTORY_HPP
|
||||
|
||||
#include "../algorithms/douglas_peucker.hpp"
|
||||
#include "../data_structures/phantom_node.hpp"
|
||||
#include "../data_structures/segment_information.hpp"
|
||||
#include "../data_structures/turn_instructions.hpp"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <osrm/coordinate.hpp>
|
||||
#include <osrm/json_container.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
struct PathData;
|
||||
/* This class is fed with all way segments in consecutive order
|
||||
* and produces the description plus the encoded polyline */
|
||||
|
||||
class DescriptionFactory
|
||||
{
|
||||
DouglasPeucker polyline_generalizer;
|
||||
PhantomNode start_phantom, target_phantom;
|
||||
|
||||
double DegreeToRadian(const double degree) const;
|
||||
double RadianToDegree(const double degree) const;
|
||||
|
||||
std::vector<unsigned> via_indices;
|
||||
|
||||
double entire_length;
|
||||
|
||||
public:
|
||||
struct RouteSummary
|
||||
{
|
||||
unsigned distance;
|
||||
EdgeWeight duration;
|
||||
unsigned source_name_id;
|
||||
unsigned target_name_id;
|
||||
RouteSummary() : distance(0), duration(0), source_name_id(0), target_name_id(0) {}
|
||||
|
||||
void BuildDurationAndLengthStrings(const double raw_distance, const unsigned raw_duration)
|
||||
{
|
||||
// compute distance/duration for route summary
|
||||
distance = static_cast<unsigned>(std::round(raw_distance));
|
||||
duration = static_cast<EdgeWeight>(std::round(raw_duration / 10.));
|
||||
}
|
||||
} summary;
|
||||
|
||||
// I know, declaring this public is considered bad. I'm lazy
|
||||
std::vector<SegmentInformation> path_description;
|
||||
DescriptionFactory();
|
||||
void AppendSegment(const FixedPointCoordinate &coordinate, const PathData &data);
|
||||
void BuildRouteSummary(const double distance, const unsigned time);
|
||||
void SetStartSegment(const PhantomNode &start_phantom, const bool traversed_in_reverse);
|
||||
void SetEndSegment(const PhantomNode &start_phantom,
|
||||
const bool traversed_in_reverse,
|
||||
const bool is_via_location = false);
|
||||
osrm::json::Value AppendGeometryString(const bool return_encoded);
|
||||
std::vector<unsigned> const &GetViaIndices() const;
|
||||
|
||||
double get_entire_length() const { return entire_length; }
|
||||
|
||||
void Run(const unsigned zoom_level);
|
||||
};
|
||||
|
||||
#endif /* DESCRIPTION_FACTORY_HPP */
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef DESCRIPTOR_BASE_HPP
|
||||
#define DESCRIPTOR_BASE_HPP
|
||||
|
||||
#include "../algorithms/coordinate_calculation.hpp"
|
||||
#include "../data_structures/internal_route_result.hpp"
|
||||
#include "../data_structures/phantom_node.hpp"
|
||||
#include "../typedefs.h"
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <osrm/json_container.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
struct DescriptorTable : public std::unordered_map<std::string, unsigned>
|
||||
{
|
||||
unsigned get_id(const std::string &key)
|
||||
{
|
||||
auto iter = find(key);
|
||||
if (iter != end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct DescriptorConfig
|
||||
{
|
||||
DescriptorConfig() : instructions(true), geometry(true), encode_geometry(true), zoom_level(18)
|
||||
{
|
||||
}
|
||||
|
||||
template <class OtherT>
|
||||
DescriptorConfig(const OtherT &other)
|
||||
: instructions(other.print_instructions), geometry(other.geometry),
|
||||
encode_geometry(other.compression), zoom_level(other.zoom_level)
|
||||
{
|
||||
BOOST_ASSERT(zoom_level >= 0);
|
||||
}
|
||||
|
||||
bool instructions;
|
||||
bool geometry;
|
||||
bool encode_geometry;
|
||||
short zoom_level;
|
||||
};
|
||||
|
||||
template <class DataFacadeT> class BaseDescriptor
|
||||
{
|
||||
public:
|
||||
BaseDescriptor() {}
|
||||
// Maybe someone can explain the pure virtual destructor thing to me (dennis)
|
||||
virtual ~BaseDescriptor() {}
|
||||
virtual void Run(const InternalRouteResult &raw_route, osrm::json::Object &json_result) = 0;
|
||||
virtual void SetConfig(const DescriptorConfig &c) = 0;
|
||||
};
|
||||
|
||||
#endif // DESCRIPTOR_BASE_HPP
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef GPX_DESCRIPTOR_HPP
|
||||
#define GPX_DESCRIPTOR_HPP
|
||||
|
||||
#include "descriptor_base.hpp"
|
||||
#include "../util/xml_renderer.hpp"
|
||||
|
||||
#include <osrm/json_container.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
template <class DataFacadeT> class GPXDescriptor final : public BaseDescriptor<DataFacadeT>
|
||||
{
|
||||
private:
|
||||
DescriptorConfig config;
|
||||
DataFacadeT *facade;
|
||||
|
||||
void AddRoutePoint(const FixedPointCoordinate &coordinate, osrm::json::Array &json_route)
|
||||
{
|
||||
osrm::json::Object json_lat;
|
||||
osrm::json::Object json_lon;
|
||||
osrm::json::Array json_row;
|
||||
|
||||
std::string tmp;
|
||||
|
||||
coordinate_calculation::lat_or_lon_to_string(coordinate.lat, tmp);
|
||||
json_lat.values["_lat"] = tmp;
|
||||
|
||||
coordinate_calculation::lat_or_lon_to_string(coordinate.lon, tmp);
|
||||
json_lon.values["_lon"] = tmp;
|
||||
|
||||
json_row.values.push_back(json_lat);
|
||||
json_row.values.push_back(json_lon);
|
||||
osrm::json::Object entry;
|
||||
entry.values["rtept"] = json_row;
|
||||
json_route.values.push_back(entry);
|
||||
}
|
||||
|
||||
public:
|
||||
explicit GPXDescriptor(DataFacadeT *facade) : facade(facade) {}
|
||||
|
||||
virtual void SetConfig(const DescriptorConfig &c) final { config = c; }
|
||||
|
||||
virtual void Run(const InternalRouteResult &raw_route, osrm::json::Object &json_result) final
|
||||
{
|
||||
osrm::json::Array json_route;
|
||||
if (raw_route.shortest_path_length != INVALID_EDGE_WEIGHT)
|
||||
{
|
||||
AddRoutePoint(raw_route.segment_end_coordinates.front().source_phantom.location,
|
||||
json_route);
|
||||
|
||||
for (const std::vector<PathData> &path_data_vector : raw_route.unpacked_path_segments)
|
||||
{
|
||||
for (const PathData &path_data : path_data_vector)
|
||||
{
|
||||
const FixedPointCoordinate current_coordinate =
|
||||
facade->GetCoordinateOfNode(path_data.node);
|
||||
AddRoutePoint(current_coordinate, json_route);
|
||||
}
|
||||
}
|
||||
AddRoutePoint(raw_route.segment_end_coordinates.back().target_phantom.location,
|
||||
json_route);
|
||||
}
|
||||
// osrm::json::gpx_render(reply.content, json_route);
|
||||
json_result.values["route"] = json_route;
|
||||
}
|
||||
};
|
||||
#endif // GPX_DESCRIPTOR_HPP
|
||||
@@ -1,403 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2015, Project OSRM contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list
|
||||
of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef JSON_DESCRIPTOR_HPP
|
||||
#define JSON_DESCRIPTOR_HPP
|
||||
|
||||
#include "descriptor_base.hpp"
|
||||
#include "description_factory.hpp"
|
||||
#include "../algorithms/object_encoder.hpp"
|
||||
#include "../algorithms/route_name_extraction.hpp"
|
||||
#include "../data_structures/segment_information.hpp"
|
||||
#include "../data_structures/turn_instructions.hpp"
|
||||
#include "../util/bearing.hpp"
|
||||
#include "../util/cast.hpp"
|
||||
#include "../util/integer_range.hpp"
|
||||
#include "../util/json_renderer.hpp"
|
||||
#include "../util/simple_logger.hpp"
|
||||
#include "../util/string_util.hpp"
|
||||
#include "../util/timing_util.hpp"
|
||||
|
||||
#include <osrm/json_container.hpp>
|
||||
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
template <class DataFacadeT> class JSONDescriptor final : public BaseDescriptor<DataFacadeT>
|
||||
{
|
||||
private:
|
||||
DataFacadeT *facade;
|
||||
DescriptorConfig config;
|
||||
DescriptionFactory description_factory, alternate_description_factory;
|
||||
FixedPointCoordinate current;
|
||||
|
||||
public:
|
||||
struct Segment
|
||||
{
|
||||
Segment() : name_id(INVALID_NAMEID), length(-1), position(0) {}
|
||||
Segment(unsigned n, int l, unsigned p) : name_id(n), length(l), position(p) {}
|
||||
unsigned name_id;
|
||||
int length;
|
||||
unsigned position;
|
||||
};
|
||||
private:
|
||||
std::vector<Segment> shortest_path_segments, alternative_path_segments;
|
||||
ExtractRouteNames<DataFacadeT, Segment> GenerateRouteNames;
|
||||
|
||||
public:
|
||||
explicit JSONDescriptor(DataFacadeT *facade) : facade(facade)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void SetConfig(const DescriptorConfig &c) override final { config = c; }
|
||||
|
||||
unsigned DescribeLeg(const std::vector<PathData> &route_leg,
|
||||
const PhantomNodes &leg_phantoms,
|
||||
const bool target_traversed_in_reverse,
|
||||
const bool is_via_leg)
|
||||
{
|
||||
unsigned added_element_count = 0;
|
||||
// Get all the coordinates for the computed route
|
||||
FixedPointCoordinate current_coordinate;
|
||||
for (const PathData &path_data : route_leg)
|
||||
{
|
||||
current_coordinate = facade->GetCoordinateOfNode(path_data.node);
|
||||
description_factory.AppendSegment(current_coordinate, path_data);
|
||||
++added_element_count;
|
||||
}
|
||||
description_factory.SetEndSegment(leg_phantoms.target_phantom, target_traversed_in_reverse,
|
||||
is_via_leg);
|
||||
++added_element_count;
|
||||
BOOST_ASSERT((route_leg.size() + 1) == added_element_count);
|
||||
return added_element_count;
|
||||
}
|
||||
|
||||
virtual void Run(const InternalRouteResult &raw_route,
|
||||
osrm::json::Object &json_result) override final
|
||||
{
|
||||
if (INVALID_EDGE_WEIGHT == raw_route.shortest_path_length)
|
||||
{
|
||||
// We do not need to do much, if there is no route ;-)
|
||||
return;
|
||||
}
|
||||
|
||||
// check if first segment is non-zero
|
||||
BOOST_ASSERT(raw_route.unpacked_path_segments.size() ==
|
||||
raw_route.segment_end_coordinates.size());
|
||||
|
||||
description_factory.SetStartSegment(
|
||||
raw_route.segment_end_coordinates.front().source_phantom,
|
||||
raw_route.source_traversed_in_reverse.front());
|
||||
|
||||
// for each unpacked segment add the leg to the description
|
||||
for (const auto i : osrm::irange<std::size_t>(0, raw_route.unpacked_path_segments.size()))
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
const int added_segments =
|
||||
#endif
|
||||
DescribeLeg(raw_route.unpacked_path_segments[i],
|
||||
raw_route.segment_end_coordinates[i],
|
||||
raw_route.target_traversed_in_reverse[i], raw_route.is_via_leg(i));
|
||||
BOOST_ASSERT(0 < added_segments);
|
||||
}
|
||||
description_factory.Run(config.zoom_level);
|
||||
|
||||
if (config.geometry)
|
||||
{
|
||||
osrm::json::Value route_geometry =
|
||||
description_factory.AppendGeometryString(config.encode_geometry);
|
||||
json_result.values["route_geometry"] = route_geometry;
|
||||
}
|
||||
if (config.instructions)
|
||||
{
|
||||
osrm::json::Array json_route_instructions = BuildTextualDescription(description_factory, shortest_path_segments);
|
||||
json_result.values["route_instructions"] = json_route_instructions;
|
||||
}
|
||||
description_factory.BuildRouteSummary(description_factory.get_entire_length(),
|
||||
raw_route.shortest_path_length);
|
||||
osrm::json::Object json_route_summary;
|
||||
json_route_summary.values["total_distance"] = description_factory.summary.distance;
|
||||
json_route_summary.values["total_time"] = description_factory.summary.duration;
|
||||
json_route_summary.values["start_point"] =
|
||||
facade->get_name_for_id(description_factory.summary.source_name_id);
|
||||
json_route_summary.values["end_point"] =
|
||||
facade->get_name_for_id(description_factory.summary.target_name_id);
|
||||
json_result.values["route_summary"] = json_route_summary;
|
||||
|
||||
BOOST_ASSERT(!raw_route.segment_end_coordinates.empty());
|
||||
|
||||
osrm::json::Array json_via_points_array;
|
||||
osrm::json::Array json_first_coordinate;
|
||||
json_first_coordinate.values.push_back(
|
||||
raw_route.segment_end_coordinates.front().source_phantom.location.lat /
|
||||
COORDINATE_PRECISION);
|
||||
json_first_coordinate.values.push_back(
|
||||
raw_route.segment_end_coordinates.front().source_phantom.location.lon /
|
||||
COORDINATE_PRECISION);
|
||||
json_via_points_array.values.push_back(json_first_coordinate);
|
||||
for (const PhantomNodes &nodes : raw_route.segment_end_coordinates)
|
||||
{
|
||||
std::string tmp;
|
||||
osrm::json::Array json_coordinate;
|
||||
json_coordinate.values.push_back(nodes.target_phantom.location.lat /
|
||||
COORDINATE_PRECISION);
|
||||
json_coordinate.values.push_back(nodes.target_phantom.location.lon /
|
||||
COORDINATE_PRECISION);
|
||||
json_via_points_array.values.push_back(json_coordinate);
|
||||
}
|
||||
json_result.values["via_points"] = json_via_points_array;
|
||||
|
||||
osrm::json::Array json_via_indices_array;
|
||||
|
||||
std::vector<unsigned> const &shortest_leg_end_indices = description_factory.GetViaIndices();
|
||||
json_via_indices_array.values.insert(json_via_indices_array.values.end(),
|
||||
shortest_leg_end_indices.begin(),
|
||||
shortest_leg_end_indices.end());
|
||||
json_result.values["via_indices"] = json_via_indices_array;
|
||||
|
||||
// only one alternative route is computed at this time, so this is hardcoded
|
||||
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
|
||||
{
|
||||
json_result.values["found_alternative"] = osrm::json::True();
|
||||
BOOST_ASSERT(!raw_route.alt_source_traversed_in_reverse.empty());
|
||||
alternate_description_factory.SetStartSegment(
|
||||
raw_route.segment_end_coordinates.front().source_phantom,
|
||||
raw_route.alt_source_traversed_in_reverse.front());
|
||||
// Get all the coordinates for the computed route
|
||||
for (const PathData &path_data : raw_route.unpacked_alternative)
|
||||
{
|
||||
current = facade->GetCoordinateOfNode(path_data.node);
|
||||
alternate_description_factory.AppendSegment(current, path_data);
|
||||
}
|
||||
alternate_description_factory.SetEndSegment(
|
||||
raw_route.segment_end_coordinates.back().target_phantom,
|
||||
raw_route.alt_source_traversed_in_reverse.back());
|
||||
alternate_description_factory.Run(config.zoom_level);
|
||||
|
||||
if (config.geometry)
|
||||
{
|
||||
osrm::json::Value alternate_geometry_string =
|
||||
alternate_description_factory.AppendGeometryString(config.encode_geometry);
|
||||
osrm::json::Array json_alternate_geometries_array;
|
||||
json_alternate_geometries_array.values.push_back(alternate_geometry_string);
|
||||
json_result.values["alternative_geometries"] = json_alternate_geometries_array;
|
||||
}
|
||||
// Generate instructions for each alternative (simulated here)
|
||||
osrm::json::Array json_alt_instructions;
|
||||
osrm::json::Array json_current_alt_instructions;
|
||||
if (config.instructions)
|
||||
{
|
||||
json_current_alt_instructions = BuildTextualDescription(alternate_description_factory, alternative_path_segments);
|
||||
json_alt_instructions.values.push_back(json_current_alt_instructions);
|
||||
json_result.values["alternative_instructions"] = json_alt_instructions;
|
||||
}
|
||||
alternate_description_factory.BuildRouteSummary(
|
||||
alternate_description_factory.get_entire_length(),
|
||||
raw_route.alternative_path_length);
|
||||
|
||||
osrm::json::Object json_alternate_route_summary;
|
||||
osrm::json::Array json_alternate_route_summary_array;
|
||||
json_alternate_route_summary.values["total_distance"] =
|
||||
alternate_description_factory.summary.distance;
|
||||
json_alternate_route_summary.values["total_time"] =
|
||||
alternate_description_factory.summary.duration;
|
||||
json_alternate_route_summary.values["start_point"] =
|
||||
facade->get_name_for_id(alternate_description_factory.summary.source_name_id);
|
||||
json_alternate_route_summary.values["end_point"] =
|
||||
facade->get_name_for_id(alternate_description_factory.summary.target_name_id);
|
||||
json_alternate_route_summary_array.values.push_back(json_alternate_route_summary);
|
||||
json_result.values["alternative_summaries"] = json_alternate_route_summary_array;
|
||||
|
||||
std::vector<unsigned> const &alternate_leg_end_indices =
|
||||
alternate_description_factory.GetViaIndices();
|
||||
osrm::json::Array json_altenative_indices_array;
|
||||
json_altenative_indices_array.values.insert(json_altenative_indices_array.values.end(),
|
||||
alternate_leg_end_indices.begin(),
|
||||
alternate_leg_end_indices.end());
|
||||
json_result.values["alternative_indices"] = json_altenative_indices_array;
|
||||
}
|
||||
else
|
||||
{
|
||||
json_result.values["found_alternative"] = osrm::json::False();
|
||||
}
|
||||
|
||||
// Get Names for both routes
|
||||
RouteNames route_names =
|
||||
GenerateRouteNames(shortest_path_segments, alternative_path_segments, facade);
|
||||
osrm::json::Array json_route_names;
|
||||
json_route_names.values.push_back(route_names.shortest_path_name_1);
|
||||
json_route_names.values.push_back(route_names.shortest_path_name_2);
|
||||
json_result.values["route_name"] = json_route_names;
|
||||
|
||||
if (INVALID_EDGE_WEIGHT != raw_route.alternative_path_length)
|
||||
{
|
||||
osrm::json::Array json_alternate_names_array;
|
||||
osrm::json::Array json_alternate_names;
|
||||
json_alternate_names.values.push_back(route_names.alternative_path_name_1);
|
||||
json_alternate_names.values.push_back(route_names.alternative_path_name_2);
|
||||
json_alternate_names_array.values.push_back(json_alternate_names);
|
||||
json_result.values["alternative_names"] = json_alternate_names_array;
|
||||
}
|
||||
|
||||
json_result.values["hint_data"] = BuildHintData(raw_route);
|
||||
}
|
||||
|
||||
inline osrm::json::Object BuildHintData(const InternalRouteResult& raw_route) const
|
||||
{
|
||||
osrm::json::Object json_hint_object;
|
||||
json_hint_object.values["checksum"] = facade->GetCheckSum();
|
||||
osrm::json::Array json_location_hint_array;
|
||||
std::string hint;
|
||||
for (const auto i : osrm::irange<std::size_t>(0, raw_route.segment_end_coordinates.size()))
|
||||
{
|
||||
ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates[i].source_phantom,
|
||||
hint);
|
||||
json_location_hint_array.values.push_back(hint);
|
||||
}
|
||||
ObjectEncoder::EncodeToBase64(raw_route.segment_end_coordinates.back().target_phantom,
|
||||
hint);
|
||||
json_location_hint_array.values.push_back(hint);
|
||||
json_hint_object.values["locations"] = json_location_hint_array;
|
||||
|
||||
return json_hint_object;
|
||||
}
|
||||
|
||||
inline osrm::json::Array BuildTextualDescription(const DescriptionFactory &description_factory,
|
||||
std::vector<Segment> &route_segments_list) const
|
||||
{
|
||||
osrm::json::Array json_instruction_array;
|
||||
// Segment information has following format:
|
||||
//["instruction id","streetname",length,position,time,"length","earth_direction",azimuth]
|
||||
unsigned necessary_segments_running_index = 0;
|
||||
|
||||
struct RoundAbout
|
||||
{
|
||||
RoundAbout() : start_index(std::numeric_limits<int>::max()), name_id(INVALID_NAMEID), leave_at_exit(std::numeric_limits<int>::max()) {}
|
||||
int start_index;
|
||||
unsigned name_id;
|
||||
int leave_at_exit;
|
||||
} round_about;
|
||||
|
||||
round_about.leave_at_exit = 0;
|
||||
round_about.name_id = 0;
|
||||
std::string temp_dist, temp_length, temp_duration, temp_bearing, temp_instruction;
|
||||
TravelMode last_travel_mode = TRAVEL_MODE_DEFAULT;
|
||||
|
||||
// Fetch data from Factory and generate a string from it.
|
||||
for (const SegmentInformation &segment : description_factory.path_description)
|
||||
{
|
||||
osrm::json::Array json_instruction_row;
|
||||
TurnInstruction current_instruction = segment.turn_instruction;
|
||||
if (TurnInstructionsClass::TurnIsNecessary(current_instruction))
|
||||
{
|
||||
if (TurnInstruction::EnterRoundAbout == current_instruction)
|
||||
{
|
||||
round_about.name_id = segment.name_id;
|
||||
round_about.start_index = necessary_segments_running_index;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string current_turn_instruction;
|
||||
if (TurnInstruction::LeaveRoundAbout == current_instruction)
|
||||
{
|
||||
temp_instruction = std::to_string(
|
||||
cast::enum_to_underlying(TurnInstruction::EnterRoundAbout));
|
||||
current_turn_instruction += temp_instruction;
|
||||
current_turn_instruction += "-";
|
||||
temp_instruction = std::to_string(round_about.leave_at_exit + 1);
|
||||
current_turn_instruction += temp_instruction;
|
||||
round_about.leave_at_exit = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_instruction =
|
||||
std::to_string(cast::enum_to_underlying(current_instruction));
|
||||
current_turn_instruction += temp_instruction;
|
||||
}
|
||||
json_instruction_row.values.push_back(current_turn_instruction);
|
||||
|
||||
json_instruction_row.values.push_back(facade->get_name_for_id(segment.name_id));
|
||||
json_instruction_row.values.push_back(std::round(segment.length));
|
||||
json_instruction_row.values.push_back(necessary_segments_running_index);
|
||||
json_instruction_row.values.push_back(std::round(segment.duration / 10.));
|
||||
json_instruction_row.values.push_back(
|
||||
std::to_string(static_cast<unsigned>(segment.length)) + "m");
|
||||
|
||||
// post turn bearing
|
||||
const double post_turn_bearing_value = (segment.post_turn_bearing / 10.);
|
||||
json_instruction_row.values.push_back(bearing::get(post_turn_bearing_value));
|
||||
json_instruction_row.values.push_back(
|
||||
static_cast<unsigned>(round(post_turn_bearing_value)));
|
||||
|
||||
json_instruction_row.values.push_back(segment.travel_mode);
|
||||
last_travel_mode = segment.travel_mode;
|
||||
|
||||
// pre turn bearing
|
||||
const double pre_turn_bearing_value = (segment.pre_turn_bearing / 10.);
|
||||
json_instruction_row.values.push_back(bearing::get(pre_turn_bearing_value));
|
||||
json_instruction_row.values.push_back(
|
||||
static_cast<unsigned>(round(pre_turn_bearing_value)));
|
||||
|
||||
json_instruction_array.values.push_back(json_instruction_row);
|
||||
|
||||
route_segments_list.emplace_back(
|
||||
segment.name_id, static_cast<int>(segment.length),
|
||||
static_cast<unsigned>(route_segments_list.size()));
|
||||
}
|
||||
}
|
||||
else if (TurnInstruction::StayOnRoundAbout == current_instruction)
|
||||
{
|
||||
++round_about.leave_at_exit;
|
||||
}
|
||||
if (segment.necessary)
|
||||
{
|
||||
++necessary_segments_running_index;
|
||||
}
|
||||
}
|
||||
|
||||
osrm::json::Array json_last_instruction_row;
|
||||
temp_instruction =
|
||||
std::to_string(cast::enum_to_underlying(TurnInstruction::ReachedYourDestination));
|
||||
json_last_instruction_row.values.push_back(temp_instruction);
|
||||
json_last_instruction_row.values.push_back("");
|
||||
json_last_instruction_row.values.push_back(0);
|
||||
json_last_instruction_row.values.push_back(necessary_segments_running_index - 1);
|
||||
json_last_instruction_row.values.push_back(0);
|
||||
json_last_instruction_row.values.push_back("0m");
|
||||
json_last_instruction_row.values.push_back(bearing::get(0.0));
|
||||
json_last_instruction_row.values.push_back(0.);
|
||||
json_last_instruction_row.values.push_back(last_travel_mode);
|
||||
json_last_instruction_row.values.push_back(bearing::get(0.0));
|
||||
json_last_instruction_row.values.push_back(0.);
|
||||
json_instruction_array.values.push_back(json_last_instruction_row);
|
||||
|
||||
return json_instruction_array;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* JSON_DESCRIPTOR_H_ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user