ImportSingleOSGBToPostGIS.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. __author__ = 'liying'
  2. __date__ = 'May 2025'
  3. __copyright__ = '(C) 2025, liying'
  4. import uuid
  5. import os
  6. import psycopg2
  7. from datetime import datetime
  8. from psycopg2 import sql
  9. from qgis.core import (
  10. QgsProcessingAlgorithm,
  11. QgsProcessingParameterFile,
  12. QgsProcessingParameterProviderConnection,
  13. QgsProcessingParameterDatabaseSchema,
  14. QgsProcessingParameterString,
  15. QgsProcessingParameterEnum,
  16. QgsProcessingParameterDateTime,
  17. QgsProcessingParameterBoolean,
  18. QgsProcessingParameterCrs
  19. )
  20. from qgis.PyQt.QtCore import QCoreApplication
  21. from processing.tools.PostgreSQL.PostgreSQL import PostgreSQL
  22. class ImportSingleOSGBToPostGIS(QgsProcessingAlgorithm):
  23. DATABASE = 'DATABASE'
  24. SCHEMA = 'SCHEMA'
  25. TABLE = 'TABLE'
  26. INPUT_DIR = 'INPUT_DIR'
  27. VECTOR_SJLY = 'VECTOR_SJLY'
  28. VECTOR_YEAR = 'VECTOR_YEAR'
  29. VECTOR_YWLX = 'VECTOR_YWLX'
  30. VECTOR_GLBM = 'VECTOR_GLBM'
  31. VECTOR_ZYML = 'VECTOR_ZYML'
  32. T_SRS = 'T_SRS'
  33. RASTER_T = 'RASTER_T'
  34. SOURCE_TYPE = 'SOURCE_TYPE'
  35. Metadata_storage = 'Metadata_storage'
  36. INDEX = 'INDEX'
  37. RASTER_T_LIST = ['不分块', '128', '256', '512']
  38. @staticmethod
  39. def tr(string):
  40. return QCoreApplication.translate('ImportSingleOSGBToPostGIS', string)
  41. def initAlgorithm(self, config=None):
  42. self.addParameter(QgsProcessingParameterProviderConnection(
  43. self.DATABASE,
  44. self.tr('数据库连接'),
  45. 'postgres',
  46. defaultValue='192.168.60.2'
  47. ))
  48. self.addParameter(QgsProcessingParameterDatabaseSchema(
  49. self.SCHEMA,
  50. self.tr('模式'),
  51. connectionParameterName=self.DATABASE,
  52. defaultValue='base'
  53. ))
  54. self.addParameter(QgsProcessingParameterString(
  55. self.TABLE,
  56. self.tr('表名'),
  57. defaultValue='t_vector_storage'
  58. ))
  59. self.addParameter(QgsProcessingParameterFile(
  60. self.INPUT_DIR,
  61. self.tr('OSGB 数据目录'),
  62. behavior=QgsProcessingParameterFile.Folder,
  63. optional=False
  64. ))
  65. self.addParameter(QgsProcessingParameterString(
  66. self.VECTOR_SJLY,
  67. self.tr('数据来源'),
  68. optional=False
  69. ))
  70. self.addParameter(QgsProcessingParameterDateTime(
  71. self.VECTOR_YEAR,
  72. self.tr('数据时效'),
  73. type=QgsProcessingParameterDateTime.Type.Date,
  74. optional=False
  75. ))
  76. pgconn = PostgreSQL(schema='base')
  77. rows = pgconn.getVectorYwlx()
  78. self.ywlxs = [row[0] for row in rows]
  79. self.addParameter(QgsProcessingParameterEnum(name=self.VECTOR_YWLX,
  80. description=self.tr('业务类型'), options=self.ywlxs,
  81. optional=False))
  82. rows = pgconn.getDeptList()
  83. self.depts = [row[0] for row in rows]
  84. self.addParameter(QgsProcessingParameterEnum(name=self.VECTOR_GLBM,
  85. description=self.tr('管理部门'), options=self.depts))
  86. rows = pgconn.getVectorZyml()
  87. self.zymls = [row[1] for row in rows]
  88. self.addParameter(QgsProcessingParameterEnum(name=self.VECTOR_ZYML,
  89. description=self.tr('资源目录'), options=self.zymls))
  90. self.addParameter(QgsProcessingParameterCrs(
  91. self.T_SRS,
  92. self.tr('指定入库坐标系'),
  93. defaultValue='EPSG:4326',
  94. optional=False
  95. ))
  96. self.addParameter(QgsProcessingParameterEnum(
  97. self.RASTER_T,
  98. self.tr('分块存储大小'),
  99. options=self.RASTER_T_LIST,
  100. defaultValue=0,
  101. optional=False
  102. ))
  103. self.addParameter(QgsProcessingParameterString(
  104. self.SOURCE_TYPE,
  105. self.tr('数据源类型'),
  106. defaultValue='osgb',
  107. optional=False
  108. ))
  109. self.addParameter(QgsProcessingParameterBoolean(
  110. self.Metadata_storage,
  111. self.tr('元数据入库'),
  112. defaultValue=True
  113. ))
  114. self.addParameter(QgsProcessingParameterBoolean(
  115. self.INDEX,
  116. self.tr('创建空间索引'),
  117. defaultValue=True
  118. ))
  119. def processAlgorithm(self, parameters, context, feedback):
  120. connection_name = self.parameterAsString(parameters, self.DATABASE, context)
  121. schema = self.parameterAsString(parameters, self.SCHEMA, context)
  122. table = self.parameterAsString(parameters, self.TABLE, context)
  123. input_dir = self.parameterAsString(parameters, self.INPUT_DIR, context)
  124. data_source = self.parameterAsString(parameters, self.VECTOR_SJLY, context)
  125. # 转换 QDateTime 为 Python date
  126. qdatetime = self.parameterAsDateTime(parameters, self.VECTOR_YEAR, context)
  127. data_year = qdatetime.date().toPyDate().year # 只保留年份(整数)
  128. business_type_index = self.parameterAsInt(parameters, self.VECTOR_YWLX, context)
  129. management_dept_index = self.parameterAsInt(parameters, self.VECTOR_GLBM, context)
  130. resource_catalog_index = self.parameterAsInt(parameters, self.VECTOR_ZYML, context)
  131. source_type = self.parameterAsString(parameters, self.SOURCE_TYPE, context)
  132. pgconn = PostgreSQL(schema='base')
  133. business_type = pgconn.getVectorYwlx()[business_type_index][0]
  134. management_dept = pgconn.getDeptList()[management_dept_index][0]
  135. resource_catalog = pgconn.getVectorZyml()[resource_catalog_index][1]
  136. query = f"SELECT bsm FROM t_vector_zyml WHERE name = '{resource_catalog}'"
  137. result = pgconn.execute(query)
  138. if result and len(result) > 0:
  139. resource_catalog = result[0][0]
  140. else:
  141. feedback.pushWarning(f"未找到名称为 {resource_catalog} 的BSM值")
  142. conn_params = {
  143. 'host': "192.168.60.2",
  144. 'port': "5432",
  145. 'dbname': "real3d",
  146. 'user': "postgres",
  147. 'password': "postgis"
  148. }
  149. conn = psycopg2.connect(**conn_params)
  150. cursor = conn.cursor()
  151. feedback.pushInfo("插入目录级元数据记录...")
  152. id = str(uuid.uuid4())
  153. nm = os.path.basename(input_dir)
  154. insert_sql = sql.SQL("""
  155. INSERT INTO {schema}.{table}
  156. (sjywz, rksj, year, ywlx, glbm, id, sjlx, xmlx, name, sjly)
  157. VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
  158. """).format(
  159. schema=sql.Identifier(schema),
  160. table=sql.Identifier(table)
  161. )
  162. cursor.execute(insert_sql, (
  163. input_dir,
  164. datetime.now().date(),
  165. data_year,
  166. business_type,
  167. management_dept,
  168. id,
  169. source_type,
  170. resource_catalog,
  171. nm,
  172. data_source
  173. ))
  174. conn.commit()
  175. feedback.pushInfo("扫描目录并插入单体模型记录...")
  176. for root, dirs, files in os.walk(input_dir):
  177. for file in files:
  178. if file.lower().endswith('.osgb'):
  179. full_path = os.path.join(root, file)
  180. model_id = str(uuid.uuid4())
  181. cursor.execute(insert_sql, (
  182. full_path,
  183. datetime.now().date(),
  184. data_year,
  185. business_type,
  186. management_dept,
  187. model_id,
  188. source_type,
  189. resource_catalog,
  190. file,
  191. data_source
  192. ))
  193. conn.commit()
  194. cursor.close()
  195. conn.close()
  196. feedback.pushInfo("所有单体模型路径已成功插入数据库。")
  197. return {}
  198. def name(self):
  199. return "importsingleosgbtopostgis"
  200. def displayName(self):
  201. return "单体三维模型入库"
  202. def group(self):
  203. return "三维数据工具"
  204. def groupId(self):
  205. return "osgbtools"
  206. def shortHelpString(self):
  207. return "扫描 OSGB 文件目录,将单体模型文件路径等元数据信息写入 PostGIS 数据库。"
  208. def createInstance(self):
  209. return ImportSingleOSGBToPostGIS()