上一篇介紹了如何在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/
作者:阿凡盧
出處:http://www.cnblogs.com/luxiaoxun/
本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。