Browse Source

拓扑检查实现框架提交

wanger 7 months ago
parent
commit
1c7beace02

+ 243 - 0
processing/algs/gdal/A03.py

@@ -0,0 +1,243 @@
+# -*- coding: utf-8 -*-
+"""
+***************************************************************************
+    A03.py
+    ---------------------
+    Date                 : November 2012
+    Copyright            : (C) 2012 by Victor Olaya
+    Email                : volayaf at gmail dot com
+***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************
+"""
+
+__author__ = 'wanger'
+__date__ = 'November 2024'
+__copyright__ = '(C) 2024, wanger'
+
+import os
+
+from PyQt5.QtSql import QSqlDatabase, QSqlQuery
+from osgeo import ogr, gdal
+from PyQt5.QtGui import QIcon
+from PyQt5.QtWidgets import QApplication
+from future.moves import sys
+
+from qgis.PyQt import QtWidgets
+from qgis._core import QgsProcessingParameterVectorDestination, QgsVectorLayer, QgsVectorFileWriter, \
+    QgsCoordinateTransformContext
+from qgis.core import (QgsProcessing,
+                       QgsProcessingParameterFeatureSource,
+                       QgsProcessingParameterString,
+                       QgsProcessingParameterFile,
+                       QgsProcessingParameterDateTime,
+                       QgsProcessingParameterEnum,
+                       QgsProcessingParameterCrs,
+                       QgsProcessingParameterField,
+                       QgsProcessingParameterExtent,
+                       QgsProcessingParameterBoolean,
+                       QgsProcessingParameterProviderConnection,
+                       QgsProcessingParameterDatabaseSchema,
+                       QgsProcessingParameterDatabaseTable,
+                       QgsProviderRegistry,
+                       QgsProcessingException,
+                       QgsProcessingParameterDefinition,
+                       QgsProviderConnectionException,
+                       QgsDataSourceUri)
+
+from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
+from processing.algs.gdal.GdalUtils import GdalUtils
+from processing.tools.PrintUtils import printStr
+from processing.tools.StringUtils import (getConnectionStr, getNow)
+from processing.tools.GeoServer.Geoserver import Geoserver
+from processing.tools.PostgreSQL.PostgreSQL import PostgreSQL
+from processing.tools.system import isWindows
+from processing.tools.FileUtils import getParentFolderPath
+from processing.tools.topology.read import (getTopoCheckSQL, getTopoCheckDescription, getTopoCheckNote)
+import sqlite3
+
+pluginPath = os.path.normpath(os.path.join(
+    os.path.split(os.path.dirname(__file__))[0], os.pardir))
+gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES")
+gdal.SetConfigOption("SHAPE_ENCODING", "GBK")
+
+
+class A03(GdalAlgorithm):
+    INPUTVECTOR = "INPUTVECTOR"
+    OUTPUTVECTOR = 'OUTPUTVECTOR'
+    TOPOLOGYTYPE = "A03"
+    in_table = "topology_table"
+    out_table = "topology_table_temp"
+    TOPOLOGYPARAMS = {
+        "intable_s": in_table,
+        "outtable": out_table
+    }
+
+    def __init__(self):
+        super().__init__()
+
+    def initAlgorithm(self, config=None):
+        self.addParameter(QgsProcessingParameterFeatureSource(self.INPUTVECTOR,
+                                                              self.tr('待检查数据'),
+                                                              types=[QgsProcessing.TypeVectorPolygon]))
+        self.addParameter(QgsProcessingParameterVectorDestination(self.OUTPUTVECTOR,
+                                                                  self.tr('输出位置(矢量数据和报告)')))
+
+    def name(self):
+        return 'A03'
+
+    def icon(self):
+        return QIcon(os.path.join(pluginPath, 'images', 'dbms', 'topology.png'))
+
+    def displayName(self):
+        return self.tr(getTopoCheckNote(self.TOPOLOGYTYPE))
+
+    def shortDescription(self):
+        return self.tr(getTopoCheckDescription(self.TOPOLOGYTYPE))
+
+    def tags(self):
+        t = self.tr('import,into,postgis,database,vector').split(',')
+        t.extend(super().tags())
+        return t
+
+    def group(self):
+        return self.tr('拓扑检查')
+
+    def groupId(self):
+        return 'topology'
+
+    def topologycheck(self, parameters, context, feedback, executing=True):
+        print("面不能有空隙检查开始啦")
+        # TODO 参数设置
+        spatialite_db_path = self.spatialite_db_path  # Spatialite 数据库路径
+        table_name = self.in_table  # 导入后的表名
+        outtable_name = self.out_table  # 分析执行后的表名
+        output_vector_path = self.parameterAsOutputLayer(parameters, self.OUTPUTVECTOR, context)  # 输出的 SHP 文件路径
+        export_layer_name = outtable_name
+        # TODO 将 vectorlayer导入到Spatialite
+        input_layer = self.parameterAsVectorLayer(parameters, self.INPUTVECTOR, context)
+        if not input_layer.isValid():
+            return {
+                "状态": "拓扑检查失败",
+                "错误信息": f"Failed to load SHP file."
+            }
+        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)
+        if result[0] != QgsVectorFileWriter.NoError:
+            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}"
+            }
+        # TODO SQL语句
+        sql = getTopoCheckSQL(self.TOPOLOGYTYPE, self.TOPOLOGYPARAMS)
+        try:
+            cursor.executescript(f"{sql}")
+            print(f"Script executed successfully.{sql}")
+        except sqlite3.Error as e:
+            return {
+                "状态": "拓扑检查失败",
+                "错误信息": f"An error occurred: {e}"
+            }
+        conn.commit()
+        conn.close()
+        print("SQL execution completed.")
+        # TODO 将数据导出为本地矢量文件
+        processed_layer = QgsVectorLayer(f"{spatialite_db_path}|layername={export_layer_name}", "processed_layer",
+                                         "ogr")
+        path = getParentFolderPath(output_vector_path)
+        csv_path = f"{path}\\report.csv"
+        if not processed_layer.isValid():
+            return {
+                "状态": "拓扑检查失败",
+                "错误信息": "Failed to load processed layer."
+            }
+        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
+        }
+
+    # 判断数据是否为字符串
+    def is_string(self, var):
+        return isinstance(var, str)
+
+    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 []
+
+    def contains_keys(self, obj, keys):
+        if isinstance(obj, dict):
+            return all(key in obj.keys() for key in keys)
+        elif hasattr(type(obj), '__dict__'):
+            return all(key in obj.__dict__ for key in keys)
+        else:
+            raise ValueError("Invalid object type")
+
+    def commandName(self):
+        return "ogr2ogr"

+ 7 - 1
processing/algs/gdal/GdalAlgorithm.py

@@ -59,6 +59,7 @@ class GdalAlgorithm(QgsProcessingAlgorithm):
         super().__init__()
         # TODO wanger GdalAlgorithm全局参数配置
         self.output_values = {}
+        self.spatialite_db_path = "D:\\temp\\output.sqlite"
         self.pgcoon = {
             "host": "127.0.0.1",
             "schema": "vector",
@@ -165,6 +166,10 @@ class GdalAlgorithm(QgsProcessingAlgorithm):
         self.output_values[name] = value
 
     def processAlgorithm(self, parameters, context, feedback):
+        # TODO wanger 拓扑检查
+        if parameters.get("INPUTVECTOR") is not None:
+            res = self.topologycheck(parameters, context, feedback, executing=True)
+            return res
         # TODO wanger 生成许可文件
         if parameters.get("LICENSEHOST") is not None:
             self.generateLicense(parameters)
@@ -274,7 +279,8 @@ class GdalAlgorithm(QgsProcessingAlgorithm):
                 ogrLayer = raster_layer.source()
             print(ogrLayer)
             pgconn.metadataStorage(parameters, ssxzqh, fileliststr, self.ywlxs[parameters.get("VECTOR_YWLX")],
-                                   self.depts[parameters.get("VECTOR_GLBM")], ogrLayer, self.zymls[parameters.get("VECTOR_ZYML")])
+                                   self.depts[parameters.get("VECTOR_GLBM")], ogrLayer,
+                                   self.zymls[parameters.get("VECTOR_ZYML")])
             pgconn.close()
         return results
 

+ 1 - 1
processing/algs/gdal/GdalAlgorithmDialog.py

@@ -82,7 +82,7 @@ class GdalParametersPanel(ParametersPanel):
         layout.setMargin(0)
         layout.setSpacing(6)
 
-        gdalHidden = False
+        gdalHidden = True
         loop = True
 
         if algname == "postgistogeoserver":

+ 5 - 1
processing/algs/gdal/GdalAlgorithmProvider.py

@@ -99,6 +99,8 @@ from .ExportVectorByMask import ExportVectorByMask
 from .ExportRasterByMask import ExportRasterByMask
 from .VectorProject import VectorProject
 from .LicenseMake import LicenseMake
+from .A03 import A03
+from .topologycheck import TopologyCheck
 
 # from .ogr2ogrtabletopostgislist import Ogr2OgrTableToPostGisList
 
@@ -221,7 +223,9 @@ class GdalAlgorithmProvider(QgsProcessingProvider):
             ExportVectorByMask(),
             ExportRasterByMask(),
             VectorProject(),
-            LicenseMake()
+            LicenseMake(),
+            TopologyCheck(),
+            A03()
             # Ogr2OgrTableToPostGisList(),
         ]
 

+ 207 - 0
processing/algs/gdal/topologycheck.py

