QGIS自定义地图工具
官方示例
首先看一下官方文档中的矩形工具源码:
class RectangleMapTool(QgsMapToolEmitPoint):def __init__(self, canvas):self.canvas = canvasQgsMapToolEmitPoint.__init__(self, self.canvas)self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)self.rubberBand.setColor(QColor(255, 0, 0, 100))self.rubberBand.setWidth(1)self.reset()def reset(self):self.startPoint = self.endPoint = Noneself.isEmittingPoint = Falseself.rubberBand.reset(True)def canvasPressEvent(self, e):self.startPoint = self.toMapCoordinates(e.pos())self.endPoint = self.startPointself.isEmittingPoint = Trueself.showRect(self.startPoint, self.endPoint)def canvasReleaseEvent(self, e):self.isEmittingPoint = Falser = self.rectangle()if r is not None:print("Rectangle:", r.xMinimum(), r.yMinimum(), r.xMaximum(), r.yMaximum())def canvasMoveEvent(self, e):if not self.isEmittingPoint:returnself.endPoint = self.toMapCoordinates(e.pos())self.showRect(self.startPoint, self.endPoint)def showRect(self, startPoint, endPoint):self.rubberBand.reset(QgsWkbTypes.PolygonGeometry)if startPoint.x() == endPoint.x() or startPoint.y() == endPoint.y():returnpoint1 = QgsPointXY(startPoint.x(), startPoint.y())point2 = QgsPointXY(startPoint.x(), endPoint.y())point3 = QgsPointXY(endPoint.x(), endPoint.y())point4 = QgsPointXY(endPoint.x(), startPoint.y())self.rubberBand.addPoint(point1, False)self.rubberBand.addPoint(point2, False)self.rubberBand.addPoint(point3, False)self.rubberBand.addPoint(point4, True) # true to update canvasself.rubberBand.show()def rectangle(self):if self.startPoint is None or self.endPoint is None:return Noneelif self.startPoint.x() == self.endPoint.x() or self.startPoint.y() == self.endPoint.y():return Nonereturn QgsRectangle(self.startPoint, self.endPoint)def deactivate(self):super(RectangleMapTool, self).deactivate()self.deactivated.emit()self.reset()
文档中的有些语法还是QGIS2的写法,比如QGis.Polygon在QGIS3中应该用QgsWkbTypes.PolygonGeometry、QgsPoint在QGIS3中对应QgsPointXY,这里我已经做了更改。
源码解析
- 首先继承QgsMapToolEmitPoint类
- 重写canvasPressEvent、canvasReleaseEvent、canvasMoveEvent
- 使用QgsRubberBand渲染绘制的图形(支持PolygonGeometry、PointGeometry、LineGeometry)
具体思路是当鼠标按压画布时,触发canvasPressEvent,得到第一个点self.startPoint,鼠标拖动后触发canvasMoveEvent,得到第二个点,使用这两个点绘制一个矩形,鼠标释放时触发canvasReleaseEvent,结束绘制。
注:每次绘制前都要清除之前的图形,否则会出现拖影,使用rubberBand的reset方法:
self.rubberBand.reset(QgsWkbTypes.PolygonGeometry)
实现多边形绘制
QGIS自带的矢量编辑工具中已经有多边形绘制工具,如下:
接下来我们添加一个自动垂直绘制的功能,源码如下:
class PolygonMapTool(QgsMapToolEmitPoint):def __init__(self, canvas):self.canvas = canvasQgsMapToolEmitPoint.__init__(self, self.canvas)self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)self.rubberBand.setColor(QColor(255, 0, 0, 100))self.rubberBand.setWidth(1)self.reset()def reset(self):self.is_start = False # 开始绘图self.is_vertical = False # 垂直画线self.cursor_point = Noneself.points = []self.rubberBand.reset(True)def canvasPressEvent(self, event):if event.button() == Qt.LeftButton:self.points.append(self.cursor_point)self.is_start = Trueelif event.button() == Qt.RightButton:# 右键结束绘制if self.is_start:self.is_start = Falseself.cursor_point = Noneself.show_polygon()self.points = []else:passelse:passdef canvasMoveEvent(self, event):self.cursor_point = event.mapPoint()if not self.is_start:returnself.show_polygon()def show_polygon(self):self.rubberBand.reset(QgsWkbTypes.PolygonGeometry) # 防止拖影first_point = self.points[0]last_point = self.points[-1]self.rubberBand.addPoint(first_point, False)for point in self.points[1:-1]:self.rubberBand.addPoint(point, False)if self.cursor_point:self.rubberBand.addPoint(QgsPointXY(last_point.x(), last_point.y()), False)else:self.rubberBand.addPoint(QgsPointXY(last_point.x(), last_point.y()), True)self.rubberBand.show()return# 光标所在点if self.is_vertical and len(self.points) >= 2:countdown_second_point = self.points[-2]cursor_point_x = self.cursor_point.x()cursor_point_y = self.cursor_point.y()diff_x = int(math.fabs(last_point.x() - countdown_second_point.x()))diff_y = int(math.fabs(last_point.y() - countdown_second_point.y()))if diff_x > diff_y:# 最后一条线的x,y差值比较cursor_point_x = equation(countdown_second_point.x(), countdown_second_point.y(), last_point.x(),last_point.y(), self.cursor_point.y(), solve_type='x')else:cursor_point_y = equation(countdown_second_point.x(), countdown_second_point.y(), last_point.x(),last_point.y(), self.cursor_point.x(), solve_type='y')_cursor_point = QgsPointXY(cursor_point_x, cursor_point_y)self.cursor_point = _cursor_pointself.rubberBand.addPoint(self.cursor_point, True)self.rubberBand.show()def deactivate(self):super(PolygonMapTool, self).deactivate()self.deactivated.emit()self.reset()
其中equation算法是自己实现的,原理就是直角三角形直角边平方和等于斜边平方(),自行理解,使用到了sympy库(第一次使用,好强大。。。),源码如下:
def equation(x1, y1, x2, y2, f, solve_type='x'):'''已知两点坐标和第三个点x或y,求对应的y或x:param x1:第一个点x坐标:param y1:第一个点y坐标:param x2:第二个点x坐标:param y2:第二个点y坐标:param f:x或y的坐标值:param solve_type:'x'或'y',默认'x':return:'''if solve_type == 'x':x = symbols('x')y = fs = solve((x - x1) ** 2 + (y - y1) ** 2 - (x2 - x1) ** 2 - (y2 - y1) ** 2 - (x - x2) ** 2 - (y - y2) ** 2, x)return s[0]else:y = symbols('y')x = fs = solve((x - x1) ** 2 + (y - y1) ** 2 - (x2 - x1) ** 2 - (y2 - y1) ** 2 - (x - x2) ** 2 - (y - y2) ** 2, y)return s[0]
截图
矩形
多边形
QGIS自定义地图工具相关推荐
- DOTA无法加载服务器指定的地图,Dota2自定义地图工具怎么安装_Dota2自定义地图工具常见问题处理方法...
Dota 2 创意工坊工具的早期测试(Alpha)版本已经发布,如果你有新奇的想法可以使用工具开发制作自己的地图,为Dota 2再添砖瓦. 如果是抱着"玩"的心态小编建议就不要下载 ...
- OpenLayers 3自定义地图工具条(一)
对于一个WEB地图应用来说,地图工具条可以说是不可或缺的一个部分,但由于一些样式.功能往往并不能满足实际项目需要,所以仍要对此部分进行定制,从这里将说明如何利用Oplenayers 3根据项目要求做一 ...
- QGIS自定义符号的原理与实践——以北京市标准地图为例
01 符号概述 符号(Symbol)是地图和GIS的核心概念.QGIS使用渲染器(Renderer)完成图层在地图窗口中的绘制,即所谓的图层渲染.图层渲染之前需要告诉渲染器使用什么符号渲染图层,如果 ...
- power bi自定义地图_如何使用自定义形状图在Power BI中创建地理图
power bi自定义地图 介绍 (Introduction) This is the third article of a series dedicated to discovering geogr ...
- ROS自定义地图(CAD、手绘等)
0x00 概述 在前面的文章中,我们介绍如何自动导航时,都是基于使用gmapping或者hector_mapping创建的地图.当然使用其他的建图方法创建的地图也可以,但是目前为止,无论使用哪种建图方 ...
- echarts自定义地图总结(VUE)
需求: 全国地图中内蒙古地区分为蒙东.蒙西,河北省地区分为河北.冀北,需要自定义地图. 思路: 从json文件上做文章,例如整个中国地图的json里包含各个省的json,各个省包含各个市的json,以 ...
- 百度地图API详解之自定义地图类型
个人博客原文地址:http://www.jiazhengblog.com/blog/2011/10/08/422/ 今天的文章主要介绍如何利用地图API实现自定义地图. 百度地图API目前默认支持两种 ...
- php网页地图上自定义,如何添加在线自定义地图
在奥维互动地图浏览器中,除内置的在线地图外,用户还可以添加自定义地图,如在线电子地图和航拍图等,以满足用户对特定地图的需求. 1.正常添加在线电子地图的前提条件 (1)被添加的地图采用墨卡托投影方式, ...
- 手把手教你绘制自定义地图
1. 内容概述 自定义地图组件支持使用用户自己绘制的地图绑定和呈现数据. 我们可以直接在设计器中绘制自定义地图,只需导入底图图片,进行描边和调整标记点,即可使用. 如下图所示,我们根据一张商场的平面图 ...
- jvectormap的自定义地图和区域上色、图片标记
jvectormap的自定义地图和区域上色.图片标记 因为网上例子太少,上手实属不易,所以在这里跟大家分享一下我的使用! (第一次写,因为粘贴代码卡死几次,重写了几次,心累 ╥﹏╥-) 这里就简单的介 ...
最新文章
- python的cfg是什么模块_cfg4py:一个严肃的Python配置模块应有的风格-层级式、部署环境自适应、自动补全...
- 详解C++移动语义std::move()
- string index out of range_Java 12 骚操作, String居然还能这样玩!
- 一种同于计算机键盘的测试装置,一种计算机键盘按键测试装置
- 如何查看linux的版本?
- 一次简单的 JVM 调优,性能提升了15%
- Tomcat(二)环境变量配置
- Rhino导入Revit生成体量幕墙的方法和操作要点
- Cesium gltf(1.70)三维人物动画制作
- PC端 流光溢彩 Arduino
- U盘被写保护无法格式化(我用win10,同样成功格式化了U盘)
- 家用计算机音效部件图示,唱吧新版自定义音效设置方法(附上最佳音效设置参数图)...
- 服务器ip总是被封,怎么办?
- css学习记录第一天(选择器)
- java 将json转成utf 8_C# JSON转换以及编码转换
- html如何查看字体样式,css2.0文档查阅及字体样式
- 联想小新 win10电脑系统安装教程
- pip 下载安装包及依赖包 并安装
- java后台程序员转android 之《三B》 支付宝支付 client join server 及采坑记录
- cmake教程(cmake教程pdf)
热门文章
- 快来喝杯Java(初级第一章)
- 160页PPT神经网络图,颜色形状随意DIY
- newifi路由器 php,newifi路由器有线桥接教程
- 个人网页制作(教你制作简单网页)
- nginx日志中$request_body 十六进制字符(\\x22) 引号问题处理记录
- tmux的安装及用法
- 豫教科计算机资源管理教案,豫科版小学五年级上册信息技术教案(全册.doc
- php mcrypt blowfish,php加密算法blowfish
- Blender插件安装不显示问题
- FMI飞马网 | 人工智能/大数据/程序/语言/项目管理/机器学习/Python书籍免费赠书