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/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM