Files
sunvpy-docs/docs/content/27-dao-ru-wai-bu-shu-ju.md
2026-04-10 13:47:53 +08:00

25 KiB
Raw Permalink Blame History

本页面详细介绍如何将各种格式的外部数据导入到 SunvStation 工作空间中。数据导入是地理信息系统中最常用的功能之一,通过合理配置导入参数,您可以精确控制数据转换行为,包括坐标系统、编码方式、图层映射等关键属性。掌握数据导入功能是构建数据处理流程的基础技能。

Sources: PySSDataX.py

数据导入架构概览

数据导入功能基于 DataXScript 类实现,该类通过参数配置与执行分离的设计模式,提供了灵活且可扩展的数据交换框架。导入过程涉及数据源类型识别、参数配置、坐标转换和数据验证等多个环节,确保导入的数据能够正确集成到 SunvStation 工作空间中。

graph TB
    A[开始数据导入] --> B[准备导入参数]
    B --> C{识别数据源类型}
    C -->|Shapefile| D[SHP 格式处理]
    C -->|MDB| E[数据库格式处理]
    C -->|DXF| F[CAD 格式处理]
    C -->|其他| G[GDAL 通用处理]
    D --> H[创建 DataXScript 实例]
    E --> H
    F --> H
    G --> H
    H --> I[配置导入参数]
    I --> J[importData 执行导入]
    J --> K{导入成功?}
    K -->|是| L[验证导入结果]
    K -->|否| M[检查错误信息]
    L --> N[更新工作空间]
    M --> N

数据导入的核心是 DataXScript 类,该类不作为全局单例暴露,因此每次导入任务都需要创建新的实例。这种设计避免了不同导入任务之间的参数污染,提高了脚本的隔离性和安全性。

Sources: PySSDataX.py

支持的数据源类型

SunvStation 支持通过 GDAL 和 OGR 库导入多种常见的数据格式。系统通过静态方法 DataSource.getDataSourceTypeByExt() 自动识别文件扩展名并选择合适的数据源处理器。

标准矢量数据格式

格式名称 文件扩展名 数据源类型 支持的几何类型 适用场景
Shapefile .shp e_DataSource_EPS_GDAL 点、线、面 基础矢量数据交换
Personal Geodatabase .mdb e_DataSource_EPS_GDAL 点、线、面 ArcGIS 数据格式
File Geodatabase .gdb e_DataSource_EPS_GDAL 点、线、面 大型空间数据库
GeoPackage .gpkg e_DataSource_EPS_GDAL 点、线、面 现代 GIS 数据格式
KML/KMZ .kml, .kmz e_DataSource_EPS_GDAL 点、线、面 Google Earth 数据
GeoJSON .geojson, .json e_DataSource_EPS_GDAL 点、线、面 Web GIS 数据
CSV .csv e_DataSource_EPS_GDAL 点(含坐标) 表格坐标数据

CAD 和工程数据格式

格式名称 文件扩展名 数据源类型 支持的几何类型 适用场景
AutoCAD DXF .dxf e_DataSource_DWG 点、线、面、文字 CAD 数据交换
AutoCAD DWG .dwg e_DataSource_DWG 点、线、面、文字 AutoCAD 原生格式

栅格和影像数据格式

格式名称 文件扩展名 数据源类型 支持的数据类型 适用场景
GeoTIFF .tif, .tiff e_DataSource_IMG 栅格影像 高精度正射影像
ECW .ecw e_DataSource_IMG 压缩栅格 大幅面影像
JPEG 2000 .jp2, .j2k e_DataSource_IMG 压缩栅格 无损压缩影像
PNG .png e_DataSource_IMG 栅格影像 网络影像服务
BMP .bmp e_DataSource_IMG 栅格影像 简单栅格数据

三维和点云数据格式

格式名称 文件扩展名 数据源类型 支持的数据类型 适用场景
3D Tiles .3dtiles e_DataSource_3DTILES 三维瓦片 Web 三维场景
3D Model .3ds, .obj e_DataSource_3DModel 三维模型 三维建筑数据
LAS/LAZ .las, .laz e_DataSource_PCD 点云数据 激光扫描数据
DEM .dem e_DataSource_DEM 数字高程模型 地形数据
DSM .dsm e_DataSource_DSM 数字表面模型 地表高程数据

