本页面详细介绍如何将 SunvStation 工作空间中的地理数据导出为各种格式的文件。数据导出是地理信息系统数据共享和交换的重要手段，通过合理配置导出参数，您可以精确控制输出格式、编码方式、坐标系统和属性字段映射等关键属性，确保导出的数据能够满足不同应用场景的需求。

Sources: [PySSDataX.py](PySSDataX.py#L113-L173)

## 数据导出架构概览

数据导出功能基于 **DataXScript** 类实现，该类采用与数据导入相同的架构设计，通过参数配置与执行分离的模式，提供了灵活且可扩展的数据交换框架。导出过程涉及数据源识别、参数配置、坐标转换、属性映射和文件生成等多个环节，确保导出的数据能够在其他系统中正确加载和使用。

```mermaid
graph TB
    A[开始数据导出] --> B[准备导出数据源]
    B --> C{识别导出格式}
    C -->|Shapefile| D[SHP 格式处理]
    C -->|MDB| E[数据库格式处理]
    C -->|DXF| F[CAD 格式处理]
    C -->|GeoJSON| G[Web 格式处理]
    C -->|其他| H[GDAL 通用处理]
    D --> I[创建 DataXScript 实例]
    E --> I
    F --> I
    G --> I
    H --> I
    I --> J[配置导出参数]
    J --> K[exportData 执行导出]
    K --> L{导出成功?}
    L -->|是| M[验证输出文件]
    L -->|否| N[检查错误信息]
    M --> O[导出完成]
    N --> O
```

DataXScript 类作为数据导出的核心组件，提供了完整的参数管理和执行接口。与数据导入类似，导出功能也不依赖全局单例，每次导出任务都需要创建新的实例。这种设计确保了不同导出任务之间的参数隔离，提高了脚本的可靠性和可维护性。

Sources: [PySSDataX.py](PySSDataX.py#L113-L120)

## 支持的导出格式

SunvStation 支持通过 GDAL 和 OGR 库导出多种常见的数据格式，覆盖了从传统 GIS 格式到现代 Web GIS 格式的广泛范围。系统会根据指定的输出文件扩展名自动选择合适的导出驱动器，并应用相应的格式转换规则。

### 标准矢量数据格式

| 格式名称 | 文件扩展名 | 导出特点 | 几何类型支持 | 属性字段限制 |
|---------|-----------|---------|------------|------------|
| Shapefile | `.shp` | 最常用的交换格式，字段名限制 10 字符 | 点、线、面 | 单文件 2GB 限制 |
| Personal Geodatabase | `.mdb` | Microsoft Access 数据库，支持复杂关系 | 点、线、面 | 2GB 数据库限制 |
| File Geodatabase | `.gdb` | Esri 现代格式，支持大数据量 | 点、线、面 | 单数据集 1TB 限制 |
| GeoPackage | `.gpkg` | OGC 标准，轻量级跨平台 | 点、线、面 | 无明确大小限制 |
| KML/KMZ | `.kml`, `.kmz` | Google Earth 格式，支持样式和标注 | 点、线、面 | 适合可视化展示 |
| GeoJSON | `.geojson`, `.json` | Web 标准，基于 JSON | 点、线、面 | 适合 Web 应用 |
| CSV | `.csv` | 文本表格格式，可导出坐标信息 | 点（带坐标） | 适合表格处理 |

### CAD 和工程数据格式

| 格式名称 | 文件扩展名 | 导出特点 | 几何类型支持 | 样式保留 |
|---------|-----------|---------|------------|---------|
| AutoCAD DXF | `.dxf` | 开放的 CAD 交换格式 | 点、线、面、文字 | 部分样式保留 |
| AutoCAD DWG | `.dwg` | AutoCAD 原生格式 | 点、线、面、文字 | 完整样式保留 |

### 栅格和影像数据格式

| 格式名称 | 文件扩展名 | 导出特点 | 压缩支持 | 适用场景 |
|---------|-----------|---------|---------|---------|
| GeoTIFF | `.tif`, `.tiff` | 地理信息标准格式 | LZW, DEFLATE, JPEG | 高质量影像输出 |
| ECW | `.ecw` | 高压缩率格式 | 小波压缩 | 大幅面影像压缩 |
| JPEG 2000 | `.jp2`, `.j2k` | 无损压缩标准 | JPEG 2000 压缩 | 专业影像处理 |
| PNG | `.png` | Web 常用格式 | 无损压缩 | Web 地图服务 |
| BMP | `.bmp` | 简单位图格式 | 无压缩 | 兼容性要求高的场景 |

Sources: [PySSDataSource.py](PySSDataSource.py#L330-L345)

## 数据导出核心方法

DataXScript 类提供了执行数据导出的核心方法集。这些方法构成了数据导出的完整流程，从参数配置到执行导出，再到结果验证。理解这些方法的调用顺序和依赖关系是成功实现数据导出的关键。

| 方法名称 | 方法签名 | 功能描述 | 返回值 |
|---------|---------|---------|--------|
| `exportData` | `exportData()` | 执行数据导出操作 | 布尔值，表示是否成功 |
| `setDataXParameter` | `setDataXParameter(name, value)` | 设置导出参数 | 无 |
| `getDataXParameter` | `getDataXParameter(name)` | 获取参数当前值 | 字符串形式的参数值 |
| `clearDataXParameter` | `clearDataXParameter()` | 清除所有参数 | 无 |

### 执行数据导出

`exportData()` 方法是数据导出的核心执行方法，它会根据之前配置的参数完成实际的导出操作。该方法会自动处理坐标转换、编码转换、属性映射、格式转换等复杂过程，将工作空间中的数据正确输出到指定的目标文件中。

```python
from sunvpy.PySSDataX import DataXScript

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

# 配置导出参数
datax.setDataXParameter("ExportPath", "D:\\export\\roads.shp")
datax.setDataXParameter("TargetEncoding", "UTF-8")

# 执行导出
success = datax.exportData()
if success:
    print("数据导出成功！")
else:
    print("数据导出失败，请检查参数配置。")
```

`exportData()` 方法的返回值是一个布尔值，`True` 表示导出成功，`False` 表示导出失败。在实际应用中，应该始终检查返回值，并根据结果进行相应的错误处理和用户提示。

Sources: [PySSDataX.py](PySSDataX.py#L157-L161)

## 完整导出流程

数据导出需要遵循一定的操作顺序，从参数配置到执行导出，再到结果验证。下图展示了完整的导出流程，包括每个步骤的决策点和可能的错误处理路径。

```mermaid
flowchart TD
    Start([开始数据导出]) --> Create[创建 DataXScript 实例]
    Create --> SetPath[设置 ExportPath 参数]
    SetPath --> CheckPath{路径有效?}
    CheckPath -->|否| PathError[提示路径错误并结束]
    CheckPath -->|是| SetFormat[设置格式相关参数]
    SetFormat --> SetEncoding[设置 TargetEncoding]
    SetEncoding --> SetCoord[设置坐标系统参数]
    SetCoord --> SetFields[设置字段映射参数]
    SetFields --> Export[调用 exportData]
    Export --> CheckResult{导出成功?}
    CheckResult -->|否| AnalyzeError[分析错误原因]
    AnalyzeError --> Retry{是否重试?}
    Retry -->|是| SetPath
    Retry -->|否| ErrorEnd([结束并报告错误])
    CheckResult -->|是| Verify[验证输出文件]
    Verify --> Valid{文件有效?}
    Valid -->|否| WarningEnd([结束并显示警告])
    Valid -->|是| SuccessEnd([导出成功完成])
```

Sources: [PySSDataX.py](PySSDataX.py#L120-L161)

## 导出参数配置详解

数据导出的行为完全由参数配置决定。理解每个参数的作用和取值范围，对于实现精确控制导出结果至关重要。本节详细介绍常用的导出参数及其配置方法。

### 基础路径和格式参数

| 参数名称 | 参数说明 | 示例值 | 必填性 |
|---------|---------|-------|--------|
| `ExportPath` | 导出目标文件完整路径 | `D:\data\export\roads.shp` | 必填 |
| `ExportFormat` | 导出格式驱动名称 | `ESRI Shapefile` | 可选（自动推断） |
| `TargetEncoding` | 目标文件编码 | `UTF-8`, `GBK` | 推荐 |
| `Overwrite` | 是否覆盖已存在文件 | `true`, `false` | 可选（默认 false） |

```python
# 配置基础导出参数
datax.setDataXParameter("ExportPath", "D:\\export\\buildings.shp")
datax.setDataXParameter("TargetEncoding", "UTF-8")
datax.setDataXParameter("Overwrite", "true")
```

`ExportPath` 是最关键的参数，它不仅指定了输出文件的路径，其扩展名也决定了导出格式。系统会根据文件扩展名自动选择合适的驱动器。如果需要使用非标准扩展名，可以通过 `ExportFormat` 参数显式指定驱动名称。

Sources: [PySSDataX.py](PySSDataX.py#L120-L128)

### 坐标系统参数

| 参数名称 | 参数说明 | 示例值 | 适用场景 |
|---------|---------|-------|---------|
| `CoordSystem` | 目标坐标系统 EPSG 代码 | `EPSG:4326`, `EPSG:3857` | 坐标转换 |
| `CoordTransform` | 坐标转换方法 | `nearest`, `bilinear` | 栅格重采样 |
| `SpatialRef` | 空间参考定义 | `.prj` 文件路径 | 自定义投影 |

```python
# 导出为 WGS84 坐标系统
datax.setDataXParameter("CoordSystem", "EPSG:4326")

# 导出为墨卡托投影（Web Mercator）
datax.setDataXParameter("CoordSystem", "EPSG:3857")
```

坐标系统参数在需要将数据从工作空间坐标系统转换为其他坐标系统时非常重要。系统会在导出过程中自动执行坐标转换，确保输出的数据具有正确的空间参考信息。对于栅格数据，`CoordTransform` 参数可以指定重采样方法。

Sources: [PySSDataX.py](PySSDataX.py#L120-L128)

### 字段映射和筛选参数

| 参数名称 | 参数说明 | 示例值 | 适用场景 |
|---------|---------|-------|---------|
| `FieldList` | 要导出的字段列表（逗号分隔） | `SSObj_ID,SSObj_Name,SSObj_Code` | 字段筛选 |
| `FieldMapping` | 字段映射规则 | `原字段名:目标字段名` | 字段重命名 |
| `FieldFilter` | 字段过滤表达式 | `SSObj_Code <> '3103013'` | 条件导出 |

```python
# 只导出指定字段
datax.setDataXParameter("FieldList", "SSObj_ID,SSObj_Name,SSObj_Area")

# 字段重命名映射
datax.setDataXParameter("FieldMapping", "SSObj_Name:Name,SSObj_Area:Area")

# 导出时不包含特定编码的对象
datax.setDataXParameter("FieldFilter", "SSObj_Code <> 'TEMP'")
```

字段映射和筛选参数提供了对导出数据的精细控制能力。通过 `FieldList` 参数，可以选择性地导出部分字段，减少输出文件的大小并提高导出效率。`FieldMapping` 参数可以在导出过程中重命名字段，使输出数据的字段名符合目标系统的命名规范。

Sources: [PySSDataX.py](PySSDataX.py#L120-L128)

## 导出场景实战

本节通过具体的代码示例，展示在不同应用场景下如何配置导出参数并执行数据导出。这些示例涵盖了最常见的导出需求，您可以根据实际情况进行调整和扩展。

### 场景一：导出选择集数据为 Shapefile

将当前选择集中的地理对象导出为 Shapefile 格式，适用于与其他 GIS 软件进行数据交换的场景。

```python
from sunvpy.PySSProcess import SSProcess
from sunvpy.PySSDataX import DataXScript
from sunvpy.ObjBaseAttr import ObjBaseAttr

# 步骤 1：准备选择集数据
SSProcess.clearSelection()
SSProcess.clearSelectCondition()
SSProcess.setSelectCondition("SSObj_Code", "==", "3103013")
SSProcess.selectFilter()

print(f"选择集对象数量: {SSProcess.getSelGeoCount()}")

# 步骤 2：配置导出参数
datax = DataXScript()
datax.setDataXParameter("ExportPath", "D:\\export\\roads_selection.shp")
datax.setDataXParameter("TargetEncoding", "UTF-8")
datax.setDataXParameter("Overwrite", "true")

# 步骤 3：设置字段列表（只导出关键字段）
datax.setDataXParameter("FieldList", "SSObj_ID,SSObj_Code,SSObj_Name,SSObj_LayerName")

# 步骤 4：执行导出
success = datax.exportData()
if success:
    print(f"成功导出 {SSProcess.getSelGeoCount()} 个对象到 roads_selection.shp")
else:
    print("导出失败")
```

Sources: [PySSProcess.py](PySSProcess.py#L1-L70)

### 场景二：导出为 GeoJSON 用于 Web 地图

将数据导出为 GeoJSON 格式，适用于在 Web GIS 应用中直接使用的场景。

```python
from sunvpy.PySSDataX import DataXScript

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

# 配置导出参数
datax.setDataXParameter("ExportPath", "D:\\export\\webmap_buildings.geojson")
datax.setDataXParameter("TargetEncoding", "UTF-8")
datax.setDataXParameter("CoordSystem", "EPSG:4326")  # WGS84 坐标

# 只导出建筑相关的字段
datax.setDataXParameter("FieldList", "SSObj_ID,SSObj_Name,SSObj_Area,[JG],[CS]")

# 执行导出
success = datax.exportData()
if success:
    print("GeoJSON 文件导出成功，可用于 Web 地图展示")
else:
    print("GeoJSON 导出失败")
```

GeoJSON 格式使用 WGS84 坐标系统（EPSG:4326），这是 Web GIS 的标准坐标系统。如果原始数据使用其他坐标系统，导出时会自动进行坐标转换。

Sources: [PySSDataX.py](PySSDataX.py#L157-L161)

### 场景三：导出为 AutoCAD DXF 格式

将地理数据导出为 DXF 格式，适用于与 CAD 软件进行数据交换的场景。

```python
from sunvpy.PySSDataX import DataXScript

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

# 配置导出参数
datax.setDataXParameter("ExportPath", "D:\\export\\survey_data.dxf")
datax.setDataXParameter("TargetEncoding", "UTF-8")
datax.setDataXParameter("Overwrite", "true")

# 设置 CAD 相关参数（根据实际需求调整）
datax.setDataXParameter("CADVersion", "2007")  # DXF 版本
datax.setDataXParameter("CADLayer", "Survey")  # 输出图层名

# 执行导出
success = datax.exportData()
if success:
    print("DXF 文件导出成功，可在 AutoCAD 中打开")
else:
    print("DXF 导出失败")
```

DXF 导出时需要注意坐标系统的兼容性。CAD 软件通常使用局部坐标系统，如果工作空间数据使用大地坐标（如经纬度），可能需要进行坐标变换后再导出，或者使用专门的坐标转换工具。

Sources: [PySSDataX.py](PySSDataX.py#L120-L161)

### 场景四：批量导出多个图层

将工作空间中的不同图层分别导出为独立的文件，适用于数据分发的场景。

```python
from sunvpy.PySSProcess import SSProcess
from sunvpy.PySSDataX import DataXScript
from sunvpy.ObjBaseAttr import ObjBaseAttr
import os

# 获取所有图层
layer_count = SSProcess.getLayerCount()
print(f"工作空间中共有 {layer_count} 个图层")

# 创建导出目录
export_dir = "D:\\export\\layers"
if not os.path.exists(export_dir):
    os.makedirs(export_dir)

# 遍历每个图层并导出
for i in range(layer_count):
    layer_name = SSProcess.getLayerName(i)
    if not layer_name:
        continue
    
    print(f"正在导出图层: {layer_name}")
    
    # 清除选择集并选择当前图层的所有对象
    SSProcess.clearSelection()
    SSProcess.clearSelectCondition()
    SSProcess.setSelectCondition("SSObj_LayerName", "==", layer_name)
    SSProcess.selectFilter()
    
    geo_count = SSProcess.getSelGeoCount()
    if geo_count == 0:
        print(f"  图层 {layer_name} 无数据，跳过")
        continue
    
    # 配置导出参数
    datax = DataXScript()
    safe_layer_name = layer_name.replace(" ", "_")  # 替换空格
    export_path = os.path.join(export_dir, f"{safe_layer_name}.shp")
    
    datax.setDataXParameter("ExportPath", export_path)
    datax.setDataXParameter("TargetEncoding", "UTF-8")
    datax.setDataXParameter("Overwrite", "true")
    
    # 执行导出
    success = datax.exportData()
    if success:
        print(f"  成功导出 {geo_count} 个对象到 {safe_layer_name}.shp")
    else:
        print(f"  图层 {layer_name} 导出失败")

print("批量导出完成")
```

批量导出时需要注意文件名的合法性，Windows 文件系统不支持某些特殊字符（如 `< > : " / \ | ? *`），在构造文件名时应进行适当的处理和替换。

Sources: [PySSProcess.py](PySSProcess.py#L100-L140)

## 错误处理与故障排除

数据导出过程中可能遇到各种错误，了解常见错误的成因和解决方法，可以帮助您快速定位问题并恢复导出操作。

### 常见导出错误及解决方案

| 错误现象 | 可能原因 | 解决方案 |
|---------|---------|---------|
| `exportData()` 返回 `False` | 输出路径无写入权限 | 检查路径权限，使用管理员权限运行 |
| 输出文件为空 | 选择集为空或参数配置错误 | 验证选择集对象数量，检查参数配置 |
| 字段名称被截断 | Shapefile 字段名限制 | 使用 `FieldMapping` 重命名长字段名 |
| 坐标系统错误 | EPSG 代码不正确 | 验证目标坐标系统的 EPSG 代码 |
| 编码乱码 | 编码参数不匹配 | 设置正确的 `TargetEncoding` 参数 |

### 导出前参数验证清单

在执行 `exportData()` 前，建议进行以下参数验证，以提高导出成功率：

```python
def validate_export_parameters(datax, export_path):
    """验证导出参数的合法性"""
    # 检查路径参数
    path_param = datax.getDataXParameter("ExportPath")
    if not path_param or path_param != export_path:
        print(f"错误：ExportPath 参数未正确设置")
        return False
    
    # 检查路径是否可写
    import os
    export_dir = os.path.dirname(export_path)
    if not os.path.exists(export_dir):
        print(f"错误：输出目录不存在: {export_dir}")
        return False
    if not os.access(export_dir, os.W_OK):
        print(f"错误：输出目录无写入权限: {export_dir}")
        return False
    
    # 检查编码参数
    encoding = datax.getDataXParameter("TargetEncoding")
    if not encoding:
        print("警告：未设置 TargetEncoding，可能使用默认编码")
    
    # 检查是否覆盖
    overwrite = datax.getDataXParameter("Overwrite")
    if overwrite == "false" and os.path.exists(export_path):
        print(f"错误：输出文件已存在且不允许覆盖: {export_path}")
        return False
    
    return True

# 使用验证函数
datax = DataXScript()
datax.setDataXParameter("ExportPath", "D:\\export\\data.shp")
datax.setDataXParameter("Overwrite", "true")

if validate_export_parameters(datax, "D:\\export\\data.shp"):
    success = datax.exportData()
    print(f"导出{'成功' if success else '失败'}")
```

Sources: [PySSDataX.py](PySSDataX.py#L130-L140)

## 最佳实践与性能优化

在实际开发中，遵循一些最佳实践可以显著提高数据导出的效率和可靠性。本节总结了基于项目经验积累的优化建议。

### 性能优化建议

| 优化策略 | 实施方法 | 预期效果 |
|---------|---------|---------|
| 减少字段数量 | 使用 `FieldList` 只导出必要字段 | 减少 30-50% 导出时间 |
| 批量导出 | 合并多个导出任务为单次操作 | 减少初始化开销 |
| 覆盖模式 | 设置 `Overwrite="true"` 避免检查 | 减少文件系统调用 |
| 数据筛选 | 使用选择集过滤不需要的数据 | 提高导出效率 |

### 代码组织建议

将数据导出功能封装为可重用的函数，可以提高代码的可维护性和可测试性。

```python
def export_selection_to_file(
    export_path: str,
    encoding: str = "UTF-8",
    overwrite: bool = True,
    field_list: str = None,
    coord_system: str = None
) -> bool:
    """
    导出当前选择集到指定文件
    
    参数:
        export_path: 导出文件路径
        encoding: 目标编码，默认 UTF-8
        overwrite: 是否覆盖已存在文件
        field_list: 字段列表（逗号分隔）
        coord_system: 坐标系统（EPSG 代码）
    
    返回:
        bool: 导出是否成功
    """
    from sunvpy.PySSDataX import DataXScript
    import os
    
    # 验证路径
    export_dir = os.path.dirname(export_path)
    if not os.path.exists(export_dir):
        os.makedirs(export_dir)
    
    # 创建 DataXScript 实例
    datax = DataXScript()
    
    # 设置基础参数
    datax.setDataXParameter("ExportPath", export_path)
    datax.setDataXParameter("TargetEncoding", encoding)
    datax.setDataXParameter("Overwrite", "true" if overwrite else "false")
    
    # 设置可选参数
    if field_list:
        datax.setDataXParameter("FieldList", field_list)
    if coord_system:
        datax.setDataXParameter("CoordSystem", coord_system)
    
    # 执行导出
    return datax.exportData()

# 使用示例
export_selection_to_file(
    "D:\\export\\roads.shp",
    encoding="UTF-8",
    field_list="SSObj_ID,SSObj_Name,SSObj_Code",
    coord_system="EPSG:4326"
)
```

Sources: [PySSDataX.py](PySSDataX.py#L157-L161)

## 进阶学习路径

掌握基础的数据导出功能后，您可以进一步探索以下高级主题，以实现更复杂的数据交换需求。

- **[自定义数据交换流程](29-zi-ding-yi-shu-ju-jiao-huan-liu-cheng)**：了解如何构建完整的数据交换管道，实现导入、转换、导出的自动化流程
- **[数据交换参数配置](26-shu-ju-jiao-huan-can-shu-pei-zhi)**：深入学习参数配置的详细机制，包括高级参数和自定义参数
- **[批量保存到数据库](24-pi-liang-bao-cun-dao-shu-ju-ku)**：了解如何将导出的数据批量保存到数据库，实现数据持久化