I'm using the Uber H3 Library for Java https://github.com/uber/h3-java
I'm trying to figure out what is the average distance between 2 neighboring H3 cells of resolution 15 (the distance between their respective center points, or 2 x apothem).
I'm getting 3 significantly different results, depending on how I try to calculate:
- 1.148 meters
- 0.882 meters
- 0.994 meters
Which one is correct ? And why am I getting such different results ?
public static final long RES_15_HEXAGON = 644569124665188486L; // some random res 15 H3 index (as Long)
private final H3Core h3;
H3UtilsTest() throws IOException {
h3 = H3Core.newInstance();
}
@Test
void calculateDistanceBetweenNeighborsFromRealEdges() {
final long h3Index = RES_15_HEXAGON;
final GeoCoord centerPoint = h3.h3ToGeo(h3Index);
assertEquals(46.94862876826281, centerPoint.lat);
assertEquals(7.4404471879141205, centerPoint.lng);
assertEquals(15, h3.h3GetResolution(h3Index));
final List<GeoCoord> hexagon = this.h3.h3ToGeoBoundary(h3Index);
assertEquals(6, hexagon.size());
List<Double> edgeLengths = new ArrayList<>();
for (int i = 0; i < hexagon.size(); i++) {
edgeLengths.add(h3.pointDist(hexagon.get(i), hexagon.get((i + 1) % hexagon.size()), LengthUnit.m));
}
final double apothem = edgeLengths.stream().mapToDouble(Double::doubleValue).average().getAsDouble();
assertEquals(0.5739852101653261, apothem);
final double distanceBetweenNeighbors = 2 * apothem;
assertEquals(1.1479704203306522, distanceBetweenNeighbors);
}
@Test
void calculateDistanceBetweenNeighborsFromAverageEdges() {
final double averageEdgeLength = h3.edgeLength(15, LengthUnit.m);
assertEquals(0.509713273, averageEdgeLength);
assertEquals(1.019426546, 2 * averageEdgeLength);
final double apothem = averageEdgeLength * Math.sqrt(3) / 2;
assertEquals(0.4414246430641128, apothem);
final double distanceBetweenNeighbors = 2 * apothem;
assertEquals(0.8828492861282256, distanceBetweenNeighbors);
}
@Test
void calculateDistanceBetweenNeighborsFromNeighbors() {
final GeoCoord origin = h3.h3ToGeo(RES_15_HEXAGON);
final List<Long> neighbors = h3.kRing(RES_15_HEXAGON, 1);
assertEquals(7, neighbors.size()); // contains the center hexagon as well
neighbors.forEach(neighbor -> assertEquals(6, h3.h3ToGeoBoundary(neighbor).size())); // they are really 6-sided hexagons !
final List<Double> distances = neighbors.stream().filter(neighbor -> neighbor != RES_15_HEXAGON).map(neighbor -> h3.pointDist(origin, h3.h3ToGeo(neighbor), LengthUnit.m)).toList();
assertEquals(6, distances.size());
final Double distanceBetweenNeighbors = distances.stream().mapToDouble(Double::doubleValue).average().getAsDouble();
assertEquals(0.9941567117250641, distanceBetweenNeighbors);
}