/// <summary> /// 求指定简单多边形的面积 /// </summary> /// <param name="points"></param> /// <returns></returns> internal static double GetPolygonSquare(moPoints points) { Int32 sPointCount = points.Count; double s = 0; double x0 = points.GetItem(0).X, y0 = points.GetItem(0).Y; for (Int32 i = 1; i <= sPointCount - 2; i++) { s = s + (points.GetItem(i).X - x0) * (points.GetItem(i + 1).Y - y0) - (points.GetItem(i + 1).X - x0) * (points.GetItem(i).Y - y0); } s = Math.Abs(s / 2); return(s); }
//采用简单线符号绘制简单折线 private static void DrawPolylineBySimpleLine(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, moPoints points, moSimpleLineSymbol symbol) { double sOffsetX = extent.MinX, sOffsetY = extent.MaxY; //获取投影坐标系相对屏幕坐标系的平移量 //(1)转换为屏幕坐标 GraphicsPath sGraphicPath = new GraphicsPath(); //用于屏幕绘制 Int32 sPointCount = points.Count; //顶点数目 PointF[] sScreenPoints = new PointF[sPointCount]; for (Int32 j = 0; j <= sPointCount - 1; j++) { PointF sScreenPoint = new PointF(); moPoint sCurPoint = points.GetItem(j); sScreenPoint.X = (float)((sCurPoint.X - sOffsetX) * mpu / mapScale * dpm); sScreenPoint.Y = (float)((sOffsetY - sCurPoint.Y) * mpu / mapScale * dpm); sScreenPoints[j] = sScreenPoint; } sGraphicPath.AddLines(sScreenPoints); //(2)绘制 Pen sPen = new Pen(symbol.Color, (float)(symbol.Size / 1000 * dpm)); sPen.DashStyle = (DashStyle)symbol.Style; g.DrawPath(sPen, sGraphicPath); sPen.Dispose(); }
/// <summary> /// 指示指定复合折线是否部分或完全位于指定矩形盒内 /// </summary> /// <param name="multipolyline"></param> /// <param name="box"></param> /// <returns></returns> public static bool IsMultiPolylinePartiallyWithinBox(moMultiPolyline multipolyline, moRectangle box) { //思路:先判断矩形盒是否相交,如是,按如下顺序,满足任何一个条件,则返回True //(1)复合折线任何一个点位于矩形盒内; //(2)矩形盒与复合折线有交点 moRectangle sBox = multipolyline.GetEnvelope(); if (AreBoxesCross(sBox, box) == false) { return(false); } //(1)复合折线任何一个点位于矩形盒内; Int32 sPartCount = multipolyline.Parts.Count; for (Int32 i = 0; i <= sPartCount - 1; i++) { Int32 sPointCount = multipolyline.Parts.GetItem(i).Count; for (Int32 j = 0; j <= sPointCount - 1; j++) { moPoint sCurPoint = multipolyline.Parts.GetItem(i).GetItem(j); if (IsPointWithinBox(sCurPoint, box) == true) { return(true); } } } //(2)矩形盒与复合折线有交点 for (Int32 i = 0; i <= sPartCount - 1; i++) { moPoints sPoints = multipolyline.Parts.GetItem(i); Int32 sPointCount = sPoints.Count; for (Int32 j = 0; j <= sPointCount - 2; j++) { if (IsSegmentCrossBox(sPoints.GetItem(j), sPoints.GetItem(j + 1), box) == true) { return(true); } } } //(3)都不满足,返回false return(false); }
/// <summary> /// 指示在指定容限下,指定点是否位于指定的折线上 /// </summary> /// <param name="point"></param> /// <param name="points"></param> /// <param name="tolerance"></param> /// <returns></returns> public static bool IsPointOnPolyline(moPoint point, moPoints points, double tolerance) { moRectangle sBox = new moRectangle(points.MinX - tolerance, points.MaxX + tolerance, points.MinY - tolerance, points.MaxY + tolerance); if (IsPointWithinBox(point, sBox) == false) { return(false); } Int32 sPointCount = points.Count; for (Int32 i = 0; i <= sPointCount - 2; i++) { if (GetDistanceFromPointToSegment(point.X, point.Y, points.GetItem(i).X, points.GetItem(i).Y, points.GetItem(i + 1).X, points.GetItem(i + 1).Y) <= tolerance) { return(true); } } return(false); }
/// <summary> /// 求一条水平向右的射线与一个多边形的交点个数 /// </summary> /// <param name="point"></param> /// <param name="polygon"></param> /// <returns></returns> internal static Int32 GetIntersectionCountBetweenRayAndPolygon(moPoint point, moPoints points) { Int32 sIntersectionCount = 0; Int32 sPointCount = points.Count; if (IsRayCrossSegment(point, points.GetItem(sPointCount - 1), points.GetItem(0)) == true) { //起点与最后一点的连线与射线有交点 sIntersectionCount = sIntersectionCount + 1; } //求射线与其他边的交点 for (Int32 i = 0; i <= sPointCount - 2; i++) { if (IsRayCrossSegment(point, points.GetItem(i), points.GetItem(i + 1)) == true) { sIntersectionCount = sIntersectionCount + 1; } } return(sIntersectionCount); }
/// <summary> /// 获取指定折线的中点 /// </summary> /// <param name="points"></param> /// <returns></returns> public static moPoint GetMidPointOfPolyline(moPoints points) { Int32 sPointCount = points.Count; List <double> sDises = new List <double>(); //所有顶点至起点的距离 sDises.Add(0); //第一个点至起点的距离 for (Int32 i = 1; i <= sPointCount - 1; i++) { double sCurDis = sDises.Last() + GetDistance(points.GetItem(i).X, points.GetItem(i).Y, points.GetItem(i - 1).X, points.GetItem(i - 1).Y); sDises.Add(sCurDis); } //查找中点所在的线段索引号 Int32 sIndex = 0; double sMidDis = sDises.Last() / 2; //中点与起点的距离 for (Int32 i = 0; i <= sPointCount - 2; i++) { if (sMidDis >= sDises[i] && sMidDis < sDises[i + 1]) { sIndex = i; break; } } //计算中点 double x1 = points.GetItem(sIndex).X, y1 = points.GetItem(sIndex).Y; double x2 = points.GetItem(sIndex + 1).X, y2 = points.GetItem(sIndex + 1).Y; double sSegDis = GetDistance(x1, y1, x2, y2); double x = x1 + (x2 - x1) * (sMidDis - sDises[sIndex]) / sSegDis; double y = y1 + (y2 - y1) * (sMidDis - sDises[sIndex]) / sSegDis; moPoint sMidPoint = new moPoint(x, y); return(sMidPoint); }
//绘制点集合(多点) internal static void DrawPoints(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, moPoints points, moSymbol symbol) { if (symbol.SymbolType == moSymbolTypeConstant.SimpleMarkerSymbol) { moSimpleMarkerSymbol sSymbol = (moSimpleMarkerSymbol)symbol; if (sSymbol.Visible == true) { Int32 sPointCount = points.Count; for (Int32 i = 0; i <= sPointCount - 1; i++) { moPoint sPoint = points.GetItem(i); DrawPointBySimpleMarker(g, extent, mapScale, dpm, mpu, sPoint, sSymbol); } } } }
//采用简单填充符号绘制简单多边形 private static void DrawPolygonBySimpleFill(Graphics g, moRectangle extent, double mapScale, double dpm, double mpu, moPoints points, moSimpleFillSymbol symbol) { double sOffsetX = extent.MinX, sOffsetY = extent.MaxY; //获取投影坐标系相对屏幕坐标系的平移量 //(1)转换为屏幕坐标 GraphicsPath sGraphicPath = new GraphicsPath(); //用于屏幕绘制 Int32 sPointCount = points.Count; //顶点数目 PointF[] sScreenPoints = new PointF[sPointCount]; for (Int32 j = 0; j <= sPointCount - 1; j++) { PointF sScreenPoint = new PointF(); moPoint sCurPoint = points.GetItem(j); sScreenPoint.X = (float)((sCurPoint.X - sOffsetX) * mpu / mapScale * dpm); sScreenPoint.Y = (float)((sOffsetY - sCurPoint.Y) * mpu / mapScale * dpm); sScreenPoints[j] = sScreenPoint; } sGraphicPath.AddPolygon(sScreenPoints); //(2)填充 SolidBrush sBrush = new SolidBrush(symbol.Color); g.FillPath(sBrush, sGraphicPath); sBrush.Dispose(); //(3)绘制边界 if (symbol.Outline.SymbolType == moSymbolTypeConstant.SimpleLineSymbol) { moSimpleLineSymbol sOutline = symbol.Outline; if (sOutline.Visible == true) { Pen sPen = new Pen(sOutline.Color, (float)(sOutline.Size / 1000 * dpm)); sPen.DashStyle = (DashStyle)sOutline.Style; g.DrawPath(sPen, sGraphicPath); sPen.Dispose(); } } }
/// <summary> /// 指示指定复合多边形是否部分或完全位于指定矩形盒内 /// </summary> /// <param name="multipolygon"></param> /// <param name="box"></param> /// <returns></returns> public static bool IsMultiPolygonPartiallyWithinBox(moMultiPolygon multipolygon, moRectangle box) { //思路:先判断矩形盒是否相交,如是,按如下顺序,满足任何一个条件,则返回True //(1)复合多边形任何一个点位于矩形盒内; //(2)矩形盒任何一个顶点位于复合多边形内 //(3)矩形盒与复合多边形有交点 moRectangle sBox = multipolygon.GetEnvelope(); if (AreBoxesCross(sBox, box) == false) { return(false); } //(1)多边形任何一个点位于矩形盒内 Int32 sPartCount = multipolygon.Parts.Count; for (Int32 i = 0; i <= sPartCount - 1; i++) { Int32 sPointCount = multipolygon.Parts.GetItem(i).Count; for (Int32 j = 0; j <= sPointCount - 1; j++) { moPoint sCurPoint = multipolygon.Parts.GetItem(i).GetItem(j); if (IsPointWithinBox(sCurPoint, box) == true) { return(true); } } } //(2)矩形盒任何一个顶点位于多边形内 moPoint sRectPoint = new moPoint(box.MinX, box.MinY); //左下点 if (IsPointWithinMultiPolygon(sRectPoint, multipolygon) == true) { return(true); } sRectPoint = new moPoint(box.MinX, box.MaxY); //左上点 if (IsPointWithinMultiPolygon(sRectPoint, multipolygon) == true) { return(true); } sRectPoint = new moPoint(box.MaxX, box.MaxY); //右上点 if (IsPointWithinMultiPolygon(sRectPoint, multipolygon) == true) { return(true); } sRectPoint = new moPoint(box.MaxX, box.MinY); //右下点 if (IsPointWithinMultiPolygon(sRectPoint, multipolygon) == true) { return(true); } //(3)矩形盒与复合多边形有交点 for (Int32 i = 0; i <= sPartCount - 1; i++) { moPoints sPoints = multipolygon.Parts.GetItem(i); Int32 sPointCount = sPoints.Count; for (Int32 j = 0; j <= sPointCount - 2; j++) { if (IsSegmentCrossBox(sPoints.GetItem(j), sPoints.GetItem(j + 1), box) == true) { return(true); } } if (IsSegmentCrossBox(sPoints.GetItem(sPointCount - 1), sPoints.GetItem(0), box) == true) { return(true); } } //(4)都不满足,返回false return(false); }
/// <summary> /// 获取指定扫描线与指定多边形的交点的X坐标序列 /// </summary> /// <param name="scanY"></param> /// <param name="points"></param> /// <returns></returns> internal static List <double> GetIntersectionsBetweenScanAndPolygon(double scanY, moPoints points) { Int32 sPointCount = points.Count; List <double> sIntersections = new List <double>(); //交点X坐标序列 if (IsScanCrossSegment(scanY, points.GetItem(sPointCount - 1), points.GetItem(0)) == true) { //起点与最后一点的连线与扫描线有交点 double x1 = points.GetItem(sPointCount - 1).X, y1 = points.GetItem(sPointCount - 1).Y; double x2 = points.GetItem(0).X, y2 = points.GetItem(0).Y; double x = x1 + (x2 - x1) * (scanY - y1) / (y2 - y1); sIntersections.Add(x); } //求扫描线与其他边的交点 for (Int32 i = 0; i <= sPointCount - 2; i++) { if (IsScanCrossSegment(scanY, points.GetItem(i), points.GetItem(i + 1)) == true) { double x1 = points.GetItem(i).X, y1 = points.GetItem(i).Y; double x2 = points.GetItem(i + 1).X, y2 = points.GetItem(i + 1).Y; double x = x1 + (x2 - x1) * (scanY - y1) / (y2 - y1); sIntersections.Add(x); } } return(sIntersections); }