pyvalhalla-git 3.5.1.post132__cp312-cp312-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. _valhalla.cp312-win_amd64.pyd +0 -0
  2. pyvalhalla_git-3.5.1.post132.data/platlib/Lerc-d4ff05a506ddcfc551c350aa718ab4da.dll +0 -0
  3. pyvalhalla_git-3.5.1.post132.data/platlib/abseil_dll-bdd8a5a1f5a4da3f67279509940f7994.dll +0 -0
  4. pyvalhalla_git-3.5.1.post132.data/platlib/gdal-e68c9d36ee94002182307d221cc91ce3.dll +0 -0
  5. pyvalhalla_git-3.5.1.post132.data/platlib/geos-b8640de6faf146d9855a807e72427e47.dll +0 -0
  6. pyvalhalla_git-3.5.1.post132.data/platlib/geos_c-7d79920a3a18ad2c1ff594fcef060f0a.dll +0 -0
  7. pyvalhalla_git-3.5.1.post132.data/platlib/geotiff-020296779aedd28fd03f34200e6e3c61.dll +0 -0
  8. pyvalhalla_git-3.5.1.post132.data/platlib/jpeg62-52d863f4f0f8139faf1608976c1d91f6.dll +0 -0
  9. pyvalhalla_git-3.5.1.post132.data/platlib/json-c-0d6db73c6075abe84a7bdd2a2d393471.dll +0 -0
  10. pyvalhalla_git-3.5.1.post132.data/platlib/libcurl-bfd466d47923540033e77b192031a728.dll +0 -0
  11. pyvalhalla_git-3.5.1.post132.data/platlib/libexpat-6da76b3644b9424613b6d75323fcdc82.dll +0 -0
  12. pyvalhalla_git-3.5.1.post132.data/platlib/liblzma-9b97b163f3fff34e786ef56c4f919383.dll +0 -0
  13. pyvalhalla_git-3.5.1.post132.data/platlib/libpng16-45e0d625267ecee5996170051645e533.dll +0 -0
  14. pyvalhalla_git-3.5.1.post132.data/platlib/libprotobuf-lite-2bea258fef20ab8f71dcb2fec86675a8.dll +0 -0
  15. pyvalhalla_git-3.5.1.post132.data/platlib/lz4-cb6b9d0ac653fc68b286ff6ba7ef9bf5.dll +0 -0
  16. pyvalhalla_git-3.5.1.post132.data/platlib/msvcp140-73e7ea186a7d9ab676a764ffa64cf7e6.dll +0 -0
  17. pyvalhalla_git-3.5.1.post132.data/platlib/proj_9-3a2a70c01b92ddd4e14ab2bc22e06ab7.dll +0 -0
  18. pyvalhalla_git-3.5.1.post132.data/platlib/qhull_r-46ecfc2e889bb30a2c3af738edb6eeb9.dll +0 -0
  19. pyvalhalla_git-3.5.1.post132.data/platlib/sqlite3-219685aef036100e03dd97e60c61281d.dll +0 -0
  20. pyvalhalla_git-3.5.1.post132.data/platlib/tiff-f8c8a1908722e0556fad08f0b5c1bb6f.dll +0 -0
  21. pyvalhalla_git-3.5.1.post132.data/platlib/zlib1-8425906e295d322425fe840dc45228db.dll +0 -0
  22. pyvalhalla_git-3.5.1.post132.dist-info/DELVEWHEEL +2 -0
  23. pyvalhalla_git-3.5.1.post132.dist-info/METADATA +137 -0
  24. pyvalhalla_git-3.5.1.post132.dist-info/RECORD +38 -0
  25. pyvalhalla_git-3.5.1.post132.dist-info/WHEEL +5 -0
  26. pyvalhalla_git-3.5.1.post132.dist-info/licenses/AUTHORS +5 -0
  27. pyvalhalla_git-3.5.1.post132.dist-info/licenses/COPYING +22 -0
  28. pyvalhalla_git-3.5.1.post132.dist-info/licenses/LICENSE.md +1 -0
  29. pyvalhalla_git-3.5.1.post132.dist-info/top_level.txt +2 -0
  30. valhalla/__init__.py +22 -0
  31. valhalla/__main__.py +72 -0
  32. valhalla/__version__.py +21 -0
  33. valhalla/_scripts.py +46 -0
  34. valhalla/_valhalla.cc +81 -0
  35. valhalla/actor.py +118 -0
  36. valhalla/config.py +45 -0
  37. valhalla/utils.py +62 -0
  38. valhalla/valhalla_build_config.py +760 -0
