ogrvrtlayer.cpp

来自「支持各种栅格图像和矢量图像读取的库」· C++ 代码 · 共 1,133 行 · 第 1/3 页

CPP
1,133
字号
/* -------------------------------------------------------------------- */     const char *pszFIDFieldName = CPLGetXMLValue( psLTree, "FID", NULL );     if( pszFIDFieldName != NULL )     {         iFIDField =              poSrcLayer->GetLayerDefn()->GetFieldIndex( pszFIDFieldName );         if( iFIDField == -1 )         {             CPLError( CE_Failure, CPLE_AppDefined,                        "Unable to identify FID field '%s'.",                       pszFIDFieldName );             return FALSE;         }     }     /* -------------------------------------------------------------------- *//*      Do we have a SrcRegion?                                         *//* -------------------------------------------------------------------- */#ifdef notdef     CPLXMLNode *psSRNode = CPLGetXMLNode( psLTree, "SrcRegion" );     if( pszLayerSRS != NULL )     {         if( EQUAL(pszLayerSRS,"NULL") )             poSRS = NULL;         else         {             OGRSpatialReference oSRS;             if( oSRS.SetFromUserInput( pszLayerSRS ) != OGRERR_NONE )             {                 CPLError( CE_Failure, CPLE_AppDefined,                            "Failed to import LayerSRS `%s'.", pszLayerSRS );                 return FALSE;             }             poSRS = oSRS.Clone();         }     }     else     {         if( poSrcLayer->GetSpatialRef() != NULL )             poSRS = poSrcLayer->GetSpatialRef()->Clone();         else             poSRS = NULL;     }#endif     return TRUE;}/************************************************************************//*                            ResetReading()                            *//************************************************************************/void OGRVRTLayer::ResetReading(){    bNeedReset = TRUE;}/************************************************************************//*                         ResetSourceReading()                         *//************************************************************************/int OGRVRTLayer::ResetSourceReading(){    int bSuccess = TRUE;/* -------------------------------------------------------------------- *//*      Do we want to let source layer do spatial restriction?          *//* -------------------------------------------------------------------- */    char *pszFilter = NULL;    if( m_poFilterGeom && m_bFilterIsEnvelope && bUseSpatialSubquery )    {        const char *pszXField, *pszYField;        pszXField = poSrcLayer->GetLayerDefn()->GetFieldDefn(iGeomXField)->GetNameRef();        pszYField = poSrcLayer->GetLayerDefn()->GetFieldDefn(iGeomYField)->GetNameRef();        pszFilter = (char *)             CPLMalloc(2*strlen(pszXField)+2*strlen(pszYField) + 100);        sprintf( pszFilter,                  "%s > %.15g AND %s < %.15g AND %s > %.15g AND %s < %.15g",                  pszXField, m_sFilterEnvelope.MinX,                 pszXField, m_sFilterEnvelope.MaxX,                 pszYField, m_sFilterEnvelope.MinY,                 pszYField, m_sFilterEnvelope.MaxY );    }/* -------------------------------------------------------------------- *//*      Install spatial + attr filter query on source layer.            *//* -------------------------------------------------------------------- */    if( pszFilter == NULL && pszAttrFilter == NULL )        bSuccess = (poSrcLayer->SetAttributeFilter( NULL ) == CE_None);    else if( pszFilter != NULL && pszAttrFilter == NULL )        bSuccess = (poSrcLayer->SetAttributeFilter( pszFilter ) == CE_None);    else if( pszFilter == NULL && pszAttrFilter != NULL )        bSuccess = (poSrcLayer->SetAttributeFilter( pszAttrFilter ) == CE_None);    else    {        CPLString osMerged = pszFilter;        osMerged += " AND ";        osMerged += pszAttrFilter;        bSuccess = (poSrcLayer->SetAttributeFilter(osMerged) == CE_None);    }    CPLFree( pszFilter );/* -------------------------------------------------------------------- *//*      Clear spatial filter (to be safe) and reset reading.            *//* -------------------------------------------------------------------- */    poSrcLayer->SetSpatialFilter( NULL );    poSrcLayer->ResetReading();    bNeedReset = FALSE;    return bSuccess;}/************************************************************************//*                           GetNextFeature()                           *//************************************************************************/OGRFeature *OGRVRTLayer::GetNextFeature(){    if( poSrcLayer == NULL )        return NULL;    if( bNeedReset )    {        if( !ResetSourceReading() )            return NULL;    }    for( ; TRUE; )    {        OGRFeature      *poSrcFeature, *poFeature;        poSrcFeature = poSrcLayer->GetNextFeature();        if( poSrcFeature == NULL )            return NULL;        poFeature = TranslateFeature( poSrcFeature );        delete poSrcFeature;        if( poFeature == NULL )            return NULL;        if( (m_poFilterGeom == NULL            || FilterGeometry( poFeature->GetGeometryRef() ) )            && (m_poAttrQuery == NULL                || m_poAttrQuery->Evaluate( poFeature )) )            return poFeature;        delete poFeature;    }}/************************************************************************//*                          TranslateFeature()                          *//*                                                                      *//*      Translate a source feature into a feature for this layer.       *//************************************************************************/OGRFeature *OGRVRTLayer::TranslateFeature( OGRFeature *poSrcFeat ){    OGRFeature *poDstFeat = new OGRFeature( poFeatureDefn );    m_nFeaturesRead++;/* -------------------------------------------------------------------- *//*      Handle FID.  We should offer an option to derive it from a      *//*      field.  (TODO)                                                  *//* -------------------------------------------------------------------- */    if( iFIDField == -1 )        poDstFeat->SetFID( poSrcFeat->GetFID() );    else        poDstFeat->SetFID( poSrcFeat->GetFieldAsInteger( iFIDField ) );    /* -------------------------------------------------------------------- *//*      Handle the geometry.  Eventually there will be several more     *//*      supported options.                                              *//* -------------------------------------------------------------------- */    if( eGeometryType == VGS_None )    {        /* do nothing */    }    else if( eGeometryType == VGS_WKT )    {        char *pszWKT = (char *) poSrcFeat->GetFieldAsString( iGeomField );                if( pszWKT != NULL )        {            OGRGeometry *poGeom = NULL;            OGRGeometryFactory::createFromWkt( &pszWKT, NULL, &poGeom );            if( poGeom == NULL )                CPLDebug( "OGR_VRT", "Did not get geometry from %s",                          pszWKT );            poDstFeat->SetGeometryDirectly( poGeom );        }    }    else if( eGeometryType == VGS_WKB )    {        int nBytes;        GByte *pabyWKB;        int bNeedFree = FALSE;        if( poSrcFeat->GetFieldDefnRef(iGeomField)->GetType() == OFTBinary )        {            pabyWKB = poSrcFeat->GetFieldAsBinary( iGeomField, &nBytes );        }        else        {            const char *pszWKT = poSrcFeat->GetFieldAsString( iGeomField );            pabyWKB = CPLHexToBinary( pszWKT, &nBytes );            bNeedFree = TRUE;        }                if( pabyWKB != NULL )        {            OGRGeometry *poGeom = NULL;            if( OGRGeometryFactory::createFromWkb( pabyWKB, NULL, &poGeom,                                                   nBytes ) == OGRERR_NONE )                poDstFeat->SetGeometryDirectly( poGeom );        }        if( bNeedFree )            CPLFree( pabyWKB );    }    else if( eGeometryType == VGS_Shape )    {        int nBytes;        GByte *pabyWKB;        int bNeedFree = FALSE;        if( poSrcFeat->GetFieldDefnRef(iGeomField)->GetType() == OFTBinary )        {            pabyWKB = poSrcFeat->GetFieldAsBinary( iGeomField, &nBytes );        }        else        {            const char *pszWKT = poSrcFeat->GetFieldAsString( iGeomField );            pabyWKB = CPLHexToBinary( pszWKT, &nBytes );            bNeedFree = TRUE;        }                if( pabyWKB != NULL )        {            OGRGeometry *poGeom = NULL;            if( createFromShapeBin( pabyWKB, &poGeom, nBytes ) == OGRERR_NONE )                poDstFeat->SetGeometryDirectly( poGeom );        }        if( bNeedFree )            CPLFree( pabyWKB );    }    else if( eGeometryType == VGS_Direct )    {        poDstFeat->SetGeometry( poSrcFeat->GetGeometryRef() );    }    else if( eGeometryType == VGS_PointFromColumns )    {        double dfZ = 0.0;        if( iGeomZField != -1 )            dfZ = poSrcFeat->GetFieldAsDouble( iGeomZField );                poDstFeat->SetGeometryDirectly(             new OGRPoint( poSrcFeat->GetFieldAsDouble( iGeomXField ),                          poSrcFeat->GetFieldAsDouble( iGeomYField ),                          dfZ ) );    }    else        /* add other options here. */;/* -------------------------------------------------------------------- *//*      Copy fields.                                                    *//* -------------------------------------------------------------------- */    int iField;    for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )    {        if( panSrcField[iField] < 0 )            continue;        OGRFieldDefn *poDstDefn = poFeatureDefn->GetFieldDefn( iField );        OGRFieldDefn *poSrcDefn = poFeatureDefn->GetFieldDefn( panSrcField[iField] );        if( pabDirectCopy[iField]             && poDstDefn->GetType() == poSrcDefn->GetType() )        {            poDstFeat->SetField( iField,                                 poSrcFeat->GetRawFieldRef( panSrcField[iField] ) );        }        else        {            /* Eventually we need to offer some more sophisticated translation               options here for more esoteric types. */                        poDstFeat->SetField( iField,                                  poSrcFeat->GetFieldAsString(panSrcField[iField]));        }    }    return poDstFeat;}/************************************************************************//*                             GetFeature()                             *//************************************************************************/OGRFeature *OGRVRTLayer::GetFeature( long nFeatureId ){    if( poSrcLayer == NULL )        return NULL;    bNeedReset = TRUE;/* -------------------------------------------------------------------- *//*      If the FID is directly mapped, we can do a simple               *//*      GetFeature() to get our target feature.  Otherwise we need      *//*      to setup an appropriate query to get it.                        *//* -------------------------------------------------------------------- */    OGRFeature      *poSrcFeature, *poFeature;        if( iFIDField == -1 )    {        poSrcFeature = poSrcLayer->GetFeature( nFeatureId );    }    else     {        char szFIDQuery[200];        poSrcLayer->ResetReading();        sprintf( szFIDQuery, "%s = %ld",             poSrcLayer->GetLayerDefn()->GetFieldDefn(iFIDField)->GetNameRef(),                 nFeatureId );        poSrcLayer->SetSpatialFilter( NULL );        poSrcLayer->SetAttributeFilter( szFIDQuery );                poSrcFeature = poSrcLayer->GetNextFeature();    }    if( poSrcFeature == NULL )        return NULL;    /* -------------------------------------------------------------------- *//*      Translate feature and return it.                                *//* -------------------------------------------------------------------- */    poFeature = TranslateFeature( poSrcFeature );    delete poSrcFeature;    return poFeature;}/************************************************************************//*                         SetAttributeFilter()                         *//************************************************************************/OGRErr OGRVRTLayer::SetAttributeFilter( const char *pszNewQuery )

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?