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

相关推荐
u0103055276 天前
AI驱动的安卓UI自动生成功能实现
人工智能·1024程序员节
u0103055276 天前
长株潭智能体赋能腾讯元器链接共享
1024程序员节
云贝贝贝8 天前
OceanBase认证体系介绍与备考指南
运维·服务器·oceanbase·1024程序员节
u0103055278 天前
Java图像处理实战指南
人工智能·1024程序员节
u0103055278 天前
Java AWT鼠标事件全解析
人工智能·1024程序员节
u01030552711 天前
Java实用类应用精讲
人工智能·1024程序员节
u01030552711 天前
Java I/O核心操作实战
人工智能·1024程序员节
u01030552712 天前
ArrayList操作详解与实战应用
人工智能·1024程序员节
u01030552713 天前
Java模块化编程实战指南
人工智能·笔记·1024程序员节
u01030552714 天前
使用BufferedReader读取控制台输入
人工智能·1024程序员节