【Qgis二次开发】在QgsVectorLayer下添加要素
最初的需求是在Qgis中,在QgsVectorLayer中的点下显示与之对应的影像。影像实现控制旋转、放大和缩小的功能(无需选中)。这里记录一下问题解决的过程。
尝试使用QgsMapItem绘制要素
最初的想法是使用QgsMapItem(继承于QGraphicsItem)添加到QgsMapCanvas中,然后设置其z-Value让他显示在Layer的下面,但是遇到了一些问题。
测试过程中发现:z值大于-10时,要素一直显示在layer之上;z值小于-10时,要素不见了,只有在mapcanvas刷新时闪烁一下。
这里把mapcanvas中的QGraphicsItem都拿出来看他们的z值显示如下(从items()中取出QGraphicsItem对象是按z值从大到小排序的):
这意味着图中值为-10的z值即为layer所在的QGraphicsItem,且该QGraphicsItem有一个背景色把视图区域都覆盖了。无奈,若不能去掉该背景颜色那就只能寻求其他的方法了。
尝试使用QgsVectorLayer图层属性中的符号化(symbol)绘制要素
在Qgis 3.6以上的版本中对应point数据的QgsVectorLayer图层可添加RasterImage的symbol(先手动尝试添加,如果可行再使用代码实现)。
操作如下:
1、选择设置方式;
2、选择按分类的列数;
3、点击分类;
4、双击进入Marker设置;
5、选中子Marker;
6、选中显示方式;
7、设置Raster Image路径;
8、设置Image显示的大小(下面还可设置旋转、透明度、偏移量等);
9、选中主Marker;
10、设置基准单位;
效果如下:
这里我还在Marker中添加了一个红色圆形的子marker,表示point的位置。
这样就完成了在以点为中心位置显示影像的功能。但是遗憾的是公司使用Qgis的是3.2.n的版本,类似的功能要么就是主动拖动影像时效果不对,要么就是无法指定影像大小,无奈只能再另寻他法。
尝试将Layer和要素在一个GraphicsItem上绘制
这里说一下结论,要素还是显示在layer之上,总之还是不行……
尝试使用vrt文件格式将要素作为一个图层保存
使用vrt格式可以在一个Layer中显示多个image,关键就在于其能否实现需要的旋转、缩放功能。
阅读gdalbuildvrt代码,发现:
geotransform中的旋转参数不可用。继续无奈,另寻他法……
再次尝试使用QgsMapItem绘制要素
前面提到该方法存在的问题是背景色把要显示的要素给遮挡住了,能不能将背景设置成透明的?
在QgsMapCanvas中找到函数:
//! Write property of QColor bgColor.
void setCanvasColor( const QColor &_newVal );
设置背景颜色:
//设置画布背景为空
QColor const * conColor = new QColor(0,0,0,0);
m_pCanvas->setCanvasColor(*conColor);
显示效果:
这里有个奇怪点是为什么setCanvasColor的传入参数是引用。如果使用QColor 成员对象传入,函数结束不就被释放了么?所以这里给入参数必须是指针new出来的对象。
到此,所需的功能已经全部实现。关于图像的旋转和缩放均由QGraphicsItem控件控制。
最后的问题
在设置CanvasColor时发现,在透明度同为0的情况下,RGB值还是会对Canvas图像显示有影响。
//设置画布背景为空 CanvasColor默认值为QColor(255,255,255,255)
QColor const * conColor = new QColor(255,255,255,0);
m_pCanvas->setCanvasColor(*conColor);
RGB三值为255,透明度0时的图像:
RGB三值为0,透明度为0时的图像:
RGB值为255时,矢量图层边缘显示有异常,为0时就不会。具体原因还不明确。