Changeset 23008


Ignore:
Timestamp:
Aug 29, 2011, 11:50:02 AM (13 years ago)
Author:
Even Rouault
Message:

Spatialite: speed-up spatial filter on table layers by using spatial index table instead of MBRIntersects() function (#4212)

Location:
trunk/gdal/ogr/ogrsf_frmts/sqlite
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/gdal/ogr/ogrsf_frmts/sqlite/ogr_sqlite.h

    r22846 r23008  
    218218    CPLString           osWHERE;
    219219    CPLString           osQuery;
     220    int                 bHasCheckedSpatialIndexTable;
    220221
    221222    char               *pszEscapedTableName;
  • trunk/gdal/ogr/ogrsf_frmts/sqlite/ogrsqlitetablelayer.cpp

    r22800 r23008  
    5252    poFeatureDefn = NULL;
    5353    pszEscapedTableName = NULL;
     54
     55    bHasCheckedSpatialIndexTable = FALSE;
    5456}
    5557
     
    344346
    345347        m_poFilterGeom->getEnvelope( &sEnvelope );
     348
     349        /* Old and inefficient way ...
    346350        osWHERE.Printf("WHERE MBRIntersects(\"%s\", BuildMBR(%.12f, %.12f, %.12f, %.12f, %d)) ",
    347351                       osGeomColumn.c_str(),
     
    349353                       sEnvelope.MaxX + 1e-11, sEnvelope.MaxY + 1e-11,
    350354                       nSRSId);
     355        */
     356
     357        /* We first check that the spatial index table exists */
     358        if (!bHasCheckedSpatialIndexTable)
     359        {
     360            bHasCheckedSpatialIndexTable = TRUE;
     361            char **papszResult;
     362            int nRowCount, nColCount;
     363            char *pszErrMsg = NULL;
     364
     365            CPLString osSQL;
     366            osSQL.Printf("SELECT name FROM sqlite_master "
     367                        "WHERE name='idx_%s_%s'",
     368                        pszEscapedTableName, osGeomColumn.c_str());
     369
     370            int  rc = sqlite3_get_table( poDS->GetDB(), osSQL.c_str(),
     371                                        &papszResult, &nRowCount,
     372                                        &nColCount, &pszErrMsg );
     373
     374            if( rc != SQLITE_OK )
     375            {
     376                CPLError( CE_Failure, CPLE_AppDefined, "Error: %s",
     377                        pszErrMsg );
     378                sqlite3_free( pszErrMsg );
     379                bHasSpatialIndex = FALSE;
     380            }
     381            else
     382            {
     383                if (nRowCount != 1)
     384                {
     385                    bHasSpatialIndex = FALSE;
     386                }
     387
     388                sqlite3_free_table(papszResult);
     389            }
     390        }
     391
     392        if (bHasSpatialIndex)
     393        {
     394            osWHERE.Printf("WHERE ROWID IN ( SELECT pkid FROM 'idx_%s_%s' WHERE "
     395                           "xmax > %.12f AND xmin < %.12f AND ymax > %.12f AND ymin < %.12f) ",
     396                            pszEscapedTableName, osGeomColumn.c_str(),
     397                            sEnvelope.MinX - 1e-11, sEnvelope.MaxX + 1e-11,
     398                            sEnvelope.MinY - 1e-11, sEnvelope.MaxY + 1e-11);
     399        }
     400        else
     401        {
     402            CPLDebug("SQLITE", "Count not find idx_%s_%s layer. Disabling spatial index",
     403                     pszEscapedTableName, osGeomColumn.c_str());
     404        }
     405
    351406    }
    352407
Note: See TracChangeset for help on using the changeset viewer.