这个功能其实很简单,但是看到网上很多人不知道怎么做,故记录下帮助需要的朋友。
其实看源码就知道怎么做了。
如果自己重新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