@@ -504,6 +504,9 @@ int msOGRGeometryToShape(OGRGeometryH hGeometry, shapeObj *psShape,
504
504
505
505
// Special field index codes for handling text string and angle coming from
506
506
// OGR style strings.
507
+
508
+ #define MSOGR_FID_INDEX -99
509
+
507
510
#define MSOGR_LABELNUMITEMS 21
508
511
#define MSOGR_LABELFONTNAMENAME " OGR:LabelFont"
509
512
#define MSOGR_LABELFONTNAMEINDEX -100
@@ -602,6 +605,9 @@ static char **msOGRGetValues(layerObj *layer, OGRFeatureH hFeature)
602
605
if (itemindexes[i] >= 0 ) {
603
606
// Extract regular attributes
604
607
values[i] = msStrdup (OGR_F_GetFieldAsString ( hFeature, itemindexes[i]));
608
+ } else if (itemindexes[i] == MSOGR_FID_INDEX ) {
609
+ values[i] = msStrdup (CPLSPrintf (CPL_FRMT_GIB,
610
+ (GIntBig) OGR_F_GetFID (hFeature)));
605
611
} else {
606
612
// Handle special OGR attributes coming from StyleString
607
613
if (!hStyleMgr) {
@@ -1283,6 +1289,16 @@ msOGRFileOpen(layerObj *layer, const char *connection )
1283
1289
psInfo->last_record_index_read = -1 ;
1284
1290
psInfo->dialect = NULL ;
1285
1291
1292
+ psInfo->pszSelect = NULL ;
1293
+ psInfo->pszSpatialFilterTableName = NULL ;
1294
+ psInfo->pszSpatialFilterGeometryColumn = NULL ;
1295
+ psInfo->pszMainTableName = NULL ;
1296
+ psInfo->pszRowId = NULL ;
1297
+ psInfo->bIsOKForSQLCompose = true ;
1298
+ psInfo->bPaging = false ;
1299
+ psInfo->bHasSpatialIndex = false ;
1300
+ psInfo->pszTablePrefix = NULL ;
1301
+
1286
1302
// GDAL 1.x API
1287
1303
OGRSFDriverH dr = OGR_DS_GetDriver (hDS);
1288
1304
const char *name = OGR_Dr_GetName (dr);
@@ -1321,18 +1337,60 @@ msOGRFileOpen(layerObj *layer, const char *connection )
1321
1337
psInfo->dialect = " PostgreSQL" ;
1322
1338
// todo: PostgreSQL not yet tested
1323
1339
1324
- } // todo: other dialects, for example OGR SQL
1340
+ } else if (strcmp (name, " GPKG" ) == 0 && nLayerIndex >= 0 &&
1341
+ atoi (GDALVersionInfo (" VERSION_NUM" )) >= 2000000 ) {
1325
1342
1343
+ bool has_rtree = false ;
1344
+ const char * test_rtree =
1345
+ CPLSPrintf (" SELECT 1 FROM sqlite_master WHERE name = 'rtree_%s_%s'" ,
1346
+ OGR_L_GetName (hLayer), OGR_L_GetGeometryColumn (hLayer));
1347
+ OGRLayerH l = OGR_DS_ExecuteSQL (hDS, test_rtree, NULL , NULL );
1348
+ if ( l )
1349
+ {
1350
+ if ( OGR_L_GetFeatureCount (l, TRUE ) == 1 )
1351
+ {
1352
+ has_rtree = true ;
1353
+ }
1354
+ OGR_DS_ReleaseResultSet (hDS, l);
1355
+ }
1356
+ if ( has_rtree )
1357
+ {
1358
+ bool have_gpkg_spatialite = false ;
1326
1359
1327
- psInfo->pszSelect = NULL ;
1328
- psInfo->pszSpatialFilterTableName = NULL ;
1329
- psInfo->pszSpatialFilterGeometryColumn = NULL ;
1330
- psInfo->pszMainTableName = NULL ;
1331
- psInfo->pszRowId = NULL ;
1332
- psInfo->bIsOKForSQLCompose = true ;
1333
- psInfo->bPaging = false ;
1334
- psInfo->bHasSpatialIndex = false ;
1335
- psInfo->pszTablePrefix = NULL ;
1360
+ CPLPushErrorHandler (CPLQuietErrorHandler);
1361
+
1362
+ // test for Spatialite >= 4.3 support in driver
1363
+ const char *test_spatialite = " SELECT spatialite_version()" ;
1364
+ l = OGR_DS_ExecuteSQL (hDS, test_spatialite, NULL , NULL );
1365
+ if (l) {
1366
+ OGRFeatureH hFeat = OGR_L_GetNextFeature (l);
1367
+ if ( hFeat )
1368
+ {
1369
+ const char * pszVersion = OGR_F_GetFieldAsString (hFeat, 0 );
1370
+ have_gpkg_spatialite = atof (pszVersion) >= 4.3 ;
1371
+ OGR_F_Destroy (hFeat);
1372
+ }
1373
+ OGR_DS_ReleaseResultSet (hDS, l);
1374
+ }
1375
+ CPLPopErrorHandler ();
1376
+
1377
+ if ( have_gpkg_spatialite )
1378
+ {
1379
+ psInfo->pszMainTableName = msStrdup ( OGR_L_GetName (hLayer) );
1380
+ psInfo->pszSpatialFilterTableName = msStrdup ( OGR_L_GetName (hLayer) );
1381
+ psInfo->pszSpatialFilterGeometryColumn = msStrdup ( OGR_L_GetGeometryColumn (hLayer) );
1382
+ psInfo->dialect = " GPKG" ;
1383
+ psInfo->bPaging = true ;
1384
+ psInfo->bHasSpatialIndex = true ;
1385
+ }
1386
+ else
1387
+ msDebug (" msOGRFileOpen: Spatialite support in GPKG not enabled\n " );
1388
+ }
1389
+ else
1390
+ {
1391
+ msDebug (" msOGRFileOpen: RTree index not available\n " );
1392
+ }
1393
+ }
1336
1394
1337
1395
if ( psInfo->dialect != NULL && EQUAL (psInfo->dialect , " Spatialite" ) )
1338
1396
msOGRFileOpenSpatialite (layer, pszLayerDef, psInfo);
@@ -1806,7 +1864,7 @@ char *msOGRGetToken(layerObj* layer, tokenListNodeObjPtr *node) {
1806
1864
char wild_any = ' %' ;
1807
1865
char wild_one = ' _' ;
1808
1866
1809
- if (EQUAL (info->dialect , " Spatialite" )) {
1867
+ if (EQUAL (info->dialect , " Spatialite" ) || EQUAL (info-> dialect , " GPKG " ) ) {
1810
1868
if (case_sensitive) {
1811
1869
op = " GLOB" ;
1812
1870
wild_any = ' *' ;
@@ -1926,7 +1984,7 @@ char *msOGRGetToken(layerObj* layer, tokenListNodeObjPtr *node) {
1926
1984
else
1927
1985
{
1928
1986
const char *SQLtype = " float(16)" ;
1929
- if (EQUAL (info->dialect , " Spatialite" ))
1987
+ if (EQUAL (info->dialect , " Spatialite" ) || EQUAL (info-> dialect , " GPKG " ) )
1930
1988
SQLtype = " REAL" ;
1931
1989
else if (EQUAL (info->dialect , " PostgreSQL" ))
1932
1990
SQLtype = " double precision" ;
@@ -2205,17 +2263,19 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
2205
2263
}
2206
2264
psInfo->rect = rect;
2207
2265
2208
- bool bSpatialiteAddOrderByFID = false ;
2266
+ bool bSpatialiteOrGPKGAddOrderByFID = false ;
2209
2267
2210
- if ( psInfo->dialect && EQUAL (psInfo->dialect , " Spatialite" ) &&
2211
- psInfo->pszMainTableName != NULL && psInfo->bHasSpatialIndex &&
2268
+ if ( psInfo->dialect && psInfo->pszMainTableName != NULL &&
2269
+ ( (EQUAL (psInfo->dialect , " Spatialite" ) && psInfo->bHasSpatialIndex )
2270
+ || EQUAL (psInfo->dialect , " GPKG" ) ) &&
2212
2271
bIsValidRect )
2213
2272
{
2214
2273
select = msStringConcatenate (select , " JOIN " );
2215
2274
2216
2275
char szSpatialIndexName[256 ];
2217
2276
snprintf ( szSpatialIndexName, sizeof (szSpatialIndexName),
2218
- " idx_%s_%s" ,
2277
+ " %s_%s_%s" ,
2278
+ EQUAL (psInfo->dialect , " Spatialite" ) ? " idx" : " rtree" ,
2219
2279
psInfo->pszSpatialFilterTableName ,
2220
2280
psInfo->pszSpatialFilterGeometryColumn );
2221
2281
char * pszEscapedSpatialIndexName = msLayerEscapePropertyName (
@@ -2240,20 +2300,35 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
2240
2300
}
2241
2301
else
2242
2302
select = msStringConcatenate (select , " ROWID" );
2243
- select = msStringConcatenate (select , " = ms_spat_idx.pkid AND " );
2303
+ if ( EQUAL (psInfo->dialect , " Spatialite" ) )
2304
+ select = msStringConcatenate (select , " = ms_spat_idx.pkid AND " );
2305
+ else
2306
+ select = msStringConcatenate (select , " = ms_spat_idx.id AND " );
2244
2307
2245
2308
char szCond[256 ];
2246
- snprintf (szCond, sizeof (szCond),
2309
+ if ( EQUAL (psInfo->dialect , " Spatialite" ) )
2310
+ {
2311
+ snprintf (szCond, sizeof (szCond),
2247
2312
" ms_spat_idx.xmin <= %.15g AND ms_spat_idx.xmax >= %.15g AND "
2248
2313
" ms_spat_idx.ymin <= %.15g AND ms_spat_idx.ymax >= %.15g" ,
2249
2314
rect.maxx , rect.minx , rect.maxy , rect.miny );
2315
+ }
2316
+ else
2317
+ {
2318
+ snprintf (szCond, sizeof (szCond),
2319
+ " ms_spat_idx.minx <= %.15g AND ms_spat_idx.maxx >= %.15g AND "
2320
+ " ms_spat_idx.miny <= %.15g AND ms_spat_idx.maxy >= %.15g" ,
2321
+ rect.maxx , rect.minx , rect.maxy , rect.miny );
2322
+ }
2250
2323
select = msStringConcatenate (select , szCond);
2251
2324
2252
- bSpatialiteAddOrderByFID = true ;
2325
+ bSpatialiteOrGPKGAddOrderByFID = true ;
2253
2326
}
2254
2327
2255
2328
if (psInfo->dialect ) {
2256
- if (EQUAL (psInfo->dialect , " Spatialite" ) || EQUAL (psInfo->dialect , " PostgreSQL" )) {
2329
+ if (EQUAL (psInfo->dialect , " Spatialite" ) ||
2330
+ EQUAL (psInfo->dialect , " GPKG" ) ||
2331
+ EQUAL (psInfo->dialect , " PostgreSQL" )) {
2257
2332
const char *sql = layer->filter .native_string ;
2258
2333
if (sql && *sql != ' \0 ' ) {
2259
2334
if (filter) filter = msStringConcatenate (filter, " AND " );
@@ -2318,7 +2393,7 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
2318
2393
}
2319
2394
}
2320
2395
2321
- if ( bSpatialiteAddOrderByFID )
2396
+ if ( bSpatialiteOrGPKGAddOrderByFID )
2322
2397
{
2323
2398
if ( sort == NULL )
2324
2399
sort = msStringConcatenate (NULL , " ORDER BY " );
@@ -3577,7 +3652,16 @@ static int msOGRLayerInitItemInfo(layerObj *layer)
3577
3652
itemindexes[i] = MSOGR_SYMBOLPARAMINDEX
3578
3653
+ atoi (layer->items [i] + MSOGR_SYMBOLPARAMNAMELEN);
3579
3654
else
3655
+ {
3580
3656
itemindexes[i] = OGR_FD_GetFieldIndex ( hDefn, layer->items [i] );
3657
+ if ( itemindexes[i] == -1 )
3658
+ {
3659
+ if ( EQUAL ( layer->items [i], OGR_L_GetFIDColumn ( psInfo->hLayer ) ) )
3660
+ {
3661
+ itemindexes[i] = MSOGR_FID_INDEX;
3662
+ }
3663
+ }
3664
+ }
3581
3665
if (itemindexes[i] == -1 ) {
3582
3666
msSetError (MS_OGRERR,
3583
3667
" Invalid Field name: %s" ,
0 commit comments