Merge pull request 'Permafix-optimization-refiner' (#9) from Permafix-optimization-refiner into main
Reviewed-on: remoll/fast-network-navigation#9
This commit is contained in:
commit
f590ebb5ed
28
.vscode/launch.json
vendored
28
.vscode/launch.json
vendored
@ -1,28 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "frontend",
|
||||
"cwd": "frontend",
|
||||
"request": "launch",
|
||||
"type": "dart"
|
||||
},
|
||||
{
|
||||
"name": "frontend (profile mode)",
|
||||
"cwd": "frontend",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "profile"
|
||||
},
|
||||
{
|
||||
"name": "frontend (release mode)",
|
||||
"cwd": "frontend",
|
||||
"request": "launch",
|
||||
"type": "dart",
|
||||
"flutterMode": "release"
|
||||
},
|
||||
]
|
||||
}
|
1
backend/.gitignore
vendored
1
backend/.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
# osm-cache
|
||||
cache/
|
||||
apicache/
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
|
@ -10,5 +10,11 @@ fastapi = "*"
|
||||
osmpythontools = "*"
|
||||
pydantic = "*"
|
||||
shapely = "*"
|
||||
networkx = "*"
|
||||
geopy = "*"
|
||||
requests = ">=2.20.1"
|
||||
mwparserfromhell = ">=0.5.2"
|
||||
packaging = "*"
|
||||
pywikibot = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
860
backend/Pipfile.lock
generated
860
backend/Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "0f88c01cde3be9a6332acec33fa0ccf13b6e122a6df8ee5cfefa52ba1e98034f"
|
||||
"sha256": "b089081defe09c4ffad85fd22c5de336c76b31e7f6f67e5969b731bdaa58e528"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
@ -40,11 +40,107 @@
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516",
|
||||
"sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"
|
||||
"sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b",
|
||||
"sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"
|
||||
],
|
||||
"markers": "python_version >= '3.6'",
|
||||
"version": "==2024.6.2"
|
||||
"version": "==2024.7.4"
|
||||
},
|
||||
"charset-normalizer": {
|
||||
"hashes": [
|
||||
"sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027",
|
||||
"sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087",
|
||||
"sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786",
|
||||
"sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8",
|
||||
"sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09",
|
||||
"sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185",
|
||||
"sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574",
|
||||
"sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e",
|
||||
"sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519",
|
||||
"sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898",
|
||||
"sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269",
|
||||
"sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3",
|
||||
"sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f",
|
||||
"sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6",
|
||||
"sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8",
|
||||
"sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a",
|
||||
"sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73",
|
||||
"sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc",
|
||||
"sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714",
|
||||
"sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2",
|
||||
"sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc",
|
||||
"sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce",
|
||||
"sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d",
|
||||
"sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e",
|
||||
"sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6",
|
||||
"sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269",
|
||||
"sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96",
|
||||
"sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d",
|
||||
"sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a",
|
||||
"sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4",
|
||||
"sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77",
|
||||
"sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d",
|
||||
"sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0",
|
||||
"sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed",
|
||||
"sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068",
|
||||
"sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac",
|
||||
"sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25",
|
||||
"sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8",
|
||||
"sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab",
|
||||
"sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26",
|
||||
"sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2",
|
||||
"sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db",
|
||||
"sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f",
|
||||
"sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5",
|
||||
"sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99",
|
||||
"sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c",
|
||||
"sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d",
|
||||
"sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811",
|
||||
"sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa",
|
||||
"sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a",
|
||||
"sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03",
|
||||
"sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b",
|
||||
"sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04",
|
||||
"sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c",
|
||||
"sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001",
|
||||
"sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458",
|
||||
"sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389",
|
||||
"sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99",
|
||||
"sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985",
|
||||
"sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537",
|
||||
"sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238",
|
||||
"sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f",
|
||||
"sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d",
|
||||
"sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796",
|
||||
"sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a",
|
||||
"sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143",
|
||||
"sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8",
|
||||
"sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c",
|
||||
"sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5",
|
||||
"sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5",
|
||||
"sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711",
|
||||
"sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4",
|
||||
"sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6",
|
||||
"sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c",
|
||||
"sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7",
|
||||
"sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4",
|
||||
"sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b",
|
||||
"sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae",
|
||||
"sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12",
|
||||
"sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c",
|
||||
"sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae",
|
||||
"sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8",
|
||||
"sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887",
|
||||
"sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b",
|
||||
"sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4",
|
||||
"sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f",
|
||||
"sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5",
|
||||
"sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33",
|
||||
"sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519",
|
||||
"sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"
|
||||
],
|
||||
"markers": "python_full_version >= '3.7.0'",
|
||||
"version": "==3.3.2"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
@ -130,20 +226,20 @@
|
||||
},
|
||||
"exceptiongroup": {
|
||||
"hashes": [
|
||||
"sha256:5258b9ed329c5bbdd31a309f53cbfb0b155341807f6ff7606a1e801a891b29ad",
|
||||
"sha256:a4785e48b045528f5bfe627b6ad554ff32def154f42372786903b7abcfe1aa16"
|
||||
"sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b",
|
||||
"sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"
|
||||
],
|
||||
"markers": "python_version < '3.11'",
|
||||
"version": "==1.2.1"
|
||||
"version": "==1.2.2"
|
||||
},
|
||||
"fastapi": {
|
||||
"hashes": [
|
||||
"sha256:97ecbf994be0bcbdadedf88c3150252bed7b2087075ac99735403b1b76cc8fc0",
|
||||
"sha256:b9db9dd147c91cb8b769f7183535773d8741dd46f9dc6676cd82eab510228cd7"
|
||||
"sha256:4f51cfa25d72f9fbc3280832e84b32494cf186f50158d364a8765aabf22587bf",
|
||||
"sha256:ddd1ac34cb1f76c2e2d7f8545a4bcb5463bce4834e81abf0b189e0c359ab2413"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==0.111.0"
|
||||
"version": "==0.111.1"
|
||||
},
|
||||
"fastapi-cli": {
|
||||
"hashes": [
|
||||
@ -155,51 +251,59 @@
|
||||
},
|
||||
"fonttools": {
|
||||
"hashes": [
|
||||
"sha256:099634631b9dd271d4a835d2b2a9e042ccc94ecdf7e2dd9f7f34f7daf333358d",
|
||||
"sha256:0c555e039d268445172b909b1b6bdcba42ada1cf4a60e367d68702e3f87e5f64",
|
||||
"sha256:1e677bfb2b4bd0e5e99e0f7283e65e47a9814b0486cb64a41adf9ef110e078f2",
|
||||
"sha256:2367d47816cc9783a28645bc1dac07f8ffc93e0f015e8c9fc674a5b76a6da6e4",
|
||||
"sha256:28d072169fe8275fb1a0d35e3233f6df36a7e8474e56cb790a7258ad822b6fd6",
|
||||
"sha256:31f0e3147375002aae30696dd1dc596636abbd22fca09d2e730ecde0baad1d6b",
|
||||
"sha256:3e0ad3c6ea4bd6a289d958a1eb922767233f00982cf0fe42b177657c86c80a8f",
|
||||
"sha256:45b4afb069039f0366a43a5d454bc54eea942bfb66b3fc3e9a2c07ef4d617380",
|
||||
"sha256:4a2a6ba400d386e904fd05db81f73bee0008af37799a7586deaa4aef8cd5971e",
|
||||
"sha256:4f520d9ac5b938e6494f58a25c77564beca7d0199ecf726e1bd3d56872c59749",
|
||||
"sha256:52a6e0a7a0bf611c19bc8ec8f7592bdae79c8296c70eb05917fd831354699b20",
|
||||
"sha256:5a4788036201c908079e89ae3f5399b33bf45b9ea4514913f4dbbe4fac08efe0",
|
||||
"sha256:6b4f04b1fbc01a3569d63359f2227c89ab294550de277fd09d8fca6185669fa4",
|
||||
"sha256:715b41c3e231f7334cbe79dfc698213dcb7211520ec7a3bc2ba20c8515e8a3b5",
|
||||
"sha256:73121a9b7ff93ada888aaee3985a88495489cc027894458cb1a736660bdfb206",
|
||||
"sha256:74ae2441731a05b44d5988d3ac2cf784d3ee0a535dbed257cbfff4be8bb49eb9",
|
||||
"sha256:7d6166192dcd925c78a91d599b48960e0a46fe565391c79fe6de481ac44d20ac",
|
||||
"sha256:7f193f060391a455920d61684a70017ef5284ccbe6023bb056e15e5ac3de11d1",
|
||||
"sha256:907fa0b662dd8fc1d7c661b90782ce81afb510fc4b7aa6ae7304d6c094b27bce",
|
||||
"sha256:93156dd7f90ae0a1b0e8871032a07ef3178f553f0c70c386025a808f3a63b1f4",
|
||||
"sha256:93bc9e5aaa06ff928d751dc6be889ff3e7d2aa393ab873bc7f6396a99f6fbb12",
|
||||
"sha256:95db0c6581a54b47c30860d013977b8a14febc206c8b5ff562f9fe32738a8aca",
|
||||
"sha256:973d030180eca8255b1bce6ffc09ef38a05dcec0e8320cc9b7bcaa65346f341d",
|
||||
"sha256:9cd7a6beec6495d1dffb1033d50a3f82dfece23e9eb3c20cd3c2444d27514068",
|
||||
"sha256:9fe9096a60113e1d755e9e6bda15ef7e03391ee0554d22829aa506cdf946f796",
|
||||
"sha256:a209d2e624ba492df4f3bfad5996d1f76f03069c6133c60cd04f9a9e715595ec",
|
||||
"sha256:a239afa1126b6a619130909c8404070e2b473dd2b7fc4aacacd2e763f8597fea",
|
||||
"sha256:ba9f09ff17f947392a855e3455a846f9855f6cf6bec33e9a427d3c1d254c712f",
|
||||
"sha256:bb7273789f69b565d88e97e9e1da602b4ee7ba733caf35a6c2affd4334d4f005",
|
||||
"sha256:bd5bc124fae781a4422f61b98d1d7faa47985f663a64770b78f13d2c072410c2",
|
||||
"sha256:bff98816cb144fb7b85e4b5ba3888a33b56ecef075b0e95b95bcd0a5fbf20f06",
|
||||
"sha256:c4ee5a24e281fbd8261c6ab29faa7fd9a87a12e8c0eed485b705236c65999109",
|
||||
"sha256:c93ed66d32de1559b6fc348838c7572d5c0ac1e4a258e76763a5caddd8944002",
|
||||
"sha256:d1a24f51a3305362b94681120c508758a88f207fa0a681c16b5a4172e9e6c7a9",
|
||||
"sha256:d8f191a17369bd53a5557a5ee4bab91d5330ca3aefcdf17fab9a497b0e7cff7a",
|
||||
"sha256:daaef7390e632283051e3cf3e16aff2b68b247e99aea916f64e578c0449c9c68",
|
||||
"sha256:e40013572bfb843d6794a3ce076c29ef4efd15937ab833f520117f8eccc84fd6",
|
||||
"sha256:eceef49f457253000e6a2d0f7bd08ff4e9fe96ec4ffce2dbcb32e34d9c1b8161",
|
||||
"sha256:ee595d7ba9bba130b2bec555a40aafa60c26ce68ed0cf509983e0f12d88674fd",
|
||||
"sha256:ef50ec31649fbc3acf6afd261ed89d09eb909b97cc289d80476166df8438524d",
|
||||
"sha256:fa1f3e34373aa16045484b4d9d352d4c6b5f9f77ac77a178252ccbc851e8b2ee",
|
||||
"sha256:fca66d9ff2ac89b03f5aa17e0b21a97c21f3491c46b583bb131eb32c7bab33af"
|
||||
"sha256:02569e9a810f9d11f4ae82c391ebc6fb5730d95a0657d24d754ed7763fb2d122",
|
||||
"sha256:0679a30b59d74b6242909945429dbddb08496935b82f91ea9bf6ad240ec23397",
|
||||
"sha256:10f5e6c3510b79ea27bb1ebfcc67048cde9ec67afa87c7dd7efa5c700491ac7f",
|
||||
"sha256:2af40ae9cdcb204fc1d8f26b190aa16534fcd4f0df756268df674a270eab575d",
|
||||
"sha256:32f029c095ad66c425b0ee85553d0dc326d45d7059dbc227330fc29b43e8ba60",
|
||||
"sha256:35250099b0cfb32d799fb5d6c651220a642fe2e3c7d2560490e6f1d3f9ae9169",
|
||||
"sha256:3b3c8ebafbee8d9002bd8f1195d09ed2bd9ff134ddec37ee8f6a6375e6a4f0e8",
|
||||
"sha256:4824c198f714ab5559c5be10fd1adf876712aa7989882a4ec887bf1ef3e00e31",
|
||||
"sha256:5ff7e5e9bad94e3a70c5cd2fa27f20b9bb9385e10cddab567b85ce5d306ea923",
|
||||
"sha256:651390c3b26b0c7d1f4407cad281ee7a5a85a31a110cbac5269de72a51551ba2",
|
||||
"sha256:6e08f572625a1ee682115223eabebc4c6a2035a6917eac6f60350aba297ccadb",
|
||||
"sha256:6ed170b5e17da0264b9f6fae86073be3db15fa1bd74061c8331022bca6d09bab",
|
||||
"sha256:73379d3ffdeecb376640cd8ed03e9d2d0e568c9d1a4e9b16504a834ebadc2dfb",
|
||||
"sha256:75a157d8d26c06e64ace9df037ee93a4938a4606a38cb7ffaf6635e60e253b7a",
|
||||
"sha256:791b31ebbc05197d7aa096bbc7bd76d591f05905d2fd908bf103af4488e60670",
|
||||
"sha256:7b6b35e52ddc8fb0db562133894e6ef5b4e54e1283dff606fda3eed938c36fc8",
|
||||
"sha256:84ec3fb43befb54be490147b4a922b5314e16372a643004f182babee9f9c3407",
|
||||
"sha256:8959a59de5af6d2bec27489e98ef25a397cfa1774b375d5787509c06659b3671",
|
||||
"sha256:9dfdae43b7996af46ff9da520998a32b105c7f098aeea06b2226b30e74fbba88",
|
||||
"sha256:9e6ceba2a01b448e36754983d376064730690401da1dd104ddb543519470a15f",
|
||||
"sha256:9efd176f874cb6402e607e4cc9b4a9cd584d82fc34a4b0c811970b32ba62501f",
|
||||
"sha256:a1c7c5aa18dd3b17995898b4a9b5929d69ef6ae2af5b96d585ff4005033d82f0",
|
||||
"sha256:aae7bd54187e8bf7fd69f8ab87b2885253d3575163ad4d669a262fe97f0136cb",
|
||||
"sha256:b21952c092ffd827504de7e66b62aba26fdb5f9d1e435c52477e6486e9d128b2",
|
||||
"sha256:b96cd370a61f4d083c9c0053bf634279b094308d52fdc2dd9a22d8372fdd590d",
|
||||
"sha256:becc5d7cb89c7b7afa8321b6bb3dbee0eec2b57855c90b3e9bf5fb816671fa7c",
|
||||
"sha256:bee32ea8765e859670c4447b0817514ca79054463b6b79784b08a8df3a4d78e3",
|
||||
"sha256:c6e7170d675d12eac12ad1a981d90f118c06cf680b42a2d74c6c931e54b50719",
|
||||
"sha256:c818c058404eb2bba05e728d38049438afd649e3c409796723dfc17cd3f08749",
|
||||
"sha256:c8696544c964500aa9439efb6761947393b70b17ef4e82d73277413f291260a4",
|
||||
"sha256:c9cd19cf4fe0595ebdd1d4915882b9440c3a6d30b008f3cc7587c1da7b95be5f",
|
||||
"sha256:d4d0096cb1ac7a77b3b41cd78c9b6bc4a400550e21dc7a92f2b5ab53ed74eb02",
|
||||
"sha256:d92d3c2a1b39631a6131c2fa25b5406855f97969b068e7e08413325bc0afba58",
|
||||
"sha256:da33440b1413bad53a8674393c5d29ce64d8c1a15ef8a77c642ffd900d07bfe1",
|
||||
"sha256:e013aae589c1c12505da64a7d8d023e584987e51e62006e1bb30d72f26522c41",
|
||||
"sha256:e128778a8e9bc11159ce5447f76766cefbd876f44bd79aff030287254e4752c4",
|
||||
"sha256:e54f1bba2f655924c1138bbc7fa91abd61f45c68bd65ab5ed985942712864bbb",
|
||||
"sha256:e5b708073ea3d684235648786f5f6153a48dc8762cdfe5563c57e80787c29fbb",
|
||||
"sha256:e8bf06b94694251861ba7fdeea15c8ec0967f84c3d4143ae9daf42bbc7717fe3",
|
||||
"sha256:f08df60fbd8d289152079a65da4e66a447efc1d5d5a4d3f299cdd39e3b2e4a7d",
|
||||
"sha256:f1f8758a2ad110bd6432203a344269f445a2907dc24ef6bccfd0ac4e14e0d71d",
|
||||
"sha256:f677ce218976496a587ab17140da141557beb91d2a5c1a14212c994093f2eae2"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==4.53.0"
|
||||
"version": "==4.53.1"
|
||||
},
|
||||
"geographiclib": {
|
||||
"hashes": [
|
||||
"sha256:6b7225248e45ff7edcee32becc4e0a1504c606ac5ee163a5656d482e0cd38734",
|
||||
"sha256:f7f41c85dc3e1c2d3d935ec86660dc3b2c848c83e17f9a9e51ba9d5146a15859"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.0"
|
||||
},
|
||||
"geojson": {
|
||||
"hashes": [
|
||||
@ -209,6 +313,15 @@
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==3.1.0"
|
||||
},
|
||||
"geopy": {
|
||||
"hashes": [
|
||||
"sha256:50283d8e7ad07d89be5cb027338c6365a32044df3ae2556ad3f52f4840b3d0d1",
|
||||
"sha256:ae8b4bc5c1131820f4d75fce9d4aaaca0c85189b3aa5d64c3dcaf5e3b7b882a7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.4.1"
|
||||
},
|
||||
"h11": {
|
||||
"hashes": [
|
||||
"sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d",
|
||||
@ -624,38 +737,38 @@
|
||||
},
|
||||
"matplotlib": {
|
||||
"hashes": [
|
||||
"sha256:063af8587fceeac13b0936c42a2b6c732c2ab1c98d38abc3337e430e1ff75e38",
|
||||
"sha256:06a478f0d67636554fa78558cfbcd7b9dba85b51f5c3b5a0c9be49010cf5f321",
|
||||
"sha256:0a490715b3b9984fa609116481b22178348c1a220a4499cda79132000a79b4db",
|
||||
"sha256:0fc51eaa5262553868461c083d9adadb11a6017315f3a757fc45ec6ec5f02888",
|
||||
"sha256:13beb4840317d45ffd4183a778685e215939be7b08616f431c7795276e067463",
|
||||
"sha256:290d304e59be2b33ef5c2d768d0237f5bd132986bdcc66f80bc9bcc300066a03",
|
||||
"sha256:2bcee1dffaf60fe7656183ac2190bd630842ff87b3153afb3e384d966b57fe56",
|
||||
"sha256:2e7f03e5cbbfacdd48c8ea394d365d91ee8f3cae7e6ec611409927b5ed997ee4",
|
||||
"sha256:3f988bafb0fa39d1074ddd5bacd958c853e11def40800c5824556eb630f94d3b",
|
||||
"sha256:52146fc3bd7813cc784562cb93a15788be0b2875c4655e2cc6ea646bfa30344b",
|
||||
"sha256:550cdda3adbd596078cca7d13ed50b77879104e2e46392dcd7c75259d8f00e85",
|
||||
"sha256:616fabf4981a3b3c5a15cd95eba359c8489c4e20e03717aea42866d8d0465956",
|
||||
"sha256:76cce0f31b351e3551d1f3779420cf8f6ec0d4a8cf9c0237a3b549fd28eb4abb",
|
||||
"sha256:7ff2e239c26be4f24bfa45860c20ffccd118d270c5b5d081fa4ea409b5469fcd",
|
||||
"sha256:8146ce83cbc5dc71c223a74a1996d446cd35cfb6a04b683e1446b7e6c73603b7",
|
||||
"sha256:81c40af649d19c85f8073e25e5806926986806fa6d54be506fbf02aef47d5a89",
|
||||
"sha256:9a2fa6d899e17ddca6d6526cf6e7ba677738bf2a6a9590d702c277204a7c6152",
|
||||
"sha256:a5be985db2596d761cdf0c2eaf52396f26e6a64ab46bd8cd810c48972349d1be",
|
||||
"sha256:af4001b7cae70f7eaacfb063db605280058246de590fa7874f00f62259f2df7e",
|
||||
"sha256:bd4f2831168afac55b881db82a7730992aa41c4f007f1913465fb182d6fb20c0",
|
||||
"sha256:bdd1ecbe268eb3e7653e04f451635f0fb0f77f07fd070242b44c076c9106da84",
|
||||
"sha256:c53aeb514ccbbcbab55a27f912d79ea30ab21ee0531ee2c09f13800efb272674",
|
||||
"sha256:c79f3a585f1368da6049318bdf1f85568d8d04b2e89fc24b7e02cc9b62017382",
|
||||
"sha256:cd53c79fd02f1c1808d2cfc87dd3cf4dbc63c5244a58ee7944497107469c8d8a",
|
||||
"sha256:d38e85a1a6d732f645f1403ce5e6727fd9418cd4574521d5803d3d94911038e5",
|
||||
"sha256:d91a4ffc587bacf5c4ce4ecfe4bcd23a4b675e76315f2866e588686cc97fccdf",
|
||||
"sha256:e6d29ea6c19e34b30fb7d88b7081f869a03014f66fe06d62cc77d5a6ea88ed7a",
|
||||
"sha256:eaf3978060a106fab40c328778b148f590e27f6fa3cd15a19d6892575bce387d",
|
||||
"sha256:fe428e191ea016bb278758c8ee82a8129c51d81d8c4bc0846c09e7e8e9057241"
|
||||
"sha256:0000354e32efcfd86bda75729716b92f5c2edd5b947200be9881f0a671565c33",
|
||||
"sha256:0c584210c755ae921283d21d01f03a49ef46d1afa184134dd0f95b0202ee6f03",
|
||||
"sha256:0e835c6988edc3d2d08794f73c323cc62483e13df0194719ecb0723b564e0b5c",
|
||||
"sha256:0fc001516ffcf1a221beb51198b194d9230199d6842c540108e4ce109ac05cc0",
|
||||
"sha256:11fed08f34fa682c2b792942f8902e7aefeed400da71f9e5816bea40a7ce28fe",
|
||||
"sha256:208cbce658b72bf6a8e675058fbbf59f67814057ae78165d8a2f87c45b48d0ff",
|
||||
"sha256:2315837485ca6188a4b632c5199900e28d33b481eb083663f6a44cfc8987ded3",
|
||||
"sha256:26040c8f5121cd1ad712abffcd4b5222a8aec3a0fe40bc8542c94331deb8780d",
|
||||
"sha256:3fda72d4d472e2ccd1be0e9ccb6bf0d2eaf635e7f8f51d737ed7e465ac020cb3",
|
||||
"sha256:421851f4f57350bcf0811edd754a708d2275533e84f52f6760b740766c6747a7",
|
||||
"sha256:44a21d922f78ce40435cb35b43dd7d573cf2a30138d5c4b709d19f00e3907fd7",
|
||||
"sha256:4db17fea0ae3aceb8e9ac69c7e3051bae0b3d083bfec932240f9bf5d0197a049",
|
||||
"sha256:565d572efea2b94f264dd86ef27919515aa6d629252a169b42ce5f570db7f37b",
|
||||
"sha256:591d3a88903a30a6d23b040c1e44d1afdd0d778758d07110eb7596f811f31842",
|
||||
"sha256:6d397fd8ccc64af2ec0af1f0efc3bacd745ebfb9d507f3f552e8adb689ed730a",
|
||||
"sha256:7ccd6270066feb9a9d8e0705aa027f1ff39f354c72a87efe8fa07632f30fc6bb",
|
||||
"sha256:82cd5acf8f3ef43f7532c2f230249720f5dc5dd40ecafaf1c60ac8200d46d7eb",
|
||||
"sha256:83c6a792f1465d174c86d06f3ae85a8fe36e6f5964633ae8106312ec0921fdf5",
|
||||
"sha256:84b3ba8429935a444f1fdc80ed930babbe06725bcf09fbeb5c8757a2cd74af04",
|
||||
"sha256:a0c977c5c382f6696caf0bd277ef4f936da7e2aa202ff66cad5f0ac1428ee15b",
|
||||
"sha256:a973c53ad0668c53e0ed76b27d2eeeae8799836fd0d0caaa4ecc66bf4e6676c0",
|
||||
"sha256:ab38a4f3772523179b2f772103d8030215b318fef6360cb40558f585bf3d017f",
|
||||
"sha256:b3fce58971b465e01b5c538f9d44915640c20ec5ff31346e963c9e1cd66fa812",
|
||||
"sha256:b918770bf3e07845408716e5bbda17eadfc3fcbd9307dc67f37d6cf834bb3d98",
|
||||
"sha256:d12cb1837cffaac087ad6b44399d5e22b78c729de3cdae4629e252067b705e2b",
|
||||
"sha256:dc23f48ab630474264276be156d0d7710ac6c5a09648ccdf49fef9200d8cbe80",
|
||||
"sha256:dd2a59ff4b83d33bca3b5ec58203cc65985367812cb8c257f3e101632be86d92",
|
||||
"sha256:de06b19b8db95dd33d0dc17c926c7c9ebed9f572074b6fac4f65068a6814d010",
|
||||
"sha256:f1f2e5d29e9435c97ad4c36fb6668e89aee13d48c75893e25cef064675038ac9"
|
||||
],
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==3.9.0"
|
||||
"version": "==3.9.1"
|
||||
},
|
||||
"mdurl": {
|
||||
"hashes": [
|
||||
@ -665,6 +778,48 @@
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==0.1.2"
|
||||
},
|
||||
"mwparserfromhell": {
|
||||
"hashes": [
|
||||
"sha256:007d0859e5467241b73c6e974df039a074609ce4e2b9df8c2263a8920554d032",
|
||||
"sha256:03e03b8bec729af850457d045b04d0c9d3e296ff8bf66b455f754cccb29c3bea",
|
||||
"sha256:063c1e79befd1f55d77c358e0f5006f5ecf88ddf218ff6af55188d686139330e",
|
||||
"sha256:1915fe4f5e5ae34f16242d4cd98da2adc81a810ab94105ec2af3dc95d7ce74aa",
|
||||
"sha256:1960bcc5115ea57427df130150edf1dbfc2fb03465e548e630bb6eb37976d793",
|
||||
"sha256:19e9a4bcd85707c83172405eb2a9a046eff9d38dd7f1a56a5e5ecbbfef4a640a",
|
||||
"sha256:1d2422659abb29191a0fa096cf8bead837ac3ecd343065569b2acc7a84ecf866",
|
||||
"sha256:2b75fae6d01c8fda19dbf127175122d7aa2964ef6454690e6868bbc3d80a7bc1",
|
||||
"sha256:50c482e703d2d51401f7e36a71ae9493901f170225940196292f97398713dde5",
|
||||
"sha256:54e2dd30edc1a358408d14343b30dcca0b4613227781e4bbee968bd4395d94ff",
|
||||
"sha256:59633d3cc09993af75ced8dfbd6800e1e38e64620851a095575621548448875c",
|
||||
"sha256:6a89edf53f15877223d923e122e9a97f3f7b85f56dc56d91a3d77b89c9dd4126",
|
||||
"sha256:6b11dea3bcdebe4554933169eade815e9d6b898175faa5a20a744524fd99210f",
|
||||
"sha256:71afec1e9784ba576e95d6f34845582d3c733a3a52ba770dd8a9c3a40e5b649f",
|
||||
"sha256:746bad799179684994ecee72a26352e0bbe2b697f6a7e35dc5ad151606bcb8ab",
|
||||
"sha256:910d36bc70e8bea758380e75c12fd47626b295abec9f73a6099d8f937a649e77",
|
||||
"sha256:9136696d6b29838adcf8f428e3f7028b2c6e788fc05fe1beeb4b135429c356df",
|
||||
"sha256:a58251a5d5c77abdfd061624dc05667c2774e93e8178a2fbd1a3b45f8673f1a9",
|
||||
"sha256:cdc46c115b2495d4025920b7b30a6885a96d2b797ccc4009bf3cc02940ae55d3",
|
||||
"sha256:d2febd92a55a3f19b461833267726cb81429c3d6cb0006ad1691dfa849789e5d",
|
||||
"sha256:d6995b9cfe6ec79556db0232a39210ac11aa69ee304cfc95b29c51be381e202b",
|
||||
"sha256:dbe5976b1b524e26aa2eb71b6219960f2578f56b536c68e0a79deb63e3b7f710",
|
||||
"sha256:e28ffa9a7e0748ec64002a84234201ef69c2d4a710508baf9cc25f4ee274c6bd",
|
||||
"sha256:ebc70f8a24aa60e54728be740f1c12a4acb1b12d1cc947d87b067cc1c83339fd",
|
||||
"sha256:fd05481adc0806f4b8f8f8cb309ec56924b17ce386cb1c2f73919d8a012e6b16",
|
||||
"sha256:fff66e97f7c02aa0fd57ff8f702977a9c5a1d72ef55b64ee9b146291e4c41057"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==0.6.6"
|
||||
},
|
||||
"networkx": {
|
||||
"hashes": [
|
||||
"sha256:0c127d8b2f4865f59ae9cb8aafcd60b5c70f3241ebd66f7defad7c4ab90126c9",
|
||||
"sha256:28575580c6ebdaf4505b22c6256a2b9de86b316dc63ba9e93abde3d78dfdbcf2"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==3.3"
|
||||
},
|
||||
"numpy": {
|
||||
"hashes": [
|
||||
"sha256:04494f6ec467ccb5369d1808570ae55f6ed9b5809d7f035059000a37b8d7e86f",
|
||||
@ -717,58 +872,6 @@
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==2.0.0"
|
||||
},
|
||||
"orjson": {
|
||||
"hashes": [
|
||||
"sha256:03b565c3b93f5d6e001db48b747d31ea3819b89abf041ee10ac6988886d18e01",
|
||||
"sha256:099e81a5975237fda3100f918839af95f42f981447ba8f47adb7b6a3cdb078fa",
|
||||
"sha256:10c0eb7e0c75e1e486c7563fe231b40fdd658a035ae125c6ba651ca3b07936f5",
|
||||
"sha256:1146bf85ea37ac421594107195db8bc77104f74bc83e8ee21a2e58596bfb2f04",
|
||||
"sha256:1670fe88b116c2745a3a30b0f099b699a02bb3482c2591514baf5433819e4f4d",
|
||||
"sha256:185c394ef45b18b9a7d8e8f333606e2e8194a50c6e3c664215aae8cf42c5385e",
|
||||
"sha256:1ad1de7fef79736dde8c3554e75361ec351158a906d747bd901a52a5c9c8d24b",
|
||||
"sha256:235dadefb793ad12f7fa11e98a480db1f7c6469ff9e3da5e73c7809c700d746b",
|
||||
"sha256:28afa96f496474ce60d3340fe8d9a263aa93ea01201cd2bad844c45cd21f5268",
|
||||
"sha256:2d97531cdfe9bdd76d492e69800afd97e5930cb0da6a825646667b2c6c6c0211",
|
||||
"sha256:338fd4f071b242f26e9ca802f443edc588fa4ab60bfa81f38beaedf42eda226c",
|
||||
"sha256:36a10f43c5f3a55c2f680efe07aa93ef4a342d2960dd2b1b7ea2dd764fe4a37c",
|
||||
"sha256:3d21b9983da032505f7050795e98b5d9eee0df903258951566ecc358f6696969",
|
||||
"sha256:51bbcdea96cdefa4a9b4461e690c75ad4e33796530d182bdd5c38980202c134a",
|
||||
"sha256:53ed1c879b10de56f35daf06dbc4a0d9a5db98f6ee853c2dbd3ee9d13e6f302f",
|
||||
"sha256:545d493c1f560d5ccfc134803ceb8955a14c3fcb47bbb4b2fee0232646d0b932",
|
||||
"sha256:584c902ec19ab7928fd5add1783c909094cc53f31ac7acfada817b0847975f26",
|
||||
"sha256:5a35455cc0b0b3a1eaf67224035f5388591ec72b9b6136d66b49a553ce9eb1e6",
|
||||
"sha256:5df58d206e78c40da118a8c14fc189207fffdcb1f21b3b4c9c0c18e839b5a214",
|
||||
"sha256:64c9cc089f127e5875901ac05e5c25aa13cfa5dbbbd9602bda51e5c611d6e3e2",
|
||||
"sha256:68f85ecae7af14a585a563ac741b0547a3f291de81cd1e20903e79f25170458f",
|
||||
"sha256:6970ed7a3126cfed873c5d21ece1cd5d6f83ca6c9afb71bbae21a0b034588d96",
|
||||
"sha256:6b68742c469745d0e6ca5724506858f75e2f1e5b59a4315861f9e2b1df77775a",
|
||||
"sha256:7a5baef8a4284405d96c90c7c62b755e9ef1ada84c2406c24a9ebec86b89f46d",
|
||||
"sha256:7d10cc1b594951522e35a3463da19e899abe6ca95f3c84c69e9e901e0bd93d38",
|
||||
"sha256:85c89131d7b3218db1b24c4abecea92fd6c7f9fab87441cfc342d3acc725d807",
|
||||
"sha256:8a11d459338f96a9aa7f232ba95679fc0c7cedbd1b990d736467894210205c09",
|
||||
"sha256:8c13ca5e2ddded0ce6a927ea5a9f27cae77eee4c75547b4297252cb20c4d30e6",
|
||||
"sha256:9cd684927af3e11b6e754df80b9ffafd9fb6adcaa9d3e8fdd5891be5a5cad51e",
|
||||
"sha256:b2efbd67feff8c1f7728937c0d7f6ca8c25ec81373dc8db4ef394c1d93d13dc5",
|
||||
"sha256:b39e006b00c57125ab974362e740c14a0c6a66ff695bff44615dcf4a70ce2b86",
|
||||
"sha256:b6c8e30adfa52c025f042a87f450a6b9ea29649d828e0fec4858ed5e6caecf63",
|
||||
"sha256:be79e2393679eda6a590638abda16d167754393f5d0850dcbca2d0c3735cebe2",
|
||||
"sha256:c05f16701ab2a4ca146d0bca950af254cb7c02f3c01fca8efbbad82d23b3d9d4",
|
||||
"sha256:c4057c3b511bb8aef605616bd3f1f002a697c7e4da6adf095ca5b84c0fd43595",
|
||||
"sha256:c4a65310ccb5c9910c47b078ba78e2787cb3878cdded1702ac3d0da71ddc5228",
|
||||
"sha256:ca0b3a94ac8d3886c9581b9f9de3ce858263865fdaa383fbc31c310b9eac07c9",
|
||||
"sha256:cc28e90a7cae7fcba2493953cff61da5a52950e78dc2dacfe931a317ee3d8de7",
|
||||
"sha256:cdf7365063e80899ae3a697def1277c17a7df7ccfc979990a403dfe77bb54d40",
|
||||
"sha256:d69858c32f09c3e1ce44b617b3ebba1aba030e777000ebdf72b0d8e365d0b2b3",
|
||||
"sha256:dbead71dbe65f959b7bd8cf91e0e11d5338033eba34c114f69078d59827ee139",
|
||||
"sha256:dcbe82b35d1ac43b0d84072408330fd3295c2896973112d495e7234f7e3da2e1",
|
||||
"sha256:dfc91d4720d48e2a709e9c368d5125b4b5899dced34b5400c3837dadc7d6271b",
|
||||
"sha256:eded5138cc565a9d618e111c6d5c2547bbdd951114eb822f7f6309e04db0fb47",
|
||||
"sha256:f4324929c2dd917598212bfd554757feca3e5e0fa60da08be11b4aa8b90013c1",
|
||||
"sha256:fb66215277a230c456f9038d5e2d84778141643207f85336ef8d2a9da26bd7ca"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==3.10.5"
|
||||
},
|
||||
"osmpythontools": {
|
||||
"hashes": [
|
||||
"sha256:13ff721f760fdad5dd78b4d1461d286b78bba96ee151a7301ee8c11a0c258be9"
|
||||
@ -781,6 +884,7 @@
|
||||
"sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002",
|
||||
"sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==24.1"
|
||||
},
|
||||
@ -821,172 +925,193 @@
|
||||
},
|
||||
"pillow": {
|
||||
"hashes": [
|
||||
"sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c",
|
||||
"sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2",
|
||||
"sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb",
|
||||
"sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d",
|
||||
"sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa",
|
||||
"sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3",
|
||||
"sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1",
|
||||
"sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a",
|
||||
"sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd",
|
||||
"sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8",
|
||||
"sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999",
|
||||
"sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599",
|
||||
"sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936",
|
||||
"sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375",
|
||||
"sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d",
|
||||
"sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b",
|
||||
"sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60",
|
||||
"sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572",
|
||||
"sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3",
|
||||
"sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced",
|
||||
"sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f",
|
||||
"sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b",
|
||||
"sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19",
|
||||
"sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f",
|
||||
"sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d",
|
||||
"sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383",
|
||||
"sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795",
|
||||
"sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355",
|
||||
"sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57",
|
||||
"sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09",
|
||||
"sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b",
|
||||
"sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462",
|
||||
"sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf",
|
||||
"sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f",
|
||||
"sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a",
|
||||
"sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad",
|
||||
"sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9",
|
||||
"sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d",
|
||||
"sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45",
|
||||
"sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994",
|
||||
"sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d",
|
||||
"sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338",
|
||||
"sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463",
|
||||
"sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451",
|
||||
"sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591",
|
||||
"sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c",
|
||||
"sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd",
|
||||
"sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32",
|
||||
"sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9",
|
||||
"sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf",
|
||||
"sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5",
|
||||
"sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828",
|
||||
"sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3",
|
||||
"sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5",
|
||||
"sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2",
|
||||
"sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b",
|
||||
"sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2",
|
||||
"sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475",
|
||||
"sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3",
|
||||
"sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb",
|
||||
"sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef",
|
||||
"sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015",
|
||||
"sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002",
|
||||
"sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170",
|
||||
"sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84",
|
||||
"sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57",
|
||||
"sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f",
|
||||
"sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27",
|
||||
"sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"
|
||||
"sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885",
|
||||
"sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea",
|
||||
"sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df",
|
||||
"sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5",
|
||||
"sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c",
|
||||
"sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d",
|
||||
"sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd",
|
||||
"sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06",
|
||||
"sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908",
|
||||
"sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a",
|
||||
"sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be",
|
||||
"sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0",
|
||||
"sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b",
|
||||
"sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80",
|
||||
"sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a",
|
||||
"sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e",
|
||||
"sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9",
|
||||
"sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696",
|
||||
"sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b",
|
||||
"sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309",
|
||||
"sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e",
|
||||
"sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab",
|
||||
"sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d",
|
||||
"sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060",
|
||||
"sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d",
|
||||
"sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d",
|
||||
"sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4",
|
||||
"sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3",
|
||||
"sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6",
|
||||
"sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb",
|
||||
"sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94",
|
||||
"sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b",
|
||||
"sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496",
|
||||
"sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0",
|
||||
"sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319",
|
||||
"sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b",
|
||||
"sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856",
|
||||
"sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef",
|
||||
"sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680",
|
||||
"sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b",
|
||||
"sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42",
|
||||
"sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e",
|
||||
"sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597",
|
||||
"sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a",
|
||||
"sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8",
|
||||
"sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3",
|
||||
"sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736",
|
||||
"sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da",
|
||||
"sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126",
|
||||
"sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd",
|
||||
"sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5",
|
||||
"sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b",
|
||||
"sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026",
|
||||
"sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b",
|
||||
"sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc",
|
||||
"sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46",
|
||||
"sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2",
|
||||
"sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c",
|
||||
"sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe",
|
||||
"sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984",
|
||||
"sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a",
|
||||
"sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70",
|
||||
"sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca",
|
||||
"sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b",
|
||||
"sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91",
|
||||
"sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3",
|
||||
"sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84",
|
||||
"sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1",
|
||||
"sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5",
|
||||
"sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be",
|
||||
"sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f",
|
||||
"sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc",
|
||||
"sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9",
|
||||
"sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e",
|
||||
"sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141",
|
||||
"sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef",
|
||||
"sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22",
|
||||
"sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27",
|
||||
"sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e",
|
||||
"sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==10.3.0"
|
||||
"version": "==10.4.0"
|
||||
},
|
||||
"pydantic": {
|
||||
"hashes": [
|
||||
"sha256:0c84efd9548d545f63ac0060c1e4d39bb9b14db8b3c0652338aecc07b5adec52",
|
||||
"sha256:ee8538d41ccb9c0a9ad3e0e5f07bf15ed8015b481ced539a1759d8cc89ae90d0"
|
||||
"sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a",
|
||||
"sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==2.7.4"
|
||||
"version": "==2.8.2"
|
||||
},
|
||||
"pydantic-core": {
|
||||
"hashes": [
|
||||
"sha256:01dd777215e2aa86dfd664daed5957704b769e726626393438f9c87690ce78c3",
|
||||
"sha256:0eb2a4f660fcd8e2b1c90ad566db2b98d7f3f4717c64fe0a83e0adb39766d5b8",
|
||||
"sha256:0fbbdc827fe5e42e4d196c746b890b3d72876bdbf160b0eafe9f0334525119c8",
|
||||
"sha256:123c3cec203e3f5ac7b000bd82235f1a3eced8665b63d18be751f115588fea30",
|
||||
"sha256:14601cdb733d741b8958224030e2bfe21a4a881fb3dd6fbb21f071cabd48fa0a",
|
||||
"sha256:18f469a3d2a2fdafe99296a87e8a4c37748b5080a26b806a707f25a902c040a8",
|
||||
"sha256:19894b95aacfa98e7cb093cd7881a0c76f55731efad31073db4521e2b6ff5b7d",
|
||||
"sha256:1b4de2e51bbcb61fdebd0ab86ef28062704f62c82bbf4addc4e37fa4b00b7cbc",
|
||||
"sha256:1d886dc848e60cb7666f771e406acae54ab279b9f1e4143babc9c2258213daa2",
|
||||
"sha256:1f4d26ceb5eb9eed4af91bebeae4b06c3fb28966ca3a8fb765208cf6b51102ab",
|
||||
"sha256:21a5e440dbe315ab9825fcd459b8814bb92b27c974cbc23c3e8baa2b76890077",
|
||||
"sha256:293afe532740370aba8c060882f7d26cfd00c94cae32fd2e212a3a6e3b7bc15e",
|
||||
"sha256:2f5966897e5461f818e136b8451d0551a2e77259eb0f73a837027b47dc95dab9",
|
||||
"sha256:2fd41f6eff4c20778d717af1cc50eca52f5afe7805ee530a4fbd0bae284f16e9",
|
||||
"sha256:2fdf2156aa3d017fddf8aea5adfba9f777db1d6022d392b682d2a8329e087cef",
|
||||
"sha256:3c40d4eaad41f78e3bbda31b89edc46a3f3dc6e171bf0ecf097ff7a0ffff7cb1",
|
||||
"sha256:43d447dd2ae072a0065389092a231283f62d960030ecd27565672bd40746c507",
|
||||
"sha256:44a688331d4a4e2129140a8118479443bd6f1905231138971372fcde37e43528",
|
||||
"sha256:44c7486a4228413c317952e9d89598bcdfb06399735e49e0f8df643e1ccd0558",
|
||||
"sha256:44cd83ab6a51da80fb5adbd9560e26018e2ac7826f9626bc06ca3dc074cd198b",
|
||||
"sha256:46387e38bd641b3ee5ce247563b60c5ca098da9c56c75c157a05eaa0933ed154",
|
||||
"sha256:4701b19f7e3a06ea655513f7938de6f108123bf7c86bbebb1196eb9bd35cf724",
|
||||
"sha256:4748321b5078216070b151d5271ef3e7cc905ab170bbfd27d5c83ee3ec436695",
|
||||
"sha256:4b06beb3b3f1479d32befd1f3079cc47b34fa2da62457cdf6c963393340b56e9",
|
||||
"sha256:4d0dcc59664fcb8974b356fe0a18a672d6d7cf9f54746c05f43275fc48636851",
|
||||
"sha256:4e99bc050fe65c450344421017f98298a97cefc18c53bb2f7b3531eb39bc7805",
|
||||
"sha256:509daade3b8649f80d4e5ff21aa5673e4ebe58590b25fe42fac5f0f52c6f034a",
|
||||
"sha256:51991a89639a912c17bef4b45c87bd83593aee0437d8102556af4885811d59f5",
|
||||
"sha256:53db086f9f6ab2b4061958d9c276d1dbe3690e8dd727d6abf2321d6cce37fa94",
|
||||
"sha256:564d7922e4b13a16b98772441879fcdcbe82ff50daa622d681dd682175ea918c",
|
||||
"sha256:574d92eac874f7f4db0ca653514d823a0d22e2354359d0759e3f6a406db5d55d",
|
||||
"sha256:578e24f761f3b425834f297b9935e1ce2e30f51400964ce4801002435a1b41ef",
|
||||
"sha256:59ff3e89f4eaf14050c8022011862df275b552caef8082e37b542b066ce1ff26",
|
||||
"sha256:5f09baa656c904807e832cf9cce799c6460c450c4ad80803517032da0cd062e2",
|
||||
"sha256:6891a2ae0e8692679c07728819b6e2b822fb30ca7445f67bbf6509b25a96332c",
|
||||
"sha256:6a750aec7bf431517a9fd78cb93c97b9b0c496090fee84a47a0d23668976b4b0",
|
||||
"sha256:6f5c4d41b2771c730ea1c34e458e781b18cc668d194958e0112455fff4e402b2",
|
||||
"sha256:77450e6d20016ec41f43ca4a6c63e9fdde03f0ae3fe90e7c27bdbeaece8b1ed4",
|
||||
"sha256:81b5efb2f126454586d0f40c4d834010979cb80785173d1586df845a632e4e6d",
|
||||
"sha256:823be1deb01793da05ecb0484d6c9e20baebb39bd42b5d72636ae9cf8350dbd2",
|
||||
"sha256:834b5230b5dfc0c1ec37b2fda433b271cbbc0e507560b5d1588e2cc1148cf1ce",
|
||||
"sha256:847a35c4d58721c5dc3dba599878ebbdfd96784f3fb8bb2c356e123bdcd73f34",
|
||||
"sha256:86110d7e1907ab36691f80b33eb2da87d780f4739ae773e5fc83fb272f88825f",
|
||||
"sha256:8951eee36c57cd128f779e641e21eb40bc5073eb28b2d23f33eb0ef14ffb3f5d",
|
||||
"sha256:8a7164fe2005d03c64fd3b85649891cd4953a8de53107940bf272500ba8a788b",
|
||||
"sha256:8b8bab4c97248095ae0c4455b5a1cd1cdd96e4e4769306ab19dda135ea4cdb07",
|
||||
"sha256:90afc12421df2b1b4dcc975f814e21bc1754640d502a2fbcc6d41e77af5ec312",
|
||||
"sha256:938cb21650855054dc54dfd9120a851c974f95450f00683399006aa6e8abb057",
|
||||
"sha256:942ba11e7dfb66dc70f9ae66b33452f51ac7bb90676da39a7345e99ffb55402d",
|
||||
"sha256:972658f4a72d02b8abfa2581d92d59f59897d2e9f7e708fdabe922f9087773af",
|
||||
"sha256:97736815b9cc893b2b7f663628e63f436018b75f44854c8027040e05230eeddb",
|
||||
"sha256:98906207f29bc2c459ff64fa007afd10a8c8ac080f7e4d5beff4c97086a3dabd",
|
||||
"sha256:99457f184ad90235cfe8461c4d70ab7dd2680e28821c29eca00252ba90308c78",
|
||||
"sha256:a0d829524aaefdebccb869eed855e2d04c21d2d7479b6cada7ace5448416597b",
|
||||
"sha256:a2fdd81edd64342c85ac7cf2753ccae0b79bf2dfa063785503cb85a7d3593223",
|
||||
"sha256:a55b5b16c839df1070bc113c1f7f94a0af4433fcfa1b41799ce7606e5c79ce0a",
|
||||
"sha256:a642295cd0c8df1b86fc3dced1d067874c353a188dc8e0f744626d49e9aa51c4",
|
||||
"sha256:ab86ce7c8f9bea87b9d12c7f0af71102acbf5ecbc66c17796cff45dae54ef9a5",
|
||||
"sha256:abc267fa9837245cc28ea6929f19fa335f3dc330a35d2e45509b6566dc18be23",
|
||||
"sha256:ae1d6df168efb88d7d522664693607b80b4080be6750c913eefb77e34c12c71a",
|
||||
"sha256:b2ebef0e0b4454320274f5e83a41844c63438fdc874ea40a8b5b4ecb7693f1c4",
|
||||
"sha256:b48ece5bde2e768197a2d0f6e925f9d7e3e826f0ad2271120f8144a9db18d5c8",
|
||||
"sha256:b7cdf28938ac6b8b49ae5e92f2735056a7ba99c9b110a474473fd71185c1af5d",
|
||||
"sha256:bb4462bd43c2460774914b8525f79b00f8f407c945d50881568f294c1d9b4443",
|
||||
"sha256:bc4ff9805858bd54d1a20efff925ccd89c9d2e7cf4986144b30802bf78091c3e",
|
||||
"sha256:c1322d7dd74713dcc157a2b7898a564ab091ca6c58302d5c7b4c07296e3fd00f",
|
||||
"sha256:c67598100338d5d985db1b3d21f3619ef392e185e71b8d52bceacc4a7771ea7e",
|
||||
"sha256:ca26a1e73c48cfc54c4a76ff78df3727b9d9f4ccc8dbee4ae3f73306a591676d",
|
||||
"sha256:d323a01da91851a4f17bf592faf46149c9169d68430b3146dcba2bb5e5719abc",
|
||||
"sha256:dc1803ac5c32ec324c5261c7209e8f8ce88e83254c4e1aebdc8b0a39f9ddb443",
|
||||
"sha256:e00a3f196329e08e43d99b79b286d60ce46bed10f2280d25a1718399457e06be",
|
||||
"sha256:e85637bc8fe81ddb73fda9e56bab24560bdddfa98aa64f87aaa4e4b6730c23d2",
|
||||
"sha256:e858ac0a25074ba4bce653f9b5d0a85b7456eaddadc0ce82d3878c22489fa4ee",
|
||||
"sha256:eae237477a873ab46e8dd748e515c72c0c804fb380fbe6c85533c7de51f23a8f",
|
||||
"sha256:ebef0dd9bf9b812bf75bda96743f2a6c5734a02092ae7f721c048d156d5fabae",
|
||||
"sha256:ec3beeada09ff865c344ff3bc2f427f5e6c26401cc6113d77e372c3fdac73864",
|
||||
"sha256:f76d0ad001edd426b92233d45c746fd08f467d56100fd8f30e9ace4b005266e4",
|
||||
"sha256:f85d05aa0918283cf29a30b547b4df2fbb56b45b135f9e35b6807cb28bc47951",
|
||||
"sha256:f9899c94762343f2cc2fc64c13e7cae4c3cc65cdfc87dd810a31654c9b7358cc"
|
||||
"sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d",
|
||||
"sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f",
|
||||
"sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686",
|
||||
"sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482",
|
||||
"sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006",
|
||||
"sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83",
|
||||
"sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6",
|
||||
"sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88",
|
||||
"sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86",
|
||||
"sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a",
|
||||
"sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6",
|
||||
"sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a",
|
||||
"sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6",
|
||||
"sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6",
|
||||
"sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43",
|
||||
"sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c",
|
||||
"sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4",
|
||||
"sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e",
|
||||
"sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203",
|
||||
"sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd",
|
||||
"sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1",
|
||||
"sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24",
|
||||
"sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc",
|
||||
"sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc",
|
||||
"sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3",
|
||||
"sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598",
|
||||
"sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98",
|
||||
"sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331",
|
||||
"sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2",
|
||||
"sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a",
|
||||
"sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6",
|
||||
"sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688",
|
||||
"sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91",
|
||||
"sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa",
|
||||
"sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b",
|
||||
"sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0",
|
||||
"sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840",
|
||||
"sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c",
|
||||
"sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd",
|
||||
"sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3",
|
||||
"sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231",
|
||||
"sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1",
|
||||
"sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953",
|
||||
"sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250",
|
||||
"sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a",
|
||||
"sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2",
|
||||
"sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20",
|
||||
"sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434",
|
||||
"sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab",
|
||||
"sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703",
|
||||
"sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a",
|
||||
"sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2",
|
||||
"sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac",
|
||||
"sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611",
|
||||
"sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121",
|
||||
"sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e",
|
||||
"sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b",
|
||||
"sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09",
|
||||
"sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906",
|
||||
"sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9",
|
||||
"sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7",
|
||||
"sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b",
|
||||
"sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987",
|
||||
"sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c",
|
||||
"sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b",
|
||||
"sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e",
|
||||
"sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237",
|
||||
"sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1",
|
||||
"sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19",
|
||||
"sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b",
|
||||
"sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad",
|
||||
"sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0",
|
||||
"sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94",
|
||||
"sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312",
|
||||
"sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f",
|
||||
"sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669",
|
||||
"sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1",
|
||||
"sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe",
|
||||
"sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99",
|
||||
"sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a",
|
||||
"sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a",
|
||||
"sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52",
|
||||
"sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c",
|
||||
"sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad",
|
||||
"sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1",
|
||||
"sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a",
|
||||
"sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f",
|
||||
"sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a",
|
||||
"sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==2.18.4"
|
||||
"version": "==2.20.1"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
@ -1034,6 +1159,15 @@
|
||||
],
|
||||
"version": "==2024.1"
|
||||
},
|
||||
"pywikibot": {
|
||||
"hashes": [
|
||||
"sha256:3f4fbc57f1765aa0fa1ccf84125bcfa475cae95b9cc0291867b751f3d4ac8fa2",
|
||||
"sha256:a26d918cf88ef56fdb1421b65b09def200cc28031cdc922d72a4198fbfddd225"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_full_version >= '3.7.0'",
|
||||
"version": "==9.2.1"
|
||||
},
|
||||
"pyyaml": {
|
||||
"hashes": [
|
||||
"sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5",
|
||||
@ -1090,6 +1224,15 @@
|
||||
],
|
||||
"version": "==6.0.1"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760",
|
||||
"sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==2.32.3"
|
||||
},
|
||||
"rich": {
|
||||
"hashes": [
|
||||
"sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222",
|
||||
@ -1100,83 +1243,78 @@
|
||||
},
|
||||
"scipy": {
|
||||
"hashes": [
|
||||
"sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d",
|
||||
"sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c",
|
||||
"sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca",
|
||||
"sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9",
|
||||
"sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54",
|
||||
"sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16",
|
||||
"sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2",
|
||||
"sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5",
|
||||
"sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59",
|
||||
"sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326",
|
||||
"sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b",
|
||||
"sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1",
|
||||
"sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d",
|
||||
"sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24",
|
||||
"sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627",
|
||||
"sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c",
|
||||
"sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa",
|
||||
"sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949",
|
||||
"sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989",
|
||||
"sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004",
|
||||
"sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f",
|
||||
"sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884",
|
||||
"sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299",
|
||||
"sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94",
|
||||
"sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f"
|
||||
"sha256:076c27284c768b84a45dcf2e914d4000aac537da74236a0d45d82c6fa4b7b3c0",
|
||||
"sha256:07e179dc0205a50721022344fb85074f772eadbda1e1b3eecdc483f8033709b7",
|
||||
"sha256:176c6f0d0470a32f1b2efaf40c3d37a24876cebf447498a4cefb947a79c21e9d",
|
||||
"sha256:42470ea0195336df319741e230626b6225a740fd9dce9642ca13e98f667047c0",
|
||||
"sha256:4c4161597c75043f7154238ef419c29a64ac4a7c889d588ea77690ac4d0d9b20",
|
||||
"sha256:5b083c8940028bb7e0b4172acafda6df762da1927b9091f9611b0bcd8676f2bc",
|
||||
"sha256:64b2ff514a98cf2bb734a9f90d32dc89dc6ad4a4a36a312cd0d6327170339eb0",
|
||||
"sha256:65df4da3c12a2bb9ad52b86b4dcf46813e869afb006e58be0f516bc370165159",
|
||||
"sha256:687af0a35462402dd851726295c1a5ae5f987bd6e9026f52e9505994e2f84ef6",
|
||||
"sha256:6a9c9a9b226d9a21e0a208bdb024c3982932e43811b62d202aaf1bb59af264b1",
|
||||
"sha256:6d056a8709ccda6cf36cdd2eac597d13bc03dba38360f418560a93050c76a16e",
|
||||
"sha256:7d3da42fbbbb860211a811782504f38ae7aaec9de8764a9bef6b262de7a2b50f",
|
||||
"sha256:7e911933d54ead4d557c02402710c2396529540b81dd554fc1ba270eb7308484",
|
||||
"sha256:94c164a9e2498e68308e6e148646e486d979f7fcdb8b4cf34b5441894bdb9caf",
|
||||
"sha256:9e3154691b9f7ed73778d746da2df67a19d046a6c8087c8b385bc4cdb2cfca74",
|
||||
"sha256:9eee2989868e274aae26125345584254d97c56194c072ed96cb433f32f692ed8",
|
||||
"sha256:a01cc03bcdc777c9da3cfdcc74b5a75caffb48a6c39c8450a9a05f82c4250a14",
|
||||
"sha256:a7d46c3e0aea5c064e734c3eac5cf9eb1f8c4ceee756262f2c7327c4c2691c86",
|
||||
"sha256:ad36af9626d27a4326c8e884917b7ec321d8a1841cd6dacc67d2a9e90c2f0359",
|
||||
"sha256:b5923f48cb840380f9854339176ef21763118a7300a88203ccd0bdd26e58527b",
|
||||
"sha256:bbc0471b5f22c11c389075d091d3885693fd3f5e9a54ce051b46308bc787e5d4",
|
||||
"sha256:bff2438ea1330e06e53c424893ec0072640dac00f29c6a43a575cbae4c99b2b9",
|
||||
"sha256:c40003d880f39c11c1edbae8144e3813904b10514cd3d3d00c277ae996488cdb",
|
||||
"sha256:d91db2c41dd6c20646af280355d41dfa1ec7eead235642178bd57635a3f82209",
|
||||
"sha256:f0a50da861a7ec4573b7c716b2ebdcdf142b66b756a0d392c236ae568b3a93fb"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.9'",
|
||||
"version": "==1.13.1"
|
||||
"markers": "python_version >= '3.10'",
|
||||
"version": "==1.14.0"
|
||||
},
|
||||
"shapely": {
|
||||
"hashes": [
|
||||
"sha256:011b77153906030b795791f2fdfa2d68f1a8d7e40bce78b029782ade3afe4f2f",
|
||||
"sha256:03152442d311a5e85ac73b39680dd64a9892fa42bb08fd83b3bab4fe6999bfa0",
|
||||
"sha256:05ffd6491e9e8958b742b0e2e7c346635033d0a5f1a0ea083547fcc854e5d5cf",
|
||||
"sha256:0776c92d584f72f1e584d2e43cfc5542c2f3dd19d53f70df0900fda643f4bae6",
|
||||
"sha256:263bcf0c24d7a57c80991e64ab57cba7a3906e31d2e21b455f493d4aab534aaa",
|
||||
"sha256:2fbdc1140a7d08faa748256438291394967aa54b40009f54e8d9825e75ef6113",
|
||||
"sha256:30982f79f21bb0ff7d7d4a4e531e3fcaa39b778584c2ce81a147f95be1cd58c9",
|
||||
"sha256:31c19a668b5a1eadab82ff070b5a260478ac6ddad3a5b62295095174a8d26398",
|
||||
"sha256:3f9103abd1678cb1b5f7e8e1af565a652e036844166c91ec031eeb25c5ca8af0",
|
||||
"sha256:41388321a73ba1a84edd90d86ecc8bfed55e6a1e51882eafb019f45895ec0f65",
|
||||
"sha256:4310b5494271e18580d61022c0857eb85d30510d88606fa3b8314790df7f367d",
|
||||
"sha256:464157509ce4efa5ff285c646a38b49f8c5ef8d4b340f722685b09bb033c5ccf",
|
||||
"sha256:485246fcdb93336105c29a5cfbff8a226949db37b7473c89caa26c9bae52a242",
|
||||
"sha256:489c19152ec1f0e5c5e525356bcbf7e532f311bff630c9b6bc2db6f04da6a8b9",
|
||||
"sha256:4f2ab0faf8188b9f99e6a273b24b97662194160cc8ca17cf9d1fb6f18d7fb93f",
|
||||
"sha256:55a38dcd1cee2f298d8c2ebc60fc7d39f3b4535684a1e9e2f39a80ae88b0cea7",
|
||||
"sha256:58b0ecc505bbe49a99551eea3f2e8a9b3b24b3edd2a4de1ac0dc17bc75c9ec07",
|
||||
"sha256:5af4cd0d8cf2912bd95f33586600cac9c4b7c5053a036422b97cfe4728d2eb53",
|
||||
"sha256:5bbd974193e2cc274312da16b189b38f5f128410f3377721cadb76b1e8ca5328",
|
||||
"sha256:5c4849916f71dc44e19ed370421518c0d86cf73b26e8656192fcfcda08218fbd",
|
||||
"sha256:5dc736127fac70009b8d309a0eeb74f3e08979e530cf7017f2f507ef62e6cfb8",
|
||||
"sha256:63f3a80daf4f867bd80f5c97fbe03314348ac1b3b70fb1c0ad255a69e3749879",
|
||||
"sha256:674d7baf0015a6037d5758496d550fc1946f34bfc89c1bf247cabdc415d7747e",
|
||||
"sha256:6cd4ccecc5ea5abd06deeaab52fcdba372f649728050c6143cc405ee0c166679",
|
||||
"sha256:790a168a808bd00ee42786b8ba883307c0e3684ebb292e0e20009588c426da47",
|
||||
"sha256:7d56ce3e2a6a556b59a288771cf9d091470116867e578bebced8bfc4147fbfd7",
|
||||
"sha256:841f93a0e31e4c64d62ea570d81c35de0f6cea224568b2430d832967536308e6",
|
||||
"sha256:8de4578e838a9409b5b134a18ee820730e507b2d21700c14b71a2b0757396acc",
|
||||
"sha256:92a41d936f7d6743f343be265ace93b7c57f5b231e21b9605716f5a47c2879e7",
|
||||
"sha256:9831816a5d34d5170aa9ed32a64982c3d6f4332e7ecfe62dc97767e163cb0b17",
|
||||
"sha256:994c244e004bc3cfbea96257b883c90a86e8cbd76e069718eb4c6b222a56f78b",
|
||||
"sha256:9dab4c98acfb5fb85f5a20548b5c0abe9b163ad3525ee28822ffecb5c40e724c",
|
||||
"sha256:b79bbd648664aa6f44ef018474ff958b6b296fed5c2d42db60078de3cffbc8aa",
|
||||
"sha256:c3e700abf4a37b7b8b90532fa6ed5c38a9bfc777098bc9fbae5ec8e618ac8f30",
|
||||
"sha256:c52ed79f683f721b69a10fb9e3d940a468203f5054927215586c5d49a072de8d",
|
||||
"sha256:c75c98380b1ede1cae9a252c6dc247e6279403fae38c77060a5e6186c95073ac",
|
||||
"sha256:d2b4431f522b277c79c34b65da128029a9955e4481462cbf7ebec23aab61fc58",
|
||||
"sha256:ddf4a9bfaac643e62702ed662afc36f6abed2a88a21270e891038f9a19bc08fc",
|
||||
"sha256:de0205cb21ad5ddaef607cda9a3191eadd1e7a62a756ea3a356369675230ac35",
|
||||
"sha256:ec555c9d0db12d7fd777ba3f8b75044c73e576c720a851667432fabb7057da6c",
|
||||
"sha256:fb5cdcbbe3080181498931b52a91a21a781a35dcb859da741c0345c6402bf00c"
|
||||
"sha256:03bd7b5fa5deb44795cc0a503999d10ae9d8a22df54ae8d4a4cd2e8a93466195",
|
||||
"sha256:06efe39beafde3a18a21dde169d32f315c57da962826a6d7d22630025200c5e6",
|
||||
"sha256:0f8e71bb9a46814019f6644c4e2560a09d44b80100e46e371578f35eaaa9da1c",
|
||||
"sha256:1b65365cfbf657604e50d15161ffcc68de5cdb22a601bbf7823540ab4918a98d",
|
||||
"sha256:1e5cb5ee72f1bc7ace737c9ecd30dc174a5295fae412972d3879bac2e82c8fae",
|
||||
"sha256:21f64e647a025b61b19585d2247137b3a38a35314ea68c66aaf507a1c03ef6fe",
|
||||
"sha256:2e119444bc27ca33e786772b81760f2028d930ac55dafe9bc50ef538b794a8e1",
|
||||
"sha256:2ff9521991ed9e201c2e923da014e766c1aa04771bc93e6fe97c27dcf0d40ace",
|
||||
"sha256:30e8737983c9d954cd17feb49eb169f02f1da49e24e5171122cf2c2b62d65c95",
|
||||
"sha256:35110e80070d664781ec7955c7de557456b25727a0257b354830abb759bf8311",
|
||||
"sha256:3ac7dc1350700c139c956b03d9c3df49a5b34aaf91d024d1510a09717ea39199",
|
||||
"sha256:401cb794c5067598f50518e5a997e270cd7642c4992645479b915c503866abed",
|
||||
"sha256:4461509afdb15051e73ab178fae79974387f39c47ab635a7330d7fee02c68a3f",
|
||||
"sha256:45211276900c4790d6bfc6105cbf1030742da67594ea4161a9ce6812a6721e68",
|
||||
"sha256:49b299b91557b04acb75e9732645428470825061f871a2edc36b9417d66c1fc5",
|
||||
"sha256:4c83a36f12ec8dee2066946d98d4d841ab6512a6ed7eb742e026a64854019b5f",
|
||||
"sha256:5bbfb048a74cf273db9091ff3155d373020852805a37dfc846ab71dde4be93ec",
|
||||
"sha256:6c6b78c0007a34ce7144f98b7418800e0a6a5d9a762f2244b00ea560525290c9",
|
||||
"sha256:7545a39c55cad1562be302d74c74586f79e07b592df8ada56b79a209731c0219",
|
||||
"sha256:798090b426142df2c5258779c1d8d5734ec6942f778dab6c6c30cfe7f3bf64ff",
|
||||
"sha256:7e8cf5c252fac1ea51b3162be2ec3faddedc82c256a1160fc0e8ddbec81b06d2",
|
||||
"sha256:7fed9dbfbcfec2682d9a047b9699db8dcc890dfca857ecba872c42185fc9e64e",
|
||||
"sha256:8203a8b2d44dcb366becbc8c3d553670320e4acf0616c39e218c9561dd738d92",
|
||||
"sha256:89d34787c44f77a7d37d55ae821f3a784fa33592b9d217a45053a93ade899375",
|
||||
"sha256:89e640c2cd37378480caf2eeda9a51be64201f01f786d127e78eaeff091ec897",
|
||||
"sha256:8af6f7260f809c0862741ad08b1b89cb60c130ae30efab62320bbf4ee9cc71fa",
|
||||
"sha256:93be600cbe2fbaa86c8eb70656369f2f7104cd231f0d6585c7d0aa555d6878b8",
|
||||
"sha256:9a4492a2b2ccbeaebf181e7310d2dfff4fdd505aef59d6cb0f217607cb042fb3",
|
||||
"sha256:b5870633f8e684bf6d1ae4df527ddcb6f3895f7b12bced5c13266ac04f47d231",
|
||||
"sha256:b714a840402cde66fd7b663bb08cacb7211fa4412ea2a209688f671e0d0631fd",
|
||||
"sha256:bff2366bc786bfa6cb353d6b47d0443c570c32776612e527ee47b6df63fcfe32",
|
||||
"sha256:d5251c28a29012e92de01d2e84f11637eb1d48184ee8f22e2df6c8c578d26760",
|
||||
"sha256:e91ee179af539100eb520281ba5394919067c6b51824e6ab132ad4b3b3e76dd0",
|
||||
"sha256:f5456dd522800306ba3faef77c5ba847ec30a0bd73ab087a25e0acdd4db2514f",
|
||||
"sha256:ff7731fea5face9ec08a861ed351734a79475631b7540ceb0b66fb9732a5f529",
|
||||
"sha256:ff9e520af0c5a578e174bca3c18713cd47a6c6a15b6cf1f50ac17dc8bb8db6a2"
|
||||
],
|
||||
"index": "pypi",
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==2.0.4"
|
||||
"version": "==2.0.5"
|
||||
},
|
||||
"shellingham": {
|
||||
"hashes": [
|
||||
@ -1326,6 +1464,14 @@
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==5.10.0"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472",
|
||||
"sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"
|
||||
],
|
||||
"markers": "python_version >= '3.8'",
|
||||
"version": "==2.2.2"
|
||||
},
|
||||
"uvicorn": {
|
||||
"extras": [
|
||||
"standard"
|
||||
|
@ -8,4 +8,5 @@ geological
|
||||
'tourism'='alpine_hut'
|
||||
'tourism'='viewpoint'
|
||||
'tourism'='zoo'
|
||||
'tourism'='artwork'
|
||||
'waterway'='waterfall'
|
@ -1,8 +1,11 @@
|
||||
'tourism'='museum'
|
||||
'tourism'='attraction'
|
||||
'tourism'='gallery'
|
||||
'tourism'='artwork'
|
||||
historic
|
||||
'amenity'='planetarium'
|
||||
'amenity'='place_of_worship'
|
||||
'amenity'='fountain'
|
||||
'water'='reflecting_pool'
|
||||
'water'='reflecting_pool'
|
||||
# 'tourism'='attraction' might be a bit too broad
|
||||
# historic as well
|
@ -3,6 +3,10 @@ import json, os
|
||||
|
||||
from typing import List, Tuple, Optional
|
||||
from OSMPythonTools.overpass import Overpass, overpassQueryBuilder
|
||||
from pywikibot import ItemPage, Site
|
||||
from pywikibot import config
|
||||
config.put_throttle = 0
|
||||
config.maxlag = 0
|
||||
|
||||
from structs.landmarks import Landmark, LandmarkType
|
||||
from structs.preferences import Preferences, Preference
|
||||
@ -43,31 +47,6 @@ def generate_landmarks(preferences: Preferences, coordinates: Tuple[float, float
|
||||
return L, take_most_important(L)
|
||||
|
||||
|
||||
"""def generate_landmarks(preferences: Preferences, city_country: str = None, coordinates: Tuple[float, float] = None) -> Tuple[List[Landmark], List[Landmark]] :
|
||||
|
||||
l_sights, l_nature, l_shop = get_amenities()
|
||||
L = []
|
||||
|
||||
# List for sightseeing
|
||||
if preferences.sightseeing.score != 0 :
|
||||
L1 = get_landmarks(l_sights, SIGHTSEEING, city_country=city_country, coordinates=coordinates)
|
||||
correct_score(L1, preferences.sightseeing)
|
||||
L += L1
|
||||
|
||||
# List for nature
|
||||
if preferences.nature.score != 0 :
|
||||
L2 = get_landmarks(l_nature, NATURE, city_country=city_country, coordinates=coordinates)
|
||||
correct_score(L2, preferences.nature)
|
||||
L += L2
|
||||
|
||||
# List for shopping
|
||||
if preferences.shopping.score != 0 :
|
||||
L3 = get_landmarks(l_shop, SHOPPING, city_country=city_country, coordinates=coordinates)
|
||||
correct_score(L3, preferences.shopping)
|
||||
L += L3
|
||||
|
||||
return remove_duplicates(L), take_most_important(L)
|
||||
"""
|
||||
# Helper function to gather the amenities list
|
||||
def get_amenities() -> List[List[str]] :
|
||||
|
||||
@ -87,7 +66,8 @@ def get_list(path: str) -> List[str] :
|
||||
|
||||
amenities = []
|
||||
for line in content :
|
||||
amenities.append(line.strip('\n'))
|
||||
if not line.startswith('#') :
|
||||
amenities.append(line.strip('\n'))
|
||||
|
||||
return amenities
|
||||
|
||||
@ -173,7 +153,7 @@ def correct_score(L: List[Landmark], preference: Preference) :
|
||||
raise TypeError(f"LandmarkType {preference.type} does not match the type of Landmark {L[0].name}")
|
||||
|
||||
for elem in L :
|
||||
elem.attractiveness = int(elem.attractiveness*preference.score/500) # arbitrary computation
|
||||
elem.attractiveness = int(elem.attractiveness*preference.score/5) # arbitrary computation
|
||||
|
||||
|
||||
# Function to count elements within a certain radius of a location
|
||||
@ -192,20 +172,24 @@ def count_elements_within_radius(coordinates: Tuple[float, float], radius: int)
|
||||
try :
|
||||
overpass = Overpass()
|
||||
radius_result = overpass.query(radius_query)
|
||||
return radius_result.countElements()
|
||||
N_elem = radius_result.countWays() + radius_result.countRelations()
|
||||
#print(f"There are {N_elem} ways/relations within 50m")
|
||||
if N_elem is None :
|
||||
return 0
|
||||
return N_elem
|
||||
|
||||
except :
|
||||
return None
|
||||
return 0
|
||||
|
||||
|
||||
# Creates a bounding box around given coordinates
|
||||
# Creates a bounding box around given coordinates, side_length in meters
|
||||
def create_bbox(coordinates: Tuple[float, float], side_length: int) -> Tuple[float, float, float, float]:
|
||||
|
||||
|
||||
lat = coordinates[0]
|
||||
lon = coordinates[1]
|
||||
|
||||
# Half the side length in km (since it's a square bbox)
|
||||
half_side_length_km = side_length / 2.0
|
||||
half_side_length_km = side_length / 2 / 1000
|
||||
|
||||
# Convert distance to degrees
|
||||
lat_diff = half_side_length_km / 111 # 1 degree latitude is approximately 111 km
|
||||
@ -260,106 +244,65 @@ def get_landmarks(list_amenity: list, landmarktype: LandmarkType, coordinates: T
|
||||
# skip if part of another building
|
||||
if 'building:part' in elem.tags().keys() and elem.tag('building:part') == 'yes':
|
||||
continue
|
||||
|
||||
|
||||
else :
|
||||
osm_type = elem.type() # Add type : 'way' or 'relation'
|
||||
osm_id = elem.id() # Add OSM id
|
||||
elem_type = landmarktype # Add the landmark type as 'sightseeing
|
||||
elem_type = landmarktype # Add the landmark type as 'sightseeing,
|
||||
n_tags = len(elem.tags().keys()) # Add number of tags
|
||||
|
||||
|
||||
# remove specific tags
|
||||
skip = False
|
||||
for tag in elem.tags().keys() :
|
||||
if "pay" in tag :
|
||||
n_tags -= 1 # discard payment options for tags
|
||||
|
||||
if "disused" in tag :
|
||||
skip = True # skip disused amenities
|
||||
break
|
||||
|
||||
if "wikipedia" in tag :
|
||||
n_tags += 3 # wikipedia entries count more
|
||||
|
||||
if tag == "wikidata" :
|
||||
Q = elem.tag('wikidata')
|
||||
site = Site("wikidata", "wikidata")
|
||||
item = ItemPage(site, Q)
|
||||
item.get()
|
||||
n_languages = len(item.labels)
|
||||
n_tags += n_languages/10
|
||||
|
||||
if elem_type != LandmarkType(landmark_type="nature") :
|
||||
if "leisure" in tag and elem.tag('leisure') == "park":
|
||||
elem_type = LandmarkType(landmark_type="nature")
|
||||
|
||||
if amenity not in ["'shop'='department_store'", "'shop'='mall'"] :
|
||||
if "shop" in tag :
|
||||
skip = True
|
||||
break
|
||||
|
||||
if tag == "building" and elem.tag('building') in ['retail', 'supermarket', 'parking']:
|
||||
skip = True
|
||||
break
|
||||
|
||||
if skip:
|
||||
continue
|
||||
|
||||
# Add score of given landmark based on the number of surrounding elements. Penalty for churches as there are A LOT
|
||||
if amenity == "'amenity'='place_of_worship'" :
|
||||
score = int((count_elements_within_radius(location, radius) + n_tags*tag_coeff )*church_coeff)
|
||||
#score = int((count_elements_within_radius(location, radius) + (n_tags*tag_coeff) )*church_coeff)
|
||||
score = int((count_elements_within_radius(location, radius) + ((n_tags**1.2)*tag_coeff) )*church_coeff)
|
||||
elif amenity == "'leisure'='park'" :
|
||||
score = int((count_elements_within_radius(location, radius) + n_tags*tag_coeff )*park_coeff)
|
||||
score = int((count_elements_within_radius(location, radius) + ((n_tags**1.2)*tag_coeff) )*park_coeff)
|
||||
else :
|
||||
score = count_elements_within_radius(location, radius) + n_tags*tag_coeff
|
||||
score = int(count_elements_within_radius(location, radius) + ((n_tags**1.2)*tag_coeff))
|
||||
|
||||
if score is not None :
|
||||
# Generate the landmark and append it to the list
|
||||
landmark = Landmark(name=name, type=elem_type, location=location, osm_type=osm_type, osm_id=osm_id, attractiveness=score, must_do=False, n_tags=n_tags)
|
||||
#print(f"There are {n_tags} tags on this Landmark. Total score : {score}\n")
|
||||
landmark = Landmark(name=name, type=elem_type, location=location, osm_type=osm_type, osm_id=osm_id, attractiveness=score, must_do=False, n_tags=int(n_tags))
|
||||
L.append(landmark)
|
||||
|
||||
return L
|
||||
|
||||
|
||||
|
||||
"""def get_landmarks(list_amenity: list, landmarktype: LandmarkType, city_country: str = None, coordinates: Tuple[float, float] = None) -> List[Landmark] :
|
||||
|
||||
if city_country is None and coordinates is None :
|
||||
raise ValueError("Either one of 'city_country' and 'coordinates' arguments must be specified")
|
||||
|
||||
if city_country is not None and coordinates is not None :
|
||||
raise ValueError("Cannot specify both 'city_country' and 'coordinates' at the same time, please choose either one")
|
||||
|
||||
# Read the parameters from the file
|
||||
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/landmarks_manager.params', "r") as f :
|
||||
parameters = json.loads(f.read())
|
||||
tag_coeff = parameters['tag coeff']
|
||||
park_coeff = parameters['park coeff']
|
||||
church_coeff = parameters['church coeff']
|
||||
radius = parameters['radius close to']
|
||||
bbox_side = parameters['city bbox side']
|
||||
|
||||
# If city_country is specified :
|
||||
if city_country is not None :
|
||||
nominatim = Nominatim()
|
||||
areaId = nominatim.query(city_country).areaId()
|
||||
bbox = None
|
||||
|
||||
# If coordinates are specified :
|
||||
elif coordinates is not None :
|
||||
bbox = create_bbox(coordinates, bbox_side)
|
||||
areaId = None
|
||||
|
||||
else :
|
||||
raise ValueError("Argument number is not corresponding.")
|
||||
|
||||
# Initialize some variables
|
||||
N = 0
|
||||
L = []
|
||||
overpass = Overpass()
|
||||
|
||||
for amenity in list_amenity :
|
||||
query = overpassQueryBuilder(area=areaId, bbox=bbox, elementType=['way', 'relation'], selector=amenity, includeCenter=True, out='body')
|
||||
result = overpass.query(query)
|
||||
N += result.countElements()
|
||||
|
||||
for elem in result.elements():
|
||||
|
||||
name = elem.tag('name') # Add name
|
||||
location = (elem.centerLat(), elem.centerLon()) # Add coordinates (lat, lon)
|
||||
|
||||
# skip if unprecise location
|
||||
if name is None or location[0] is None:
|
||||
continue
|
||||
|
||||
# skip if unused
|
||||
if 'disused:leisure' in elem.tags().keys():
|
||||
continue
|
||||
|
||||
# skip if part of another building
|
||||
if 'building:part' in elem.tags().keys() and elem.tag('building:part') == 'yes':
|
||||
continue
|
||||
|
||||
else :
|
||||
osm_type = elem.type() # Add type : 'way' or 'relation'
|
||||
osm_id = elem.id() # Add OSM id
|
||||
elem_type = landmarktype # Add the landmark type as 'sightseeing
|
||||
n_tags = len(elem.tags().keys()) # Add number of tags
|
||||
|
||||
# Add score of given landmark based on the number of surrounding elements. Penalty for churches as there are A LOT
|
||||
if amenity == "'amenity'='place_of_worship'" :
|
||||
score = int((count_elements_within_radius(location, radius) + n_tags*tag_coeff )*church_coeff)
|
||||
elif amenity == "'leisure'='park'" :
|
||||
score = int((count_elements_within_radius(location, radius) + n_tags*tag_coeff )*park_coeff)
|
||||
else :
|
||||
score = count_elements_within_radius(location, radius) + n_tags*tag_coeff
|
||||
|
||||
if score is not None :
|
||||
# Generate the landmark and append it to the list
|
||||
landmark = Landmark(name=name, type=elem_type, location=location, osm_type=osm_type, osm_id=osm_id, attractiveness=score, must_do=False, n_tags=n_tags)
|
||||
L.append(landmark)
|
||||
|
||||
return L
|
||||
"""
|
@ -1,23 +0,0 @@
|
||||
import fastapi
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Destination:
|
||||
name: str
|
||||
location: tuple
|
||||
attractiveness: int
|
||||
|
||||
|
||||
|
||||
d = Destination()
|
||||
|
||||
|
||||
|
||||
def get_route() -> list[Destination]:
|
||||
return {"route": "Hello World"}
|
||||
|
||||
endpoint = ("/get_route", get_route)
|
||||
end
|
||||
if __name__ == "__main__":
|
||||
fastapi.run()
|
@ -344,6 +344,8 @@ def link_list_simple(ordered_visit: List[Landmark])-> List[Landmark] :
|
||||
elem.next_uuid = next.uuid
|
||||
d = get_distance(elem.location, next.location, detour_factor, speed)[1]
|
||||
elem.time_to_reach_next = d
|
||||
if elem.name not in ['start', 'finish'] :
|
||||
elem.must_do = True
|
||||
L.append(elem)
|
||||
j += 1
|
||||
total_dist += d
|
||||
|
446
backend/src/optimizer_v4.py
Normal file
446
backend/src/optimizer_v4.py
Normal file
@ -0,0 +1,446 @@
|
||||
import numpy as np
|
||||
import json, os
|
||||
|
||||
from typing import List, Tuple
|
||||
from scipy.optimize import linprog
|
||||
from collections import defaultdict, deque
|
||||
from geopy.distance import geodesic
|
||||
|
||||
from structs.landmarks import Landmark
|
||||
|
||||
|
||||
# Function to print the result
|
||||
def print_res(L: List[Landmark]):
|
||||
|
||||
print('The following order is suggested : ')
|
||||
|
||||
dist = 0
|
||||
for elem in L :
|
||||
if elem.time_to_reach_next is not None :
|
||||
print('- ' + elem.name + ', time to reach next = ' + str(elem.time_to_reach_next))
|
||||
dist += elem.time_to_reach_next
|
||||
else :
|
||||
print('- ' + elem.name)
|
||||
|
||||
print("\nMinutes walked : " + str(dist))
|
||||
print(f"Visited {len(L)-2} landmarks")
|
||||
|
||||
|
||||
# Prevent the use of a particular solution
|
||||
def prevent_config(resx):
|
||||
|
||||
for i, elem in enumerate(resx):
|
||||
resx[i] = round(elem)
|
||||
|
||||
N = len(resx) # Number of edges
|
||||
L = int(np.sqrt(N)) # Number of landmarks
|
||||
|
||||
nonzeroind = np.nonzero(resx)[0] # the return is a little funky so I use the [0]
|
||||
nonzero_tup = np.unravel_index(nonzeroind, (L,L))
|
||||
|
||||
ind_a = nonzero_tup[0].tolist()
|
||||
vertices_visited = ind_a
|
||||
vertices_visited.remove(0)
|
||||
|
||||
ones = [1]*L
|
||||
h = [0]*N
|
||||
for i in range(L) :
|
||||
if i in vertices_visited :
|
||||
h[i*L:i*L+L] = ones
|
||||
|
||||
return h, [len(vertices_visited)-1]
|
||||
|
||||
|
||||
# Prevents the creation of the same circle (both directions)
|
||||
def prevent_circle(circle_vertices: list, L: int) :
|
||||
|
||||
l1 = [0]*L*L
|
||||
l2 = [0]*L*L
|
||||
for i, node in enumerate(circle_vertices[:-1]) :
|
||||
next = circle_vertices[i+1]
|
||||
|
||||
l1[node*L + next] = 1
|
||||
l2[next*L + node] = 1
|
||||
|
||||
s = circle_vertices[0]
|
||||
g = circle_vertices[-1]
|
||||
|
||||
l1[g*L + s] = 1
|
||||
l2[s*L + g] = 1
|
||||
|
||||
return np.vstack((l1, l2)), [0, 0]
|
||||
|
||||
|
||||
# Returns the order of visit as well as any circles if there are some
|
||||
def is_connected(resx) :
|
||||
|
||||
# first round the results to have only 0-1 values
|
||||
for i, elem in enumerate(resx):
|
||||
resx[i] = round(elem)
|
||||
|
||||
N = len(resx) # length of res
|
||||
L = int(np.sqrt(N)) # number of landmarks. CAST INTO INT but should not be a problem because N = L**2 by def.
|
||||
n_edges = resx.sum() # number of edges
|
||||
|
||||
nonzeroind = np.nonzero(resx)[0] # the return is a little funny so I use the [0]
|
||||
|
||||
nonzero_tup = np.unravel_index(nonzeroind, (L,L))
|
||||
|
||||
ind_a = nonzero_tup[0].tolist()
|
||||
ind_b = nonzero_tup[1].tolist()
|
||||
|
||||
# Step 1: Create a graph representation
|
||||
graph = defaultdict(list)
|
||||
for a, b in zip(ind_a, ind_b):
|
||||
graph[a].append(b)
|
||||
|
||||
# Step 2: Function to perform BFS/DFS to extract journeys
|
||||
def get_journey(start):
|
||||
journey_nodes = []
|
||||
visited = set()
|
||||
stack = deque([start])
|
||||
|
||||
while stack:
|
||||
node = stack.pop()
|
||||
if node not in visited:
|
||||
visited.add(node)
|
||||
journey_nodes.append(node)
|
||||
for neighbor in graph[node]:
|
||||
if neighbor not in visited:
|
||||
stack.append(neighbor)
|
||||
|
||||
return journey_nodes
|
||||
|
||||
# Step 3: Extract all journeys
|
||||
all_journeys_nodes = []
|
||||
visited_nodes = set()
|
||||
|
||||
for node in ind_a:
|
||||
if node not in visited_nodes:
|
||||
journey_nodes = get_journey(node)
|
||||
all_journeys_nodes.append(journey_nodes)
|
||||
visited_nodes.update(journey_nodes)
|
||||
|
||||
for l in all_journeys_nodes :
|
||||
if 0 in l :
|
||||
order = l
|
||||
all_journeys_nodes.remove(l)
|
||||
break
|
||||
|
||||
if len(all_journeys_nodes) == 0 :
|
||||
return order, None
|
||||
|
||||
return order, all_journeys_nodes
|
||||
|
||||
|
||||
# Function that returns the time in minutes from one location to another
|
||||
def get_time(p1: Tuple[float, float], p2: Tuple[float, float], detour: float, speed: float) :
|
||||
|
||||
# Compute the straight-line distance in km
|
||||
if p1 == p2 :
|
||||
return 0
|
||||
else:
|
||||
dist = geodesic(p1, p2).kilometers
|
||||
|
||||
# Consider the detour factor for average cityto deterline walking distance (in km)
|
||||
walk_dist = dist*detour
|
||||
|
||||
# Time to walk this distance (in minutes)
|
||||
walk_time = walk_dist/speed*60
|
||||
|
||||
return round(walk_time)
|
||||
|
||||
|
||||
# Initialize A and c. Compute the distances from all landmarks to each other and store attractiveness
|
||||
# We want to maximize the sightseeing : max(c) st. A*x < b and A_eq*x = b_eq
|
||||
def init_ub_dist(landmarks: List[Landmark], max_steps: int):
|
||||
|
||||
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
|
||||
parameters = json.loads(f.read())
|
||||
detour = parameters['detour factor']
|
||||
speed = parameters['average walking speed']
|
||||
|
||||
# Objective function coefficients. a*x1 + b*x2 + c*x3 + ...
|
||||
c = []
|
||||
# Coefficients of inequality constraints (left-hand side)
|
||||
A_ub = []
|
||||
|
||||
for spot1 in landmarks :
|
||||
dist_table = [0]*len(landmarks)
|
||||
c.append(-spot1.attractiveness)
|
||||
for j, spot2 in enumerate(landmarks) :
|
||||
t = get_time(spot1.location, spot2.location, detour, speed)
|
||||
dist_table[j] = t
|
||||
closest = sorted(dist_table)[:22]
|
||||
for i, dist in enumerate(dist_table) :
|
||||
if dist not in closest :
|
||||
dist_table[i] = 32700
|
||||
A_ub += dist_table
|
||||
c = c*len(landmarks)
|
||||
|
||||
return c, A_ub, [max_steps]
|
||||
|
||||
|
||||
# Constraint to respect only one travel per landmark. Also caps the total number of visited landmarks
|
||||
def respect_number(L: int, max_landmarks: int):
|
||||
|
||||
ones = [1]*L
|
||||
zeros = [0]*L
|
||||
A = ones + zeros*(L-1)
|
||||
b = [1]
|
||||
for i in range(L-1) :
|
||||
h_new = zeros*i + ones + zeros*(L-1-i)
|
||||
A = np.vstack((A, h_new))
|
||||
b.append(1)
|
||||
|
||||
if max_landmarks is None :
|
||||
# Read the parameters from the file
|
||||
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
|
||||
parameters = json.loads(f.read())
|
||||
max_landmarks = parameters['max landmarks']
|
||||
|
||||
A = np.vstack((A, ones*L))
|
||||
b.append(max_landmarks+1)
|
||||
|
||||
return A, b
|
||||
|
||||
|
||||
# Constraint to not have d14 and d41 simultaneously. Does not prevent cyclic paths with more elements
|
||||
def break_sym(L):
|
||||
|
||||
upper_ind = np.triu_indices(L,0,L)
|
||||
|
||||
up_ind_x = upper_ind[0]
|
||||
up_ind_y = upper_ind[1]
|
||||
|
||||
A = [0]*L*L # useless row to prevent overhead ? better solution welcomed
|
||||
# A[up_ind_x[0]*L + up_ind_y[0]] = 1
|
||||
# A[up_ind_y[0]*L + up_ind_x[0]] = 1
|
||||
b = [1]
|
||||
|
||||
for i, _ in enumerate(up_ind_x[1:]) :
|
||||
l = [0]*L*L
|
||||
if up_ind_x[i] != up_ind_y[i] :
|
||||
l[up_ind_x[i]*L + up_ind_y[i]] = 1
|
||||
l[up_ind_y[i]*L + up_ind_x[i]] = 1
|
||||
|
||||
A = np.vstack((A,l))
|
||||
b.append(1)
|
||||
|
||||
return A, b
|
||||
|
||||
|
||||
# Constraint to not stay in position. Removes d11, d22, d33, etc.
|
||||
def init_eq_not_stay(L: int):
|
||||
l = [0]*L*L
|
||||
|
||||
for i in range(L) :
|
||||
for j in range(L) :
|
||||
if j == i :
|
||||
l[j + i*L] = 1
|
||||
|
||||
l = np.array(np.array(l), dtype=np.int8)
|
||||
|
||||
return [l], [0]
|
||||
|
||||
|
||||
# Go through the landmarks and force the optimizer to use landmarks marked as must_do
|
||||
def respect_user_must_do(landmarks: List[Landmark]) :
|
||||
L = len(landmarks)
|
||||
|
||||
A = [0]*L*L
|
||||
b = [0]
|
||||
for i, elem in enumerate(landmarks[1:]) :
|
||||
if elem.must_do is True and elem.name not in ['finish', 'start']:
|
||||
l = [0]*L*L
|
||||
l[i*L:i*L+L] = [1]*L # set mandatory departures from landmarks tagged as 'must_do'
|
||||
|
||||
A = np.vstack((A,l))
|
||||
b.append(1)
|
||||
|
||||
return A, b
|
||||
|
||||
|
||||
# Constraint to ensure start at start and finish at goal
|
||||
def respect_start_finish(L: int):
|
||||
l_start = [1]*L + [0]*L*(L-1) # sets departures only for start (horizontal ones)
|
||||
l_start[L-1] = 0 # prevents the jump from start to finish
|
||||
l_goal = [0]*L*L # sets arrivals only for finish (vertical ones)
|
||||
l_L = [0]*L*(L-1) + [1]*L # prevents arrivals at start and departures from goal
|
||||
for k in range(L-1) : # sets only vertical ones for goal (go to)
|
||||
l_L[k*L] = 1
|
||||
if k != 0 :
|
||||
l_goal[k*L+L-1] = 1
|
||||
|
||||
|
||||
A = np.vstack((l_start, l_goal))
|
||||
b = [1, 1]
|
||||
A = np.vstack((A,l_L))
|
||||
b.append(0)
|
||||
|
||||
return A, b
|
||||
|
||||
|
||||
# Constraint to tie the problem together. Necessary but not sufficient to avoid circles
|
||||
def respect_order(L: int):
|
||||
|
||||
A = [0]*L*L # useless row to reduce overhead ? better solution is welcome
|
||||
b = [0]
|
||||
for i in range(L-1) : # Prevent stacked ones
|
||||
if i == 0 or i == L-1: # Don't touch start or finish
|
||||
continue
|
||||
else :
|
||||
l = [0]*L
|
||||
l[i] = -1
|
||||
l = l*L
|
||||
for j in range(L) :
|
||||
l[i*L + j] = 1
|
||||
|
||||
A = np.vstack((A,l))
|
||||
b.append(0)
|
||||
|
||||
return A, b
|
||||
|
||||
|
||||
# Computes the time to reach from each landmark to the next
|
||||
def link_list(order: List[int], landmarks: List[Landmark])->List[Landmark] :
|
||||
|
||||
# Read the parameters from the file
|
||||
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
|
||||
parameters = json.loads(f.read())
|
||||
detour_factor = parameters['detour factor']
|
||||
speed = parameters['average walking speed']
|
||||
|
||||
L = []
|
||||
j = 0
|
||||
total_dist = 0
|
||||
while j < len(order)-1 :
|
||||
elem = landmarks[order[j]]
|
||||
next = landmarks[order[j+1]]
|
||||
|
||||
d = get_time(elem.location, next.location, detour_factor, speed)
|
||||
elem.time_to_reach_next = d
|
||||
elem.must_do = True
|
||||
elem.location = (round(elem.location[0], 5), round(elem.location[1], 5))
|
||||
L.append(elem)
|
||||
j += 1
|
||||
total_dist += d
|
||||
|
||||
next.location = (round(next.location[0], 5), round(next.location[1], 5))
|
||||
L.append(next)
|
||||
|
||||
return L, total_dist
|
||||
|
||||
|
||||
# Same as link_list but does it on a already ordered list
|
||||
def link_list_simple(ordered_visit: List[Landmark])-> List[Landmark] :
|
||||
|
||||
# Read the parameters from the file
|
||||
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
|
||||
parameters = json.loads(f.read())
|
||||
detour_factor = parameters['detour factor']
|
||||
speed = parameters['average walking speed']
|
||||
|
||||
L = []
|
||||
j = 0
|
||||
total_dist = 0
|
||||
while j < len(ordered_visit)-1 :
|
||||
elem = ordered_visit[j]
|
||||
next = ordered_visit[j+1]
|
||||
|
||||
elem.next_uuid = next.uuid
|
||||
d = get_time(elem.location, next.location, detour_factor, speed)
|
||||
elem.time_to_reach_next = d
|
||||
if elem.name not in ['start', 'finish'] :
|
||||
elem.must_do = True
|
||||
L.append(elem)
|
||||
j += 1
|
||||
total_dist += d
|
||||
|
||||
L.append(next)
|
||||
|
||||
return L, total_dist
|
||||
|
||||
|
||||
# Main optimization pipeline
|
||||
def solve_optimization (landmarks :List[Landmark], max_steps: int, printing_details: bool, max_landmarks = None) :
|
||||
|
||||
L = len(landmarks)
|
||||
|
||||
# SET CONSTRAINTS FOR INEQUALITY
|
||||
c, A_ub, b_ub = init_ub_dist(landmarks, max_steps) # Add the distances from each landmark to the other
|
||||
A, b = respect_number(L, max_landmarks) # Respect max number of visits (no more possible stops than landmarks).
|
||||
A_ub = np.vstack((A_ub, A), dtype=np.int16)
|
||||
b_ub += b
|
||||
A, b = break_sym(L) # break the 'zig-zag' symmetry
|
||||
A_ub = np.vstack((A_ub, A), dtype=np.int16)
|
||||
b_ub += b
|
||||
|
||||
|
||||
# SET CONSTRAINTS FOR EQUALITY
|
||||
A_eq, b_eq = init_eq_not_stay(L) # Force solution not to stay in same place
|
||||
A, b = respect_user_must_do(landmarks) # Check if there are user_defined must_see. Also takes care of start/goal
|
||||
A_eq = np.vstack((A_eq, A), dtype=np.int8)
|
||||
b_eq += b
|
||||
A, b = respect_start_finish(L) # Force start and finish positions
|
||||
A_eq = np.vstack((A_eq, A), dtype=np.int8)
|
||||
b_eq += b
|
||||
A, b = respect_order(L) # Respect order of visit (only works when max_steps is limiting factor)
|
||||
A_eq = np.vstack((A_eq, A), dtype=np.int8)
|
||||
b_eq += b
|
||||
|
||||
# SET BOUNDS FOR DECISION VARIABLE (x can only be 0 or 1)
|
||||
x_bounds = [(0, 1)]*L*L
|
||||
|
||||
# Solve linear programming problem
|
||||
res = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq = b_eq, bounds=x_bounds, method='highs', integrality=3)
|
||||
|
||||
# Raise error if no solution is found
|
||||
if not res.success :
|
||||
raise ArithmeticError("No solution could be found, the problem is overconstrained. Please adapt your must_dos")
|
||||
|
||||
# If there is a solution, we're good to go, just check for connectiveness
|
||||
else :
|
||||
order, circles = is_connected(res.x)
|
||||
#nodes, edges = is_connected(res.x)
|
||||
i = 0
|
||||
timeout = 80
|
||||
while circles is not None and i < timeout:
|
||||
A, b = prevent_config(res.x)
|
||||
A_ub = np.vstack((A_ub, A))
|
||||
b_ub += b
|
||||
#A_ub, b_ub = prevent_circle(order, len(landmarks), A_ub, b_ub)
|
||||
for circle in circles :
|
||||
A, b = prevent_circle(circle, len(landmarks))
|
||||
A_eq = np.vstack((A_eq, A))
|
||||
b_eq += b
|
||||
res = linprog(c, A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq = b_eq, bounds=x_bounds, method='highs', integrality=3)
|
||||
if not res.success :
|
||||
print("Solving failed because of overconstrained problem")
|
||||
return None
|
||||
order, circles = is_connected(res.x)
|
||||
#nodes, edges = is_connected(res.x)
|
||||
if circles is None :
|
||||
break
|
||||
print(i)
|
||||
i += 1
|
||||
|
||||
if i == timeout :
|
||||
raise TimeoutError(f"Optimization took too long. No solution found after {timeout} iterations.")
|
||||
|
||||
# Add the times to reach and stop optimizing
|
||||
L, _ = link_list(order, landmarks)
|
||||
|
||||
if printing_details is True :
|
||||
if i != 0 :
|
||||
print(f"Neded to recompute paths {i} times because of unconnected loops...")
|
||||
print_res(L)
|
||||
print("\nTotal score : " + str(int(-res.fun)))
|
||||
|
||||
return L
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"city bbox side" : 10,
|
||||
"radius close to" : 27.5,
|
||||
"church coeff" : 0.6,
|
||||
"park coeff" : 1.5,
|
||||
"tag coeff" : 100,
|
||||
"city bbox side" : 5000,
|
||||
"radius close to" : 50,
|
||||
"church coeff" : 0.8,
|
||||
"park coeff" : 1.2,
|
||||
"tag coeff" : 10,
|
||||
"N important" : 40
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"detour factor" : 1.4,
|
||||
"average walking speed" : 4.8,
|
||||
"max landmarks" : 10
|
||||
"max landmarks" : 7
|
||||
}
|
@ -1,17 +1,15 @@
|
||||
from collections import defaultdict
|
||||
from heapq import heappop, heappush
|
||||
from itertools import permutations
|
||||
import os, json
|
||||
|
||||
from shapely import buffer, LineString, Point, Polygon, MultiPoint, convex_hull, concave_hull, LinearRing
|
||||
from shapely import buffer, LineString, Point, Polygon, MultiPoint, concave_hull
|
||||
from typing import List, Tuple
|
||||
from math import pi
|
||||
|
||||
from structs.landmarks import Landmark
|
||||
from landmarks_manager import take_most_important
|
||||
from optimizer import solve_optimization, link_list_simple, print_res, get_distance
|
||||
from optimizer_v4 import solve_optimization, link_list_simple, print_res, get_time
|
||||
|
||||
|
||||
# Create corridor from tour
|
||||
def create_corridor(landmarks: List[Landmark], width: float) :
|
||||
|
||||
corrected_width = (180*width)/(6371000*pi)
|
||||
@ -22,6 +20,7 @@ def create_corridor(landmarks: List[Landmark], width: float) :
|
||||
return obj
|
||||
|
||||
|
||||
# Create linestring from tour
|
||||
def create_linestring(landmarks: List[Landmark])->List[Point] :
|
||||
|
||||
points = []
|
||||
@ -32,11 +31,13 @@ def create_linestring(landmarks: List[Landmark])->List[Point] :
|
||||
return LineString(points)
|
||||
|
||||
|
||||
# Check if some coordinates are in area. Used for the corridor
|
||||
def is_in_area(area: Polygon, coordinates) -> bool :
|
||||
point = Point(coordinates)
|
||||
return point.within(area)
|
||||
|
||||
|
||||
# Function to determine if two landmarks are close to each other
|
||||
def is_close_to(location1: Tuple[float], location2: Tuple[float]):
|
||||
"""Determine if two locations are close by rounding their coordinates to 3 decimals."""
|
||||
absx = abs(location1[0] - location2[0])
|
||||
@ -46,6 +47,7 @@ def is_close_to(location1: Tuple[float], location2: Tuple[float]):
|
||||
#return (round(location1[0], 3), round(location1[1], 3)) == (round(location2[0], 3), round(location2[1], 3))
|
||||
|
||||
|
||||
# Rearrange some landmarks in the order of visit to group visit
|
||||
def rearrange(landmarks: List[Landmark]) -> List[Landmark]:
|
||||
|
||||
i = 1
|
||||
@ -62,66 +64,9 @@ def rearrange(landmarks: List[Landmark]) -> List[Landmark]:
|
||||
|
||||
return landmarks
|
||||
|
||||
"""
|
||||
def find_shortest_path(landmarks: List[Landmark]) -> List[Landmark]:
|
||||
|
||||
# Read from data
|
||||
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
|
||||
parameters = json.loads(f.read())
|
||||
detour = parameters['detour factor']
|
||||
speed = parameters['average walking speed']
|
||||
|
||||
# Step 1: Build the graph
|
||||
graph = defaultdict(list)
|
||||
for i in range(len(landmarks)):
|
||||
for j in range(len(landmarks)):
|
||||
if i != j:
|
||||
distance = get_distance(landmarks[i].location, landmarks[j].location, detour, speed)[1]
|
||||
graph[i].append((distance, j))
|
||||
|
||||
# Step 2: Dijkstra's algorithm to find the shortest path from start to finish
|
||||
start_idx = next(i for i, lm in enumerate(landmarks) if lm.name == 'start')
|
||||
finish_idx = next(i for i, lm in enumerate(landmarks) if lm.name == 'finish')
|
||||
|
||||
distances = {i: float('inf') for i in range(len(landmarks))}
|
||||
previous_nodes = {i: None for i in range(len(landmarks))}
|
||||
distances[start_idx] = 0
|
||||
priority_queue = [(0, start_idx)]
|
||||
|
||||
while priority_queue:
|
||||
current_distance, current_index = heappop(priority_queue)
|
||||
|
||||
if current_distance > distances[current_index]:
|
||||
continue
|
||||
|
||||
for neighbor_distance, neighbor_index in graph[current_index]:
|
||||
distance = current_distance + neighbor_distance
|
||||
|
||||
if distance < distances[neighbor_index]:
|
||||
distances[neighbor_index] = distance
|
||||
previous_nodes[neighbor_index] = current_index
|
||||
heappush(priority_queue, (distance, neighbor_index))
|
||||
|
||||
# Step 3: Backtrack from finish to start to find the path
|
||||
path = []
|
||||
current_index = finish_idx
|
||||
while current_index is not None:
|
||||
path.append(landmarks[current_index])
|
||||
current_index = previous_nodes[current_index]
|
||||
path.reverse()
|
||||
|
||||
return path
|
||||
"""
|
||||
"""
|
||||
def total_path_distance(path: List[Landmark], detour, speed) -> float:
|
||||
total_distance = 0
|
||||
for i in range(len(path) - 1):
|
||||
total_distance += get_distance(path[i].location, path[i + 1].location, detour, speed)[1]
|
||||
return total_distance
|
||||
"""
|
||||
|
||||
|
||||
def find_shortest_path_through_all_landmarks(landmarks: List[Landmark]) -> List[Landmark]:
|
||||
# Simple nearest neighbour planner to try to fix the path
|
||||
def find_shortest_path_through_all_landmarks(landmarks: List[Landmark]) -> Tuple[List[Landmark], Polygon]:
|
||||
|
||||
# Read from data
|
||||
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
|
||||
@ -148,7 +93,7 @@ def find_shortest_path_through_all_landmarks(landmarks: List[Landmark]) -> List[
|
||||
|
||||
# Step 4: Use nearest neighbor heuristic to visit all landmarks
|
||||
while unvisited_landmarks:
|
||||
nearest_landmark = min(unvisited_landmarks, key=lambda lm: get_distance(current_landmark.location, lm.location, detour, speed)[1])
|
||||
nearest_landmark = min(unvisited_landmarks, key=lambda lm: get_time(current_landmark.location, lm.location, detour, speed))
|
||||
path.append(nearest_landmark)
|
||||
coordinates.append(nearest_landmark.location)
|
||||
current_landmark = nearest_landmark
|
||||
@ -162,6 +107,8 @@ def find_shortest_path_through_all_landmarks(landmarks: List[Landmark]) -> List[
|
||||
|
||||
return path, path_poly
|
||||
|
||||
|
||||
# Returns a list of minor landmarks around the planned path to enhance experience
|
||||
def get_minor_landmarks(all_landmarks: List[Landmark], visited_landmarks: List[Landmark], width: float) -> List[Landmark] :
|
||||
|
||||
second_order_landmarks = []
|
||||
@ -178,116 +125,120 @@ def get_minor_landmarks(all_landmarks: List[Landmark], visited_landmarks: List[L
|
||||
return take_most_important(second_order_landmarks, len(visited_landmarks))
|
||||
|
||||
|
||||
# Try fix the shortest path using shapely
|
||||
def fix_using_polygon(tour: List[Landmark])-> List[Landmark] :
|
||||
|
||||
"""def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] :
|
||||
coords = []
|
||||
coords_dict = {}
|
||||
for landmark in tour :
|
||||
coords.append(landmark.location)
|
||||
if landmark.name != 'finish' :
|
||||
coords_dict[landmark.location] = landmark
|
||||
|
||||
minor_landmarks = get_minor_landmarks(landmarks, base_tour, 200)
|
||||
tour_poly = Polygon(coords)
|
||||
|
||||
better_tour_poly = tour_poly.buffer(0)
|
||||
try :
|
||||
xs, ys = better_tour_poly.exterior.xy
|
||||
|
||||
if print_infos : print("There are " + str(len(minor_landmarks)) + " minor landmarks around the predicted path")
|
||||
if len(xs) != len(tour) :
|
||||
better_tour_poly = concave_hull(MultiPoint(coords)) # Create concave hull with "core" of tour leaving out start and finish
|
||||
xs, ys = better_tour_poly.exterior.xy
|
||||
|
||||
full_set = base_tour[:-1] + minor_landmarks # create full set of possible landmarks (without finish)
|
||||
full_set.append(base_tour[-1]) # add finish back
|
||||
|
||||
new_tour = solve_optimization(full_set, max_time, print_infos)
|
||||
|
||||
return new_tour"""
|
||||
except :
|
||||
better_tour_poly = concave_hull(MultiPoint(coords)) # Create concave hull with "core" of tour leaving out start and finish
|
||||
xs, ys = better_tour_poly.exterior.xy
|
||||
|
||||
|
||||
def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, print_infos: bool) -> List[Landmark] :
|
||||
# reverse the xs and ys
|
||||
xs.reverse()
|
||||
ys.reverse()
|
||||
|
||||
better_tour = [] # List of ordered visit
|
||||
name_index = {} # Maps the name of a landmark to its index in the concave polygon
|
||||
|
||||
# Loop through the polygon and generate the better (ordered) tour
|
||||
for i,x in enumerate(xs[:-1]) :
|
||||
y = ys[i]
|
||||
better_tour.append(coords_dict[tuple((x,y))])
|
||||
name_index[coords_dict[tuple((x,y))].name] = i
|
||||
|
||||
|
||||
# Scroll the list to have start in front again
|
||||
start_index = name_index['start']
|
||||
better_tour = better_tour[start_index:] + better_tour[:start_index]
|
||||
|
||||
# Append the finish back and correct the time to reach
|
||||
better_tour.append(tour[-1])
|
||||
|
||||
# Rearrange only if polygon still not simple
|
||||
if not better_tour_poly.is_simple :
|
||||
better_tour = rearrange(better_tour)
|
||||
|
||||
return better_tour
|
||||
|
||||
|
||||
# Second stage of the optimization. Use linear programming again to refine the path
|
||||
def refine_optimization(landmarks: List[Landmark], base_tour: List[Landmark], max_time: int, detour: int, print_infos: bool) -> List[Landmark] :
|
||||
|
||||
# Read from the file
|
||||
with open (os.path.dirname(os.path.abspath(__file__)) + '/parameters/optimizer.params', "r") as f :
|
||||
parameters = json.loads(f.read())
|
||||
max_landmarks = parameters['max landmarks']
|
||||
|
||||
if len(base_tour)-2 >= max_landmarks :
|
||||
return base_tour
|
||||
|
||||
max_landmarks = parameters['max landmarks'] + 4
|
||||
|
||||
minor_landmarks = get_minor_landmarks(landmarks, base_tour, 200)
|
||||
|
||||
if print_infos : print("Using " + str(len(minor_landmarks)) + " minor landmarks around the predicted path")
|
||||
|
||||
# full set of visitable landmarks
|
||||
full_set = base_tour[:-1] + minor_landmarks # create full set of possible landmarks (without finish)
|
||||
full_set.append(base_tour[-1]) # add finish back
|
||||
|
||||
# get a new tour
|
||||
new_tour = solve_optimization(full_set, max_time, False)
|
||||
new_tour, new_dist = link_list_simple(new_tour)
|
||||
|
||||
"""#if base_tour[0].location == base_tour[-1].location :
|
||||
# No need to refine if no detour is taken
|
||||
# if detour == 0 :
|
||||
if False :
|
||||
coords = [] # Coordinates of the new tour
|
||||
coords_dict = {} # maps the location of an element to the element itself. Used to access the elements back once we get the geometry
|
||||
|
||||
# Iterate through the new tour without finish
|
||||
for elem in new_tour[:-1] :
|
||||
coords.append(Point(elem.location))
|
||||
coords_dict[elem.location] = elem # if start = goal, only finish remains
|
||||
|
||||
# Create a concave polygon using the coordinates
|
||||
better_tour_poly = concave_hull(MultiPoint(coords)) # Create concave hull with "core" of tour leaving out start and finish
|
||||
xs, ys = better_tour_poly.exterior.xy
|
||||
|
||||
# reverse the xs and ys
|
||||
xs.reverse()
|
||||
ys.reverse()
|
||||
|
||||
better_tour = [] # List of ordered visit
|
||||
name_index = {} # Maps the name of a landmark to its index in the concave polygon
|
||||
|
||||
# Loop through the polygon and generate the better (ordered) tour
|
||||
for i,x in enumerate(xs[:-1]) :
|
||||
better_tour.append(coords_dict[tuple((x,ys[i]))])
|
||||
name_index[coords_dict[tuple((x,ys[i]))].name] = i
|
||||
|
||||
|
||||
# Scroll the list to have start in front again
|
||||
start_index = name_index['start']
|
||||
better_tour = better_tour[start_index:] + better_tour[:start_index]
|
||||
|
||||
# Append the finish back and correct the time to reach
|
||||
better_tour.append(new_tour[-1])
|
||||
|
||||
# Rearrange only if polygon
|
||||
better_tour = rearrange(better_tour)
|
||||
|
||||
# Add the time to reach
|
||||
better_tour = add_time_to_reach_simple(better_tour)
|
||||
"""
|
||||
new_tour = base_tour
|
||||
|
||||
else :
|
||||
minor_landmarks = get_minor_landmarks(landmarks, base_tour, 200)
|
||||
|
||||
"""
|
||||
if not better_poly.is_simple :
|
||||
|
||||
coords_dict = {}
|
||||
better_tour2 = []
|
||||
for elem in better_tour :
|
||||
coords_dict[elem.location] = elem
|
||||
if print_infos : print("Using " + str(len(minor_landmarks)) + " minor landmarks around the predicted path")
|
||||
|
||||
better_poly2 = better_poly.buffer(0)
|
||||
new_coords = better_poly2.exterior.coords[:]
|
||||
start_coords = base_tour[0].location
|
||||
start_index = new_coords.
|
||||
# full set of visitable landmarks
|
||||
full_set = base_tour[:-1] + minor_landmarks # create full set of possible landmarks (without finish)
|
||||
full_set.append(base_tour[-1]) # add finish back
|
||||
|
||||
#for point in new_coords :
|
||||
"""
|
||||
# get a new tour
|
||||
new_tour = solve_optimization(full_set, max_time+detour, False, max_landmarks)
|
||||
if new_tour is None :
|
||||
new_tour = base_tour
|
||||
|
||||
# Link the new tour
|
||||
new_tour, new_dist = link_list_simple(new_tour)
|
||||
|
||||
# If the tour contains only one landmark, return
|
||||
if len(new_tour) < 4 :
|
||||
return new_tour
|
||||
|
||||
# Find shortest path using the nearest neighbor heuristic
|
||||
better_tour, better_poly = find_shortest_path_through_all_landmarks(new_tour)
|
||||
|
||||
# Fix the tour using Polygons if the path looks weird
|
||||
if base_tour[0].location == base_tour[-1].location and not better_poly.is_valid :
|
||||
better_tour = fix_using_polygon(better_tour)
|
||||
|
||||
# Link the tour again
|
||||
better_tour, better_dist = link_list_simple(better_tour)
|
||||
|
||||
# Choose the better tour depending on walked distance
|
||||
if new_dist < better_dist :
|
||||
final_tour = new_tour
|
||||
else :
|
||||
final_tour = better_tour
|
||||
|
||||
if print_infos :
|
||||
print("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n")
|
||||
print("\nRefined tour (result of second stage optimization): ")
|
||||
print_res(final_tour, len(full_set))
|
||||
print("\n\n\nRefined tour (result of second stage optimization): ")
|
||||
print_res(final_tour)
|
||||
total_score = 0
|
||||
for elem in final_tour :
|
||||
total_score += elem.attractiveness
|
||||
|
||||
print("\nTotal score : " + str(total_score))
|
||||
|
||||
|
||||
|
||||
return final_tour
|
||||
|
||||
|
||||
|
@ -7,8 +7,6 @@ from uuid import uuid4
|
||||
|
||||
# Output to frontend
|
||||
class Landmark(BaseModel) :
|
||||
# Unique ID of a given landmark
|
||||
uuid: str = Field(default_factory=uuid4) # TODO implement this ASAP
|
||||
|
||||
# Properties of the landmark
|
||||
name : str
|
||||
@ -21,6 +19,9 @@ class Landmark(BaseModel) :
|
||||
image_url : Optional[str] = None # TODO future
|
||||
description : Optional[str] = None # TODO future
|
||||
duration : Optional[int] = 0 # TODO future
|
||||
|
||||
# Unique ID of a given landmark
|
||||
uuid: str = Field(default_factory=uuid4) # TODO implement this ASAP
|
||||
|
||||
# Additional properties depending on specific tour
|
||||
must_do : bool
|
||||
|
@ -4,7 +4,7 @@ from typing import List
|
||||
from landmarks_manager import generate_landmarks
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
|
||||
from optimizer import solve_optimization
|
||||
from optimizer_v4 import solve_optimization
|
||||
from refiner import refine_optimization
|
||||
from structs.landmarks import Landmark
|
||||
from structs.landmarktype import LandmarkType
|
||||
@ -23,7 +23,8 @@ def write_data(L: List[Landmark], file_name: str):
|
||||
|
||||
data.to_json(file_name, indent = 2, force_ascii=False)
|
||||
|
||||
def test3(city_country: str) -> List[Landmark]:
|
||||
|
||||
def test4(coordinates: tuple[float, float]) -> List[Landmark]:
|
||||
|
||||
|
||||
preferences = Preferences(
|
||||
@ -38,52 +39,12 @@ def test3(city_country: str) -> List[Landmark]:
|
||||
shopping=Preference(
|
||||
name='shopping',
|
||||
type=LandmarkType(landmark_type='shopping'),
|
||||
score = 5))
|
||||
|
||||
coordinates = None
|
||||
|
||||
landmarks, landmarks_short = generate_landmarks(preferences=preferences, city_country=city_country, coordinates=coordinates)
|
||||
|
||||
#write_data(landmarks)
|
||||
|
||||
start = Landmark(name='start', type=LandmarkType(landmark_type='start'), location=(48.2044576, 16.3870242), osm_type='start', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(48.2044576, 16.3870242), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
|
||||
|
||||
test = landmarks_short
|
||||
|
||||
test.insert(0, start)
|
||||
test.append(finish)
|
||||
|
||||
max_walking_time = 2 # hours
|
||||
|
||||
visiting_list = solve_optimization(test, max_walking_time*60, True)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test4(coordinates: tuple[float, float]) -> List[Landmark]:
|
||||
|
||||
|
||||
preferences = Preferences(
|
||||
sightseeing=Preference(
|
||||
name='sightseeing',
|
||||
type=LandmarkType(landmark_type='sightseeing'),
|
||||
score = 5),
|
||||
nature=Preference(
|
||||
name='nature',
|
||||
type=LandmarkType(landmark_type='nature'),
|
||||
score = 5),
|
||||
shopping=Preference(
|
||||
name='shopping',
|
||||
type=LandmarkType(landmark_type='shopping'),
|
||||
score = 5))
|
||||
score = 0))
|
||||
|
||||
|
||||
# Create start and finish
|
||||
start = Landmark(name='start', type=LandmarkType(landmark_type='start'), location=coordinates, osm_type='start', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=coordinates, osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
start = Landmark(name='start', type=LandmarkType(landmark_type='start'), location=coordinates, osm_type='start', osm_id=0, attractiveness=0, must_do=False, n_tags = 0)
|
||||
finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=coordinates, osm_type='finish', osm_id=0, attractiveness=0, must_do=False, n_tags = 0)
|
||||
#finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(48.8777055, 2.3640967), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
#start = Landmark(name='start', type=LandmarkType(landmark_type='start'), location=(48.847132, 2.312359), osm_type='start', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
#finish = Landmark(name='finish', type=LandmarkType(landmark_type='finish'), location=(48.843185, 2.344533), osm_type='finish', osm_id=0, attractiveness=0, must_do=True, n_tags = 0)
|
||||
@ -91,26 +52,29 @@ def test4(coordinates: tuple[float, float]) -> List[Landmark]:
|
||||
|
||||
# Generate the landmarks from the start location
|
||||
landmarks, landmarks_short = generate_landmarks(preferences=preferences, coordinates=start.location)
|
||||
#write_data(landmarks, "landmarks.txt")
|
||||
#write_data(landmarks, "landmarks_Wien.txt")
|
||||
|
||||
# Insert start and finish to the landmarks list
|
||||
landmarks_short.insert(0, start)
|
||||
landmarks_short.append(finish)
|
||||
|
||||
# TODO use these parameters in another way
|
||||
max_walking_time = 2 # hours
|
||||
detour = 30 # minutes
|
||||
max_walking_time = 180 # minutes
|
||||
detour = 0 # minutes
|
||||
|
||||
# First stage optimization
|
||||
base_tour = solve_optimization(landmarks_short, max_walking_time*60, True)
|
||||
|
||||
# Second stage optimization
|
||||
refined_tour = refine_optimization(landmarks, base_tour, max_walking_time*60+detour, True)
|
||||
base_tour = solve_optimization(landmarks_short, max_walking_time, True)
|
||||
|
||||
# Second stage using linear optimization
|
||||
|
||||
refined_tour = refine_optimization(landmarks, base_tour, max_walking_time, detour, True)
|
||||
|
||||
|
||||
return refined_tour
|
||||
|
||||
|
||||
test4(tuple((48.8344400, 2.3220540))) # Café Chez César
|
||||
#test4(tuple((48.8344400, 2.3220540))) # Café Chez César
|
||||
#test4(tuple((48.8375946, 2.2949904))) # Point random
|
||||
#test4(tuple((47.377859, 8.540585))) # Zurich HB
|
||||
#test3('Vienna, Austria')
|
||||
#test4(tuple((45.7576485, 4.8330241))) # Lyon Bellecour
|
||||
test4(tuple((48.5848435, 7.7332974))) # Strasbourg Gare
|
||||
#test4(tuple((48.2067858, 16.3692340))) # Vienne
|
0
backend/throttle.ctrl
Normal file
0
backend/throttle.ctrl
Normal file
9730
landmarks.txt
9730
landmarks.txt
File diff suppressed because it is too large
Load Diff
@ -1,482 +0,0 @@
|
||||
{
|
||||
"0":{
|
||||
"name":"Atelier Brancusi",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8614029,
|
||||
2.3519903
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":55503399,
|
||||
"attractiveness":13,
|
||||
"must_do":false,
|
||||
"n_tags":13,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"1":{
|
||||
"name":"Musée de Cluny",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8506604,
|
||||
2.3437398
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":56640163,
|
||||
"attractiveness":18,
|
||||
"must_do":false,
|
||||
"n_tags":18,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"2":{
|
||||
"name":"Musée du Luxembourg",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8485965,
|
||||
2.3340156
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":170226810,
|
||||
"attractiveness":15,
|
||||
"must_do":false,
|
||||
"n_tags":15,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"3":{
|
||||
"name":"Musée national Eugène Delacroix",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8546662,
|
||||
2.3353836
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":395785603,
|
||||
"attractiveness":15,
|
||||
"must_do":false,
|
||||
"n_tags":15,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"4":{
|
||||
"name":"Hôtel de Sully",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.854635,
|
||||
2.3638126
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":403146,
|
||||
"attractiveness":14,
|
||||
"must_do":false,
|
||||
"n_tags":13,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"5":{
|
||||
"name":"Hôtel de la Monnaie",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.856403,
|
||||
2.3388625
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":967664,
|
||||
"attractiveness":11,
|
||||
"must_do":false,
|
||||
"n_tags":11,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"6":{
|
||||
"name":"Musée Bourdelle",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8432078,
|
||||
2.3186583
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":1212876,
|
||||
"attractiveness":23,
|
||||
"must_do":false,
|
||||
"n_tags":23,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"7":{
|
||||
"name":"Musée Carnavalet",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8576819,
|
||||
2.3627147
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":2405955,
|
||||
"attractiveness":25,
|
||||
"must_do":false,
|
||||
"n_tags":25,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"8":{
|
||||
"name":"Pont Neuf",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8565248,
|
||||
2.3408132
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":53574149,
|
||||
"attractiveness":16,
|
||||
"must_do":false,
|
||||
"n_tags":15,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"9":{
|
||||
"name":"Jardin du Luxembourg",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8467137,
|
||||
2.3363649
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":128206209,
|
||||
"attractiveness":35,
|
||||
"must_do":false,
|
||||
"n_tags":23,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"10":{
|
||||
"name":"Cathédrale Notre-Dame de Paris",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8529372,
|
||||
2.3498701
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":201611261,
|
||||
"attractiveness":55,
|
||||
"must_do":false,
|
||||
"n_tags":54,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"11":{
|
||||
"name":"Maison à l'enseigne du Faucheur",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8558553,
|
||||
2.3568266
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":1123456865,
|
||||
"attractiveness":13,
|
||||
"must_do":false,
|
||||
"n_tags":11,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"12":{
|
||||
"name":"Maison à l'enseigne du Mouton",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8558431,
|
||||
2.3568914
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":1123456866,
|
||||
"attractiveness":13,
|
||||
"must_do":false,
|
||||
"n_tags":11,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"13":{
|
||||
"name":"Palais de Justice de Paris",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8556537,
|
||||
2.3446072
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":536982,
|
||||
"attractiveness":24,
|
||||
"must_do":false,
|
||||
"n_tags":24,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"14":{
|
||||
"name":"Mémorial des Martyrs de la Déportation",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8517365,
|
||||
2.3524734
|
||||
],
|
||||
"osm_type":"relation",
|
||||
"osm_id":9396191,
|
||||
"attractiveness":21,
|
||||
"must_do":false,
|
||||
"n_tags":21,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"15":{
|
||||
"name":"Fontaine des Innocents",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8606368,
|
||||
2.3480233
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":52469222,
|
||||
"attractiveness":16,
|
||||
"must_do":false,
|
||||
"n_tags":15,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"16":{
|
||||
"name":"Hôtel de Sens",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8535257,
|
||||
2.3588733
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":55541122,
|
||||
"attractiveness":21,
|
||||
"must_do":false,
|
||||
"n_tags":20,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"17":{
|
||||
"name":"Hôtel d'Ourscamp",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8555465,
|
||||
2.3571206
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":55620201,
|
||||
"attractiveness":10,
|
||||
"must_do":false,
|
||||
"n_tags":9,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"18":{
|
||||
"name":"Hôtel de Choiseul-Praslin",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8478008,
|
||||
2.3203873
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":65756922,
|
||||
"attractiveness":12,
|
||||
"must_do":false,
|
||||
"n_tags":12,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"19":{
|
||||
"name":"Chapelle Notre-Dame-des-Anges",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8462836,
|
||||
2.3235558
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":219378497,
|
||||
"attractiveness":16,
|
||||
"must_do":false,
|
||||
"n_tags":16,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"20":{
|
||||
"name":"Fontaine du Palmier",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8575005,
|
||||
2.3472864
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":261092850,
|
||||
"attractiveness":23,
|
||||
"must_do":false,
|
||||
"n_tags":14,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"21":{
|
||||
"name":"Église Saint-Séverin",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8520913,
|
||||
2.3457237
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":19740659,
|
||||
"attractiveness":15,
|
||||
"must_do":false,
|
||||
"n_tags":25,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"22":{
|
||||
"name":"Église Orthodoxe Roumaine des Saints Archanges",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.849488,
|
||||
2.3471975
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":55366403,
|
||||
"attractiveness":10,
|
||||
"must_do":false,
|
||||
"n_tags":16,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"23":{
|
||||
"name":"Église Saint-Merri",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8590777,
|
||||
2.3508448
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":55742120,
|
||||
"attractiveness":16,
|
||||
"must_do":false,
|
||||
"n_tags":26,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"24":{
|
||||
"name":"Église Saint-Germain des Prés",
|
||||
"type":{
|
||||
"landmark_type":"sightseeing"
|
||||
},
|
||||
"location":[
|
||||
48.8539667,
|
||||
2.334463
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":62287173,
|
||||
"attractiveness":12,
|
||||
"must_do":false,
|
||||
"n_tags":21,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"25":{
|
||||
"name":"Square de la Tour Saint-Jacques",
|
||||
"type":{
|
||||
"landmark_type":"nature"
|
||||
},
|
||||
"location":[
|
||||
48.857913,
|
||||
2.3487608
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":15895172,
|
||||
"attractiveness":19,
|
||||
"must_do":false,
|
||||
"n_tags":12,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"26":{
|
||||
"name":"Square Jean XXIII",
|
||||
"type":{
|
||||
"landmark_type":"nature"
|
||||
},
|
||||
"location":[
|
||||
48.8523775,
|
||||
2.3503406
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":20444455,
|
||||
"attractiveness":23,
|
||||
"must_do":false,
|
||||
"n_tags":15,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"27":{
|
||||
"name":"Square Félix Desruelles",
|
||||
"type":{
|
||||
"landmark_type":"nature"
|
||||
},
|
||||
"location":[
|
||||
48.8536974,
|
||||
2.3345069
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":62287123,
|
||||
"attractiveness":12,
|
||||
"must_do":false,
|
||||
"n_tags":7,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"28":{
|
||||
"name":"Jardin des Rosiers – Joseph-Migneret",
|
||||
"type":{
|
||||
"landmark_type":"nature"
|
||||
},
|
||||
"location":[
|
||||
48.8572946,
|
||||
2.3602516
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":365878540,
|
||||
"attractiveness":14,
|
||||
"must_do":false,
|
||||
"n_tags":8,
|
||||
"time_to_reach":0
|
||||
},
|
||||
"29":{
|
||||
"name":"Jardin du Père-Armand-David",
|
||||
"type":{
|
||||
"landmark_type":"nature"
|
||||
},
|
||||
"location":[
|
||||
48.8478674,
|
||||
2.3220972
|
||||
],
|
||||
"osm_type":"way",
|
||||
"osm_id":588324415,
|
||||
"attractiveness":10,
|
||||
"must_do":false,
|
||||
"n_tags":7,
|
||||
"time_to_reach":0
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user