in src/h3lib/lib/cellsToMultiPoly.c [523:573]
static H3Error createMultiPolygon(SortableLoopSet loopset,
GeoMultiPolygon *mpoly) {
if (loopset.numLoops == 0) {
return createGlobeMultiPolygon(mpoly);
}
int64_t numPolys = countPolys(loopset);
SortablePoly *spolys = H3_MEMORY(malloc)(sizeof(SortablePoly) * numPolys);
if (!spolys) {
return E_MEMORY_ALLOC;
}
SortableLoop *sloop = loopset.sloops;
int64_t i = 0; // index of first loop in polygon (outer loop)
int64_t j = 0; // index + 1 of last loop in polygon (last hole + 1)
int64_t p = 0; // index of polygon we're working on
for (; j <= loopset.numLoops; j++) {
if (j == loopset.numLoops || sloop[i].root != sloop[j].root) {
// We've reached the end of the loops in the polygon, so
// now construct a polygon from the start of those loops.
H3Error err =
createSortablePoly(&sloop[i], (j - i) - 1, &spolys[p]);
if (err) {
destroySortablePolys(spolys, p);
return err;
}
p++;
i = j;
}
}
// Sort polygons by their outer loop area. For example, in a multipolygon
// representing the USA, the continental US will come before any of the
// Hawaiian islands
qsort(spolys, numPolys, sizeof(SortablePoly), cmp_SortablePoly);
mpoly->polygons = H3_MEMORY(malloc)(sizeof(GeoPolygon) * numPolys);
if (!mpoly->polygons) {
destroySortablePolys(spolys, numPolys);
return E_MEMORY_ALLOC;
}
mpoly->numPolygons = numPolys;
for (int64_t i = 0; i < numPolys; i++) {
mpoly->polygons[i] = spolys[i].poly;
}
H3_MEMORY(free)(spolys);
return E_SUCCESS;
}