Sources: PySSDataSource.py

数据导入核心方法

DataXScript 类提供了执行数据导入的核心方法。这些方法构成了数据导入的完整流程,从参数配置到结果验证。

方法名称 方法签名 功能描述 返回值
importData importData() 执行数据导入操作 布尔值,表示是否成功
getImportFileName getImportFileName() 获取实际导入的文件名 字符串形式的文件名

执行数据导入

importData() 方法是数据导入的核心执行方法,它会根据之前配置的参数完成实际的导入操作。该方法会自动处理坐标转换、编码解析、数据验证等复杂过程,将外部数据正确加载到当前工作空间中。

from sunvpy.PySSDataX import DataXScript

# 创建数据交换脚本实例
datax = DataXScript()

# 配置导入参数
datax.setDataXParameter("ImportPath", "D:\\gis_data\\roads.shp")
datax.setDataXParameter("SourceEncoding", "GBK")
datax.setDataXParameter("CoordSystem", "EPSG:4326")
datax.setDataXParameter("LayerMapping", "道路")
datax.setDataXParameter("OverwriteExisting", "true")

# 执行数据导入
success = datax.importData()

if success:
    print("数据导入成功")
else:
    print("数据导入失败,请检查参数配置")

importData() 方法的返回值是一个布尔值,表示导入操作是否成功。如果导入失败,通常是由于参数配置错误、文件不存在、格式不兼容或权限问题导致的。

Sources: PySSDataX.py

获取导入文件名

getImportFileName() 方法用于获取实际导入的文件名称。在某些情况下,系统可能会根据命名规则对导入的文件名进行调整(如添加时间戳、避免命名冲突等),因此实际导入的文件名可能与原始文件名不同。

# 执行导入后获取文件名
success = datax.importData()

if success:
    import_file = datax.getImportFileName()
    print(f"导入的文件名: {import_file}")
    
    # 可以使用这个文件名进行后续操作
    # 例如:记录到日志、显示给用户等

getImportFileName() 方法对于调试和记录非常有用,特别是在批量导入或自动化脚本中,可以帮助您追踪实际导入的文件。

Sources: PySSDataX.py

数据导入流程详解

完整的数据导入流程包括文件识别、参数配置、执行导入和结果验证四个阶段。理解每个阶段的关键点和注意事项可以帮助您编写更健壮的导入脚本。

第一步:准备和验证源文件

在开始导入前,确保源文件满足基本要求:文件路径正确、文件格式支持、文件可访问。您可以使用静态方法 DataSource.getDataSourceTypeByExt() 预先识别数据源类型。

from sunvpy.PySSDataSource import DataSource
import os

# 定义源文件路径
source_file = "D:\\gis_data\\survey.shp"

# 验证文件是否存在
if not os.path.exists(source_file):
    raise FileNotFoundError(f"源文件不存在: {source_file}")

# 识别数据源类型
data_type = DataSource.getDataSourceTypeByExt(source_file)
print(f"识别的数据源类型: {data_type}")

文件验证是数据导入流程中的关键第一步,通过提前检查文件存在性和类型,可以避免后续导入过程中的错误。

Sources: PySSDataSource.py

第二步:配置导入参数

参数配置是数据导入的核心环节。不同的数据格式可能需要不同的参数配置,但大多数导入任务都包含以下基本参数。

flowchart LR
    A[开始参数配置] --> B[设置 ImportPath<br/>源文件路径]
    B --> C[设置 SourceEncoding<br/>字符编码]
    C --> D[设置 CoordSystem<br/>坐标系统]
    D --> E{需要图层映射?}
    E -->|是| F[设置 LayerMapping<br/>图层映射规则]
    E -->|否| G{需要覆盖已有数据?}
    F --> G
    G -->|是| H[设置 OverwriteExisting<br/>覆盖标志]
    G -->|否| I[完成参数配置]
    H --> I
from sunvpy.PySSDataX import DataXScript

# 创建数据交换脚本实例
datax = DataXScript()

# 配置基础导入参数
datax.setDataXParameter("ImportPath", "D:\\gis_data\\survey.shp")

# 设置字符编码(根据源文件实际编码)
datax.setDataXParameter("SourceEncoding", "GBK")

# 设置坐标系统(如果需要坐标转换)
datax.setDataXParameter("CoordSystem", "EPSG:4326")

# 设置图层映射(可选)
datax.setDataXParameter("LayerMapping", "测区数据")

# 设置是否覆盖已有数据(可选)
datax.setDataXParameter("OverwriteExisting", "true")

# 设置几何容差(可选,用于简化几何)
datax.setDataXParameter("Tolerance", "0.001")

参数配置时应遵循以下原则:使用绝对路径、明确指定编码方式、设置正确的坐标系统、根据需求配置图层映射和覆盖选项。

Sources: PySSDataX.py

第三步:执行数据导入

参数配置完成后,调用 importData() 方法执行导入操作。导入过程中可能会显示进度条(如果启用),系统会自动处理数据解析、坐标转换、属性映射等复杂操作。

# 执行数据导入
print("开始导入数据...")
success = datax.importData()

if success:
    print("数据导入成功")
    import_file = datax.getImportFileName()
    print(f"导入文件: {import_file}")
else:
    print("数据导入失败")
    # 可以添加更详细的错误处理逻辑

导入操作可能会持续较长时间,特别是对于大型数据集。建议在导入前提示用户,并在导入完成后给出明确的反馈信息。

Sources: PySSDataX.py

第四步:验证导入结果

导入完成后,应验证数据是否正确加载到工作空间中。可以通过检查数据集数量、对象数量、属性完整性等方式进行验证。

from sunvpy.PySSProcess import SSProcess

# 获取当前工作空间的数据集列表
dataset_list = SSProcess.map.getCurrentDataSource().getDatasetList()
print(f"导入后的数据集数量: {dataset_list.size()}")

# 如果知道具体的数据集名称,可以进一步验证
for i in range(dataset_list.size()):
    dataset = dataset_list.at(i)
    dataset_name = dataset.getName()
    print(f"数据集 {i}: {dataset_name}")

验证导入结果是确保数据质量的重要步骤。特别是对于自动化脚本,应建立完善的验证机制,及时发现并处理导入过程中的问题。

Sources: PySSDataSource.py

完整导入示例

以下是一个完整的 Shapefile 数据导入示例,包含了文件验证、参数配置、导入执行和结果验证的全过程。

import os
from sunvpy.PySSDataX import DataXScript
from sunvpy.PySSDataSource import DataSource
from sunvpy.PySSProcess import SSProcess

def import_shapefile(source_path: str, target_encoding: str = "GBK", 
                     coord_system: str = "EPSG:4326", 
                     layer_name: str = "导入数据",
                     overwrite: bool = True) -> bool:
    """
    导入 Shapefile 数据到当前工作空间
    
    参数:
        source_path: 源文件路径
        target_encoding: 目标字符编码,默认为 GBK
        coord_system: 坐标系统,默认为 EPSG:4326
        layer_name: 映射的图层名称
        overwrite: 是否覆盖已有数据
        
    返回:
        bool: 导入是否成功
    """
    # ========== 第一步:验证源文件 ==========
    print(f"验证源文件: {source_path}")
    
    if not os.path.exists(source_path):
        print(f"错误:源文件不存在: {source_path}")
        return False
    
    # 识别数据源类型
    data_type = DataSource.getDataSourceTypeByExt(source_path)
    print(f"识别的数据源类型: {data_type}")
    
    if not source_path.lower().endswith('.shp'):
        print(f"警告:文件扩展名不是 .shp可能不是 Shapefile 格式")
    
    # ========== 第二步:配置导入参数 ==========
    print("配置导入参数...")
    
    datax = DataXScript()
    
    # 设置源文件路径(使用绝对路径)
    datax.setDataXParameter("ImportPath", os.path.abspath(source_path))
    
    # 设置源文件编码
    datax.setDataXParameter("SourceEncoding", target_encoding)
    
    # 设置坐标系统
    datax.setDataXParameter("CoordSystem", coord_system)
    
    # 设置图层映射
    datax.setDataXParameter("LayerMapping", layer_name)
    
    # 设置是否覆盖已有数据
    datax.setDataXParameter("OverwriteExisting", "true" if overwrite else "false")
    
    # 设置几何容差(可选,用于简化几何)
    datax.setDataXParameter("Tolerance", "0.001")
    
    # ========== 第三步:执行数据导入 ==========
    print("执行数据导入...")
    success = datax.importData()
    
    if not success:
        print("错误:数据导入失败")
        return False
    
    # ========== 第四步:验证导入结果 ==========
    print("验证导入结果...")
    
    import_file = datax.getImportFileName()
    print(f"导入的文件名: {import_file}")
    
    # 获取当前数据源
    current_datasource = SSProcess.map.getCurrentDataSource()
    if current_datasource is None:
        print("错误:无法获取当前数据源")
        return False
    
    # 获取数据集列表
    dataset_list = current_datasource.getDatasetList()
    print(f"导入后的数据集数量: {dataset_list.size()}")
    
    # 清理参数
    datax.clearDataXParameter()
    
    print("数据导入流程完成")
    return True

