Reputation: 3106
I have created Multi polygons using h3SetToMultiPolygon from the list of H3 cell ids as shown below:
Now I want to get the center (I know it's not a perfect shape to get the center, but a rough one should be fine) of the Multi Polygon which I am unable to get using any H3 or leaflet methods. I want to show a marker at the center of the boundary of the multi polygons as shown below roughly:
Any help would be appreciated. Here is my code:
const clusterBoundaryCoordinates = [];
clusters?.forEach((element) => {
clusterBoundaryCoordinates.push(
h3.h3SetToMultiPolygon(element.cellIdsArr, true)
);
});
Upvotes: 0
Views: 836
Reputation: 3106
I found the solution. I didn't notice earlier that to find the center, I can utilize the lat longs which I receive when I do h3SetToMultiPolygon (it returns the lat long in reverse order).
const clusterBoundaryCoordinates = [];
clusters?.forEach((element) => {
clusterBoundaryCoordinates.push(
h3.h3SetToMultiPolygon(element.cellIdsArr, true); //it returns the latlong in reverse order, so need to reverse it
);
});
const getCentroid = (arr) => {
return arr.reduce(
(x, y) => {
return [x[0] + y[0] / arr.length, x[1] + y[1] / arr.length];
},
[0, 0]
);
};
const centroid = getCentroid(clusterBoundaryCoordinates);
Upvotes: 0
Reputation: 55688
This isn't really specific to H3 - in general, you want an algorithm that can give you the centroid of a polygon, e.g. @turf/centroid. There are different centroid algorithms based on the use case - e.g. you may or may not require the centroid to be inside a concave polygon (think a C shape) or within one of many small polygons in a multipolygon (think an archipelago).
There's an interesting H3-based option here as well, though I don't know offhand how to make it performant. You can find the center cell by finding the cell whose mean distance to all other cells is lowest, e.g.
let min = Infinity;
let center = null;
for (const cell of cells) {
let total = 0;
for (const neighbor of cells) {
total += h3.h3Distance(cell, neighbor);
}
if (total < min) {
min = total;
center = cell;
}
}
This will always give you a cell in your set, so it will always be within your area, and should give a reasonable value even for pathological shapes. But, because the algorithm is O(n^2)
, it's going to be very slow for large sets of cells.
Upvotes: 1