@@ -0,0 +1,207 @@
+# -*- coding: utf-8 -*-
+"""
+***************************************************************************
+    TopologyCheck.py
+    ---------------------
+    Date                 : November 2012
+    Copyright            : (C) 2012 by Victor Olaya
+    Email                : volayaf at gmail dot com
+***************************************************************************
+*                                                                         *
+*   This program is free software; you can redistribute it and/or modify  *
+*   it under the terms of the GNU General Public License as published by  *
+*   the Free Software Foundation; either version 2 of the License, or     *
+*   (at your option) any later version.                                   *
+*                                                                         *
+***************************************************************************
+"""
+
+__author__ = 'wanger'
+__date__ = 'November 2024'
+__copyright__ = '(C) 2024, wanger'
+
+import os
+
+from PyQt5.QtSql import QSqlDatabase, QSqlQuery
+from osgeo import ogr, gdal
+from PyQt5.QtGui import QIcon
+from PyQt5.QtWidgets import QApplication
+from future.moves import sys
+
+from qgis.PyQt import QtWidgets
+from qgis._core import QgsProcessingParameterVectorDestination, QgsVectorLayer, QgsVectorFileWriter, \
+    QgsCoordinateTransformContext
+from qgis.core import (QgsProcessing,
+                       QgsProcessingParameterFeatureSource,
+                       QgsProcessingParameterString,
+                       QgsProcessingParameterFile,
+                       QgsProcessingParameterDateTime,
+                       QgsProcessingParameterEnum,
+                       QgsProcessingParameterCrs,
+                       QgsProcessingParameterField,
+                       QgsProcessingParameterExtent,
+                       QgsProcessingParameterBoolean,
+                       QgsProcessingParameterProviderConnection,
+                       QgsProcessingParameterDatabaseSchema,
+                       QgsProcessingParameterDatabaseTable,
+                       QgsProviderRegistry,
+                       QgsProcessingException,
+                       QgsProcessingParameterDefinition,
+                       QgsProviderConnectionException,
+                       QgsDataSourceUri)
+
+from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
+from processing.algs.gdal.GdalUtils import GdalUtils
+from processing.tools.PrintUtils import printStr
+from processing.tools.StringUtils import (getConnectionStr, getNow)
+from processing.tools.GeoServer.Geoserver import Geoserver
+from processing.tools.PostgreSQL.PostgreSQL import PostgreSQL
+from processing.tools.system import isWindows
+
+pluginPath = os.path.normpath(os.path.join(
+    os.path.split(os.path.dirname(__file__))[0], os.pardir))
+gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES")
+gdal.SetConfigOption("SHAPE_ENCODING", "GBK")
+
+
+class TopologyCheck(GdalAlgorithm):
+    INPUTVECTOR = "INPUTVECTOR"
+    TOPOLOGYTYPE = "TOPOLOGYTYPE"
+    TOPOLOGYTYPES = ["必须不相交", "不能重叠", "不能相交", "不能有悬挂点", "不能有伪结点", "不能自重叠", "不能自相交",
+                     "不能相交或内部接触", "必须为单一部件", "不能有空隙"]
+    OUTPUTVECTOR = 'OUTPUTVECTOR'
+
+    def __init__(self):
+        super().__init__()
+
+    def initAlgorithm(self, config=None):
+        self.addParameter(QgsProcessingParameterFeatureSource(self.INPUTVECTOR,
+                                                              self.tr('待检查数据'),
+                                                              types=[QgsProcessing.TypeVector]))
+
+        EnumOption = QgsProcessingParameterEnum(name=self.TOPOLOGYTYPE,
+                                                description=self.tr('拓扑检查类型'),
+                                                options=self.TOPOLOGYTYPES)
+        EnumOption.setAllowMultiple(True)
+        self.addParameter(EnumOption)
+        self.addParameter(QgsProcessingParameterVectorDestination(self.OUTPUTVECTOR,
+                                                                  self.tr('输出位置')))
+
+    def name(self):
+        return 'topologycheck'
+
+    def icon(self):
+        return QIcon(os.path.join(pluginPath, 'images', 'dbms', 'topology.png'))
+
+    def displayName(self):
+        return self.tr('拓扑检查')
+
+    def shortDescription(self):
+        return self.tr('拓扑检查')
+
+    def tags(self):
+        t = self.tr('import,into,postgis,database,vector').split(',')
+        t.extend(super().tags())
+        return t
+
+    def group(self):
+        return self.tr('拓扑检查')
+
+    def groupId(self):
+        return 'topology'
+
+    def topologycheck(self, parameters, context, feedback, executing=True):
+        print("拓扑检查开始啦")
+        types = print(parameters[self.TOPOLOGYTYPE])
+        print(f"拓扑检查类型:{types}")
+
+        # TODO 参数设置
+        spatialite_db_path = "D:\\temp\\output.sqlite"  # Spatialite 数据库路径
+        table_name = "topology_table"  # 导入后的表名
+        output_vector_path = self.parameterAsOutputLayer(parameters, self.OUTPUTVECTOR, context)  # 输出的 SHP 文件路径
+        export_layer_name = table_name
+
+        # TODO 将 vectorlayer导入到Spatialite
+        input_layer = self.parameterAsVectorLayer(parameters, self.INPUTVECTOR, context)
+        if not input_layer.isValid():
+            print("Failed to load SHP file.")
+        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)
+        if result[0] != QgsVectorFileWriter.NoError:
+            print("Failed to import SHP file to Spatialite.")
+        print(f"SHP file imported to Spatialite as table: {table_name}")
+
+        # TODO 执行 SQL 语句
+        db = QSqlDatabase.addDatabase("QSQLITE")
+        db.setDatabaseName(spatialite_db_path)
+        if not db.open():
+            print("Failed to open Spatialite database.")
+        query = QSqlQuery(db)
+
+        # TODO SQL语句
+        sql = f"""
+            SELECT * FROM {table_name};
+        """
+        if not query.exec(sql):
+            print("SQL execution failed:", query.lastError().text())
+
+        print("SQL execution completed.")
+
+        # TODO 将数据导出为本地矢量文件
+        processed_layer = QgsVectorLayer(f"{spatialite_db_path}|layername={export_layer_name}", "processed_layer",
+                                         "ogr")
+        if not processed_layer.isValid():
+            print("Failed to load processed layer.")
+
+        # 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:
+            print("Failed to export processed layer to SHP file.")
+        print(f"Processed layer exported to SHP file: {output_vector_path}")
+        return {
+            "状态": "拓扑检查成功",
+            "错误项": "条记录",
+            "矢量数据输出位置": output_vector_path,
+            "报告输出位置": ""
+        }
+
+    # 判断数据是否为字符串
+    def is_string(self, var):
+        return isinstance(var, str)
+
+    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 []
+
+    def contains_keys(self, obj, keys):
+        if isinstance(obj, dict):
+            return all(key in obj.keys() for key in keys)
+        elif hasattr(type(obj), '__dict__'):
+            return all(key in obj.__dict__ for key in keys)
+        else:
+            raise ValueError("Invalid object type")
+
+    def commandName(self):
+        return "ogr2ogr"

BIN
processing/images/dbms/topology.png


+ 9 - 0
processing/tools/FileUtils.py

@@ -1,4 +1,7 @@
 # 获取文件名称
+from pathlib import Path
+
+
 def getInputFileName(filepath):
     if "/" in filepath:
         filename = filepath.split("/")[len(filepath.split("/")) - 1]
@@ -6,3 +9,9 @@ def getInputFileName(filepath):
     elif "\\" in filepath:
         filename = filepath.split("\\")[len(filepath.split("\\")) - 1]
         return filename[0: filename.find(".")]
+
+#获取文件夹的父节点路径
+def getParentFolderPath(path):
+    file_path = Path(path)
+    parent_dir = file_path.parent
+    return str(parent_dir)

BIN
processing/tools/Image/1.jpg


BIN
processing/tools/Image/2.jpg


+ 25 - 0
processing/tools/Image/read.py

@@ -0,0 +1,25 @@
+from PIL import Image
+from PIL.ExifTags import TAGS, GPSTAGS
+
+def get_exif_data(image_path):
+    # 打开图片文件
+    image = Image.open(image_path)
+    exif_data = image._getexif()  # 获取 EXIF 数据
+    if not exif_data:
+        return None  # 如果没有 EXIF 数据,返回 None
+
+    # 转换 EXIF 标签为人类可读格式
+    readable_exif = {}
+    for tag_id, value in exif_data.items():
+        tag_name = TAGS.get(tag_id, tag_id)
+        readable_exif[tag_name] = value
+    return readable_exif
+
+# 使用示例
+image_path = "2.jpg"
+exif = get_exif_data(image_path)
+if exif:
+    for key, value in exif.items():
+        print(f"{key}: {value}")
+else:
+    print("No EXIF data found.")

BIN
processing/tools/Image/temp.jpg


BIN
processing/tools/Image/test.jpg


+ 0 - 0
processing/tools/topology/__init__.py


+ 51 - 0
processing/tools/topology/read.py

@@ -0,0 +1,51 @@
+import yaml
+
+topoCheckData = None
+
+
+# 读取yaml
+def read_yaml_file(filepath):
+    with open(filepath, 'r') as file:
+        data = yaml.load(file, Loader=yaml.FullLoader)
+    return data
+
+
+# 调用示例
+topoCheckData = read_yaml_file(
+    "D:\\Program Files\\QGIS 3.34.9\\apps\\qgis-ltr\\python\\plugins\\processing\\tools\\topology\\topoCheck.yaml")
+print(topoCheckData)
+print(topoCheckData["topoCheck"]["A03"])
+
+
+def getTopoCheckSQL(type, my_dict):
+    # sqllist = []
+    data = topoCheckData["topoCheck"][type]
+    tempSql = data["ALG"]
+    for key in my_dict:
+        value = my_dict[key]
+        k = f"@{key}@"
+        tempSql = tempSql.replace(k, value)
+    return tempSql
+
+#获取description
+def getTopoCheckDescription(type):
+    # sqllist = []
+    data = topoCheckData["topoCheck"][type]
+    description = data["UI"]["description"]
+    return description
+
+#获取note
+def getTopoCheckNote(type):
+    # sqllist = []
+    data = topoCheckData["topoCheck"][type]
+    note = data["note"]
+    return note
+
+# my_dict = {
+#     "intable_s": "topology_table",
+#     "outtable": "topology_table_temp"
+# }
+# sql = getTopoCheckSQL("A03", my_dict)
+# print(sql)
+# for s in sql.split(";"):
+#     print(s)

