栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

GMap.net 地图标绘实现(四):箭头

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

GMap.net 地图标绘实现(四):箭头

  • DoubleArrow:钳击
    /// 
    /// 钳击
    /// 
    public class DoubleArrow : GMapPolygon, IPlot
    {
        protected string geo_type = string.Empty;
        protected PointLatLng[] points;

        private PlotTypes type;
        private double headHeightFactor = 0.0;
        private double headWidthFactor = 0.0;
        private double neckHeightFactor = 0.15;
        private double neckWidthFactor = 0.15;
        private PointLatLng connPoint;
        private PointLatLng tempPoint4;
        private int fixPointCount = 0;

        public DoubleArrow(PointLatLng[] points,string name= "DoubleArrow")
            : base(points.ToList(), name)
        {
            this.points = points;
            this.geo_type = "RootTest";

            this.type = PlotTypes.DOUBLE_ARROW;
            this.headHeightFactor = 0.25;
            this.headWidthFactor = 0.3;
            this.neckHeightFactor = 0.85;
            this.neckWidthFactor = 0.15;
            this.connPoint = PointLatLng.Empty;
            this.tempPoint4 = PointLatLng.Empty; ;
            this.fixPointCount = 4;
            this.SetPoints(points);
        }
        public void FinishDrawing()
        {
            List pointList = points.ToList();
            if (this.GetPointCount() == 3 && this.tempPoint4 != null)
                pointList.Add(this.tempPoint4);
            if (this.connPoint != null)
                pointList.Add(this.connPoint);
            this.points = pointList.ToArray();
        }

        public void Generate()
        {
            var count = this.GetPointCount();
            if (count < 2)
            {
                return;
            }
            if (count == 2)
            {
                this.Points.Clear();
                var temp=GeometryUtil.ConvertCoordinates(points.ToList(), ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);
                this.Points.AddRange(temp);
                return;
            }
            var pnt1 = this.points[0];
            var pnt2 = this.points[1];
            var pnt3 = this.points[2];
            count = this.GetPointCount();
            if (count == 3)
                this.tempPoint4 = this.GetTempPoint4(pnt1, pnt2, pnt3);
            else
                this.tempPoint4 = this.points[3];
            if (count == 3 || count == 4)
                this.connPoint = PlotUtil.Mid(pnt1, pnt2);
            else
                this.connPoint = this.points[4];
            PointLatLng[] leftArrowPnts;
            PointLatLng[] rightArrowPnts;
            if (PlotUtil.IsClockWise(pnt1, pnt2, pnt3))
            {
                leftArrowPnts = this.GetArrowPoints(pnt1, this.connPoint, this.tempPoint4, false);
                rightArrowPnts = this.GetArrowPoints(this.connPoint, pnt2, pnt3, true);
            }
            else
            {
                leftArrowPnts = this.GetArrowPoints(pnt2, this.connPoint, pnt3, false);
                rightArrowPnts = this.GetArrowPoints(this.connPoint, pnt1, this.tempPoint4, true);
            }
            var m = leftArrowPnts.Length;
            var t = (m - 5) / 2;

            var llBodyPnts = leftArrowPnts.Take(t).ToArray();
            var lArrowPnts = leftArrowPnts.Skip(t).Take(5).ToArray();
            var lrBodyPnts = leftArrowPnts.Skip(t + 5).Take(m - (t + 5)).ToArray();

            var rlBodyPnts = rightArrowPnts.Take(t).ToArray();
            var rArrowPnts = rightArrowPnts.Skip(t).Take(5).ToArray();
            var rrBodyPnts = rightArrowPnts.Skip(t + 5).Take(m - (t + 5)).ToArray();

            rlBodyPnts = PlotUtil.GetBezierPoints(rlBodyPnts).ToArray();
            var bodyPnts = PlotUtil.GetBezierPoints(rrBodyPnts.Concat(llBodyPnts.Skip(1)).ToArray());
            lrBodyPnts = PlotUtil.GetBezierPoints(lrBodyPnts).ToArray();

            var pnts = rlBodyPnts.Concat(rArrowPnts.Concat(bodyPnts).Concat(lArrowPnts).Concat(lrBodyPnts).ToArray());
            var temps = GeometryUtil.ConvertCoordinates(pnts.ToList(), ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);
            this.Points.Clear();
            this.Points.AddRange(temps);
        }

        private PointLatLng[] GetArrowPoints(PointLatLng pnt1, PointLatLng pnt2, PointLatLng pnt3, bool clockWise)
        {
            var midPnt = PlotUtil.Mid(pnt1, pnt2);
            var len = PlotUtil.Distance(midPnt, pnt3);
            var midPnt1 = PlotUtil.GetThirdPoint(pnt3, midPnt, 0, len * 0.3, true);
            var midPnt2 = PlotUtil.GetThirdPoint(pnt3, midPnt, 0, len * 0.5, true);
            //var midPnt3=PlotUtils.getThirdPoint(pnt3, midPnt, 0, len * 0.7, true);
            midPnt1 = PlotUtil.GetThirdPoint(midPnt, midPnt1, Constants.HALF_PI, len / 5, clockWise);
            midPnt2 = PlotUtil.GetThirdPoint(midPnt, midPnt2, Constants.HALF_PI, len / 4, clockWise);
            //midPnt3=PlotUtils.getThirdPoint(midPnt, midPnt3, Constants.HALF_PI, len / 5, clockWise);

            var points = new PointLatLng[] { midPnt, midPnt1, midPnt2, pnt3 };
            // 计算箭头部分
            var arrowPnts = this.GetArrowHeadPoints(points, this.headHeightFactor, this.headWidthFactor, this.neckHeightFactor, this.neckWidthFactor);
            var neckLeftPoint = arrowPnts[0];
            var neckRightPoint = arrowPnts[4];
            // 计算箭身部分
            var tailWidthFactor = PlotUtil.Distance(pnt1, pnt2) / PlotUtil.GetBaseLength(points.ToList()) / 2;
            var bodyPnts = this.GetArrowBodyPoints(points, neckLeftPoint, neckRightPoint, tailWidthFactor).ToArray();
            var n = bodyPnts.Length;
            var lPoints = bodyPnts.Take(n / 2).ToList();
            var rPoints = bodyPnts.Skip(n / 2).Take(n).ToList();
            lPoints.Add(neckLeftPoint);
            rPoints.Add(neckRightPoint);
            lPoints.Reverse();
            lPoints.Add(pnt2);
            rPoints.Reverse();
            rPoints.Add(pnt1);
            lPoints.Reverse();
            return lPoints.Concat(arrowPnts).Concat(rPoints).ToArray();
        }

        private PointLatLng[] GetArrowBodyPoints(PointLatLng[] points, PointLatLng neckLeft, PointLatLng neckRight, double tailWidthFactor)
        {
            var allLen = PlotUtil.WholeDistance(points.ToList());
            var len = PlotUtil.GetBaseLength(points.ToList());
            var tailWidth = len * tailWidthFactor;
            var neckWidth = PlotUtil.Distance(neckLeft, neckRight);
            var widthDif = (tailWidth - neckWidth) / 2;
            double tempLen = 0.0;
            List leftBodyPnts = new List();
            List rightBodyPnts = new List();
            for (var i = 1; i < points.Length - 1; i++)
            {
                var angle = PlotUtil.GetAngleOfThreePoints(points[i - 1], points[i], points[i + 1]) / 2;
                tempLen += PlotUtil.Distance(points[i - 1], points[i]);
                var w = (tailWidth / 2 - tempLen / allLen * widthDif) / Math.Sin(angle);
                var left = PlotUtil.GetThirdPoint(points[i - 1], points[i], Math.PI - angle, w, true);
                var right = PlotUtil.GetThirdPoint(points[i - 1], points[i], angle, w, false);
                leftBodyPnts.Add(left);
                rightBodyPnts.Add(right);
            }
            return leftBodyPnts.Concat(rightBodyPnts).ToArray();
        }

        private PointLatLng[] GetArrowHeadPoints(PointLatLng[] points, double headHeightFactor, double headWidthFactor, double neckHeightFactor, double neckWidthFactor)
        {
            var len = PlotUtil.GetBaseLength(points.ToList());
            var headHeight = len * headHeightFactor;
            var headPnt = points[points.Length - 1];
            //var tailWidth = PlotUtil.Distance(tailLeft, tailRight);
            var headWidth = headHeight * headWidthFactor;
            var neckWidth = headHeight * neckWidthFactor;
            var neckHeight = headHeight * neckHeightFactor;
            var headEndPnt = PlotUtil.GetThirdPoint(points[points.Length - 2], headPnt, 0, headHeight, true);
            var neckEndPnt = PlotUtil.GetThirdPoint(points[points.Length - 2], headPnt, 0, neckHeight, true);
            var headLeft = PlotUtil.GetThirdPoint(headPnt, headEndPnt, Constants.HALF_PI, headWidth, false);
            var headRight = PlotUtil.GetThirdPoint(headPnt, headEndPnt, Constants.HALF_PI, headWidth, true);
            var neckLeft = PlotUtil.GetThirdPoint(headPnt, neckEndPnt, Constants.HALF_PI, neckWidth, false);
            var neckRight = PlotUtil.GetThirdPoint(headPnt, neckEndPnt, Constants.HALF_PI, neckWidth, true);
            return new PointLatLng[] { neckLeft, headLeft, headPnt, headRight, neckRight };
        }

        private PointLatLng GetTempPoint4(PointLatLng linePnt1, PointLatLng linePnt2, PointLatLng point)
        {
            var midPnt = PlotUtil.Mid(linePnt1, linePnt2);
            var len = PlotUtil.Distance(midPnt, point);
            var angle = PlotUtil.GetAngleOfThreePoints(linePnt1, midPnt, point);
            PointLatLng symPnt;
            double distance1;
            double distance2;
            PointLatLng mid;
            if (angle < Constants.HALF_PI)
            {
                distance1 = len * Math.Sin(angle);
                distance2 = len * Math.Cos(angle);
                mid = PlotUtil.GetThirdPoint(linePnt1, midPnt, Constants.HALF_PI, distance1, false);
                symPnt = PlotUtil.GetThirdPoint(midPnt, mid, Constants.HALF_PI, distance2, true);
            }
            else if (angle >= Constants.HALF_PI && angle < Math.PI)
            {
                distance1 = len * Math.Sin(Math.PI - angle);
                distance2 = len * Math.Cos(Math.PI - angle);
                mid = PlotUtil.GetThirdPoint(linePnt1, midPnt, Constants.HALF_PI, distance1, false);
                symPnt = PlotUtil.GetThirdPoint(midPnt, mid, Constants.HALF_PI, distance2, false);
            }
            else if (angle >= Math.PI && angle < Math.PI * 1.5)
            {
                distance1 = len * Math.Sin(angle - Math.PI);
                distance2 = len * Math.Cos(angle - Math.PI);
                mid = PlotUtil.GetThirdPoint(linePnt1, midPnt, Constants.HALF_PI, distance1, true);
                symPnt = PlotUtil.GetThirdPoint(midPnt, mid, Constants.HALF_PI, distance2, true);
            }
            else
            {
                distance1 = len * Math.Sin(Math.PI * 2 - angle);
                distance2 = len * Math.Cos(Math.PI * 2 - angle);
                mid = PlotUtil.GetThirdPoint(linePnt1, midPnt, Constants.HALF_PI, distance1, true);
                symPnt = PlotUtil.GetThirdPoint(midPnt, mid, Constants.HALF_PI, distance2, false);
            }
            return symPnt;
        }

        public int GetPointCount()
        {
            return this.points.Length;
        }

        public PointLatLng[] GetPoints()
        {
            return this.points;
        }

        public bool IsPlot()
        {
            return true;
        }

        public void SetPoints(PointLatLng[] value)
        {
            //将经纬度坐标转为投影坐标参与计算
            if (value != null)
                value = GeometryUtil.WGS84ToWebMercator2(value.ToList()).ToArray();
            this.points = (value != null) ? value : new PointLatLng[] { };
            if (this.points.Length >= 1)
                this.Generate();
        }

        public void UpdateLastPoint(PointLatLng point)
        {
            this.UpdatePoint(point, this.points.Length - 1);
        }

        public void UpdatePoint(PointLatLng point, int index)
        {
            if (index >= 0 && index < this.points.Length)
            {
                this.points[index] = point;
                this.Generate();
            }
        }
    }
  • StraightArrow:直箭头 
    /// 
    /// 直箭头
    /// 
    public class StraightArrow : GMapRoute,IPlot
    {
        protected string geo_type = string.Empty;
        protected PointLatLng[] points;

        private PlotTypes type;
        private int fixPointCount = 0;
        private double maxArrowLength = 0.0;
        private int arrowLengthScale=5;


        public StraightArrow(PointLatLng[] points,string name= "StraightArrow")
            :base(points.ToList(), name)
        {
            this.points = points;
            this.geo_type = "RootTest";

            this.type = PlotTypes.STRAIGHT_ARROW;
            this.fixPointCount = 2;
            this.maxArrowLength = 3000000;
            this.arrowLengthScale = 5;
            this.SetPoints(points);
        }
        public void FinishDrawing()
        {
            
        }

        public void Generate()
        {
            if (this.GetPointCount() < 2)
            {
                return;
            }
            var pnts = this.GetPoints();
            var pnt1 = pnts[0];
            var pnt2 = pnts[1];
            var distance = PlotUtil.Distance(pnt1, pnt2);
            var len = distance / this.arrowLengthScale;
            len = len > this.maxArrowLength ? this.maxArrowLength : len;
            var leftPnt = PlotUtil.GetThirdPoint(pnt1, pnt2, Math.PI / 6, len, false);
            var rightPnt = PlotUtil.GetThirdPoint(pnt1, pnt2, Math.PI / 6, len, true);
            List tempPoints = new PointLatLng[] { pnt1, pnt2, leftPnt, pnt2, rightPnt }.ToList();
            var temps = GeometryUtil.ConvertCoordinates(tempPoints, ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);
            this.Points.Clear();

            this.Points.AddRange(temps);
        }

        public int GetPointCount()
        {
            return this.points.Length;
        }

        public PointLatLng[] GetPoints()
        {
            return this.points;
        }

        public bool IsPlot()
        {
            return true;
        }

        public void SetPoints(PointLatLng[] value)
        {
            //将经纬度坐标转为投影坐标参与计算
            if (value != null)
                value = GeometryUtil.WGS84ToWebMercator2(value.ToList()).ToArray();
            this.points = (value != null) ? value : new PointLatLng[] { };
            if (this.points.Length >= 1)
                this.Generate();
        }

        public void UpdateLastPoint(PointLatLng point)
        {
            this.UpdatePoint(point, this.points.Length - 1);
        }

        public void UpdatePoint(PointLatLng point, int index)
        {
            if (index >= 0 && index < this.points.Length)
            {
                this.points[index] = point;
                this.Generate();
            }
        }
    }
  •  FineArrow:细直箭头
    /// 
    /// 细直箭头
    /// 
    public class FineArrow : GMapPolygon, IPlot
    {
        protected string geo_type = string.Empty;
        protected PointLatLng[] points;

        protected PlotTypes type = PlotTypes.FINE_ARROW;
        protected double tailWidthFactor = 0.15;
        protected double neckWidthFactor = 0.2;
        protected double headWidthFactor = 0.25;
        protected double headAngle = Math.PI / 8.5;
        protected double neckAngle = Math.PI / 13;
        private int fixPointCount = 2;

        public FineArrow(PointLatLng[] points):
            base(points.ToList(), "FineArrow")
        {
            this.points = points;
            this.geo_type = "RootTest";

            this.type = PlotTypes.FINE_ARROW;
            this.tailWidthFactor = 0.15;
            this.neckWidthFactor = 0.2;
            this.headWidthFactor = 0.25;
            this.headAngle = Math.PI / 8.5;
            this.neckAngle = Math.PI / 13;
            this.fixPointCount = 2;
            this.SetPoints(points);
        }

        public void FinishDrawing()
        {
            
        }

        public void Generate()
        {
            var count = this.GetPointCount();
            if (count < 2)
            {
                return;
            }
            var pnts = this.GetPoints();
            var pnt1 = pnts[0];
            var pnt2 = pnts[1];
            var len = PlotUtil.GetBaseLength(pnts.ToList());
            var tailWidth = len * this.tailWidthFactor;
            var neckWidth = len * this.neckWidthFactor;
            var headWidth = len * this.headWidthFactor;
            var tailLeft = PlotUtil.GetThirdPoint(pnt2, pnt1, Constants.HALF_PI, tailWidth, true);
            var tailRight = PlotUtil.GetThirdPoint(pnt2, pnt1, Constants.HALF_PI, tailWidth, false);
            var headLeft = PlotUtil.GetThirdPoint(pnt1, pnt2, this.headAngle, headWidth, false);
            var headRight = PlotUtil.GetThirdPoint(pnt1, pnt2, this.headAngle, headWidth, true);
            var neckLeft = PlotUtil.GetThirdPoint(pnt1, pnt2, this.neckAngle, neckWidth, false);
            var neckRight = PlotUtil.GetThirdPoint(pnt1, pnt2, this.neckAngle, neckWidth, true);
            var pList = new PointLatLng[]{ tailLeft, neckLeft, headLeft, pnt2, headRight, neckRight, tailRight };

            var temps = GeometryUtil.ConvertCoordinates(pList.ToList(), ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);
            this.Points.Clear();
            this.Points.AddRange(temps);
        }

        public int GetPointCount()
        {
            return this.points.Length;
        }

        public PointLatLng[] GetPoints()
        {
            return this.points;
        }

        public bool IsPlot()
        {
            return true;
        }

        public void SetPoints(PointLatLng[] value)
        {
            //将经纬度坐标转为投影坐标参与计算
            if (value != null)
                value = GeometryUtil.WGS84ToWebMercator2(value.ToList()).ToArray();
            this.points = (value != null) ? value : new PointLatLng[] { };
            if (this.points.Length >= 1)
                this.Generate();
        }

        public void UpdateLastPoint(PointLatLng point)
        {
            this.UpdatePoint(point, this.points.Length - 1);
        }

        public void UpdatePoint(PointLatLng point, int index)
        {
            if (index >= 0 && index < this.points.Length)
            {
                this.points[index] = point;
                this.Generate();
            }
        }
    }
  • AssaultDirection:突击方向

 

    /// 
    /// 突击方向
    /// 
    public class AssaultDirection:FineArrow
    {
        public AssaultDirection(PointLatLng[] points)
            :base(points)
        {
            this.type = PlotTypes.ASSAULT_DIRECTION;
            this.tailWidthFactor = 0.2;
            this.neckWidthFactor = 0.25;
            this.headWidthFactor = 0.3;
            this.headAngle = Math.PI / 4;
            this.neckAngle = Math.PI * 0.17741;
            this.SetPoints(points);
        }
    }
  •  AttackArrow:进攻方向

 

    /// 
    /// 进攻方向
    /// 
    public class AttackArrow : GMapPolygon, IPlot
    {
        protected string geo_type = string.Empty;
        protected PointLatLng[] points;

        protected PlotTypes type = PlotTypes.ATTACK_ARROW;
        protected double headHeightFactor = 0.18;
        protected double headWidthFactor = 0.3;
        protected double neckHeightFactor = 0.85;
        protected double neckWidthFactor = 0.15;
        protected double headTailFactor = 0.8;

        public AttackArrow(PointLatLng[] points,string name= "AttackArrow")
            :base(points.ToList(), name)
        {
            this.points = points;
            this.geo_type = "RootTest";

            this.type = PlotTypes.ATTACK_ARROW;
            this.headHeightFactor = 0.18;
            this.headWidthFactor = 0.3;
            this.neckHeightFactor = 0.85;
            this.neckWidthFactor = 0.15;
            this.headTailFactor = 0.8;
            this.SetPoints(points);
        }
        public void FinishDrawing()
        {
            
        }

        public virtual void Generate()
        {
            if (this.GetPointCount() < 2)
            {
                return;
            }
            if (this.GetPointCount() == 2)
            {
                var temp = GeometryUtil.ConvertCoordinates(this.points.ToList(), ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);
                this.Points.Clear();
                this.Points.AddRange(temp);
                return;
            }
            var pnts = this.GetPoints();
            // 计算箭尾
            var tailLeft = pnts[0];
            var tailRight = pnts[1];
            if (PlotUtil.IsClockWise(pnts[0], pnts[1], pnts[2]))
            {
                tailLeft = pnts[1];
                tailRight = pnts[0];
            }
            var midTail = PlotUtil.Mid(tailLeft, tailRight);
            var bonePnts = new PointLatLng[] { midTail }.Concat(pnts.Skip(2)).ToArray();
            // 计算箭头
            var headPnts = this.GetArrowHeadPoints(bonePnts, tailLeft, tailRight);
            var neckLeft = headPnts[0];
            var neckRight = headPnts[4];
            var tailWidthFactor = PlotUtil.Distance(tailLeft, tailRight) / PlotUtil.GetBaseLength(bonePnts.ToList());
            // 计算箭身
            var bodyPnts = this.GetArrowBodyPoints(bonePnts, neckLeft, neckRight, tailWidthFactor);
            // 整合
            var count = bodyPnts.Length;
            var leftPnts = new PointLatLng[] { tailLeft }.Concat(bodyPnts.Take(count / 2)).ToList();
            leftPnts.RemoveAt(1);
            leftPnts.Add(neckLeft);
            var rightPnts = new PointLatLng[] { tailRight }.Concat(bodyPnts.Skip(count / 2).Take(bodyPnts.Length)).ToList();
            rightPnts.RemoveAt(1);
            rightPnts.Add(neckRight);

            leftPnts = PlotUtil.GetQBSplinePoints(leftPnts.ToArray());
            rightPnts = PlotUtil.GetQBSplinePoints(rightPnts.ToArray());

            //右侧曲线节点反转
            rightPnts.Reverse();

            List tempPoints = leftPnts.ToArray().Concat(headPnts).Concat(rightPnts).ToList();
            var temps = GeometryUtil.ConvertCoordinates(tempPoints, ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);
            this.Points.Clear();
            this.Points.AddRange(temps);
        }

        protected PointLatLng[] GetArrowHeadPoints(PointLatLng[] points, PointLatLng tailLeft, PointLatLng tailRight)
        {
            var len = PlotUtil.GetBaseLength(points.ToList());
            var headHeight = len * this.headHeightFactor;
            var headPnt = points[points.Length - 1];
            len = PlotUtil.Distance(headPnt, points[points.Length - 2]);
            var tailWidth = PlotUtil.Distance(tailLeft, tailRight);
            if (headHeight > tailWidth * this.headTailFactor)
            {
                headHeight = tailWidth * this.headTailFactor;
            }
            var headWidth = headHeight * this.headWidthFactor;
            var neckWidth = headHeight * this.neckWidthFactor;
            headHeight = headHeight > len ? len : headHeight;
            var neckHeight = headHeight * this.neckHeightFactor;
            var headEndPnt = PlotUtil.GetThirdPoint(points[points.Length - 2], headPnt, 0, headHeight, true);
            var neckEndPnt = PlotUtil.GetThirdPoint(points[points.Length - 2], headPnt, 0, neckHeight, true);
            var headLeft = PlotUtil.GetThirdPoint(headPnt, headEndPnt, Constants.HALF_PI, headWidth, false);
            var headRight = PlotUtil.GetThirdPoint(headPnt, headEndPnt, Constants.HALF_PI, headWidth, true);
            var neckLeft = PlotUtil.GetThirdPoint(headPnt, neckEndPnt, Constants.HALF_PI, neckWidth, false);
            var neckRight = PlotUtil.GetThirdPoint(headPnt, neckEndPnt, Constants.HALF_PI, neckWidth, true);
            return new PointLatLng[] { neckLeft, headLeft, headPnt, headRight, neckRight };
        }

        protected PointLatLng[] GetArrowBodyPoints(PointLatLng[] bonePnts, PointLatLng neckLeft, PointLatLng neckRight, double tailWidthFactor)
        {
            var allLen = PlotUtil.WholeDistance(points.ToList());
            var len = PlotUtil.GetBaseLength(points.ToList());
            var tailWidth = len * tailWidthFactor;
            var neckWidth = PlotUtil.Distance(neckLeft, neckRight);
            var widthDif = (tailWidth - neckWidth) / 2;
            var tempLen = 0.0;
            List leftBodyPnts = new List();
            List  rightBodyPnts = new List();
            for (int i = 1; i < points.Length - 1; i++)
            {
                var angle = PlotUtil.GetAngleOfThreePoints(points[i - 1], points[i], points[i + 1]) / 2;
                tempLen += PlotUtil.Distance(points[i - 1], points[i]);
                var w = (tailWidth / 2 - tempLen / allLen * widthDif) / Math.Sin(angle);
                var left = PlotUtil.GetThirdPoint(points[i - 1], points[i], Math.PI - angle, w, true);
                var right = PlotUtil.GetThirdPoint(points[i - 1], points[i], angle, w, false);
                leftBodyPnts.Add(left);
                rightBodyPnts.Add(right);
            }
            return leftBodyPnts.Concat(rightBodyPnts).ToArray();
        }


        public int GetPointCount()
        {
            return points.Length;
        }

        public PointLatLng[] GetPoints()
        {
            return this.points;
        }

        public bool IsPlot()
        {
            return true;
        }

        public void SetPoints(PointLatLng[] value)
        {
            //将经纬度坐标转为投影坐标参与计算
            if (value != null)
                value = GeometryUtil.WGS84ToWebMercator2(value.ToList()).ToArray();
            this.points = (value != null) ? value : new PointLatLng[] { };
            if (this.points.Length >= 1)
                this.Generate();
        }

        public void UpdateLastPoint(PointLatLng point)
        {
            this.UpdatePoint(point, this.points.Length - 1);
        }

        public void UpdatePoint(PointLatLng point, int index)
        {
            if (index >= 0 && index < this.points.Length)
            {
                this.points[index] = point;
                this.Generate();
            }
        }
    }
  • TailedAttackArrow:进攻方向(尾)

 

    /// 
    /// 进攻箭头(尾)
    /// 
    public class TailedAttackArrow:AttackArrow
    {
        private double tailWidthFactor = 0.1;
        private double swallowTailFactor = 1;
        private PointLatLng swallowTailPnt;

        public TailedAttackArrow(PointLatLng[] points,string name= "TailedAttackArrow")
            :base(points,name)
        {
            this.points = points;
            this.geo_type = "RootTest";

            this.type = PlotTypes.TAILED_ATTACK_ARROW;
            this.headHeightFactor = 0.18;
            this.headWidthFactor = 0.3;
            this.neckHeightFactor = 0.85;
            this.neckWidthFactor = 0.15;
            this.tailWidthFactor = 0.1;
            this.headTailFactor = 0.8;
            this.swallowTailFactor = 1;
            this.swallowTailPnt = PointLatLng.Empty; ;
            this.SetPoints(points);
        }

        public override void Generate()
        {
            var count = this.GetPointCount();
            if (count < 2)
            {
                return;
            }
            if (this.GetPointCount() == 2)
            {
                this.Points.Clear();
                var temp = GeometryUtil.ConvertCoordinates(this.points.ToList(), ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);
                this.Points.AddRange(temp);
                return;
            }
            var pnts = this.GetPoints();
            var tailLeft = pnts[0];
            var tailRight = pnts[1];
            if (PlotUtil.IsClockWise(pnts[0], pnts[1], pnts[2]))
            {
                tailLeft = pnts[1];
                tailRight = pnts[0];
            }
            var midTail = PlotUtil.Mid(tailLeft, tailRight);
            var bonePnts = new PointLatLng[] { midTail }.Concat(pnts.Skip(2).Take(pnts.Length)).ToArray();
            var headPnts = this.GetArrowHeadPoints(bonePnts, tailLeft, tailRight);
            var neckLeft = headPnts[0];
            var neckRight = headPnts[4];
            var tailWidth = PlotUtil.Distance(tailLeft, tailRight);
            var allLen = PlotUtil.GetBaseLength(bonePnts.ToList());
            var len = allLen * this.tailWidthFactor * this.swallowTailFactor;
            this.swallowTailPnt = PlotUtil.GetThirdPoint(bonePnts[1], bonePnts[0], 0, len, true);
            var factor = tailWidth / allLen;
            var bodyPnts = this.GetArrowBodyPoints(bonePnts, neckLeft, neckRight, factor);
            count = bodyPnts.Length;
            var leftPnts = new PointLatLng[] { tailLeft }.Concat(bodyPnts.Take(count / 2)).ToList();
            leftPnts.RemoveAt(1);
            leftPnts.Add(neckLeft);
            var rightPnts = new PointLatLng[] { tailRight }.Concat(bodyPnts.Skip(count / 2)).ToList();
            rightPnts.RemoveAt(1);
            rightPnts.Add(neckRight);

            leftPnts = PlotUtil.GetQBSplinePoints(leftPnts.ToArray());
            rightPnts = PlotUtil.GetQBSplinePoints(rightPnts.ToArray());
            rightPnts.Reverse();


            List tempPoints = leftPnts.Concat(headPnts).Concat(rightPnts).Concat(new PointLatLng[] { swallowTailPnt, leftPnts[0] }).ToList();
            var temps = GeometryUtil.ConvertCoordinates(tempPoints, ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);

            this.Points.Clear();
            this.Points.AddRange(temps);
        }
    }
  •  SquadCombat:分队战斗行动

 

    /// 
    /// 分队战斗行动
    /// 
    public class SquadCombat:AttackArrow
    {
        private double tailWidthFactor = 0.0;
        public SquadCombat(PointLatLng[] points)
            :base(points)
        {
            this.type = PlotTypes.SQUAD_COMBAT;
            this.headHeightFactor = 0.18;
            this.headWidthFactor = 0.3;
            this.neckHeightFactor = 0.85;
            this.neckWidthFactor = 0.15;
            this.tailWidthFactor = 0.1;
            this.SetPoints(points);
        }

        public override void Generate()
        {
            var count = this.GetPointCount();
            if (count < 2)
            {
                return;
            }
            var pnts = this.GetPoints();
            var tailPnts = this.GetTailPoints(pnts);
            var headPnts = this.GetArrowHeadPoints(pnts, tailPnts[0], tailPnts[1]);
            var neckLeft = headPnts[0];
            var neckRight = headPnts[4];
            var bodyPnts = this.GetArrowBodyPoints(pnts, neckLeft, neckRight, this.tailWidthFactor);
            count = bodyPnts.Length;
            var leftPnts = new PointLatLng[] { tailPnts[0] }.Concat(bodyPnts.Take(count / 2)).ToList();
            leftPnts.Add(neckLeft);
            var rightPnts = new PointLatLng[] { tailPnts[1] }.Concat(bodyPnts.Skip(count / 2).Take(count)).ToList();
            rightPnts.Add(neckRight);

            leftPnts = PlotUtil.GetQBSplinePoints(leftPnts.ToArray());
            rightPnts = PlotUtil.GetQBSplinePoints(rightPnts.ToArray());
            rightPnts.Reverse();

            List tempPoints = leftPnts.Concat(headPnts.Concat(rightPnts)).ToList();
            var temps = GeometryUtil.ConvertCoordinates(tempPoints, ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);

            this.Points.Clear();
            this.Points.AddRange(temps);
        }

        private PointLatLng[] GetTailPoints(PointLatLng[] pnts)
        {
            var allLen = PlotUtil.GetBaseLength(points.ToList());
            var tailWidth = allLen * this.tailWidthFactor;
            var tailLeft = PlotUtil.GetThirdPoint(points[1], points[0], Constants.HALF_PI, tailWidth, false);
            var tailRight = PlotUtil.GetThirdPoint(points[1], points[0], Constants.HALF_PI, tailWidth, true);
            return new PointLatLng[] { tailLeft, tailRight };
        }
    }
  •  TailedSquadCombat:分队战斗行动(尾)
