📄 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 + -