Skip to content

"cellsToMultiPolygon" occasionally produces degenerate polygons with only 1 vertex #1049

@benguild

Description

@benguild

For example, when calling with a specific set of 164 valid resolution-2 cells, the function returns 14 polygons where:

  • 12 polygons are valid (≥ 3 vertices)
  • 2 polygons have only 1 vertex each (degenerate)

My data could be somehow wrong or invalid here, but I didn't think so? These I believe are valid cells, and a valid polygon ring requires at least 3 vertices.

A workaround is to look for invalid polygons and recursively subdivide the collection and retry until the issue disappears (which also "solves" #1046) but it seems like there's some underlying instability here.

As noted, I'm just playing with this library right now, and noticed this stuff.

Reproduction

#include <h3/h3api.h>
#include <stdio.h>

int main() {
    H3Index cells[164] = {
        0x827487fffffffffULL, 0x82748ffffffffffULL, 0x827497fffffffffULL, 0x82749ffffffffffULL,
        0x8274affffffffffULL, 0x8274c7fffffffffULL, 0x8274cffffffffffULL, 0x8274d7fffffffffULL,
        0x8274e7fffffffffULL, 0x8274effffffffffULL, 0x8274f7fffffffffULL, 0x82754ffffffffffULL,
        0x827c07fffffffffULL, 0x827c27fffffffffULL, 0x827c2ffffffffffULL, 0x827c37fffffffffULL,
        0x827d87fffffffffULL, 0x827d8ffffffffffULL, 0x827d97fffffffffULL, 0x827d9ffffffffffULL,
        0x827da7fffffffffULL, 0x827daffffffffffULL, 0x82801ffffffffffULL, 0x8280a7fffffffffULL,
        0x8280affffffffffULL, 0x8280b7fffffffffULL, 0x828197fffffffffULL, 0x82819ffffffffffULL,
        0x8281a7fffffffffULL, 0x8281b7fffffffffULL, 0x828207fffffffffULL, 0x82820ffffffffffULL,
        0x828227fffffffffULL, 0x82822ffffffffffULL, 0x8282e7fffffffffULL, 0x828307fffffffffULL,
        0x82830ffffffffffULL, 0x82831ffffffffffULL, 0x82832ffffffffffULL, 0x828347fffffffffULL,
        0x82834ffffffffffULL, 0x828357fffffffffULL, 0x82835ffffffffffULL, 0x828367fffffffffULL,
        0x828377fffffffffULL, 0x82a447fffffffffULL, 0x82a457fffffffffULL, 0x82a45ffffffffffULL,
        0x82a467fffffffffULL, 0x82a46ffffffffffULL, 0x82a477fffffffffULL, 0x82a4c7fffffffffULL,
        0x82a4cffffffffffULL, 0x82a4d7fffffffffULL, 0x82a4e7fffffffffULL, 0x82a4effffffffffULL,
        0x82a4f7fffffffffULL, 0x82a547fffffffffULL, 0x82a54ffffffffffULL, 0x82a557fffffffffULL,
        0x82a55ffffffffffULL, 0x82a567fffffffffULL, 0x82a577fffffffffULL, 0x82a837fffffffffULL,
        0x82a897fffffffffULL, 0x82a8a7fffffffffULL, 0x82a8b7fffffffffULL, 0x82a917fffffffffULL,
        0x82a927fffffffffULL, 0x82a937fffffffffULL, 0x82a987fffffffffULL, 0x82a98ffffffffffULL,
        0x82a997fffffffffULL, 0x82a99ffffffffffULL, 0x82a9a7fffffffffULL, 0x82a9affffffffffULL,
        0x82ac47fffffffffULL, 0x82ac57fffffffffULL, 0x82ac5ffffffffffULL, 0x82ac67fffffffffULL,
        0x82ac6ffffffffffULL, 0x82ac77fffffffffULL, 0x82ad47fffffffffULL, 0x82ad4ffffffffffULL,
        0x82ad57fffffffffULL, 0x82ad5ffffffffffULL, 0x82ad67fffffffffULL, 0x82ad77fffffffffULL,
        0x82c207fffffffffULL, 0x82c217fffffffffULL, 0x82c227fffffffffULL, 0x82c237fffffffffULL,
        0x82c287fffffffffULL, 0x82c28ffffffffffULL, 0x82c29ffffffffffULL, 0x82c2a7fffffffffULL,
        0x82c2affffffffffULL, 0x82c2b7fffffffffULL, 0x82c307fffffffffULL, 0x82c317fffffffffULL,
        0x82c31ffffffffffULL, 0x82c337fffffffffULL, 0x82cfb7fffffffffULL, 0x82d0c7fffffffffULL,
        0x82d0d7fffffffffULL, 0x82d0dffffffffffULL, 0x82d0e7fffffffffULL, 0x82d0f7fffffffffULL,
        0x82d147fffffffffULL, 0x82d157fffffffffULL, 0x82d15ffffffffffULL, 0x82d167fffffffffULL,
        0x82d177fffffffffULL, 0x82d187fffffffffULL, 0x82d18ffffffffffULL, 0x82d197fffffffffULL,
        0x82d19ffffffffffULL, 0x82d1a7fffffffffULL, 0x82d1affffffffffULL, 0x82dc47fffffffffULL,
        0x82dc57fffffffffULL, 0x82dc5ffffffffffULL, 0x82dc67fffffffffULL, 0x82dc6ffffffffffULL,
        0x82dc77fffffffffULL, 0x82dcc7fffffffffULL, 0x82dccffffffffffULL, 0x82dcd7fffffffffULL,
        0x82dce7fffffffffULL, 0x82dceffffffffffULL, 0x82dcf7fffffffffULL, 0x82dd1ffffffffffULL,
        0x82dd47fffffffffULL, 0x82dd4ffffffffffULL, 0x82dd57fffffffffULL, 0x82dd5ffffffffffULL,
        0x82dd6ffffffffffULL, 0x82dd87fffffffffULL, 0x82dd8ffffffffffULL, 0x82dd97fffffffffULL,
        0x82dd9ffffffffffULL, 0x82ddaffffffffffULL, 0x82ddb7fffffffffULL, 0x82dec7fffffffffULL,
        0x82decffffffffffULL, 0x82ded7fffffffffULL, 0x82dee7fffffffffULL, 0x82deeffffffffffULL,
        0x82def7fffffffffULL, 0x82df0ffffffffffULL, 0x82df1ffffffffffULL, 0x82df47fffffffffULL,
        0x82df4ffffffffffULL, 0x82df57fffffffffULL, 0x82df5ffffffffffULL, 0x82df77fffffffffULL,
        0x82df8ffffffffffULL, 0x82df9ffffffffffULL, 0x82e6c7fffffffffULL, 0x82e6cffffffffffULL,
        0x82e6d7fffffffffULL, 0x82e6dffffffffffULL, 0x82e6effffffffffULL, 0x82e6f7fffffffffULL,
    };

    LinkedGeoPolygon polygons;
    H3Error err = cellsToMultiPolygon(cells, 164, &polygons);

    if (err != E3_OK) {
        fprintf(stderr, "cellsToMultiPolygon failed with error: %d\n", err);
        return 1;
    }

    int polygonCount = 0;
    int degenerateCount = 0;
    LinkedGeoPolygon* current = &polygons;

    while (current != NULL) {
        int vertexCount = 0;
        LinkedLatLng* vertex = current->first;
        while (vertex != NULL) {
            vertexCount++;
            vertex = vertex->next;
        }

        if (vertexCount < 3) {
            printf("Polygon %d: %d vertices (DEGENERATE)\n", polygonCount, vertexCount);
            degenerateCount++;
        } else {
            printf("Polygon %d: %d vertices (valid)\n", polygonCount, vertexCount);
        }

        polygonCount++;
        current = current->next;
    }

    printf("\nTotal: %d polygons, %d degenerate\n", polygonCount, degenerateCount);

    destroyLinkedMultiPolygon(&polygons);
    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions