ArcObjects SDK开发 021 开发框架搭建-FrameWork包设计
1、框架引擎部分
引擎模块其实就是之前我们说的App-Command-Tool模块,通过这个模块,把系统的主干框架搭建起来。

其中大部分出现在菜单以及工具条上的按钮都会继承这个框架定义ICommand和ITool。整个系统也是通过整合一些列Comand和Tool的方式,把整个系统搭建出来,这点也可以通过我们系统的主窗体代码中看到。

2、常用Command和Tool
一些常用的工具,例如地图放大、缩小、平移等。这些工具要求定义能够被框架引擎识别,并且符合当前使用的UI风格。定义如下。

使用的时候,只需要一行代码即可。
this.UI_Tool_Bar.Items.Add(new BarCheckItemCommandUI(new FrameworkUI.MapTools.MapZoomInTool(this._MapApplication)));
this.UI_Tool_Bar.Items.Add(new BarCheckItemCommandUI(new FrameworkUI.MapTools.MapZoomOutTool(this._MapApplication)));
FrameworkUI.MapTools.MapPanTool myMapPanTool = new FrameworkUI.MapTools.MapPanTool(this._MapApplication);
this.UI_Tool_Bar.Items.Add(new BarCheckItemCommandUI(myMapPanTool));
this._MapApplication.MapPanTool = myMapPanTool;
this._MapApplication.CrruteTool = myMapPanTool;
this.UI_Tool_Bar.Items.Add(new BarButtonItemCommandUI(new FrameworkUI.MapTools.MapFullExtentCommand(this._MapApplication)));
this.UI_Tool_Bar.Items.Add(new BarButtonItemCommandUI(new FrameworkUI.MapTools.MapZoomInFixedCommand(this._MapApplication)));
this.UI_Tool_Bar.Items.Add(new BarButtonItemCommandUI(new FrameworkUI.MapTools.MapZoomOutFixedCommand(this._MapApplication)));
this.UI_Tool_Bar.Items.Add(new BarButtonItemCommandUI(new FrameworkUI.MapTools.MapZoomBackCommand(this._MapApplication)));
this.UI_Tool_Bar.Items.Add(new BarButtonItemCommandUI(new FrameworkUI.MapTools.MapZoomForwardCommand(this._MapApplication)));
3、通用模块部分
通用模块设计主要包括一些比较通用且核心的模块定义。目前我开发的GeoChem系统定义了三个模块。进度信息模块,Geoprocessor扩展模块和多语言支持模块。

能在Core里面出现的模块,要满足通用性以及核心性两点。我们以最简单的ProcessInfo为例,来说明这样的模块的特性。

配合这个ProcessInfo的是FrameworkUI里面定义的ProcessInfoDialog对话框,定义如下。

