上一篇介紹了如何在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/