vasturiano / globe.gl

UI component for Globe Data Visualization using ThreeJS/WebGL
https://vasturiano.github.io/globe.gl/example/world-population/
MIT License
1.99k stars 298 forks source link

How to access the rendered hex polygons? #76

Closed ian-whitestone closed 2 years ago

ian-whitestone commented 2 years ago

I am using the hexed polygons layer to render some shapes within a region. Here is an example:

import regions from "./geo-data.json";
import Globe from 'globe.gl';

const globe = new Globe()
  (document.getElementById('globeViz'))
  .hexPolygonsData(regions.features)
  .hexPolygonResolution(1)
  .hexPolygonMargin(0.7)
;
CleanShot 2021-12-26 at 14 38 57@2x

I would like to get the coordinates of each hexagon, so that i can emit arcs / particles from them. What would be the best way to do this? I tried looking through the underlying globe.hexPolygonsData()[0].__threeObj but am a bit lost with what I should be looking for and how to leverage the BufferAttribute data i can see.

Any points or ideas would be greatly appreciated, thanks in advance!

vasturiano commented 2 years ago

@ian-whitestone thanks for reaching out.

I don't think you'll be able to (at least easily) reverse engineer the hex coordinates from the three geometry itself. Those would be already calculated 3D vertex coords.

If you just need the hex coordinates on click event, you can get the coordinates from the click event callback, for example via onHexPolygonCallback((polygon, event, coords) => ...).

Otherwise if you need the hex coordinates for all the polygons for some custom processing, I'd recommend using the h3 module for this purpose. You can use the polyfill functionality to convert your geojson polygons to hex objects, using the same h3 resolution you pass to globe.gl. That's essentially what this layer uses internally.

ian-whitestone commented 2 years ago

Thanks @vasturiano ! I'll give that a shot and close this once I have a working POC to share back.

Update: was quite simple.

regions is a geojson object that looks like this:

{
    "type": "FeatureCollection",
    "features": [
      {
        "type": "Feature",
        "properties": {
          "foo": "bar",
        },
        "geometry": {
          "type": "Polygon",
          "coordinates": [
            [
              [
                -19.07298749479517,
                60.39284533764041
              ],
              // more points ...
              [
                -19.07298749479517,
                60.39284533764041
              ]
            ]
          ]
        }
      }
    ]
  }

To get the center points of the hexagons, you can use this:

import { polyfill, h3ToGeo } from 'h3-js';

let h3Res = 2; // must be same as whatever is put for `hexPolygonResolution`
let centerPoints = [];
let res = polyfill(regions.features[0].geometry.coordinates, h3Res, true);
res.forEach(h3Idx => centerPoints.push(h3ToGeo(h3Idx)))
console.log(centerPoints)