PIE SDK组件式开发综合运用示例
1. 功能概述
关于PIE SDK的功能开发,在我们的博客上已经分门别类的进行了展示,点击PIESat博客就可以访问,为了初学者入门,本章节将对从PIE SDK组件式二次开发如何搭建界面、如何综合开发进行详细的讲解。
目录树图
2. 功能实现
2.1.界面搭建
最终的界面如下图所示:
图1最终结果图
2.1.1 新建项目
选择“Window窗体应用程序”,设置程序的名称和保存路径即可。(新建完成后可以将程序的窗体名称右键重命名为“FormMain”,,将窗体界面的属性的Text设置名称为“PIE应用程序”)
图2新建项目
2.1.2 环境搭建
新建项目完成后,系统默认的环境解决方案配置是Debug 模式,解决方平台是Any CPU,这里可以进行将平台改为x86
图3
图4
添加引用:
图5
步骤:右键点击引用-》添加引用选择框内常用的dll即可
图6
图7
2.1.3 菜单设计
第一步:从“工具箱”选择“menuStrip”控件拖到窗体界面,然后依次在菜单栏中设置相应的模块,并修改每个ToolStripMenuItem的属性Name的值,例如“文件”,设置为“toolStripMenuItem_Menu”,其他的同理
图8
第二步:在每一级模块下展开子菜单,如下图:
图9
第三步:从工具箱选择“toolStrip”控件,点击下三角根据不同功能选择不同类型的控件
图10
2.1.4 主界面设计
第一步:添加容器splitContainer容器控件和labControl控件(添加容器之前要先添加状态栏StatusStrip控件,否则界面的控件会出现重叠现象)
图11
第二步:在右边的pannel2里面从工具箱里添加一个TabControl控件,将Dock属性设置为填充“Fill”;
然后右键TabControl控件修改属性“Alignment”为“Bottom”,
修改属性“Dock”为“Bottom”填充,使控件填充页面
图12
最后修改属性,进入TabPage集合编辑器页面,依次选择左侧的将tabPage1的Text修改为“地图模式”,tabPage2的Text修改为“制图模式”。然后确定。
图13
2.1.5 状态栏设计
在“StatusStrip”控件中,设计8个label,一个Combox为比例尺的值控件,地图坐标和屏幕坐标的显示值控件边框显示的属性“BorderSides”设置为“All”
图14. 状态栏
注意:显示比例尺下拉框不能直接的控件可以拖放,具体步骤如下:
第一步选择SplitButton控件,第二步点击下图中的1指向的下三角,第三步点击2旁边的下三角,第四步,选择新建Combox,3指向的选项,最后,点击新建的Combox,复制Ctrl+C,然后点击状态栏进行粘贴,再把原来的splitButton删除就可以。
图15.比例尺下拉框控件
2.2.图层树如何和地图和制图模式控件关联
TOCControl 为用户提供了一个交互式的环境,如果 TOCControl 控件的伙伴控件是 MapControl 控件,当我们将 TOCControl 控件中图层删掉是,MapControl 控件中相应的图层也会被删掉。
当地图视图和制图视图都存在的时候,TocControl控件要与PageLayoutControl控件进行绑定,MapControl的map和PageLayoutControl的map关联,这样才能确保地图视图和制图视图的数据保持一致。
图层树控件tocComtrolMain,地图控件mapControl1,制图控件pageLayoutControl1,为了图层树和地图进行关联,地图和制图数据同步,所以将mapControl1的地图和PageLayoutControl1的地图进行绑定,将PageLayoutControl与图层树进行绑定。并进行地图模式切换的事件功能设计
/// <summary>
/// 初始化函数
/// </summary>
private void InitFrm()
{//绑定
mapControl1.FocusMap = pageLayoutControl1.FocusMap;
tocControlMain.SetBuddyControl(pageLayoutControl1);
mapControl1.Activate();
pageLayoutControl1.DeActivate();
}
然后进行地图模式和制图模式切换事件,右键TabControl控件属性,选择事件,找到SelectIndexChange事件,进行
图16
/// <summary>
/// 地图模式和制图模式切换按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (tabControl1.SelectedIndex == )
{
ActivateMapControl();
}
else if (tabControl1.SelectedIndex == )
{
ActivatePageLayoutControl();
}
}
/// <summary>
/// 激活地图模式
/// </summary>
private void ActivateMapControl()
{
pageLayoutControl1.DeActivate();
mapControl1.Activate();
mapControl1.PartialRefresh(ViewDrawPhaseType.ViewAll);
}
/// <summary>
/// 激活制图模式
/// </summary>
private void ActivatePageLayoutControl()
{
mapControl1.DeActivate();
pageLayoutControl1.Activate();
pageLayoutControl1.PartialRefresh(ViewDrawPhaseType.ViewAll);
}
2.3.功能的实现(部分功能为例)
2.3.1 Pmd地图文档数据的加载
/// <summary>
/// 新建pmd文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripMenuItem_NewPmd_Click(object sender, EventArgs e)
{
NewPmd();
}
/// <summary>
/// 打开pmd文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripMenuItem_OpenPmd_Click(object sender, EventArgs e)
{
OpenPmd();
} /// <summary>
/// 新建Pmd文件
/// </summary>
private void NewPmd()
{
IMapDocument mapDocument = new MapDocument();
DialogResult resultType = MessageBox.Show("是否保存当前地图工程", "新建地图工程", MessageBoxButtons.YesNoCancel);
if (resultType == DialogResult.Cancel)
{
return;
}
else if (resultType == DialogResult.Yes)
{
// 获得保存路径信息
string pmdFilePath = mapDocument.GetDocumentFilename();
if (string.IsNullOrEmpty(pmdFilePath))
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Title = "地图文档另存为:";
saveFileDialog.Filter = "PMD|*.pmd";
if (saveFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
pmdFilePath = saveFileDialog.FileName;
if (string.IsNullOrEmpty(pmdFilePath)) return;
}
if (!pmdFilePath.EndsWith(".pmd"))
{
pmdFilePath = pmdFilePath + ".pmd";
}
mapDocument.SaveAs(pmdFilePath, true, true);
} IMapDocument newMapDocument = new MapDocument();
newMapDocument.New(""); //新建地图工程文档 // 为PageLayoutControl设置PageLayout
IPageLayout newPageLayout = newMapDocument.GetPageLayout();
pageLayoutControl1.PageLayout = newPageLayout; // 为MapControl设置Map
IMap newMap = (newPageLayout as IActiveView).FocusMap;
mapControl1.FocusMap = newMap; if (tabControl1.SelectedIndex == )
{
// 刷新
ActivateMapControl();
}
else if (tabControl1.SelectedIndex == )
{
// 刷新
ActivatePageLayoutControl();
}
}
/// <summary>
/// 打开Pmd文件
/// </summary>
private void OpenPmd()
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "请选择要打开的地图文档:";
openFileDialog.Multiselect = false;
openFileDialog.Filter = "PMD|*.pmd";
if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) return; string pmdNewFilePath = openFileDialog.FileName;
if (string.IsNullOrEmpty(pmdNewFilePath)) return; IMapDocument newMapDocument = new MapDocument();
newMapDocument.Open(pmdNewFilePath); // 为PageLayoutControl设置PageLayout
IPageLayout newPageLayout = newMapDocument.GetPageLayout();
pageLayoutControl1.PageLayout = newPageLayout; // 为MapControl设置Map
IMap newMap = (newPageLayout as IActiveView).FocusMap;
mapControl1.FocusMap = newMap; if (tabControl1.SelectedIndex == )
{
ActivateMapControl();
}
else if (tabControl1.SelectedIndex == )
{
ActivatePageLayoutControl();
}
}
2.3.2 矢量栅格数据的加载
在界面找到自己设计加载数据的按钮,双击按钮进入代码界面进行功能开发
/// <summary>
/// 加载数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripButton_AddData_Click(object sender, EventArgs e)
{
//获取数据路径
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Title = "加载数据";
openFileDialog.Multiselect = false;
openFileDialog.Filter = "Shape Files|*.shp;*.000|Raster Files|*.tif;*.tiff;*.dat;*.bmp;*.img;*.jpg|HDF Files|*.hdf;*.h5|NC Files|*.nc";
if (openFileDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) return; //加载数据
ILayer layer = LayerFactory.CreateDefaultLayer(openFileDialog.FileName);
mapControl1.FocusMap.AddLayer(layer);
mapControl1.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll);
}
2.3.3 图层树的右键操作
图层树的右键操作在PIESat博客的PIE SDK图层树右键菜单与命令绑定中有具体的介绍,右键菜单主要就是通过右键点击图层树弹出ContextMenuStrip控件,在此基础上进行对图层的相应操作。
从工具箱中添加ContextMenuStrip控件,Name设置为contextMenuStrip_Layer;
再添加两个子菜单删除图层和缩放至图层
图17.右键菜单目录
/// <summary>
/// toc点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tocControlMain_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)//右键
{
PIETOCNodeType type = PIETOCNodeType.Null;
IMap map = null;
ILayer layer = null;
Object unk = Type.Missing;
Object data = Type.Missing;
tocControlMain.HitTest(e.X, e.Y, ref type, ref map, ref layer, ref unk, ref data); PIETOCNodeTag tag = new PIETOCNodeTag();
tag.Map = map;
tag.Layer = layer;
tag.UNK = unk;
tag.Data = data;
mapControl1.CustomerProperty = tag; switch (type)
{
case PIETOCNodeType.FeatureLayer://矢量
IFeatureLayer featureLayer = layer as IFeatureLayer;
if (featureLayer == null) return;
contextMenuStrip_Layer.Show(tocControlMain, new System.Drawing.Point(e.X, e.Y));//显示右键菜单
break;
case PIETOCNodeType.RasterLayer://栅格
IRasterLayer rasterLayer = layer as IRasterLayer;
if (rasterLayer == null) return;
contextMenuStrip_Layer.Show(tocControlMain, new System.Drawing.Point(e.X, e.Y));
break;
case PIETOCNodeType.Map://地图
contextMenuStrip_TocMenu.Show(tocControlMain, new System.Drawing.Point(e.X, e.Y));
break;
}
}
} /// <summary>
/// Toc具体选右键菜单中具体项的功能操作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tocMenuItem_Click(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right) return;
ToolStripMenuItem item = sender as ToolStripMenuItem;
if (item == null) return;
ICommand cmd = item.Tag as ICommand;
if (cmd == null) return; cmd.OnCreate(mapControl1);//必须加上
cmd.OnClick(); ITool tool = cmd as ITool;
if (tool != null)
{
mapControl1.CurrentTool = tool;
}
}
图18.初始化函数图
删除图层和缩放图层的MouseUp事件都设置为tocMenuItem_Click事件,在地图初始化InitFrm()中只需要将图层右键菜单的每一项功能的属性tag都设置对应的命令,剩下的操作都共用一份代码,达到了高效便捷的目的;
这种写法虽然高效但是比较难懂,只是为了更有效高级的开发,翻译一下上面的写法就是如下写法,如果右键菜单只是几个功能可以照下方的方式写,但是如果是很多功能点会造成代码的堆砌,最好的方法就是上述示例中的包装方法
图19.调用删除图层命令
代码示例中的右键菜单的具体功能的实现与博客中的图层树的右键菜单功能示例中的两种实现方式都不同,但又有联系,直接的按钮事件可以自己根据需求进行功能开发,也可以直接调用现成的命令,如图15中的删除图层,也可以将命令封装
2.3.4 按钮命令的绑定
图20.界面菜单图
图16中的程序菜单中的大部分的功能都是直接调用的PIE SDK中已经封装好的Command,稍后会以列表的方式汇总展示,下面以部分功能进行介绍其用法图16应用程序菜单
调用命令,需要区分ICommand和ITool的作用,具体介绍请前往PIE SDK Command、Tool、Control的调用和拓展;这篇文章也介绍了Command和Tool的拓展, 即自定义开发功能。
//ITool用法 /// <summary>
/// 地图拉框放大
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripButton_MapZoomIn_Click(object sender, EventArgs e)
{
ITool tool = new MapZoomInTool();
if (tabControl1.SelectedIndex == )
{
(tool as ICommand).OnCreate(mapControl1);
mapControl1.CurrentTool = tool;
}
else if (tabControl1.SelectedIndex == )
{
(tool as ICommand).OnCreate(pageLayoutControl1);
pageLayoutControl1.CurrentTool = tool;
}
}
/// <summary>
/// 属性查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripButton_AttributeIdentify_Click(object sender, EventArgs e)
{
ITool attIdentifyTool = new AttributeIdentifyTool();
ICommand cmd = attIdentifyTool as ICommand;
if (tabControl1.SelectedIndex == )
{
cmd.OnCreate(mapControl1);
cmd.OnClick();
mapControl1.CurrentTool = attIdentifyTool;
}
}
//ICommand /// <summary>
/// 全图显示
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripButton_MapFullExtent_Click(object sender, EventArgs e)
{
ICommand cmd = new FullExtentCommand();
if (tabControl1.SelectedIndex==)
{
cmd.OnCreate(mapControl1);
}
else if(tabControl1.SelectedIndex==)
{
cmd.OnCreate(pageLayoutControl1);
}
cmd.OnClick();
} /// <summary>
/// 比例尺(制图)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void toolStripMenuItem_DrawScaleBarElement_Click(object sender, EventArgs e)
{
ICommand cmd = new AddPageScaleBarCommand();
cmd.OnCreate(pageLayoutControl1);
cmd.OnClick();
}
2.3.5. 状态栏的功能实现
状态栏中的信息有坐标系信息,比例尺,地图坐标和屏幕坐标,这些主要在MapControl和PageLayoutControl控件上操作,可以前往PIE SDK地图鼠标事件监听进行查看。
/// <summary>
/// 鼠标在MapControl上移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void mapControl1_MouseMove(object sender, MouseEventArgs e)
{
//1、当地图空间参考为空时,鼠标移动不起作用
int layerCount = mapControl1.FocusMap.GetAllLayer().Count;
if (layerCount < )
{
mapControl1.SpatialReference = null;
}
ISpatialReference spatialReference = mapControl1.SpatialReference;
if (spatialReference == null)
{
toolStripStatusLabel_CoordinateInfo.Text = null;
return;
} toolStripStatusLabel_CoordinateInfo.Text = spatialReference.Name.ToString();
//2、鼠标移动的屏幕坐标
toolStripStatusLabel_screenCoordinate.Text = string.Format("{0},{1}", e.X, e.Y);
//3、鼠标移动的地图坐标
IPoint point = mapControl1.ToMapPoint(e.X, e.Y);
toolStripStatusLabel_coordinateSystem.Text = string.Format("{0},{1}", point.X.ToString("0.0000"), point.Y.ToString("0.0000"));//保留四位小数
}
比例尺调用的PIE SDK 封装的控件,具体的比例尺看PIE SDK地图范围设置博客中的即可,主要是对mapControl1.ActiveView.DisplayTransformation.MapScale的设置。
图21
3. 代码路径
项目路径 |
百度云盘地址下/PIE示例程序/15.综合运用/PIEApplication1 |
视频路径 |
百度云盘地址下/PIE视频教程/15.综合运用/组件式开发综合运用示例.avi |
PIE SDK组件式开发综合运用示例的更多相关文章
- Agile.Net 组件式开发平台 - 组件开发示例
所谓组件式开发平台,它所有的功能模块都是以组件的形式扩展的,下面我来演示一个简单的组件开发例程. Agile.Net开发管理平台项目,已经托管在开源中国码云平台(http://git.oschina. ...
- Agile.Net 组件式开发平台 - 驱动开发示例
首先讲一下概念,此驱动非彼驱动.在Agle.Net中我们将组件规划成两种类型,一种是基于业务的窗体组件,一种是提供扩展功能的驱动组件. 打个比方例如一般系统中需要提供身份证读卡功能,然而市面上有很多种 ...
- Agile.Net 组件式开发平台 - 服务开发示例
在上一篇文章中已经讲解了组件的开发,这篇文章讲解平台服务开发. Agile.Net开发管理平台项目,已经托管在开源中国码云平台(http://git.oschina.net) 登陆码云平台进入项目主页 ...
- 基于TypeScript的FineUIMvc组件式开发(开头篇)
了解FineUIMvc的都知道,FineUIMvc中采用了大量的IFrame框架,对于IFrame的优缺点网上也有很多的讨论,这里我要说它的一个优点“有助于隔离代码逻辑”,这也是FineUIMvc官网 ...
- Agile.Net 组件式开发平台 - 平台系统介绍
平台介绍 Agile.Net 组件式开发平台是一款针对企业级产品的开发框架,平台架构基于SOA服务体系,多层组件式架构打造.平台提供企业应用开发所需的诸如ORM.IOC.WCF.EBS.SOA等分布式 ...
- 组件式开发(Vue)
什么是组件式开发: 组件式开发就是将单个组件组合起来,形成一个大的组件进行页面的开发完成 什么是复合型组件: 复合型组件就是将相同的功能写成一个公用的组件(单元组件),供其他组件使用,就类似于后台开发 ...
- PIE.NET-SDK组件式二次开发文档
一.PIE.Net开发环境及目录说明 1. 开发环境 确保Win7系统已安装SP1 安装Visual Studio2013(支持VS2010/2012/2013/2015) 安装PIESDK.ex ...
- 基于TypeScript的FineUIMvc组件式开发(概述)
WebForm与Mvc 我简单说一下WebForm与Mvc,WebForm是微软很早就推出的一种WEB开发架构,微软对其进行了大量的封装,使开发人员可以像开发桌面程序一样去开发WEB程序,虽然开发效率 ...
- Vuejs - 组件式开发
初识组件 组件(Component)绝对是 Vue 最强大的功能之一.它可以扩展HTML元素,封装可复用代码.从较高层面讲,可以理解组件为自定义的HTML元素,Vue 的编译器为它添加了特殊强大的功能 ...
随机推荐
- centos7.0查看有没有运行mysql
centos7自带是mariadb,一个mysql的变种. 查看有没有安装过:yum list installed mysql*rpm -qa | grep mysql* 安装mysql软件(mari ...
- java调.NET webapi时间戳报错问题
JAVA时间戳长度是13位,如:1294890876859 PHP .NET时间戳长度是10位, 如:1294890859 主要最后三位的不同,JAVA时间戳在.NETPHP中使用,去掉后三位,如:1 ...
- lnmp 多站点配置负载均衡
1.虚拟机安装3个centos 2.三台服务器IP: 192.168.191.129(主)192.168.191.130192.168.191.131 3.分别在3台服务器的vhost目录下新建配置文 ...
- 部分类Partial
Partial告诉编译器,一个类,结构,接口的定义源代码可能要分散到一个或者多个源文件中. 在下面的情况下用Partial类型: (1) 类型特别大,不宜放在一个文件中实现.(2) 一个类型中的一部分 ...
- 关于利用word发布文章到博客
目前大部分的博客作者在写博客这件事情上都会遇到以下3个痛点:1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.2.发布到博客或公众号平台 ...
- 引用数据数据类型Scanner、Random
键盘录入Scanner 获取键盘录入的数据,对获取数据的具体操作进行了封装,只需要调用方法,即可得到键盘录入的数据 A:导包 import java.util.Scanner; ...
- (二)ASP.NET中JavaScript的中英文(多语言)实现方案(二)
在ASP.NET中JavaScript的中英文(多语言)实现方案中简单的介绍了js实现多语言的一种方案.下面将要讲述另外一种方法,尽管很相似,但是有些地方也是需要细细琢磨的,不说了,先看看. 在Lan ...
- NIOS II SOPC系统自定义IP常见知识点总结
封装IP1.将写好的Verilog代码添加在Quartus工程中,IP目录下,(如果没有,自己建一个)2.打开Qsys工具,选择New Component3.name和Display name输入合理 ...
- pom.xml导入项目的时候,出错
- 使用Amazon Simple Queue Service(SQS) 实现简单的消息服务
一 引言 亚马逊Amazon作为云计算的领跑者推出了很多云服务,最近因为项目的原因,需要用到SQS服务,因此简要地写下这篇随笔,一来方便以后查阅,二来方便共享一些简单的操作. SQS即可以理解为一个 ...