Binary file
@@ -0,0 +1,2 @@
1
+ Version: 1.10.1
2
+ Arguments: ['C:\\hostedtoolcache\\windows\\Python\\3.9.13\\x64\\Scripts\\delvewheel', 'repair', '--add-path', 'build/vcpkg_installed/custom-x64-windows/bin', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-f0975jq8\\cp312-win_amd64\\built_wheel\\pyvalhalla_git-3.5.1.post132-cp312-cp312-win_amd64.whl', '-w', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-f0975jq8\\cp312-win_amd64\\repaired_wheel']
@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyvalhalla-git
3
+ Version: 3.5.1.post132
4
+ Summary: High-level bindings to the Valhalla C++ library
5
+ Home-page: https://github.com/valhalla/valhalla
6
+ Author: Nils Nolde
7
+ Author-email: nilsnolde+pyvalhalla@proton.me
8
+ Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: Implementation :: CPython
11
+ Requires-Python: >=3.9.0
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE.md
14
+ License-File: COPYING
15
+ License-File: AUTHORS
16
+ Dynamic: author
17
+ Dynamic: author-email
18
+ Dynamic: classifier
19
+ Dynamic: description
20
+ Dynamic: description-content-type
21
+ Dynamic: home-page
22
+ Dynamic: license-file
23
+ Dynamic: requires-python
24
+ Dynamic: summary
25
+
26
+
27
+ ## Valhalla Python bindings
28
+
29
+ This folder contains the Python bindings to [Valhalla routing engine](https://github.com/valhalla/valhalla).
30
+
31
+ > [!NOTE]
32
+ > `pyvalhalla(-git)` packages are currently only published for:
33
+ > - `linux-x86_x64`
34
+ > - `win-amd64`
35
+ > - `macos-arm64`
36
+
37
+ On top of the (very) high-level Python bindings, we package some data-building Valhalla executables to ease the process of graph creation.
38
+
39
+ ### Installation
40
+
41
+ We distribute all currently maintained CPython versions as **binary wheels** for Win64, MacOS (`arm64`) and Linux (`x86_64`) distributions with `glibc>=2.28`. We **do not** offer a source distribution on PyPI.
42
+
43
+ `pip install pyvalhalla` to install the most recent Valhalla **release**.
44
+ `pip install pyvalhalla-git` to install the most recent Valhalla **master commit**.
45
+
46
+ ### Usage
47
+
48
+ #### Bindings
49
+
50
+ Find a more extended notebook in `./examples`, e.g. how to [use the actor](./examples/actor_examples.ipynb).
51
+
52
+ Before using the Python bindings you need to have access to a routable Valhalla graph. Either install Valhalla from source and built the graph from OSM compatible data or use our [Valhalla docker image](https://github.com/gis-ops/docker-valhalla) for a painless experience, e.g. this will build the routing graph for Andorra in `./custom_files`:
53
+
54
+ ```shell
55
+ docker run --rm --name valhalla_gis-ops -p 8002:8002 -v $PWD/custom_files:/custom_files -e tile_urls=https://download.geofabrik.de/europe/andorra-latest.osm.pbf gisops/valhalla:latest
56
+ ```
57
+
58
+ Once you have created a graph locally, you can use it like this:
59
+
60
+ ```python
61
+ from valhalla import Actor, get_config, get_help
62
+
63
+ # generate configuration
64
+ config = get_config(tile_extract='./custom_files/valhalla_tiles.tar', verbose=True)
65
+
66
+ # print the help for specific config items (has the same structure as the output of get_config()
67
+ print(get_help()["service_limits"]["auto"]["max_distance"])
68
+
69
+ # instantiate Actor to load graph and call actions
70
+ actor = Actor(config)
71
+ route = actor.route({"locations": [...]})
72
+ ```
73
+
74
+ #### Valhalla executables (**`linux-x86_x64` only**)
75
+
76
+ To access the C++ (native) executables, there are 2 options:
77
+ - (recommended) execute the module, e.g. `python -m valhalla valhalla_build_tiles -h`
78
+ - execute the Python wrapper scripts directly, e.g. `valhalla_build_tiles -h`
79
+
80
+ > [!NOTE]
81
+ > For the latter option to work, the Python environment's `bin/` folder has to be in the `$PATH`. Inside virtual environments, that's always the case.
82
+
83
+ Executing the scripts directly might also not work properly if there's a system-wide Valhalla installation, unless the Python environment's `bin/` folder has higher priority than system folders in `$PATH`. The module execution uses an explicit Python executable which should be preferred.
84
+
85
+ There are also some additional commands we added:
86
+ - `--help`: print the help for `python -m valhalla` explicitly
87
+ - `--quiet`: redirect `stdout` of the C++ executables to `/dev/null`; can be added **once** anywhere in the command, will not be forwarded to a C++ executable
88
+ - `print_bin_path`: simply prints the absolute path to the package-internal `bin/` directory where the C++ executables are; useful if the executables should be accessed directly in some script
89
+
90
+ To find out which Valhalla executables are currently included, run `python -m valhalla --help`. We limit the number of executables to control the wheel size. However, we're open to include any other executable if there's a good reason.
91
+
92
+ ### Building from source
93
+
94
+ #### Linux
95
+
96
+ To package arch-dependent Linux bindings we use a `manylinux` fork, where we install all dependencies into the `manylinux_2_28` image, based on AlmaLinux 8. This is necessary to have a broad `glibc` compatibility with many semi-recent Linux distros.
97
+
98
+ Either pull the `manylinux` image, or build it locally for testing:
99
+
100
+ ```shell
101
+ docker pull ghcr.io/valhalla/manylinux:2_28_valhalla_python
102
+
103
+ # or pull the image from ghcr.io
104
+ git clone https://github.com/valhalla/manylinux
105
+ cd manylinux
106
+ POLICY=manylinux_2_28 PLATFORM=x86_64 COMMIT_SHA=$(git rev-parse --verify HEAD) BUILDX_BUILDER=builder-docker-container ./build.sh
107
+ docker tag quay.io/pypa/manylinux_2_28_x86_64:$(git rev-parse --verify HEAD) ghcr.io/valhalla/manylinux:2_28_valhalla_python
108
+ ```
109
+
110
+ Once built, start a container to actually build Valhalla using AlmaLinux 8:
111
+
112
+ ```shell
113
+ cd valhalla
114
+ docker run -dt -v $PWD:/valhalla-py --name valhalla-py --workdir /valhalla-py ghcr.io/valhalla/manylinux:2_28_valhalla_python
115
+ docker exec -t valhalla-py /valhalla-py/src/bindings/python/build_linux.sh build_manylinux 3.13
116
+ ```
117
+
118
+ This will also build & install `libvalhalla` before building the bindings. At this point there should be a `wheelhouse` folder with the fixed python wheel, ready to be installed or distributed to arbitrary python 3.12 installations.
119
+
120
+ ### `cibuildwheel`
121
+
122
+ On our CI, this orchestrates the packaging of all `pyvalhalla` wheels for every supported, minor Python version and every platform. It can also be run locally (obviously only being able to build wheels for _your_ platform), e.g.
123
+
124
+ ```shell
125
+ python -m pip install cibuildwheel
126
+ cibuildwheel --print-build-identifiers
127
+ cibuildwheel --only cp313-manylinux_x86_64
128
+
129
+ # for windows you'll have to set an env var to the vcpkg win root
130
+ VCPKG_ARCH_ROOT="build/vcpkg_installed/custom-x64-windows" cibuildwheel --only cp313-manylinux_x86_64
131
+ ```
132
+
133
+ On Linux, this might download the [`manylinux` docker image](https://github.com/valhalla/manylinux/pkgs/container/manylinux). In the end, you'll find the wheel in `./wheelhouse`.
134
+
135
+ ### Testing (**`linux-x86_x64` only**)
136
+
137
+ We have a small [test script](./test/test_pyvalhalla_package.sh) which makes sure that all the executables are working properly. If run locally for some reason, install a `pyvalhalla` wheel first. We run this in CI in a fresh Docker container with no dependencies installed, mostly to verify dynamic linking of the vendored dependencies.
@@ -0,0 +1,38 @@
1
+ _valhalla.cp312-win_amd64.pyd,sha256=J28YTAKadKQQadTeNBqirLGsvELMTAgrvFYLKS7eQp0,8132096
2
+ pyvalhalla_git-3.5.1.post132.data/platlib/abseil_dll-bdd8a5a1f5a4da3f67279509940f7994.dll,sha256=1tPsKVjXYxXSMRqiwisqWBZqan9oTY0QdIbO1lkPkKA,1887744
3
+ pyvalhalla_git-3.5.1.post132.data/platlib/gdal-e68c9d36ee94002182307d221cc91ce3.dll,sha256=9hXkACzQk79BuHHgTl-ez5WRfMX1wbSvYKSq-erJW1w,18052096
4
+ pyvalhalla_git-3.5.1.post132.data/platlib/geos-b8640de6faf146d9855a807e72427e47.dll,sha256=rMxgojYCprUIpViJo_yVD_pdo-dMNrJDKjIdw7gDI9w,2582016
5
+ pyvalhalla_git-3.5.1.post132.data/platlib/geos_c-7d79920a3a18ad2c1ff594fcef060f0a.dll,sha256=4Y7CAmrVctYKVXfrZCg0VFvxhKaJHNijLPUdM6OtTTs,457728
6
+ pyvalhalla_git-3.5.1.post132.data/platlib/geotiff-020296779aedd28fd03f34200e6e3c61.dll,sha256=PWk3itN74x-HJAediz-Gjw83Z3NyTwa1cvXxA7h65w0,161792
7
+ pyvalhalla_git-3.5.1.post132.data/platlib/jpeg62-52d863f4f0f8139faf1608976c1d91f6.dll,sha256=SjnGiaIWwMiUwvuTBP_vkfsWjjvVLXkpmC7CFy5iDac,683520
8
+ pyvalhalla_git-3.5.1.post132.data/platlib/json-c-0d6db73c6075abe84a7bdd2a2d393471.dll,sha256=IlPXuHM61ne0troWglvEwMK378fN8duzzNGUog7p6YU,58880
9
+ pyvalhalla_git-3.5.1.post132.data/platlib/Lerc-d4ff05a506ddcfc551c350aa718ab4da.dll,sha256=-DySnPhaoH9nCPkQ2Y7Vq2w3pRWyg9B4NPbM-0l5Vcw,526848
10
+ pyvalhalla_git-3.5.1.post132.data/platlib/libcurl-bfd466d47923540033e77b192031a728.dll,sha256=nB2vYmFVYjnnrOeYwmbtHQY6xCwq6JDToh6oq71Tf0c,595456
11
+ pyvalhalla_git-3.5.1.post132.data/platlib/libexpat-6da76b3644b9424613b6d75323fcdc82.dll,sha256=vxuy9QhoEf_ft2kgIRIdOVVnfj_sVkU-Dhf6VhxZf-c,159232
12
+ pyvalhalla_git-3.5.1.post132.data/platlib/liblzma-9b97b163f3fff34e786ef56c4f919383.dll,sha256=ud-buTBlGnilzkiz-jyM8R8cECpICtG6YIlnRGwuCZU,185856
13
+ pyvalhalla_git-3.5.1.post132.data/platlib/libpng16-45e0d625267ecee5996170051645e533.dll,sha256=MZvYOuWjg9vqE9Vik1Q0bR19UEqakLekRuBBbsCWgCM,201216
14
+ pyvalhalla_git-3.5.1.post132.data/platlib/libprotobuf-lite-2bea258fef20ab8f71dcb2fec86675a8.dll,sha256=z437wWJ5T6V4xBrWjpXjFoXO4KeDXIzWfhJOE-yc1ZY,1502208
15
+ pyvalhalla_git-3.5.1.post132.data/platlib/lz4-cb6b9d0ac653fc68b286ff6ba7ef9bf5.dll,sha256=miEEE0apHQb6DFgVksS8WI1XNUuKI5dLDbp8JI4f_QA,127488
16
+ pyvalhalla_git-3.5.1.post132.data/platlib/msvcp140-73e7ea186a7d9ab676a764ffa64cf7e6.dll,sha256=cDrXxV8uCWYH7Gp3qLX1LVNdvnH93wIel8vLvCP3SSo,576128
17
+ pyvalhalla_git-3.5.1.post132.data/platlib/proj_9-3a2a70c01b92ddd4e14ab2bc22e06ab7.dll,sha256=K4UyFrthaMgtt5JDBbJBcS3fqLz-M4rbB0A_9mm-aL0,3414528
18
+ pyvalhalla_git-3.5.1.post132.data/platlib/qhull_r-46ecfc2e889bb30a2c3af738edb6eeb9.dll,sha256=r4AobL8RQVZlP8WWC5x3ia_Z2LcFwDJNX6g6nNo6k5I,451072
19
+ pyvalhalla_git-3.5.1.post132.data/platlib/sqlite3-219685aef036100e03dd97e60c61281d.dll,sha256=2pgdTUHtB3sMMJDytAVh6Ca83hcPjPK7BLrIBQVbosA,1118208
20
+ pyvalhalla_git-3.5.1.post132.data/platlib/tiff-f8c8a1908722e0556fad08f0b5c1bb6f.dll,sha256=znbA_SkIowGQeQ8bR22yrlCDH9xEcvK8BEVbGNOxlKI,468480
21
+ pyvalhalla_git-3.5.1.post132.data/platlib/zlib1-8425906e295d322425fe840dc45228db.dll,sha256=krva8_8mnj2x_8xU3AcXFXyjJFT0ybZhKiIWURHpYu0,90624
22
+ pyvalhalla_git-3.5.1.post132.dist-info/DELVEWHEEL,sha256=1kYh8ExDuV1OfkRrnvXvVDjnw9-vsg4HU6eN-E0I_b4,433
23
+ pyvalhalla_git-3.5.1.post132.dist-info/METADATA,sha256=6Id03ahAgtjOIeYS3Ycr3iwL6CIXacZB12PZxjN3pEo,6795
24
+ pyvalhalla_git-3.5.1.post132.dist-info/RECORD,,
25
+ pyvalhalla_git-3.5.1.post132.dist-info/top_level.txt,sha256=mU472JpF5fOfpVQ8UxZ_dwLmecLogajAMO5RmYsU1gw,19
26
+ pyvalhalla_git-3.5.1.post132.dist-info/WHEEL,sha256=8UP9x9puWI0P1V_d7K2oMTBqfeLNm21CTzZ_Ptr0NXU,101
27
+ pyvalhalla_git-3.5.1.post132.dist-info/licenses/AUTHORS,sha256=zfqnWlS9zAHTcyIVTaquUA0hwOLARt8RbHyxV8ksIdo,176
28
+ pyvalhalla_git-3.5.1.post132.dist-info/licenses/COPYING,sha256=0-hXmYGEWqvizZa7uHZz_AefTiGcyE6O9mZH1e9Pf10,1157
29
+ pyvalhalla_git-3.5.1.post132.dist-info/licenses/LICENSE.md,sha256=TTSAvGrQ2khsitpI11WKnicjvEODZlalhi8PAzaRrV4,45
30
+ valhalla/actor.py,sha256=_A8eZpk7xk-7C6Xzz5nFE5Qp5GNInFjXurzjlh_ZmFA,4195
31
+ valhalla/config.py,sha256=LnxZ7uA42QOIB68ld_8VhRdTdsfs-sXQlu_AylLLFi4,1533
32
+ valhalla/utils.py,sha256=-hHjEDCftpOlRBib4CSZVDCLAZMqgtOtkX2V3-5bsJg,1985
33
+ valhalla/valhalla_build_config.py,sha256=xx8HY5RnP492PMP_DgJSgrum7OjkGWeUQAkZgag6LQM,43267
34
+ valhalla/_scripts.py,sha256=t7qQvmsbTfw7aVyJtI0o6aClfoC1rt4KUT2C8YQer74,1550
35
+ valhalla/_valhalla.cc,sha256=2PTlFjS5hA_mWn7_43zsSqx_lhjEzJZE2Ud6N3WpvnI,3780
36
+ valhalla/__init__.py,sha256=aV9sb4MMgTlHsEIPkaN4S_V0VXr_1n5cQ_25vrdFA3c,598
37
+ valhalla/__main__.py,sha256=HFxHPQfERuNIsitGTrvCEJ2to6IHDbRBGlCRZ6bZ2p0,2223
38
+ valhalla/__version__.py,sha256=69eEI6SOiFX0ni7aBQt84fKxcPdDq4R7skoBz6EuySU,551
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: false
4
+ Tag: cp312-cp312-win_amd64
5
+
@@ -0,0 +1,5 @@
1
+ Duane Gearhart <duane@mapzen.com>
2
+ Greg Knisely <greg@mapzen.com>
3
+ Kevin Kreiser <kevinkreiser@gmail.com>
4
+ Kristen DiLuca <kristen@mapzen.com>
5
+ Dave Nesbitt <dave@mapzen.com>
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Valhalla contributors
4
+ Copyright (c) 2015-2017 Mapillary AB, Mapzen
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
@@ -0,0 +1 @@
1
+ For license information see [here](COPYING)
@@ -0,0 +1,2 @@
1
+ _valhalla
2
+ valhalla
valhalla/__init__.py ADDED
@@ -0,0 +1,22 @@
1
+ """""" # start delvewheel patch
2
+ def _delvewheel_patch_1_10_1():
3
+ import os
4
+ if os.path.isdir(libs_dir := os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, '.'))):
5
+ os.add_dll_directory(libs_dir)
6
+
7
+
8
+ _delvewheel_patch_1_10_1()
9
+ del _delvewheel_patch_1_10_1
10
+ # end delvewheel patch
11
+
12
+ from pathlib import Path
13
+
14
+ try:
15
+ from ._valhalla import *
16
+ except ModuleNotFoundError:
17
+ from _valhalla import *
18
+ from .actor import Actor
19
+ from .config import get_config, get_help
20
+ from .__version__ import __version__
21
+
22
+ PYVALHALLA_DIR = Path(__file__).parent.resolve()
valhalla/__main__.py ADDED
@@ -0,0 +1,72 @@
1
+ import subprocess
2
+ import sys
3
+ from typing import Optional
4
+
5
+ from ._scripts import PYVALHALLA_BIN_DIR, run
6
+
7
+ try:
8
+ from .__version__ import version as __version__
9
+ except ImportError:
10
+ __version__ = "undefined"
11
+
12
+ PRINT_BIN_PATH = "print_bin_path"
13
+
14
+
15
+ def print_help():
16
+ # left-align executable names
17
+ exe_names = [p.name for p in PYVALHALLA_BIN_DIR.iterdir()]
18
+ fixed_width = len(max(exe_names, key=lambda x: len(x)))
19
+
20
+ # TODO: we also want the git commit to show here, probably written to __version__.py by setup.py's BDistWheelCommand
21
+ print(
22
+ F"""
23
+ valhalla Python package {__version__}
24
+
25
+ pyvalhalla package provides a CLI to run Valhalla C++ executables. Arguments are simply passed on as they are.
26
+ One notable exception is --quiet/-q, which will forward the C++ executable's stdout to /dev/null.
27
+ 'python -m valhalla --help' will print this help.
28
+
29
+ Example usage: 'python -m valhalla --quiet valhalla_build_tiles -c valhalla.json -s initialize -e build test.pbf'
30
+
31
+ Available commands (in {PYVALHALLA_BIN_DIR}):
32
+ \t{PRINT_BIN_PATH:<{fixed_width}} - Print the absolute path of directory containing the C++ executables
33
+ """
34
+ )
35
+
36
+
37
+ def main():
38
+ if len(sys.argv) < 2:
39
+ print("[FATAL] command needs arguments, see 'python -m valhalla --help': \n")
40
+ print_help()
41
+ sys.exit(1)
42
+
43
+ prog_or_opt = sys.argv[1]
44
+
45
+ if prog_or_opt in ("--help", "-h"):
46
+ print_help()
47
+ sys.exit(0)
48
+ elif prog_or_opt == PRINT_BIN_PATH:
49
+ # useful when another script wants to run the executables directly for some reason
50
+ print(PYVALHALLA_BIN_DIR)
51
+ else:
52
+ exc: Optional[Exception] = None
53
+ try:
54
+ run(from_main=True)
55
+ except (FileNotFoundError, subprocess.CalledProcessError) as e:
56
+ exc = e
57
+ finally:
58
+ if not exc:
59
+ sys.exit(0)
60
+
61
+ if isinstance(exc, subprocess.CalledProcessError):
62
+ print(f"Failed calling command '{exc.cmd}'\n")
63
+
64
+ print_help()
65
+ print("Sub-command failed with:\n")
66
+ print(exc, file=sys.stderr)
67
+
68
+ sys.exit(1)
69
+
70
+
71
+ if __name__ == "__main__":
72
+ main()
@@ -0,0 +1,21 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
+
6
+ TYPE_CHECKING = False
7
+ if TYPE_CHECKING:
8
+ from typing import Tuple
9
+ from typing import Union
10
+
11
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
12
+ else:
13
+ VERSION_TUPLE = object
14
+
15
+ version: str
16
+ __version__: str
17
+ __version_tuple__: VERSION_TUPLE
18
+ version_tuple: VERSION_TUPLE
19
+
20
+ __version__ = version = '3.5.1.post132'
21
+ __version_tuple__ = version_tuple = (3, 5, 1, 'post132')
valhalla/_scripts.py ADDED
@@ -0,0 +1,46 @@
1
+ from pathlib import Path
2
+ from shutil import which
3
+ import subprocess
4
+ import sys
5
+
6
+ from . import PYVALHALLA_DIR
7
+
8
+ PYVALHALLA_BIN_DIR = PYVALHALLA_DIR.joinpath("bin").resolve()
9
+
10
+
11
+ def run(from_main=False) -> None:
12
+ """
13
+ Parses the command line arguments and runs the Valhalla executables with the
14
+ provided arguments. Note, by default we assume this is not being called by
15
+ __main__.py via e.g. 'python -m valhalla ...', but directly with e.g.d
16
+ 'valhalla_build_tiles -h'. sys.argv relates to different executables for
17
+ both scenarios.
18
+
19
+ :param from_main: We parse sys.argv differently if it's called from __main__.py
20
+ """
21
+ prog = sys.argv[1] if from_main else Path(sys.argv[0]).name
22
+ prog_args = sys.argv[2:] if from_main else sys.argv[1:]
23
+
24
+ if not which(prog):
25
+ raise FileNotFoundError(f"Can't find executable at {prog}")
26
+ prog_path = PYVALHALLA_BIN_DIR.joinpath(prog).resolve()
27
+
28
+ print(f"[INFO] Running {prog_path} with args: {prog_args}...")
29
+
30
+ # --quiet/-q is our option, don't pass it to the executables
31
+ is_quiet = False
32
+ for arg in prog_args:
33
+ if arg not in ("--quiet", "-q"):
34
+ continue
35
+ prog_args.pop(prog_args.index(arg))
36
+ is_quiet = True
37
+
38
+ # recommended way to call exe
39
+ proc = subprocess.run(
40
+ [str(prog_path)] + prog_args,
41
+ stderr=sys.stderr,
42
+ stdout=subprocess.DEVNULL if is_quiet else sys.stdout,
43
+ )
44
+
45
+ # raises CalledProcessError if not successful
46
+ proc.check_returncode()
valhalla/_valhalla.cc ADDED
@@ -0,0 +1,81 @@
1
+ #include "baldr/rapidjson_utils.h"
2
+ #include "midgard/logging.h"
3
+ #include "midgard/util.h"
4
+ #include "tyr/actor.h"
5
+
6
+ #include <boost/make_shared.hpp>
7
+ #include <boost/noncopyable.hpp>
8
+ #include <boost/property_tree/ptree.hpp>
9
+ #include <pybind11/pybind11.h>
10
+
11
+ #include <string>
12
+
13
+ namespace vt = valhalla::tyr;
14
+ namespace {
15
+
16
+ // configuring multiple times is wasteful/ineffectual but not harmful
17
+ // TODO: make this threadsafe just in case its abused
18
+ const boost::property_tree::ptree configure(const std::string& config) {
19
+ boost::property_tree::ptree pt;
20
+ try {
21
+ // parse the config and configure logging
22
+ rapidjson::read_json(config, pt);
23
+
24
+ auto logging_subtree = pt.get_child_optional("mjolnir.logging");
25
+ if (logging_subtree) {
26
+ auto logging_config = valhalla::midgard::ToMap<const boost::property_tree::ptree&,
27
+ std::unordered_map<std::string, std::string>>(
28
+ logging_subtree.get());
29
+ valhalla::midgard::logging::Configure(logging_config);
30
+ }
31
+ } catch (...) { throw std::runtime_error("Failed to load config from: " + config); }
32
+
33
+ return pt;
34
+ }
35
+ } // namespace
36
+
37
+ namespace py = pybind11;
38
+
39
+ PYBIND11_MODULE(_valhalla, m) {
40
+ py::class_<vt::actor_t>(m, "_Actor", "Valhalla Actor class")
41
+ .def(py::init<>([](std::string config) { return vt::actor_t(configure(config), true); }))
42
+ .def(
43
+ "route", [](vt::actor_t& self, std::string& req) { return self.route(req); },
44
+ "Calculates a route.")
45
+ .def(
46
+ "locate", [](vt::actor_t& self, std::string& req) { return self.locate(req); },
47
+ "Provides information about nodes and edges.")
48
+ .def(
49
+ "optimized_route",
50
+ [](vt::actor_t& self, std::string& req) { return self.optimized_route(req); },
51
+ "Optimizes the order of a set of waypoints by time.")
52
+ .def(
53
+ "matrix", [](vt::actor_t& self, std::string& req) { return self.matrix(req); },
54
+ "Computes the time and distance between a set of locations and returns them as a matrix table.")
55
+ .def(
56
+ "isochrone", [](vt::actor_t& self, std::string& req) { return self.isochrone(req); },
57
+ "Calculates isochrones and isodistances.")
58
+ .def(
59
+ "trace_route", [](vt::actor_t& self, std::string& req) { return self.trace_route(req); },
60
+ "Map-matching for a set of input locations, e.g. from a GPS.")
61
+ .def(
62
+ "trace_attributes",
63
+ [](vt::actor_t& self, std::string& req) { return self.trace_attributes(req); },
64
+ "Returns detailed attribution along each portion of a route calculated from a set of input locations, e.g. from a GPS trace.")
65
+ .def(
66
+ "height", [](vt::actor_t& self, std::string& req) { return self.height(req); },
67
+ "Provides elevation data for a set of input geometries.")
68
+ .def(
69
+ "transit_available",
70
+ [](vt::actor_t& self, std::string& req) { return self.transit_available(req); },
71
+ "Lookup if transit stops are available in a defined radius around a set of input locations.")
72
+ .def(
73
+ "expansion", [](vt::actor_t& self, std::string& req) { return self.expansion(req); },
74
+ "Returns all road segments which were touched by the routing algorithm during the graph traversal.")
75
+ .def(
76
+ "centroid", [](vt::actor_t& self, std::string& req) { return self.centroid(req); },
77
+ "Returns routes from all the input locations to the minimum cost meeting point of those paths.")
78
+ .def(
79
+ "status", [](vt::actor_t& self, std::string& req) { return self.status(req); },
80
+ "Returns nothing or optionally details about Valhalla's configuration.");
81
+ }
valhalla/actor.py ADDED
@@ -0,0 +1,118 @@
1
+ import json
2
+ import tempfile
3
+ from pathlib import Path
4
+ from typing import Union
5
+
6
+ try:
7
+ from ._valhalla import _Actor
8
+ except ModuleNotFoundError:
9
+ from _valhalla import _Actor
10
+
11
+
12
+ # TODO: wasteful for dict input/output; more reasonable would be to extend
13
+ # the Actor's action C++ interfaces with a JSON arg
14
+ def dict_or_str(func):
15
+ def wrapped(*args):
16
+ # /status doesn't take any parameters
17
+ if not len(args) > 1:
18
+ return func(*args)
19
+
20
+ if isinstance(args[1], dict):
21
+ return json.loads(func(args[0], json.dumps(args[1])))
22
+ elif not isinstance(args[1], str):
23
+ raise ValueError("Request must be either of type str or dict")
24
+ return func(*args)
25
+
26
+ return wrapped
27
+
28
+
29
+ class Actor(_Actor):
30
+ def __init__(self, config: Union[Path, str, dict]):
31
+ """
32
+ Valhalla's Actor class is used to call its actions, like route, isochrone, matrix etc.
33
+
34
+ Configuration passed in either by an existing configuration JSON file path or in `dict` form,
35
+ e.g. by calling valhalla.config.get_config(). In the latter case a temp file will be
36
+ created.
37
+
38
+ For details on parameters for each function consult Valhalla's documentation:
39
+ https://github.com/valhalla/valhalla/blob/master/docs/api
40
+ """
41
+ # make sure there's a valhalla.json file
42
+ if isinstance(config, dict):
43
+ with tempfile.NamedTemporaryFile(
44
+ "w", suffix=".json", prefix="valhalla_config_", delete=False
45
+ ) as f:
46
+ json.dump(config, f)
47
+ self._config_path = f.name
48
+ elif isinstance(config, str):
49
+ if not Path(config).is_file():
50
+ raise FileNotFoundError(f"Valhalla JSON config file doesn't exist: {config}")
51
+ self._config_path = config
52
+ elif isinstance(config, Path):
53
+ self._config_path = str(config.resolve())
54
+ else:
55
+ raise AttributeError(f"Valhalla JSON config can't be of type {type(config)}")
56
+
57
+ # test if there's an extract or tile_dir
58
+ with open(self._config_path) as f:
59
+ config = json.load(f)
60
+ tile_extract_fp = config.get("mjolnir", {}).get("tile_extract")
61
+ tile_dir = config.get("mjolnir", {}).get("tile_dir")
62
+
63
+ # raise if neither exists
64
+ if not tile_extract_fp and not tile_dir:
65
+ raise AttributeError(
66
+ "Valhalla config JSON is not valid: mjolnir.tile_extract and mjolnir.tile_dir are missing."
67
+ )
68
+ if not Path(config["mjolnir"]["tile_extract"]).is_file():
69
+ if not Path(config["mjolnir"]["tile_dir"]).is_dir():
70
+ raise FileNotFoundError(
71
+ f"Neither mjolnir.tile_extract ({Path(tile_extract_fp).resolve()}) nor mjolnir.tile_dir ({Path(tile_dir).resolve()}) exists. Can't load graph."
72
+ )
73
+
74
+ super(Actor, self).__init__(self._config_path)
75
+
76
+ @dict_or_str
77
+ def route(self, req: Union[str, dict]):
78
+ return super().route(req)
79
+
80
+ @dict_or_str
81
+ def locate(self, req: Union[str, dict]):
82
+ return super().locate(req)
83
+
84
+ @dict_or_str
85
+ def isochrone(self, req: Union[str, dict]):
86
+ return super().isochrone(req)
87
+
88
+ @dict_or_str
89
+ def matrix(self, req: Union[str, dict]):
90
+ return super().matrix(req)
91
+
92
+ @dict_or_str
93
+ def trace_route(self, req: Union[str, dict]):
94
+ return super().trace_route(req)
95
+
96
+ @dict_or_str
97
+ def trace_attributes(self, req: Union[str, dict]):
98
+ return super().trace_attributes(req)
99
+
100
+ @dict_or_str
101
+ def height(self, req: Union[str, dict]):
102
+ return super().height(req)
103
+
104
+ @dict_or_str
105
+ def transit_available(self, req: Union[str, dict]):
106
+ return super().transit_available(req)
107
+
108
+ @dict_or_str
109
+ def expansion(self, req: Union[str, dict]):
110
+ return super().expansion(req)
111
+
112
+ @dict_or_str
113
+ def centroid(self, req: Union[str, dict]):
114
+ return super().centroid(req)
115
+
116
+ @dict_or_str
117
+ def status(self, req: Union[str, dict] = ""):
118
+ return super().status(req)