+ 31 - 0
processing/tools/topology/spatialite.py

@@ -0,0 +1,31 @@
+import sqlite3
+
+# Path to your SpatiaLite database
+db_path = "D:\\temp\\output.sqlite"
+
+# Connect to the SQLite database
+conn = sqlite3.connect(db_path)
+
+# Enable loading of extensions
+conn.enable_load_extension(True)
+
+# Load the SpatiaLite extension
+try:
+    conn.execute("SELECT load_extension('mod_spatialite');")
+    print("SpatiaLite extension loaded successfully!")
+except sqlite3.OperationalError as e:
+    print(f"Error loading SpatiaLite extension: {e}")
+
+# Create a cursor to execute queries
+cursor = conn.cursor()
+
+# Example: Check SpatiaLite version
+cursor.execute("drop table if exists topology_table_temp;")
+cursor.execute("create table topology_table_temp(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,idx,rulecode,geometry MULTILINESTRING);")
+cursor.execute("with t as( select 0 sid, 0 did, numgeometries(linesfromrings(gunion(geometry))) cnt, linesfromrings(gunion(geometry)) geometry from topology_table ), cte(idx, sid, did, cnt, geometry, subgeom) AS ( SELECT 1 idx, sid, did, cnt, geometry, geometryN(geometry, 1) subgeom from t UNION ALL SELECT idx + 1 idx, sid, did, cnt, geometry, geometryN(geometry, idx + 1) subgeom FROM cte WHERE idx < cnt ) insert into topology_table_temp SELECT null,createuuid(),isvalid(casttomulti(subgeom)), sid, idx, 'A03' rulecode, casttomulti(subgeom) geometry FROM cte; ")
+cursor.execute("select recovergeometrycolumn('topology_table_temp', 'geometry',  (select srid from geometry_columns where f_table_name = 'topology_table'), 'MULTILINESTRING', 'XY');")
+# version = cursor.fetchone()
+# print(f"SpatiaLite version: {version[0]}")
+
+# Close the connection when done
+conn.close()

+ 3110 - 0
processing/tools/topology/topoCheck.yaml

