visgl / deck.gl

WebGL2 powered visualization framework
https://deck.gl
MIT License
12.29k stars 2.09k forks source link

[Feat] H3HexagonLayer / Allow to lift hexagons above the ground #9165

Open birdofpreyru opened 2 months ago

birdofpreyru commented 2 months ago

Target Use Case

I need to render data on H3 grid as 3D (extruded) hexagons stacked on top of each other. I figured out, the easy and versatile way to support it is to optionally allow user to lift each hexagon above the ground by a per-hexagon value (I'll deliberately avoid saying elevation here and below, as there is already an optional getElevation accessor in the layer, and it specifies extrusion of the hexagon, rather than the lift of entire hexagon above the ground). Then multiple hexagons with the same H3 index and different lift above the ground can be used to render a stack of hexagons, and perhaps some other visualizations may also leverage it.

Proposal

I think to modify getHexagon accessor's signature from the current () => string to () => string | [string, number]. If it returns a string, it is just H3 index, and zero lift above the ground — the library will act the same as before, thus maintaining the full backward compatibility; if getHexagon returns a [string, number] tuple, the first value is interpreted as H3 index, and the second one as the lift of entire hex (hex base) above the ground.

I'll put together a PR with this update today. Created the issue to collect any feedback before it.

felixpalmer commented 2 months ago

Thanks for the proposal :)

It feels a little odd to me to have getHexagon return a mix of data like this, even if I see how it is sort of similar to how other layers returning 3D coordinates from getPosition. Some thoughts:

ibgreen commented 2 months ago

Then multiple hexagons with the same H3 index and different lift above the ground can be used to render a stack of hexagons, and perhaps some other visualizations may also leverage it.

Stacked columns is a use case that has come up before and it would indeed be cool to have good support for it.

I haven't looked at this for a while, but I agree with @felixpalmer's thoughts. I believe that it could be possible to build such support into e.g. the column layer as well and define common conventions for how to do it across a subset of our layers.

It might be nice to have perhaps a composite layer built on top where you could specify which columns of a table should be "stacked" in each "column". That would make it really easy to do this type of visualizations at least when the data is grouped by H3 in a single table.

birdofpreyru commented 2 months ago

even if I see how it is sort of similar to how other layers returning 3D coordinates from getPosition

Exactly. Not knowing any better, I just followed the logic in the underlying PolygonLayer, in particular explained in its getElevation docs — that returns the «extrusion height» of the polygon, and the «base elevation» of polygon is taken from Z-coordinate returned by getPolygon accessor.

Would getElevation returning a 2D range be more intuitive?

That will make getElevation unnecessary different from PolygonLayer.

Does the name of getElevation make sense if the column is not grounded at 0?

Not sure, but it mimics the way things are in PolygonLayer.

If we are to include this in the library, we should support all geocell style layers

How would this work for transitions

Could any potential API be applied in the case of aggregation layers?

As I said, I need to render stacked H3 hexagon layer in an ongoing, and quite intense project. I am afraid, I don't have capacity now to deep-dive into inner DeckGL engineering, beyond a minimal, quick patch solving the immediate need of my client.

It might be nice to have perhaps a composite layer built on top where you could specify which columns of a table should be "stacked" in each "column". That would make it really easy to do this type of visualizations at least when the data is grouped by H3 in a single table.

I think, leaving the exact stacking logic to consumer is more flexible, in a useful way. E.g. one may want some vertical gaps between stacked hexes, or, say, if in some hex some data are missing, it may want to leave an empty vertical space instead of them, or «collapse» the missing space. Providing config options for every esoteric edge case won't be feasible; but just leaving it to user to make stacks using the «base elevation» seems to allow lots of stuff.

ibgreen commented 2 months ago

It might be nice to have perhaps a composite layer built on top where you could specify which columns of a table should be "stacked" in each "column". That would make it really easy to do this type of visualizations at least when the data is grouped by H3 in a single table.

I think, leaving the exact stacking logic to consumer is more flexible, in a useful way. E.g. one may want some vertical gaps between stacked hexes, or, say, if in some hex some data are missing, it may want to leave an empty vertical space instead of them, or «collapse» the missing space. Providing config options for every esoteric edge case won't be feasible; but just leaving it to user to make stacks using the «base elevation» seems to allow lots of stuff.

True. But adding a new composite layer on top of the elevation capable "columnn layers" would not prevent users from using the underlying layers and process data themselves instead if they want to do the required work. deck.gl caters to a wide range of users with different skills and appetites for coding such things.