QGIS学习之-显示SVG图片

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


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


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


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


头文件定义如下:

#ifndef SVGANNOTATIONITEM_H

#define SVGANNOTATIONITEM_H
#include <qgsannotationitem.h>
#include <qgsapplication.h>
#include <qgsproviderregistry.h>
#include <qgssinglesymbolrendererv2.h>
#include <qgsmaplayerregistry.h>
#include <qgsvectorlayer.h>
#include <qgsmapcanvas.h>
#include <qgsproject.h>
#include <qgslayertreenode.h>
#include <qgslayertreegroup.h>
#include <qgslayertreeregistrybridge.h>
#include <qgsattributetablemodel.h>
#include <qgsattributetableview.h>
#include <qgsattributetablefiltermodel.h>
#include <qgsvectorlayercache.h>
#include <qgseditorwidgetregistry.h>
#include <qgspallabeling.h>
#include <qgscustomlayerorderwidget.h>
#include <QgsRasterLayer.h>
#include <qgssymbollayerv2.h>
#include <qgssimplifymethod.h>
#include <qgssymbollayerv2.h>
#include <qgssymbolv2.h>
#include <qgsmarkersymbollayerv2.h>
#include <qgsvectorlayerrenderer.h>
#include <qgsrendercontext.h>
#include <qgssinglesymbolrendererv2.h>
#include <qgssymbollayerv2.h>
#include "SCVectorLayer.h"
#include "SCMapCanvas.h"
#include "qgstextannotationitem.h"
#include <qgsformannotationitem.h>
#include "MeasureTool.h"
#include <qgssvgannotationitem.h>
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 <QDomDocument>
#include <QDomElement>
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



QGIS中,可以利用矢量数据生成SVG(可缩放矢量图形)格式的纹理图片,这种方式特别适合需要高质量、可缩放的图形输出,例如用于地图出版、插图设计或Web可视化应用。QGIS支持将地图画布内容导出为SVG格式,包括矢量图层、符号化样式和标注信息,从而生成具有地理空间信息的矢量纹理图片QGIS提供了“导出地图为SVG”的功能,用户可以通过菜单“项目” > “导出地图” > “导出地图为SVG”来执行此操作。该功能允许将当前地图视图中的所有图层(包括矢量数据)导出为一个SVG文件,支持保留图层样式、颜色和符号设置[^1]。 在导出过程中,可以调整输出范围、分辨率和地图比例尺,确保生成的SVG图像符合纹理贴图的尺寸和精度要求。此外,QGIS还支持将单个矢量图层导出为SVG文件,通过右键点击图层并选择“导出” > “另存为SVG”,可以仅导出特定矢量图层的几何与样式,适用于需要单独处理某个图层作为纹理的情况[^1]。 为了实现更精细的控制,例如批量导出多个矢量图层为SVG格式,可以使用PyQGIS脚本进行自动化处理。以下是一个示例代码,展示如何通过Python脚本将矢量图层导出为SVG文件: ```python from qgis.core import QgsVectorLayer, QgsMapSettings, QgsMapRendererParallelJob from qgis.gui import QgsMapCanvas from PyQt5.QtSvg import QSvgGenerator from PyQt5.QtGui import QPainter # 加载矢量图层 vector_layer = QgsVectorLayer("path/to/vector.shp", "Vector Layer", "ogr") # 设置地图画布 canvas = QgsMapCanvas() canvas.setLayers([vector_layer]) canvas.setExtent(vector_layer.extent()) canvas.refresh() # 设置SVG输出 svg = QSvgGenerator() svg.setFileName("/path/to/output.svg") svg.setSize(canvas.size()) svg.setViewBox(canvas.rect()) svg.setTitle("Vector Texture SVG") svg.setDescription("Generated by QGIS") # 渲染并保存为SVG painter = QPainter(svg) canvas.render(painter) painter.end() ``` 该脚本通过QGIS的渲染引擎将矢量图层渲染为SVG格式,适用于需要程序化控制输出内容的场景。 生成的SVG文件可以作为纹理贴图用于WebGL三维可视化、GIS软件中的矢量叠加或图形编辑软件中的进一步处理。 ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值