社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

QGIS Python编程完成高级地理分析功能——以湖岸线样方生成为例

走天涯徐小洋地理数据科学 • 1 年前 • 436 次点击  


最近在出野外,遇到了一些样方划分的问题,常规的格网划分方法无法生成,这个时候怎么办呢,我在Kimi的帮助下,使用QGIS Python编程完成了一些高级的自定义地理分析功能。

问题

如何沿湖边划分50个网格?

问题分解

  1. 湖区范围提取
  2. 湖岸线提取
  3. 按湖岸线生成格网

湖区范围提取

湖区范围我使用了中科星图智脑引擎来完成。中科星图智脑引擎提供了非常方便的水体提取功能,能够很好地完成水体范围提取。

  • 星图地球主页:https://geovisearth.com/

星图地球智脑引擎提供了很多很方便的工具,再加上中科星图数据云提供的高分影像,可以很方便的完成一些水体提取工作。

选择水体提取工具
选择水体提取工具

处理速度非常快,提取完水体之后,把结果保存到云盘,然后去云盘中下载即可。保存可以直接保存为geojson格式,这样就能生成一个geojson文件,在QGIS中可以直接打开。

保存到云盘,然后就可以去云盘中下载水体提取结果
保存到云盘,然后就可以去云盘中下载水体提取结果

湖岸线提取

在QGIS中可以直接把湖区范围转为线,使用Polygons to lines工具。

QGIS里面的面转线工具
QGIS里面的面转线工具

但是发现这个转出来的线太复杂了,用来生成格网可能过于复杂,最终还是选择沿着湖边随便手画一条。

先创建一个gpkg数据库,方便存储矢量数据。然后右击,New Table,一个矢量线就相当于gpkg的一个新的表。

New Table,在gpkg数据库中创建一个新表
New Table,在gpkg数据库中创建一个新表

在这里我需要创建一个线矢量。

创建一个线矢量
创建一个线矢量

然后把这个线矢量拖到图层中,开始编辑

点击这个铅笔按钮,开始编辑
点击这个铅笔按钮,开始编辑

添加线要素,开始绘制,绘制完成后,再点击铅笔按钮,保存,停止编辑即可。

添加线要素
添加线要素

沿湖岸线生成样方

注意,我这个指令前提是已经跟Kimi进行了多轮有关QGIS的对话后才生成的。完整对话过程可以参考:

点击链接查看和 Kimi 的对话 https://www.kimi.com/share/d1psv64nvj4kt3e4p0mg

指令

Source H:/Lashihai/Lashihai.gpkg|layername=WaterLine

请帮我在这个线基础上,等距离生成50个点,然后在这50个点基础上,生成50个外接矩形,请完成Python代码

Kimi回答

下面给出一段可直接在 QGIS Python 控制台运行的完整脚本。
逻辑:

  1. 从线图层(WaterLine)中读取第一条线要素;
  2. 按线长 L 等距生成 50 个点(含起点,不含终点);
  3. 以每个点为中心,边长 s = L/50 生成正方形外接矩形;
  4. 输出结果到新的临时图层 “WaterLine_Grid50”。
# -*- coding: utf-8 -*-


    

"""
在 WaterLine 上按长度等距生成 50 个点,并以每个点为中心生成正方形外接矩形
"""


from qgis.core import (
    QgsProject, QgsVectorLayer, QgsFeature, QgsGeometry,
    QgsRectangle, QgsPoint, QgsField, QgsWkbTypes
)
from qgis.PyQt.QtCore import QVariant

# 1. 载入线图层
uri = r"H:/Lashihai/Lashihai.gpkg|layername=WaterLine"
line_lyr = QgsVectorLayer(uri, "WaterLine", "ogr")
ifnot line_lyr.isValid():
    raise RuntimeError("线图层加载失败!")

# 2. 取第一条线
line_feat = next(line_lyr.getFeatures())
line_geom = line_feat.geometry()
line_length = line_geom.length()

# 3. 计算正方形边长
side = line_length / 50.0
print(f"正方形边长:{side:.2f} 地图单位")

# 4. 创建输出图层
grid_lyr = QgsVectorLayer("Polygon?crs=" + line_lyr.crs().authid(),
                          "WaterLine_Grid50", "memory")
prov = grid_lyr.dataProvider()
prov.addAttributes([QgsField("id", QVariant.Int)])
grid_lyr.updateFields()

# 5. 生成 50 个点 → 50 个正方形
for i in range(50):
    # 等距点位置(0~49)
    dist = (i * line_length) / 50.0
    pt = line_geom.interpolate(dist).asPoint()          # QgsPointXY
    # 以该点为中心的正方形外接矩形
    xmin = pt.x() - side / 2.0
    xmax = pt.x() + side / 2.0
    ymin = pt.y() - side / 2.0
    ymax = pt.y() + side / 2.0
    rect_geom = QgsGeometry.fromRect(QgsRectangle(xmin, ymin, xmax, ymax))

    feat = QgsFeature()
    feat.setGeometry(rect_geom)
    feat.setAttributes([i])
    prov.addFeature(feat)

grid_lyr.updateExtents()
QgsProject.instance().addMapLayer(grid_lyr)
print("已生成 50 个正方形外接矩形并加载到地图。")

使用方法

  1. 打开 QGIS → 插件 → Python 控制台 (Ctrl+Alt+P)。
  2. 将上述代码整段粘贴并按回车即可。
如图所示,先打开控制台,然后点击Show Editor,把代码粘贴进去,运行
如图所示,先打开控制台,然后点击Show Editor,把代码粘贴进去,运行

这样就沿着湖岸线生成了样方。

样方生成结果
样方生成结果
更多GIS、遥感、R语言培训课程欢迎加入地理数据科学培训班:

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/184359