Skip to content

Commit

Permalink
Shape and OGR providers: allow TILESRS keyword to support tileindex w…
Browse files Browse the repository at this point in the history
…ith tiles of different SRS

This is the extension of previous work to support raster tile index.

Such vector tileindex with mixed SRS can be generated with GDAL 2.2 ogrtindex utility
with the -t_srs and -src_srs_name options.
  • Loading branch information
rouault committed Mar 30, 2017
1 parent bf858b9 commit bb61f1f
Show file tree
Hide file tree
Showing 16 changed files with 464 additions and 76 deletions.
98 changes: 80 additions & 18 deletions mapogr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ typedef struct ms_ogr_file_info_t {
OGRFeatureH hLastFeature;

int nTileId; /* applies on the tiles themselves. */
projectionObj sTileProj; /* applies on the tiles themselves. */

struct ms_ogr_file_info_t *poCurTile; /* exists on tile index, -> tiles */
bool rect_is_defined;
Expand Down Expand Up @@ -1286,6 +1287,7 @@ msOGRFileOpen(layerObj *layer, const char *connection )
psInfo->hLayer = hLayer;

psInfo->nTileId = 0;
msInitProjection(&(psInfo->sTileProj));
psInfo->poCurTile = NULL;
psInfo->rect_is_defined = false;
psInfo->rect.minx = psInfo->rect.maxx = 0;
Expand Down Expand Up @@ -1693,7 +1695,8 @@ static int msOGRFileClose(layerObj *layer, msOGRFileInfo *psInfo )
// Free current tile if there is one.
if( psInfo->poCurTile != NULL )
msOGRFileClose( layer, psInfo->poCurTile );


msFreeProjection(&(psInfo->sTileProj));
msFree(psInfo->pszSelect);
msFree(psInfo->pszSpatialFilterTableName);
msFree(psInfo->pszSpatialFilterGeometryColumn);
Expand Down Expand Up @@ -3047,6 +3050,16 @@ int msOGRFileReadTile( layerObj *layer, msOGRFileInfo *psInfo,
connection = msStrdup( OGR_F_GetFieldAsString( hFeature,
layer->tileitemindex ));

char* pszSRS = NULL;
if( layer->tilesrs != NULL )
{
int idx = OGR_F_GetFieldIndex( hFeature, layer->tilesrs);
if( idx >= 0 )
{
pszSRS = msStrdup( OGR_F_GetFieldAsString( hFeature, idx ));
}
}

nFeatureId = (int)OGR_F_GetFID( hFeature ); // FIXME? GetFID() is a 64bit integer in GDAL 2.0

OGR_F_Destroy( hFeature );
Expand All @@ -3066,15 +3079,38 @@ int msOGRFileReadTile( layerObj *layer, msOGRFileInfo *psInfo,
#endif

if( psTileInfo == NULL )
{
msFree(pszSRS);
return MS_FAILURE;
}

if( pszSRS != NULL )
{
if( msOGCWKT2ProjectionObj( pszSRS, &(psInfo->sTileProj),
layer->debug ) != MS_SUCCESS )
{
msFree(pszSRS);
return MS_FAILURE;
}
msFree(pszSRS);
}

psTileInfo->nTileId = nFeatureId;

/* -------------------------------------------------------------------- */
/* Initialize the spatial query on this file. */
/* -------------------------------------------------------------------- */
if( psInfo->rect.minx != 0 || psInfo->rect.maxx != 0 ) {
status = msOGRFileWhichShapes( layer, psInfo->rect, psTileInfo );
rectObj rect = psInfo->rect;

#ifdef USE_PROJ
if( layer->tileindex != NULL && psInfo->sTileProj.numargs > 0 )
{
msProjectRect(&(layer->projection), &(psInfo->sTileProj), &rect);
}
#endif

status = msOGRFileWhichShapes( layer, rect, psTileInfo );
if( status != MS_SUCCESS )
return status;
}
Expand Down Expand Up @@ -3975,23 +4011,10 @@ int msOGRLayerOpen(layerObj *layer, const char *pszOverrideConnection)
if( layer->layerinfo == NULL )
return MS_FAILURE;

if( layer->tilesrs != NULL ) {
msSetError(MS_OGRERR,
"TILESRS not supported in vector layers.",
"msOGRLayerOpen()");
return MS_FAILURE;
}

// Identify TILEITEM

OGRFeatureDefnH hDefn = OGR_L_GetLayerDefn( psInfo->hLayer );
for( layer->tileitemindex = 0;
layer->tileitemindex < OGR_FD_GetFieldCount( hDefn )
&& !EQUAL( OGR_Fld_GetNameRef( OGR_FD_GetFieldDefn( hDefn, layer->tileitemindex) ),
layer->tileitem);
layer->tileitemindex++ ) {}

if( layer->tileitemindex == OGR_FD_GetFieldCount( hDefn ) ) {
layer->tileitemindex = OGR_FD_GetFieldIndex(hDefn, layer->tileitem);
if( layer->tileitemindex < 0 ) {
msSetError(MS_OGRERR,
"Can't identify TILEITEM %s field in TILEINDEX `%s'.",
"msOGRLayerOpen()",
Expand All @@ -4000,6 +4023,29 @@ int msOGRLayerOpen(layerObj *layer, const char *pszOverrideConnection)
layer->layerinfo = NULL;
return MS_FAILURE;
}

// Identify TILESRS
if( layer->tilesrs != NULL &&
OGR_FD_GetFieldIndex(hDefn, layer->tilesrs) < 0 ) {
msSetError(MS_OGRERR,
"Can't identify TILESRS %s field in TILEINDEX `%s'.",
"msOGRLayerOpen()",
layer->tilesrs, layer->tileindex );
msOGRFileClose( layer, psInfo );
layer->layerinfo = NULL;
return MS_FAILURE;
}
if( layer->tilesrs != NULL && layer->projection.numargs == 0 )
{
msSetError(MS_OGRERR,
"A layer with TILESRS set in TILEINDEX `%s' must have a "
"projection set on itself.",
"msOGRLayerOpen()",
layer->tileindex );
msOGRFileClose( layer, psInfo );
layer->layerinfo = NULL;
return MS_FAILURE;
}
}

/* ------------------------------------------------------------------
Expand Down Expand Up @@ -4420,7 +4466,16 @@ int msOGRLayerNextShape(layerObj *layer, shapeObj *shape)
// Try getting a shape from this tile.
status = msOGRFileNextShape( layer, shape, psInfo->poCurTile );
if( status != MS_DONE )
{
#ifdef USE_PROJ
if( psInfo->sTileProj.numargs > 0 )
{
msProjectShape(&(psInfo->sTileProj), &(layer->projection), shape);
}
#endif

return status;
}

// try next tile.
status = msOGRFileReadTile( layer, psInfo );
Expand Down Expand Up @@ -4477,7 +4532,14 @@ int msOGRLayerGetShape(layerObj *layer, shapeObj *shape, resultObj *record)
return MS_FAILURE;
}

return msOGRFileGetShape(layer, shape, shapeindex, psInfo->poCurTile, record_is_fid );
int status = msOGRFileGetShape(layer, shape, shapeindex, psInfo->poCurTile, record_is_fid );
#ifdef USE_PROJ
if( status == MS_SUCCESS && psInfo->sTileProj.numargs > 0 )
{
msProjectShape(&(psInfo->sTileProj), &(layer->projection), shape);
}
#endif
return status;
}
#else
/* ------------------------------------------------------------------
Expand Down
Loading

0 comments on commit bb61f1f

Please sign in to comment.