Skip to content

Commit 60fd6de

Browse files
committed
For GPKG datasources with Spatialite support, translate mapserver expressions to SQL
1 parent 93e3eb2 commit 60fd6de

File tree

1 file changed

+105
-21
lines changed

1 file changed

+105
-21
lines changed

mapogr.cpp

+105-21
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,9 @@ int msOGRGeometryToShape(OGRGeometryH hGeometry, shapeObj *psShape,
504504

505505
// Special field index codes for handling text string and angle coming from
506506
// OGR style strings.
507+
508+
#define MSOGR_FID_INDEX -99
509+
507510
#define MSOGR_LABELNUMITEMS 21
508511
#define MSOGR_LABELFONTNAMENAME "OGR:LabelFont"
509512
#define MSOGR_LABELFONTNAMEINDEX -100
@@ -602,6 +605,9 @@ static char **msOGRGetValues(layerObj *layer, OGRFeatureH hFeature)
602605
if (itemindexes[i] >= 0) {
603606
// Extract regular attributes
604607
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)));
605611
} else {
606612
// Handle special OGR attributes coming from StyleString
607613
if (!hStyleMgr) {
@@ -1283,6 +1289,16 @@ msOGRFileOpen(layerObj *layer, const char *connection )
12831289
psInfo->last_record_index_read = -1;
12841290
psInfo->dialect = NULL;
12851291

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+
12861302
// GDAL 1.x API
12871303
OGRSFDriverH dr = OGR_DS_GetDriver(hDS);
12881304
const char *name = OGR_Dr_GetName(dr);
@@ -1321,18 +1337,60 @@ msOGRFileOpen(layerObj *layer, const char *connection )
13211337
psInfo->dialect = "PostgreSQL";
13221338
// todo: PostgreSQL not yet tested
13231339

1324-
} // todo: other dialects, for example OGR SQL
1340+
} else if (strcmp(name, "GPKG") == 0 && nLayerIndex >= 0 &&
1341+
atoi(GDALVersionInfo("VERSION_NUM")) >= 2000000) {
13251342

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;
13261359

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+
}
13361394

13371395
if( psInfo->dialect != NULL && EQUAL(psInfo->dialect, "Spatialite") )
13381396
msOGRFileOpenSpatialite(layer, pszLayerDef, psInfo);
@@ -1806,7 +1864,7 @@ char *msOGRGetToken(layerObj* layer, tokenListNodeObjPtr *node) {
18061864
char wild_any = '%';
18071865
char wild_one = '_';
18081866

1809-
if (EQUAL(info->dialect, "Spatialite")) {
1867+
if (EQUAL(info->dialect, "Spatialite") || EQUAL(info->dialect, "GPKG")) {
18101868
if (case_sensitive) {
18111869
op = "GLOB";
18121870
wild_any = '*';
@@ -1926,7 +1984,7 @@ char *msOGRGetToken(layerObj* layer, tokenListNodeObjPtr *node) {
19261984
else
19271985
{
19281986
const char *SQLtype = "float(16)";
1929-
if (EQUAL(info->dialect, "Spatialite"))
1987+
if (EQUAL(info->dialect, "Spatialite") || EQUAL(info->dialect, "GPKG"))
19301988
SQLtype = "REAL";
19311989
else if (EQUAL(info->dialect, "PostgreSQL"))
19321990
SQLtype = "double precision";
@@ -2205,17 +2263,19 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
22052263
}
22062264
psInfo->rect = rect;
22072265

2208-
bool bSpatialiteAddOrderByFID = false;
2266+
bool bSpatialiteOrGPKGAddOrderByFID = false;
22092267

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") ) &&
22122271
bIsValidRect )
22132272
{
22142273
select = msStringConcatenate(select, " JOIN ");
22152274

22162275
char szSpatialIndexName[256];
22172276
snprintf( szSpatialIndexName, sizeof(szSpatialIndexName),
2218-
"idx_%s_%s",
2277+
"%s_%s_%s",
2278+
EQUAL(psInfo->dialect, "Spatialite") ? "idx" : "rtree",
22192279
psInfo->pszSpatialFilterTableName,
22202280
psInfo->pszSpatialFilterGeometryColumn );
22212281
char* pszEscapedSpatialIndexName = msLayerEscapePropertyName(
@@ -2240,20 +2300,35 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
22402300
}
22412301
else
22422302
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 ");
22442307

22452308
char szCond[256];
2246-
snprintf(szCond, sizeof(szCond),
2309+
if( EQUAL(psInfo->dialect, "Spatialite") )
2310+
{
2311+
snprintf(szCond, sizeof(szCond),
22472312
"ms_spat_idx.xmin <= %.15g AND ms_spat_idx.xmax >= %.15g AND "
22482313
"ms_spat_idx.ymin <= %.15g AND ms_spat_idx.ymax >= %.15g",
22492314
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+
}
22502323
select = msStringConcatenate(select, szCond);
22512324

2252-
bSpatialiteAddOrderByFID = true;
2325+
bSpatialiteOrGPKGAddOrderByFID = true;
22532326
}
22542327

22552328
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")) {
22572332
const char *sql = layer->filter.native_string;
22582333
if (sql && *sql != '\0') {
22592334
if (filter) filter = msStringConcatenate(filter, "AND ");
@@ -2318,7 +2393,7 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect, msOGRFileInfo *ps
23182393
}
23192394
}
23202395

2321-
if( bSpatialiteAddOrderByFID )
2396+
if( bSpatialiteOrGPKGAddOrderByFID )
23222397
{
23232398
if( sort == NULL )
23242399
sort = msStringConcatenate(NULL, " ORDER BY ");
@@ -3577,7 +3652,16 @@ static int msOGRLayerInitItemInfo(layerObj *layer)
35773652
itemindexes[i] = MSOGR_SYMBOLPARAMINDEX
35783653
+ atoi(layer->items[i] + MSOGR_SYMBOLPARAMNAMELEN);
35793654
else
3655+
{
35803656
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+
}
35813665
if(itemindexes[i] == -1) {
35823666
msSetError(MS_OGRERR,
35833667
"Invalid Field name: %s",

0 commit comments

Comments
 (0)