zoukankan      html  css  js  c++  java
  • C#2008+ArcGIS Mobile实现路口定位

    第一步:在道路图层中,通过模糊查询获取道路列表,并选取所需的道路,C#代码如下:

    代码
     1         /// <summary>
     2         /// 模糊查询道路
     3         /// </summary>
     4         /// <param name="_name">道路名关键字</param>
     5         /// <param name="_ms">待操作的mobileservice</param>
     6         /// <param name="_layername">操作的图层名</param>
     7         /// <param name="_lb">填充结果的ListBox</param>
     8         /// <param name="_lg">获取的geometry集合</param>
     9         public static void SearchRoadList(string _name, MobileService _ms, string _layername, ListBox _lb,out List<Geometry> _lg)
    10         {
    11             _lb.Items.Clear();
    12             if (String.IsNullOrEmpty(_name))
    13             {
    14                 _lg = null;
    15                 return;
    16             }
    17        
    18             MobileServiceLayer msl = _ms.Layers[_layername] as MobileServiceLayer;
    19             FeatureLayer fl = msl as ESRI.ArcGIS.Mobile.MobileServices.FeatureLayer;
    20             string qstr = "NAME Like '%" + _name + "%'";//过滤内容
    21 
    22             QueryFilter qf = new QueryFilter(qstr, true);//过滤器
    23 
    24             using (FeatureDataReader fdr = fl.GetDataReader(qf))
    25             {
    26                 _lg = new List<Geometry>();
    27                 while (fdr.Read())
    28                 {
    29                     Geometry geo = fdr.GetGeometry() as ESRI.ArcGIS.Mobile.Geometries.Geometry;
    30                     _lg.Add(geo);
    31                     string id = Convert.ToString(fdr["OBJECTID"]);
    32                     string name = Convert.ToString(fdr["NAME"]);
    33                     _lb.Items.Add(id + "-" + name);
    34                 }
    35             }
    36             if (_lb.Items.Count == 0)
    37             {
    38                 MessageBox.Show("搜寻结果为空!""提示");
    39             }
    40 
    41 
    42         }

    这里除了获取名称以外,也获取了道路的ID,这是因为在实际的数据中可能会有多条道路Polyline的Name相同,但ID不同,下面主要是通过ID定位道路

       在ListBox有查询结果,选择道路后,可以从上面的List<Geometry> _lg中获取对应的Geometry,下面另外附了一段代码,是通过ID获取道路的Geometry的:

    代码
     1    /// <summary>
     2         /// 根据ID获取道路的Geometry
     3         /// </summary>
     4         /// <param name="_roadid">道路ID</param>
     5         /// <param name="_layername">道路操作图层</param>
     6         /// <param name="_ms">要操作的MobileService</param>
     7         /// <returns></returns>
     8         public static ESRI.ArcGIS.Mobile.Geometries.Geometry GetGeometry(string _roadid, string _layername, MobileService _ms)
     9         {
    10             MobileServiceLayer msl = _ms.Layers[_layername] as MobileServiceLayer;
    11             FeatureLayer fl = msl as FeatureLayer;
    12             string qstr = "OBJECTID=" + _roadid;
    13             QueryFilter qf = new QueryFilter(qstr, true);
    14             ESRI.ArcGIS.Mobile.Geometries.Geometry G = null;
    15             try
    16             {
    17                 using (FeatureDataReader fdr = fl.GetDataReader(qf))
    18                 {
    19                     while (fdr.Read())
    20                     {
    21                         G = fdr.GetGeometry() as ESRI.ArcGIS.Mobile.Geometries.Geometry;
    22                         return G;
    23                     }
    24                 }
    25                 return G = null;
    26             }
    27             catch (Exception ex)
    28             {
    29                 MessageBox.Show(ex.Message, "错误");
    30                 return G = null;
    31             }
    32         }

    第二步,分析处理两个道路的Geometry,得到路口,并在图中高亮显示出来,C#代码如下,我的表述能力不怎么好,希望通过代码来弥补

    代码
     1    /// <summary>
     2         /// 高亮显示路口
     3         /// </summary>
     4         /// <param name="mainroadid">主路的道路ID</param>
     5         /// <param name="crossroadid">跨越道路ID</param>
     6         /// <param name="layername">操作的图层名</param>
     7         /// <param name="ms">操作的MobileService</param>
     8         /// <param name="mp">操作的MobileMap</param>
     9         /// <param name="cc">搜集到的CoordinateCollection</param>
    10         /// <param name="IsMacth">是否超过一个路口</param>
    11         public static void HightLightRoadCorner(Geometry mainGeo,Geometry crossGeo, string layername, MobileService ms, ESRI.ArcGIS.Mobile.Map mp, out CoordinateCollection cc, bool IsTouch)
    12         {
    13             try
    14             {
    15                 //Geometry mainGeo = GetGeometry(mainroadid, layername, ms);
    16                 if (mainGeo == null)
    17                 {
    18                     MessageBox.Show("不能获取对应道路,请检查""提示");
    19                     cc = null;
    20                     return;
    21                 }
    22                 
    23                 //Geometry crossGeo = GetGeometry(crossroadid, layername, ms);
    24                 if (crossGeo == null)
    25                 {
    26                     MessageBox.Show("不能获取第二条道路,请检查""提示");
    27                     cc = null;
    28                     return;
    29                 }
    30                 GeometricRelationshipType _type;
    31                 if (IsTouch == true)
    32                     _type = GeometricRelationshipType.Touch;//两条道路有两个或以上的路口
    33                 else
    34                     _type = GeometricRelationshipType.Cross;//两条道路有一个路口
    35 
    36                 bool IsCross = mainGeo.Relate(crossGeo, _type);//判断两者是否相交
    37 
    38                 if (IsCross == true)
    39                 {
    40                     IList<CoordinateCollection> crossRoadParts = crossGeo.Parts;
    41                     IList<Coordinate> crossRoadCoordinate = crossRoadParts[0];
    42                     CoordinateCollection tmpCollect = new CoordinateCollection();
    43 
    44                     if (crossRoadCoordinate.Count != 0)
    45                     {
    46                         for (int i = 0; i < crossRoadCoordinate.Count; i++)
    47                         {
    48                             ESRI.ArcGIS.Mobile.Geometries.Point tmppoint = new ESRI.ArcGIS.Mobile.Geometries.Point(crossRoadCoordinate[i]);
    49 
    50                             if (tmppoint.Within(mainGeo))
    51                             {
    52                                 if (IsTouch == true)//有两个或以上交叉路口
    53                                 {
    54                                     Coordinate c = tmppoint.GetExtent().GetCenter();
    55                                     tmpCollect.Add(c);
    56                                     HighLightOnlyRoadCorner(tmppoint, mp, ms, layername);
    57                                 }
    58                                 else
    59                                 {
    60                                     cc=tmpCollect = null;
    61                                     HighLightOnlyRoadCorner(tmppoint, mp, ms, layername);
    62                                     return;                                
    63                                 }                             
    64 
    65                             }
    66 
    67                         }
    68                     }
    69                     //if (tmpCollect.Count == 0)
    70                     //    cc = null;
    71                     //else
    72                     //    cc = tmpCollect;
    73                     cc = tmpCollect;
    74 
    75                 }
    76                 else
    77                 {
    78                     MessageBox.Show("两条道路不能相交,不能确定路口!""提示");
    79                     cc = null;
    80                     return;
    81                 }
    82             }
    83             catch
    84             {
    85                 cc = null;
    86             }
    87 
    88         }

    下面是写的两个相关的函数

    代码
     1        /// <summary>
     2         /// 判断点是否在指定区域内
     3         /// </summary>
     4         /// <param name="_g">geometry</param>
     5         /// <param name="_ev">指定区域</param>
     6         /// <returns></returns>
     7         public static bool PointInEnvelop(Geometry _g, Envelope _ev)
     8         {
     9             Coordinate cd = _g.GetExtent().GetCenter();
    10             double evcenterx = _ev.XCenter;
    11             double evcentery = _ev.YCenter;
    12             double minx = evcenterx - _ev.Width / 2;
    13             double maxx = evcenterx + _ev.Width / 2;
    14             double miny = evcentery - _ev.Height / 2;
    15             double maxy = evcentery + _ev.Height / 2;
    16 
    17             if (cd.X > minx && cd.X < maxx && cd.Y > miny && cd.Y < maxy)
    18             {
    19                 return true;
    20             }
    21             else
    22             {
    23                 return false;
    24             }
    25         }
    26 
    27         /// <summary>
    28         /// 定位路口单点
    29         /// </summary>
    30         /// <param name="cornerpoint">路口点</param>
    31         /// <param name="mp">地图控件</param>
    32         /// <param name="layername">图层名</param>
    33         public static void HighLightOnlyRoadCorner(ESRI.ArcGIS.Mobile.Geometries.Point cornerpoint, ESRI.ArcGIS.Mobile.Map mp,MobileService ms,string layername)
    34         {
    35             Envelope newEnvelope = mp.GetExtent();
    36             MobileServiceLayer msl = ms.Layers[layername] as MobileServiceLayer;
    37             FeatureLayer fl = msl as ESRI.ArcGIS.Mobile.MobileServices.FeatureLayer;
    38             if (fl.InScaleRange(mp.Scale))
    39             {
    40                 if (PointInEnvelop(cornerpoint as Geometry,newEnvelope))
    41                 {
    42                     mp.FlashGeometry(new Pen(Color.Blue, 2.0F), new SolidBrush(Color.Red), 1550015, cornerpoint);
    43                 }
    44                 else
    45                 {
    46                     Coordinate tmpcd = cornerpoint.GetExtent().GetCenter();
    47                     Envelope tmpel = new Envelope(tmpcd, 250250);
    48                     mp.SetExtent(tmpel);
    49                     mp.FlashGeometry(new Pen(Color.Blue, 2.0F), new SolidBrush(Color.Red), 2050020, cornerpoint);
    50                 }
    51 
    52             }
    53             else
    54             {
    55                 Coordinate tmpcd = cornerpoint.GetExtent().GetCenter();
    56                 Envelope tmpel = new Envelope(tmpcd, 250250);
    57                 mp.SetExtent(tmpel);
    58                 mp.FlashGeometry(new Pen(Color.Blue, 2.0F), new SolidBrush(Color.Red), 2050020, cornerpoint);
    59 
    60             }
    61         }
    62     }

     希望以上代码对大家使用ArcGIS Mobile进行道路定位有所帮助,如果有什么问题,可以与我联系~~~~

     在实际操作过程中,可能两条道路会有两个路口甚至更多,举个例子:在上海,桂林路与桂林西街,桂林东街都有两个路口~

     不过我上面的代码还有一个不算是Bug的Bug,就是在定位两个路口,甚至是两个路口以上的路口时,设置Mainroad和Crossroad时会有不同的结果,如果有高手能发现问题,请指出,兄弟在此谢过了!!!!!!!!!!

  • 相关阅读:
    2019-6-23-win10-uwp-未给任务-GenerateAppxPackageRecipe-的必需参数-AppxManifestXml-赋值
    2018-8-17-C#-从零开始写-SharpDx-应用-控制台创建-Sharpdx-窗口
    QToolBox
    QListWidget
    宽字节 多字节 mbstowcs wcstombs
    va_start可变参数函数
    c语言二进制、八进制、十六进制
    文件锁 flock/fcntl
    volatile和锁
    串口应用程序
  • 原文地址:https://www.cnblogs.com/MyLucifer/p/1665418.html
Copyright © 2011-2022 走看看