美文网首页
Qgis从数据库读数据到渲染当前视图

Qgis从数据库读数据到渲染当前视图

作者: 李坡_e17f | 来源:发表于2020-12-28 09:49 被阅读0次

一、有关渲染的类

QgsVectorLayerRenderer类:(渲染矢量图层要素)

    {

      drawRendererV2( QgsFeatureIterator& fit )  渲染要素遍历器中的单个要素

      setGeometryCachePointer( QgsGeometryCache* cache )  建立缓存,存储要渲染的几何对象

      render() 

      stopRendererV2( QgsSingleSymbolRendererV2* selRenderer ) 结束渲染

     }

QgsFeatureRendererV2类:子类(QgsSingleSymbolRendererV2、Qgs25DRenderer、QgsCategorizedSymbolRendererV2、 QgsGraduatedSymbolRendererV2、QgsHeatmapRenderer、QgsInvertedPolygonRenderer、 QgsNullSymbolRenderer、 QgsPointDisplacementRenderer )   

      QgsSingleSymbolRendererV2类:

        {

          startRender( QgsRenderContext& context, const QgsFields& fields )

        }

QgsVectorLayer类:矢量图层类功能(图层数据调度、图层要素操作、选择要素操作、图层渲染操作、要素节点操作、添加要素操作、)

QgsVectorLayerFeatureIterator类:图层要素遍历操作()

      {

          fetchFeature( QgsFeature& f )//获取feature

          fetchNextChangedGeomFeature( QgsFeature& f ) //遍历编辑过的feature

          fetchNextChangedAttributeFeature( QgsFeature& f )

          fetchNextAddedFeature( QgsFeature& f )

       }

QgsVectorLayerEditBuffer类:缓存矢量图层编辑(存储编辑的要素(要素操作、节点操作 ))

QgsSettingsTree类:      

QgsMapRendererSequentialJob类:画布操作(创建QImage画布、在画布渲染) 

QgsMapRendererJob类:子类(QgsMapRendererCustomPainterJob类、QgsMapRendererQImageJob类、)

QgsMapRendererCustomPainterJob类:(渲染工作的准备)

QgsOgrFeatureIterator类:

     {

       QgsOgrFeatureIterator( QgsOgrFeatureSource*source, bool ownSource, const 

       QgsFeatureRequest& request )// 根据图层索引号从数据库获取该图层及信息

       nextFeatureFilterExpresson( QgsFeature& f )

       fetchFeature( QgsFeature& feature ) //获取下个要素、

        fetchFeatureWithId( QgsFeatureId id, QgsFeature& feature ) const

        readFeature( OGRFeatureH fet, QgsFeature& feature ) // 将OgrFeatue 转QgisFeature

        rewind()// 重置以开始读取下一个要素

        getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex ) //将OgrFeatueAttribute 转QgisFeatureAttribute

      }   

QgsOgrFeatureSource类:

         {

           virtual QgsFeatureIterator getFeatures( const QgsFeatureRequest& request ) override//将数据库获取的数据存储到Qgs要素遍历器中

         }

QgsOpenVectorLayerDialog类:加载数据对话框

QgisApp类:Qgis窗口的操作(添加矢量栅格图层、设置地图窗口大小、放大缩小、移动、地图编辑操作)

        {

           askUserForOGRSublayers( QgsVectorLayer *layer ) //

        }

QgsVectorDataProvider类:

二、操作流程:

QgsVectorLayerRenderer::render() //图层渲染

 {

        //从数据库中获取当前视图窗口的要素

          QgsFeatureIterator fit = mSource->getFeatures( featureRequest );

   }

//////////////////如果编辑要素,获取编辑的要素;否则获取当前视图窗口显示的要素////////////////////         

                                   ↓

QgsVectorLayerFeatureSource::getFeatures( const QgsFeatureRequest& request ) //获取改变节点的要素列表、添加的要素列表、改变属性的要素列表 

    {

            // return feature iterator that does not own this source

              return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( this, false, request ) );

     }              

