zoukankan      html  css  js  c++  java
  • ArcGIS.Server.9.2.DotNet自带例子分析(一、四)

    目的:
    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. 加入具体的线距离测量和面积测量功能代码,具体的代码和说明如下:
      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}

    3.代码贴太多了编辑器死掉了一样了,郁闷换个新篇继续写了...
  • 相关阅读:
    源码解析之–网络层YTKNetwork
    ARC和非ARC文件混编
    Xcode真机调试中"There was an internal API error"错误解决方法
    设置textView或者label的行间距方法
    iOS中__block 关键字的底层实现原理
    使用AVCaptureSession捕捉静态图片
    使用AVCaptureSession显示相机预览
    短小强悍的JavaScript异步调用库
    开源中国愚人节网页变模糊的js blur代码
    undefined与null的区别
  • 原文地址:https://www.cnblogs.com/hll2008/p/1267538.html
Copyright © 2011-2022 走看看