@@ -0,0 +1,3110 @@
+version:
+  provider: 第八开发小组
+  lastupdated: [2023-1-3,]
+  name: 拓扑检查
+
+topoCheck:
+    P00:
+        note: "点图层有效性"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:               
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+      
+            select SqlProc_execute(SqlProc_FromText('drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode);
+            select AddGeometryColumn(''@outtable@'',''geometry'',@@intable_s@_srid@,''POINT'',''XY'');
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,pieid sid,''P00'' rulecode, geometry
+            from @intable_s@ where geometrytype(geometry) = ''POINT'' and isvalid(geometry) <> 1;'))"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入点图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "P00.png"
+          icon: "processingAlgorithm.png"
+          description: "说明:点要素不能无效。"
+
+    P01:
+        note: "点必须不能相交(单点)"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry POINT);
+            with t as(
+            select c.PIEUUID,c.PIEVALIDED,c.pieid sid, d.pieid did,'P01' rulecode, c.geometry geometry
+            from  idx_@intable_s@_geometry a, idx_@intable_s@_geometry b, @intable_s@ c, @intable_s@ d
+            where c.pievalided and d.pievalided and a.rowid < b.rowid
+            and (a.xmax >= b.xmin and a.xmin <= b.xmax and a.ymax >= b.ymin and a.ymin <= b.ymax)
+            and a.rowid = c.rowid and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry)
+            and geometrytype(c.geometry) = 'POINT'
+            and geometrytype(d.geometry) = 'POINT')
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,sid,did,rulecode,geometry from t;
+            
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'))"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入点图层
+              description: 
+              defaultValue: 
+              help: 
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "P01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明:一个图层中的点要素不能与同一图层中的点要素重合。被另一个点覆盖的任何点都是错误的。"
+
+    L00:
+        note: "线图层有效性"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+      
+            select SqlProc_execute(SqlProc_FromText('drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode);
+            select AddGeometryColumn(''@outtable@'',''geometry'',@@intable_s@_srid@,''LINESTRING'',''XY'');
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,pieid sid,''L00'' rulecode, geometry geometry
+            from @intable_s@ where isvalid(geometry) <> 1;'))"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "L00.png"
+          icon: "processingAlgorithm.png"
+          description: "说明:线要素不能无效"
+
+    L01:
+        note: "线不能有悬挂点"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry POINT);
+            with d as (
+            select PIEUUID,pieid,
+            's' || pieid  flag,
+            startpoint(geometry) geometry
+            from @intable_s@ where  pievalided and not isring(geometry)
+            union
+            select PIEUUID, pieid,
+            'e' || pieid flag,
+            endpoint(geometry)
+            from @intable_s@ where  pievalided and not isring(geometry)
+            ),
+            u as (
+            select d.pieid sid,flag,
+            g.pieid did,
+            intersection(d.geometry, g.geometry) geometry
+            from d,
+            idx_@intable_s@_geometry t,
+            @intable_s@ as g
+            where X(d.geometry) between t.xmin and t.xmax
+            and Y(d.geometry) between t.ymin and t.ymax
+            and t.rowid = g.rowid
+            and intersects(d.geometry, g.geometry) = 1
+            and d.pieid <> g.pieid
+            and g.pievalided
+            union
+            select pieid,
+            's' || pieid  flag,
+            null did,
+            startpoint(geometry) geometry
+            from @intable_s@
+            where numpoints(geometry) > 2 and pievalided
+            and intersects(startpoint(geometry), removepoint(geometry, 0)) = 1
+            and not isring(geometry)
+            union
+            select pieid,
+            'e' || pieid  flag,
+            null did,
+            endpoint(geometry) geometry
+            from @intable_s@
+            where numpoints(geometry) > 2 and pievalided
+            and intersects(
+            endpoint(geometry),
+            removepoint(geometry, numpoints(geometry) -1)
+            ) = 1
+            and not isring(geometry)
+            )
+            insert into @outtable@
+            select null,PIEUUID,isvalid(geometry),pieid sid, flag did, 'L01' rulecode, geometry
+            from d
+            where flag not in (select flag from u);
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "L01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明:一个图层中的线必须在两个端点处与同一图层中的其他线接触。线的任何端点未与其他线接触都是错误的。"
+
+    L02:
+        note: "线不能有伪节点"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+            
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry POINT);
+            with t as
+            (
+            select PIEUUID, sid, did, rulecode, geometry from
+            (
+            select PIEUUID, id1 sid,id2 did,'L02' rulecode, inter geometry from
+            (
+            select PIEUUID, id1, group_concat( casttotext( within(inter, gc) + within(inter, gd) ) , '_')   id2 , inter
+            from
+            (
+            select c.PIEUUID PIEUUID, c.pieid id1, d.pieid id2,c.geometry gc, d.geometry gd,
+            intersection(c.geometry, d.geometry) inter
+            from idx_@intable_s@_geometry a, idx_@intable_s@_geometry b, @intable_s@ c, @intable_s@ d
+            where a.rowid < b.rowid
+            and (a.xmin < b.xmax and a.xmax > b.xmin  and  a.ymin < b.ymax and  a.ymax > b.ymin)
+            and a.rowid = c.rowid and b.rowid = d.rowid
+            and touches(c.geometry, d.geometry)
+            ) t1
+            group by inter
+            ) t2
+            where geometrytype( inter ) = 'POINT' and id2='0'
+            union
+            select PIEUUID,pieid sid, null did ,'L02' rulecode, startpoint(geometry) geometry
+            from @intable_s@
+            where not isring(geometry) and st_npoints(geometry) > 2
+            and  touches( startpoint(geometry), removepoint(geometry, 0) ) = 1
+            union
+            select PIEUUID, pieid sid, null did ,'L02' rulecode, endpoint(geometry) geometry
+            from @intable_s@
+            where not isring(geometry) and st_npoints(geometry) > 2
+            and touches( endpoint(geometry),  removepoint(geometry, st_npoints(geometry)-1 ) ) = 1
+            order by id1))
+            insert into @outtable@
+            select null,PIEUUID,isvalid(geometry),sid,did,rulecode,geometry from t;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "L02.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的线必须在其端点处与同一图层中的多条线接触。线的任何端点仅与一条其他线接触都是错误的。"
+
+    L03:
+        note: "线必须为单一部分"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+            
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry MULTILINESTRING);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,pieid sid,'L03' rulecode, casttomulti(geometry) geometry from @intable_s@
+            where pievalided and geometry is not null and casttosingle(geometry) is null;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''MULTILINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "L03.png"
+          icon: "processingAlgorithm.png"
+          description: "说明:一个图层中的线要素不能具有一个以上的构成部分。任何具有超过一个构成部分的线要素都是错误的。"
+
+    L04:
+        note: "线不能重叠(线)"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtableP:
+              meaning: 输出点错误表的名字
+              type: B
+          - outtableL:
+              meaning: 输出线错误表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtableP@=输出点错误表的名字','@outtableL@=输出线错误表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop view if exists tempTableC; 
+            create view tempTableC as
+            WITH cte(idx, sid, did,cnt,geometry,point) AS
+            (
+            SELECT 1 idx, sid, did ,cnt, geometry, geometryN(geometry, 1) point from
+            (
+            select c.pieid sid, d.pieid did,numGeometries(intersection(c.geometry, d.geometry))  cnt,
+            intersection(c.geometry, d.geometry) geometry
+            from idx_@intable_s@_geometry a,idx_@intable_s@_geometry b, @intable_s@ c, @intable_s@ d
+            where a.rowid < b.rowid and c.pievalided and d.pievalided
+            and (a.xmax >= b.xmin and a.xmin <= b.xmax and a.ymax >= b.ymin and a.ymin <= b.ymax)
+            and a.rowid = c.rowid and b.rowid = d.rowid
+            and   intersects(c.geometry, d.geometry) = 1 and overlaps(c.geometry, d.geometry)  = 1
+            ) t
+            UNION ALL
+            SELECT idx + 1 idx, sid, did, cnt,geometry,  geometryN(geometry , idx +1 ) point FROM cte
+            WHERE idx < cnt
+            )
+            SELECT sid, did
+            , case geometrytype(casttomulti( point)) when 'MULTIPOINT' then '0' when 'MULTILINESTRING' then '1' end as rulecode,
+            casttomulti( point)  geometry
+            FROM cte;
+            
+            drop table if exists @outtable@_P; 
+            create table @outtable@_P(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry MULTIPOINT);
+            insert into @outtable@_P
+            SELECT null,createuuid(),isvalid(geometry),sid, did, 'L04' rulecode, geometry
+            FROM tempTableC where rulecode = '0';
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@_P'', ''geometry'', @@intable_s@_srid@, ''MULTIPOINT'', ''XY'');'));
+            
+            drop table if exists @outtable@_L; 
+            create table @outtable@_L(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry MULTILINESTRING);
+            insert into @outtable@_L
+            SELECT null,createuuid(),isvalid(geometry),sid, did, 'L04' rulecode, geometry
+            FROM tempTableC where rulecode = '1';
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@_L'', ''geometry'', @@intable_s@_srid@, ''MULTILINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help: 
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "L04.png"
+          icon: "processingAlgorithm.png"
+          description: "说明:一个图层中的线不能与同一图层中的线重叠。任何重叠的线都是错误的。"
+
+    L05:
+        note: "线不能相交(线)"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry POINT);
+            with t as
+            (
+            select c.PIEUUID,c.pieid sid, d.pieid did,
+            numGeometries(ExtractMultiPoint(intersection(c.geometry, d.geometry))) cnt,
+            ExtractMultiPoint(intersection(c.geometry, d.geometry)) geometry
+            from idx_@intable_s@_geometry a,idx_@intable_s@_geometry b, @intable_s@  c, @intable_s@ d
+            where a.rowid < b.rowid and c.pievalided and d.pievalided
+            and (a.xmax >= b.xmin and a.xmin <= b.xmax and a.ymax >= b.ymin and a.ymin <= b.ymax)
+            and a.rowid = c.rowid and b.rowid = d.rowid
+            and   intersects(c.geometry, d.geometry) = 1 and crosses(c.geometry, d.geometry)  = 1
+            and ExtractMultiPoint(intersection(c.geometry, d.geometry)) is not null
+            ),
+            cte(PIEUUID,idx, sid, did, cnt,geometry,line) AS
+            (
+            SELECT PIEUUID,1 idx, sid, did,cnt, geometry, geometryN(geometry, 1) line from t
+            UNION ALL
+            SELECT PIEUUID,idx + 1 idx, sid, did, cnt,geometry,  geometryN(geometry , idx +1 ) line FROM cte
+            WHERE idx < cnt
+            )
+            insert into @outtable@
+            SELECT null,PIEUUID,isvalid(line),sid, did,'L05' rulecode, line geometry FROM cte order by sid, did;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "L05.png"
+          icon: "processingAlgorithm.png"
+          description: "说明:同一图层中的线互相之间不能相交或叠置。任何与要素叠置的线或任何相交点都是错误的。"
+
+    L06:
+        note: "线不能自重叠"
+        lastupdated: [2023-1-3,]
+        roadmap: "临时表创建为view无法建立索引,暂时去除索引判断"
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - tolerance:
+              meaning: 容差
+              type: f
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@tolerance@=容差','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists temp_line;
+            create table temp_line(PIEUUID,id integer, idx integer, cnt integer);
+            select AddGeometryColumn('temp_line', 'geometry', 3857, 'LINESTRING', 'XY');
+            select CreateSpatialIndex('temp_line', 'geometry');
+            insert into temp_line(PIEUUID,id, idx,cnt, geometry)
+            WITH t as
+            (select PIEUUID, pieid id, numGeometries(DissolveSegments(geometry)) cnt,  DissolveSegments(geometry) geometry
+            from @intable_s@
+            where numpoints(geometry)  > 2 )
+            ,cte(PIEUUID,idx, id,cnt,geometry,line) AS
+            (
+            SELECT PIEUUID,1 idx, id ,cnt, geometry, geometryN(geometry, 1) line from t
+            UNION ALL
+            SELECT PIEUUID,idx + 1 idx, id, cnt,geometry,  geometryN(geometry , idx +1 ) line FROM cte
+            WHERE idx < cnt
+            )
+            SELECT PIEUUID,id, idx, cnt,transform(line,3857) geometry FROM cte order by id, idx;
+
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,idx,rulecode,geometry MULTILINESTRING);
+            with t1 as(
+            select c.PIEUUID,c.id sid, (c.idx || '_' || d.idx) idx, collect(c.geometry, d.geometry) geom,
+            abs(degrees(azimuth(startpoint(c.geometry), endpoint(c.geometry)) - azimuth(startpoint(d.geometry), endpoint(d.geometry)))) angle,
+            abs( ST_MaxDistance(c.geometry, d.geometry) - st_length(c.geometry) - st_length(d.geometry)) maxdist,
+            ExtractMultiLinestring(intersection(c.geometry, d.geometry)) inter
+            from idx_temp_line_geometry a, idx_temp_line_geometry b, temp_line c, temp_line d
+            where (a.xmax >= b.xmin and a.xmin <= b.xmax and a.ymax >= b.ymin and a.ymin <= b.ymax)
+            and a.rowid = c.rowid and b.rowid = d.rowid
+            and c.id = d.id and c.idx < d.idx
+            and (( abs(c.idx - d.idx) > 1 and abs(c.idx - d.idx) <> c.cnt - 1 and st_distance(c.geometry, d.geometry) <  @tolerance@ )
+            or (inter is not null) )
+            order by c.id, c.idx, d.idx
+            ),
+            t2 as(
+            select PIEUUID, sid, idx, 'L06' rulecode, casttomulti(transform(geom,CastToInteger(StoredVar_GetValue('@intable_s@_srid')))) geometry from t1
+            where (angle < 2.0 or abs( angle - 180.0 ) < 2.0 ) and maxdist > @tolerance@)
+            insert into @outtable@
+            select null,PIEUUID,isvalid(geometry),sid,idx,rulecode,geometry from t2;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''MULTILINESTRING'', ''XY'');'))"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: double
+              ARG: tolerance
+              name: 容差
+              description: 
+              defaultValue: 
+              help: 
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "L06.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的线要素不能自相交或自叠置。任何存在要素自叠置的线都是错误的。"
+
+    L07:
+        note: "线不能自相交"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,id,idx,rulecode,geometry POINT);
+            with t as(
+            select PIEUUID, pieid as id,
+            numGeometries(ST_SelfIntersections(geometry)) cnt,
+            ST_SelfIntersections(geometry) geometry
+            from @intable_s@
+            where ST_SelfIntersections(geometry) is not null),
+            cte(PIEUUID,idx, id,cnt,geometry,line) AS
+            (
+            SELECT PIEUUID, 1 idx, id, cnt, geometry, geometryN(geometry, 1) line from t
+            UNION ALL
+            SELECT PIEUUID,idx + 1 idx, id, cnt,geometry,  geometryN(geometry , idx +1 ) line FROM cte
+            WHERE idx < cnt
+            )
+            insert into @outtable@
+            SELECT null,PIEUUID,isvalid(line),id,idx,'L07' rulecode, line geometry FROM cte order by id, idx;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'))"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "L07.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的线要素不能自相交。任何存在要素自叠置的线或要素自相交的点都是错误的。"
+
+    L08:
+        note: "线不能相交或者内部相连"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtableP:
+              meaning: 输出点错误表的名字
+              type: B
+          - outtableL:
+              meaning: 输出线错误表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtableP@=输出点错误表的名字','@outtableL@=输出线错误表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop view if exists L08view;
+            create view L08view as
+            select c.pieid sid, d.pieid did,
+            numGeometries( intersection( c.geometry, d.geometry )) cnt,
+            intersection( c.geometry, d.geometry ) geometry
+            from idx_@intable_s@_geometry a, idx_@intable_s@_geometry b, @intable_s@ as c, @intable_s@ as d
+            where a.rowid < b.rowid
+            and (a.xmin < b.xmax and a.xmax > b.xmin  and  a.ymin < b.ymax and  a.ymax > b.ymin)
+            and a.rowid = c.rowid and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry )
+            and relate(c.geometry, d.geometry) not like 'FF_F0____'
+            ;
+
+            drop table if exists @outtable@_P; 
+            create table @outtable@_P(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry POINT);
+            with t as (select sid,did,cnt, geometry geometry
+            from L08view
+            where geometrytype(geometry) like '%POINT')
+            , cte as         (
+            SELECT 1 idx, sid, did, cnt, geometry, geometryN(geometry, 1) line from t
+            UNION ALL
+            SELECT idx + 1 idx, sid, did,cnt,geometry,  geometryN(geometry , idx + 1 ) line FROM cte
+            WHERE idx < cnt
+            )
+            insert into @outtable@_P
+            select null,createuuid(),isvalid(line),sid,did,'L08' rulecode,line geometry from cte
+            order by sid, did, idx;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@_P'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));
+
+            drop table if exists @outtable@_L; 
+            create table @outtable@_L(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry MULTILINESTRING);
+            insert into @outtable@_L
+            select null,createuuid(),isvalid(ExtractMultiLinestring(geometry)), sid,did, 'L08' rulecode, ExtractMultiLinestring(geometry) geometry
+            from L08view
+            where geometrytype(geometry) like '%LINESTRING'
+            order by sid, did;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@_L'', ''geometry'', @@intable_s@_srid@, ''MULTILINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "L08.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的线必须在其端点处与同一图层中的其他线相接触。任何与要素叠置的线或任何相交点都是错误的。"
+
+    L09:
+        note: "线线相交交点处必须存在节点"
+        lastupdated: [2023-1-3,]
+        roadmap: "存在问题,临时表创建为view无法建立索引,最后的判断无法进行"
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists temp_points;
+            create table temp_points(id integer, idx integer);
+            select SqlProc_execute(SqlProc_FromText('select AddGeometryColumn(''temp_points'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));
+            select CreateSpatialIndex('temp_points', 'geometry');
+            insert into temp_points(id, idx, geometry)
+            WITH t as (
+            select pieid id,
+            numGeometries(DissolvePoints(geometry)) cnt,
+            DissolvePoints(geometry) geometry
+            from @intable_s@
+            ),
+            cte(idx, id, cnt, geometry, point) AS (
+            SELECT 1 idx,
+            id,
+            cnt,
+            geometry,
+            geometryN(geometry, 1) point
+            from t
+            UNION ALL
+            SELECT idx + 1 idx,
+            id,
+            cnt,
+            geometry,
+            geometryN(geometry, idx + 1) point
+            FROM cte
+            WHERE idx < cnt
+            )
+            SELECT id,
+            idx,
+            point geometry
+            FROM cte
+            order by id,
+            idx;
+            drop table if exists temp_points_other;
+            create table temp_points_other(id integer, idx integer);
+            select SqlProc_execute(SqlProc_FromText('select AddGeometryColumn(''temp_points_other'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));
+            select CreateSpatialIndex('temp_points_other', 'geometry');
+            insert into temp_points_other(id, idx, geometry)
+            WITH t as (
+            select c.pieid * 100000 + d.pieid id,
+            numgeometries(ExtractMultiPoint(intersection(c.geometry, d.geometry))) cnt,
+            ExtractMultiPoint(intersection(c.geometry, d.geometry)) geometry
+            from idx_@intable_s@_geometry a,
+            idx_@intable_s@_geometry b,
+            @intable_s@ as c,
+            @intable_s@ as d
+            where a.rowid < b.rowid
+            and (
+            a.xmin <= b.xmax
+            and a.xmax >= b.xmin
+            and a.ymin <= b.ymax
+            and a.ymax >= b.ymin
+            )
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and crosses(c.geometry, d.geometry) = 1
+            and ExtractMultiPoint(intersection(c.geometry, d.geometry)) is not null
+            ),
+            cte(idx, id, cnt, geometry, point) AS (
+            SELECT 1 idx,
+            id,
+            cnt,
+            geometry,
+            geometryN(geometry, 1) point
+            from t
+            UNION ALL
+            SELECT idx + 1 idx,
+            id,
+            cnt,
+            geometry,
+            geometryN(geometry, idx + 1) point
+            FROM cte
+            WHERE idx < cnt
+            )
+            SELECT id,
+            idx,
+            point geometry
+            FROM cte
+            order by id,
+            idx;
+
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,id,idx,rulecode,geometry POINT);
+            insert into @outtable@
+            select null,createuuid(),isvalid(geometry),id,
+            idx,
+            'L09' rulecode,
+            geometry
+            from temp_points_other
+            where rowid not in (
+            select a.rowid
+            from idx_temp_points_other_geometry a,
+            idx_temp_points_geometry b
+            where (
+            a.xmin < b.xmax
+            and a.xmax > b.xmin
+            and a.ymin < b.ymax
+            and a.ymax > b.ymin
+            )
+            );
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "L09.png"
+          icon: "processingAlgorithm.png"
+          description: "说明:一个图层中的线如果存在相交的情况,那么在相交处必须存在节点。任何不存在节点的相交线都是错误的。"
+
+    L10:
+        note: "线节点距离必须大于聚合阈值"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - tolerance:
+              meaning: 容差
+              type: f
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@tolerance@=容差','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,id,idx,length,rulecode,geometry LINESTRING);
+            WITH t as (
+            select PIEUUID, pieid id,
+            numGeometries(DissolveSegments(geometry)) cnt,
+            DissolveSegments(geometry) geometry
+            from @intable_s@
+            ),
+            cte(PIEUUID,idx, id, cnt, geometry, line) AS (
+            SELECT PIEUUID,
+            1 idx,
+            id,
+            cnt,
+            geometry,
+            geometryN(geometry, 1) line
+            from t
+            UNION ALL
+            SELECT PIEUUID,
+            idx + 1 idx,
+            id,
+            cnt,
+            geometry,
+            geometryN(geometry, idx + 1) line
+            FROM cte
+            WHERE idx < cnt
+            )
+            insert into @outtable@
+            SELECT null,PIEUUID,isvalid(line), id,
+            idx,
+            st_length(transform(line,3857)) length,
+            'L10' rulecode,
+            line geometry
+            FROM cte
+            where st_length(transform(line,3857)) < @tolerance@
+            order by id,
+            idx;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''LINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: double
+              ARG: tolerance
+              name: 容差
+              description: 
+              defaultValue: 
+              help: 
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "L10.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 线节点距离必须大于拓扑容差值,这样两个节点自动连接在一起,避免有缝隙出现。任何两个小于拓扑容差距离的线节点都是错误的。"
+
+    A00:
+        note: "面有效性检查"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode);
+            select AddGeometryColumn('@outtable@','geometry',(select srid from geometry_columns where f_table_name = '@intable_s@') ,'POLYGON','XY');
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,pieid sid,'A00' rulecode, geometry geometry
+            from @intable_s@ where isvalid(geometry) <> 1;"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "A00.png"
+          icon: "processingAlgorithm.png"
+          description: "<br/>说明: 面要素不能无效"
+    A01:
+        note: "面不能重叠"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry POLYGON);
+            with t as(
+            select c.PIEUUID,c.pieid sid, d.pieid did,
+            numGeometries(intersection(c.geometry, d.geometry)) cnt,
+            intersection(c.geometry, d.geometry) geometry
+            from idx_@intable_s@_geometry a,
+            idx_@intable_s@_geometry b,
+            @intable_s@ as c,
+            @intable_s@ as d
+            where a.rowid < b.rowid
+            and (
+            a.xmin < b.xmax
+            and a.xmax > b.xmin
+            and a.ymin < b.ymax
+            and a.ymax > b.ymin
+            )
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry) = 1
+            and ST_Dimension(intersection(c.geometry, d.geometry)) > 1
+            ),
+            cte(PIEUUID,idx, sid,did, cnt, geometry, subgeom) AS (
+            SELECT PIEUUID,
+            1 idx,
+            sid,
+            did,
+            cnt,
+            geometry,
+            geometryN(geometry, 1) subgeom
+            from t
+            UNION ALL
+            SELECT PIEUUID,
+            idx + 1 idx,
+            sid,
+            did,
+            cnt,
+            geometry,
+            geometryN(geometry, idx + 1) subgeom
+            FROM cte
+            WHERE idx < cnt
+            )
+            insert into @outtable@
+            SELECT null,PIEUUID,isvalid(subgeom),sid,
+            did,
+            'A01' rulecode,
+            subgeom geometry
+            FROM cte
+            where geometrytype(subgeom) = 'POLYGON'
+            order by sid,
+            did;
+            select recovergeometrycolumn('@outtable@', 'geometry',(select srid from geometry_columns where f_table_name = '@intable_s@'), 'POLYGON', 'XY');"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "A01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个区域不能与同一图层的另一个区域叠置。任何存在要素重叠的区域都是错误的。"
+
+    A02:
+        note: "面自身不能有内洞"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,ringNum,rulecode,geometry POLYGON);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,pieid sid, NumInteriorRing(geometry) ringNum, 'A02' rulecode, geometry geometry
+            from  @intable_s@
+            where NumInteriorRing(geometry)  > 0
+            order by sid;
+            select recovergeometrycolumn('@outtable@', 'geometry', (select srid from geometry_columns where f_table_name = '@intable_s@'), 'POLYGON', 'XY');"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "A02.png"
+          icon: "processingAlgorithm.png"
+          description: "<br/>说明:一个区域内部不能出现空的情况。任何存在空的区域都是错误的。"
+
+    A03:
+        note: "面不能有空隙"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,idx,rulecode,geometry MULTILINESTRING);
+            with t as(
+            select 0 sid,
+            0 did,
+            numgeometries(linesfromrings(gunion(geometry))) cnt,
+            linesfromrings(gunion(geometry)) geometry
+            from @intable_s@
+            ),
+            cte(idx, sid, did, cnt, geometry, subgeom) AS (
+            SELECT 1 idx,
+            sid,
+            did,
+            cnt,
+            geometry,
+            geometryN(geometry, 1) subgeom
+            from t
+            UNION ALL
+            SELECT idx + 1 idx,
+            sid,
+            did,
+            cnt,
+            geometry,
+            geometryN(geometry, idx + 1) subgeom
+            FROM cte
+            WHERE idx < cnt
+            )
+            insert into @outtable@
+            SELECT null,createuuid(),isvalid(casttomulti(subgeom)),
+            sid,
+            idx,
+            'A03' rulecode,
+            casttomulti(subgeom) geometry
+            FROM cte;
+            select recovergeometrycolumn('@outtable@', 'geometry',  (select srid from geometry_columns where f_table_name = '@intable_s@'), 'MULTILINESTRING', 'XY');"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "A03.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 同一图层中的区域之间不能存在空隙。存在任何空隙的边界都是错误的。"
+
+    A04:
+        note: "面不能自相交"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode);
+            select AddGeometryColumn('@outtable@','geometry', (select srid from geometry_columns where f_table_name = '@intable_s@'),'POLYGON','XY');
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,
+            pieid sid,
+            'A04' rulecode,
+            geometry geometry
+            from @intable_s@
+            where ST_NumPoints(linesfromrings(geometry)) > 3
+            and ST_SelfIntersections(linesfromrings(geometry)) is not null;"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "A04.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的面要素不能自相交。任何存在要素自叠置的面或要素自相交的点都是错误的。"
+
+    A05:
+        note: "面节点距离必须大于聚合阈值"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - tolerance:
+              meaning: 容差
+              type: f
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@tolerance@=容差','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,id,idx,length,rulecode,geometry LINESTRING);
+            WITH t as (
+            select PIEUUID,pieid id,
+            numGeometries(DissolveSegments(geometry)) cnt,
+            DissolveSegments(geometry) geometry
+            from @intable_s@
+            ),
+            cte(PIEUUID,idx, id, cnt, geometry, line) AS (
+            SELECT PIEUUID,
+            1 idx,
+            id,
+            cnt,
+            geometry,
+            geometryN(geometry, 1) line
+            from t
+            UNION ALL
+            SELECT PIEUUID,
+            idx + 1 idx,
+            id,
+            cnt,
+            geometry,
+            geometryN(geometry, idx + 1) line
+            FROM cte
+            WHERE idx < cnt
+            )
+            insert into @outtable@
+            SELECT null,PIEUUID,isvalid(line),
+            id,
+            idx,
+            st_length(transform(line,3857)) length,
+            'A05' rulecode,
+            line geometry
+            FROM cte
+            where st_length(transform(line,3857)) < @tolerance@
+            order by id,
+            idx;
+            select recovergeometrycolumn('@outtable@', 'geometry', (select srid from geometry_columns where f_table_name = '@intable_s@'), 'LINESTRING', 'XY');"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: double
+              ARG: tolerance
+              name: 容差
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "A05.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 面节点距离必须大于容差值,这样两个节点自动连接在一起,避免多边形有缝隙出现。任何两个小于容差距离的节点都是错误的。"
+
+    PP01:
+        note: "点必须被其他要素类覆盖(点-点)"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry POINT);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED, pieid sid,'PP01' rulecode, geometry from @intable_s@ where rowid not in
+            (select a.rowid
+            from  idx_@intable_s@_geometry a, idx_@intable_t@_geometry b, @intable_s@ c, @intable_t@ d
+            where (a.xmax >= b.xmin and a.xmin <= b.xmax and a.ymax >= b.ymin and a.ymin <= b.ymax)
+            and a.rowid = c.rowid and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry)
+            and geometrytype(c.geometry) = 'POINT'
+            and geometrytype(d.geometry) = 'POINT');
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入点图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标点图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "PP01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的点要素必须被另一个图层中的点要素重合。第一个图层中未被第二个图层中的点覆盖的任何点都是错误的。"
+
+    PP02:
+        note: "点不与其他要素点重合(点-点)"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,count,rulecode,geometry POINT);
+            with t as
+            (
+            select c.PIEUUID,c.PIEVALIDED,c.pieid sid, count(d.pieid ) count, 'PP02' rulecode, c.geometry geometry
+            from  idx_@intable_s@_geometry a, idx_@intable_t@_geometry b,
+            @intable_s@ c, @intable_t@ d
+            where (a.xmax >= b.xmin and a.xmin <= b.xmax and a.ymax >= b.ymin and a.ymin <= b.ymax)
+            and a.rowid = c.rowid and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry)
+            and geometrytype(c.geometry) = 'POINT'
+            and geometrytype(d.geometry) = 'POINT'
+            group by c.pieid)
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,sid,count,rulecode,geometry from t;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入点图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标点图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "PP02.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的点要素不与另一个图层中的点要素重合。第一个图层中被第二个图层中的点覆盖的任何点都是错误的。"
+
+    PL01:
+        note: "点必须被其他要素类的端点覆盖(点-线)"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry POINT);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,
+            pieid sid,
+            'PL01' rulecode,
+            geometry
+            from @intable_s@
+            where rowid not in(
+            select a.rowid
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and touches(c.geometry, d.geometry)
+            );
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入点图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "PL01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的点要素必须被另一个图层的线要素的端点覆盖。如果点图层中的要素未落在线要素端点上,则是错误的。"
+
+    PL02:
+        note: "点必须被线覆盖(点-线)"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry POINT);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,
+            pieid sid,
+            'PL02' rulecode,
+            geometry
+            from @intable_s@
+            where rowid not in(
+            select a.rowid
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry)
+            and  not touches(c.geometry, d.geometry)
+            );
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入点图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "PL02.png"
+          icon: "processingAlgorithm.png"
+          description: "算说明: 一个图层中的点要素必须被另一个图层中的线要素覆盖。任何未被线要素覆盖的点都是错误的。"
+
+    PA01:
+        note: "点必须被其他要素的边界覆盖(点-面)"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry POINT);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,
+            pieid sid,
+            'PA01' rulecode,
+            geometry
+            from @intable_s@
+            where rowid not in(
+            select a.rowid
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and touches(c.geometry, d.geometry)
+            );
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入点图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "PA01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的点要素必须与另一个图层中面要素的边界重合。如果点图层中的要素未落在边界上,则它是错误的。"
+
+    PA02:
+        note: "点必须完全位于面内部(点-面)"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') 
+        and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry POINT);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,
+            pieid sid,
+            'PA02' rulecode,
+            geometry
+            from @intable_s@
+            where rowid not in(
+            select a.rowid
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and within(c.geometry, d.geometry)
+            and not touches(c.geometry, d.geometry)
+            );
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入点图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "PA02.png"
+          icon: "processingAlgorithm.png"
+          description: "说明:一个图层中的点要素必须完全位于另一个图层的面要素内。未在面要素内的任何点都是错误的。"
+
+    PA03:
+        note: "点不在面内部或边界(点-面)"
+        lastupdated: [2023-1-3,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry POINT);
+            with t as
+            (
+            select c.PIEUUID,c.PIEVALIDED, c.pieid sid, group_concat(d.pieid, '-') did,'PA03' rulecode,c.geometry geometry
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry)
+            group by sid)
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,sid,did,rulecode,geometry from t;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入点图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "PA03.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的点要素不能位于另一个图层的面要素内部或边界。在面要素内部和边界的任何点都是错误的。"
+
+    LP01:
+        note: "线端点必须被其他要素覆盖(线-点)"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry LINESTRING);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,
+            pieid sid,
+            'LP01' rulecode,
+            geometry geometry
+            from @intable_s@
+            where rowid not in(
+            select rowid from (
+            select a.rowid,count(*) cnt
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and touches(c.geometry, d.geometry)
+            group by a.rowid
+            having cnt > 1)
+            );
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''LINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标点图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "LP01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中线的端点必须被另一个图层中的点要素覆盖。任何未被点要素覆盖的端点都是错误的。"
+
+    LL01:
+        note: "线不能与其他要素线相交(线-线)"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry POINT);
+            with t as (
+            select c.pieid * 100000 + d.pieid id,
+            numGeometries(intersection(c.geometry, d.geometry)) cnt,
+            intersection(c.geometry, d.geometry) geometry
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and crosses(c.geometry, d.geometry)
+            ),
+            cte(idx, id, cnt, geometry, line) AS (
+            SELECT 1 idx,
+            id,
+            cnt,
+            geometry,
+            geometryN(geometry, 1) line
+            from t
+            UNION ALL
+            SELECT idx + 1 idx,
+            id,
+            cnt,
+            geometry,
+            geometryN(geometry, idx + 1) line
+            FROM cte
+            WHERE idx < cnt
+            )
+            insert into @outtable@
+            SELECT null,createuuid(),isvalid(line),
+            id sid,
+            idx did,
+            'LL01' rulecode,
+            line geometry
+            FROM cte
+            order by id,
+            idx;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "LL01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的线不能与另一个图层中的线相交。第二个图层中的要素与第一个图层中的要素相交的任何线都是错误的。"
+
+    LL02:
+        note: "线必须被其他要素类的要素覆盖(线-线)"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop view if exists LL02view; create view LL02view as
+            select c.pieid sid,c.geometry cg, d.pieid did, d.geometry dg
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry)
+            order by c.pieid;
+
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry MULTILINESTRING);
+            with sel as
+            (
+            select sid from LL02view where overlaps(cg,dg) union
+            select pieid from @intable_s@ where pieid not in(
+            SELECT sid FROM LL02view where equals(cg, dg)  or overlaps(cg, dg)
+            )
+            ), t as
+            (
+            select c.pieid sid,c.geometry cg, d.pieid did, d.geometry dg
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where c.pieid in sel
+            and a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            order by sid, did
+            ),u as
+            (
+            select sid, st_difference(cg , gunion(dg) ) geom from t
+            group by sid
+            )
+            insert into @outtable@
+            select null,createuuid(),isvalid(ExtractMultiLinestring(geom)),sid,'LL02' rulecode, ExtractMultiLinestring(geom) geometry
+            from u
+            where ExtractMultiLinestring(geom) is not null;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''MULTILINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "LL02.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的线必须与另一个图层中的线重合。第一个图层中有任何线未与第二个图层的线重合都是错误的。"
+
+    LL03:
+        note: "线不能与其他要素重叠(线-线)"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry MULTILINESTRING);
+            with t as
+            (
+            select c.pieid sid, d.pieid did, 'LL03' rulecode,
+            ExtractMultiLinestring(intersection(c.geometry, d.geometry)) geometry
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry) = 1
+            and ST_Dimension(intersection(c.geometry,d.geometry)) = 1)
+            insert into @outtable@
+            select null,createuuid(),isvalid(geometry),sid,did,rulecode,geometry from t;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''MULTILINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "LL03.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的线不能与另一个图层中的线重叠。第二个图层中的要素与第一个图层中的要素重叠处的任何线都是错误的。"
+
+    LL04:
+        note: "线不能与其他要素相交或内部相连"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtableP:
+              meaning: 输出点错误表的名字
+              type: B
+          - outtableL:
+              meaning: 输出线错误表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtableP@=输出点错误表的名字','@outtableL@=输出线错误表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop view if exists LL04view;
+            create view LL04view as
+            select c.pieid sid, d.pieid did,
+            numGeometries( intersection( c.geometry, d.geometry )) cnt,
+            intersection( c.geometry, d.geometry ) geometry
+            from idx_@intable_s@_geometry a, idx_@intable_t@_geometry b,
+            @intable_s@ as c, @intable_t@ as d
+            where (a.xmin < b.xmax and a.xmax > b.xmin  and  a.ymin < b.ymax and  a.ymax > b.ymin)
+            and a.rowid = c.rowid and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry )
+            and  relate(c.geometry, d.geometry)  not like 'FF_F0____'
+            ;
+
+            drop table if exists @outtable@_P; 
+            create table @outtable@_P(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry POINT);
+            with t as (select sid,did,cnt, geometry geometry
+            from LL04view
+            where geometrytype(geometry) like '%POINT')
+            , cte as         (
+            SELECT 1 idx, sid, did, cnt, geometry, geometryN(geometry, 1) line from t
+            UNION ALL
+            SELECT idx + 1 idx, sid, did,cnt,geometry,  geometryN(geometry , idx + 1 ) line FROM cte
+            WHERE idx < cnt
+            )
+            insert into @outtable@_P
+            select null,createuuid(),isvalid(line),sid,did,'LL04' rulecode,line geometry from cte
+            order by sid, did, idx;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@_P'', ''geometry'', @@intable_s@_srid@, ''POINT'', ''XY'');'));
+
+            drop table if exists @outtable@_L; 
+            create table @outtable@_L(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry MULTILINESTRING);
+            insert into @outtable@_L
+            select null,createuuid(),isvalid(geometry),sid,did, 'LL04' rulecode, ExtractMultiLinestring(geometry) geometry
+            from LL04view
+            where geometrytype(geometry) like '%LINESTRING'
+            order by sid, did;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@_L'', ''geometry'', @@intable_s@_srid@, ''MULTILINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标线图层
+              description: 
+              defaultValue: 
+              help: 
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "LL04.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的线只能在其端点处与另一图层中的线相接触。任何与要素叠置的线或任何交叉点都是错误的。"
+
+    LA01:
+        note: "线必须完全位于面内部"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry LINESTRING);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,
+            pieid sid,
+            'LA01' rulecode,
+            geometry geometry
+            from @intable_s@
+            where rowid not in(
+            select a.rowid
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and within(c.geometry, d.geometry) = 1
+            and touches(c.geometry, linesfromrings(d.geometry) <> 1)
+            );
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''LINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "LA01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的线必须包含在另一个图层的面要素内。第一个图层中未包含在第二个图层面要素内的任何线都是错误的。"
+
+    LA02:
+        note: "线必须被其他要素的边界覆盖"
+        lastupdated: [2023-1-4,]
+        roadmap: "结果创建的是table而不是view"
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop view if exists LA02view; create view LA02view as
+            select c.pieid sid,c.geometry cg, d.pieid did, linesfromrings(d.geometry) dg
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(c.geometry, linesfromrings(d.geometry))
+            and relate(c.geometry, linesfromrings(d.geometry)) like '1%'
+            order by c.pieid;
+
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry MULTILINESTRING);
+            with t1 as
+            (
+            select sid, group_concat(did, '-') did, 'LA02' rulecode,
+            ExtractMultiLinestring(st_difference(cg, gunion(dg))) geometry
+            from LA02view
+            group by sid
+            having geometry is not null)
+            insert into @outtable@
+            select null,createuuid(),isvalid(geometry),sid,did,rulecode,geometry from t1;
+
+            with t2 as
+            (
+            select PIEUUID,pieid sid, null did, 'LA02' rulecode , ExtractMultiLinestring(geometry) geometry
+            from @intable_s@
+            where pieid not in (select sid from LA02view))
+            insert into @outtable@
+            select null,PIEUUID,isvalid(geometry),sid,did,rulecode,geometry from t2;
+            
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''MULTILINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "LA02.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的线要素必须与另一个图层面要素的边界重合。线图层要素中与面图层边界不重合的任何线都是错误的。"
+
+    LA03:
+        note: "线不能与面重叠"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry MULTILINESTRING);
+            with t as(
+            select c.pieid sid, d.pieid did, 'LA03' rulecode,
+            ExtractMultiLinestring(intersection(c.geometry, d.geometry) ) geometry
+            from idx_@intable_s@_geometry a, idx_@intable_t@_geometry b, @intable_s@ c, @intable_t@ d
+            where a.xmax >= b.xmin and a.xmin <= b.xmax and a.ymax >= b.ymin and a.ymin <= b.ymax
+            and a.rowid = c.rowid  and b.rowid = d.rowid
+            and ( crosses(c.geometry, d.geometry) or within(c.geometry, d.geometry) )
+            and ExtractMultiLinestring(intersection(c.geometry, d.geometry) ) is not null)
+            insert into @outtable@
+            select null,createuuid(),isvalid(geometry),sid,did,rulecode,geometry from t;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''MULTILINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入线图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "LA03.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的线不能与另一个图层中的面重叠。第二个图层中的要素与第一个图层中的要素重叠处的任何区域都是错误的。"
+
+    AP01:
+        note: "面必须包含点"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry POLYGON);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,
+            pieid sid,
+            'AP01' rulecode,
+            geometry geometry
+            from @intable_s@
+            where rowid not in(
+            select a.rowid
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and contains(c.geometry, d.geometry) = 1
+            order by a.rowid
+            );
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POLYGON'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标点图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "AP01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的面要素必须至少包含另一个图层中的一个点要素。任何不包含至少一个点要素的面要素都是错误的。"
+
+    AP02:
+        note: "面只能包含一个点(面的内部的点个数不是1(0,2...))"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry POLYGON);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED,
+            pieid sid,
+            'AP02' rulecode,
+            geometry geometry
+            from @intable_s@
+            where rowid not in(
+            select c.rowid sid
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where (
+            b.xmax >= a.xmin
+            and b.xmin <= a.xmax
+            and b.ymax >= a.ymin
+            and b.ymin <= a.ymax
+            )
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and contains(c.geometry, d.geometry) = 1
+            group by sid
+            having count(d.rowid) = 1
+            );
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POLYGON'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标点图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "AP02.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的面要素必须完全包含另一个图层中的一个点要素。任何未完全包含一个点要素的面要素都是错误的。"
+
+    AL01:
+        note: "面边界必须被其他要素覆盖(面-线)"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry MULTILINESTRING);
+            with t1 as(
+            select c.pieid sid,linesfromrings(c.geometry) cg, d.pieid did, d.geometry dg
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(linesfromrings(c.geometry), d.geometry)
+            and  ST_Dimension(intersection(linesfromrings(c.geometry), d.geometry)) = 1
+            order by c.pieid, d.pieid
+            ) ,
+            t2 as(
+            select sid,'AL01' rulecode, casttomulti(st_difference(cg, gunion(dg)))  geometry
+            from t1 group by sid)
+            insert into @outtable@
+            select null,createuuid(),isvalid(geometry),
+            sid,rulecode,geometry
+            from t2 where geometry is not null;
+            insert into @outtable@
+            select null,PIEUUID,isvalid(casttomulti(linesfromrings(geometry))),
+            pieid sid,'AL01' rulecode, casttomulti(linesfromrings(geometry)) geometry
+            from @intable_s@ where rowid not in(
+            select c.rowid sid
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where     a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(linesfromrings(c.geometry), d.geometry)
+            and ST_Dimension(intersection(linesfromrings(c.geometry), d.geometry)) = 1
+            order by c.rowid, d.rowid
+            );
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''MULTILINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标线图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "AL01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中面要素的边界必须被另一个图层的线要素覆盖。未与线要素重合的面要素边界是错误的。"
+
+    AA01:
+        note: "面不与其他要素重叠(面-面)"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+            
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry POLYGON);
+            with t as(
+            select c.pieid sid, d.pieid did,
+            numGeometries(intersection(c.geometry, d.geometry)) cnt,
+            intersection(c.geometry, d.geometry) geometry
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ as c,
+            @intable_t@ as d
+            where (
+            a.xmin < b.xmax
+            and a.xmax > b.xmin
+            and a.ymin < b.ymax
+            and a.ymax > b.ymin
+            )
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry) = 1
+            and ST_Dimension(intersection(c.geometry, d.geometry)) > 1
+            and c.pievalided
+            and d.pievalided
+            ),
+            cte(idx, sid, did, cnt, geometry, subgeom) AS (
+            SELECT 1 idx,
+            sid,
+            did,
+            cnt,
+            geometry,
+            geometryN(geometry, 1) subgeom
+            from t
+            UNION ALL
+            SELECT idx + 1 idx,
+            sid,
+            did,
+            cnt,
+            geometry,
+            geometryN(geometry, idx + 1) subgeom
+            FROM cte
+            WHERE idx < cnt
+            )
+            insert into @outtable@
+            SELECT null,createuuid(),isvalid(subgeom),
+            sid,
+            did,
+            'AA01' rulecode,
+            subgeom geometry
+            FROM cte
+            where geometrytype(subgeom) = 'POLYGON'
+            order by sid,
+            did;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POLYGON'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "AA01.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中的区域不能与另一个图层中的区域重叠。第二个图层中的要素与第一个图层中的要素重叠处的任何区域都是错误的。"
+
+    AA02:
+        note: "面必须被其他要素类的要素覆盖"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop view if exists AA02view;
+            create view AA02view as
+            select c.pieid cid, d.pieid did, c.geometry cg, d.geometry dg
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry);
+
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry MULTIPOLYGON);
+            insert into @outtable@
+            select null,createuuid(),isvalid(geom),cid sid, ids did, 'AA02' rilecode, geom geometry from  (
+            select cid, group_concat(did, '-') ids, ExtractMultiPolygon(ST_Difference(cg, gunion(dg))) geom
+            from AA02view
+            group by cid
+            ) where geom is not null;
+            insert into @outtable@
+            select null,PIEUUID, isvalid(casttomulti(geometry)),pieid sid, null did, 'AA02' rulecode, casttomulti(geometry) geometry from @intable_s@
+            where pieid not in (select cid from AA02view);
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''MULTIPOLYGON'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "AA02.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层的面要素必须覆盖另一个图层的面要素。如果任何区域中第一个图层中的要素没有被第二个图层中的要素覆盖,该区域都是错误的。"
+
+    AA03:
+        note: "面必须互相覆盖"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+        
+            drop view if exists AA03view;
+            create view AA03view as
+            select c.pieid cid, d.pieid did, c.geometry cg, d.geometry dg
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry)
+            and not touches(c.geometry, d.geometry);
+
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,did,rulecode,geometry MULTIPOLYGON);
+            insert into @outtable@
+            select null,createuuid(),isvalid(geom), cid sid, ids did, 'AA03' rilecode, geom geometry from (
+            select cid, group_concat(did, '-') ids, ExtractMultiPolygon(ST_Difference(cg, gunion(dg))) geom from AA03view
+            group by cid
+            ) where geom is not null;
+            
+            insert into @outtable@
+            select null,createuuid(),isvalid(geom),ids sid, did ,'AA03' rilecode, geom geometry from (
+            select did, group_concat(cid, '-') ids, ExtractMultiPolygon(ST_Difference(dg, gunion(cg))) geom from AA03view
+            group by did
+            ) where geom is not null;
+            
+            insert into @outtable@
+            select null,PIEUUID,isvalid(casttomulti(geometry)), pieid sid, null did, 'AA03' rulecode, casttomulti(geometry) geometry
+            from @intable_s@ where pieid not in (select cid from AA03view);
+            
+            insert into @outtable@
+            select null,PIEUUID,isvalid(casttomulti(geometry)),null sid, pieid did, 'AA03' rulecode, casttomulti(geometry) geometry
+            from @intable_t@ where pieid not in (select did from AA03view);
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''MULTIPOLYGON'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "AA03.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层的面要素必须与另一个图层的面要素互相覆盖。如果在任何区域中一个图层的要素未覆盖另一个图层的要素,该区域都是错误的。"
+
+    AA04:
+        note: "面必须被单个面覆盖(村必须在某个乡镇之内)"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "select StoredVar_Delete('@intable_s@_srid') and StoredVar_Register('@intable_s@_srid','intable srid',(SELECT srid FROM geom_cols_ref_sys where f_table_name like '@intable_s@'));
+            
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry POLYGON);
+            insert into @outtable@
+            select null,PIEUUID,PIEVALIDED, pieid sid, 'AA04' rulecode, geometry geometry
+            from @intable_s@ where rowid not in(
+            select a.rowid
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(c.geometry, d.geometry)
+            and within(c.geometry, d.geometry)
+            );
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''POLYGON'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "AA04.png"
+          icon: "processingAlgorithm.png"
+          description: "说明:一个图层中的面要素必须包含在另一个图层的面要素内。第一个图层中的任何面要素未包含在第二个图层的要素内都是错误的。"
+
+    AA05:
+        note: "面边界必须被其他要素边界覆盖(面-面)"
+        lastupdated: [2023-1-4,]
+        roadmap: ""
+        front: []
+        ARG:
+          - intable_s:
+              meaning: 输入表的名字
+              type: B
+          - intable_t:
+              meaning: 目标表的名字
+              type: B
+        RTN:
+          - outtable:
+              meaning: 输出表的名字
+              type: B
+        DRTN: { meaning: 正确执行返回1, type: int }
+        RARG: ['@intable_s@=输入表的名字','@intable_t@=目标表的名字','@outtable@=输出表的名字']
+        RUNTYPE: repl
+        ALG: "drop view if exists AA05view; create view AA05view as
+            select c.pieid sid,linesfromrings(c.geometry) cg, d.pieid did, linesfromrings(d.geometry) dg
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            and intersects(linesfromrings(c.geometry), linesfromrings(d.geometry))
+            order by c.pieid;
+
+            drop table if exists @outtable@; 
+            create table @outtable@(PIEID INTEGER PRIMARY KEY not null,PIEUUID VARCHAR(128),PIEVALIDED BOOLEAN,sid,rulecode,geometry MULTILINESTRING);
+            with sel as
+            (
+            select sid from AA05view where overlaps(cg,dg) union
+            select pieid from @intable_s@ where pieid not in(
+            SELECT sid FROM AA05view where equals(cg, dg)  or overlaps(cg, dg)
+            )
+            ), t as
+            (
+            select c.pieid sid,linesfromrings(c.geometry) cg, d.pieid did, linesfromrings(d.geometry) dg
+            from idx_@intable_s@_geometry a,
+            idx_@intable_t@_geometry b,
+            @intable_s@ c,
+            @intable_t@ d
+            where c.pieid in sel
+            and a.xmax >= b.xmin
+            and a.xmin <= b.xmax
+            and a.ymax >= b.ymin
+            and a.ymin <= b.ymax
+            and a.rowid = c.rowid
+            and b.rowid = d.rowid
+            order by sid, did
+            ),u as
+            (
+            select sid, st_difference(cg , gunion(dg) ) geom from t
+            group by sid                        
+            )
+            insert into @outtable@
+            select null,createuuid(),isvalid(ExtractMultiLinestring(geom)),sid,'AA05' rulecode, ExtractMultiLinestring(geom) geometry
+            from u
+            where ExtractMultiLinestring(geom) is not null;
+            select SqlProc_execute(SqlProc_FromText('select recovergeometrycolumn(''@outtable@'', ''geometry'', @@intable_s@_srid@, ''MULTILINESTRING'', ''XY'');'));"
+        UI:
+          inparam:
+            - type: vector
+              ARG: intable_s
+              name: 输入面图层
+              description: 
+              defaultValue: 
+              help:  
+            - type: vector
+              ARG: intable_t
+              name: 目标面图层
+              description: 
+              defaultValue: 
+              help:  
+          outparam:
+            - type: databasetable
+              ARG: outtable
+              name: 输出结果表
+              description: 
+              fileFilter: "gsf;;shp;;spa"
+              defaultValue: newTable
+              help: ""
+              parentLayerParameterName: intable_s
+          image: "AA05.png"
+          icon: "processingAlgorithm.png"
+          description: "说明: 一个图层中面要素的边界必须被另一个图层中面要素的边界覆盖。第一个图层中任何未被第二个图层中面要素的边界覆盖的面要素边界都是错误的。"
+    
+    

