-
-
Notifications
You must be signed in to change notification settings - Fork 51
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
Add pmtiles extract
command
#31
Comments
Maybe there is already a trivial way to do something like this with mbtiles tools like |
Yeah, this is not implemented yet for v3. The new design should allow for really efficient spatial extracts from remote archives, but the implementation will be a bit more complex. |
I guess the Hilbert ordering of tiles helps with the efficient extracts, right? Where do you think will be the main complexity in implementing area downloads? |
Can I help implementing an |
Here is list of all the tasks I can think of right now:
|
Cool, thanks for the list. What also could be nice is geofabrik-like area names, e.g. |
Supporting the .poly format would allow for that. (They have the downloadable polygons in that format on Geofabrik.) |
Haha my first go program! case "extract":
var z uint8 = 14
var x_min uint32 = 0
var x_max uint32 = 10000 // included
var y_min uint32 = 0
var y_max uint32 = 10000 // included
var tile_ids []uint64
for x := x_min; x <= x_max; x++ {
for y := y_min; y <= y_max; y++ {
// fmt.Println(z, x, y, pmtiles.ZxyToId(z, x, y))
tile_ids = append(tile_ids, pmtiles.ZxyToId(z, x, y))
}
}
sort.Slice(tile_ids, func(i, j int) bool { return tile_ids[i] < tile_ids[j]})
var tile_id_ranges [][2]uint64
tile_id_ranges = append(tile_id_ranges, [2]uint64{tile_ids[0], tile_ids[0]})
for i := 1; i < len(tile_ids); i++ {
if tile_id_ranges[len(tile_id_ranges)-1][1] + 1 == tile_ids[i] {
tile_id_ranges[len(tile_id_ranges)-1][1] = tile_ids[i]
} else {
tile_id_ranges = append(tile_id_ranges, [2]uint64{tile_ids[i], tile_ids[i]})
}
}
fmt.Println(len(tile_ids))
fmt.Println(len(tile_id_ranges))
It computes the ranges of tiles which lie in hilbert ordering inside a rectangle which is defined by a x, y bounding box. Running it at z14 for something which is almost as large as the planet takes like 20 seconds on my laptop... |
I found a few snippets on how to write a .pmtiles file, but I am not sure how to read one. Can I use the code in |
You should reuse the code in https://github.com/protomaps/go-pmtiles/blob/main/pmtiles/directory.go#L135 etc loop.go isn't the best comparison, because that requires random access over an archive. for extracting you should only need to iterate over the entire directory once, so you can keep just one leaf in memory at a time instead of an LRU cache. |
Thanks for the hint. It seems like By the way, the z/x/y = 0/0/0 tile in my example archive has offset = 0. Does that mean that the first byte of the pmtiles file is where the 0/0/0 tile starts? |
for tile entries ( |
I don't quite understand yet how pmtiles works. Maybe you can help me with an example... Let's say I would like to extract a single tile |
The logic to extract a single tile is these lines in https://github.com/protomaps/go-pmtiles/blob/main/pmtiles/show.go#L144 is the point at which you know you have a matching tile in the archive and grab the bytes using |
Thanks, exactly, this seems like the right approach for reading data. What I am unsure about is how I get from an |
#20 is relevant so we can refactor the write logic out of convert.go |
Can I suggest that it would also be nice if there was a --maxzoom option, similar to what is implemented in the python version, so that it would be possible to extract tiles down to a specific zoom level. |
* Experimental cli support for extracting a region from a larger archive, given a maxzoom and GeoJSON multipolygon region. * Limited to credentialed buckets or local files now, public HTTP to come later * Limited to a single download thread * Change directory optimization to be faster and match Java implementation, affects root/leaf sizes
* include the DstOffset so we can multithread downloads later * set header statistics * implement --dry-run * add logging messages for user feedback
* implement pmtiles extract [#31, #52] * Experimental cli support for extracting a region from a larger archive, given a maxzoom and GeoJSON multipolygon region. * Limited to credentialed buckets or local files now, public HTTP to come later * Limited to a single download thread * Change directory optimization to be faster and match Java implementation, affects root/leaf sizes * Finish initial extract [#31] * include the DstOffset so we can multithread downloads later * set header statistics * implement --dry-run * add logging messages for user feedback
This has been implemented in https://github.com/protomaps/go-pmtiles/releases/tag/v1.9.0 The only big missing feature is faster download speed - let's exercise the code as-is to make sure results are correct starting a separate feedback thread, report success and failure there |
It would be useful to be able to extract tiles from a pmtiles file for a certain area and put the extracted tiles into a new pmtiles file.
It could look something like this:
A usecase could be to have a global tileset and allow users to download an extract for a city or so.
The text was updated successfully, but these errors were encountered: