supercluster: Duplicate coordinates throwing `No cluster with the specified ID`

We are using Supercluster wrapped in https://github.com/novalabio/react-native-maps-super-cluster

On loading our map, we’ve experienced the No cluster with the specified ID error when clicking on a cluster. This was happening within the following call to getLeaves(), where clusteringEngine is Supercluster.

clusteringEngine
    .getLeaves(clusterId, 100)
    .map(c => c.properties.item);

It turns out the error happened when a cluster had two points that shared exactly the same coordinates, leading to the below stack trace, where I log out from the getChildren() function. As you can see, it thinks the child of the cluster is also a cluster at the same coordinates, and the child of that cluster is also apparently a cluster at the same coordinates, but that ‘cluster’ doesn’t have any children IDs so the error is thrown.

I’m wondering:

  1. whether Supercluster is already meant to handle multiple points at the same coordinates, in which case is this a bug?; and
  2. whether in the event that getChildren cannot find the children for a cluster, an empty array should be returned rather than an error thrown. Or perhaps _appendLeaves should set children to an empty array if the error gets thrown, like this:
_appendLeaves: function (result, clusterId, limit, offset, skipped) {
        try {
          var children = this.getChildren(clusterId);
        } catch(error){
          if (error.message.includes('No cluster with the specified id')) {
            children = []
          } else {
            throw error
         }
        }
     ...

Stack trace:

2018-10-19 21:27:40.887 [info][tid:com.facebook.react.JavaScript] ------------------------ get children
2018-10-19 21:27:40.887170+0100 Refill[68457:2682417] ------------------------ get children
2018-10-19 21:27:40.887 [info][tid:com.facebook.react.JavaScript] 'clusterId', 368017
2018-10-19 21:27:40.887494+0100 Refill[68457:2682417] 'clusterId', 368017
2018-10-19 21:27:40.888 [info][tid:com.facebook.react.JavaScript] '------------------------ ids', [ 11500 ]
2018-10-19 21:27:40.887822+0100 Refill[68457:2682417] '------------------------ ids', [ 11500 ]
2018-10-19 21:27:40.888 [info][tid:com.facebook.react.JavaScript] 'c.parentId', 368017
2018-10-19 21:27:40.888069+0100 Refill[68457:2682417] 'c.parentId', 368017
2018-10-19 21:27:40.888 [info][tid:com.facebook.react.JavaScript] push into children array
2018-10-19 21:27:40.888282+0100 Refill[68457:2682417] push into children array
2018-10-19 21:27:40.889 [info][tid:com.facebook.react.JavaScript] 'children', [ { type: 'Feature',
    properties: 
     { cluster: true,
       cluster_id: 385970,
       point_count: 2,
       point_count_abbreviated: 2 },
    geometry: 
     { type: 'Point',
       coordinates: [ -5.538370000000008, 50.11913999999999 ] } } ]
2018-10-19 21:27:40.888730+0100 Refill[68457:2682417] 'children', [ { type: 'Feature',
    properties: 
     { cluster: true,
       cluster_id: 385970,
       point_count: 2,
       point_count_abbreviated: 2 },
    geometry: 
     { type: 'Point',
       coordinates: [ -5.538370000000008, 50.11913999999999 ] } } ]
2018-10-19 21:27:40.889 [info][tid:com.facebook.react.JavaScript] ------------------------ get children
2018-10-19 21:27:40.888954+0100 Refill[68457:2682417] ------------------------ get children
2018-10-19 21:27:40.889 [info][tid:com.facebook.react.JavaScript] 'clusterId', 385970
2018-10-19 21:27:40.889217+0100 Refill[68457:2682417] 'clusterId', 385970
2018-10-19 21:27:40.889 [info][tid:com.facebook.react.JavaScript] '------------------------ ids', [ 12061 ]
2018-10-19 21:27:40.889467+0100 Refill[68457:2682417] '------------------------ ids', [ 12061 ]
2018-10-19 21:27:40.890 [info][tid:com.facebook.react.JavaScript] 'c.parentId', 385970
2018-10-19 21:27:40.889677+0100 Refill[68457:2682417] 'c.parentId', 385970
2018-10-19 21:27:40.890 [info][tid:com.facebook.react.JavaScript] push into children array
2018-10-19 21:27:40.889931+0100 Refill[68457:2682417] push into children array
2018-10-19 21:27:40.890 [info][tid:com.facebook.react.JavaScript] 'children', [ { type: 'Feature',
    properties: 
     { cluster: true,
       cluster_id: 388691,
       point_count: 2,
       point_count_abbreviated: 2 },
    geometry: 
     { type: 'Point',
       coordinates: [ -5.538370000000008, 50.11913999999999 ] } } ]
2018-10-19 21:27:40.890418+0100 Refill[68457:2682417] 'children', [ { type: 'Feature',
    properties: 
     { cluster: true,
       cluster_id: 388691,
       point_count: 2,
       point_count_abbreviated: 2 },
    geometry: 
     { type: 'Point',
       coordinates: [ -5.538370000000008, 50.11913999999999 ] } } ]
2018-10-19 21:27:40.891 [info][tid:com.facebook.react.JavaScript] ------------------------ get children
2018-10-19 21:27:40.890627+0100 Refill[68457:2682417] ------------------------ get children
2018-10-19 21:27:40.891 [info][tid:com.facebook.react.JavaScript] 'clusterId', 388691
2018-10-19 21:27:40.890848+0100 Refill[68457:2682417] 'clusterId', 388691
2018-10-19 21:27:40.891 [info][tid:com.facebook.react.JavaScript] '------------------------ ids', []
2018-10-19 21:27:40.891095+0100 Refill[68457:2682417] '------------------------ ids', []
2018-10-19 21:27:40.891 [info][tid:com.facebook.react.JavaScript] 'children', []
2018-10-19 21:27:40.891329+0100 Refill[68457:2682417] 'children', []
2018-10-19 21:27:42.898 [warn][tid:com.facebook.react.JavaScript] Possible Unhandled Promise Rejection (id: 0):
Error: No cluster with the specified id.

About this issue

  • Original URL
  • State: open
  • Created 6 years ago
  • Comments: 16 (6 by maintainers)

Most upvoted comments

Also having this issue with 7.1.5 with maxZoom > 30

On my case, if this helps someone was:

 const [points, supercluster] = useClusterer(
    debouncedDataToBeMerged ? debouncedDataToBeMerged : [],
    SCREEN,
    mapCoordsDebounced,
    SUPERCLUSTER_OPTS
  );

I have this hook that creates a supercluster instance, but forgot to add the dep into onClusterPress:

  const onClusterPress = useCallback(
    async (clusterId: number) => {
      {
        const regionToAnimate = supercluster.expandCluster(clusterId);
        const zoom = supercluster.getClusterExpansionZoom(clusterId);
        mapRef.current?.animateCamera({
          center: {
            ...regionToAnimate,
          },
          zoom: zoom + 2,
        });
      }
    },
-  [],
+ [supercluster]
  );

@mourner Before closing the issue, could you please have checked the example I posted in the comment above?

For some weird scenarios, this issue still happens, even on version 7.1.4. Here’s the updated codesandbox with the code still failing on 7.1.4: https://codesandbox.io/s/supercluster-no-cluster-with-the-specified-id-forked-r8jc6?file=/src/index.js

Thanks.