图标是gis(地理信息系统)中重要的实现,主要用于地图上特定位置的标注,从本质上讲就是点要素的符号化处理。根据实现有两种,一是点图层的要素的符号化,这种可以通过制图的图层样式化解决;另外一种就是根据情况在地图上的临时标注,这种标注跟具体图层没有关联。下面将介绍QGIS中的两种实现:
一、利用橡皮擦类实现(QgsRubberBand)
橡皮擦类可以实现临时对象绘制,对象的类型包括点、线、面,如果对象类型为点时,通过设置具体样式即可实现具体的图标。
涉及的关键成员函数:
void QgsRubberBand::setIcon ( IconType icon )
其中IconType是个枚举类型,指明图标的类型,包括
Enumerator | |
---|---|
ICON_NONE | No icon is used. |
ICON_CROSS | A cross is used to highlight points (+) |
ICON_X | A cross is used to highlight points (x) |
ICON_BOX | A box is used to highlight points (□) |
ICON_CIRCLE | A circle is used to highlight points (○) |
ICON_FULL_BOX | A full box is used to highlight points (■) |
ICON_DIAMOND | A diamond is used to highlight points (◇) Since QGIS 3.0 |
ICON_FULL_DIAMOND | A diamond is used to highlight points (◆) Since QGIS 3.0 |
ICON_SVG | An svg image is used to highlight points. Since QGIS 3.10 |
如果类型是ICON_SVG,则表明图标来源于SVG图片,此时可以通过调用下面函数实现图标文件指定:
void QgsRubberBand::setSvgIcon(const QString & path,QPoint drawOffset )
具体例子如下:
QgsRubberBand *rb = new QgsRubberBand(mapCanvas,QgsWkbTyps::PointGeometry);
rb->setIcon(QgsRubberBand::IconType::ICON_SVG); //设置图标类型
rb->setSvgIcon("你的xxxx.svg",QPoint(0,0)); //设置图标文件路径和偏移
rb->setIconSize(10); //设置图标尺寸
QgsGeometry geo = QgsGeometry::fromPointXY(10,10);
rb->addGeometry(geo); //绘制
由于橡皮擦没有具体管理类,因此要实现图标的查询、删除等管理功能需要进行大量的开发,建议参考系列文章:跟踪图层的实现。
二、利用标注图层实现(QgsAnnotationLayer)
1、创建标注图层
QgsCoordinateTransformContext* coordinateTransformContext = new QgsCoordinateTransformContext;
//实例化标签图层
QgsAnnotationLayer *annotationMarkerLayer = new SHQgsAnnotationLayer("SYSTEM_ANNOTATION_LAYER", QgsAnnotationLayer::LayerOptions(*coordinateTransformContext));
//添加到画布和工程
QList layers = m_mapCanvas->layers();//m_mapCanvas为画布控件
layers.append(layer);
if (!QgsProject::instance()->mapLayer(layer->id())) {
QgsProject::instance()->addMapLayer(layer);
}
m_mapCanvas->setLayers(layers);
注意:QgsAnnotationLayer依赖于已有的图层存在,因此必须在加载了空间数据后添加进画布才有效。
2、添加标签等元素到标注图层
标注图层通过addItem()实现将要素添加到图层,支持添加的要素包括:
其中QgsAnnotationMarkerItem即为图标元素,该元素类有两个重要的方法:
(1)setGeometry,用于设置图标元素所在的空间坐标
void QgsAnnotationMarkerItem::setGeometry(const QgsPoint & geometry)
(2)setSymbol,设置图标要素的样式,也就是显示的图片等等
void QgsAnnotationMarkerItem::setSymbol(QgsMarkerSymbol * symbol)
QgsMarkerSymbol是整个样式的关键
QgsMarkerSymbol::QgsMarkerSymbol(const QgsSymbolLayerList & layers = QgsSymbolLayerList())
QgsSymbolLayerList是样式组合列表,也表明支持多种显示样式的叠加组合,目前支持的类型包括:
实现例子如下:
QgsSymbolLayerList symList;
//第一个子图标,svg
QgsSvgMarkerSymbolLayer *marker0 = new QgsSvgMarkerSymbolLayer("d://temp//1.svg");
marker0->setSize(10); //大小
marker0->setOffset(QPointF(0,0);//偏移
symList.append(marker0->clone());
delete marker0;
marker0 = nullptr;
//第二个子图标,
QgsRasterMarkerSymbolLayer *marker = new QgsRasterMarkerSymbolLayer("d://temp//2.png");
marker->setSize(12);
marker->setOffset(QPointF(10,0);
symList.append(marker->clone());
delete marker;
marker = nullptr;
(3)实例化图标元素
QgsAnnotationMarkerItem *markerItem = new QgsAnnotationMarkerItem();
markerItem->setGeometry(QgsPoint(10.0,10);
QgsMarkerSymbol *symbol = new QgsMarkerSymbol(symList);
markerItem->setSymbol(symbol);
(4)图标元素添加到图层
annotationLayer->addItem(markerItem);