/// <summary> /// /// </summary> /// <param name="e"></param> protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); if (_mouse_type == MouseType.DragMap) //拖动地图 鼠标弹起 { } if (_mouse_type == MouseType.DrawDownloadArea) //绘制下载区域 弹起鼠标 { BDownloadRectangle d = _current_drawing as BDownloadRectangle; if (d != null) { LatLngPoint left_down = MapHelper.GetLatLngByScreenLocation(new Point(d.LeftTop.X, d.LeftTop.Y + d.Height), _center, _zoom, ClientSize); LatLngPoint right_up = MapHelper.GetLatLngByScreenLocation(new Point(d.LeftTop.X + d.Width, d.LeftTop.Y), _center, _zoom, ClientSize); using (MapDownloadDialog dlg = new MapDownloadDialog(left_down, right_up)) { if (dlg.ShowDialog() == DialogResult.OK) { } _current_drawing = null; Invalidate(); } } } _current_cursor_cache = Cursor = Cursors.Arrow; _mouse_type = MouseType.None; }
/// <summary> /// /// </summary> /// <param name="e"></param> protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (e.Button == System.Windows.Forms.MouseButtons.Left) { if (_mouse_type == MouseType.DragMap) //拖拽地图 { int deltax = e.Location.X - _previous_point_cache.X; int deltay = e.Location.Y - _previous_point_cache.Y; LatLngPoint llp = MapHelper.GetLatLngByScreenLocation(new Point(ClientSize.Width / 2 - deltax, ClientSize.Height / 2 - deltay), _center, _zoom, ClientSize); Center = llp; _previous_point_cache = e.Location; } // } if (e.Button == System.Windows.Forms.MouseButtons.Right) { if (_mouse_type == MouseType.DrawDownloadArea && _current_drawing as BDownloadRectangle != null) //绘制截图矩形 { (_current_drawing as BDownloadRectangle).Width = e.Location.X - (_current_drawing as BDownloadRectangle).LeftTop.X; (_current_drawing as BDownloadRectangle).Height = e.Location.Y - (_current_drawing as BDownloadRectangle).LeftTop.Y; } } Invalidate(); }
/// <summary> /// /// </summary> /// <param name="e"></param> protected override void OnMouseWheel(MouseEventArgs e) { base.OnMouseWheel(e); //缩放 int z = _zoom + e.Delta / 100; if (z >= 3 && z <= 19) { LatLngPoint p = MapHelper.GetLatLngByScreenLocation(e.Location, _center, _zoom, ClientSize); //鼠标经纬度坐标 PointF pt = MapHelper.GetLocationByLatLng(p, z); //鼠标像素坐标 PointF pt_center = new PointF(pt.X + (ClientSize.Width / 2 - e.Location.X), pt.Y + (e.Location.Y - ClientSize.Height / 2)); //缩放后中心点像素坐标 LatLngPoint p_center = MapHelper.GetLatLngByLocation(pt_center, z); //像素坐标到经纬度坐标 Center = p_center; Zoom = z; Invalidate(); } }
/// <summary> /// 将位置显示在列表中 /// </summary> /// <param name="places"></param> internal void AddPlaces(JToken places) { flpPlaces.Controls.Clear(); //清空原来所有位置 if (Parent != null && Parent is TabPage) //如果父控件是tabpage 则选中 { ((Parent as TabPage).Parent as TabControl).SelectedTab = (Parent as TabPage); } if (BDirectionBoard != null) //导航控件初始化 { BDirectionBoard.Clear(); } //加载位置项 int index = 0; List <BPOI> _list = new List <BPOI>(); foreach (JObject place in places) { if (place["location"] != null && place["location"]["lng"] != null && (string)place["location"]["lng"] != "") { LatLngPoint location = new LatLngPoint(double.Parse((string)place["location"]["lng"]), double.Parse((string)place["location"]["lat"])); BPOI poi = new BPOI { DataSource = place, Index = index, Selected = false, Location = location }; _list.Add(poi); BPlaceItem item = new BPlaceItem(); item.Index = index++; item.POI = poi; item.SetDestinationPlace += new SetDestinationPlaceEventHandler(item_SetDestinationPlace); item.SetSourcePlace += new SetSourcePlaceEventHandler(item_SetSourcePlace); item.PlaceSelectedChanged += new PlaceSelectedChangedEventHandler(item_PlaceSelectedChanged); item.Height = 104; flpPlaces.Controls.Add(item); } } if (BMapControl != null) { BMapControl.AddPlaces(_list); } }
/// <summary> /// 绘制地图左下角的一些附加信息 如当前坐标、地图级别、logo、版权等 /// </summary> /// <param name="g"></param> private void DrawMapInfo(Graphics g) { using (GraphicsPath gp = MapHelper.CreateRoundedRectanglePath(new Rectangle(10, Height - 100, 250, 90), 6)) { using (SolidBrush sb = new SolidBrush(Color.FromArgb(180, Color.White))) { g.FillPath(sb, gp); g.DrawPath(Pens.Black, gp); using (Font f = new Font("微软雅黑", 11)) { g.DrawString(MapHelper.GetMapModeTitle(_mode) + "," + _zoom + "级," + MapHelper.GetLoadMapModeTitle(_loadmode), f, Brushes.Teal, new PointF(20, Height - 100 + 10)); Point p = PointToClient(Cursor.Position); if (ClientRectangle.Contains(p)) { LatLngPoint llp = MapHelper.GetLatLngByScreenLocation(p, _center, _zoom, ClientSize); //当前鼠标经纬度 g.DrawString(Math.Round(llp.Lat, 5) + "," + Math.Round(llp.Lng, 5), f, Brushes.Teal, new PointF(20, Height - 100 + 35)); } g.DrawString("BMap.NET 2015 by 周见智", f, Brushes.Teal, new PointF(20, Height - 100 + 60)); } } } }
/// <summary> /// 根据屏幕坐标计算该点的经纬度坐标 /// </summary> /// <param name="p"></param> /// <param name="center"></param> /// <param name="zoom"></param> /// <param name="screen_size"></param> /// <returns></returns> public static LatLngPoint GetLatLngByScreenLocation(PointF p, LatLngPoint center, int zoom, Size screen_size) { PointF cp = GetLocationByLatLng(center, zoom); //中心点像素坐标 //目标点与中心点屏幕坐标差 float delta_x = p.X - screen_size.Width/2; float delta_y = p.Y - screen_size.Height/2; PointF dp = new PointF(cp.X + delta_x, cp.Y + delta_y * (-1)); //目标点像素坐标 return GetLatLngByLocation(dp, zoom); }
/// <summary> /// 根据经纬度坐标计算该点在屏幕中的坐标 /// </summary> /// <param name="p">要计算的经纬度</param> /// <param name="center">屏幕中心经纬度</param> /// <param name="zoom">地图当前缩放级别</param> /// <param name="screen_size">屏幕大小</param> /// <returns></returns> public static Point GetScreenLocationByLatLng(LatLngPoint p, LatLngPoint center, int zoom, Size screen_size) { PointF dp = GetLocationByLatLng(p, zoom); //目标点的像素坐标 PointF cp = GetLocationByLatLng(center, zoom); //中心点的像素坐标 //计算目标点和中心点像素坐标差 double delta_x = dp.X - cp.X; double delta_y = dp.Y - cp.Y; //转换成屏幕坐标系统的坐标 并返回 return new Point((int)((float)screen_size.Width / 2 + delta_x), (int)((float)screen_size.Height / 2 + (-1) * delta_y)); }
/// <summary> /// 根据经纬度计算两点实际距离(m) /// </summary> /// <param name="p1">第一个经纬度坐标点</param> /// <param name="p2">第二个经纬度坐标点</param> /// <returns></returns> public static double GetDistanceByLatLng(LatLngPoint p1, LatLngPoint p2) { double radLat1 = rad(p1.Lat); double radLat2 = rad(p2.Lat); double a = radLat1 - radLat2; double b = rad(p1.Lng) - rad(p2.Lng); double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2))); s = s * EARTH_RADIUS; s = Math.Round(s * 10000) / 10000; return s; }
/// <summary> /// 周边搜索 /// </summary> /// <param name="query"></param> /// <param name="center"></param> void _bTipControl_SearchNearbyStarted(string query, LatLngPoint center) { ((Action)delegate() { PlaceService ps = new PlaceService(); JObject places = ps.SearchInCircle(query, center.Lat + "," + center.Lng, 5000); //默认周边5km this.Invoke((Action)delegate() { if (BPlacesBoard != null) { BPlacesBoard.AddPlaces(places["results"]); //具体json格式参见api文档 } }); }).BeginInvoke(null, null); }
/// <summary> /// 矩形区域搜索 /// </summary> /// <param name="searchName"></param> void _bQuickSearchControl_QuickSearch(string searchName) { LatLngPoint leftbottom = new LatLngPoint(_b_bound.LeftTop.Lng, _b_bound.RightBottom.Lat); LatLngPoint righttop = new LatLngPoint(_b_bound.RightBottom.Lng, _b_bound.LeftTop.Lat); ((Action)delegate() { PlaceService ps = new PlaceService(); JObject places = ps.SearchInBound(searchName, leftbottom.Lat + "," + leftbottom.Lng + "," + righttop.Lat + "," + righttop.Lng);//区域搜索 this.Invoke((Action)delegate() { if (BPlacesBoard != null) { BPlacesBoard.AddPlaces(places["results"]); //具体json格式参见api文档 } }); }).BeginInvoke(null, null); _bQuickSearchControl.Visible = false; }
/// <summary> /// 城市切换 /// </summary> /// <param name="cityName"></param> void _bCityControl_SelectedCityChanged(string cityName) { _bCityControl.Visible = false; _currentCity = cityName; if (BPlaceBox != null) //关联的位置输入框 { BPlaceBox.CurrentCity = cityName; } if (BPlacesBoard != null) //关联的位置列表控件 { BPlacesBoard.CurrentCity = cityName; } if (BDirectionBoard != null) //关联的导航控件 { BDirectionBoard.CurrentCity = _currentCity; } _bMarkerTipControl.CurrentCity = _currentCity; _bPOITipControl.CurrentCity = _currentCity; _bPointTipControl.CurrentCity = _currentCity; Invalidate(); ((Action)delegate() //定位到指定城市 { GeocodingService gs = new GeocodingService(); JObject city_location = gs.Geocoding(_currentCity); if (city_location != null && city_location["result"] != null) { Center = new LatLngPoint(double.Parse((string)city_location["result"]["location"]["lng"]), double.Parse((string)city_location["result"]["location"]["lat"])); Locate(false); } this.Invoke((Action)delegate() { Zoom = 12; Invalidate(); }); }).BeginInvoke(null, null); }
ArrayList _waittodownload = new ArrayList(); //待下载图片集合 public MapDownloadDialog(LatLngPoint p1, LatLngPoint p2) { InitializeComponent(); this.p1 = p1; this.p2 = p2; }
/// <summary> /// 设置地图中的导航路线(可以设为null表示清空) /// </summary> /// <param name="route"></param> internal void SetRoute(BRoute route) { _b_route = route; _bPointTipControl.Visible = false; _bPOITipControl.Visible = false; _bMarkerEditorControl.Visible = false; _bMarkerTipControl.Visible = false; if (_theRouteStart != null && _theRouteEnd != null) //定位到路线中心 { Center = new LatLngPoint((_theRouteEnd.Location.Lng + _theRouteStart.Location.Lng) / 2, (_theRouteStart.Location.Lat + _theRouteEnd.Location.Lat) / 2); Zoom = 13; Locate(false); SyncControlsLocation(); } Invalidate(); }
/// <summary> /// 定位 /// </summary> /// <param name="mylocation">为true表示定位自己 否则定位当前地图中的城市</param> private void Locate(bool mylocation) { //定位位置 ((Action)(delegate() { if (mylocation) //定位自己 { IPService ips = new IPService(); JObject _location = ips.LocationByIP(); if (_location != null && _location["content"] != null) { _currentCity = (string)(_location["content"]["address_detail"]["city"]); //返回JSON结构请参见百度API文档 _center = new LatLngPoint(double.Parse((string)_location["content"]["point"]["x"]), double.Parse((string)_location["content"]["point"]["y"])); } } else //定位地图中心点 { GeocodingService gs = new GeocodingService(); JObject _location = gs.DeGeocoding(_center.Lat + "," + _center.Lng); if (_location != null) { if (_location["result"] != null && _location["result"]["addressComponent"] != null) { if (_zoom <= 8) //定位到国家 { _currentCity = (string)(_location["result"]["addressComponent"]["country"]); //返回JSON结构请参见百度API文档 } else if (_zoom <= 10) //定位到省份 { _currentCity = (string)(_location["result"]["addressComponent"]["province"]); //返回JSON结构请参见百度API文档 } else if (_zoom <= 18) //定位到城市 { if (_location["result"]["addressComponent"]["city"] != null) _currentCity = (string)(_location["result"]["addressComponent"]["city"]); //返回JSON结构请参见百度API文档 } //else //定位到县区 //{ // if (_location["result"]["addressComponent"]["district"] != null) // _currentCity = (string)(_location["result"]["addressComponent"]["district"]); //返回JSON结构请参见百度API文档 //} } } } this.Invoke((Action)delegate() { Invalidate(); if (BPlaceBox != null) //关联的位置输入控件 { BPlaceBox.CurrentCity = _currentCity; } if (BPlacesBoard != null) //关联的位置列表控件 { BPlacesBoard.CurrentCity = _currentCity; } if (BDirectionBoard != null) //关联的导航控件 { BDirectionBoard.CurrentCity = _currentCity; } _bMarkerTipControl.CurrentCity = _currentCity; _bPOITipControl.CurrentCity = _currentCity; _bPointTipControl.CurrentCity = _currentCity; }); })).BeginInvoke(null, null); }
/// <summary> /// 根据经纬度坐标计算该点的像素坐标 /// </summary> /// <param name="p">要计算的经纬度</param> /// <param name="zoom">地图当前缩放级别</param> /// <returns></returns> public static PointF GetLocationByLatLng(LatLngPoint p, int zoom) { PointF mer_p = LatLng2Mercator(p); //墨卡托坐标 return new PointF((float)(mer_p.X / Math.Pow(2, 18 - zoom)), (float)(mer_p.Y / Math.Pow(2, 18 - zoom))); }
private static PointF LatLng2Mercator(LatLngPoint p) { double[] arr = null; double n_lat = p.Lat > 74 ? 74 : p.Lat; n_lat = n_lat < -74 ? -74 : n_lat; for (var i = 0; i < array1.Length; i++) { if (p.Lat >= array1[i]) { arr = array2[i]; break; } } if (arr == null) { for (var i = array1.Length - 1; i >= 0; i--) { if (p.Lat <= -array1[i]) { arr = array2[i]; break; } } } double[] res = Convertor(p.Lng, p.Lat, arr); return new PointF((float)res[0], (float)res[1]); }
/// <summary> /// 设置路线中高亮部分 /// </summary> /// <param name="path"></param> /// <param name="enlarge"></param> internal void SetHighlightPath(string path, bool enlarge) { string[] points = path.Split(';'); if (_b_route != null) { _b_route.HighlightPath = path; if (enlarge) //放大定位 { LatLngPoint lp = new LatLngPoint(double.Parse(points[0].Split(',')[0]), double.Parse(points[0].Split(',')[1])); Center = lp; Zoom = 18; Locate(false); SyncControlsLocation(); } Invalidate(); } }