-
Notifications
You must be signed in to change notification settings - Fork 785
Add simple vector tile rendering service #5663
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| @@ -0,0 +1,303 @@ | |||
| <!DOCTYPE html> | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I quickly built demo server using our very new NodeJS bindings...
bed27b1 to
7e77558
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a vector tile rendering service to Valhalla, enabling the generation of Mapbox Vector Tiles (MVT) from Valhalla's graph data. The implementation is inspired by OSRM's similar functionality and provides a new tile(x, y, z) API endpoint.
Key changes:
- Introduced
heimdallmodule for vector tile generation with configurable zoom levels per road class - Added
tile()method toactor_tfor serving MVT tiles via z/x/y coordinates - Integrated vtzero library as a third-party dependency for MVT encoding
Reviewed Changes
Copilot reviewed 27 out of 28 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| valhalla/heimdall/worker.h | New worker class for rendering vector tiles with edges and nodes layers |
| valhalla/heimdall/util.h | Utility functions for Web Mercator projection and tile coordinate conversion |
| src/heimdall/worker.cc | Core tile rendering implementation with geometry clipping and property encoding |
| src/heimdall/util.cc | Implementation of tile-to-bbox and coordinate conversion utilities |
| valhalla/tyr/actor.h | Added public tile() method to actor interface |
| src/tyr/actor.cc | Actor implementation delegating to heimdall worker |
| test/gurka/test_heimdall.cc | Gurka-based tests for tile rendering at various zoom levels |
| test/actor.cc | Integration tests using Utrecht tiles dataset |
| src/bindings/python/valhalla/actor.py | Python binding for tile method returning bytes |
| src/bindings/nodejs/src/valhalla.cc | Node.js async binding for tile method |
| src/bindings/nodejs/examples/tilevis/ | Complete tile visualization example with HTTP server and MapLibre integration |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
I think I am ready for first round of review... Let's decide what should be done to have it merged to |
hehe classic:) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like a great start @SiarheiFedartsou ! thanks a lot, this has been on the roadmap forever.. and finally an endpoint where (I hope) we don't have to worry about PBF output:) thanks for switching to maplibre and being generous with docstrings! this took quite a bit of effort to review tbh, but was also fun:) sorry for the tons of comments, I've been pretty nitty, feel free to ignore some of it or push it out into another PR. I think this is already pretty great.
after some demoing it seems level 12 tiles are super heavy with easily 20 MB around berlin for a single one (and there's multiple similar ones). we should probably tweak the min zoom per road class defaults a bit so we don't overload I/O. but of course it's configurable.
also we should add a page to the docs for API reference, so people understand how to use it with GET, what query parameters we offer etc. and mark it BETA for now I'd say. never mind, no HTTP yet..
I wanna implement this in the web app and the qgis plugin, that'll be very helpful when debugging. a few questions or ideas:
- let's get this into valhalla_service and wire it up with the other HTTP workers; I can do that if you want
- over time it'd be cool to have a few standard MVT styles/filters/views(whatever's the right term :D), e.g highlight dest-only edges, coloring by road class etc. would we pack them into individual style.json files and use the github raw endpoint for distribution? or is there a smarter way? I guess one could allow for manual style.json's as well, with QGIS one can style pretty easily and export as MBX style.json
- would an attribute controller be beneficial to decrease the tile size even more? how big are urban tiles typically? (answered my own question: the busiest is by default level 12 with > 20 MB tiles)
|
I'd also offer to do the changes myself in case you're overstretched @SiarheiFedartsou, I'm quite eager to merge this :) if you're ok with that, just let me know which change requests you don't agree with. |
@nilsnolde I was going to look into it by the end of the week, but if you can do it instead - it is even better 🙂 I went through comments - seems that I agree with everything, so please feel free to finish it if you have time for that 🙏 I'd just ask to avoid force pushes just in case 😀 |
|
a bit of a downer: we can't have this as its own module & worker sadly.. it works fine for the actor, but for HTTP we can only have a single module/endpoint connected to prime_server. the easiest is to put it into loki, it's well inline with its scope.
|
|
I tried this with QGIS: doesn't work with prime_server for some reason.. the requests never reach Valhalla. It did work with the example JS server, albeit crazy slow.. Didn't investigate further yet.. |
| double min_lat_rad = std::atan(std::sinh(kPiD * (1 - 2 * (y + 1) / n))); | ||
| double max_lat_rad = std::atan(std::sinh(kPiD * (1 - 2 * y / n))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not gonna touch /tile again before this PR is merged, but for future reference, we might want to copy a few lines from OSRM, which seems to have a fast approx algo to do the projection: https://github.com/Project-OSRM/osrm-backend/blob/01605f7589e6fe68df3fc690ad001b687128aba7/include/util/web_mercator.hpp#L64.
Issue
#1703
Basically what I am doing is:
actor_tnow has simpletile(x, y, z)method which returns std::string containing generated tileCandidateSearch::RangeQueryfrom meili with bbox of tile from request and obtain all edges from that bbox in this way (may be CandidateSearch is not the best choice here, but it seems to do exactly what we need)It is for 100% inspired by OSRMs similar method - they have it for years...
Still on very early stage. A lot of things to be done:
Tasklist
Requirements / Relations
Link any requirements here. Other pull requests this PR is based on?