ArcGIS.Server.9.2.DotNet自带例子分析(六、一)

目的:
1.arcgis server9.2 ADF实现Select Features功能

准备工作:
1.用ArcGis Server Manager或者ArcCatalog发布一个叫world的Map Service,并且把这个Service启动起来。
2.找到DeveloperKit\SamplesNET\Server\Web_Applications目录下的Common_SelectBufferToolCSharp.zip。

开始:
1.新建名为SelectTool的ASP.NET Web应用程序,  然后在页面上添加MapResourceManager1、Map1、Toolbar1、Toc1控件。同时对这些控件做相应的设置,这个已经做了很多次了这里不详细说了,具体可以看前面的几篇文章。
2.MapResourceManager1的MapResourceItem总共有3个从最上层往下分别是Buffer(GraphicsLayer,用来缓冲选择元素高亮显示用)、Selection(GraphicsLayer,用来选择元素高亮显示用)、Data Layers(ArcGIS Server Local,就是显示上面发布的world的Map Service)。
3.Toolbar1中添加一个Tool,Name为Select;Text为Select Features;ToolTip为Select Features;ClientAction为DragRectangle;ServerActionAssembly为SelectTool;ServerActionClass为SelectTool.SelectTool。
4.新建SelectTool.cs文件,在这个文件中编写SelectTool类来实现Tool的ServerActionClass。SelectTool类需要实现IMapServerToolAction的接口,实现这个接口必须实现ServerAction的方法。具体代码如下:

1namespace SelectTool
2{
3    public class SelectTool : IMapServerToolAction
4    {
5        void IMapServerToolAction.ServerAction(ToolEventArgs args)
6        
7        }

8    }

9}
5.接下来在ServerAction的方法添加框选查询把结果进行高亮显示的代码,具体代码和说明如下:
 1void IMapServerToolAction.ServerAction(ToolEventArgs args)
 2        {
 3            //Data Layers Resource index为2
 4            int resource_index = 2;
 5            //获取地图控件Map
 6            ESRI.ArcGIS.ADF.Web.UI.WebControls.Map mapctrl = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)args.Control;
 7            //从Session获取目标图层的名称
 8            string targetlayername = (string)mapctrl.Page.Session["TargetLayer"];
 9            //矩形参数
10            RectangleEventArgs rectargs = (RectangleEventArgs)args;
11            //矩形
12            System.Drawing.Rectangle myrect = rectargs.ScreenExtent;
13            //矩形左下定点坐标转换成地理坐标
14            ESRI.ArcGIS.ADF.Web.Geometry.Point minpnt = ESRI.ArcGIS.ADF.Web.Geometry.Point.ToMapPoint(myrect.Left, myrect.Bottom, mapctrl.GetTransformationParams(ESRI.ArcGIS.ADF.Web.Geometry.TransformationDirection.ToMap));
15            //矩形右上定点坐标转换成地理坐标
16            ESRI.ArcGIS.ADF.Web.Geometry.Point maxpnt = ESRI.ArcGIS.ADF.Web.Geometry.Point.ToMapPoint(myrect.Right, myrect.Top, mapctrl.GetTransformationParams(ESRI.ArcGIS.ADF.Web.Geometry.TransformationDirection.ToMap));
17            //
18            ESRI.ArcGIS.ADF.Web.Geometry.Envelope mappoly = new ESRI.ArcGIS.ADF.Web.Geometry.Envelope(minpnt, maxpnt);
19            //获取Data Layers的MapFunctionality
20            ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality mf = (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality)mapctrl.GetFunctionality(resource_index);
21            //获取Data Layers的Resource
22            ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource = mf.Resource;
23            //是否支持Query
24            bool supported = gisresource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality));
25            if (supported)
26            {
27                //建立QueryFunctionality
28                ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality qfunc = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisresource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);
29                //查询图层id和名称
30                string[] lids;
31                string[] lnames;
32                qfunc.GetQueryableLayers(nullout lids, out lnames);
33                int layer_index = 0;
34                //获取目标图层的index
35                for (int i = 0; i < lnames.Length; i++)
36                {
37                    if (lnames[i] == targetlayername)
38                    {
39                        layer_index = i;
40                        break;
41                    }

42                }

43                //SpatialFilter空间过滤
44                ESRI.ArcGIS.ADF.Web.SpatialFilter spatialfilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter();
45                //是否返回地理元素
46                spatialfilter.ReturnADFGeometries = true;
47                //返回的最大记录数
48                spatialfilter.MaxRecords = 1000;
49                //过滤的地理区域
50                spatialfilter.Geometry = mappoly;
51                //进行查询把结果放入DataTable
52                System.Data.DataTable datatable = qfunc.Query(null, lids[layer_index], spatialfilter);
53
54                //把查询结果转成GraphicsLayer,GraphicsLayer是基于System.Data.DataTable类型
55                ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicslayer = Converter.ToGraphicsLayer(datatable, Color.Yellow, Color.Green);
56                //
57                IEnumerable gfc = mapctrl.GetFunctionalities();
58                ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource gResource = null;
59                foreach (IGISFunctionality gfunc in gfc)
60                {
61                    //当Resource为Selection时
62                    if ((gfunc.Resource is ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource) && (gfunc.Resource.Name == "Selection"))
63                    {
64                        //清除Selection的内容
65                        gResource = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource)gfunc.Resource;
66                        gResource.Graphics.Tables.Clear();
67                    }

