?? ogr_gensql.cpp
字號:
}
/************************************************************************/
/* TestCapability() */
/************************************************************************/
int OGRGenSQLResultsLayer::TestCapability( const char *pszCap )
{
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
if( EQUAL(pszCap,OLCFastSetNextByIndex) )
{
if( psSelectInfo->query_mode == SWQM_SUMMARY_RECORD
|| psSelectInfo->query_mode == SWQM_DISTINCT_LIST
|| panFIDIndex != NULL )
return TRUE;
else
return poSrcLayer->TestCapability( pszCap );
}
if( psSelectInfo->query_mode == SWQM_RECORDSET
&& (EQUAL(pszCap,OLCFastFeatureCount)
|| EQUAL(pszCap,OLCRandomRead)
|| EQUAL(pszCap,OLCFastGetExtent)) )
return poSrcLayer->TestCapability( pszCap );
else if( psSelectInfo->query_mode != SWQM_RECORDSET )
{
if( EQUAL(pszCap,OLCFastFeatureCount) )
return TRUE;
}
return FALSE;
}
/************************************************************************/
/* PrepareSummary() */
/************************************************************************/
int OGRGenSQLResultsLayer::PrepareSummary()
{
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
if( poSummaryFeature != NULL )
return TRUE;
poSummaryFeature = new OGRFeature( poDefn );
poSummaryFeature->SetFID( 0 );
/* -------------------------------------------------------------------- */
/* Ensure our query parameters are in place on the source */
/* layer. And initialize reading. */
/* -------------------------------------------------------------------- */
poSrcLayer->SetAttributeFilter( psSelectInfo->whole_where_clause );
poSrcLayer->SetSpatialFilter( m_poFilterGeom );
poSrcLayer->ResetReading();
/* -------------------------------------------------------------------- */
/* We treat COUNT(*) (or COUNT of anything without distinct) as */
/* a special case, and fill with GetFeatureCount(). */
/* -------------------------------------------------------------------- */
if( psSelectInfo->result_columns == 1
&& psSelectInfo->column_defs[0].col_func == SWQCF_COUNT
&& !psSelectInfo->column_defs[0].distinct_flag )
{
poSummaryFeature->SetField( 0, poSrcLayer->GetFeatureCount( TRUE ) );
return TRUE;
}
/* -------------------------------------------------------------------- */
/* Otherwise, process all source feature through the summary */
/* building facilities of SWQ. */
/* -------------------------------------------------------------------- */
const char *pszError;
OGRFeature *poSrcFeature;
while( (poSrcFeature = poSrcLayer->GetNextFeature()) != NULL )
{
for( int iField = 0; iField < psSelectInfo->result_columns; iField++ )
{
swq_col_def *psColDef = psSelectInfo->column_defs + iField;
pszError = swq_select_summarize( psSelectInfo, iField,
poSrcFeature->GetFieldAsString(
psColDef->field_index ) );
if( pszError != NULL )
{
delete poSummaryFeature;
poSummaryFeature = NULL;
CPLError( CE_Failure, CPLE_AppDefined, "%s", pszError );
return FALSE;
}
}
delete poSrcFeature;
}
pszError = swq_select_finish_summarize( psSelectInfo );
if( pszError != NULL )
{
delete poSummaryFeature;
poSummaryFeature = NULL;
CPLError( CE_Failure, CPLE_AppDefined, "%s", pszError );
return FALSE;
}
/* -------------------------------------------------------------------- */
/* If we have run out of features on the source layer, clear */
/* away the filters we have installed till a next run through */
/* the features. */
/* -------------------------------------------------------------------- */
if( poSrcFeature == NULL )
ClearFilters();
/* -------------------------------------------------------------------- */
/* Now apply the values to the summary feature. If we are in */
/* DISTINCT_LIST mode we don't do this step. */
/* -------------------------------------------------------------------- */
if( psSelectInfo->query_mode == SWQM_SUMMARY_RECORD
&& psSelectInfo->column_summary != NULL )
{
for( int iField = 0; iField < psSelectInfo->result_columns; iField++ )
{
swq_col_def *psColDef = psSelectInfo->column_defs + iField;
swq_summary *psSummary = psSelectInfo->column_summary + iField;
if( psColDef->col_func == SWQCF_AVG )
poSummaryFeature->SetField( iField,
psSummary->sum / psSummary->count );
else if( psColDef->col_func == SWQCF_MIN )
poSummaryFeature->SetField( iField, psSummary->min );
else if( psColDef->col_func == SWQCF_MAX )
poSummaryFeature->SetField( iField, psSummary->max );
else if( psColDef->col_func == SWQCF_COUNT )
poSummaryFeature->SetField( iField, psSummary->count );
else if( psColDef->col_func == SWQCF_SUM )
poSummaryFeature->SetField( iField, psSummary->sum );
}
}
return TRUE;
}
/************************************************************************/
/* TranslateFeature() */
/************************************************************************/
OGRFeature *OGRGenSQLResultsLayer::TranslateFeature( OGRFeature *poSrcFeat )
{
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
OGRFeature *poDstFeat;
if( poSrcFeat == NULL )
return NULL;
m_nFeaturesRead++;
/* -------------------------------------------------------------------- */
/* Create destination feature. */
/* -------------------------------------------------------------------- */
poDstFeat = new OGRFeature( poDefn );
poDstFeat->SetFID( poSrcFeat->GetFID() );
poDstFeat->SetGeometry( poSrcFeat->GetGeometryRef() );
/* -------------------------------------------------------------------- */
/* Copy fields from primary record to the destination feature. */
/* -------------------------------------------------------------------- */
for( int iField = 0; iField < psSelectInfo->result_columns; iField++ )
{
swq_col_def *psColDef = psSelectInfo->column_defs + iField;
if ( psColDef->field_index >= iFIDFieldIndex &&
psColDef->field_index < iFIDFieldIndex + SPECIAL_FIELD_COUNT )
{
switch (SpecialFieldTypes[psColDef->field_index - iFIDFieldIndex])
{
case SWQ_INTEGER:
poDstFeat->SetField( iField, poSrcFeat->GetFieldAsInteger(psColDef->field_index) );
break;
default:
poDstFeat->SetField( iField, poSrcFeat->GetFieldAsString(psColDef->field_index) );
}
}
else if( psColDef->table_index == 0 )
poDstFeat->SetField( iField,
poSrcFeat->GetRawFieldRef( psColDef->field_index ) );
}
/* -------------------------------------------------------------------- */
/* Copy values from any joined tables. */
/* -------------------------------------------------------------------- */
int iJoin;
for( iJoin = 0; iJoin < psSelectInfo->join_count; iJoin++ )
{
char szFilter[512];
swq_join_def *psJoinInfo = psSelectInfo->join_defs + iJoin;
OGRLayer *poJoinLayer = papoTableLayers[psJoinInfo->secondary_table];
// if source key is null, we can't do join.
if( !poSrcFeat->IsFieldSet( psJoinInfo->primary_field ) )
continue;
// Prepare attribute query to express fetching on the joined variable
sprintf( szFilter, "%s = ",
poJoinLayer->GetLayerDefn()->GetFieldDefn(
psJoinInfo->secondary_field )->GetNameRef() );
OGRField *psSrcField =
poSrcFeat->GetRawFieldRef(psJoinInfo->primary_field);
switch( poSrcLayer->GetLayerDefn()->GetFieldDefn(
psJoinInfo->primary_field )->GetType() )
{
case OFTInteger:
sprintf( szFilter+strlen(szFilter), "%d", psSrcField->Integer );
break;
case OFTReal:
sprintf( szFilter+strlen(szFilter), "%.16g", psSrcField->Real );
break;
case OFTString:
// the string really ought to be escaped.
sprintf( szFilter+strlen(szFilter), "\"%s\"",
psSrcField->String );
break;
default:
CPLAssert( FALSE );
continue;
}
poJoinLayer->ResetReading();
if( poJoinLayer->SetAttributeFilter( szFilter ) != OGRERR_NONE )
continue;
// Fetch first joined feature.
OGRFeature *poJoinFeature;
poJoinFeature = poJoinLayer->GetNextFeature();
if( poJoinFeature == NULL )
continue;
// Copy over selected field values.
for( int iField = 0; iField < psSelectInfo->result_columns; iField++ )
{
swq_col_def *psColDef = psSelectInfo->column_defs + iField;
if( psColDef->table_index == psJoinInfo->secondary_table )
poDstFeat->SetField( iField,
poJoinFeature->GetRawFieldRef(
psColDef->field_index ) );
}
delete poJoinFeature;
}
return poDstFeat;
}
/************************************************************************/
/* GetNextFeature() */
/************************************************************************/
OGRFeature *OGRGenSQLResultsLayer::GetNextFeature()
{
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
/* -------------------------------------------------------------------- */
/* Handle summary sets. */
/* -------------------------------------------------------------------- */
if( psSelectInfo->query_mode == SWQM_SUMMARY_RECORD
|| psSelectInfo->query_mode == SWQM_DISTINCT_LIST )
return GetFeature( nNextIndexFID++ );
/* -------------------------------------------------------------------- */
/* Handle ordered sets. */
/* -------------------------------------------------------------------- */
while( TRUE )
{
OGRFeature *poFeature;
if( panFIDIndex != NULL )
poFeature = GetFeature( nNextIndexFID++ );
else
{
OGRFeature *poSrcFeat = poSrcLayer->GetNextFeature();
if( poSrcFeat == NULL )
return NULL;
poFeature = TranslateFeature( poSrcFeat );
delete poSrcFeat;
}
if( poFeature == NULL )
return NULL;
if( m_poAttrQuery == NULL
|| m_poAttrQuery->Evaluate( poFeature ) )
return poFeature;
delete poFeature;
}
return NULL;
}
/************************************************************************/
/* GetFeature() */
/************************************************************************/
OGRFeature *OGRGenSQLResultsLayer::GetFeature( long nFID )
{
swq_select *psSelectInfo = (swq_select *) pSelectInfo;
/* -------------------------------------------------------------------- */
/* Handle request for summary record. */
/* -------------------------------------------------------------------- */
if( psSelectInfo->query_mode == SWQM_SUMMARY_RECORD )
{
if( !PrepareSummary() || nFID != 0 || poSummaryFeature == NULL )
return NULL;
else
return poSummaryFeature->Clone();
}
/* -------------------------------------------------------------------- */
/* Handle request for distinct list record. */
/* -------------------------------------------------------------------- */
if( psSelectInfo->query_mode == SWQM_DISTINCT_LIST )
{
if( !PrepareSummary() )
return NULL;
swq_summary *psSummary = psSelectInfo->column_summary + 0;
if( psSummary == NULL )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -