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时会有不同的结果,如果有高手能发现问题,请指出,兄弟在此谢过了!!!!!!!!!!

 

posted on 2010-02-07 15:56  风之恋  阅读(3168)  评论(8编辑  收藏  举报

导航