+ 88 - 0
processing/tools/topology/topology.py

@@ -0,0 +1,88 @@
+from qgis._core import QgsCoordinateTransformContext
+from qgis.core import (
+    QgsVectorLayer,
+    QgsDataSourceUri,
+    QgsVectorFileWriter,
+    QgsApplication
+)
+from PyQt5.QtSql import QSqlDatabase, QSqlQuery
+
+# 初始化 QGIS 应用程序(如果在外部运行脚本需要添加)
+qgs = QgsApplication([], False)
+qgs.initQgis()
+
+# 1. 将 SHP 文件导入到 Spatialite
+shp_file_path = "D:\\gisdata\\hainanShp\\building4326\\Building.shp"  # 输入的 SHP 文件路径
+spatialite_db_path = "D:\\temp\\output.sqlite"  # Spatialite 数据库路径
+table_name = "building_table"  # 导入后的表名
+output_shp_path = "D:\\gisdata\\hainanShp\\building4326\\test\\sqlliteexport.shp"  # 输出的 SHP 文件路径
+export_layer_name = table_name
+
+# 加载 SHP 文件
+shp_layer = QgsVectorLayer(shp_file_path, "shp_layer", "ogr")
+if not shp_layer.isValid():
+    print("Failed to load SHP file.")
+    exit()
+
+# 获取 SHP 文件的 CRS(坐标参考系)
+shp_crs = shp_layer.crs().authid()
+
+# 构造连接到 Spatialite 数据库的 URI
+uri = QgsDataSourceUri()
+uri.setDatabase(spatialite_db_path)
+
+# 将 SHP 文件写入 Spatialite 数据库
+options = QgsVectorFileWriter.SaveVectorOptions()
+options.driverName = "SQLite"
+options.layerName = table_name
+options.fileEncoding = "UTF-8"
+options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
+# 将QgsVectorLayer导入到spatialite并指定表名
+result = QgsVectorFileWriter.writeAsVectorFormatV2(shp_layer, spatialite_db_path, QgsCoordinateTransformContext(), options)
+if result[0] != QgsVectorFileWriter.NoError:
+    print("Failed to import SHP file to Spatialite.")
+    exit()
+
+print(f"SHP file imported to Spatialite as table: {table_name}")
+
+# 2. 执行 SQL 语句
+db = QSqlDatabase.addDatabase("QSQLITE")
+db.setDatabaseName(spatialite_db_path)
+if not db.open():
+    print("Failed to open Spatialite database.")
+    exit()
+
+query = QSqlQuery(db)
+sql = f"""
+-- 在这里输入你的 SQL 语句
+SELECT * FROM {table_name};
+"""
+if not query.exec(sql):
+    print("SQL execution failed:", query.lastError().text())
+    exit()
+
+print("SQL execution completed.")
+
+# 3. 将数据导出为本地 SHP 文件
+
+# 加载处理后的表
+processed_layer = QgsVectorLayer(f"{spatialite_db_path}|layername={export_layer_name}", "processed_layer", "ogr")
+if not processed_layer.isValid():
+    print("Failed to load processed layer.")
+    exit()
+
+# 导出为 SHP 文件
+export_options = QgsVectorFileWriter.SaveVectorOptions()
+export_options.driverName = "ESRI Shapefile"
+export_options.fileEncoding = "UTF-8"
+
+result = QgsVectorFileWriter.writeAsVectorFormatV2(processed_layer, output_shp_path, QgsCoordinateTransformContext(), export_options)
+if result[0] != QgsVectorFileWriter.NoError:
+    print("Failed to export processed layer to SHP file.")
+    exit()
+
+print(f"Processed layer exported to SHP file: {output_shp_path}")
+
+# 释放资源
+db.close()
+qgs.exitQgis()