QgsVectorLayerFeatureIterator::QgsVectorLayerFeatureIterator( QgsVectorLayerFeatureSource* source, bool ownSource, const QgsFeatureRequest& request )

  : QgsAbstractFeatureIteratorFromSource( source, ownSource, request )   

 , mFetchedFid( false )

 , mInterruptionChecker( nullptr )

{

   ......

       if ( mSource->mHasEditBuffer )

 是否编辑要素(添加、修改)    

             {

               mChangedFeaturesIterator = mSource->mProviderFeatureSource->getFeatures( mChangedFeaturesRequest );

             } else{

 mProviderIterator = mSource->mProviderFeatureSource->getFeatures( mProviderRequest );

  }

      rewindEditBuffer(); //mSource里编辑的要素存到QgsVectorLayerFeatureIterator

}

                                               ↓

QgsOgrFeatureSource::getFeatures( const QgsFeatureRequest& request )

     {            

            return QgsFeatureIterator( new QgsOgrFeatureIterator( this, false, request ) );                

     }

                                               ↓

//从数据库获取当前视图窗口的额要素

QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool ownSource, const QgsFeatureRequest& request )

: QgsAbstractFeatureIteratorFromSource( source, ownSource, request )  

, mFeatureFetched( false )

, mConn( nullptr )

, ogrLayer( nullptr )

 , mSubsetStringSet( false )

 , mFetchGeometry( false )

 , mExpressonCompiled( false )

, mFilterFids( mRequest.filterFids() )

, mFilterFidsIt( mFilterFids.constBegin() )

{

.......

  if ( mSource->mLayerName.isNull() )

  {   

  //根据索引号(图层序列号)获取图层

  ogrLayer = OGR_DS_GetLayer( mConn->ds, mSource->mLayerIndex );

  int LayerCount =OGR_L_GetFeatureCount(ogrLayer,1);

  QgsDebugMsg( QString( "LayerCount = %1  OGR_L_GetRefCount = %2 " ).arg( LayerCount ).arg( OGR_L_GetRefCount(ogrLayer)) );  

    }

 .........

//获取试图窗口范围内的要素

if ( !mRequest.filterRect().isNull() )

   { 

    const QgsRectangle& rect = mRequest.filterRect();

    OGR_L_SetSpatialFilterRect( ogrLayer, rect.xMinimum(), rect.yMinimum(), rect.xMaximum(), rect.yMaximum() );

    }

else

  {

    OGR_L_SetSpatialFilter( ogrLayer, nullptr );

  }

.......获取属性...

}

//////////////////////////////////////遍历要素渲染到当前视图窗口///////////                    

QgsVectorLayerRenderer::render() //图层渲染

 {

     //从数据库中获取当前视图窗口的要素

     QgsFeatureIterator fit = mSource->getFeatures( featureRequest );

     .......

     //渲染要素

     if (( mRendererV2->capabilities() & QgsFeatureRendererV2::SymbolLevels ) && mRendererV2->usingSymbolLevels() )

        drawRendererV2Levels( fit );

     else

        drawRendererV2( fit );

   }

QgsVectorLayerRenderer::drawRendererV2( QgsFeatureIterator& fit )

{

    while ( fit.nextFeature( fet ) )  

    {

      渲染 fet要素

    }

}

                                                   ↓

inline bool QgsFeatureIterator::nextFeature( QgsFeature& f )

{

  return mIter ? mIter->nextFeature( f ) : false;

}

bool QgsAbstractFeatureIterator::nextFeature( QgsFeature& f )

  .........

          dataOk = fetchFeature( f );

                  break;

               }

           } 

         if ( dataOk )    

            mFetchedCount++;  

        return dataOk;

}

bool QgsVectorLayerFeatureIterator::fetchFeature( QgsFeature& f )

