static H3Error createMultiPolygon()

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;
}