Compare commits
2082 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f7fbca3e5e | |||
| 9695eaa28a | |||
| 0d7546a510 | |||
| 9dc8136240 | |||
| a02a83f8bd | |||
| 9b18f55d29 | |||
| a3434e7ae9 | |||
| 64b15028e4 | |||
| d8e466fdaa | |||
| 43bbe8f2ae | |||
| b5c10b1fbf | |||
| 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 | |||
| f6116db957 | |||
| b36145e3c4 | |||
| 1c1bfd7541 | |||
| c824429458 | |||
| 238e77d959 | |||
| 23b2154d98 | |||
| 25c8711aad | |||
| cf30628d4e | |||
| e21eaa4b9e | |||
| 80b897d8cf | |||
| 1ed7bcfb2c | |||
| e20f92bbbb | |||
| 6e717bfd30 | |||
| 5d743bb0a3 | |||
| 7675c730b6 | |||
| 42942bb1e0 | |||
| 9d12de9bce | |||
| 790520e335 | |||
| 4b0e1a4b19 | |||
| a877f8abf0 | |||
| 491b1d9c96 | |||
| 2ce74c05e1 | |||
| 88e6558da3 | |||
| f1140ec903 | |||
| 8a745ecdfd | |||
| b8e29f5ae3 | |||
| 22e83013e3 | |||
| cc4713d878 | |||
| 490e838c60 | |||
| 6b15f29d7c | |||
| e7d9e42a16 | |||
| bd91727f49 | |||
| 328faf3744 | |||
| 1157cb9b95 | |||
| 7c8626d144 | |||
| 03faf2665b | |||
| 9959fd26bb | |||
| 43dcdb21ec | |||
| 3727637145 | |||
| 466251287f | |||
| f46706843b | |||
| c93ca02fb8 | |||
| 4813488f84 | |||
| fc292cc2d8 | |||
| f875e26fbf | |||
| 05658aeb3b | |||
| a14cb1fc06 | |||
| f68247673a | |||
| f65dd63210 | |||
| 03f64a6c20 | |||
| 0627c3443d | |||
| c65dd16460 | |||
| c590596dbe | |||
| 23cd4d5ed2 | |||
| 4dc6ff9fb8 | |||
| 8638cbf8b2 | |||
| a2555983e6 | |||
| 21804aecdb | |||
| 6991a38703 | |||
| 6b18e4f7e9 | |||
| efc9007cbf | |||
| efd33b295a | |||
| fa4ba42f15 | |||
| d3ef520915 | |||
| 811e29ff1b | |||
| 95d1efb7f8 | |||
| 5341cb5ff9 | |||
| cb37c0d135 | |||
| 73d40ce02a | |||
| c1709da6bf | |||
| dcfa81f983 | |||
| 42b1eaa240 | |||
| 1da1fa5a31 | |||
| 707931125e | |||
| f4e82a879b | |||
| 4f7369ed02 | |||
| 4312013552 | |||
| e8bc69aa01 | |||
| befb667759 | |||
| b35254ec78 | |||
| 9956988938 | |||
| 5b0e2e487a | |||
| ccd3872bf1 | |||
| b209952ce0 | |||
| 3568de2c6c | |||
| a8957d75b9 | |||
| 028ca5c9d9 | |||
| d516e1c736 | |||
| afdf8e7b21 | |||
| 9852b147f8 | |||
| 552cdbfe20 | |||
| 4ca29dd18e | |||
| 0d971a70cc | |||
| 0dda98384b | |||
| 685d330ee2 | |||
| 2d455018ae | |||
| fce486735b | |||
| 45073ce9eb | |||
| 4ba732c886 | |||
| a6cb786718 | |||
| 93a2e66704 | |||
| facbe2c012 | |||
| 02a49c8a68 | |||
| 97585bb26a | |||
| b618a1241f | |||
| d936009ea1 | |||
| 078f71c144 | |||
| bfc6c9b89d | |||
| 758d402305 | |||
| e6789fab6c | |||
| a2e114e852 | |||
| 0baf90a218 | |||
| f9f3d43152 | |||
| 326f2d2743 | |||
| 57f257dce5 | |||
| c27fc4e4d8 | |||
| a37192c102 | |||
| 68bd6a29b6 | |||
| da11113bf1 | |||
| 70f4cdd0ca | |||
| 78ac3cffde | |||
| 7eb2af6cd3 | |||
| 0b1c9d33a5 | |||
| 648a62112e | |||
| ff7cb91d9c | |||
| fd5881670d | |||
| fc8768b79b | |||
| 914570b053 | |||
| 1a8783cfa0 | |||
| 28bfefcac6 | |||
| bec56522e3 | |||
| 0ddd473477 | |||
| 2defc8e826 | |||
| c3756f6b58 | |||
| 66af3d260c | |||
| 5c3398c280 | |||
| 63a59325f5 | |||
| f1091f97fc | |||
| fe9bdfef79 | |||
| a8f11981e3 | |||
| 94651744af | |||
| 24e7d00af5 | |||
| f85a35b5fc | |||
| a27aad0061 | |||
| 9a332d2f86 | |||
| 1264983688 | |||
| 4d4a3d02ed | |||
| 53cee90933 | |||
| 6daa3290d4 | |||
| 5a9bee0527 | |||
| 6914d26187 | |||
| 68c01d09bb | |||
| 4bf1ad2566 | |||
| 00ed526fb0 | |||
| 9bdc58069b | |||
| 4ddbd2efb6 | |||
| f3f153cb38 | |||
| 9414a8085d | |||
| 33b18df1a0 | |||
| da91d342f7 | |||
| 4950e044ba | |||
| b41af5f580 | |||
| 24090d4642 | |||
| cdb1918973 | |||
| a8e8f04fa3 | |||
| 4ec3102df2 | |||
| 7e722db3ee | |||
| 20c45be3b3 | |||
| f2ee0aad20 | |||
| 478d4a571a | |||
| 4253ebf243 | |||
| 5b782a783a | |||
| c38183423f | |||
| 019e26dd8e | |||
| 6d2a65b4ea | |||
| 4206d98b55 | |||
| 9005fe2f61 | |||
| f87f18a291 | |||
| c0fdcb381a | |||
| aeaf0e7ba8 | |||
| 6dada4e347 | |||
| 61f015eef6 | |||
| d843521839 | |||
| 420369fe13 | |||
| 71bf1edc5e | |||
| d06ac519ab | |||
| 50512b52e1 | |||
| 543e77b9be | |||
| 783d455bd7 | |||
| 6c35272fe2 | |||
| 6955978a62 | |||
| 27d87dff79 | |||
| d8ca58a04e | |||
| ce34798685 | |||
| 16fd5249dd | |||
| b9a4c322a7 | |||
| 673bf356e4 | |||
| 6228412e61 | |||
| 578d947e2d | |||
| 72629d0081 | |||
| d7989f19cf | |||
| 8b11cdbf61 | |||
| 5c1f76e3cf | |||
| 63ba6018f3 | |||
| 8f3482561b | |||
| 13ceeb191c | |||
| 1536d1c044 | |||
| 16b6c26d6e | |||
| c7e30e2266 | |||
| d5e4495f89 | |||
| 963960a44c | |||
| a62c10321c | |||
| bb49e03435 | |||
| 38e7b1a262 | |||
| a00d3dfc00 | |||
| cd458e7a44 | |||
| 3f82570469 | |||
| a8642bd208 | |||
| b404c79ca4 | |||
| 29c75337f2 | |||
| fca4aeb50b | |||
| 1dfa2d6e91 | |||
| 79650ca3fd | |||
| fd84827e51 | |||
| 78283a0e0e | |||
| 993321e971 | |||
| f7a1e2f652 | |||
| e75be68466 | |||
| 74ac283c52 | |||
| 9ef1f8cba3 | |||
| e45656e5bf | |||
| cdc4fb45f2 | |||
| 5379a555db | |||
| d07c0bde80 | |||
| 7015ed203a | |||
| 1ead4cbb14 | |||
| 84ebca0dd2 | |||
| cf45b2cddb | |||
| 8f8bd05f83 | |||
| b1155a202c | |||
| d4aaaf16f8 | |||
| 119fb63576 | |||
| 3f7afd47d2 | |||
| ca0f8ed653 | |||
| 809bdb7c1f | |||
| 0424ff0818 | |||
| 9b952ff48c | |||
| c5064710a8 | |||
| 57e522065a | |||
| 7143daf500 | |||
| 71a00fc01b | |||
| 941483c14d | |||
| 17d8e65c64 | |||
| 72c0feb048 | |||
| 9e20dbe226 | |||
| 06f2738c03 | |||
| 5a257416ca | |||
| f9f0ffb64d | |||
| 31cf8a8813 | |||
| 98b7e0a407 | |||
| 7ed63d2ab5 | |||
| 6e6b38e8e9 | |||
| 829b9d96e4 | |||
| 85cef7e37c | |||
| c526bec798 | |||
| 9231335eef | |||
| dfac34beac | |||
| 82dd5d8ccf | |||
| be506f7121 | |||
| 2470494009 | |||
| f95a4b9b46 | |||
| 6b444a0877 | |||
| 5c4a845b55 | |||
| 468c01056f | |||
| 397078758e | |||
| c9af06c9e0 | |||
| 5a7e663b1d | |||
| e0550cd20b | |||
| 5844231a37 | |||
| 8d435638e1 | |||
| 55cad1b3ac | |||
| 9deadc1371 | |||
| 998abf05ba | |||
| aab5092da3 | |||
| 65ee5c4bbb | |||
| 42ab938a19 | |||
| 2891de2fcd | |||
| ed3758874d | |||
| 895d8179a2 |
+59
-23
@@ -2,53 +2,89 @@
|
|||||||
Language: Cpp
|
Language: Cpp
|
||||||
# BasedOnStyle: LLVM
|
# BasedOnStyle: LLVM
|
||||||
AccessModifierOffset: -2
|
AccessModifierOffset: -2
|
||||||
ConstructorInitializerIndentWidth: 4
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
AlignEscapedNewlinesLeft: false
|
AlignEscapedNewlinesLeft: false
|
||||||
|
AlignOperands: true
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: true
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
AllowShortFunctionsOnASingleLine: true
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
AlwaysBreakTemplateDeclarations: false
|
AlwaysBreakAfterReturnType: None
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
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
|
BreakBeforeBinaryOperators: false
|
||||||
|
BreakBeforeBraces: Allman
|
||||||
BreakBeforeTernaryOperators: true
|
BreakBeforeTernaryOperators: true
|
||||||
BreakConstructorInitializersBeforeComma: false
|
BreakConstructorInitializersBeforeComma: false
|
||||||
BinPackParameters: false
|
|
||||||
ColumnLimit: 100
|
ColumnLimit: 100
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
DerivePointerBinding: false
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
ExperimentalAutoDetectBinPacking: 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
|
IndentCaseLabels: false
|
||||||
MaxEmptyLinesToKeep: 1
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
ObjCSpaceAfterProperty: false
|
ObjCSpaceAfterProperty: false
|
||||||
ObjCSpaceBeforeProtocolList: true
|
ObjCSpaceBeforeProtocolList: true
|
||||||
PenaltyBreakBeforeFirstCallParameter: 19
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
PenaltyBreakComment: 300
|
PenaltyBreakComment: 300
|
||||||
PenaltyBreakString: 1000
|
|
||||||
PenaltyBreakFirstLessLess: 120
|
PenaltyBreakFirstLessLess: 120
|
||||||
PenaltyExcessCharacter: 1000
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
PointerBindsToType: false
|
PointerAlignment: Right
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
SpacesBeforeTrailingComments: 1
|
SpacesBeforeTrailingComments: 1
|
||||||
Cpp11BracedListStyle: true
|
SpacesInAngles: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
Standard: Cpp11
|
Standard: Cpp11
|
||||||
IndentWidth: 4
|
|
||||||
TabWidth: 8
|
TabWidth: 8
|
||||||
UseTab: Never
|
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
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
Checks: '-clang-analyzer-*,google-*,llvm-*,misc-*,readability-*,-google-build-explicit-make-pair,-google-explicit-constructor,-google-readability-braces-around-statements,-google-readability-casting,-google-readability-namespace-comments,-google-readability-function,-google-readability-todo,-google-runtime-int,-llvm-namespace-comment,-llvm-header-guard,-llvm-twine-local,-misc-argument-comment,-readability-braces-around-statements,-readability-identifier-naming'
|
||||||
|
...
|
||||||
|
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
# Kind-specific patterns to check AST nodes against. Both python-clang and
|
||||||
|
# libclang docs explain CursorKind, with differences in detail. See also:
|
||||||
|
# - https://github.com/llvm-mirror/clang/blob/aca4fe314a55cacae29e1548cb7bfd2119c6df4c/bindings/python/clang/cindex.py#L599
|
||||||
|
# - http://clang.llvm.org/doxygen/group__CINDEX.html#gaaccc432245b4cd9f2d470913f9ef0013
|
||||||
|
# - https://docs.python.org/2/library/re.html#regular-expression-syntax
|
||||||
|
|
||||||
|
class_decl: '^([A-Z]+[a-z]+)+$'
|
||||||
|
struct_decl: '^([A-Z]+[a-z]+)+$'
|
||||||
|
field_decl: '^[a-z_]+$'
|
||||||
|
var_decl: '^[a-z]+[a-z0-9_]*$'
|
||||||
|
parm_decl: '^[a-z]*[a-z0-9_]*$'
|
||||||
|
namespace: '^[a-z_]*$'
|
||||||
|
cxx_method: '^([A-Z]+[a-z]+)+$'
|
||||||
|
function_decl: '^[a-z]+([A-Z]+[a-z]+)*$'
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"rules": {
|
||||||
|
"indent": [
|
||||||
|
2,
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"quotes": [
|
||||||
|
1,
|
||||||
|
"single"
|
||||||
|
],
|
||||||
|
"linebreak-style": [
|
||||||
|
2,
|
||||||
|
"unix"
|
||||||
|
],
|
||||||
|
"semi": [
|
||||||
|
2,
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"no-console": [
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"es6": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": "eslint:recommended"
|
||||||
|
}
|
||||||
@@ -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
-2
@@ -1,3 +1,8 @@
|
|||||||
|
# mason #
|
||||||
|
#########
|
||||||
|
/.mason
|
||||||
|
/mason_packages
|
||||||
|
|
||||||
# pre compiled dependencies #
|
# pre compiled dependencies #
|
||||||
#############################
|
#############################
|
||||||
osrm-deps
|
osrm-deps
|
||||||
@@ -40,8 +45,8 @@ Thumbs.db
|
|||||||
# build related files #
|
# build related files #
|
||||||
#######################
|
#######################
|
||||||
/build/
|
/build/
|
||||||
/util/fingerprint_impl.hpp
|
/example/build/
|
||||||
/util/git_sha.cpp
|
/test/data/monaco*
|
||||||
/cmake/postinst
|
/cmake/postinst
|
||||||
|
|
||||||
# Eclipse related files #
|
# Eclipse related files #
|
||||||
@@ -75,8 +80,20 @@ stxxl.errlog
|
|||||||
###################
|
###################
|
||||||
/sandbox/
|
/sandbox/
|
||||||
|
|
||||||
|
# Test related files #
|
||||||
|
######################
|
||||||
/test/profile.lua
|
/test/profile.lua
|
||||||
|
/test/cache
|
||||||
|
/test/speeds.csv
|
||||||
|
/test/penalties.csv
|
||||||
|
/test/data/monaco.*
|
||||||
|
node_modules
|
||||||
|
|
||||||
# Deprecated config file #
|
# Deprecated config file #
|
||||||
##########################
|
##########################
|
||||||
/server.ini
|
/server.ini
|
||||||
|
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# local lua debugging file
|
||||||
|
debug.lua
|
||||||
+198
-58
@@ -1,63 +1,203 @@
|
|||||||
language: cpp
|
language: cpp
|
||||||
compiler:
|
|
||||||
- gcc
|
git:
|
||||||
# - clang
|
depth: 10
|
||||||
# Make sure CMake is installed
|
|
||||||
install:
|
# sudo:required is needed for trusty images
|
||||||
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
|
sudo: required
|
||||||
- sudo add-apt-repository -y ppa:boost-latest/ppa
|
dist: trusty
|
||||||
- sudo apt-get update >/dev/null
|
|
||||||
- sudo apt-get -q install libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
|
notifications:
|
||||||
- sudo apt-get -q install g++-4.8
|
email: false
|
||||||
- sudo apt-get install libboost1.54-all-dev
|
|
||||||
- sudo apt-get install libgdal-dev
|
|
||||||
# luabind
|
|
||||||
- curl https://gist.githubusercontent.com/DennisOSRM/f2eb7b948e6fe1ae319e/raw/install-luabind.sh | sudo bash
|
|
||||||
# osmosis
|
|
||||||
- curl -s https://gist.githubusercontent.com/DennisOSRM/803a64a9178ec375069f/raw/ | sudo bash
|
|
||||||
# cmake
|
|
||||||
- curl -s https://gist.githubusercontent.com/DennisOSRM/5fad9bee5c7f09fd7fc9/raw/ | sudo bash
|
|
||||||
before_script:
|
|
||||||
- rvm use 1.9.3
|
|
||||||
- gem install bundler
|
|
||||||
- bundle install
|
|
||||||
- mkdir build
|
|
||||||
- cd build
|
|
||||||
- cmake .. $CMAKEOPTIONS -DBUILD_TOOLS=1
|
|
||||||
script:
|
|
||||||
- make
|
|
||||||
- make tests
|
|
||||||
- make benchmarks
|
|
||||||
- ./algorithm-tests
|
|
||||||
- ./datastructure-tests
|
|
||||||
- cd ..
|
|
||||||
- cucumber -p verify
|
|
||||||
after_script:
|
|
||||||
# - cd ..
|
|
||||||
# - cucumber -p verify
|
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
- develop
|
- "5.6"
|
||||||
cache:
|
|
||||||
- bundler
|
|
||||||
- apt
|
|
||||||
env:
|
|
||||||
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5000 OSRM_TIMEOUT=60
|
|
||||||
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5010 OSRM_TIMEOUT=60
|
|
||||||
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5020 OSRM_TIMEOUT=60
|
|
||||||
notifications:
|
|
||||||
slack: mapbox:4A6euphDwfxAQnhLurXbu6A1
|
|
||||||
irc:
|
|
||||||
channels:
|
|
||||||
- irc.oftc.net#osrm
|
|
||||||
on_success: change
|
|
||||||
on_failure: always
|
|
||||||
use_notice: true
|
|
||||||
skip_join: false
|
|
||||||
|
|
||||||
recipients:
|
cache:
|
||||||
- patrick@mapbox.com
|
ccache: true
|
||||||
email:
|
apt: true
|
||||||
on_success: change
|
directories:
|
||||||
on_failure: always
|
- 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:
|
||||||
|
|
||||||
|
# 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-3.9-debug"
|
||||||
|
addons: &clang38
|
||||||
|
apt:
|
||||||
|
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: "mason-linux-release"
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: ['libstdc++-5-dev']
|
||||||
|
env: CLANG_VERSION='3.9.1' BUILD_TYPE='Release' ENABLE_MASON=ON RUN_CLANG_FORMAT=ON
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
compiler: "gcc-6-release"
|
||||||
|
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_COMPONENTS=ON
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
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++-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-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
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- if [[ ! -z $TARGET_ARCH ]] ; then source ./scripts/travis/before_install.$TARGET_ARCH.sh ; fi
|
||||||
|
- |
|
||||||
|
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
|
||||||
|
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
|
||||||
|
|
||||||
|
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:
|
||||||
|
- 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
|
||||||
|
|||||||
+434
@@ -0,0 +1,434 @@
|
|||||||
|
|
||||||
|
# 5.6.2
|
||||||
|
- Changes from 5.6.0
|
||||||
|
- Bugfixes
|
||||||
|
- Fix incorrect forward datasources getter in facade
|
||||||
|
- Fix include `access=private` non-car roads in the car profile
|
||||||
|
|
||||||
|
# 5.6.1
|
||||||
|
- Changes from 5.6.0
|
||||||
|
- Bugfixes
|
||||||
|
- Fix #3754 restricted access roads not penalized if restriction begins non at an intersection
|
||||||
|
|
||||||
|
# 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`
|
||||||
+623
-225
@@ -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)
|
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR AND NOT MSVC_IDE)
|
||||||
message(FATAL_ERROR "In-source builds are not allowed.
|
message(FATAL_ERROR "In-source builds are not allowed.
|
||||||
@@ -6,156 +7,286 @@ 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.")
|
This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. Please delete them.")
|
||||||
endif()
|
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)
|
project(OSRM C CXX)
|
||||||
|
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)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
include(GetGitRevisionDescription)
|
|
||||||
git_describe(GIT_DESCRIPTION)
|
|
||||||
|
|
||||||
set(bitness 32)
|
set(bitness 32)
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
set(bitness 64)
|
set(bitness 64)
|
||||||
message(STATUS "Building on a 64 bit system")
|
message(STATUS "Building on a 64 bit system")
|
||||||
else()
|
else()
|
||||||
message(WARNING "Building on a 32 bit system is unsupported")
|
message(STATUS "Building on a 32 bit system")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32 AND MSVC_VERSION LESS 1800)
|
if(WIN32 AND MSVC_VERSION LESS 1900)
|
||||||
message(FATAL_ERROR "Building with Microsoft compiler needs Visual Studio 2013 or later (Express version works too)")
|
message(FATAL_ERROR "Building with Microsoft compiler needs Latest Visual Studio 2015 (Community or better)")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(ENABLE_JSON_LOGGING "Adds additional JSON debug logging to the response" OFF)
|
# Strictly require GCC>=4.9 and Clang>=3.4 - GCC 4.8 is already too old for C++14.
|
||||||
option(WITH_TOOLS "Build OSRM tools" OFF)
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
option(BUILD_TOOLS "Build OSRM tools" OFF)
|
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/)
|
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/)
|
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/libosmium/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
|
set(BOOST_COMPONENTS date_time chrono filesystem iostreams program_options regex system thread unit_test_framework)
|
||||||
${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_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)
|
|
||||||
add_custom_target(benchmarks DEPENDS rtree-bench)
|
|
||||||
|
|
||||||
set(BOOST_COMPONENTS date_time filesystem iostreams program_options regex system thread unit_test_framework)
|
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/util/git_sha.cpp.in
|
${CMAKE_CURRENT_SOURCE_DIR}/include/util/version.hpp.in
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/util/git_sha.cpp
|
${CMAKE_CURRENT_BINARY_DIR}/include/util/version.hpp
|
||||||
)
|
)
|
||||||
file(GLOB ExtractorGlob extractor/*.cpp)
|
file(GLOB UtilGlob src/util/*.cpp src/util/*/*.cpp)
|
||||||
file(GLOB ImporterGlob data_structures/import_edge.cpp data_structures/external_memory_node.cpp data_structures/raster_source.cpp)
|
file(GLOB ExtractorGlob src/extractor/*.cpp src/extractor/*/*.cpp)
|
||||||
add_library(IMPORT OBJECT ${ImporterGlob})
|
file(GLOB ContractorGlob src/contractor/*.cpp)
|
||||||
add_library(LOGGER OBJECT util/simple_logger.cpp)
|
file(GLOB StorageGlob src/storage/*.cpp)
|
||||||
add_library(PHANTOMNODE OBJECT data_structures/phantom_node.cpp)
|
file(GLOB ServerGlob src/server/*.cpp src/server/**/*.cpp)
|
||||||
add_library(RASTERSOURCE OBJECT data_structures/raster_source.cpp)
|
file(GLOB EngineGlob src/engine/*.cpp src/engine/**/*.cpp)
|
||||||
add_library(EXCEPTION OBJECT util/osrm_exception.cpp)
|
|
||||||
add_library(MERCATOR OBJECT util/mercator.cpp)
|
|
||||||
add_library(ANGLE OBJECT util/compute_angle.cpp)
|
|
||||||
|
|
||||||
set(ExtractorSources extract.cpp ${ExtractorGlob})
|
add_library(UTIL OBJECT ${UtilGlob})
|
||||||
add_executable(osrm-extract ${ExtractorSources} $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:IMPORT> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR>)
|
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)
|
set_target_properties(UTIL PROPERTIES LINKER_LANGUAGE CXX)
|
||||||
add_library(COMPRESSEDEDGE OBJECT data_structures/compressed_edge_container.cpp)
|
|
||||||
add_library(GRAPHCOMPRESSOR OBJECT algorithms/graph_compressor.cpp)
|
|
||||||
|
|
||||||
file(GLOB PrepareGlob contractor/*.cpp data_structures/hilbert_value.cpp {RestrictionMapGlob})
|
add_executable(osrm-extract src/tools/extract.cpp)
|
||||||
set(PrepareSources prepare.cpp ${PrepareGlob})
|
add_executable(osrm-contract src/tools/contract.cpp)
|
||||||
add_executable(osrm-prepare ${PrepareSources} $<TARGET_OBJECTS:ANGLE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<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-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)
|
if(ENABLE_GOLD_LINKER)
|
||||||
file(GLOB DescriptorGlob descriptors/*.cpp)
|
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||||
file(GLOB DatastructureGlob data_structures/search_engine_data.cpp data_structures/route_parameters.cpp util/bearing.cpp)
|
if("${LD_VERSION}" MATCHES "GNU gold")
|
||||||
file(GLOB CoordinateGlob data_structures/coordinate.cpp algorithms/coordinate_calculation.cpp)
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
|
||||||
file(GLOB AlgorithmGlob algorithms/polyline_compressor.cpp algorithms/polyline_formatter.cpp algorithms/douglas_peucker.cpp)
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
|
||||||
file(GLOB HttpGlob server/http/*.cpp)
|
set(OSRM_LDFLAGS "${OSRM_LDFLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
|
||||||
file(GLOB LibOSRMGlob library/*.cpp)
|
message(STATUS "Using GNU gold as linker.")
|
||||||
file(GLOB DataStructureTestsGlob unit_tests/data_structures/*.cpp data_structures/hilbert_value.cpp)
|
|
||||||
file(GLOB AlgorithmTestsGlob unit_tests/algorithms/*.cpp algorithms/graph_compressor.cpp)
|
|
||||||
|
|
||||||
set(
|
# Issue 2785: check gold binutils version and don't use gc-sections for versions prior 2.25
|
||||||
OSRMSources
|
string(REGEX REPLACE ".*\\(GNU Binutils[^\\)0-9]+([0-9]+\\.[0-9]+)[^\\)]*\\).*" "\\1" GOLD_BINUTILS_VERSION "${LD_VERSION}")
|
||||||
${LibOSRMGlob}
|
if ("${GOLD_BINUTILS_VERSION}" VERSION_LESS "2.26")
|
||||||
${DescriptorGlob}
|
message(STATUS "Disabling gc-sections on gold binutils < 2.26, see: https://sourceware.org/bugzilla/show_bug.cgi?id=17639")
|
||||||
${DatastructureGlob}
|
set(LD_AVOID_GC_SECTIONS TRUE)
|
||||||
${AlgorithmGlob}
|
endif()
|
||||||
${HttpGlob}
|
else()
|
||||||
)
|
message(WARNING "GNU gold linker isn't available.")
|
||||||
|
set(ENABLE_GOLD_LINKER OFF)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(COORDINATE OBJECT ${CoordinateGlob})
|
# Explicitly set the build type to Release if no other type is specified
|
||||||
add_library(GITDESCRIPTION OBJECT util/git_sha.cpp)
|
# on the command line. Without this, cmake defaults to an unoptimized,
|
||||||
add_library(OSRM ${OSRMSources} $<TARGET_OBJECTS:ANGLE> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:RESTRICTION> $<TARGET_OBJECTS:PHANTOMNODE> $<TARGET_OBJECTS:EXCEPTION> $<TARGET_OBJECTS:MERCATOR> $<TARGET_OBJECTS:IMPORT>)
|
# non-debug build, which almost nobody wants.
|
||||||
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
add_library(FINGERPRINT OBJECT util/fingerprint.cpp)
|
message(STATUS "No build type specified, defaulting to Release")
|
||||||
add_dependencies(FINGERPRINT FingerPrintConfigure)
|
|
||||||
add_dependencies(OSRM FingerPrintConfigure)
|
|
||||||
set_target_properties(FINGERPRINT PROPERTIES LINKER_LANGUAGE CXX)
|
|
||||||
|
|
||||||
add_executable(osrm-routed routed.cpp ${ServerGlob} $<TARGET_OBJECTS:EXCEPTION>)
|
|
||||||
add_executable(osrm-datastore datastore.cpp $<TARGET_OBJECTS:COORDINATE> $<TARGET_OBJECTS:FINGERPRINT> $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION> $<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>)
|
|
||||||
|
|
||||||
# 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)
|
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
set(CMAKE_BUILD_TYPE Release)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
if(CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
message(STATUS "Configuring OSRM in debug mode")
|
message(STATUS "Configuring OSRM in debug mode")
|
||||||
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
|
elseif(CMAKE_BUILD_TYPE MATCHES Release)
|
||||||
message(STATUS "adding profiling flags")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
|
|
||||||
set(CMAKE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -fno-inline")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES Release)
|
|
||||||
message(STATUS "Configuring OSRM in release mode")
|
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")
|
||||||
|
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 OR CMAKE_BUILD_TYPE MATCHES MinRelSize OR CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
|
||||||
|
message(STATUS "Configuring release mode optimizations")
|
||||||
# Check if LTO is available
|
# Check if LTO is available
|
||||||
set(LTO_FLAGS "")
|
check_cxx_compiler_flag("-Wl,-flto" LTO_AVAILABLE)
|
||||||
check_cxx_compiler_flag("-flto" LTO_AVAILABLE)
|
|
||||||
if(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")
|
||||||
|
include(ProcessorCount)
|
||||||
|
ProcessorCount(NPROC)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto=${NPROC}")
|
||||||
|
else()
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flto")
|
||||||
|
endif()
|
||||||
set(CHECK_LTO_SRC "int main(){return 0;}")
|
set(CHECK_LTO_SRC "int main(){return 0;}")
|
||||||
check_cxx_source_compiles("${CHECK_LTO_SRC}" LTO_WORKS)
|
check_cxx_source_compiles("${CHECK_LTO_SRC}" LTO_WORKS)
|
||||||
if(LTO_WORKS)
|
if(LTO_WORKS)
|
||||||
message(STATUS "LTO working")
|
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()
|
else()
|
||||||
message(STATUS "LTO broken")
|
message(STATUS "LTO broken")
|
||||||
set(CMAKE_CXX_FLAGS "${OLD_CXX_FLAGS}")
|
set(CMAKE_CXX_FLAGS "${OLD_CXX_FLAGS}")
|
||||||
|
set(ENABLE_LTO Off)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Since gcc 4.9 the LTO format is non-standart ('slim'), so we need to use the build-in tools
|
# Since gcc 4.9 the LTO format is non-standart ('slim'), so we need to use the build-in tools
|
||||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND
|
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND
|
||||||
NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.9.0" AND NOT MINGW)
|
NOT "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "4.9.0" AND NOT MINGW)
|
||||||
message(STATUS "Using gcc specific binutils for LTO.")
|
find_program(GCC_AR gcc-ar)
|
||||||
set(CMAKE_AR "/usr/bin/gcc-ar")
|
find_program(GCC_RANLIB gcc-ranlib)
|
||||||
set(CMAKE_RANLIB "/usr/bin/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()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT WIN32)
|
if(UNIX AND NOT APPLE AND ENABLE_MASON AND (LTO_WORKS OR ENABLE_GOLD_LINKER))
|
||||||
add_definitions(-DBOOST_TEST_DYN_LINK)
|
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()
|
endif()
|
||||||
|
|
||||||
# Configuring compilers
|
# Configuring compilers
|
||||||
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
|
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
|
||||||
# using Clang
|
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")
|
||||||
# -Weverything -Wno-c++98-compat -Wno-shadow -Wno-exit-time-destructors
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wunreachable-code -pedantic -fPIC")
|
|
||||||
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
|
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
|
||||||
set(COLOR_FLAG "-fdiagnostics-color=auto")
|
set(COLOR_FLAG "-fdiagnostics-color=auto")
|
||||||
check_cxx_compiler_flag("-fdiagnostics-color=auto" HAS_COLOR_FLAG)
|
check_cxx_compiler_flag("-fdiagnostics-color=auto" HAS_COLOR_FLAG)
|
||||||
@@ -163,10 +294,9 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
|
|||||||
set(COLOR_FLAG "")
|
set(COLOR_FLAG "")
|
||||||
endif()
|
endif()
|
||||||
# using GCC
|
# using GCC
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -fPIC ${COLOR_FLAG}")
|
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
|
if(WIN32) # using mingw
|
||||||
add_definitions(-D_USE_MATH_DEFINES) # define M_PI, M_1_PI etc.
|
add_dependency_defines(-DWIN32)
|
||||||
add_definitions(-DWIN32)
|
|
||||||
set(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
|
set(OPTIONAL_SOCKET_LIBS ws2_32 wsock32)
|
||||||
endif()
|
endif()
|
||||||
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
|
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
|
||||||
@@ -174,23 +304,49 @@ elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
|
|||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -wd10237 -Wall -ipo -fPIC")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-intel -wd10237 -Wall -ipo -fPIC")
|
||||||
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
|
elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
|
||||||
# using Visual Studio C++
|
# using Visual Studio C++
|
||||||
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} date_time chrono zlib)
|
set(BOOST_COMPONENTS ${BOOST_COMPONENTS} zlib)
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
add_dependency_defines(-DBOOST_LIB_DIAGNOSTIC)
|
||||||
add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation
|
add_dependency_defines(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
add_definitions(-D_USE_MATH_DEFINES) # define M_PI
|
add_dependency_defines(-DNOMINMAX) # avoid min and max macros that can break compilation
|
||||||
add_definitions(-D_WIN32_WINNT=0x0501)
|
add_dependency_defines(-D_USE_MATH_DEFINES) #needed for M_PI with cmath.h
|
||||||
add_definitions(-DXML_STATIC)
|
add_dependency_defines(-D_WIN32_WINNT=0x0501)
|
||||||
|
add_dependency_defines(-DXML_STATIC)
|
||||||
find_library(ws2_32_LIBRARY_PATH ws2_32)
|
find_library(ws2_32_LIBRARY_PATH ws2_32)
|
||||||
target_link_libraries(osrm-extract wsock32 ws2_32)
|
target_link_libraries(osrm-extract wsock32 ws2_32)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Activate C++11
|
# Configuring linker
|
||||||
|
execute_process(COMMAND ${CMAKE_CXX_COMPILER} "-Wl,--version" ERROR_QUIET OUTPUT_VARIABLE LINKER_VERSION)
|
||||||
|
# For ld.gold and ld.bfs (the GNU linkers) we optimize hard
|
||||||
|
if("${LINKER_VERSION}" MATCHES "GNU gold" OR "${LINKER_VERSION}" MATCHES "GNU ld")
|
||||||
|
message(STATUS "Setting linker optimizations")
|
||||||
|
if(NOT (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC" 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
|
||||||
|
set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,--gc-sections")
|
||||||
|
endif()
|
||||||
|
# Default linker optimization flags
|
||||||
|
set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,-O1 -Wl,--hash-style=gnu -Wl,--sort-common")
|
||||||
|
|
||||||
|
else()
|
||||||
|
message(STATUS "Using unknown linker, not setting linker optimizations")
|
||||||
|
endif ()
|
||||||
|
set(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++1y
|
||||||
if(NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
|
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()
|
endif()
|
||||||
|
|
||||||
# Configuring other platform dependencies
|
# Configuring other platform dependencies
|
||||||
if(APPLE)
|
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")
|
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||||
message(STATUS "Set Architecture to x64 on OS X")
|
message(STATUS "Set Architecture to x64 on OS X")
|
||||||
exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION)
|
exec_program(uname ARGS -v OUTPUT_VARIABLE DARWIN_VERSION)
|
||||||
@@ -205,75 +361,182 @@ if(APPLE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
target_link_libraries(osrm-prepare rt)
|
set(MAYBE_RT_LIBRARY -lrt)
|
||||||
target_link_libraries(osrm-datastore rt)
|
|
||||||
target_link_libraries(OSRM rt)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#Check Boost
|
# Disallow deprecated protozero APIs
|
||||||
set(BOOST_MIN_VERSION "1.49.0")
|
add_definitions(-DPROTOZERO_STRICT_API)
|
||||||
find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS ${BOOST_COMPONENTS} REQUIRED)
|
|
||||||
if(NOT Boost_FOUND)
|
|
||||||
message(FATAL_ERROR "Fatal error: Boost (version >= 1.49.0) required.\n")
|
|
||||||
endif()
|
|
||||||
include_directories(${Boost_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
target_link_libraries(OSRM ${Boost_LIBRARIES})
|
|
||||||
target_link_libraries(osrm-extract ${Boost_LIBRARIES})
|
|
||||||
target_link_libraries(osrm-prepare ${Boost_LIBRARIES})
|
|
||||||
target_link_libraries(osrm-routed ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
|
|
||||||
target_link_libraries(osrm-datastore ${Boost_LIBRARIES})
|
|
||||||
target_link_libraries(datastructure-tests ${Boost_LIBRARIES})
|
|
||||||
target_link_libraries(algorithm-tests ${Boost_LIBRARIES} ${OPTIONAL_SOCKET_LIBS} OSRM)
|
|
||||||
target_link_libraries(rtree-bench ${Boost_LIBRARIES})
|
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
target_link_libraries(osrm-extract ${CMAKE_THREAD_LIBS_INIT})
|
|
||||||
target_link_libraries(osrm-datastore ${CMAKE_THREAD_LIBS_INIT})
|
# if mason is enabled no find_package calls are made
|
||||||
target_link_libraries(osrm-prepare ${CMAKE_THREAD_LIBS_INIT})
|
# to ensure that we are only compiling and linking against
|
||||||
target_link_libraries(OSRM ${CMAKE_THREAD_LIBS_INIT})
|
# fully portable mason packages
|
||||||
target_link_libraries(datastructure-tests ${CMAKE_THREAD_LIBS_INIT})
|
if(ENABLE_MASON)
|
||||||
target_link_libraries(algorithm-tests ${CMAKE_THREAD_LIBS_INIT})
|
message(STATUS "Installing dependencies via mason")
|
||||||
target_link_libraries(rtree-bench ${CMAKE_THREAD_LIBS_INIT})
|
|
||||||
|
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})
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
else()
|
||||||
|
|
||||||
|
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)
|
find_package(TBB REQUIRED)
|
||||||
|
add_dependency_includes(${TBB_INCLUDE_DIR})
|
||||||
if(WIN32 AND CMAKE_BUILD_TYPE MATCHES Debug)
|
if(WIN32 AND CMAKE_BUILD_TYPE MATCHES Debug)
|
||||||
set(TBB_LIBRARIES ${TBB_DEBUG_LIBRARIES})
|
set(TBB_LIBRARIES ${TBB_DEBUG_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries(osrm-datastore ${TBB_LIBRARIES})
|
|
||||||
target_link_libraries(osrm-extract ${TBB_LIBRARIES})
|
|
||||||
target_link_libraries(osrm-prepare ${TBB_LIBRARIES})
|
|
||||||
target_link_libraries(osrm-routed ${TBB_LIBRARIES})
|
|
||||||
target_link_libraries(datastructure-tests ${TBB_LIBRARIES})
|
|
||||||
target_link_libraries(algorithm-tests ${TBB_LIBRARIES})
|
|
||||||
target_link_libraries(rtree-bench ${TBB_LIBRARIES})
|
|
||||||
include_directories(${TBB_INCLUDE_DIR})
|
|
||||||
|
|
||||||
find_package( Luabind REQUIRED )
|
|
||||||
include(check_luabind)
|
|
||||||
|
|
||||||
include_directories(${LUABIND_INCLUDE_DIR})
|
|
||||||
target_link_libraries(osrm-extract ${LUABIND_LIBRARY})
|
|
||||||
target_link_libraries(osrm-prepare ${LUABIND_LIBRARY})
|
|
||||||
|
|
||||||
if(LUAJIT_FOUND)
|
|
||||||
target_link_libraries(osrm-extract ${LUAJIT_LIBRARIES})
|
|
||||||
target_link_libraries(osrm-prepare ${LUAJIT_LIBRARIES})
|
|
||||||
else()
|
|
||||||
target_link_libraries(osrm-extract ${LUA_LIBRARY})
|
|
||||||
target_link_libraries(osrm-prepare ${LUA_LIBRARY})
|
|
||||||
endif()
|
|
||||||
include_directories(${LUA_INCLUDE_DIR})
|
|
||||||
|
|
||||||
find_package(EXPAT REQUIRED)
|
find_package(EXPAT REQUIRED)
|
||||||
include_directories(${EXPAT_INCLUDE_DIRS})
|
add_dependency_includes(${EXPAT_INCLUDE_DIRS})
|
||||||
target_link_libraries(osrm-extract ${EXPAT_LIBRARIES})
|
|
||||||
|
|
||||||
find_package(STXXL REQUIRED)
|
find_package(STXXL REQUIRED)
|
||||||
include_directories(${STXXL_INCLUDE_DIR})
|
add_dependency_includes(${STXXL_INCLUDE_DIR})
|
||||||
target_link_libraries(OSRM ${STXXL_LIBRARY})
|
|
||||||
target_link_libraries(osrm-extract ${STXXL_LIBRARY})
|
find_package(BZip2 REQUIRED)
|
||||||
target_link_libraries(osrm-prepare ${STXXL_LIBRARY})
|
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()
|
||||||
|
|
||||||
|
# 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()
|
||||||
|
|
||||||
|
# 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)
|
set(OpenMP_FIND_QUIETLY ON)
|
||||||
find_package(OpenMP)
|
find_package(OpenMP)
|
||||||
@@ -282,87 +545,222 @@ if(OPENMP_FOUND)
|
|||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(BZip2 REQUIRED)
|
add_definitions(${OSRM_DEFINES})
|
||||||
include_directories(${BZIP_INCLUDE_DIRS})
|
include_directories(SYSTEM ${DEPENDENCIES_INCLUDE_DIRS})
|
||||||
target_link_libraries(osrm-extract ${BZIP2_LIBRARIES})
|
|
||||||
|
|
||||||
find_package(ZLIB REQUIRED)
|
set(BOOST_BASE_LIBRARIES
|
||||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
${Boost_DATE_TIME_LIBRARY}
|
||||||
target_link_libraries(osrm-extract ${ZLIB_LIBRARY})
|
${Boost_CHRONO_LIBRARY}
|
||||||
target_link_libraries(osrm-routed ${ZLIB_LIBRARY})
|
${Boost_FILESYSTEM_LIBRARY}
|
||||||
|
${Boost_IOSTREAMS_LIBRARY}
|
||||||
|
${Boost_THREAD_LIBRARY}
|
||||||
|
${Boost_SYSTEM_LIBRARY})
|
||||||
|
|
||||||
if (ENABLE_JSON_LOGGING)
|
set(BOOST_ENGINE_LIBRARIES
|
||||||
message(STATUS "Enabling json logging")
|
${Boost_ZLIB_LIBRARY}
|
||||||
add_definitions(-DENABLE_JSON_LOGGING)
|
${Boost_REGEX_LIBRARY}
|
||||||
endif()
|
${BOOST_BASE_LIBRARIES})
|
||||||
|
|
||||||
if(WITH_TOOLS OR BUILD_TOOLS)
|
# Binaries
|
||||||
message(STATUS "Activating OSRM internal tools")
|
target_link_libraries(osrm-datastore osrm_store ${Boost_PROGRAM_OPTIONS_LIBRARY})
|
||||||
find_package(GDAL)
|
target_link_libraries(osrm-extract osrm_extract ${Boost_PROGRAM_OPTIONS_LIBRARY})
|
||||||
if(GDAL_FOUND)
|
target_link_libraries(osrm-contract osrm_contract ${Boost_PROGRAM_OPTIONS_LIBRARY})
|
||||||
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-routed osrm ${Boost_PROGRAM_OPTIONS_LIBRARY} ${OPTIONAL_SOCKET_LIBS} ${ZLIB_LIBRARY})
|
||||||
target_link_libraries(osrm-components ${TBB_LIBRARIES})
|
|
||||||
include_directories(${GDAL_INCLUDE_DIR})
|
set(EXTRACTOR_LIBRARIES
|
||||||
target_link_libraries(
|
${BZIP2_LIBRARIES}
|
||||||
osrm-components
|
${Boost_REGEX_LIBRARY}
|
||||||
${GDAL_LIBRARIES} ${Boost_LIBRARIES})
|
${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)
|
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:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER>)
|
|
||||||
target_link_libraries(osrm-io-benchmark ${Boost_LIBRARIES})
|
|
||||||
add_executable(osrm-unlock-all tools/unlock_all_mutexes.cpp $<TARGET_OBJECTS:GITDESCRIPTION> $<TARGET_OBJECTS:LOGGER> $<TARGET_OBJECTS:EXCEPTION>)
|
|
||||||
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:GITDESCRIPTION> $<TARGET_OBJECTS:EXCEPTION>)
|
|
||||||
target_link_libraries(osrm-springclean ${Boost_LIBRARIES})
|
|
||||||
|
|
||||||
install(TARGETS osrm-cli DESTINATION bin)
|
if(BUILD_TOOLS)
|
||||||
|
message(STATUS "Activating OSRM internal tools")
|
||||||
|
add_executable(osrm-io-benchmark src/tools/io-benchmark.cpp $<TARGET_OBJECTS:UTIL>)
|
||||||
|
target_link_libraries(osrm-io-benchmark ${BOOST_BASE_LIBRARIES})
|
||||||
|
|
||||||
install(TARGETS osrm-io-benchmark DESTINATION bin)
|
install(TARGETS osrm-io-benchmark DESTINATION bin)
|
||||||
install(TARGETS osrm-unlock-all DESTINATION bin)
|
|
||||||
install(TARGETS osrm-check-hsgr DESTINATION bin)
|
find_package(Shapefile) # package libshp-dev
|
||||||
install(TARGETS osrm-springclean DESTINATION bin)
|
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()
|
endif()
|
||||||
|
|
||||||
file(GLOB InstallGlob include/osrm/*.hpp library/osrm.hpp)
|
if (ENABLE_ASSERTIONS)
|
||||||
file(GLOB VariantGlob third_party/variant/*.hpp)
|
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
|
# 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
|
# (i.e., from /usr/local/bin/) the linker can find library dependencies. For
|
||||||
# more info see http://www.cmake.org/Wiki/CMake_RPATH_handling
|
# 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-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-datastore PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
|
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||||
|
|
||||||
install(FILES ${InstallGlob} DESTINATION include/osrm)
|
file(GLOB VariantGlob third_party/variant/include/mapbox/*.hpp)
|
||||||
install(FILES ${VariantGlob} DESTINATION include/variant)
|
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-extract DESTINATION bin)
|
||||||
install(TARGETS osrm-prepare DESTINATION bin)
|
install(TARGETS osrm-contract DESTINATION bin)
|
||||||
install(TARGETS osrm-datastore DESTINATION bin)
|
install(TARGETS osrm-datastore DESTINATION bin)
|
||||||
install(TARGETS osrm-routed DESTINATION bin)
|
install(TARGETS osrm-routed DESTINATION bin)
|
||||||
install(TARGETS OSRM DESTINATION lib)
|
install(TARGETS osrm DESTINATION lib)
|
||||||
list(GET Boost_LIBRARIES 1 BOOST_LIBRARY_FIRST)
|
install(TARGETS osrm_extract DESTINATION lib)
|
||||||
get_filename_component(BOOST_LIBRARY_LISTING "${BOOST_LIBRARY_FIRST}" PATH)
|
install(TARGETS osrm_contract DESTINATION lib)
|
||||||
set(BOOST_LIBRARY_LISTING "-L${BOOST_LIBRARY_LISTING}")
|
install(TARGETS osrm_store DESTINATION lib)
|
||||||
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()
|
|
||||||
|
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pkgconfig.in libosrm.pc @ONLY)
|
|
||||||
install(FILES ${PROJECT_BINARY_DIR}/libosrm.pc DESTINATION lib/pkgconfig)
|
|
||||||
|
|
||||||
if(BUILD_DEBIAN_PACKAGE)
|
# Install profiles and support library to /usr/local/share/osrm/profiles by default
|
||||||
include(CPackDebianConfig)
|
set(DefaultProfilesDir profiles)
|
||||||
|
install(DIRECTORY ${DefaultProfilesDir} DESTINATION share/osrm)
|
||||||
|
|
||||||
|
# Setup exporting variables for pkgconfig and subproject
|
||||||
|
#
|
||||||
|
|
||||||
|
if(BUILD_PACKAGE)
|
||||||
|
include(CPackConfig)
|
||||||
include(CPack)
|
include(CPack)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
# 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()
|
||||||
|
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.
|
||||||
|
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
PROJECT_NAME = "Project OSRM"
|
||||||
|
PROJECT_BRIEF = "Open Source Routing Machine"
|
||||||
|
BUILTIN_STL_SUPPORT = YES
|
||||||
|
|
||||||
|
EXTRACT_ALL = YES
|
||||||
|
EXTRACT_PRIVATE = YES
|
||||||
|
EXTRACT_PACKAGE = YES
|
||||||
|
EXTRACT_STATIC = YES
|
||||||
|
EXTRACT_LOCAL_CLASSES = YES
|
||||||
|
EXTRACT_ANON_NSPACES = YES
|
||||||
|
|
||||||
|
QUIET = YES
|
||||||
|
|
||||||
|
INPUT = @CMAKE_CURRENT_SOURCE_DIR@
|
||||||
|
USE_MDFILE_AS_MAINPAGE = @CMAKE_CURRENT_SOURCE_DIR@/README.md
|
||||||
|
FILE_PATTERNS = *.h *.hpp *.c *.cc *.cpp *.md
|
||||||
|
RECURSIVE = YES
|
||||||
|
|
||||||
|
EXCLUDE = @CMAKE_CURRENT_SOURCE_DIR@/third_party \
|
||||||
|
@CMAKE_CURRENT_SOURCE_DIR@/build \
|
||||||
|
@CMAKE_CURRENT_SOURCE_DIR@/node_modules \
|
||||||
|
@CMAKE_CURRENT_SOURCE_DIR@/unit_tests \
|
||||||
|
@CMAKE_CURRENT_SOURCE_DIR@/benchmarks \
|
||||||
|
@CMAKE_CURRENT_SOURCE_DIR@/features
|
||||||
|
|
||||||
|
SOURCE_BROWSER = YES
|
||||||
|
|
||||||
|
CLANG_ASSISTED_PARSING = NO
|
||||||
|
|
||||||
|
HTML_COLORSTYLE_HUE = 217
|
||||||
|
HTML_COLORSTYLE_SAT = 71
|
||||||
|
HTML_COLORSTYLE_GAMMA = 50
|
||||||
|
|
||||||
|
GENERATE_TREEVIEW = YES
|
||||||
|
|
||||||
|
HAVE_DOT = @DOXYGEN_DOT_FOUND@
|
||||||
|
CALL_GRAPH = YES
|
||||||
|
CALLER_GRAPH = YES
|
||||||
|
|
||||||
|
DOT_IMAGE_FORMAT = svg
|
||||||
|
INTERACTIVE_SVG = YES
|
||||||
|
DOT_GRAPH_MAX_NODES = 500
|
||||||
|
DOT_TRANSPARENT = YES
|
||||||
|
DOT_MULTI_TARGETS = YES
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
source "http://rubygems.org"
|
|
||||||
|
|
||||||
gem "cucumber"
|
|
||||||
gem "rake"
|
|
||||||
gem "osmlib-base"
|
|
||||||
gem "sys-proctable"
|
|
||||||
gem "rspec-expectations"
|
|
||||||
@@ -1,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.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
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 |
|
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
|
||||||
| Linux | master | [](https://travis-ci.org/Project-OSRM/osrm-backend) |
|
- Route - Finds the fastest route between coordinates
|
||||||
| Linux | develop | [](https://travis-ci.org/Project-OSRM/osrm-backend) |
|
- Table - Computes the duration of the fastest route between all pairs of supplied coordinates
|
||||||
| Windows | master/develop | [](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
|
- Match - Snaps noisy GPS traces to the road network in the most plausible way
|
||||||
| LUAbind fork | master | [](https://travis-ci.org/DennisOSRM/luabind) |
|
- 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
|
## 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
|
## References in publications
|
||||||
|
|
||||||
@@ -43,4 +109,3 @@ When using the code in a (scientific) publication, please cite
|
|||||||
address = {New York, NY, USA},
|
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 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 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 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 euclidean_distance(const FixedPointCoordinate &coordinate_1,
|
|
||||||
const FixedPointCoordinate &coordinate_2)
|
|
||||||
{
|
|
||||||
return euclidean_distance(coordinate_1.lat, coordinate_1.lon, coordinate_2.lat,
|
|
||||||
coordinate_2.lon);
|
|
||||||
}
|
|
||||||
|
|
||||||
float euclidean_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 =
|
|
||||||
euclidean_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
|
|
||||||
great_circle_distance(const int lat1, const int lon1, const int lat2, const int lon2);
|
|
||||||
|
|
||||||
double great_circle_distance(const FixedPointCoordinate &first_coordinate,
|
|
||||||
const FixedPointCoordinate &second_coordinate);
|
|
||||||
|
|
||||||
float euclidean_distance(const FixedPointCoordinate &first_coordinate,
|
|
||||||
const FixedPointCoordinate &second_coordinate);
|
|
||||||
|
|
||||||
float euclidean_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,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 "../contractor/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,91 +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 "../util/string_util.hpp"
|
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
#include <boost/archive/iterators/base64_from_binary.hpp>
|
|
||||||
#include <boost/archive/iterators/binary_from_base64.hpp>
|
|
||||||
#include <boost/archive/iterators/transform_width.hpp>
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <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)));
|
|
||||||
replaceAll(encoded, "+", "-");
|
|
||||||
replaceAll(encoded, "/", "_");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class ObjectT> static void DecodeFromBase64(const std::string &input, ObjectT &object)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::string encoded(input);
|
|
||||||
// replace "-" with "+" and "_" with "/"
|
|
||||||
replaceAll(encoded, "-", "+");
|
|
||||||
replaceAll(encoded, "_", "/");
|
|
||||||
|
|
||||||
std::copy(binary_t(encoded.begin()), binary_t(encoded.begin() + encoded.length()),
|
|
||||||
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,106 +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)
|
|
||||||
{
|
|
||||||
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
|
|
||||||
+63
-9
@@ -6,16 +6,41 @@ ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %~f0 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||||||
|
|
||||||
SET PROJECT_DIR=%CD%
|
SET PROJECT_DIR=%CD%
|
||||||
ECHO PROJECT_DIR^: %PROJECT_DIR%
|
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 ...
|
ECHO activating VS command prompt ...
|
||||||
SET PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%PATH%
|
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
|
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
|
||||||
|
|
||||||
ECHO platform^: %platform%
|
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
|
:: HARDCODE "x64" as it is uppercase on AppVeyor and download from S3 is case sensitive
|
||||||
SET DEPSPKG=osrm-deps-win-x64-14.0.7z
|
SET DEPSPKG=osrm-deps-win-x64-14.0.7z
|
||||||
|
|
||||||
:: local development
|
:: local development
|
||||||
|
ECHO.
|
||||||
ECHO LOCAL_DEV^: %LOCAL_DEV%
|
ECHO LOCAL_DEV^: %LOCAL_DEV%
|
||||||
IF NOT DEFINED LOCAL_DEV SET LOCAL_DEV=0
|
IF NOT DEFINED LOCAL_DEV SET LOCAL_DEV=0
|
||||||
IF DEFINED LOCAL_DEV IF %LOCAL_DEV% EQU 1 IF EXIST %DEPSPKG% ECHO skipping deps download && GOTO SKIPDL
|
IF DEFINED LOCAL_DEV IF %LOCAL_DEV% EQU 1 IF EXIST %DEPSPKG% ECHO skipping deps download && GOTO SKIPDL
|
||||||
@@ -31,27 +56,39 @@ IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
|||||||
|
|
||||||
IF EXIST osrm-deps ECHO deleting osrm-deps... && RD /S /Q osrm-deps
|
IF EXIST osrm-deps ECHO deleting osrm-deps... && RD /S /Q osrm-deps
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
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
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
|
||||||
7z -y x %DEPSPKG% | %windir%\system32\FIND "ing archive"
|
7z -y x %DEPSPKG% | %windir%\system32\FIND "ing archive"
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
|
||||||
|
::tree osrm-deps
|
||||||
|
|
||||||
MKDIR build
|
MKDIR build
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
cd build
|
cd build
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||||
|
|
||||||
SET OSRMDEPSDIR=%PROJECT_DIR%\osrm-deps
|
SET OSRMDEPSDIR=%PROJECT_DIR%/osrm-deps
|
||||||
set PREFIX=%OSRMDEPSDIR%/libs
|
set PREFIX=%OSRMDEPSDIR%/libs
|
||||||
set BOOST_ROOT=%OSRMDEPSDIR%/boost
|
set BOOST_ROOT=%OSRMDEPSDIR%/boost
|
||||||
|
set BOOST_LIBRARYDIR=%BOOST_ROOT%/lib
|
||||||
set TBB_INSTALL_DIR=%OSRMDEPSDIR%/tbb
|
set TBB_INSTALL_DIR=%OSRMDEPSDIR%/tbb
|
||||||
set TBB_ARCH_PLATFORM=intel64/vc14
|
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 ....
|
ECHO calling cmake ....
|
||||||
cmake .. ^
|
cmake .. ^
|
||||||
-G "Visual Studio 14 Win64" ^
|
-G "Visual Studio 14 2015 Win64" ^
|
||||||
-DBOOST_ROOT=%BOOST_ROOT% ^
|
-DBOOST_ROOT=%BOOST_ROOT% ^
|
||||||
|
-DBOOST_LIBRARYDIR=%BOOST_LIBRARYDIR% ^
|
||||||
-DBoost_ADDITIONAL_VERSIONS=1.58 ^
|
-DBoost_ADDITIONAL_VERSIONS=1.58 ^
|
||||||
-DBoost_USE_MULTITHREADED=ON ^
|
-DBoost_USE_MULTITHREADED=ON ^
|
||||||
-DBoost_USE_STATIC_LIBS=ON ^
|
-DBoost_USE_STATIC_LIBS=ON ^
|
||||||
@@ -79,14 +116,31 @@ IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
|||||||
|
|
||||||
SET PATH=%PROJECT_DIR%\osrm-deps\libs\bin;%PATH%
|
SET PATH=%PROJECT_DIR%\osrm-deps\libs\bin;%PATH%
|
||||||
|
|
||||||
ECHO running datastructure-tests.exe ...
|
ECHO running extractor-tests.exe ...
|
||||||
%Configuration%\datastructure-tests.exe
|
unit_tests\%Configuration%\extractor-tests.exe
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
|
||||||
ECHO running algorithm-tests.exe ...
|
|
||||||
%Configuration%\algorithm-tests.exe
|
|
||||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
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 ==========
|
ECHO ========= CREATING PACKAGES ==========
|
||||||
|
|
||||||
CD %PROJECT_DIR%\build\%Configuration%
|
CD %PROJECT_DIR%\build\%Configuration%
|
||||||
|
|||||||
+15
-7
@@ -3,6 +3,9 @@ environment:
|
|||||||
- configuration: Release
|
- configuration: Release
|
||||||
# - configuration: Debug
|
# - configuration: Debug
|
||||||
|
|
||||||
|
install:
|
||||||
|
- ps: Install-Product node 6
|
||||||
|
|
||||||
# scripts that are called at very beginning, before repo cloning
|
# scripts that are called at very beginning, before repo cloning
|
||||||
init:
|
init:
|
||||||
- git config --global core.autocrlf input
|
- git config --global core.autocrlf input
|
||||||
@@ -17,7 +20,14 @@ platform: x64
|
|||||||
build_script:
|
build_script:
|
||||||
- CALL appveyor-build.bat
|
- 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:
|
artifacts:
|
||||||
- path: osrm_Release.zip
|
- path: osrm_Release.zip
|
||||||
@@ -25,6 +35,10 @@ artifacts:
|
|||||||
# - path: osrm_Debug.zip
|
# - path: osrm_Debug.zip
|
||||||
# name: osrm_Debug.zip
|
# name: osrm_Debug.zip
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
provider: FTP
|
provider: FTP
|
||||||
server:
|
server:
|
||||||
@@ -36,9 +50,3 @@ deploy:
|
|||||||
folder: /
|
folder: /
|
||||||
enable_ssl: true
|
enable_ssl: true
|
||||||
active_mode: false
|
active_mode: false
|
||||||
|
|
||||||
# notifications:
|
|
||||||
# - provider: HipChat
|
|
||||||
# auth_token:
|
|
||||||
# secure: boLE7BjcahdIUxv9jkN7U3F8iOASF+MkhtctlVoWJoo=
|
|
||||||
# room: Directions
|
|
||||||
|
|||||||
@@ -1,184 +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/query_node.hpp"
|
|
||||||
#include "../data_structures/shared_memory_vector_wrapper.hpp"
|
|
||||||
#include "../data_structures/static_rtree.hpp"
|
|
||||||
#include "../util/boost_filesystem_2_fix.hpp"
|
|
||||||
#include "../data_structures/edge_based_node.hpp"
|
|
||||||
|
|
||||||
#include <osrm/coordinate.hpp>
|
|
||||||
|
|
||||||
#include <random>
|
|
||||||
|
|
||||||
// Choosen by a fair W20 dice roll (this value is completely arbitrary)
|
|
||||||
constexpr unsigned RANDOM_SEED = 13;
|
|
||||||
constexpr int32_t WORLD_MIN_LAT = -90 * COORDINATE_PRECISION;
|
|
||||||
constexpr int32_t WORLD_MAX_LAT = 90 * COORDINATE_PRECISION;
|
|
||||||
constexpr int32_t WORLD_MIN_LON = -180 * COORDINATE_PRECISION;
|
|
||||||
constexpr int32_t WORLD_MAX_LON = 180 * COORDINATE_PRECISION;
|
|
||||||
|
|
||||||
using RTreeLeaf = EdgeBasedNode;
|
|
||||||
using FixedPointCoordinateListPtr = std::shared_ptr<std::vector<FixedPointCoordinate>>;
|
|
||||||
using BenchStaticRTree = StaticRTree<RTreeLeaf, ShM<FixedPointCoordinate, false>::vector, false>;
|
|
||||||
|
|
||||||
FixedPointCoordinateListPtr LoadCoordinates(const boost::filesystem::path &nodes_file)
|
|
||||||
{
|
|
||||||
boost::filesystem::ifstream nodes_input_stream(nodes_file, std::ios::binary);
|
|
||||||
|
|
||||||
QueryNode current_node;
|
|
||||||
unsigned 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Benchmark(BenchStaticRTree &rtree, unsigned num_queries)
|
|
||||||
{
|
|
||||||
std::mt19937 mt_rand(RANDOM_SEED);
|
|
||||||
std::uniform_int_distribution<> lat_udist(WORLD_MIN_LAT, WORLD_MAX_LAT);
|
|
||||||
std::uniform_int_distribution<> lon_udist(WORLD_MIN_LON, WORLD_MAX_LON);
|
|
||||||
std::vector<FixedPointCoordinate> queries;
|
|
||||||
for (unsigned i = 0; i < num_queries; i++)
|
|
||||||
{
|
|
||||||
queries.emplace_back(FixedPointCoordinate(lat_udist(mt_rand), lon_udist(mt_rand)));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const unsigned num_results = 5;
|
|
||||||
std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results
|
|
||||||
<< " phantom nodes"
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
TIMER_START(query_phantom);
|
|
||||||
std::vector<PhantomNode> phantom_node_vector;
|
|
||||||
for (const auto &q : queries)
|
|
||||||
{
|
|
||||||
phantom_node_vector.clear();
|
|
||||||
rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 3, num_results);
|
|
||||||
phantom_node_vector.clear();
|
|
||||||
rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 17, num_results);
|
|
||||||
}
|
|
||||||
TIMER_STOP(query_phantom);
|
|
||||||
|
|
||||||
std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries
|
|
||||||
<< " queries."
|
|
||||||
<< "\n";
|
|
||||||
std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query."
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
std::cout << "#### LocateClosestEndPointForCoordinate"
|
|
||||||
<< "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
TIMER_START(query_endpoint);
|
|
||||||
FixedPointCoordinate result;
|
|
||||||
for (const auto &q : queries)
|
|
||||||
{
|
|
||||||
rtree.LocateClosestEndPointForCoordinate(q, result, 3);
|
|
||||||
}
|
|
||||||
TIMER_STOP(query_endpoint);
|
|
||||||
|
|
||||||
std::cout << "Took " << TIMER_MSEC(query_endpoint) << " msec for " << num_queries << " queries."
|
|
||||||
<< "\n";
|
|
||||||
std::cout << TIMER_MSEC(query_endpoint) / ((double)num_queries) << " msec/query."
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
std::cout << "#### FindPhantomNodeForCoordinate"
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
TIMER_START(query_node);
|
|
||||||
for (const auto &q : queries)
|
|
||||||
{
|
|
||||||
PhantomNode phantom;
|
|
||||||
rtree.FindPhantomNodeForCoordinate(q, phantom, 3);
|
|
||||||
}
|
|
||||||
TIMER_STOP(query_node);
|
|
||||||
|
|
||||||
std::cout << "Took " << TIMER_MSEC(query_node) << " msec for " << num_queries << " queries."
|
|
||||||
<< "\n";
|
|
||||||
std::cout << TIMER_MSEC(query_node) / ((double)num_queries) << " msec/query."
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
{
|
|
||||||
const unsigned num_results = 1;
|
|
||||||
std::cout << "#### IncrementalFindPhantomNodeForCoordinate : " << num_results
|
|
||||||
<< " phantom nodes"
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
TIMER_START(query_phantom);
|
|
||||||
std::vector<PhantomNode> phantom_node_vector;
|
|
||||||
for (const auto &q : queries)
|
|
||||||
{
|
|
||||||
phantom_node_vector.clear();
|
|
||||||
rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 3, num_results);
|
|
||||||
phantom_node_vector.clear();
|
|
||||||
rtree.IncrementalFindPhantomNodeForCoordinate(q, phantom_node_vector, 17, num_results);
|
|
||||||
}
|
|
||||||
TIMER_STOP(query_phantom);
|
|
||||||
|
|
||||||
std::cout << "Took " << TIMER_MSEC(query_phantom) << " msec for " << num_queries
|
|
||||||
<< " queries."
|
|
||||||
<< "\n";
|
|
||||||
std::cout << TIMER_MSEC(query_phantom) / ((double)num_queries) << " msec/query."
|
|
||||||
<< "\n";
|
|
||||||
|
|
||||||
std::cout << "#### LocateClosestEndPointForCoordinate"
|
|
||||||
<< "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc < 4)
|
|
||||||
{
|
|
||||||
std::cout << "./rtree-bench file.ramIndex file.fileIndx file.nodes"
|
|
||||||
<< "\n";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ramPath = argv[1];
|
|
||||||
const char *filePath = argv[2];
|
|
||||||
const char *nodesPath = argv[3];
|
|
||||||
|
|
||||||
auto coords = LoadCoordinates(nodesPath);
|
|
||||||
|
|
||||||
BenchStaticRTree rtree(ramPath, filePath, coords);
|
|
||||||
|
|
||||||
Benchmark(rtree, 10000);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
+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
|
FOR /F "tokens=*" %%i in ('git rev-parse --abbrev-ref HEAD') do SET APPVEYOR_REPO_BRANCH=%%i
|
||||||
ECHO APPVEYOR_REPO_BRANCH^: %APPVEYOR_REPO_BRANCH%
|
ECHO APPVEYOR_REPO_BRANCH^: %APPVEYOR_REPO_BRANCH%
|
||||||
|
|
||||||
SET PATH=C:\mb\windows-builds-64\tmp-bin\cmake-3.1.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%
|
SET PATH=C:\Program Files\7-Zip;%PATH%
|
||||||
|
|
||||||
powershell Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force
|
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
|
FIND_LIBRARY(STXXL_LIBRARY
|
||||||
NAMES stxxl
|
NAMES stxxl stxxl_debug
|
||||||
HINTS
|
HINTS
|
||||||
$ENV{STXXL_DIR}
|
$ENV{STXXL_DIR}
|
||||||
PATH_SUFFIXES lib64 lib
|
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)
|
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}")
|
STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}")
|
||||||
set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}")
|
set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}")
|
||||||
|
message(STATUS "TBB interface version: ${TBB_INTERFACE_VERSION}")
|
||||||
endif (TBB_FOUND)
|
endif (TBB_FOUND)
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
set(OLDFILE ${SOURCE_DIR}/util/fingerprint_impl.hpp)
|
|
||||||
set(NEWFILE ${OLDFILE}.tmp)
|
|
||||||
set(INFILE ${OLDFILE}.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,123 +0,0 @@
|
|||||||
# - Returns a version string from Git
|
|
||||||
#
|
|
||||||
# These functions force a re-configure on each git commit so that you can
|
|
||||||
# trust the values of the variables in your build system.
|
|
||||||
#
|
|
||||||
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])
|
|
||||||
#
|
|
||||||
# Returns the refspec and sha hash of the current head revision
|
|
||||||
#
|
|
||||||
# git_describe(<var> [<additional arguments to git describe> ...])
|
|
||||||
#
|
|
||||||
# Returns the results of git describe on the source tree, and adjusting
|
|
||||||
# the output so that it tests false if an error occurs.
|
|
||||||
#
|
|
||||||
# git_get_exact_tag(<var> [<additional arguments to git describe> ...])
|
|
||||||
#
|
|
||||||
# Returns the results of git describe --exact-match on the source tree,
|
|
||||||
# and adjusting the output so that it tests false if there was no exact
|
|
||||||
# matching tag.
|
|
||||||
#
|
|
||||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
|
||||||
#
|
|
||||||
# Original Author:
|
|
||||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
|
||||||
# http://academic.cleardefinition.com
|
|
||||||
# Iowa State University HCI Graduate Program/VRAC
|
|
||||||
#
|
|
||||||
# Copyright Iowa State University 2009-2010.
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
# http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
if(__get_git_revision_description)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(__get_git_revision_description YES)
|
|
||||||
|
|
||||||
# We must run the following at "include" time, not at function call time,
|
|
||||||
# to find the path to this module rather than the path to a calling list file
|
|
||||||
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
|
||||||
|
|
||||||
function(get_git_head_revision _refspecvar _hashvar)
|
|
||||||
set(GIT_PARENT_DIR "${CMAKE_SOURCE_DIR}")
|
|
||||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
|
||||||
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories
|
|
||||||
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}")
|
|
||||||
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)
|
|
||||||
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)
|
|
||||||
# We have reached the root directory, we are not in git
|
|
||||||
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
|
|
||||||
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(GIT_DIR "${GIT_PARENT_DIR}/.git")
|
|
||||||
endwhile()
|
|
||||||
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data")
|
|
||||||
if(NOT EXISTS "${GIT_DATA}")
|
|
||||||
file(MAKE_DIRECTORY "${GIT_DATA}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT EXISTS "${GIT_DIR}/HEAD")
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
set(HEAD_FILE "${GIT_DATA}/HEAD")
|
|
||||||
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY)
|
|
||||||
|
|
||||||
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in"
|
|
||||||
"${GIT_DATA}/grabRef.cmake"
|
|
||||||
@ONLY)
|
|
||||||
include("${GIT_DATA}/grabRef.cmake")
|
|
||||||
|
|
||||||
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE)
|
|
||||||
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(git_describe _var)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
find_package(Git QUIET)
|
|
||||||
endif()
|
|
||||||
get_git_head_revision(refspec hash)
|
|
||||||
if(NOT GIT_FOUND)
|
|
||||||
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
if(NOT hash)
|
|
||||||
set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE)
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# TODO sanitize
|
|
||||||
#if((${ARGN}" MATCHES "&&") OR
|
|
||||||
# (ARGN MATCHES "||") OR
|
|
||||||
# (ARGN MATCHES "\\;"))
|
|
||||||
# message("Please report the following error to the project!")
|
|
||||||
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}")
|
|
||||||
#endif()
|
|
||||||
|
|
||||||
#message(STATUS "Arguments to execute_process: ${ARGN}")
|
|
||||||
|
|
||||||
execute_process(COMMAND
|
|
||||||
"${GIT_EXECUTABLE}"
|
|
||||||
describe
|
|
||||||
${hash}
|
|
||||||
${ARGN}
|
|
||||||
WORKING_DIRECTORY
|
|
||||||
"${CMAKE_SOURCE_DIR}"
|
|
||||||
RESULT_VARIABLE
|
|
||||||
res
|
|
||||||
OUTPUT_VARIABLE
|
|
||||||
out
|
|
||||||
ERROR_QUIET
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
if(NOT res EQUAL 0)
|
|
||||||
set(out "${out}-${res}-NOTFOUND")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(${_var} "${out}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(git_get_exact_tag _var)
|
|
||||||
git_describe(out --exact-match ${ARGN})
|
|
||||||
set(${_var} "${out}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#
|
|
||||||
# Internal file for GetGitRevisionDescription.cmake
|
|
||||||
#
|
|
||||||
# Requires CMake 2.6 or newer (uses the 'function' command)
|
|
||||||
#
|
|
||||||
# Original Author:
|
|
||||||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
|
||||||
# http://academic.cleardefinition.com
|
|
||||||
# Iowa State University HCI Graduate Program/VRAC
|
|
||||||
#
|
|
||||||
# Copyright Iowa State University 2009-2010.
|
|
||||||
# Distributed under the Boost Software License, Version 1.0.
|
|
||||||
# (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
# http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
set(HEAD_HASH)
|
|
||||||
|
|
||||||
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024)
|
|
||||||
|
|
||||||
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS)
|
|
||||||
if(HEAD_CONTENTS MATCHES "ref")
|
|
||||||
# named branch
|
|
||||||
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}")
|
|
||||||
if(EXISTS "@GIT_DIR@/${HEAD_REF}")
|
|
||||||
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
|
||||||
elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}")
|
|
||||||
configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY)
|
|
||||||
set(HEAD_HASH "${HEAD_REF}")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
# detached HEAD
|
|
||||||
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT HEAD_HASH)
|
|
||||||
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024)
|
|
||||||
string(STRIP "${HEAD_HASH}" HEAD_HASH)
|
|
||||||
endif()
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
INCLUDE (CheckCXXSourceCompiles)
|
|
||||||
unset(LUABIND_WORKS CACHE)
|
|
||||||
unset(LUABIND51_WORKS CACHE)
|
|
||||||
set (LUABIND_CHECK_SRC "#include \"lua.h\"\n#include <luabind/luabind.hpp>\n int main() { lua_State *myLuaState = luaL_newstate(); luabind::open(myLuaState); return 0;}")
|
|
||||||
set (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
|
db = None
|
||||||
if os.access(cache_file, os.R_OK) == 0:
|
if os.access(cache_file, os.R_OK) == 0:
|
||||||
db = load_db(sys.argv[1])
|
db = load_db(sys.argv[1])
|
||||||
f = open(cache_file, "wb")
|
with open(cache_file, "wb") as f:
|
||||||
pickle.dump(db, f)
|
pickle.dump(db, f)
|
||||||
f.close()
|
|
||||||
else:
|
else:
|
||||||
f = open(cache_file)
|
with open(cache_file) as f:
|
||||||
db = pickle.load(f)
|
db = pickle.load(f)
|
||||||
f.close()
|
|
||||||
|
|
||||||
if db and sys.argv[2] in db:
|
if db and sys.argv[2] in db:
|
||||||
for option in db[sys.argv[2]]:
|
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@
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
includedir=${prefix}/include/osrm
|
includedir=@PKGCONFIG_INCLUDE_DIR@
|
||||||
libdir=${prefix}/lib
|
libdir=@PKGCONFIG_LIBRARY_DIR@
|
||||||
|
|
||||||
Name: libOSRM
|
Name: libOSRM
|
||||||
Description: Project OSRM library
|
Description: Project OSRM library
|
||||||
Version: @GIT_DESCRIPTION@
|
Version: v@OSRM_VERSION@
|
||||||
Requires:
|
Requires:
|
||||||
Libs: -L${libdir} -lOSRM
|
Libs: -L${libdir} -losrm @PKGCONFIG_OSRM_LDFLAGS@
|
||||||
Libs.private: @BOOST_LIBRARY_LISTING@
|
Libs.private: @PKGCONFIG_OSRM_DEPENDENT_LIBRARIES@
|
||||||
Cflags: -I${includedir}
|
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
|
|
||||||
@@ -1,989 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2015, Project OSRM, Dennis Luxen, others
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright notice, this list
|
|
||||||
of conditions and the following disclaimer.
|
|
||||||
Redistributions in binary form must reproduce the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer in the documentation and/or
|
|
||||||
other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CONTRACTOR_HPP
|
|
||||||
#define CONTRACTOR_HPP
|
|
||||||
|
|
||||||
#include "../data_structures/binary_heap.hpp"
|
|
||||||
#include "../data_structures/deallocating_vector.hpp"
|
|
||||||
#include "../data_structures/dynamic_graph.hpp"
|
|
||||||
#include "../data_structures/percent.hpp"
|
|
||||||
#include "../data_structures/query_edge.hpp"
|
|
||||||
#include "../data_structures/xor_fast_hash.hpp"
|
|
||||||
#include "../data_structures/xor_fast_hash_storage.hpp"
|
|
||||||
#include "../util/integer_range.hpp"
|
|
||||||
#include "../util/simple_logger.hpp"
|
|
||||||
#include "../util/timing_util.hpp"
|
|
||||||
#include "../typedefs.h"
|
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
|
|
||||||
#include <stxxl/vector>
|
|
||||||
|
|
||||||
#include <tbb/enumerable_thread_specific.h>
|
|
||||||
#include <tbb/parallel_for.h>
|
|
||||||
#include <tbb/parallel_sort.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <limits>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class Contractor
|
|
||||||
{
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct ContractorEdgeData
|
|
||||||
{
|
|
||||||
ContractorEdgeData()
|
|
||||||
: distance(0), id(0), originalEdges(0), shortcut(0), forward(0), backward(0),
|
|
||||||
is_original_via_node_ID(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
ContractorEdgeData(unsigned distance,
|
|
||||||
unsigned original_edges,
|
|
||||||
unsigned id,
|
|
||||||
bool shortcut,
|
|
||||||
bool forward,
|
|
||||||
bool backward)
|
|
||||||
: distance(distance), id(id),
|
|
||||||
originalEdges(std::min((unsigned)1 << 28, original_edges)), shortcut(shortcut),
|
|
||||||
forward(forward), backward(backward), is_original_via_node_ID(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
unsigned distance;
|
|
||||||
unsigned id;
|
|
||||||
unsigned originalEdges : 28;
|
|
||||||
bool shortcut : 1;
|
|
||||||
bool forward : 1;
|
|
||||||
bool backward : 1;
|
|
||||||
bool is_original_via_node_ID : 1;
|
|
||||||
} data;
|
|
||||||
|
|
||||||
struct ContractorHeapData
|
|
||||||
{
|
|
||||||
short hop;
|
|
||||||
bool target;
|
|
||||||
ContractorHeapData() : hop(0), target(false) {}
|
|
||||||
ContractorHeapData(short h, bool t) : hop(h), target(t) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
using ContractorGraph = DynamicGraph<ContractorEdgeData>;
|
|
||||||
// using ContractorHeap = BinaryHeap<NodeID, NodeID, int, ContractorHeapData,
|
|
||||||
// ArrayStorage<NodeID, NodeID>
|
|
||||||
// >;
|
|
||||||
using ContractorHeap =
|
|
||||||
BinaryHeap<NodeID, NodeID, int, ContractorHeapData, XORFastHashStorage<NodeID, NodeID>>;
|
|
||||||
using ContractorEdge = ContractorGraph::InputEdge;
|
|
||||||
|
|
||||||
struct ContractorThreadData
|
|
||||||
{
|
|
||||||
ContractorHeap heap;
|
|
||||||
std::vector<ContractorEdge> inserted_edges;
|
|
||||||
std::vector<NodeID> neighbours;
|
|
||||||
explicit ContractorThreadData(NodeID nodes) : heap(nodes) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct NodePriorityData
|
|
||||||
{
|
|
||||||
int depth;
|
|
||||||
NodePriorityData() : depth(0) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ContractionStats
|
|
||||||
{
|
|
||||||
int edges_deleted_count;
|
|
||||||
int edges_added_count;
|
|
||||||
int original_edges_deleted_count;
|
|
||||||
int original_edges_added_count;
|
|
||||||
ContractionStats()
|
|
||||||
: edges_deleted_count(0), edges_added_count(0), original_edges_deleted_count(0),
|
|
||||||
original_edges_added_count(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RemainingNodeData
|
|
||||||
{
|
|
||||||
RemainingNodeData() : id(0), is_independent(false) {}
|
|
||||||
NodeID id : 31;
|
|
||||||
bool is_independent : 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ThreadDataContainer
|
|
||||||
{
|
|
||||||
explicit ThreadDataContainer(int number_of_nodes) : number_of_nodes(number_of_nodes) {}
|
|
||||||
|
|
||||||
inline ContractorThreadData *getThreadData()
|
|
||||||
{
|
|
||||||
bool exists = false;
|
|
||||||
auto &ref = data.local(exists);
|
|
||||||
if (!exists)
|
|
||||||
{
|
|
||||||
ref = std::make_shared<ContractorThreadData>(number_of_nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ref.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
int number_of_nodes;
|
|
||||||
using EnumerableThreadData =
|
|
||||||
tbb::enumerable_thread_specific<std::shared_ptr<ContractorThreadData>>;
|
|
||||||
EnumerableThreadData data;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
template <class ContainerT> Contractor(int nodes, ContainerT &input_edge_list)
|
|
||||||
{
|
|
||||||
std::vector<ContractorEdge> edges;
|
|
||||||
edges.reserve(input_edge_list.size() * 2);
|
|
||||||
|
|
||||||
const auto dend = input_edge_list.dend();
|
|
||||||
for (auto diter = input_edge_list.dbegin(); diter != dend; ++diter)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(diter->weight, 1)) > 0,
|
|
||||||
"edge distance < 1");
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (static_cast<unsigned int>(std::max(diter->weight, 1)) > 24 * 60 * 60 * 10)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write(logWARNING)
|
|
||||||
<< "Edge weight large -> "
|
|
||||||
<< static_cast<unsigned int>(std::max(diter->weight, 1)) << " : "
|
|
||||||
<< static_cast<unsigned int>(diter->source) << " -> " << static_cast<unsigned int>(diter->target);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
edges.emplace_back(diter->source, diter->target,
|
|
||||||
static_cast<unsigned int>(std::max(diter->weight, 1)), 1,
|
|
||||||
diter->edge_id, false, diter->forward ? true : false,
|
|
||||||
diter->backward ? true : false);
|
|
||||||
|
|
||||||
edges.emplace_back(diter->target, diter->source,
|
|
||||||
static_cast<unsigned int>(std::max(diter->weight, 1)), 1,
|
|
||||||
diter->edge_id, false, diter->backward ? true : false,
|
|
||||||
diter->forward ? true : false);
|
|
||||||
}
|
|
||||||
// clear input vector
|
|
||||||
input_edge_list.clear();
|
|
||||||
// FIXME not sure if we need this
|
|
||||||
edges.shrink_to_fit();
|
|
||||||
|
|
||||||
tbb::parallel_sort(edges.begin(), edges.end());
|
|
||||||
NodeID edge = 0;
|
|
||||||
for (NodeID i = 0; i < edges.size();)
|
|
||||||
{
|
|
||||||
const NodeID source = edges[i].source;
|
|
||||||
const NodeID target = edges[i].target;
|
|
||||||
const NodeID id = edges[i].data.id;
|
|
||||||
// remove eigenloops
|
|
||||||
if (source == target)
|
|
||||||
{
|
|
||||||
++i;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ContractorEdge forward_edge;
|
|
||||||
ContractorEdge reverse_edge;
|
|
||||||
forward_edge.source = reverse_edge.source = source;
|
|
||||||
forward_edge.target = reverse_edge.target = target;
|
|
||||||
forward_edge.data.forward = reverse_edge.data.backward = true;
|
|
||||||
forward_edge.data.backward = reverse_edge.data.forward = false;
|
|
||||||
forward_edge.data.shortcut = reverse_edge.data.shortcut = false;
|
|
||||||
forward_edge.data.id = reverse_edge.data.id = id;
|
|
||||||
forward_edge.data.originalEdges = reverse_edge.data.originalEdges = 1;
|
|
||||||
forward_edge.data.distance = reverse_edge.data.distance =
|
|
||||||
std::numeric_limits<int>::max();
|
|
||||||
// remove parallel edges
|
|
||||||
while (i < edges.size() && edges[i].source == source && edges[i].target == target)
|
|
||||||
{
|
|
||||||
if (edges[i].data.forward)
|
|
||||||
{
|
|
||||||
forward_edge.data.distance =
|
|
||||||
std::min(edges[i].data.distance, forward_edge.data.distance);
|
|
||||||
}
|
|
||||||
if (edges[i].data.backward)
|
|
||||||
{
|
|
||||||
reverse_edge.data.distance =
|
|
||||||
std::min(edges[i].data.distance, reverse_edge.data.distance);
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
// merge edges (s,t) and (t,s) into bidirectional edge
|
|
||||||
if (forward_edge.data.distance == reverse_edge.data.distance)
|
|
||||||
{
|
|
||||||
if ((int)forward_edge.data.distance != std::numeric_limits<int>::max())
|
|
||||||
{
|
|
||||||
forward_edge.data.backward = true;
|
|
||||||
edges[edge++] = forward_edge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // insert seperate edges
|
|
||||||
if (((int)forward_edge.data.distance) != std::numeric_limits<int>::max())
|
|
||||||
{
|
|
||||||
edges[edge++] = forward_edge;
|
|
||||||
}
|
|
||||||
if ((int)reverse_edge.data.distance != std::numeric_limits<int>::max())
|
|
||||||
{
|
|
||||||
edges[edge++] = reverse_edge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cout << "merged " << edges.size() - edge << " edges out of " << edges.size()
|
|
||||||
<< std::endl;
|
|
||||||
edges.resize(edge);
|
|
||||||
contractor_graph = std::make_shared<ContractorGraph>(nodes, edges);
|
|
||||||
edges.clear();
|
|
||||||
edges.shrink_to_fit();
|
|
||||||
|
|
||||||
BOOST_ASSERT(0 == edges.capacity());
|
|
||||||
// unsigned maxdegree = 0;
|
|
||||||
// NodeID highestNode = 0;
|
|
||||||
//
|
|
||||||
// for(unsigned i = 0; i < contractor_graph->GetNumberOfNodes(); ++i) {
|
|
||||||
// unsigned degree = contractor_graph->EndEdges(i) -
|
|
||||||
// contractor_graph->BeginEdges(i);
|
|
||||||
// if(degree > maxdegree) {
|
|
||||||
// maxdegree = degree;
|
|
||||||
// highestNode = i;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// SimpleLogger().Write() << "edges at node with id " << highestNode << " has degree
|
|
||||||
// " << maxdegree;
|
|
||||||
// for(unsigned i = contractor_graph->BeginEdges(highestNode); i <
|
|
||||||
// contractor_graph->EndEdges(highestNode); ++i) {
|
|
||||||
// SimpleLogger().Write() << " ->(" << highestNode << "," <<
|
|
||||||
// contractor_graph->GetTarget(i)
|
|
||||||
// << "); via: " << contractor_graph->GetEdgeData(i).via;
|
|
||||||
// }
|
|
||||||
|
|
||||||
std::cout << "contractor finished initalization" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
~Contractor() {}
|
|
||||||
|
|
||||||
void Run( double core_factor = 1.0 )
|
|
||||||
{
|
|
||||||
// for the preperation we can use a big grain size, which is much faster (probably cache)
|
|
||||||
constexpr size_t InitGrainSize = 100000;
|
|
||||||
constexpr size_t PQGrainSize = 100000;
|
|
||||||
// auto_partitioner will automatically increase the blocksize if we have
|
|
||||||
// a lot of data. It is *important* for the last loop iterations
|
|
||||||
// (which have a very small dataset) that it is devisible.
|
|
||||||
constexpr size_t IndependentGrainSize = 1;
|
|
||||||
constexpr size_t ContractGrainSize = 1;
|
|
||||||
constexpr size_t NeighboursGrainSize = 1;
|
|
||||||
constexpr size_t DeleteGrainSize = 1;
|
|
||||||
|
|
||||||
const NodeID number_of_nodes = contractor_graph->GetNumberOfNodes();
|
|
||||||
Percent p(number_of_nodes);
|
|
||||||
|
|
||||||
ThreadDataContainer thread_data_list(number_of_nodes);
|
|
||||||
|
|
||||||
NodeID number_of_contracted_nodes = 0;
|
|
||||||
std::vector<RemainingNodeData> remaining_nodes(number_of_nodes);
|
|
||||||
std::vector<float> node_priorities(number_of_nodes);
|
|
||||||
std::vector<NodePriorityData> node_data(number_of_nodes);
|
|
||||||
is_core_node.resize(number_of_nodes, false);
|
|
||||||
|
|
||||||
// initialize priorities in parallel
|
|
||||||
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, InitGrainSize),
|
|
||||||
[&remaining_nodes](const tbb::blocked_range<int> &range)
|
|
||||||
{
|
|
||||||
for (int x = range.begin(), end = range.end(); x != end; ++x)
|
|
||||||
{
|
|
||||||
remaining_nodes[x].id = x;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
std::cout << "initializing elimination PQ ..." << std::flush;
|
|
||||||
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, PQGrainSize),
|
|
||||||
[this, &node_priorities, &node_data, &thread_data_list](
|
|
||||||
const tbb::blocked_range<int> &range)
|
|
||||||
{
|
|
||||||
ContractorThreadData *data = thread_data_list.getThreadData();
|
|
||||||
for (int x = range.begin(), end = range.end(); x != end; ++x)
|
|
||||||
{
|
|
||||||
node_priorities[x] =
|
|
||||||
this->EvaluateNodePriority(data, &node_data[x], x);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
std::cout << "ok" << std::endl << "preprocessing " << number_of_nodes << " nodes ..."
|
|
||||||
<< std::flush;
|
|
||||||
|
|
||||||
bool flushed_contractor = false;
|
|
||||||
while (number_of_nodes > 2 && number_of_contracted_nodes < static_cast<NodeID>(number_of_nodes * core_factor) )
|
|
||||||
{
|
|
||||||
if (!flushed_contractor && (number_of_contracted_nodes > static_cast<NodeID>(number_of_nodes * 0.65 * core_factor)))
|
|
||||||
{
|
|
||||||
DeallocatingVector<ContractorEdge> new_edge_set; // this one is not explicitely
|
|
||||||
// cleared since it goes out of
|
|
||||||
// scope anywa
|
|
||||||
std::cout << " [flush " << number_of_contracted_nodes << " nodes] " << std::flush;
|
|
||||||
|
|
||||||
// Delete old heap data to free memory that we need for the coming operations
|
|
||||||
thread_data_list.data.clear();
|
|
||||||
|
|
||||||
// Create new priority array
|
|
||||||
std::vector<float> new_node_priority(remaining_nodes.size());
|
|
||||||
// this map gives the old IDs from the new ones, necessary to get a consistent graph
|
|
||||||
// at the end of contraction
|
|
||||||
orig_node_id_from_new_node_id_map.resize(remaining_nodes.size());
|
|
||||||
// this map gives the new IDs from the old ones, necessary to remap targets from the
|
|
||||||
// remaining graph
|
|
||||||
std::vector<NodeID> new_node_id_from_orig_id_map(number_of_nodes, UINT_MAX);
|
|
||||||
|
|
||||||
// build forward and backward renumbering map and remap ids in remaining_nodes and
|
|
||||||
// Priorities.
|
|
||||||
for (const auto new_node_id : osrm::irange<std::size_t>(0, remaining_nodes.size()))
|
|
||||||
{
|
|
||||||
// create renumbering maps in both directions
|
|
||||||
orig_node_id_from_new_node_id_map[new_node_id] = remaining_nodes[new_node_id].id;
|
|
||||||
new_node_id_from_orig_id_map[remaining_nodes[new_node_id].id] = new_node_id;
|
|
||||||
new_node_priority[new_node_id] =
|
|
||||||
node_priorities[remaining_nodes[new_node_id].id];
|
|
||||||
remaining_nodes[new_node_id].id = new_node_id;
|
|
||||||
}
|
|
||||||
// walk over all nodes
|
|
||||||
for (const auto i :
|
|
||||||
osrm::irange<std::size_t>(0, contractor_graph->GetNumberOfNodes()))
|
|
||||||
{
|
|
||||||
const NodeID source = i;
|
|
||||||
for (auto current_edge : contractor_graph->GetAdjacentEdgeRange(source))
|
|
||||||
{
|
|
||||||
ContractorGraph::EdgeData &data =
|
|
||||||
contractor_graph->GetEdgeData(current_edge);
|
|
||||||
const NodeID target = contractor_graph->GetTarget(current_edge);
|
|
||||||
if (SPECIAL_NODEID == new_node_id_from_orig_id_map[i])
|
|
||||||
{
|
|
||||||
external_edge_list.push_back({source, target, data});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// node is not yet contracted.
|
|
||||||
// add (renumbered) outgoing edges to new DynamicGraph.
|
|
||||||
ContractorEdge new_edge = {new_node_id_from_orig_id_map[source],
|
|
||||||
new_node_id_from_orig_id_map[target],
|
|
||||||
data};
|
|
||||||
|
|
||||||
new_edge.data.is_original_via_node_ID = true;
|
|
||||||
BOOST_ASSERT_MSG(UINT_MAX != new_node_id_from_orig_id_map[source],
|
|
||||||
"new source id not resolveable");
|
|
||||||
BOOST_ASSERT_MSG(UINT_MAX != new_node_id_from_orig_id_map[target],
|
|
||||||
"new target id not resolveable");
|
|
||||||
new_edge_set.push_back(new_edge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete map from old NodeIDs to new ones.
|
|
||||||
new_node_id_from_orig_id_map.clear();
|
|
||||||
new_node_id_from_orig_id_map.shrink_to_fit();
|
|
||||||
|
|
||||||
// Replace old priorities array by new one
|
|
||||||
node_priorities.swap(new_node_priority);
|
|
||||||
// Delete old node_priorities vector
|
|
||||||
new_node_priority.clear();
|
|
||||||
new_node_priority.shrink_to_fit();
|
|
||||||
// old Graph is removed
|
|
||||||
contractor_graph.reset();
|
|
||||||
|
|
||||||
// create new graph
|
|
||||||
std::sort(new_edge_set.begin(), new_edge_set.end());
|
|
||||||
contractor_graph =
|
|
||||||
std::make_shared<ContractorGraph>(remaining_nodes.size(), new_edge_set);
|
|
||||||
|
|
||||||
new_edge_set.clear();
|
|
||||||
flushed_contractor = true;
|
|
||||||
|
|
||||||
// INFO: MAKE SURE THIS IS THE LAST OPERATION OF THE FLUSH!
|
|
||||||
// reinitialize heaps and ThreadData objects with appropriate size
|
|
||||||
thread_data_list.number_of_nodes = contractor_graph->GetNumberOfNodes();
|
|
||||||
}
|
|
||||||
|
|
||||||
const int last = (int)remaining_nodes.size();
|
|
||||||
tbb::parallel_for(tbb::blocked_range<int>(0, last, IndependentGrainSize),
|
|
||||||
[this, &node_priorities, &remaining_nodes, &thread_data_list](
|
|
||||||
const tbb::blocked_range<int> &range)
|
|
||||||
{
|
|
||||||
ContractorThreadData *data = thread_data_list.getThreadData();
|
|
||||||
// determine independent node set
|
|
||||||
for (int i = range.begin(), end = range.end(); i != end; ++i)
|
|
||||||
{
|
|
||||||
const NodeID node = remaining_nodes[i].id;
|
|
||||||
remaining_nodes[i].is_independent =
|
|
||||||
this->IsNodeIndependent(node_priorities, data, node);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const auto first = stable_partition(remaining_nodes.begin(), remaining_nodes.end(),
|
|
||||||
[](RemainingNodeData node_data)
|
|
||||||
{
|
|
||||||
return !node_data.is_independent;
|
|
||||||
});
|
|
||||||
const int first_independent_node = static_cast<int>(first - remaining_nodes.begin());
|
|
||||||
|
|
||||||
// contract independent nodes
|
|
||||||
tbb::parallel_for(
|
|
||||||
tbb::blocked_range<int>(first_independent_node, last, ContractGrainSize),
|
|
||||||
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int> &range)
|
|
||||||
{
|
|
||||||
ContractorThreadData *data = thread_data_list.getThreadData();
|
|
||||||
for (int position = range.begin(), end = range.end(); position != end; ++position)
|
|
||||||
{
|
|
||||||
const NodeID x = remaining_nodes[position].id;
|
|
||||||
this->ContractNode<false>(data, x);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// make sure we really sort each block
|
|
||||||
tbb::parallel_for(
|
|
||||||
thread_data_list.data.range(),
|
|
||||||
[&](const ThreadDataContainer::EnumerableThreadData::range_type &range)
|
|
||||||
{
|
|
||||||
for (auto &data : range)
|
|
||||||
std::sort(data->inserted_edges.begin(), data->inserted_edges.end());
|
|
||||||
});
|
|
||||||
tbb::parallel_for(
|
|
||||||
tbb::blocked_range<int>(first_independent_node, last, DeleteGrainSize),
|
|
||||||
[this, &remaining_nodes, &thread_data_list](const tbb::blocked_range<int> &range)
|
|
||||||
{
|
|
||||||
ContractorThreadData *data = thread_data_list.getThreadData();
|
|
||||||
for (int position = range.begin(), end = range.end(); position != end; ++position)
|
|
||||||
{
|
|
||||||
const NodeID x = remaining_nodes[position].id;
|
|
||||||
this->DeleteIncomingEdges(data, x);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// insert new edges
|
|
||||||
for (auto &data : thread_data_list.data)
|
|
||||||
{
|
|
||||||
for (const ContractorEdge &edge : data->inserted_edges)
|
|
||||||
{
|
|
||||||
const EdgeID current_edge_ID =
|
|
||||||
contractor_graph->FindEdge(edge.source, edge.target);
|
|
||||||
if (current_edge_ID < contractor_graph->EndEdges(edge.source))
|
|
||||||
{
|
|
||||||
ContractorGraph::EdgeData ¤t_data =
|
|
||||||
contractor_graph->GetEdgeData(current_edge_ID);
|
|
||||||
if (current_data.shortcut && edge.data.forward == current_data.forward &&
|
|
||||||
edge.data.backward == current_data.backward &&
|
|
||||||
edge.data.distance < current_data.distance)
|
|
||||||
{
|
|
||||||
// found a duplicate edge with smaller weight, update it.
|
|
||||||
current_data = edge.data;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
contractor_graph->InsertEdge(edge.source, edge.target, edge.data);
|
|
||||||
}
|
|
||||||
data->inserted_edges.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
tbb::parallel_for(
|
|
||||||
tbb::blocked_range<int>(first_independent_node, last, NeighboursGrainSize),
|
|
||||||
[this, &remaining_nodes, &node_priorities, &node_data, &thread_data_list](
|
|
||||||
const tbb::blocked_range<int> &range)
|
|
||||||
{
|
|
||||||
ContractorThreadData *data = thread_data_list.getThreadData();
|
|
||||||
for (int position = range.begin(), end = range.end(); position != end; ++position)
|
|
||||||
{
|
|
||||||
NodeID x = remaining_nodes[position].id;
|
|
||||||
this->UpdateNodeNeighbours(node_priorities, node_data, data, x);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// remove contracted nodes from the pool
|
|
||||||
number_of_contracted_nodes += last - first_independent_node;
|
|
||||||
remaining_nodes.resize(first_independent_node);
|
|
||||||
remaining_nodes.shrink_to_fit();
|
|
||||||
// unsigned maxdegree = 0;
|
|
||||||
// unsigned avgdegree = 0;
|
|
||||||
// unsigned mindegree = UINT_MAX;
|
|
||||||
// unsigned quaddegree = 0;
|
|
||||||
//
|
|
||||||
// for(unsigned i = 0; i < remaining_nodes.size(); ++i) {
|
|
||||||
// unsigned degree = contractor_graph->EndEdges(remaining_nodes[i].id)
|
|
||||||
// -
|
|
||||||
// contractor_graph->BeginEdges(remaining_nodes[i].first);
|
|
||||||
// if(degree > maxdegree)
|
|
||||||
// maxdegree = degree;
|
|
||||||
// if(degree < mindegree)
|
|
||||||
// mindegree = degree;
|
|
||||||
//
|
|
||||||
// avgdegree += degree;
|
|
||||||
// quaddegree += (degree*degree);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// avgdegree /= std::max((unsigned)1,(unsigned)remaining_nodes.size() );
|
|
||||||
// quaddegree /= std::max((unsigned)1,(unsigned)remaining_nodes.size() );
|
|
||||||
//
|
|
||||||
// SimpleLogger().Write() << "rest: " << remaining_nodes.size() << ", max: "
|
|
||||||
// << maxdegree << ", min: " << mindegree << ", avg: " << avgdegree << ",
|
|
||||||
// quad: " << quaddegree;
|
|
||||||
|
|
||||||
p.printStatus(number_of_contracted_nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remaining_nodes.size() > 2)
|
|
||||||
{
|
|
||||||
// TODO: for small cores a sorted array of core ids might also work good
|
|
||||||
for (const auto& node : remaining_nodes)
|
|
||||||
{
|
|
||||||
auto orig_id = orig_node_id_from_new_node_id_map[node.id];
|
|
||||||
is_core_node[orig_id] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// in this case we don't need core markers since we fully contracted
|
|
||||||
// the graph
|
|
||||||
is_core_node.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "[core] " << remaining_nodes.size() << " nodes " << contractor_graph->GetNumberOfEdges() << " edges." << std::endl;
|
|
||||||
|
|
||||||
thread_data_list.data.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void GetCoreMarker(std::vector<bool> &out_is_core_node)
|
|
||||||
{
|
|
||||||
out_is_core_node.swap(is_core_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Edge> inline void GetEdges(DeallocatingVector<Edge> &edges)
|
|
||||||
{
|
|
||||||
Percent p(contractor_graph->GetNumberOfNodes());
|
|
||||||
SimpleLogger().Write() << "Getting edges of minimized graph";
|
|
||||||
const NodeID number_of_nodes = contractor_graph->GetNumberOfNodes();
|
|
||||||
if (contractor_graph->GetNumberOfNodes())
|
|
||||||
{
|
|
||||||
Edge new_edge;
|
|
||||||
for (const auto node : osrm::irange(0u, number_of_nodes))
|
|
||||||
{
|
|
||||||
p.printStatus(node);
|
|
||||||
for (auto edge : contractor_graph->GetAdjacentEdgeRange(node))
|
|
||||||
{
|
|
||||||
const NodeID target = contractor_graph->GetTarget(edge);
|
|
||||||
const ContractorGraph::EdgeData &data = contractor_graph->GetEdgeData(edge);
|
|
||||||
if (!orig_node_id_from_new_node_id_map.empty())
|
|
||||||
{
|
|
||||||
new_edge.source = orig_node_id_from_new_node_id_map[node];
|
|
||||||
new_edge.target = orig_node_id_from_new_node_id_map[target];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new_edge.source = node;
|
|
||||||
new_edge.target = target;
|
|
||||||
}
|
|
||||||
BOOST_ASSERT_MSG(UINT_MAX != new_edge.source, "Source id invalid");
|
|
||||||
BOOST_ASSERT_MSG(UINT_MAX != new_edge.target, "Target id invalid");
|
|
||||||
new_edge.data.distance = data.distance;
|
|
||||||
new_edge.data.shortcut = data.shortcut;
|
|
||||||
if (!data.is_original_via_node_ID && !orig_node_id_from_new_node_id_map.empty())
|
|
||||||
{
|
|
||||||
// tranlate the _node id_ of the shortcutted node
|
|
||||||
new_edge.data.id = orig_node_id_from_new_node_id_map[data.id];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new_edge.data.id = data.id;
|
|
||||||
}
|
|
||||||
BOOST_ASSERT_MSG(new_edge.data.id != INT_MAX, // 2^31
|
|
||||||
"edge id invalid");
|
|
||||||
new_edge.data.forward = data.forward;
|
|
||||||
new_edge.data.backward = data.backward;
|
|
||||||
edges.push_back(new_edge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
contractor_graph.reset();
|
|
||||||
orig_node_id_from_new_node_id_map.clear();
|
|
||||||
orig_node_id_from_new_node_id_map.shrink_to_fit();
|
|
||||||
|
|
||||||
BOOST_ASSERT(0 == orig_node_id_from_new_node_id_map.capacity());
|
|
||||||
|
|
||||||
edges.append(external_edge_list.begin(), external_edge_list.end());
|
|
||||||
external_edge_list.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
inline void Dijkstra(const int max_distance,
|
|
||||||
const unsigned number_of_targets,
|
|
||||||
const int maxNodes,
|
|
||||||
ContractorThreadData *const data,
|
|
||||||
const NodeID middleNode)
|
|
||||||
{
|
|
||||||
|
|
||||||
ContractorHeap &heap = data->heap;
|
|
||||||
|
|
||||||
int nodes = 0;
|
|
||||||
unsigned number_of_targets_found = 0;
|
|
||||||
while (!heap.Empty())
|
|
||||||
{
|
|
||||||
const NodeID node = heap.DeleteMin();
|
|
||||||
const int distance = heap.GetKey(node);
|
|
||||||
const short current_hop = heap.GetData(node).hop + 1;
|
|
||||||
|
|
||||||
if (++nodes > maxNodes)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (distance > max_distance)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destination settled?
|
|
||||||
if (heap.GetData(node).target)
|
|
||||||
{
|
|
||||||
++number_of_targets_found;
|
|
||||||
if (number_of_targets_found >= number_of_targets)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// iterate over all edges of node
|
|
||||||
for (auto edge : contractor_graph->GetAdjacentEdgeRange(node))
|
|
||||||
{
|
|
||||||
const ContractorEdgeData &data = contractor_graph->GetEdgeData(edge);
|
|
||||||
if (!data.forward)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const NodeID to = contractor_graph->GetTarget(edge);
|
|
||||||
if (middleNode == to)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const int to_distance = distance + data.distance;
|
|
||||||
|
|
||||||
// New Node discovered -> Add to Heap + Node Info Storage
|
|
||||||
if (!heap.WasInserted(to))
|
|
||||||
{
|
|
||||||
heap.Insert(to, to_distance, ContractorHeapData(current_hop, false));
|
|
||||||
}
|
|
||||||
// Found a shorter Path -> Update distance
|
|
||||||
else if (to_distance < heap.GetKey(to))
|
|
||||||
{
|
|
||||||
heap.DecreaseKey(to, to_distance);
|
|
||||||
heap.GetData(to).hop = current_hop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float EvaluateNodePriority(ContractorThreadData *const data,
|
|
||||||
NodePriorityData *const node_data,
|
|
||||||
const NodeID node)
|
|
||||||
{
|
|
||||||
ContractionStats stats;
|
|
||||||
|
|
||||||
// perform simulated contraction
|
|
||||||
ContractNode<true>(data, node, &stats);
|
|
||||||
|
|
||||||
// Result will contain the priority
|
|
||||||
float result;
|
|
||||||
if (0 == (stats.edges_deleted_count * stats.original_edges_deleted_count))
|
|
||||||
{
|
|
||||||
result = 1.f * node_data->depth;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = 2.f * (((float)stats.edges_added_count) / stats.edges_deleted_count) +
|
|
||||||
4.f * (((float)stats.original_edges_added_count) /
|
|
||||||
stats.original_edges_deleted_count) +
|
|
||||||
1.f * node_data->depth;
|
|
||||||
}
|
|
||||||
BOOST_ASSERT(result >= 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <bool RUNSIMULATION>
|
|
||||||
inline bool
|
|
||||||
ContractNode(ContractorThreadData *data, const NodeID node, ContractionStats *stats = nullptr)
|
|
||||||
{
|
|
||||||
ContractorHeap &heap = data->heap;
|
|
||||||
int inserted_edges_size = data->inserted_edges.size();
|
|
||||||
std::vector<ContractorEdge> &inserted_edges = data->inserted_edges;
|
|
||||||
|
|
||||||
for (auto in_edge : contractor_graph->GetAdjacentEdgeRange(node))
|
|
||||||
{
|
|
||||||
const ContractorEdgeData &in_data = contractor_graph->GetEdgeData(in_edge);
|
|
||||||
const NodeID source = contractor_graph->GetTarget(in_edge);
|
|
||||||
if (RUNSIMULATION)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(stats != nullptr);
|
|
||||||
++stats->edges_deleted_count;
|
|
||||||
stats->original_edges_deleted_count += in_data.originalEdges;
|
|
||||||
}
|
|
||||||
if (!in_data.backward)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
heap.Clear();
|
|
||||||
heap.Insert(source, 0, ContractorHeapData());
|
|
||||||
int max_distance = 0;
|
|
||||||
unsigned number_of_targets = 0;
|
|
||||||
|
|
||||||
for (auto out_edge : contractor_graph->GetAdjacentEdgeRange(node))
|
|
||||||
{
|
|
||||||
const ContractorEdgeData &out_data = contractor_graph->GetEdgeData(out_edge);
|
|
||||||
if (!out_data.forward)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const NodeID target = contractor_graph->GetTarget(out_edge);
|
|
||||||
const int path_distance = in_data.distance + out_data.distance;
|
|
||||||
max_distance = std::max(max_distance, path_distance);
|
|
||||||
if (!heap.WasInserted(target))
|
|
||||||
{
|
|
||||||
heap.Insert(target, INT_MAX, ContractorHeapData(0, true));
|
|
||||||
++number_of_targets;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RUNSIMULATION)
|
|
||||||
{
|
|
||||||
Dijkstra(max_distance, number_of_targets, 1000, data, node);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Dijkstra(max_distance, number_of_targets, 2000, data, node);
|
|
||||||
}
|
|
||||||
for (auto out_edge : contractor_graph->GetAdjacentEdgeRange(node))
|
|
||||||
{
|
|
||||||
const ContractorEdgeData &out_data = contractor_graph->GetEdgeData(out_edge);
|
|
||||||
if (!out_data.forward)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const NodeID target = contractor_graph->GetTarget(out_edge);
|
|
||||||
const int path_distance = in_data.distance + out_data.distance;
|
|
||||||
const int distance = heap.GetKey(target);
|
|
||||||
if (path_distance < distance)
|
|
||||||
{
|
|
||||||
if (RUNSIMULATION)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(stats != nullptr);
|
|
||||||
stats->edges_added_count += 2;
|
|
||||||
stats->original_edges_added_count +=
|
|
||||||
2 * (out_data.originalEdges + in_data.originalEdges);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
inserted_edges.emplace_back(source, target, path_distance,
|
|
||||||
out_data.originalEdges + in_data.originalEdges,
|
|
||||||
node, true, true, false);
|
|
||||||
|
|
||||||
inserted_edges.emplace_back(target, source, path_distance,
|
|
||||||
out_data.originalEdges + in_data.originalEdges,
|
|
||||||
node, true, false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!RUNSIMULATION)
|
|
||||||
{
|
|
||||||
int iend = inserted_edges.size();
|
|
||||||
for (int i = inserted_edges_size; i < iend; ++i)
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
for (int other = i + 1; other < iend; ++other)
|
|
||||||
{
|
|
||||||
if (inserted_edges[other].source != inserted_edges[i].source)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (inserted_edges[other].target != inserted_edges[i].target)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (inserted_edges[other].data.distance != inserted_edges[i].data.distance)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (inserted_edges[other].data.shortcut != inserted_edges[i].data.shortcut)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
inserted_edges[other].data.forward |= inserted_edges[i].data.forward;
|
|
||||||
inserted_edges[other].data.backward |= inserted_edges[i].data.backward;
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
inserted_edges[inserted_edges_size++] = inserted_edges[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inserted_edges.resize(inserted_edges_size);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void DeleteIncomingEdges(ContractorThreadData *data, const NodeID node)
|
|
||||||
{
|
|
||||||
std::vector<NodeID> &neighbours = data->neighbours;
|
|
||||||
neighbours.clear();
|
|
||||||
|
|
||||||
// find all neighbours
|
|
||||||
for (auto e : contractor_graph->GetAdjacentEdgeRange(node))
|
|
||||||
{
|
|
||||||
const NodeID u = contractor_graph->GetTarget(e);
|
|
||||||
if (u != node)
|
|
||||||
{
|
|
||||||
neighbours.push_back(u);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// eliminate duplicate entries ( forward + backward edges )
|
|
||||||
std::sort(neighbours.begin(), neighbours.end());
|
|
||||||
neighbours.resize(std::unique(neighbours.begin(), neighbours.end()) - neighbours.begin());
|
|
||||||
|
|
||||||
for (const auto i : osrm::irange<std::size_t>(0, neighbours.size()))
|
|
||||||
{
|
|
||||||
contractor_graph->DeleteEdgesTo(neighbours[i], node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool UpdateNodeNeighbours(std::vector<float> &priorities,
|
|
||||||
std::vector<NodePriorityData> &node_data,
|
|
||||||
ContractorThreadData *const data,
|
|
||||||
const NodeID node)
|
|
||||||
{
|
|
||||||
std::vector<NodeID> &neighbours = data->neighbours;
|
|
||||||
neighbours.clear();
|
|
||||||
|
|
||||||
// find all neighbours
|
|
||||||
for (auto e : contractor_graph->GetAdjacentEdgeRange(node))
|
|
||||||
{
|
|
||||||
const NodeID u = contractor_graph->GetTarget(e);
|
|
||||||
if (u == node)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
neighbours.push_back(u);
|
|
||||||
node_data[u].depth = (std::max)(node_data[node].depth + 1, node_data[u].depth);
|
|
||||||
}
|
|
||||||
// eliminate duplicate entries ( forward + backward edges )
|
|
||||||
std::sort(neighbours.begin(), neighbours.end());
|
|
||||||
neighbours.resize(std::unique(neighbours.begin(), neighbours.end()) - neighbours.begin());
|
|
||||||
|
|
||||||
// re-evaluate priorities of neighboring nodes
|
|
||||||
for (const NodeID u : neighbours)
|
|
||||||
{
|
|
||||||
priorities[u] = EvaluateNodePriority(data, &(node_data)[u], u);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool IsNodeIndependent(const std::vector<float> &priorities,
|
|
||||||
ContractorThreadData *const data,
|
|
||||||
NodeID node) const
|
|
||||||
{
|
|
||||||
const float priority = priorities[node];
|
|
||||||
|
|
||||||
std::vector<NodeID> &neighbours = data->neighbours;
|
|
||||||
neighbours.clear();
|
|
||||||
|
|
||||||
for (auto e : contractor_graph->GetAdjacentEdgeRange(node))
|
|
||||||
{
|
|
||||||
const NodeID target = contractor_graph->GetTarget(e);
|
|
||||||
if (node == target)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const float target_priority = priorities[target];
|
|
||||||
BOOST_ASSERT(target_priority >= 0);
|
|
||||||
// found a neighbour with lower priority?
|
|
||||||
if (priority > target_priority)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// tie breaking
|
|
||||||
if (std::abs(priority - target_priority) < std::numeric_limits<float>::epsilon() &&
|
|
||||||
bias(node, target))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
neighbours.push_back(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(neighbours.begin(), neighbours.end());
|
|
||||||
neighbours.resize(std::unique(neighbours.begin(), neighbours.end()) - neighbours.begin());
|
|
||||||
|
|
||||||
// examine all neighbours that are at most 2 hops away
|
|
||||||
for (const NodeID u : neighbours)
|
|
||||||
{
|
|
||||||
for (auto e : contractor_graph->GetAdjacentEdgeRange(u))
|
|
||||||
{
|
|
||||||
const NodeID target = contractor_graph->GetTarget(e);
|
|
||||||
if (node == target)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const float target_priority = priorities[target];
|
|
||||||
BOOST_ASSERT(target_priority >= 0);
|
|
||||||
// found a neighbour with lower priority?
|
|
||||||
if (priority > target_priority)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// tie breaking
|
|
||||||
if (std::abs(priority - target_priority) < std::numeric_limits<float>::epsilon() &&
|
|
||||||
bias(node, target))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This bias function takes up 22 assembly instructions in total on X86
|
|
||||||
inline bool bias(const NodeID a, const NodeID b) const
|
|
||||||
{
|
|
||||||
const unsigned short hasha = fast_hash(a);
|
|
||||||
const unsigned short hashb = fast_hash(b);
|
|
||||||
|
|
||||||
// The compiler optimizes that to conditional register flags but without branching
|
|
||||||
// statements!
|
|
||||||
if (hasha != hashb)
|
|
||||||
{
|
|
||||||
return hasha < hashb;
|
|
||||||
}
|
|
||||||
return a < b;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ContractorGraph> contractor_graph;
|
|
||||||
stxxl::vector<QueryEdge> external_edge_list;
|
|
||||||
std::vector<NodeID> orig_node_id_from_new_node_id_map;
|
|
||||||
std::vector<bool> is_core_node;
|
|
||||||
XORFastHash fast_hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CONTRACTOR_HPP
|
|
||||||
@@ -1,140 +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/git_sha.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()(
|
|
||||||
"restrictions,r",
|
|
||||||
boost::program_options::value<boost::filesystem::path>(&contractor_config.restrictions_path),
|
|
||||||
"Restrictions file in .osrm.restrictions format")(
|
|
||||||
"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]");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 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() << g_GIT_DESCRIPTION;
|
|
||||||
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("restrictions"))
|
|
||||||
{
|
|
||||||
contractor_config.restrictions_path = contractor_config.osrm_input_path.string() + ".restrictions";
|
|
||||||
}
|
|
||||||
|
|
||||||
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.node_output_path = contractor_config.osrm_input_path.string() + ".nodes";
|
|
||||||
contractor_config.core_output_path = contractor_config.osrm_input_path.string() + ".core";
|
|
||||||
contractor_config.edge_output_path = contractor_config.osrm_input_path.string() + ".edges";
|
|
||||||
contractor_config.geometry_output_path = contractor_config.osrm_input_path.string() + ".geometry";
|
|
||||||
contractor_config.graph_output_path = contractor_config.osrm_input_path.string() + ".hsgr";
|
|
||||||
contractor_config.rtree_nodes_output_path = contractor_config.osrm_input_path.string() + ".ramIndex";
|
|
||||||
contractor_config.rtree_leafs_output_path = contractor_config.osrm_input_path.string() + ".fileIndex";
|
|
||||||
}
|
|
||||||
@@ -1,75 +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 restrictions_path;
|
|
||||||
boost::filesystem::path profile_path;
|
|
||||||
|
|
||||||
std::string node_output_path;
|
|
||||||
std::string core_output_path;
|
|
||||||
std::string edge_output_path;
|
|
||||||
std::string geometry_output_path;
|
|
||||||
std::string graph_output_path;
|
|
||||||
std::string rtree_nodes_output_path;
|
|
||||||
std::string rtree_leafs_output_path;
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ContractorOptions
|
|
||||||
{
|
|
||||||
static return_code ParseArguments(int argc, char *argv[], ContractorConfig &extractor_config);
|
|
||||||
|
|
||||||
static void GenerateOutputFilesNames(ContractorConfig &extractor_config);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // EXTRACTOR_OPTIONS_HPP
|
|
||||||
@@ -1,562 +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 "edge_based_graph_factory.hpp"
|
|
||||||
#include "../data_structures/percent.hpp"
|
|
||||||
#include "../util/compute_angle.hpp"
|
|
||||||
#include "../util/integer_range.hpp"
|
|
||||||
#include "../util/lua_util.hpp"
|
|
||||||
#include "../util/simple_logger.hpp"
|
|
||||||
#include "../util/timing_util.hpp"
|
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
|
||||||
std::shared_ptr<NodeBasedDynamicGraph> node_based_graph,
|
|
||||||
const CompressedEdgeContainer &compressed_edge_container,
|
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
|
||||||
const std::unordered_set<NodeID> &traffic_lights,
|
|
||||||
std::shared_ptr<const RestrictionMap> restriction_map,
|
|
||||||
const std::vector<QueryNode> &node_info_list,
|
|
||||||
SpeedProfileProperties speed_profile)
|
|
||||||
: m_max_edge_id(0), m_node_info_list(node_info_list), m_node_based_graph(std::move(node_based_graph)),
|
|
||||||
m_restriction_map(std::move(restriction_map)), m_barrier_nodes(barrier_nodes),
|
|
||||||
m_traffic_lights(traffic_lights), m_compressed_edge_container(compressed_edge_container),
|
|
||||||
speed_profile(std::move(speed_profile))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &output_edge_list)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT_MSG(0 == output_edge_list.size(), "Vector is not empty");
|
|
||||||
m_edge_based_edge_list.swap(output_edge_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
for (const EdgeBasedNode &node : m_edge_based_node_list)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(m_node_info_list.at(node.u).lat != INT_MAX);
|
|
||||||
BOOST_ASSERT(m_node_info_list.at(node.u).lon != INT_MAX);
|
|
||||||
BOOST_ASSERT(m_node_info_list.at(node.v).lon != INT_MAX);
|
|
||||||
BOOST_ASSERT(m_node_info_list.at(node.v).lat != INT_MAX);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
nodes.swap(m_edge_based_node_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned EdgeBasedGraphFactory::GetHighestEdgeID()
|
|
||||||
{
|
|
||||||
return m_max_edge_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u,
|
|
||||||
const NodeID node_v)
|
|
||||||
{
|
|
||||||
// merge edges together into one EdgeBasedNode
|
|
||||||
BOOST_ASSERT(node_u != SPECIAL_NODEID);
|
|
||||||
BOOST_ASSERT(node_v != SPECIAL_NODEID);
|
|
||||||
|
|
||||||
// find forward edge id and
|
|
||||||
const EdgeID edge_id_1 = m_node_based_graph->FindEdge(node_u, node_v);
|
|
||||||
BOOST_ASSERT(edge_id_1 != SPECIAL_EDGEID);
|
|
||||||
|
|
||||||
const EdgeData &forward_data = m_node_based_graph->GetEdgeData(edge_id_1);
|
|
||||||
|
|
||||||
// find reverse edge id and
|
|
||||||
const EdgeID edge_id_2 = m_node_based_graph->FindEdge(node_v, node_u);
|
|
||||||
BOOST_ASSERT(edge_id_2 != SPECIAL_EDGEID);
|
|
||||||
|
|
||||||
const EdgeData &reverse_data = m_node_based_graph->GetEdgeData(edge_id_2);
|
|
||||||
|
|
||||||
if (forward_data.edge_id == SPECIAL_NODEID &&
|
|
||||||
reverse_data.edge_id == SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(m_compressed_edge_container.HasEntryForID(edge_id_1) ==
|
|
||||||
m_compressed_edge_container.HasEntryForID(edge_id_2));
|
|
||||||
if (m_compressed_edge_container.HasEntryForID(edge_id_1))
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(m_compressed_edge_container.HasEntryForID(edge_id_2));
|
|
||||||
|
|
||||||
// reconstruct geometry and put in each individual edge with its offset
|
|
||||||
const auto& forward_geometry = m_compressed_edge_container.GetBucketReference(edge_id_1);
|
|
||||||
const auto& reverse_geometry = m_compressed_edge_container.GetBucketReference(edge_id_2);
|
|
||||||
BOOST_ASSERT(forward_geometry.size() == reverse_geometry.size());
|
|
||||||
BOOST_ASSERT(0 != forward_geometry.size());
|
|
||||||
const unsigned geometry_size = static_cast<unsigned>(forward_geometry.size());
|
|
||||||
BOOST_ASSERT(geometry_size > 1);
|
|
||||||
|
|
||||||
// reconstruct bidirectional edge with individual weights and put each into the NN index
|
|
||||||
|
|
||||||
std::vector<int> forward_dist_prefix_sum(forward_geometry.size(), 0);
|
|
||||||
std::vector<int> reverse_dist_prefix_sum(reverse_geometry.size(), 0);
|
|
||||||
|
|
||||||
// quick'n'dirty prefix sum as std::partial_sum needs addtional casts
|
|
||||||
// TODO: move to lambda function with C++11
|
|
||||||
int temp_sum = 0;
|
|
||||||
|
|
||||||
for (const auto i : osrm::irange(0u, geometry_size))
|
|
||||||
{
|
|
||||||
forward_dist_prefix_sum[i] = temp_sum;
|
|
||||||
temp_sum += forward_geometry[i].second;
|
|
||||||
|
|
||||||
BOOST_ASSERT(forward_data.distance >= temp_sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
temp_sum = 0;
|
|
||||||
for (const auto i : osrm::irange(0u, geometry_size))
|
|
||||||
{
|
|
||||||
temp_sum += reverse_geometry[reverse_geometry.size() - 1 - i].second;
|
|
||||||
reverse_dist_prefix_sum[i] = reverse_data.distance - temp_sum;
|
|
||||||
// BOOST_ASSERT(reverse_data.distance >= temp_sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeID current_edge_source_coordinate_id = node_u;
|
|
||||||
|
|
||||||
// traverse arrays from start and end respectively
|
|
||||||
for (const auto i : osrm::irange(0u, geometry_size))
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(current_edge_source_coordinate_id ==
|
|
||||||
reverse_geometry[geometry_size - 1 - i].first);
|
|
||||||
const NodeID current_edge_target_coordinate_id = forward_geometry[i].first;
|
|
||||||
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
|
|
||||||
|
|
||||||
// build edges
|
|
||||||
m_edge_based_node_list.emplace_back(
|
|
||||||
forward_data.edge_id, reverse_data.edge_id,
|
|
||||||
current_edge_source_coordinate_id, current_edge_target_coordinate_id,
|
|
||||||
forward_data.name_id, forward_geometry[i].second,
|
|
||||||
reverse_geometry[geometry_size - 1 - i].second, forward_dist_prefix_sum[i],
|
|
||||||
reverse_dist_prefix_sum[i], m_compressed_edge_container.GetPositionForID(edge_id_1),
|
|
||||||
INVALID_COMPONENTID, i, forward_data.travel_mode, reverse_data.travel_mode);
|
|
||||||
current_edge_source_coordinate_id = current_edge_target_coordinate_id;
|
|
||||||
|
|
||||||
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
|
|
||||||
|
|
||||||
BOOST_ASSERT(node_u != m_edge_based_node_list.back().u ||
|
|
||||||
node_v != m_edge_based_node_list.back().v);
|
|
||||||
|
|
||||||
BOOST_ASSERT(node_u != m_edge_based_node_list.back().v ||
|
|
||||||
node_v != m_edge_based_node_list.back().u);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(current_edge_source_coordinate_id == node_v);
|
|
||||||
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(!m_compressed_edge_container.HasEntryForID(edge_id_2));
|
|
||||||
|
|
||||||
if (forward_data.edge_id != SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(!forward_data.reversed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(forward_data.reversed);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reverse_data.edge_id != SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(!reverse_data.reversed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(reverse_data.reversed);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(forward_data.edge_id != SPECIAL_NODEID ||
|
|
||||||
reverse_data.edge_id != SPECIAL_NODEID);
|
|
||||||
|
|
||||||
m_edge_based_node_list.emplace_back(
|
|
||||||
forward_data.edge_id, reverse_data.edge_id, node_u, node_v,
|
|
||||||
forward_data.name_id, forward_data.distance, reverse_data.distance, 0, 0, SPECIAL_EDGEID,
|
|
||||||
INVALID_COMPONENTID, 0, forward_data.travel_mode, reverse_data.travel_mode);
|
|
||||||
BOOST_ASSERT(!m_edge_based_node_list.back().IsCompressed());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::FlushVectorToStream(
|
|
||||||
std::ofstream &edge_data_file, std::vector<OriginalEdgeData> &original_edge_data_vector) const
|
|
||||||
{
|
|
||||||
if (original_edge_data_vector.empty())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
edge_data_file.write((char *)&(original_edge_data_vector[0]),
|
|
||||||
original_edge_data_vector.size() * sizeof(OriginalEdgeData));
|
|
||||||
original_edge_data_vector.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
|
|
||||||
lua_State *lua_state)
|
|
||||||
{
|
|
||||||
TIMER_START(renumber);
|
|
||||||
m_max_edge_id = RenumberEdges() - 1;
|
|
||||||
TIMER_STOP(renumber);
|
|
||||||
|
|
||||||
TIMER_START(generate_nodes);
|
|
||||||
GenerateEdgeExpandedNodes();
|
|
||||||
TIMER_STOP(generate_nodes);
|
|
||||||
|
|
||||||
TIMER_START(generate_edges);
|
|
||||||
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state);
|
|
||||||
TIMER_STOP(generate_edges);
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Timing statistics for edge-expanded graph:";
|
|
||||||
SimpleLogger().Write() << "Renumbering edges: " << TIMER_SEC(renumber) << "s";
|
|
||||||
SimpleLogger().Write() << "Generating nodes: " << TIMER_SEC(generate_nodes) << "s";
|
|
||||||
SimpleLogger().Write() << "Generating edges: " << TIMER_SEC(generate_edges) << "s";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Renumbers all _forward_ edges and sets the edge_id.
|
|
||||||
/// A specific numbering is not important. Any unique ID will do.
|
|
||||||
/// Returns the number of edge based nodes.
|
|
||||||
unsigned EdgeBasedGraphFactory::RenumberEdges()
|
|
||||||
{
|
|
||||||
// renumber edge based node of outgoing edges
|
|
||||||
unsigned numbered_edges_count = 0;
|
|
||||||
for (const auto current_node : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
|
||||||
{
|
|
||||||
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(current_node))
|
|
||||||
{
|
|
||||||
EdgeData &edge_data = m_node_based_graph->GetEdgeData(current_edge);
|
|
||||||
|
|
||||||
// only number incoming edges
|
|
||||||
if (edge_data.reversed)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(numbered_edges_count < m_node_based_graph->GetNumberOfEdges());
|
|
||||||
edge_data.edge_id = numbered_edges_count;
|
|
||||||
++numbered_edges_count;
|
|
||||||
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != edge_data.edge_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return numbered_edges_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates the nodes in the edge expanded graph from edges in the node-based graph.
|
|
||||||
void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
|
|
||||||
{
|
|
||||||
Percent progress(m_node_based_graph->GetNumberOfNodes());
|
|
||||||
|
|
||||||
// loop over all edges and generate new set of nodes
|
|
||||||
for (const auto node_u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(node_u != SPECIAL_NODEID);
|
|
||||||
BOOST_ASSERT(node_u < m_node_based_graph->GetNumberOfNodes());
|
|
||||||
progress.printStatus(node_u);
|
|
||||||
for (EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(node_u))
|
|
||||||
{
|
|
||||||
const EdgeData &edge_data = m_node_based_graph->GetEdgeData(e1);
|
|
||||||
BOOST_ASSERT(e1 != SPECIAL_EDGEID);
|
|
||||||
const NodeID node_v = m_node_based_graph->GetTarget(e1);
|
|
||||||
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != node_v);
|
|
||||||
// pick only every other edge, since we have every edge as an outgoing
|
|
||||||
// and incoming egde
|
|
||||||
if (node_u > node_v)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(node_u < node_v);
|
|
||||||
|
|
||||||
// if we found a non-forward edge reverse and try again
|
|
||||||
if (edge_data.edge_id == SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
InsertEdgeBasedNode(node_v, node_u);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InsertEdgeBasedNode(node_u, node_v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size()
|
|
||||||
<< " nodes in edge-expanded graph";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Actually it also generates OriginalEdgeData and serializes them...
|
|
||||||
void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|
||||||
const std::string &original_edge_data_filename, lua_State *lua_state)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "generating edge-expanded edges";
|
|
||||||
|
|
||||||
unsigned node_based_edge_counter = 0;
|
|
||||||
unsigned original_edges_counter = 0;
|
|
||||||
|
|
||||||
std::ofstream edge_data_file(original_edge_data_filename.c_str(), std::ios::binary);
|
|
||||||
|
|
||||||
// writes a dummy value that is updated later
|
|
||||||
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
|
|
||||||
|
|
||||||
std::vector<OriginalEdgeData> original_edge_data_vector;
|
|
||||||
original_edge_data_vector.reserve(1024 * 1024);
|
|
||||||
|
|
||||||
// Loop over all turns and generate new set of edges.
|
|
||||||
// Three nested loop look super-linear, but we are dealing with a (kind of)
|
|
||||||
// linear number of turns only.
|
|
||||||
unsigned restricted_turns_counter = 0;
|
|
||||||
unsigned skipped_uturns_counter = 0;
|
|
||||||
unsigned skipped_barrier_turns_counter = 0;
|
|
||||||
unsigned compressed = 0;
|
|
||||||
|
|
||||||
Percent progress(m_node_based_graph->GetNumberOfNodes());
|
|
||||||
|
|
||||||
for (const auto node_u : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
|
||||||
{
|
|
||||||
progress.printStatus(node_u);
|
|
||||||
for (const EdgeID e1 : m_node_based_graph->GetAdjacentEdgeRange(node_u))
|
|
||||||
{
|
|
||||||
if (m_node_based_graph->GetEdgeData(e1).reversed)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
++node_based_edge_counter;
|
|
||||||
const NodeID node_v = m_node_based_graph->GetTarget(e1);
|
|
||||||
const NodeID only_restriction_to_node =
|
|
||||||
m_restriction_map->CheckForEmanatingIsOnlyTurn(node_u, node_v);
|
|
||||||
const bool is_barrier_node = m_barrier_nodes.find(node_v) != m_barrier_nodes.end();
|
|
||||||
|
|
||||||
for (const EdgeID e2 : m_node_based_graph->GetAdjacentEdgeRange(node_v))
|
|
||||||
{
|
|
||||||
if (m_node_based_graph->GetEdgeData(e2).reversed)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const NodeID node_w = m_node_based_graph->GetTarget(e2);
|
|
||||||
|
|
||||||
if ((only_restriction_to_node != SPECIAL_NODEID) &&
|
|
||||||
(node_w != only_restriction_to_node))
|
|
||||||
{
|
|
||||||
// We are at an only_-restriction but not at the right turn.
|
|
||||||
++restricted_turns_counter;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_barrier_node)
|
|
||||||
{
|
|
||||||
if (node_u != node_w)
|
|
||||||
{
|
|
||||||
++skipped_barrier_turns_counter;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((node_u == node_w) && (m_node_based_graph->GetOutDegree(node_v) > 1))
|
|
||||||
{
|
|
||||||
++skipped_uturns_counter;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// only add an edge if turn is not a U-turn except when it is
|
|
||||||
// at the end of a dead-end street
|
|
||||||
if (m_restriction_map->CheckIfTurnIsRestricted(node_u, node_v, node_w) &&
|
|
||||||
(only_restriction_to_node == SPECIAL_NODEID) &&
|
|
||||||
(node_w != only_restriction_to_node))
|
|
||||||
{
|
|
||||||
// We are at an only_-restriction but not at the right turn.
|
|
||||||
++restricted_turns_counter;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// only add an edge if turn is not prohibited
|
|
||||||
const EdgeData &edge_data1 = m_node_based_graph->GetEdgeData(e1);
|
|
||||||
const EdgeData &edge_data2 = m_node_based_graph->GetEdgeData(e2);
|
|
||||||
|
|
||||||
BOOST_ASSERT(edge_data1.edge_id != edge_data2.edge_id);
|
|
||||||
BOOST_ASSERT(!edge_data1.reversed);
|
|
||||||
BOOST_ASSERT(!edge_data2.reversed);
|
|
||||||
|
|
||||||
// the following is the core of the loop.
|
|
||||||
unsigned distance = edge_data1.distance;
|
|
||||||
if (m_traffic_lights.find(node_v) != m_traffic_lights.end())
|
|
||||||
{
|
|
||||||
distance += speed_profile.traffic_signal_penalty;
|
|
||||||
}
|
|
||||||
|
|
||||||
// unpack last node of first segment if packed
|
|
||||||
const auto first_coordinate =
|
|
||||||
m_node_info_list[(m_compressed_edge_container.HasEntryForID(e1)
|
|
||||||
? m_compressed_edge_container.GetLastEdgeSourceID(e1)
|
|
||||||
: node_u)];
|
|
||||||
|
|
||||||
// unpack first node of second segment if packed
|
|
||||||
const auto third_coordinate =
|
|
||||||
m_node_info_list[(m_compressed_edge_container.HasEntryForID(e2)
|
|
||||||
? m_compressed_edge_container.GetFirstEdgeTargetID(e2)
|
|
||||||
: node_w)];
|
|
||||||
|
|
||||||
const double turn_angle = ComputeAngle::OfThreeFixedPointCoordinates(
|
|
||||||
first_coordinate, m_node_info_list[node_v], third_coordinate);
|
|
||||||
|
|
||||||
const int turn_penalty = GetTurnPenalty(turn_angle, lua_state);
|
|
||||||
TurnInstruction turn_instruction = AnalyzeTurn(node_u, node_v, node_w, turn_angle);
|
|
||||||
if (turn_instruction == TurnInstruction::UTurn)
|
|
||||||
{
|
|
||||||
distance += speed_profile.u_turn_penalty;
|
|
||||||
}
|
|
||||||
distance += turn_penalty;
|
|
||||||
|
|
||||||
const bool edge_is_compressed = m_compressed_edge_container.HasEntryForID(e1);
|
|
||||||
|
|
||||||
if (edge_is_compressed)
|
|
||||||
{
|
|
||||||
++compressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
original_edge_data_vector.emplace_back(
|
|
||||||
(edge_is_compressed ? m_compressed_edge_container.GetPositionForID(e1) : node_v),
|
|
||||||
edge_data1.name_id, turn_instruction, edge_is_compressed,
|
|
||||||
edge_data2.travel_mode);
|
|
||||||
|
|
||||||
++original_edges_counter;
|
|
||||||
|
|
||||||
if (original_edge_data_vector.size() > 1024 * 1024 * 10)
|
|
||||||
{
|
|
||||||
FlushVectorToStream(edge_data_file, original_edge_data_vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != edge_data1.edge_id);
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != edge_data2.edge_id);
|
|
||||||
|
|
||||||
m_edge_based_edge_list.emplace_back(edge_data1.edge_id, edge_data2.edge_id,
|
|
||||||
m_edge_based_edge_list.size(), distance, true, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FlushVectorToStream(edge_data_file, original_edge_data_vector);
|
|
||||||
|
|
||||||
edge_data_file.seekp(std::ios::beg);
|
|
||||||
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
|
|
||||||
edge_data_file.close();
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size() << " edge based nodes";
|
|
||||||
SimpleLogger().Write() << "Node-based graph contains " << node_based_edge_counter << " edges";
|
|
||||||
SimpleLogger().Write() << "Edge-expanded graph ...";
|
|
||||||
SimpleLogger().Write() << " contains " << m_edge_based_edge_list.size() << " edges";
|
|
||||||
SimpleLogger().Write() << " skips " << restricted_turns_counter << " turns, "
|
|
||||||
"defined by "
|
|
||||||
<< m_restriction_map->size() << " restrictions";
|
|
||||||
SimpleLogger().Write() << " skips " << skipped_uturns_counter << " U turns";
|
|
||||||
SimpleLogger().Write() << " skips " << skipped_barrier_turns_counter << " turns over barriers";
|
|
||||||
}
|
|
||||||
|
|
||||||
int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if (speed_profile.has_turn_penalty_function)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// call lua profile to compute turn penalty
|
|
||||||
double penalty = luabind::call_function<double>(lua_state, "turn_function", 180. - angle);
|
|
||||||
return static_cast<int>(penalty);
|
|
||||||
}
|
|
||||||
catch (const luabind::error &er)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write(logWARNING) << er.what();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID node_u,
|
|
||||||
const NodeID node_v,
|
|
||||||
const NodeID node_w,
|
|
||||||
const double angle) const
|
|
||||||
{
|
|
||||||
if (node_u == node_w)
|
|
||||||
{
|
|
||||||
return TurnInstruction::UTurn;
|
|
||||||
}
|
|
||||||
|
|
||||||
const EdgeID edge1 = m_node_based_graph->FindEdge(node_u, node_v);
|
|
||||||
const EdgeID edge2 = m_node_based_graph->FindEdge(node_v, node_w);
|
|
||||||
|
|
||||||
const EdgeData &data1 = m_node_based_graph->GetEdgeData(edge1);
|
|
||||||
const EdgeData &data2 = m_node_based_graph->GetEdgeData(edge2);
|
|
||||||
|
|
||||||
// roundabouts need to be handled explicitely
|
|
||||||
if (data1.roundabout && data2.roundabout)
|
|
||||||
{
|
|
||||||
// Is a turn possible? If yes, we stay on the roundabout!
|
|
||||||
if (1 == m_node_based_graph->GetDirectedOutDegree(node_v))
|
|
||||||
{
|
|
||||||
// No turn possible.
|
|
||||||
return TurnInstruction::NoTurn;
|
|
||||||
}
|
|
||||||
return TurnInstruction::StayOnRoundAbout;
|
|
||||||
}
|
|
||||||
// Does turn start or end on roundabout?
|
|
||||||
if (data1.roundabout || data2.roundabout)
|
|
||||||
{
|
|
||||||
// We are entering the roundabout
|
|
||||||
if ((!data1.roundabout) && data2.roundabout)
|
|
||||||
{
|
|
||||||
return TurnInstruction::EnterRoundAbout;
|
|
||||||
}
|
|
||||||
// We are leaving the roundabout
|
|
||||||
if (data1.roundabout && (!data2.roundabout))
|
|
||||||
{
|
|
||||||
return TurnInstruction::LeaveRoundAbout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If street names stay the same and if we are certain that it is not a
|
|
||||||
// a segment of a roundabout, we skip it.
|
|
||||||
if (data1.name_id == data2.name_id && data1.travel_mode == data2.travel_mode)
|
|
||||||
{
|
|
||||||
// TODO: Here we should also do a small graph exploration to check for
|
|
||||||
// more complex situations
|
|
||||||
if (0 != data1.name_id || m_node_based_graph->GetOutDegree(node_v) <= 2)
|
|
||||||
{
|
|
||||||
return TurnInstruction::NoTurn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TurnInstructionsClass::GetTurnDirectionOfInstruction(angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright notice, this list
|
|
||||||
of conditions and the following disclaimer.
|
|
||||||
Redistributions in binary form must reproduce the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer in the documentation and/or
|
|
||||||
other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// This class constructs the edge-expanded routing graph
|
|
||||||
|
|
||||||
#ifndef EDGE_BASED_GRAPH_FACTORY_HPP_
|
|
||||||
#define EDGE_BASED_GRAPH_FACTORY_HPP_
|
|
||||||
|
|
||||||
#include "speed_profile.hpp"
|
|
||||||
#include "../typedefs.h"
|
|
||||||
#include "../data_structures/compressed_edge_container.hpp"
|
|
||||||
#include "../data_structures/deallocating_vector.hpp"
|
|
||||||
#include "../data_structures/edge_based_node.hpp"
|
|
||||||
#include "../data_structures/original_edge_data.hpp"
|
|
||||||
#include "../data_structures/query_node.hpp"
|
|
||||||
#include "../data_structures/turn_instructions.hpp"
|
|
||||||
#include "../data_structures/node_based_graph.hpp"
|
|
||||||
#include "../data_structures/restriction_map.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <memory>
|
|
||||||
#include <queue>
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
struct lua_State;
|
|
||||||
|
|
||||||
class EdgeBasedGraphFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EdgeBasedGraphFactory() = delete;
|
|
||||||
EdgeBasedGraphFactory(const EdgeBasedGraphFactory &) = delete;
|
|
||||||
|
|
||||||
explicit EdgeBasedGraphFactory(std::shared_ptr<NodeBasedDynamicGraph> node_based_graph,
|
|
||||||
const CompressedEdgeContainer &compressed_edge_container,
|
|
||||||
const std::unordered_set<NodeID> &barrier_nodes,
|
|
||||||
const std::unordered_set<NodeID> &traffic_lights,
|
|
||||||
std::shared_ptr<const RestrictionMap> restriction_map,
|
|
||||||
const std::vector<QueryNode> &node_info_list,
|
|
||||||
SpeedProfileProperties speed_profile);
|
|
||||||
|
|
||||||
void Run(const std::string &original_edge_data_filename,
|
|
||||||
lua_State *lua_state);
|
|
||||||
|
|
||||||
void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges);
|
|
||||||
|
|
||||||
void GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes);
|
|
||||||
|
|
||||||
unsigned GetHighestEdgeID();
|
|
||||||
|
|
||||||
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, const double angle) const;
|
|
||||||
|
|
||||||
int GetTurnPenalty(double angle, lua_State *lua_state) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
using EdgeData = NodeBasedDynamicGraph::EdgeData;
|
|
||||||
|
|
||||||
std::vector<EdgeBasedNode> m_edge_based_node_list;
|
|
||||||
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
|
|
||||||
unsigned m_max_edge_id;
|
|
||||||
|
|
||||||
const std::vector<QueryNode>& m_node_info_list;
|
|
||||||
std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
|
|
||||||
std::shared_ptr<RestrictionMap const> m_restriction_map;
|
|
||||||
|
|
||||||
const std::unordered_set<NodeID>& m_barrier_nodes;
|
|
||||||
const std::unordered_set<NodeID>& m_traffic_lights;
|
|
||||||
const CompressedEdgeContainer& m_compressed_edge_container;
|
|
||||||
|
|
||||||
SpeedProfileProperties speed_profile;
|
|
||||||
|
|
||||||
void CompressGeometry();
|
|
||||||
unsigned RenumberEdges();
|
|
||||||
void GenerateEdgeExpandedNodes();
|
|
||||||
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
|
|
||||||
lua_State *lua_state);
|
|
||||||
|
|
||||||
void InsertEdgeBasedNode(const NodeID u, const NodeID v);
|
|
||||||
|
|
||||||
void FlushVectorToStream(std::ofstream &edge_data_file,
|
|
||||||
std::vector<OriginalEdgeData> &original_edge_data_vector) const;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* EDGE_BASED_GRAPH_FACTORY_HPP_ */
|
|
||||||
@@ -1,539 +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 "../algorithms/graph_compressor.hpp"
|
|
||||||
#include "../algorithms/tarjan_scc.hpp"
|
|
||||||
#include "../algorithms/crc32_processor.hpp"
|
|
||||||
#include "../data_structures/compressed_edge_container.hpp"
|
|
||||||
#include "../data_structures/deallocating_vector.hpp"
|
|
||||||
#include "../data_structures/static_rtree.hpp"
|
|
||||||
#include "../data_structures/restriction_map.hpp"
|
|
||||||
|
|
||||||
#include "../util/git_sha.hpp"
|
|
||||||
#include "../util/graph_loader.hpp"
|
|
||||||
#include "../util/integer_range.hpp"
|
|
||||||
#include "../util/lua_util.hpp"
|
|
||||||
#include "../util/osrm_exception.hpp"
|
|
||||||
#include "../util/simple_logger.hpp"
|
|
||||||
#include "../util/string_util.hpp"
|
|
||||||
#include "../util/timing_util.hpp"
|
|
||||||
#include "../typedefs.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>
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
TIMER_START(preparing);
|
|
||||||
|
|
||||||
// Create a new lua state
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Generating edge-expanded graph representation";
|
|
||||||
|
|
||||||
TIMER_START(expansion);
|
|
||||||
|
|
||||||
std::vector<EdgeBasedNode> node_based_edge_list;
|
|
||||||
DeallocatingVector<EdgeBasedEdge> edge_based_edge_list;
|
|
||||||
std::vector<QueryNode> internal_to_external_node_map;
|
|
||||||
auto graph_size = BuildEdgeExpandedGraph(internal_to_external_node_map, node_based_edge_list,
|
|
||||||
edge_based_edge_list);
|
|
||||||
|
|
||||||
auto number_of_node_based_nodes = graph_size.first;
|
|
||||||
auto max_edge_id = graph_size.second;
|
|
||||||
|
|
||||||
TIMER_STOP(expansion);
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "building r-tree ...";
|
|
||||||
TIMER_START(rtree);
|
|
||||||
|
|
||||||
FindComponents(max_edge_id, edge_based_edge_list, node_based_edge_list);
|
|
||||||
|
|
||||||
BuildRTree(node_based_edge_list, internal_to_external_node_map);
|
|
||||||
|
|
||||||
TIMER_STOP(rtree);
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "writing node map ...";
|
|
||||||
WriteNodeMapping(internal_to_external_node_map);
|
|
||||||
|
|
||||||
// Contracting the edge-expanded graph
|
|
||||||
|
|
||||||
TIMER_START(contraction);
|
|
||||||
std::vector<bool> is_core_node;
|
|
||||||
DeallocatingVector<QueryEdge> contracted_edge_list;
|
|
||||||
ContractGraph(max_edge_id, edge_based_edge_list, contracted_edge_list, is_core_node);
|
|
||||||
TIMER_STOP(contraction);
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Contraction took " << TIMER_SEC(contraction) << " sec";
|
|
||||||
|
|
||||||
std::size_t number_of_used_edges =
|
|
||||||
WriteContractedGraph(max_edge_id, node_based_edge_list, contracted_edge_list);
|
|
||||||
WriteCoreNodeMarker(std::move(is_core_node));
|
|
||||||
|
|
||||||
TIMER_STOP(preparing);
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Preprocessing : " << TIMER_SEC(preparing) << " seconds";
|
|
||||||
SimpleLogger().Write() << "Expansion : " << (number_of_node_based_nodes / TIMER_SEC(expansion))
|
|
||||||
<< " nodes/sec and " << ((max_edge_id + 1) / TIMER_SEC(expansion))
|
|
||||||
<< " edges/sec";
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Prepare::FindComponents(unsigned max_edge_id,
|
|
||||||
const DeallocatingVector<EdgeBasedEdge> &input_edge_list,
|
|
||||||
std::vector<EdgeBasedNode> &input_nodes) const
|
|
||||||
{
|
|
||||||
struct UncontractedEdgeData
|
|
||||||
{
|
|
||||||
};
|
|
||||||
struct InputEdge
|
|
||||||
{
|
|
||||||
unsigned source;
|
|
||||||
unsigned target;
|
|
||||||
UncontractedEdgeData data;
|
|
||||||
|
|
||||||
bool operator<(const InputEdge &rhs) const
|
|
||||||
{
|
|
||||||
return source < rhs.source || (source == rhs.source && target < rhs.target);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const InputEdge &rhs) const
|
|
||||||
{
|
|
||||||
return source == rhs.source && target == rhs.target;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
using UncontractedGraph = StaticGraph<UncontractedEdgeData>;
|
|
||||||
std::vector<InputEdge> edges;
|
|
||||||
edges.reserve(input_edge_list.size() * 2);
|
|
||||||
|
|
||||||
for (const auto &edge : input_edge_list)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT_MSG(static_cast<unsigned int>(std::max(edge.weight, 1)) > 0,
|
|
||||||
"edge distance < 1");
|
|
||||||
if (edge.forward)
|
|
||||||
{
|
|
||||||
edges.push_back({edge.source, edge.target, {}});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (edge.backward)
|
|
||||||
{
|
|
||||||
edges.push_back({edge.target, edge.source, {}});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect forward and backward nodes of each edge
|
|
||||||
for (const auto &node : input_nodes)
|
|
||||||
{
|
|
||||||
if (node.reverse_edge_based_node_id != SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
edges.push_back({node.forward_edge_based_node_id, node.reverse_edge_based_node_id, {}});
|
|
||||||
edges.push_back({node.reverse_edge_based_node_id, node.forward_edge_based_node_id, {}});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tbb::parallel_sort(edges.begin(), edges.end());
|
|
||||||
auto new_end = std::unique(edges.begin(), edges.end());
|
|
||||||
edges.resize(new_end - edges.begin());
|
|
||||||
|
|
||||||
auto uncontractor_graph = std::make_shared<UncontractedGraph>(max_edge_id + 1, edges);
|
|
||||||
|
|
||||||
TarjanSCC<UncontractedGraph> component_search(
|
|
||||||
std::const_pointer_cast<const UncontractedGraph>(uncontractor_graph));
|
|
||||||
component_search.run();
|
|
||||||
|
|
||||||
for (auto &node : input_nodes)
|
|
||||||
{
|
|
||||||
auto forward_component = component_search.get_component_id(node.forward_edge_based_node_id);
|
|
||||||
BOOST_ASSERT(node.reverse_edge_based_node_id == SPECIAL_EDGEID ||
|
|
||||||
forward_component ==
|
|
||||||
component_search.get_component_id(node.reverse_edge_based_node_id));
|
|
||||||
|
|
||||||
const unsigned component_size = component_search.get_component_size(forward_component);
|
|
||||||
const bool is_tiny_component = component_size < 1000;
|
|
||||||
node.component_id = is_tiny_component ? (1 + forward_component) : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Prepare::WriteCoreNodeMarker(std::vector<bool> &&in_is_core_node) const
|
|
||||||
{
|
|
||||||
std::vector<bool> is_core_node(in_is_core_node);
|
|
||||||
std::vector<char> unpacked_bool_flags(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 std::vector<EdgeBasedNode> &node_based_edge_list,
|
|
||||||
const DeallocatingVector<QueryEdge> &contracted_edge_list)
|
|
||||||
{
|
|
||||||
const unsigned crc32_value = CalculateEdgeChecksum(node_based_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";
|
|
||||||
|
|
||||||
const unsigned node_array_size = node_array.size();
|
|
||||||
// serialize crc32, aka checksum
|
|
||||||
hsgr_output_stream.write((char *)&crc32_value, sizeof(unsigned));
|
|
||||||
// serialize number of nodes
|
|
||||||
hsgr_output_stream.write((char *)&node_array_size, sizeof(unsigned));
|
|
||||||
// serialize number of edges
|
|
||||||
hsgr_output_stream.write((char *)&contracted_edge_count, sizeof(unsigned));
|
|
||||||
// serialize all nodes
|
|
||||||
if (node_array_size > 0)
|
|
||||||
{
|
|
||||||
hsgr_output_stream.write((char *)&node_array[0],
|
|
||||||
sizeof(StaticGraph<EdgeData>::NodeArrayEntry) * node_array_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// serialize all edges
|
|
||||||
SimpleLogger().Write() << "Building edge array";
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned Prepare::CalculateEdgeChecksum(const std::vector<EdgeBasedNode> &node_based_edge_list)
|
|
||||||
{
|
|
||||||
RangebasedCRC32 crc32;
|
|
||||||
if (crc32.using_hardware())
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "using hardware based CRC32 computation";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "using software based CRC32 computation";
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned crc32_value = crc32(node_based_edge_list);
|
|
||||||
SimpleLogger().Write() << "CRC32: " << crc32_value;
|
|
||||||
|
|
||||||
return crc32_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Setups scripting environment (lua-scripting)
|
|
||||||
Also initializes speed profile.
|
|
||||||
*/
|
|
||||||
void Prepare::SetupScriptingEnvironment(lua_State *lua_state, SpeedProfileProperties &speed_profile)
|
|
||||||
{
|
|
||||||
// open utility libraries string library;
|
|
||||||
luaL_openlibs(lua_state);
|
|
||||||
|
|
||||||
// adjust lua load path
|
|
||||||
luaAddScriptFolderToLoadPath(lua_state, config.profile_path.string().c_str());
|
|
||||||
|
|
||||||
// Now call our function in a lua script
|
|
||||||
if (0 != luaL_dofile(lua_state, config.profile_path.string().c_str()))
|
|
||||||
{
|
|
||||||
std::stringstream msg;
|
|
||||||
msg << lua_tostring(lua_state, -1) << " occured in scripting block";
|
|
||||||
throw osrm::exception(msg.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != luaL_dostring(lua_state, "return traffic_signal_penalty\n"))
|
|
||||||
{
|
|
||||||
std::stringstream msg;
|
|
||||||
msg << lua_tostring(lua_state, -1) << " occured in scripting block";
|
|
||||||
throw osrm::exception(msg.str());
|
|
||||||
}
|
|
||||||
speed_profile.traffic_signal_penalty = 10 * lua_tointeger(lua_state, -1);
|
|
||||||
SimpleLogger().Write(logDEBUG)
|
|
||||||
<< "traffic_signal_penalty: " << speed_profile.traffic_signal_penalty;
|
|
||||||
|
|
||||||
if (0 != luaL_dostring(lua_state, "return u_turn_penalty\n"))
|
|
||||||
{
|
|
||||||
std::stringstream msg;
|
|
||||||
msg << lua_tostring(lua_state, -1) << " occured in scripting block";
|
|
||||||
throw osrm::exception(msg.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
speed_profile.u_turn_penalty = 10 * lua_tointeger(lua_state, -1);
|
|
||||||
speed_profile.has_turn_penalty_function = lua_function_exists(lua_state, "turn_function");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Build load restrictions from .restriction file
|
|
||||||
*/
|
|
||||||
std::shared_ptr<RestrictionMap> Prepare::LoadRestrictionMap()
|
|
||||||
{
|
|
||||||
boost::filesystem::ifstream input_stream(config.restrictions_path,
|
|
||||||
std::ios::in | std::ios::binary);
|
|
||||||
|
|
||||||
std::vector<TurnRestriction> restriction_list;
|
|
||||||
loadRestrictionsFromFile(input_stream, restriction_list);
|
|
||||||
|
|
||||||
SimpleLogger().Write() << " - " << restriction_list.size() << " restrictions.";
|
|
||||||
|
|
||||||
return std::make_shared<RestrictionMap>(restriction_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Load node based graph from .osrm file
|
|
||||||
*/
|
|
||||||
std::shared_ptr<NodeBasedDynamicGraph>
|
|
||||||
Prepare::LoadNodeBasedGraph(std::unordered_set<NodeID> &barrier_nodes,
|
|
||||||
std::unordered_set<NodeID> &traffic_lights,
|
|
||||||
std::vector<QueryNode> &internal_to_external_node_map)
|
|
||||||
{
|
|
||||||
std::vector<NodeBasedEdge> edge_list;
|
|
||||||
|
|
||||||
boost::filesystem::ifstream input_stream(config.osrm_input_path,
|
|
||||||
std::ios::in | std::ios::binary);
|
|
||||||
|
|
||||||
std::vector<NodeID> barrier_list;
|
|
||||||
std::vector<NodeID> traffic_light_list;
|
|
||||||
NodeID number_of_node_based_nodes = loadNodesFromFile(
|
|
||||||
input_stream, barrier_list, traffic_light_list, internal_to_external_node_map);
|
|
||||||
|
|
||||||
SimpleLogger().Write() << " - " << barrier_list.size() << " bollard nodes, "
|
|
||||||
<< traffic_light_list.size() << " traffic lights";
|
|
||||||
|
|
||||||
// insert into unordered sets for fast lookup
|
|
||||||
barrier_nodes.insert(barrier_list.begin(), barrier_list.end());
|
|
||||||
traffic_lights.insert(traffic_light_list.begin(), traffic_light_list.end());
|
|
||||||
|
|
||||||
barrier_list.clear();
|
|
||||||
barrier_list.shrink_to_fit();
|
|
||||||
traffic_light_list.clear();
|
|
||||||
traffic_light_list.shrink_to_fit();
|
|
||||||
|
|
||||||
loadEdgesFromFile(input_stream, edge_list);
|
|
||||||
|
|
||||||
if (edge_list.empty())
|
|
||||||
{
|
|
||||||
SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
|
|
||||||
return std::shared_ptr<NodeBasedDynamicGraph>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return NodeBasedDynamicGraphFromEdges(number_of_node_based_nodes, edge_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Building an edge-expanded graph from node-based input and turn restrictions
|
|
||||||
*/
|
|
||||||
std::pair<std::size_t, std::size_t>
|
|
||||||
Prepare::BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_node_map,
|
|
||||||
std::vector<EdgeBasedNode> &node_based_edge_list,
|
|
||||||
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list)
|
|
||||||
{
|
|
||||||
lua_State *lua_state = luaL_newstate();
|
|
||||||
luabind::open(lua_state);
|
|
||||||
|
|
||||||
SpeedProfileProperties speed_profile;
|
|
||||||
SetupScriptingEnvironment(lua_state, speed_profile);
|
|
||||||
|
|
||||||
std::unordered_set<NodeID> barrier_nodes;
|
|
||||||
std::unordered_set<NodeID> traffic_lights;
|
|
||||||
|
|
||||||
auto restriction_map = LoadRestrictionMap();
|
|
||||||
auto node_based_graph =
|
|
||||||
LoadNodeBasedGraph(barrier_nodes, traffic_lights, internal_to_external_node_map);
|
|
||||||
|
|
||||||
CompressedEdgeContainer compressed_edge_container;
|
|
||||||
GraphCompressor graph_compressor(speed_profile);
|
|
||||||
graph_compressor.Compress(barrier_nodes, traffic_lights, *restriction_map, *node_based_graph,
|
|
||||||
compressed_edge_container);
|
|
||||||
|
|
||||||
EdgeBasedGraphFactory edge_based_graph_factory(
|
|
||||||
node_based_graph, compressed_edge_container, barrier_nodes, traffic_lights,
|
|
||||||
std::const_pointer_cast<RestrictionMap const>(restriction_map),
|
|
||||||
internal_to_external_node_map, speed_profile);
|
|
||||||
|
|
||||||
compressed_edge_container.SerializeInternalVector(config.geometry_output_path);
|
|
||||||
|
|
||||||
edge_based_graph_factory.Run(config.edge_output_path, lua_state);
|
|
||||||
lua_close(lua_state);
|
|
||||||
|
|
||||||
edge_based_graph_factory.GetEdgeBasedEdges(edge_based_edge_list);
|
|
||||||
edge_based_graph_factory.GetEdgeBasedNodes(node_based_edge_list);
|
|
||||||
auto max_edge_id = edge_based_graph_factory.GetHighestEdgeID();
|
|
||||||
|
|
||||||
const std::size_t number_of_node_based_nodes = node_based_graph->GetNumberOfNodes();
|
|
||||||
return std::make_pair(number_of_node_based_nodes, max_edge_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\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)
|
|
||||||
{
|
|
||||||
Contractor contractor(max_edge_id + 1, edge_based_edge_list);
|
|
||||||
contractor.Run(config.core_factor);
|
|
||||||
contractor.GetEdges(contracted_edge_list);
|
|
||||||
contractor.GetCoreMarker(is_core_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Writing info on original (node-based) nodes
|
|
||||||
*/
|
|
||||||
void Prepare::WriteNodeMapping(const std::vector<QueryNode> &internal_to_external_node_map)
|
|
||||||
{
|
|
||||||
boost::filesystem::ofstream node_stream(config.node_output_path, std::ios::binary);
|
|
||||||
const unsigned size_of_mapping = internal_to_external_node_map.size();
|
|
||||||
node_stream.write((char *)&size_of_mapping, sizeof(unsigned));
|
|
||||||
if (size_of_mapping > 0)
|
|
||||||
{
|
|
||||||
node_stream.write((char *)internal_to_external_node_map.data(),
|
|
||||||
size_of_mapping * sizeof(QueryNode));
|
|
||||||
}
|
|
||||||
node_stream.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Building rtree-based nearest-neighbor data structure
|
|
||||||
|
|
||||||
Saves tree into '.ramIndex' and leaves into '.fileIndex'.
|
|
||||||
*/
|
|
||||||
void Prepare::BuildRTree(const std::vector<EdgeBasedNode> &node_based_edge_list,
|
|
||||||
const std::vector<QueryNode> &internal_to_external_node_map)
|
|
||||||
{
|
|
||||||
StaticRTree<EdgeBasedNode>(node_based_edge_list, config.rtree_nodes_output_path.c_str(),
|
|
||||||
config.rtree_leafs_output_path.c_str(),
|
|
||||||
internal_to_external_node_map);
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright notice, this list
|
|
||||||
of conditions and the following disclaimer.
|
|
||||||
Redistributions in binary form must reproduce the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer in the documentation and/or
|
|
||||||
other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PROCESSING_CHAIN_HPP
|
|
||||||
#define PROCESSING_CHAIN_HPP
|
|
||||||
|
|
||||||
#include "contractor_options.hpp"
|
|
||||||
#include "edge_based_graph_factory.hpp"
|
|
||||||
#include "../data_structures/query_edge.hpp"
|
|
||||||
#include "../data_structures/static_graph.hpp"
|
|
||||||
|
|
||||||
struct SpeedProfileProperties;
|
|
||||||
struct EdgeBasedNode;
|
|
||||||
struct lua_State;
|
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief class of 'prepare' utility.
|
|
||||||
*/
|
|
||||||
class Prepare
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using EdgeData = QueryEdge::EdgeData;
|
|
||||||
using InputEdge = DynamicGraph<EdgeData>::InputEdge;
|
|
||||||
using StaticEdge = StaticGraph<EdgeData>::InputEdge;
|
|
||||||
|
|
||||||
explicit Prepare(ContractorConfig contractor_config) : config(std::move(contractor_config)) {}
|
|
||||||
Prepare(const Prepare &) = delete;
|
|
||||||
~Prepare();
|
|
||||||
|
|
||||||
int Run();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void SetupScriptingEnvironment(lua_State *myLuaState, SpeedProfileProperties &speed_profile);
|
|
||||||
unsigned CalculateEdgeChecksum(const std::vector<EdgeBasedNode> &node_based_edge_list);
|
|
||||||
void ContractGraph(const unsigned max_edge_id,
|
|
||||||
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
|
||||||
DeallocatingVector<QueryEdge> &contracted_edge_list,
|
|
||||||
std::vector<bool> &is_core_node);
|
|
||||||
void WriteCoreNodeMarker(std::vector<bool> &&is_core_node) const;
|
|
||||||
std::size_t WriteContractedGraph(unsigned number_of_edge_based_nodes,
|
|
||||||
const std::vector<EdgeBasedNode> &node_based_edge_list,
|
|
||||||
const DeallocatingVector<QueryEdge> &contracted_edge_list);
|
|
||||||
std::shared_ptr<RestrictionMap> LoadRestrictionMap();
|
|
||||||
std::shared_ptr<NodeBasedDynamicGraph>
|
|
||||||
LoadNodeBasedGraph(std::unordered_set<NodeID> &barrier_nodes,
|
|
||||||
std::unordered_set<NodeID> &traffic_lights,
|
|
||||||
std::vector<QueryNode> &internal_to_external_node_map);
|
|
||||||
std::pair<std::size_t, std::size_t>
|
|
||||||
BuildEdgeExpandedGraph(std::vector<QueryNode> &internal_to_external_node_map,
|
|
||||||
std::vector<EdgeBasedNode> &node_based_edge_list,
|
|
||||||
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list);
|
|
||||||
void WriteNodeMapping(const std::vector<QueryNode> &internal_to_external_node_map);
|
|
||||||
void FindComponents(unsigned max_edge_id,
|
|
||||||
const DeallocatingVector<EdgeBasedEdge> &edges,
|
|
||||||
std::vector<EdgeBasedNode> &nodes) const;
|
|
||||||
void BuildRTree(const std::vector<EdgeBasedNode> &node_based_edge_list,
|
|
||||||
const std::vector<QueryNode> &internal_to_external_node_map);
|
|
||||||
|
|
||||||
private:
|
|
||||||
ContractorConfig config;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PROCESSING_CHAIN_HPP
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#ifndef SPEED_PROFILE_PROPERTIES_HPP
|
|
||||||
#define SPEED_PROFILE_PROPERTIES_HPP
|
|
||||||
|
|
||||||
struct SpeedProfileProperties
|
|
||||||
{
|
|
||||||
SpeedProfileProperties()
|
|
||||||
: traffic_signal_penalty(0), u_turn_penalty(0), has_turn_penalty_function(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int traffic_signal_penalty;
|
|
||||||
int u_turn_penalty;
|
|
||||||
bool has_turn_penalty_function;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -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,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 CONCURRENT_QUEUE_HPP
|
|
||||||
#define CONCURRENT_QUEUE_HPP
|
|
||||||
|
|
||||||
#include <boost/circular_buffer.hpp>
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
template <typename Data> class ConcurrentQueue
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit ConcurrentQueue(const size_t max_size) : m_internal_queue(max_size) {}
|
|
||||||
|
|
||||||
inline void push(const Data &data)
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
|
||||||
m_not_full.wait(lock, [this]
|
|
||||||
{
|
|
||||||
return m_internal_queue.size() < m_internal_queue.capacity();
|
|
||||||
});
|
|
||||||
m_internal_queue.push_back(data);
|
|
||||||
m_not_empty.notify_one();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool empty() const { return m_internal_queue.empty(); }
|
|
||||||
|
|
||||||
inline void wait_and_pop(Data &popped_value)
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
|
||||||
m_not_empty.wait(lock, [this]
|
|
||||||
{
|
|
||||||
return !m_internal_queue.empty();
|
|
||||||
});
|
|
||||||
popped_value = m_internal_queue.front();
|
|
||||||
m_internal_queue.pop_front();
|
|
||||||
m_not_full.notify_one();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool try_pop(Data &popped_value)
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
|
||||||
if (m_internal_queue.empty())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
popped_value = m_internal_queue.front();
|
|
||||||
m_internal_queue.pop_front();
|
|
||||||
m_not_full.notify_one();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
boost::circular_buffer<Data> m_internal_queue;
|
|
||||||
std::mutex m_mutex;
|
|
||||||
std::condition_variable m_not_empty;
|
|
||||||
std::condition_variable m_not_full;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CONCURRENT_QUEUE_HPP
|
|
||||||
@@ -1,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,111 +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_id(-1), fwd_segment_position(std::numeric_limits<unsigned short>::max()),
|
|
||||||
forward_travel_mode(TRAVEL_MODE_INACCESSIBLE),
|
|
||||||
backward_travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit EdgeBasedNode(NodeID forward_edge_based_node_id,
|
|
||||||
NodeID reverse_edge_based_node_id,
|
|
||||||
NodeID u,
|
|
||||||
NodeID v,
|
|
||||||
unsigned name_id,
|
|
||||||
int forward_weight,
|
|
||||||
int reverse_weight,
|
|
||||||
int forward_offset,
|
|
||||||
int reverse_offset,
|
|
||||||
unsigned packed_geometry_id,
|
|
||||||
unsigned component_id,
|
|
||||||
unsigned short fwd_segment_position,
|
|
||||||
TravelMode forward_travel_mode,
|
|
||||||
TravelMode backward_travel_mode)
|
|
||||||
: forward_edge_based_node_id(forward_edge_based_node_id),
|
|
||||||
reverse_edge_based_node_id(reverse_edge_based_node_id), u(u), v(v), name_id(name_id),
|
|
||||||
forward_weight(forward_weight), reverse_weight(reverse_weight),
|
|
||||||
forward_offset(forward_offset), reverse_offset(reverse_offset),
|
|
||||||
packed_geometry_id(packed_geometry_id), component_id(component_id),
|
|
||||||
fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode),
|
|
||||||
backward_travel_mode(backward_travel_mode)
|
|
||||||
{
|
|
||||||
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; }
|
|
||||||
|
|
||||||
bool is_in_tiny_cc() const { return 0 != component_id; }
|
|
||||||
|
|
||||||
NodeID forward_edge_based_node_id; // needed for edge-expanded graph
|
|
||||||
NodeID reverse_edge_based_node_id; // needed for edge-expanded graph
|
|
||||||
NodeID u; // indices into the coordinates array
|
|
||||||
NodeID v; // indices into the coordinates array
|
|
||||||
unsigned name_id; // id of the edge name
|
|
||||||
int forward_weight; // weight of the edge
|
|
||||||
int reverse_weight; // weight in the other direction (may be different)
|
|
||||||
int forward_offset; // prefix sum of the weight up the edge TODO: short must suffice
|
|
||||||
int reverse_offset; // prefix sum of the weight from the edge TODO: short must suffice
|
|
||||||
unsigned packed_geometry_id; // if set, then the edge represents a packed geometry
|
|
||||||
unsigned component_id;
|
|
||||||
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, unsigned int node_id, bool barrier, bool traffic_lights)
|
|
||||||
: QueryNode(lat, lon, node_id), barrier(barrier), traffic_lights(traffic_lights)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalMemoryNode::ExternalMemoryNode() : barrier(false), traffic_lights(false) {}
|
|
||||||
|
|
||||||
ExternalMemoryNode ExternalMemoryNode::min_value()
|
|
||||||
{
|
|
||||||
return ExternalMemoryNode(0, 0, 0, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalMemoryNode ExternalMemoryNode::max_value()
|
|
||||||
{
|
|
||||||
return ExternalMemoryNode(std::numeric_limits<int>::max(), std::numeric_limits<int>::max(),
|
|
||||||
std::numeric_limits<unsigned>::max(), false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ExternalMemoryNodeSTXXLCompare::operator()(const ExternalMemoryNode &left,
|
|
||||||
const ExternalMemoryNode &right) const
|
|
||||||
{
|
|
||||||
return left.node_id < right.node_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalMemoryNodeSTXXLCompare::value_type ExternalMemoryNodeSTXXLCompare::max_value()
|
|
||||||
{
|
|
||||||
return ExternalMemoryNode::max_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
ExternalMemoryNodeSTXXLCompare::value_type ExternalMemoryNodeSTXXLCompare::min_value()
|
|
||||||
{
|
|
||||||
return ExternalMemoryNode::min_value();
|
|
||||||
}
|
|
||||||
@@ -1,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, NodeID 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].second);
|
|
||||||
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,112 +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), 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,
|
|
||||||
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), 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,86 +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,
|
|
||||||
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 is_split : 1;
|
|
||||||
TravelMode travel_mode : 4;
|
|
||||||
};
|
|
||||||
|
|
||||||
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,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 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, TravelMode travel_mode)
|
|
||||||
: distance(distance), edge_id(edge_id), name_id(name_id),
|
|
||||||
access_restricted(access_restricted), reversed(reversed),
|
|
||||||
roundabout(roundabout), travel_mode(travel_mode)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int distance;
|
|
||||||
unsigned edge_id;
|
|
||||||
unsigned name_id;
|
|
||||||
bool access_restricted : 1;
|
|
||||||
bool reversed : 1;
|
|
||||||
bool roundabout : 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
|
|
||||||
/// The since DynamicGraph expects directed edges, we need to insert
|
|
||||||
/// two edges for undirected edges.
|
|
||||||
inline std::shared_ptr<NodeBasedDynamicGraph>
|
|
||||||
NodeBasedDynamicGraphFromEdges(int 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;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
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 = NodeID;
|
|
||||||
bool operator()(const NodeID left, const NodeID right) const { return left < right; }
|
|
||||||
value_type max_value() { return 0xffffffff; }
|
|
||||||
value_type min_value() { return 0x0; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#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,106 +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,
|
|
||||||
unsigned component_id,
|
|
||||||
FixedPointCoordinate &location,
|
|
||||||
unsigned short fwd_segment_position,
|
|
||||||
TravelMode forward_travel_mode,
|
|
||||||
TravelMode backward_travel_mode)
|
|
||||||
: forward_node_id(forward_node_id), reverse_node_id(reverse_node_id), name_id(name_id),
|
|
||||||
forward_weight(forward_weight), reverse_weight(reverse_weight),
|
|
||||||
forward_offset(forward_offset), reverse_offset(reverse_offset),
|
|
||||||
packed_geometry_id(packed_geometry_id), component_id(component_id), location(location),
|
|
||||||
fwd_segment_position(fwd_segment_position), forward_travel_mode(forward_travel_mode),
|
|
||||||
backward_travel_mode(backward_travel_mode)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PhantomNode::PhantomNode()
|
|
||||||
: forward_node_id(SPECIAL_NODEID), reverse_node_id(SPECIAL_NODEID),
|
|
||||||
name_id(std::numeric_limits<unsigned>::max()), forward_weight(INVALID_EDGE_WEIGHT),
|
|
||||||
reverse_weight(INVALID_EDGE_WEIGHT), forward_offset(0), reverse_offset(0),
|
|
||||||
packed_geometry_id(SPECIAL_EDGEID), component_id(std::numeric_limits<unsigned>::max()),
|
|
||||||
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)) &&
|
|
||||||
(name_id != INVALID_NAMEID);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PhantomNode::is_in_tiny_component() const { return component_id != 0; }
|
|
||||||
|
|
||||||
bool PhantomNode::is_valid() const { return location.is_valid() && (name_id != INVALID_NAMEID); }
|
|
||||||
|
|
||||||
bool PhantomNode::operator==(const PhantomNode &other) const { return location == other.location; }
|
|
||||||
@@ -1,156 +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,
|
|
||||||
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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
unsigned component_id;
|
|
||||||
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 is_in_tiny_component() const;
|
|
||||||
|
|
||||||
bool operator==(const PhantomNode &other) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
static_assert(sizeof(PhantomNode) == 48, "PhantomNode has more padding then expected");
|
|
||||||
|
|
||||||
using PhantomNodeArray = std::vector<std::vector<PhantomNode>>;
|
|
||||||
|
|
||||||
class phantom_node_pair : public std::pair<PhantomNode, PhantomNode>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PhantomNodeLists
|
|
||||||
{
|
|
||||||
std::vector<PhantomNode> source_phantom_list;
|
|
||||||
std::vector<PhantomNode> target_phantom_list;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PhantomNodes
|
|
||||||
{
|
|
||||||
PhantomNode source_phantom;
|
|
||||||
PhantomNode target_phantom;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline std::ostream &operator<<(std::ostream &out, const PhantomNodes &pn)
|
|
||||||
{
|
|
||||||
out << "source_coord: " << pn.source_phantom.location << "\n";
|
|
||||||
out << "target_coord: " << pn.target_phantom.location << std::endl;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::ostream &operator<<(std::ostream &out, const PhantomNode &pn)
|
|
||||||
{
|
|
||||||
out << "node1: " << pn.forward_node_id << ", "
|
|
||||||
<< "node2: " << pn.reverse_node_id << ", "
|
|
||||||
<< "name: " << pn.name_id << ", "
|
|
||||||
<< "fwd-w: " << pn.forward_weight << ", "
|
|
||||||
<< "rev-w: " << pn.reverse_weight << ", "
|
|
||||||
<< "fwd-o: " << pn.forward_offset << ", "
|
|
||||||
<< "rev-o: " << pn.reverse_offset << ", "
|
|
||||||
<< "geom: " << pn.packed_geometry_id << ", "
|
|
||||||
<< "comp: " << 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 = NodeID; // type of NodeID
|
|
||||||
using value_type = int; // type of lat,lons
|
|
||||||
|
|
||||||
explicit QueryNode(int lat, int lon, NodeID node_id) : lat(lat), lon(lon), node_id(node_id) {}
|
|
||||||
QueryNode()
|
|
||||||
: lat(std::numeric_limits<int>::max()), lon(std::numeric_limits<int>::max()),
|
|
||||||
node_id(std::numeric_limits<unsigned>::max())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int lat;
|
|
||||||
int lon;
|
|
||||||
NodeID node_id;
|
|
||||||
|
|
||||||
static QueryNode min_value()
|
|
||||||
{
|
|
||||||
return QueryNode(static_cast<int>(-90 * COORDINATE_PRECISION),
|
|
||||||
static_cast<int>(-180 * COORDINATE_PRECISION),
|
|
||||||
std::numeric_limits<NodeID>::min());
|
|
||||||
}
|
|
||||||
|
|
||||||
static QueryNode max_value()
|
|
||||||
{
|
|
||||||
return QueryNode(static_cast<int>(90 * COORDINATE_PRECISION),
|
|
||||||
static_cast<int>(180 * COORDINATE_PRECISION),
|
|
||||||
std::numeric_limits<NodeID>::max());
|
|
||||||
}
|
|
||||||
|
|
||||||
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(_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,211 +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::euclidean_distance(
|
|
||||||
location, FixedPointCoordinate(max_lat, location.lon));
|
|
||||||
break;
|
|
||||||
case SOUTH:
|
|
||||||
min_dist = coordinate_calculation::euclidean_distance(
|
|
||||||
location, FixedPointCoordinate(min_lat, location.lon));
|
|
||||||
break;
|
|
||||||
case WEST:
|
|
||||||
min_dist = coordinate_calculation::euclidean_distance(
|
|
||||||
location, FixedPointCoordinate(location.lat, min_lon));
|
|
||||||
break;
|
|
||||||
case EAST:
|
|
||||||
min_dist = coordinate_calculation::euclidean_distance(
|
|
||||||
location, FixedPointCoordinate(location.lat, max_lon));
|
|
||||||
break;
|
|
||||||
case NORTH_EAST:
|
|
||||||
min_dist = coordinate_calculation::euclidean_distance(
|
|
||||||
location, FixedPointCoordinate(max_lat, max_lon));
|
|
||||||
break;
|
|
||||||
case NORTH_WEST:
|
|
||||||
min_dist = coordinate_calculation::euclidean_distance(
|
|
||||||
location, FixedPointCoordinate(max_lat, min_lon));
|
|
||||||
break;
|
|
||||||
case SOUTH_EAST:
|
|
||||||
min_dist = coordinate_calculation::euclidean_distance(
|
|
||||||
location, FixedPointCoordinate(min_lat, max_lon));
|
|
||||||
break;
|
|
||||||
case SOUTH_WEST:
|
|
||||||
min_dist = coordinate_calculation::euclidean_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::euclidean_distance(location, upper_left),
|
|
||||||
coordinate_calculation::euclidean_distance(location, upper_right)));
|
|
||||||
|
|
||||||
min_max_dist =
|
|
||||||
std::min(min_max_dist,
|
|
||||||
std::max(coordinate_calculation::euclidean_distance(location, upper_right),
|
|
||||||
coordinate_calculation::euclidean_distance(location, lower_right)));
|
|
||||||
|
|
||||||
min_max_dist =
|
|
||||||
std::min(min_max_dist,
|
|
||||||
std::max(coordinate_calculation::euclidean_distance(location, lower_right),
|
|
||||||
coordinate_calculation::euclidean_distance(location, lower_left)));
|
|
||||||
|
|
||||||
min_max_dist =
|
|
||||||
std::min(min_max_dist,
|
|
||||||
std::max(coordinate_calculation::euclidean_distance(location, lower_left),
|
|
||||||
coordinate_calculation::euclidean_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;
|
|
||||||
}
|
|
||||||
|
|
||||||
friend std::ostream &operator<<(std::ostream &out, const RectangleInt2D &rect)
|
|
||||||
{
|
|
||||||
out << rect.min_lat / COORDINATE_PRECISION << "," << rect.min_lon / COORDINATE_PRECISION
|
|
||||||
<< " " << rect.max_lat / COORDINATE_PRECISION << ","
|
|
||||||
<< rect.max_lon / COORDINATE_PRECISION;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,141 +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 <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)
|
|
||||||
{
|
|
||||||
uturns.resize(coordinates.size(), uturn_default);
|
|
||||||
if (!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::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)));
|
|
||||||
}
|
|
||||||
|
|
||||||
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,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 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 bearing; // more than enough [0..3600] fits into 12 bits
|
|
||||||
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),
|
|
||||||
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),
|
|
||||||
bearing(0), turn_instruction(turn_instruction), travel_mode(travel_mode),
|
|
||||||
necessary(turn_instruction != TurnInstruction::NoTurn), is_via_location(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* SEGMENT_INFORMATION_HPP */
|
|
||||||
@@ -1,382 +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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
// Remove shared memory on destruction
|
|
||||||
class shm_remove
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
shm_remove(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;
|
|
||||||
};
|
|
||||||
|
|
||||||
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
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user