⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ogr_gensql.cpp

📁 GIS系统支持库Geospatial Data Abstraction Library代码.GDAL is a translator library for raster geospatial dat
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*                             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 + -