SuperMap iObjects .NET 11i 二次开发(十七)—— 叠加分析之擦除

前言

上一篇博文简单介绍了有关叠加分析之合并的相关操作,这个部分主要认识下叠加分析之擦除的相关操作。


一、有关常用类说明

|---------------------|--------------------------------------|
| OverlayAnalyst类 | 叠加分析类。该类用于对输入的两个数据集或记录集之间进行各种叠加分析运算。 |

二、有关常用方法说明

三、界面设计

在原有界面基础上,添加合并相关功能点,如下图所示:

四、功能实现

cs 复制代码
private void 擦除ToolStripMenuItem_Click(object sender, EventArgs e)
{
    try
    {
        // 1. 获取当前选中的数据集节点(需要选择2个:被擦除数据集和擦除数据集)
        List<WorkspaceTreeNodeBase> selectedNodes = new List<WorkspaceTreeNodeBase>();

        // 获取工作空间树中所有选中的节点
        foreach (TreeNode node in D_workspaceControl.WorkspaceTree.SelectedNodes)
        {
            if (node is WorkspaceTreeNodeBase workspaceNode)
            {
                selectedNodes.Add(workspaceNode);
            }
        }

        // 2. 检查是否选择了恰好2个数据集
        if (selectedNodes.Count != 2)
        {
            MessageBox.Show("请选择2个面数据集进行擦除操作!\n\n操作说明:按住Ctrl键选择2个数据集节点(第一个为被擦除数据集,第二个为擦除数据集),然后点击擦除功能。");
            return;
        }

        // 3. 将选中的节点转换为数据集
        List<DatasetVector> selectedDatasets = new List<DatasetVector>();
        List<string> invalidDatasets = new List<string>();

        foreach (WorkspaceTreeNodeBase node in selectedNodes)
        {
            Dataset dataset = D_workspace.Datasources[0].Datasets[node.Text];
            if (dataset == null)
            {
                invalidDatasets.Add(node.Text);
                continue;
            }

            // 检查是否为矢量数据集
            if (!(dataset is DatasetVector))
            {
                invalidDatasets.Add($"{node.Text} (非矢量数据集)");
                continue;
            }

            DatasetVector vectorDataset = (DatasetVector)dataset;

            // 检查是否为面数据集(Erase方法要求)
            if (vectorDataset.Type != DatasetType.Region)
            {
                invalidDatasets.Add($"{node.Text} ({GetDatasetTypeChineseName(vectorDataset.Type)}数据集)");
                continue;
            }

            selectedDatasets.Add(vectorDataset);
        }

        // 4. 检查有效的面数据集数量
        if (selectedDatasets.Count != 2)
        {
            string invalidList = invalidDatasets.Count > 0 ?
                $"\n\n无效的数据集:\n{string.Join("\n", invalidDatasets)}" : "";

            MessageBox.Show($"需要选择2个面数据集进行擦除!当前选择了 {selectedDatasets.Count} 个有效的面数据集。{invalidList}");
            return;
        }

        // 5. 检查所有数据集的投影信息一致性
        PrjCoordSys firstPrj = selectedDatasets[0].PrjCoordSys;
        List<string> inconsistentDatasets = new List<string>();

        for (int i = 1; i < selectedDatasets.Count; i++) // 从第二个开始检查
        {
            if (!IsPrjCoordSysEqual(firstPrj, selectedDatasets[i].PrjCoordSys))
            {
                inconsistentDatasets.Add(selectedDatasets[i].Name);
            }
        }

        if (inconsistentDatasets.Count > 0)
        {
            MessageBox.Show($"数据集投影信息不一致!请确保所有数据集使用相同的投影坐标系。\n" +
                          $"投影不一致的数据集: {string.Join(", ", inconsistentDatasets)}\n" +
                          $"参考投影: {selectedDatasets[0].Name}");
            return;
        }

        // 6. 检查数据集是否都有记录
        List<string> emptyDatasets = new List<string>();
        foreach (DatasetVector dataset in selectedDatasets)
        {
            if (dataset.RecordCount == 0)
            {
                emptyDatasets.Add(dataset.Name);
            }
        }

        if (emptyDatasets.Count > 0)
        {
            MessageBox.Show($"以下数据集没有记录,无法进行擦除:\n{string.Join("\n", emptyDatasets)}");
            return;
        }

        // 7. 设置擦除参数
        DatasetVector sourceDataset = selectedDatasets[0]; // 被擦除数据集
        DatasetVector eraseDataset = selectedDatasets[1];  // 擦除数据集

        OverlayAnalystParameter overlayParameter = new OverlayAnalystParameter();
        overlayParameter.Tolerance = 0.0; // 容限值

        // 合并两个数据集的所有字段名称
        List<string> allFields = new List<string>();

        // 添加源数据集的所有字段
        foreach (SuperMap.Data.FieldInfo field in sourceDataset.FieldInfos)
        {
            allFields.Add(field.Name);
        }

        // 添加擦除数据集的所有字段(避免重复字段)
        foreach (SuperMap.Data.FieldInfo field in eraseDataset.FieldInfos)
        {
            string fieldName = field.Name;

            // 如果字段名已存在,可能需要重命名或跳过
            // 这里简单跳过重复字段名,您可以根据需要调整
            if (!allFields.Contains(fieldName))
            {
                allFields.Add(fieldName);
            }
            else
            {
                // 如果字段名重复,可以添加后缀区分
                // allFields.Add($"{fieldName}_Erase");
            }
        }

        overlayParameter.OperationRetainedFields = allFields.ToArray();


        // 生成唯一的结果数据集名称
        string resultDatasetName = GenerateUniqueDatasetName($"{sourceDataset.Name}_擦除结果");
        Datasource resultDatasource = sourceDataset.Datasource;

        // 8. 先创建结果数据集
        DatasetVectorInfo datasetVectorInfo = new DatasetVectorInfo();
        datasetVectorInfo.Name = resultDatasetName;
        datasetVectorInfo.Type = DatasetType.Region; // 面数据集

        // 创建结果数据集
        DatasetVector resultDataset = resultDatasource.Datasets.Create(datasetVectorInfo) as DatasetVector;
        // 结果数据集和擦除数据集坐标系一致
        resultDataset.PrjCoordSys = sourceDataset.PrjCoordSys;
        if (resultDataset == null)
        {
            MessageBox.Show("创建结果数据集失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return;
        }

        // 9. 显示确认对话框
        StringBuilder confirmMessage = new StringBuilder();
        confirmMessage.AppendLine("将要执行擦除操作:");
        confirmMessage.AppendLine($"  被擦除数据集: {sourceDataset.Name} ({sourceDataset.RecordCount} 条记录)");
        confirmMessage.AppendLine($"  擦除数据集: {eraseDataset.Name} ({eraseDataset.RecordCount} 条记录)");
        confirmMessage.AppendLine();
        confirmMessage.AppendLine($"结果数据集: {resultDatasetName}");
        confirmMessage.AppendLine();
        confirmMessage.AppendLine("擦除操作说明:将第一个数据集中包含在第二个数据集内的对象裁剪并删除。");
        confirmMessage.AppendLine();
        confirmMessage.AppendLine("是否继续执行擦除操作?");

        DialogResult confirmResult = MessageBox.Show(
            confirmMessage.ToString(),
            "确认面数据集擦除",
            MessageBoxButtons.YesNo,
            MessageBoxIcon.Question);

        if (confirmResult != DialogResult.Yes)
        {
            // 取消操作时删除已创建的结果数据集
            resultDatasource.Datasets.Delete(resultDatasetName);
            return;
        }

        // 10. 执行擦除操作(使用图片中的四个参数方法)
        bool eraseSuccess = OverlayAnalyst.Erase(
            sourceDataset,      
            eraseDataset,       
            resultDataset,      
            overlayParameter    
        );

        if (eraseSuccess)
        {
            MessageBox.Show($"面数据集擦除完成!\n" +
                          $"被擦除数据集:{sourceDataset.Name}\n" +
                          $"擦除数据集:{eraseDataset.Name}\n" +
                          $"结果数据集:{resultDatasetName}\n" +
                          $"结果记录数:{resultDataset.RecordCount}",
                          "擦除成功",
                          MessageBoxButtons.OK,
                          MessageBoxIcon.Information);

            // 刷新工作空间树显示新数据集
            D_workspaceControl.WorkspaceTree.Refresh();
        }
        else
        {
            // 擦除失败时删除空的结果数据集
            resultDatasource.Datasets.Delete(resultDatasetName);
            MessageBox.Show("面数据集擦除失败!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show($"面数据集擦除过程中发生错误: {ex.Message}\n\n堆栈跟踪:\n{ex.StackTrace}",
                      "错误",
                      MessageBoxButtons.OK,
                      MessageBoxIcon.Error);
    }
}

private string GenerateUniqueDatasetName(string baseName)
{
    string resultName = baseName;
    int counter = 1;
    while (D_workspace.Datasources[0].Datasets[resultName] != null)
    {
        resultName = $"{baseName}_{counter}";
        counter++;
    }
    return resultName;
}

private string GetDatasetTypeChineseName(DatasetType datasetType)
{
    switch (datasetType)
    {
        case DatasetType.Point: return "点";
        case DatasetType.Line: return "线";
        case DatasetType.Region: return "面";
        default: return datasetType.ToString();
    }
}

五、运行结果


总结

以上就是有关于 SuperMap iObjects 11i .NET 叠加分析之擦除相关操作的一些过程记录,我们下篇博文再见!

相关推荐
dust_and_stars2 小时前
ubuntu24使用apt安装VS-code-server code-server
linux·服务器·windows
用户298698530142 小时前
C#: 如何自动化创建Word可填写表单,告别手动填写时代
后端·c#·.net
郑泰科技2 小时前
快速地图匹配(FMM)在轨迹可视化中的核心应用
windows·python·交通物流
梦星辰.3 小时前
超大 JSONL 数据集交互式查看器 Linux便捷工具
linux·windows·microsoft
取个名字太难了a3 小时前
插入APC
windows
mudtools5 小时前
飞书 .NET SDK 事件处理的幂等性与去重机制
websocket·.net·飞书·webhook
非凡ghost5 小时前
ImageConverter(图像转换编辑工具)
图像处理·人工智能·windows·学习·计算机视觉·软件需求
洛克大航海5 小时前
Python 在系统 Windows 和 Ubuntu 中创建虚拟环境
windows·python·ubuntu·虚拟环境
ZEERO~5 小时前
@dataclass的作用
开发语言·windows·python