Changeset 23944
- Timestamp:
- Feb 11, 2012, 6:07:49 AM (13 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
-
autotest/ogr/ogr_sqlite.py (modified) (3 diffs)
-
gdal/ogr/ogrsf_frmts/sqlite/ogr_sqlite.h (modified) (5 diffs)
-
gdal/ogr/ogrsf_frmts/sqlite/ogrsqliteselectlayer.cpp (modified) (4 diffs)
-
gdal/ogr/ogrsf_frmts/sqlite/ogrsqlitetablelayer.cpp (modified) (2 diffs)
-
gdal/ogr/ogrsf_frmts/sqlite/ogrsqliteviewlayer.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/autotest/ogr/ogr_sqlite.py
r23613 r23944 1203 1203 return 'fail' 1204 1204 1205 lyr = ds.GetLayerByName('polygon') 1206 if lyr is None: 1207 gdaltest.post_reason('failed') 1208 return 'fail' 1209 1210 if lyr.GetLayerDefn().GetFieldCount() == 0: 1211 gdaltest.post_reason('failed') 1212 return 'fail' 1213 1205 1214 return 'success' 1206 1215 … … 1288 1297 srs.SetFromUserInput('EPSG:4326') 1289 1298 lyr = ds.CreateLayer( 'test_spatialfilter', srs = srs) 1290 1299 lyr.CreateField(ogr.FieldDefn('intcol', ogr.OFTInteger)) 1300 1291 1301 lyr.StartTransaction() 1292 1302 … … 1316 1326 'POLYGON((2 2,2 8,8 8,8 2,2 2))' ) 1317 1327 lyr.SetSpatialFilter( geom ) 1318 geom.Destroy()1319 1328 1320 1329 if lyr.TestCapability(ogr.OLCFastFeatureCount) != True: 1330 gdaltest.post_reason('OLCFastFeatureCount failed') 1321 1331 return 'fail' 1322 1332 if lyr.TestCapability(ogr.OLCFastSpatialFilter) != True: 1333 gdaltest.post_reason('OLCFastSpatialFilter failed') 1323 1334 return 'fail' 1324 1335 1325 1336 if lyr.GetFeatureCount() != 50: 1326 gdaltest.post_reason('did not get expected feature count (1)')1337 gdaltest.post_reason('did not get expected feature count') 1327 1338 print(lyr.GetFeatureCount()) 1328 1339 return 'fail' 1340 1341 # Test spatial filter with a SQL result layer without WHERE clause 1342 sql_lyr = ds.ExecuteSQL("SELECT * FROM 'test_spatialfilter'") 1343 if sql_lyr.TestCapability(ogr.OLCFastSpatialFilter) != True: 1344 gdaltest.post_reason('OLCFastSpatialFilter failed') 1345 return 'fail' 1346 sql_lyr.SetSpatialFilter( geom ) 1347 if sql_lyr.TestCapability(ogr.OLCFastSpatialFilter) != True: 1348 gdaltest.post_reason('OLCFastSpatialFilter failed') 1349 return 'fail' 1350 if sql_lyr.GetFeatureCount() != 50: 1351 gdaltest.post_reason('did not get expected feature count') 1352 print(sql_lyr.GetFeatureCount()) 1353 return 'fail' 1354 ds.ReleaseResultSet(sql_lyr) 1355 1356 # Test spatial filter with a SQL result layer with WHERE clause 1357 sql_lyr = ds.ExecuteSQL('SELECT * FROM test_spatialfilter WHERE 1=1') 1358 if sql_lyr.TestCapability(ogr.OLCFastSpatialFilter) != True: 1359 gdaltest.post_reason('OLCFastSpatialFilter failed') 1360 return 'fail' 1361 sql_lyr.SetSpatialFilter( geom ) 1362 if sql_lyr.TestCapability(ogr.OLCFastSpatialFilter) != True: 1363 gdaltest.post_reason('OLCFastSpatialFilter failed') 1364 return 'fail' 1365 if sql_lyr.GetFeatureCount() != 50: 1366 gdaltest.post_reason('did not get expected feature count') 1367 print(sql_lyr.GetFeatureCount()) 1368 return 'fail' 1369 ds.ReleaseResultSet(sql_lyr) 1370 1371 # Test spatial filter with a SQL result layer with ORDER BY clause 1372 sql_lyr = ds.ExecuteSQL('SELECT * FROM test_spatialfilter ORDER BY intcol') 1373 if sql_lyr.TestCapability(ogr.OLCFastSpatialFilter) != True: 1374 gdaltest.post_reason('OLCFastSpatialFilter failed') 1375 return 'fail' 1376 sql_lyr.SetSpatialFilter( geom ) 1377 if sql_lyr.TestCapability(ogr.OLCFastSpatialFilter) != True: 1378 gdaltest.post_reason('OLCFastSpatialFilter failed') 1379 return 'fail' 1380 if sql_lyr.GetFeatureCount() != 50: 1381 gdaltest.post_reason('did not get expected feature count') 1382 print(sql_lyr.GetFeatureCount()) 1383 return 'fail' 1384 ds.ReleaseResultSet(sql_lyr) 1329 1385 1330 1386 # Remove spatial index -
trunk/gdal/ogr/ogrsf_frmts/sqlite/ogr_sqlite.h
r23736 r23944 244 244 245 245 int HasSpatialIndex() const { return bHasSpatialIndex; } 246 247 virtual CPLString GetSpatialWhere(OGRGeometry* poFilterGeom) { return ""; } 246 248 }; 247 249 … … 342 344 343 345 virtual int IsTableLayer() { return TRUE; } 346 347 virtual CPLString GetSpatialWhere(OGRGeometry* poFilterGeom); 344 348 }; 345 349 … … 383 387 384 388 virtual int TestCapability( const char * ); 389 390 virtual CPLString GetSpatialWhere(OGRGeometry* poFilterGeom); 385 391 }; 386 392 … … 391 397 class OGRSQLiteSelectLayer : public OGRSQLiteLayer 392 398 { 393 CPLString osSQL; 399 CPLString osSQLBase; 400 CPLString osSQLCurrent; 394 401 395 402 OGRErr ResetStatement(); 403 404 OGRSQLiteLayer *GetBaseLayer(size_t& i); 405 void RebuildSQL(); 396 406 397 407 public: … … 400 410 sqlite3_stmt * ); 401 411 ~OGRSQLiteSelectLayer(); 412 413 virtual void SetSpatialFilter( OGRGeometry * ); 414 415 virtual int TestCapability( const char * ); 402 416 }; 403 417 -
trunk/gdal/ogr/ogrsf_frmts/sqlite/ogrsqliteselectlayer.cpp
r19800 r23944 38 38 39 39 OGRSQLiteSelectLayer::OGRSQLiteSelectLayer( OGRSQLiteDataSource *poDSIn, 40 CPLString osSQL ,40 CPLString osSQLIn, 41 41 sqlite3_stmt *hStmtIn ) 42 42 … … 52 52 sqlite3_finalize( hStmtIn ); 53 53 54 this->osSQL = osSQL; 54 osSQLBase = osSQLIn; 55 osSQLCurrent = osSQLIn; 55 56 } 56 57 … … 77 78 iNextShapeId = 0; 78 79 79 rc = sqlite3_prepare( poDS->GetDB(), osSQL, osSQL.size(), 80 #ifdef DEBUG 81 CPLDebug( "OGR_SQLITE", "prepare(%s)", osSQLCurrent.c_str() ); 82 #endif 83 84 rc = sqlite3_prepare( poDS->GetDB(), osSQLCurrent, osSQLCurrent.size(), 80 85 &hStmt, NULL ); 81 86 … … 88 93 CPLError( CE_Failure, CPLE_AppDefined, 89 94 "In ResetStatement(): sqlite3_prepare(%s):\n %s", 90 osSQL .c_str(), sqlite3_errmsg(poDS->GetDB()) );95 osSQLCurrent.c_str(), sqlite3_errmsg(poDS->GetDB()) ); 91 96 hStmt = NULL; 92 97 return OGRERR_FAILURE; 93 98 } 94 99 } 100 101 /************************************************************************/ 102 /* SetSpatialFilter() */ 103 /************************************************************************/ 104 105 void OGRSQLiteSelectLayer::SetSpatialFilter( OGRGeometry * poGeomIn ) 106 107 { 108 if( InstallFilter( poGeomIn ) ) 109 { 110 RebuildSQL(); 111 112 ResetReading(); 113 } 114 } 115 116 /************************************************************************/ 117 /* GetBaseLayer() */ 118 /************************************************************************/ 119 120 OGRSQLiteLayer* OGRSQLiteSelectLayer::GetBaseLayer(size_t& i) 121 { 122 char** papszTokens = CSLTokenizeString(osSQLBase.c_str()); 123 int bCanInsertSpatialFilter = TRUE; 124 int nCountSelect = 0, nCountFrom = 0, nCountWhere = 0; 125 126 for(int iToken = 0; papszTokens[iToken] != NULL; iToken++) 127 { 128 if (EQUAL(papszTokens[iToken], "SELECT")) 129 nCountSelect ++; 130 else if (EQUAL(papszTokens[iToken], "FROM")) 131 nCountFrom ++; 132 else if (EQUAL(papszTokens[iToken], "WHERE")) 133 nCountWhere ++; 134 else if (EQUAL(papszTokens[iToken], "UNION") || 135 EQUAL(papszTokens[iToken], "JOIN") || 136 EQUAL(papszTokens[iToken], "INTERSECT") || 137 EQUAL(papszTokens[iToken], "EXCEPT")) 138 { 139 bCanInsertSpatialFilter = FALSE; 140 } 141 } 142 CSLDestroy(papszTokens); 143 144 if (!(bCanInsertSpatialFilter && nCountSelect == 1 && nCountFrom == 1 && nCountWhere <= 1)) 145 { 146 CPLDebug("SQLITE", "SQL expression too complex to analyse"); 147 return NULL; 148 } 149 150 size_t nFromPos = osSQLBase.ifind(" from "); 151 if (nFromPos == std::string::npos) 152 { 153 return NULL; 154 } 155 156 int bInSingleQuotes = (osSQLBase[nFromPos + 6] == '\''); 157 CPLString osBaseLayerName; 158 for( i = nFromPos + 6 + (bInSingleQuotes ? 1 : 0); 159 i < osSQLBase.size(); i++ ) 160 { 161 if (osSQLBase[i] == '\'' && i + 1 < osSQLBase.size() && 162 osSQLBase[i + 1] == '\'' ) 163 { 164 osBaseLayerName += osSQLBase[i]; 165 i++; 166 } 167 else if (osSQLBase[i] == '\'' && bInSingleQuotes) 168 { 169 i++; 170 break; 171 } 172 else if (osSQLBase[i] == ' ' && !bInSingleQuotes) 173 break; 174 else 175 osBaseLayerName += osSQLBase[i]; 176 } 177 178 return (OGRSQLiteLayer*) poDS->GetLayerByName(osBaseLayerName); 179 } 180 181 /************************************************************************/ 182 /* RebuildSQL() */ 183 /************************************************************************/ 184 185 void OGRSQLiteSelectLayer::RebuildSQL() 186 187 { 188 osSQLCurrent = osSQLBase; 189 190 if (m_poFilterGeom == NULL) 191 { 192 return; 193 } 194 195 size_t i = 0; 196 OGRSQLiteLayer* poBaseLayer = GetBaseLayer(i); 197 if (poBaseLayer == NULL) 198 { 199 CPLDebug("SQLITE", "Cannot find base layer"); 200 return; 201 } 202 203 CPLString osSpatialWhere = poBaseLayer->GetSpatialWhere(m_poFilterGeom); 204 if (osSpatialWhere.size() == 0) 205 { 206 CPLDebug("SQLITE", "Cannot get spatial where clause"); 207 return; 208 } 209 210 while (i < osSQLBase.size() && osSQLBase[i] == ' ') 211 i ++; 212 213 if (i < osSQLBase.size() && EQUALN(osSQLBase.c_str() + i, "WHERE ", 6)) 214 { 215 osSQLCurrent = osSQLBase.substr(0, i + 6); 216 osSQLCurrent += osSpatialWhere; 217 osSQLCurrent += " AND "; 218 osSQLCurrent += osSQLBase.substr(i + 6); 219 } 220 else if (i < osSQLBase.size() && 221 (EQUALN(osSQLBase.c_str() + i, "GROUP ", 6) || 222 EQUALN(osSQLBase.c_str() + i, "ORDER ", 6) || 223 EQUALN(osSQLBase.c_str() + i, "LIMIT ", 6))) 224 { 225 osSQLCurrent = osSQLBase.substr(0, i); 226 osSQLCurrent += " WHERE "; 227 osSQLCurrent += osSpatialWhere; 228 osSQLCurrent += " "; 229 osSQLCurrent += osSQLBase.substr(i); 230 } 231 else if (i == osSQLBase.size()) 232 { 233 osSQLCurrent = osSQLBase.substr(0, i); 234 osSQLCurrent += " WHERE "; 235 osSQLCurrent += osSpatialWhere; 236 } 237 else 238 { 239 CPLDebug("SQLITE", "SQL expression too complex for the driver to insert spatial filter in it"); 240 } 241 } 242 243 /************************************************************************/ 244 /* TestCapability() */ 245 /************************************************************************/ 246 247 int OGRSQLiteSelectLayer::TestCapability( const char * pszCap ) 248 249 { 250 if (EQUAL(pszCap,OLCFastSpatialFilter)) 251 { 252 if (osSQLCurrent != osSQLBase) 253 return TRUE; 254 255 size_t i = 0; 256 OGRSQLiteLayer* poBaseLayer = GetBaseLayer(i); 257 if (poBaseLayer == NULL) 258 { 259 CPLDebug("SQLITE", "Cannot find base layer"); 260 return FALSE; 261 } 262 263 OGRPolygon oFakePoly; 264 const char* pszWKT = "POLYGON((0 0,0 1,1 1,1 0,0 0))"; 265 oFakePoly.importFromWkt((char**) &pszWKT); 266 CPLString osSpatialWhere = poBaseLayer->GetSpatialWhere(&oFakePoly); 267 268 return osSpatialWhere.size() != 0; 269 } 270 else 271 return OGRSQLiteLayer::TestCapability( pszCap ); 272 } -
trunk/gdal/ogr/ogrsf_frmts/sqlite/ogrsqlitetablelayer.cpp
r23942 r23944 456 456 457 457 /************************************************************************/ 458 /* GetSpatialWhere() */ 459 /************************************************************************/ 460 461 CPLString OGRSQLiteTableLayer::GetSpatialWhere(OGRGeometry* poFilterGeom) 462 { 463 CPLString osSpatialWHERE; 464 465 if( poFilterGeom != NULL && CheckSpatialIndexTable() ) 466 { 467 OGREnvelope sEnvelope; 468 469 poFilterGeom->getEnvelope( &sEnvelope ); 470 471 osSpatialWHERE.Printf("ROWID IN ( SELECT pkid FROM 'idx_%s_%s' WHERE " 472 "xmax >= %.12f AND xmin <= %.12f AND ymax >= %.12f AND ymin <= %.12f)", 473 pszEscapedTableName, osGeomColumn.c_str(), 474 sEnvelope.MinX - 1e-11, sEnvelope.MaxX + 1e-11, 475 sEnvelope.MinY - 1e-11, sEnvelope.MaxY + 1e-11); 476 } 477 478 if( poFilterGeom != NULL && bSpatialiteLoaded && !bHasSpatialIndex) 479 { 480 OGREnvelope sEnvelope; 481 482 poFilterGeom->getEnvelope( &sEnvelope ); 483 484 /* A bit inefficient but still faster than OGR filtering */ 485 osSpatialWHERE.Printf("MBRIntersects(\"%s\", BuildMBR(%.12f, %.12f, %.12f, %.12f, %d))", 486 osGeomColumn.c_str(), 487 sEnvelope.MinX - 1e-11, sEnvelope.MinY - 1e-11, 488 sEnvelope.MaxX + 1e-11, sEnvelope.MaxY + 1e-11, 489 nSRSId); 490 } 491 492 return osSpatialWHERE; 493 } 494 495 /************************************************************************/ 458 496 /* BuildWhere() */ 459 497 /* */ … … 467 505 osWHERE = ""; 468 506 469 if( m_poFilterGeom != NULL && CheckSpatialIndexTable() ) 470 { 471 OGREnvelope sEnvelope; 472 473 m_poFilterGeom->getEnvelope( &sEnvelope ); 474 475 osWHERE.Printf("WHERE ROWID IN ( SELECT pkid FROM 'idx_%s_%s' WHERE " 476 "xmax >= %.12f AND xmin <= %.12f AND ymax >= %.12f AND ymin <= %.12f) ", 477 pszEscapedTableName, osGeomColumn.c_str(), 478 sEnvelope.MinX - 1e-11, sEnvelope.MaxX + 1e-11, 479 sEnvelope.MinY - 1e-11, sEnvelope.MaxY + 1e-11); 480 } 481 482 if( m_poFilterGeom != NULL && bSpatialiteLoaded && !bHasSpatialIndex) 483 { 484 OGREnvelope sEnvelope; 485 486 m_poFilterGeom->getEnvelope( &sEnvelope ); 487 488 /* A bit inefficient but still faster than OGR filtering */ 489 osWHERE.Printf("WHERE MBRIntersects(\"%s\", BuildMBR(%.12f, %.12f, %.12f, %.12f, %d)) ", 490 osGeomColumn.c_str(), 491 sEnvelope.MinX - 1e-11, sEnvelope.MinY - 1e-11, 492 sEnvelope.MaxX + 1e-11, sEnvelope.MaxY + 1e-11, 493 nSRSId); 494 } 495 496 if( strlen(osQuery) > 0 ) 497 { 498 if( strlen(osWHERE) == 0 ) 499 { 500 osWHERE.Printf( "WHERE %s ", osQuery.c_str() ); 507 CPLString osSpatialWHERE = GetSpatialWhere(m_poFilterGeom); 508 if (osSpatialWHERE.size() != 0) 509 { 510 osWHERE = "WHERE "; 511 osWHERE += osSpatialWHERE; 512 } 513 514 if( osQuery.size() > 0 ) 515 { 516 if( osWHERE.size() == 0 ) 517 { 518 osWHERE = "WHERE "; 519 osWHERE += osQuery; 501 520 } 502 521 else 503 522 { 504 osWHERE += " AND (";523 osWHERE += " AND ("; 505 524 osWHERE += osQuery; 506 525 osWHERE += ")"; -
trunk/gdal/ogr/ogrsf_frmts/sqlite/ogrsqliteviewlayer.cpp
r23942 r23944 299 299 300 300 /************************************************************************/ 301 /* BuildWhere() */ 302 /* */ 303 /* Build the WHERE statement appropriate to the current set of */ 304 /* criteria (spatial and attribute queries). */ 305 /************************************************************************/ 306 307 void OGRSQLiteViewLayer::BuildWhere() 308 309 { 310 osWHERE = ""; 311 312 if( m_poFilterGeom != NULL && bHasSpatialIndex ) 301 /* GetSpatialWhere() */ 302 /************************************************************************/ 303 304 CPLString OGRSQLiteViewLayer::GetSpatialWhere(OGRGeometry* poFilterGeom) 305 { 306 CPLString osSpatialWHERE; 307 308 if( poFilterGeom != NULL && bHasSpatialIndex ) 313 309 { 314 310 OGREnvelope sEnvelope; 315 311 316 m_poFilterGeom->getEnvelope( &sEnvelope );312 poFilterGeom->getEnvelope( &sEnvelope ); 317 313 318 314 /* We first check that the spatial index table exists */ … … 353 349 if (bHasSpatialIndex) 354 350 { 355 os WHERE.Printf("WHERE%s IN ( SELECT pkid FROM 'idx_%s_%s' WHERE "356 "xmax > %.12f AND xmin < %.12f AND ymax > %.12f AND ymin < %.12f) ",351 osSpatialWHERE.Printf("%s IN ( SELECT pkid FROM 'idx_%s_%s' WHERE " 352 "xmax > %.12f AND xmin < %.12f AND ymax > %.12f AND ymin < %.12f)", 357 353 pszFIDColumn, 358 354 pszEscapedUnderlyingTableName, osUnderlyingGeometryColumn.c_str(), … … 368 364 } 369 365 370 if( m_poFilterGeom != NULL && bSpatialiteLoaded && !bHasSpatialIndex )366 if( poFilterGeom != NULL && bSpatialiteLoaded && !bHasSpatialIndex ) 371 367 { 372 368 OGREnvelope sEnvelope; 373 369 374 m_poFilterGeom->getEnvelope( &sEnvelope );370 poFilterGeom->getEnvelope( &sEnvelope ); 375 371 376 372 /* A bit inefficient but still faster than OGR filtering */ 377 os WHERE.Printf("WHERE MBRIntersects(\"%s\", BuildMBR(%.12f, %.12f, %.12f, %.12f))",373 osSpatialWHERE.Printf("MBRIntersects(\"%s\", BuildMBR(%.12f, %.12f, %.12f, %.12f))", 378 374 osGeomColumn.c_str(), 379 375 sEnvelope.MinX - 1e-11, sEnvelope.MinY - 1e-11, … … 381 377 } 382 378 383 if( strlen(osQuery) > 0 ) 384 { 385 if( strlen(osWHERE) == 0 ) 379 return osSpatialWHERE; 380 } 381 382 /************************************************************************/ 383 /* BuildWhere() */ 384 /* */ 385 /* Build the WHERE statement appropriate to the current set of */ 386 /* criteria (spatial and attribute queries). */ 387 /************************************************************************/ 388 389 void OGRSQLiteViewLayer::BuildWhere() 390 391 { 392 osWHERE = ""; 393 394 CPLString osSpatialWHERE = GetSpatialWhere(m_poFilterGeom); 395 if (osSpatialWHERE.size() != 0) 396 { 397 osWHERE = "WHERE "; 398 osWHERE += osSpatialWHERE; 399 } 400 401 if( osQuery.size() > 0 ) 402 { 403 if( osWHERE.size() == 0 ) 386 404 { 387 osWHERE.Printf( "WHERE %s ", osQuery.c_str() ); 405 osWHERE = "WHERE "; 406 osWHERE += osQuery; 388 407 } 389 else 408 else 390 409 { 391 osWHERE += " AND (";410 osWHERE += " AND ("; 392 411 osWHERE += osQuery; 393 412 osWHERE += ")";
Note:
See TracChangeset
for help on using the changeset viewer.