/// 
    /// 分队战斗行动(尾)
    /// 
    public class TailedSquadCombat: AttackArrow
    {
        private double tailWidthFactor = 0.0;
        private double swallowTailFactor = 1;
        private PointLatLng swallowTailPnt;

        public TailedSquadCombat(PointLatLng[] points,string name="TailedSquadCombat")
            :base(points,name)
        {
            this.points = points;
            this.geo_type = "RootTest";

            this.type = PlotTypes.TAILED_SQUAD_COMBAT;
            this.headHeightFactor = 0.18;
            this.headWidthFactor = 0.3;
            this.neckHeightFactor = 0.85;
            this.neckWidthFactor = 0.15;
            this.tailWidthFactor = 0.1;
            this.swallowTailFactor = 1;
            this.swallowTailPnt = PointLatLng.Empty ;
            this.SetPoints(points);
        }

        public override void Generate()
        {
            var count = this.GetPointCount();
            if (count < 2)
            {
                return;
            }
            var pnts = this.GetPoints();
            var tailPnts = this.GetTailPoints(pnts);
            var headPnts = this.GetArrowHeadPoints(pnts, tailPnts[0], tailPnts[2]);
            var neckLeft = headPnts[0];
            var neckRight = headPnts[4];
            var bodyPnts = this.GetArrowBodyPoints(pnts, neckLeft, neckRight, this.tailWidthFactor);
            count = bodyPnts.Length;
            var leftPnts = new PointLatLng[] { tailPnts[0] }.Concat(bodyPnts.Take(count / 2)).ToList();
            leftPnts.Add(neckLeft);
            var rightPnts = new PointLatLng[] { tailPnts[2] }.Concat(bodyPnts.Skip(count / 2).Take(count)).ToList();
            rightPnts.Add(neckRight);

            leftPnts = PlotUtil.GetQBSplinePoints(leftPnts.ToArray());
            rightPnts = PlotUtil.GetQBSplinePoints(rightPnts.ToArray());
            rightPnts.Reverse();
            List tempPoints = leftPnts.Concat(headPnts).Concat(rightPnts).Concat(new PointLatLng[] { tailPnts[1], leftPnts[0] }).ToList();

            var temps = GeometryUtil.ConvertCoordinates(tempPoints, ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator, ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84);

            this.Points.Clear();
            this.Points.AddRange(temps);
        }

        private PointLatLng[] GetTailPoints(PointLatLng[] points)
        {
            var allLen = PlotUtil.GetBaseLength(points.ToList());
            var tailWidth = allLen * this.tailWidthFactor;
            var tailLeft = PlotUtil.GetThirdPoint(points[1], points[0], Constants.HALF_PI, tailWidth, false);
            var tailRight = PlotUtil.GetThirdPoint(points[1], points[0], Constants.HALF_PI, tailWidth, true);
            var len = tailWidth * this.swallowTailFactor;
            var swallowTailPnt = PlotUtil.GetThirdPoint(points[1], points[0], 0, len, true);
            return new PointLatLng[] { tailLeft, swallowTailPnt, tailRight };
        }
    }
  • 坐标列表去重:基于List的Distinct方法去重
    public class PointLatLngComparer : IEqualityComparer
    {
        public bool Equals(PointLatLng x, PointLatLng y)
        {
            return x.Lat == y.Lat && x.Lng == y.Lng;
        }
        public int GetHashCode(PointLatLng obj)
        {
            return string.Format("{0},{1}", obj.Lng, obj.Lat).GetHashCode();
        }
    }
//controlPoints 是List的变量,坐标去重
controlPoints = controlPoints.Distinct(new PointLatLngComparer()).ToList();

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/955599.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号