SuperMap iObjects .NET 11i 二次开发(十六)—— 叠加分析之合并

前言

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


一、有关常用类说明

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

二、有关常用方法说明

|-------------------------------------------------------------------------------------------------|-------------------------------------------|
| OverlayAnalyst.Union(DatasetVector[],OverlayOutputAttributeType,Double,Datasource,String) | 用于对多个面数据集进行合并方式的叠加分析,结果数据集中保存被合并叠加分析的数据集。 |

三、界面设计

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

四、功能实现

cs 复制代码
private void 合并ToolStripMenuItem_Click(object sender, EventArgs e)
{
    try
    {
        // 1. 获取当前选中的多个数据集节点
        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键多选数据集节点,然后点击合并功能。");
            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;

            // 检查是否为面数据集(Union方法要求)
            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. 显示无效数据集的警告(如果有)
        if (invalidDatasets.Count > 0)
        {
            MessageBox.Show($"以下选中的数据集不是面数据集,将被排除在合并操作之外:\n{string.Join("\n", invalidDatasets)}",
                          "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }

        // 6. 检查所有数据集的投影信息一致性
        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;
        }

        // 7. 检查数据集是否都有记录
        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;
        }

        // 8. 设置合并参数
        DatasetVector[] inputDatasets = selectedDatasets.ToArray();
        OverlayOutputAttributeType outputAttributeType = OverlayOutputAttributeType.OnlyAttributes;
        double tolerance = 0.0; // 容限值,根据实际情况调整

        // 生成唯一的结果数据集名称
        string resultDatasetName = GenerateUniqueDatasetName("面数据集合并结果");
        Datasource resultDatasource = selectedDatasets[0].Datasource;

        // 9. 显示确认对话框
        StringBuilder confirmMessage = new StringBuilder();
        confirmMessage.AppendLine($"将要合并以下 {selectedDatasets.Count} 个面数据集:");

        foreach (DatasetVector dataset in selectedDatasets)
        {
            confirmMessage.AppendLine($"  • {dataset.Name} ({dataset.RecordCount} 条记录)");
        }

        confirmMessage.AppendLine();
        confirmMessage.AppendLine($"结果数据集: {resultDatasetName}");
        confirmMessage.AppendLine();
        confirmMessage.AppendLine("是否继续执行合并操作?");

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

        if (confirmResult != DialogResult.Yes)
        {
            return;
        }

        // 10. 执行合并操作
        DatasetVector unionResult = OverlayAnalyst.Union(
            inputDatasets,
            outputAttributeType,
            tolerance,
            resultDatasource,
            resultDatasetName
        );

        if (unionResult != null)
        {
            MessageBox.Show($"面数据集合并完成!\n" +
                          $"成功合并了 {selectedDatasets.Count} 个面数据集\n" +
                          $"结果数据集:{resultDatasetName}\n" +
                          $"总记录数:{unionResult.RecordCount}",
                          "合并成功",
                          MessageBoxButtons.OK,
                          MessageBoxIcon.Information);

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

// 辅助方法
private bool IsPrjCoordSysEqual(PrjCoordSys prj1, PrjCoordSys prj2)
{
    if (prj1 == null && prj2 == null) return true;
    if (prj1 == null || prj2 == null) return false;
    return prj1.ToString() == prj2.ToString();
}

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 叠加分析之合并相关操作的一些过程记录,我们下篇博文再见!

相关推荐
金融小师妹1 小时前
基于NLP政策文本分析与多智能体博弈模拟的FOMC决策推演:“美联储传声筒”下的利率路径分歧
大数据·人工智能·深度学习·1024程序员节
打码人的日常分享1 天前
IPD项目质量体系管理方案
大数据·运维·人工智能·信息可视化·1024程序员节
CoderYanger2 天前
动态规划算法-两个数组的dp(含字符串数组):42.不相交的线
java·算法·leetcode·动态规划·1024程序员节
CoderYanger2 天前
动态规划算法-两个数组的dp(含字符串数组):43.不同的子序列
java·算法·leetcode·动态规划·1024程序员节
CoderYanger2 天前
动态规划算法-两个数组的dp(含字符串数组):41.最长公共子序列(模板)
java·算法·leetcode·动态规划·1024程序员节
CoderYanger3 天前
动态规划算法-子序列问题(数组中不连续的一段):28.摆动序列
java·算法·leetcode·动态规划·1024程序员节
CoderYanger3 天前
动态规划算法-子序列问题(数组中不连续的一段):30.最长数对链
java·算法·leetcode·动态规划·1024程序员节
CoderYanger3 天前
C.滑动窗口——2762. 不间断子数组
java·开发语言·数据结构·算法·leetcode·1024程序员节
智者知已应修善业4 天前
【输入两个数字,判断两数相乘是否等于各自逆序数相乘】2023-10-24
c语言·c++·经验分享·笔记·算法·1024程序员节
CoderYanger4 天前
动态规划算法-子数组、子串系列(数组中连续的一段):21.乘积最大子数组
开发语言·算法·leetcode·职场和发展·动态规划·1024程序员节