# 使用示例
if __name__ == "__main__":
    # 导入 Shapefile 数据
    result = import_shapefile(
        source_path="D:\\gis_data\\roads.shp",
        target_encoding="GBK",
        coord_system="EPSG:4326",
        layer_name="道路",
        overwrite=True
    )
    
    if result:
        print("导入成功")
    else:
        print("导入失败")

这个完整的示例展示了数据导入的最佳实践:在每一步都进行验证、使用绝对路径、提供详细的日志输出、正确处理错误情况。

Sources: PySSDataX.py

批量导入数据

在实际应用中,经常需要批量导入多个文件。以下示例展示了如何批量导入一个目录下的所有 Shapefile 文件。

import os
from sunvpy.PySSDataX import DataXScript
from sunvpy.PySSDataSource import DataSource

def batch_import_shapefiles(directory: str, pattern: str = "*.shp") -> dict:
    """
    批量导入目录下的 Shapefile 文件
    
    参数:
        directory: 包含源文件的目录
        pattern: 文件匹配模式,默认为 *.shp
        
    返回:
        dict: 导入结果统计 {成功: 数量, 失败: 数量, 文件列表: [结果]}
    """
    results = {
        "success_count": 0,
        "fail_count": 0,
        "files": []
    }
    
    # 获取目录下所有匹配的文件
    import glob
    files = glob.glob(os.path.join(directory, pattern))
    
    print(f"找到 {len(files)} 个文件待导入")
    
    for index, source_file in enumerate(files, 1):
        file_name = os.path.basename(source_file)
        print(f"\n[{index}/{len(files)}] 导入文件: {file_name}")
        
        try:
            # 为每个文件创建独立的 DataXScript 实例
            datax = DataXScript()
            
            # 配置导入参数
            datax.setDataXParameter("ImportPath", os.path.abspath(source_file))
            datax.setDataXParameter("SourceEncoding", "GBK")
            datax.setDataXParameter("CoordSystem", "EPSG:4326")
            datax.setDataXParameter("LayerMapping", f"批量导入_{file_name}")
            datax.setDataXParameter("OverwriteExisting", "true")
            
            # 执行导入
            success = datax.importData()
            
            if success:
                import_file = datax.getImportFileName()
                print(f"  导入成功: {import_file}")
                results["success_count"] += 1
                results["files"].append({
                    "file": file_name,
                    "status": "成功",
                    "imported_as": import_file
                })
            else:
                print(f"  导入失败")
                results["fail_count"] += 1
                results["files"].append({
                    "file": file_name,
                    "status": "失败",
                    "error": "未知错误"
                })
            
            # 清理参数
            datax.clearDataXParameter()
            
        except Exception as e:
            print(f"  导入异常: {str(e)}")
            results["fail_count"] += 1
            results["files"].append({
                "file": file_name,
                "status": "异常",
                "error": str(e)
            })
    
    # 输出汇总信息
    print(f"\n批量导入完成:")
    print(f"  成功: {results['success_count']} 个")
    print(f"  失败: {results['fail_count']} 个")
    print(f"  总计: {len(files)} 个")
    
    return results

