QGIS学习之-显示SVG图片

这个功能其实很简单,但是看到网上很多人不知道怎么做,故记录下帮助需要的朋友。


其实看源码就知道怎么做了。


如果自己重新QGraphicsItem 可以将图片加入图层,但是有很多问题,比如地图坐标等等,其实QGIS已经帮我们实现了,它就是QgsAnnotationItem


所以我们要实现显示SVG图片 又不想自己去管理缩放,坐标等等 就从QgsAnnotationItem继承并重新paint就好了.


头文件定义如下:

#ifndef SVGANNOTATIONITEM_H

#define SVGANNOTATIONITEM_H
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "SCVectorLayer.h"
#include "SCMapCanvas.h"
#include "qgstextannotationitem.h"
#include 
#include "MeasureTool.h"
#include 
class  QSvgRenderer;
class SvgAnnotationImageItem: public QgsAnnotationItem
{
  public:
    SvgAnnotationImageItem( QgsMapCanvas* canvas );
    ~SvgAnnotationImageItem();
    void writeXML( QDomDocument& doc ) const override;
     void readXML( const QDomDocument& doc, const QDomElement& itemElem ) override;
    void paint( QPainter* painter ) override;
    void setFilePath( const QString& file );
    QString filePath() const { return mFilePath; }
  private:
    QSvgRenderer *mSvgRenderer;
    QString mFilePath;
};
#endif // SVGANNOTATIONITEM_H


源文件如下:


#include "SvgAnnotationItem.h"

#include "qgsproject.h"
#include 
#include 
SvgAnnotationImageItem::SvgAnnotationImageItem( QgsMapCanvas* canvas ): QgsAnnotationItem( canvas )
{
    mSvgRenderer = new QSvgRenderer();
}
SvgAnnotationImageItem::~SvgAnnotationImageItem()
{
    mSvgRenderer->deleteLater();
}
void SvgAnnotationImageItem::writeXML( QDomDocument& doc ) const
{
  QDomElement documentElem = doc.documentElement();
  if ( documentElem.isNull() )
  {
    return;
  }
  QDomElement svgAnnotationElem = doc.createElement( "SVGAnnotationItem" );
  svgAnnotationElem.setAttribute( "file", QgsProject::instance()->writePath( mFilePath ) );
  _writeXML( doc, svgAnnotationElem );
  documentElem.appendChild( svgAnnotationElem );
}
void SvgAnnotationImageItem::readXML( const QDomDocument& doc, const QDomElement& itemElem )
{
  QString filePath = QgsProject::instance()->readPath( itemElem.attribute( "file" ) );
  setFilePath( filePath );
  QDomElement annotationElem = itemElem.firstChildElement( "AnnotationItem" );
  if ( !annotationElem.isNull() )
  {
    _readXML( doc, annotationElem );
  }
}
void SvgAnnotationImageItem::paint( QPainter* painter )
{
  if ( !painter )
  {
    return;
  }
  //keep width/height ratio of svg
  QRect viewBox = mSvgRenderer->viewBox();
  if ( viewBox.isValid() )
  {
    double widthRatio = mFrameSize.width() / viewBox.width();
    double heightRatio = mFrameSize.height() / viewBox.height();
    double renderWidth = 0;
    double renderHeight = 0;
    if ( widthRatio <= heightRatio )
    {
      renderWidth = mFrameSize.width();
      renderHeight = viewBox.height() * mFrameSize.width() / viewBox.width();
    }
    else
    {
      renderHeight = mFrameSize.height();
      renderWidth = viewBox.width() * mFrameSize.height() / viewBox.height();
    }
    mSvgRenderer->render( painter, QRectF( mOffsetFromReferencePoint.x(), mOffsetFromReferencePoint.y(), renderWidth,
                                          renderHeight ) );
  }
  if ( isSelected() )
  {
    drawSelectionBoxes( painter );
  }
}
void SvgAnnotationImageItem::setFilePath( const QString& file )
{
  mFilePath = file;
  mSvgRenderer->load( mFilePath );
}



使用方法:


   SvgAnnotationImageItem *item = new SvgAnnotationImageItem(mapCanvas);
   item->setFrameSize(QSizeF(64, 64));
   item->setFrameBorderWidth(0);
   item->setMapPosition(QgsPoint(200, 300));
   item->setFilePath("F:\\3.svg");
 


so easy



你可能感兴趣的:(Qt;QGIS)