H3Error _getEdgeHexagons()

in h3_algos.c [825:877]


H3Error _getEdgeHexagons(const GeoLoop *geoloop, int64_t numHexagons, int res,
                         int64_t *numSearchHexes, H3Index *search,
                         H3Index *found) {
    for (int i = 0; i < geoloop->numVerts; i++) {
        LatLng origin = geoloop->verts[i];
        LatLng destination = i == geoloop->numVerts - 1 ? geoloop->verts[0]
                                                        : geoloop->verts[i + 1];
        int64_t numHexesEstimate;
        H3Error estimateErr =
            lineHexEstimate(&origin, &destination, res, &numHexesEstimate);
        if (estimateErr) {
            return estimateErr;
        }
        for (int64_t j = 0; j < numHexesEstimate; j++) {
            LatLng interpolate;
            double invNumHexesEst = 1.0 / numHexesEstimate;
            interpolate.lat =
                (origin.lat * (numHexesEstimate - j) * invNumHexesEst) +
                (destination.lat * j * invNumHexesEst);
            interpolate.lng =
                (origin.lng * (numHexesEstimate - j) * invNumHexesEst) +
                (destination.lng * j * invNumHexesEst);
            H3Index pointHex;
            H3Error e = H3_EXPORT(latLngToCell)(&interpolate, res, &pointHex);
            if (e) {
                return e;
            }
            // A simple hash to store the hexagon, or move to another place if
            // needed
            int64_t loc = (int64_t)(pointHex % numHexagons);
            int64_t loopCount = 0;
            while (found[loc] != 0) {
                // If this conditional is reached, the `found` memory block is
                // too small for the given polygon. This should not happen.
                // TODO: Reachable via fuzzer
                if (loopCount > numHexagons) return E_FAILED;
                if (found[loc] == pointHex)
                    break;  // At least two points of the geoloop index to the
                            // same cell
                loc = (loc + 1) % numHexagons;
                loopCount++;
            }
            if (found[loc] == pointHex)
                continue;  // Skip this hex, already exists in the found hash
            // Otherwise, set it in the found hash for now
            found[loc] = pointHex;

            search[*numSearchHexes] = pointHex;
            (*numSearchHexes)++;
        }
    }
    return E_SUCCESS;
}