Loading...
墨滴

Beeman

2021/09/18  阅读:42  主题:默认主题

超图二次开发

超图二次开发

介绍

supermap一般指北京超图软件股份有限公司。北京超图软件股份有限公司是全球第三大、亚洲最大的地理信息系统(GIS)软件厂商,主要从事地理信息系统相关软件技术研发与应用服务。

SuperMap 和 SharpMap 一样是 Map 渲染类库,可以渲染各类 GIS 数据。

公司与 SuperMap

公司在做「总院机场选址」之前一直都是用的 SharpMap

转而使用 SuperMap 的重要的原因是渲染速度会更快

自此开始 SuperMap .Net 桌面端组件二次开发

安装指南

申请许可

申请网址

​ 申请试用许可:产品系列选择 10i&9D,输入计算机名,得到 .lic9D 文件,即为使用许可(正式许可为.v2c)

​ 许可中心:启动许可中心客户端(注意:要以管理员身份启动,否则无法激活许可)

​ 激活许可:选择刚刚下载的使用许可文件后,点击更新,更新成功即可在许可状态中查看到许可状态。

快速部署

​ 找到组件包下面的「Install_x64.bat」,「Install_x86.bat」双击即可,把「Bin_x64」的路径配置到环境遍历

卸载产品

​ 执行「unsetEnv.bat _x86」,「unsetEnv.bat _x64」即可。

软件结构

工作空间管理器

工作空间管理器,用来展现工作空间所保存的数据内容,由于工作空间的数据组织结构为树状层次结构,所以,工作空间管理器采用工作空间树来形象地展示工作空间中的数据内容。同时,工作空间管理器还提供了管理工作空间的界面互操作功能,包括:以拖拽的方式打开外部工作空间、数据源;以拖拽数据集节点的方式复制数据集;管理工作空间树节点的显示等功能。

image-20210914165242197
image-20210914165242197

工作空间树

工作空间管理器中的工作空间树,实质是 SuperMap 提供的一个控件,该控件对应 WorkspaceTree 类。

工作空间树以树状层次结构形象地展示了 SuperMap 工作空间的数据组织结构,如下图所示,工作空间树的不同层次的节点对应工作空间中相应层次的数据。例如:工作空间节点对应当前所管理的工作空间;数据源集合节点对应工作空间中的数据源集合;数据集节点对应数据源中的数据集等等,以此类推。

image-20210914165251915
image-20210914165251915

工作空间管理器和工作空间树——界面交互操作

功能分类 包含的功能点简介
打开工作空间管理器 通过 WorkspaceControl 类,打开工作空间管理器。
打开工作空间树 通过 WorkspaceTree 类,打开管理工作空间数据结构的工作空间树。
工作空间管理器工具条 工作空间管理器工具条上的功能按钮提供了管理工作空间管理器中的工作空间树节点的功能,如:隐藏或者显示数据源集合、布局集合等节点;对数据集节点、地图节点等进行排序。
打开数据 在工作空间树中,打开工作空间文件;在当前工作空间中打开文件型数据源;工作空间管理器与图层管理器间的交互操作。
复制/追加数据集 在工作空间树中,进行数据集的复制操作。 在工作空间树中,将数据集追加到其他数据集中。
重命名/删除操作 在工作空间树中,进行重命名数据源别名称、数据集名称、地图名称、布局名称以及场景名称。 在工作空间树中,删除工作空间中所保存的数据集、地图、布局、场景。 在工作空间树中,关闭数据源,即将数据源从当前工作空间中移除。
查找 在工作空间树中,查找与给定关键字匹配的树节点,方便数据的定位。

图层管理器

图层管理器,用来展现和管理其所关联的地图或者场景中的图层。如下图所示:左图为关联地图的图层管理器,右图为关联场景的图层管理器。在图层管理器中,所关联的地图或场景中的每一个图层对应图层管理器中的一个节点,对于一些图层,如专题图层,其对应的节点下还存在一些子节点,子节点对应专题图的各个子项,图层管理器中的这些节点所构成的树称为图层树。

image-20210914165828087
image-20210914165828087

二维图层树

如果图层管理器关联的是地图,那么,其中的图层树实质是一个二维图层树,该控件对应 LayersTree 类;如果图层管理器关联的是地图,那么,在图层管理器中对各个图层的交互操作,实质是二维图层树所提供的交互操作功能。

如上图(左图)所示,每一个图层节点对应地图中的一个图层,图层节点上所显示的内容可以分为三类:图层控制按钮,通过单击这些按钮可以对相应的图层进行一些控制,如可显示、可选择、可捕捉、可编辑,对于不同类型的图层,这部分显示的功能按钮可能有所不同,如标签专题图层节点;表达图层类型的图标,二维图层树通过特定的图标,对应表达相应图层的类型;图层名称,图层节点上显示的文字为图层的标题(Layer.Caption 属性值)。

图层管理器和二维/三维图层树——界面交互操作

功能分类 包含的功能点简介
打开二维图管理器 通过 LayersControl 类,打开图层管理器。
打开二维图层树 过 LayersTree 类,打开管理地图图层的二维图层树。
打开三维图层树 通过 Layer3DsTree 类,打开管理场景图层的三维图层树。
图层控制 控制图层的可显示、可编辑、可选择、可捕捉状态。
图层操作 整图层顺序、重命名图层、移除图层、图层复制。
查找图层 在图层树中,查找与给定关键字匹配的树节点,方便地图图层的定位。

功能实现

这里拿公司第一个 SuperMap 项目 『AirporteSiteSPGIS』 说明

image-20210914170818478
image-20210914170818478

软件具备工作空间管理器、图层管理器、地图管理器(二维视图浏览器)、工作空间的打开、另存为、保存、关闭、具备叠加分析和专题图显示功能

工作空间管理器

Workspace workspace = new Workspace(); 
WorkspaceControl workspaceControl = new WorkspaceControl(workspace);//前提需要一个工作空间
pancelWorkspace.Controls.Add(workspaceControl); //绑定到一个 Pancel 上即可实现工作空间管理器可视化  pancelWorkspace 是 winform 的 pancel

图层管理器

LayersControl layersControl = new LayersControl();
layersControl.Dock = DockStyle.Fill;
pancelLayersControl.Controls.Add(layersControl); //pancelLayersControl 是 winform 的 pancel
layersControl.Map = mapControl.Map; //图层管理器的 map 要和 地图管理器的 map 绑定,这样新增加的图层会同时在树结构和二维视图浏览器同时添加并显示

地图管理器

TabPage tabPage = new TabPage(); //winform -> tabControlView -> TabPage 后面如果有需求还可以在添加一个三维视图浏览器
tabPage.Name = "二维视图浏览器";
tabPage.Text = "二维视图浏览器";
tabControlView.Controls.Add(tabPage);
tabControlView.TabPages[0].Controls.Add(m_mapControl); //把地图管理器绑定到这个控件来显示矢量数据

地图管理器的基础操作

分为 选择、漫游、放大、缩小、视图居中、刷新,这些是超图组件自带实现的,直接拿去用就行,就可以实现如上图所示效果。

/// <summary>
/// 初始化二维浏览工具
/// Initialize the browse tool
/// </summary>
private void InitializeBrowseTools()
{
    try
    {
        ToolStrip toolStripBrowseTools = new ToolStrip();
        toolStripBrowseTools.GripStyle = ToolStripGripStyle.Hidden;

        ToolStripButton toolStripButtonSelect = new ToolStripButton();
        ToolStripButton toolStripButtonPan = new ToolStripButton();
        ToolStripButton toolStripButtonZoomIn = new ToolStripButton();
        ToolStripButton toolStripButtonZoomOut = new ToolStripButton();
        ToolStripButton toolStripButtonZoomFree = new ToolStripButton();
        ToolStripButton toolStripButtonViewEntire = new ToolStripButton();
        ToolStripButton toolStripButtonRefresh = new ToolStripButton();

        toolStripBrowseTools.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
        {
            toolStripButtonSelect,
            toolStripButtonPan,
            toolStripButtonZoomIn,
            toolStripButtonZoomOut,
            toolStripButtonZoomFree,
            toolStripButtonViewEntire,
            toolStripButtonRefresh
       });

        if (SuperMap.Data.Environment.CurrentCulture != "zh-CN")
        {
            toolStripButtonSelect.ToolTipText = "Select";

            toolStripButtonPan.ToolTipText = "Pan";

            toolStripButtonZoomIn.ToolTipText = "Zoom In";

            toolStripButtonZoomOut.ToolTipText = "Zoom Out";

            toolStripButtonZoomFree.ToolTipText = "Zoom";

            toolStripButtonViewEntire.ToolTipText = "Full Extent";

            toolStripButtonRefresh.ToolTipText = "Refresh";
        }
        else
        {
            toolStripButtonSelect.ToolTipText = "选择";

            toolStripButtonPan.ToolTipText = "漫游";

            toolStripButtonZoomIn.ToolTipText = "放大";

            toolStripButtonZoomOut.ToolTipText = "缩小";

            toolStripButtonZoomFree.ToolTipText = "自由缩放";

            toolStripButtonViewEntire.ToolTipText = "全幅显示";

            toolStripButtonRefresh.ToolTipText = "刷新";
        }

        toolStripButtonSelect.Image = Properties.Resources.MapSelect;
        toolStripButtonSelect.Click += new EventHandler(toolStripButtonSelect_Click);

        toolStripButtonPan.Image = Properties.Resources.MapPan;
        toolStripButtonPan.Click += new EventHandler(toolStripButtonPan_Click);

        toolStripButtonZoomIn.Image = Properties.Resources.MapZoomIn;
        toolStripButtonZoomIn.Click += new EventHandler(toolStripButtonZoomIn_Click);

        toolStripButtonZoomOut.Image = Properties.Resources.MapZoomOut;
        toolStripButtonZoomOut.Click += new EventHandler(toolStripButtonZoomOut_Click);

        toolStripButtonZoomFree.Image = Properties.Resources.MapZoomFree;
        toolStripButtonZoomFree.Click += new EventHandler(toolStripButtonZoomFree_Click);

        toolStripButtonViewEntire.Image = Properties.Resources.MapEntire;
        toolStripButtonViewEntire.Click += new EventHandler(toolStripButtonViewEntire_Click);

        toolStripButtonRefresh.Image = Properties.Resources.MapRefresh;
        toolStripButtonRefresh.Click += new EventHandler(toolStripButtonRefresh_Click);

        tabControlView.TabPages[0].Controls.Add(toolStripBrowseTools);
        toolStripBrowseTools.SendToBack();
        toolStripBrowseTools.Dock = DockStyle.Top;
    }
    catch (Exception ex)
    {
        Trace.WriteLine(ex.Message);
        MessageBox.Show(ex.Message, "提示");
    }
}

private void toolStripButtonRefresh_Click(object sender, EventArgs e)
{
    m_mapControl.Map.Refresh();
}

private void toolStripButtonViewEntire_Click(object sender, EventArgs e)
{
    m_mapControl.Map.ViewEntire();
}

private void toolStripButtonZoomFree_Click(object sender, EventArgs e)
{
    m_mapControl.Action = SuperMap.UI.Action.ZoomFree;
}

private void toolStripButtonZoomOut_Click(object sender, EventArgs e)
{
    m_mapControl.Action = SuperMap.UI.Action.ZoomOut;
}

private void toolStripButtonZoomIn_Click(object sender, EventArgs e)
{
    m_mapControl.Action = SuperMap.UI.Action.ZoomIn;
}

private void toolStripButtonPan_Click(object sender, EventArgs e)
{
    m_mapControl.Action = SuperMap.UI.Action.Pan;
}

private void toolStripButtonSelect_Click(object sender, EventArgs e)
{
    m_mapControl.Action = SuperMap.UI.Action.Select;
}

到此为止你已经可以拥有这三种显示器了

工作空间操作

