Skip to content

Instantly share code, notes, and snippets.

@erikbern
Created September 2, 2022 22:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erikbern/945fe32b7db987ae94950795169c6219 to your computer and use it in GitHub Desktop.
Save erikbern/945fe32b7db987ae94950795169c6219 to your computer and use it in GitHub Desktop.
import json
import subprocess
import sys
import tempfile
import modal
stub = modal.Stub()
stub.sv = modal.SharedVolume().persist("valhalla")
image = modal.DockerhubImage("valhalla/valhalla:run-latest", setup_commands=["apt-get update", "apt-get install -y python3-pip"])
def run_command(cmd):
subprocess.run(cmd, shell=True, stdout=sys.stdout, stderr=sys.stderr)
@stub.function(image=image, shared_volumes={"/valhalla": stub.sv})
def install():
run_command("wget -P /valhalla http://download.geofabrik.de/europe/liechtenstein-latest.osm.pbf")
run_command("mkdir -p /valhalla/tiles")
run_command("valhalla_build_config --mjolnir-tile-dir /valhalla/tiles --mjolnir-tile-extract /valhalla/tiles.tar --mjolnir-timezone /valhalla/tiles/timezones.sqlite --mjolnir-admin /valhalla/tiles/admins.sqlite > /valhalla/valhalla.json")
run_command("valhalla_build_timezones > /valhalla/tiles/timezones.sqlite")
run_command("valhalla_build_tiles -c /valhalla/valhalla.json /valhalla/liechtenstein-latest.osm.pbf")
run_command("valhalla_build_extract -c /valhalla/valhalla.json -v")
@stub.function(image=image, shared_volumes={"/valhalla": stub.sv})
def isochrone(payload):
with tempfile.NamedTemporaryFile() as t:
with open(t.name, "w") as f:
json.dump(payload, f)
p = subprocess.run(f"valhalla_service /valhalla/valhalla.json isochrone {t.name}", shell=True, capture_output=True)
return json.loads(p.stdout)
if __name__ == "__main__":
with stub.run():
# uncomment this if you want to install everything (slow)
# install()
payload = {
"locations": [
{"lat": 47.1410, "lon": 9.5209}, # vaduz
],
"costing":"pedestrian",
"contours": [
{"time": 10, "color": "ff0000"}
],
"show_locations": True
}
# Compute a single isochrone
result = isochrone(payload)
print(result)
# Use Modal to parallelize and compute 1000 isochrones
results = []
for result in isochrone.map([payload] * 1000):
results.append(result)
print(f"got {len(results)} results so far")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment