|
@@ -57,8 +57,10 @@ from processing.tools.StringUtils import (getConnectionStr, getNow)
|
|
|
from processing.tools.GeoServer.Geoserver import Geoserver
|
|
from processing.tools.GeoServer.Geoserver import Geoserver
|
|
|
from processing.tools.PostgreSQL.PostgreSQL import PostgreSQL
|
|
from processing.tools.PostgreSQL.PostgreSQL import PostgreSQL
|
|
|
from processing.tools.system import isWindows
|
|
from processing.tools.system import isWindows
|
|
|
|
|
+from processing.tools.StringUtils import getUUID
|
|
|
from processing.tools.FileUtils import getParentFolderPath
|
|
from processing.tools.FileUtils import getParentFolderPath
|
|
|
from processing.tools.topology.read import (getTopoCheckSQL, getTopoCheckDescription, getTopoCheckNote)
|
|
from processing.tools.topology.read import (getTopoCheckSQL, getTopoCheckDescription, getTopoCheckNote)
|
|
|
|
|
+from processing.tools.SpatiaLite.SpatiaLite import SpatiaLiteUtils
|
|
|
import sqlite3
|
|
import sqlite3
|
|
|
|
|
|
|
|
pluginPath = os.path.normpath(os.path.join(
|
|
pluginPath = os.path.normpath(os.path.join(
|
|
@@ -71,11 +73,12 @@ class A03(GdalAlgorithm):
|
|
|
INPUTVECTOR = "INPUTVECTOR"
|
|
INPUTVECTOR = "INPUTVECTOR"
|
|
|
OUTPUTVECTOR = 'OUTPUTVECTOR'
|
|
OUTPUTVECTOR = 'OUTPUTVECTOR'
|
|
|
TOPOLOGYTYPE = "A03"
|
|
TOPOLOGYTYPE = "A03"
|
|
|
- in_table = "topology_table"
|
|
|
|
|
- out_table = "topology_table_temp"
|
|
|
|
|
|
|
+ uid = getUUID()
|
|
|
|
|
+ in_table = "topology_in_table"
|
|
|
|
|
+ out_table = "topology_out_table"
|
|
|
TOPOLOGYPARAMS = {
|
|
TOPOLOGYPARAMS = {
|
|
|
- "intable_s": in_table,
|
|
|
|
|
- "outtable": out_table
|
|
|
|
|
|
|
+ "intable_s": f"{in_table}_{uid}",
|
|
|
|
|
+ "outtable": f"{out_table}_{uid}",
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
def __init__(self):
|
|
def __init__(self):
|
|
@@ -89,7 +92,7 @@ class A03(GdalAlgorithm):
|
|
|
self.tr('输出位置(矢量数据和报告)')))
|
|
self.tr('输出位置(矢量数据和报告)')))
|
|
|
|
|
|
|
|
def name(self):
|
|
def name(self):
|
|
|
- return 'A03'
|
|
|
|
|
|
|
+ return self.TOPOLOGYTYPE
|
|
|
|
|
|
|
|
def icon(self):
|
|
def icon(self):
|
|
|
return QIcon(os.path.join(pluginPath, 'images', 'dbms', 'topology.png'))
|
|
return QIcon(os.path.join(pluginPath, 'images', 'dbms', 'topology.png'))
|
|
@@ -112,11 +115,11 @@ class A03(GdalAlgorithm):
|
|
|
return 'topology'
|
|
return 'topology'
|
|
|
|
|
|
|
|
def topologycheck(self, parameters, context, feedback, executing=True):
|
|
def topologycheck(self, parameters, context, feedback, executing=True):
|
|
|
- print("面不能有空隙检查开始啦")
|
|
|
|
|
|
|
+ print("拓扑检查开始啦")
|
|
|
# TODO 参数设置
|
|
# TODO 参数设置
|
|
|
spatialite_db_path = self.spatialite_db_path # Spatialite 数据库路径
|
|
spatialite_db_path = self.spatialite_db_path # Spatialite 数据库路径
|
|
|
- table_name = self.in_table # 导入后的表名
|
|
|
|
|
- outtable_name = self.out_table # 分析执行后的表名
|
|
|
|
|
|
|
+ table_name = f"{self.in_table}_{self.uid}" # 导入后的表名
|
|
|
|
|
+ outtable_name = f"{self.out_table}_{self.uid}" # 分析执行后的表名
|
|
|
output_vector_path = self.parameterAsOutputLayer(parameters, self.OUTPUTVECTOR, context) # 输出的 SHP 文件路径
|
|
output_vector_path = self.parameterAsOutputLayer(parameters, self.OUTPUTVECTOR, context) # 输出的 SHP 文件路径
|
|
|
export_layer_name = outtable_name
|
|
export_layer_name = outtable_name
|
|
|
# TODO 将 vectorlayer导入到Spatialite
|
|
# TODO 将 vectorlayer导入到Spatialite
|
|
@@ -124,111 +127,55 @@ class A03(GdalAlgorithm):
|
|
|
if not input_layer.isValid():
|
|
if not input_layer.isValid():
|
|
|
return {
|
|
return {
|
|
|
"状态": "拓扑检查失败",
|
|
"状态": "拓扑检查失败",
|
|
|
- "错误信息": f"Failed to load SHP file."
|
|
|
|
|
|
|
+ "错误信息": f"图层数据不可用。"
|
|
|
}
|
|
}
|
|
|
- crs = input_layer.crs().authid()
|
|
|
|
|
- # TODO 构造连接到Spatialite数据库的URI
|
|
|
|
|
- uri = QgsDataSourceUri()
|
|
|
|
|
- uri.setDatabase(spatialite_db_path)
|
|
|
|
|
- # TODO 将vectorlayer写入Spatialite 数据库
|
|
|
|
|
- options = QgsVectorFileWriter.SaveVectorOptions()
|
|
|
|
|
- options.driverName = "SQLite"
|
|
|
|
|
- options.layerName = table_name
|
|
|
|
|
- options.fileEncoding = "UTF-8"
|
|
|
|
|
- options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
|
|
|
|
|
- # TODO 将QgsVectorLayer导入到spatialite并指定表名
|
|
|
|
|
- result = QgsVectorFileWriter.writeAsVectorFormatV2(input_layer, spatialite_db_path,
|
|
|
|
|
- QgsCoordinateTransformContext(), options)
|
|
|
|
|
|
|
+ result = self.importLayerToSpatiaLite(layer=input_layer, table_name=table_name)
|
|
|
if result[0] != QgsVectorFileWriter.NoError:
|
|
if result[0] != QgsVectorFileWriter.NoError:
|
|
|
return {
|
|
return {
|
|
|
"状态": "拓扑检查失败",
|
|
"状态": "拓扑检查失败",
|
|
|
- "错误信息": f"Failed to import SHP file to Spatialite."
|
|
|
|
|
- }
|
|
|
|
|
- print(f"SHP file imported to Spatialite as table: {table_name}")
|
|
|
|
|
- # TODO 执行 SQL 语句
|
|
|
|
|
- conn = sqlite3.connect(spatialite_db_path)
|
|
|
|
|
- conn.enable_load_extension(True)
|
|
|
|
|
- cursor = conn.cursor()
|
|
|
|
|
- conn.execute("PRAGMA synchronous = OFF")
|
|
|
|
|
- conn.execute("PRAGMA cache_size = -20000") # In KB
|
|
|
|
|
- conn.execute("PRAGMA temp_store = MEMORY")
|
|
|
|
|
- try:
|
|
|
|
|
- conn.execute("SELECT load_extension('mod_spatialite');")
|
|
|
|
|
- print("mod_spatialite loaded successfully.")
|
|
|
|
|
- except sqlite3.OperationalError as e:
|
|
|
|
|
- return {
|
|
|
|
|
- "状态": "拓扑检查失败",
|
|
|
|
|
- "错误信息": f"Failed to load extension: {e}"
|
|
|
|
|
|
|
+ "错误信息": f"图层数据导出到SpatiaLite数据库失败。"
|
|
|
}
|
|
}
|
|
|
|
|
+ print(f"file imported to Spatialite as table: {table_name}")
|
|
|
|
|
+ dbutils = SpatiaLiteUtils(spatialite_db_path)
|
|
|
# TODO SQL语句
|
|
# TODO SQL语句
|
|
|
sql = getTopoCheckSQL(self.TOPOLOGYTYPE, self.TOPOLOGYPARAMS)
|
|
sql = getTopoCheckSQL(self.TOPOLOGYTYPE, self.TOPOLOGYPARAMS)
|
|
|
try:
|
|
try:
|
|
|
- cursor.executescript(f"{sql}")
|
|
|
|
|
- print(f"Script executed successfully.{sql}")
|
|
|
|
|
|
|
+ dbutils.executescript(f"{sql}")
|
|
|
except sqlite3.Error as e:
|
|
except sqlite3.Error as e:
|
|
|
return {
|
|
return {
|
|
|
"状态": "拓扑检查失败",
|
|
"状态": "拓扑检查失败",
|
|
|
- "错误信息": f"An error occurred: {e}"
|
|
|
|
|
|
|
+ "错误信息": f"SpatiaLite数据库执行SQL语句失败: {e}"
|
|
|
}
|
|
}
|
|
|
- conn.commit()
|
|
|
|
|
- conn.close()
|
|
|
|
|
- print("SQL execution completed.")
|
|
|
|
|
|
|
+ # TODO 获取结果集条目
|
|
|
|
|
+ feature_count = dbutils.queryCount(outtable_name)
|
|
|
|
|
+ if feature_count == 0:
|
|
|
|
|
+ dbutils.resetDb()
|
|
|
|
|
+ dbutils.closeDb()
|
|
|
|
|
+ return self.topologySuccessWithNone()
|
|
|
# TODO 将数据导出为本地矢量文件
|
|
# TODO 将数据导出为本地矢量文件
|
|
|
processed_layer = QgsVectorLayer(f"{spatialite_db_path}|layername={export_layer_name}", "processed_layer",
|
|
processed_layer = QgsVectorLayer(f"{spatialite_db_path}|layername={export_layer_name}", "processed_layer",
|
|
|
"ogr")
|
|
"ogr")
|
|
|
path = getParentFolderPath(output_vector_path)
|
|
path = getParentFolderPath(output_vector_path)
|
|
|
csv_path = f"{path}\\report.csv"
|
|
csv_path = f"{path}\\report.csv"
|
|
|
if not processed_layer.isValid():
|
|
if not processed_layer.isValid():
|
|
|
|
|
+ dbutils.closeDb()
|
|
|
return {
|
|
return {
|
|
|
"状态": "拓扑检查失败",
|
|
"状态": "拓扑检查失败",
|
|
|
- "错误信息": "Failed to load processed layer."
|
|
|
|
|
|
|
+ "错误信息": "拓扑检查结果图层加载失败。"
|
|
|
}
|
|
}
|
|
|
else:
|
|
else:
|
|
|
- options = QgsVectorFileWriter.SaveVectorOptions()
|
|
|
|
|
- options.driverName = "CSV" # Output format
|
|
|
|
|
- options.includeGeometry = True # Include geometry
|
|
|
|
|
- # options.setLayerOptions(QgsVectorFileWriter.LayerOptions())
|
|
|
|
|
- # context = QgsCoordinateTransformContext()
|
|
|
|
|
- # options.setOutputWkt(True)
|
|
|
|
|
- context2 = QgsCoordinateTransformContext()
|
|
|
|
|
- error = QgsVectorFileWriter.writeAsVectorFormatV3(processed_layer, csv_path, context2, options)
|
|
|
|
|
- if error[0] == QgsVectorFileWriter.NoError:
|
|
|
|
|
- print(f"Exported {table_name} to {csv_path} successfully!")
|
|
|
|
|
- else:
|
|
|
|
|
- return {
|
|
|
|
|
- "状态": "拓扑检查失败",
|
|
|
|
|
- "错误信息": f"Failed to export {table_name} to CSV: {error}"
|
|
|
|
|
- }
|
|
|
|
|
- # TODO 导出矢量文件参数配置
|
|
|
|
|
- export_options = QgsVectorFileWriter.SaveVectorOptions()
|
|
|
|
|
- export_options.driverName = "ESRI Shapefile"
|
|
|
|
|
- export_options.fileEncoding = "UTF-8"
|
|
|
|
|
- result = QgsVectorFileWriter.writeAsVectorFormatV2(processed_layer, output_vector_path,
|
|
|
|
|
- QgsCoordinateTransformContext(), export_options)
|
|
|
|
|
- if result[0] != QgsVectorFileWriter.NoError:
|
|
|
|
|
- return {
|
|
|
|
|
- "状态": "拓扑检查失败",
|
|
|
|
|
- "错误信息": f"Failed to export processed layer to SHP file."
|
|
|
|
|
- }
|
|
|
|
|
- feature_count = processed_layer.featureCount()
|
|
|
|
|
- return {
|
|
|
|
|
- "状态": "拓扑检查成功",
|
|
|
|
|
- "结论": "不符合" if feature_count > 0 else "符合",
|
|
|
|
|
- "错误项": f"{feature_count}条记录",
|
|
|
|
|
- # "矢量数据输出位置": output_vector_path,
|
|
|
|
|
- "报告输出位置": csv_path
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ self.vectorLayerExport(layer=processed_layer, type="CSV", path=csv_path)
|
|
|
|
|
+ self.vectorLayerExportToVector(layer=processed_layer, path=output_vector_path)
|
|
|
|
|
+ os.startfile(path)
|
|
|
|
|
+ dbutils.resetDb()
|
|
|
|
|
+ dbutils.closeDb()
|
|
|
|
|
+ return self.topologySuccess(count=feature_count, reportpath=csv_path)
|
|
|
|
|
|
|
|
# 判断数据是否为字符串
|
|
# 判断数据是否为字符串
|
|
|
def is_string(self, var):
|
|
def is_string(self, var):
|
|
|
return isinstance(var, str)
|
|
return isinstance(var, str)
|
|
|
|
|
|
|
|
def getConsoleCommands(self, parameters, context, feedback, executing=True):
|
|
def getConsoleCommands(self, parameters, context, feedback, executing=True):
|
|
|
- inputvector = self.parameterAsVectorLayer(parameters, self.INPUTVECTOR, context)
|
|
|
|
|
- print(f"拓扑检查输入矢量图层:")
|
|
|
|
|
- print(inputvector)
|
|
|
|
|
- outFile = self.parameterAsOutputLayer(parameters, self.OUTPUTVECTOR, context)
|
|
|
|
|
- print(f"拓扑检查输出文件:{outFile}")
|
|
|
|
|
return []
|
|
return []
|
|
|
|
|
|
|
|
def contains_keys(self, obj, keys):
|
|
def contains_keys(self, obj, keys):
|