utils.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. # -*- coding: utf-8 -*-
  2. __author__ = 'wanger'
  3. __description__ = '批量生成栅格数据元数据相关工具'
  4. __date__ = '2024-11-25'
  5. __copyright__ = '(C) 2024 by siwei'
  6. __revision__ = '1.0'
  7. import os
  8. from osgeo import osr
  9. from qgis._core import QgsCoordinateReferenceSystem
  10. from qgis.core import (
  11. QgsRasterLayer,
  12. QgsVectorLayer,
  13. QgsSpatialIndex,
  14. QgsFeatureRequest,
  15. QgsGeometry
  16. )
  17. # 通过文件路径来获取文件名和文件后缀
  18. def getImageNumberAndFormat(filepath):
  19. # 获取文件名(包括后缀)
  20. file_name = os.path.basename(filepath)
  21. # 获取文件名(不包括后缀)
  22. file_name_no_ext = os.path.splitext(file_name)[0]
  23. # 获取文件后缀
  24. file_ext = os.path.splitext(file_name)[1][1:]
  25. return file_name_no_ext, file_ext
  26. # 通过文件路径获取文件大小
  27. def getFileSize(filepath):
  28. try:
  29. file_size = os.path.getsize(filepath)
  30. size_mb = file_size / (1024 * 1024)
  31. return f"{size_mb:.2f}"
  32. except FileNotFoundError:
  33. print("文件未找到,请检查路径是否正确!")
  34. return 0
  35. def getImageLeftTop(dataset):
  36. # 获取地理变换参数
  37. geotransform = dataset.GetGeoTransform()
  38. if not geotransform:
  39. raise ValueError("无法获取地理变换参数!")
  40. # 左上角像素的坐标(投影坐标系)
  41. x_min = geotransform[0]
  42. y_max = geotransform[3]
  43. # 获取栅格的空间参考(投影坐标系)
  44. spatial_ref = osr.SpatialReference()
  45. spatial_ref.ImportFromWkt(dataset.GetProjection())
  46. # 转换为地理坐标系(经纬度)
  47. if spatial_ref.IsProjected():
  48. # spatial_ref_geo = spatial_ref.CloneGeogCS()
  49. wgs84_crs = osr.SpatialReference()
  50. wgs84_crs.ImportFromEPSG(4326)
  51. transform = osr.CoordinateTransformation(spatial_ref, wgs84_crs)
  52. lon, lat, _ = transform.TransformPoint(x_min, y_max)
  53. else:
  54. lon, lat = x_min, y_max # 如果已经是地理坐标系,直接使用
  55. return {
  56. "lon": lat,
  57. "lat": lon,
  58. "y": int(x_min),
  59. "x": int(y_max)
  60. }
  61. # 获取中央子午线
  62. def getCentralMeridian(spatial_ref):
  63. proj4 = spatial_ref.ExportToProj4()
  64. print(f"Projection PROJ.4: {proj4}")
  65. central_meridian = None
  66. for param in proj4.split():
  67. if param.startswith('+lon_0'):
  68. central_meridian = param.split('=')[1]
  69. break
  70. if central_meridian:
  71. return central_meridian
  72. else:
  73. print("No central meridian found.")
  74. return None
  75. # 通过栅格数据与矢量数据叠加分析 获取相交面积最大的一块 返回要素
  76. def get_largest_overlapping_feature(raster_path, shp_path):
  77. """
  78. 查询与栅格相交的矢量要素中面积最大的一块,并返回指定字段的值。
  79. :param raster_path: 栅格文件路径
  80. :param shp_path: 矢量文件路径
  81. :return: 面积最大的要素
  82. """
  83. # 加载栅格图层
  84. raster_layer = QgsRasterLayer(raster_path, "Raster Layer")
  85. if not raster_layer.isValid():
  86. raise Exception(f"栅格文件无效: {raster_path}")
  87. # 加载矢量图层
  88. vector_layer = QgsVectorLayer(shp_path, "Vector Layer", "ogr")
  89. if not vector_layer.isValid():
  90. raise Exception(f"SHP文件无效: {shp_path}")
  91. # 获取栅格的范围
  92. raster_extent = raster_layer.extent()
  93. # 创建空间索引以加速查询
  94. spatial_index = QgsSpatialIndex(vector_layer.getFeatures())
  95. # 查询与栅格范围相交的要素ID
  96. intersecting_ids = spatial_index.intersects(raster_extent)
  97. # 遍历这些要素并计算相交区域的面积
  98. max_area = 0
  99. largest_feature = None
  100. for fid in intersecting_ids:
  101. feature = vector_layer.getFeature(fid)
  102. intersection = feature.geometry().intersection(QgsGeometry.fromRect(raster_extent))
  103. # 检查是否有有效相交区域
  104. if intersection.isEmpty():
  105. continue
  106. # 计算相交区域的面积
  107. area = intersection.area()
  108. # 找到面积最大的要素
  109. if area > max_area:
  110. max_area = area
  111. largest_feature = feature
  112. if largest_feature:
  113. return largest_feature
  114. else:
  115. return None
  116. # 处理数值
  117. def processingNumericalValues(value):
  118. print(value)
  119. if isinstance(value, str):
  120. try:
  121. value = float(value)
  122. except ValueError:
  123. print(f"无法将 '{value}' 转换为浮动数")
  124. return None
  125. if value.is_integer():
  126. return int(value)
  127. else:
  128. return round(value, 2)