上一篇介绍了如何在GMap地图上添加多边形,这篇介绍下如何使用在线的地图服务进行“地址解析”和“路径查找”。
先看地址解析,GMap中的地址解析主要用到GeocodingProvider中的如下方法:
//根据关键字得到一组坐标
GeoCoderStatusCode GetPoints(string keywords, out List
PointLatLng? GetPoint(string keywords, out GeoCoderStatusCode status); //根据坐标得到一组地址
GeoCoderStatusCode GetPlacemarks(PointLatLng location, out List
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/
参考: