首页 > 其他分享 >PyQGIS笔记

PyQGIS笔记

时间:2024-04-15 17:15:50浏览次数:22  
标签:layer self feature 笔记 PyQGIS mapCanvas symbol def

PyQGIS笔记

添加栅格
PROJECT = QgsProject.instance()
rlayer = QgsRasterLayer(file_path, name)
if not rlayer.isValid():
QMessageBox.information(self, '信息', '图像图层加载失败!')
else:
PROJECT.addMapLayer(rlayer) # 将图层添加到mapcanvas以及目录树根节点,并可以通过目录树进行控制
   # PROJECT.addMapLayer(rlayer, False) # 将图层添加到mapcanvas,但不能通过目录树进行控制
向根节点添加图层组
root = PROJECT.layerTreeRoot()
root.addGroup('aa')
根据名称查询图层组
group1 = root.findGroup('aa') # 获取名字为aa的图层组
group2 = group1.findGroup('bb')  # 获取aa图层组下的bb图层组
向图层组图层,并加载到mapcanvas中
group2.addLayer(rlayer)
PROJECT.addMapLayer(rlayer, False)  # 添加图层到canvas中,但不添加到TOC中
添加矢量
# 加载矢量图层到根节点和mapcanvas中
vlayer = QgsVectorLayer(file_path, name)
PROJECT.addMapLayer(vlayer)

# 加载矢量图层到指定图层组和mapcanvas中
group2.addLayer(vlayer)
PROJECT.addMapLayer(vlayer, False)
缩放到全图
self.mapCanvas = QgsMapCanvas(self)
def zoomToMap(self):
   '''缩放到全图'''
   self.mapCanvas.zoomToFullExtent()
   self.mapCanvas.enableAntiAliasing(True)
拉框放大
class ZoomInTool(QgsMapToolZoom):
   '''拉框放大'''
   def __init__(self, mapCanvas):
       super(ZoomInTool, self).__init__(mapCanvas, False)
       self.mapCanvas = mapCanvas
       self.rubberBand = QgsRubberBand(mapCanvas, QgsWkbTypes.PolygonGeometry)
       self.rubberBand.setColor(QColor(0, 0, 255, 100))
       self.rubberBand.setWidth(1)
       self.reset()

   def reset(self):
       '''重置拉框放大的参数'''
       self.startPoint = self.endPoint = None
       self.isPressed = False
       self.rubberBand.reset(QgsWkbTypes.PolygonGeometry)

   # 鼠标按下事件,获取起始坐标
   def canvasPressEvent(self, e):
       self.startPoint = self.toMapCoordinates(e.pos())
       self.endPoint = self.startPoint
       self.showRect(self.startPoint, self.endPoint)
       self.isPressed =True

   # 鼠标松开事件
   def canvasReleaseEvent(self, e):
       self.isPressed = False
       x = e.pos().x()
       y = e.pos().y()
       r = self.getRectangle()
       self.mapCanvas.setExtent(r) # 将绘制的矩形范围赋给当前画布即可实现拉框放大
       self.mapCanvas.refresh()    # 刷新当前画布
       self.reset()

   def canvasMoveEvent(self, e):
       if not self.isPressed:
           return
       self.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():
           return

       point1 = 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)
       self.rubberBand.show()

   def getRectangle(self):
       '''判断是否为矩形拉框,并获取矩形范围'''
       if self.startPoint is None or self.endPoint is None:
           return None
       elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y() == self.endPoint.y():
           return None
       return QgsRectangle(self.startPoint, self.endPoint)

   def deactivate(self):
       super(ZoomInTool, self).deactivate()
       self.deactivated.emit()
       self.reset()
创建点shp矢量
def createPointShp(self, name_path, name):
   '''创建点shp'''
   fields = QgsFields()
   fields.append(QgsField("类型", QVariant.String))
   fields.append(QgsField("节点数", QVariant.String))
   """创建一个矢量文件编写器的实例,它将创建矢量文件
  参数:
  1. 新文件的路径(如果已存在则失败)
  2. 属性编码
  3. 字段映射
  4. 几何类型 - WKBTYPE枚举
  5. 图层的空间参考(QgsCoordinateReferenceSystem的实例) - 可选
  6. 输出文件的驱动程序名称"""
   writer = QgsVectorFileWriter(name_path, "GBK", fields, QgsWkbTypes.Point, driverName = "ESRI  Shapefile") # GBK支持中文,UTF-8不支持中文
   # 删除writer以将要素保存到磁盘
   del writer
创建线shp矢量
def createLineShp(self, name_path, name):
   '''创建线shp'''
   fields = QgsFields()
   fields.append(QgsField("类型", QVariant.String))
   fields.append(QgsField("长度(m)", QVariant.String))
   writer = QgsVectorFileWriter(name_path, "GBK", fields, QgsWkbTypes.LineString, driverName="ESRI  Shapefile")
   del writer
创建面shp矢量
def createPolygonShp(self, name_path, name):
   '''创建面shp'''
   fields = QgsFields()
   fields.append(QgsField("类型", QVariant.String))
   fields.append(QgsField("面积(m2)", QVariant.String))

   writer = QgsVectorFileWriter(name_path, "GBK", fields, QgsWkbTypes.Polygon, driverName = "ESRI  Shapefile")
   del writer
点shp符号化(默认图形)
# self.shape:'circle'(圆形填充)self.color:QColor(255, 0, 255, 255)self.size:3
symbol = QgsMarkerSymbol.createSimple({'name': self.shape, 'color': self.color, 'size': self.size})
renderer = QgsSingleSymbolRenderer(symbol)
self.layer.setRenderer(renderer) # self.layer指需要符号化的图层
self.layer.triggerRepaint()
点shp符号化(svg填充)
svg = QgsSvgMarkerSymbolLayer(self.svgPath)  # 加载SVG的路径
# svg.setSize(svg_size) # 设置大小
symbol = QgsMarkerSymbol()
symbol.appendSymbolLayer(svg)  # 添加SVG的标记
symbol.deleteSymbolLayer(0)  # 删除默认的原始标记
renderer = QgsSingleSymbolRenderer(symbol)
self.layer.setRenderer(renderer)
self.layer.triggerRepaint()
线shp符号化
symbol = QgsLineSymbol.createSimple({'color': 'red'})  # 'color': '0,128,0,255'
symbol.setColor(self.color)  # 设置线颜色
symbol.setWidth(self.shp_width)  # 设置线宽度
renderer = QgsSingleSymbolRenderer(symbol)
self.layer.setRenderer(renderer)
self.layer.triggerRepaint()
面shp符号化(图片填充)
image = QgsRasterFillSymbolLayer(self.fillImagePath)
symbol = QgsFillSymbol()   # 填充符号
symbol.appendSymbolLayer(image)

symbol.setOpacity(0.5) # 设置填充图片透明度
symbol.setColor(QColor(2555,255,255,150))

# self.layer.renderer().symbol().symbolLayer(0).setStrokeStyle(Qt.SolidLine)
renderer = QgsSingleSymbolRenderer(symbol)
self.layer.setRenderer(renderer)
self.layer.triggerRepaint()
面shp符号化(纯色填充)
edge = QgsSimpleFillSymbolLayer()
edge.setStrokeStyle(self.strokeStyleList[0])  # 设置边框线型
edge.setStrokeColor(self.strokeStyleList[1])  # 设置边框颜色
edge.setStrokeWidth(self.strokeStyleList[2])  # 设置边框宽度

symbol = QgsFillSymbol()
symbol.changeSymbolLayer(0, edge)
symbol.setOpacity(0.5) # 设置填充透明度
symbol.setColor(self.fill_color)
renderer = QgsSingleSymbolRenderer(symbol)
self.layer.setRenderer(renderer)
self.layer.triggerRepaint()
为面图层添加一个新要素并设置要素属性信息
feature = QgsFeature(self.layer.fields())  # 为指定shp添加多边形要素
# self.points:QgsPointXY
feature.setGeometry(QgsGeometry.fromMultiPolygonXY([[self.points]]))
# 属性与图层属性表字段数量对应
feature.setAttributes(['aa', 'bb'])
(res, outFeatures) = self.layer.dataProvider().addFeatures([feature])
为线图层添加一个新要素并设置要素属性信息
feature = QgsFeature()
feature.setGeometry(QgsGeometry.fromMultiPolylineXY([self.points]))

feature.setAttributes(['aa', 'bb'])
(res, outFeatures) = self.layer.dataProvider().addFeatures([feature])
为点图层添加一个新要素并设置要素属性信息
feature = QgsFeature(self.layer.fields())
feature.setAttributes(['aa', 'bb'])
feature.setGeometry(QgsGeometry.fromPointXY(self.point))
(res, outFeatures) = self.layer.dataProvider().addFeatures([feature])
点、面文字标注
class DrawWordsLabel():
   def __init__(self, mapCanvas, layer):
       self.mapCanvas = mapCanvas
       self.layer = layer

   def defineLabels(self):
       '''点、面文字标注'''
       mark = QgsPalLayerSettings()
       mark.drawLabels = True;
       mark.fieldName = "aa"  # 用self.layer的aa字段名标注
       mark.centroidWhole = True  # 设置位置参考的中心点
       mark.placement= QgsPalLayerSettings.OverPoint
       mark.yOffset = 3

       format = QgsTextFormat()
       format.setSize(10)
       font = QFont()
       font.setFamily("微软雅黑")
       format.setFont(font)
       format.setColor(QColor(255, 255, 0))
       mark.setFormat(format)

       self.layer.setLabeling(QgsVectorLayerSimpleLabeling(mark))
       self.layer.setLabelsEnabled(True)
       self.mapCanvas.refresh()
线文字注记
def drawingAnnotationText(self, point, words):
   '''线文字标注(使用注记)'''
   text_annotation = QgsTextAnnotation(self.mapCanvas)
   # 设置注记填充符号
   edge = QgsSimpleFillSymbolLayer()
   edge.setStrokeStyle(Qt.DashLine)  # 设置边框线型
   edge.setStrokeColor(QColor(0, 0, 0, 0))  # 设置边框颜色(透明)
   edge.setStrokeWidth(0.1)  # 设置边框宽度

   symbol = QgsFillSymbol()
   symbol.changeSymbolLayer(0, edge)
   symbol.setColor(QColor(0, 0, 0, 0)) # 填充颜色为透明

   text_annotation.setFillSymbol(symbol)

   # 设置点符号类型(透明)
   markSymbol = QgsMarkerSymbol.createSimple({'name': 'circle', 'color': QColor(0, 0, 0, 0), 'outline_color': QColor(0, 0, 0, 0)})
   text_annotation.setMarkerSymbol(markSymbol)

   text_annotation.setMapPosition(point)

   text_annotation.setFrameOffsetFromReferencePointMm(QPointF(0.1,0.1))

   text_document = QTextDocument()
   html_content = words
   # #FFFF00:黄色 = QColor(255, 255, 0)
   font_color, font_family, font_size = "#FFFF00", "微软雅黑", 13
   text_document.setHtml('<font style="color:' + font_color +
                         "; font-family:" + font_family + "; font-size: " +
                         str(font_size) + 'px">' + html_content + "</font>")
   text_annotation.setDocument(text_document)
   # b = text_annotation.mapPosition()

   text_annotation.setMapLayer(self.layer)
   # text_annotation.setAssociatedFeature(feature)
   # text_annotation.setVisible(isVisible)

   QgsMapCanvasAnnotationItem(text_annotation, self.mapCanvas)
   # mapCanvasAnnotationItem.annotation().setVisible(False)
   # a = self.mapCanvas.scene().items()
   # self.mapCanvas.scene().removeItem()
   self.mapCanvas.refresh()
GDAL无损压缩压缩tif
def compressTif(self, orginImagePath, dstImagePath):
   dataset = gdal.Open(orginImagePath)
   driver = gdal.GetDriverByName('GTiff')
   # strict=1表示和原来的影像严格一致,0表示可以有所调整
   # callback为进度回调函数
   # PACKBITS快速无损压缩,基于流
   # LZW针对像素点,黑白图像效果好
   driver.CreateCopy(dstImagePath, dataset, strict=1, options=["TILED=YES", "COMPRESS=LZW"])
   del dataset
识别要素
class featureIdentifyTool(QgsMapToolIdentify):
   resultSignal = pyqtSignal(list, list)  # 定义一个信号用于接受两个list的数据
   def __init__(self, mapCanvas):
       super(featureIdentifyTool, self).__init__(mapCanvas)
       self.mapCanvas = mapCanvas
       self.rubberBand = QgsRubberBand(mapCanvas, True)
       self.rubberBand.setColor(QColor(255, 0, 0, 100))
       self.rubberBand.setWidth(1)
       self.reset()
       self.isPressed = False

   def setLayers(self, layers):
       '''初始化识别的图层'''
       self.identifyLayers = layers

   def reset(self):
       '''重置'''
       self.startPoint = self.endPoint = None
       self.isPressed = False
       self.rubberBand.reset(True)

   def canvasReleaseEvent(self, e):
       '''画布上鼠标松开事件,识别要素'''
       self.isPressed = False

       x = e.pos().x()
       y = e.pos().y()
       try: # 添加异常处理信息。防止识别其他图层时报错导致程序退出
           results = self.identify(x, y, self.IdentifyMode.DefaultQgsSetting, self.identifyLayers, self.Type.VectorLayer)
       except:
           QMessageBox.information(QDialog(), '错误信息', '只能删除病害数据,请重新选择!')
           return

       resultLayers = []
       resultFeatures = []
       for identifyLayer in self.identifyLayers:
           if identifyLayer.type() == QgsMapLayerType.VectorLayer:
               identifyLayer.removeSelection()
               features = []
               resultFeatureIds = []
               for result in results:
                   if result.mLayer.name() == identifyLayer.name():
                       feature = result.mFeature
                       resultFeatureIds.append(feature.id())
                       features.append(feature)
                   else:
                       continue
               if len(resultFeatureIds) > 0:
                   identifyLayer.selectByIds(resultFeatureIds)
                   resultLayers.append(identifyLayer)
                   resultFeatures.append(features)
       self.reset()
       self.resultSignal.emit(resultLayers, resultFeatures)  # 向信号提交信息
       
   def deactivate(self):
       super(featureIdentifyTool, self).deactivate()
       self.deactivated.emit()
       self.reset()
def actionIdentifyTriggered(self):
   '''识别'''
   self.mapTool = featureIdentifyTool(self.mapCanvas)

   layers = PROJECT.mapLayers()  # 获取所有图层(字典)
   self.mapTool.setLayers(layers.values())
   self.mapTool.resultSignal.connect(self.addIdentifyResultItem)  # 信号
   self.mapCanvas.setMapTool(self.mapTool)
def addIdentifyResultItem(self, layers, features):
   '''要素信息框'''
   for i in range(0, len(layers)):
       # CustomMenuProvider.openAttributeDialog(self, layers[i])
       for feature in features[i]:
           infosTable = DiseaseInfosTable(feature)  # 填写表头内容
           infosTable.inputTableData()
class DiseaseInfosTable(QDialog, Ui_featureInTableDialog):
   def __init__(self, feature):
       super(DiseaseInfosTable, self).__init__()
       self.setupUi(self)
       self.feature = feature

   def inputTableData(self):
       '''设置属性表表头及表格数据'''
       if self.feature.geometry().type() == QgsWkbTypes.PointGeometry:  # 如果是点要素, 直接设置表头内容
           self.tableWidget.setVerticalHeaderLabels(self.feature.fields().names())
           count = 0
           for attr in self.feature.attributes():
               # 位置为第0行,第0列,后面为QTableWidgetItem对象,可以为str类型,int类型
               self.tableWidget.setItem(count, 0, QTableWidgetItem(attr)) # 调用setTextAlignment()方法,设置文本居中显示
               count = count + 1

       elif self.feature.geometry().type() == QgsWkbTypes.LineGeometry:  # 如果是线要素,增加一列再设置表头内容
           orgin_row_num = self.tableWidget.rowCount()
           cur_row_num = orgin_row_num + 1
           self.tableWidget.setRowCount(cur_row_num)  # 将当前的总行数加1
           self.tableWidget.setVerticalHeaderLabels(self.feature.fields().names())
           count = 0
           for attr in self.feature.attributes():
               self.tableWidget.setItem(count, 0, QTableWidgetItem(attr))
               count = count+1

       elif self.feature.geometry().type() == QgsWkbTypes.PolygonGeometry:  # 如果是面要素,增加一列再设置表头内容
           orgin_row_num = self.tableWidget.rowCount()
           cur_row_num = orgin_row_num + 1
           self.tableWidget.setRowCount(cur_row_num)  # 将当前的总行数加1
           self.tableWidget.setVerticalHeaderLabels(self.feature.fields().names())
           count = 0
           for attr in self.feature.attributes():
               self.tableWidget.setItem(count, 0, QTableWidgetItem(attr))
               count = count + 1
       else:
           return
       self.show()
       self.exec_()  # show()与exec_()同时同时使用:窗口停靠,可弹出多个相同的窗体
选择要素并删除
def actionSelectAndDeleteFeatureTriggered(self):
   '''选择要素并删除事件'''
   self.mapTool = featureIdentifyTool(self.mapCanvas)

   layers = PROJECT.mapLayers()  # 获取所有图层(字典)
   self.mapTool.setLayers(layers.values())
   self.mapTool.resultSignal.connect(self.selectAndDeleteFeature)  # 信号
   self.mapCanvas.setMapTool(self.mapTool)

def selectAndDeleteFeature(self, layers, features):
   '''选择要素并删除的接收信号'''
   pos = {}
   for item in self.mapCanvas.annotationItems():
       annotationPosition = item.annotation().mapPosition()
       pos[annotationPosition] = item

   for i in range(0, len(layers)):
       # layerPath = layers[i].source()
       layerPath = layers[i].dataProvider().dataSourceUri();# 获取图层路径
       for feature in features[i]:
           if feature.geometry().type() == QgsWkbTypes.LineGeometry:  # 如果是线要素则还需要删除注记
               geom = feature.geometry()
               ori_pts = []
               if geom.isMultipart():  # "MultiPart"
                   for part in geom.parts():
                       pts = part.points()
                       for point in pts:
                           ori_pts.append(point)
               else:  # "Simple"
                   ori_pts = geom.get().points()
               point = ori_pts[len(ori_pts) - 1]  # 注记文字位置为线要素最后一个点的位置
               pointXY = QgsPointXY(point.x(), point.y())
               annotationItem = pos[pointXY]
               annotationItem.annotation().setVisible(False)
           layers[i].dataProvider().deleteFeatures([feature.id()])  # 如果是点、线、面要素均需要删除
取消当前地图工具
mapTool = self.mapCanvas.mapTool()
self.mapCanvas.unsetMapTool(mapTool)  # 销毁当前地图工具
实时显示坐标
def showLngLat(self, point):
   x = point.x()
   y = point.y()
   self.statusbar.showMessage(f'X:{x}, Y:{y}')
self.mapCanvas.xyCoordinates.connect(self.showLngLat)

标签:layer,self,feature,笔记,PyQGIS,mapCanvas,symbol,def
From: https://www.cnblogs.com/deng-notebook/p/18136435

