📄 ogr_gensql.cpp
字号:
/* 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 ) 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( nFID < 0 || nFID >= psSummary->count ) return NULL; poSummaryFeature->SetField( 0, psSummary->distinct_list[nFID] ); poSummaryFeature->SetFID( nFID ); return poSummaryFeature->Clone(); }/* -------------------------------------------------------------------- *//* Are we running in sorted mode? If so, run the fid through *//* the index. *//* -------------------------------------------------------------------- */ if( panFIDIndex != NULL ) { if( nFID < 0 || nFID >= nIndexSize ) return NULL; else nFID = panFIDIndex[nFID]; }/* -------------------------------------------------------------------- *//* Handle request for random record. *//* -------------------------------------------------------------------- */ OGRFeature *poSrcFeature = poSrcLayer->GetFeature( nFID ); OGRFeature *poResult; if( poSrcFeature == NULL ) return NULL; poResult = TranslateFeature( poSrcFeature ); poResult->SetFID( nFID ); delete poSrcFeature; return poResult;}/************************************************************************//* GetSpatialFilter() *//************************************************************************/OGRGeometry *OGRGenSQLResultsLayer::GetSpatialFilter() { return NULL;}/************************************************************************//* SetSpatialFilter() *//************************************************************************/void OGRGenSQLResultsLayer::SetSpatialFilter( OGRGeometry * ){ CPLDebug( "OGRGenSQLResultsLayer", "SetSpatialFilter called and ignored.");}/************************************************************************//* GetLayerDefn() *//************************************************************************/OGRFeatureDefn *OGRGenSQLResultsLayer::GetLayerDefn(){ return poDefn;}/************************************************************************//* CreateOrderByIndex() *//* *//* This method is responsible for creating an index providing *//* ordered access to the features according to the supplied *//* ORDER BY clauses. *//* *//* This is accomplished by making one pass through all the *//* eligible source features, and capturing the order by fields *//* of all records in memory. A quick sort is then applied to *//* this in memory copy of the order-by fields to create the *//* required index. *//* *//* Keeping all the key values in memory will *not* scale up to *//* very large input datasets. *//************************************************************************/void OGRGenSQLResultsLayer::CreateOrderByIndex(){ swq_select *psSelectInfo = (swq_select *) pSelectInfo; OGRField *pasIndexFields; int i, nOrderItems = psSelectInfo->order_specs; long *panFIDList; if( nOrderItems == 0 ) return; ResetReading();/* -------------------------------------------------------------------- *//* Allocate set of key values, and the output index. *//* -------------------------------------------------------------------- */ nIndexSize = poSrcLayer->GetFeatureCount(); pasIndexFields = (OGRField *) CPLCalloc(sizeof(OGRField), nOrderItems * nIndexSize); panFIDIndex = (long *) CPLCalloc(sizeof(long),nIndexSize); panFIDList = (long *) CPLCalloc(sizeof(long),nIndexSize); for( i = 0; i < nIndexSize; i++ ) panFIDIndex[i] = i;/* -------------------------------------------------------------------- *//* Read in all the key values. *//* -------------------------------------------------------------------- */ OGRFeature *poSrcFeat; int iFeature = 0; while( (poSrcFeat = poSrcLayer->GetNextFeature()) != NULL ) { int iKey; for( iKey = 0; iKey < nOrderItems; iKey++ ) { swq_order_def *psKeyDef = psSelectInfo->order_defs + iKey; OGRFieldDefn *poFDefn; OGRField *psSrcField, *psDstField; psDstField = pasIndexFields + iFeature * nOrderItems + iKey; if( psKeyDef->field_index == iFIDFieldIndex ) { psDstField->Integer = poSrcFeat->GetFID(); continue; } poFDefn = poSrcLayer->GetLayerDefn()->GetFieldDefn( psKeyDef->field_index ); psSrcField = poSrcFeat->GetRawFieldRef( psKeyDef->field_index ); if( poFDefn->GetType() == OFTInteger || poFDefn->GetType() == OFTReal ) memcpy( psDstField, psSrcField, sizeof(OGRField) ); else if( poFDefn->GetType() == OFTString ) { if( poSrcFeat->IsFieldSet( psKeyDef->field_index ) ) psDstField->String = CPLStrdup( psSrcField->String ); else memcpy( psDstField, psSrcField, sizeof(OGRField) ); } } panFIDList[iFeature] = poSrcFeat->GetFID(); delete poSrcFeat; iFeature++; } CPLAssert( nIndexSize == iFeature );/* -------------------------------------------------------------------- *//* Quick sort the records. *//* -------------------------------------------------------------------- */ SortIndexSection( pasIndexFields, 0, nIndexSize );/* -------------------------------------------------------------------- *//* Rework the FID map to map to real FIDs. *//* -------------------------------------------------------------------- */ for( i = 0; i < nIndexSize; i++ ) panFIDIndex[i] = panFIDList[panFIDIndex[i]]; CPLFree( panFIDList );/* -------------------------------------------------------------------- *//* Free the key field values. *//* -------------------------------------------------------------------- */ for( int iKey = 0; iKey < nOrderItems; iKey++ ) { swq_order_def *psKeyDef = psSelectInfo->order_defs + iKey; OGRFieldDefn *poFDefn; if( psKeyDef->field_index == iFIDFieldIndex ) continue; poFDefn = poSrcLayer->GetLayerDefn()->GetFieldDefn( psKeyDef->field_index ); if( poFDefn->GetType() == OFTString ) { for( i = 0; i < nIndexSize; i++ ) { OGRField *psField = pasIndexFields + iKey + i * nOrderItems; if( psField->Set.nMarker1 != OGRUnsetMarker || psField->Set.nMarker2 != OGRUnsetMarker ) CPLFree( psField->String ); } } } CPLFree( pasIndexFields );}/************************************************************************//* SortIndexSection() *//* *//* Sort the records in a section of the index. *//************************************************************************/void OGRGenSQLResultsLayer::SortIndexSection( OGRField *pasIndexFields, int nStart, int nEntries ){ if( nEntries < 2 ) return; swq_select *psSelectInfo = (swq_select *) pSelectInfo; int nOrderItems = psSelectInfo->order_specs; int nFirstGroup = nEntries / 2; int nFirstStart = nStart; int nSecondGroup = nEntries - nFirstGroup; int nSecondStart = nStart + nFirstGroup; int iMerge = 0; long *panMerged; SortIndexSection( pasIndexFields, nFirstStart, nFirstGroup ); SortIndexSection( pasIndexFields, nSecondStart, nSecondGroup ); panMerged = (long *) CPLMalloc( sizeof(long) * nEntries ); while( iMerge < nEntries ) { int nResult; if( nFirstGroup == 0 ) nResult = -1; else if( nSecondGroup == 0 ) nResult = 1; else nResult = Compare( pasIndexFields + panFIDIndex[nFirstStart] * nOrderItems, pasIndexFields + panFIDIndex[nSecondStart] * nOrderItems ); if( nResult < 0 ) { panMerged[iMerge++] = panFIDIndex[nSecondStart++]; nSecondGroup--; } else { panMerged[iMerge++] = panFIDIndex[nFirstStart++]; nFirstGroup--; } } /* Copy the merge list back into the main index */ memcpy( panFIDIndex + nStart, panMerged, sizeof(int) * nEntries ); CPLFree( panMerged );}/************************************************************************//* Compare() *//************************************************************************/int OGRGenSQLResultsLayer::Compare( OGRField *pasFirstTuple, OGRField *pasSecondTuple ){ swq_select *psSelectInfo = (swq_select *) pSelectInfo; int nResult = 0, iKey; for( iKey = 0; nResult == 0 && iKey < psSelectInfo->order_specs; iKey++ ) { swq_order_def *psKeyDef = psSelectInfo->order_defs + iKey; OGRFieldDefn *poFDefn; if( psKeyDef->field_index == iFIDFieldIndex ) poFDefn = NULL; else poFDefn = poSrcLayer->GetLayerDefn()->GetFieldDefn( psKeyDef->field_index ); if( (pasFirstTuple[iKey].Set.nMarker1 == OGRUnsetMarker && pasFirstTuple[iKey].Set.nMarker2 == OGRUnsetMarker) || (pasSecondTuple[iKey].Set.nMarker1 == OGRUnsetMarker && pasSecondTuple[iKey].Set.nMarker2 == OGRUnsetMarker) ) nResult = 0; else if( poFDefn == NULL || poFDefn->GetType() == OFTInteger ) { if( pasFirstTuple[iKey].Integer < pasSecondTuple[iKey].Integer ) nResult = -1; else if( pasFirstTuple[iKey].Integer > pasSecondTuple[iKey].Integer ) nResult = 1; } else if( poFDefn->GetType() == OFTString ) nResult = strcmp(pasFirstTuple[iKey].String, pasSecondTuple[iKey].String); else if( poFDefn->GetType() == OFTReal ) { if( pasFirstTuple[iKey].Real < pasSecondTuple[iKey].Real ) nResult = -1; else if( pasFirstTuple[iKey].Real > pasSecondTuple[iKey].Real ) nResult = 1; } if( psKeyDef->ascending_flag ) nResult *= -1; } return nResult;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -