OSGeo / shapelib

Official repository of shapelib

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

False positive ? "ERROR 1: Inconsistent shape count for bin"

pathmapper opened this issue · comments

Here's a dataset (Shapefile with spatial index .sbn / .sbx)

for which ogrinfo returns:

ogrinfo -ro -so -spat 5 5 6 6 glwd_2.shp --debug on
Shape: DBF Codepage = LDID/87 for glwd_2.shp
Shape: Treating as encoding 'ISO-8859-1'.
GDAL: GDALOpen(glwd_2.shp, this=0x55765f5e0090) succeeds as ESRI Shapefile.
INFO: Open of `glwd_2.shp'
      using driver `ESRI Shapefile' successful.
OGR: GetLayerCount() = 1


Layer name: glwd_2
Metadata:
  DBF_DATE_LAST_UPDATE=2003-05-20
Geometry: Polygon
ERROR 1: Inconsistent shape count for bin
SHAPE: Used spatial index, got 0 matches.
Feature Count: 13
Extent: (-180.000000, -55.587208) - (180.000000, 83.575951)
Layer SRS WKT:
(unknown)
GLWD_ID: Integer64 (10.0)
TYPE: String (12.0)
POLY_SRC: String (12.0)
AREA_SKM: Real (12.1)
PERIM_KM: Real (12.1)
LONG_DEG: Real (10.2)
LAT_DEG: Real (10.2)
GDAL: GDALClose(glwd_2.shp, this=0x55765f5e0090)

What makes me wonder, is that this dataset originated from and is widely used in scientific context, and AFAICS nobody complained about a corrupt spatial index so far.

So could it be, that the index is correct and the shown error is a false positive?

Looks like the error comes from here:

hSBN->sHooks.Error("Inconsistent shape count for bin");

hSBN->sHooks.Error("Inconsistent shape count for bin");

Can reproduce. It's line 540 of sbnsearch.c that prints the error message.

SBNSearchHandle handle = SBNOpenDiskTree("glwd_2.sbn", NULL);
int shapeCount;
const double boundsMin[2] = {5, 5};
const double boundsMax[2] = {6, 6};
int *ids = SBNSearchDiskTree(handle, boundsMin, boundsMax, &shapeCount);
SBNSearchFreeIds(ids);
SBNCloseDiskTree(handle);

This likely is not the correct patch, but it prevents the error:

diff --git a/sbnsearch.c b/sbnsearch.c
index be08021..52e807f 100644
--- a/sbnsearch.c
+++ b/sbnsearch.c
@@ -533,6 +533,11 @@ static bool SBNSearchDiskInternal(SearchStruct *psSearch, int nDepth,
                 return false;
             }
 
+            if (nShapeCountAcc == psNode->nShapeCount)
+            {
+                break;
+            }
+
             if (nShapeCountAcc + nShapes > psNode->nShapeCount)
             {
                 free(psNode->pabyShapeDesc);