# 使用示例
if __name__ == "__main__":
    # 批量导入目录下所有 SHP 文件
    results = batch_import_shapefiles("D:\\gis_data\\batch_import")

批量导入时,为每个文件创建独立的 DataXScript 实例可以避免参数污染,同时使用 try-except 捕获异常,确保单个文件的失败不会影响整个批量导入流程。

Sources: PySSDataX.py

常见导入场景与参数配置

不同的导入场景需要不同的参数配置策略。以下是几种常见导入场景的参数配置示例。

场景一:导入带中文字段的 Shapefile

中文数据导入时最常见的问题是字符编码。如果源文件的编码与系统默认编码不匹配,导入后会出现乱码。

datax = DataXScript()

# 导入带中文字段的 Shapefile
datax.setDataXParameter("ImportPath", "D:\\data\\chinese_roads.shp")
datax.setDataXParameter("SourceEncoding", "GBK")  # 中文 Windows 通常使用 GBK
datax.setDataXParameter("CoordSystem", "EPSG:4326")
datax.setDataXParameter("LayerMapping", "中文道路")

success = datax.importData()

如果仍然出现乱码,可以尝试其他编码格式,如 UTF-8BIG5(繁体中文)等。

Sources: PySSDataX.py

场景二:导入不同坐标系统的数据

当源数据的坐标系统与工作空间不同时,需要指定正确的坐标系统参数以实现坐标转换。

datax = DataXScript()

# 导入坐标系统为 EPSG:3857 (Web Mercator) 的数据
# 转换为目标坐标系统 EPSG:4326 (WGS84)
datax.setDataXParameter("ImportPath", "D:\\data\\web_mercator_data.shp")
datax.setDataXParameter("SourceCoordSystem", "EPSG:3857")  # 源坐标系统
datax.setDataXParameter("TargetCoordSystem", "EPSG:4326")  # 目标坐标系统
datax.setDataXParameter("CoordSystem", "EPSG:4326")  # 最终坐标系统
datax.setDataXParameter("TransformMode", "AUTO")  # 自动选择转换模式

success = datax.importData()

坐标系统参数通常使用 EPSG 代码表示,例如 EPSG:4326 表示 WGS84 经纬度坐标,EPSG:4490 表示 CGCS2000 坐标系。

Sources: PySSDataX.py

场景三:导入 CAD 数据DXF/DWG

CAD 数据通常包含图层、块、文字等复杂元素,导入时需要进行适当的配置。

datax = DataXScript()

# 导入 DXF 文件
datax.setDataXParameter("ImportPath", "D:\\data\\city_plan.dxf")
datax.setDataXParameter("SourceEncoding", "GB2312")
datax.setDataXParameter("CoordSystem", "EPSG:4326")
datax.setDataXParameter("LayerMapping", "城市规划")

# CAD 特定参数
datax.setDataXParameter("ImportBlocks", "true")  # 导入块
datax.setDataXParameter("ImportText", "true")    # 导入文字
datax.setDataXParameter("ImportHatch", "false")  # 不导入填充
datax.setDataXParameter("ExplodeBlocks", "true") # 炸开块为独立对象

success = datax.importData()

CAD 数据导入时,可以根据实际需要选择导入哪些元素类型(块、文字、填充等),以减少数据冗余。

Sources: PySSDataX.py

场景四:增量导入数据

当需要将新数据追加到已有数据集中时,应设置 OverwriteExisting 参数为 false

datax = DataXScript()

# 增量导入新数据
datax.setDataXParameter("ImportPath", "D:\\data\\new_survey.shp")
datax.setDataXParameter("SourceEncoding", "GBK")
datax.setDataXParameter("CoordSystem", "EPSG:4326")
datax.setDataXParameter("LayerMapping", "测区数据")
datax.setDataXParameter("OverwriteExisting", "false")  # 不覆盖已有数据

success = datax.importData()

增量导入时,系统会将新数据追加到目标数据集中,保留已有数据不变。

Sources: PySSDataX.py

