ArcGIS Server Web ADF开发不提供缓冲区分析的算法,但是ArcObject中提供了缓冲区相关接口ITopologicalOperator的Buffer方法。所以可以用ArcGIS Server远程调用ArcObject缓冲区分析功能。但是调用缓冲区分析功能后的,ADF需要实现缓冲区的表现,通常是采用通过Graphics Layer来实现。ADF通过MapResourceManage添加数据源的时候除了可以添加ArcGIS Server、ArcIMS、OGC等地图数据源外,还支持Graphics 数据源。ADF(或者说MapResourceManager)中的Graphics数据源可以支持两种图层,分别ElementGraphicsLayer 和 FeatureGraphicsLayer,两者都是System.Data.DataTable类型。用以下语句来添加要素图层Graphics数据源中:
- gResource.Graphics.Tables.Add(elementgraphicglayer);
ElementGraphicsLayer一般用来显示基本的图形元素,一个ElementGraphicsLayer可以同时存放不同几何类型(点、线、面等)的元素。一个典型的应用为用该图层来显示被选择的要素(Feature)。
FeatureGraphicsLayer用来模拟要素图层并且存储要素的属性信息。所以可以在客户端根据属性来渲染不同的要素。一个FeatureGraphicsLayer图层只能存放一种几何类型的元素。FeatureGraphicsLayer也支持查询。
Graphic图层中的元素都被存储在内存中,这点与服务器层的Graphic图层不同,后者将元素直接输出到图片上(可以在OutPut文件下查看)。
此外,MapResourceManager只能添加空的Graphics数据源,图层(GraphicsLayer)及元素(Graphic Element)的操作都必须通过编程实现。
因此,首先要在VS中创建两个资源连接,一个是连接地图服务(ArcGIS Server Local),另一个是内存图像(GraphicsLayer),如下图,用来画缓冲图形。
然后添加MapResourceManager和Map控件,用代码添加文本框和缓冲区分析按钮如下:
- <table>
- <tr>
- <td>请输入城市名称</td>
- <td><input id ="TxtName" type ="text" /></td>
- <td><input id ="OkBut" type ="button" value="缓冲分析" onclick ="GetAttriValue()"/>
- </td>
- </tr>
- </table>
下一步编写客户端向服务器传递消息,促使服务发生异步调用的Javascript函数,代码如下:
- <script language ="javascript" type="text/javascript">
- function GetAttriValue()
- {
- var name = document.getElementById("TxtName").value;
- if(name=='')
- {
- alert('请输入城市名称');
- document.getElementById("TxtName").focus();
- return;
- }
- var message = name; //传递消息
- var context = 'Map1';
- <%=m_ADFCallbackFunctionString%> //调用异步处理
- }
- </script>
下面是服务器端的相应源码:
- using System;
- using System.Collections;
- using System.Configuration;
- using System.Data;
- using System.Linq;
- using System.Web;
- using System.Web.Security;
- using System.Web.UI;
- using System.Web.UI.HtmlControls;
- using System.Web.UI.WebControls;
- using System.Web.UI.WebControls.WebParts;
- using System.Xml.Linq;
- using ESRI.ArcGIS.Carto;
- using ESRI.ArcGIS.ADF;
- namespace BufferAanalyze
- {
- public partial class _Default : System.Web.UI.Page, ICallbackEventHandler
- {
- public string m_ADFCallbackFunctionString;
- protected void Page_Load(object sender, EventArgs e)
- {
- m_ADFCallbackFunctionString = Page.ClientScript.GetCallbackEventReference(this, "message",
- "processCallbackResult", "context", "postBackError", true);
- }
- public void RaiseCallbackEvent(string eventargs)
- {
- System.Collections.IEnumerable func_enum = null;
- //获取当前map1控件中所有的functionality
- func_enum = Map1.GetFunctionalities();
- System.Data.DataTable datatable;
- //对所有的functionality进行遍历
- foreach (ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality gisfunctionality in func_enum)
- {
- ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource = null;
- //得到该functionality的resource
- gisresource = gisfunctionality.Resource;
- //判断该resource是否支持IQueryFunctionality
- bool supported = false;
- 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.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);
- string[] lids;
- string[] lnames;
- //获得图层的layerId和layerName,GetQueryableLayers的重载方法可以指定图层类型
- qfunc.GetQueryableLayers(null, out lids, out lnames);
- int selindex = -1;
- for (int i = 0; i < lids.Length; i++)
- {
- if (lnames[i] == "行政区划")
- {
- //找到行政区划图层的序号
- selindex = i;
- break;
- }
- }
- if (selindex > -1)
- {
- //设置过滤器的过滤条件
- ESRI.ArcGIS.ADF.Web.SpatialFilter spatialfilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter();
- spatialfilter.ReturnADFGeometries = true;
- spatialfilter.MaxRecords = 100;
- spatialfilter.WhereClause = "名称 like '%" + eventargs + "%'";
- //对指定的图层进行查询,查询的结果保存为
- datatable = qfunc.Query(null, lids[selindex], spatialfilter);
- if (datatable != null)
- {
- if (datatable.Rows.Count > 0)
- {
- for (int j = 0; j < datatable.Columns.Count; j++)
- {
- if (datatable.Columns[j].DataType == typeof(ESRI.ArcGIS.ADF.Web.Geometry.Geometry))
- {
- //找到该点
- ESRI.ArcGIS.ADF.Web.Geometry.Geometry pnt = (ESRI.ArcGIS.ADF.Web.Geometry.Geometry)datatable.Rows[0][j];
- //对该点进行缓冲分析
- //1,连接服务器
- ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection connection = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection();
- connection.Host = "localhost";
- connection.Connect();
- //2获得服务器对象
- ESRI.ArcGIS.Server.IServerObjectManager pSOM = connection.ServerObjectManager;
- ESRI.ArcGIS.Server.IServerContext pSC = pSOM.CreateServerContext("地图", "MapServer");//服务名和类型
- ESRI.ArcGIS.Carto.IMapServer mapserver = pSC.ServerObject as ESRI.ArcGIS.Carto.IMapServer;
- //3使用服务器对象
- ESRI.ArcGIS.Carto.IMapServerObjects pMSO = (ESRI.ArcGIS.Carto.IMapServerObjects)mapserver;
- ESRI.ArcGIS.Geometry.IGeometry compnt = (ESRI.ArcGIS.Geometry.IGeometry)ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ToIGeometry(pnt, pSC);//ValueObjectToComObject(pnt, pSC);
- ESRI.ArcGIS.Geometry.SpatialReferenceEnvironment sre = new ESRI.ArcGIS.Geometry.SpatialReferenceEnvironment();
- ESRI.ArcGIS.Geometry.ISpatialReference pSR = sre.CreateGeographicCoordinateSystem(4326);
- compnt.SpatialReference = pSR;
- ESRI.ArcGIS.Geometry.ITopologicalOperator pTOPO = (ESRI.ArcGIS.Geometry.ITopologicalOperator)compnt;
- pTOPO.Simplify();
- double bufdis = Map1.Extent.Width / 2;
- ESRI.ArcGIS.Geometry.IPolygon bufPoly = (ESRI.ArcGIS.Geometry.IPolygon)pTOPO.Buffer(1);
- ESRI.ArcGIS.ADF.ArcGISServer.PolygonN valuePoly = (ESRI.ArcGIS.ADF.ArcGISServer.PolygonN)ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ComObjectToValueObject(bufPoly, pSC, typeof(ESRI.ArcGIS.ADF.ArcGISServer.PolygonN));
- ESRI.ArcGIS.ADF.Web.Geometry.Polygon adfpoly = (ESRI.ArcGIS.ADF.Web.Geometry.Polygon)ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.Converter.ToAdfPolygon(valuePoly);
- ESRI.ArcGIS.ADF.Web.Geometry.Geometry geom = adfpoly;
- ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement ge = new ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(geom, System.Drawing.Color.BlueViolet);
- Map1.Zoom(adfpoly);
- ge.Symbol.Transparency = 70;
- System.Collections.IEnumerable gfc = Map1.GetFunctionalities();
- ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource gmap = null;
- foreach (ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality gfunc in gfc)
- {
- if (gfunc.Resource.Name == "graph")
- {
- gmap = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource)gfunc.Resource;
- }
- }
- if (gmap == null) return;
- ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer glayer = null;
- foreach (System.Data.DataTable dt in gmap.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.Graphics.ElementGraphicsLayer();
- gmap.Graphics.Tables.Add(glayer);
- }
- glayer.Clear();//清除以后数据
- glayer.Add(ge);
- //4释放服务器对象
- pSC.ReleaseContext();
- if (Map1.ImageBlendingMode == ESRI.ArcGIS.ADF.Web.UI.WebControls.ImageBlendingMode.WebTier)
- Map1.Refresh();
- else if (Map1.ImageBlendingMode == ESRI.ArcGIS.ADF.Web.UI.WebControls.ImageBlendingMode.Browser)
- Map1.RefreshResource(gmap.Name);
- m_ADFCallbackFunctionString = Map1.CallbackResults.ToString();
- return;
- }
- }
- }
- else
- {
- object[] ob = new object[1];
- string sa = "alert('没有找到该城市');";
- ob[0] = sa;
- ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult callbackresult = new ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult(null, null, "JavaScript", ob);
- Map1.CallbackResults.Add(callbackresult);
- m_ADFCallbackFunctionString = Map1.CallbackResults.ToString();
- }
- }
- }
- }
- }
- }
- public string GetCallbackResult()
- {
- return m_ADFCallbackFunctionString;
- }
- }
- }
运行结果如下图: