using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Media; using Microsoft.Maps.MapControl; using Microsoft.Maps.MapControl.Core; using Microsoft.Maps.MapControl.Navigation; using Microsoft.Maps.MapControl.Overlays; namespace CustomMap.Lib { /* * 功能描述 * 本类应该有一个强大的图层管理功能 * 至少应该要具有如下的方法: * 1.插入用户控件,参数有:所在图层,位置信息,控件信息 * 2.模式设置:是卫星地图/路径地图 * 3.定位中心点:缩放级别/中心点 * 4.测距:点集 * 5.添加/清理标注信息 * 6.清除指定图层/清除所有图层 * 7.图例的操作 * 8.保障好在加载不同的地图时,一切均能正常 */ /// <summary> /// 地图操作控件 /// </summary> public class MapEx : Microsoft.Maps.MapControl.Map { #region 字段声明 /// <summary> /// 偏移经度 /// </summary> private double dLongWarp = 0; /// <summary> /// 偏移纬度 /// </summary> private double dLatWarp = 0; #endregion #region 属性声明 /// <summary> /// 图层名称集合 /// </summary> private List<MapLayerInfo> listLayer = null; public List<MapLayerInfo> ListLayer { get { return listLayer; } } #endregion #region 构造函数 /// <summary> /// 构造函数 /// </summary> public MapEx() { listLayer = new List<MapLayerInfo>(); #region 事件注册 this.MapForeground.TemplateApplied += delegate(object sender, EventArgs args) { this.MapForeground.NavigationBar.TemplateApplied += new EventHandler(NavigationBar_TemplateApplied); }; this.LoadingError += delegate(object sender, LoadingErrorEventArgs e) { //移除 Unable to contact server 的错误消息 try { (VisualTreeHelper.GetChild(this, 0) as MapLayer).Children.Remove(VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(this, 0), 5) as LoadingErrorMessage); } catch { } }; #endregion btnRoad_Click(null, null); } #endregion #region 地图自定义菜单操作 void NavigationBar_TemplateApplied(object sender, EventArgs e) { //清除导航菜单上现有项 NavigationBar navBar = this.MapForeground.NavigationBar; navBar.HorizontalPanel.Children.Clear(); navBar.VerticalPanel.Children.Clear(); //添加自定义导航菜单项 ChangeMapModeButton btnAerial = new ChangeMapModeButton(new AerialMode(true), "卫星地图", "点击导航到卫星地图"); btnAerial.IsChecked = true; navBar.HorizontalPanel.Children.Add(btnAerial); btnAerial.Click += new RoutedEventHandler(btnAerial_Click); ChangeMapModeButton btnRoad = new ChangeMapModeButton(new RoadMode(), "路径地图", "点击导航到路径地图"); btnRoad.IsChecked = false; navBar.HorizontalPanel.Children.Add(btnRoad); btnRoad.Click += new RoutedEventHandler(btnRoad_Click); ChangeMapModeButton btnStreet = new ChangeMapModeButton(new RoadMode(), "街道地图", "点击导航到街道地图"); btnStreet.IsChecked = false; navBar.HorizontalPanel.Children.Add(btnStreet); btnStreet.Click += new RoutedEventHandler(btnStreet_Click); } /// <summary> /// 卫星地图 /// </summary> void btnAerial_Click(object sender, RoutedEventArgs e) { //中文地图---目前Bing因为法律问题暂时不支持中文卫星地图访问 MapTileLayer tileLayer = new MapTileLayer(); GoogleWXSource gts = new GoogleWXSource(); tileLayer.TileSources.Add(gts); this.Children.Add(tileLayer); this.Mode = new AerialMode(); dLatWarp = 0; dLongWarp = 0; } /// <summary> /// 路径地图 /// </summary> void btnRoad_Click(object sender, RoutedEventArgs e) { MapTileLayer tileLayer = new MapTileLayer(); GoogleTileSource gts = new GoogleTileSource(); tileLayer.TileSources.Add(gts); this.Children.Add(tileLayer); this.Mode = new MercatorMode(); dLatWarp = -0.00041397; dLongWarp = 0.00557889; } /// <summary> /// 街道地图 /// </summary> void btnStreet_Click(object sender, RoutedEventArgs e) { MapTileLayer tileLayer = new MapTileLayer(); StreetTileSource sts = new StreetTileSource(); tileLayer.TileSources.Add(sts); this.Children.Add(tileLayer); this.Mode = new MercatorMode(); dLatWarp = -0.0007038; dLongWarp = 0.0054717; } #endregion #region 地图操作方法 /// <summary> /// 地图中心点定位 /// </summary> /// <param name="latitude">纬度</param> /// <param name="longitude">经度</param> /// <param name="zoomLevel">缩放级别</param> public void SetPosition(double latitude, double longitude, double zoomLevel) { latitude += dLatWarp; longitude += dLongWarp; Location location = new Location(latitude, longitude); zoomLevel = zoomLevel == 0 ? this.ZoomLevel : zoomLevel; this.SetView(location, zoomLevel); } /// <summary> /// 添加UI对象 /// </summary> /// <param name="layerName">图层名称</param> /// <param name="latitude">纬度</param> /// <param name="longitude">经度</param> /// <param name="element">UIElement对象</param> public void AddUIElement(string layerName, double latitude, double longitude, UIElement element) { MapLayer MapLayer = this.CreateLayer(layerName); // 获UIElement对象名称 string name = element.GetValue(NameProperty).ToString(); // 判断该UIElement对象在地图上是否存在 // 如果存在则移除 UIElement uc = MapLayer.FindName(name) as UIElement; if (uc != null) MapLayer.Children.Remove(uc); PositionOrigin position = PositionOrigin.Center; latitude += dLatWarp; longitude += dLongWarp; Location location = new Location(latitude, longitude); MapLayer.AddChild(element, location, position); } /// <summary> /// 重载添加UI对象 /// </summary> /// <param name="layerName">图层名称</param> /// <param name="latitude">纬度</param> /// <param name="longitude">经度</param> /// <param name="element">UIElement对象</param> /// <param name="position">偏移定位</param> public void AddUIElement(string layerName, double latitude, double longitude, UIElement element, PositionOrigin position) { MapLayer MapLayer = this.CreateLayer(layerName); // 获UIElement对象名称 string name = element.GetValue(NameProperty).ToString(); // 判断该UIElement对象在地图上是否存在 // 如果存在则移除 UIElement uc = MapLayer.FindName(name) as UIElement; if (uc != null) MapLayer.Children.Remove(uc); latitude += dLatWarp; longitude += dLongWarp; Location location = new Location(latitude, longitude); MapLayer.AddChild(element, location, position); } /// <summary> /// 重载添加UI对象 /// </summary> /// <param name="layerName">图层名称</param> /// <param name="latitude">纬度</param> /// <param name="longitude">经度</param> /// <param name="element">UIElement对象</param> /// <param name="zoomLevel">地图缩放级别</param> public void AddUIElement(string layerName, double latitude, double longitude, UIElement element, double zoomLevel) { MapLayer MapLayer = this.CreateLayer(layerName); // 获UIElement对象名称 string name = element.GetValue(NameProperty).ToString(); // 判断该UIElement对象在地图上是否存在 // 如果存在则移除 UIElement uc = MapLayer.FindName(name) as UIElement; if (uc != null) MapLayer.Children.Remove(uc); PositionOrigin position = PositionOrigin.Center; latitude += dLatWarp; longitude += dLongWarp; Location location = new Location(latitude, longitude); MapLayer.AddChild(element, location, position); this.SetView(location, zoomLevel); } /// <summary> /// 重载添加UI对象 /// </summary> /// <param name="layerName">图层名称</param> /// <param name="latitude">纬度</param> /// <param name="longitude">经度</param> /// <param name="element">UIElement对象</param> /// <param name="zoomLevel">地图缩放级别</param> /// <param name="position">偏移定位</param> public void AddUIElement(string layerName, double latitude, double longitude, UIElement element, double zoomLevel, PositionOrigin position) { MapLayer MapLayer = this.CreateLayer(layerName); // 获UIElement对象名称 string name = element.GetValue(NameProperty).ToString(); // 判断该UIElement对象在地图上是否存在 // 如果存在则移除 UIElement uc = MapLayer.FindName(name) as UIElement; if (uc != null) MapLayer.Children.Remove(uc); latitude += dLatWarp; longitude += dLongWarp; Location location = new Location(latitude, longitude); MapLayer.AddChild(element, location, position); this.SetView(location, zoomLevel); } /// <summary> /// 创建图层 /// </summary> /// <param name="layerName">图层名称</param> /// <returns>返回当前添加的图层</returns> public MapLayer CreateLayer(string layerName) { MapLayerInfo MyLayer = listLayer.FirstOrDefault(n => n.LayerName == layerName); if (MyLayer == null) { MyLayer = new MapLayerInfo() { LayerName = layerName, MapLayer = new MapLayer() }; this.Children.Add(MyLayer.MapLayer); listLayer.Add(MyLayer); } return MyLayer.MapLayer; } /// <summary> /// 清除用户控件 /// </summary> /// <param name="layerName">图层名称</param> /// <param name="name">对象名称</param> public void RemoveUIElement(string layerName, string name) { MapLayerInfo MyLayer = listLayer.FirstOrDefault(n => n.LayerName == layerName); if (MyLayer == null) return; UIElement uc = MyLayer.MapLayer.FindName(name) as UIElement; if (uc == null) return; MyLayer.MapLayer.Children.Remove(uc); } /// <summary> /// 清除指定图层 /// <param name="layerName">图层名称</param> /// </summary> public void RemoveLayer(string layerName) { MapLayerInfo MyLayer = listLayer.FirstOrDefault(n => n.LayerName == layerName); if (MyLayer == null) return; // 清空指定图层里面对象 MyLayer.MapLayer.Children.Clear(); // 清空当前图层 this.Children.Remove(MyLayer.MapLayer); // 从图层集合中移除当前图层 this.listLayer.Remove(MyLayer); } /// <summary> /// 清除地图上所有图层信息 /// </summary> public void RemoveAll() { if (listLayer.Count == 0) return; foreach (MapLayerInfo layer in listLayer) { layer.MapLayer.Children.Clear(); this.Children.Remove(layer.MapLayer); } listLayer.Clear(); } #endregion } #region 图层信息类 /// <summary> /// 图层信息 /// </summary> public class MapLayerInfo { /// <summary> /// 图层名称 /// </summary> public string LayerName { get; set; } /// <summary> /// 图层对象 /// </summary> public MapLayer MapLayer { get; set; } } #endregion }