Exemple #1
0
        /// <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();
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
        /// <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);
        }
Exemple #6
0
        /// <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();
                }
            }
        }
Exemple #9
0
        /// <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);
        }
Exemple #10
0
        /// <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);
        }