设计一,在ProcessInfoDialogHelper使用了一个新线程弹出进度对话框,在主线程进行运算的时候,进度条可以很顺畅的响应进度变化不会卡。
设计二,ProcessInfo定义了SubProcessInfo的概念,可以很好的和子函数衔接。例如一个模型计算,有5个步骤,A(10)、B(30)、C(60)、D(90)、E(100)。其中两个步骤比较复杂,其中B包含3个步骤,B1(20)、B2(80)、B3(100)。D包含了5个步骤,分别是和D1(20)、D2(40)、D3(60)、D4(80)、D5(100)。如何把B和D的计算进度反馈更方便的反馈给计算模型呢?
版本1,不关注B和D的细节了,进度到了A之后,进度条不在动了,只是更新上面的计算信息,等B计算完,一下跳到B该有的进度。D同理。
版本2,加入B是一个专门为本模型定义的一个函数,那么可以把ProcessInfo传入进去,直接设置B1的计算完值为14%,B2计算完之后,设置为26%,B3计算完设置为30%。假如D是一个通用的函数,除了该模块调用,其他模块也会调用,那么可以传ProcessInfo进入,然后再传起始进度值和结束进度值进度。例如调用D,传入ProcessInfo和60、90。计算完D1,设置进度之为60+(90-60)*20%,依次类推。
版本3,设计了SubProcess的概念。当模型调用B的时候,会调用主ProcessInfo,创建一个子ProcessInfo,并设置这个子ProcessInfo应该进度到何值。当子ProcessInfo进度值发生变化的时候,反馈给其父ProcessInfo,由父ProcessInfo计算自己应该前进多少进度。二接收子ProcessInfo的函数,还是设置进度从0-100即可。
调用代码如下。
使用子进度对象的函数定义如下。
public void Exe(ProcessInfo pProcessInfo)
{
//获取栅格CellSize
pProcessInfo.SetProcess(5, "Get cell size...");
double myCellSize = GetRasterCellSize(); //提取栅格数据的范围
pProcessInfo.SetProcess(10, "Data Extent...");
string myRasterDomainFile = this.GetRasterDomain(); //平滑数据
pProcessInfo.SetProcess(12, "Smooth Data...");
string myRasterFilePath = this.SmoothData(this.RasterFilePath); //生成等值线
pProcessInfo.SetProcess(20, "ContourList...");
string myContourLineFile = this.CreateContourLine(myRasterFilePath); //调整等值线值的数据精度
pProcessInfo.SetProcess(25, "Calculate CONTOUR field...");
this.AdjustAccuracy(myContourLineFile); //平滑等值线
pProcessInfo.SetProcess(30, "SmoothLine...");
myContourLineFile = this.SmoothContourLine(myContourLineFile, myCellSize); //用栅格数据的范围裁切等值线
pProcessInfo.SetProcess(35, "Clip Contour Line...");
myContourLineFile = this.ClipContourLineByRasterDomain(myContourLineFile, myRasterDomainFile); //根据等值线,生成等值面
pProcessInfo.SetProcess(40, "Create Contour Polygon");
pProcessInfo.StartSubProcess(70);
string myContourPolygonFile = this.GetContourPolygonFile(pProcessInfo.SubProcessInfo, myContourLineFile, myRasterDomainFile);
pProcessInfo.EndSubProcess(); //得到切割时使用的 Shape文件
pProcessInfo.SetProcess(75, "Clip data...");
this.ClipContourLineAndPolygon(myRasterDomainFile, ref myContourLineFile, ref myContourPolygonFile); //删除面积较为小的面
pProcessInfo.SetProcess(88, "Eliminate Small Area...");
this.ContourEliminate(ref myContourLineFile, ref myContourPolygonFile); //计算极值标注
pProcessInfo.SetProcess(90, "Create Limite Value Point...");
this.UpdateThresholdLabel(myContourPolygonFile); pProcessInfo.SetProcess(95, "Save Map Document...");
this.SaveAsMxdFile(myContourLineFile, myContourPolygonFile);
pProcessInfo.SetProcess(100, "Complete!");
}
使用子进度对象的函数定义如下。
private string GetContourPolygonFile(ProcessInfo pProcessInfo, string pContourLineFile, string pRasterDomainFile)
{
var myContourPolygonCal = new ContourPCreator
{
ContourLineFilePath = pContourLineFile,
ExtentFilePath = pRasterDomainFile,
ResultPolygonFilePath = FilePathHelper.GetTempShapeFilePath()
};
myContourPolygonCal.Exe(pProcessInfo);
return myContourPolygonCal.ResultPolygonFilePath;
}
ContourPCreator类的Exe函数定义如下。
public void Exe(ProcessInfo pProcessInfo)
{
this._PolygonList.Clear();
this._PolylineList.Clear(); //把线转换成面
pProcessInfo.SetProcess(0, "Feature To Polygon...");
var myPolygonFilePath = FilePathHelper.GetTempShapeFilePath();
var myFeatureToPolygon = new FeatureToPolygon()
{
in_features = this.ContourLineFilePath + ";" + this.ExtentFilePath,
out_feature_class = myPolygonFilePath,
cluster_tolerance = "0.001 Meters"
};
GPEx myGPEx = new GPEx();
myGPEx.Execute(myFeatureToPolygon); //用栅格范围裁切面
string myClipOutFilePath = FilePathHelper.GetTempShapeFilePath();
pProcessInfo.SetProcess(10, "Clip...");
var myClip = new ESRI.ArcGIS.AnalysisTools.Clip()
{
in_features = myPolygonFilePath,
clip_features = this.ExtentFilePath,
out_feature_class = myClipOutFilePath
};
myGPEx.Execute(myClip); //添加字段
pProcessInfo.SetProcess(20, "Add Field...");
var myAddField = new AddField
{
in_table = myClipOutFilePath,
field_name = "Value",
field_type = "DOUBLE"
};
myGPEx.ExecuteByGP(myAddField); //拷贝结果数据
ShapeFileHelper.Copy(myClipOutFilePath, this.ResultPolygonFilePath); //读取面信息
pProcessInfo.SetProcess(30, "Init ContourPolygon ...");
this.LoadContourPolygonList(); //分析面与面之间的临近关系
pProcessInfo.SetProcess(40, "Polygon Neighbors ...");
this.LoadContourPolygonRels(); //读取等值线的值列表
pProcessInfo.SetProcess(50, "Read Line Value ...");
this.LoadContourPolylineList(); //面与线 临近分析
pProcessInfo.SetProcess(60, "Load Contour Polygon Line Rels ...");
this.LoadContourPolygonLineRels(); //计算等值面值,在此循环,主要是为了避免特殊情况,导致死循环
pProcessInfo.SetProcess(70, "Cal Contour Polygon Value...");
for (int i = 0; i < 100; i++)
{
int myUnCalCount = this.CalContourPolygonValue();
if (myUnCalCount == 0)
{
break;
}
} //把计算的值写入该文件中
pProcessInfo.SetProcess(90, "Write Value To Contour Polygon File...");
this.WritePolygonValueToFeatureClass(); //计算完成
pProcessInfo.SetProcess(100, "Contour Polygon Cal Complete...");
}
因为ProcessInfo是非常核心一个类,使用范围非常广泛,如果把这个定义好了,会让系统非常清晰。这样的话,每个需要暴露进度的函数,值需要定义一个ProcessInfo参数传入进来即可,在函数内部进度从0开始,100结束,其他的都不需要关心了。
4、常用函数库
常用函数库,我一般会定义到Framework程序集的Helper目录下。如果是字段相关的会定义成FieldHelper,空间参考相关的会定义成SpatialReferenceHepler。并且里面大部分都是静态函数,方便直接调用。

在这些里面用的最多的就是FolderPathHelper、ShapeFileHelper、SpatialReferenceHepler以及FeatureClassHelper等。
ArcObjects SDK开发 021 开发框架搭建-FrameWork包设计的更多相关文章
- TortoiseSVN安装以及淘宝 TAE SDK 开发环境的搭建
一.TortoiseSVN 的下载和安装 1.进入TortoiseSVN 官网下载地址http://tortoisesvn.net/downloads.html,根据自己的操作系统位数下载相应最新版本 ...
- esp8266 SDK开发之环境搭建
最近在弄这个WiFi模块,发现网上SDK开发方面的资料很少,发现了一套视频教程,不过主讲人的讲课方式实在受不了.对基于SDK开发感兴趣的同学可以通过本帖在Ubuntu系统上通过Eclipes搭建开发环 ...
- SDK 开发 .a .framework .bundle (xcode引用) 依赖sdk工程
一. 静态库.a 1.创建静态库工程 Cocoa Touch Static Libray ,然后可以创建一个测试视图 TestView 2.暴露头文件 -> Build Phases--> ...
- Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建
Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ...
- 基于Homestead搭建PHP项目开发环境(适合Zend Framework,Laravel,Yii,thinkphp等)
参考: https://framework.zend.com/bl...参考: https://laravel.com/docs/5.5/... 第一步:软件的下载和安装 软件1:VirtualBox ...
- C# 快速开发框架搭建—开发工具介绍
C# 快速开发框架搭建—开发工具介绍 一.VS2013,SQL SERVER R22008 以上两种工具如有不会者自行百度学习下. 二.动软代码生成器 对于经典的三层架构框架来说,使用动软代码生成器会 ...
- Linux学习心得之 Linux下命令行Android开发环境的搭建
作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Linux学习心得之 Linux下命令行Android开发环境的搭建 1. 前言2. Jav ...
- Java开发环境的搭建以及使用eclipse从头一步步创建java项目
一.java 开发环境的搭建 这里主要说的是在windows 环境下怎么配置环境. 1.首先安装JDK java的sdk简称JDK ,去其官方网站下载最近的JDK即可..http://www.orac ...
- Linux环境下Android开发环境的搭建
本文主要介绍在Ubuntu下Android开发环境的搭建,所使用的IDE为Eclipse(Android Studio同理,且可省去配置SDK以及安装adt插件的步骤). 1.安装JDK (1)JDK ...
- Cordova开发环境的搭建
Cordova开发环境的搭建 原文地址:http://imziv.com/blog/article/read.htm?id=66 Cordova为目前做混合式开发中比较受欢迎的一个解决方案了,并且拥有 ...
随机推荐
- IC入门课第五课作业:完善 Microblog 前端(1、显示发布者的名字;2、增加新UI、3、关注其他学员的 canister)
上周完成了 IC 入门课程第五课的作业 现将答案贴出,欢迎同学们参考,禁止抄袭作业哦 课程作业 (完善 microblog 前端) 1. 显示消息的发布者名字 a. 给 Message 增加 auth ...
- Debian+Wine For Termux,兼容Windows on arm的安卓手机子系统!
如果已经安装了termux,先删掉. 安装方法 下载安装我提供的termux 链接: https://pan.baidu.com/s/13hbp6igps18V2RJcOxgQIg 提取码: 1irn ...
- 改善C#程序的方法-1 操作字符串
正确操作字符串 引言: 字符串是使用很频繁的一种数据类型. 如果使用不慎,则会为一次字符串操作所带来的额外性能开销而付出代价. 下面从这几个方面来探讨如何正确操作字符串: 1.确保尽量少的装箱,尽可能 ...
- Java并发编程 | 从进程、线程到并发问题实例解决
计划写几篇文章讲述下Java并发编程,帮助一些初学者成体系的理解并发编程并实际使用,而不只是碎片化的了解一些Synchronized.ReentrantLock等技术点.在讲述的过程中,也想融入一些相 ...
- NOI2018 D1T1 洛谷P4768 归程 (Kruskal重构树)
实际上是一个最短路问题,但加上了海拔这个条件限制,要在海拔<水位线p中找最短路. 这里使用Kruskal重构树,将其按海拔建成小根堆,我们就可以在树中用倍增找出他不得不下车的点:树中节点有两个权 ...
- Mybatis PageHelper 使用的注意事项
什么时候会导致不安全的分页? PageHelper 方法使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的. 只要你可以保证在 PageHelper 方法调用后紧跟 MyBatis 查 ...
- Vue学习之--------Vue生命周期beforeCreate、created、beforeMount、mounted、beforeDestroy 。。。(图解详细过程)(2022/7/17)
文章目录 1.Vue生命周期 1.1 概念 1.2 图解 2.钩子函数的用法说明 2.1 beforeCreate()和created()的详细讲述 2.1.1 方法说明 2.1.2 代码实例 2.1 ...
- go channel原理及使用场景
转载自:go channel原理及使用场景 源码解析 type hchan struct { qcount uint // Channel 中的元素个数 dataqsiz uint // Channe ...
- debian如何删除无效的应用图标
1.看/usr/share/applications下是否有xxx.desktop 2.可以到-/.local/share/applications下看是否有xxx.desktop 来源:https: ...
- VBA---Basic
题记: 之前用VBA做过几个小工具,用来实现办公自动化的.在编写过程中也遇到了一些问题,但最终都通过网友们的分享予以解决,现对其中的一些知识点进行总结. common sense 取消文件刷新: Ap ...