{

   f.setValid( false );

   if ( mClosed ) 

      return false;

  if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )  

  {

   if ( mFetchedFid )

        return false;

      bool res = nextFeatureFid( f );

      mFetchedFid = true;

      return res;

   }

  //遍历改变的要素

  if ( !mRequest.filterRect().isNull() )

  {

         if ( fetchNextChangedGeomFeature( f ) )

            return true;

    // no more changed geometries

   }

  //遍历改变要素属性

  if ( mRequest.filterType() == QgsFeatureRequest::FilterExpresson )

  {

    if ( fetchNextChangedAttributeFeature( f ) )

          return true;

    // no more changed features

  }

   //遍历添加的要素

  while ( fetchNextAddedFeature( f ) )

   {

    return true;

  }

  //先清空ogrlayer,重新从数据库中加载当前视图窗口数据 

  if ( mProviderIterator.isClosed() )

  {

    mChangedFeaturesIterator.close();

     mProviderIterator = mSource->mProviderFeatureSource->getFeatures( mProviderRequest );

     mProviderIterator.setInterruptionChecker( mInterruptionChecker )

 }

//遍历ogrlayer中没有被编辑的要素  mProviderIterator.nextFeature( f )

// → QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature ) (在下面详细介绍

  )

while ( mProviderIterator.nextFeature( f ) )  

  {    

        //判断修改的featureID列表是否包括f.id()

        if ( mFetchConsidered.contains( f.id() ) )  

             continue;

        // TODO[MD]: just one resize of attributes

f.setFields( mSource->mFields );

// update attributes 

if ( mSource->mHasEditBuffer )  

updateChangedAttributes( f ); 

if ( mHasVirtualAttributes )    

addVirtualAttributes( f );  

if ( mRequest.filterType() == QgsFeatureRequest::FilterExpresson && mProviderRequest.filterType() != QgsFeatureRequest::FilterExpresson ) 

{   //filtering by expresson, and couldn't do it on the provider side    

   mRequest.expressonContext()->setFeature( f );

     if ( !mRequest.filterExpresson()->evaluate( mRequest.expressonContext() ).toBool() )  

     {

        //feature did not match filter      

                        continue;    

       }

  }

// update geometry

 // TODO[MK]: FilterRect check after updating the geometry    

if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) )     

updateFeatureGeometry( f );

     return true;

   }

  close();

  return false;

}

三、附加:                                                                                  

bool QgsOgrFeatureIterator::fetchFeature( QgsFeature& feature )

{

  feature.setValid( false );

  if ( mClosed || !ogrLayer )

    return false;

  if ( mRequest.filterType() == QgsFeatureRequest::FilterFid )

  {

    bool result = fetchFeatureWithId( mRequest.filterFid(), feature );

    close(); // the feature has been read or was not found: we have finished here

    return result;

  }

  else if ( mRequest.filterType() == QgsFeatureRequest::FilterFids )

  {

    while ( mFilterFidsIt != mFilterFids.constEnd() )

    {

      QgsFeatureId nextId = *mFilterFidsIt;

      mFilterFidsIt++;

      if ( fetchFeatureWithId( nextId, feature ) )

        return true;

    }

    close();

    return false;

  }

  OGRFeatureH fet;

  //遍历ogrLayer

  while (( fet = OGR_L_GetNextFeature( ogrLayer ) ) )

  {

//将ogrfeature 转 qgisFeature

    if ( !readFeature( fet, feature ) )

      continue;

    else

      OGR_F_Destroy( fet );

    if ( !mRequest.filterRect().isNull() && !feature.constGeometry() )

      continue;

QgsDebugMsg( QString( "ogrLayer -- featureID = %1 " ).arg( feature.id() ) );

    // we have a feature, end this cycle

    feature.setValid( true );

    return true;

  } // while

  close();

  return false;

}

相关文章

网友评论

      本文标题:Qgis从数据库读数据到渲染当前视图

      本文链接:https://www.haomeiwen.com/subject/npnunhtx.html