首先下载必须插件:http://greatmaps.codeplex.com/。并引用里面的dll插件。
在我们编码的时候,必须要弄懂地图是怎么构成的,是有三层构成的,图片如下(剪切地址:http://www.flickr.com/photos/33793929@N07/6008096410/):
最上层:GMapMarker.中间层:GMapOverlay。最底层:GMapControl。GMapMarker就是用户选中的地址做的水滴标记。当我们要添加水滴标记的时候,标记先添加进入GMapMarker,再把GMapMarker添加进GMapOverlay,最后把GMapOverlay添加进GMapMarker中,就会打到如下面图片中的水滴效果。如果是移除水滴标记,则以相反方向依次移除。下面就开始贴代码了。
功能代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using GMap.NET; using GMap.NET.WindowsForms.Markers; using GMap.NET.WindowsForms; using GMap.NET.MapProviders; using GMap.NET.Projections; using WindowsFormsApplication1.Properties; using System.Windows; namespace WindowsFormsApplication1 { public partial class FrmMap : Form { //地图由三层组成。最上层:GMapMarker.中间层:GMapOverlay。最底层:GMapControl。 GMapOverlay objects;
GMapControl MainMap; public FrmMap() { InitializeComponent(); //获得地图信息,默认北京位置。 SuspendLayout(); MainMap = new GMapControl(); { //Google中国地图。 MainMap.MapProvider = GMapProviders.GoogleChinaMap; MainMap.Position = new PointLatLng(39.904214, 116.407113); MainMap.MinZoom = 1; MainMap.MaxZoom = 19; MainMap.Zoom = 10; MainMap.Dock = DockStyle.Fill; MainMap.MarkersEnabled = true; this.label2.Text = this.label1.Text = ""; this.label1.Text = "经度:" + MainMap.Position.Lng.ToString(); this.label2.Text = "纬度:" + MainMap.Position.Lat.ToString(); } //this.MainMap.ReloadMap();//重新加载地图。 GMapProvider.Language = LanguageType.ChineseSimplified; //最上层的图标显示。 Cursor.Current = Cursors.WaitCursor; var current = new PointLatLng(MainMap.Position.Lat, MainMap.Position.Lng); var currentMark = new GMapMarkerGoogleGreen(current); var overlay = new GMapOverlay(MainMap, "current"); overlay.Markers.Add(currentMark); MainMap.Overlays.Add(overlay); Cursor.Current = Cursors.Default; //用户双击标记选中点。并获得当前的经纬度。 { MainMap.MouseDoubleClick += new MouseEventHandler(MainMap_MouseDoubleClick); } gMapControl1.Controls.Add(MainMap); ResumeLayout(true); objects = new GMapOverlay(this.gMapControl1, "objects"); this.gMapControl1.Overlays.Add(objects); GMapMarkerRect rect = new GMapMarkerRect(MainMap.Position); rect.Size = new System.Drawing.Size(0, 0); rect.ToolTipText = "北京市"; rect.ToolTipMode = MarkerTooltipMode.Always; overlay.Markers.Add(rect); MainMap.DragButton = MouseButtons.Left; txtAddress.Focus(); } //用户选中地图位置,获得经纬度。 void MainMap_MouseDoubleClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { //图标显示。 Cursor.Current = Cursors.WaitCursor; PointLatLng latLng = MainMap.FromLocalToLatLng(e.X, e.Y); var current = new PointLatLng(Math.Abs(latLng.Lat), latLng.Lng); var currentMark = new GMapMarkerGoogleGreen(current); var overlay = new GMapOverlay(MainMap, "current"); MainMap.MarkersEnabled = false; overlay.Markers.Clear(); MainMap.Overlays.Clear(); overlay.Markers.Add(currentMark); MainMap.Overlays.Add(overlay); MainMap.MarkersEnabled = true; Cursor.Current = Cursors.Hand; this.label2.Text = this.label1.Text = ""; this.label1.Text = "经度:" + latLng.Lng.ToString(); this.label2.Text = "纬度:" + latLng.Lat.ToString(); } } //根据城市查询地图。 private void btnSearch_Click(object sender, EventArgs e) { if (this.txtAddress.Text.Length == 0) { this.txtAddress.Focus(); MessageBox.Show("请输入查询的地址"); return; } this.MainMap.ReloadMap(); GMapProvider.Language = LanguageType.ChineseSimplified; string search = string.Format("{0}", this.txtAddress.Text); //判断地址键是否存在。 GeoCoderStatusCode code = MainMap.SetCurrentPositionByKeywords(search); if (code != GeoCoderStatusCode.G_GEO_SUCCESS) { MessageBox.Show("地址没有找到:'" + this.txtAddress.Text + "', 原因:" + code.ToString(), "GMap.NET", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } objects = new GMapOverlay(MainMap, "objects"); objects.Markers.Clear(); this.MainMap.Overlays.Clear(); AddLocation(txtAddress.Text); } //由地址获得经纬度,再显示地图位置。 private void AddLocation(string place) { GeoCoderStatusCode unknow = GeoCoderStatusCode.Unknow; PointLatLng? latLngFromGeocoder = GMap.NET.MapProviders.GMapProviders.GoogleChinaMap.GetPoint(place, out unknow); if (latLngFromGeocoder.HasValue && (unknow == GeoCoderStatusCode.G_GEO_SUCCESS)) { GMapMarker item = new GMapMarkerGoogleGreen(latLngFromGeocoder.Value); GMapMarkerRect rect = new GMapMarkerRect(latLngFromGeocoder.Value); rect.Size = new System.Drawing.Size(100, 100); rect.ToolTipText = place; rect.ToolTipMode = MarkerTooltipMode.Always; objects = new GMapOverlay(MainMap, "objects"); objects.Markers.Add(item); objects.Markers.Add(rect); MainMap.Overlays.Add(objects); this.label2.Text = this.label1.Text = ""; this.label1.Text = "经度:" + latLngFromGeocoder.Value.Lng.ToString(); this.label2.Text = "纬度:" + latLngFromGeocoder.Value.Lat.ToString(); if (txtAddress.Text.Length < 4) { this.MainMap.Zoom = 10; } else { this.MainMap.Zoom += 3; } } } } }
界面如下:
加载运行后的效果如下:
其中搜索的方法AddLocation中有一个类GMapMarkerRect 需要重新建立一个类,类中代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace WindowsFormsApplication1 { using System.Drawing; using GMap.NET.WindowsForms; using GMap.NET.WindowsForms.Markers; using GMap.NET; using System; using System.Runtime.Serialization; using System.Drawing.Drawing2D; [Serializable] public class GMapMarkerRect : GMapMarker, ISerializable { [NonSerialized] public Pen Pen; //[NonSerialized] //public GMarkerGoogle InnerMarker; public GMapMarkerRect(PointLatLng p): base(p) { Pen = new Pen(Brushes.Blue, 5); // do not forget set Size of the marker // if so, you shall have no event on it ;} Size = new System.Drawing.Size(111, 111); Offset = new System.Drawing.Point(-Size.Width / 2, -Size.Height / 2); } public override void OnRender(Graphics g) { g.DrawRectangle(Pen, new System.Drawing.Rectangle(LocalPosition.X, LocalPosition.Y, Size.Width, Size.Height)); } } }
按地址搜索后的效果如下:
《参考文章:http://www.cnblogs.com/wuhuacong/archive/2010/03/10/1681790.html》
源码下载:http://files.cnblogs.com/Health/WindowsFormsApplication1.rar