zoukankan      html  css  js  c++  java
  • GMap.Net开发之地址解析与路径查找

    上一篇介绍了如何在GMap地图上添加多边形,这篇介绍下如何使用在线的地图服务进行“地址解析”和“路径查找”。

    先看地址解析,GMap中的地址解析主要用到GeocodingProvider中的如下方法:

    //根据关键字得到一组坐标
    GeoCoderStatusCode GetPoints(string keywords, out List<PointLatLng> pointList); 
    
    //根据关键字得到一个坐标
    PointLatLng? GetPoint(string keywords, out GeoCoderStatusCode status);
    
    //根据坐标得到一组地址
    GeoCoderStatusCode GetPlacemarks(PointLatLng location, out List<Placemark> placemarkList);
    
    //根据坐标得到一个地址
    Placemark GetPlacemark(PointLatLng location, out GeoCoderStatusCode status);

    先定义一些变量:

            private GMapOverlay locations = new GMapOverlay("locations"); //放置搜索结果的图层
            private GeocodingProvider gp; //地址编码服务
            List<PointLatLng> searchResult = new List<PointLatLng>(); //搜索结果
            PointLatLng start = PointLatLng.Empty; //路径开始点
            PointLatLng end = PointLatLng.Empty;   //路径结束点
    
    
            mapControl.Overlays.Add(locations); //不要忘了添加使用的图层

    地址解析的准确度和当前使用的地图服务有很大关系,一般使用什么MapProvider就使用该MapProvider提供的服务。

    如我使用的是GoogleChinaMap,就使用google的地址解析:

                mapControl.MapProvider = GMapProviders.GoogleChinaMap; //google china 地图
    
                gp = mapControl.MapProvider as GeocodingProvider;
                if (gp == null) //地址转换服务,没有就使用OpenStreetMap
                {
                    gp = GMapProviders.OpenStreetMap as GeocodingProvider;
                }
                GMapProvider.Language = LanguageType.ChineseSimplified; //使用的语言,默认是英文

    地址解析一般有2种情况,第一种就是根据坐标点得到该点对应的地址信息,在map的double click中,我们得到双击点的地址信息:

            void mapControl_MouseDoubleClick(object sender, MouseEventArgs e)
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    PointLatLng point = mapControl.FromLocalToLatLng(e.X, e.Y);
                    GeoCoderStatusCode statusCode = GeoCoderStatusCode.Unknow;
                    Placemark? place = gp.GetPlacemark(point, out statusCode);
                    if (statusCode == GeoCoderStatusCode.G_GEO_SUCCESS)
                    {
                        GMapMarker marker = new GMarkerGoogle(point, GMarkerGoogleType.green);
                        marker.ToolTipText = place.Value.Address;
                        marker.ToolTipMode = MarkerTooltipMode.Always;
    
                        locations.Markers.Add(marker);
                    }
                }
            }

    效果图如下:

    第二种情况就是根据地址得到对应的坐标点,输入字符串地址,在地图上得到对应的位置点,可能有多个,就做个了comboBox保存所有查询得到的结果,每次选择一个地址的时候,将地图的中心位置移到对应的Marker的位置,代码如下:

            private void buttonSearch_Click(object sender, EventArgs e)
            {
                searchResult.Clear();
                locations.Markers.Clear();
                this.comboBoxSearchResult.Items.Clear();
    
                string searchStr = this.textBoxSearch.Text;
                GeoCoderStatusCode statusCode = gp.GetPoints(searchStr, out searchResult);
                if (statusCode == GeoCoderStatusCode.G_GEO_SUCCESS)
                {
                    foreach (PointLatLng point in searchResult)
                    {
                        GMarkerGoogle marker = new GMarkerGoogle(point, GMarkerGoogleType.arrow);
    
                        GeoCoderStatusCode placeMarkResult = new GeoCoderStatusCode();
                        Placemark? place = gp.GetPlacemark(point, out placeMarkResult);
                        locations.Markers.Add(marker);
                        this.comboBoxSearchResult.Items.Add(place.Value.Address);
                    }
                    mapControl.ZoomAndCenterMarkers(locations.Id);
                }
            }
    
            private void comboBoxSearchResult_SelectedIndexChanged(object sender, EventArgs e)
            {
                if (this.comboBoxSearchResult.SelectedIndex < 0)
                {
                    return;
                }
                locations.Clear();
                GMarkerGoogle marker = new GMarkerGoogle(searchResult[this.comboBoxSearchResult.SelectedIndex], GMarkerGoogleType.red);
                locations.Markers.Add(marker);
                mapControl.Position = this.searchResult[this.comboBoxSearchResult.SelectedIndex];
            }

    效果图:

    只是简单的测了下,还是比较准确的。。

    再来看看路径查找,GMap中的路径查找主要用到RoutingProvider的如下方法:

    //avoidHighways:是否避免走高速公路
    //walkingMode:是否步行
    //zoom:查找路径时的zoom,貌似越大路径越准确
    
    //根据起止点start、end和当前的zoom查找路径
    MapRoute GetRoute(PointLatLng start, PointLatLng end, bool avoidHighways, bool walkingMode, int Zoom);
    
    //根据出发点地址start、目的点地址end和当前的zoom查找路径
    MapRoute GetRoute(string start, string end, bool avoidHighways, bool walkingMode, int Zoom);

    先在地图上添加2个Marker,确定“起点”和“终点”:

            void mapControl_OnMarkerClick(GMapMarker item, MouseEventArgs e)
            {
                if (item is GMapMarkerImage)
                {
                    currentMarker = item as GMapMarkerImage;
                    currentMarker.Pen = new Pen(Brushes.Red, 2);
                }
            }
    
            private void buttonSetStart_Click(object sender, EventArgs e)
            {
                if (currentMarker != null)
                {
                    start = currentMarker.Position;
                }
            }
    
            private void buttonSetEnd_Click(object sender, EventArgs e)
            {
                if (currentMarker != null)
                {
                    end = currentMarker.Position;
                }
            }

    再通过RoutingProvider得到起点和终点之间的路径:

            private void buttonFindRoute_Click(object sender, EventArgs e)
            {
                RoutingProvider rp = mapControl.MapProvider as RoutingProvider;
                if (rp == null)
                {
                    rp = GMapProviders.OpenStreetMap; // use OpenStreetMap if provider does not implement routing
                }
    
                MapRoute route = rp.GetRoute(start, end, false, false, (int)mapControl.Zoom);
                if (route != null)
                {
                    // add route
                    GMapRoute r = new GMapRoute(route.Points, route.Name);
                    r.IsHitTestVisible = true;
                    locations.Routes.Add(r);
    
                    // add route start/end marks
                    GMapMarker m1 = new GMarkerGoogle(start, GMarkerGoogleType.green_big_go);
                    m1.ToolTipText = "Start: " + route.Name;
                    m1.ToolTipMode = MarkerTooltipMode.Always;
    
                    GMapMarker m2 = new GMarkerGoogle(end, GMarkerGoogleType.red_big_stop);
                    m2.ToolTipText = "End: " + end.ToString();
                    m2.ToolTipMode = MarkerTooltipMode.Always;
    
                    objects.Markers.Add(m1);
                    objects.Markers.Add(m2);
    
                    mapControl.ZoomAndCenterRoute(r);
                }
            }

    效果图:

    这里使用的google的地图服务,却没有使用google的API,GMap的作者通过解析浏览器访问google地图服务器和地图服务的URL(其他地图也一样),得到了每次访问的URL的格式和传入参数的格式,并找到了规律,确定如何传入参数和解析返回结果而封装了这些类和API,做了这个开源的项目,有兴趣的可看其源代码,还是很有收获的。。。

    项目地址:https://github.com/luxiaoxun/MapDownloader

    更新:GMap默认提供的google地图的“路径查找”和“地址解析”功能已经无效,可以通过集成地图服务的API去做,需要申请开发者key。

    一些地图开发者网站:

    高德:https://lbs.amap.com/api/webservice/summary/

    腾讯:http://lbs.qq.com/index.html

    百度:http://developer.baidu.com/map/index.html

    谷歌:http://maps.googleapis.com/

    参考:

    https://greatmaps.codeplex.com/

  • 相关阅读:
    PHP调试的时候出现了警告:
    快报滚动
    js foreach、map函数
    箭头函数和普通函数的区别
    flex布局
    react+propTypes
    手机尺寸
    less的使用
    发现是在IE6-IE9下,下列元素table,thead,tfoot,tbody,tr,col,colgroup,html,title,style,frameset的innerHTML属性是只读的
    div+css 组织结构
  • 原文地址:https://www.cnblogs.com/luxiaoxun/p/3494756.html
Copyright © 2011-2022 走看看