Skip to content
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

Implement screen coord translation for MVT writer #150

Merged
merged 5 commits into from
Aug 9, 2023
Merged

Implement screen coord translation for MVT writer #150

merged 5 commits into from
Aug 9, 2023

Conversation

pka
Copy link
Member

@pka pka commented Aug 6, 2023

Contains a breaking change in the ToMvt signatures. @nyurik Is that ok for you?

@pka pka requested a review from nyurik August 6, 2023 11:42
@nyurik
Copy link
Member

nyurik commented Aug 7, 2023

Hi @pka, i'm ok with changing signatures, as long as we obey the versioning rules (bump the minor). Otherwise we could go the easier route and simply not change the existing method, but instead add a new as_mvt_scaled. Either is fine i guess.

That said, I am not too certain about the API itself. If we take PostGIS's MVT as a guide, it has 2 components: envelope and extent. The extent is a positive integer (same for both X and Y), and should probably be named extent. The envelope is a trickier one - technically MVT never mandates things to be in the 3857 (web mercator), but that's usually the case. Could you elaborate of your thinking with the API? Thx!

@pka
Copy link
Member Author

pka commented Aug 7, 2023

Thanks for pointing to Postgis. My starting point was the Morecantile API, on which the rewrite of tile-grid as an OGC API Tiles implementation was based. OGC has a type boundingBox with lowerLeft and upperRight, but also other variants and tileWidth/tileHeight. Since MVT tiles are quadratic, I ended up with tile_size. But extent is ok too, since this is the term from the MVT spec. The proposed bounds are in geometric coordinates without tile borders like ST_AsMVTGeom. So you can directly use the calculated bounds from the tile matrix set.

I'm for changing the signature with an appropriate version bump and I'm fine with changing tile_size to extent, to match the MVT spec.

@pka
Copy link
Member Author

pka commented Aug 7, 2023

What speaks against extent is, that it's often used as an other term for bounds. It's not wrong, but rather unusual for describing a tile size in pixels.

@nyurik
Copy link
Member

nyurik commented Aug 7, 2023

thx, yes, i do think extent is a much better thing here simply to match the spec - creates fewer "new words" keeps things easier.

The conversion of any given geo-object (i.e. geojson) to MVT is a tricky subject because of how it is possible to do it in multiple ways. So, given a geojson, a user may want to:

  • convert it to a single MVT tile, clipping unrelated stuff, and translating geometry to MVT coordinates
  • convert it to multiple geometries same way as Planetiler does, resulting in a vector of Vec<(zxy_coordinate, MvtTile)>
  • treat incoming geometry as already being in the tile coordinate space (not sure if this is actually useful for anyone?)

So for the first case, MVTWriter should probably have the knowledge of the current tile its writing to (for the first usecase), but for the second it would simply receive geometry in the local tile coordinate space. From the optimization perspective, those coordinates should already be integers.

@pka
Copy link
Member Author

pka commented Aug 7, 2023

We should stay with the minimal useful conversion function and not try to write a full ST_AsMVTGeom with generalization, clipping, etc. That can be done by a tile server engine using geozero. For translating geometries into MVT, tile size (extent) and bounds have to be known. As far as I remember, MVT geometries can be concatenated. So you could also merge to the output of multiple geometries into a single feature. The tile coordinate use case is rather exotic, but makes maybe sense for a Planetiler-like transformation pipeline. Since geozero has only a f64 coordinates API, this use case is not easy to support.

@nyurik
Copy link
Member

nyurik commented Aug 7, 2023

I agree that (at least initially) geozero should focus on the MVP. The current mvp essentially has no re-projection, so it doesn't do proper conversion to a planar coordinate system, possibly resulting in an error. Your modification adds simple scaling that assumes that the initial coordinates are in the 0th tile of the planar projection, and you simply scale it to the right zoom/x/y location. I guess this is needed, but in general, esp when dealing with geojson, the input is likely to be in a 4326, so there should be an easy way to reproject as part of the conversion... which I am not too certain how to do in geozero context yet.

WRT concatenations, AFAIK, you can only concatenate MVT Layers (because they are at the top of the MVT spec). I used that trick in OpenMapTiles to generate MVTs directly from PostGIS, concatenating multiple ST_AsMVT calls together, each generating individual layer.

WRT f64 - yep, makes sense, i guess we will have to wait for the georust to support proper multi-type geotypes, including the ones with integers, and also migrate geozero to those types?

@nyurik
Copy link
Member

nyurik commented Aug 8, 2023

P.S. I think the original to_mvt should be renamed to to_mvt_raw -- simply because a "tile" without any scaling has no meaning. That said, it seems other conversions like to_json do not make much sense either - simply because there is no point in converting an MVT tile to geojson without the transformation... Should we perhaps remove it?

@pka
Copy link
Member Author

pka commented Aug 8, 2023

Good point regarding geographic coordinates. Projecting to planar coordinates is indeed an important step which is not integrated in geozero yet. I made some experiments with processing chains a long time ago, but they weren't successful.
to_json is still useful for MVT inspection having a text format including non-geometric properties (unlike WKT).

@nyurik
Copy link
Member

nyurik commented Aug 8, 2023

I did a few minor optimizations in #152 that would be merged into this PR first, and then I can merge this PR

Copy link
Member

@nyurik nyurik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

Going forward, perhaps we should create a separate "MVT wrapper" that could be created on top of an MVT object, and somehow apply all the re-projection logic?

pka and others added 5 commits August 9, 2023 15:34
* On a second though, I think `to_mvt_unscaled` is more accurate. `raw`
here would be confusing.
* There is no need to store bounds and do additional math ops on it. Can
precompute a few things earlier on.
* Default can be auto-derived
@nyurik nyurik merged commit 1023c28 into main Aug 9, 2023
2 checks passed
@nyurik nyurik deleted the mvttrans branch August 9, 2023 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants