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

Add H3 layers #2808

Merged
merged 6 commits into from
Mar 20, 2019
Merged

Add H3 layers #2808

merged 6 commits into from
Mar 20, 2019

Conversation

Pessimistress
Copy link
Collaborator

For #2443

H3HexagonLayer (instanced):

h3-hexagon

H3ClusterLayer (renders geojson polygons):

h3-cluster

Change List

  • Add H3HexagonLayer and H3ClusterLayer
  • API documentation
  • Tests

@coveralls
Copy link

coveralls commented Mar 16, 2019

Coverage Status

Coverage increased (+0.2%) to 58.982% when pulling d8993c1 on h3-layers into 5aa5714 on master.

Copy link
Collaborator

@akre54 akre54 left a comment

Choose a reason for hiding this comment

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

This looks great and will help us a ton, thanks @Pessimistress!

renderLayers() {
const {data, getHexagon, updateTriggers} = this.props;

const SubLayerClass = this.getSubLayerClass('hexagon-cell', ColumnLayer);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does ColumnLayer handle calculation of normals based on vertices in the primitive geometry?

Copy link
Collaborator Author

@Pessimistress Pessimistress Mar 19, 2019

Choose a reason for hiding this comment

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

Not yet, it currently assumes that normals are close enough to the regular polygon. We do not render normals correctly anyways (normals are interpolated instead of flat for each side).

Copy link
Collaborator

Choose a reason for hiding this comment

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

normals are interpolated instead of flat for each side

Unless we have some other good ideas, the standard solution is to duplicate vertices for the edges. Since this leads to a bigger geometry, we may want to have that as an option/prop on the ColumnLayer: shading: 'flat' or shading; 'smooth'.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The ColumnLayer is currently using CylinderGeometry from luma. I feel this option needs to be added at the source.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That could make sense. Opened luma issue visgl/luma.gl#994, so that deck can reference this in a follow-up tracker ticket for the H3 layers.

data: h3.kRing('882830829bfffff', 4),
getHexagon: d => d,
getColor: (d, {index}) => [255, index * 5, 0],
getElevation: (d, {index}) => index * 100
Copy link
Collaborator

Choose a reason for hiding this comment

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

is it possible to add another getCoverage accessor?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes? What is the use case, do we need different coverage for each hexagon?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will do in a follow up PR.

Copy link
Collaborator

@ibgreen ibgreen left a comment

Choose a reason for hiding this comment

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

Looks quite thorough, nice work!

  • The best validation of the updates would be to update internal apps to use the open source versions.
  • Do we want to give ourself some freedom until then by marking these as experiments (could just be marked after title, no underscore or similar)?


# H3ClusterLayer

The H3ClusterLayer Layer renders regions represented by hexagon sets from the [h3](https://uber.github.io/h3/) geospatial indexing system.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: backticks around class names

Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps worth auditing the naming with H3 folks. At the time I was working with the library, a cluster wasn't a thing, maybe there is a term that fits better?

@nrabinowitz @isaacbrodsky

An idea is that it would ultimately be nice to offer some level of "parity" between H3 and S2 layers, so a similar cluster layer could be on the roadmap for S2 layers...

docs/layers/h3-hexagon-layer.md Outdated Show resolved Hide resolved

## Remarks

* Each hexagon in the H3 indexing system is [slightly different in shape](https://uber.github.io/h3/#/documentation/core-library/coordinate-systems). To draw a large number of hexagons efficiently, the H3HexagonLayer assumes that all hexagons within the current viewport have the same shape as the one at the center of the current viewport. This strategy is usually sufficient. However, the discrepancy may become visually significant at rare geolocations. In that case, the [H3ClusterLayer] can be used as an alternative by trading performance for accuracy.
Copy link
Collaborator

Choose a reason for hiding this comment

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

  • Backticks.
  • In spite of being a composite layer, this only handles one H3 aperture, maybe mention that?
  • Top aperture has mix of hexagons and pentagons, comment that this is not covered?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It is mentioned in the description of getHexagon.

Copy link

Choose a reason for hiding this comment

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

If I can interject, every aperture has a mix of hexagons and pentagons. The pentagons have simply been placed in water so common use-cases do not run into them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This will require some changes in the ColumnLayer, will do in a follow up PR. Do you have a hex id I can test with?

Copy link

Choose a reason for hiding this comment

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

Sure. One example pentagon at resolution 9 is 891c0000003ffff.

Copy link

Choose a reason for hiding this comment

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

(To be fair, when I said "a mix of hexagons and pentagons" there are always 12 pentagons at each resolution, so the higher the resolution it becomes far, far less likely to run into one.)

You may also want to run a kRing of 10 or 20 around that pentagon, since pentagons are at the epicenter of the hexagon distortions and you're going to run into essentially 5 different hexagon shapes in that area (one for each of the icosahedron faces the hexagons are on, and technically some really weird ones that are split across the icosahedron boundaries).

@@ -4,11 +4,14 @@ import {
MeshLayer,
ScenegraphLayer,
GreatCircleLayer,
S2Layer
S2Layer,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Playing with alignment... S2CellLayer?

renderLayers() {
const {data, getHexagon, updateTriggers} = this.props;

const SubLayerClass = this.getSubLayerClass('hexagon-cell', ColumnLayer);
Copy link
Collaborator

Choose a reason for hiding this comment

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

normals are interpolated instead of flat for each side

Unless we have some other good ideas, the standard solution is to duplicate vertices for the edges. Since this leads to a bigger geometry, we may want to have that as an option/prop on the ColumnLayer: shading: 'flat' or shading; 'smooth'.

@@ -407,6 +407,14 @@ export const docPages = generatePath([
name: 'GridCellLayer',
content: getDocUrl('layers/grid-cell-layer.md')
},
{
name: 'H3HexagonLayer',
content: getDocUrl('layers/h3-hexagon-layer.md')
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: I think we should have a separate index rather than duplicate layers in two places just to get an alphabetic list. An index could be easily auto-generated by ocular once we port the deck website after v7 release. The docs should just contain folders corresponding to the modules. If keeping this.

modules/geo-layers/src/h3-layers/h3-hexagon-layer.js Outdated Show resolved Hide resolved
docs/layers/h3-cluster-layer.md Outdated Show resolved Hide resolved
docs/layers/h3-hexagon-layer.md Outdated Show resolved Hide resolved
docs/layers/h3-hexagon-layer.md Outdated Show resolved Hide resolved
docs/layers/h3-hexagon-layer.md Outdated Show resolved Hide resolved

<p class="badges">
<img src="https://img.shields.io/badge/64--bit-support-blue.svg?style=flat-square" alt="64-bit" />
<img src="https://img.shields.io/badge/extruded-yes-blue.svg?style=flat-square" alt="extruded" />
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to add an H3 version badge, similar to what we have on the binding readme: http://github.com/uber/h3-js?

Copy link
Collaborator Author

@Pessimistress Pessimistress Mar 19, 2019

Choose a reason for hiding this comment

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

I don't expect the JavaScript API to be important here, but the version of the indexing system definitely matters. How stable is the h3-js API? Could we relax the dependency to something like ">=2" so users may pick their version?

Copy link
Contributor

Choose a reason for hiding this comment

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

As long as it's the same major version it should be fine. cc @nrabinowitz

Copy link
Contributor

Choose a reason for hiding this comment

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

Honestly even the major version of the library shouldn't matter, as long as it's the same index version.

if (resolution < 0) {
return;
}
const hex = geoToH3(viewport.latitude, viewport.longitude, resolution);
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if this is a pentagon?

Copy link
Contributor

Choose a reason for hiding this comment

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

Discussed offline with @Pessimistress - the responsibility is on the user to use this fast version only if they're willing to deal with occasional issues arising from pentagons and crossing icosahedron edges.

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.

8 participants