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

一、有关渲染的类

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;

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容