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 + -
显示快捷键?