相关文章

  • JWT 前端笔记
    JWTJTW全称JsonWebToken没有JWT的时候,服务端给客户端发送信息,客户端返回信息,通常存在cookie或localstorage,不过服务器无法信任这个信息传给服务器的信息可能是被篡改的,也可能是被伪造的JWT的雏形原始信息和密钥一样的情况下才能生成相同签名info.签名返回后,服务器用相......
  • 算法相关读书笔记
    由于算法导论中涉及大量数学公式,在腾讯文档才能友好的展示,因此下面分享的为腾讯文档的链接个人能力有限,可能有的理解是错误的,请谅解,仅供分享和参考【腾讯文档】算法导论1~3部分【腾讯文档】算法导论第4~5部分【腾讯文档】算法导论第6部分22~24章【腾讯文档】算法导论第6部分2......
  • Java并发编程实战读书笔记
    1.线程池模型    netty实战中讲到的线程池模型可以描述为:1.从线程池中选择一个空间的线程去执行任务,2.任务完成时,把线程归还给线程池。这个模型与连接池类似。    根据jdk源码的研究,具体的实现模型是,线程池ThreadPoolExecutor中有一个静态内部类Worker,使用装饰器模式扩......
  • Min_25 筛学习笔记
    MyBlogs杜教筛是一种能在\(\mathcalO(n^{\frac23})\)的时间复杂度内求积性函数前缀和的筛法。虽然复杂度比较优秀,但是被筛的积性函数需要满足特殊性质。Min_25筛由Min_25发明,相对更通用,其时间复杂度为\(\mathcalO(\frac{n^{\frac34}}{\logn})\)。首先构造一个完......
  • ROS笔记[1]-搭建Gazebo仿真环境
    摘要在阿里无影云电脑Ubuntu20.04上搭建ROS1-Noetic环境及Gazebo环境;搭建XTDrone仿真环境.关键信息系统:Ubuntu20.04ROS1版本:NoeticGazebo版本:9原理简介阿里无影云电脑[https://www.aliyun.com/product/ecs][https://wuying.aliyun.com/]无影云电脑(WUYINGWorkspac......
  • 「二分图」笔记
    二分图同时满足不存在奇数环和染色法不矛盾。二分图的判定:染色法#include<bits/stdc++.h>usingnamespacestd;constintN=1e3+10,M=2e6+10;struct{ intto,next;}e[M];inttop,h[N],color[N],n,m;voidadd(intx,inty){ e[++top]={y,h[x]};......
  • 「树链剖分」 学习笔记
    一,树链剖分的思想与概述正如其名,树链剖分用于将树剖分成若干条链的形式,以维护树上路径的信息,其中剖分出的链有多种形式,最常见的是重链,还有长链或更多其它的链。其中剖分出的链为重链时,就引出了下文的主角「重链剖分」。重链剖分能保证划分出的每条重链上的节点DFS序连续,因此......
  • day06_我的Java学习笔记 (综合应用专题课)
    专题课(综合案例)案例一:买飞机票案例二:找素数上述老师代码有点问题,即:j<i/2;应为j<=i/2;见如下判断:其实出问题的点,只会在i=4时,因为当i=4时,j<i/2:不成立,直接跳过该循环,执行步骤3的操作了。(当范围不是101-200,而是包含了4,则会出现上述的现象,因4不满......
  • day04_我的Java学习笔记 (数组的静态初始化、数组的动态初始化,debug调试等)
    1.数组1.1数组的定义那python怎么定义数组的呢?Java:String[]names={"zhangsan","lisi","wangwu"}Python:names=["zhangsan","lisi","wangwu"]在python中,列表可以存储不同类型的数据,而在Java中,数组只能存储相同类型的数据。1......
  • day02_我的Java学习笔记 (类型转换、+做连接符、变量自增自减运算、三元运算符、键盘
    Java语言基础知识1.类型转换1.1自动类型转换1.2表达式的自动类型转换1.3强制类型转换这里得出的结果为啥是-36呢???后面高级篇再细讲。2.运算符2.1算数运算符2.1.1基本算数运算符2.1.2案例:数值拆分2.2+符号做连接符【思考1】:a+'a'为啥......