Compare commits
4402 Commits
Author | SHA1 | Date | |
---|---|---|---|
6ab6564d42 | |||
513966056b | |||
2c91c0c259 | |||
|
c59ad69d6a | ||
|
61464fc2bd | ||
|
6f235cca15 | ||
|
3614af7f64 | ||
|
48e8382785 | ||
|
becfd8a56d | ||
|
4f1c62a768 | ||
|
09a716a9e5 | ||
|
676f6d4704 | ||
|
f636dbfd44 | ||
|
5f67e715af | ||
|
203314b1aa | ||
|
e5e25a1aca | ||
|
84f12c7c6d | ||
|
7802f86bd6 | ||
|
43afec3b39 | ||
|
2da7ca5338 | ||
|
8ae9abaa63 | ||
|
d3638ace59 | ||
|
c2f877eb9d | ||
|
825132eec7 | ||
|
7436835244 | ||
|
5e6fdda16b | ||
|
f5598efcff | ||
|
ab771c6142 | ||
|
f1510b758d | ||
|
4930d2ef05 | ||
|
57b792c768 | ||
|
d0ed29adb7 | ||
|
bdc6ed8a53 | ||
|
93c0e1dab3 | ||
|
cacb1b23f9 | ||
|
0e17869e21 | ||
|
5a48ce85b3 | ||
|
7d72dfebf7 | ||
|
3d01d96036 | ||
|
e8da3d9231 | ||
|
d9ce9cf780 | ||
|
3285ce3b2f | ||
|
f1eabc3ecc | ||
|
c3f2a6cdb9 | ||
|
97f676d5a3 | ||
|
7ffc08be28 | ||
|
feb9389436 | ||
|
a0eda3e7d7 | ||
|
7652f6ca6b | ||
|
aa4e6b1cf3 | ||
|
de2f392960 | ||
|
0188d2bccd | ||
|
054161fc7e | ||
|
89435aa87f | ||
|
0cbb23abe1 | ||
|
a2915f78c5 | ||
|
99cb17aed3 | ||
|
8fd8d0c24a | ||
|
c57b0d28b0 | ||
|
523ee762f0 | ||
|
feeed75cf1 | ||
|
c7ee1a59eb | ||
|
2725202771 | ||
|
42fafdcdfe | ||
|
c8de759cd6 | ||
|
fb9d1cefcc | ||
|
a9b1bd88d3 | ||
|
1ff096ac5c | ||
|
0ea757ed02 | ||
|
42cbca0ff0 | ||
|
c1ed73126d | ||
|
01b1673c8a | ||
|
d4dc297f75 | ||
|
9aaab7a53f | ||
|
1a6f4c44e7 | ||
|
163a2cfe3c | ||
|
667fd198ac | ||
|
b7a990d0b5 | ||
|
8306ed8ae3 | ||
|
640df69aa1 | ||
|
8b48e2ccc6 | ||
|
babdced52f | ||
|
21607e0cb2 | ||
|
24646aada9 | ||
|
51b74a99aa | ||
|
ed5003b502 | ||
|
46dc660801 | ||
|
73fb53cf36 | ||
|
efe6840d08 | ||
|
d259848456 | ||
|
8a82d3929c | ||
|
89fce286a7 | ||
|
11c7ddc84d | ||
|
54e50a67a8 | ||
|
c00c157479 | ||
|
ee8e0f890a | ||
|
1e2ffee97c | ||
|
ffc39b8ad2 | ||
|
70969186f6 | ||
|
dff76d31d5 | ||
|
3254686933 | ||
|
a6dfff725b | ||
|
10237b8761 | ||
|
79de092bb2 | ||
|
82aa369db3 | ||
|
0583582772 | ||
|
99809e105c | ||
|
6d361ced41 | ||
|
790fa901c7 | ||
|
7f9d591ab7 | ||
|
b503e96a98 | ||
|
d691af4860 | ||
|
befd9dc5ae | ||
|
4968d7f9d9 | ||
|
c26f0612d1 | ||
|
de41299eda | ||
|
c37bbfd07a | ||
|
0fd1fb2904 | ||
|
7ebd21f39e | ||
|
8ef366e061 | ||
|
367933fc1a | ||
|
c28ba66039 | ||
|
d0e3e2af23 | ||
|
8526cc7d45 | ||
|
016440fc7e | ||
|
6e77d53946 | ||
|
99875b4d24 | ||
|
c315a586f7 | ||
|
69c38401bc | ||
|
e219eb9442 | ||
|
31e31a63d0 | ||
|
b437ce5b33 | ||
|
5723eaaa6a | ||
|
0f7b86b099 | ||
|
14dcf91812 | ||
|
d234c7246c | ||
|
3f9347cfb2 | ||
|
db7946d762 | ||
|
522d0f066e | ||
|
3bb82ce1e2 | ||
|
62e11fd5db | ||
|
503d558e90 | ||
|
af59a9cfae | ||
|
72da455185 | ||
|
0ca913132a | ||
|
134da91fa8 | ||
|
d51631401e | ||
|
d6afe91d8f | ||
|
192d077ada | ||
|
82b73ed9ab | ||
|
0e7c3d8ad4 | ||
|
a63ba91c8f | ||
|
51e04209e3 | ||
|
56ed2cb196 | ||
|
ebd9ab4548 | ||
|
376282d946 | ||
|
53295760ac | ||
|
e590dae5f6 | ||
|
d9df33dd0a | ||
|
95c4523987 | ||
|
26987f9049 | ||
|
7c06726a35 | ||
|
d7c44f0bc0 | ||
|
a4aa153ba4 | ||
|
1204b746d5 | ||
|
076cbd7018 | ||
|
afd340da44 | ||
|
898cbe8da4 | ||
|
16c6f23791 | ||
|
612ca82a06 | ||
|
1215062e4c | ||
|
5292172770 | ||
|
6e5f0d74bd | ||
|
5bab68c737 | ||
|
152a52bc1a | ||
|
c605b1db38 | ||
|
f4189d9487 | ||
|
f983d626ac | ||
|
73b2a86a95 | ||
|
2044398dfd | ||
|
095b726a92 | ||
|
18dcd27a9b | ||
|
a1b3efe260 | ||
|
6d10523440 | ||
|
2bbb347f57 | ||
|
5f82d0c9ba | ||
|
aeaf5e0735 | ||
|
8a186e6f49 | ||
|
2ea168c26c | ||
|
a12625afac | ||
|
8bff55cd85 | ||
|
bb4fd93fab | ||
|
b13820f520 | ||
|
fc12b6c365 | ||
|
cb515ba42f | ||
|
634e7fe392 | ||
|
6ab8728807 | ||
|
0ae5190937 | ||
|
a1c1fefd6e | ||
|
6fa7bd8abd | ||
|
7359d6a21b | ||
|
5dda33fa88 | ||
|
5280ca4e16 | ||
|
2c02d4e5ab | ||
|
54d486ae12 | ||
|
afe34456b9 | ||
|
2f75d6f22b | ||
|
85e6a854aa | ||
|
12f49d6f24 | ||
|
7149547645 | ||
|
565959b389 | ||
|
5c9d0d152c | ||
|
274dcc58a5 | ||
|
d06b23d819 | ||
|
91e9623b31 | ||
|
0021ccef59 | ||
|
061f0a1f14 | ||
|
60e283312c | ||
|
f97e18d285 | ||
|
7b73b977ff | ||
|
5d468f2897 | ||
|
16685d0de9 | ||
|
82897791d1 | ||
|
9ad432c5b2 | ||
|
c1d2c15995 | ||
|
fb1bb7a15b | ||
|
d65e8c7d1e | ||
|
5e5f1f4add | ||
|
9d160a9b5d | ||
|
d143de597d | ||
|
4026ed54c0 | ||
|
895e4bf6d5 | ||
|
cb90d587be | ||
|
284e110f2e | ||
|
ac1edc7675 | ||
|
7be9039f53 | ||
|
52b516e943 | ||
|
f3c03307cb | ||
|
9a4b4648f4 | ||
|
41fd947ebd | ||
|
e328031661 | ||
|
b7daa7e641 | ||
|
21888334dd | ||
|
395cc6e9df | ||
|
902bfc7806 | ||
|
3c5d99b4cb | ||
|
ef8f3d7508 | ||
|
660cea8fcc | ||
|
be353630d5 | ||
|
9b834810d5 | ||
|
1c65ea2194 | ||
|
96f5780f06 | ||
|
c003ac1055 | ||
|
9a638f3568 | ||
|
2cf957148b | ||
|
b17cbb4c47 | ||
|
d8b358e810 | ||
|
b4142cf1a2 | ||
|
06719be2b1 | ||
|
18e5faa113 | ||
|
a46241e45c | ||
|
bfb74c2dad | ||
|
3d5db4511c | ||
|
d74e7b66bd | ||
|
bb18a2b428 | ||
|
c204360aa0 | ||
|
df3c553f4f | ||
|
91895604c9 | ||
|
a98074a051 | ||
|
8e74b7af9d | ||
|
869b3fae82 | ||
|
32fb8607e4 | ||
|
928867c520 | ||
|
972a848094 | ||
|
3cfd0e8334 | ||
|
b4b1aea567 | ||
|
e3c7995b00 | ||
|
7f014bd616 | ||
|
e872f1d6c3 | ||
|
47e5591ed8 | ||
|
9d4dd2595e | ||
|
aadc088084 | ||
|
8f0cd5cf7b | ||
|
624fea6d33 | ||
|
9688e48ad1 | ||
|
51a8486375 | ||
|
440c00064e | ||
|
e5450e8c68 | ||
|
f19247a7ca | ||
|
e7185b4bcb | ||
|
00816722dd | ||
|
589becbfec | ||
|
4e8ee288d9 | ||
|
204fdaff6e | ||
|
1a3d0f7c20 | ||
|
06b1b980bb | ||
|
19d2ec56b8 | ||
|
3d2db20777 | ||
|
59953172e8 | ||
|
79d4363d59 | ||
|
662a8d0a12 | ||
|
f2e284623e | ||
|
c0b79a8d0e | ||
|
1e70b645e4 | ||
|
04c2167c2d | ||
|
2c81083406 | ||
|
472cce6742 | ||
|
ff1af413d6 | ||
|
ffa4256ad3 | ||
|
3da45c1d92 | ||
|
d5cd702242 | ||
|
b120c971a0 | ||
|
eb3bf5cfe3 | ||
|
56a427f839 | ||
|
73a2b91251 | ||
|
34877482e6 | ||
|
b739658681 | ||
|
37cfc7f99d | ||
|
2d1e620429 | ||
|
f6349a7fbe | ||
|
f1f96166c5 | ||
|
8e100ea1a0 | ||
|
f1a6056953 | ||
|
d413d0639d | ||
|
9884684701 | ||
|
0911691008 | ||
|
971f0d3fe2 | ||
|
eb0c089574 | ||
|
8af4f700f7 | ||
|
155ca8b1f1 | ||
|
03001ff90a | ||
|
ba4e7bfa11 | ||
|
38df7d5e05 | ||
|
dca35dcc86 | ||
|
f7478ba80f | ||
|
ec36319232 | ||
|
051e931091 | ||
|
3a029d476c | ||
|
d97fe2322d | ||
|
baca7b70f1 | ||
|
50f5a753ea | ||
|
4ac827a849 | ||
|
def699dafd | ||
|
41dda32546 | ||
|
8d3ebc64dc | ||
|
c15b02ecf6 | ||
|
480807500b | ||
|
e2de71bdcf | ||
|
574060418a | ||
|
9d81eb327a | ||
|
677598a8d8 | ||
|
781a2ad0f8 | ||
|
a613375460 | ||
|
960269f95a | ||
|
ed7b1baacc | ||
|
d4e7b3d60b | ||
|
bd3eb6591e | ||
|
b0b8069ab0 | ||
|
d9d873903f | ||
|
e7acc9df76 | ||
|
b6557b8cac | ||
|
a05d7a8f73 | ||
|
35ff807e1d | ||
|
e554624438 | ||
|
58ba3fc84f | ||
|
dddf83db7b | ||
|
5266ac1635 | ||
|
eb1d399f3b | ||
|
6bf68fb0c6 | ||
|
33b2a193f9 | ||
|
158d260cbb | ||
|
83b17e664c | ||
|
89a9bc9d70 | ||
|
b0a4ad92c4 | ||
|
9a20e8e614 | ||
|
af5efd2abb | ||
|
9ae9a1f6d7 | ||
|
370081ec14 | ||
|
d340f4eabc | ||
|
0e10b94d38 | ||
|
1a5e5df6bd | ||
|
18a0f6c1f8 | ||
|
8510d6850a | ||
|
566cf785f5 | ||
|
687a3cdfbe | ||
|
50d9632ed7 | ||
|
f376225080 | ||
|
fcb7dd2a21 | ||
|
aa06029801 | ||
|
1ce573ef35 | ||
|
cf13a9714d | ||
|
8697a6b14a | ||
|
9a32722634 | ||
|
24d0af6faf | ||
|
b1646622e6 | ||
|
697c2ff88d | ||
|
e181cb325c | ||
|
41af9615cd | ||
|
13067844ee | ||
|
ca68518763 | ||
|
f6065de494 | ||
|
58fbda0483 | ||
|
e693b8963a | ||
|
5b6e82fa9c | ||
|
a7a088d416 | ||
|
43b920bfb5 | ||
|
deacc8fb5c | ||
|
a3f1c2afb0 | ||
|
7e4fbaf4a8 | ||
|
dfc1bfc27e | ||
|
96acdaf0d5 | ||
|
98fd17589d | ||
|
21444ce7cb | ||
|
b840c0be95 | ||
|
17eb39d0a9 | ||
|
c090457f1f | ||
|
7d28b7aa3a | ||
|
1ba8aba466 | ||
|
9f80f6d64d | ||
|
a8362d75b5 | ||
|
df3ed43d70 | ||
|
c021cea770 | ||
|
628784eb7d | ||
|
440fb61f8f | ||
|
f87a324633 | ||
|
2222ee6a67 | ||
|
e033e0b553 | ||
|
c24f917dcf | ||
|
1e98ae7efe | ||
|
55b3260cc3 | ||
|
3451d1ec82 | ||
|
4799b46eeb | ||
|
f6b313e958 | ||
|
d3ab6f1fca | ||
|
523d9e9c05 | ||
|
8e81034bb2 | ||
|
4a47267455 | ||
|
f545f2293e | ||
|
78160c0fe4 | ||
|
a35961ca6a | ||
|
933e36190f | ||
|
03d9e7a8ce | ||
|
7e24dcfd0a | ||
|
cdce2af1c9 | ||
|
3116734bec | ||
|
4d6272b030 | ||
|
a7993eebac | ||
|
2d0b2ca987 | ||
|
699ca2bbd0 | ||
|
8b40c594be | ||
|
909570fd7f | ||
|
df9fda177d | ||
|
d2e7e6e9e6 | ||
|
b9ebe0c369 | ||
|
cd4e6a1fe3 | ||
|
5cac188711 | ||
|
b7fa2c5981 | ||
|
106082f6f8 | ||
|
36d34073da | ||
|
57ed232423 | ||
|
24f12c9d1b | ||
|
bdf2222f6a | ||
|
220ad9fe8c | ||
|
ae6326719a | ||
|
0503a2fcd3 | ||
|
219f2c3aa9 | ||
|
493e821b93 | ||
|
9c3eeffe2c | ||
|
526191256c | ||
|
9861faa456 | ||
|
919fe74c40 | ||
|
365121dac4 | ||
|
cbec111eb6 | ||
|
7d369b9ab9 | ||
|
2c13f2f735 | ||
|
15f0ca8dda | ||
|
d59ecb321e | ||
|
404ebb1898 | ||
|
11b0a2e02a | ||
|
1ada466081 | ||
|
973722d0ec | ||
|
ca5d17adab | ||
|
68dcab7c15 | ||
|
92406da194 | ||
|
6d8cf826d7 | ||
|
48be5a5622 | ||
|
46ab931c64 | ||
|
0b139ff05d | ||
|
9da6cf8764 | ||
|
ee177efe41 | ||
|
fd0f1b60bb | ||
|
9c1c842b79 | ||
|
17f32f4ca1 | ||
|
542c3ba872 | ||
|
f36707d1fb | ||
|
a587b14006 | ||
|
f9ee74d78e | ||
|
eef072234e | ||
|
a9fce74e63 | ||
|
432d49e23d | ||
|
e4aaf07879 | ||
|
d316ff9d41 | ||
|
921c2f9482 | ||
|
62c8b70f78 | ||
|
f520379419 | ||
|
d8d9ac8686 | ||
|
016c77a4de | ||
|
0205cbc578 | ||
|
28895373fb | ||
|
018a9bc804 | ||
|
71433c67b1 | ||
|
d25a530942 | ||
|
a6097cdc01 | ||
|
50a1c8a08d | ||
|
6214f16552 | ||
|
e97ec13064 | ||
|
fa5567e669 | ||
|
a9d4e28e38 | ||
|
a5127539eb | ||
|
660c0cc602 | ||
|
600f48e15a | ||
|
1b47242a58 | ||
|
10c1b38139 | ||
|
81071b5af9 | ||
|
746b2e94a0 | ||
|
43f60bc69c | ||
|
145974bc92 | ||
|
c9bd9a967c | ||
|
3c607a4570 | ||
|
6dfcfcb105 | ||
|
e701243641 | ||
|
f1a4b70a56 | ||
|
df60947794 | ||
|
cd7229ba06 | ||
|
624724031d | ||
|
0be87c73cf | ||
|
b8182dd7ff | ||
|
80e1abba0c | ||
|
ce71e08ef1 | ||
|
97270ae473 | ||
|
a9c187c99b | ||
|
ff46e98d21 | ||
|
a196e67e1a | ||
|
1a259ccca0 | ||
|
2a1593fe05 | ||
|
5888894787 | ||
|
73f544d4da | ||
|
889c82516f | ||
|
306c047c14 | ||
|
533f1ffc6b | ||
|
a44a75b211 | ||
|
e26a5cc392 | ||
|
90191c9f34 | ||
|
b7e9e5f2c0 | ||
|
13287d9970 | ||
|
affa8a4653 | ||
|
9d7a74445d | ||
|
acd3e81ab4 | ||
|
ea111129dd | ||
|
7ddda105a3 | ||
|
56406e80ce | ||
|
75aadb0f3f | ||
|
f6f86b2a52 | ||
|
3f34c8d88c | ||
|
59a83bd537 | ||
|
59ca7840f4 | ||
|
88979d0d86 | ||
|
2462826c20 | ||
|
9efcab2108 | ||
|
4fbf58adb3 | ||
|
a7b7d77e1f | ||
|
22550d078f | ||
|
a0582a3e68 | ||
|
92c7b6fbd1 | ||
|
86aebc0812 | ||
|
b4f849adaa | ||
|
d964d368aa | ||
|
38700e207e | ||
|
817aeace55 | ||
|
501e866992 | ||
|
f2724e9e63 | ||
|
2820853fb6 | ||
|
f5ebe8bc3b | ||
|
98294e3ddd | ||
|
ce33f1ae98 | ||
|
e86d93760f | ||
|
a1e5061799 | ||
|
2c7c18fd24 | ||
|
5ddbb25237 | ||
|
9ba60d0d5c | ||
|
4f0ec785f6 | ||
|
02b50458b0 | ||
|
0a556fe450 | ||
|
f2f167c95d | ||
|
8b45ff7a18 | ||
|
4c665b24d9 | ||
|
381d492a8f | ||
|
e250c83c21 | ||
|
e2e326d15e | ||
|
4abca85474 | ||
|
2c78d862a3 | ||
|
b1451a7421 | ||
|
da1c251144 | ||
|
1eab7b41d1 | ||
|
1dca8ae76a | ||
|
002e86863d | ||
|
1d82b01816 | ||
|
714719c377 | ||
|
77b4fbb69c | ||
|
11fde865f7 | ||
|
717406043a | ||
|
1ef85c57cc | ||
|
d0180517a8 | ||
|
520b7ebbb6 | ||
|
2caba96076 | ||
|
81bc2f41a6 | ||
|
06e010b4d0 | ||
|
92d3ce789b | ||
|
01ca32c81c | ||
|
2e17f3010a | ||
|
c4238c4ed6 | ||
|
3d781e6f28 | ||
|
4976233cff | ||
|
98ea2a0b09 | ||
|
f978900ab0 | ||
|
8b6580128b | ||
|
4dde9c7bbe | ||
|
973837207b | ||
|
364e35af06 | ||
|
985ab58f45 | ||
|
cb1db646f2 | ||
|
a67c4bf84d | ||
|
498259b220 | ||
|
5327f8da4e | ||
|
802ccfb497 | ||
|
ec369d560a | ||
|
535647e439 | ||
|
954121634f | ||
|
594a45e7e0 | ||
|
96c7b47afe | ||
|
b7e7d32361 | ||
|
2f9cb44368 | ||
|
d80318f8ea | ||
|
b1791d1ab3 | ||
|
a53da9095a | ||
|
72e03f9af9 | ||
|
5597415f28 | ||
|
5476f6ab27 | ||
|
0971f06193 | ||
|
85515f063a | ||
|
69d7825542 | ||
|
9b779c704f | ||
|
5bd7d04fe3 | ||
|
0f78f7b2cc | ||
|
8473be69d2 | ||
|
c0124f7d77 | ||
|
b630b4e32a | ||
|
89fabc1b9c | ||
|
a649a8a5cf | ||
|
f928956584 | ||
|
7ff68792d7 | ||
|
3088dd0342 | ||
|
d2590989f5 | ||
|
3a7b377586 | ||
|
82b5648c97 | ||
|
1628a3c4d5 | ||
|
e5d8319c43 | ||
|
06699132eb | ||
|
918e794d6a | ||
|
8dd8ee1fc2 | ||
|
c3d0efda93 | ||
|
3b4e2e83ef | ||
|
c459530cb6 | ||
|
2a15e6dec8 | ||
|
1a1293608d | ||
|
318df9deaa | ||
|
cacb162520 | ||
|
105709cb43 | ||
|
9695fa7941 | ||
|
fd9bebbfa7 | ||
|
db18e8669f | ||
|
9b4a4fdd82 | ||
|
cdc7e5f021 | ||
|
adc87149e2 | ||
|
8adbfe06ed | ||
|
ae805f9ec8 | ||
|
be24689b0f | ||
|
41c31a2388 | ||
|
8b866502d1 | ||
|
7837cd61df | ||
|
b573485c31 | ||
|
4e68f3a7e1 | ||
|
5ba26d3d6d | ||
|
a6cf2eee7e | ||
|
6843eb1479 | ||
|
b331885d3c | ||
|
73716bd651 | ||
|
9edd161da3 | ||
|
1bc3ff6491 | ||
|
b0f2ef287e | ||
|
16f53ff81a | ||
|
7a260dc2ba | ||
|
1c0d951f5e | ||
|
77a740c0fb | ||
|
61101db8cf | ||
|
b51632a2fb | ||
|
9d10503a9c | ||
|
7d50e5afe0 | ||
|
549216c792 | ||
|
1990de7dcc | ||
|
89f6e2d55b | ||
|
c628ecbf24 | ||
|
b6f19cd544 | ||
|
14860b62e9 | ||
|
9970b7d580 | ||
|
7feb79ef91 | ||
|
6f84812903 | ||
|
8085e86170 | ||
|
35973576d9 | ||
|
7740d5d7c0 | ||
|
c4eff6cd65 | ||
|
5c4353b46e | ||
|
05a5918909 | ||
|
80ad38bbc6 | ||
|
6bee8866de | ||
|
ba92674c6e | ||
|
68019a1fb2 | ||
|
3a9acde2c3 | ||
|
a3a7a822e1 | ||
|
c7d22c2b92 | ||
|
b2aeb47630 | ||
|
0a1d1901cc | ||
|
29db0c80d9 | ||
|
4654751872 | ||
|
b5b18d8afc | ||
|
15139c934f | ||
|
7b8619e37c | ||
|
f52b5c31b6 | ||
|
e98859e4c0 | ||
|
c5cc4c5a74 | ||
|
e3b831364f | ||
|
730d2b5ef2 | ||
|
16abee1022 | ||
|
69fa52a010 | ||
|
e1efa4c6ab | ||
|
17cd1575f6 | ||
|
3cd8e0fef8 | ||
|
397bb694fd | ||
|
473ebfcbf6 | ||
|
a06171438e | ||
|
ea0881553e | ||
|
c4bf450fc6 | ||
|
bf2b45120a | ||
|
7edf0f218c | ||
|
600ca06166 | ||
|
8d8042ebae | ||
|
be123cd72f | ||
|
282415bbc1 | ||
|
b08191b2c4 | ||
|
39dd484f45 | ||
|
5450574d63 | ||
|
29d1b34140 | ||
|
a915542916 | ||
|
fea07f343b | ||
|
c7daa521ad | ||
|
c2532b1589 | ||
|
4610fd9ff1 | ||
|
c4b90f52c0 | ||
|
0e8b8b4901 | ||
|
2c80f76004 | ||
|
666ce46d36 | ||
|
bc120776f0 | ||
|
5693ffd2cf | ||
|
51fe0dd5a0 | ||
|
14d2199cd8 | ||
|
9889a454ce | ||
|
cb4586ebee | ||
|
44924b4bb4 | ||
|
3af3e06e75 | ||
|
39effb8f7e | ||
|
5a68f4c214 | ||
|
f558b16147 | ||
|
4c2d578561 | ||
|
81a4747acb | ||
|
9fc2c32408 | ||
|
24e0028afb | ||
|
c334d11e95 | ||
|
aec9b6a178 | ||
|
81929c984b | ||
|
5395290fd5 | ||
|
b3ef2a0383 | ||
|
9e97748700 | ||
|
4a9fdca7b2 | ||
|
f3b7ab92ff | ||
|
eae9e7fab6 | ||
|
649d4ee512 | ||
|
b5a4ffed96 | ||
|
8a63ad9b4b | ||
|
0d9f18fe1f | ||
|
2690dd0621 | ||
|
4ef331db1f | ||
|
e572d6c340 | ||
|
0c48f5fe2f | ||
|
3ee8a963cb | ||
|
c322d93435 | ||
|
c0dd5d7c76 | ||
|
993f5badf1 | ||
|
a542da3678 | ||
|
f1a392c4df | ||
|
f2bace6c1f | ||
|
921235b2dc | ||
|
bde51a9ef5 | ||
|
a52213c885 | ||
|
8e800c48bc | ||
|
e25654c210 | ||
|
ee447afd72 | ||
|
c410c200bd | ||
|
8152dcfb4c | ||
|
86ffce3a50 | ||
|
bed53f5fd5 | ||
|
2b010fc6f3 | ||
|
b8260e44fa | ||
|
a594008e57 | ||
|
f407afa694 | ||
|
06f28ffd34 | ||
|
4f454a3761 | ||
|
d4300e73f3 | ||
|
990e411361 | ||
|
73b3d37837 | ||
|
5d7d5fceba | ||
|
b1dfbce675 | ||
|
da5aebaef3 | ||
|
bced9a5a6d | ||
|
2c5e4e6c02 | ||
|
6ea296fb5c | ||
|
cf5f6be472 | ||
|
c61198b26b | ||
|
5d1b4ce71d | ||
|
c664d0392a | ||
|
aaf39162a8 | ||
|
cb31f9ec29 | ||
|
fed77c4066 | ||
|
6a09d2aa9b | ||
|
15b53de056 | ||
|
6d96a9a2e3 | ||
|
653f647fee | ||
|
f7b7335d75 | ||
|
495131efd7 | ||
|
2eb633bc41 | ||
|
86bfe1ede1 | ||
|
c04e1b2ded | ||
|
098d77c658 | ||
|
385bba4949 | ||
|
bc980e72bf | ||
|
535bb49893 | ||
|
b56a7579a8 | ||
|
8b52c6c7ac | ||
|
d166fc6a75 | ||
|
bdb116afe5 | ||
|
873e766d2e | ||
|
a84277f246 | ||
|
b80764b6b8 | ||
|
14082d0e00 | ||
|
f7775f5e0b | ||
|
b7af6eb2a4 | ||
|
a4ee2ccb13 | ||
|
c61acaf8be | ||
|
0fc8b6289c | ||
|
0f93a7dd05 | ||
|
4d0fb89489 | ||
|
6f4af330ed | ||
|
7c8c25f7bc | ||
|
cf56b5ddbf | ||
|
ac23e3b223 | ||
|
7922a6172a | ||
|
e34f2db4db | ||
|
5df33e5b90 | ||
|
db608559f6 | ||
|
c048a36a4c | ||
|
33021d37a1 | ||
|
31d6d74f90 | ||
|
bec57258a4 | ||
|
43f0723b73 | ||
|
9b74a47c91 | ||
|
993a36ea20 | ||
|
8b5af24eb8 | ||
|
5c9a7a0152 | ||
|
83588fd00f | ||
|
5acf660f37 | ||
|
de13834c12 | ||
|
49811e1f46 | ||
|
8788b0fae8 | ||
|
1cafafc4cd | ||
|
e2c1956aa5 | ||
|
a8bc2cf8a7 | ||
|
975ede4bec | ||
|
faff2c774d | ||
|
d8e3b03ec1 | ||
|
ae41066fbe | ||
|
342da81591 | ||
|
df9195b939 | ||
|
519eae63c6 | ||
|
5f598da76d | ||
|
0da2029d2d | ||
|
e82b51d0cb | ||
|
5531cace7f | ||
|
1aed13500d | ||
|
f6db8ff3b0 | ||
|
26e5c4eae2 | ||
|
bee3bdb576 | ||
|
b96d36f482 | ||
|
d13d6566f8 | ||
|
aa1048154c | ||
|
6c2d26f9bd | ||
|
84845ffaa6 | ||
|
f65958fc14 | ||
|
3d6b667997 | ||
|
97d027a173 | ||
|
f48dd665ad | ||
|
eb1e83858a | ||
|
371dc57dfc | ||
|
425a46fe78 | ||
|
fa553659de | ||
|
03cffd0f56 | ||
|
a06d1782c0 | ||
|
05f6b55036 | ||
|
fa8d788bb6 | ||
|
92b7d581ce | ||
|
19651c3d91 | ||
|
b4cfc8d6e0 | ||
|
71cfb03738 | ||
|
e7bb612050 | ||
|
83d7a57b73 | ||
|
cac310123b | ||
|
bb71d9b28a | ||
|
ea4d0fa1dd | ||
|
91561992a7 | ||
|
a3ea825a11 | ||
|
7ebbd5cebe | ||
|
9e93f198ae | ||
|
10de243556 | ||
|
988b6e3311 | ||
|
36877e4de5 | ||
|
1794185d43 | ||
|
de938df560 | ||
|
e02c5c3c6d | ||
|
90ff725125 | ||
|
1cbfbd34cf | ||
|
c6d12e064c | ||
|
30ed1fae99 | ||
|
2987292cc0 | ||
|
8114104a43 | ||
|
03f598b93d | ||
|
5a844f4b7d | ||
|
91e6d68604 | ||
|
1119a542d6 | ||
|
d706696179 | ||
|
c154875272 | ||
|
77f8a4f741 | ||
|
61e06fcaba | ||
|
13bb997525 | ||
|
350bc6f756 | ||
|
02712cd513 | ||
|
a9d94d35a2 | ||
|
155772f01f | ||
|
341a5345da | ||
|
72de59ac91 | ||
|
a7f1cd36fb | ||
|
26f0b4dc77 | ||
|
181eff29c7 | ||
|
cdad265d49 | ||
|
6eb4247484 | ||
|
72a23645a8 | ||
|
c3e06356d6 | ||
|
7a8390e68e | ||
|
168e313f73 | ||
|
30f910e861 | ||
|
e998c1193d | ||
|
a8f3474996 | ||
|
55cc06fd8b | ||
|
8883d8cc56 | ||
|
5b2af6ef09 | ||
|
6d801e7086 | ||
|
17eb7052ba | ||
|
330f25eddb | ||
|
08b88bad63 | ||
|
153f9b02a5 | ||
|
0568dca4a3 | ||
|
60ef179d18 | ||
|
c64904f5ea | ||
|
4b9e3a8068 | ||
|
db7c76d04d | ||
|
cc1a5ea78d | ||
|
9c033ff461 | ||
|
3c3322173c | ||
|
e805f85407 | ||
|
4d54456f66 | ||
|
7359d0542f | ||
|
da4fb13aa3 | ||
|
3649ab4d31 | ||
|
9e9e3fb1e4 | ||
|
e73aa01725 | ||
|
a5353c7179 | ||
|
a5e0d7011b | ||
|
742c32d936 | ||
|
3dec680058 | ||
|
9237430be2 | ||
|
12d1d84b11 | ||
|
6dd029e6ea | ||
|
e45d44cb8e | ||
|
84b6ef4340 | ||
|
5af776d963 | ||
|
ddf11cc2cc | ||
|
c7b1d0c131 | ||
|
423a4ef326 | ||
|
ccfbce5300 | ||
|
b99d3a0a69 | ||
|
659b470320 | ||
|
9a8ed30e95 | ||
|
4166b1ebbf | ||
|
89080fb2b0 | ||
|
56459d37d1 | ||
|
d5232d5f5c | ||
|
3f7b5da683 | ||
|
24562acd30 | ||
|
8bce061691 | ||
|
701c5f853d | ||
|
d1e4ba373a | ||
|
8cf8f0d7d6 | ||
|
978350c388 | ||
|
2e97c78181 | ||
|
979ec7fa78 | ||
|
1d7f179374 | ||
|
994fae0ef6 | ||
|
88ee51ba2e | ||
|
25ee26de3b | ||
|
353829a4cc | ||
|
6fd0b56e32 | ||
|
c1efefae27 | ||
|
0c96f093ff | ||
|
6f835d57b4 | ||
|
e1e53d274b | ||
|
d9a03f8365 | ||
|
ce5f284ec6 | ||
|
02a2d25a3f | ||
|
9fca6987c9 | ||
|
7361558c19 | ||
|
834890cf0b | ||
|
a53794f864 | ||
|
8fa98ed27d | ||
|
111030864c | ||
|
90e361c3dc | ||
|
32e6ccb037 | ||
|
258fcd8626 | ||
|
92c4a228e1 | ||
|
9eae1de9bc | ||
|
76f793533a | ||
|
ec7e58e10e | ||
|
ac5e095d17 | ||
|
ee7912f882 | ||
|
f460a9f17e | ||
|
37685dae73 | ||
|
5b58445535 | ||
|
5b79640b44 | ||
|
921471a153 | ||
|
3a1bf2c85d | ||
|
9b83649a03 | ||
|
2224389fb3 | ||
|
aed7bd852d | ||
|
c5b48e3506 | ||
|
73f4e1d45a | ||
|
002da129c8 | ||
|
1b545fee8a | ||
|
cbc96ec492 | ||
|
c95d845876 | ||
|
ac7705e9a0 | ||
|
0b6eb85106 | ||
|
e197dae54d | ||
|
4bf3c97476 | ||
|
19d2e82d15 | ||
|
eb48945807 | ||
|
a68db86dc8 | ||
|
948025440f | ||
|
8365e20d4f | ||
|
0fc6903d7e | ||
|
23fd27422b | ||
|
e965cf12f8 | ||
|
523be8f7e5 | ||
|
c2a605a70d | ||
|
910ee0829f | ||
|
704cf314d4 | ||
|
b8651bfac9 | ||
|
bf28e40ba6 | ||
|
a8de007d98 | ||
|
4684d2e35c | ||
|
27a9603b98 | ||
|
1610ea8dee | ||
|
171ff1191f | ||
|
b5f9ba63d5 | ||
|
a3c0f6a4e2 | ||
|
963c042b2a | ||
|
1be7dedda7 | ||
|
493a9a1cb2 | ||
|
e1149bd4b7 | ||
|
895f072425 | ||
|
37774a331a | ||
|
8719821363 | ||
|
0cc4c4380a | ||
|
553310fb31 | ||
|
404c275101 | ||
|
088d4edc6b | ||
|
bf03dcd1e6 | ||
|
456b198702 | ||
|
dc81c7b926 | ||
|
90b3be8d10 | ||
|
ba2a2ff5e8 | ||
|
9b87b8b7b1 | ||
|
69db219423 | ||
|
17ac731772 | ||
|
b6db39e69c | ||
|
d22b37961f | ||
|
f9c7e1e55e | ||
|
4b8daac104 | ||
|
4e5f74aebe | ||
|
6b357a7783 | ||
|
fc9a89ea8b | ||
|
832cdbf566 | ||
|
0dfec13c0a | ||
|
a2b8698bca | ||
|
c42e247d87 | ||
|
7851de9af8 | ||
|
3fd961a551 | ||
|
3634aa9a3c | ||
|
a05e9c4932 | ||
|
5fd77aebb5 | ||
|
9a660e3c18 | ||
|
1d4c5b2e4d | ||
|
c718f140fa | ||
|
1b819bfcc3 | ||
|
e385f6352e | ||
|
4f3414c4cc | ||
|
df79b5b4cc | ||
|
2d1ea7a3de | ||
|
2a13f9d10b | ||
|
7cf7c46939 | ||
|
031ce72db1 | ||
|
fe8a2251cd | ||
|
59f8330db4 | ||
|
999211ed9c | ||
|
dba825d829 | ||
|
ee6e7dab3b | ||
|
2a51ce131b | ||
|
7ce3ffd3cc | ||
|
40d9aec71f | ||
|
d405331447 | ||
|
e781e06a17 | ||
|
33742532f6 | ||
|
f2fbe16979 | ||
|
5af05631c2 | ||
|
8300a6c57e | ||
|
29d4bca9ba | ||
|
fd52c80573 | ||
|
74e1d1c27a | ||
|
884ce4025b | ||
|
2ddd98ee6d | ||
|
9b044aaa42 | ||
|
fe88d7fcd1 | ||
|
7923fdcaef | ||
|
837dba2191 | ||
|
a7ea6e5327 | ||
|
38ab22ee7c | ||
|
7f8e467523 | ||
|
fbb2970044 | ||
|
d23a5fcfc4 | ||
|
db83b186cf | ||
|
7d9b17fd41 | ||
|
a900f5229e | ||
|
de72a8adb6 | ||
|
5010084fb0 | ||
|
11e7b6e911 | ||
|
545097cf06 | ||
|
476bc347b4 | ||
|
095b345713 | ||
|
0f498d13f5 | ||
|
2059f7234a | ||
|
12b2242ad5 | ||
|
fec2b602a2 | ||
|
a7c1967ca0 | ||
|
20ff138f08 | ||
|
421115200b | ||
|
b15288e0ea | ||
|
4eac861eae | ||
|
7ad9e13f1e | ||
|
fc39e0ce1a | ||
|
fb02a4c674 | ||
|
6468f55627 | ||
|
f40b7975f2 | ||
|
55a38c9e01 | ||
|
3c399e5c28 | ||
|
fca00fa09e | ||
|
de942155bf | ||
|
af3f0a4782 | ||
|
c9673741de | ||
|
9a482ff828 | ||
|
020c17d19a | ||
|
d0936dc7fd | ||
|
708b47938d | ||
|
79d07ef45c | ||
|
5d33a387e0 | ||
|
b3b6e16940 | ||
|
f9fb0b84a8 | ||
|
83acb46390 | ||
|
f36b3fb4bc | ||
|
e7be271c43 | ||
|
790b574114 | ||
|
b3f59ab92c | ||
|
f2333eb31a | ||
|
a862e5fb3a | ||
|
2715e5758b | ||
|
454487dd41 | ||
|
2ed4f6eb0c | ||
|
d7bcafcb59 | ||
|
c37a8ddd83 | ||
|
fc3f96abcb | ||
|
c37ea441fc | ||
|
fa1a4e8bf6 | ||
|
2532d56b85 | ||
|
00fd869224 | ||
|
5661726e2e | ||
|
cfa5d7e172 | ||
|
fd7791a0e2 | ||
|
e32b8bae00 | ||
|
966139cde9 | ||
|
ee19383f4d | ||
|
172a8bdcdb | ||
|
543048efcc | ||
|
67c85ffa4c | ||
|
c065335882 | ||
|
f6313fcbfb | ||
|
6a3ea876b5 | ||
|
64ad308e9d | ||
|
94169a20de | ||
|
5ca38eee3a | ||
|
f4f65f62ee | ||
|
f89ada7f61 | ||
|
ff3b398e23 | ||
|
84cb7865ab | ||
|
75bdf114be | ||
|
c2fd64d3cc | ||
|
580c5e39ae | ||
|
8da6281dcd | ||
|
f79bcc6b8d | ||
|
f2b63ba0aa | ||
|
a253111cbe | ||
|
a5776288f6 | ||
|
dbcf4cab16 | ||
|
4ea3f33376 | ||
|
e4cdfb50cd | ||
|
c2dc7e9cd0 | ||
|
0fc1aa2711 | ||
|
89cf6d9e74 | ||
|
61c430c098 | ||
|
4b75cb8b0e | ||
|
53f87c08b5 | ||
|
e23dc8977f | ||
|
421dc5b6ec | ||
|
247f1c120f | ||
|
e011c60e12 | ||
|
26c909b64b | ||
|
acb7916996 | ||
|
40b5045a0a | ||
|
b17f40862c | ||
|
7702ebde61 | ||
|
6951eadc18 | ||
|
cf2573157f | ||
|
80c55119d2 | ||
|
7323221e3b | ||
|
fb5bd818d9 | ||
|
43a4e8db12 | ||
|
302390696e | ||
|
2508629d6c | ||
|
90c390d7a6 | ||
|
28178b12c7 | ||
|
6eb4f090f9 | ||
|
95442d45aa | ||
|
b4ad6588ed | ||
|
56282b0e3f | ||
|
2385602500 | ||
|
628a154d7f | ||
|
efaed59b9b | ||
|
bdee13dea8 | ||
|
c615910874 | ||
|
9e1398c68a | ||
|
af10692d2d | ||
|
e7abe37b10 | ||
|
bc8617a9f4 | ||
|
00e243b23b | ||
|
27324d0270 | ||
|
0c838fb60c | ||
|
0713ef5862 | ||
|
bee1ba8854 | ||
|
da252c7597 | ||
|
a4460abc83 | ||
|
261636febb | ||
|
21f15f0a29 | ||
|
bd068ff2a6 | ||
|
d09f5c0e3a | ||
|
45140ca9f7 | ||
|
c6be2e768a | ||
|
6339395cba | ||
|
bd6492bb38 | ||
|
f93b331817 | ||
|
20e4096c4b | ||
|
97952a9289 | ||
|
960a595268 | ||
|
a3c94ef632 | ||
|
84fd38ac9c | ||
|
303a8fae32 | ||
|
21686ee8a9 | ||
|
c8b142a676 | ||
|
58061a68c4 | ||
|
9c11197768 | ||
|
f347efb006 | ||
|
af8ddac2af | ||
|
b1358de9bb | ||
|
f4dc93ae66 | ||
|
20a77f6d51 | ||
|
c1ad275e71 | ||
|
6bae070091 | ||
|
3687b6cb4b | ||
|
196ed9eb46 | ||
|
37c941dff3 | ||
|
40a428d49f | ||
|
48eeef2d30 | ||
|
c34520f3a4 | ||
|
36db965c39 | ||
|
4e81764ce2 | ||
|
1e9f983289 | ||
|
2e404c60f4 | ||
|
40857aae61 | ||
|
a64145b712 | ||
|
945f6da85e | ||
|
76d5d054cb | ||
|
20cfa159ec | ||
|
3ff1a4263d | ||
|
3141eb5dce | ||
|
75d6f59026 | ||
|
ae42ce7017 | ||
|
e9c9c87bbc | ||
|
8a6dba46b1 | ||
|
93299d6651 | ||
|
f34320a89b | ||
|
a17b07bc4c | ||
|
3a01ba52ef | ||
|
d796c66990 | ||
|
80b705e997 | ||
|
7069af3e20 | ||
|
209a926b45 | ||
|
71e0c7a3cf | ||
|
b88d96f07d | ||
|
46f75c3d92 | ||
|
3b8e5cec88 | ||
|
a420169109 | ||
|
a8db269fd5 | ||
|
a5efcfdede | ||
|
1ecc913fc2 | ||
|
08eb3b11bc | ||
|
b59d9a2f27 | ||
|
e9a5e32330 | ||
|
be9bdfa47e | ||
|
153e934ed4 | ||
|
4757c96d9a | ||
|
1efc527281 | ||
|
468b59c53d | ||
|
15426975b6 | ||
|
bbcf343e40 | ||
|
f0d3cf4e43 | ||
|
4c965b9f44 | ||
|
e5143247c2 | ||
|
3a676183b2 | ||
|
64265926a4 | ||
|
df2d4daad3 | ||
|
fd0d79e17b | ||
|
84ce97a31e | ||
|
7e0c9f7340 | ||
|
917a36eaee | ||
|
7620d419c6 | ||
|
50c90b29d2 | ||
|
0e77cf53f6 | ||
|
9dfbae69cc | ||
|
c1ad4f6b45 | ||
|
8135f08958 | ||
|
645b1ffd75 | ||
|
8d0202d240 | ||
|
b1809d1667 | ||
|
2e9a7d9c1a | ||
|
1f7aa6f812 | ||
|
032a189440 | ||
|
be5fc50136 | ||
|
0affec8f17 | ||
|
8c9ae4d3b4 | ||
|
dac6bb27aa | ||
|
6c0ab24100 | ||
|
95c7832c3e | ||
|
c2e8d6160f | ||
|
f609905267 | ||
|
f7c8bac3fd | ||
|
58811d8f5c | ||
|
54960f9b5d | ||
|
cd45ddda13 | ||
|
04acd2141b | ||
|
336ec4741c | ||
|
8da40419ee | ||
|
0b5c7a97a7 | ||
|
d9e8caf369 | ||
|
e208485c17 | ||
|
5a6dee80ac | ||
|
67fae1d1f0 | ||
|
1b31099f73 | ||
|
897518a297 | ||
|
a9b6686725 | ||
|
2c7cb5baba | ||
|
29160eec9c | ||
|
fe00a8a0ca | ||
|
64574c779f | ||
|
64e4b7eaa0 | ||
|
48824c4c8a | ||
|
ababeb3a69 | ||
|
cfa2a63323 | ||
|
9418f5613a | ||
|
22a3e06e1c | ||
|
b91c2f0299 | ||
|
07416c7a46 | ||
|
440dccb81b | ||
|
e413b25cd9 | ||
|
5ece65cade | ||
|
c0c9ec1c7b | ||
|
f2f00b99e0 | ||
|
7b755d6f8b | ||
|
7d63301039 | ||
|
49f0b1eb59 | ||
|
b2ed46efb5 | ||
|
58b61c68a3 | ||
|
30b8225812 | ||
|
54530a14e9 | ||
|
ee8ffcf57b | ||
|
5e9397fcca | ||
|
8508834e50 | ||
|
924a8a7e38 | ||
|
960e9178ba | ||
|
a3257ff651 | ||
|
960f9ba29a | ||
|
3940cc1641 | ||
|
a498ba6537 | ||
|
5b5a907023 | ||
|
c1cb3ebff7 | ||
|
6a555a477b | ||
|
175d27691d | ||
|
5ede5577d1 | ||
|
0bfbe5ad16 | ||
|
54ceb05420 | ||
|
fef0344be0 | ||
|
b12fee5c0a | ||
|
1ef75c7a61 | ||
|
8c5ac84f0c | ||
|
44739f2dc3 | ||
|
d52d530cbe | ||
|
5fb00ff7bf | ||
|
4c7aa8f1c0 | ||
|
2522f70f86 | ||
|
e47e8ed335 | ||
|
2927b491c3 | ||
|
ba2a0b3566 | ||
|
98caa0bcd9 | ||
|
4a2a100569 | ||
|
3073f4c0d1 | ||
|
7d900e3b5a | ||
|
6d78c11fd2 | ||
|
1bee82e288 | ||
|
a41caf0efb | ||
|
a3e0eb03db | ||
|
34f62b4894 | ||
|
b28077a437 | ||
|
359ab2b56e | ||
|
e42c23686b | ||
|
d98f1a2632 | ||
|
aa736dbe3a | ||
|
3534203083 | ||
|
517cb5f094 | ||
|
b910ab9bcb | ||
|
5a29e29535 | ||
|
0fd71260d3 | ||
|
54367bfa98 | ||
|
1e9806f872 | ||
|
1e704aa7f2 | ||
|
8a404ea850 | ||
|
e2e279bc85 | ||
|
c914afdbf1 | ||
|
49a057ebc0 | ||
|
d660c1609c | ||
|
74bc8966a8 | ||
|
9d8a3e3c97 | ||
|
a308b86056 | ||
|
1b540fe0ba | ||
|
929e5a4de6 | ||
|
df4f0d043a | ||
|
09df8d47a5 | ||
|
c8b75c9046 | ||
|
dd8f5ac01d | ||
|
22479ff5d8 | ||
|
688b1f8bef | ||
|
e5464526c8 | ||
|
37b8d3acd4 | ||
|
4f13208ce8 | ||
|
383640caaf | ||
|
42f3401dd7 | ||
|
7fb57c924f | ||
|
97592e5bc3 | ||
|
9922c0f4f7 | ||
|
f27434f2fb | ||
|
32d39b7b49 | ||
|
5c20c7b295 | ||
|
df000debe9 | ||
|
31511416ed | ||
|
99b02cedfb | ||
|
4136bf2808 | ||
|
93d6fd05a9 | ||
|
73c4bc1411 | ||
|
dc9b4bcfec | ||
|
e3276324b9 | ||
|
f80e5db346 | ||
|
35550d8c0a | ||
|
b68d79407e | ||
|
27ed69b08f | ||
|
cd8fb82215 | ||
|
5c8e2b6f78 | ||
|
9d30817294 | ||
|
5ee3c4de9f | ||
|
afbcb3d38c | ||
|
de1d5f199f | ||
|
9158f69ea0 | ||
|
2cfd9c8d01 | ||
|
5026741652 | ||
|
3d77714c36 | ||
|
03e83ec6a0 | ||
|
9315dc1c73 | ||
|
b8bb12b2e2 | ||
|
bd1532847c | ||
|
3602b58517 | ||
|
d7035291ea | ||
|
6b0bcb5171 | ||
|
6b8f3c7fef | ||
|
0d12d2fd28 | ||
|
10460fc2fb | ||
|
6c7f0edf50 | ||
|
51bf9c4ff2 | ||
|
0266c9d969 | ||
|
879de346ea | ||
|
50d9c4b34a | ||
|
a195d7dfd3 | ||
|
1c3cb897c1 | ||
|
0e39320a77 | ||
|
1b162c1962 | ||
|
f497201322 | ||
|
65746edd2d | ||
|
91e1ac83d9 | ||
|
63ea75612b | ||
|
f9a650792a | ||
|
564a29141e | ||
|
c937d20e48 | ||
|
ca353eb7db | ||
|
f268163ea0 | ||
|
6f41e3faf1 | ||
|
aed2c0124a | ||
|
f5564c9275 | ||
|
632ce270fa | ||
|
93dac6b246 | ||
|
a92674022a | ||
|
ceaf065d0e | ||
|
a58139dfb5 | ||
|
9bd2b0deaa | ||
|
d262c4dfaa | ||
|
dd009322de | ||
|
858ec2e655 | ||
|
5d4ab4100a | ||
|
43ddc63d67 | ||
|
b5d1565dec | ||
|
6658bb7d51 | ||
|
eb2db4994f | ||
|
d88e5ddf20 | ||
|
f3558260b6 | ||
|
0317bbb35d | ||
|
a4a6ed7e38 | ||
|
15a1e10487 | ||
|
98ad9d8b61 | ||
|
c573cdb0ae | ||
|
82a149eb87 | ||
|
089c98a107 | ||
|
17a73e3979 | ||
|
f65299d665 | ||
|
f782dfbfd9 | ||
|
ec7934ea33 | ||
|
2de17f3fd0 | ||
|
ba2bf4f78e | ||
|
8a54e6a0ec | ||
|
8e70c87e64 | ||
|
579a1ed42e | ||
|
a544935e7d | ||
|
7eab227ab1 | ||
|
382a5cebab | ||
|
6d2353c302 | ||
|
45ee096260 | ||
|
c21a476b00 | ||
|
25c870dc57 | ||
|
4605c35101 | ||
|
8655c61ec2 | ||
|
314cf3f31a | ||
|
1d26deb0be | ||
|
ac35757616 | ||
|
47f2f17987 | ||
|
a63b43c259 | ||
|
14582fea5f | ||
|
862ec14e06 | ||
|
570d81c6dd | ||
|
4964d0dcbd | ||
|
5c00fc9769 | ||
|
3599d1db8e | ||
|
5c61f00ffa | ||
|
aef3ff3e7b | ||
|
a971c2ef37 | ||
|
c757f70b97 | ||
|
403db7cc84 | ||
|
7a4c5a64fa | ||
|
c535e74a65 | ||
|
e605917083 | ||
|
14db5f8d1f | ||
|
3546abc30e | ||
|
e4b58c1258 | ||
|
5e2e1d4c96 | ||
|
1a7cd785f2 | ||
|
65de940882 | ||
|
26702920b4 | ||
|
373087d74f | ||
|
ca6b1b39b7 | ||
|
8934167e76 | ||
|
9972b5f1f9 | ||
|
d8877abf26 | ||
|
bce3b68281 | ||
|
7d42e18479 | ||
|
4294295242 | ||
|
16f492026a | ||
|
7d58f0ec53 | ||
|
6bd724fe24 | ||
|
26a208529e | ||
|
3fbdb19956 | ||
|
ea9d5eca0f | ||
|
0f66278532 | ||
|
b9206ef017 | ||
|
9d8f1d9dbf | ||
|
e064a9334b | ||
|
e12c7756d9 | ||
|
f8002480c2 | ||
|
799a677e7a | ||
|
12f47708cd | ||
|
9358aa1128 | ||
|
a44b63fbb9 | ||
|
e2b7e8a4da | ||
|
a5bfcd876f | ||
|
2f02384d22 | ||
|
3de8613843 | ||
|
ccb8a07dc7 | ||
|
6484fed190 | ||
|
6b103c6d0b | ||
|
669ac058b8 | ||
|
e92967167f | ||
|
f3de2c9b94 | ||
|
21cd1a44e8 | ||
|
6ca46795aa | ||
|
35d7b7ceaf | ||
|
faa2094488 | ||
|
e6d776699f | ||
|
200e90ad43 | ||
|
c66f67ac07 | ||
|
334a7b50cd | ||
|
a9d3e61884 | ||
|
88082c48cf | ||
|
40d0297885 | ||
|
be1acae20c | ||
|
f1e4349c82 | ||
|
1f701341db | ||
|
2a24468267 | ||
|
f531a956f5 | ||
|
1aea10010b | ||
|
2cf6010665 | ||
|
2402d60429 | ||
|
19494984eb | ||
|
07c7cb3c6c | ||
|
358aebec4d | ||
|
05826150f6 | ||
|
5827358a1e | ||
|
9334cc463d | ||
|
5532ee627f | ||
|
2021c30805 | ||
|
0e39aa9488 | ||
|
8ec0745883 | ||
|
c446b017ef | ||
|
a68435d856 | ||
|
814324146b | ||
|
11d8b2ba5a | ||
|
d6c6a262d8 | ||
|
5c4f96e4bc | ||
|
9974b8b1da | ||
|
c81baae1b9 | ||
|
e96545be2e | ||
|
609801ae99 | ||
|
a66918a303 | ||
|
e85c4f87e9 | ||
|
8ff5a22799 | ||
|
4929d1297e | ||
|
b830a8f942 | ||
|
0c388a5264 | ||
|
e4eb18cf4e | ||
|
5b4f432cba | ||
|
15f7257645 | ||
|
12c11f1d48 | ||
|
a196d5ced3 | ||
|
802af08179 | ||
|
85ec50552d | ||
|
8da96f8d94 | ||
|
5b9d858f57 | ||
|
023242ec03 | ||
|
683e53e950 | ||
|
df0ee955e8 | ||
|
771834793f | ||
|
3915c1286b | ||
|
b422b636d3 | ||
|
5bbc675c6b | ||
|
addf4d90e9 | ||
|
721e5e7947 | ||
|
dea3144c4d | ||
|
1080d25fcf | ||
|
afb553a31e | ||
|
e2c231234d | ||
|
103f7117ed | ||
|
59b70c4d11 | ||
|
f96bae40ac | ||
|
ba974c73bf | ||
|
e498ad3ee7 | ||
|
1de031ed06 | ||
|
d6ac924b94 | ||
|
ee24473cbb | ||
|
c19a3cec1c | ||
|
f3694be1a0 | ||
|
306d86ce58 | ||
|
2c001b63a5 | ||
|
e162dda836 | ||
|
10c532bd4c | ||
|
c8a7bc1d6a | ||
|
9ca3c69b49 | ||
|
d1cf8c1fd5 | ||
|
018742f50f | ||
|
b82d21f856 | ||
|
cfaadf198f | ||
|
6698b5e07e | ||
|
37794a5e8a | ||
|
a88fef2937 | ||
|
da474a16a9 | ||
|
59bbfeb67f | ||
|
4e9e2ed5bd | ||
|
e0593c7ca2 | ||
|
1f69df0d89 | ||
|
05706879a0 | ||
|
7e49b36198 | ||
|
56bcb491d3 | ||
|
f4e2bd848d | ||
|
0cf96314a3 | ||
|
91e24cab9e | ||
|
288155ead0 | ||
|
85454857d3 | ||
|
fe50f6590a | ||
|
2da5da3f16 | ||
|
446c865415 | ||
|
0072bf0c59 | ||
|
4ec7ca29f1 | ||
|
d94017dfae | ||
|
dce0ce0e17 | ||
|
d61102e255 | ||
|
7f6e0c478b | ||
|
786a3d8919 | ||
|
ef3fcdc6e6 | ||
|
90c194fc81 | ||
|
5ed686a17b | ||
|
4e3009260c | ||
|
c87ce2dede | ||
|
99a87b4c83 | ||
|
3f5fc1e897 | ||
|
97d1de1beb | ||
|
d7e1c9c09c | ||
|
865111bca9 | ||
|
08d62cd5e3 | ||
|
603e2ee7de | ||
|
98948989d0 | ||
|
1aa8cc3b65 | ||
|
c487d1307e | ||
|
604f4957f7 | ||
|
7726576bb7 | ||
|
cf17a3a4c3 | ||
|
0972ec9115 | ||
|
f660ae30dc | ||
|
2766c24b42 | ||
|
cab83555e1 | ||
|
48a098a9c7 | ||
|
a1fa1c610c | ||
|
905ca69301 | ||
|
d66cc125aa | ||
|
3fc0fc65f9 | ||
|
8c64b01d67 | ||
|
2566f64c34 | ||
|
8cd40b9e90 | ||
|
45df8568b6 | ||
|
0da041477b | ||
|
272ea9b92e | ||
|
571681d019 | ||
|
9b614c6057 | ||
|
721f319909 | ||
|
a3621f3655 | ||
|
789311abd6 | ||
|
091a495632 | ||
|
16665aeb00 | ||
|
d6e56c38d5 | ||
|
87874006c7 | ||
|
703588b684 | ||
|
b21ee1b63b | ||
|
427437d49b | ||
|
01deefc3bc | ||
|
157ca9161f | ||
|
266e65e6d2 | ||
|
70b3962c35 | ||
|
e568b600f0 | ||
|
273fd689ce | ||
|
0363d64722 | ||
|
d200507424 | ||
|
fc84f605af | ||
|
927dea37bb | ||
|
de98ae57b7 | ||
|
614398ed6c | ||
|
2cd4ba9a0a | ||
|
57d3f71bf9 | ||
|
8f8df969a2 | ||
|
e39dc3c464 | ||
|
dbc6535221 | ||
|
e262cac3e8 | ||
|
4ab3165ae3 | ||
|
7a1a209168 | ||
|
ac6f07a744 | ||
|
dac929f8df | ||
|
ebd938a8fc | ||
|
5ba54a62d6 | ||
|
827a595b6c | ||
|
c03f74d8b0 | ||
|
f5393f44f7 | ||
|
ad6e834992 | ||
|
3439b21177 | ||
|
730c809395 | ||
|
5a2da798c8 | ||
|
c0e7f6e9f4 | ||
|
ed83d3ed13 | ||
|
aa1dff3fc4 | ||
|
c1901e9689 | ||
|
c6e6d9fa94 | ||
|
88eabb98b9 | ||
|
3dcc7132b6 | ||
|
379380abd8 | ||
|
497709da13 | ||
|
b95a58591d | ||
|
5727b1387e | ||
|
221cd00b1a | ||
|
cce4f6344c | ||
|
a49c6f433b | ||
|
ef308ac53a | ||
|
2fab696bb3 | ||
|
836a5066c2 | ||
|
69422cc4e7 | ||
|
e9c0987e8a | ||
|
bd9eb76a2d | ||
|
441eae9df2 | ||
|
bfc272f3e8 | ||
|
215489286d | ||
|
c772210cc0 | ||
|
934f87bcdd | ||
|
ff872b4009 | ||
|
7278f88aa9 | ||
|
16621f00c1 | ||
|
0c9eb8e16c | ||
|
78cd460395 | ||
|
2351b5a084 | ||
|
ff238c2724 | ||
|
810e3c6a66 | ||
|
98529ee071 | ||
|
e902ab4693 | ||
|
b085add973 | ||
|
2b397942fe | ||
|
655ca803d8 | ||
|
58681fa7ea | ||
|
78a199e2fb | ||
|
851fcf0758 | ||
|
7379be90f9 | ||
|
af65ccd054 | ||
|
79ef204e1f | ||
|
f1b88adebe | ||
|
0c6ce6ce08 | ||
|
5e40b12450 | ||
|
a75fd560d7 | ||
|
152f77b665 | ||
|
c39690195e | ||
|
20c6b4682f | ||
|
97c442482d | ||
|
6586737835 | ||
|
fe5d1a6e74 | ||
|
81771a3bfd | ||
|
c648711f30 | ||
|
6829f46c31 | ||
|
43a7e8e08a | ||
|
c370ddd89a | ||
|
57c6c6e51c | ||
|
bf6698f4cc | ||
|
44757729b7 | ||
|
eb2e4d0aaf | ||
|
4684a498c4 | ||
|
864543b023 | ||
|
ed143b503d | ||
|
809d8a7d03 | ||
|
5ab882759d | ||
|
acbaecf45d | ||
|
1f238fedd8 | ||
|
5828f4400d | ||
|
4e2b157db3 | ||
|
8f9b4fcdbb | ||
|
23c74af2b5 | ||
|
2cc22ce098 | ||
|
2df02aa301 | ||
|
cec1f223e9 | ||
|
17f8339aa6 | ||
|
35c4c2a256 | ||
|
3c81baa26e | ||
|
0a917a77f5 | ||
|
583699c84d | ||
|
0f7218c0c4 | ||
|
2d66fec174 | ||
|
3cae315a76 | ||
|
d661f3f31e | ||
|
907f933a54 | ||
|
c6e9cc8024 | ||
|
40094ceeab | ||
|
24c70e3c8e | ||
|
a636e8cc13 | ||
|
ffd6311e7d | ||
|
260a84b94b | ||
|
fb552fd751 | ||
|
94e2a8598d | ||
|
4986f5ea2d | ||
|
1b5ab37dfd | ||
|
83820bf82c | ||
|
20e028c47b | ||
|
89c62bf67f | ||
|
bc43229055 | ||
|
e43a8ca528 | ||
|
c7fc36a61b | ||
|
e705ff16e3 | ||
|
0a13390ab0 | ||
|
bf6b571455 | ||
|
e13ba8ba11 | ||
|
5aba239fc1 | ||
|
dff8c48842 | ||
|
ec3cda32fa | ||
|
faaf82c837 | ||
|
3f6ae245f6 | ||
|
bc2e06502e | ||
|
aa1c4eb262 | ||
|
264cec12e9 | ||
|
e423aa5511 | ||
|
9b5458840a | ||
|
fae1c737a3 | ||
|
6f9aea4e56 | ||
|
d575561d39 | ||
|
f42136637d | ||
|
53b0417e36 | ||
|
5bb933dd84 | ||
|
821351f56e | ||
|
a92fa257af | ||
|
c29391636a | ||
|
c8bd01caae | ||
|
1f39d936c5 | ||
|
36ab848aba | ||
|
6cb401b1ff | ||
|
fc9b5938e6 | ||
|
8ad9a0aa9a | ||
|
8f9e980945 | ||
|
b2f3b901e0 | ||
|
517b27bfc3 | ||
|
00d01946cd | ||
|
694bf9d8b1 | ||
|
ef71cc0d12 | ||
|
5f73ac1eda | ||
|
108fce896b | ||
|
ff0a98196f | ||
|
757e7ca936 | ||
|
74b382d881 | ||
|
a725fb4655 | ||
|
ee076e6156 | ||
|
65669f23a1 | ||
|
172b1ff9d1 | ||
|
596890a0f4 | ||
|
0770d8b8cf | ||
|
cc3a4899a2 | ||
|
93cdd8bb46 | ||
|
c2a5cc034a | ||
|
e737700c7b | ||
|
a32f8a6a59 | ||
|
ed00965d18 | ||
|
3f485ac09b | ||
|
a901bda41e | ||
|
0ac1f99f9c | ||
|
30ff0fa977 | ||
|
7da86b5984 | ||
|
922e155763 | ||
|
436b34ffea | ||
|
2fa8d0f534 | ||
|
71e95c92b6 | ||
|
fbf7521769 | ||
|
7c911b3891 | ||
|
9f61f72ee8 | ||
|
d32ebd57e6 | ||
|
8e43c8cbce | ||
|
7632c20ddf | ||
|
4fa3a5c362 | ||
|
886421b43a | ||
|
e20cbf673f | ||
|
54c35710f6 | ||
|
748ade5fea | ||
|
f5e9c7df07 | ||
|
1541d32a42 | ||
|
ed7438b9ba | ||
|
e8cca36369 | ||
|
d473acb56d | ||
|
b5d63e5ed5 | ||
|
c712fafae3 | ||
|
e589ab814d | ||
|
5015e12d59 | ||
|
3e409bea26 | ||
|
e0665856b0 | ||
|
f71d742b5e | ||
|
299d071e9d | ||
|
075f69acc2 | ||
|
be41e8b321 | ||
|
739ad73ae9 | ||
|
b62b09e5f6 | ||
|
b789da45bd | ||
|
e316dad1cb | ||
|
c3cc79f798 | ||
|
b9ed20bb9b | ||
|
786be6f570 | ||
|
dd60ae31ae | ||
|
db7adfa77b | ||
|
dd3f351874 | ||
|
d56db500d3 | ||
|
07221f5a48 | ||
|
421d336b0f | ||
|
5be6f8959a | ||
|
f7b8e06c3a | ||
|
18a50d357f | ||
|
6c3390f14d | ||
|
8d83c3adbb | ||
|
cd1a73dde6 | ||
|
4161181a6c | ||
|
82acd59a8e | ||
|
438aa66b4c | ||
|
5739c27ef4 | ||
|
b59295e55e | ||
|
49862d1bcd | ||
|
544e54894f | ||
|
046d3128c4 | ||
|
1ad1ff5fc1 | ||
|
e06ffabf21 | ||
|
b2b5e2bb4d | ||
|
c2727f2029 | ||
|
a0e7bab598 | ||
|
67ae86882a | ||
|
e52a8e060b | ||
|
1bc8dbf139 | ||
|
73b1a46d15 | ||
|
7ecf3410bf | ||
|
03bb6dc161 | ||
|
a45b9e07fc | ||
|
6567e79ec5 | ||
|
224848fc11 | ||
|
6468a1ba79 | ||
|
ce1141982b | ||
|
6e18af2267 | ||
|
73ce44028f | ||
|
335362315c | ||
|
e75278f9c2 | ||
|
a31f401995 | ||
|
6446257a93 | ||
|
1bace1288d | ||
|
23b07c9197 | ||
|
a61b1a3623 | ||
|
7f39c9fcb0 | ||
|
921ff43acf | ||
|
1ed1bae249 | ||
|
38a1edfe3c | ||
|
dc1d491c15 | ||
|
e4d500f451 | ||
|
d52ea86cb9 | ||
|
b906f2a628 | ||
|
2b00d92463 | ||
|
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 | ||
|
6f27aae022 | ||
|
d8c54fb815 | ||
|
5c93609142 | ||
|
c277b95f03 | ||
|
b1f1c26703 | ||
|
a5d0707dd0 | ||
|
d129b0ef24 | ||
|
f2c3b9859e | ||
|
bb1f4a025a | ||
|
8c36012653 | ||
|
0c6dee4bef | ||
|
66cb75f4a3 | ||
|
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 | ||
|
8f6fc0146b | ||
|
e1ac1c4fdc | ||
|
a6b44a1470 | ||
|
e8834a68f3 | ||
|
6ad1cd3fb5 | ||
|
3279cbac24 | ||
|
5094bad838 | ||
|
94af9b7f13 | ||
|
8e02263084 | ||
|
fe0fe1873a | ||
|
de29574314 | ||
|
5ac024788e | ||
|
a1e273e983 | ||
|
a95bf64ccf | ||
|
4fa9022932 | ||
|
f10fb77a81 | ||
|
db092c828e | ||
|
bed0598530 | ||
|
b734d4bbc1 | ||
|
d2080808db | ||
|
345d5e8d9e | ||
|
bcc41bf3d1 | ||
|
b2d444d782 | ||
|
bac6703f8e | ||
|
6cbbd1e5a1 | ||
|
b6ef558c86 | ||
|
70bb082973 | ||
|
8b8a19c75d | ||
|
0b53242564 | ||
|
f11bd509b0 | ||
|
57608628a4 | ||
|
f167c3e12e | ||
|
262b380280 | ||
|
ee0c20ae44 | ||
|
c30c144120 | ||
|
a5ee82b0d1 | ||
|
a4f558181d | ||
|
120303e6e3 | ||
|
b3822d5802 | ||
|
980e4ee89a | ||
|
bb1428eeb1 | ||
|
f6a90e9b42 | ||
|
a71159667d | ||
|
74e00cf652 | ||
|
e773a80b06 | ||
|
e6eea67eeb | ||
|
8429a1e792 | ||
|
47fbd2a2b5 | ||
|
93835b9b94 | ||
|
2de3fc9f6f | ||
|
78a8cf6982 | ||
|
99cf3219d4 | ||
|
7587e97d46 | ||
|
3061c8b854 | ||
|
77e9e95067 | ||
|
6191b6bee2 | ||
|
b15f8f68e4 | ||
|
84c12793e8 | ||
|
6eeadddd4d | ||
|
a40b3a98dc | ||
|
f0d66ff0fb | ||
|
d3ebd360b2 | ||
|
ebbe1692c8 | ||
|
ca7d406787 | ||
|
a2dc8378f5 | ||
|
b570e89dbd | ||
|
108f87678a | ||
|
00146ae87c | ||
|
e3757fbbfa | ||
|
ac64e8b15e | ||
|
c39ca7189b | ||
|
03c8fdd30a | ||
|
788bc67faa | ||
|
048be2da2c | ||
|
8e1f70865e | ||
|
6143f1ff5b | ||
|
db30836b53 | ||
|
3e8ef5e462 | ||
|
0a53dccd4c | ||
|
2b5aa142fb | ||
|
40443d1e25 | ||
|
cb4e7614ee | ||
|
3d84dbc73f | ||
|
beb2ab9ad5 | ||
|
9a0877379c | ||
|
bbd0239ece | ||
|
92956f2b45 | ||
|
48d1a5ec5d | ||
|
2ff2ce460c | ||
|
7cc875b8db | ||
|
9387f583fa | ||
|
707dd700b0 | ||
|
ddff9b612f | ||
|
338ac5d4a3 | ||
|
ca7abd727a | ||
|
62b20769ee | ||
|
4ec323c5cc | ||
|
84e72ede72 | ||
|
bd37c48596 | ||
|
e30f0e8e11 | ||
|
c43a2513a8 | ||
|
4b4bc0dde2 | ||
|
49adf2192a | ||
|
a7eabeb73f | ||
|
f838f3427b | ||
|
1cc75ca636 | ||
|
d4356b0453 | ||
|
35542e5823 | ||
|
c80c2233c5 | ||
|
c2f0e4f683 | ||
|
2621f4a2fa | ||
|
3c055642d5 | ||
|
43b881d0cd | ||
|
8b7b32e225 | ||
|
00b0ff50f3 | ||
|
1acde593b5 | ||
|
c43c043521 | ||
|
b526cadebd | ||
|
94f44e1d5d | ||
|
0352d9c99e | ||
|
0cd3f37e1b | ||
|
486d7b6d62 | ||
|
8f4e332409 | ||
|
f0389c0b2f | ||
|
922e8a4912 | ||
|
021a1c7a39 | ||
|
4a7451682b | ||
|
faa880d60a | ||
|
fd30e82836 | ||
|
3ef34fbb56 | ||
|
7345dc6861 | ||
|
9958937fd1 | ||
|
f19c57200d | ||
|
8a2652f53d | ||
|
dddde4ddab | ||
|
300d901618 | ||
|
1cb72acd27 | ||
|
a17776cb5f | ||
|
94b749ab00 | ||
|
5fc0d284cb | ||
|
bbe1211451 | ||
|
ce152b205f | ||
|
a5fd7cf4e9 | ||
|
da38a1367a | ||
|
1445f11c19 | ||
|
86df55f5cc | ||
|
cf294c938e | ||
|
ebff45f803 | ||
|
7b8021a36e | ||
|
5c77bb7c67 | ||
|
8ade26b4a4 | ||
|
bdbc60b4f7 | ||
|
373fa7a7d9 | ||
|
eec4f173a7 | ||
|
d726ce6340 | ||
|
b406844c96 | ||
|
153d38f10c | ||
|
dce917eb74 | ||
|
eb711787ae | ||
|
9967dbbaa9 | ||
|
71dc10ebea | ||
|
782fba2ce7 | ||
|
4d73f98050 | ||
|
79d2083a00 | ||
|
ee3b296a99 | ||
|
8b62d04453 | ||
|
9b0d3dfaeb | ||
|
b1ef4cfee9 | ||
|
f12f6a56ba | ||
|
2777d53a12 | ||
|
aba3ec692f | ||
|
b7c8fcd062 | ||
|
3065de63dd | ||
|
a57fb4f1ab | ||
|
c493a22765 | ||
|
d85e5def5d | ||
|
0aba499c8e | ||
|
4146695f34 | ||
|
4e57e10ba8 | ||
|
daa6d02887 | ||
|
a87d89302f | ||
|
2a9b1311d3 | ||
|
7d73501b87 | ||
|
039d6acd3e | ||
|
405fcdc483 | ||
|
f52abc1a62 | ||
|
e763953562 | ||
|
4cab617c25 | ||
|
0190b5e5af | ||
|
abc0952247 | ||
|
6ce2726a87 | ||
|
17a4463f59 | ||
|
e76d8df246 | ||
|
a46bcf45d5 | ||
|
1f985d04a2 | ||
|
d64e6e6c1f | ||
|
1164a65df8 | ||
|
d57f07d57e | ||
|
5c0a964321 | ||
|
cf3b8d09d9 | ||
|
1c7397fb21 | ||
|
6a08d93e2c | ||
|
4c03ace9eb | ||
|
2cd616dd30 | ||
|
eab87c0827 | ||
|
8b8188710e | ||
|
fd9bb3ac43 | ||
|
6d9c3bca33 | ||
|
dd33a45644 | ||
|
074c7a9c40 | ||
|
de2f06970d | ||
|
6166d946f7 | ||
|
c778ab9622 | ||
|
aad846b968 | ||
|
f04a3e3d2e | ||
|
7ad52de2b1 | ||
|
0706ba9bec | ||
|
ed53888fce | ||
|
fd76fba235 | ||
|
95088a785a | ||
|
f46b600ec0 | ||
|
566ab993df | ||
|
407036e215 | ||
|
7b1a5566fb | ||
|
1b0d8739c1 | ||
|
266feea397 | ||
|
c4c6ab2494 | ||
|
079eea3f2b | ||
|
a457d69034 | ||
|
d0175798bf | ||
|
80e07943ee | ||
|
e2954211ec | ||
|
337bed8176 | ||
|
71197e1c89 | ||
|
e1a13f5ce8 | ||
|
1ed2c16a51 | ||
|
12e1bd80b3 |
7
.babelrc
Normal file
7
.babelrc
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"plugins": ["transform-class-properties"],
|
||||||
|
"presets": [
|
||||||
|
"@babel/preset-env",
|
||||||
|
"@babel/preset-react"
|
||||||
|
]
|
||||||
|
}
|
@ -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
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
101
.clang-tidy
Normal file
101
.clang-tidy
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
---
|
||||||
|
Checks: >
|
||||||
|
bugprone-*,
|
||||||
|
-bugprone-narrowing-conversions,
|
||||||
|
-bugprone-easily-swappable-parameters,
|
||||||
|
-bugprone-branch-clone,
|
||||||
|
-bugprone-misplaced-widening-cast,
|
||||||
|
-bugprone-exception-escape,
|
||||||
|
-bugprone-implicit-widening-of-multiplication-result,
|
||||||
|
-bugprone-integer-division,
|
||||||
|
-bugprone-reserved-identifier,
|
||||||
|
-bugprone-unhandled-self-assignment,
|
||||||
|
-bugprone-forward-declaration-namespace,
|
||||||
|
-bugprone-sizeof-expression,
|
||||||
|
-bugprone-throw-keyword-missing,
|
||||||
|
-bugprone-chained-comparison,
|
||||||
|
-bugprone-incorrect-enable-if,
|
||||||
|
-bugprone-switch-missing-default-case,
|
||||||
|
-bugprone-empty-catch,
|
||||||
|
-bugprone-unchecked-optional-access,
|
||||||
|
-clang-analyzer-*,
|
||||||
|
-clang-diagnostic-deprecated-declarations,
|
||||||
|
-clang-diagnostic-constant-conversion,
|
||||||
|
cppcoreguidelines-avoid-goto,
|
||||||
|
cppcoreguidelines-no-malloc,
|
||||||
|
cppcoreguidelines-virtual-class-destructor,
|
||||||
|
google-*,
|
||||||
|
-google-build-explicit-make-pair,
|
||||||
|
-google-build-using-namespace,
|
||||||
|
-google-explicit-constructor,
|
||||||
|
-google-default-arguments,
|
||||||
|
-google-readability-braces-around-statements,
|
||||||
|
-google-readability-casting,
|
||||||
|
-google-readability-namespace-comments,
|
||||||
|
-google-readability-function,
|
||||||
|
-google-readability-todo,
|
||||||
|
-google-runtime-int,
|
||||||
|
-google-build-namespaces,
|
||||||
|
-google-runtime-references,
|
||||||
|
-google-readability-function-size,
|
||||||
|
llvm-*,
|
||||||
|
-llvm-namespace-comment,
|
||||||
|
-llvm-qualified-auto,
|
||||||
|
-llvm-include-order,
|
||||||
|
-llvm-else-after-return,
|
||||||
|
-llvm-header-guard,
|
||||||
|
-llvm-twine-local,
|
||||||
|
misc-*,
|
||||||
|
-misc-argument-comment,
|
||||||
|
-misc-const-correctness,
|
||||||
|
-misc-non-private-member-variables-in-classes,
|
||||||
|
-misc-unconventional-assign-operator,
|
||||||
|
-misc-no-recursion,
|
||||||
|
-misc-misplaced-const,
|
||||||
|
-misc-definitions-in-headers,
|
||||||
|
-misc-unused-parameters,
|
||||||
|
-misc-include-cleaner,
|
||||||
|
modernize-concat-nested-namespaces,
|
||||||
|
modernize-use-using,
|
||||||
|
performance-*,
|
||||||
|
-performance-no-int-to-ptr,
|
||||||
|
-performance-enum-size,
|
||||||
|
-performance-avoid-endl,
|
||||||
|
readability-*,
|
||||||
|
-readability-avoid-const-params-in-decls,
|
||||||
|
-readability-braces-around-statements,
|
||||||
|
-readability-container-size-empty,
|
||||||
|
-readability-convert-member-functions-to-static,
|
||||||
|
-readability-const-return-type,
|
||||||
|
-readability-function-cognitive-complexity,
|
||||||
|
-readability-function-size,
|
||||||
|
-readability-identifier-naming,
|
||||||
|
-readability-implicit-bool-conversion,
|
||||||
|
-readability-magic-numbers,
|
||||||
|
-readability-else-after-return,
|
||||||
|
-readability-inconsistent-declaration-parameter-name,
|
||||||
|
-readability-isolate-declaration,
|
||||||
|
-readability-identifier-length,
|
||||||
|
-readability-redundant-declaration,
|
||||||
|
-readability-uppercase-literal-suffix,
|
||||||
|
-readability-named-parameter,
|
||||||
|
-readability-qualified-auto,
|
||||||
|
-readability-suspicious-call-argument,
|
||||||
|
-readability-redundant-access-specifiers,
|
||||||
|
-readability-redundant-member-init,
|
||||||
|
-readability-static-definition-in-anonymous-namespace,
|
||||||
|
-readability-use-anyofallof,
|
||||||
|
-readability-simplify-boolean-expr,
|
||||||
|
-readability-make-member-function-const,
|
||||||
|
-readability-redundant-string-init,
|
||||||
|
-readability-non-const-parameter,
|
||||||
|
-readability-redundant-inline-specifier,
|
||||||
|
-readability-avoid-nested-conditional-operator,
|
||||||
|
-readability-avoid-return-with-void-value,
|
||||||
|
-readability-redundant-casting,
|
||||||
|
-readability-static-accessed-through-instance
|
||||||
|
|
||||||
|
WarningsAsErrors: '*'
|
||||||
|
HeaderFilterRegex: '.*'
|
||||||
|
|
||||||
|
|
14
.cncc.style
Normal file
14
.cncc.style
Normal file
@ -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]+)*$'
|
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
test
|
||||||
|
build
|
30
.editorconfig
Normal file
30
.editorconfig
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# EditorConfig is awesome: http://EditorConfig.org
|
||||||
|
#
|
||||||
|
# NOTE: Keep settings in sync with the master .clang-format file
|
||||||
|
#
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# CMake configuration files
|
||||||
|
[{CMakeLists.txt,CMakeSettings.json,*.cmake}]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
# CI configuration files
|
||||||
|
[{.travis.yml,appveyor.yml}]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
# Unix shell scripts
|
||||||
|
[*.sh]
|
||||||
|
end_of_line = lf
|
||||||
|
indent_style = space
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
# Windows shell scripts
|
||||||
|
[*.bat]
|
||||||
|
end_of_line = crlf
|
||||||
|
indent_style = space
|
||||||
|
trim_trailing_whitespace = true
|
2
.eslintignore
Normal file
2
.eslintignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
features/support/flatbuffers.js
|
||||||
|
features/support/fbresult_generated.js
|
28
.eslintrc
Normal file
28
.eslintrc
Normal file
@ -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"
|
||||||
|
}
|
18
.gitattributes
vendored
Normal file
18
.gitattributes
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Set the default behavior, in case people don't have core.autocrlf set.
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
# Explicitly declare text files you want to always be normalized and converted
|
||||||
|
# to native line endings on checkout.
|
||||||
|
*.cpp text
|
||||||
|
*.hpp text
|
||||||
|
|
||||||
|
# Declare files that will always have CRLF line endings on checkout.
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.cmd text eol=crlf
|
||||||
|
*.ps1 text eol=crlf
|
||||||
|
|
||||||
|
# Declare files that will always have LF line endings on checkout.
|
||||||
|
*.sh text eol=lf
|
||||||
|
|
||||||
|
# https://eslint.org/docs/latest/rules/linebreak-style#using-this-rule-with-version-control-systems
|
||||||
|
*.js text eol=lf
|
65
.gitea/workflows/publish-container.yaml
Normal file
65
.gitea/workflows/publish-container.yaml
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
name: Build and Publish Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published, prereleased]
|
||||||
|
|
||||||
|
env:
|
||||||
|
IMAGE_NAME: openharbor/osrm-backend
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
docker-base-image: ["debian", "alpine"]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out the repo
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v4
|
||||||
|
with:
|
||||||
|
images: ${{ env.IMAGE_NAME }}
|
||||||
|
|
||||||
|
- name: Docker meta - debug
|
||||||
|
id: metadebug
|
||||||
|
uses: docker/metadata-action@v4
|
||||||
|
with:
|
||||||
|
images: ${{ env.IMAGE_NAME }}
|
||||||
|
flavor: |
|
||||||
|
latest=true
|
||||||
|
suffix=-debug,onlatest=true
|
||||||
|
|
||||||
|
- name: Log in to DockerHub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push debug image
|
||||||
|
uses: docker/build-push-action@v4
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/riscv64
|
||||||
|
file: ./docker/Dockerfile-${{ matrix.docker-base-image }}
|
||||||
|
tags: ${{ steps.metadebug.outputs.tags }}
|
||||||
|
build-args: |
|
||||||
|
DOCKER_TAG=${{ join(steps.metadebug.outputs.tags) }}-${{ matrix.docker-base-image }}
|
||||||
|
|
||||||
|
- name: Build and push normal image
|
||||||
|
uses: docker/build-push-action@v4
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64,linux/arm64,linux/ppc64le,linux/riscv64
|
||||||
|
file: ./docker/Dockerfile-${{ matrix.docker-base-image }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
build-args: |
|
||||||
|
DOCKER_TAG=${{ join(steps.meta.outputs.tags) }}-${{ matrix.docker-base-image }}
|
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
name: Bug Report
|
||||||
|
about: Report issue with osrm-backend
|
||||||
|
labels: Bug Report
|
||||||
|
---
|
||||||
|
|
||||||
|
# Issue
|
||||||
|
|
||||||
|
Please describe the issue you are seeing with OSRM.
|
||||||
|
Images are a good way to illustrate your problem.
|
||||||
|
|
||||||
|
**Note**: If your issue relates to the demo site (https://map.project-osrm.org) or routing provided on openstreetmap.org, be aware that they use separate [profile settings](https://github.com/fossgis-routing-server/cbf-routing-profiles) from those provided by default in `osrm-backend`.
|
||||||
|
If your issue relates to the demo site or openstreetmap.org behaviour, please check these profiles first to see if they explain the behaviour before creating an issue here.
|
||||||
|
|
||||||
|
# Steps to reproduce
|
||||||
|
|
||||||
|
Please provide the steps required to reproduce your problem.
|
||||||
|
- `osrm-backend` version being used
|
||||||
|
- OSM extract that was processed
|
||||||
|
- Processing commands (e.g. CH vs MLD processing)
|
||||||
|
- Server queries
|
||||||
|
|
||||||
|
If you're reporting an issue with https://map.project-osrm.org, please provide a link to the problematic request.
|
||||||
|
|
||||||
|
# Specifications
|
||||||
|
|
||||||
|
Please provide details of your development environment.
|
||||||
|
- Library/dependency versions
|
||||||
|
- Operating system
|
||||||
|
- Hardware
|
10
.github/ISSUE_TEMPLATE/feature.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/feature.md
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
name: Feature Request
|
||||||
|
about: Request a new feature in osrm-backend
|
||||||
|
labels: Feature Request
|
||||||
|
---
|
||||||
|
|
||||||
|
# Feature
|
||||||
|
|
||||||
|
Please describe the feature you would like to see in OSRM.
|
||||||
|
Images are often a good way to illustrate your requested feature.
|
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
19
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
Please read our [documentation](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/releasing.md) on release and version management.
|
||||||
|
If your PR is still work in progress please attach the relevant label.
|
||||||
|
|
||||||
|
## Tasklist
|
||||||
|
|
||||||
|
- [ ] CHANGELOG.md entry ([How to write a changelog entry](http://keepachangelog.com/en/1.0.0/#how))
|
||||||
|
- [ ] update relevant [Wiki pages](https://github.com/Project-OSRM/osrm-backend/wiki)
|
||||||
|
- [ ] add tests (see [testing documentation](https://github.com/Project-OSRM/osrm-backend/blob/master/docs/testing.md))
|
||||||
|
- [ ] review
|
||||||
|
- [ ] adjust for comments
|
||||||
|
- [ ] cherry pick to release branch
|
||||||
|
|
||||||
|
## Requirements / Relations
|
||||||
|
|
||||||
|
Link any requirements here. Other pull requests this PR is based on?
|
84
.github/workflows/osrm-backend-docker.yml
vendored
Normal file
84
.github/workflows/osrm-backend-docker.yml
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
name: build and publish container image
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
docker-base-image: ["debian", "alpine"]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out the repo
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: ghcr.io/${{ github.repository }}
|
||||||
|
|
||||||
|
- name: Docker meta - debug
|
||||||
|
id: metadebug
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: ghcr.io/${{ github.repository }}
|
||||||
|
flavor: |
|
||||||
|
latest=true
|
||||||
|
suffix=-debug,onlatest=true
|
||||||
|
|
||||||
|
- name: Docker meta - assertions
|
||||||
|
id: metaassertions
|
||||||
|
uses: docker/metadata-action@v3
|
||||||
|
with:
|
||||||
|
images: ghcr.io/${{ github.repository }}
|
||||||
|
flavor: |
|
||||||
|
latest=true
|
||||||
|
suffix=-assertions,onlatest=true
|
||||||
|
|
||||||
|
- name: Log in to GitHub Docker Registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build container image - debug
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
file: ./docker/Dockerfile-${{ matrix.docker-base-image }}
|
||||||
|
tags: ${{ steps.metadebug.outputs.tags }}
|
||||||
|
build-args: |
|
||||||
|
DOCKER_TAG=${{ join(steps.metadebug.outputs.tags ) }}-${{ matrix.docker-base-image }}
|
||||||
|
|
||||||
|
|
||||||
|
- name: Build container image - assertions
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
file: ./docker/Dockerfile-${{ matrix.docker-base-image }}
|
||||||
|
tags: ${{ steps.metaassertions.outputs.tags }}
|
||||||
|
build-args: |
|
||||||
|
DOCKER_TAG=${{ join(steps.metaassertions.outputs.tags ) }}-${{ matrix.docker-base-image }}
|
||||||
|
|
||||||
|
# build and publish "normal" image as last to get it listed on top
|
||||||
|
- name: Build container image - normal
|
||||||
|
uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
file: ./docker/Dockerfile-${{ matrix.docker-base-image }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
build-args: |
|
||||||
|
DOCKER_TAG=${{ join(steps.meta.outputs.tags ) }}-${{ matrix.docker-base-image }}
|
786
.github/workflows/osrm-backend.yml
vendored
Normal file
786
.github/workflows/osrm-backend.yml
vendored
Normal file
@ -0,0 +1,786 @@
|
|||||||
|
name: osrm-backend CI
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
tags:
|
||||||
|
- v[1-9]+.[0-9]+.[0-9]+
|
||||||
|
- v[1-9]+.[0-9]+.[0-9]+-[a-zA-Z]+.[0-9]+
|
||||||
|
- v[1-9]+.[0-9]+-[0-9a-zA-Z]+
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
env:
|
||||||
|
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
|
||||||
|
CMAKE_VERSION: 3.21.2
|
||||||
|
ENABLE_NODE_BINDINGS: "ON"
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
windows-release-node:
|
||||||
|
needs: format-taginfo-docs
|
||||||
|
runs-on: windows-2022
|
||||||
|
continue-on-error: false
|
||||||
|
env:
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- run: pip install "conan<2.0.0"
|
||||||
|
- run: conan --version
|
||||||
|
- run: cmake --version
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- run: node --version
|
||||||
|
- run: npm --version
|
||||||
|
- name: Prepare environment
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)")
|
||||||
|
echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV
|
||||||
|
- run: npm install --ignore-scripts
|
||||||
|
- run: npm link --ignore-scripts
|
||||||
|
- name: Build
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_CONAN=ON -DENABLE_NODE_BINDINGS=ON ..
|
||||||
|
cmake --build . --config Release
|
||||||
|
|
||||||
|
# TODO: MSVC goes out of memory when building our tests
|
||||||
|
# - name: Run tests
|
||||||
|
# shell: bash
|
||||||
|
# run: |
|
||||||
|
# cd build
|
||||||
|
# cmake --build . --config Release --target tests
|
||||||
|
# # TODO: run tests
|
||||||
|
# - name: Run node tests
|
||||||
|
# shell: bash
|
||||||
|
# run: |
|
||||||
|
# ./lib/binding/osrm-extract.exe -p profiles/car.lua test/data/monaco.osm.pbf
|
||||||
|
|
||||||
|
# mkdir -p test/data/ch
|
||||||
|
# cp test/data/monaco.osrm* test/data/ch/
|
||||||
|
# ./lib/binding/osrm-contract.exe test/data/ch/monaco.osrm
|
||||||
|
|
||||||
|
# ./lib/binding/osrm-datastore.exe test/data/ch/monaco.osrm
|
||||||
|
# node test/nodejs/index.js
|
||||||
|
- name: Build Node package
|
||||||
|
shell: bash
|
||||||
|
run: ./scripts/ci/node_package.sh
|
||||||
|
- name: Publish Node package
|
||||||
|
if: ${{ env.PUBLISH == 'On' }}
|
||||||
|
uses: ncipollo/release-action@v1
|
||||||
|
with:
|
||||||
|
allowUpdates: true
|
||||||
|
artifactErrorsFailBuild: true
|
||||||
|
artifacts: build/stage/**/*.tar.gz
|
||||||
|
omitBody: true
|
||||||
|
omitBodyDuringUpdate: true
|
||||||
|
omitName: true
|
||||||
|
omitNameDuringUpdate: true
|
||||||
|
replacesArtifacts: true
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
format-taginfo-docs:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Use Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- name: Enable Node.js cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-
|
||||||
|
- name: Prepare environment
|
||||||
|
run: |
|
||||||
|
npm ci --ignore-scripts
|
||||||
|
clang-format-15 --version
|
||||||
|
- name: Run checks
|
||||||
|
run: |
|
||||||
|
./scripts/check_taginfo.py taginfo.json profiles/car.lua
|
||||||
|
./scripts/format.sh && ./scripts/error_on_dirty.sh
|
||||||
|
node ./scripts/validate_changelog.js
|
||||||
|
npm run docs && ./scripts/error_on_dirty.sh
|
||||||
|
npm audit --production
|
||||||
|
|
||||||
|
docker-image-matrix:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
docker-base-image: ["debian", "alpine"]
|
||||||
|
needs: format-taginfo-docs
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
continue-on-error: false
|
||||||
|
steps:
|
||||||
|
- name: Check out the repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Enable osm.pbf cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: berlin-latest.osm.pbf
|
||||||
|
key: v1-berlin-osm-pbf
|
||||||
|
restore-keys: |
|
||||||
|
v1-berlin-osm-pbf
|
||||||
|
- name: Docker build
|
||||||
|
run: |
|
||||||
|
docker build -t osrm-backend-local -f docker/Dockerfile-${{ matrix.docker-base-image }} .
|
||||||
|
- name: Test Docker image
|
||||||
|
run: |
|
||||||
|
if [ ! -f "${PWD}/berlin-latest.osm.pbf" ]; then
|
||||||
|
wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf
|
||||||
|
fi
|
||||||
|
TAG=osrm-backend-local
|
||||||
|
# when `--memory-swap` value equals `--memory` it means container won't use swap
|
||||||
|
# see https://docs.docker.com/config/containers/resource_constraints/#--memory-swap-details
|
||||||
|
MEMORY_ARGS="--memory=1g --memory-swap=1g"
|
||||||
|
docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-extract --dump-nbg-graph -p /opt/car.lua /data/berlin-latest.osm.pbf
|
||||||
|
docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-components /data/berlin-latest.osrm.nbg /data/berlin-latest.geojson
|
||||||
|
if [ ! -s "${PWD}/berlin-latest.geojson" ]
|
||||||
|
then
|
||||||
|
>&2 echo "No berlin-latest.geojson found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# removing `.osrm.nbg` to check that whole pipeline works without it
|
||||||
|
rm -rf "${PWD}/berlin-latest.osrm.nbg"
|
||||||
|
|
||||||
|
docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-partition /data/berlin-latest.osrm
|
||||||
|
docker run $MEMORY_ARGS -t -v "${PWD}:/data" "${TAG}" osrm-customize /data/berlin-latest.osrm
|
||||||
|
docker run $MEMORY_ARGS --name=osrm-container -t -p 5000:5000 -v "${PWD}:/data" "${TAG}" osrm-routed --algorithm mld /data/berlin-latest.osrm &
|
||||||
|
curl --retry-delay 3 --retry 10 --retry-all-errors "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true"
|
||||||
|
docker stop osrm-container
|
||||||
|
|
||||||
|
build-test-publish:
|
||||||
|
needs: format-taginfo-docs
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: gcc-13-debug-cov
|
||||||
|
continue-on-error: false
|
||||||
|
node: 20
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Debug
|
||||||
|
CCOMPILER: gcc-13
|
||||||
|
CUCUMBER_TIMEOUT: 20000
|
||||||
|
CXXCOMPILER: g++-13
|
||||||
|
ENABLE_COVERAGE: ON
|
||||||
|
|
||||||
|
- name: clang-18-debug-asan-ubsan
|
||||||
|
continue-on-error: false
|
||||||
|
node: 20
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Debug
|
||||||
|
CCOMPILER: clang-18
|
||||||
|
CUCUMBER_TIMEOUT: 20000
|
||||||
|
CXXCOMPILER: clang++-18
|
||||||
|
ENABLE_SANITIZER: ON
|
||||||
|
TARGET_ARCH: x86_64-asan-ubsan
|
||||||
|
OSRM_CONNECTION_RETRIES: 10
|
||||||
|
OSRM_CONNECTION_EXP_BACKOFF_COEF: 1.5
|
||||||
|
|
||||||
|
- name: clang-18-release
|
||||||
|
continue-on-error: false
|
||||||
|
node: 18
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CCOMPILER: clang-18
|
||||||
|
CXXCOMPILER: clang++-18
|
||||||
|
CUCUMBER_TIMEOUT: 60000
|
||||||
|
ENABLE_LTO: OFF
|
||||||
|
|
||||||
|
- name: clang-18-debug
|
||||||
|
continue-on-error: false
|
||||||
|
node: 18
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Debug
|
||||||
|
CCOMPILER: clang-18
|
||||||
|
CXXCOMPILER: clang++-18
|
||||||
|
CUCUMBER_TIMEOUT: 60000
|
||||||
|
ENABLE_LTO: OFF
|
||||||
|
|
||||||
|
- name: clang-18-debug-clang-tidy
|
||||||
|
continue-on-error: false
|
||||||
|
node: 18
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Debug
|
||||||
|
CCOMPILER: clang-18
|
||||||
|
CXXCOMPILER: clang++-18
|
||||||
|
CUCUMBER_TIMEOUT: 60000
|
||||||
|
ENABLE_CLANG_TIDY: ON
|
||||||
|
|
||||||
|
|
||||||
|
- name: clang-17-release
|
||||||
|
continue-on-error: false
|
||||||
|
node: 18
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CCOMPILER: clang-17
|
||||||
|
CXXCOMPILER: clang++-17
|
||||||
|
CUCUMBER_TIMEOUT: 60000
|
||||||
|
ENABLE_LTO: OFF
|
||||||
|
|
||||||
|
- name: clang-16-release
|
||||||
|
continue-on-error: false
|
||||||
|
node: 18
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CCOMPILER: clang-16
|
||||||
|
CXXCOMPILER: clang++-16
|
||||||
|
CUCUMBER_TIMEOUT: 60000
|
||||||
|
ENABLE_LTO: OFF
|
||||||
|
|
||||||
|
- name: conan-linux-debug-asan-ubsan
|
||||||
|
continue-on-error: false
|
||||||
|
node: 18
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CCOMPILER: clang-18
|
||||||
|
CXXCOMPILER: clang++-18
|
||||||
|
ENABLE_CONAN: ON
|
||||||
|
ENABLE_SANITIZER: ON
|
||||||
|
ENABLE_LTO: OFF
|
||||||
|
|
||||||
|
- name: conan-linux-release
|
||||||
|
continue-on-error: false
|
||||||
|
node: 18
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CCOMPILER: clang-18
|
||||||
|
CXXCOMPILER: clang++-18
|
||||||
|
ENABLE_CONAN: ON
|
||||||
|
ENABLE_LTO: OFF
|
||||||
|
|
||||||
|
- name: gcc-14-release
|
||||||
|
continue-on-error: false
|
||||||
|
node: 20
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CCOMPILER: gcc-14
|
||||||
|
CXXCOMPILER: g++-14
|
||||||
|
CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized'
|
||||||
|
|
||||||
|
- name: gcc-13-release
|
||||||
|
continue-on-error: false
|
||||||
|
node: 20
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CCOMPILER: gcc-13
|
||||||
|
CXXCOMPILER: g++-13
|
||||||
|
CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized'
|
||||||
|
|
||||||
|
- name: gcc-12-release
|
||||||
|
continue-on-error: false
|
||||||
|
node: 20
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
BUILD_TOOLS: ON
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CCOMPILER: gcc-12
|
||||||
|
CXXCOMPILER: g++-12
|
||||||
|
CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized'
|
||||||
|
|
||||||
|
- name: conan-linux-release-node
|
||||||
|
build_node_package: true
|
||||||
|
continue-on-error: false
|
||||||
|
node: 20
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CCOMPILER: clang-16
|
||||||
|
CXXCOMPILER: clang++-16
|
||||||
|
ENABLE_CONAN: ON
|
||||||
|
NODE_PACKAGE_TESTS_ONLY: ON
|
||||||
|
|
||||||
|
- name: conan-linux-debug-node
|
||||||
|
build_node_package: true
|
||||||
|
continue-on-error: false
|
||||||
|
node: 20
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
BUILD_TYPE: Debug
|
||||||
|
CCOMPILER: clang-16
|
||||||
|
CXXCOMPILER: clang++-16
|
||||||
|
ENABLE_CONAN: ON
|
||||||
|
NODE_PACKAGE_TESTS_ONLY: ON
|
||||||
|
|
||||||
|
- name: conan-macos-x64-release-node
|
||||||
|
build_node_package: true
|
||||||
|
continue-on-error: true
|
||||||
|
node: 20
|
||||||
|
runs-on: macos-13 # x86_64
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CCOMPILER: clang
|
||||||
|
CXXCOMPILER: clang++
|
||||||
|
CUCUMBER_TIMEOUT: 60000
|
||||||
|
ENABLE_ASSERTIONS: ON
|
||||||
|
ENABLE_CONAN: ON
|
||||||
|
|
||||||
|
- name: conan-macos-arm64-release-node
|
||||||
|
build_node_package: true
|
||||||
|
continue-on-error: true
|
||||||
|
node: 20
|
||||||
|
runs-on: macos-14 # arm64
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
CCOMPILER: clang
|
||||||
|
CXXCOMPILER: clang++
|
||||||
|
CUCUMBER_TIMEOUT: 60000
|
||||||
|
ENABLE_ASSERTIONS: ON
|
||||||
|
ENABLE_CONAN: ON
|
||||||
|
|
||||||
|
name: ${{ matrix.name}}
|
||||||
|
continue-on-error: ${{ matrix.continue-on-error }}
|
||||||
|
runs-on: ${{ matrix.runs-on }}
|
||||||
|
env:
|
||||||
|
BUILD_TOOLS: ${{ matrix.BUILD_TOOLS }}
|
||||||
|
BUILD_TYPE: ${{ matrix.BUILD_TYPE }}
|
||||||
|
BUILD_SHARED_LIBS: ${{ matrix.BUILD_SHARED_LIBS }}
|
||||||
|
CCOMPILER: ${{ matrix.CCOMPILER }}
|
||||||
|
CFLAGS: ${{ matrix.CFLAGS }}
|
||||||
|
CUCUMBER_TIMEOUT: ${{ matrix.CUCUMBER_TIMEOUT }}
|
||||||
|
CXXCOMPILER: ${{ matrix.CXXCOMPILER }}
|
||||||
|
CXXFLAGS: ${{ matrix.CXXFLAGS }}
|
||||||
|
ENABLE_ASSERTIONS: ${{ matrix.ENABLE_ASSERTIONS }}
|
||||||
|
ENABLE_CLANG_TIDY: ${{ matrix.ENABLE_CLANG_TIDY }}
|
||||||
|
ENABLE_COVERAGE: ${{ matrix.ENABLE_COVERAGE }}
|
||||||
|
ENABLE_CONAN: ${{ matrix.ENABLE_CONAN }}
|
||||||
|
ENABLE_SANITIZER: ${{ matrix.ENABLE_SANITIZER }}
|
||||||
|
NODE_PACKAGE_TESTS_ONLY: ${{ matrix.NODE_PACKAGE_TESTS_ONLY }}
|
||||||
|
TARGET_ARCH: ${{ matrix.TARGET_ARCH }}
|
||||||
|
OSRM_CONNECTION_RETRIES: ${{ matrix.OSRM_CONNECTION_RETRIES }}
|
||||||
|
OSRM_CONNECTION_EXP_BACKOFF_COEF: ${{ matrix.OSRM_CONNECTION_EXP_BACKOFF_COEF }}
|
||||||
|
ENABLE_LTO: ${{ matrix.ENABLE_LTO }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Build machine architecture
|
||||||
|
run: uname -m
|
||||||
|
- name: Use Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node }}
|
||||||
|
- name: Enable Node.js cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.npm
|
||||||
|
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-
|
||||||
|
- name: Enable compiler cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.ccache
|
||||||
|
key: ccache-${{ matrix.name }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
ccache-${{ matrix.name }}-
|
||||||
|
- name: Enable Conan cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.conan
|
||||||
|
key: v9-conan-${{ matrix.name }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
v9-conan-${{ matrix.name }}-
|
||||||
|
- name: Enable test cache
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{github.workspace}}/test/cache
|
||||||
|
key: v4-test-${{ matrix.name }}-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
v4-test-${{ matrix.name }}-
|
||||||
|
- name: Prepare environment
|
||||||
|
run: |
|
||||||
|
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
|
||||||
|
mkdir -p $HOME/.ccache
|
||||||
|
|
||||||
|
PACKAGE_JSON_VERSION=$(node -e "console.log(require('./package.json').version)")
|
||||||
|
echo PUBLISH=$([[ "${GITHUB_REF:-}" == "refs/tags/v${PACKAGE_JSON_VERSION}" ]] && echo "On" || echo "Off") >> $GITHUB_ENV
|
||||||
|
echo "OSRM_INSTALL_DIR=${GITHUB_WORKSPACE}/install-osrm" >> $GITHUB_ENV
|
||||||
|
echo "OSRM_BUILD_DIR=${GITHUB_WORKSPACE}/build-osrm" >> $GITHUB_ENV
|
||||||
|
if [[ "$ENABLE_SANITIZER" == 'ON' ]]; then
|
||||||
|
# We can only set this after checkout once we know the workspace directory
|
||||||
|
echo "LSAN_OPTIONS=print_suppressions=0:suppressions=${GITHUB_WORKSPACE}/scripts/ci/leaksanitizer.conf" >> $GITHUB_ENV
|
||||||
|
echo "UBSAN_OPTIONS=symbolize=1:halt_on_error=1:print_stacktrace=1:suppressions=${GITHUB_WORKSPACE}/scripts/ci/undefinedsanitizer.conf" >> $GITHUB_ENV
|
||||||
|
echo "ASAN_OPTIONS=print_suppressions=0:suppressions=${GITHUB_WORKSPACE}/scripts/ci/addresssanitizer.conf" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${RUNNER_OS}" == "Linux" ]]; then
|
||||||
|
echo "JOBS=$((`nproc` + 1))" >> $GITHUB_ENV
|
||||||
|
elif [[ "${RUNNER_OS}" == "macOS" ]]; then
|
||||||
|
echo "JOBS=$((`sysctl -n hw.ncpu` + 1))" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
# See: https://github.com/actions/toolkit/issues/946#issuecomment-1590016041
|
||||||
|
# We need it to be able to access system folders while restoring cached Boost below
|
||||||
|
- name: Give tar root ownership
|
||||||
|
if: runner.os == 'Linux' && matrix.ENABLE_CONAN != 'ON'
|
||||||
|
run: sudo chown root /bin/tar && sudo chmod u+s /bin/tar
|
||||||
|
- name: Cache Boost
|
||||||
|
if: runner.os == 'Linux' && matrix.ENABLE_CONAN != 'ON'
|
||||||
|
id: cache-boost
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
/usr/local/include/boost
|
||||||
|
/usr/local/lib/libboost*
|
||||||
|
key: v1-boost-${{ runner.os }}-${{ runner.arch }}-${{ matrix.runs-on }}
|
||||||
|
restore-keys: |
|
||||||
|
v1-boost-${{ runner.os }}-${{ runner.arch }}-${{ matrix.runs-on }}
|
||||||
|
|
||||||
|
- name: Install Boost
|
||||||
|
if: steps.cache-boost.outputs.cache-hit != 'true' && runner.os == 'Linux' && matrix.ENABLE_CONAN != 'ON'
|
||||||
|
run: |
|
||||||
|
BOOST_VERSION="1.85.0"
|
||||||
|
BOOST_VERSION_FLAVOR="${BOOST_VERSION}-b2-nodocs"
|
||||||
|
wget -q https://github.com/boostorg/boost/releases/download/boost-${BOOST_VERSION}/boost-${BOOST_VERSION_FLAVOR}.tar.gz
|
||||||
|
tar xzf boost-${BOOST_VERSION_FLAVOR}.tar.gz
|
||||||
|
cd boost-${BOOST_VERSION}
|
||||||
|
sudo ./bootstrap.sh
|
||||||
|
sudo ./b2 install
|
||||||
|
cd ..
|
||||||
|
sudo rm -rf boost-${BOOST_VERSION}*
|
||||||
|
|
||||||
|
- name: Install dev dependencies
|
||||||
|
run: |
|
||||||
|
python3 -m pip install "conan<2.0.0" || python3 -m pip install "conan<2.0.0" --break-system-packages
|
||||||
|
|
||||||
|
# workaround for issue that GitHub Actions seems to not adding it to PATH after https://github.com/actions/runner-images/pull/6499
|
||||||
|
# and that's why CI cannot find conan executable installed above
|
||||||
|
if [[ "${RUNNER_OS}" == "macOS" ]]; then
|
||||||
|
echo "/Library/Frameworks/Python.framework/Versions/Current/bin" >> $GITHUB_PATH
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ccache
|
||||||
|
if [[ "${RUNNER_OS}" == "Linux" ]]; then
|
||||||
|
sudo apt-get update -y && sudo apt-get install ccache
|
||||||
|
elif [[ "${RUNNER_OS}" == "macOS" ]]; then
|
||||||
|
brew install ccache
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Linux dev packages
|
||||||
|
if [ "${ENABLE_CONAN}" != "ON" ]; then
|
||||||
|
sudo apt-get update -y
|
||||||
|
sudo apt-get install -y libbz2-dev libxml2-dev libzip-dev liblua5.2-dev
|
||||||
|
if [[ "${CCOMPILER}" != clang-* ]]; then
|
||||||
|
sudo apt-get install -y ${CXXCOMPILER}
|
||||||
|
fi
|
||||||
|
if [[ "${ENABLE_COVERAGE}" == "ON" ]]; then
|
||||||
|
sudo apt-get install -y lcov
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TBB
|
||||||
|
TBB_VERSION=2021.12.0
|
||||||
|
if [[ "${RUNNER_OS}" == "Linux" ]]; then
|
||||||
|
TBB_URL="https://github.com/oneapi-src/oneTBB/releases/download/v${TBB_VERSION}/oneapi-tbb-${TBB_VERSION}-lin.tgz"
|
||||||
|
elif [[ "${RUNNER_OS}" == "macOS" ]]; then
|
||||||
|
TBB_URL="https://github.com/oneapi-src/oneTBB/releases/download/v${TBB_VERSION}/oneapi-tbb-${TBB_VERSION}-mac.tgz"
|
||||||
|
fi
|
||||||
|
wget --tries 5 ${TBB_URL} -O onetbb.tgz
|
||||||
|
tar zxvf onetbb.tgz
|
||||||
|
sudo cp -a oneapi-tbb-${TBB_VERSION}/lib/. /usr/local/lib/
|
||||||
|
sudo cp -a oneapi-tbb-${TBB_VERSION}/include/. /usr/local/include/
|
||||||
|
- name: Add Clang 18 to list of Conan compilers # workaround for the issue that Conan 1.x doesn't know about Clang 18
|
||||||
|
if: ${{ matrix.ENABLE_CONAN == 'ON' && matrix.CCOMPILER == 'clang-18' }}
|
||||||
|
run: |
|
||||||
|
sudo wget https://github.com/mikefarah/yq/releases/download/v4.9.6/yq_linux_amd64 -O /usr/bin/yq && sudo chmod +x /usr/bin/yq
|
||||||
|
|
||||||
|
conan config init
|
||||||
|
yq eval '.compiler.clang.version += ["18"]' -i "$HOME/.conan/settings.yml"
|
||||||
|
- name: Add Apple-clang 16 to list of Conan compilers # workaround for the issue that Conan 1.x doesn't know about Apple-clang 16
|
||||||
|
if: ${{ matrix.ENABLE_CONAN == 'ON' && matrix.runs-on == 'macos-14' }}
|
||||||
|
run: |
|
||||||
|
sudo wget https://github.com/mikefarah/yq/releases/download/v4.9.6/yq_darwin_arm64 -O /usr/local/bin/yq && sudo chmod +x /usr/local/bin/yq
|
||||||
|
|
||||||
|
conan config init
|
||||||
|
yq eval '.compiler.apple-clang.version += ["16.0"]' -i "$HOME/.conan/settings.yml"
|
||||||
|
- name: Prepare build
|
||||||
|
run: |
|
||||||
|
mkdir ${OSRM_BUILD_DIR}
|
||||||
|
ccache --max-size=256M
|
||||||
|
npm ci --ignore-scripts
|
||||||
|
if [[ "${ENABLE_COVERAGE}" == "ON" ]]; then
|
||||||
|
lcov --directory . --zerocounters # clean cached files
|
||||||
|
fi
|
||||||
|
echo "CC=${CCOMPILER}" >> $GITHUB_ENV
|
||||||
|
echo "CXX=${CXXCOMPILER}" >> $GITHUB_ENV
|
||||||
|
if [[ "${RUNNER_OS}" == "macOS" ]]; then
|
||||||
|
# missing from GCC path, needed for conan builds of libiconv, for example.
|
||||||
|
sudo xcode-select --switch /Library/Developer/CommandLineTools
|
||||||
|
echo "LIBRARY_PATH=${LIBRARY_PATH}:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib" >> $GITHUB_ENV
|
||||||
|
echo "CPATH=${CPATH}:/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Build and install OSRM
|
||||||
|
run: |
|
||||||
|
echo "Using ${JOBS} jobs"
|
||||||
|
pushd ${OSRM_BUILD_DIR}
|
||||||
|
|
||||||
|
ccache --zero-stats
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
|
||||||
|
-DENABLE_CONAN=${ENABLE_CONAN:-OFF} \
|
||||||
|
-DENABLE_ASSERTIONS=${ENABLE_ASSERTIONS:-OFF} \
|
||||||
|
-DENABLE_CLANG_TIDY=${ENABLE_CLANG_TIDY:-OFF} \
|
||||||
|
-DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS:-OFF} \
|
||||||
|
-DENABLE_COVERAGE=${ENABLE_COVERAGE:-OFF} \
|
||||||
|
-DENABLE_NODE_BINDINGS=${ENABLE_NODE_BINDINGS:-OFF} \
|
||||||
|
-DENABLE_SANITIZER=${ENABLE_SANITIZER:-OFF} \
|
||||||
|
-DBUILD_TOOLS=${BUILD_TOOLS:-OFF} \
|
||||||
|
-DENABLE_CCACHE=ON \
|
||||||
|
-DENABLE_LTO=${ENABLE_LTO:-ON} \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=${OSRM_INSTALL_DIR}
|
||||||
|
make --jobs=${JOBS}
|
||||||
|
|
||||||
|
if [[ "${NODE_PACKAGE_TESTS_ONLY}" != "ON" ]]; then
|
||||||
|
make tests --jobs=${JOBS}
|
||||||
|
make benchmarks --jobs=${JOBS}
|
||||||
|
|
||||||
|
sudo make install
|
||||||
|
if [[ "${RUNNER_OS}" == "Linux" ]]; then
|
||||||
|
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${OSRM_INSTALL_DIR}/lib" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
echo "PKG_CONFIG_PATH=${OSRM_INSTALL_DIR}/lib/pkgconfig" >> $GITHUB_ENV
|
||||||
|
fi
|
||||||
|
popd
|
||||||
|
- name: Build example
|
||||||
|
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' }}
|
||||||
|
run: |
|
||||||
|
mkdir example/build && pushd example/build
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
|
||||||
|
make --jobs=${JOBS}
|
||||||
|
popd
|
||||||
|
- name: Run all tests
|
||||||
|
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY != 'ON' }}
|
||||||
|
run: |
|
||||||
|
make -C test/data benchmark
|
||||||
|
|
||||||
|
# macOS SIP strips the linker path. Reset this inside the running shell
|
||||||
|
export LD_LIBRARY_PATH=${{ env.LD_LIBRARY_PATH }}
|
||||||
|
./example/build/osrm-example test/data/mld/monaco.osrm
|
||||||
|
|
||||||
|
# All tests assume to be run from the build directory
|
||||||
|
pushd ${OSRM_BUILD_DIR}
|
||||||
|
for i in ./unit_tests/*-tests ; do echo Running $i ; $i ; done
|
||||||
|
if [ -z "${ENABLE_SANITIZER}" ]; then
|
||||||
|
npm run nodejs-tests
|
||||||
|
fi
|
||||||
|
popd
|
||||||
|
npm test
|
||||||
|
|
||||||
|
- name: Use Node 18
|
||||||
|
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- name: Run Node package tests on Node 18
|
||||||
|
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
|
||||||
|
run: |
|
||||||
|
node --version
|
||||||
|
npm run nodejs-tests
|
||||||
|
- name: Use Node 20
|
||||||
|
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20
|
||||||
|
- name: Run Node package tests on Node 20
|
||||||
|
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
|
||||||
|
run: |
|
||||||
|
node --version
|
||||||
|
npm run nodejs-tests
|
||||||
|
- name: Use Node latest
|
||||||
|
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: latest
|
||||||
|
- name: Run Node package tests on Node-latest
|
||||||
|
if: ${{ matrix.NODE_PACKAGE_TESTS_ONLY == 'ON' }}
|
||||||
|
run: |
|
||||||
|
node --version
|
||||||
|
npm run nodejs-tests
|
||||||
|
|
||||||
|
- name: Upload test logs
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
name: logs
|
||||||
|
path: test/logs/
|
||||||
|
|
||||||
|
# - name: Generate code coverage
|
||||||
|
# if: ${{ matrix.ENABLE_COVERAGE == 'ON' }}
|
||||||
|
# run: |
|
||||||
|
# lcov --directory . --capture --output-file coverage.info # capture coverage info
|
||||||
|
# lcov --remove coverage.info '/usr/*' --output-file coverage.info # filter out system
|
||||||
|
# lcov --list coverage.info #debug info
|
||||||
|
|
||||||
|
# # Uploading report to CodeCov
|
||||||
|
# - name: Upload code coverage
|
||||||
|
# if: ${{ matrix.ENABLE_COVERAGE == 'ON' }}
|
||||||
|
# uses: codecov/codecov-action@v4
|
||||||
|
# with:
|
||||||
|
# files: coverage.info
|
||||||
|
# name: codecov-osrm-backend
|
||||||
|
# fail_ci_if_error: true
|
||||||
|
# verbose: true
|
||||||
|
- name: Build Node package
|
||||||
|
if: ${{ matrix.build_node_package }}
|
||||||
|
run: ./scripts/ci/node_package.sh
|
||||||
|
- name: Publish Node package
|
||||||
|
if: ${{ matrix.build_node_package && env.PUBLISH == 'On' }}
|
||||||
|
uses: ncipollo/release-action@v1
|
||||||
|
with:
|
||||||
|
allowUpdates: true
|
||||||
|
artifactErrorsFailBuild: true
|
||||||
|
artifacts: build/stage/**/*.tar.gz
|
||||||
|
omitBody: true
|
||||||
|
omitBodyDuringUpdate: true
|
||||||
|
omitName: true
|
||||||
|
omitNameDuringUpdate: true
|
||||||
|
replacesArtifacts: true
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Show CCache statistics
|
||||||
|
run: |
|
||||||
|
ccache -p
|
||||||
|
ccache -s
|
||||||
|
|
||||||
|
benchmarks:
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
needs: [format-taginfo-docs]
|
||||||
|
runs-on: self-hosted
|
||||||
|
env:
|
||||||
|
CCOMPILER: clang-16
|
||||||
|
CXXCOMPILER: clang++-16
|
||||||
|
CC: clang-16
|
||||||
|
CXX: clang++-16
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
|
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||||
|
RUN_BIG_BENCHMARK: ${{ contains(github.event.pull_request.labels.*.name, 'Performance') }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout PR Branch
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.head_ref }}
|
||||||
|
path: pr
|
||||||
|
- name: Activate virtualenv
|
||||||
|
run: |
|
||||||
|
python3 -m venv .venv
|
||||||
|
source .venv/bin/activate
|
||||||
|
echo PATH=$PATH >> $GITHUB_ENV
|
||||||
|
pip install "conan<2.0.0" "requests==2.31.0" "numpy==1.26.4"
|
||||||
|
- name: Prepare data
|
||||||
|
run: |
|
||||||
|
if [ "$RUN_BIG_BENCHMARK" = "true" ]; then
|
||||||
|
rm -rf ~/data.osm.pbf
|
||||||
|
wget http://download.geofabrik.de/europe/poland-latest.osm.pbf -O ~/data.osm.pbf --quiet
|
||||||
|
gunzip -c ./pr/test/data/poland_gps_traces.csv.gz > ~/gps_traces.csv
|
||||||
|
else
|
||||||
|
if [ ! -f "~/data.osm.pbf" ]; then
|
||||||
|
wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf -O ~/data.osm.pbf
|
||||||
|
else
|
||||||
|
echo "Using cached data.osm.pbf"
|
||||||
|
fi
|
||||||
|
gunzip -c ./pr/test/data/berlin_gps_traces.csv.gz > ~/gps_traces.csv
|
||||||
|
fi
|
||||||
|
- name: Prepare environment
|
||||||
|
run: |
|
||||||
|
echo "CCACHE_DIR=$HOME/.ccache" >> $GITHUB_ENV
|
||||||
|
mkdir -p $HOME/.ccache
|
||||||
|
ccache --zero-stats
|
||||||
|
ccache --max-size=256M
|
||||||
|
- name: Checkout Base Branch
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.base.ref }}
|
||||||
|
path: base
|
||||||
|
- name: Build Base Branch
|
||||||
|
run: |
|
||||||
|
cd base
|
||||||
|
npm ci --ignore-scripts
|
||||||
|
cd ..
|
||||||
|
mkdir base/build
|
||||||
|
cd base/build
|
||||||
|
cmake -DENABLE_CONAN=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_NODE_BINDINGS=ON ..
|
||||||
|
make -j$(nproc)
|
||||||
|
make -j$(nproc) benchmarks
|
||||||
|
cd ..
|
||||||
|
make -C test/data
|
||||||
|
- name: Build PR Branch
|
||||||
|
run: |
|
||||||
|
cd pr
|
||||||
|
npm ci --ignore-scripts
|
||||||
|
cd ..
|
||||||
|
mkdir -p pr/build
|
||||||
|
cd pr/build
|
||||||
|
cmake -DENABLE_CONAN=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_NODE_BINDINGS=ON ..
|
||||||
|
make -j$(nproc)
|
||||||
|
make -j$(nproc) benchmarks
|
||||||
|
cd ..
|
||||||
|
make -C test/data
|
||||||
|
# we run benchmarks in tmpfs to avoid impact of disk IO
|
||||||
|
- name: Create folder for tmpfs
|
||||||
|
run: |
|
||||||
|
# if by any chance it was mounted before(e.g. due to previous job failed), unmount it
|
||||||
|
sudo umount ~/benchmarks | true
|
||||||
|
rm -rf ~/benchmarks
|
||||||
|
mkdir -p ~/benchmarks
|
||||||
|
# see https://llvm.org/docs/Benchmarking.html
|
||||||
|
- name: Run PR Benchmarks
|
||||||
|
run: |
|
||||||
|
sudo cset shield -c 2-3 -k on
|
||||||
|
sudo mount -t tmpfs -o size=4g none ~/benchmarks
|
||||||
|
cp -rf pr/build ~/benchmarks/build
|
||||||
|
cp -rf pr/lib ~/benchmarks/lib
|
||||||
|
mkdir -p ~/benchmarks/test
|
||||||
|
cp -rf pr/test/data ~/benchmarks/test/data
|
||||||
|
cp -rf pr/profiles ~/benchmarks/profiles
|
||||||
|
|
||||||
|
sudo cset shield --exec -- ./pr/scripts/ci/run_benchmarks.sh -f ~/benchmarks -r $(pwd)/pr_results -s $(pwd)/pr -b ~/benchmarks/build -o ~/data.osm.pbf -g ~/gps_traces.csv
|
||||||
|
sudo umount ~/benchmarks
|
||||||
|
sudo cset shield --reset
|
||||||
|
- name: Run Base Benchmarks
|
||||||
|
run: |
|
||||||
|
sudo cset shield -c 2-3 -k on
|
||||||
|
sudo mount -t tmpfs -o size=4g none ~/benchmarks
|
||||||
|
cp -rf base/build ~/benchmarks/build
|
||||||
|
cp -rf base/lib ~/benchmarks/lib
|
||||||
|
mkdir -p ~/benchmarks/test
|
||||||
|
cp -rf base/test/data ~/benchmarks/test/data
|
||||||
|
cp -rf base/profiles ~/benchmarks/profiles
|
||||||
|
|
||||||
|
# TODO: remove it when base branch will have this file at needed location
|
||||||
|
if [ ! -f ~/benchmarks/test/data/portugal_to_korea.json ]; then
|
||||||
|
cp base/src/benchmarks/portugal_to_korea.json ~/benchmarks/test/data/portugal_to_korea.json
|
||||||
|
fi
|
||||||
|
# we intentionally use scripts from PR branch to be able to update them and see results in the same PR
|
||||||
|
sudo cset shield --exec -- cset shield --exec -- ./pr/scripts/ci/run_benchmarks.sh -f ~/benchmarks -r $(pwd)/base_results -s $(pwd)/pr -b ~/benchmarks/build -o ~/data.osm.pbf -g ~/gps_traces.csv
|
||||||
|
sudo umount ~/benchmarks
|
||||||
|
sudo cset shield --reset
|
||||||
|
- name: Post Benchmark Results
|
||||||
|
run: |
|
||||||
|
python3 pr/scripts/ci/post_benchmark_results.py base_results pr_results
|
||||||
|
- name: Show CCache statistics
|
||||||
|
run: |
|
||||||
|
ccache -p
|
||||||
|
ccache -s
|
||||||
|
|
||||||
|
ci-complete:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
needs: [build-test-publish, docker-image-matrix, windows-release-node, benchmarks]
|
||||||
|
steps:
|
||||||
|
- run: echo "CI complete"
|
||||||
|
|
29
.github/workflows/stale.yml
vendored
Normal file
29
.github/workflows/stale.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
name: 'Close stale issues'
|
||||||
|
on:
|
||||||
|
# NOTE: uncomment if you want to test changes to this file in PRs CI
|
||||||
|
# pull_request:
|
||||||
|
# branches:
|
||||||
|
# - master
|
||||||
|
schedule:
|
||||||
|
- cron: '30 1 * * *' # every day at 1:30am
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v9
|
||||||
|
with:
|
||||||
|
operations-per-run: 3000
|
||||||
|
stale-issue-message: 'This issue seems to be stale. It will be closed in 30 days if no further activity occurs.'
|
||||||
|
stale-pr-message: 'This PR seems to be stale. Is it still relevant?'
|
||||||
|
days-before-issue-stale: 180 # 6 months
|
||||||
|
days-before-issue-close: 30 # 1 month
|
||||||
|
days-before-pr-stale: 180 # 6 months
|
||||||
|
days-before-pr-close: -1 # never close PRs
|
||||||
|
exempt-issue-labels: 'Do Not Stale,Feature Request,Performance,Bug Report,CI,Starter Task,Refactor,Guidance'
|
||||||
|
|
||||||
|
|
||||||
|
|
43
.gitignore
vendored
43
.gitignore
vendored
@ -1,3 +1,9 @@
|
|||||||
|
# pre compiled dependencies #
|
||||||
|
#############################
|
||||||
|
osrm-deps
|
||||||
|
|
||||||
|
.ycm_extra_conf.py
|
||||||
|
|
||||||
# Compiled source #
|
# Compiled source #
|
||||||
###################
|
###################
|
||||||
*.com
|
*.com
|
||||||
@ -35,9 +41,12 @@ Thumbs.db
|
|||||||
|
|
||||||
# build related files #
|
# build related files #
|
||||||
#######################
|
#######################
|
||||||
|
/_build*
|
||||||
/build/
|
/build/
|
||||||
/util/fingerprint_impl.hpp
|
/example/build/
|
||||||
/util/git_sha.cpp
|
/test/data/monaco.osrm*
|
||||||
|
/test/data/ch
|
||||||
|
/test/data/mld
|
||||||
/cmake/postinst
|
/cmake/postinst
|
||||||
|
|
||||||
# Eclipse related files #
|
# Eclipse related files #
|
||||||
@ -47,11 +56,16 @@ Thumbs.db
|
|||||||
.cproject
|
.cproject
|
||||||
.project
|
.project
|
||||||
|
|
||||||
# stxxl related files #
|
# Visual Studio (Code) related files #
|
||||||
#######################
|
######################################
|
||||||
.stxxl
|
/.vs*
|
||||||
stxxl.log
|
/*.local.bat
|
||||||
stxxl.errlog
|
/CMakeSettings.json
|
||||||
|
/.cache
|
||||||
|
|
||||||
|
# Jetbrains related files #
|
||||||
|
###########################
|
||||||
|
.idea/
|
||||||
|
|
||||||
# Compiled Binary Files #
|
# Compiled Binary Files #
|
||||||
####################################
|
####################################
|
||||||
@ -71,8 +85,23 @@ stxxl.errlog
|
|||||||
###################
|
###################
|
||||||
/sandbox/
|
/sandbox/
|
||||||
|
|
||||||
|
# Test related files #
|
||||||
|
######################
|
||||||
/test/profile.lua
|
/test/profile.lua
|
||||||
|
/test/cache
|
||||||
|
/test/speeds.csv
|
||||||
|
/test/penalties.csv
|
||||||
|
node_modules
|
||||||
|
|
||||||
# Deprecated config file #
|
# Deprecated config file #
|
||||||
##########################
|
##########################
|
||||||
/server.ini
|
/server.ini
|
||||||
|
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# local lua debugging file
|
||||||
|
debug.lua
|
||||||
|
|
||||||
|
# node-osrm artifacts
|
||||||
|
lib/binding
|
||||||
|
|
||||||
|
16
.npmignore
Normal file
16
.npmignore
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
*
|
||||||
|
!README.md
|
||||||
|
!CHANGELOG.md
|
||||||
|
!CONTRIBUTING.MD
|
||||||
|
!LICENCE.TXT
|
||||||
|
!package.json
|
||||||
|
!package-lock.json
|
||||||
|
!yarn.lock
|
||||||
|
!docs
|
||||||
|
!example
|
||||||
|
!taginfo.json
|
||||||
|
!lib/*.js
|
||||||
|
!profiles/*
|
||||||
|
!profiles/lib/*
|
||||||
|
!profiles/examples/*
|
||||||
|
!scripts/node_install.sh
|
64
.travis.yml
64
.travis.yml
@ -1,64 +0,0 @@
|
|||||||
language: cpp
|
|
||||||
compiler:
|
|
||||||
- gcc
|
|
||||||
# - clang
|
|
||||||
# Make sure CMake is installed
|
|
||||||
install:
|
|
||||||
- sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test
|
|
||||||
- sudo add-apt-repository -y ppa:boost-latest/ppa
|
|
||||||
- sudo apt-get update >/dev/null
|
|
||||||
- sudo apt-get -q install protobuf-compiler libprotoc-dev libprotobuf7 libprotobuf-dev libbz2-dev libstxxl-dev libstxxl1 libxml2-dev libzip-dev lua5.1 liblua5.1-0-dev rubygems libtbb-dev
|
|
||||||
- sudo apt-get -q install g++-4.8
|
|
||||||
- sudo apt-get install libboost1.54-all-dev
|
|
||||||
- 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
|
|
||||||
# osmpbf library
|
|
||||||
- curl -s https://gist.githubusercontent.com/DennisOSRM/13b1b4fe38a57ead850e/raw/install_osmpbf.sh | sudo bash
|
|
||||||
before_script:
|
|
||||||
- rvm use 1.9.3
|
|
||||||
- gem install bundler
|
|
||||||
- bundle install
|
|
||||||
- mkdir build
|
|
||||||
- cd build
|
|
||||||
- cmake .. $CMAKEOPTIONS -DBUILD_TOOLS=1
|
|
||||||
script:
|
|
||||||
- make
|
|
||||||
- make tests
|
|
||||||
- make benchmarks
|
|
||||||
- ./datastructure-tests
|
|
||||||
- cd ..
|
|
||||||
- cucumber -p verify
|
|
||||||
after_script:
|
|
||||||
# - cd ..
|
|
||||||
# - cucumber -p verify
|
|
||||||
branches:
|
|
||||||
only:
|
|
||||||
- master
|
|
||||||
- develop
|
|
||||||
cache:
|
|
||||||
- bundler
|
|
||||||
- apt
|
|
||||||
env:
|
|
||||||
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5000 OSRM_TIMEOUT=60
|
|
||||||
- CMAKEOPTIONS="-DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_COMPILER=g++-4.8" OSRM_PORT=5010 OSRM_TIMEOUT=60
|
|
||||||
- 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:
|
|
||||||
- dennis@mapbox.com
|
|
||||||
email:
|
|
||||||
on_success: change
|
|
||||||
on_failure: always
|
|
1102
CHANGELOG.md
Normal file
1102
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
945
CMakeLists.txt
945
CMakeLists.txt
File diff suppressed because it is too large
Load Diff
3
CODE-OF-CONDUCT.md
Normal file
3
CODE-OF-CONDUCT.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Code of conduct
|
||||||
|
|
||||||
|
Everyone is invited to participate in Project OSRM’s open source projects and public discussions: we want to create a welcoming and friendly environment. Harassment of participants or other unethical and unprofessional behavior will not be tolerated in our spaces. The [Contributor Covenant](http://contributor-covenant.org) applies to all projects under the Project-OSRM organization and we ask that you please read [the full text](http://contributor-covenant.org/version/1/2/0/).
|
81
CONTRIBUTING.md
Normal file
81
CONTRIBUTING.md
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
# Everyone
|
||||||
|
|
||||||
|
Please take some time to review our [code of conduct](CODE-OF-CONDUCT.md) to help guide your interactions with others on this project.
|
||||||
|
|
||||||
|
# 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 reaction to the issue if you want to express interest in this.
|
||||||
|
|
||||||
|
# Developer
|
||||||
|
|
||||||
|
We use `clang-format` version `15` 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 && ./scripts/error_on_dirty.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
Doxyfile.in
Normal file
44
Doxyfile.in
Normal file
@ -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
|
7
Gemfile
7
Gemfile
@ -1,7 +0,0 @@
|
|||||||
source "http://rubygems.org"
|
|
||||||
|
|
||||||
gem "cucumber"
|
|
||||||
gem "rake"
|
|
||||||
gem "osmlib-base"
|
|
||||||
gem "sys-proctable"
|
|
||||||
gem "rspec-expectations"
|
|
30
Gemfile.lock
30
Gemfile.lock
@ -1,30 +0,0 @@
|
|||||||
GEM
|
|
||||||
remote: http://rubygems.org/
|
|
||||||
specs:
|
|
||||||
builder (3.2.2)
|
|
||||||
cucumber (1.3.8)
|
|
||||||
builder (>= 2.1.2)
|
|
||||||
diff-lcs (>= 1.1.3)
|
|
||||||
gherkin (~> 2.12.1)
|
|
||||||
multi_json (>= 1.7.5, < 2.0)
|
|
||||||
multi_test (>= 0.0.2)
|
|
||||||
diff-lcs (1.2.4)
|
|
||||||
gherkin (2.12.1)
|
|
||||||
multi_json (~> 1.3)
|
|
||||||
multi_json (1.8.0)
|
|
||||||
multi_test (0.0.2)
|
|
||||||
osmlib-base (0.1.4)
|
|
||||||
rake (10.1.0)
|
|
||||||
rspec-expectations (2.14.3)
|
|
||||||
diff-lcs (>= 1.1.3, < 2.0)
|
|
||||||
sys-proctable (0.9.3)
|
|
||||||
|
|
||||||
PLATFORMS
|
|
||||||
ruby
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
cucumber
|
|
||||||
osmlib-base
|
|
||||||
rake
|
|
||||||
rspec-expectations
|
|
||||||
sys-proctable
|
|
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2015, Project OSRM contributors
|
Copyright (c) 2017, 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,
|
178
README.md
178
README.md
@ -1,12 +1,171 @@
|
|||||||
# Readme
|
## Open Source Routing Machine
|
||||||
|
|
||||||
For instructions on how to compile and run OSRM, please consult the Wiki at
|
|
||||||
|
|
||||||
https://github.com/Project-OSRM/osrm-backend/wiki
|
[](https://github.com/Project-OSRM/osrm-backend/actions/workflows/osrm-backend.yml) [](https://codecov.io/gh/Project-OSRM/osrm-backend) [](https://discord.gg/es9CdcCXcb)
|
||||||
|
|
||||||
or use our free and daily updated online service at
|
High performance routing engine written in C++ designed to run on OpenStreetMap data.
|
||||||
|
|
||||||
|
The following services are available via HTTP API, C++ library interface and NodeJs wrapper:
|
||||||
|
- Nearest - Snaps coordinates to the street network and returns the nearest matches
|
||||||
|
- Route - Finds the fastest route between coordinates
|
||||||
|
- Table - Computes the duration or distances of the fastest route between all pairs of supplied coordinates
|
||||||
|
- Match - Snaps noisy GPS traces to the road network in the most plausible way
|
||||||
|
- Trip - Solves the Traveling Salesman Problem using a greedy heuristic
|
||||||
|
- Tile - Generates Mapbox Vector Tiles with internal routing metadata
|
||||||
|
|
||||||
|
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 a quick introduction about how the road network is represented in OpenStreetMap and how to map specific road network features have a look at [the OSM wiki on routing](https://wiki.openstreetmap.org/wiki/Routing) or [this guide about mapping for navigation](https://web.archive.org/web/20221206013651/https://labs.mapbox.com/mapping/mapping-for-navigation/).
|
||||||
|
|
||||||
|
Related [Project-OSRM](https://github.com/Project-OSRM) repositories:
|
||||||
|
- [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
|
||||||
|
- [osrm-backend-docker](https://github.com/project-osrm/osrm-backend/pkgs/container/osrm-backend) - Ready to use Docker images
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
### Full documentation
|
||||||
|
|
||||||
|
- [Hosted documentation](http://project-osrm.org)
|
||||||
|
- [osrm-routed HTTP API documentation](docs/http.md)
|
||||||
|
- [libosrm API documentation](docs/libosrm.md)
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
- Discord: [join](https://discord.gg/es9CdcCXcb)
|
||||||
|
- IRC: `irc.oftc.net`, channel: `#osrm` ([Webchat](https://webchat.oftc.net))
|
||||||
|
- Mailinglist: `https://lists.openstreetmap.org/listinfo/osrm-talk`
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
The easiest and quickest way to setup your own routing engine is to use Docker images we provide.
|
||||||
|
|
||||||
|
There are two pre-processing pipelines available:
|
||||||
|
- Contraction Hierarchies (CH)
|
||||||
|
- Multi-Level Dijkstra (MLD)
|
||||||
|
|
||||||
|
we recommend using MLD by default except for special use-cases such as very large distance matrices where CH is still a better fit for the time being.
|
||||||
|
In the following we explain the MLD pipeline.
|
||||||
|
If you want to use the CH pipeline instead replace `osrm-partition` and `osrm-customize` with a single `osrm-contract` and change the algorithm option for `osrm-routed` to `--algorithm ch`.
|
||||||
|
|
||||||
|
### Using Docker
|
||||||
|
|
||||||
|
We base our Docker images ([backend](https://github.com/Project-OSRM/osrm-backend/pkgs/container/osrm-backend), [frontend](https://hub.docker.com/r/osrm/osrm-frontend/)) on Debian and make sure they are as lightweight as possible. Older backend versions can be found on [Docker Hub](https://hub.docker.com/r/osrm/osrm-backend/).
|
||||||
|
|
||||||
|
Download OpenStreetMap extracts for example from [Geofabrik](http://download.geofabrik.de/)
|
||||||
|
|
||||||
|
wget http://download.geofabrik.de/europe/germany/berlin-latest.osm.pbf
|
||||||
|
|
||||||
|
Pre-process the extract with the car profile and start a routing engine HTTP server on port 5000
|
||||||
|
|
||||||
|
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-extract -p /opt/car.lua /data/berlin-latest.osm.pbf || echo "osrm-extract failed"
|
||||||
|
|
||||||
|
The flag `-v "${PWD}:/data"` creates the directory `/data` inside the docker container and makes the current working directory `"${PWD}"` available there. The file `/data/berlin-latest.osm.pbf` inside the container is referring to `"${PWD}/berlin-latest.osm.pbf"` on the host.
|
||||||
|
|
||||||
|
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-partition /data/berlin-latest.osrm || echo "osrm-partition failed"
|
||||||
|
docker run -t -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-customize /data/berlin-latest.osrm || echo "osrm-customize failed"
|
||||||
|
|
||||||
|
Note there is no `berlin-latest.osrm` file, but multiple `berlin-latest.osrm.*` files, i.e. `berlin-latest.osrm` is not file path, but "base" path referring to set of files and there is an option to omit this `.osrm` suffix completely(e.g. `osrm-partition /data/berlin-latest`).
|
||||||
|
|
||||||
|
docker run -t -i -p 5000:5000 -v "${PWD}:/data" ghcr.io/project-osrm/osrm-backend osrm-routed --algorithm mld /data/berlin-latest.osrm
|
||||||
|
|
||||||
|
Make requests against the HTTP server
|
||||||
|
|
||||||
|
curl "http://127.0.0.1:5000/route/v1/driving/13.388860,52.517037;13.385983,52.496891?steps=true"
|
||||||
|
|
||||||
|
Optionally start a user-friendly frontend on port 9966, and open it up in your browser
|
||||||
|
|
||||||
|
docker run -p 9966:9966 osrm/osrm-frontend
|
||||||
|
xdg-open 'http://127.0.0.1:9966'
|
||||||
|
|
||||||
|
In case Docker complains about not being able to connect to the Docker daemon make sure you are in the `docker` group.
|
||||||
|
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
|
|
||||||
|
After adding yourself to the `docker` group make sure to log out and back in again with your terminal.
|
||||||
|
|
||||||
|
We support the following images in the Container Registry:
|
||||||
|
|
||||||
|
Name | Description
|
||||||
|
-----|------
|
||||||
|
`latest` | `master` compiled with release flag
|
||||||
|
`latest-assertions` | `master` compiled with with release flag, assertions enabled and debug symbols
|
||||||
|
`latest-debug` | `master` compiled with debug flag
|
||||||
|
`<tag>` | specific tag compiled with release flag
|
||||||
|
`<tag>-debug` | specific tag compiled with debug flag
|
||||||
|
|
||||||
|
### Building from Source
|
||||||
|
|
||||||
|
The following targets Ubuntu 22.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 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
|
||||||
|
```
|
||||||
|
|
||||||
|
### Request Against the Demo Server
|
||||||
|
|
||||||
|
Read the [API usage policy](https://github.com/Project-OSRM/osrm-backend/wiki/Demo-server).
|
||||||
|
|
||||||
|
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"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using the Node.js Bindings
|
||||||
|
|
||||||
|
The Node.js bindings provide read-only access to the routing engine.
|
||||||
|
We provide API documentation and examples [here](docs/nodejs/api.md).
|
||||||
|
|
||||||
|
You will need a modern `libstdc++` toolchain (`>= GLIBCXX_3.4.26`) for binary compatibility if you want to use the pre-built binaries.
|
||||||
|
For older Ubuntu systems you can upgrade your standard library for example with:
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
|
||||||
|
sudo apt-get update -y
|
||||||
|
sudo apt-get install -y libstdc++-9-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
You can install the Node.js bindings via `npm install @project-osrm/osrm` or from this repository either via
|
||||||
|
|
||||||
|
npm install
|
||||||
|
|
||||||
|
which will check and use pre-built binaries if they're available for this release and your Node version, or via
|
||||||
|
|
||||||
|
npm install --build-from-source
|
||||||
|
|
||||||
|
to always force building the Node.js bindings from source.
|
||||||
|
|
||||||
|
#### Unscoped packages
|
||||||
|
|
||||||
|
Prior to v5.27.0, the `osrm` Node package was unscoped. If you are upgrading from an old package, you will need to do the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm uninstall osrm --save
|
||||||
|
npm install @project-osrm/osrm --save
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Package docs
|
||||||
|
|
||||||
|
For usage details have a look [these API docs](docs/nodejs/api.md).
|
||||||
|
|
||||||
|
An exemplary implementation by a 3rd party with Docker and Node.js can be found [here](https://github.com/door2door-io/osrm-express-server-demo).
|
||||||
|
|
||||||
http://map.project-osrm.org
|
|
||||||
|
|
||||||
## References in publications
|
## References in publications
|
||||||
|
|
||||||
@ -30,12 +189,3 @@ When using the code in a (scientific) publication, please cite
|
|||||||
address = {New York, NY, USA},
|
address = {New York, NY, USA},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Current build status
|
|
||||||
|
|
||||||
| build config | branch | status |
|
|
||||||
|:-------------|:--------|:------------|
|
|
||||||
| Linux | master | [](https://travis-ci.org/DennisOSRM/Project-OSRM) |
|
|
||||||
| Linux | develop | [](https://travis-ci.org/DennisOSRM/Project-OSRM) |
|
|
||||||
| Windows | master/develop | [](https://ci.appveyor.com/project/DennisOSRM/osrm-backend) |
|
|
||||||
| LUAbind fork | master | [](https://travis-ci.org/DennisOSRM/luabind) |
|
|
||||||
|
190
Rakefile
190
Rakefile
@ -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,145 +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 ITERATOR_BASED_CRC32_H
|
|
||||||
#define ITERATOR_BASED_CRC32_H
|
|
||||||
|
|
||||||
#if defined(__x86_64__) && !defined(__MINGW64__)
|
|
||||||
#include <cpuid.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <boost/crc.hpp> // for boost::crc_32_type
|
|
||||||
|
|
||||||
#include <iterator>
|
|
||||||
|
|
||||||
class IteratorbasedCRC32
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool using_hardware() const { return use_hardware_implementation; }
|
|
||||||
|
|
||||||
IteratorbasedCRC32() : crc(0) { use_hardware_implementation = detect_hardware_support(); }
|
|
||||||
|
|
||||||
template <class Iterator> unsigned operator()(Iterator iter, const Iterator end)
|
|
||||||
{
|
|
||||||
unsigned crc = 0;
|
|
||||||
while (iter != end)
|
|
||||||
{
|
|
||||||
using value_type = typename std::iterator_traits<Iterator>::value_type;
|
|
||||||
const char *data = reinterpret_cast<const char *>(&(*iter));
|
|
||||||
|
|
||||||
if (use_hardware_implementation)
|
|
||||||
{
|
|
||||||
crc = compute_in_hardware(data, sizeof(value_type));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
crc = compute_in_software(data, sizeof(value_type));
|
|
||||||
}
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool detect_hardware_support() const
|
|
||||||
{
|
|
||||||
static const int sse42_bit = 0x00100000;
|
|
||||||
const unsigned ecx = cpuid();
|
|
||||||
const bool sse42_found = (ecx & sse42_bit) != 0;
|
|
||||||
return sse42_found;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned compute_in_software(const char *str, unsigned len)
|
|
||||||
{
|
|
||||||
crc_processor.process_bytes(str, len);
|
|
||||||
return crc_processor.checksum();
|
|
||||||
}
|
|
||||||
|
|
||||||
// adapted from http://byteworm.com/2010/10/13/crc32/
|
|
||||||
unsigned compute_in_hardware(const char *str, unsigned len)
|
|
||||||
{
|
|
||||||
#if defined(__x86_64__)
|
|
||||||
unsigned q = len / sizeof(unsigned);
|
|
||||||
unsigned r = len % sizeof(unsigned);
|
|
||||||
unsigned *p = (unsigned *)str;
|
|
||||||
|
|
||||||
// crc=0;
|
|
||||||
while (q--)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__(".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
|
|
||||||
: "=S"(crc)
|
|
||||||
: "0"(crc), "c"(*p));
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
|
|
||||||
str = reinterpret_cast<char *>(p);
|
|
||||||
while (r--)
|
|
||||||
{
|
|
||||||
__asm__ __volatile__(".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;"
|
|
||||||
: "=S"(crc)
|
|
||||||
: "0"(crc), "c"(*str));
|
|
||||||
++str;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned cpuid() const
|
|
||||||
{
|
|
||||||
unsigned eax = 0, ebx = 0, ecx = 0, edx = 0;
|
|
||||||
// on X64 this calls hardware cpuid(.) instr. otherwise a dummy impl.
|
|
||||||
__get_cpuid(1, &eax, &ebx, &ecx, &edx);
|
|
||||||
return ecx;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__MINGW64__) || defined(_MSC_VER) || !defined(__x86_64__)
|
|
||||||
inline void
|
|
||||||
__get_cpuid(int param, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) const
|
|
||||||
{
|
|
||||||
*ecx = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
boost::crc_optimal<32, 0x1EDC6F41, 0x0, 0x0, true, true> crc_processor;
|
|
||||||
unsigned crc;
|
|
||||||
bool use_hardware_implementation;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RangebasedCRC32
|
|
||||||
{
|
|
||||||
template <typename Iteratable> unsigned operator()(const Iteratable &iterable)
|
|
||||||
{
|
|
||||||
return crc32(std::begin(iterable), std::end(iterable));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool using_hardware() const { return crc32.using_hardware(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
IteratorbasedCRC32 crc32;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* ITERATOR_BASED_CRC32_H */
|
|
@ -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");
|
|
||||||
RandomAccessIt left_border = begin;
|
|
||||||
RandomAccessIt right_border = std::next(begin);
|
|
||||||
// Sweep over array and identify those ranges that need to be checked
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// traverse list until new border element found
|
|
||||||
if (right_border->necessary)
|
|
||||||
{
|
|
||||||
// sanity checks
|
|
||||||
BOOST_ASSERT(left_border->necessary);
|
|
||||||
BOOST_ASSERT(right_border->necessary);
|
|
||||||
recursion_stack.emplace(left_border, right_border);
|
|
||||||
left_border = right_border;
|
|
||||||
}
|
|
||||||
++right_border;
|
|
||||||
} while (right_border != end);
|
|
||||||
}
|
|
||||||
|
|
||||||
// mark locations as 'necessary' by divide-and-conquer
|
|
||||||
while (!recursion_stack.empty())
|
|
||||||
{
|
|
||||||
// pop next element
|
|
||||||
const GeometryRange pair = recursion_stack.top();
|
|
||||||
recursion_stack.pop();
|
|
||||||
// sanity checks
|
|
||||||
BOOST_ASSERT_MSG(pair.first->necessary, "left border must be necessary");
|
|
||||||
BOOST_ASSERT_MSG(pair.second->necessary, "right border must be necessary");
|
|
||||||
BOOST_ASSERT_MSG(std::distance(pair.second, end) > 0, "right border outside of geometry");
|
|
||||||
BOOST_ASSERT_MSG(std::distance(pair.first, pair.second) >= 0,
|
|
||||||
"left border on the wrong side");
|
|
||||||
|
|
||||||
int max_int_distance = 0;
|
|
||||||
auto farthest_entry_it = pair.second;
|
|
||||||
const CoordinatePairCalculator dist_calc(pair.first->location, pair.second->location);
|
|
||||||
|
|
||||||
// sweep over range to find the maximum
|
|
||||||
for (auto it = std::next(pair.first); it != pair.second; ++it)
|
|
||||||
{
|
|
||||||
const int distance = dist_calc(it->location);
|
|
||||||
// found new feasible maximum?
|
|
||||||
if (distance > max_int_distance && distance > DOUGLAS_PEUCKER_THRESHOLDS[zoom_level])
|
|
||||||
{
|
|
||||||
farthest_entry_it = it;
|
|
||||||
max_int_distance = distance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if maximum violates a zoom level dependent threshold
|
|
||||||
if (max_int_distance > DOUGLAS_PEUCKER_THRESHOLDS[zoom_level])
|
|
||||||
{
|
|
||||||
// mark idx as necessary
|
|
||||||
farthest_entry_it->necessary = true;
|
|
||||||
if (1 < std::distance(pair.first, farthest_entry_it))
|
|
||||||
{
|
|
||||||
recursion_stack.emplace(pair.first, farthest_entry_it);
|
|
||||||
}
|
|
||||||
if (1 < std::distance(farthest_entry_it, pair.second))
|
|
||||||
{
|
|
||||||
recursion_stack.emplace(farthest_entry_it, pair.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,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,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() - 1),
|
|
||||||
reinterpret_cast<char *>(&object));
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* OBJECT_ENCODER_HPP */
|
|
@ -1,90 +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);
|
|
||||||
}
|
|
@ -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,239 +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 TINY_COMPONENTS_HPP
|
|
||||||
#define TINY_COMPONENTS_HPP
|
|
||||||
|
|
||||||
#include "../typedefs.h"
|
|
||||||
#include "../data_structures/deallocating_vector.hpp"
|
|
||||||
#include "../data_structures/import_edge.hpp"
|
|
||||||
#include "../data_structures/query_node.hpp"
|
|
||||||
#include "../data_structures/percent.hpp"
|
|
||||||
#include "../data_structures/restriction.hpp"
|
|
||||||
#include "../data_structures/restriction_map.hpp"
|
|
||||||
#include "../data_structures/turn_instructions.hpp"
|
|
||||||
|
|
||||||
#include "../util/integer_range.hpp"
|
|
||||||
#include "../util/simple_logger.hpp"
|
|
||||||
#include "../util/std_hash.hpp"
|
|
||||||
#include "../util/timing_util.hpp"
|
|
||||||
|
|
||||||
#include <osrm/coordinate.hpp>
|
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
|
|
||||||
#include <tbb/parallel_sort.h>
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <stack>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
template <typename GraphT> class TarjanSCC
|
|
||||||
{
|
|
||||||
struct TarjanStackFrame
|
|
||||||
{
|
|
||||||
explicit TarjanStackFrame(NodeID v, NodeID parent) : v(v), parent(parent) {}
|
|
||||||
NodeID v;
|
|
||||||
NodeID parent;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TarjanNode
|
|
||||||
{
|
|
||||||
TarjanNode() : index(SPECIAL_NODEID), low_link(SPECIAL_NODEID), on_stack(false) {}
|
|
||||||
unsigned index;
|
|
||||||
unsigned low_link;
|
|
||||||
bool on_stack;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<unsigned> components_index;
|
|
||||||
std::vector<NodeID> component_size_vector;
|
|
||||||
std::shared_ptr<GraphT> m_node_based_graph;
|
|
||||||
std::unordered_set<NodeID> barrier_node_set;
|
|
||||||
RestrictionMap m_restriction_map;
|
|
||||||
std::size_t size_one_counter;
|
|
||||||
|
|
||||||
public:
|
|
||||||
template <class ContainerT>
|
|
||||||
TarjanSCC(std::shared_ptr<GraphT> graph,
|
|
||||||
const RestrictionMap &restrictions,
|
|
||||||
const ContainerT &barrier_node_list)
|
|
||||||
: components_index(graph->GetNumberOfNodes(), SPECIAL_NODEID), m_node_based_graph(graph),
|
|
||||||
m_restriction_map(restrictions), size_one_counter(0)
|
|
||||||
{
|
|
||||||
barrier_node_set.insert(std::begin(barrier_node_list), std::end(barrier_node_list));
|
|
||||||
BOOST_ASSERT(m_node_based_graph->GetNumberOfNodes() > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void run()
|
|
||||||
{
|
|
||||||
TIMER_START(SCC_RUN);
|
|
||||||
const NodeID max_node_id = m_node_based_graph->GetNumberOfNodes();
|
|
||||||
|
|
||||||
// The following is a hack to distinguish between stuff that happens
|
|
||||||
// before the recursive call and stuff that happens after
|
|
||||||
std::stack<TarjanStackFrame> recursion_stack;
|
|
||||||
// true = stuff before, false = stuff after call
|
|
||||||
std::stack<NodeID> tarjan_stack;
|
|
||||||
std::vector<TarjanNode> tarjan_node_list(max_node_id);
|
|
||||||
unsigned component_index = 0, size_of_current_component = 0;
|
|
||||||
unsigned index = 0;
|
|
||||||
std::vector<bool> processing_node_before_recursion(max_node_id, true);
|
|
||||||
for (const NodeID node : osrm::irange(0u, max_node_id))
|
|
||||||
{
|
|
||||||
if (SPECIAL_NODEID == components_index[node])
|
|
||||||
{
|
|
||||||
recursion_stack.emplace(TarjanStackFrame(node, node));
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!recursion_stack.empty())
|
|
||||||
{
|
|
||||||
TarjanStackFrame currentFrame = recursion_stack.top();
|
|
||||||
const NodeID u = currentFrame.parent;
|
|
||||||
const NodeID v = currentFrame.v;
|
|
||||||
recursion_stack.pop();
|
|
||||||
|
|
||||||
const bool before_recursion = processing_node_before_recursion[v];
|
|
||||||
|
|
||||||
if (before_recursion && tarjan_node_list[v].index != UINT_MAX)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (before_recursion)
|
|
||||||
{
|
|
||||||
// Mark frame to handle tail of recursion
|
|
||||||
recursion_stack.emplace(currentFrame);
|
|
||||||
processing_node_before_recursion[v] = false;
|
|
||||||
|
|
||||||
// Mark essential information for SCC
|
|
||||||
tarjan_node_list[v].index = index;
|
|
||||||
tarjan_node_list[v].low_link = index;
|
|
||||||
tarjan_stack.push(v);
|
|
||||||
tarjan_node_list[v].on_stack = true;
|
|
||||||
++index;
|
|
||||||
|
|
||||||
const NodeID to_node_of_only_restriction =
|
|
||||||
m_restriction_map.CheckForEmanatingIsOnlyTurn(u, v);
|
|
||||||
|
|
||||||
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(v))
|
|
||||||
{
|
|
||||||
const auto vprime = m_node_based_graph->GetTarget(current_edge);
|
|
||||||
|
|
||||||
// Traverse outgoing edges
|
|
||||||
if (barrier_node_set.find(v) != barrier_node_set.end() && u != vprime)
|
|
||||||
{
|
|
||||||
// continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to_node_of_only_restriction != std::numeric_limits<unsigned>::max() &&
|
|
||||||
vprime == to_node_of_only_restriction)
|
|
||||||
{
|
|
||||||
// At an only_-restriction but not at the right turn
|
|
||||||
// continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_restriction_map.CheckIfTurnIsRestricted(u, v, vprime))
|
|
||||||
{
|
|
||||||
// continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SPECIAL_NODEID == tarjan_node_list[vprime].index)
|
|
||||||
{
|
|
||||||
recursion_stack.emplace(TarjanStackFrame(vprime, v));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (tarjan_node_list[vprime].on_stack &&
|
|
||||||
tarjan_node_list[vprime].index < tarjan_node_list[v].low_link)
|
|
||||||
{
|
|
||||||
tarjan_node_list[v].low_link = tarjan_node_list[vprime].index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
processing_node_before_recursion[v] = true;
|
|
||||||
tarjan_node_list[currentFrame.parent].low_link =
|
|
||||||
std::min(tarjan_node_list[currentFrame.parent].low_link,
|
|
||||||
tarjan_node_list[v].low_link);
|
|
||||||
// after recursion, lets do cycle checking
|
|
||||||
// Check if we found a cycle. This is the bottom part of the recursion
|
|
||||||
if (tarjan_node_list[v].low_link == tarjan_node_list[v].index)
|
|
||||||
{
|
|
||||||
NodeID vprime;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
vprime = tarjan_stack.top();
|
|
||||||
tarjan_stack.pop();
|
|
||||||
tarjan_node_list[vprime].on_stack = false;
|
|
||||||
components_index[vprime] = component_index;
|
|
||||||
++size_of_current_component;
|
|
||||||
} while (v != vprime);
|
|
||||||
|
|
||||||
component_size_vector.emplace_back(size_of_current_component);
|
|
||||||
|
|
||||||
if (size_of_current_component > 1000)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "large component [" << component_index
|
|
||||||
<< "]=" << size_of_current_component;
|
|
||||||
}
|
|
||||||
|
|
||||||
++component_index;
|
|
||||||
size_of_current_component = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TIMER_STOP(SCC_RUN);
|
|
||||||
SimpleLogger().Write() << "SCC run took: " << TIMER_MSEC(SCC_RUN) / 1000. << "s";
|
|
||||||
|
|
||||||
size_one_counter = std::count_if(component_size_vector.begin(), component_size_vector.end(),
|
|
||||||
[](unsigned value)
|
|
||||||
{
|
|
||||||
return 1 == value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t get_number_of_components() const { return component_size_vector.size(); }
|
|
||||||
|
|
||||||
std::size_t get_size_one_count() const { return size_one_counter; }
|
|
||||||
|
|
||||||
unsigned get_component_size(const NodeID node) const
|
|
||||||
{
|
|
||||||
return component_size_vector[components_index[node]];
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned get_component_id(const NodeID node) const { return components_index[node]; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* TINY_COMPONENTS_HPP */
|
|
75
appveyor.yml
75
appveyor.yml
@ -1,75 +0,0 @@
|
|||||||
environment:
|
|
||||||
matrix:
|
|
||||||
- configuration: Debug
|
|
||||||
- configuration: Release
|
|
||||||
|
|
||||||
# branches to build
|
|
||||||
branches:
|
|
||||||
# whitelist
|
|
||||||
only:
|
|
||||||
- develop
|
|
||||||
|
|
||||||
# scripts that are called at very beginning, before repo cloning
|
|
||||||
init:
|
|
||||||
- git config --global core.autocrlf input
|
|
||||||
|
|
||||||
# clone directory
|
|
||||||
clone_folder: c:\projects\osrm
|
|
||||||
|
|
||||||
platform: x64
|
|
||||||
|
|
||||||
install:
|
|
||||||
# by default, all script lines are interpreted as batch
|
|
||||||
- nuget install protobuf
|
|
||||||
- cd c:\projects\osrm
|
|
||||||
- curl -O http://build.project-osrm.org/libs_osrm_%Configuration%.7z
|
|
||||||
- 7z x libs_osrm_%Configuration%.7z | find ":"
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- cd c:/projects/osrm
|
|
||||||
- mkdir build
|
|
||||||
- cd build
|
|
||||||
- echo Running cmake...
|
|
||||||
- call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
|
|
||||||
- SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH%
|
|
||||||
- SET P=c:/projects/osrm
|
|
||||||
- set TBB_INSTALL_DIR=%P%/tbb
|
|
||||||
- set TBB_ARCH_PLATFORM=intel64/vc12
|
|
||||||
- cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_ADDITIONAL_VERSIONS=1.57 -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013
|
|
||||||
- msbuild /clp:Verbosity=minimal /nologo OSRM.sln
|
|
||||||
- msbuild /clp:Verbosity=minimal /nologo tests.vcxproj
|
|
||||||
- cd %Configuration%
|
|
||||||
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip)
|
|
||||||
- cd ..\..\profiles
|
|
||||||
- echo disk=c:\temp\stxxl,10000,wincall > .stxxl.txt
|
|
||||||
- if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip * -tzip)
|
|
||||||
- set PATH=%PATH%;c:/projects/osrm/libs/bin
|
|
||||||
- cd c:/projects/osrm/build/%Configuration%
|
|
||||||
- datastructure-tests.exe
|
|
||||||
- algorithm-tests.exe
|
|
||||||
|
|
||||||
test: off
|
|
||||||
|
|
||||||
artifacts:
|
|
||||||
- path: osrm_Debug.zip
|
|
||||||
name: osrm_Debug.zip
|
|
||||||
- path: osrm_Release.zip
|
|
||||||
name: osrm_Release.zip
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
provider: FTP
|
|
||||||
server:
|
|
||||||
secure: ef7oiQTTXFGt8NdNiOHm/uRFVrUttzyFbIlnaeHhQvw=
|
|
||||||
username:
|
|
||||||
secure: Bw+Se2GTJxA6+GtRkEc//tQSBHOuFIuJHBjFwR9cD+8=
|
|
||||||
password:
|
|
||||||
secure: eqwESZqxMXC/j5mOCpaXuw==
|
|
||||||
folder: /
|
|
||||||
enable_ssl: true
|
|
||||||
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;
|
|
||||||
}
|
|
44
cmake/CPackConfig.cmake
Normal file
44
cmake/CPackConfig.cmake
Normal file
@ -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}/LICENSE.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, libprotobuf-dev, libosmpbf-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]")
|
|
@ -1,29 +0,0 @@
|
|||||||
# - Check whether the CXX compiler supports a given flag.
|
|
||||||
# CHECK_CXX_COMPILER_FLAG(<flag> <var>)
|
|
||||||
# <flag> - the compiler flag
|
|
||||||
# <var> - variable to store the result
|
|
||||||
# This internally calls the check_cxx_source_compiles macro. See help
|
|
||||||
# for CheckCXXSourceCompiles for a listing of variables that can
|
|
||||||
# modify the build.
|
|
||||||
|
|
||||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
|
||||||
#
|
|
||||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
|
||||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
|
||||||
|
|
||||||
|
|
||||||
INCLUDE(CheckCXXSourceCompiles)
|
|
||||||
|
|
||||||
MACRO (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT)
|
|
||||||
SET(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
|
|
||||||
SET(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
|
|
||||||
CHECK_CXX_SOURCE_COMPILES("int main() { return 0;}" ${_RESULT}
|
|
||||||
# Some compilers do not fail with a bad flag
|
|
||||||
FAIL_REGEX "unrecognized .*option" # GNU
|
|
||||||
FAIL_REGEX "ignoring unknown option" # MSVC
|
|
||||||
FAIL_REGEX "[Uu]nknown option" # HP
|
|
||||||
FAIL_REGEX "[Ww]arning: [Oo]ption" # SunPro
|
|
||||||
FAIL_REGEX "command option .* is not recognized" # XL
|
|
||||||
)
|
|
||||||
SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
|
|
||||||
ENDMACRO (CHECK_CXX_COMPILER_FLAG)
|
|
205
cmake/FindLua.cmake
Normal file
205
cmake/FindLua.cmake
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
# 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/
|
||||||
|
|
||||||
|
if(NOT PKG_CONFIG_FOUND)
|
||||||
|
include(CMakeFindDependencyMacro)
|
||||||
|
find_dependency(PkgConfig)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
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.4 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}
|
||||||
|
)
|
||||||
|
pkg_check_modules(LUA QUIET "lua${ver}")
|
||||||
|
list(APPEND _lua_include_subdirs ${LUA_INCLUDE_DIRS})
|
||||||
|
list(APPEND _lua_library_names ${LUA_LIBRARIES})
|
||||||
|
list(APPEND _lua_library_dirs ${LUA_LIBRARY_DIRS})
|
||||||
|
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)
|
||||||
|
set(_lua_library_dirs "${_lua_library_dirs}" 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
|
||||||
|
${_lua_library_dirs}
|
||||||
|
~/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)
|
|
@ -1,54 +0,0 @@
|
|||||||
# Locate OSMPBF library
|
|
||||||
# This module defines
|
|
||||||
# OSMPBF_FOUND, if false, do not try to link to OSMPBF
|
|
||||||
# OSMPBF_LIBRARIES
|
|
||||||
# OSMPBF_INCLUDE_DIR, where to find OSMPBF.hpp
|
|
||||||
#
|
|
||||||
# Note that the expected include convention is
|
|
||||||
# #include <osmpbf/osmpbf.h>
|
|
||||||
# and not
|
|
||||||
# #include <osmpbf.h>
|
|
||||||
|
|
||||||
IF( NOT OSMPBF_FIND_QUIETLY )
|
|
||||||
MESSAGE(STATUS "Looking for OSMPBF...")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
FIND_PATH(OSMPBF_INCLUDE_DIR osmpbf.h
|
|
||||||
HINTS
|
|
||||||
$ENV{OSMPBF_DIR}
|
|
||||||
PATH_SUFFIXES OSMPBF include/osmpbf include
|
|
||||||
PATHS
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/usr/local
|
|
||||||
/usr
|
|
||||||
/opt/local # DarwinPorts
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
FIND_LIBRARY(OSMPBF_LIBRARY
|
|
||||||
NAMES osmpbf
|
|
||||||
HINTS
|
|
||||||
$ENV{OSMPBF_DIR}
|
|
||||||
PATH_SUFFIXES lib64 lib
|
|
||||||
PATHS
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/usr/local
|
|
||||||
/usr
|
|
||||||
/opt/local
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
INCLUDE(FindPackageHandleStandardArgs)
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set OSMPBF_FOUND to TRUE if
|
|
||||||
# all listed variables are TRUE
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OSMPBF DEFAULT_MSG OSMPBF_LIBRARY OSMPBF_INCLUDE_DIR)
|
|
||||||
|
|
||||||
IF( NOT OSMPBF_FIND_QUIETLY )
|
|
||||||
IF( OSMPBF_FOUND )
|
|
||||||
MESSAGE(STATUS "Found OSMPBF: ${OSMPBF_LIBRARY}" )
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
#MARK_AS_ADVANCED(OSMPBF_INCLUDE_DIR OSMPBF_LIBRARIES OSMPBF_LIBRARY OSMPBF_LIBRARY_DBG)
|
|
@ -1,51 +0,0 @@
|
|||||||
# Locate STXXL library
|
|
||||||
# This module defines
|
|
||||||
# STXXL_FOUND, if false, do not try to link to libstxxl
|
|
||||||
# STXXL_LIBRARY
|
|
||||||
# STXXL_INCLUDE_DIR, where to find stxxl.h
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
IF( NOT STXXL_FIND_QUIETLY )
|
|
||||||
MESSAGE(STATUS "Looking for STXXL...")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
FIND_PATH(STXXL_INCLUDE_DIR stxxl.h
|
|
||||||
HINTS
|
|
||||||
$ENV{STXXL_DIR}
|
|
||||||
PATH_SUFFIXES stxxl include/stxxl/stxxl include/stxxl include
|
|
||||||
PATHS
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/usr/local
|
|
||||||
/usr
|
|
||||||
/opt/local # DarwinPorts
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
FIND_LIBRARY(STXXL_LIBRARY
|
|
||||||
NAMES stxxl
|
|
||||||
HINTS
|
|
||||||
$ENV{STXXL_DIR}
|
|
||||||
PATH_SUFFIXES lib64 lib
|
|
||||||
PATHS
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/usr/local
|
|
||||||
/usr
|
|
||||||
/opt/local
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
INCLUDE(FindPackageHandleStandardArgs)
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set STXXL_FOUND to TRUE if
|
|
||||||
# all listed variables are TRUE
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(STXXL DEFAULT_MSG STXXL_LIBRARY STXXL_INCLUDE_DIR)
|
|
||||||
|
|
||||||
IF( NOT STXXL_FIND_QUIETLY )
|
|
||||||
IF( STXXL_FOUND )
|
|
||||||
MESSAGE(STATUS "Found STXXL: ${STXXL_LIBRARY}" )
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(STXXL_INCLUDE_DIR STXXL_LIBRARY)
|
|
@ -1,283 +1,456 @@
|
|||||||
# Locate Intel Threading Building Blocks include paths and libraries
|
# - Find ThreadingBuildingBlocks include dirs and libraries
|
||||||
# FindTBB.cmake can be found at https://code.google.com/p/findtbb/
|
# Use this module by invoking find_package with the form:
|
||||||
# Written by Hannes Hofmann <hannes.hofmann _at_ informatik.uni-erlangen.de>
|
# find_package(TBB
|
||||||
# Improvements by Gino van den Bergen <gino _at_ dtecta.com>,
|
# [REQUIRED] # Fail with error if TBB is not found
|
||||||
# Florian Uhlig <F.Uhlig _at_ gsi.de>,
|
# ) #
|
||||||
# Jiri Marsik <jiri.marsik89 _at_ gmail.com>
|
# Once done, this will define
|
||||||
|
|
||||||
# The MIT License
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 2011 Hannes Hofmann
|
# TBB_FOUND - system has TBB
|
||||||
|
# TBB_INCLUDE_DIRS - the TBB include directories
|
||||||
|
# TBB_LIBRARIES - TBB libraries to be lined, doesn't include malloc or
|
||||||
|
# malloc proxy
|
||||||
|
# TBB::tbb - imported target for the TBB library
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# TBB_VERSION_MAJOR - Major Product Version Number
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# TBB_VERSION_MINOR - Minor Product Version Number
|
||||||
# in the Software without restriction, including without limitation the rights
|
# TBB_INTERFACE_VERSION - Engineering Focused Version Number
|
||||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
# TBB_COMPATIBLE_INTERFACE_VERSION - The oldest major interface version
|
||||||
# copies of the Software, and to permit persons to whom the Software is
|
# still supported. This uses the engineering
|
||||||
# furnished to do so, subject to the following conditions:
|
# focused interface version numbers.
|
||||||
#
|
#
|
||||||
# The above copyright notice and this permission notice shall be included in
|
# TBB_MALLOC_FOUND - system has TBB malloc library
|
||||||
# all copies or substantial portions of the Software.
|
# TBB_MALLOC_INCLUDE_DIRS - the TBB malloc include directories
|
||||||
|
# TBB_MALLOC_LIBRARIES - The TBB malloc libraries to be lined
|
||||||
|
# TBB::malloc - imported target for the TBB malloc library
|
||||||
#
|
#
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
# TBB_MALLOC_PROXY_FOUND - system has TBB malloc proxy library
|
||||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
# TBB_MALLOC_PROXY_INCLUDE_DIRS = the TBB malloc proxy include directories
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
# TBB_MALLOC_PROXY_LIBRARIES - The TBB malloc proxy libraries to be lined
|
||||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
# TBB::malloc_proxy - imported target for the TBB malloc proxy library
|
||||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
# THE SOFTWARE.
|
|
||||||
|
|
||||||
# GvdB: This module uses the environment variable TBB_ARCH_PLATFORM which defines architecture and compiler.
|
|
||||||
# e.g. "ia32/vc8" or "em64t/cc4.1.0_libc2.4_kernel2.6.16.21"
|
|
||||||
# TBB_ARCH_PLATFORM is set by the build script tbbvars[.bat|.sh|.csh], which can be found
|
|
||||||
# in the TBB installation directory (TBB_INSTALL_DIR).
|
|
||||||
#
|
#
|
||||||
# GvdB: Mac OS X distribution places libraries directly in lib directory.
|
|
||||||
#
|
#
|
||||||
# For backwards compatibility, you may explicitely set the CMake variables TBB_ARCHITECTURE and TBB_COMPILER.
|
# This module reads hints about search locations from variables:
|
||||||
# TBB_ARCHITECTURE [ ia32 | em64t | itanium ]
|
# ENV TBB_ARCH_PLATFORM - for eg. set it to "mic" for Xeon Phi builds
|
||||||
# which architecture to use
|
# ENV TBB_ROOT or just TBB_ROOT - root directory of tbb installation
|
||||||
# TBB_COMPILER e.g. vc9 or cc3.2.3_libc2.3.2_kernel2.4.21 or cc4.0.1_os10.4.9
|
# ENV TBB_BUILD_PREFIX - specifies the build prefix for user built tbb
|
||||||
# which compiler to use (detected automatically on Windows)
|
# libraries. Should be specified with ENV TBB_ROOT
|
||||||
|
# and optionally...
|
||||||
# This module respects
|
# ENV TBB_BUILD_DIR - if build directory is different than ${TBB_ROOT}/build
|
||||||
# TBB_INSTALL_DIR or $ENV{TBB21_INSTALL_DIR} or $ENV{TBB_INSTALL_DIR}
|
#
|
||||||
|
#
|
||||||
# This module defines
|
# Modified by Robert Maynard from the original OGRE source
|
||||||
# TBB_INCLUDE_DIRS, where to find task_scheduler_init.h, etc.
|
#
|
||||||
# TBB_LIBRARY_DIRS, where to find libtbb, libtbbmalloc
|
#-------------------------------------------------------------------
|
||||||
# TBB_DEBUG_LIBRARY_DIRS, where to find libtbb_debug, libtbbmalloc_debug
|
# This file is part of the CMake build system for OGRE
|
||||||
# TBB_INSTALL_DIR, the base TBB install directory
|
# (Object-oriented Graphics Rendering Engine)
|
||||||
# TBB_LIBRARIES, the libraries to link against to use TBB.
|
# For the latest info, see http://www.ogre3d.org/
|
||||||
# TBB_DEBUG_LIBRARIES, the libraries to link against to use TBB with debug symbols.
|
#
|
||||||
# TBB_FOUND, If false, don't try to use TBB.
|
# The contents of this file are placed in the public domain. Feel
|
||||||
# TBB_INTERFACE_VERSION, as defined in tbb/tbb_stddef.h
|
# free to make use of it in any way you like.
|
||||||
|
#-------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2010-2012 Kitware, Inc.
|
||||||
|
# Copyright 2012 Rolf Eike Beer <eike@sf-mail.de>
|
||||||
|
#
|
||||||
|
# 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.)
|
||||||
|
|
||||||
|
|
||||||
if (WIN32)
|
#=============================================================================
|
||||||
# has em64t/vc8 em64t/vc9
|
# FindTBB helper functions and macros
|
||||||
# has ia32/vc7.1 ia32/vc8 ia32/vc9
|
#
|
||||||
set(_TBB_DEFAULT_INSTALL_DIR "C:/Program Files/Intel/TBB" "C:/Program Files (x86)/Intel/TBB")
|
|
||||||
set(_TBB_LIB_NAME "tbb")
|
|
||||||
set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc")
|
|
||||||
set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug")
|
|
||||||
set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug")
|
|
||||||
if (MSVC71)
|
|
||||||
set (_TBB_COMPILER "vc7.1")
|
|
||||||
endif(MSVC71)
|
|
||||||
if (MSVC80)
|
|
||||||
set(_TBB_COMPILER "vc8")
|
|
||||||
endif(MSVC80)
|
|
||||||
if (MSVC90)
|
|
||||||
set(_TBB_COMPILER "vc9")
|
|
||||||
endif(MSVC90)
|
|
||||||
if(MSVC10)
|
|
||||||
set(_TBB_COMPILER "vc10")
|
|
||||||
endif(MSVC10)
|
|
||||||
# Todo: add other Windows compilers such as ICL.
|
|
||||||
set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE})
|
|
||||||
endif (WIN32)
|
|
||||||
|
|
||||||
if (UNIX)
|
# Use TBBConfig.cmake if possible.
|
||||||
if (APPLE)
|
|
||||||
# MAC
|
|
||||||
set(_TBB_DEFAULT_INSTALL_DIR "/Library/Frameworks/Intel_TBB.framework/Versions")
|
|
||||||
# libs: libtbb.dylib, libtbbmalloc.dylib, *_debug
|
|
||||||
set(_TBB_LIB_NAME "tbb")
|
|
||||||
set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc")
|
|
||||||
set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug")
|
|
||||||
set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug")
|
|
||||||
# default flavor on apple: ia32/cc4.0.1_os10.4.9
|
|
||||||
# Jiri: There is no reason to presume there is only one flavor and
|
|
||||||
# that user's setting of variables should be ignored.
|
|
||||||
if(NOT TBB_COMPILER)
|
|
||||||
set(_TBB_COMPILER "cc4.0.1_os10.4.9")
|
|
||||||
elseif (NOT TBB_COMPILER)
|
|
||||||
set(_TBB_COMPILER ${TBB_COMPILER})
|
|
||||||
endif(NOT TBB_COMPILER)
|
|
||||||
if(NOT TBB_ARCHITECTURE)
|
|
||||||
set(_TBB_ARCHITECTURE "ia32")
|
|
||||||
elseif(NOT TBB_ARCHITECTURE)
|
|
||||||
set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE})
|
|
||||||
endif(NOT TBB_ARCHITECTURE)
|
|
||||||
else (APPLE)
|
|
||||||
# LINUX
|
|
||||||
set(_TBB_DEFAULT_INSTALL_DIR "/opt/intel/tbb" "/usr/local/include" "/usr/include")
|
|
||||||
set(_TBB_LIB_NAME "tbb")
|
|
||||||
set(_TBB_LIB_MALLOC_NAME "${_TBB_LIB_NAME}malloc")
|
|
||||||
set(_TBB_LIB_DEBUG_NAME "${_TBB_LIB_NAME}_debug")
|
|
||||||
set(_TBB_LIB_MALLOC_DEBUG_NAME "${_TBB_LIB_MALLOC_NAME}_debug")
|
|
||||||
# has em64t/cc3.2.3_libc2.3.2_kernel2.4.21 em64t/cc3.3.3_libc2.3.3_kernel2.6.5 em64t/cc3.4.3_libc2.3.4_kernel2.6.9 em64t/cc4.1.0_libc2.4_kernel2.6.16.21
|
|
||||||
# has ia32/*
|
|
||||||
# has itanium/*
|
|
||||||
set(_TBB_COMPILER ${TBB_COMPILER})
|
|
||||||
set(_TBB_ARCHITECTURE ${TBB_ARCHITECTURE})
|
|
||||||
endif (APPLE)
|
|
||||||
endif (UNIX)
|
|
||||||
|
|
||||||
if (CMAKE_SYSTEM MATCHES "SunOS.*")
|
|
||||||
# SUN
|
|
||||||
# not yet supported
|
|
||||||
# has em64t/cc3.4.3_kernel5.10
|
|
||||||
# has ia32/*
|
|
||||||
endif (CMAKE_SYSTEM MATCHES "SunOS.*")
|
|
||||||
|
|
||||||
|
|
||||||
#-- Clear the public variables
|
|
||||||
set (TBB_FOUND "NO")
|
|
||||||
|
|
||||||
|
|
||||||
#-- Find TBB install dir and set ${_TBB_INSTALL_DIR} and cached ${TBB_INSTALL_DIR}
|
|
||||||
# first: use CMake variable TBB_INSTALL_DIR
|
|
||||||
if (TBB_INSTALL_DIR)
|
|
||||||
set (_TBB_INSTALL_DIR ${TBB_INSTALL_DIR})
|
|
||||||
endif (TBB_INSTALL_DIR)
|
|
||||||
# second: use environment variable
|
|
||||||
if (NOT _TBB_INSTALL_DIR)
|
|
||||||
if (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "")
|
|
||||||
set (_TBB_INSTALL_DIR $ENV{TBB_INSTALL_DIR})
|
|
||||||
endif (NOT "$ENV{TBB_INSTALL_DIR}" STREQUAL "")
|
|
||||||
# Intel recommends setting TBB21_INSTALL_DIR
|
|
||||||
if (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "")
|
|
||||||
set (_TBB_INSTALL_DIR $ENV{TBB21_INSTALL_DIR})
|
|
||||||
endif (NOT "$ENV{TBB21_INSTALL_DIR}" STREQUAL "")
|
|
||||||
if (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "")
|
|
||||||
set (_TBB_INSTALL_DIR $ENV{TBB22_INSTALL_DIR})
|
|
||||||
endif (NOT "$ENV{TBB22_INSTALL_DIR}" STREQUAL "")
|
|
||||||
if (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "")
|
|
||||||
set (_TBB_INSTALL_DIR $ENV{TBB30_INSTALL_DIR})
|
|
||||||
endif (NOT "$ENV{TBB30_INSTALL_DIR}" STREQUAL "")
|
|
||||||
endif (NOT _TBB_INSTALL_DIR)
|
|
||||||
# third: try to find path automatically
|
|
||||||
if (NOT _TBB_INSTALL_DIR)
|
|
||||||
if (_TBB_DEFAULT_INSTALL_DIR)
|
|
||||||
set (_TBB_INSTALL_DIR ${_TBB_DEFAULT_INSTALL_DIR})
|
|
||||||
endif (_TBB_DEFAULT_INSTALL_DIR)
|
|
||||||
endif (NOT _TBB_INSTALL_DIR)
|
|
||||||
# sanity check
|
|
||||||
if (NOT _TBB_INSTALL_DIR)
|
|
||||||
message ("ERROR: Unable to find Intel TBB install directory. ${_TBB_INSTALL_DIR}")
|
|
||||||
else (NOT _TBB_INSTALL_DIR)
|
|
||||||
# finally: set the cached CMake variable TBB_INSTALL_DIR
|
|
||||||
if (NOT TBB_INSTALL_DIR)
|
|
||||||
set (TBB_INSTALL_DIR ${_TBB_INSTALL_DIR} CACHE PATH "Intel TBB install directory")
|
|
||||||
mark_as_advanced(TBB_INSTALL_DIR)
|
|
||||||
endif (NOT TBB_INSTALL_DIR)
|
|
||||||
|
|
||||||
|
|
||||||
#-- A macro to rewrite the paths of the library. This is necessary, because
|
|
||||||
# find_library() always found the em64t/vc9 version of the TBB libs
|
|
||||||
macro(TBB_CORRECT_LIB_DIR var_name)
|
|
||||||
# if (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t")
|
|
||||||
string(REPLACE em64t "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}})
|
|
||||||
# endif (NOT "${_TBB_ARCHITECTURE}" STREQUAL "em64t")
|
|
||||||
string(REPLACE ia32 "${_TBB_ARCHITECTURE}" ${var_name} ${${var_name}})
|
|
||||||
string(REPLACE vc7.1 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
|
||||||
string(REPLACE vc8 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
|
||||||
string(REPLACE vc9 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
|
||||||
string(REPLACE vc10 "${_TBB_COMPILER}" ${var_name} ${${var_name}})
|
|
||||||
endmacro(TBB_CORRECT_LIB_DIR var_content)
|
|
||||||
|
|
||||||
|
|
||||||
#-- Look for include directory and set ${TBB_INCLUDE_DIR}
|
|
||||||
set (TBB_INC_SEARCH_DIR ${_TBB_INSTALL_DIR}/include)
|
|
||||||
# Jiri: tbbvars now sets the CPATH environment variable to the directory
|
|
||||||
# containing the headers.
|
|
||||||
find_path(TBB_INCLUDE_DIR
|
|
||||||
tbb/task_scheduler_init.h
|
|
||||||
PATHS ${TBB_INC_SEARCH_DIR} ENV CPATH
|
|
||||||
)
|
|
||||||
mark_as_advanced(TBB_INCLUDE_DIR)
|
|
||||||
|
|
||||||
|
|
||||||
#-- Look for libraries
|
|
||||||
# GvdB: $ENV{TBB_ARCH_PLATFORM} is set by the build script tbbvars[.bat|.sh|.csh]
|
|
||||||
if (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "")
|
|
||||||
set (_TBB_LIBRARY_DIR
|
|
||||||
${_TBB_INSTALL_DIR}/lib/$ENV{TBB_ARCH_PLATFORM}
|
|
||||||
${_TBB_INSTALL_DIR}/$ENV{TBB_ARCH_PLATFORM}/lib
|
|
||||||
)
|
|
||||||
endif (NOT $ENV{TBB_ARCH_PLATFORM} STREQUAL "")
|
|
||||||
# Jiri: This block isn't mutually exclusive with the previous one
|
|
||||||
# (hence no else), instead I test if the user really specified
|
|
||||||
# the variables in question.
|
|
||||||
if ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL ""))
|
|
||||||
# HH: deprecated
|
|
||||||
message(STATUS "[Warning] FindTBB.cmake: The use of TBB_ARCHITECTURE and TBB_COMPILER is deprecated and may not be supported in future versions. Please set \$ENV{TBB_ARCH_PLATFORM} (using tbbvars.[bat|csh|sh]).")
|
|
||||||
# Jiri: It doesn't hurt to look in more places, so I store the hints from
|
|
||||||
# ENV{TBB_ARCH_PLATFORM} and the TBB_ARCHITECTURE and TBB_COMPILER
|
|
||||||
# variables and search them both.
|
|
||||||
set (_TBB_LIBRARY_DIR "${_TBB_INSTALL_DIR}/${_TBB_ARCHITECTURE}/${_TBB_COMPILER}/lib" ${_TBB_LIBRARY_DIR})
|
|
||||||
endif ((NOT ${TBB_ARCHITECTURE} STREQUAL "") AND (NOT ${TBB_COMPILER} STREQUAL ""))
|
|
||||||
|
|
||||||
# GvdB: Mac OS X distribution places libraries directly in lib directory.
|
|
||||||
list(APPEND _TBB_LIBRARY_DIR ${_TBB_INSTALL_DIR}/lib)
|
|
||||||
|
|
||||||
# Jiri: No reason not to check the default paths. From recent versions,
|
|
||||||
# tbbvars has started exporting the LIBRARY_PATH and LD_LIBRARY_PATH
|
|
||||||
# variables, which now point to the directories of the lib files.
|
|
||||||
# It all makes more sense to use the ${_TBB_LIBRARY_DIR} as a HINTS
|
|
||||||
# argument instead of the implicit PATHS as it isn't hard-coded
|
|
||||||
# but computed by system introspection. Searching the LIBRARY_PATH
|
|
||||||
# and LD_LIBRARY_PATH environment variables is now even more important
|
|
||||||
# that tbbvars doesn't export TBB_ARCH_PLATFORM and it facilitates
|
|
||||||
# the use of TBB built from sources.
|
|
||||||
find_library(TBB_LIBRARY ${_TBB_LIB_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
|
||||||
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
|
||||||
find_library(TBB_MALLOC_LIBRARY ${_TBB_LIB_MALLOC_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
|
||||||
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
|
||||||
|
|
||||||
#Extract path from TBB_LIBRARY name
|
|
||||||
get_filename_component(TBB_LIBRARY_DIR ${TBB_LIBRARY} PATH)
|
|
||||||
|
|
||||||
#TBB_CORRECT_LIB_DIR(TBB_LIBRARY)
|
|
||||||
#TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY)
|
|
||||||
mark_as_advanced(TBB_LIBRARY TBB_MALLOC_LIBRARY)
|
|
||||||
|
|
||||||
#-- Look for debug libraries
|
|
||||||
# Jiri: Changed the same way as for the release libraries.
|
|
||||||
find_library(TBB_LIBRARY_DEBUG ${_TBB_LIB_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
|
||||||
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
|
||||||
find_library(TBB_MALLOC_LIBRARY_DEBUG ${_TBB_LIB_MALLOC_DEBUG_NAME} HINTS ${_TBB_LIBRARY_DIR}
|
|
||||||
PATHS ENV LIBRARY_PATH ENV LD_LIBRARY_PATH)
|
|
||||||
|
|
||||||
# Jiri: Self-built TBB stores the debug libraries in a separate directory.
|
|
||||||
# Extract path from TBB_LIBRARY_DEBUG name
|
|
||||||
get_filename_component(TBB_LIBRARY_DEBUG_DIR ${TBB_LIBRARY_DEBUG} PATH)
|
|
||||||
|
|
||||||
#TBB_CORRECT_LIB_DIR(TBB_LIBRARY_DEBUG)
|
|
||||||
#TBB_CORRECT_LIB_DIR(TBB_MALLOC_LIBRARY_DEBUG)
|
|
||||||
mark_as_advanced(TBB_LIBRARY_DEBUG TBB_MALLOC_LIBRARY_DEBUG)
|
|
||||||
|
|
||||||
|
|
||||||
if (TBB_INCLUDE_DIR)
|
|
||||||
if (TBB_LIBRARY)
|
|
||||||
set (TBB_FOUND "YES")
|
|
||||||
set (TBB_LIBRARIES ${TBB_LIBRARY} ${TBB_MALLOC_LIBRARY} ${TBB_LIBRARIES})
|
|
||||||
set (TBB_DEBUG_LIBRARIES ${TBB_LIBRARY_DEBUG} ${TBB_MALLOC_LIBRARY_DEBUG} ${TBB_DEBUG_LIBRARIES})
|
|
||||||
set (TBB_INCLUDE_DIRS ${TBB_INCLUDE_DIR} CACHE PATH "TBB include directory" FORCE)
|
|
||||||
set (TBB_LIBRARY_DIRS ${TBB_LIBRARY_DIR} CACHE PATH "TBB library directory" FORCE)
|
|
||||||
# Jiri: Self-built TBB stores the debug libraries in a separate directory.
|
|
||||||
set (TBB_DEBUG_LIBRARY_DIRS ${TBB_LIBRARY_DEBUG_DIR} CACHE PATH "TBB debug library directory" FORCE)
|
|
||||||
mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARY_DIRS TBB_DEBUG_LIBRARY_DIRS TBB_LIBRARIES TBB_DEBUG_LIBRARIES)
|
|
||||||
message(STATUS "Found Intel TBB")
|
|
||||||
endif (TBB_LIBRARY)
|
|
||||||
endif (TBB_INCLUDE_DIR)
|
|
||||||
|
|
||||||
if (NOT TBB_FOUND)
|
|
||||||
message("ERROR: Intel TBB NOT found!")
|
|
||||||
message(STATUS "Looked for Threading Building Blocks in ${_TBB_INSTALL_DIR}")
|
|
||||||
# do only throw fatal, if this pkg is REQUIRED
|
|
||||||
if (TBB_FIND_REQUIRED)
|
|
||||||
message(FATAL_ERROR "Could NOT find TBB library.")
|
|
||||||
endif (TBB_FIND_REQUIRED)
|
|
||||||
endif (NOT TBB_FOUND)
|
|
||||||
|
|
||||||
endif (NOT _TBB_INSTALL_DIR)
|
|
||||||
|
|
||||||
|
set(_tbb_find_quiet)
|
||||||
|
if (TBB_FIND_QUIETLY)
|
||||||
|
set(_tbb_find_quiet QUIET)
|
||||||
|
endif ()
|
||||||
|
set(_tbb_find_components)
|
||||||
|
set(_tbb_find_optional_components)
|
||||||
|
foreach (_tbb_find_component IN LISTS TBB_FIND_COMPONENTS)
|
||||||
|
if (TBB_FIND_REQUIRED_${_tbb_find_component})
|
||||||
|
list(APPEND _tbb_find_components "${_tbb_find_component}")
|
||||||
|
else ()
|
||||||
|
list(APPEND _tbb_find_optional_components "${_tbb_find_component}")
|
||||||
|
endif ()
|
||||||
|
endforeach ()
|
||||||
|
unset(_tbb_find_component)
|
||||||
|
find_package(TBB CONFIG ${_tbb_find_quiet}
|
||||||
|
COMPONENTS ${_tbb_find_components}
|
||||||
|
OPTIONAL_COMPONENTS ${_tbb_find_optional_components})
|
||||||
|
unset(_tbb_find_quiet)
|
||||||
|
unset(_tbb_find_components)
|
||||||
|
unset(_tbb_find_optional_components)
|
||||||
if (TBB_FOUND)
|
if (TBB_FOUND)
|
||||||
set(TBB_INTERFACE_VERSION 0)
|
return ()
|
||||||
FILE(READ "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" _TBB_VERSION_CONTENTS)
|
endif ()
|
||||||
STRING(REGEX REPLACE ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1" TBB_INTERFACE_VERSION "${_TBB_VERSION_CONTENTS}")
|
|
||||||
set(TBB_INTERFACE_VERSION "${TBB_INTERFACE_VERSION}")
|
#====================================================
|
||||||
endif (TBB_FOUND)
|
# Fix the library path in case it is a linker script
|
||||||
|
#====================================================
|
||||||
|
function(tbb_extract_real_library library real_library)
|
||||||
|
if(NOT UNIX OR NOT EXISTS ${library})
|
||||||
|
set(${real_library} "${library}" PARENT_SCOPE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#Read in the first 4 bytes and see if they are the ELF magic number
|
||||||
|
set(_elf_magic "7f454c46")
|
||||||
|
file(READ ${library} _hex_data OFFSET 0 LIMIT 4 HEX)
|
||||||
|
if(_hex_data STREQUAL _elf_magic)
|
||||||
|
#we have opened a elf binary so this is what
|
||||||
|
#we should link to
|
||||||
|
set(${real_library} "${library}" PARENT_SCOPE)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
file(READ ${library} _data OFFSET 0 LIMIT 1024)
|
||||||
|
if("${_data}" MATCHES "INPUT \\(([^(]+)\\)")
|
||||||
|
#extract out the .so name from REGEX MATCH command
|
||||||
|
set(_proper_so_name "${CMAKE_MATCH_1}")
|
||||||
|
|
||||||
|
#construct path to the real .so which is presumed to be in the same directory
|
||||||
|
#as the input file
|
||||||
|
get_filename_component(_so_dir "${library}" DIRECTORY)
|
||||||
|
set(${real_library} "${_so_dir}/${_proper_so_name}" PARENT_SCOPE)
|
||||||
|
else()
|
||||||
|
#unable to determine what this library is so just hope everything works
|
||||||
|
#and pass it unmodified.
|
||||||
|
set(${real_library} "${library}" PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
#===============================================
|
||||||
|
# Do the final processing for the package find.
|
||||||
|
#===============================================
|
||||||
|
macro(findpkg_finish PREFIX TARGET_NAME)
|
||||||
|
if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY)
|
||||||
|
set(${PREFIX}_FOUND TRUE)
|
||||||
|
set (${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR})
|
||||||
|
set (${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY})
|
||||||
|
else ()
|
||||||
|
if (${PREFIX}_FIND_REQUIRED AND NOT ${PREFIX}_FIND_QUIETLY)
|
||||||
|
message(FATAL_ERROR "Required library ${PREFIX} not found.")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT TARGET "TBB::${TARGET_NAME}")
|
||||||
|
if (${PREFIX}_LIBRARY_RELEASE)
|
||||||
|
tbb_extract_real_library(${${PREFIX}_LIBRARY_RELEASE} real_release)
|
||||||
|
endif ()
|
||||||
|
if (${PREFIX}_LIBRARY_DEBUG)
|
||||||
|
tbb_extract_real_library(${${PREFIX}_LIBRARY_DEBUG} real_debug)
|
||||||
|
endif ()
|
||||||
|
add_library(TBB::${TARGET_NAME} UNKNOWN IMPORTED)
|
||||||
|
set_target_properties(TBB::${TARGET_NAME} PROPERTIES
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${${PREFIX}_INCLUDE_DIR}")
|
||||||
|
if (${PREFIX}_LIBRARY_DEBUG AND ${PREFIX}_LIBRARY_RELEASE)
|
||||||
|
set_target_properties(TBB::${TARGET_NAME} PROPERTIES
|
||||||
|
IMPORTED_LOCATION "${real_release}"
|
||||||
|
IMPORTED_LOCATION_DEBUG "${real_debug}"
|
||||||
|
IMPORTED_LOCATION_RELEASE "${real_release}")
|
||||||
|
elseif (${PREFIX}_LIBRARY_RELEASE)
|
||||||
|
set_target_properties(TBB::${TARGET_NAME} PROPERTIES
|
||||||
|
IMPORTED_LOCATION "${real_release}")
|
||||||
|
elseif (${PREFIX}_LIBRARY_DEBUG)
|
||||||
|
set_target_properties(TBB::${TARGET_NAME} PROPERTIES
|
||||||
|
IMPORTED_LOCATION "${real_debug}")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
#mark the following variables as internal variables
|
||||||
|
mark_as_advanced(${PREFIX}_INCLUDE_DIR
|
||||||
|
${PREFIX}_LIBRARY
|
||||||
|
${PREFIX}_LIBRARY_DEBUG
|
||||||
|
${PREFIX}_LIBRARY_RELEASE)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
#===============================================
|
||||||
|
# Generate debug names from given release names
|
||||||
|
#===============================================
|
||||||
|
macro(get_debug_names PREFIX)
|
||||||
|
foreach(i ${${PREFIX}})
|
||||||
|
set(${PREFIX}_DEBUG ${${PREFIX}_DEBUG} ${i}d ${i}D ${i}_d ${i}_D ${i}_debug ${i})
|
||||||
|
endforeach()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
#===============================================
|
||||||
|
# See if we have env vars to help us find tbb
|
||||||
|
#===============================================
|
||||||
|
macro(getenv_path VAR)
|
||||||
|
set(ENV_${VAR} $ENV{${VAR}})
|
||||||
|
# replace won't work if var is blank
|
||||||
|
if (ENV_${VAR})
|
||||||
|
string( REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}} )
|
||||||
|
endif ()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
#===============================================
|
||||||
|
# Couple a set of release AND debug libraries
|
||||||
|
#===============================================
|
||||||
|
macro(make_library_set PREFIX)
|
||||||
|
if (${PREFIX}_RELEASE AND ${PREFIX}_DEBUG)
|
||||||
|
set(${PREFIX} optimized ${${PREFIX}_RELEASE} debug ${${PREFIX}_DEBUG})
|
||||||
|
elseif (${PREFIX}_RELEASE)
|
||||||
|
set(${PREFIX} ${${PREFIX}_RELEASE})
|
||||||
|
elseif (${PREFIX}_DEBUG)
|
||||||
|
set(${PREFIX} ${${PREFIX}_DEBUG})
|
||||||
|
endif ()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Now to actually find TBB
|
||||||
|
#
|
||||||
|
|
||||||
|
# Get path, convert backslashes as ${ENV_${var}}
|
||||||
|
getenv_path(TBB_ROOT)
|
||||||
|
|
||||||
|
# initialize search paths
|
||||||
|
set(TBB_PREFIX_PATH ${TBB_ROOT} ${ENV_TBB_ROOT})
|
||||||
|
set(TBB_INC_SEARCH_PATH "")
|
||||||
|
set(TBB_LIB_SEARCH_PATH "")
|
||||||
|
|
||||||
|
|
||||||
|
# If user built from sources
|
||||||
|
set(TBB_BUILD_PREFIX $ENV{TBB_BUILD_PREFIX})
|
||||||
|
if (TBB_BUILD_PREFIX AND ENV_TBB_ROOT)
|
||||||
|
getenv_path(TBB_BUILD_DIR)
|
||||||
|
if (NOT ENV_TBB_BUILD_DIR)
|
||||||
|
set(ENV_TBB_BUILD_DIR ${ENV_TBB_ROOT}/build)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# include directory under ${ENV_TBB_ROOT}/include
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH
|
||||||
|
${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_release
|
||||||
|
${ENV_TBB_BUILD_DIR}/${TBB_BUILD_PREFIX}_debug)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
|
# For Windows, let's assume that the user might be using the precompiled
|
||||||
|
# TBB packages from the main website. These use a rather awkward directory
|
||||||
|
# structure (at least for automatically finding the right files) depending
|
||||||
|
# on platform and compiler, but we'll do our best to accommodate it.
|
||||||
|
# Not adding the same effort for the precompiled linux builds, though. Those
|
||||||
|
# have different versions for CC compiler versions and linux kernels which
|
||||||
|
# will never adequately match the user's setup, so there is no feasible way
|
||||||
|
# to detect the "best" version to use. The user will have to manually
|
||||||
|
# select the right files. (Chances are the distributions are shipping their
|
||||||
|
# custom version of tbb, anyway, so the problem is probably nonexistent.)
|
||||||
|
if (WIN32 AND MSVC)
|
||||||
|
set(COMPILER_PREFIX "vc7.1")
|
||||||
|
if (MSVC_VERSION EQUAL 1400)
|
||||||
|
set(COMPILER_PREFIX "vc8")
|
||||||
|
elseif(MSVC_VERSION EQUAL 1500)
|
||||||
|
set(COMPILER_PREFIX "vc9")
|
||||||
|
elseif(MSVC_VERSION EQUAL 1600)
|
||||||
|
set(COMPILER_PREFIX "vc10")
|
||||||
|
elseif(MSVC_VERSION EQUAL 1700)
|
||||||
|
set(COMPILER_PREFIX "vc11")
|
||||||
|
elseif(MSVC_VERSION EQUAL 1800)
|
||||||
|
set(COMPILER_PREFIX "vc12")
|
||||||
|
elseif(MSVC_VERSION GREATER_EQUAL 1900)
|
||||||
|
set(COMPILER_PREFIX "vc14")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# for each prefix path, add ia32/64\${COMPILER_PREFIX}\lib to the lib search path
|
||||||
|
foreach (dir IN LISTS TBB_PREFIX_PATH)
|
||||||
|
if (CMAKE_CL_64)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia64/${COMPILER_PREFIX}/lib)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia64/${COMPILER_PREFIX})
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${COMPILER_PREFIX}/lib)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${COMPILER_PREFIX})
|
||||||
|
else ()
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${COMPILER_PREFIX}/lib)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${COMPILER_PREFIX})
|
||||||
|
endif ()
|
||||||
|
endforeach ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# For OS X binary distribution, choose libc++ based libraries for Mavericks (10.9)
|
||||||
|
# and above and AppleClang
|
||||||
|
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND
|
||||||
|
NOT CMAKE_SYSTEM_VERSION VERSION_LESS 13.0)
|
||||||
|
set (USE_LIBCXX OFF)
|
||||||
|
cmake_policy(GET CMP0025 POLICY_VAR)
|
||||||
|
|
||||||
|
if (POLICY_VAR STREQUAL "NEW")
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||||
|
set (USE_LIBCXX ON)
|
||||||
|
endif ()
|
||||||
|
else ()
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
set (USE_LIBCXX ON)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (USE_LIBCXX)
|
||||||
|
foreach (dir IN LISTS TBB_PREFIX_PATH)
|
||||||
|
list (APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/libc++ ${dir}/libc++/lib)
|
||||||
|
endforeach ()
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# check compiler ABI
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
|
set(COMPILER_PREFIX)
|
||||||
|
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
|
||||||
|
list(APPEND COMPILER_PREFIX "gcc4.8")
|
||||||
|
endif()
|
||||||
|
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
|
||||||
|
list(APPEND COMPILER_PREFIX "gcc4.7")
|
||||||
|
endif()
|
||||||
|
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4)
|
||||||
|
list(APPEND COMPILER_PREFIX "gcc4.4")
|
||||||
|
endif()
|
||||||
|
list(APPEND COMPILER_PREFIX "gcc4.1")
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||||
|
set(COMPILER_PREFIX)
|
||||||
|
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.0) # Complete guess
|
||||||
|
list(APPEND COMPILER_PREFIX "gcc4.8")
|
||||||
|
endif()
|
||||||
|
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6)
|
||||||
|
list(APPEND COMPILER_PREFIX "gcc4.7")
|
||||||
|
endif()
|
||||||
|
list(APPEND COMPILER_PREFIX "gcc4.4")
|
||||||
|
else() # Assume compatibility with 4.4 for other compilers
|
||||||
|
list(APPEND COMPILER_PREFIX "gcc4.4")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
# if platform architecture is explicitly specified
|
||||||
|
set(TBB_ARCH_PLATFORM $ENV{TBB_ARCH_PLATFORM})
|
||||||
|
if (TBB_ARCH_PLATFORM)
|
||||||
|
foreach (dir IN LISTS TBB_PREFIX_PATH)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/${TBB_ARCH_PLATFORM}/lib)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/${TBB_ARCH_PLATFORM})
|
||||||
|
endforeach ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
foreach (dir IN LISTS TBB_PREFIX_PATH)
|
||||||
|
foreach (prefix IN LISTS COMPILER_PREFIX)
|
||||||
|
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/intel64/${prefix})
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/lib)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/intel64/${prefix}/lib)
|
||||||
|
else ()
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib/ia32/${prefix})
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/lib)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/ia32/${prefix}/lib)
|
||||||
|
endif ()
|
||||||
|
endforeach()
|
||||||
|
endforeach ()
|
||||||
|
|
||||||
|
# add general search paths
|
||||||
|
foreach (dir IN LISTS TBB_PREFIX_PATH)
|
||||||
|
list(APPEND TBB_LIB_SEARCH_PATH ${dir}/lib ${dir}/Lib ${dir}/lib/tbb
|
||||||
|
${dir}/Libs)
|
||||||
|
list(APPEND TBB_INC_SEARCH_PATH ${dir}/include ${dir}/Include
|
||||||
|
${dir}/include/tbb)
|
||||||
|
endforeach ()
|
||||||
|
|
||||||
|
set(TBB_LIBRARY_NAMES tbb)
|
||||||
|
get_debug_names(TBB_LIBRARY_NAMES)
|
||||||
|
|
||||||
|
|
||||||
|
find_path(TBB_INCLUDE_DIR
|
||||||
|
NAMES tbb/tbb.h
|
||||||
|
PATHS ${TBB_INC_SEARCH_PATH})
|
||||||
|
|
||||||
|
find_library(TBB_LIBRARY_RELEASE
|
||||||
|
NAMES ${TBB_LIBRARY_NAMES}
|
||||||
|
PATHS ${TBB_LIB_SEARCH_PATH})
|
||||||
|
find_library(TBB_LIBRARY_DEBUG
|
||||||
|
NAMES ${TBB_LIBRARY_NAMES_DEBUG}
|
||||||
|
PATHS ${TBB_LIB_SEARCH_PATH})
|
||||||
|
make_library_set(TBB_LIBRARY)
|
||||||
|
|
||||||
|
findpkg_finish(TBB tbb)
|
||||||
|
|
||||||
|
#if we haven't found TBB no point on going any further
|
||||||
|
if (NOT TBB_FOUND)
|
||||||
|
return()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Look for TBB's malloc package
|
||||||
|
set(TBB_MALLOC_LIBRARY_NAMES tbbmalloc)
|
||||||
|
get_debug_names(TBB_MALLOC_LIBRARY_NAMES)
|
||||||
|
|
||||||
|
find_path(TBB_MALLOC_INCLUDE_DIR
|
||||||
|
NAMES tbb/tbb.h
|
||||||
|
PATHS ${TBB_INC_SEARCH_PATH})
|
||||||
|
|
||||||
|
find_library(TBB_MALLOC_LIBRARY_RELEASE
|
||||||
|
NAMES ${TBB_MALLOC_LIBRARY_NAMES}
|
||||||
|
PATHS ${TBB_LIB_SEARCH_PATH})
|
||||||
|
find_library(TBB_MALLOC_LIBRARY_DEBUG
|
||||||
|
NAMES ${TBB_MALLOC_LIBRARY_NAMES_DEBUG}
|
||||||
|
PATHS ${TBB_LIB_SEARCH_PATH})
|
||||||
|
make_library_set(TBB_MALLOC_LIBRARY)
|
||||||
|
|
||||||
|
findpkg_finish(TBB_MALLOC tbbmalloc)
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Look for TBB's malloc proxy package
|
||||||
|
set(TBB_MALLOC_PROXY_LIBRARY_NAMES tbbmalloc_proxy)
|
||||||
|
get_debug_names(TBB_MALLOC_PROXY_LIBRARY_NAMES)
|
||||||
|
|
||||||
|
find_path(TBB_MALLOC_PROXY_INCLUDE_DIR
|
||||||
|
NAMES tbb/tbbmalloc_proxy.h
|
||||||
|
PATHS ${TBB_INC_SEARCH_PATH})
|
||||||
|
|
||||||
|
find_library(TBB_MALLOC_PROXY_LIBRARY_RELEASE
|
||||||
|
NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES}
|
||||||
|
PATHS ${TBB_LIB_SEARCH_PATH})
|
||||||
|
find_library(TBB_MALLOC_PROXY_LIBRARY_DEBUG
|
||||||
|
NAMES ${TBB_MALLOC_PROXY_LIBRARY_NAMES_DEBUG}
|
||||||
|
PATHS ${TBB_LIB_SEARCH_PATH})
|
||||||
|
make_library_set(TBB_MALLOC_PROXY_LIBRARY)
|
||||||
|
|
||||||
|
findpkg_finish(TBB_MALLOC_PROXY tbbmalloc_proxy)
|
||||||
|
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
#parse all the version numbers from tbb
|
||||||
|
if(NOT TBB_VERSION)
|
||||||
|
if (EXISTS "${TBB_INCLUDE_DIR}/oneapi/tbb/version.h")
|
||||||
|
file(STRINGS
|
||||||
|
"${TBB_INCLUDE_DIR}/oneapi/tbb/version.h"
|
||||||
|
TBB_VERSION_CONTENTS
|
||||||
|
REGEX "VERSION")
|
||||||
|
else()
|
||||||
|
#only read the start of the file
|
||||||
|
file(STRINGS
|
||||||
|
"${TBB_INCLUDE_DIR}/tbb/tbb_stddef.h"
|
||||||
|
TBB_VERSION_CONTENTS
|
||||||
|
REGEX "VERSION")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
string(REGEX REPLACE
|
||||||
|
".*#define TBB_VERSION_MAJOR ([0-9]+).*" "\\1"
|
||||||
|
TBB_VERSION_MAJOR "${TBB_VERSION_CONTENTS}")
|
||||||
|
|
||||||
|
string(REGEX REPLACE
|
||||||
|
".*#define TBB_VERSION_MINOR ([0-9]+).*" "\\1"
|
||||||
|
TBB_VERSION_MINOR "${TBB_VERSION_CONTENTS}")
|
||||||
|
|
||||||
|
string(REGEX REPLACE
|
||||||
|
".*#define TBB_INTERFACE_VERSION ([0-9]+).*" "\\1"
|
||||||
|
TBB_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}")
|
||||||
|
|
||||||
|
string(REGEX REPLACE
|
||||||
|
".*#define TBB_COMPATIBLE_INTERFACE_VERSION ([0-9]+).*" "\\1"
|
||||||
|
TBB_COMPATIBLE_INTERFACE_VERSION "${TBB_VERSION_CONTENTS}")
|
||||||
|
|
||||||
|
endif()
|
@ -1,10 +0,0 @@
|
|||||||
set(OLDFILE ${SOURCE_DIR}/util/fingerprint_impl.hpp)
|
|
||||||
if (EXISTS ${OLDFILE})
|
|
||||||
file(REMOVE_RECURSE ${OLDFILE})
|
|
||||||
endif()
|
|
||||||
file(MD5 ${SOURCE_DIR}/prepare.cpp MD5PREPARE)
|
|
||||||
file(MD5 ${SOURCE_DIR}/data_structures/static_rtree.hpp MD5RTREE)
|
|
||||||
file(MD5 ${SOURCE_DIR}/util/graph_loader.hpp MD5GRAPH)
|
|
||||||
file(MD5 ${SOURCE_DIR}/server/data_structures/internal_datafacade.hpp MD5OBJECTS)
|
|
||||||
|
|
||||||
CONFIGURE_FILE(${SOURCE_DIR}/util/fingerprint_impl.hpp.in ${SOURCE_DIR}/util/fingerprint_impl.hpp)
|
|
@ -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()
|
|
290
cmake/JSONParser.cmake
Normal file
290
cmake/JSONParser.cmake
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
# https://github.com/sbellus/json-cmake/blob/9913da8800b95322d393894d3525d634568f305e/JSONParser.cmake
|
||||||
|
# MIT Licensed - https://github.com/sbellus/json-cmake/blob/master/LICENSE
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.18)
|
||||||
|
|
||||||
|
if (DEFINED JSonParserGuard)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(JSonParserGuard yes)
|
||||||
|
|
||||||
|
macro(sbeParseJson prefix jsonString)
|
||||||
|
cmake_policy(PUSH)
|
||||||
|
|
||||||
|
set(json_string "${${jsonString}}")
|
||||||
|
string(LENGTH "${json_string}" json_jsonLen)
|
||||||
|
set(json_index 0)
|
||||||
|
set(json_AllVariables ${prefix})
|
||||||
|
set(json_ArrayNestingLevel 0)
|
||||||
|
set(json_MaxArrayNestingLevel 0)
|
||||||
|
|
||||||
|
_sbeParse(${prefix})
|
||||||
|
|
||||||
|
unset(json_index)
|
||||||
|
unset(json_AllVariables)
|
||||||
|
unset(json_jsonLen)
|
||||||
|
unset(json_string)
|
||||||
|
unset(json_value)
|
||||||
|
unset(json_inValue)
|
||||||
|
unset(json_name)
|
||||||
|
unset(json_inName)
|
||||||
|
unset(json_newPrefix)
|
||||||
|
unset(json_reservedWord)
|
||||||
|
unset(json_arrayIndex)
|
||||||
|
unset(json_char)
|
||||||
|
unset(json_end)
|
||||||
|
unset(json_ArrayNestingLevel)
|
||||||
|
foreach(json_nestingLevel RANGE ${json_MaxArrayNestingLevel})
|
||||||
|
unset(json_${json_nestingLevel}_arrayIndex)
|
||||||
|
endforeach()
|
||||||
|
unset(json_nestingLevel)
|
||||||
|
unset(json_MaxArrayNestingLevel)
|
||||||
|
|
||||||
|
cmake_policy(POP)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(sbeClearJson prefix)
|
||||||
|
foreach(json_var ${${prefix}})
|
||||||
|
unset(${json_var})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
unset(${prefix})
|
||||||
|
unset(json_var)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(sbePrintJson prefix)
|
||||||
|
foreach(json_var ${${prefix}})
|
||||||
|
message("${json_var} = ${${json_var}}")
|
||||||
|
endforeach()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(_sbeParse prefix)
|
||||||
|
|
||||||
|
while(${json_index} LESS ${json_jsonLen})
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
|
||||||
|
if("\"" STREQUAL "${json_char}")
|
||||||
|
_sbeParseNameValue(${prefix})
|
||||||
|
elseif("{" STREQUAL "${json_char}")
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
_sbeParseObject(${prefix})
|
||||||
|
elseif("[" STREQUAL "${json_char}")
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
_sbeParseArray(${prefix})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${json_index} LESS ${json_jsonLen})
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
else()
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if ("}" STREQUAL "${json_char}" OR "]" STREQUAL "${json_char}")
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
endwhile()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(_sbeParseNameValue prefix)
|
||||||
|
set(json_name "")
|
||||||
|
set(json_inName no)
|
||||||
|
|
||||||
|
while(${json_index} LESS ${json_jsonLen})
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
|
||||||
|
# check if name ends
|
||||||
|
if("\"" STREQUAL "${json_char}" AND json_inName)
|
||||||
|
set(json_inName no)
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
if(NOT ${json_index} LESS ${json_jsonLen})
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
set(json_newPrefix ${prefix}.${json_name})
|
||||||
|
set(json_name "")
|
||||||
|
|
||||||
|
if(":" STREQUAL "${json_char}")
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
if(NOT ${json_index} LESS ${json_jsonLen})
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
|
||||||
|
if("\"" STREQUAL "${json_char}")
|
||||||
|
_sbeParseValue(${json_newPrefix})
|
||||||
|
break()
|
||||||
|
elseif("{" STREQUAL "${json_char}")
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
_sbeParseObject(${json_newPrefix})
|
||||||
|
break()
|
||||||
|
elseif("[" STREQUAL "${json_char}")
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
_sbeParseArray(${json_newPrefix})
|
||||||
|
break()
|
||||||
|
else()
|
||||||
|
# reserved word starts
|
||||||
|
_sbeParseReservedWord(${json_newPrefix})
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
# name without value
|
||||||
|
list(APPEND ${json_AllVariables} ${json_newPrefix})
|
||||||
|
set(${json_newPrefix} "")
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(json_inName)
|
||||||
|
# remove escapes
|
||||||
|
if("\\" STREQUAL "${json_char}")
|
||||||
|
math(EXPR json_index "${json_index} + 1")
|
||||||
|
if(NOT ${json_index} LESS ${json_jsonLen})
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(json_name "${json_name}${json_char}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# check if name starts
|
||||||
|
if("\"" STREQUAL "${json_char}" AND NOT json_inName)
|
||||||
|
set(json_inName yes)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
endwhile()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(_sbeParseReservedWord prefix)
|
||||||
|
set(json_reservedWord "")
|
||||||
|
set(json_end no)
|
||||||
|
while(${json_index} LESS ${json_jsonLen} AND NOT json_end)
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
|
||||||
|
if("," STREQUAL "${json_char}" OR "}" STREQUAL "${json_char}" OR "]" STREQUAL "${json_char}")
|
||||||
|
set(json_end yes)
|
||||||
|
else()
|
||||||
|
set(json_reservedWord "${json_reservedWord}${json_char}")
|
||||||
|
math(EXPR json_index "${json_index} + 1")
|
||||||
|
endif()
|
||||||
|
endwhile()
|
||||||
|
|
||||||
|
list(APPEND ${json_AllVariables} ${prefix})
|
||||||
|
string(STRIP "${json_reservedWord}" json_reservedWord)
|
||||||
|
set(${prefix} ${json_reservedWord})
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(_sbeParseValue prefix)
|
||||||
|
cmake_policy(SET CMP0054 NEW) # turn off implicit expansions in if statement
|
||||||
|
|
||||||
|
set(json_value "")
|
||||||
|
set(json_inValue no)
|
||||||
|
|
||||||
|
while(${json_index} LESS ${json_jsonLen})
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
|
||||||
|
# check if json_value ends, it is ended by "
|
||||||
|
if("\"" STREQUAL "${json_char}" AND json_inValue)
|
||||||
|
set(json_inValue no)
|
||||||
|
|
||||||
|
set(${prefix} ${json_value})
|
||||||
|
list(APPEND ${json_AllVariables} ${prefix})
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(json_inValue)
|
||||||
|
# if " is escaped consume
|
||||||
|
if("\\" STREQUAL "${json_char}")
|
||||||
|
math(EXPR json_index "${json_index} + 1")
|
||||||
|
if(NOT ${json_index} LESS ${json_jsonLen})
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
if(NOT "\"" STREQUAL "${json_char}")
|
||||||
|
# if it is not " then copy also escape character
|
||||||
|
set(json_char "\\${json_char}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
_sbeAddEscapedCharacter("${json_char}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# check if value starts
|
||||||
|
if("\"" STREQUAL "${json_char}" AND NOT json_inValue)
|
||||||
|
set(json_inValue yes)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
math(EXPR json_index "${json_index} + 1")
|
||||||
|
endwhile()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(_sbeAddEscapedCharacter char)
|
||||||
|
string(CONCAT json_value "${json_value}" "${char}")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(_sbeParseObject prefix)
|
||||||
|
_sbeParse(${prefix})
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(_sbeParseArray prefix)
|
||||||
|
math(EXPR json_ArrayNestingLevel "${json_ArrayNestingLevel} + 1")
|
||||||
|
set(json_${json_ArrayNestingLevel}_arrayIndex 0)
|
||||||
|
|
||||||
|
set(${prefix} "")
|
||||||
|
list(APPEND ${json_AllVariables} ${prefix})
|
||||||
|
|
||||||
|
while(${json_index} LESS ${json_jsonLen})
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
|
||||||
|
if("\"" STREQUAL "${json_char}")
|
||||||
|
# simple value
|
||||||
|
list(APPEND ${prefix} ${json_${json_ArrayNestingLevel}_arrayIndex})
|
||||||
|
_sbeParseValue(${prefix}_${json_${json_ArrayNestingLevel}_arrayIndex})
|
||||||
|
elseif("{" STREQUAL "${json_char}")
|
||||||
|
# object
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
list(APPEND ${prefix} ${json_${json_ArrayNestingLevel}_arrayIndex})
|
||||||
|
_sbeParseObject(${prefix}_${json_${json_ArrayNestingLevel}_arrayIndex})
|
||||||
|
else()
|
||||||
|
list(APPEND ${prefix} ${json_${json_ArrayNestingLevel}_arrayIndex})
|
||||||
|
_sbeParseReservedWord(${prefix}_${json_${json_ArrayNestingLevel}_arrayIndex})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT ${json_index} LESS ${json_jsonLen})
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
|
||||||
|
if("]" STREQUAL "${json_char}")
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
break()
|
||||||
|
elseif("," STREQUAL "${json_char}")
|
||||||
|
math(EXPR json_${json_ArrayNestingLevel}_arrayIndex "${json_${json_ArrayNestingLevel}_arrayIndex} + 1")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
_sbeMoveToNextNonEmptyCharacter()
|
||||||
|
endwhile()
|
||||||
|
|
||||||
|
if(${json_MaxArrayNestingLevel} LESS ${json_ArrayNestingLevel})
|
||||||
|
set(json_MaxArrayNestingLevel ${json_ArrayNestingLevel})
|
||||||
|
endif()
|
||||||
|
math(EXPR json_ArrayNestingLevel "${json_ArrayNestingLevel} - 1")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
macro(_sbeMoveToNextNonEmptyCharacter)
|
||||||
|
math(EXPR json_index "${json_index} + 1")
|
||||||
|
if(${json_index} LESS ${json_jsonLen})
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
while(${json_char} MATCHES "[ \t\n\r]" AND ${json_index} LESS ${json_jsonLen})
|
||||||
|
math(EXPR json_index "${json_index} + 1")
|
||||||
|
string(SUBSTRING "${json_string}" ${json_index} 1 json_char)
|
||||||
|
endwhile()
|
||||||
|
endif()
|
||||||
|
endmacro()
|
@ -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]]:
|
||||||
|
21
cmake/cmake_uninstall.cmake.in
Normal file
21
cmake/cmake_uninstall.cmake.in
Normal file
@ -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)
|
1026
cmake/conan.cmake
Normal file
1026
cmake/conan.cmake
Normal file
File diff suppressed because it is too large
Load Diff
@ -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: @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
|
|
88
cmake/warnings.cmake
Normal file
88
cmake/warnings.cmake
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
include (CheckCXXCompilerFlag)
|
||||||
|
include (CheckCCompilerFlag)
|
||||||
|
|
||||||
|
# Try to add -Wflag if compiler supports it
|
||||||
|
macro (add_warning flag)
|
||||||
|
string(REPLACE "-" "_" underscored_flag ${flag})
|
||||||
|
string(REPLACE "+" "x" underscored_flag ${underscored_flag})
|
||||||
|
|
||||||
|
check_cxx_compiler_flag("-W${flag}" SUPPORTS_CXXFLAG_${underscored_flag})
|
||||||
|
check_c_compiler_flag("-W${flag}" SUPPORTS_CFLAG_${underscored_flag})
|
||||||
|
|
||||||
|
if (SUPPORTS_CXXFLAG_${underscored_flag})
|
||||||
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W${flag}")
|
||||||
|
else()
|
||||||
|
message (STATUS "Flag -W${flag} is unsupported")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (SUPPORTS_CFLAG_${underscored_flag})
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W${flag}")
|
||||||
|
else()
|
||||||
|
message(STATUS "Flag -W${flag} is unsupported")
|
||||||
|
endif()
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
# Try to add -Wno flag if compiler supports it
|
||||||
|
macro (no_warning flag)
|
||||||
|
add_warning(no-${flag})
|
||||||
|
endmacro ()
|
||||||
|
|
||||||
|
|
||||||
|
# The same but only for specified target.
|
||||||
|
macro (target_add_warning target flag)
|
||||||
|
string (REPLACE "-" "_" underscored_flag ${flag})
|
||||||
|
string (REPLACE "+" "x" underscored_flag ${underscored_flag})
|
||||||
|
|
||||||
|
check_cxx_compiler_flag("-W${flag}" SUPPORTS_CXXFLAG_${underscored_flag})
|
||||||
|
|
||||||
|
if (SUPPORTS_CXXFLAG_${underscored_flag})
|
||||||
|
target_compile_options (${target} PRIVATE "-W${flag}")
|
||||||
|
else ()
|
||||||
|
message (STATUS "Flag -W${flag} is unsupported")
|
||||||
|
endif ()
|
||||||
|
endmacro ()
|
||||||
|
|
||||||
|
macro (target_no_warning target flag)
|
||||||
|
target_add_warning(${target} no-${flag})
|
||||||
|
endmacro ()
|
||||||
|
|
||||||
|
add_warning(all)
|
||||||
|
add_warning(extra)
|
||||||
|
add_warning(pedantic)
|
||||||
|
add_warning(error) # treat all warnings as errors
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
|
add_warning(strict-overflow=1)
|
||||||
|
endif()
|
||||||
|
add_warning(suggest-override)
|
||||||
|
add_warning(suggest-destructor-override)
|
||||||
|
add_warning(unused)
|
||||||
|
add_warning(unreachable-code)
|
||||||
|
add_warning(delete-incomplete)
|
||||||
|
add_warning(duplicated-cond)
|
||||||
|
add_warning(disabled-optimization)
|
||||||
|
add_warning(init-self)
|
||||||
|
add_warning(bool-compare)
|
||||||
|
add_warning(logical-not-parentheses)
|
||||||
|
add_warning(logical-op)
|
||||||
|
add_warning(misleading-indentation)
|
||||||
|
# `no-` prefix is part of warning name(i.e. doesn't mean we are disabling it)
|
||||||
|
add_warning(no-return-local-addr)
|
||||||
|
add_warning(odr)
|
||||||
|
add_warning(pointer-arith)
|
||||||
|
add_warning(redundant-decls)
|
||||||
|
add_warning(reorder)
|
||||||
|
add_warning(shift-negative-value)
|
||||||
|
add_warning(sizeof-array-argument)
|
||||||
|
add_warning(switch-bool)
|
||||||
|
add_warning(tautological-compare)
|
||||||
|
add_warning(trampolines)
|
||||||
|
# these warnings are not enabled by default
|
||||||
|
# no_warning(name-of-warning)
|
||||||
|
no_warning(deprecated-comma-subscript)
|
||||||
|
no_warning(comma-subscript)
|
||||||
|
no_warning(ambiguous-reversed-operator)
|
||||||
|
no_warning(restrict)
|
||||||
|
no_warning(free-nonheap-object)
|
||||||
|
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||||
|
no_warning(stringop-overflow)
|
||||||
|
endif()
|
6
codecov.yml
Normal file
6
codecov.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
coverage:
|
||||||
|
|
||||||
|
ignore:
|
||||||
|
- 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,962 +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));
|
|
||||||
}
|
|
||||||
#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();
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// initialize priorities in parallel
|
|
||||||
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, InitGrainSize),
|
|
||||||
[&remaining_nodes](const tbb::blocked_range<int> &range)
|
|
||||||
{
|
|
||||||
for (int x = range.begin(); x != range.end(); ++x)
|
|
||||||
{
|
|
||||||
remaining_nodes[x].id = x;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
std::cout << "initializing elimination PQ ..." << std::flush;
|
|
||||||
tbb::parallel_for(tbb::blocked_range<int>(0, number_of_nodes, PQGrainSize),
|
|
||||||
[this, &node_priorities, &node_data, &thread_data_list](
|
|
||||||
const tbb::blocked_range<int> &range)
|
|
||||||
{
|
|
||||||
ContractorThreadData *data = thread_data_list.getThreadData();
|
|
||||||
for (int x = range.begin(); x != range.end(); ++x)
|
|
||||||
{
|
|
||||||
node_priorities[x] =
|
|
||||||
this->EvaluateNodePriority(data, &node_data[x], x);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
std::cout << "ok" << std::endl << "preprocessing " << number_of_nodes << " nodes ..."
|
|
||||||
<< std::flush;
|
|
||||||
|
|
||||||
bool flushed_contractor = false;
|
|
||||||
while (number_of_nodes > 2 && number_of_contracted_nodes < number_of_nodes)
|
|
||||||
{
|
|
||||||
if (!flushed_contractor && (number_of_contracted_nodes > (number_of_nodes * 0.65)))
|
|
||||||
{
|
|
||||||
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_to_new_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_to_new_id_map[new_node_id] = remaining_nodes[new_node_id].id;
|
|
||||||
new_node_id_from_orig_id_map[remaining_nodes[new_node_id].id] = new_node_id;
|
|
||||||
new_node_priority[new_node_id] =
|
|
||||||
node_priorities[remaining_nodes[new_node_id].id];
|
|
||||||
remaining_nodes[new_node_id].id = new_node_id;
|
|
||||||
}
|
|
||||||
// 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(); i != range.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(); position != range.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(); position != range.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(); position != range.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].first)
|
|
||||||
// -
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_data_list.data.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
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_to_new_id_map.empty())
|
|
||||||
{
|
|
||||||
new_edge.source = orig_node_id_to_new_id_map[node];
|
|
||||||
new_edge.target = orig_node_id_to_new_id_map[target];
|
|
||||||
}
|
|
||||||
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_to_new_id_map.empty())
|
|
||||||
{
|
|
||||||
new_edge.data.id = orig_node_id_to_new_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_to_new_id_map.clear();
|
|
||||||
orig_node_id_to_new_id_map.shrink_to_fit();
|
|
||||||
|
|
||||||
BOOST_ASSERT(0 == orig_node_id_to_new_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;
|
|
||||||
std::vector<ContractorGraph::InputEdge> contracted_edge_list;
|
|
||||||
stxxl::vector<QueryEdge> external_edge_list;
|
|
||||||
std::vector<NodeID> orig_node_id_to_new_id_map;
|
|
||||||
XORFastHash fast_hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CONTRACTOR_HPP
|
|
@ -1,762 +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 "../algorithms/tiny_components.hpp"
|
|
||||||
#include "../data_structures/percent.hpp"
|
|
||||||
#include "../util/compute_angle.hpp"
|
|
||||||
#include "../util/integer_range.hpp"
|
|
||||||
#include "../util/lua_util.hpp"
|
|
||||||
#include "../util/simple_logger.hpp"
|
|
||||||
#include "../util/timing_util.hpp"
|
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
EdgeBasedGraphFactory::EdgeBasedGraphFactory(
|
|
||||||
const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
|
|
||||||
std::unique_ptr<RestrictionMap> restriction_map,
|
|
||||||
std::vector<NodeID> &barrier_node_list,
|
|
||||||
std::vector<NodeID> &traffic_light_node_list,
|
|
||||||
std::vector<QueryNode> &node_info_list,
|
|
||||||
SpeedProfileProperties &speed_profile)
|
|
||||||
: speed_profile(speed_profile),
|
|
||||||
m_number_of_edge_based_nodes(std::numeric_limits<unsigned>::max()),
|
|
||||||
m_node_info_list(node_info_list), m_node_based_graph(node_based_graph),
|
|
||||||
m_restriction_map(std::move(restriction_map)), max_id(0), removed_node_count(0)
|
|
||||||
{
|
|
||||||
// insert into unordered sets for fast lookup
|
|
||||||
m_barrier_nodes.insert(barrier_node_list.begin(), barrier_node_list.end());
|
|
||||||
m_traffic_lights.insert(traffic_light_node_list.begin(), traffic_light_node_list.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &output_edge_list)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT_MSG(0 == output_edge_list.size(), "Vector is not empty");
|
|
||||||
m_edge_based_edge_list.swap(output_edge_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes)
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
for (const EdgeBasedNode &node : m_edge_based_node_list)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(m_node_info_list.at(node.u).lat != INT_MAX);
|
|
||||||
BOOST_ASSERT(m_node_info_list.at(node.u).lon != INT_MAX);
|
|
||||||
BOOST_ASSERT(m_node_info_list.at(node.v).lon != INT_MAX);
|
|
||||||
BOOST_ASSERT(m_node_info_list.at(node.v).lat != INT_MAX);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
nodes.swap(m_edge_based_node_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::InsertEdgeBasedNode(const NodeID node_u,
|
|
||||||
const NodeID node_v,
|
|
||||||
const unsigned component_id)
|
|
||||||
{
|
|
||||||
// merge edges together into one EdgeBasedNode
|
|
||||||
BOOST_ASSERT(node_u != SPECIAL_NODEID);
|
|
||||||
BOOST_ASSERT(node_v != SPECIAL_NODEID);
|
|
||||||
|
|
||||||
// find forward edge id and
|
|
||||||
const EdgeID 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.edgeBasedNodeID == SPECIAL_NODEID &&
|
|
||||||
reverse_data.edgeBasedNodeID == SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(m_geometry_compressor.HasEntryForID(edge_id_1) ==
|
|
||||||
m_geometry_compressor.HasEntryForID(edge_id_2));
|
|
||||||
if (m_geometry_compressor.HasEntryForID(edge_id_1))
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(m_geometry_compressor.HasEntryForID(edge_id_2));
|
|
||||||
|
|
||||||
// reconstruct geometry and put in each individual edge with its offset
|
|
||||||
const std::vector<GeometryCompressor::CompressedNode> &forward_geometry =
|
|
||||||
m_geometry_compressor.GetBucketReference(edge_id_1);
|
|
||||||
const std::vector<GeometryCompressor::CompressedNode> &reverse_geometry =
|
|
||||||
m_geometry_compressor.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;
|
|
||||||
|
|
||||||
if (SPECIAL_NODEID != forward_data.edgeBasedNodeID)
|
|
||||||
{
|
|
||||||
max_id = std::max(forward_data.edgeBasedNodeID, max_id);
|
|
||||||
}
|
|
||||||
if (SPECIAL_NODEID != reverse_data.edgeBasedNodeID)
|
|
||||||
{
|
|
||||||
max_id = std::max(reverse_data.edgeBasedNodeID, max_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// traverse arrays from start and end respectively
|
|
||||||
for (const auto i : osrm::irange(0u, geometry_size))
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(current_edge_source_coordinate_id ==
|
|
||||||
reverse_geometry[geometry_size - 1 - i].first);
|
|
||||||
const NodeID current_edge_target_coordinate_id = forward_geometry[i].first;
|
|
||||||
BOOST_ASSERT(current_edge_target_coordinate_id != current_edge_source_coordinate_id);
|
|
||||||
|
|
||||||
// build edges
|
|
||||||
m_edge_based_node_list.emplace_back(
|
|
||||||
forward_data.edgeBasedNodeID, reverse_data.edgeBasedNodeID,
|
|
||||||
current_edge_source_coordinate_id, current_edge_target_coordinate_id,
|
|
||||||
forward_data.nameID, forward_geometry[i].second,
|
|
||||||
reverse_geometry[geometry_size - 1 - i].second, forward_dist_prefix_sum[i],
|
|
||||||
reverse_dist_prefix_sum[i], m_geometry_compressor.GetPositionForID(edge_id_1),
|
|
||||||
component_id, i, forward_data.travel_mode, reverse_data.travel_mode);
|
|
||||||
current_edge_source_coordinate_id = current_edge_target_coordinate_id;
|
|
||||||
|
|
||||||
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
|
|
||||||
|
|
||||||
BOOST_ASSERT(node_u != m_edge_based_node_list.back().u ||
|
|
||||||
node_v != m_edge_based_node_list.back().v);
|
|
||||||
|
|
||||||
BOOST_ASSERT(node_u != m_edge_based_node_list.back().v ||
|
|
||||||
node_v != m_edge_based_node_list.back().u);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(current_edge_source_coordinate_id == node_v);
|
|
||||||
BOOST_ASSERT(m_edge_based_node_list.back().IsCompressed());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(!m_geometry_compressor.HasEntryForID(edge_id_2));
|
|
||||||
|
|
||||||
if (forward_data.edgeBasedNodeID != SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(forward_data.forward);
|
|
||||||
}
|
|
||||||
if (reverse_data.edgeBasedNodeID != SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(reverse_data.forward);
|
|
||||||
}
|
|
||||||
if (forward_data.edgeBasedNodeID == SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(!forward_data.forward);
|
|
||||||
}
|
|
||||||
if (reverse_data.edgeBasedNodeID == SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(!reverse_data.forward);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(forward_data.edgeBasedNodeID != SPECIAL_NODEID ||
|
|
||||||
reverse_data.edgeBasedNodeID != SPECIAL_NODEID);
|
|
||||||
|
|
||||||
m_edge_based_node_list.emplace_back(
|
|
||||||
forward_data.edgeBasedNodeID, reverse_data.edgeBasedNodeID, node_u, node_v,
|
|
||||||
forward_data.nameID, forward_data.distance, reverse_data.distance, 0, 0, SPECIAL_EDGEID,
|
|
||||||
component_id, 0, forward_data.travel_mode, reverse_data.travel_mode);
|
|
||||||
BOOST_ASSERT(!m_edge_based_node_list.back().IsCompressed());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::FlushVectorToStream(
|
|
||||||
std::ofstream &edge_data_file, std::vector<OriginalEdgeData> &original_edge_data_vector) const
|
|
||||||
{
|
|
||||||
if (original_edge_data_vector.empty())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
edge_data_file.write((char *)&(original_edge_data_vector[0]),
|
|
||||||
original_edge_data_vector.size() * sizeof(OriginalEdgeData));
|
|
||||||
original_edge_data_vector.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::Run(const std::string &original_edge_data_filename,
|
|
||||||
const std::string &geometry_filename,
|
|
||||||
lua_State *lua_state)
|
|
||||||
{
|
|
||||||
|
|
||||||
TIMER_START(geometry);
|
|
||||||
CompressGeometry();
|
|
||||||
TIMER_STOP(geometry);
|
|
||||||
|
|
||||||
TIMER_START(renumber);
|
|
||||||
RenumberEdges();
|
|
||||||
TIMER_STOP(renumber);
|
|
||||||
|
|
||||||
TIMER_START(generate_nodes);
|
|
||||||
GenerateEdgeExpandedNodes();
|
|
||||||
TIMER_STOP(generate_nodes);
|
|
||||||
|
|
||||||
TIMER_START(generate_edges);
|
|
||||||
GenerateEdgeExpandedEdges(original_edge_data_filename, lua_state);
|
|
||||||
TIMER_STOP(generate_edges);
|
|
||||||
|
|
||||||
m_geometry_compressor.SerializeInternalVector(geometry_filename);
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Timing statistics for edge-expanded graph:";
|
|
||||||
SimpleLogger().Write() << "Geometry compression: " << TIMER_SEC(geometry) << "s";
|
|
||||||
SimpleLogger().Write() << "Renumbering edges: " << TIMER_SEC(renumber) << "s";
|
|
||||||
SimpleLogger().Write() << "Generating nodes: " << TIMER_SEC(generate_nodes) << "s";
|
|
||||||
SimpleLogger().Write() << "Generating edges: " << TIMER_SEC(generate_edges) << "s";
|
|
||||||
}
|
|
||||||
|
|
||||||
void EdgeBasedGraphFactory::CompressGeometry()
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "Removing graph geometry while preserving topology";
|
|
||||||
|
|
||||||
const unsigned original_number_of_nodes = m_node_based_graph->GetNumberOfNodes();
|
|
||||||
const unsigned original_number_of_edges = m_node_based_graph->GetNumberOfEdges();
|
|
||||||
|
|
||||||
Percent progress(original_number_of_nodes);
|
|
||||||
|
|
||||||
for (const NodeID node_v : osrm::irange(0u, original_number_of_nodes))
|
|
||||||
{
|
|
||||||
progress.printStatus(node_v);
|
|
||||||
|
|
||||||
// only contract degree 2 vertices
|
|
||||||
if (2 != m_node_based_graph->GetOutDegree(node_v))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't contract barrier node
|
|
||||||
if (m_barrier_nodes.end() != m_barrier_nodes.find(node_v))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if v is a via node for a turn restriction, i.e. a 'directed' barrier node
|
|
||||||
if (m_restriction_map->IsViaNode(node_v))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool reverse_edge_order =
|
|
||||||
!(m_node_based_graph->GetEdgeData(m_node_based_graph->BeginEdges(node_v)).forward);
|
|
||||||
const EdgeID forward_e2 = m_node_based_graph->BeginEdges(node_v) + reverse_edge_order;
|
|
||||||
BOOST_ASSERT(SPECIAL_EDGEID != forward_e2);
|
|
||||||
const EdgeID reverse_e2 = m_node_based_graph->BeginEdges(node_v) + 1 - reverse_edge_order;
|
|
||||||
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e2);
|
|
||||||
|
|
||||||
const EdgeData &fwd_edge_data2 = m_node_based_graph->GetEdgeData(forward_e2);
|
|
||||||
const EdgeData &rev_edge_data2 = m_node_based_graph->GetEdgeData(reverse_e2);
|
|
||||||
|
|
||||||
const NodeID node_w = m_node_based_graph->GetTarget(forward_e2);
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != node_w);
|
|
||||||
BOOST_ASSERT(node_v != node_w);
|
|
||||||
const NodeID node_u = m_node_based_graph->GetTarget(reverse_e2);
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != node_u);
|
|
||||||
BOOST_ASSERT(node_u != node_v);
|
|
||||||
|
|
||||||
const EdgeID forward_e1 = m_node_based_graph->FindEdge(node_u, node_v);
|
|
||||||
BOOST_ASSERT(SPECIAL_EDGEID != forward_e1);
|
|
||||||
BOOST_ASSERT(node_v == m_node_based_graph->GetTarget(forward_e1));
|
|
||||||
const EdgeID reverse_e1 = m_node_based_graph->FindEdge(node_w, node_v);
|
|
||||||
BOOST_ASSERT(SPECIAL_EDGEID != reverse_e1);
|
|
||||||
BOOST_ASSERT(node_v == m_node_based_graph->GetTarget(reverse_e1));
|
|
||||||
|
|
||||||
const EdgeData &fwd_edge_data1 = m_node_based_graph->GetEdgeData(forward_e1);
|
|
||||||
const EdgeData &rev_edge_data1 = m_node_based_graph->GetEdgeData(reverse_e1);
|
|
||||||
|
|
||||||
if (m_node_based_graph->FindEdgeInEitherDirection(node_u, node_w) != SPECIAL_EDGEID)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( // TODO: rename to IsCompatibleTo
|
|
||||||
fwd_edge_data1.IsEqualTo(fwd_edge_data2) && rev_edge_data1.IsEqualTo(rev_edge_data2))
|
|
||||||
{
|
|
||||||
// Get distances before graph is modified
|
|
||||||
const int forward_weight1 = m_node_based_graph->GetEdgeData(forward_e1).distance;
|
|
||||||
const int forward_weight2 = m_node_based_graph->GetEdgeData(forward_e2).distance;
|
|
||||||
|
|
||||||
BOOST_ASSERT(0 != forward_weight1);
|
|
||||||
BOOST_ASSERT(0 != forward_weight2);
|
|
||||||
|
|
||||||
const int reverse_weight1 = m_node_based_graph->GetEdgeData(reverse_e1).distance;
|
|
||||||
const int reverse_weight2 = m_node_based_graph->GetEdgeData(reverse_e2).distance;
|
|
||||||
|
|
||||||
BOOST_ASSERT(0 != reverse_weight1);
|
|
||||||
BOOST_ASSERT(0 != forward_weight2);
|
|
||||||
|
|
||||||
const bool has_node_penalty = m_traffic_lights.find(node_v) != m_traffic_lights.end();
|
|
||||||
|
|
||||||
// add weight of e2's to e1
|
|
||||||
m_node_based_graph->GetEdgeData(forward_e1).distance += fwd_edge_data2.distance;
|
|
||||||
m_node_based_graph->GetEdgeData(reverse_e1).distance += rev_edge_data2.distance;
|
|
||||||
if (has_node_penalty)
|
|
||||||
{
|
|
||||||
m_node_based_graph->GetEdgeData(forward_e1).distance +=
|
|
||||||
speed_profile.traffic_signal_penalty;
|
|
||||||
m_node_based_graph->GetEdgeData(reverse_e1).distance +=
|
|
||||||
speed_profile.traffic_signal_penalty;
|
|
||||||
}
|
|
||||||
|
|
||||||
// extend e1's to targets of e2's
|
|
||||||
m_node_based_graph->SetTarget(forward_e1, node_w);
|
|
||||||
m_node_based_graph->SetTarget(reverse_e1, node_u);
|
|
||||||
|
|
||||||
// remove e2's (if bidir, otherwise only one)
|
|
||||||
m_node_based_graph->DeleteEdge(node_v, forward_e2);
|
|
||||||
m_node_based_graph->DeleteEdge(node_v, reverse_e2);
|
|
||||||
|
|
||||||
// update any involved turn restrictions
|
|
||||||
m_restriction_map->FixupStartingTurnRestriction(node_u, node_v, node_w);
|
|
||||||
m_restriction_map->FixupArrivingTurnRestriction(node_u, node_v, node_w,
|
|
||||||
m_node_based_graph);
|
|
||||||
|
|
||||||
m_restriction_map->FixupStartingTurnRestriction(node_w, node_v, node_u);
|
|
||||||
m_restriction_map->FixupArrivingTurnRestriction(node_w, node_v, node_u,
|
|
||||||
m_node_based_graph);
|
|
||||||
|
|
||||||
// store compressed geometry in container
|
|
||||||
m_geometry_compressor.CompressEdge(
|
|
||||||
forward_e1, forward_e2, node_v, node_w,
|
|
||||||
forward_weight1 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0),
|
|
||||||
forward_weight2);
|
|
||||||
m_geometry_compressor.CompressEdge(
|
|
||||||
reverse_e1, reverse_e2, node_v, node_u, reverse_weight1,
|
|
||||||
reverse_weight2 + (has_node_penalty ? speed_profile.traffic_signal_penalty : 0));
|
|
||||||
++removed_node_count;
|
|
||||||
|
|
||||||
BOOST_ASSERT(m_node_based_graph->GetEdgeData(forward_e1).nameID ==
|
|
||||||
m_node_based_graph->GetEdgeData(reverse_e1).nameID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SimpleLogger().Write() << "removed " << removed_node_count << " nodes";
|
|
||||||
m_geometry_compressor.PrintStatistics();
|
|
||||||
|
|
||||||
unsigned new_node_count = 0;
|
|
||||||
unsigned new_edge_count = 0;
|
|
||||||
|
|
||||||
for (const auto i : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
|
||||||
{
|
|
||||||
if (m_node_based_graph->GetOutDegree(i) > 0)
|
|
||||||
{
|
|
||||||
++new_node_count;
|
|
||||||
new_edge_count += (m_node_based_graph->EndEdges(i) - m_node_based_graph->BeginEdges(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SimpleLogger().Write() << "new nodes: " << new_node_count << ", edges " << new_edge_count;
|
|
||||||
SimpleLogger().Write() << "Node compression ratio: "
|
|
||||||
<< new_node_count / (double)original_number_of_nodes;
|
|
||||||
SimpleLogger().Write() << "Edge compression ratio: "
|
|
||||||
<< new_edge_count / (double)original_number_of_edges;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes the id of the edge in the edge expanded graph (into the edge in the node based graph)
|
|
||||||
*/
|
|
||||||
void EdgeBasedGraphFactory::RenumberEdges()
|
|
||||||
{
|
|
||||||
// renumber edge based node IDs
|
|
||||||
unsigned numbered_edges_count = 0;
|
|
||||||
for (const auto current_node : osrm::irange(0u, m_node_based_graph->GetNumberOfNodes()))
|
|
||||||
{
|
|
||||||
for (const auto current_edge : m_node_based_graph->GetAdjacentEdgeRange(current_node))
|
|
||||||
{
|
|
||||||
EdgeData &edge_data = m_node_based_graph->GetEdgeData(current_edge);
|
|
||||||
if (!edge_data.forward)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(numbered_edges_count < m_node_based_graph->GetNumberOfEdges());
|
|
||||||
edge_data.edgeBasedNodeID = numbered_edges_count;
|
|
||||||
++numbered_edges_count;
|
|
||||||
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != edge_data.edgeBasedNodeID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_number_of_edge_based_nodes = numbered_edges_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the nodes in the edge expanded graph from edges in the node-based graph.
|
|
||||||
*/
|
|
||||||
void EdgeBasedGraphFactory::GenerateEdgeExpandedNodes()
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "Identifying components of the (compressed) road network";
|
|
||||||
|
|
||||||
// Run a BFS on the undirected graph and identify small components
|
|
||||||
TarjanSCC<NodeBasedDynamicGraph> component_explorer(m_node_based_graph, *m_restriction_map,
|
|
||||||
m_barrier_nodes);
|
|
||||||
|
|
||||||
component_explorer.run();
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "identified: "
|
|
||||||
<< component_explorer.get_number_of_components() - removed_node_count
|
|
||||||
<< " (compressed) components";
|
|
||||||
SimpleLogger().Write() << "identified "
|
|
||||||
<< component_explorer.get_size_one_count() - removed_node_count
|
|
||||||
<< " (compressed) SCCs of size 1";
|
|
||||||
SimpleLogger().Write() << "generating edge-expanded nodes";
|
|
||||||
|
|
||||||
Percent progress(m_node_based_graph->GetNumberOfNodes());
|
|
||||||
|
|
||||||
// loop over all edges and generate new set of nodes
|
|
||||||
for (const auto 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
|
|
||||||
if (node_u > node_v)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(node_u < node_v);
|
|
||||||
|
|
||||||
// Note: edges that end on barrier nodes or on a turn restriction
|
|
||||||
// may actually be in two distinct components. We choose the smallest
|
|
||||||
const unsigned size_of_component =
|
|
||||||
std::min(component_explorer.get_component_size(node_u),
|
|
||||||
component_explorer.get_component_size(node_v));
|
|
||||||
|
|
||||||
const unsigned id_of_smaller_component = [node_u, node_v, &component_explorer]
|
|
||||||
{
|
|
||||||
if (component_explorer.get_component_size(node_u) <
|
|
||||||
component_explorer.get_component_size(node_v))
|
|
||||||
{
|
|
||||||
return component_explorer.get_component_id(node_u);
|
|
||||||
}
|
|
||||||
return component_explorer.get_component_id(node_v);
|
|
||||||
}();
|
|
||||||
|
|
||||||
const bool component_is_tiny = size_of_component < 1000;
|
|
||||||
|
|
||||||
if (edge_data.edgeBasedNodeID == SPECIAL_NODEID)
|
|
||||||
{
|
|
||||||
InsertEdgeBasedNode(node_v, node_u,
|
|
||||||
(component_is_tiny ? id_of_smaller_component + 1 : 0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InsertEdgeBasedNode(node_u, node_v,
|
|
||||||
(component_is_tiny ? id_of_smaller_component + 1 : 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size()
|
|
||||||
<< " nodes in edge-expanded graph";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actually it also generates OriginalEdgeData and serializes them...
|
|
||||||
*/
|
|
||||||
void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|
||||||
const std::string &original_edge_data_filename, lua_State *lua_state)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "generating edge-expanded edges";
|
|
||||||
|
|
||||||
unsigned node_based_edge_counter = 0;
|
|
||||||
unsigned original_edges_counter = 0;
|
|
||||||
|
|
||||||
std::ofstream edge_data_file(original_edge_data_filename.c_str(), std::ios::binary);
|
|
||||||
|
|
||||||
// writes a dummy value that is updated later
|
|
||||||
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
|
|
||||||
|
|
||||||
std::vector<OriginalEdgeData> original_edge_data_vector;
|
|
||||||
original_edge_data_vector.reserve(1024 * 1024);
|
|
||||||
|
|
||||||
// Loop over all turns and generate new set of edges.
|
|
||||||
// Three nested loop look super-linear, but we are dealing with a (kind of)
|
|
||||||
// linear number of turns only.
|
|
||||||
unsigned restricted_turns_counter = 0;
|
|
||||||
unsigned skipped_uturns_counter = 0;
|
|
||||||
unsigned skipped_barrier_turns_counter = 0;
|
|
||||||
unsigned compressed = 0;
|
|
||||||
|
|
||||||
Percent progress(m_node_based_graph->GetNumberOfNodes());
|
|
||||||
|
|
||||||
for (const auto 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).forward)
|
|
||||||
{
|
|
||||||
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).forward)
|
|
||||||
{
|
|
||||||
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.edgeBasedNodeID != edge_data2.edgeBasedNodeID);
|
|
||||||
BOOST_ASSERT(edge_data1.forward);
|
|
||||||
BOOST_ASSERT(edge_data2.forward);
|
|
||||||
|
|
||||||
// the following is the core of the loop.
|
|
||||||
unsigned distance = edge_data1.distance;
|
|
||||||
if (m_traffic_lights.find(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_geometry_compressor.HasEntryForID(e1)
|
|
||||||
? m_geometry_compressor.GetLastNodeIDOfBucket(e1)
|
|
||||||
: node_u)];
|
|
||||||
|
|
||||||
// unpack first node of second segment if packed
|
|
||||||
const auto third_coordinate =
|
|
||||||
m_node_info_list[(m_geometry_compressor.HasEntryForID(e2)
|
|
||||||
? m_geometry_compressor.GetFirstNodeIDOfBucket(e2)
|
|
||||||
: 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_geometry_compressor.HasEntryForID(e1);
|
|
||||||
|
|
||||||
if (edge_is_compressed)
|
|
||||||
{
|
|
||||||
++compressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
original_edge_data_vector.emplace_back(
|
|
||||||
(edge_is_compressed ? m_geometry_compressor.GetPositionForID(e1) : node_v),
|
|
||||||
edge_data1.nameID, turn_instruction, edge_is_compressed,
|
|
||||||
edge_data2.travel_mode);
|
|
||||||
|
|
||||||
++original_edges_counter;
|
|
||||||
|
|
||||||
if (original_edge_data_vector.size() > 1024 * 1024 * 10)
|
|
||||||
{
|
|
||||||
FlushVectorToStream(edge_data_file, original_edge_data_vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != edge_data1.edgeBasedNodeID);
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != edge_data2.edgeBasedNodeID);
|
|
||||||
|
|
||||||
m_edge_based_edge_list.emplace_back(
|
|
||||||
EdgeBasedEdge(edge_data1.edgeBasedNodeID, edge_data2.edgeBasedNodeID,
|
|
||||||
m_edge_based_edge_list.size(), distance, true, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FlushVectorToStream(edge_data_file, original_edge_data_vector);
|
|
||||||
|
|
||||||
edge_data_file.seekp(std::ios::beg);
|
|
||||||
edge_data_file.write((char *)&original_edges_counter, sizeof(unsigned));
|
|
||||||
edge_data_file.close();
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Generated " << m_edge_based_node_list.size() << " edge based nodes";
|
|
||||||
SimpleLogger().Write() << "Node-based graph contains " << node_based_edge_counter << " edges";
|
|
||||||
SimpleLogger().Write() << "Edge-expanded graph ...";
|
|
||||||
SimpleLogger().Write() << " contains " << m_edge_based_edge_list.size() << " edges";
|
|
||||||
SimpleLogger().Write() << " skips " << restricted_turns_counter << " turns, "
|
|
||||||
"defined by "
|
|
||||||
<< m_restriction_map->size() << " restrictions";
|
|
||||||
SimpleLogger().Write() << " skips " << skipped_uturns_counter << " U turns";
|
|
||||||
SimpleLogger().Write() << " skips " << skipped_barrier_turns_counter << " turns over barriers";
|
|
||||||
}
|
|
||||||
|
|
||||||
int EdgeBasedGraphFactory::GetTurnPenalty(double angle, lua_State *lua_state) const
|
|
||||||
{
|
|
||||||
|
|
||||||
if (speed_profile.has_turn_penalty_function)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// call lua profile to compute turn penalty
|
|
||||||
return luabind::call_function<int>(lua_state, "turn_function", 180. - angle);
|
|
||||||
}
|
|
||||||
catch (const luabind::error &er)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write(logWARNING) << er.what();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TurnInstruction EdgeBasedGraphFactory::AnalyzeTurn(const NodeID node_u,
|
|
||||||
const NodeID node_v,
|
|
||||||
const NodeID node_w,
|
|
||||||
const double angle) const
|
|
||||||
{
|
|
||||||
if (node_u == node_w)
|
|
||||||
{
|
|
||||||
return TurnInstruction::UTurn;
|
|
||||||
}
|
|
||||||
|
|
||||||
const EdgeID edge1 = m_node_based_graph->FindEdge(node_u, node_v);
|
|
||||||
const EdgeID edge2 = m_node_based_graph->FindEdge(node_v, node_w);
|
|
||||||
|
|
||||||
const EdgeData &data1 = m_node_based_graph->GetEdgeData(edge1);
|
|
||||||
const EdgeData &data2 = m_node_based_graph->GetEdgeData(edge2);
|
|
||||||
|
|
||||||
// roundabouts need to be handled explicitely
|
|
||||||
if (data1.roundabout && data2.roundabout)
|
|
||||||
{
|
|
||||||
// Is a turn possible? If yes, we stay on the roundabout!
|
|
||||||
if (1 == m_node_based_graph->GetDirectedOutDegree(node_v))
|
|
||||||
{
|
|
||||||
// No turn possible.
|
|
||||||
return TurnInstruction::NoTurn;
|
|
||||||
}
|
|
||||||
return TurnInstruction::StayOnRoundAbout;
|
|
||||||
}
|
|
||||||
// Does turn start or end on roundabout?
|
|
||||||
if (data1.roundabout || data2.roundabout)
|
|
||||||
{
|
|
||||||
// We are entering the roundabout
|
|
||||||
if ((!data1.roundabout) && data2.roundabout)
|
|
||||||
{
|
|
||||||
return TurnInstruction::EnterRoundAbout;
|
|
||||||
}
|
|
||||||
// We are leaving the roundabout
|
|
||||||
if (data1.roundabout && (!data2.roundabout))
|
|
||||||
{
|
|
||||||
return TurnInstruction::LeaveRoundAbout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If street names stay the same and if we are certain that it is not a
|
|
||||||
// a segment of a roundabout, we skip it.
|
|
||||||
if (data1.nameID == data2.nameID)
|
|
||||||
{
|
|
||||||
// TODO: Here we should also do a small graph exploration to check for
|
|
||||||
// more complex situations
|
|
||||||
if (0 != data1.nameID || m_node_based_graph->GetOutDegree(node_v) <= 2)
|
|
||||||
{
|
|
||||||
return TurnInstruction::NoTurn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TurnInstructionsClass::GetTurnDirectionOfInstruction(angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned EdgeBasedGraphFactory::GetNumberOfEdgeBasedNodes() const
|
|
||||||
{
|
|
||||||
return m_number_of_edge_based_nodes;
|
|
||||||
}
|
|
@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright notice, this list
|
|
||||||
of conditions and the following disclaimer.
|
|
||||||
Redistributions in binary form must reproduce the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer in the documentation and/or
|
|
||||||
other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// This class constructs the edge-expanded routing graph
|
|
||||||
|
|
||||||
#ifndef EDGE_BASED_GRAPH_FACTORY_HPP_
|
|
||||||
#define EDGE_BASED_GRAPH_FACTORY_HPP_
|
|
||||||
|
|
||||||
#include "geometry_compressor.hpp"
|
|
||||||
#include "../typedefs.h"
|
|
||||||
#include "../data_structures/deallocating_vector.hpp"
|
|
||||||
#include "../data_structures/edge_based_node.hpp"
|
|
||||||
#include "../data_structures/original_edge_data.hpp"
|
|
||||||
#include "../data_structures/query_node.hpp"
|
|
||||||
#include "../data_structures/turn_instructions.hpp"
|
|
||||||
#include "../data_structures/node_based_graph.hpp"
|
|
||||||
#include "../data_structures/restriction_map.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <memory>
|
|
||||||
#include <queue>
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
struct lua_State;
|
|
||||||
|
|
||||||
class EdgeBasedGraphFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EdgeBasedGraphFactory() = delete;
|
|
||||||
EdgeBasedGraphFactory(const EdgeBasedGraphFactory &) = delete;
|
|
||||||
|
|
||||||
struct SpeedProfileProperties;
|
|
||||||
|
|
||||||
explicit EdgeBasedGraphFactory(const std::shared_ptr<NodeBasedDynamicGraph> &node_based_graph,
|
|
||||||
std::unique_ptr<RestrictionMap> restricion_map,
|
|
||||||
std::vector<NodeID> &barrier_node_list,
|
|
||||||
std::vector<NodeID> &traffic_light_node_list,
|
|
||||||
std::vector<QueryNode> &node_info_list,
|
|
||||||
SpeedProfileProperties &speed_profile);
|
|
||||||
|
|
||||||
void Run(const std::string &original_edge_data_filename,
|
|
||||||
const std::string &geometry_filename,
|
|
||||||
lua_State *lua_state);
|
|
||||||
|
|
||||||
void GetEdgeBasedEdges(DeallocatingVector<EdgeBasedEdge> &edges);
|
|
||||||
|
|
||||||
void GetEdgeBasedNodes(std::vector<EdgeBasedNode> &nodes);
|
|
||||||
|
|
||||||
TurnInstruction AnalyzeTurn(const NodeID u, const NodeID v, const NodeID w, const double angle) const;
|
|
||||||
|
|
||||||
int GetTurnPenalty(double angle, lua_State *lua_state) const;
|
|
||||||
|
|
||||||
unsigned GetNumberOfEdgeBasedNodes() const;
|
|
||||||
|
|
||||||
struct SpeedProfileProperties
|
|
||||||
{
|
|
||||||
SpeedProfileProperties()
|
|
||||||
: traffic_signal_penalty(0), u_turn_penalty(0), has_turn_penalty_function(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int traffic_signal_penalty;
|
|
||||||
int u_turn_penalty;
|
|
||||||
bool has_turn_penalty_function;
|
|
||||||
} speed_profile;
|
|
||||||
|
|
||||||
private:
|
|
||||||
using EdgeData = NodeBasedDynamicGraph::EdgeData;
|
|
||||||
|
|
||||||
unsigned m_number_of_edge_based_nodes;
|
|
||||||
|
|
||||||
std::vector<QueryNode> m_node_info_list;
|
|
||||||
std::vector<EdgeBasedNode> m_edge_based_node_list;
|
|
||||||
DeallocatingVector<EdgeBasedEdge> m_edge_based_edge_list;
|
|
||||||
|
|
||||||
std::shared_ptr<NodeBasedDynamicGraph> m_node_based_graph;
|
|
||||||
std::unordered_set<NodeID> m_barrier_nodes;
|
|
||||||
std::unordered_set<NodeID> m_traffic_lights;
|
|
||||||
|
|
||||||
std::unique_ptr<RestrictionMap> m_restriction_map;
|
|
||||||
|
|
||||||
GeometryCompressor m_geometry_compressor;
|
|
||||||
|
|
||||||
void CompressGeometry();
|
|
||||||
void RenumberEdges();
|
|
||||||
void GenerateEdgeExpandedNodes();
|
|
||||||
void GenerateEdgeExpandedEdges(const std::string &original_edge_data_filename,
|
|
||||||
lua_State *lua_state);
|
|
||||||
|
|
||||||
void InsertEdgeBasedNode(const NodeID u, const NodeID v, const unsigned component_id);
|
|
||||||
|
|
||||||
void FlushVectorToStream(std::ofstream &edge_data_file,
|
|
||||||
std::vector<OriginalEdgeData> &original_edge_data_vector) const;
|
|
||||||
|
|
||||||
NodeID max_id;
|
|
||||||
std::size_t removed_node_count;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* EDGE_BASED_GRAPH_FACTORY_HPP_ */
|
|
@ -1,236 +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 "geometry_compressor.hpp"
|
|
||||||
#include "../util/simple_logger.hpp"
|
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
#include <boost/filesystem/fstream.hpp>
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
GeometryCompressor::GeometryCompressor()
|
|
||||||
{
|
|
||||||
m_free_list.reserve(100);
|
|
||||||
IncreaseFreeList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeometryCompressor::IncreaseFreeList()
|
|
||||||
{
|
|
||||||
m_compressed_geometries.resize(m_compressed_geometries.size() + 100);
|
|
||||||
for (unsigned i = 100; i > 0; --i)
|
|
||||||
{
|
|
||||||
m_free_list.emplace_back(free_list_maximum);
|
|
||||||
++free_list_maximum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GeometryCompressor::HasEntryForID(const EdgeID edge_id) const
|
|
||||||
{
|
|
||||||
auto iter = m_edge_id_to_list_index_map.find(edge_id);
|
|
||||||
return iter != m_edge_id_to_list_index_map.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned GeometryCompressor::GetPositionForID(const EdgeID edge_id) const
|
|
||||||
{
|
|
||||||
auto map_iterator = m_edge_id_to_list_index_map.find(edge_id);
|
|
||||||
BOOST_ASSERT(map_iterator != m_edge_id_to_list_index_map.end());
|
|
||||||
BOOST_ASSERT(map_iterator->second < m_compressed_geometries.size());
|
|
||||||
return map_iterator->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeometryCompressor::SerializeInternalVector(const std::string &path) const
|
|
||||||
{
|
|
||||||
|
|
||||||
boost::filesystem::fstream geometry_out_stream(path, std::ios::binary | std::ios::out);
|
|
||||||
const unsigned compressed_geometries = m_compressed_geometries.size() + 1;
|
|
||||||
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != compressed_geometries);
|
|
||||||
geometry_out_stream.write((char *)&compressed_geometries, sizeof(unsigned));
|
|
||||||
|
|
||||||
// write indices array
|
|
||||||
unsigned prefix_sum_of_list_indices = 0;
|
|
||||||
for (const auto &elem : m_compressed_geometries)
|
|
||||||
{
|
|
||||||
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
|
|
||||||
|
|
||||||
const std::vector<CompressedNode> ¤t_vector = elem;
|
|
||||||
const unsigned unpacked_size = current_vector.size();
|
|
||||||
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != unpacked_size);
|
|
||||||
prefix_sum_of_list_indices += unpacked_size;
|
|
||||||
}
|
|
||||||
// sentinel element
|
|
||||||
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
|
|
||||||
|
|
||||||
// number of geometry entries to follow, it is the (inclusive) prefix sum
|
|
||||||
geometry_out_stream.write((char *)&prefix_sum_of_list_indices, sizeof(unsigned));
|
|
||||||
|
|
||||||
unsigned control_sum = 0;
|
|
||||||
// write compressed geometries
|
|
||||||
for (auto &elem : m_compressed_geometries)
|
|
||||||
{
|
|
||||||
const std::vector<CompressedNode> ¤t_vector = elem;
|
|
||||||
const unsigned unpacked_size = current_vector.size();
|
|
||||||
control_sum += unpacked_size;
|
|
||||||
BOOST_ASSERT(std::numeric_limits<unsigned>::max() != unpacked_size);
|
|
||||||
for (const CompressedNode current_node : current_vector)
|
|
||||||
{
|
|
||||||
geometry_out_stream.write((char *)&(current_node.first), sizeof(NodeID));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BOOST_ASSERT(control_sum == prefix_sum_of_list_indices);
|
|
||||||
// all done, let's close the resource
|
|
||||||
geometry_out_stream.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeometryCompressor::CompressEdge(const EdgeID edge_id_1,
|
|
||||||
const EdgeID edge_id_2,
|
|
||||||
const NodeID via_node_id,
|
|
||||||
const NodeID target_node_id,
|
|
||||||
const EdgeWeight weight1,
|
|
||||||
const EdgeWeight weight2)
|
|
||||||
{
|
|
||||||
// remove super-trivial geometries
|
|
||||||
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_1);
|
|
||||||
BOOST_ASSERT(SPECIAL_EDGEID != edge_id_2);
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != via_node_id);
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != target_node_id);
|
|
||||||
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight1);
|
|
||||||
BOOST_ASSERT(INVALID_EDGE_WEIGHT != weight2);
|
|
||||||
|
|
||||||
// append list of removed edge_id plus via node to surviving edge id:
|
|
||||||
// <surv_1, .. , surv_n, via_node_id, rem_1, .. rem_n
|
|
||||||
//
|
|
||||||
// General scheme:
|
|
||||||
// 1. append via node id to list of edge_id_1
|
|
||||||
// 2. find list for edge_id_2, if yes add all elements and delete it
|
|
||||||
|
|
||||||
// Add via node id. List is created if it does not exist
|
|
||||||
if (!HasEntryForID(edge_id_1))
|
|
||||||
{
|
|
||||||
// create a new entry in the map
|
|
||||||
if (0 == m_free_list.size())
|
|
||||||
{
|
|
||||||
// make sure there is a place to put the entries
|
|
||||||
IncreaseFreeList();
|
|
||||||
}
|
|
||||||
BOOST_ASSERT(!m_free_list.empty());
|
|
||||||
m_edge_id_to_list_index_map[edge_id_1] = m_free_list.back();
|
|
||||||
m_free_list.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// find bucket index
|
|
||||||
const auto iter = m_edge_id_to_list_index_map.find(edge_id_1);
|
|
||||||
BOOST_ASSERT(iter != m_edge_id_to_list_index_map.end());
|
|
||||||
const unsigned edge_bucket_id1 = iter->second;
|
|
||||||
BOOST_ASSERT(edge_bucket_id1 == GetPositionForID(edge_id_1));
|
|
||||||
BOOST_ASSERT(edge_bucket_id1 < m_compressed_geometries.size());
|
|
||||||
|
|
||||||
std::vector<CompressedNode> &edge_bucket_list1 = m_compressed_geometries[edge_bucket_id1];
|
|
||||||
|
|
||||||
if (edge_bucket_list1.empty())
|
|
||||||
{
|
|
||||||
edge_bucket_list1.emplace_back(via_node_id, weight1);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_ASSERT(0 < edge_bucket_list1.size());
|
|
||||||
BOOST_ASSERT(!edge_bucket_list1.empty());
|
|
||||||
|
|
||||||
if (HasEntryForID(edge_id_2))
|
|
||||||
{
|
|
||||||
// second edge is not atomic anymore
|
|
||||||
const unsigned list_to_remove_index = GetPositionForID(edge_id_2);
|
|
||||||
BOOST_ASSERT(list_to_remove_index < m_compressed_geometries.size());
|
|
||||||
|
|
||||||
std::vector<CompressedNode> &edge_bucket_list2 =
|
|
||||||
m_compressed_geometries[list_to_remove_index];
|
|
||||||
|
|
||||||
// found an existing list, append it to the list of edge_id_1
|
|
||||||
edge_bucket_list1.insert(edge_bucket_list1.end(), edge_bucket_list2.begin(),
|
|
||||||
edge_bucket_list2.end());
|
|
||||||
|
|
||||||
// remove the list of edge_id_2
|
|
||||||
m_edge_id_to_list_index_map.erase(edge_id_2);
|
|
||||||
BOOST_ASSERT(m_edge_id_to_list_index_map.end() ==
|
|
||||||
m_edge_id_to_list_index_map.find(edge_id_2));
|
|
||||||
edge_bucket_list2.clear();
|
|
||||||
BOOST_ASSERT(0 == edge_bucket_list2.size());
|
|
||||||
m_free_list.emplace_back(list_to_remove_index);
|
|
||||||
BOOST_ASSERT(list_to_remove_index == m_free_list.back());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// we are certain that the second edge is atomic.
|
|
||||||
edge_bucket_list1.emplace_back(target_node_id, weight2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GeometryCompressor::PrintStatistics() const
|
|
||||||
{
|
|
||||||
const uint64_t compressed_edges = m_compressed_geometries.size();
|
|
||||||
BOOST_ASSERT(0 == compressed_edges % 2);
|
|
||||||
BOOST_ASSERT(m_compressed_geometries.size() + m_free_list.size() > 0);
|
|
||||||
|
|
||||||
uint64_t compressed_geometries = 0;
|
|
||||||
uint64_t longest_chain_length = 0;
|
|
||||||
for (const std::vector<CompressedNode> ¤t_vector : m_compressed_geometries)
|
|
||||||
{
|
|
||||||
compressed_geometries += current_vector.size();
|
|
||||||
longest_chain_length = std::max(longest_chain_length, (uint64_t)current_vector.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Geometry successfully removed:"
|
|
||||||
"\n compressed edges: " << compressed_edges
|
|
||||||
<< "\n compressed geometries: " << compressed_geometries
|
|
||||||
<< "\n longest chain length: " << longest_chain_length
|
|
||||||
<< "\n cmpr ratio: " << ((float)compressed_edges /
|
|
||||||
std::max(compressed_geometries, (uint64_t)1))
|
|
||||||
<< "\n avg chain length: "
|
|
||||||
<< (float)compressed_geometries /
|
|
||||||
std::max((uint64_t)1, compressed_edges);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<GeometryCompressor::CompressedNode> &
|
|
||||||
GeometryCompressor::GetBucketReference(const EdgeID edge_id) const
|
|
||||||
{
|
|
||||||
const unsigned index = m_edge_id_to_list_index_map.at(edge_id);
|
|
||||||
return m_compressed_geometries.at(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeID GeometryCompressor::GetFirstNodeIDOfBucket(const EdgeID edge_id) const
|
|
||||||
{
|
|
||||||
const auto &bucket = GetBucketReference(edge_id);
|
|
||||||
BOOST_ASSERT(bucket.size() >= 2);
|
|
||||||
return bucket[1].first;
|
|
||||||
}
|
|
||||||
NodeID GeometryCompressor::GetLastNodeIDOfBucket(const EdgeID edge_id) const
|
|
||||||
{
|
|
||||||
const auto &bucket = GetBucketReference(edge_id);
|
|
||||||
BOOST_ASSERT(bucket.size() >= 2);
|
|
||||||
return bucket[bucket.size() - 2].first;
|
|
||||||
}
|
|
@ -1,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 GeometryCompressor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using CompressedNode = std::pair<NodeID, EdgeWeight>;
|
|
||||||
|
|
||||||
GeometryCompressor();
|
|
||||||
void CompressEdge(const EdgeID surviving_edge_id,
|
|
||||||
const EdgeID removed_edge_id,
|
|
||||||
const NodeID via_node_id,
|
|
||||||
const NodeID target_node,
|
|
||||||
const EdgeWeight weight1,
|
|
||||||
const EdgeWeight weight2);
|
|
||||||
|
|
||||||
bool HasEntryForID(const EdgeID edge_id) const;
|
|
||||||
void PrintStatistics() const;
|
|
||||||
void SerializeInternalVector(const std::string &path) const;
|
|
||||||
unsigned GetPositionForID(const EdgeID edge_id) const;
|
|
||||||
const std::vector<GeometryCompressor::CompressedNode> &
|
|
||||||
GetBucketReference(const EdgeID edge_id) const;
|
|
||||||
NodeID GetFirstNodeIDOfBucket(const EdgeID edge_id) const;
|
|
||||||
NodeID GetLastNodeIDOfBucket(const EdgeID edge_id) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
int free_list_maximum = 0;
|
|
||||||
|
|
||||||
void IncreaseFreeList();
|
|
||||||
std::vector<std::vector<CompressedNode>> m_compressed_geometries;
|
|
||||||
std::vector<unsigned> m_free_list;
|
|
||||||
std::unordered_map<EdgeID, unsigned> m_edge_id_to_list_index_map;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // GEOMETRY_COMPRESSOR_HPP_
|
|
@ -1,567 +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/crc32_processor.hpp"
|
|
||||||
#include "../data_structures/deallocating_vector.hpp"
|
|
||||||
#include "../data_structures/static_rtree.hpp"
|
|
||||||
#include "../data_structures/restriction_map.hpp"
|
|
||||||
|
|
||||||
#include "../util/git_sha.hpp"
|
|
||||||
#include "../util/graph_loader.hpp"
|
|
||||||
#include "../util/integer_range.hpp"
|
|
||||||
#include "../util/lua_util.hpp"
|
|
||||||
#include "../util/make_unique.hpp"
|
|
||||||
#include "../util/osrm_exception.hpp"
|
|
||||||
#include "../util/simple_logger.hpp"
|
|
||||||
#include "../util/string_util.hpp"
|
|
||||||
#include "../util/timing_util.hpp"
|
|
||||||
#include "../typedefs.h"
|
|
||||||
|
|
||||||
#include <boost/filesystem/fstream.hpp>
|
|
||||||
#include <boost/program_options.hpp>
|
|
||||||
|
|
||||||
#include <tbb/task_scheduler_init.h>
|
|
||||||
#include <tbb/parallel_sort.h>
|
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <thread>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
Prepare::Prepare() : requested_num_threads(1) {}
|
|
||||||
|
|
||||||
Prepare::~Prepare() {}
|
|
||||||
|
|
||||||
int Prepare::Process(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
LogPolicy::GetInstance().Unmute();
|
|
||||||
TIMER_START(preparing);
|
|
||||||
TIMER_START(expansion);
|
|
||||||
|
|
||||||
if (!ParseArguments(argc, argv))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!boost::filesystem::is_regular_file(input_path))
|
|
||||||
{
|
|
||||||
SimpleLogger().Write(logWARNING) << "Input file " << input_path.string() << " not found!";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!boost::filesystem::is_regular_file(profile_path))
|
|
||||||
{
|
|
||||||
SimpleLogger().Write(logWARNING) << "Profile " << profile_path.string() << " not found!";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (1 > requested_num_threads)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned recommended_num_threads = tbb::task_scheduler_init::default_num_threads();
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Input file: " << input_path.filename().string();
|
|
||||||
SimpleLogger().Write() << "Restrictions file: " << restrictions_path.filename().string();
|
|
||||||
SimpleLogger().Write() << "Profile: " << profile_path.filename().string();
|
|
||||||
SimpleLogger().Write() << "Threads: " << requested_num_threads;
|
|
||||||
if (recommended_num_threads != requested_num_threads)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write(logWARNING) << "The recommended number of threads is "
|
|
||||||
<< recommended_num_threads
|
|
||||||
<< "! This setting may have performance side-effects.";
|
|
||||||
}
|
|
||||||
|
|
||||||
tbb::task_scheduler_init init(requested_num_threads);
|
|
||||||
|
|
||||||
LogPolicy::GetInstance().Unmute();
|
|
||||||
|
|
||||||
FingerPrint fingerprint_orig;
|
|
||||||
CheckRestrictionsFile(fingerprint_orig);
|
|
||||||
|
|
||||||
boost::filesystem::ifstream input_stream(input_path, std::ios::in | std::ios::binary);
|
|
||||||
|
|
||||||
node_filename = input_path.string() + ".nodes";
|
|
||||||
edge_out = input_path.string() + ".edges";
|
|
||||||
geometry_filename = input_path.string() + ".geometry";
|
|
||||||
graph_out = input_path.string() + ".hsgr";
|
|
||||||
rtree_nodes_path = input_path.string() + ".ramIndex";
|
|
||||||
rtree_leafs_path = input_path.string() + ".fileIndex";
|
|
||||||
|
|
||||||
/*** Setup Scripting Environment ***/
|
|
||||||
// Create a new lua state
|
|
||||||
lua_State *lua_state = luaL_newstate();
|
|
||||||
|
|
||||||
// Connect LuaBind to this lua state
|
|
||||||
luabind::open(lua_state);
|
|
||||||
|
|
||||||
EdgeBasedGraphFactory::SpeedProfileProperties speed_profile;
|
|
||||||
|
|
||||||
if (!SetupScriptingEnvironment(lua_state, speed_profile))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#pragma message("Memory consumption on Windows can be higher due to different bit packing")
|
|
||||||
#else
|
|
||||||
static_assert(sizeof(ImportEdge) == 20,
|
|
||||||
"changing ImportEdge type has influence on memory consumption!");
|
|
||||||
#endif
|
|
||||||
NodeID number_of_node_based_nodes = readBinaryOSRMGraphFromStream(
|
|
||||||
input_stream, edge_list, barrier_node_list, traffic_light_list,
|
|
||||||
&internal_to_external_node_map, restriction_list);
|
|
||||||
input_stream.close();
|
|
||||||
|
|
||||||
if (edge_list.empty())
|
|
||||||
{
|
|
||||||
SimpleLogger().Write(logWARNING) << "The input data is empty, exiting.";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleLogger().Write() << restriction_list.size() << " restrictions, "
|
|
||||||
<< barrier_node_list.size() << " bollard nodes, "
|
|
||||||
<< traffic_light_list.size() << " traffic lights";
|
|
||||||
|
|
||||||
std::vector<EdgeBasedNode> node_based_edge_list;
|
|
||||||
unsigned number_of_edge_based_nodes = 0;
|
|
||||||
DeallocatingVector<EdgeBasedEdge> edge_based_edge_list;
|
|
||||||
|
|
||||||
// init node_based_edge_list, edge_based_edge_list by edgeList
|
|
||||||
number_of_edge_based_nodes =
|
|
||||||
BuildEdgeExpandedGraph(lua_state, number_of_node_based_nodes, node_based_edge_list,
|
|
||||||
edge_based_edge_list, speed_profile);
|
|
||||||
lua_close(lua_state);
|
|
||||||
|
|
||||||
TIMER_STOP(expansion);
|
|
||||||
|
|
||||||
BuildRTree(node_based_edge_list);
|
|
||||||
|
|
||||||
RangebasedCRC32 crc32;
|
|
||||||
if (crc32.using_hardware())
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "using hardware based CRC32 computation";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "using software based CRC32 computation";
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned crc32_value = crc32(node_based_edge_list);
|
|
||||||
node_based_edge_list.clear();
|
|
||||||
node_based_edge_list.shrink_to_fit();
|
|
||||||
SimpleLogger().Write() << "CRC32: " << crc32_value;
|
|
||||||
|
|
||||||
WriteNodeMapping();
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Contracting the edge-expanded graph
|
|
||||||
*/
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "initializing contractor";
|
|
||||||
auto contractor =
|
|
||||||
osrm::make_unique<Contractor>(number_of_edge_based_nodes, edge_based_edge_list);
|
|
||||||
|
|
||||||
TIMER_START(contraction);
|
|
||||||
contractor->Run();
|
|
||||||
TIMER_STOP(contraction);
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Contraction took " << TIMER_SEC(contraction) << " sec";
|
|
||||||
|
|
||||||
DeallocatingVector<QueryEdge> contracted_edge_list;
|
|
||||||
contractor->GetEdges(contracted_edge_list);
|
|
||||||
contractor.reset();
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Sorting contracted edges in a way that the static query graph can read some in in-place.
|
|
||||||
*/
|
|
||||||
|
|
||||||
tbb::parallel_sort(contracted_edge_list.begin(), contracted_edge_list.end());
|
|
||||||
const unsigned contracted_edge_count = contracted_edge_list.size();
|
|
||||||
SimpleLogger().Write() << "Serializing compacted graph of " << contracted_edge_count
|
|
||||||
<< " edges";
|
|
||||||
|
|
||||||
boost::filesystem::ofstream hsgr_output_stream(graph_out, std::ios::binary);
|
|
||||||
hsgr_output_stream.write((char *)&fingerprint_orig, sizeof(FingerPrint));
|
|
||||||
const unsigned max_used_node_id = 1 + [&contracted_edge_list]
|
|
||||||
{
|
|
||||||
unsigned tmp_max = 0;
|
|
||||||
for (const QueryEdge &edge : contracted_edge_list)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != edge.source);
|
|
||||||
BOOST_ASSERT(SPECIAL_NODEID != edge.target);
|
|
||||||
tmp_max = std::max(tmp_max, edge.source);
|
|
||||||
tmp_max = std::max(tmp_max, edge.target);
|
|
||||||
}
|
|
||||||
return tmp_max;
|
|
||||||
}();
|
|
||||||
|
|
||||||
SimpleLogger().Write(logDEBUG) << "input graph has " << number_of_edge_based_nodes << " nodes";
|
|
||||||
SimpleLogger().Write(logDEBUG) << "contracted graph has " << max_used_node_id << " nodes";
|
|
||||||
|
|
||||||
std::vector<StaticGraph<EdgeData>::NodeArrayEntry> node_array;
|
|
||||||
node_array.resize(number_of_edge_based_nodes + 1);
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Building node array";
|
|
||||||
StaticGraph<EdgeData>::EdgeIterator edge = 0;
|
|
||||||
StaticGraph<EdgeData>::EdgeIterator position = 0;
|
|
||||||
StaticGraph<EdgeData>::EdgeIterator last_edge = edge;
|
|
||||||
|
|
||||||
// initializing 'first_edge'-field of nodes:
|
|
||||||
for (const auto node : osrm::irange(0u, max_used_node_id))
|
|
||||||
{
|
|
||||||
last_edge = edge;
|
|
||||||
while ((edge < contracted_edge_count) && (contracted_edge_list[edge].source == node))
|
|
||||||
{
|
|
||||||
++edge;
|
|
||||||
}
|
|
||||||
node_array[node].first_edge = position; //=edge
|
|
||||||
position += edge - last_edge; // remove
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto sentinel_counter : osrm::irange<unsigned>(max_used_node_id, node_array.size()))
|
|
||||||
{
|
|
||||||
// sentinel element, guarded against underflow
|
|
||||||
node_array[sentinel_counter].first_edge = contracted_edge_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Serializing node array";
|
|
||||||
|
|
||||||
const unsigned node_array_size = node_array.size();
|
|
||||||
// serialize crc32, aka checksum
|
|
||||||
hsgr_output_stream.write((char *)&crc32_value, sizeof(unsigned));
|
|
||||||
// serialize number of nodes
|
|
||||||
hsgr_output_stream.write((char *)&node_array_size, sizeof(unsigned));
|
|
||||||
// serialize number of edges
|
|
||||||
hsgr_output_stream.write((char *)&contracted_edge_count, sizeof(unsigned));
|
|
||||||
// serialize all nodes
|
|
||||||
if (node_array_size > 0)
|
|
||||||
{
|
|
||||||
hsgr_output_stream.write((char *)&node_array[0],
|
|
||||||
sizeof(StaticGraph<EdgeData>::NodeArrayEntry) * node_array_size);
|
|
||||||
}
|
|
||||||
// serialize all edges
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Building edge array";
|
|
||||||
edge = 0;
|
|
||||||
int number_of_used_edges = 0;
|
|
||||||
|
|
||||||
StaticGraph<EdgeData>::EdgeArrayEntry current_edge;
|
|
||||||
for (const auto edge : osrm::irange<std::size_t>(0, contracted_edge_list.size()))
|
|
||||||
{
|
|
||||||
// no eigen loops
|
|
||||||
BOOST_ASSERT(contracted_edge_list[edge].source != contracted_edge_list[edge].target);
|
|
||||||
current_edge.target = contracted_edge_list[edge].target;
|
|
||||||
current_edge.data = contracted_edge_list[edge].data;
|
|
||||||
|
|
||||||
// every target needs to be valid
|
|
||||||
BOOST_ASSERT(current_edge.target < max_used_node_id);
|
|
||||||
#ifndef NDEBUG
|
|
||||||
if (current_edge.data.distance <= 0)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write(logWARNING) << "Edge: " << edge
|
|
||||||
<< ",source: " << contracted_edge_list[edge].source
|
|
||||||
<< ", target: " << contracted_edge_list[edge].target
|
|
||||||
<< ", dist: " << current_edge.data.distance;
|
|
||||||
|
|
||||||
SimpleLogger().Write(logWARNING) << "Failed at adjacency list of node "
|
|
||||||
<< contracted_edge_list[edge].source << "/"
|
|
||||||
<< node_array.size() - 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
hsgr_output_stream.write((char *)¤t_edge,
|
|
||||||
sizeof(StaticGraph<EdgeData>::EdgeArrayEntry));
|
|
||||||
|
|
||||||
++number_of_used_edges;
|
|
||||||
}
|
|
||||||
hsgr_output_stream.close();
|
|
||||||
|
|
||||||
TIMER_STOP(preparing);
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Preprocessing : " << TIMER_SEC(preparing) << " seconds";
|
|
||||||
SimpleLogger().Write() << "Expansion : " << (number_of_node_based_nodes / TIMER_SEC(expansion))
|
|
||||||
<< " nodes/sec and "
|
|
||||||
<< (number_of_edge_based_nodes / TIMER_SEC(expansion)) << " edges/sec";
|
|
||||||
|
|
||||||
SimpleLogger().Write() << "Contraction: "
|
|
||||||
<< (number_of_edge_based_nodes / TIMER_SEC(contraction))
|
|
||||||
<< " nodes/sec and " << number_of_used_edges / TIMER_SEC(contraction)
|
|
||||||
<< " edges/sec";
|
|
||||||
|
|
||||||
node_array.clear();
|
|
||||||
SimpleLogger().Write() << "finished preprocessing";
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Parses command line arguments
|
|
||||||
\param argc count of arguments
|
|
||||||
\param argv array of arguments
|
|
||||||
\param result [out] value for exit return value
|
|
||||||
\return true if everything is ok, false if need to terminate execution
|
|
||||||
*/
|
|
||||||
bool Prepare::ParseArguments(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
// declare a group of options that will be allowed only on command line
|
|
||||||
boost::program_options::options_description generic_options("Options");
|
|
||||||
generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
|
|
||||||
"config,c", boost::program_options::value<boost::filesystem::path>(&config_file_path)
|
|
||||||
->default_value("contractor.ini"),
|
|
||||||
"Path to a configuration file.");
|
|
||||||
|
|
||||||
// declare a group of options that will be allowed both on command line and in config file
|
|
||||||
boost::program_options::options_description config_options("Configuration");
|
|
||||||
config_options.add_options()(
|
|
||||||
"restrictions,r",
|
|
||||||
boost::program_options::value<boost::filesystem::path>(&restrictions_path),
|
|
||||||
"Restrictions file in .osrm.restrictions format")(
|
|
||||||
"profile,p", boost::program_options::value<boost::filesystem::path>(&profile_path)
|
|
||||||
->default_value("profile.lua"),
|
|
||||||
"Path to LUA routing profile")(
|
|
||||||
"threads,t", boost::program_options::value<unsigned int>(&requested_num_threads)
|
|
||||||
->default_value(tbb::task_scheduler_init::default_num_threads()),
|
|
||||||
"Number of threads to use");
|
|
||||||
|
|
||||||
// hidden options, will be allowed both on command line and in config file, but will not be
|
|
||||||
// shown to the user
|
|
||||||
boost::program_options::options_description hidden_options("Hidden options");
|
|
||||||
hidden_options.add_options()(
|
|
||||||
"input,i", boost::program_options::value<boost::filesystem::path>(&input_path),
|
|
||||||
"Input file in .osm, .osm.bz2 or .osm.pbf format");
|
|
||||||
|
|
||||||
// positional option
|
|
||||||
boost::program_options::positional_options_description positional_options;
|
|
||||||
positional_options.add("input", 1);
|
|
||||||
|
|
||||||
// combine above options for parsing
|
|
||||||
boost::program_options::options_description cmdline_options;
|
|
||||||
cmdline_options.add(generic_options).add(config_options).add(hidden_options);
|
|
||||||
|
|
||||||
boost::program_options::options_description config_file_options;
|
|
||||||
config_file_options.add(config_options).add(hidden_options);
|
|
||||||
|
|
||||||
boost::program_options::options_description visible_options(
|
|
||||||
"Usage: " + boost::filesystem::basename(argv[0]) + " <input.osrm> [options]");
|
|
||||||
visible_options.add(generic_options).add(config_options);
|
|
||||||
|
|
||||||
// parse command line options
|
|
||||||
boost::program_options::variables_map option_variables;
|
|
||||||
boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
|
|
||||||
.options(cmdline_options)
|
|
||||||
.positional(positional_options)
|
|
||||||
.run(),
|
|
||||||
option_variables);
|
|
||||||
|
|
||||||
const auto &temp_config_path = option_variables["config"].as<boost::filesystem::path>();
|
|
||||||
if (boost::filesystem::is_regular_file(temp_config_path))
|
|
||||||
{
|
|
||||||
boost::program_options::store(boost::program_options::parse_config_file<char>(
|
|
||||||
temp_config_path.string().c_str(), cmdline_options, true),
|
|
||||||
option_variables);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (option_variables.count("version"))
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << g_GIT_DESCRIPTION;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (option_variables.count("help"))
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "\n" << visible_options;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::program_options::notify(option_variables);
|
|
||||||
|
|
||||||
if (!option_variables.count("restrictions"))
|
|
||||||
{
|
|
||||||
restrictions_path = std::string(input_path.string() + ".restrictions");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!option_variables.count("input"))
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "\n" << visible_options;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Loads and checks file UUIDs
|
|
||||||
*/
|
|
||||||
void Prepare::CheckRestrictionsFile(FingerPrint &fingerprint_orig)
|
|
||||||
{
|
|
||||||
boost::filesystem::ifstream restriction_stream(restrictions_path, std::ios::binary);
|
|
||||||
FingerPrint fingerprint_loaded;
|
|
||||||
unsigned number_of_usable_restrictions = 0;
|
|
||||||
restriction_stream.read((char *)&fingerprint_loaded, sizeof(FingerPrint));
|
|
||||||
if (!fingerprint_loaded.TestPrepare(fingerprint_orig))
|
|
||||||
{
|
|
||||||
SimpleLogger().Write(logWARNING) << ".restrictions was prepared with different build.\n"
|
|
||||||
"Reprocess to get rid of this warning.";
|
|
||||||
}
|
|
||||||
|
|
||||||
restriction_stream.read((char *)&number_of_usable_restrictions, sizeof(unsigned));
|
|
||||||
restriction_list.resize(number_of_usable_restrictions);
|
|
||||||
if (number_of_usable_restrictions > 0)
|
|
||||||
{
|
|
||||||
restriction_stream.read((char *)&(restriction_list[0]),
|
|
||||||
number_of_usable_restrictions * sizeof(TurnRestriction));
|
|
||||||
}
|
|
||||||
restriction_stream.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Setups scripting environment (lua-scripting)
|
|
||||||
Also initializes speed profile.
|
|
||||||
*/
|
|
||||||
bool Prepare::SetupScriptingEnvironment(
|
|
||||||
lua_State *lua_state, EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
|
|
||||||
{
|
|
||||||
// open utility libraries string library;
|
|
||||||
luaL_openlibs(lua_state);
|
|
||||||
|
|
||||||
// adjust lua load path
|
|
||||||
luaAddScriptFolderToLoadPath(lua_state, profile_path.string().c_str());
|
|
||||||
|
|
||||||
// Now call our function in a lua script
|
|
||||||
if (0 != luaL_dofile(lua_state, profile_path.string().c_str()))
|
|
||||||
{
|
|
||||||
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 != luaL_dostring(lua_state, "return traffic_signal_penalty\n"))
|
|
||||||
{
|
|
||||||
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
speed_profile.traffic_signal_penalty = 10 * lua_tointeger(lua_state, -1);
|
|
||||||
SimpleLogger().Write(logDEBUG)
|
|
||||||
<< "traffic_signal_penalty: " << speed_profile.traffic_signal_penalty;
|
|
||||||
|
|
||||||
if (0 != luaL_dostring(lua_state, "return u_turn_penalty\n"))
|
|
||||||
{
|
|
||||||
std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
speed_profile.u_turn_penalty = 10 * lua_tointeger(lua_state, -1);
|
|
||||||
speed_profile.has_turn_penalty_function = lua_function_exists(lua_state, "turn_function");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Building an edge-expanded graph from node-based input and turn restrictions
|
|
||||||
*/
|
|
||||||
std::size_t
|
|
||||||
Prepare::BuildEdgeExpandedGraph(lua_State *lua_state,
|
|
||||||
NodeID number_of_node_based_nodes,
|
|
||||||
std::vector<EdgeBasedNode> &node_based_edge_list,
|
|
||||||
DeallocatingVector<EdgeBasedEdge> &edge_based_edge_list,
|
|
||||||
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "Generating edge-expanded graph representation";
|
|
||||||
std::shared_ptr<NodeBasedDynamicGraph> node_based_graph =
|
|
||||||
NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list);
|
|
||||||
std::unique_ptr<RestrictionMap> restriction_map =
|
|
||||||
osrm::make_unique<RestrictionMap>(restriction_list);
|
|
||||||
std::shared_ptr<EdgeBasedGraphFactory> edge_based_graph_factory =
|
|
||||||
std::make_shared<EdgeBasedGraphFactory>(node_based_graph, std::move(restriction_map),
|
|
||||||
barrier_node_list, traffic_light_list,
|
|
||||||
internal_to_external_node_map, speed_profile);
|
|
||||||
edge_list.clear();
|
|
||||||
edge_list.shrink_to_fit();
|
|
||||||
|
|
||||||
edge_based_graph_factory->Run(edge_out, geometry_filename, lua_state);
|
|
||||||
|
|
||||||
restriction_list.clear();
|
|
||||||
restriction_list.shrink_to_fit();
|
|
||||||
barrier_node_list.clear();
|
|
||||||
barrier_node_list.shrink_to_fit();
|
|
||||||
traffic_light_list.clear();
|
|
||||||
traffic_light_list.shrink_to_fit();
|
|
||||||
|
|
||||||
const std::size_t number_of_edge_based_nodes =
|
|
||||||
edge_based_graph_factory->GetNumberOfEdgeBasedNodes();
|
|
||||||
|
|
||||||
BOOST_ASSERT(number_of_edge_based_nodes != std::numeric_limits<unsigned>::max());
|
|
||||||
#ifndef WIN32
|
|
||||||
static_assert(sizeof(EdgeBasedEdge) == 16,
|
|
||||||
"changing ImportEdge type has influence on memory consumption!");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
edge_based_graph_factory->GetEdgeBasedEdges(edge_based_edge_list);
|
|
||||||
edge_based_graph_factory->GetEdgeBasedNodes(node_based_edge_list);
|
|
||||||
|
|
||||||
edge_based_graph_factory.reset();
|
|
||||||
node_based_graph.reset();
|
|
||||||
|
|
||||||
return number_of_edge_based_nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Writing info on original (node-based) nodes
|
|
||||||
*/
|
|
||||||
void Prepare::WriteNodeMapping()
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "writing node map ...";
|
|
||||||
boost::filesystem::ofstream node_stream(node_filename, std::ios::binary);
|
|
||||||
const unsigned size_of_mapping = internal_to_external_node_map.size();
|
|
||||||
node_stream.write((char *)&size_of_mapping, sizeof(unsigned));
|
|
||||||
if (size_of_mapping > 0)
|
|
||||||
{
|
|
||||||
node_stream.write((char *)&(internal_to_external_node_map[0]),
|
|
||||||
size_of_mapping * sizeof(QueryNode));
|
|
||||||
}
|
|
||||||
node_stream.close();
|
|
||||||
internal_to_external_node_map.clear();
|
|
||||||
internal_to_external_node_map.shrink_to_fit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Building rtree-based nearest-neighbor data structure
|
|
||||||
|
|
||||||
Saves info to files: '.ramIndex' and '.fileIndex'.
|
|
||||||
*/
|
|
||||||
void Prepare::BuildRTree(std::vector<EdgeBasedNode> &node_based_edge_list)
|
|
||||||
{
|
|
||||||
SimpleLogger().Write() << "building r-tree ...";
|
|
||||||
StaticRTree<EdgeBasedNode>(node_based_edge_list, rtree_nodes_path.c_str(),
|
|
||||||
rtree_leafs_path.c_str(), internal_to_external_node_map);
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2014, Project OSRM, Dennis Luxen, others
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright notice, this list
|
|
||||||
of conditions and the following disclaimer.
|
|
||||||
Redistributions in binary form must reproduce the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer in the documentation and/or
|
|
||||||
other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PROCESSING_CHAIN_HPP
|
|
||||||
#define PROCESSING_CHAIN_HPP
|
|
||||||
|
|
||||||
#include "edge_based_graph_factory.hpp"
|
|
||||||
#include "../data_structures/query_edge.hpp"
|
|
||||||
#include "../data_structures/static_graph.hpp"
|
|
||||||
|
|
||||||
class FingerPrint;
|
|
||||||
struct EdgeBasedNode;
|
|
||||||
struct lua_State;
|
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief class of 'prepare' utility.
|
|
||||||
*/
|
|
||||||
class Prepare
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using EdgeData = QueryEdge::EdgeData;
|
|
||||||
using InputEdge = DynamicGraph<EdgeData>::InputEdge;
|
|
||||||
using StaticEdge = StaticGraph<EdgeData>::InputEdge;
|
|
||||||
|
|
||||||
explicit Prepare();
|
|
||||||
Prepare(const Prepare &) = delete;
|
|
||||||
~Prepare();
|
|
||||||
|
|
||||||
int Process(int argc, char *argv[]);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool ParseArguments(int argc, char *argv[]);
|
|
||||||
void CheckRestrictionsFile(FingerPrint &fingerprint_orig);
|
|
||||||
bool SetupScriptingEnvironment(lua_State *myLuaState,
|
|
||||||
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile);
|
|
||||||
std::size_t BuildEdgeExpandedGraph(lua_State *myLuaState,
|
|
||||||
NodeID nodeBasedNodeNumber,
|
|
||||||
std::vector<EdgeBasedNode> &nodeBasedEdgeList,
|
|
||||||
DeallocatingVector<EdgeBasedEdge> &edgeBasedEdgeList,
|
|
||||||
EdgeBasedGraphFactory::SpeedProfileProperties &speed_profile);
|
|
||||||
void WriteNodeMapping();
|
|
||||||
void BuildRTree(std::vector<EdgeBasedNode> &node_based_edge_list);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<QueryNode> internal_to_external_node_map;
|
|
||||||
std::vector<TurnRestriction> restriction_list;
|
|
||||||
std::vector<NodeID> barrier_node_list;
|
|
||||||
std::vector<NodeID> traffic_light_list;
|
|
||||||
std::vector<ImportEdge> edge_list;
|
|
||||||
|
|
||||||
unsigned requested_num_threads;
|
|
||||||
boost::filesystem::path config_file_path;
|
|
||||||
boost::filesystem::path input_path;
|
|
||||||
boost::filesystem::path restrictions_path;
|
|
||||||
boost::filesystem::path preinfo_path;
|
|
||||||
boost::filesystem::path profile_path;
|
|
||||||
|
|
||||||
std::string node_filename;
|
|
||||||
std::string edge_out;
|
|
||||||
std::string info_out;
|
|
||||||
std::string geometry_filename;
|
|
||||||
std::string graph_out;
|
|
||||||
std::string rtree_nodes_path;
|
|
||||||
std::string rtree_leafs_path;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PROCESSING_CHAIN_HPP
|
|
7
cucumber.js
Normal file
7
cucumber.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
module.exports = {
|
||||||
|
default: '--strict --tags ~@stress --tags ~@todo --tags ~@mld --require features/support --require features/step_definitions',
|
||||||
|
ch: '--strict --tags ~@stress --tags ~@todo --tags ~@mld -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',
|
||||||
|
mld: '--strict --tags ~@stress --tags ~@todo --tags ~@ch --require features/support --require features/step_definitions -f progress'
|
||||||
|
};
|
3160
data/driving_side.geojson
Normal file
3160
data/driving_side.geojson
Normal file
File diff suppressed because it is too large
Load Diff
5573
data/maxheight.geojson
Normal file
5573
data/maxheight.geojson
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,308 +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 BINARY_HEAP_H
|
|
||||||
#define BINARY_HEAP_H
|
|
||||||
|
|
||||||
#include <boost/assert.hpp>
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <limits>
|
|
||||||
#include <map>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
template <typename NodeID, typename Key> class ArrayStorage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit ArrayStorage(size_t size) : positions(size, 0) {}
|
|
||||||
|
|
||||||
~ArrayStorage() {}
|
|
||||||
|
|
||||||
Key &operator[](NodeID node) { return positions[node]; }
|
|
||||||
|
|
||||||
Key peek_index(const NodeID node) const { return positions[node]; }
|
|
||||||
|
|
||||||
void Clear() {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<Key> positions;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename NodeID, typename Key> class MapStorage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit MapStorage(size_t) {}
|
|
||||||
|
|
||||||
Key &operator[](NodeID node) { return nodes[node]; }
|
|
||||||
|
|
||||||
void Clear() { nodes.clear(); }
|
|
||||||
|
|
||||||
Key peek_index(const NodeID node) const
|
|
||||||
{
|
|
||||||
const auto iter = nodes.find(node);
|
|
||||||
if (nodes.end() != iter)
|
|
||||||
{
|
|
||||||
return iter->second;
|
|
||||||
}
|
|
||||||
return std::numeric_limits<Key>::max();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::map<NodeID, Key> nodes;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename NodeID, typename Key> class UnorderedMapStorage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit UnorderedMapStorage(size_t) { nodes.rehash(1000); }
|
|
||||||
|
|
||||||
Key &operator[](const NodeID node) { return nodes[node]; }
|
|
||||||
|
|
||||||
Key peek_index(const NodeID node) const
|
|
||||||
{
|
|
||||||
const auto iter = nodes.find(node);
|
|
||||||
if (std::end(nodes) != iter)
|
|
||||||
{
|
|
||||||
return iter->second;
|
|
||||||
}
|
|
||||||
return std::numeric_limits<Key>::max();
|
|
||||||
}
|
|
||||||
|
|
||||||
Key const &operator[](const NodeID node) const
|
|
||||||
{
|
|
||||||
auto iter = nodes.find(node);
|
|
||||||
return iter->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Clear() { nodes.clear(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unordered_map<NodeID, Key> nodes;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename NodeID,
|
|
||||||
typename Key,
|
|
||||||
typename Weight,
|
|
||||||
typename Data,
|
|
||||||
typename IndexStorage = ArrayStorage<NodeID, NodeID>>
|
|
||||||
class BinaryHeap
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
BinaryHeap(const BinaryHeap &right);
|
|
||||||
void operator=(const BinaryHeap &right);
|
|
||||||
|
|
||||||
public:
|
|
||||||
using WeightType = Weight;
|
|
||||||
using DataType = Data;
|
|
||||||
|
|
||||||
explicit BinaryHeap(size_t maxID) : node_index(maxID) { Clear(); }
|
|
||||||
|
|
||||||
void Clear()
|
|
||||||
{
|
|
||||||
heap.resize(1);
|
|
||||||
inserted_nodes.clear();
|
|
||||||
heap[0].weight = std::numeric_limits<Weight>::min();
|
|
||||||
node_index.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t Size() const { return (heap.size() - 1); }
|
|
||||||
|
|
||||||
bool Empty() const { return 0 == Size(); }
|
|
||||||
|
|
||||||
void Insert(NodeID node, Weight weight, const Data &data)
|
|
||||||
{
|
|
||||||
HeapElement element;
|
|
||||||
element.index = static_cast<NodeID>(inserted_nodes.size());
|
|
||||||
element.weight = weight;
|
|
||||||
const Key key = static_cast<Key>(heap.size());
|
|
||||||
heap.emplace_back(element);
|
|
||||||
inserted_nodes.emplace_back(node, key, weight, data);
|
|
||||||
node_index[node] = element.index;
|
|
||||||
Upheap(key);
|
|
||||||
CheckHeap();
|
|
||||||
}
|
|
||||||
|
|
||||||
Data &GetData(NodeID node)
|
|
||||||
{
|
|
||||||
const Key index = node_index.peek_index(node);
|
|
||||||
return inserted_nodes[index].data;
|
|
||||||
}
|
|
||||||
|
|
||||||
Data const &GetData(NodeID node) const
|
|
||||||
{
|
|
||||||
const Key index = node_index.peek_index(node);
|
|
||||||
return inserted_nodes[index].data;
|
|
||||||
}
|
|
||||||
|
|
||||||
Weight &GetKey(NodeID node)
|
|
||||||
{
|
|
||||||
const Key index = node_index[node];
|
|
||||||
return inserted_nodes[index].weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WasRemoved(const NodeID node) const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(WasInserted(node));
|
|
||||||
const Key index = node_index.peek_index(node);
|
|
||||||
return inserted_nodes[index].key == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WasInserted(const NodeID node) const
|
|
||||||
{
|
|
||||||
const auto index = node_index.peek_index(node);
|
|
||||||
if (index >= static_cast<decltype(index)>(inserted_nodes.size()))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return inserted_nodes[index].node == node;
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeID Min() const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(heap.size() > 1);
|
|
||||||
return inserted_nodes[heap[1].index].node;
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeID DeleteMin()
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(heap.size() > 1);
|
|
||||||
const Key removedIndex = heap[1].index;
|
|
||||||
heap[1] = heap[heap.size() - 1];
|
|
||||||
heap.pop_back();
|
|
||||||
if (heap.size() > 1)
|
|
||||||
{
|
|
||||||
Downheap(1);
|
|
||||||
}
|
|
||||||
inserted_nodes[removedIndex].key = 0;
|
|
||||||
CheckHeap();
|
|
||||||
return inserted_nodes[removedIndex].node;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeleteAll()
|
|
||||||
{
|
|
||||||
auto iend = heap.end();
|
|
||||||
for (typename std::vector<HeapElement>::iterator i = heap.begin() + 1; i != iend; ++i)
|
|
||||||
{
|
|
||||||
inserted_nodes[i->index].key = 0;
|
|
||||||
}
|
|
||||||
heap.resize(1);
|
|
||||||
heap[0].weight = (std::numeric_limits<Weight>::min)();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecreaseKey(NodeID node, Weight weight)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(std::numeric_limits<NodeID>::max() != node);
|
|
||||||
const Key &index = node_index.peek_index(node);
|
|
||||||
Key &key = inserted_nodes[index].key;
|
|
||||||
BOOST_ASSERT(key >= 0);
|
|
||||||
|
|
||||||
inserted_nodes[index].weight = weight;
|
|
||||||
heap[key].weight = weight;
|
|
||||||
Upheap(key);
|
|
||||||
CheckHeap();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
class HeapNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
HeapNode(NodeID n, Key k, Weight w, Data d) : node(n), key(k), weight(w), data(d) {}
|
|
||||||
|
|
||||||
NodeID node;
|
|
||||||
Key key;
|
|
||||||
Weight weight;
|
|
||||||
Data data;
|
|
||||||
};
|
|
||||||
struct HeapElement
|
|
||||||
{
|
|
||||||
Key index;
|
|
||||||
Weight weight;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<HeapNode> inserted_nodes;
|
|
||||||
std::vector<HeapElement> heap;
|
|
||||||
IndexStorage node_index;
|
|
||||||
|
|
||||||
void Downheap(Key key)
|
|
||||||
{
|
|
||||||
const Key droppingIndex = heap[key].index;
|
|
||||||
const Weight weight = heap[key].weight;
|
|
||||||
const Key heap_size = static_cast<Key>(heap.size());
|
|
||||||
Key nextKey = key << 1;
|
|
||||||
while (nextKey < heap_size)
|
|
||||||
{
|
|
||||||
const Key nextKeyOther = nextKey + 1;
|
|
||||||
if ((nextKeyOther < heap_size) && (heap[nextKey].weight > heap[nextKeyOther].weight))
|
|
||||||
{
|
|
||||||
nextKey = nextKeyOther;
|
|
||||||
}
|
|
||||||
if (weight <= heap[nextKey].weight)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
heap[key] = heap[nextKey];
|
|
||||||
inserted_nodes[heap[key].index].key = key;
|
|
||||||
key = nextKey;
|
|
||||||
nextKey <<= 1;
|
|
||||||
}
|
|
||||||
heap[key].index = droppingIndex;
|
|
||||||
heap[key].weight = weight;
|
|
||||||
inserted_nodes[droppingIndex].key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Upheap(Key key)
|
|
||||||
{
|
|
||||||
const Key risingIndex = heap[key].index;
|
|
||||||
const Weight weight = heap[key].weight;
|
|
||||||
Key nextKey = key >> 1;
|
|
||||||
while (heap[nextKey].weight > weight)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(nextKey != 0);
|
|
||||||
heap[key] = heap[nextKey];
|
|
||||||
inserted_nodes[heap[key].index].key = key;
|
|
||||||
key = nextKey;
|
|
||||||
nextKey >>= 1;
|
|
||||||
}
|
|
||||||
heap[key].index = risingIndex;
|
|
||||||
heap[key].weight = weight;
|
|
||||||
inserted_nodes[risingIndex].key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckHeap()
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
for (std::size_t i = 2; i < heap.size(); ++i)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(heap[i].weight >= heap[i >> 1].weight);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BINARY_HEAP_H
|
|
@ -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 "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,268 +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;
|
|
||||||
}
|
|
||||||
|
|
||||||
double coordinate_calculation::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 coordinate_calculation::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 coordinate_calculation::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 coordinate_calculation::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 coordinate_calculation::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 coordinate_calculation::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 coordinate_calculation::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 coordinate_calculation::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 =
|
|
||||||
coordinate_calculation::euclidean_distance(query_location, nearest_location);
|
|
||||||
BOOST_ASSERT(0.f <= approximate_distance);
|
|
||||||
return approximate_distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordinate_calculation::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 coordinate_calculation::deg_to_rad(const float degree)
|
|
||||||
{
|
|
||||||
return degree * (static_cast<float>(M_PI) / 180.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
float coordinate_calculation::rad_to_deg(const float radian)
|
|
||||||
{
|
|
||||||
return radian * (180.f * static_cast<float>(M_1_PI));
|
|
||||||
}
|
|
||||||
|
|
||||||
float coordinate_calculation::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>
|
|
||||||
|
|
||||||
struct coordinate_calculation
|
|
||||||
{
|
|
||||||
static double
|
|
||||||
great_circle_distance(const int lat1, const int lon1, const int lat2, const int lon2);
|
|
||||||
|
|
||||||
static double great_circle_distance(const FixedPointCoordinate &first_coordinate,
|
|
||||||
const FixedPointCoordinate &second_coordinate);
|
|
||||||
|
|
||||||
static float euclidean_distance(const FixedPointCoordinate &first_coordinate,
|
|
||||||
const FixedPointCoordinate &second_coordinate);
|
|
||||||
|
|
||||||
static float euclidean_distance(const int lat1, const int lon1, const int lat2, const int lon2);
|
|
||||||
|
|
||||||
static void lat_or_lon_to_string(const int value, std::string &output);
|
|
||||||
|
|
||||||
static float perpendicular_distance(const FixedPointCoordinate &segment_source,
|
|
||||||
const FixedPointCoordinate &segment_target,
|
|
||||||
const FixedPointCoordinate &query_location);
|
|
||||||
|
|
||||||
static float perpendicular_distance(const FixedPointCoordinate &segment_source,
|
|
||||||
const FixedPointCoordinate &segment_target,
|
|
||||||
const FixedPointCoordinate &query_location,
|
|
||||||
FixedPointCoordinate &nearest_location,
|
|
||||||
float &ratio);
|
|
||||||
|
|
||||||
static 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);
|
|
||||||
|
|
||||||
static 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);
|
|
||||||
|
|
||||||
static float deg_to_rad(const float degree);
|
|
||||||
static float rad_to_deg(const float radian);
|
|
||||||
|
|
||||||
static float bearing(const FixedPointCoordinate &first_coordinate,
|
|
||||||
const FixedPointCoordinate &second_coordinate);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // COORDINATE_CALCULATION
|
|
@ -1,109 +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>
|
|
||||||
|
|
||||||
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,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,158 +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)
|
|
||||||
{
|
|
||||||
for (const auto &l : candidates_list)
|
|
||||||
{
|
|
||||||
viterbi.emplace_back(l.size());
|
|
||||||
parents.emplace_back(l.size());
|
|
||||||
path_lengths.emplace_back(l.size());
|
|
||||||
suspicious.emplace_back(l.size());
|
|
||||||
pruned.emplace_back(l.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(initial_timestamp < candidates_list.size());
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
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 (breakage[initial_timestamp - 1]);
|
|
||||||
|
|
||||||
if (initial_timestamp >= viterbi.size())
|
|
||||||
{
|
|
||||||
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 = 1 << (32 - 1), P, Q, t;
|
|
||||||
int i;
|
|
||||||
// Inverse undo
|
|
||||||
for (Q = M; Q > 1; Q >>= 1)
|
|
||||||
{
|
|
||||||
P = Q - 1;
|
|
||||||
for (i = 0; i < 2; ++i)
|
|
||||||
{
|
|
||||||
|
|
||||||
const bool condition = (X[i] & Q);
|
|
||||||
if (condition)
|
|
||||||
{
|
|
||||||
X[0] ^= P; // invert
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
t = (X[0] ^ X[i]) & P;
|
|
||||||
X[0] ^= t;
|
|
||||||
X[i] ^= t;
|
|
||||||
}
|
|
||||||
} // exchange
|
|
||||||
}
|
|
||||||
// Gray encode
|
|
||||||
for (i = 1; i < 2; ++i)
|
|
||||||
{
|
|
||||||
X[i] ^= X[i - 1];
|
|
||||||
}
|
|
||||||
t = 0;
|
|
||||||
for (Q = M; Q > 1; Q >>= 1)
|
|
||||||
{
|
|
||||||
const bool condition = (X[2 - 1] & Q);
|
|
||||||
if (condition)
|
|
||||||
{
|
|
||||||
t ^= Q - 1;
|
|
||||||
}
|
|
||||||
} // check if this for loop is wrong
|
|
||||||
for (i = 0; i < 2; ++i)
|
|
||||||
{
|
|
||||||
X[i] ^= t;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2014, Project OSRM 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,106 +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(NodeID source,
|
|
||||||
NodeID target,
|
|
||||||
NodeID name_id,
|
|
||||||
EdgeWeight weight,
|
|
||||||
bool forward,
|
|
||||||
bool backward,
|
|
||||||
bool roundabout,
|
|
||||||
bool in_tiny_cc,
|
|
||||||
bool access_restricted,
|
|
||||||
TravelMode travel_mode,
|
|
||||||
bool is_split)
|
|
||||||
: source(source), target(target), name_id(name_id), weight(weight), forward(forward),
|
|
||||||
backward(backward), roundabout(roundabout), in_tiny_cc(in_tiny_cc),
|
|
||||||
access_restricted(access_restricted), is_split(is_split), travel_mode(travel_mode)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EdgeBasedEdge::operator<(const EdgeBasedEdge &other) const
|
|
||||||
{
|
|
||||||
if (source == other.source)
|
|
||||||
{
|
|
||||||
if (target == other.target)
|
|
||||||
{
|
|
||||||
if (weight == other.weight)
|
|
||||||
{
|
|
||||||
return forward && backward && ((!other.forward) || (!other.backward));
|
|
||||||
}
|
|
||||||
return weight < other.weight;
|
|
||||||
}
|
|
||||||
return target < other.target;
|
|
||||||
}
|
|
||||||
return source < other.source;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class EdgeT>
|
|
||||||
EdgeBasedEdge::EdgeBasedEdge(const EdgeT &other)
|
|
||||||
: source(other.source), target(other.target), edge_id(other.data.via),
|
|
||||||
weight(other.data.distance), forward(other.data.forward), backward(other.data.backward)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Default constructor. target and weight are set to 0.*/
|
|
||||||
EdgeBasedEdge::EdgeBasedEdge()
|
|
||||||
: source(0), target(0), edge_id(0), weight(0), forward(false), backward(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgeBasedEdge::EdgeBasedEdge(const NodeID source,
|
|
||||||
const NodeID target,
|
|
||||||
const NodeID edge_id,
|
|
||||||
const EdgeWeight weight,
|
|
||||||
const bool forward,
|
|
||||||
const bool backward)
|
|
||||||
: source(source), target(target), edge_id(edge_id), weight(weight), forward(forward),
|
|
||||||
backward(backward)
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,91 +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;
|
|
||||||
|
|
||||||
explicit NodeBasedEdge(NodeID source,
|
|
||||||
NodeID target,
|
|
||||||
NodeID name_id,
|
|
||||||
EdgeWeight weight,
|
|
||||||
bool forward,
|
|
||||||
bool backward,
|
|
||||||
bool roundabout,
|
|
||||||
bool in_tiny_cc,
|
|
||||||
bool access_restricted,
|
|
||||||
TravelMode travel_mode,
|
|
||||||
bool is_split);
|
|
||||||
|
|
||||||
NodeID source;
|
|
||||||
NodeID target;
|
|
||||||
NodeID name_id;
|
|
||||||
EdgeWeight weight;
|
|
||||||
bool forward : 1;
|
|
||||||
bool backward : 1;
|
|
||||||
bool roundabout : 1;
|
|
||||||
bool in_tiny_cc : 1;
|
|
||||||
bool access_restricted : 1;
|
|
||||||
bool is_split : 1;
|
|
||||||
TravelMode travel_mode : 4;
|
|
||||||
|
|
||||||
NodeBasedEdge() = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
using ImportEdge = NodeBasedEdge;
|
|
||||||
|
|
||||||
#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,279 +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/simple_logger.hpp"
|
|
||||||
|
|
||||||
#include <tbb/parallel_sort.h>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
struct NodeBasedEdgeData
|
|
||||||
{
|
|
||||||
NodeBasedEdgeData()
|
|
||||||
: distance(INVALID_EDGE_WEIGHT), edgeBasedNodeID(SPECIAL_NODEID),
|
|
||||||
nameID(std::numeric_limits<unsigned>::max()), isAccessRestricted(false), shortcut(false),
|
|
||||||
forward(false), backward(false), roundabout(false), ignore_in_grid(false),
|
|
||||||
travel_mode(TRAVEL_MODE_INACCESSIBLE)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int distance;
|
|
||||||
unsigned edgeBasedNodeID;
|
|
||||||
unsigned nameID;
|
|
||||||
bool isAccessRestricted : 1;
|
|
||||||
bool shortcut : 1;
|
|
||||||
bool forward : 1;
|
|
||||||
bool backward : 1;
|
|
||||||
bool roundabout : 1;
|
|
||||||
bool ignore_in_grid : 1;
|
|
||||||
TravelMode travel_mode : 4;
|
|
||||||
|
|
||||||
void SwapDirectionFlags()
|
|
||||||
{
|
|
||||||
bool temp_flag = forward;
|
|
||||||
forward = backward;
|
|
||||||
backward = temp_flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsEqualTo(const NodeBasedEdgeData &other) const
|
|
||||||
{
|
|
||||||
return (forward == other.forward) && (backward == other.backward) &&
|
|
||||||
(nameID == other.nameID) && (ignore_in_grid == other.ignore_in_grid) &&
|
|
||||||
(travel_mode == other.travel_mode);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SimpleEdgeData
|
|
||||||
{
|
|
||||||
SimpleEdgeData() : capacity(0) {}
|
|
||||||
EdgeWeight capacity;
|
|
||||||
};
|
|
||||||
|
|
||||||
using NodeBasedDynamicGraph = DynamicGraph<NodeBasedEdgeData>;
|
|
||||||
using SimpleNodeBasedDynamicGraph = DynamicGraph<SimpleEdgeData>;
|
|
||||||
|
|
||||||
// Factory method to create NodeBasedDynamicGraph from ImportEdges
|
|
||||||
inline std::shared_ptr<NodeBasedDynamicGraph>
|
|
||||||
NodeBasedDynamicGraphFromImportEdges(int number_of_nodes, std::vector<ImportEdge> &input_edge_list)
|
|
||||||
{
|
|
||||||
static_assert(sizeof(NodeBasedEdgeData) == 16,
|
|
||||||
"changing node based edge data size changes memory consumption");
|
|
||||||
|
|
||||||
DeallocatingVector<NodeBasedDynamicGraph::InputEdge> edges_list;
|
|
||||||
NodeBasedDynamicGraph::InputEdge edge;
|
|
||||||
for (const ImportEdge &import_edge : input_edge_list)
|
|
||||||
{
|
|
||||||
if (import_edge.forward)
|
|
||||||
{
|
|
||||||
edge.source = import_edge.source;
|
|
||||||
edge.target = import_edge.target;
|
|
||||||
edge.data.forward = import_edge.forward;
|
|
||||||
edge.data.backward = import_edge.backward;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
edge.source = import_edge.target;
|
|
||||||
edge.target = import_edge.source;
|
|
||||||
edge.data.backward = import_edge.forward;
|
|
||||||
edge.data.forward = import_edge.backward;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (edge.source == edge.target)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
edge.data.distance = (std::max)(static_cast<int>(import_edge.weight), 1);
|
|
||||||
BOOST_ASSERT(edge.data.distance > 0);
|
|
||||||
edge.data.shortcut = false;
|
|
||||||
edge.data.roundabout = import_edge.roundabout;
|
|
||||||
edge.data.ignore_in_grid = import_edge.in_tiny_cc;
|
|
||||||
edge.data.nameID = import_edge.name_id;
|
|
||||||
edge.data.isAccessRestricted = import_edge.access_restricted;
|
|
||||||
edge.data.travel_mode = import_edge.travel_mode;
|
|
||||||
|
|
||||||
edges_list.push_back(edge);
|
|
||||||
|
|
||||||
if (!import_edge.is_split)
|
|
||||||
{
|
|
||||||
using std::swap; // enable ADL
|
|
||||||
swap(edge.source, edge.target);
|
|
||||||
edge.data.SwapDirectionFlags();
|
|
||||||
edges_list.push_back(edge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove duplicate edges
|
|
||||||
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
|
||||||
NodeID edge_count = 0;
|
|
||||||
for (NodeID i = 0; i < edges_list.size();)
|
|
||||||
{
|
|
||||||
const NodeID source = edges_list[i].source;
|
|
||||||
const NodeID target = edges_list[i].target;
|
|
||||||
// remove eigenloops
|
|
||||||
if (source == target)
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
NodeBasedDynamicGraph::InputEdge forward_edge;
|
|
||||||
NodeBasedDynamicGraph::InputEdge reverse_edge;
|
|
||||||
forward_edge = reverse_edge = edges_list[i];
|
|
||||||
forward_edge.data.forward = reverse_edge.data.backward = true;
|
|
||||||
forward_edge.data.backward = reverse_edge.data.forward = false;
|
|
||||||
forward_edge.data.shortcut = reverse_edge.data.shortcut = false;
|
|
||||||
forward_edge.data.distance = reverse_edge.data.distance = std::numeric_limits<int>::max();
|
|
||||||
// remove parallel edges
|
|
||||||
while (i < edges_list.size() && edges_list[i].source == source &&
|
|
||||||
edges_list[i].target == target)
|
|
||||||
{
|
|
||||||
if (edges_list[i].data.forward)
|
|
||||||
{
|
|
||||||
forward_edge.data.distance =
|
|
||||||
std::min(edges_list[i].data.distance, forward_edge.data.distance);
|
|
||||||
}
|
|
||||||
if (edges_list[i].data.backward)
|
|
||||||
{
|
|
||||||
reverse_edge.data.distance =
|
|
||||||
std::min(edges_list[i].data.distance, reverse_edge.data.distance);
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
// merge edges (s,t) and (t,s) into bidirectional edge
|
|
||||||
if (forward_edge.data.distance == reverse_edge.data.distance)
|
|
||||||
{
|
|
||||||
if (static_cast<int>(forward_edge.data.distance) != std::numeric_limits<int>::max())
|
|
||||||
{
|
|
||||||
forward_edge.data.backward = true;
|
|
||||||
edges_list[edge_count++] = forward_edge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // insert seperate edges
|
|
||||||
if (static_cast<int>(forward_edge.data.distance) != std::numeric_limits<int>::max())
|
|
||||||
{
|
|
||||||
edges_list[edge_count++] = forward_edge;
|
|
||||||
}
|
|
||||||
if (static_cast<int>(reverse_edge.data.distance) != std::numeric_limits<int>::max())
|
|
||||||
{
|
|
||||||
edges_list[edge_count++] = reverse_edge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
edges_list.resize(edge_count);
|
|
||||||
SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of "
|
|
||||||
<< edges_list.size();
|
|
||||||
|
|
||||||
auto graph = std::make_shared<NodeBasedDynamicGraph>(
|
|
||||||
static_cast<NodeBasedDynamicGraph::NodeIterator>(number_of_nodes), edges_list);
|
|
||||||
return graph;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class SimpleEdgeT>
|
|
||||||
inline std::shared_ptr<SimpleNodeBasedDynamicGraph>
|
|
||||||
SimpleNodeBasedDynamicGraphFromEdges(int number_of_nodes, std::vector<SimpleEdgeT> &input_edge_list)
|
|
||||||
{
|
|
||||||
static_assert(sizeof(NodeBasedEdgeData) == 16,
|
|
||||||
"changing node based edge data size changes memory consumption");
|
|
||||||
tbb::parallel_sort(input_edge_list.begin(), input_edge_list.end());
|
|
||||||
|
|
||||||
DeallocatingVector<SimpleNodeBasedDynamicGraph::InputEdge> edges_list;
|
|
||||||
SimpleNodeBasedDynamicGraph::InputEdge edge;
|
|
||||||
edge.data.capacity = 1;
|
|
||||||
for (const SimpleEdgeT &import_edge : input_edge_list)
|
|
||||||
{
|
|
||||||
if (import_edge.source == import_edge.target)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
edge.source = import_edge.source;
|
|
||||||
edge.target = import_edge.target;
|
|
||||||
edges_list.push_back(edge);
|
|
||||||
std::swap(edge.source, edge.target);
|
|
||||||
edges_list.push_back(edge);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove duplicate edges
|
|
||||||
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
|
||||||
NodeID edge_count = 0;
|
|
||||||
for (NodeID i = 0; i < edges_list.size();)
|
|
||||||
{
|
|
||||||
const NodeID source = edges_list[i].source;
|
|
||||||
const NodeID target = edges_list[i].target;
|
|
||||||
// remove eigenloops
|
|
||||||
if (source == target)
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
SimpleNodeBasedDynamicGraph::InputEdge forward_edge;
|
|
||||||
SimpleNodeBasedDynamicGraph::InputEdge reverse_edge;
|
|
||||||
forward_edge = reverse_edge = edges_list[i];
|
|
||||||
forward_edge.data.capacity = reverse_edge.data.capacity = INVALID_EDGE_WEIGHT;
|
|
||||||
// remove parallel edges
|
|
||||||
while (i < edges_list.size() && edges_list[i].source == source &&
|
|
||||||
edges_list[i].target == target)
|
|
||||||
{
|
|
||||||
forward_edge.data.capacity =
|
|
||||||
std::min(edges_list[i].data.capacity, forward_edge.data.capacity);
|
|
||||||
reverse_edge.data.capacity =
|
|
||||||
std::min(edges_list[i].data.capacity, reverse_edge.data.capacity);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
// merge edges (s,t) and (t,s) into bidirectional edge
|
|
||||||
if (forward_edge.data.capacity == reverse_edge.data.capacity)
|
|
||||||
{
|
|
||||||
if (static_cast<int>(forward_edge.data.capacity) != INVALID_EDGE_WEIGHT)
|
|
||||||
{
|
|
||||||
edges_list[edge_count++] = forward_edge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // insert seperate edges
|
|
||||||
if (static_cast<int>(forward_edge.data.capacity) != INVALID_EDGE_WEIGHT)
|
|
||||||
{
|
|
||||||
edges_list[edge_count++] = forward_edge;
|
|
||||||
}
|
|
||||||
if (static_cast<int>(reverse_edge.data.capacity) != INVALID_EDGE_WEIGHT)
|
|
||||||
{
|
|
||||||
edges_list[edge_count++] = reverse_edge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SimpleLogger().Write() << "merged " << edges_list.size() - edge_count << " edges out of "
|
|
||||||
<< edges_list.size();
|
|
||||||
|
|
||||||
auto graph = std::make_shared<SimpleNodeBasedDynamicGraph>(number_of_nodes, edges_list);
|
|
||||||
return graph;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // NODE_BASED_GRAPH_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,152 +0,0 @@
|
|||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2015, Project OSRM contributors
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
|
||||||
are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
Redistributions of source code must retain the above copyright notice, this list
|
|
||||||
of conditions and the following disclaimer.
|
|
||||||
Redistributions in binary form must reproduce the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer in the documentation and/or
|
|
||||||
other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
||||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
||||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
||||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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;
|
|
||||||
TravelMode forward_travel_mode : 4;
|
|
||||||
TravelMode backward_travel_mode : 4;
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
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(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,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 "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,134 +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 RESTRICTION_HPP
|
|
||||||
#define RESTRICTION_HPP
|
|
||||||
|
|
||||||
#include "../typedefs.h"
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
struct TurnRestriction
|
|
||||||
{
|
|
||||||
union WayOrNode
|
|
||||||
{
|
|
||||||
NodeID node;
|
|
||||||
EdgeID way;
|
|
||||||
};
|
|
||||||
WayOrNode via;
|
|
||||||
WayOrNode from;
|
|
||||||
WayOrNode to;
|
|
||||||
|
|
||||||
struct Bits
|
|
||||||
{ // mostly unused
|
|
||||||
Bits()
|
|
||||||
: is_only(false), uses_via_way(false), unused2(false), unused3(false), unused4(false),
|
|
||||||
unused5(false), unused6(false), unused7(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_only : 1;
|
|
||||||
bool uses_via_way : 1;
|
|
||||||
bool unused2 : 1;
|
|
||||||
bool unused3 : 1;
|
|
||||||
bool unused4 : 1;
|
|
||||||
bool unused5 : 1;
|
|
||||||
bool unused6 : 1;
|
|
||||||
bool unused7 : 1;
|
|
||||||
} flags;
|
|
||||||
|
|
||||||
explicit TurnRestriction(NodeID node)
|
|
||||||
{
|
|
||||||
via.node = node;
|
|
||||||
from.node = SPECIAL_NODEID;
|
|
||||||
to.node = SPECIAL_NODEID;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit TurnRestriction(const bool is_only = false)
|
|
||||||
{
|
|
||||||
via.node = SPECIAL_NODEID;
|
|
||||||
from.node = SPECIAL_NODEID;
|
|
||||||
to.node = SPECIAL_NODEID;
|
|
||||||
flags.is_only = is_only;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is just a wrapper around TurnRestriction used in the extractor.
|
|
||||||
*
|
|
||||||
* Could be merged with TurnRestriction. For now the type-destiction makes sense
|
|
||||||
* as the format in which the restriction is presented in the extractor and in the
|
|
||||||
* preprocessing is different. (see restriction_parser.cpp)
|
|
||||||
*/
|
|
||||||
struct InputRestrictionContainer
|
|
||||||
{
|
|
||||||
TurnRestriction restriction;
|
|
||||||
|
|
||||||
InputRestrictionContainer(EdgeID fromWay, EdgeID toWay, EdgeID vw)
|
|
||||||
{
|
|
||||||
restriction.from.way = fromWay;
|
|
||||||
restriction.to.way = toWay;
|
|
||||||
restriction.via.way = vw;
|
|
||||||
}
|
|
||||||
explicit InputRestrictionContainer(bool is_only = false)
|
|
||||||
{
|
|
||||||
restriction.from.way = SPECIAL_EDGEID;
|
|
||||||
restriction.to.way = SPECIAL_EDGEID;
|
|
||||||
restriction.via.node = SPECIAL_NODEID;
|
|
||||||
restriction.flags.is_only = is_only;
|
|
||||||
}
|
|
||||||
|
|
||||||
static InputRestrictionContainer min_value() { return InputRestrictionContainer(0, 0, 0); }
|
|
||||||
static InputRestrictionContainer max_value()
|
|
||||||
{
|
|
||||||
return InputRestrictionContainer(SPECIAL_EDGEID, SPECIAL_EDGEID, SPECIAL_EDGEID);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CmpRestrictionContainerByFrom
|
|
||||||
{
|
|
||||||
using value_type = InputRestrictionContainer;
|
|
||||||
bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const
|
|
||||||
{
|
|
||||||
return a.restriction.from.way < b.restriction.from.way;
|
|
||||||
}
|
|
||||||
value_type max_value() const { return InputRestrictionContainer::max_value(); }
|
|
||||||
value_type min_value() const { return InputRestrictionContainer::min_value(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CmpRestrictionContainerByTo
|
|
||||||
{
|
|
||||||
using value_type = InputRestrictionContainer;
|
|
||||||
bool operator()(const InputRestrictionContainer &a, const InputRestrictionContainer &b) const
|
|
||||||
{
|
|
||||||
return a.restriction.to.way < b.restriction.to.way;
|
|
||||||
}
|
|
||||||
value_type max_value() const { return InputRestrictionContainer::max_value(); }
|
|
||||||
value_type min_value() const { return InputRestrictionContainer::min_value(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RESTRICTION_HPP
|
|
@ -1,177 +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 "restriction_map.hpp"
|
|
||||||
|
|
||||||
RestrictionMap::RestrictionMap(const std::vector<TurnRestriction> &restriction_list) : m_count(0)
|
|
||||||
{
|
|
||||||
// decompose restriction consisting of a start, via and end node into a
|
|
||||||
// a pair of starting edge and a list of all end nodes
|
|
||||||
for (auto &restriction : restriction_list)
|
|
||||||
{
|
|
||||||
m_restriction_start_nodes.insert(restriction.from.node);
|
|
||||||
m_no_turn_via_node_set.insert(restriction.via.node);
|
|
||||||
|
|
||||||
RestrictionSource restriction_source = {restriction.from.node, restriction.via.node};
|
|
||||||
|
|
||||||
std::size_t index;
|
|
||||||
auto restriction_iter = m_restriction_map.find(restriction_source);
|
|
||||||
if (restriction_iter == m_restriction_map.end())
|
|
||||||
{
|
|
||||||
index = m_restriction_bucket_list.size();
|
|
||||||
m_restriction_bucket_list.resize(index + 1);
|
|
||||||
m_restriction_map.emplace(restriction_source, index);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
index = restriction_iter->second;
|
|
||||||
// Map already contains an is_only_*-restriction
|
|
||||||
if (m_restriction_bucket_list.at(index).begin()->is_only)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (restriction.flags.is_only)
|
|
||||||
{
|
|
||||||
// We are going to insert an is_only_*-restriction. There can be only one.
|
|
||||||
m_count -= m_restriction_bucket_list.at(index).size();
|
|
||||||
m_restriction_bucket_list.at(index).clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++m_count;
|
|
||||||
m_restriction_bucket_list.at(index)
|
|
||||||
.emplace_back(restriction.to.node, restriction.flags.is_only);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RestrictionMap::IsViaNode(const NodeID node) const
|
|
||||||
{
|
|
||||||
return m_no_turn_via_node_set.find(node) != m_no_turn_via_node_set.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replaces start edge (v, w) with (u, w). Only start node changes.
|
|
||||||
void RestrictionMap::FixupStartingTurnRestriction(const NodeID node_u,
|
|
||||||
const NodeID node_v,
|
|
||||||
const NodeID node_w)
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(node_u != SPECIAL_NODEID);
|
|
||||||
BOOST_ASSERT(node_v != SPECIAL_NODEID);
|
|
||||||
BOOST_ASSERT(node_w != SPECIAL_NODEID);
|
|
||||||
|
|
||||||
if (!IsSourceNode(node_v))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto restriction_iterator = m_restriction_map.find({node_v, node_w});
|
|
||||||
if (restriction_iterator != m_restriction_map.end())
|
|
||||||
{
|
|
||||||
const unsigned index = restriction_iterator->second;
|
|
||||||
// remove old restriction start (v,w)
|
|
||||||
m_restriction_map.erase(restriction_iterator);
|
|
||||||
m_restriction_start_nodes.emplace(node_u);
|
|
||||||
// insert new restriction start (u,w) (pointing to index)
|
|
||||||
RestrictionSource new_source = {node_u, node_w};
|
|
||||||
m_restriction_map.emplace(new_source, index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if edge (u, v) is the start of any turn restriction.
|
|
||||||
// If so returns id of first target node.
|
|
||||||
NodeID RestrictionMap::CheckForEmanatingIsOnlyTurn(const NodeID node_u, const NodeID node_v) const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(node_u != SPECIAL_NODEID);
|
|
||||||
BOOST_ASSERT(node_v != SPECIAL_NODEID);
|
|
||||||
|
|
||||||
if (!IsSourceNode(node_u))
|
|
||||||
{
|
|
||||||
return SPECIAL_NODEID;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto restriction_iter = m_restriction_map.find({node_u, node_v});
|
|
||||||
if (restriction_iter != m_restriction_map.end())
|
|
||||||
{
|
|
||||||
const unsigned index = restriction_iter->second;
|
|
||||||
const auto &bucket = m_restriction_bucket_list.at(index);
|
|
||||||
for (const RestrictionTarget &restriction_target : bucket)
|
|
||||||
{
|
|
||||||
if (restriction_target.is_only)
|
|
||||||
{
|
|
||||||
return restriction_target.target_node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SPECIAL_NODEID;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checks if turn <u,v,w> is actually a turn restriction.
|
|
||||||
bool RestrictionMap::CheckIfTurnIsRestricted(const NodeID node_u,
|
|
||||||
const NodeID node_v,
|
|
||||||
const NodeID node_w) const
|
|
||||||
{
|
|
||||||
BOOST_ASSERT(node_u != SPECIAL_NODEID);
|
|
||||||
BOOST_ASSERT(node_v != SPECIAL_NODEID);
|
|
||||||
BOOST_ASSERT(node_w != SPECIAL_NODEID);
|
|
||||||
|
|
||||||
if (!IsSourceNode(node_u))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto restriction_iter = m_restriction_map.find({node_u, node_v});
|
|
||||||
if (restriction_iter == m_restriction_map.end())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const unsigned index = restriction_iter->second;
|
|
||||||
const auto &bucket = m_restriction_bucket_list.at(index);
|
|
||||||
|
|
||||||
for (const RestrictionTarget &restriction_target : bucket)
|
|
||||||
{
|
|
||||||
if (node_w == restriction_target.target_node && // target found
|
|
||||||
!restriction_target.is_only) // and not an only_-restr.
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node_w != restriction_target.target_node && // target not found
|
|
||||||
restriction_target.is_only) // and is an only restriction
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check of node is the start of any restriction
|
|
||||||
bool RestrictionMap::IsSourceNode(const NodeID node) const
|
|
||||||
{
|
|
||||||
if (m_restriction_start_nodes.find(node) == m_restriction_start_nodes.end())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user