根据此软件聊一聊工作空间的事

  • 初始化(new Workspace),可以添加图层、保存、另存等功能,方便用户体验。
  • 打开文件型工作空间(目前只涉及了「.snwu」文件 )
  • 另存为其他路径保存
  • 关闭 关闭一定要释放资源

初始化

初始化很简单就是 new Workspace 即可

打开

OpenFileDialog openFileDig = new OpenFileDialog();
openFileDig.Filter =
    "SMWU files (*.smwu)|*.smwu";  //这里只设置了一种类型的文件 实际还有其他类型文件也可以打开 SXWU 等

if (openFileDig.ShowDialog() == DialogResult.OK)
{
    Workspace workspace = new Workspace();
    string path = openFileDig.FileName; //文件路径
    WorkspaceConnectionInfo connectionInfo = new WorkspaceConnectionInfo(); // 构造工作空间对象和工作空间连接信息对象
    connectionInfo.Server = path; //路径
    connectionInfo.Type = WorkspaceType.SMWU;
    connectionInfo.Name = System.IO.Path.GetFileNameWithoutExtension(path);
    if (workspace.Open(connectionInfo)) 
    {        
        // 打开 返回bool 表示打开状态
    }
    else
    {
        MessageBox.Show("打开失败""提示");
    }
}

保存 And 关闭

//保存 前提对应的工作空间连接信息的 connectionInfo.Server 不能是null
Save 
//另存为
SaveAs
//关闭
close
//释放资源
mapControl.Map.Close(); //关闭地图管理器 必须在工作空间关闭前关闭资源
mapControl.Dispose(); //释放资源
workspace.Close(); //关闭工作空间
workspace.Dispose(); //释放资源

数据源操作

创建

Workspace workspace = new Workspace();
//数据源的连接信息
DatasourceConnectionInfo datasourceConnectionInfo = new DatasourceConnectionInfo();
datasourceConnectionInfo.EngineType = EngineType.UDBX;
string path = Path.Combine(Assembly.GetExecutingAssembly().FolderPath(), "WorkSpace""Datasource.udbx");
datasourceConnectionInfo.Server = path;
datasourceConnectionInfo.Alias = Path.GetFileNameWithoutExtension(path);
//创建数据源
datasource = workspace.Datasources.Create(datasourceConnectionInfo);

数据集操作

数据集实际也是矢量数据 Dataset 可以转换为 DataVector

创建

// 创建数据集
Datasource datasource = workspace.Datasources["Datasource"];
DatasetVectorInfo datasetVectorInfo = new DatasetVectorInfo();
// 设置矢量数据集的信息
datasetVectorInfo.Type = DatasetType.Point; //设置矢量数据类型
datasetVectorInfo.IsFileCache = true;
datasetVectorInfo.Name = name;
datasource.Datasets.Create(datasetVectorInfo);

记录集

了解记录集前,我们聊一聊工作空间、数据源、数据集、记录集之间的关系。

工作空间 (Datasources) > 数据源(Datasets) > 数据集(GetRecordset) > 记录集

比如一个机场坐标点的 shp 数据的所有点就是记录集,其中的一个点就是一条数据

image-20210915164927452
image-20210915164927452

获取字段名,添加字段名

FieldInfos fieldInfos = datasetVector.FieldInfos;
FieldInfo fieldInfo = new FieldInfo();
fieldInfo.Name = "分析值";
fieldInfo.Caption = "分析值";
fieldInfo.DefaultValue = "0";
fieldInfo.Type = FieldType.Double;
fieldInfo.IsRequired = true;
int code = fieldInfos.Add(fieldInfo);
//遍历FieldInfos获取FieldInfo
string attributeName = FieldInfo.Name;

遍历记录集,获取字段值

for (int i = 0; i < recordset.RecordCount; i++)
{
    //根据记录集的字段名获取字段值
    recordset.GetFieldValue(name);
    recordset.MoveNext();
}

图层操作

在介绍图层操作前首先需要着重了解一下 数据源数据集

工作空间 Workspace 包含很多数据源 Datasources,每个数据源 Datasource 都包含一个数据集集合 Datasets,而 Dataset 就可以视作一个图层来显示

增加(导入shp图层)

这里只介绍添加shp型文件作为数据集的图层,shp文件将会保存在 .UDBX 后缀名的数据源文件中,所以要以此类型的数据源来导入shp文件

//创建一个数据源
DatasourceConnectionInfo datasourceConnectionInfo = new DatasourceConnectionInfo();//数据源连接信息类
string path = Path.Combine(Assembly.GetExecutingAssembly().FolderPath(), "WorkSpace""Datasource.udbx");
if (File.Exists(path))
{
    File.Delete(path);
}
datasourceConnectionInfo.Server = path; //数据源文件路径 这里是文件型数据源
datasourceConnectionInfo.Alias = "Shap";//数据源别名
datasourceConnectionInfo.EngineType = EngineType.UDBX;
datasource = workspace.Datasources.Create(datasourceConnectionInfo);

//导入shp数据集
// 1. 构建数据源连接对象。
// 2. 构建SHP导入设置对象(ImportSettingSHP),设置数据源,设置导入数据路径。
ImportSettingSHP importSettingSHP = new ImportSettingSHP();
importSettingSHP.TargetDatasource = datasource; // 导入目标数据源
importSettingSHP.SourceFilePath = fileName; //shp文件全路径
// 3. 获取导入设置对象的导入信息集合(ImportDataInfos),设置目标数据集的名字。
string datasourceName = Path.GetFileNameWithoutExtension(fileName); //数据集名称 这里是文件名称
ImportDataInfos dataInfos = importSettingSHP.GetTargetDataInfos(""); //导入设置信息集合类
importSettingSHP.SetTargetDataInfos(dataInfos);
// 4. 构建数据导入类对象(DataImport),构建并设置导入设置对象集合。
DataImport import1 = new DataImport();  //导入数据类,通过该类可以将外部数据(文件型)导入到SuperMap的格式。 
ImportSettings settings = import1.ImportSettings;
settings.Add(importSettingSHP);
// 5. 执行DataImport类对象的run方法来进行导入,得到导入结果对象。
ImportResult result = import1.Run();
int index = datasource.Datasets.IndexOf(datasourceName); //获得导入后相应的数据集的序号

删除

Map map = mapControl.Map;
TreeNode treeNode = layersControl.LayersTree.SelectedNode; 
Layer layer = map.Layers.FindLayer(treeNode.Text); //获取在图层管理器中选中的图层
Datasource datasource = layer.Dataset.Datasource; //获取图层对应数据集的数据源
map.Layers.Remove(treeNode.Text); // 从图层中删除
datasource.Datasets.Delete(treeNode.Text.Split("@").First());//从数据源中删除
map.Refresh();

图层颜色

设置颜色
LayerSettingVector setting = new LayerSettingVector();
setting.Style.LineColor = form.dicColorSgin["颜色"].Color;//线、点的颜色
setting.Style.FillBackColor = form.dicColorSgin["背景色"].Color;//面的背景色
setting.Style.FillForeColor = form.dicColorSgin["前景色"].Color;//面的前景色
double pointSize = form.dicSizeSgin["点大小"].ToDouble();//点大小
setting.Style.MarkerSize = new Size2D(pointSize, pointSize);
setting.Style.LineWidth = form.dicSizeSgin["线宽"].ToDouble();//线宽
setting.Style.FillOpaqueRate = form.dicSizeSgin["透明度"].ToInt32();//透明度
layer = mapControl.Map.Layers.Add(Dataset, setting, true); //添加图层的时候把设置类添加进去
修改颜色
//图层树空间选中的节点
LayersTreeNodeBase node = layersControl.LayersTree.SelectedNode as LayersTreeNodeBase;
//获取选中的图层
Layer layer = node.GetData() as Layer;
//获取图层设置类
LayerSettingVector setting = layer.AdditionalSetting as LayerSettingVector;
//修改颜色属性值,此处省略不写
//修改后需要更新图层管理器和图层树空间控件
mapControl.Map.Refresh();
layersControl.LayersTree.RefreshNode(node);

图层属性

学习图层属性操作前,需要着重了解一下记录集的内容。

获取属性字段
//获得该图层所有的属性字段
FieldInfos fieldInfos = datasetVector.FieldInfos;
//遍历获取FieldInfo
FieldInfo fieldInfo = fieldInfos[i];
//得到属性名
fieldInfo.Name;
增加属性字段
int code = fieldInfos.Add(fieldInfo);// 将字段 "分析值" 添加到数据集 dataset 中
fieldInfo.Type //属性字段的类型
获取图层记录集(所有对象的属性组成的表格)
//获取记录集
Recordset recordset = datasetVector.GetRecordset(false, CursorType.Dynamic)
遍历记录集,获取属性值,修改属性值
for (int i = 0; i < recordset.RecordCount; i++)
{
    //获取ID属性值
    recordset.GetFieldValue("ID");
    //设置 “分析值” 字段属性值
    recordset.SetFieldValue("分析值"0.1);
    //recordset指向下一条数据
    recordset.MoveNext();
}

地图常用操作

上面地图管理器的基础操作知识初始化地图管理器必须操作,接下来我们结合上面的知识,介绍一些常用的复杂操作,如:

  • 点选一个 Geometry 实体,显示实体对象
  • 绘制一个形状,对一个数据集空间查找,找出与该形状有关系的对象(包含关系等)
  • 点选一点绘制一个圆
  • 选择一个图层显示属性表

绘制点、线、面

绘制点、线、面的区别在于创建的数据集的数据类型,图形管理器的操作类型不同

 // 创建数据集
Datasource datasource = workspace.Datasources["Datasource"];
DatasetVectorInfo datasetVectorInfo = new DatasetVectorInfo();
// 设置矢量数据集的信息
datasetVectorInfo.Type = DatasetType.Point;  //Line //Region
datasetVectorInfo.IsFileCache = true;
datasetVectorInfo.Name = name;
//创建数据集、添加图层这里省略
// 禁用鼠标等待
mapControl.IsWaitCursorEnabled = false;
mapControl.TrackMode = TrackMode.Edit;
m_Layer.IsEditable = true;
mapControl.Action = Action.CreatePoint; // CreatePolyline CreatePolygon

点选对象,显示对象属性

​ 逻辑分析:

  • 前提要给地图管理器绑定点击事件
  • 获取选择集
  • 获取对象记录
  • 根据上面介绍的获取记录集属性字段和对应的属性值
//绑定点击事件
mapControl.GeometrySelected += new GeometrySelectedEventHandler(mapControl_GeometrySelected);
private void mapControl_GeometrySelected(object sender, SuperMap.UI.GeometrySelectedEventArgs e)
{
    //获取选择集
 Selection[] selection = mapControl.Map.FindSelection(true);
    //因为点选一个点,实际这里还需要判断一下
    recordset = selection[0].ToRecordset(); //这样就拿到了点选的到的这个对象的记录集,就可以按照图层属性获取方式来获取属性
}

点选获取形状实体

//获取选择集
Selection[] selection = mapControl.Map.FindSelection(true);
Recordset recordset = selection[0].ToRecordset();
Dataset dataset = recordset.Dataset;
//获取数据集的某条记录集对应的形状
GeoRegion geoRegion = (GeoRegion) recordset.GetGeometry();

空间查询

//设置查询参数
QueryParameter parameter = new QueryParameter();
parameter.SpatialQueryObject = geoRegion;//查询范围
parameter.SpatialQueryMode = SuperMap.Data.SpatialQueryMode.Contain; //包含关系
//获取查询目标 某个数据集的矢量数据
DatasetVector datasetVector = workspace.Datasources["Datasource"].Datasets["区县数据"as DatasetVector;
//获得查到的结果数据集
 Recordset resultRecordset = datasetVector.Query(parameter);

Beeman

2021/09/18  阅读:42  主题:默认主题

作者介绍

Beeman