/// <summary> /// 从CGM地图文件中复原地图 /// </summary> internal void GenerateMapFromCGM(string FileName) { treeViewLayers.Nodes.Clear(); MapReader.CGM newCGM = new MapReader.CGM(FileName); myMap = newCGM.MyMap; ratio = newCGM.Ratio; scaleIndex = newCGM.ScaleIndex; centerLngLat = newCGM.CenterPos; centerXY = ETCProjection.LngLat2XY(centerLngLat); //同步更新屏幕中心点投影坐标系坐标 int i = 0; TreeNode mapNode = new TreeNode(myMap.MapName, 1, 1); //添加根节点,Map节点 mapNode.Checked = true; treeViewLayers.Nodes.Add(mapNode); for (i = 0; i < myMap.LayerNum; i++) //添加空间数据对象节点 { TreeNode layerNode = new TreeNode(myMap.GetLayerName(i), 2, 2); layerNode.Checked = true; treeViewLayers.Nodes[0].Nodes.Add(layerNode); } if (myMap.hasBaseMap) { TreeNode basemapNode = new TreeNode(myMap.GetLayerName(i), 1, 1); //添加basemap对象节点 basemapNode.Checked = true; treeViewLayers.Nodes[0].Nodes.Add(basemapNode); } treeViewLayers.ExpandAll(); //打开所有节点 picBoxMap.MouseWheel += new MouseEventHandler(picBoxMap_MouseWheel); //添加鼠标滑轮缩放地图 mapImg = new Bitmap(picBoxMap.Bounds.Width, picBoxMap.Bounds.Height); //构造地图内存图 UpdateMapImg(); }
/// <summary> /// 画注记 /// </summary> /// <param name="g"></param> /// <param name="bounds"></param> /// <param name="centerPos"></param> /// <param name="scale"></param> /// <param name="fid2Text"></param> internal override void DrawLabel(Graphics g, Rectangle bounds, PointF centerPos, double scale, Dictionary <int, string> fid2Text, TextSymbol textSymbol) { MyPoint xyCenter = ETCProjection.LngLat2XY(new MyPoint(centerPos.X, centerPos.Y)); double xmin = xyCenter.X - scale * bounds.Width / 2; double xmax = xyCenter.X + scale * bounds.Width / 2; double ymin = xyCenter.Y - scale * bounds.Height / 2; double ymax = xyCenter.Y + scale * bounds.Height / 2; for (int i = 0; i < polygons.Count; i++) { List <PointF> pointfs = new List <PointF>(); for (int j = 0; j < polygons[i].PointCount; j++) { MyPoint xyProjection = ETCProjection.LngLat2XY(polygons[i].Points[j]); double xScreen = bounds.Width * (xyProjection.X - xmin) / (xmax - xmin); double yScreen = bounds.Height * (xyProjection.Y - ymin) / (ymax - ymin); PointF p = new PointF((float)xScreen, bounds.Height - (float)yScreen); pointfs.Add(p); } RectangleF mbr = GeometryTools.GetMBR(pointfs.ToArray()); string text = fid2Text[polygons[i].FID]; if (Math.Max(mbr.Width, mbr.Height) > textSymbol.TextStyle.TextSize * text.Length) { TextSymbol.PolygonLabel(pointfs.ToArray(), g, textSymbol, text); } } }
/// <summary> /// 点选 /// </summary> /// <returns>被选中要素FID的List</returns> internal override List <int> SelectByPoint(Point mouseLocation, Rectangle bounds, PointF centerPos, double scale) { List <int> selectedID = new List <int>(); MyPoint xyCenter = ETCProjection.LngLat2XY(new MyPoint(centerPos.X, centerPos.Y)); double xmin = xyCenter.X - scale * bounds.Width / 2; double xmax = xyCenter.X + scale * bounds.Width / 2; double ymin = xyCenter.Y - scale * bounds.Height / 2; double ymax = xyCenter.Y + scale * bounds.Height / 2; for (int i = 0; i < polygons.Count; i++) { MyPoint[] screenPoints = new MyPoint[polygons[i].PointCount]; for (int j = 0; j < polygons[i].PointCount; j++) { MyPoint xyProjection = ETCProjection.LngLat2XY(polygons[i].Points[j]); double xScreen = bounds.Width * (xyProjection.X - xmin) / (xmax - xmin); double yScreen = bounds.Height * (xyProjection.Y - ymin) / (ymax - ymin); MyPoint screen = new MyPoint(xScreen, bounds.Height - yScreen); screenPoints[j] = screen; } polygons[i].Selected = GeometryTools.IsPointInPolygon(new MyPoint(mouseLocation.X, mouseLocation.Y), screenPoints); if (polygons[i].Selected == true) { selectedID.Add(i); } } return(selectedID); }
/// <summary> /// 唯一值渲染和分级渲染时的绘制要素 /// </summary> /// <param name="g"></param> /// <param name="bounds"></param> /// <param name="centerPos"></param> /// <param name="scale"></param> /// <param name="fid2Symbol"></param> internal override void DrawSpaceData(Graphics g, Rectangle bounds, PointF centerPos, double scale, Dictionary <int, Symbol> fid2Symbol) { //选中要素的样式 Brush selectedBrush = new SolidBrush(Color.Cyan); MyPoint xyCenter = ETCProjection.LngLat2XY(new MyPoint(centerPos.X, centerPos.Y)); double xmin = xyCenter.X - scale * bounds.Width / 2; double xmax = xyCenter.X + scale * bounds.Width / 2; double ymin = xyCenter.Y - scale * bounds.Height / 2; double ymax = xyCenter.Y + scale * bounds.Height / 2; for (int i = 0; i < myPoints.Count; i++) { //从symbol中获取样式 PointSymbol ps = (PointSymbol)fid2Symbol[myPoints[i].FID]; MyPoint xyProjection = ETCProjection.LngLat2XY(myPoints[i]); double xScreen = bounds.Width * (xyProjection.X - xmin) / (xmax - xmin); double yScreen = bounds.Height * (xyProjection.Y - ymin) / (ymax - ymin); if (GeometryTools.IsPointInBox(new MyPoint(xScreen, yScreen), new MyRectangle(bounds.X, bounds.Width, bounds.Y, bounds.Height)) == true) { if (myPoints[i].Selected == true) { Rectangle rect = new Rectangle((int)xScreen - 5, bounds.Height - (int)yScreen - 5, 10, 10); g.FillEllipse(selectedBrush, rect); } else { ps.GetSymbol(g, new PointF((float)xScreen, bounds.Height - (float)yScreen)); } } } }
/// <summary> /// 屏幕坐标系转地理坐标系 /// </summary> /// <param name="screenPos"></param> /// <returns></returns> private MyPoint ScreenToWGS84(Point screenPoint) { screenPoint.Y = picBoxMap.Height - screenPoint.Y; double centerScreenX = (double)picBoxMap.Width / 2; //屏幕坐标系中心点X坐标 double centerScreenY = (double)picBoxMap.Height / 2; //屏幕坐标系中心点Y坐标 double x = centerXY.X - (centerScreenX - screenPoint.X) * ratio * scaleChoice[scaleIndex]; //投影坐标系目标点X坐标 double y = centerXY.Y - (centerScreenY - screenPoint.Y) * ratio * scaleChoice[scaleIndex]; //投影坐标系目标点Y坐标 MyPoint xy = new MyPoint(x, y); //投影坐标系下的目标点 MyPoint lnglat = ETCProjection.XY2LngLat(xy); //WGS84坐标系下的目标点 return(lnglat); }
/// <summary> /// 判断一个多边形是否完全位于矩形盒内 /// </summary> /// <param name="polygon"></param> /// <param name="box"></param> /// <returns></returns> public static bool IsPolygonCompleteInBox(MyMultiPolygon polygon, MyRectangle box) { int sPointCount = polygon.PointCount; for (int i = 0; i < sPointCount; i++) { MyPoint pointXY = ETCProjection.LngLat2XY(polygon.Points[i]); //投影坐标系下的坐标 if (IsPointInBox(pointXY, box) == false) { return(false); } } return(true); }
/// <summary> /// 根据矩形盒选择要素,矩形盒坐标位于投影坐标系 /// </summary> /// <param name="box">矩形盒</param> internal override List <int> SelectByBox(MyRectangle box) { List <int> selectedID = new List <int>(); for (int i = 0; i < myPoints.Count; i++) { MyPoint pointXY = ETCProjection.LngLat2XY(myPoints[i]); //投影坐标系下的坐标 myPoints[i].Selected = GeometryTools.IsPointInBox(pointXY, box); if (myPoints[i].Selected == true) { selectedID.Add(i); } } return(selectedID); }
internal void FullExtent() { if (myMap.LayerNum != 0) { MyRectangle mbr = myMap.GetMBR(); centerLngLat = new PointF(((float)mbr.MaxX + (float)mbr.MinX) * 0.5F, ((float)mbr.MaxY + (float)mbr.MinY) * 0.5F); double x = ETCProjection.Longitude2X(mbr.MaxX) - ETCProjection.Longitude2X(mbr.MinX); double y = ETCProjection.Latitude2Y(mbr.MaxY) - ETCProjection.Latitude2Y(mbr.MinY); double scale1 = x / Width; double scale2 = y / Height; Ratio = Math.Max(scale1, scale2); scaleIndex = maxZoomLevel; UpdateMapImg(); } }
/// <summary> /// 唯一值渲染和分级渲染时的绘制要素 /// </summary> /// <param name="g"></param> /// <param name="bounds"></param> /// <param name="centerPos"></param> /// <param name="scale"></param> /// <param name="fid2Symbol"></param> internal override void DrawSpaceData(Graphics g, Rectangle bounds, PointF centerPos, double scale, Dictionary <int, Symbol> fid2Symbol) { //选中要素的样式 Pen selectedPen = new Pen(Color.Cyan); selectedPen.Width = 2.5F; MyPoint xyCenter = ETCProjection.LngLat2XY(new MyPoint(centerPos.X, centerPos.Y)); double xmin = xyCenter.X - scale * bounds.Width / 2; double xmax = xyCenter.X + scale * bounds.Width / 2; double ymin = xyCenter.Y - scale * bounds.Height / 2; double ymax = xyCenter.Y + scale * bounds.Height / 2; for (int i = 0; i < polylines.Count; i++) { //从symbol中获取样式 LineSymbol ls = (LineSymbol)fid2Symbol[polylines[i].FID]; Pen mypen = ls.GetPen; List <int> parts = new List <int>(polylines[i].firstIndex); parts.Add(polylines[i].PointCount); for (int k = 0; k < polylines[i].firstIndex.Length; k++) //对于每一条多线的子线段 { List <PointF> pointfs = new List <PointF>(); for (int j = parts[k]; j < parts[k + 1]; j++) { MyPoint xyProjection = ETCProjection.LngLat2XY(polylines[i].Points[j]); double xScreen = bounds.Width * (xyProjection.X - xmin) / (xmax - xmin); double yScreen = bounds.Height * (xyProjection.Y - ymin) / (ymax - ymin); PointF p = new PointF((float)xScreen, bounds.Height - (float)yScreen); pointfs.Add(p); } if (GeometryTools.IsPointsPartInRectangle(pointfs.ToArray(), new MyRectangle(bounds.X, bounds.Width, bounds.Y, bounds.Height)) == true) { if (polylines[i].Selected == false) { g.DrawLines(mypen, pointfs.ToArray()); } else { g.DrawLines(selectedPen, pointfs.ToArray()); } } } } }
/// <summary> /// 移动选中的要素 /// </summary> /// <param name="deltaX">X方向移动量,屏幕坐标系</param> /// <param name="deltaY">y方向移动量,屏幕坐标系</param> /// <param name="bounds"></param> /// <param name="centerPos"></param> /// <param name="scale"></param> internal override void MoveSelectedFeature(int deltaX, int deltaY, Rectangle bounds, PointF centerPos, double scale) { for (int i = 0; i < myPoints.Count; i++) { if (myPoints[i].Selected == true) { int id = myPoints[i].FID; MyPoint pointXY = ETCProjection.LngLat2XY(myPoints[i]); pointXY.X += scale * deltaX; pointXY.Y -= scale * deltaY; myPoints[i] = ETCProjection.XY2LngLat(pointXY); myPoints[i].FID = id; myPoints[i].Selected = true; } } SetMaxMin(); }
/// <summary> /// 移动选中的要素 /// </summary> /// <param name="deltaX">X方向移动量,屏幕坐标系</param> /// <param name="deltaY">y方向移动量,屏幕坐标系</param> /// <param name="bounds"></param> /// <param name="centerPos"></param> /// <param name="scale"></param> internal override void MoveSelectedFeature(int deltaX, int deltaY, Rectangle bounds, PointF centerPos, double scale) { for (int i = 0; i < polygons.Count; i++) { if (polygons[i].Selected == true) { for (int j = 0; j < polygons[i].PointCount; j++) { MyPoint pointXY = ETCProjection.LngLat2XY(polygons[i].Points[j]); pointXY.X += scale * deltaX; pointXY.Y -= scale * deltaY; polygons[i].Points[j] = ETCProjection.XY2LngLat(pointXY); } } } SetMaxMin(); }
/// <summary> /// 画注记 /// </summary> /// <param name="g"></param> /// <param name="bounds"></param> /// <param name="centerPos"></param> /// <param name="scale"></param> /// <param name="fid2Text"></param> internal override void DrawLabel(Graphics g, Rectangle bounds, PointF centerPos, double scale, Dictionary <int, string> fid2Text, TextSymbol textSymbol) { MyPoint xyCenter = ETCProjection.LngLat2XY(new MyPoint(centerPos.X, centerPos.Y)); double xmin = xyCenter.X - scale * bounds.Width / 2; double xmax = xyCenter.X + scale * bounds.Width / 2; double ymin = xyCenter.Y - scale * bounds.Height / 2; double ymax = xyCenter.Y + scale * bounds.Height / 2; for (int i = 0; i < myPoints.Count; i++) { string text = fid2Text[myPoints[i].FID]; MyPoint xyProjection = ETCProjection.LngLat2XY(myPoints[i]); double xScreen = bounds.Width * (xyProjection.X - xmin) / (xmax - xmin); double yScreen = bounds.Height * (xyProjection.Y - ymin) / (ymax - ymin); TextSymbol.PointLabel(new PointF((float)xScreen, bounds.Height - (float)yScreen), g, textSymbol, text); //此处注记样式不能修改。待完善 } }
/// <summary> /// 绘制栅格数据 /// </summary> /// <param name="g"></param> /// <param name="bounds"></param> /// <param name="centerPos"></param> /// <param name="scale"></param> internal void DrawSpaceData(Graphics g, Rectangle bounds, PointF centerPos, double scale) { double x1 = ETCProjection.Longitude2X(minX); double x2 = ETCProjection.Longitude2X(maxX); double y1 = ETCProjection.Latitude2Y(minY); double y2 = ETCProjection.Latitude2Y(maxY); double width = (x2 - x1) / scale; double height = (y2 - y1) / scale; PointF centerXY = ETCProjection.LngLat2XY(centerPos); float dx = (centerXY.X - (float)x1) / (float)scale; float dy = (centerXY.Y - (float)y2) / (float)scale; RectangleF boundary = new RectangleF((float)bounds.Width * 0.5F - dx, (float)bounds.Height * 0.5F + dy, (float)width, (float)height); g.DrawImage(mapBmp, boundary); }
/// <summary> /// 增加Shapefile图层 /// </summary> /// <param name="shp"></param> internal void AddLayer(Shapefile shp) { myMap.AddLayer(new MyLayer(shp)); TreeNode layerNode = new TreeNode(shp.Name, 2, 2); layerNode.Checked = true; centerLngLat = shp.CenterPos; centerXY = ETCProjection.LngLat2XY(centerLngLat); //同步更新屏幕中心点投影坐标系坐标 treeViewLayers.Nodes[0].Nodes.Insert(0, layerNode); treeViewLayers.ExpandAll(); double x = ETCProjection.Longitude2X(shp.Xmax) - ETCProjection.Longitude2X(shp.Xmin); double y = ETCProjection.Latitude2Y(shp.Ymax) - ETCProjection.Latitude2Y(shp.Ymin); double scale1 = x / Width; double scale2 = y / Height; Ratio = Math.Max(scale1, scale2); scaleIndex = maxZoomLevel; UpdateMapImg(); }
/// <summary> /// 增加栅格图层 /// </summary> /// <param name="grid"></param> internal void AddLayer(MyGrid grid) { myMap.AddLayer(new MyLayer(grid)); TreeNode layerNode = new TreeNode(grid.Name, 2, 2); layerNode.Checked = true; treeViewLayers.Nodes[0].Nodes.Insert(0, layerNode); treeViewLayers.ExpandAll(); centerLngLat = new PointF(((float)grid.MaxX + (float)grid.MinX) * 0.5F, ((float)grid.MaxY + (float)grid.MinY) * 0.5F); centerXY = ETCProjection.LngLat2XY(centerLngLat); //同步更新屏幕中心点投影坐标系坐标 double x = ETCProjection.Longitude2X(grid.MaxX) - ETCProjection.Longitude2X(grid.MinX); double y = ETCProjection.Latitude2Y(grid.MaxY) - ETCProjection.Latitude2Y(grid.MinY); double scale1 = x / Width; double scale2 = y / Height; Ratio = Math.Max(scale1, scale2); scaleIndex = maxZoomLevel; UpdateMapImg(); }
/// <summary> /// 点选选中要素的顶点 /// </summary> /// <param name="mouseLocation"></param> /// <param name="bounds"></param> /// <param name="centerPos"></param> /// <param name="scale"></param> internal override void SelectVertex(Point mouseLocation, Rectangle bounds, PointF centerPos, double scale) { MyPoint xyCenter = ETCProjection.LngLat2XY(new MyPoint(centerPos.X, centerPos.Y)); double xmin = xyCenter.X - scale * bounds.Width / 2; double xmax = xyCenter.X + scale * bounds.Width / 2; double ymin = xyCenter.Y - scale * bounds.Height / 2; double ymax = xyCenter.Y + scale * bounds.Height / 2; for (int i = 0; i < polygons.Count; i++) { if (polygons[i].Selected == true) //polylines[i]被选中 { for (int j = 0; j < polygons[i].PointCount; j++) { MyPoint xyProjection = ETCProjection.LngLat2XY(polygons[i].Points[j]); double xScreen = bounds.Width * (xyProjection.X - xmin) / (xmax - xmin); double yScreen = bounds.Height * (xyProjection.Y - ymin) / (ymax - ymin); MyPoint screen = new MyPoint(xScreen, bounds.Height - yScreen); //polygons[i].Points[j]在屏幕坐标系的位置 polygons[i].Points[j].Selected = GeometryTools.IsPointInCircle(new MyPoint(mouseLocation.X, mouseLocation.Y), screen, margin); //判断polylines[i].Points[j]是否被选中并修改Selected属性的值 } } } }
/// <summary> /// 点选 /// </summary> /// <returns>被选中要素FID的List</returns> internal override List <int> SelectByPoint(Point mouseLocation, Rectangle bounds, PointF centerPos, double scale) { List <int> selectedID = new List <int>(); MyPoint xyCenter = ETCProjection.LngLat2XY(new MyPoint(centerPos.X, centerPos.Y)); double xmin = xyCenter.X - scale * bounds.Width / 2; double xmax = xyCenter.X + scale * bounds.Width / 2; double ymin = xyCenter.Y - scale * bounds.Height / 2; double ymax = xyCenter.Y + scale * bounds.Height / 2; for (int i = 0; i < myPoints.Count; i++) { MyPoint xyProjection = ETCProjection.LngLat2XY(myPoints[i]); double xScreen = bounds.Width * (xyProjection.X - xmin) / (xmax - xmin); double yScreen = bounds.Height - bounds.Height * (xyProjection.Y - ymin) / (ymax - ymin); MyPoint screen = new MyPoint(xScreen, yScreen); myPoints[i].Selected = GeometryTools.IsPointInCircle(new MyPoint(mouseLocation.X, mouseLocation.Y), screen, margin); if (myPoints[i].Selected == true) { selectedID.Add(i); } } return(selectedID); }
/// <summary> /// 画注记 /// </summary> /// <param name="g"></param> /// <param name="bounds"></param> /// <param name="centerPos"></param> /// <param name="scale"></param> /// <param name="fid2Text"></param> internal override void DrawLabel(Graphics g, Rectangle bounds, PointF centerPos, double scale, Dictionary <int, string> fid2Text, TextSymbol textSymbol) { MyPoint xyCenter = ETCProjection.LngLat2XY(new MyPoint(centerPos.X, centerPos.Y)); double xmin = xyCenter.X - scale * bounds.Width / 2; double xmax = xyCenter.X + scale * bounds.Width / 2; double ymin = xyCenter.Y - scale * bounds.Height / 2; double ymax = xyCenter.Y + scale * bounds.Height / 2; for (int i = 0; i < polylines.Count; i++) { string text = fid2Text[polylines[i].FID]; List <PointF> pointfs = new List <PointF>(); for (int j = 0; j < polylines[i].PointCount; j++) { MyPoint xyProjection = ETCProjection.LngLat2XY(polylines[i].Points[j]); double xScreen = bounds.Width * (xyProjection.X - xmin) / (xmax - xmin); double yScreen = bounds.Height * (xyProjection.Y - ymin) / (ymax - ymin); PointF p = new PointF((float)xScreen, bounds.Height - (float)yScreen); pointfs.Add(p); } TextSymbol.LineLabel(pointfs.ToArray(), g, textSymbol, text); //此处注记样式不能修改。待完善 } }
/// <summary> /// 地图鼠标移动事件 /// </summary> private void picBoxMap_MouseMove(object sender, MouseEventArgs e) { isClick = false; switch (operationType) { case MapOperation.SelectElement: break; case MapOperation.ZoomIn: break; case MapOperation.ZoomOut: break; case MapOperation.Pan: //漫游 if (e.Button == MouseButtons.Left) { int deltaX = e.X - mouseOldLoc.X; int deltaY = e.Y - mouseOldLoc.Y; centerXY = ETCProjection.LngLat2XY(centerLngLat); centerXY.X -= deltaX * (float)ratio * (float)scaleChoice[scaleIndex]; centerXY.Y += deltaY * (float)ratio * (float)scaleChoice[scaleIndex]; //由于屏幕坐标系是左上坐标系,和地理坐标系相反,所以这里应该是+ centerLngLat = ETCProjection.XY2LngLat(centerXY); mouseOldLoc = e.Location; UpdateMapImg(); } break; case MapOperation.SelectFeatures: //选择要素 if (e.Button == MouseButtons.Left) { picBoxMap.Refresh(); int minX = Math.Min(startPoint.X, e.Location.X); int maxX = Math.Max(startPoint.X, e.Location.X); int minY = Math.Min(startPoint.Y, e.Location.Y); int maxY = Math.Max(startPoint.Y, e.Location.Y); DrawSelectBox(minX, minY, maxX - minX, maxY - minY); //画选择盒 } break; case MapOperation.Edit: //编辑要素 if (e.Button == System.Windows.Forms.MouseButtons.Left) { int deltaX = e.X - mouseOldLoc.X; int deltaY = e.Y - mouseOldLoc.Y; myMap.Layers[EditingIndex].MoveSelectedFeature(deltaX, deltaY, picBoxMap.Bounds, centerLngLat, ratio * scaleChoice[scaleIndex]); mouseOldLoc = e.Location; UpdateMapImg(); } break; case MapOperation.EditVertices: //编辑要素顶点 if (e.Button == System.Windows.Forms.MouseButtons.Left) { picBoxMap.Cursor = Cursors.SizeAll; myMap.Layers[EditingIndex].MoveVertex(ScreenToWGS84(e.Location)); UpdateMapImg(); } break; case MapOperation.CreateFeatures: //创建要素 if (trackingPoints.Count > 0) { picBoxMap.Refresh(); DrawTrackingFeature(); DrawRubberBand(e.Location); //画橡皮筋 } break; } //更新鼠标当前位置对应地理坐标 MyPoint mouseLngLat = ScreenToWGS84(e.Location); StatusStripLblCoordinate.Text = mouseLngLat.X.ToString() + "," + mouseLngLat.Y.ToString(); StatusStripLblScale.Text = MapScale.ToString(); }
/// <summary> /// 简单渲染时的绘制要素 /// </summary> /// <param name="g"></param> /// <param name="bounds"></param> /// <param name="centerPos"></param> /// <param name="scale"></param> /// <param name="symbol"></param> internal override void DrawSpaceData(Graphics g, Rectangle bounds, PointF centerPos, double scale, Symbol symbol) { //选中要素的样式 Pen selectedPen = new Pen(Color.Cyan); selectedPen.Width = 2.5F; //从symbol中获取样式 PolygonSymbol ps = (PolygonSymbol)symbol; Pen mypen = ps.LineStyle.GetPen; Brush mybrush = new SolidBrush(ps.GetColor()); MyPoint xyCenter = ETCProjection.LngLat2XY(new MyPoint(centerPos.X, centerPos.Y)); double xmin = xyCenter.X - scale * bounds.Width / 2; double xmax = xyCenter.X + scale * bounds.Width / 2; double ymin = xyCenter.Y - scale * bounds.Height / 2; double ymax = xyCenter.Y + scale * bounds.Height / 2; for (int i = 0; i < polygons.Count; i++) { List <int> parts = new List <int>(polygons[i].firstIndex); parts.Add(polygons[i].PointCount); for (int k = 0; k < polygons[i].firstIndex.Length; k++) //对于每一个MultiPolygon的子多边形 { List <PointF> pointfs = new List <PointF>(); for (int j = parts[k]; j < parts[k + 1]; j++) { MyPoint xyProjection = ETCProjection.LngLat2XY(polygons[i].Points[j]); double xScreen = bounds.Width * (xyProjection.X - xmin) / (xmax - xmin); double yScreen = bounds.Height * (xyProjection.Y - ymin) / (ymax - ymin); PointF p = new PointF((float)xScreen, bounds.Height - (float)yScreen); pointfs.Add(p); } if (GeometryTools.IsPointsPartInRectangle(pointfs.ToArray(), new MyRectangle(bounds.X, bounds.Width, bounds.Y, bounds.Height)) == true) { g.DrawPolygon(mypen, pointfs.ToArray()); g.FillPolygon(mybrush, pointfs.ToArray()); } } } for (int i = 0; i < polygons.Count; i++) { if (polygons[i].Selected == true) { List <int> parts = new List <int>(polygons[i].firstIndex); parts.Add(polygons[i].PointCount); for (int k = 0; k < polygons[i].firstIndex.Length; k++) //对于每一个MultiPolygon的子多边形 { List <PointF> pointfs = new List <PointF>(); for (int j = parts[k]; j < parts[k + 1]; j++) { MyPoint xyProjection = ETCProjection.LngLat2XY(polygons[i].Points[j]); double xScreen = bounds.Width * (xyProjection.X - xmin) / (xmax - xmin); double yScreen = bounds.Height * (xyProjection.Y - ymin) / (ymax - ymin); PointF p = new PointF((float)xScreen, bounds.Height - (float)yScreen); pointfs.Add(p); } if (GeometryTools.IsPointsPartInRectangle(pointfs.ToArray(), new MyRectangle(bounds.X, bounds.Width, bounds.Y, bounds.Height)) == true) { g.DrawPolygon(selectedPen, pointfs.ToArray()); //画选中多边形的轮廓 } } } } }