123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- __author__ = 'liying'
- __date__ = 'May 2025'
- __copyright__ = '(C) 2025, liying'
- import os
- import uuid
- from datetime import datetime
- import psycopg2
- import siwei_config
- from processing.tools.PostgreSQL.PostgreSQL import PostgreSQL
- from psycopg2 import sql
- from qgis.PyQt.QtCore import QCoreApplication
- from qgis.core import (
- QgsProcessingAlgorithm,
- QgsProcessingParameterFile,
- QgsProcessingParameterProviderConnection,
- QgsProcessingParameterDatabaseSchema,
- QgsProcessingParameterString,
- QgsProcessingParameterEnum,
- QgsProcessingParameterDateTime,
- QgsProcessingParameterBoolean,
- QgsProcessingParameterCrs
- )
- class ImportSingleOSGBToPostGIS(QgsProcessingAlgorithm):
- DATABASE = 'DATABASE'
- SCHEMA = 'SCHEMA'
- TABLE = 'TABLE'
- INPUT_DIR = 'INPUT_DIR'
- VECTOR_SJLY = 'VECTOR_SJLY'
- VECTOR_YEAR = 'VECTOR_YEAR'
- VECTOR_YWLX = 'VECTOR_YWLX'
- VECTOR_GLBM = 'VECTOR_GLBM'
- VECTOR_ZYML = 'VECTOR_ZYML'
- T_SRS = 'T_SRS'
- RASTER_T = 'RASTER_T'
- SOURCE_TYPE = 'SOURCE_TYPE'
- Metadata_storage = 'Metadata_storage'
- INDEX = 'INDEX'
- RASTER_T_LIST = ['不分块', '128', '256', '512']
- @staticmethod
- def tr(string):
- return QCoreApplication.translate('ImportSingleOSGBToPostGIS', string)
- def initAlgorithm(self, config=None):
- self.addParameter(QgsProcessingParameterProviderConnection(
- self.DATABASE,
- self.tr('数据库连接'),
- 'postgres',
- defaultValue=siwei_config.CONFIG['db']['host']
- ))
- self.addParameter(QgsProcessingParameterDatabaseSchema(
- self.SCHEMA,
- self.tr('模式'),
- connectionParameterName=self.DATABASE,
- defaultValue='base'
- ))
- self.addParameter(QgsProcessingParameterString(
- self.TABLE,
- self.tr('表名'),
- defaultValue='t_vector_storage'
- ))
- self.addParameter(QgsProcessingParameterFile(
- self.INPUT_DIR,
- self.tr('OSGB 数据目录'),
- behavior=QgsProcessingParameterFile.Folder,
- optional=False
- ))
- self.addParameter(QgsProcessingParameterString(
- self.VECTOR_SJLY,
- self.tr('数据来源'),
- optional=False
- ))
- self.addParameter(QgsProcessingParameterDateTime(
- self.VECTOR_YEAR,
- self.tr('数据时效'),
- type=QgsProcessingParameterDateTime.Type.Date,
- optional=False
- ))
- pgconn = PostgreSQL(schema='base')
- rows = pgconn.getVectorYwlx()
- self.ywlxs = [row[0] for row in rows]
- self.addParameter(QgsProcessingParameterEnum(name=self.VECTOR_YWLX,
- description=self.tr('业务类型'), options=self.ywlxs,
- optional=False))
- rows = pgconn.getDeptList()
- self.depts = [row[0] for row in rows]
- self.addParameter(QgsProcessingParameterEnum(name=self.VECTOR_GLBM,
- description=self.tr('管理部门'), options=self.depts))
- rows = pgconn.getVectorZyml()
- self.zymls = [row[1] for row in rows]
- self.addParameter(QgsProcessingParameterEnum(name=self.VECTOR_ZYML,
- description=self.tr('资源目录'), options=self.zymls))
- self.addParameter(QgsProcessingParameterCrs(
- self.T_SRS,
- self.tr('指定入库坐标系'),
- defaultValue='EPSG:4326',
- optional=False
- ))
- self.addParameter(QgsProcessingParameterEnum(
- self.RASTER_T,
- self.tr('分块存储大小'),
- options=self.RASTER_T_LIST,
- defaultValue=0,
- optional=False
- ))
- self.addParameter(QgsProcessingParameterString(
- self.SOURCE_TYPE,
- self.tr('数据源类型'),
- defaultValue='osgb',
- optional=False
- ))
- self.addParameter(QgsProcessingParameterBoolean(
- self.Metadata_storage,
- self.tr('元数据入库'),
- defaultValue=True
- ))
- self.addParameter(QgsProcessingParameterBoolean(
- self.INDEX,
- self.tr('创建空间索引'),
- defaultValue=True
- ))
- def processAlgorithm(self, parameters, context, feedback):
- connection_name = self.parameterAsString(parameters, self.DATABASE, context)
- schema = self.parameterAsString(parameters, self.SCHEMA, context)
- table = self.parameterAsString(parameters, self.TABLE, context)
- input_dir = self.parameterAsString(parameters, self.INPUT_DIR, context)
- data_source = self.parameterAsString(parameters, self.VECTOR_SJLY, context)
- # 转换 QDateTime 为 Python date
- qdatetime = self.parameterAsDateTime(parameters, self.VECTOR_YEAR, context)
- data_year = qdatetime.date().toPyDate().year # 只保留年份(整数)
- business_type_index = self.parameterAsInt(parameters, self.VECTOR_YWLX, context)
- management_dept_index = self.parameterAsInt(parameters, self.VECTOR_GLBM, context)
- resource_catalog_index = self.parameterAsInt(parameters, self.VECTOR_ZYML, context)
- source_type = self.parameterAsString(parameters, self.SOURCE_TYPE, context)
- pgconn = PostgreSQL(schema='base')
- business_type = pgconn.getVectorYwlx()[business_type_index][0]
- management_dept = pgconn.getDeptList()[management_dept_index][0]
- resource_catalog = pgconn.getVectorZyml()[resource_catalog_index][1]
- query = f"SELECT bsm FROM t_vector_zyml WHERE name = '{resource_catalog}'"
- result = pgconn.execute(query)
- if result and len(result) > 0:
- resource_catalog = result[0][0]
- else:
- feedback.pushWarning(f"未找到名称为 {resource_catalog} 的BSM值")
- db_config = siwei_config.CONFIG['db']
- conn_params = {
- 'host': db_config['host'],
- 'port': db_config['port'],
- 'dbname': db_config['name'],
- 'user': db_config['user'],
- 'password': db_config['password']
- }
- conn = psycopg2.connect(**conn_params)
- cursor = conn.cursor()
- feedback.pushInfo("插入目录级元数据记录...")
- id = str(uuid.uuid4())
- nm = os.path.basename(input_dir)
- insert_sql = sql.SQL("""
- INSERT INTO {schema}.{table}
- (sjywz, rksj, year, ywlx, glbm, id, sjlx, xmlx, name, sjly)
- VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
- """).format(
- schema=sql.Identifier(schema),
- table=sql.Identifier(table)
- )
- cursor.execute(insert_sql, (
- input_dir,
- datetime.now().date(),
- data_year,
- business_type,
- management_dept,
- id,
- source_type,
- resource_catalog,
- nm,
- data_source
- ))
- conn.commit()
- feedback.pushInfo("扫描目录并插入单体模型记录...")
- for root, dirs, files in os.walk(input_dir):
- for file in files:
- if file.lower().endswith('.osgb'):
- full_path = os.path.join(root, file)
- model_id = str(uuid.uuid4())
- cursor.execute(insert_sql, (
- full_path,
- datetime.now().date(),
- data_year,
- business_type,
- management_dept,
- model_id,
- source_type,
- resource_catalog,
- file,
- data_source
- ))
- conn.commit()
- cursor.close()
- conn.close()
- feedback.pushInfo("所有单体模型路径已成功插入数据库。")
- return {}
- def name(self):
- return "importsingleosgbtopostgis"
- def displayName(self):
- return "单体三维模型入库"
- def group(self):
- return "三维数据工具"
- def groupId(self):
- return "osgbtools"
- def shortHelpString(self):
- return "扫描 OSGB 文件目录,将单体模型文件路径等元数据信息写入 PostGIS 数据库。"
- def createInstance(self):
- return ImportSingleOSGBToPostGIS()
|