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

目的:
1.MapIdentify功能,自定义Tool以及TaskResults应用
准备:
1.(一、二)的工程,具体见前篇。

开始:
1.编辑Toolbar1的ToolbarItems属性添加一个Tool,ClientAction属性为MapIdentify('Map1'); Name属性为MapIdentify Text属性为Identify ToolTip属性为Identify (Ctrl-MouseClick) 具体代码如下:
1<esri:Tool ClientAction="MapIdentify('Map1');" DefaultImage="~/Images/identify.png"
2HoverImage="~/Images/identify_HOVER.gif" JavaScriptFile="" Name="MapIdentify" SelectedImage="~/Images/identify_ON.gif" Text="Identify" ToolTip="Identify (Ctrl-MouseClick)" />
2.开始代码部分的编写,添加MapIdentify.cs,用来实现具体的功能。代码和说明如下:
  1using System.Web;
  2using System.Web.Security;
  3using System.Web.UI;
  4using System.Web.UI.WebControls;
  5using System.Web.UI.WebControls.WebParts;
  6using System.Web.UI.HtmlControls;
  7using ESRI.ArcGIS.ADF.Web.UI.WebControls;
  8using System.Collections.Specialized;
  9using ESRI.ArcGIS.ADF.Web.DataSources;
 10using System.Collections.Generic;
 11using ESRI.ArcGIS.ADF.Web;
 12using ESRI.ArcGIS.ADF.Web.Display.Graphics;
 13
 14namespace MappingApp
 15{
 16    public class MapIdentify
 17    {
 18        private Page m_page;
 19        private Map m_map;
 20        //客户端脚本段
 21        private string m_callbackInvocation = "";
 22        //脚本路径
 23        private string m_filePath = "";
 24
 25        //保留几位小数
 26        private int m_numberDecimals = 3;
 27
 28        //可见图层
 29        private IdentifyOption m_idOption = IdentifyOption.VisibleLayers;
 30        //查询的冗余范围半径
 31        public int m_IdentifyTolerance = 5;
 32        //用来显示查询结果内容
 33        private TaskResults m_resultsDisplay = null;
 34
 35        private DataSet m_dataset;
 36
 37        public MapIdentify()
 38        {
 39        }

 40
 41        public MapIdentify(Map map)
 42        {
 43            if (map != null)
 44            {
 45                m_map = map;
 46
 47                //生成客户端调用方法
 48                SetupIdentify();
 49            }

 50        }

 51
 52        public MapIdentify(Map map, string filePath)
 53        {
 54            m_map = map;
 55            m_filePath = filePath;
 56
 57            //生成客户端调用方法
 58            SetupIdentify();
 59        }

 60
 61        //生成客户端调用方法
 62        public void SetupIdentify()
 63        {
 64            //获取Map控件所在的页面
 65            m_page = m_map.Page;
 66            System.Text.StringBuilder sb = new System.Text.StringBuilder();
 67            //生产客户端的脚本段
 68            m_callbackInvocation = m_page.ClientScript.GetCallbackEventReference(m_page, "message""processCallbackResult""context"true);
 69            //引用display_mapidentify.js的文件
 70            sb.Append("\n<script language=\"javascript\" type=\"text/javascript\" src=\"" + m_filePath + "JavaScript/display_mapidentify.js\" ></script>\n");
 71            //
 72            sb.Append("<script language=\"javascript\" type=\"text/javascript\">var identifyCallbackFunctionString = \"" + m_callbackInvocation + "\";</script>\n");
 73            //把sb的脚本注册到页面中
 74            if (!m_page.ClientScript.IsClientScriptBlockRegistered("IdentifyScript"))
 75            {
 76                m_page.ClientScript.RegisterClientScriptBlock(m_page.GetType(), "IdentifyScript", sb.ToString());
 77            }

 78        }

 79
 80        //具体的功能实现方法
 81        public string Identify(NameValueCollection queryString)
 82        {
 83            //x,y的坐标
 84            string xString = queryString["minx"];
 85            string yString = queryString["miny"];
 86            string locXString = "";
 87            string locYString = "";
 88            int x = Convert.ToInt32(xString);
 89            int y = Convert.ToInt32(yString);
 90
 91            IGISResource resource;
 92            IQueryFunctionality query;
 93
 94            //像素坐标转换成地理坐标
 95            ESRI.ArcGIS.ADF.Web.Geometry.Point mapPoint = ESRI.ArcGIS.ADF.Web.Geometry.Point.ToMapPoint(x, y, m_map.GetTransformationParams(ESRI.ArcGIS.ADF.Web.Geometry.TransformationDirection.ToMap));
 96            List<DataSet> gdsList = new List<DataSet>();
 97            foreach (IMapFunctionality mapFunc in m_map.GetFunctionalities())
 98            {
 99                if (mapFunc is ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality)
100                {
101                    continue;
102                }

103                resource = mapFunc.Resource;
104                //建立查询方法
105                query = resource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), "identify_"as IQueryFunctionality;
106                string[] layerIds;
107                string[] layerNames;
108                //查询地图图层id和名称
109                query.GetQueryableLayers(nullout layerIds, out layerNames);
110                //resource类型
111                string resourceType = resource.DataSource.GetType().ToString();
112
113                //只显示坐标的3个小数
114                double roundFactor = Math.Pow(10, m_numberDecimals);
115                string pointXString = Convert.ToString(Math.Round(mapPoint.X * roundFactor) / roundFactor);
116                string pointYString = Convert.ToString(Math.Round(mapPoint.Y * roundFactor) / roundFactor);
117
118                locXString = pointXString;
119                locYString = pointYString;
120
121                DataTable[] ds = null;
122                try
123                {
124                    //进行查询并且把查询结果放入DataTable数组  
125                    //                                查询坐标  冗余半径             只查可见图层
126                    ds = query.Identify(mapFunc.Name, mapPoint, m_IdentifyTolerance, m_idOption, null);
127                }

128                catch (Exception e)
129                {
130                    //出错处理
131                    DataTable table = new DataTable();
132                    table.TableName = "Identify Error: " + e.Message;
133                    ds = new DataTable[] { table };
134                }

135                //判断查询结果
136                if (ds != null && ds.Length > 0)
137                {
138                    DataSet gds = new DataSet();
139                    DataTable table;
140
141                    //对查询结果DataTable[]进行遍历添加到DataSet
142                    for (int j = ds.Length - 1; j >= 0; j--)
143                    {
144                        table = ds[j];
145                        if (table.Rows.Count == 0 && table.TableName.IndexOf("Error"< 0)
146                        {
147                            //跳过本次进入下一次循环
148                            continue;
149                        }

150
151                        //把DataTable转换成GraphicsLayer
152                        GraphicsLayer layer = ESRI.ArcGIS.ADF.Web.Converter.ToGraphicsLayer(table, System.Drawing.Color.Empty, System.Drawing.Color.Aqua);
153                        if (layer != null)
154                        {
155                            gds.Tables.Add(layer);
156                        }

157                        else
158                        {
159                            gds.Tables.Add(table);
160                        }

161                    }

162                    if (gds.Tables.Count == 0)
163                    {
164                        //跳过本次循环
165                        continue;
166                    }

167                    gds.DataSetName = resource.Name + " (" + pointXString + "" + pointYString + ")";
168                    gdsList.Add(gds);
169                }

170            }

171            for (int i = gdsList.Count - 1; i >= 0; i--)
172            {
173                //用TaskResults进行查询内容显示
174                m_resultsDisplay.DisplayResults(nullnullnull, gdsList[i]);
175            }

176
177            //没有查询到结果
178            if (gdsList.Count == 0)
179            {
180                string heading = "Location (" + locXString + "" + locYString + ") No results found";
181                string detail = "No results found";
182                SimpleTaskResult str = new SimpleTaskResult(heading, detail);
183                m_resultsDisplay.DisplayResults(nullnullnull, str);
184            }

185
186            //返回结果
187            return m_resultsDisplay.CallbackResults.ToString();
188        }

189
190        public Map Map
191        {
192            get return m_map; }
193            set { m_map = value; }
194        }

195
196        public Page Page
197        {
198            get return m_page; }
199            set { m_page = value; }
200        }

