2

When a user clicks on a Mapbox streets-v11 map, I'm attempting to:

  1. Take the clicked point, and identify the h3 hexagon (at resolution 10) around the point
  2. Convert the hexagon coordinates into the polygon hexPolygon
  3. Highlight building features (from streets-v11/composite source) within hexPolygon

Currently, this functionality is working as expected, except the h3 hexagon coordinates are forming a narrow distorted hexagon. Below is an image of the distorted hexagons being created.

Here is a jsbin with my code. To reproduce, can zoom in on the map until you see buildings render, and click on the map. At that point, a narrow hexagon of buildings should appear highlighted.

(You can then copy the hexPolygon object from the console and paste it into a tool like geojson.io to view the polygon that was created)

And here is the function:

map.on("click", function (e) {

  // Convert a lat/lng point to a hexagon index at resolution 10
  const h3Index = h3.geoToH3(e.lngLat.lng, e.lngLat.lat, 10);

  // Get the center of the hexagon
  const hexCenterCoordinates = h3.h3ToGeo(h3Index);

  // Get the vertices of the hexagon
  const hexBoundary = h3.h3ToGeoBoundary(h3Index);

  hexBoundary.push(hexBoundary[0]);

  console.log(h3Index);
  console.log(hexCenterCoordinates);
  console.log(hexBoundary);


  const hexPolygon = {
    type: 'Feature',
    properties: {
      paint: {
        "line-color": "red"
      }
    },
    geometry: {
      type: 'Polygon',
      coordinates: [hexBoundary]
    }
  };


  var features = map.querySourceFeatures("composite", {
    sourceLayer: "building"
  });

  console.log("features:");
  console.log(features);

  const collector = [];

  console.log('hexPolygon:');
  console.log(hexPolygon);

  for (let i = 0; i < features.length; i++) {

    const feature = features[i]

    if (feature.geometry.type === "Polygon" && turf.booleanWithin(feature, hexPolygon)) {
      collector.push(features[i]);
    }
  }

  console.log("collector:");
  console.log(collector);

  const buildingsHighlightedLayer = map.getSource("buildings");
  buildingsHighlightedLayer.setData({
    type: "FeatureCollection",
    features: collector
  });
});

Distorted hexagon polygons

3 Answers 3

1

Something is definitely off there - while H3 hexagons do have some distortion in various parts of the globe, and while this distortion is further distorted at extreme latitudes when rendered in a Mercator projection, this is significantly more distorted than it ought to be.

  • What lat/long are you displaying? Have you tried the same hex indexes in https://observablehq.com/@nrabinowitz/h3-index-inspector ?
  • It looks like you’re probably using lat,long output from h3ToGeoBoundary, which is probably the issue. Tryh3.h3ToGeoBoundary(h3Index, true) (the second argument gives you GeoJSON-conformal output)
1
  • This is the right answer, both geo_json_conformant in the polyfill function (if used) and h3_to_geo_boundary need to be checked for True or False parameter.
    – delimiter
    Apr 25, 2021 at 0:43
0

When you run h3ToGeoBoundary it returns pairs of long,lat not lat,long. Make sure you account for this properly.

0

const h3Index = h3.geoToH3(e.lngLat.lng, e.lngLat.lat, 10);

geoToH3 function accepts latitude and then longitude. You changed places.

h3.geo_to_h3(lat, lng, resolution)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.