错误排查与问题解决

数据导入过程中可能会遇到各种问题。本节介绍常见错误现象及其解决方法。

常见错误与解决方案

错误现象 可能原因 解决方法
importData() 返回 False 参数名称拼写错误 检查参数名称是否与系统预定义一致
导入后字段乱码 字符编码不匹配 使用正确的 SourceEncoding 参数值
坐标位置偏移 坐标系统未设置或错误 配置正确的 CoordSystem 和转换参数
部分对象未导入 图层过滤或数据范围限制 检查 LayerFilter 参数和源数据完整性
文件打开失败 文件被占用或权限不足 关闭文件访问程序,检查文件权限
内存不足 数据量过大 分批次导入,设置 Tolerance 简化几何

调试技巧

在遇到导入问题时,可以使用以下调试技巧:

from sunvpy.PySSDataX import DataXScript

datax = DataXScript()

# 配置参数
datax.setDataXParameter("ImportPath", "D:\\data\\problem_file.shp")
datax.setDataXParameter("SourceEncoding", "GBK")

# 在执行前验证关键参数
import_path = datax.getDataXParameter("ImportPath")
encoding = datax.getDataXParameter("SourceEncoding")
coord_system = datax.getDataXParameter("CoordSystem")

print(f"导入路径: {import_path}")
print(f"字符编码: {encoding}")
print(f"坐标系统: {coord_system if coord_system else '未设置'}")

# 执行导入
success = datax.importData()

if not success:
    print("导入失败,请检查:")
    print("  1. 文件是否存在且可访问")
    print("  2. 文件格式是否正确")
    print("  3. 参数配置是否完整")
    print("  4. 系统是否有足够内存")

调试时应逐步验证每个环节,从文件验证到参数配置,再到执行结果,通过日志输出追踪问题所在。

Sources: PySSDataX.py

性能优化建议

对于大规模数据导入任务,可以通过合理的参数配置和策略优化性能。

优化参数配置

datax = DataXScript()

datax.setDataXParameter("ImportPath", "D:\\data\\large_dataset.shp")

# 性能优化参数
datax.setDataXParameter("Tolerance", "0.01")  # 使用较大的容差值简化几何
datax.setDataXParameter("CompressGeometry", "true")  # 压缩几何数据
datax.setDataXParameter("CreateIndex", "true")  # 创建空间索引加速查询
datax.setDataXParameter("Verbose", "false")  # 关闭详细日志减少I/O

success = datax.importData()

性能优化需要在数据精度和处理速度之间取得平衡。容差值越大,几何简化程度越高,处理速度越快,但数据精度会降低。

Sources: PySSDataX.py

分批导入策略

对于超大规模数据集,可以考虑分批导入:

def batch_import_large_dataset(source_file: str, batch_size: int = 10000):
    """
    分批导入大数据集(示例)
    
    注意:实际分批导入需要根据具体实现调整
    """
    import os
    
    file_size = os.path.getsize(source_file)
    print(f"源文件大小: {file_size / (1024*1024):.2f} MB")
    
    if file_size > 100 * 1024 * 1024:  # 超过 100MB
        print("警告:文件较大,建议分批导入")
        
        # 可以考虑使用 GIS 工具先将大文件分割
        # 然后分批导入
        print("提示:使用 QGIS、ArcGIS 等工具分割大文件后,分批导入")
        return False
    
    # 直接导入
    datax = DataXScript()
    datax.setDataXParameter("ImportPath", source_file)
    datax.setDataXParameter("Tolerance", "0.01")
    
    return datax.importData()

分批导入策略适用于超大型数据集,通常需要借助外部 GIS 工具先将数据分割,然后分批导入。

Sources: PySSDataX.py

学习路径建议

掌握了数据导入的基础知识后,建议按照以下路径深入学习:

  1. 继续学习 数据交换参数配置,深入了解各类参数的作用和配置技巧。

  2. 学习 导出数据到文件,掌握数据导出的完整流程和参数配置。

  3. 探索 自定义数据交换流程,构建复杂的数据处理工作流。

  4. 参考 数据检查与验证,了解导入后如何检查和验证数据质量。