?? ogr_gensql.cpp
字號:
/******************************************************************************
* $Id: ogr_gensql.cpp 10646 2007-01-18 02:38:10Z warmerdam $
*
* Project: OpenGIS Simple Features Reference Implementation
* Purpose: Implements OGRGenSQLResultsLayer.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
* Copyright (c) 2002, Frank Warmerdam
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
****************************************************************************/
#include "ogr_p.h"
#include "ogr_gensql.h"
#include "cpl_string.h"
CPL_CVSID("$Id: ogr_gensql.cpp 10646 2007-01-18 02:38:10Z warmerdam $");
/************************************************************************/
/* OGRGenSQLResultsLayer() */
/************************************************************************/
OGRGenSQLResultsLayer::OGRGenSQLResultsLayer( OGRDataSource *poSrcDS,
void *pSelectInfo,
OGRGeometry *poSpatFilter )
{
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
this->poSrcDS = poSrcDS;
this->pSelectInfo = pSelectInfo;
poDefn = NULL;
poSummaryFeature = NULL;
panFIDIndex = NULL;
nIndexSize = 0;
nNextIndexFID = 0;
nExtraDSCount = 0;
papoExtraDS = NULL;
/* -------------------------------------------------------------------- */
/* Identify all the layers involved in the SELECT. */
/* -------------------------------------------------------------------- */
int iTable;
papoTableLayers = (OGRLayer **)
CPLCalloc( sizeof(OGRLayer *), psSelectInfo->table_count );
for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ )
{
swq_table_def *psTableDef = psSelectInfo->table_defs + iTable;
OGRDataSource *poTableDS = poSrcDS;
if( psTableDef->data_source != NULL )
{
OGRSFDriverRegistrar *poReg=OGRSFDriverRegistrar::GetRegistrar();
poTableDS =
poReg->OpenShared( psTableDef->data_source, FALSE, NULL );
if( poTableDS == NULL )
{
if( strlen(CPLGetLastErrorMsg()) == 0 )
CPLError( CE_Failure, CPLE_AppDefined,
"Unable to open secondary datasource\n"
"`%s' required by JOIN.",
psTableDef->data_source );
return;
}
papoExtraDS = (OGRDataSource **)
CPLRealloc( papoExtraDS, sizeof(void*) * ++nExtraDSCount );
papoExtraDS[nExtraDSCount-1] = poTableDS;
}
papoTableLayers[iTable] =
poTableDS->GetLayerByName( psTableDef->table_name );
CPLAssert( papoTableLayers[iTable] != NULL );
if( papoTableLayers[iTable] == NULL )
return;
}
poSrcLayer = papoTableLayers[0];
/* -------------------------------------------------------------------- */
/* Now that we have poSrcLayer, we can install a spatial filter */
/* if there is one. */
/* -------------------------------------------------------------------- */
if( poSpatFilter != NULL )
SetSpatialFilter( poSpatFilter );
/* -------------------------------------------------------------------- */
/* Prepare a feature definition based on the query. */
/* -------------------------------------------------------------------- */
OGRFeatureDefn *poSrcDefn = poSrcLayer->GetLayerDefn();
poDefn = new OGRFeatureDefn( psSelectInfo->table_defs[0].table_alias );
poDefn->Reference();
iFIDFieldIndex = poSrcDefn->GetFieldCount();
for( int iField = 0; iField < psSelectInfo->result_columns; iField++ )
{
swq_col_def *psColDef = psSelectInfo->column_defs + iField;
OGRFieldDefn oFDefn( psColDef->field_name, OFTInteger );
OGRFieldDefn *poSrcFDefn = NULL;
OGRFeatureDefn *poLayerDefn =
papoTableLayers[psColDef->table_index]->GetLayerDefn();
if( psColDef->field_index > -1
&& psColDef->field_index < poLayerDefn->GetFieldCount() )
poSrcFDefn = poLayerDefn->GetFieldDefn(psColDef->field_index);
if( psColDef->col_func_name != NULL )
{
oFDefn.SetName( CPLSPrintf( "%s_%s",psColDef->col_func_name,
psColDef->field_name) );
}
if( psColDef->col_func == SWQCF_COUNT )
oFDefn.SetType( OFTInteger );
else if( poSrcFDefn != NULL )
{
oFDefn.SetType( poSrcFDefn->GetType() );
oFDefn.SetWidth( poSrcFDefn->GetWidth() );
oFDefn.SetPrecision( poSrcFDefn->GetPrecision() );
}
else if ( psColDef->field_index >= iFIDFieldIndex )
{
switch ( SpecialFieldTypes[psColDef->field_index-iFIDFieldIndex] )
{
case SWQ_INTEGER:
oFDefn.SetType( OFTInteger );
break;
case SWQ_FLOAT:
oFDefn.SetType( OFTReal );
break;
default:
oFDefn.SetType( OFTString );
break;
}
}
poDefn->AddFieldDefn( &oFDefn );
}
poDefn->SetGeomType( poSrcLayer->GetLayerDefn()->GetGeomType() );
/* -------------------------------------------------------------------- */
/* If an ORDER BY is in effect, apply it now. */
/* -------------------------------------------------------------------- */
if( psSelectInfo->order_specs > 0
&& psSelectInfo->query_mode == SWQM_RECORDSET )
CreateOrderByIndex();
ResetReading();
}
/************************************************************************/
/* ~OGRGenSQLResultsLayer() */
/************************************************************************/
OGRGenSQLResultsLayer::~OGRGenSQLResultsLayer()
{
if( m_nFeaturesRead > 0 && poDefn != NULL )
{
CPLDebug( "GenSQL", "%d features read on layer '%s'.",
(int) m_nFeaturesRead,
poDefn->GetName() );
}
ClearFilters();
/* -------------------------------------------------------------------- */
/* Free various datastructures. */
/* -------------------------------------------------------------------- */
CPLFree( papoTableLayers );
papoTableLayers = NULL;
if( panFIDIndex != NULL )
CPLFree( panFIDIndex );
if( poSummaryFeature )
delete poSummaryFeature;
if( pSelectInfo != NULL )
swq_select_free( (swq_select *) pSelectInfo );
if( poDefn != NULL )
{
poDefn->Release();
}
/* -------------------------------------------------------------------- */
/* Release any additional datasources being used in joins. */
/* -------------------------------------------------------------------- */
OGRSFDriverRegistrar *poReg=OGRSFDriverRegistrar::GetRegistrar();
for( int iEDS = 0; iEDS < nExtraDSCount; iEDS++ )
poReg->ReleaseDataSource( papoExtraDS[iEDS] );
CPLFree( papoExtraDS );
}
/************************************************************************/
/* ClearFilters() */
/* */
/* Clear up all filters currently in place on the target layer, */
/* and joined layers. We try not to leave them installed */
/* except when actively fetching features. */
/************************************************************************/
void OGRGenSQLResultsLayer::ClearFilters()
{
/* -------------------------------------------------------------------- */
/* Clear any filters installed on the target layer. */
/* -------------------------------------------------------------------- */
if( poSrcLayer != NULL )
{
poSrcLayer->SetAttributeFilter( "" );
poSrcLayer->SetSpatialFilter( NULL );
}
/* -------------------------------------------------------------------- */
/* Clear any attribute filter installed on the joined layers. */
/* -------------------------------------------------------------------- */
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
int iJoin;
if( psSelectInfo != NULL )
{
for( iJoin = 0; iJoin < psSelectInfo->join_count; iJoin++ )
{
swq_join_def *psJoinInfo = psSelectInfo->join_defs + iJoin;
OGRLayer *poJoinLayer =
papoTableLayers[psJoinInfo->secondary_table];
poJoinLayer->SetAttributeFilter( "" );
}
}
}
/************************************************************************/
/* ResetReading() */
/************************************************************************/
void OGRGenSQLResultsLayer::ResetReading()
{
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
if( psSelectInfo->query_mode == SWQM_RECORDSET )
{
poSrcLayer->SetAttributeFilter( psSelectInfo->whole_where_clause );
poSrcLayer->SetSpatialFilter( m_poFilterGeom );
poSrcLayer->ResetReading();
}
nNextIndexFID = 0;
}
/************************************************************************/
/* SetNextByIndex() */
/* */
/* If we already have an FID list, we can easily resposition */
/* ourselves in it. */
/************************************************************************/
OGRErr OGRGenSQLResultsLayer::SetNextByIndex( long nIndex )
{
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
if( psSelectInfo->query_mode == SWQM_SUMMARY_RECORD
|| psSelectInfo->query_mode == SWQM_DISTINCT_LIST
|| panFIDIndex != NULL )
{
nNextIndexFID = nIndex;
return OGRERR_NONE;
}
else
{
return poSrcLayer->SetNextByIndex( nIndex );
}
}
/************************************************************************/
/* GetExtent() */
/************************************************************************/
OGRErr OGRGenSQLResultsLayer::GetExtent( OGREnvelope *psExtent,
int bForce )
{
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
if( psSelectInfo->query_mode == SWQM_RECORDSET )
return poSrcLayer->GetExtent( psExtent, bForce );
else
return OGRERR_FAILURE;
}
/************************************************************************/
/* GetSpatialRef() */
/************************************************************************/
OGRSpatialReference *OGRGenSQLResultsLayer::GetSpatialRef()
{
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
if( psSelectInfo->query_mode != SWQM_RECORDSET )
return NULL;
else
return poSrcLayer->GetSpatialRef();
}
/************************************************************************/
/* GetFeatureCount() */
/************************************************************************/
int OGRGenSQLResultsLayer::GetFeatureCount( int bForce )
{
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
if( psSelectInfo->query_mode != SWQM_RECORDSET )
return 1;
else if( m_poAttrQuery == NULL )
return poSrcLayer->GetFeatureCount( bForce );
else
return OGRLayer::GetFeatureCount( bForce );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -