1、ArcGIS Server 开 发 系 列 ( 一 ) -编 程 框 架 总 览ArcGIS Server 是一个发布企业级 GIS 应用程序的综合平台,如果想对 ArcGIS Server 基础有更多的了解,可以先看看 ArcGIS Server 体系结构、 ESRI(中国)BBS 论坛和 ESRI 网站。这里及接下来的一系列文章将主要介绍 ArcGIS Server 开发相关的内容(如不加说明,后文中 Server 专指 ArcGIS Server),由浅入深,充分利用 Server 的资源来构建我们的企业级应用,同时也可以了解 Server 的优势及不足,在实际应用中扬长避短。进行 Se
2、rver 开发之前,我们首先需要了解 Server 开发的整体架构。下图(截取自官方文档)可以看到,Server 提供了一系列的应用开发途径,从 1 到 4 难度逐步增加,当然功能和可定制性也越来越强,我们可以充分利用 Server 提供的这些资源来构建我们的应用。Web 应用开发Server 为 Web 应用开发提供了一系列的开发方式,在 visual studio 2005 中可以直接使用 Web Mapping Application template 建立应用,它包含了 Web ADF 框架,是学习Server 开发的入口。对照上面的示意图,可以这样来理解,如果想使用各种 Web 控件
3、加上少量代码来构建 Web 应用,可以直接使用第一种途径,这样的应用比较死板,让人感觉有点想搭积木,程序员可能没有任何成就感,好处是开发迅速,适合入门学习或做个简单的 Server演示。如果想在 Common API 基础上,使用各种通用的 functionality,通过各种 data source 类型来定制 Web ADF,可以使用第二种开发途径。如果想使用 Common API,并且需要通过 Common API 调用 specific API 来定制 Web ADF,可以通过第三种途径来开发。Web Service 开发Web Service 是什么不用再介绍,ArcGIS 提供了两
4、种类型的 Web Service 创建方法:GIS Web Service 和 Application Web Service。GIS Web Service 提供了一种将 ArcGIS Server Object(Local data source)发布为ArcGIS Server Web Service(Internet data source)的 ESRI 标准,GIS Web Service不用于开发,通常它们是用来发布信息和提供资源,ArcMap 就可以直接使用 GIS Web Service 的资源而不用进行任何开发,另外 Web ADF 控件和 Common API 也可以使用
5、GIS Web Service 资源。因为 GIS Web Service 基于标准 web service,它可以作为传统 web service 来使用,ArcGIS Server 提供了 SOAP API 进行相关的开发,以后的学习中会使用到。Application Web Service 是基于标准 web service 建立的应用,使用一种 ESRI 的data source 进行开发。因为 web service 没有用户接口,上图中途径一不适合这样的应用,途径四是最适合的,因为 web service 可充分利用 ESRI 提供的各种 data source specific
6、API 的所有 functionality。桌面客户端应用开发ESRI 在桌面客户端应用中提供了两种实现 GIS 功能和服务的方法: ArcGIS Engine 和data source specific developer APIs,上图中只有第四种途径可用于桌面客户端应用。ArcEngine 不论是和本地 GIS 资源交互,还是使用远程数据资源,都拥有丰富的控件和众多 API,但它在使用和分发之前必须进行授权注册,而任何 data source specific developer APIs 都可以在桌面客户端应用中编程使用。移动应用开发移动应用和 Web 应用、web services
7、比较类似,但它们是为某一个特定的客户端环境而设计,如 PocketPC。Mobile ADF 是为移动应用定制的开发框架,通常使用途径四来进行开发,这样可以充分利用 ArcGIS Server Web services 和 SOAP API 提供的功能。在以后的实际开发过程中,我们会逐步了解上述各种开发方式,并不断深入。参考资料(部分翻译):ArcGIS Server 9.2 .Net 开发文档http:/ Chinaemail: dev.vip#blog: http:/ Server 开 发 系 列 ( 二 ) -Web ADF 编 程作者:Flyingis本文严禁擅自转载或用于商业目的,如
8、有需要请事先联系作者:dev.vip# Web ADF 全名是 Web Application Develope Framework,是 ArcGIS Server 专用的开发框架,9.2 版本的 ArcIMS 也开始提供 ADF 的封装。完全使用 Web 控件编程几乎不能解决我们实际项目中的问题,因此我们从 ArcGIS Server 开发系列(一)-编程框架总览中提到的途径二开始,即 web controls + common datasource apis。目标:根据查询语句实现图层信息查询准备工作:1.Windows XP sp2 中/英文版2.Visual Studio 2005 中
9、/英文版3.ArcGIS Server 9.2(我打上了 sp2 补丁),创建一个 ArcGIS Server 服务,Map Server 属性中更改 Pooling,使用池化连接方式,Progresses 选择“In a seperate process for each instance(high isolation)”,我的服务为“World”4.利用 vs2005 创建一个模板 server 应用-Web Mapping Application,并更改MapResourceManager 属性这样我们可以测试程序看是否能够正常运行,启动调试看到如下结果:代码实现:我们要完成的工作是对图
10、层属性信息的查询,首先在页面左侧添加一个新的 panel,左侧的 Tasks、Results 等都是放置在 panel 之中,在这个新的 panel 中分别添加TreeViewPlus、TextBox、Button 三个控件,TextBox 输入查询条件,Button 确定查询, TreeViewPlus 显示结果,在设计试图中浏览效果如下:双击“Query”Button ,编写点击事件。protected void cmdQuery_Click(object sender, EventArgs e)Query(Map1.Extent);Query 方法实现了对图层属性信息的查询。 prote
11、cted void Query(ESRI.ArcGIS.ADF.Web.Geometry.Geometry geometry)IEnumerable func_enum = null;/获取当前 map1 控件中所有的 functionalityfunc_enum = Map1.GetFunctionalities();System.Data.DataTable datatable;/对所有的 functionality 进行遍历foreach (ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality gisfunctionality in func
12、_enum)ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource = null;/得到该 functionality 的 resourcegisresource = gisfunctionality.Resource;/判断该 resource 是否支持 IQueryFunctionality bool supported = false;supported = gisresource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunction
13、ality);if (supported)ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality qfunc;qfunc = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisresource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);string lids;string lnames;/获得图层的 layerId 和 layerName,GetQuery
14、ableLayers 的重载方法可以指定图层类型qfunc.GetQueryableLayers(null, out lids, out lnames);ESRI.ArcGIS.ADF.Web.SpatialFilter spatialfilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter();/设置过滤器的过滤条件,txtQuery 就是 panel 中 text box 的 IDspatialfilter.ReturnADFGeometries = false;spatialfilter.MaxRecords = 1000;spatialfilter.
15、WhereClause = txtQuery.Text;spatialfilter.Geometry = geometry;/对指定的图层进行查询,查询的结果保存为 DataTabledatatable = qfunc.Query(null, lids0, spatialfilter);TreeViewPlus1.Nodes.Clear();if (datatable != null)System.Data.DataSet ds = new System.Data.DataSet();ds.Tables.Add(datatable);TreeViewPlus1.ShowClearAllButt
16、on = false;/将结果绑定到 TreeViewPlus 控件上TreeViewPlus1.BindToDataSet(ds);TreeViewPlus1.Nodes0.Expanded = true;运行程序, text box 中输入“CNTRY_NAME LIKE A%”,查询结果:这样这个小程序就完成了,在 server 中实现了对图层属性信息的查询,现在我们需要进行更多的考虑:第一,考虑 web 控件、 functionality、datasource、resource、resourcemamager之间的关系,代码中多次对它们的关系进行了描述,用文档中的一幅图可以概括整个框架
17、,这篇文章对此进行了阐述- ArcGIS Server .Net Web ADF 体系结构。第二,程序中使用的 mxd 仅仅包含一个 world 图层,因此对图层进行遍历的过程中只需获得第一图层的 ID,如果指定图层名,可以在 lnames 得到所需的图层进行查询。第三,程序实现的查询方式相当简单,在 text box 中输入原始的 sql 来完成 where 语句,只仅仅是一个测试,一般我们会屏蔽掉 sql 相关的关键字,提供多个 text box 或dropdownlist 供用户选择进行字段查询。第四,如果查询信息量不大,返回结果数量不多,完全可以考虑 ajax 来完成页面请求,不论是速
18、度还是用户体验都会得到提高。第五,通过程序可以看到,查询结果保存在一个 datatable 中,这极大的方便了 server 查询和.net 的无缝连接,直接将结果和 TreeViewPlus 绑定,换成其他的 visual studio 控件也没问题。只要整个框架思路清晰了,查询功能的实现其实很简单,这也是途径 2 开发方式的一个例子,可以看出 ArcGIS Server ADF 给开发提供了很多便利,和 ArcIMS 相比开发难度相当,多看看文档和 ADF OMD 图可以让我们对 ArcGIS Server ADF 开发有更多的了解,记住,这只是 server 开发的起步。Flyingis
19、 Chinaemail: dev.vip#blog: http:/ Server 开 发 系 列 ( 三 ) -漫 游 Graphics data sources作者:Flyingis本文严禁擅自转载或用于商业目的,如有需要请事先联系作者:dev.vip# 和 ArcGIS Server Local、ArcGIS Server Internet 一样,GraphicsLayer 是 ArcGIS Server MapResource 的一种,提供 functionality 给 web controls 使用。本文将在 ArcGIS Server 开发系列(二) -Web ADF 编程示例基础
20、上,增加查询结果高亮显示的功能,因为高亮显示的结果并不是图层本身所具备的,因此只需将高亮显示的图片存为graphics 即可。目标:查询结果的高亮显示准备工作:1.以ArcGIS Server 开发系列(二)-Web ADF 编程示例配置和代码为基础。2.MapResourceManager 属性中增加一个名为 Selection 的 MapResource,并将它移动到编号为 0 的位置,即显示在所有 MapResource 最上面。可以看到 GraphicsLayer 的 datasource 是在内存中的,也就是说是为了临时显示或存储使用的,这样速度比较快。Selection 一定要放在
21、 World 上面,否则就被 World 图层覆盖掉了。代码实现:在 UI 界面上,增加一个 command,用来清除 graphics。双击“Select”生成事件响应方法:protected void cmdSelect_Click(object sender, EventArgs e)SelectFeatures();代码的核心就在 SelectFeature()里,它分为两个步骤,第一步对图层进行属性查询,第二步对查询结果进行高亮显示。首先是图层的属性查询:int resource_index = 1;string targetlayername = “countries“;Syste
22、m.Data.DataTable datatable = null;/直接获取 MapResourceName 为 world 的 MapFunctionality,它的编号为 1ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality mf = (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality)Map1.GetFunctionality(resource_index);/先得到 functionality,再获取 resourceESRI.ArcGIS.ADF.Web.DataSources.IGI
23、SResource gisresource = mf.Resource;bool supported = gisresource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality);if (supported)ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality qfunc;qfunc = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisresource.CreateFu
24、nctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);string lids;string lnames;qfunc.GetQueryableLayers(null, out lids, out lnames);ESRI.ArcGIS.ADF.Web.SpatialFilter spatialfilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter();spatialfilter.ReturnADFGeometries = false;spatialfil
25、ter.MaxRecords = 1000;spatialfilter.WhereClause = txtQuery.Text;datatable = qfunc.Query(null, lids0, spatialfilter);这段代码和 ArcGIS Server 开发系列(二)-Web ADF 编程示例中的代码相比,没有太多改动的地方,用到了 ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality,它继承于 ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality 接口。每一个 web control
26、 可能拥有多个 functionality,而 funtionality 是各种 resource 展现出来的,因此可以通过 web controls-funcionalities-resources 这条路线来获得当前的资源,那么如何让查询结果高亮显示呢?/重新获得 Map1 控件所有的 functionalityIEnumerable gfc = Map1.GetFunctionalities();ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource gResource = null;foreach (IGISFunctionality
27、gfunc in gfc)/找到名为“Selection“的 MapResourceif (gfunc.Resource.Name = “Selection“)/down cast 到 ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResourcegResource = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource)gfunc.Resource;if (gResource = null)return;ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGr
28、aphicsLayer glayer = null;foreach (System.Data.DataTable dt in gResource.Graphics.Tables)if (dt is ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer)glayer = (ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer)dt;break;if (glayer = null)glayer = new ESRI.ArcGIS.ADF.Web.Display.Graphic
29、s.ElementGraphicsLayer();gResource.Graphics.Tables.Add(glayer);/清除已有数据glayer.Clear();DataRowCollection drs = datatable.Rows;int shpind = -1;for (int i = 0; i datatable.Columns.Count; i+)if (datatable.Columnsi.DataType = typeof(ESRI.ArcGIS.ADF.Web.Geometry.Geometry)/找到 Geometry 字段的序号shpind = i;break;
30、tryforeach (DataRow dr in drs)ESRI.ArcGIS.ADF.Web.Geometry.Geometry geom = (ESRI.ArcGIS.ADF.Web.Geometry.Geometry)drshpind;/创建一个 GraphicElementESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement ge = null;ge = new ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(geom, System.Drawing.Color.Yellow)
31、;ge.Symbol.Transparency = 50.0;/将 GraphicElement 添加到 ElementGraphicsLayer 中glayer.Add(ge);catch (InvalidCastException ice)throw new Exception(“No geometry available in datatable“);if (Map1.ImageBlendingMode = ImageBlendingMode.WebTier) Map1.Refresh(); else if (Map1.ImageBlendingMode = ImageBlendingM
32、ode.Browser)/只刷新 Graphics ResourceMap1.RefreshResource(gResource.Name);这次我们没有将搜索到的结果绑定到控件上,只要得到高亮显示的结果,测试一下程序,看看能得到什么样的效果。搜索出国家名称以 “C“开头的国家,最典型的 “中国”、“加拿大 ”已经找到了,这样我们就实现了高亮显示的功能。同样,我们进行开发后的小结,能想到些什么呢?还是按照 CH 风格来进行总结:第一,GraphicsLayer 有两个子类,ElementGraphicLayer 和FeatureGraphicLayer,因为程序中只需要暂时显示查询的结果,因此
33、将查询要素存为ElementGraphicLayer 就可以,想想在什么情况下使用 FeatureGraphicLayer。第二,ElementGraphicLayer 继承于 System.Data.DataTable,gResource.graphics属于 System.Data.DataSet 类型,这样使得我们在开发过程中,可以将 GraphicElement添加到 ElementGraphicLayer,然后将 ElementGraphicLayer 添加到gResource.graphics,通过这种途径来向 GraphicsLayer 的 mapresource 中添加数据,这
34、种机制方便了我们能够像操纵 datatable 和 dataset 一样来控制 mapresource 中的数据,既和.Net 无缝整合,也在一定程度上降低了 Server 开发难度,例如代码中 glayer.Clear()调用了 datatable 的 clear()方法,还有后面 GraphicElement 的创建。第三,Map1.ImageBlendingMode 决定了地图的刷新是刷新整个页面,还是仅刷新当前mapresource,这样的设计在 web 开发中尽可能的较少了网络数据传输量。Graphics data sources 是学习 ArcGIS Server data sou
35、rces 的基础,下面一篇,将介绍 ArcGIS Server data sources 的开发,之前网上已经有朋友要求加快写作进度了,不过日常工作中的琐事实在比较多,写代码、文章经常会被打断,写的太差又对不住大家花的时间,所以只能尽量以最快的速度写好每一篇博客,大家的支持就是我的动力:)这篇到此为止,写完收工,回家过周末Flyingis Chinaemail: dev.vip#blog: http:/ Server 开 发 系 列 ( 四 ) -ArcGIS Server data sources 开 发作者:Flyingis本文严禁擅自转载或用于商业目的,如有需要请事先联系作者:dev.v
36、ip# ArcGIS Server 开发系列前几篇文章搭建了一个基本的 webgis 开发框架,包括模板应用程序搭建、属性查询、查询结果高亮显示,在 arcims 中,不论是使用 9.2 之前的javaconnector、.net_link、htmlviewer、还是 9.2 里的 adf,这些功能都可以轻松实现,从软件成本上来看,ArcGIS Server 企业版要比 ArcIMS 高出不少,如何体现 ArcGIS Server 价值呢?我们就从这一篇开始挖掘 ArcGIS Server 的价值,从 ArcGIS Server data sources 启航目标:对点要素进行缓冲区分析准备工
37、作:1.了解 ArcGIS Server 中的 ValueObject 和 ComOjbect。2.AO 接口中缓冲区分析的编程方法。3.重新回顾第一篇中 ArcGIS Server 开发的四种方法。4.利用 vs2005 创建一个模板 server 应用-Web Mapping Application,并更改MapResourceManager 属性。注意这里使用的 map resource 类型是 ArcGIS Server Internet,在界面上增加一个新的 panel,里面包括两个 textbox 和一个 comand,textbox 对应的分别是缓冲区中心点的x、y 坐标,以该点
38、为中心,一定半径做圆形缓冲区。思路:缓冲区分析需要在 AO 接口中实现,输入的点应该是一个 COM 对象,而在页面中输入 xy坐标点是一个 SOAP API valueojbect,valueobject 可以用于 adf web controls,但不能用于 AO 接口,因此需要进行 valueobject 到 comojbect 的转换,在调用ITopologicalOperator 接口的 Buffer 方法后会得到缓冲区分析的结果,即一个 polygon,同理,该 polygon 是一个 comobject,需要逆转换为 valueobject 才能显示到网页上。代码实现:新建一个类
39、XYBuffer,缓冲功能的在其 buffer 方法中实现。首先设置 textbox 中输入点的渲染方式,该作为一个 ESRI.ArcGIS.ADF.ArcGISServer.PointN 对象,渲染方法如下:ESRI.ArcGIS.ADF.ArcGISServer.PointN pt = new ESRI.ArcGIS.ADF.ArcGISServer.PointN();pt.X = x;pt.Y = y;/ 设置点的颜色ESRI.ArcGIS.ADF.ArcGISServer.RgbColor rgb = new ESRI.ArcGIS.ADF.ArcGISServer.RgbColor(
40、);rgb.Red = 0;rgb.Blue = 0;rgb.Green = 20;/ 设置点的符号ESRI.ArcGIS.ADF.ArcGISServer.SimpleMarkerSymbol sms = new ESRI.ArcGIS.ADF.ArcGISServer.SimpleMarkerSymbol();sms.Style = ESRI.ArcGIS.ADF.ArcGISServer.esriSimpleMarkerStyle.esriSMSCircle;sms.Color = rgb;sms.Size = 20;ESRI.ArcGIS.ADF.ArcGISServer.Marker
41、Element marker = new ESRI.ArcGIS.ADF.ArcGISServer.MarkerElement();marker.Symbol = sms;marker.Point = pt;然后用 arcgis server local 方式建立到 datasource 的连接,这点非常重要,主要是为了在这种连接状态下进行 valueobject 和 comobject 之间的转换。建立连接的用户应属于ArcGIS Server 管理组。ESRI.ArcGIS.ADF.Identity identity = new ESRI.ArcGIS.ADF.Identity(“user
42、“, “password“, “localhost“);ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsconnection;agsconnection = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection(“localhost“, identity);agsconnection.Connect();ESRI.ArcGIS.Server.IServerObjectManager som = agsconnection.ServerObjectManager;ESRI.ArcG
43、IS.Server.IServerContext serverContext = som.CreateServerContext(“Redlands“, “MapServer“);这样我们就可以在 arcgis server local 连接方式下进行对象转换:/ 定义 COM 对象的点ESRI.ArcGIS.Geometry.IPoint ipnt;/ 进行 valueobject 到 comobject 之间的转换ipnt = (ESRI.ArcGIS.Geometry.IPoint)ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converte
44、r.ValueObjectToComObject(pt, serverContext);下面是 AO 中缓冲区分析的代码,熟悉 AO 编程的对下面代码应该很了解了:ESRI.ArcGIS.Geometry.ITopologicalOperator topop = (ESRI.ArcGIS.Geometry.ITopologicalOperator)ipnt;double bufferDistance = map.Extent.Width / 6;ESRI.ArcGIS.Geometry.IPolygon bufferPolygon;bufferPolygon = (ESRI.ArcGIS.Ge
45、ometry.IPolygon)topop.Buffer(bufferDistance);bufferPolygon 就是缓冲区分析的结果,但它还不是我们最后想要的,因为ESRI.ArcGIS.Geometry.IPolygon 无法在 adf web control 中显示,还需要做一次转换:/ 定义 valueobject 的点ESRI.ArcGIS.ADF.ArcGISServer.PolygonN buffer_polyn;/ 进行 comobject 到 valueobject 之间的转换buffer_polyn = (ESRI.ArcGIS.ADF.ArcGISServer.Pol
46、ygonN)ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ComObjectToValueObject(bufferPolygon, serverContext, typeof(ESRI.ArcGIS.ADF.ArcGISServer.PolygonN);buffer_polyn 就是我们最后想要的结果,定义一种渲染方式:ESRI.ArcGIS.ADF.ArcGISServer.RgbColor rgb1 = new ESRI.ArcGIS.ADF.ArcGISServer.RgbColor();rgb1.Red = 200;rg
47、b1.Green = 200;rgb1.Blue = 20;/ 设置区的填充色ESRI.ArcGIS.ADF.ArcGISServer.SimpleFillSymbol sfs1 = new ESRI.ArcGIS.ADF.ArcGISServer.SimpleFillSymbol();sfs1.Style = ESRI.ArcGIS.ADF.ArcGISServer.esriSimpleFillStyle.esriSFSHorizontal;sfs1.Color = rgb1;ESRI.ArcGIS.ADF.ArcGISServer.PolygonElement polyelement1 =
48、 new ESRI.ArcGIS.ADF.ArcGISServer.PolygonElement();polyelement1.Symbol = sfs1;polyelement1.Polygon = buffer_polyn;最后将 marker 和 polyelement1 添加到ESRI.ArcGIS.ADF.ArcGISServer.GraphicElement 对象数组中,传给当前MapFunctionality 的 CustomGraphics 属性,刷新 map 控件,看看显示的效果图,缓冲区显示的样式为一系列水平的平行线:以上在 ArcGIS Server 中实现了缓冲区分析功能,虽然 arcims 也能实现(arcims 分析功能也仅限于此),但是两者的本质有天然的差别,前者是基于 AO,因此类推可以将 AO 中的分析功能全部引入 server 中,实现更多更复杂的分析功能。最后,我们还有哪些需要考虑的呢?1.ESRI.ArcGIS.ADF.ArcGISServer 命名空间中我们用到了 PointN 类,但同样可以找到PointB 类,对于其他几何类型也是如此,如 PolylineN 和 PolylineB,它们之间有什么差别呢?2.整个开发过程我们用到了