|
@@ -7,7 +7,11 @@ __copyright__ = '(C) 2024 by siwei'
|
|
__revision__ = '1.0'
|
|
__revision__ = '1.0'
|
|
|
|
|
|
import os
|
|
import os
|
|
|
|
+
|
|
|
|
+from PyQt5.QtCore import QVariant
|
|
|
|
+
|
|
from qgis.PyQt.QtCore import QCoreApplication
|
|
from qgis.PyQt.QtCore import QCoreApplication
|
|
|
|
+from qgis._core import QgsSpatialIndex, QgsField, QgsRectangle
|
|
from qgis.core import (QgsProcessing,
|
|
from qgis.core import (QgsProcessing,
|
|
QgsVectorLayer,
|
|
QgsVectorLayer,
|
|
QgsFeatureSink,
|
|
QgsFeatureSink,
|
|
@@ -50,38 +54,11 @@ class FishNetProcessingAlgorithm(QgsProcessingAlgorithm):
|
|
extension='shp' # 设置文件过滤器,只允许选择shp文件
|
|
extension='shp' # 设置文件过滤器,只允许选择shp文件
|
|
))
|
|
))
|
|
|
|
|
|
- # 定义检查一个网格单元格上下左右是否有相邻的网格单元
|
|
|
|
- def check_neighbors(self, feature, layer):
|
|
|
|
- # 获取当前单元格的几何
|
|
|
|
- geom = feature.geometry()
|
|
|
|
- bbox = geom.boundingBox() # 获取网格单元的包围盒(bounding box)
|
|
|
|
- # 提取当前网格的中心点位置
|
|
|
|
- center_x, center_y = geom.centroid().asPoint()
|
|
|
|
- # 定义上下左右偏移量(单位为网格的大小,假设网格是正方形或矩形)
|
|
|
|
- tolerance = 1e-5 # 设定一个微小的容忍误差,用于比较几何形状
|
|
|
|
- neighbors = {
|
|
|
|
- 'north': None,
|
|
|
|
- 'south': None,
|
|
|
|
- 'west': None,
|
|
|
|
- 'east': None
|
|
|
|
- }
|
|
|
|
- for other_feature in layer.getFeatures():
|
|
|
|
- if other_feature.id() == feature.id():
|
|
|
|
- continue # 跳过自己
|
|
|
|
- other_geom = other_feature.geometry()
|
|
|
|
- # 检查上、下、左、右的邻接
|
|
|
|
- if abs(center_y - other_geom.centroid().asPoint().y()) < tolerance and other_geom.centroid().asPoint().x() < center_x:
|
|
|
|
- neighbors['west'] = other_feature
|
|
|
|
- elif abs(
|
|
|
|
- center_y - other_geom.centroid().asPoint().y()) < tolerance and other_geom.centroid().asPoint().x() > center_x:
|
|
|
|
- neighbors['east'] = other_feature
|
|
|
|
- elif abs(
|
|
|
|
- center_x - other_geom.centroid().asPoint().x()) < tolerance and other_geom.centroid().asPoint().y() < center_y:
|
|
|
|
- neighbors['south'] = other_feature
|
|
|
|
- elif abs(
|
|
|
|
- center_x - other_geom.centroid().asPoint().x()) < tolerance and other_geom.centroid().asPoint().y() > center_y:
|
|
|
|
- neighbors['north'] = other_feature
|
|
|
|
- return neighbors
|
|
|
|
|
|
+ def cacl(self, neighbors):
|
|
|
|
+ if len(neighbors) == 0:
|
|
|
|
+ return "自由"
|
|
|
|
+ else:
|
|
|
|
+ return None
|
|
|
|
|
|
# 执行
|
|
# 执行
|
|
def processAlgorithm(self, parameters, context, feedback):
|
|
def processAlgorithm(self, parameters, context, feedback):
|
|
@@ -90,26 +67,76 @@ class FishNetProcessingAlgorithm(QgsProcessingAlgorithm):
|
|
if not os.path.exists(shp_file_path):
|
|
if not os.path.exists(shp_file_path):
|
|
feedback.reportError(f"指定的文件路径 {shp_file_path} 不存在!")
|
|
feedback.reportError(f"指定的文件路径 {shp_file_path} 不存在!")
|
|
return {}
|
|
return {}
|
|
-
|
|
|
|
# 加载Shapefile为QgsVectorLayer
|
|
# 加载Shapefile为QgsVectorLayer
|
|
layer = QgsVectorLayer(shp_file_path, "Vector Layer", 'ogr')
|
|
layer = QgsVectorLayer(shp_file_path, "Vector Layer", 'ogr')
|
|
- print(layer)
|
|
|
|
layer.startEditing()
|
|
layer.startEditing()
|
|
- # 获取所有要素(假设网格单元是矩形或正方形)
|
|
|
|
- features = list(layer.getFeatures())
|
|
|
|
- # 遍历所有网格单元,检查相邻的网格
|
|
|
|
- for feature in features:
|
|
|
|
- neighbors = self.check_neighbors(feature, layer)
|
|
|
|
- for direction, neighbor in neighbors.items():
|
|
|
|
- if neighbor:
|
|
|
|
- print(f"")
|
|
|
|
- else:
|
|
|
|
- # 更新字段值
|
|
|
|
- feature.setAttribute(direction, "自由")
|
|
|
|
- # 更新要素
|
|
|
|
- layer.updateFeature(feature)
|
|
|
|
|
|
+ grid_width = 100 # 替换为实际网格宽度
|
|
|
|
+ grid_height = 100 # 替换为实际网格高度
|
|
|
|
+ if layer.featureCount() > 0:
|
|
|
|
+ # 获取第一个要素
|
|
|
|
+ feature = next(layer.getFeatures())
|
|
|
|
+ geom = feature.geometry()
|
|
|
|
+ # 获取要素的边界矩形(bounding box)
|
|
|
|
+ bounds = geom.boundingBox()
|
|
|
|
+ # 计算宽度和高度
|
|
|
|
+ grid_width = bounds.width()
|
|
|
|
+ grid_height = bounds.height()
|
|
|
|
+ print(f"网格宽度:{grid_width}")
|
|
|
|
+ print(f"网格高度:{grid_height}")
|
|
|
|
+ else:
|
|
|
|
+ print("图层没有任何要素!")
|
|
|
|
+ return {
|
|
|
|
+ "状态": "图层没有任何要素!"
|
|
|
|
+ }
|
|
|
|
+ # 为图层添加邻居字段
|
|
|
|
+ layer.startEditing()
|
|
|
|
+ for field in ["east", "west", "south", "north"]:
|
|
|
|
+ if field not in [f.name() for f in layer.fields()]:
|
|
|
|
+ layer.dataProvider().addAttributes([QgsField(field, QVariant.String)])
|
|
|
|
+ layer.updateFields()
|
|
|
|
+ # 创建空间索引
|
|
|
|
+ spatial_index = QgsSpatialIndex(layer)
|
|
|
|
+ # 设置误差值 过滤掉仅仅是边线重叠的数据
|
|
|
|
+ tolerance = grid_width if grid_width < grid_height else grid_height
|
|
|
|
+ tolerance = tolerance / 5
|
|
|
|
+ print(f"网格边界容差:{tolerance}")
|
|
|
|
+ # 遍历图层中的所有要素
|
|
|
|
+ for feature in layer.getFeatures():
|
|
|
|
+ geom = feature.geometry()
|
|
|
|
+ extent = geom.boundingBox()
|
|
|
|
+ # 获取网格宽度和高度
|
|
|
|
+ width = grid_width
|
|
|
|
+ height = grid_height
|
|
|
|
+ # 构造东西南北方向的矩形
|
|
|
|
+ west_extent = QgsRectangle(extent.xMinimum() - width + tolerance, extent.yMinimum() + tolerance,
|
|
|
|
+ extent.xMinimum() - tolerance,
|
|
|
|
+ extent.yMaximum() - tolerance)
|
|
|
|
+ east_extent = QgsRectangle(extent.xMaximum() + tolerance, extent.yMinimum() + tolerance,
|
|
|
|
+ extent.xMaximum() + width - tolerance,
|
|
|
|
+ extent.yMaximum() - tolerance)
|
|
|
|
+ south_extent = QgsRectangle(extent.xMinimum() + tolerance, extent.yMinimum() - height + tolerance,
|
|
|
|
+ extent.xMaximum() - tolerance,
|
|
|
|
+ extent.yMinimum() - tolerance)
|
|
|
|
+ north_extent = QgsRectangle(extent.xMinimum() + tolerance, extent.yMaximum() + tolerance,
|
|
|
|
+ extent.xMaximum() - tolerance,
|
|
|
|
+ extent.yMaximum() + height - tolerance)
|
|
|
|
+ # 查询每个方向是否有其他网格
|
|
|
|
+ west_neighbors = spatial_index.intersects(west_extent)
|
|
|
|
+ east_neighbors = spatial_index.intersects(east_extent)
|
|
|
|
+ south_neighbors = spatial_index.intersects(south_extent)
|
|
|
|
+ north_neighbors = spatial_index.intersects(north_extent)
|
|
|
|
+ neighbor_geometries = {
|
|
|
|
+ "north": self.cacl(north_neighbors),
|
|
|
|
+ "south": self.cacl(south_neighbors),
|
|
|
|
+ "west": self.cacl(west_neighbors),
|
|
|
|
+ "east": self.cacl(east_neighbors)
|
|
|
|
+ }
|
|
|
|
+ for direction, value in neighbor_geometries.items():
|
|
|
|
+ feature[direction] = value
|
|
|
|
+ layer.updateFeature(feature)
|
|
# 保存编辑
|
|
# 保存编辑
|
|
layer.commitChanges()
|
|
layer.commitChanges()
|
|
|
|
+ print("邻居计算完成!")
|
|
return {
|
|
return {
|
|
"状态": "处理成功"
|
|
"状态": "处理成功"
|
|
}
|
|
}
|