1.距离测量功能。
准备:
1.(一、三)的工程,具体见前篇。
开始:
1.新建名为Measure.ascx的用户控件,并且实现ICallbackEventHandler接口,具体代码如下:
1namespace MappingApp
2{
3 public partial class Measure : System.Web.UI.UserControl, ICallbackEventHandler
4 {
5 protected void Page_Load(object sender, EventArgs e)
6 {
7
8 }
9
10 ICallbackEventHandler 成员
25 }
26}
2. 加入具体的线距离测量和面积测量功能代码,具体的代码和说明如下:2{
3 public partial class Measure : System.Web.UI.UserControl, ICallbackEventHandler
4 {
5 protected void Page_Load(object sender, EventArgs e)
6 {
7
8 }
9
10 ICallbackEventHandler 成员
25 }
26}
1namespace MappingApp
2{
3 //地图单位
4 public enum MapUnit
5 {
6 Resource_Default, Degrees, Feet, Meters //默认,度,码,米
7 }
8
9 //测量单位
10 public enum MeasureUnit
11 {
12 Feet, Kilometers, Meters, Miles //码,千米,米,英里
13 }
14
15 //区域单位
16 public enum AreaUnit
17 {
18 Acres, Sq_Feet, Sq_Kilometers, Sq_Meters, Sq_Miles //英亩,平方码,平方千米,平方米,平方英里
19 }
20
21 public partial class Measure : System.Web.UI.UserControl, ICallbackEventHandler
22 {
23 MapResourceManager m_resourceManger;
24 IMapFunctionality m_mapFunctionality;
25 //页面
26 private Page m_page;
27 //客户端代码段
28 public string m_callbackInvocation = "";
29 //地图控件ID
30 private string m_mapBuddyId = "Map1";
31 //用户控件id
32 public string m_id;
33 //地图控件
34 private Map m_map;
35 //默认地图单位
36 private MapUnit m_FallbackMapUnit = MapUnit.Degrees;
37 private MapUnit m_mapUnits;
38 //
39 private MapUnit m_startMapUnits = MapUnit.Degrees;
40 //默认测量单位
41 public MeasureUnit m_measureUnits = MeasureUnit.Miles;
42 //默认区域单位
43 public AreaUnit m_areaUnits = AreaUnit.Sq_Miles;
44 //数字精确到4位
45 private double m_numberDecimals = 4;
46
47 protected void Page_Load(object sender, EventArgs e)
48 {
49 //控件id
50 m_id = this.ClientID;
51 //页面
52 m_page = this.Page;
53 if (m_mapBuddyId == null || m_mapBuddyId.Length == 0)
54 {
55 m_mapBuddyId = "Map1";
56 }
57 //获取map控件
58 m_map = m_page.FindControl(m_mapBuddyId) as Map;
59 //获取MapResourceManager控件
60 m_resourceManger = m_page.FindControl(m_map.MapResourceManager) as MapResourceManager;
61 //通过GetCallbackEventReference生成客户端调用的javascript方法段
62 m_callbackInvocation = m_page.ClientScript.GetCallbackEventReference(this, "argument", "processCallbackResult", "context", true);
63 }
64
65 //
66 protected void Page_PreRender(object sender, EventArgs e)
67 {
68 GetMeasureResource();
69 }
70
71 private void GetMeasureResource()
72 {
73 string primeResource = m_map.PrimaryMapResource;
74 IEnumerable mapResources = m_resourceManger.GetResources();
75 IEnumerator resEnum = mapResources.GetEnumerator();
76
77 resEnum.MoveNext();
78
79 IGISResource resource;
80 if (primeResource != null && primeResource.Length > 0)
81 {
82 resource = m_resourceManger.GetResource(primeResource);
83 }
84 else
85 {
86 resource = resEnum.Current as IGISResource;
87 }
88
89 if (resource != null)
90 {
91 m_mapFunctionality = (IMapFunctionality)resource.CreateFunctionality(typeof(IMapFunctionality), "mapFunctionality");
92 }
93 }
94
95 ICallbackEventHandler 成员
163
164 //根据请求字符串进行不同的测量
165 public string ProcessMeasureRequest(NameValueCollection queryString)
166 {
167 if (m_mapFunctionality == null)
168 {
169 GetMeasureResource();
170 }
171 object o = Session["MeasureMapUnits"];
172 if (o != null)
173 {
174 m_mapUnits = (MapUnit)Enum.Parse(typeof(MapUnit), o.ToString());
175 }
176 else if (m_startMapUnits == MapUnit.Resource_Default)
177 {
178 //获取默认地图单位
179 m_mapUnits = GetResourceDefaultMapUnit();
180 }
181 else
182 {
183 m_mapUnits = m_startMapUnits;
184 }
185
186 //请求参数
187 string eventArg = queryString["EventArg"].ToLower();
188 string vectorAction = queryString["VectorAction"].ToLower();
189 string[] coordPairs, xys;
190 //坐标字符串
191 string coordString = queryString["coords"];
192 if (coordString == null && coordString.Length == 0)
193 {
194 coordString = "";
195 }
196 //坐标字符串分割
197 coordPairs = coordString.Split(char.Parse("|"));
198 //地图单位
199 string mapUnitString = queryString["MapUnits"];
200 if (mapUnitString != null && mapUnitString.Length > 0)
201 {
202 m_mapUnits = (MapUnit)Enum.Parse(typeof(MapUnit), mapUnitString);
203 }
204 Session["MeasureMapUnits"] = m_mapUnits;
205 //测量单位
206 string measureUnitString = queryString["MeasureUnits"];
207 if (measureUnitString != null && measureUnitString.Length > 0)
208 {
209 m_measureUnits = (MeasureUnit)Enum.Parse(typeof(MeasureUnit), measureUnitString);
210 }
211 //区域单位
212 string areaUnitstring = queryString["AreaUnits"];
213 if (areaUnitstring != null && areaUnitstring.Length > 0)
214 {
215 m_areaUnits = (AreaUnit)Enum.Parse(typeof(AreaUnit), areaUnitstring);
216 }
217
218 //输出内容字符串
219 string response = "";
220 PointCollection points = new PointCollection();
221 PointCollection dPoints = new PointCollection();
222 ArrayList distances = new ArrayList();
223 double totalDistance = 0;
224 double segmentDistance = 0;
225 double area = 0;
226 double perimeter = 0;
227 double roundFactor = Math.Pow(10, m_numberDecimals);
228 double xD, yD, tempDist, tempDist2, tempArea, x1, x2, y1, y2;
229
230 //动作为添加点
231 if (vectorAction == "addpoint")
232 {
233 //坐标点大于1个时,就是保证是一条线
234 if (coordPairs != null && coordPairs.Length > 1)
235 {
236 for (int i = 0; i < coordPairs.Length; i++)
237 {
238 xys = coordPairs[i].Split(char.Parse(":"));
239 //像素坐标转换成地理坐标
240 points.Add(Point.ToMapPoint(Convert.ToInt32(xys[0]), Convert.ToInt32(xys[1]), m_map.GetTransformationParams(ESRI.ArcGIS.ADF.Web.Geometry.TransformationDirection.ToMap)));
241
242 if (i > 0)//第二个坐标点的时候
243 {
244 if (m_mapUnits == MapUnit.Degrees)//地图单位为度的时候
245 {
246 //计算与前一个点的距离,分段距离
247 tempDist = DegreeToFeetDistance(points[i - 1].X, points[i - 1].Y, points[i].X, points[i].Y);
248 //度转成码
249 y1 = DegreeToFeetDistance(points[i].X, points[i].Y, points[i].X, 0);
250 //度转成码
251 x1 = DegreeToFeetDistance(points[i].X, points[i].Y, 0, points[i].Y);
252 dPoints.Add(new Point(x1, y1));
253 //单位换算
254 segmentDistance = ConvertUnits(tempDist, MapUnit.Feet, m_measureUnits);
255 }
256 else//地图单位为米的时候
257 {
258 xD = Math.Abs(points[i].X - points[i - 1].X);
259 yD = Math.Abs(points[i].Y - points[i - 1].Y);
260 //计算2个坐标之间的距离
261 tempDist = Math.Sqrt(Math.Pow(xD, 2) + Math.Pow(yD, 2));
262 //单位换算
263 segmentDistance = ConvertUnits(tempDist, m_mapUnits, m_measureUnits);
264
265 }
266
267 //把分段距离添加到distances
268 distances.Add(segmentDistance);
269 //计算总距离
270 totalDistance += segmentDistance;
271 //只显示4位小数
272 segmentDistance = Math.Round(segmentDistance * roundFactor) / roundFactor;
273 totalDistance = Math.Round(totalDistance * roundFactor) / roundFactor;
274 }
275 else//第一个坐标点的时候
276 {
277 if (m_mapUnits == MapUnit.Degrees)
278 {
279 //度转成码
280 y1 = DegreeToFeetDistance(points[i].X, points[i].Y, points[i].X, 0);
281 x1 = DegreeToFeetDistance(points[i].X, points[i].Y, 0, points[i].Y);
282 dPoints.Add(new Point(x1, y1));
283 }
284 }
285 }
286 }
287
288 //为多边形时
289 if (eventArg == "polygon")
290 {
291 if (points.Count > 2)
292 {
293 if (m_mapUnits == MapUnit.Degrees)
294 {
295 //最后一段的距离计算
296 tempDist = DegreeToFeetDistance(points[points.Count - 1].X, points[points.Count - 1].Y, points[0].X, points[0].Y);
297 tempDist2 = ConvertUnits(tempDist, MapUnit.Feet, m_measureUnits);
298 distances.Add(tempDist2);
299 //加入第一点作为多边形的结束节点
300 dPoints.Add(dPoints[0]);
301 }
302 else
303 {
304 //最后一段的距离计算
305 xD = Math.Abs(points[points.Count - 1].X - points[0].X);
306 yD = Math.Abs(points[points.Count - 1].Y - points[0].Y);
307 tempDist = Math.Sqrt(Math.Pow(xD, 2) + Math.Pow(yD, 2));
308 tempDist2 = ConvertUnits(tempDist, m_mapUnits, m_measureUnits);
309 distances.Add(tempDist2);
310 }
311 //加入第一点作为多边形的结束节点
312 points.Add(points[0]);
313 //总长度+最后一段长度
314 perimeter = totalDistance + tempDist2;
315 //多边形面积计算
316 tempArea = 0;
317 MapUnit mUnits = m_mapUnits;
318 for (int j = 0; j < points.Count - 1; j++)
319 {
320 if (m_mapUnits == MapUnit.Degrees)
321 {
322 x1 = Convert.ToDouble(dPoints[j].X);
323 x2 = Convert.ToDouble(dPoints[j + 1].X);
324 y1 = Convert.ToDouble(dPoints[j].Y);
325 y2 = Convert.ToDouble(dPoints[j + 1].Y);
326 mUnits = MapUnit.Feet;
327 }
328 else
329 {
330 x1 = Convert.ToDouble(points[j].X);
331 x2 = Convert.ToDouble(points[j + 1].X);
332 y1 = Convert.ToDouble(points[j].Y);
333 y2 = Convert.ToDouble(points[j + 1].Y);
334 }
335 //tempArea += tempArea + (x1 + x2) * (y1 - y2);
336 double xDiff = x2 - x1;
337 double yDiff = y2 - y1;
338 tempArea += x1 * yDiff - y1 * xDiff;
339 }
340 tempArea = Math.Abs(tempArea) / 2;
341 //单位换算
342 area = ConvertAreaUnits(tempArea, mUnits, m_areaUnits);
343 //保留4位小数
344 perimeter = Math.Round(perimeter * roundFactor) / roundFactor;
345 area = Math.Round(area * roundFactor) / roundFactor;
346
347 //输出显示内容html
348 response = String.Format("<table cellspacing='0' ><tr><td>Perimeter: </td><td align='right'>{0}</td><td>{1}</td></tr><tr><td>Area:</td><td align='right'>{2}</td><td>{3}</td></tr></table>", perimeter, WriteMeasureUnitDropdown(), area, WriteAreaUnitDropdown());
349 }
350 else
351 {
352 //输出显示内容html,小于3个点时候
353 response = String.Format("<table cellspacing='0' ><tr><td>Perimeter: </td><td align='right'> 0</td><td>{0}</td></tr><tr><td>Area:</td><td align='right'>0 </td><td>{1}</td></tr></table>", WriteMeasureUnitDropdown(), WriteAreaUnitDropdown());
354 }
355 }
356 else
357 {
358 //输出显示内容html,为线的时候
359 response = String.Format("<table cellspacing='0' ><tr><td>Segment: </td><td align='right'>{0} </td><td>{1}</td></tr><tr><td>Total Length:</td><td align='right'>{2} </td><td>{3}</td></tr></table>", segmentDistance, m_measureUnits.ToString(), totalDistance, WriteMeasureUnitDropdown());
360 }
361
362 }
363 //动作为获取坐标
364 else if (vectorAction == "coordinates")
365 {
366 xys = coordPairs[0].Split(char.Parse(":"));
367 Point coordPoint = Point.ToMapPoint(Convert.ToInt32(xys[0]), Convert.ToInt32(xys[1]), m_map.GetTransformationParams(ESRI.ArcGIS.ADF.Web.Geometry.TransformationDirection.ToMap));
368
369 //输出坐标的html显示内容
370 response = String.Format("<table cellspacing='0' ><tr><td>X Coordinate:</td><td align='right'>{0}</td></tr><tr><td>Y Coordinate:</td><td align='right'>{1}</td></tr></table>", (Math.Round(coordPoint.X * roundFactor) / roundFactor).ToString(), (Math.Round(coordPoint.Y * roundFactor) / roundFactor).ToString());
371 }
372 //动作为结束画线
373 else if (vectorAction == "finish")
374 {
375 response = "Shape complete";
376 }
377
378 //把结果内容返回给客户端
379 return String.Format("measure:::{0}:::{1}:::{2}", m_id, vectorAction, response);
380 }
381
382 //输出测量单位选择下拉框
383 public string WriteMeasureUnitDropdown()
384 {
385 System.Text.StringBuilder sb = new System.Text.StringBuilder();
386 sb.Append("<select id=\"MeasureUnits2\" onchange=\"changeMeasureUnits()\" style=\"font: normal 7pt Verdana; 100px;\">");
387 Array mArray = Enum.GetValues(typeof(MeasureUnit));
388 foreach (MeasureUnit mu in mArray)
389 {
390 sb.AppendFormat("<option value=\"{0}\" {1}>{0}</option>", mu.ToString(), CheckFormMeasureUnits(mu.ToString()));
391
392 }
393 sb.Append("</select>");
394
395 return sb.ToString();
396 }
397
398 //检查默认选中项
399 public string CheckFormMeasureUnits(string unit)
400 {
401 string response = "";
402 if (unit == m_measureUnits.ToString())
403 response = "selected=\"selected\"";
404 return response;
405 }
406
407 //输出测量单位选择下拉框
408 public string WriteAreaUnitDropdown()
409 {
410 System.Text.StringBuilder sb = new System.Text.StringBuilder();
411 sb.Append("<select id=\"AreaUnits2\" onchange=\"changeAreaUnits()\" style=\"font: normal 7pt Verdana; 100px;\">");
412 Array aArray = Enum.GetValues(typeof(AreaUnit));
413 foreach (AreaUnit au in aArray)
414 {
415 sb.AppendFormat("<option value=\"{0}\" {1}>{0}</option>", au.ToString(), CheckFormAreaUnits(au.ToString()));
416
417 }
418 sb.Append("</select>");
419
420 return sb.ToString();
421 }
422
423 //检查默认选中项
424 public string CheckFormAreaUnits(string unit)
425 {
426 string response = "";
427 if (unit == m_areaUnits.ToString())
428 response = "selected=\"selected\"";
429 return response;
430 }
431
432 //面积单位换算
433 private double ConvertAreaUnits(double area, MapUnit baseUnits, AreaUnit toUnits)
434 {
435 double mArea = area;
436 if (baseUnits == MapUnit.Feet)
437 {
438 if (toUnits == AreaUnit.Acres)
439 mArea = area * 0.000022956;
440 else if (toUnits == AreaUnit.Sq_Meters)
441 mArea = area * 0.09290304;
442 else if (toUnits == AreaUnit.Sq_Miles)
443 mArea = area * 0.00000003587;
444 else if (toUnits == AreaUnit.Sq_Kilometers)
445 mArea = area * 0.09290304 / 1000000;
446 }
447 else if (baseUnits == MapUnit.Meters)
448 {
449 if (toUnits == AreaUnit.Acres)
450 mArea = area * 0.0002471054;
451 else if (toUnits == AreaUnit.Sq_Miles)
452 mArea = area * 0.0000003861003;
453 else if (toUnits == AreaUnit.Sq_Kilometers)
454 mArea = area * 1.0e-6;
455 else if (toUnits == AreaUnit.Sq_Feet)
456 mArea = area * 10.76391042;
457 }
458
459 return mArea;
460 }
461
462 //单位换算
463 public double ConvertUnits(double distance, MapUnit fromUnits, MeasureUnit toUnits)
464 {
465 double mDistance = distance;
466 if (fromUnits == MapUnit.Feet)
467 {
468 if (toUnits == MeasureUnit.Miles)
469 {
470 mDistance = distance / 5280;
471 }
472 else if (toUnits == MeasureUnit.Meters)
473 {
474 mDistance = distance * 0.304800609601;
475 }
476 else if (toUnits == MeasureUnit.Kilometers)
477 {
478 mDistance = distance * 0.0003048;
479 }
480 }
481 else
482 {
483 if (toUnits == MeasureUnit.Miles)
484 {
485 mDistance = distance * 0.0006213700922;
486 }
487 else if (toUnits == MeasureUnit.Feet)
488 {
489 mDistance = distance * 3.280839895;
490 }
491 else if (toUnits == MeasureUnit.Kilometers)
492 {
493 mDistance = distance / 1000;
494 }
495 }
496 return mDistance;
497 }
498
499 //度转成码距离
500 private double DegreeToFeetDistance(double x1, double y1, double x2, double y2)
501 {
502 double Lat1 = DegToRad(y1);
503 double Lat2 = DegToRad(y2);
504 double Lon1 = DegToRad(x1);
505 double Lon2 = DegToRad(x2);
506 double LonDist = Lon1 - Lon2;
507 double LatDist = Lat1 - Lat2;
508 double x = Math.Pow(Math.Sin(LatDist / 2), 2) + Math.Cos(Lat1) * Math.Cos(Lat2) * Math.Pow(Math.Sin(LonDist / 2), 2);
509 x = 2 * Math.Asin(Math.Min(1, Math.Sqrt(x)));
510 x = (3963 - 13 * Math.Sin((Lat1 + Lat2) / 2)) * x;
511 // in miles convert to feet and use that as base
512 return (x * 5280);
513 }
514
515 //度转成弧度
516 private double DegToRad(double degrees)
517 {
518 return Convert.ToDouble(degrees * Math.PI / 180);
519 }
520
521 private MapUnit GetResourceDefaultMapUnit()
522 {
523 MapUnit mUnit = MapUnit.Degrees;
524 try
525 {
526 //获取地图资源单位
527 Units mu = m_mapFunctionality.Units;
528 if (mu == Units.DecimalDegrees)
529 {
530 mUnit = MapUnit.Degrees;
531 }
532 else if (mu == Units.Feet)
533 {
534 mUnit = MapUnit.Feet;
535 }
536 else if (mu == Units.Meters)
537 {
538 mUnit = MapUnit.Meters;
539 }
540
541 }
542 catch
543 {
544 //不能获取地图资源单位时用m_FallbackMapUnit定义的单位
545 mUnit = m_FallbackMapUnit;
546 }
547 return mUnit;
548
549 }
550
551 public string Id
552 {
553 get { return m_id; }
554 set { m_id = value; }
555 }
556
557 private string ClientCallbackInvocation
558 {
559 get { return m_callbackInvocation; }
560 set { m_callbackInvocation = value; }
561 }
562
563 private MapResourceManager MapResourceManager
564 {
565 get { return m_resourceManger; }
566 set { m_resourceManger = value; }
567 }
568
569 /// <summary>
570 /// Id of Buddy MapControl
571 /// </summary>
572 public string MapBuddyId
573 {
574 get { return m_mapBuddyId; }
575 set { m_mapBuddyId = value; }
576 }
577
578
579 /// <summary>
580 /// Unit used resource. Resource_Default will return value from resource, if available. Other values will force calculations to use that unit.
581 /// </summary>
582 public MapUnit MapUnits
583 {
584 get { return m_startMapUnits; }
585 set { m_startMapUnits = value; }
586 }
587
588 /// <summary>
589 /// Unit used in display of linear measurements.
590 /// </summary>
591 public MeasureUnit MeasureUnits
592 {
593 get { return m_measureUnits; }
594 set { m_measureUnits = value; }
595 }
596
597 /// <summary>
598 /// Area Units - Unit used in display of area measurements.
599 /// </summary>
600 public AreaUnit AreaUnits
601 {
602 get { return m_areaUnits; }
603 set { m_areaUnits = value; }
604 }
605
606 // Number of Decimals - Number of decimal digits displayed in measurements.
607 public double NumberDecimals
608 {
609 get { return m_numberDecimals; }
610 set { m_numberDecimals = value; }
611 }
612
613
614 public override bool Visible
615 {
616 get { return base.Visible; }
617 }
618
619 public override bool EnableTheming
620 {
621 get
622 {
623 return base.EnableTheming;
624 }
625 }
626
627 public override bool EnableViewState
628 {
629 get
630 {
631 return base.EnableViewState;
632 }
633 }
634
635 }
636}
2{
3 //地图单位
4 public enum MapUnit
5 {
6 Resource_Default, Degrees, Feet, Meters //默认,度,码,米
7 }
8
9 //测量单位
10 public enum MeasureUnit
11 {
12 Feet, Kilometers, Meters, Miles //码,千米,米,英里
13 }
14
15 //区域单位
16 public enum AreaUnit
17 {
18 Acres, Sq_Feet, Sq_Kilometers, Sq_Meters, Sq_Miles //英亩,平方码,平方千米,平方米,平方英里
19 }
20
21 public partial class Measure : System.Web.UI.UserControl, ICallbackEventHandler
22 {
23 MapResourceManager m_resourceManger;
24 IMapFunctionality m_mapFunctionality;
25 //页面
26 private Page m_page;
27 //客户端代码段
28 public string m_callbackInvocation = "";
29 //地图控件ID
30 private string m_mapBuddyId = "Map1";
31 //用户控件id
32 public string m_id;
33 //地图控件
34 private Map m_map;
35 //默认地图单位
36 private MapUnit m_FallbackMapUnit = MapUnit.Degrees;
37 private MapUnit m_mapUnits;
38 //
39 private MapUnit m_startMapUnits = MapUnit.Degrees;
40 //默认测量单位
41 public MeasureUnit m_measureUnits = MeasureUnit.Miles;
42 //默认区域单位
43 public AreaUnit m_areaUnits = AreaUnit.Sq_Miles;
44 //数字精确到4位
45 private double m_numberDecimals = 4;
46
47 protected void Page_Load(object sender, EventArgs e)
48 {
49 //控件id
50 m_id = this.ClientID;
51 //页面
52 m_page = this.Page;
53 if (m_mapBuddyId == null || m_mapBuddyId.Length == 0)
54 {
55 m_mapBuddyId = "Map1";
56 }
57 //获取map控件
58 m_map = m_page.FindControl(m_mapBuddyId) as Map;
59 //获取MapResourceManager控件
60 m_resourceManger = m_page.FindControl(m_map.MapResourceManager) as MapResourceManager;
61 //通过GetCallbackEventReference生成客户端调用的javascript方法段
62 m_callbackInvocation = m_page.ClientScript.GetCallbackEventReference(this, "argument", "processCallbackResult", "context", true);
63 }
64
65 //
66 protected void Page_PreRender(object sender, EventArgs e)
67 {
68 GetMeasureResource();
69 }
70
71 private void GetMeasureResource()
72 {
73 string primeResource = m_map.PrimaryMapResource;
74 IEnumerable mapResources = m_resourceManger.GetResources();
75 IEnumerator resEnum = mapResources.GetEnumerator();
76
77 resEnum.MoveNext();
78
79 IGISResource resource;
80 if (primeResource != null && primeResource.Length > 0)
81 {
82 resource = m_resourceManger.GetResource(primeResource);
83 }
84 else
85 {
86 resource = resEnum.Current as IGISResource;
87 }
88
89 if (resource != null)
90 {
91 m_mapFunctionality = (IMapFunctionality)resource.CreateFunctionality(typeof(IMapFunctionality), "mapFunctionality");
92 }
93 }
94
95 ICallbackEventHandler 成员
163
164 //根据请求字符串进行不同的测量
165 public string ProcessMeasureRequest(NameValueCollection queryString)
166 {
167 if (m_mapFunctionality == null)
168 {
169 GetMeasureResource();
170 }
171 object o = Session["MeasureMapUnits"];
172 if (o != null)
173 {
174 m_mapUnits = (MapUnit)Enum.Parse(typeof(MapUnit), o.ToString());
175 }
176 else if (m_startMapUnits == MapUnit.Resource_Default)
177 {
178 //获取默认地图单位
179 m_mapUnits = GetResourceDefaultMapUnit();
180 }
181 else
182 {
183 m_mapUnits = m_startMapUnits;
184 }
185
186 //请求参数
187 string eventArg = queryString["EventArg"].ToLower();
188 string vectorAction = queryString["VectorAction"].ToLower();
189 string[] coordPairs, xys;
190 //坐标字符串
191 string coordString = queryString["coords"];
192 if (coordString == null && coordString.Length == 0)
193 {
194 coordString = "";
195 }
196 //坐标字符串分割
197 coordPairs = coordString.Split(char.Parse("|"));
198 //地图单位
199 string mapUnitString = queryString["MapUnits"];
200 if (mapUnitString != null && mapUnitString.Length > 0)
201 {
202 m_mapUnits = (MapUnit)Enum.Parse(typeof(MapUnit), mapUnitString);
203 }
204 Session["MeasureMapUnits"] = m_mapUnits;
205 //测量单位
206 string measureUnitString = queryString["MeasureUnits"];
207 if (measureUnitString != null && measureUnitString.Length > 0)
208 {
209 m_measureUnits = (MeasureUnit)Enum.Parse(typeof(MeasureUnit), measureUnitString);
210 }
211 //区域单位
212 string areaUnitstring = queryString["AreaUnits"];
213 if (areaUnitstring != null && areaUnitstring.Length > 0)
214 {
215 m_areaUnits = (AreaUnit)Enum.Parse(typeof(AreaUnit), areaUnitstring);
216 }
217
218 //输出内容字符串
219 string response = "";
220 PointCollection points = new PointCollection();
221 PointCollection dPoints = new PointCollection();
222 ArrayList distances = new ArrayList();
223 double totalDistance = 0;
224 double segmentDistance = 0;
225 double area = 0;
226 double perimeter = 0;
227 double roundFactor = Math.Pow(10, m_numberDecimals);
228 double xD, yD, tempDist, tempDist2, tempArea, x1, x2, y1, y2;
229
230 //动作为添加点
231 if (vectorAction == "addpoint")
232 {
233 //坐标点大于1个时,就是保证是一条线
234 if (coordPairs != null && coordPairs.Length > 1)
235 {
236 for (int i = 0; i < coordPairs.Length; i++)
237 {
238 xys = coordPairs[i].Split(char.Parse(":"));
239 //像素坐标转换成地理坐标
240 points.Add(Point.ToMapPoint(Convert.ToInt32(xys[0]), Convert.ToInt32(xys[1]), m_map.GetTransformationParams(ESRI.ArcGIS.ADF.Web.Geometry.TransformationDirection.ToMap)));
241
242 if (i > 0)//第二个坐标点的时候
243 {
244 if (m_mapUnits == MapUnit.Degrees)//地图单位为度的时候
245 {
246 //计算与前一个点的距离,分段距离
247 tempDist = DegreeToFeetDistance(points[i - 1].X, points[i - 1].Y, points[i].X, points[i].Y);
248 //度转成码
249 y1 = DegreeToFeetDistance(points[i].X, points[i].Y, points[i].X, 0);
250 //度转成码
251 x1 = DegreeToFeetDistance(points[i].X, points[i].Y, 0, points[i].Y);
252 dPoints.Add(new Point(x1, y1));
253 //单位换算
254 segmentDistance = ConvertUnits(tempDist, MapUnit.Feet, m_measureUnits);
255 }
256 else//地图单位为米的时候
257 {
258 xD = Math.Abs(points[i].X - points[i - 1].X);
259 yD = Math.Abs(points[i].Y - points[i - 1].Y);
260 //计算2个坐标之间的距离
261 tempDist = Math.Sqrt(Math.Pow(xD, 2) + Math.Pow(yD, 2));
262 //单位换算
263 segmentDistance = ConvertUnits(tempDist, m_mapUnits, m_measureUnits);
264
265 }
266
267 //把分段距离添加到distances
268 distances.Add(segmentDistance);
269 //计算总距离
270 totalDistance += segmentDistance;
271 //只显示4位小数
272 segmentDistance = Math.Round(segmentDistance * roundFactor) / roundFactor;
273 totalDistance = Math.Round(totalDistance * roundFactor) / roundFactor;
274 }
275 else//第一个坐标点的时候
276 {
277 if (m_mapUnits == MapUnit.Degrees)
278 {
279 //度转成码
280 y1 = DegreeToFeetDistance(points[i].X, points[i].Y, points[i].X, 0);
281 x1 = DegreeToFeetDistance(points[i].X, points[i].Y, 0, points[i].Y);
282 dPoints.Add(new Point(x1, y1));
283 }
284 }
285 }
286 }
287
288 //为多边形时
289 if (eventArg == "polygon")
290 {
291 if (points.Count > 2)
292 {
293 if (m_mapUnits == MapUnit.Degrees)
294 {
295 //最后一段的距离计算
296 tempDist = DegreeToFeetDistance(points[points.Count - 1].X, points[points.Count - 1].Y, points[0].X, points[0].Y);
297 tempDist2 = ConvertUnits(tempDist, MapUnit.Feet, m_measureUnits);
298 distances.Add(tempDist2);
299 //加入第一点作为多边形的结束节点
300 dPoints.Add(dPoints[0]);
301 }
302 else
303 {
304 //最后一段的距离计算
305 xD = Math.Abs(points[points.Count - 1].X - points[0].X);
306 yD = Math.Abs(points[points.Count - 1].Y - points[0].Y);
307 tempDist = Math.Sqrt(Math.Pow(xD, 2) + Math.Pow(yD, 2));
308 tempDist2 = ConvertUnits(tempDist, m_mapUnits, m_measureUnits);
309 distances.Add(tempDist2);
310 }
311 //加入第一点作为多边形的结束节点
312 points.Add(points[0]);
313 //总长度+最后一段长度
314 perimeter = totalDistance + tempDist2;
315 //多边形面积计算
316 tempArea = 0;
317 MapUnit mUnits = m_mapUnits;
318 for (int j = 0; j < points.Count - 1; j++)
319 {
320 if (m_mapUnits == MapUnit.Degrees)
321 {
322 x1 = Convert.ToDouble(dPoints[j].X);
323 x2 = Convert.ToDouble(dPoints[j + 1].X);
324 y1 = Convert.ToDouble(dPoints[j].Y);
325 y2 = Convert.ToDouble(dPoints[j + 1].Y);
326 mUnits = MapUnit.Feet;
327 }
328 else
329 {
330 x1 = Convert.ToDouble(points[j].X);
331 x2 = Convert.ToDouble(points[j + 1].X);
332 y1 = Convert.ToDouble(points[j].Y);
333 y2 = Convert.ToDouble(points[j + 1].Y);
334 }
335 //tempArea += tempArea + (x1 + x2) * (y1 - y2);
336 double xDiff = x2 - x1;
337 double yDiff = y2 - y1;
338 tempArea += x1 * yDiff - y1 * xDiff;
339 }
340 tempArea = Math.Abs(tempArea) / 2;
341 //单位换算
342 area = ConvertAreaUnits(tempArea, mUnits, m_areaUnits);
343 //保留4位小数
344 perimeter = Math.Round(perimeter * roundFactor) / roundFactor;
345 area = Math.Round(area * roundFactor) / roundFactor;
346
347 //输出显示内容html
348 response = String.Format("<table cellspacing='0' ><tr><td>Perimeter: </td><td align='right'>{0}</td><td>{1}</td></tr><tr><td>Area:</td><td align='right'>{2}</td><td>{3}</td></tr></table>", perimeter, WriteMeasureUnitDropdown(), area, WriteAreaUnitDropdown());
349 }
350 else
351 {
352 //输出显示内容html,小于3个点时候
353 response = String.Format("<table cellspacing='0' ><tr><td>Perimeter: </td><td align='right'> 0</td><td>{0}</td></tr><tr><td>Area:</td><td align='right'>0 </td><td>{1}</td></tr></table>", WriteMeasureUnitDropdown(), WriteAreaUnitDropdown());
354 }
355 }
356 else
357 {
358 //输出显示内容html,为线的时候
359 response = String.Format("<table cellspacing='0' ><tr><td>Segment: </td><td align='right'>{0} </td><td>{1}</td></tr><tr><td>Total Length:</td><td align='right'>{2} </td><td>{3}</td></tr></table>", segmentDistance, m_measureUnits.ToString(), totalDistance, WriteMeasureUnitDropdown());
360 }
361
362 }
363 //动作为获取坐标
364 else if (vectorAction == "coordinates")
365 {
366 xys = coordPairs[0].Split(char.Parse(":"));
367 Point coordPoint = Point.ToMapPoint(Convert.ToInt32(xys[0]), Convert.ToInt32(xys[1]), m_map.GetTransformationParams(ESRI.ArcGIS.ADF.Web.Geometry.TransformationDirection.ToMap));
368
369 //输出坐标的html显示内容
370 response = String.Format("<table cellspacing='0' ><tr><td>X Coordinate:</td><td align='right'>{0}</td></tr><tr><td>Y Coordinate:</td><td align='right'>{1}</td></tr></table>", (Math.Round(coordPoint.X * roundFactor) / roundFactor).ToString(), (Math.Round(coordPoint.Y * roundFactor) / roundFactor).ToString());
371 }
372 //动作为结束画线
373 else if (vectorAction == "finish")
374 {
375 response = "Shape complete";
376 }
377
378 //把结果内容返回给客户端
379 return String.Format("measure:::{0}:::{1}:::{2}", m_id, vectorAction, response);
380 }
381
382 //输出测量单位选择下拉框
383 public string WriteMeasureUnitDropdown()
384 {
385 System.Text.StringBuilder sb = new System.Text.StringBuilder();
386 sb.Append("<select id=\"MeasureUnits2\" onchange=\"changeMeasureUnits()\" style=\"font: normal 7pt Verdana; 100px;\">");
387 Array mArray = Enum.GetValues(typeof(MeasureUnit));
388 foreach (MeasureUnit mu in mArray)
389 {
390 sb.AppendFormat("<option value=\"{0}\" {1}>{0}</option>", mu.ToString(), CheckFormMeasureUnits(mu.ToString()));
391
392 }
393 sb.Append("</select>");
394
395 return sb.ToString();
396 }
397
398 //检查默认选中项
399 public string CheckFormMeasureUnits(string unit)
400 {
401 string response = "";
402 if (unit == m_measureUnits.ToString())
403 response = "selected=\"selected\"";
404 return response;
405 }
406
407 //输出测量单位选择下拉框
408 public string WriteAreaUnitDropdown()
409 {
410 System.Text.StringBuilder sb = new System.Text.StringBuilder();
411 sb.Append("<select id=\"AreaUnits2\" onchange=\"changeAreaUnits()\" style=\"font: normal 7pt Verdana; 100px;\">");
412 Array aArray = Enum.GetValues(typeof(AreaUnit));
413 foreach (AreaUnit au in aArray)
414 {
415 sb.AppendFormat("<option value=\"{0}\" {1}>{0}</option>", au.ToString(), CheckFormAreaUnits(au.ToString()));
416
417 }
418 sb.Append("</select>");
419
420 return sb.ToString();
421 }
422
423 //检查默认选中项
424 public string CheckFormAreaUnits(string unit)
425 {
426 string response = "";
427 if (unit == m_areaUnits.ToString())
428 response = "selected=\"selected\"";
429 return response;
430 }
431
432 //面积单位换算
433 private double ConvertAreaUnits(double area, MapUnit baseUnits, AreaUnit toUnits)
434 {
435 double mArea = area;
436 if (baseUnits == MapUnit.Feet)
437 {
438 if (toUnits == AreaUnit.Acres)
439 mArea = area * 0.000022956;
440 else if (toUnits == AreaUnit.Sq_Meters)
441 mArea = area * 0.09290304;
442 else if (toUnits == AreaUnit.Sq_Miles)
443 mArea = area * 0.00000003587;
444 else if (toUnits == AreaUnit.Sq_Kilometers)
445 mArea = area * 0.09290304 / 1000000;
446 }
447 else if (baseUnits == MapUnit.Meters)
448 {
449 if (toUnits == AreaUnit.Acres)
450 mArea = area * 0.0002471054;
451 else if (toUnits == AreaUnit.Sq_Miles)
452 mArea = area * 0.0000003861003;
453 else if (toUnits == AreaUnit.Sq_Kilometers)
454 mArea = area * 1.0e-6;
455 else if (toUnits == AreaUnit.Sq_Feet)
456 mArea = area * 10.76391042;
457 }
458
459 return mArea;
460 }
461
462 //单位换算
463 public double ConvertUnits(double distance, MapUnit fromUnits, MeasureUnit toUnits)
464 {
465 double mDistance = distance;
466 if (fromUnits == MapUnit.Feet)
467 {
468 if (toUnits == MeasureUnit.Miles)
469 {
470 mDistance = distance / 5280;
471 }
472 else if (toUnits == MeasureUnit.Meters)
473 {
474 mDistance = distance * 0.304800609601;
475 }
476 else if (toUnits == MeasureUnit.Kilometers)
477 {
478 mDistance = distance * 0.0003048;
479 }
480 }
481 else
482 {
483 if (toUnits == MeasureUnit.Miles)
484 {
485 mDistance = distance * 0.0006213700922;
486 }
487 else if (toUnits == MeasureUnit.Feet)
488 {
489 mDistance = distance * 3.280839895;
490 }
491 else if (toUnits == MeasureUnit.Kilometers)
492 {
493 mDistance = distance / 1000;
494 }
495 }
496 return mDistance;
497 }
498
499 //度转成码距离
500 private double DegreeToFeetDistance(double x1, double y1, double x2, double y2)
501 {
502 double Lat1 = DegToRad(y1);
503 double Lat2 = DegToRad(y2);
504 double Lon1 = DegToRad(x1);
505 double Lon2 = DegToRad(x2);
506 double LonDist = Lon1 - Lon2;
507 double LatDist = Lat1 - Lat2;
508 double x = Math.Pow(Math.Sin(LatDist / 2), 2) + Math.Cos(Lat1) * Math.Cos(Lat2) * Math.Pow(Math.Sin(LonDist / 2), 2);
509 x = 2 * Math.Asin(Math.Min(1, Math.Sqrt(x)));
510 x = (3963 - 13 * Math.Sin((Lat1 + Lat2) / 2)) * x;
511 // in miles convert to feet and use that as base
512 return (x * 5280);
513 }
514
515 //度转成弧度
516 private double DegToRad(double degrees)
517 {
518 return Convert.ToDouble(degrees * Math.PI / 180);
519 }
520
521 private MapUnit GetResourceDefaultMapUnit()
522 {
523 MapUnit mUnit = MapUnit.Degrees;
524 try
525 {
526 //获取地图资源单位
527 Units mu = m_mapFunctionality.Units;
528 if (mu == Units.DecimalDegrees)
529 {
530 mUnit = MapUnit.Degrees;
531 }
532 else if (mu == Units.Feet)
533 {
534 mUnit = MapUnit.Feet;
535 }
536 else if (mu == Units.Meters)
537 {
538 mUnit = MapUnit.Meters;
539 }
540
541 }
542 catch
543 {
544 //不能获取地图资源单位时用m_FallbackMapUnit定义的单位
545 mUnit = m_FallbackMapUnit;
546 }
547 return mUnit;
548
549 }
550
551 public string Id
552 {
553 get { return m_id; }
554 set { m_id = value; }
555 }
556
557 private string ClientCallbackInvocation
558 {
559 get { return m_callbackInvocation; }
560 set { m_callbackInvocation = value; }
561 }
562
563 private MapResourceManager MapResourceManager
564 {
565 get { return m_resourceManger; }
566 set { m_resourceManger = value; }
567 }
568
569 /// <summary>
570 /// Id of Buddy MapControl
571 /// </summary>
572 public string MapBuddyId
573 {
574 get { return m_mapBuddyId; }
575 set { m_mapBuddyId = value; }
576 }
577
578
579 /// <summary>
580 /// Unit used resource. Resource_Default will return value from resource, if available. Other values will force calculations to use that unit.
581 /// </summary>
582 public MapUnit MapUnits
583 {
584 get { return m_startMapUnits; }
585 set { m_startMapUnits = value; }
586 }
587
588 /// <summary>
589 /// Unit used in display of linear measurements.
590 /// </summary>
591 public MeasureUnit MeasureUnits
592 {
593 get { return m_measureUnits; }
594 set { m_measureUnits = value; }
595 }
596
597 /// <summary>
598 /// Area Units - Unit used in display of area measurements.
599 /// </summary>
600 public AreaUnit AreaUnits
601 {
602 get { return m_areaUnits; }
603 set { m_areaUnits = value; }
604 }
605
606 // Number of Decimals - Number of decimal digits displayed in measurements.
607 public double NumberDecimals
608 {
609 get { return m_numberDecimals; }
610 set { m_numberDecimals = value; }
611 }
612
613
614 public override bool Visible
615 {
616 get { return base.Visible; }
617 }
618
619 public override bool EnableTheming
620 {
621 get
622 {
623 return base.EnableTheming;
624 }
625 }
626
627 public override bool EnableViewState
628 {
629 get
630 {
631 return base.EnableViewState;
632 }
633 }
634
635 }
636}
3.代码贴太多了编辑器死掉了一样了,郁闷换个新篇继续写了...