68                    //当Resource为Buffer时
69                    else if ((gfunc.Resource is ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource) && (gfunc.Resource.Name == "Buffer"))
70                    {
71                        //清除Buffer的内容
72                        ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource buf_res;
73                        buf_res = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource)gfunc.Resource;
74                        buf_res.Graphics.Tables.Clear();
75                    }

76
77                }

78                if (gResource == null)
79                {
80                    return;
81                }

82                //把查询结果添加到Selection中进行高亮显示
83                gResource.Graphics.Tables.Add(graphicslayer);
84
85                //刷新地图显示
86                if (mapctrl.ImageBlendingMode == ImageBlendingMode.WebTier)
87                
88                    mapctrl.Refresh(); 
89                }

90                else if (mapctrl.ImageBlendingMode == ImageBlendingMode.Browser)
91                
92                    mapctrl.RefreshResource(gResource.Name); 
93                }

94
95            }

96        }
6.加入目标图层的选择功能首先在Default的Page_PreRender方法中绑定可以供选择的图层,具体说明和代码如下:
 1protected void Page_PreRender(object sender, EventArgs e)
 2        {
 3            if (!IsPostBack)
 4            {
 5                //获取Data Layers 的IMapFunctionality
 6                ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality mf = (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality)Map1.GetFunctionality(2);
 7
 8                ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisresource = mf.Resource;
 9                bool supported = gisresource.SupportsFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality));
10
11                if (supported)
12                {
13                    //建立QueryFunctionality
14                    ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality qfunc = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisresource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);
15
16                    string[] lids;
17                    string[] lnames;
18                    //查询图层id和名称
19                    qfunc.GetQueryableLayers(nullout lids, out lnames);
20                    for (int i = 0; i < lnames.Length; i++)
21                    {
22                        //把地图名称添加到DropDownList1
23                        DropDownList1.Items.Add(lnames[i]);
24                    }

25                    //默认的目标图层为DropDownList1的第一项
26                    Session["TargetLayer"= DropDownList1.Items[0].Value;
27                }

28            }

29        }
 