201
202        public DataSet DataSet
203        {
204            get return m_dataset; }
205            set { m_dataset = value; }
206        }

207
208        public IdentifyOption IdentifyOption
209        {
210            get return m_idOption; }
211            set { m_idOption = value; }
212        }

213
214        public string ClientCallbackInvocation
215        {
216            get return m_callbackInvocation; }
217            set { m_callbackInvocation = value; }
218        }

219
220        public string FilePath
221        {
222            get return m_filePath; }
223            set { m_filePath = value; }
224        }

225
226        public TaskResults ResultsDisplay
227        {
228            get return m_resultsDisplay; }
229            set { m_resultsDisplay = value; }
230        }

231
232        public int NumberDecimals
233        {
234            get return m_numberDecimals; }
235            set { m_numberDecimals = value; }
236        }

237    }

238}

239
3.在页面上新增TaskResults控件用来显示查询内容ID为TaskResults1,接着在Page_Load事件里添加实例化上面的MapIdentify类具体代码和说明如下:
1//实例化MapIdentify,并且把Map1控件作为参数
2MapIdentify identify = new MapIdentify(Map1);
3//显示查询结果的控件
4identify.ResultsDisplay = TaskResults1;
5//小数位数
6identify.NumberDecimals = 4;
4.接着还需要对RaiseCallbackEvent方法进行修改添加对查询结果处理的代码,具体代码和说明如下:
 1//对客户端的请求进行处理
 2        public virtual string RaiseCallbackEvent(string responseString)
 3        {
 4            //对请求字符串进行分割以键值的形式放到NameValueCollection m_queryString中,方便接下来的使用
 5            Array keyValuePairs = responseString.Split("&".ToCharArray());
 6            NameValueCollection m_queryString = new NameValueCollection();
 7            string[] keyValue;
 8            string response = "";
 9            if (keyValuePairs.Length > 0)
10            {
11                for (int i = 0; i < keyValuePairs.Length; i++)
12                {
13                    keyValue = keyValuePairs.GetValue(i).ToString().Split("=".ToCharArray());
14                    m_queryString.Add(keyValue[0], keyValue[1]);
15                }

16            }

17            else
18            {
19                keyValue = responseString.Split("=".ToCharArray());
20                if (keyValue.Length > 0)
21                {
22                    m_queryString.Add(keyValue[0], keyValue[1]);
23                }

24            }

25
26            //请求字符串样例:ControlID=Map1&ControlType=Map&EventArg=CloseOutApplication,这样就可以很容易理解了
27            string controlType = m_queryString["ControlType"];
28            string eventArg = m_queryString["EventArg"];
29            if (controlType == null)
30            {
31                controlType = "Map";
32            }

33
34            //根据controlType的不同对请求做不同的处理
35            switch (controlType)
36            {
37                case "Map":
38                    if (eventArg == "CloseOutApplication")//关闭页面请求-CloseOut()
39                    {
40                        //ServerContext对象,需要 ESRI.ArcGIS.Server;
41                        IServerContext context;
42                        for (int i = 0; i < Session.Count; i++)
43                        {
44                            //清除session
45                            context = Session[i] as IServerContext;
46                            if (context != null)
47                            {
48                                context.RemoveAll();
49                                context.ReleaseContext();
50                            }

51                        }

52                        Session.RemoveAll();
53                        //从webconfig中获取关闭后的页面地址
54                        response = ConfigurationManager.AppSettings["CloseOutUrl"];
55                        if (response == null || response.Length == 0)
56                        {
57                            response = "ApplicationClosed.aspx";
58                        }

59                    }

60                    else if (eventArg == "GetCopyrightText")//显示版权-webMapAppGetCopyrightText()
61                    {
62                        System.Text.StringBuilder sb = new System.Text.StringBuilder();
63                        //webMapAppGetCopyrightText()请求服务器后返回结果由processCallbackResult进行客户端处理
64                        //关于processCallbackResult方法的参数格式 控件类型:::控件ID:::内容类型:::内容,如div:::mydiv:::content:::你好,GIS!
65                        sb.AppendFormat("///:::{0}:::innercontent:::""CopyrightTextContents");
66                        int sbLength = sb.Length;
67                        //获取版权内容
68                        sb.Append(GetCopyrightText());
69                        if (sb.Length == sbLength)
70                        {
71                            //没有获取,显示为没有版权
72                            sb.Append("No Copyright information available.");
73                        }
 
74                        response = sb.ToString();
75                    }

76                    else if (eventArg == "MapIdentify")//当eventArg == "MapIdentify"是调用identify类的方法进行处理并且返回内容
77                    {
78                        if (identify != null)
79                        {
80                            identify.Map = Map1; 
81                            response = identify.Identify(m_queryString);
82                        }

83                    }

84                    break;
85                default:
86                    break;
87            }

88            //输出给客户端的内容
89            return response;
90        }
5.还需要编写客户端的脚本MapIdentify('Map1');响应MapIdentify工具的操作,在javascript目录中新增display_mapidentify.js文件,至于页面对这个文件的引用在前面的MapIdentify类的SetupIdentify()方法已经添加的对这个文件的引用,具体的代码和说明如下:
 1//路径
 2var identifyFilePath = "";
 3var identifyImageType = "png";
 4
 5//Tool MapIdentify的ClientAction
 6function MapIdentify(divid) 
 7{
 8    //获取地图控件
 9    map = Maps[divid];
10    //esri的方法,把工具条状态切换到MapIdentify的状态
11    MapPoint(map.controlName, "MapIdentify"false);
12    
13    //设置在地图上按下鼠标后的事件为MapIdClick
14    map.divObject.onmousedown = MapIdClick;
15}

16
17//鼠标在地图上按下鼠标后触发的事件
18function MapIdClick(e) 
19{
20   //鼠标指针显示
21    map.cursor = map.divObject.style.cursor;
22    //map.divObject.style.cursor = "wait";
23    getXY(e);
24    //esri的方法,获取地图控件容器的坐标位置
25    var box = calcElementPosition(map.containerDivId);
26    //鼠标相对与地图控件的x坐标
27    zleft = mouseX - box.left;
28    //鼠标相对与地图控件的y坐标
29    ztop = mouseY - box.top;
30
31    map.xMin=zleft;
32    map.yMin=ztop;
33    //查找IdentifyLocation元素
34    var div = document.getElementById("IdentifyLocation");
35    if (div==null{
36        //调用在地图上添加小图标方法
37        addIdentifyLocation();
38    }

39    
40    //查找页面上的TaskResults1控件
41    var fpBody = document.getElementById('Results_TaskResults1');
42    var html = fpBody.innerHTML;
43    //进行载入时的信息提醒
44    fpBody.innerHTML = "<div><img src='images/callbackActivityIndicator.gif' align='middle'/> 正在获取信息. . .</div>" + html;
45    //显示放置TaskResults1的Results控件
46    showFloatingPanel('Results');
47    pBody=document.getElementById('Results_BodyRow');
48    //如果Results控件为关闭状态就切换到展可视状态
49    if (fpBody.style.display=="none")
50    {
51       toggleFloatingPanelState('Results','images/collapse.gif','images/expand.gif');
52    }

53    //传递给服务器端的参数
54    var message = "ControlID=Map1&ControlType=Map&EventArg=MapIdentify&Map1_mode=MapIdentify&minx=" + zleft + "&miny=" + ztop;
55    var context = map.controlName;
56    //用javascript的eval的方法执行identifyCallbackFunctionString字符串
57    eval(map.identifyCallbackFunctionString);
58    
59    //考虑小图标的高和宽,一遍小图标的下尖点刚刚在点击的位置上
60    var div = document.getElementById("IdentifyLocation");
61    var cWidth = Math.floor(div.clientWidth / 2);
62    var cHeight = div.clientHeight;
63    if (cWidth==0) cWidth = 12;
64    if (cHeight==0) cHeight = 29;
65    var idLeft = zleft - parseInt(map.divObject.style.left) - cWidth;
66    var idTop = ztop - parseInt(map.divObject.style.top) - cHeight + 2
67    
68    //移动IdentifyLocation的位置,并且显示IdentifyLocation
69    window.setTimeout('moveLayer("IdentifyLocation", ' + idLeft + '' + idTop + '); showLayer("IdentifyLocation");'0);
70    map.mode = map.tempMode;
71    map.actionType = map.tempAction;
72    map.cursor = map.tempCursor;
73    return false;
74        
75}

76
77//在地图上添加小图标
78function addIdentifyLocation() 
79{
80    var content = '<div id="IdentifyLocation" style="position: absolute; left: 0px; top: 0px; visibility: hidden;">';
81    //根据浏览器的不同进行相应的处理
82    if (isIE  && ieVersion < 7 && (identifyImageType.toLowerCase()=="png")) 
83    {
84        content += '<img src="' + identifyFilePath + 'images/blank.gif" alt="" border="0"  hspace="0" vspace="0" style="filter:  progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + identifyFilePath + 'images/identify-map-icon.png\');" />\n';
85    }  
86    else
87    {
88        content += '<img src="' + identifyFilePath + 'images/identify-map-icon.png" alt="" border="0"  hspace="0" vspace="0" />\n';
89    }

90        
91    content += '</div>';
92    //把包含小图标的div添加到地图之上
93    map.overlayObject.insertAdjacentHTML("BeforeEnd", content);
94}
6.到此为止完成了Identify功能的开发,调试运行查看效果。剩下的下一篇继续写。
posted @ 2008-08-13 21:13  水的右边  阅读(6044)  评论(70编辑  收藏  举报