H3Error H3_EXPORT()

in h3_h3Index.c [1333:1393]


H3Error H3_EXPORT(childPosToCell)(int64_t childPos, H3Index parent,
                                  int childRes, H3Index *child) {
    // Validate resolution
    if (childRes < 0 || childRes > MAX_H3_RES) {
        return E_RES_DOMAIN;
    }
    // Validate parent resolution
    int parentRes = H3_GET_RESOLUTION(parent);
    if (childRes < parentRes) {
        return E_RES_MISMATCH;
    }
    // Validate child pos
    H3Error childPosErr = validateChildPos(childPos, parent, childRes);
    if (childPosErr) {
        return childPosErr;
    }

    int resOffset = childRes - parentRes;

    *child = parent;
    int64_t idx = childPos;

    H3_SET_RESOLUTION(*child, childRes);

    if (H3_EXPORT(isPentagon)(parent)) {
        // Pentagon tile logic. Pentagon tiles skip the 1 digit, so the offsets
        // are different
        bool inPent = true;
        for (int res = 1; res <= resOffset; res++) {
            int64_t resWidth = _ipow(7, resOffset - res);
            if (inPent) {
                // While we are inside a parent pentagon, we need to check if
                // this cell is a pentagon, and if not, we need to offset its
                // digit to account for the skipped direction
                int64_t pentWidth = 1 + (5 * (resWidth - 1)) / 6;
                if (idx < pentWidth) {
                    H3_SET_INDEX_DIGIT(*child, parentRes + res, 0);
                } else {
                    idx -= pentWidth;
                    inPent = false;
                    H3_SET_INDEX_DIGIT(*child, parentRes + res,
                                       (idx / resWidth) + 2);
                    idx %= resWidth;
                }
            } else {
                // We're no longer inside a pentagon, continue as for hex
                H3_SET_INDEX_DIGIT(*child, parentRes + res, idx / resWidth);
                idx %= resWidth;
            }
        }
    } else {
        // Hexagon tile logic. Offsets are simple powers of 7
        for (int res = 1; res <= resOffset; res++) {
            int64_t resWidth = _ipow(7, resOffset - res);
            H3_SET_INDEX_DIGIT(*child, parentRes + res, idx / resWidth);
            idx %= resWidth;
        }
    }

    return E_SUCCESS;
}