7.接下来加入目标图层选择后把选择值存入到Session["TargetLayer"] 中。因为是页面无刷新的执行需要实现ICallbackEventHandler接口。首先是Page_Load事件,具体说明和代码如下:
 1public string sADFCallBackFunctionInvocation;
 2        private string returnstring = "";
 3
 4        protected void Page_Load(object sender, EventArgs e)
 5        {
 6            if (!IsPostBack)
 7            {
 8          
 9                Session["TargetLayer"= "";
10            }

11            //给DropDownList1添加下拉选择的js事件
12            DropDownList1.Attributes.Add("onchange""ChangeDDLContext()");
13            //服务端对客户端回调脚本段
14            sADFCallBackFunctionInvocation = Page.ClientScript.GetCallbackEventReference(this"message""processCallbackResult""context""postBackError"true);
15        }
8.接下来Default.aspx切换到HTML视图添加ChangeDDLContext()脚本方法,具体代码和说明如下:
 1<script language="javascript" type="text/javascript"> 
 2         var context;
 3         //选择目标图层的方法
 4         function ChangeDDLContext()
 5         {
 6            context = 'DDLContext';
 7            ChangeClient(); 
 8         }

 9         
10         function ChangeClient()
11         {
12            var message;
13            if (context == 'DDLContext')
14            {
15              //获取选择值
16              var ddl1value = document.getElementById('DropDownList1').value;
17              message = 'ddl';
18              message += ',' + ddl1value;  
19            }
 
20            //回调方法执行服务端是事情     
21            <%=sCallBackFunctionInvocation%>
22         }

23         
24         //服务端回调函数,为空不做任何处理
25         function HandleResponse()
26         {
27         }

28         
29    </script>
9.接下来进行服务端的功能处理,具体的说明和代码如下:
 1//把服务端的处理结果返回给客户端
 2        public string GetCallbackResult()
 3        {
 4            return returnstring;
 5        }

 6
 7        //接受客户端的请求进行处理
 8        public void RaiseCallbackEvent(string eventArgs)
 9        {
10            if (eventArgs.Contains("ddl"))
11            {
12                ChangeDropDownListServer(eventArgs);
13            }

14        }

15
16        //保存选择的图层到Session["TargetLayer"]中
17        public void ChangeDropDownListServer(string ea)
18        {
19            char[] parser_char = ',' };
20            string[] messages = ea.Split(parser_char);
21            string dll1 = messages[1];
22            Session["TargetLayer"= dll1;
23        }
9.这样就完成了框选并且高亮显示被选中的地理元素。接下来要做的功能就是在上面的基础上把框选的结果同时显示在GridView中。
10.在页面上添加ID为griddiv的DIV,然后在这个DIV中添加一个GridView1,同时给griddiv添加style="visibility: hidden; ",使得这个DIV默认不显示,添加一个CheckBox1用来设置是否把结果显示在GridView中。
11.接下来对SelectTool类的ServerAction方法进行修改添加数据在GridView中显示的功能,具体的代码和说明如下:
 1void IMapServerToolAction.ServerAction(ToolEventArgs args)
 2        {
 3..
 4                //获取CheckBox1的是否选择值
 5                string cbxvalue = (string)mapctrl.Page.Session["CheckBox1Value"];
 6                //查找页面中的GridView1
 7                GridView gdview = (GridView)mapctrl.Page.FindControl("GridView1");
 8  
 9                //不显示
10                string showtable = "'hidden'";
11                //是否在表格中显示结果
12                if (bool.Parse(cbxvalue))
13                {
14                    //把查询结果作为GridView1的数据源进行绑定
15                    gdview.DataSource = datatable;
16                    gdview.DataBind();
17
18                    //获取GridView1显示html
19                    string returnstring = null;
20                    StringWriter sw = new StringWriter();
21                    HtmlTextWriter htw = new HtmlTextWriter(sw);
22                    gdview.RenderControl(htw);
23                    htw.Flush();
24                    returnstring = sw.ToString();
25
26                    //关于CallbackResult方法的使用可以看前面几篇的文章有详细的说明
27                    //无刷新的更新griddiv内容显示,把GridView1的html内容显示在griddiv中
28                    CallbackResult cr = new CallbackResult("div""griddiv""innercontent", returnstring);
29                    mapctrl.CallbackResults.Add(cr);
30                    if (datatable.Rows.Count > 1)
31                    {
32                        showtable = "'visible'";
33                    }

34                    //关于CallbackResult方法的使用可以看前面几篇的文章有详细的说明
35                    //把griddiv的显示状态置为显示
36                    object[] oa = new object[1];
37                    string sa = "var griddiv = document.getElementById('griddiv');";
38                    sa += "griddiv.style.visibility = " + showtable + ";";
39                    oa[0= sa;
40                    CallbackResult cr1 = new CallbackResult(nullnull"javascript", oa);
41                    mapctrl.CallbackResults.Add(cr1);
42                        
43                }

44
45..
46            }

47        }
12.接下拉修改Page_Load方法添加CheckBox1的客户端事件,修改后的代码如下:
 1public string sCallBackFunctionInvocation;
 2        private string returnstring = "";
 3        public string sADFCallBackFunctionInvocation;
 4
 5        protected void Page_Load(object sender, EventArgs e)
 6        {
 7            if (!IsPostBack)
 8            {
 9          
10                Session["TargetLayer"= "";
11                Session["CheckBox1Value"= "false";
12            }

13            //给DropDownList1添加下拉选择的js事件
14            DropDownList1.Attributes.Add("onchange""ChangeDDLContext()");
15            //服务端对客户端回调脚本段
16            sCallBackFunctionInvocation = Page.ClientScript.GetCallbackEventReference(this"message""HandleResponse""context""postBackError"true);
17
18            //给CheckBox1添加点击的js事件
19            CheckBox1.Attributes.Add("onclick""ChangeCheckContext()");
20            //服务端对客户端回调脚本段
21            sADFCallBackFunctionInvocation = Page.ClientScript.GetCallbackEventReference(this"message""processCallbackResult""context""postBackError"true);
22        }

23
13.接下来Default.aspx切换到HTML视图添加CheckBox1的点击事件ChangeCheckContext()脚本方法,具体代码和说明如下:
 1function ChangeClient()
 2         {
 3            var message;
 4            
 5            //目标图层选择
 6            if (context == 'DDLContext')
 7            {
 8              //获取选择值
 9              var ddl1value = document.getElementById('DropDownList1').value;
10              message = 'ddl';
11              message += ',' + ddl1value;  
12            }
 
13            
14            //是否在表格中显示数据
15            if (context == 'CheckBox')
16            {
17                var checkboxvalue = document.getElementById('CheckBox1').checked;
18                
19                message = 'checkbox';
20                message += ',' + checkboxvalue;
21            }

22            
23            //回调方法执行服务端是事情     
24            <%=sCallBackFunctionInvocation%>
25         }

26         
27         //CheckBox1点击事件
28         function ChangeCheckContext(){
29         
30            context = "CheckBox"
31            ChangeClient();
32         }
14.修改服务端的RaiseCallbackEvent方法处理客户端脚本ChangeCheckContext()的请求,具体说明和代码如下:
Code
15.调试运行查看效果,这样框选功能就完成了。本例子剩下的BufferSelect功能下篇在写。
posted @ 2008-08-24 14:59  水的右边  阅读(3234)  评论(13编辑  收藏  举报