专题图——点密度

点密度专题图个人理解,某区域内某个属性值得大小以点的个数显示。

步骤:

1.查询获取属性值;

2.设置单点值大小,计算点个数

3.随机生成点;

4.将点显示到graphiclayer图层;

这里的主要难点是如何在区域(以下称多边形)内生成指定个数的点;本人的主要思路是:

1.获取区域的范围和多边形顶点;

2.利用随机函数生成范围内的随机点;

3.判断点是否在多边形内;

4.将在多边形内的点记录,达到指定个数,结束;

其中,判断点在任意多边形内的方法,是以随机点为起点,像左过范围做一条线段,若该线段,与多边形的交点个数为偶数则在多边形外,奇数为内,

算法如下:

 /// <summary>
        /// 获取任意多边形中指定个数的随机点
        /// </summary>
        /// <param name="polygon">多边形</param>
        /// <param name="count">生成随机点的个数</param>
        /// <returns></returns>
        public static List<MapPoint> CalRandomPoints(ESRI.ArcGIS.Client.Geometry.Polygon polygon, int count)
        {
            List<MapPoint> listMp = new List<MapPoint>();
            if (polygon == null || count <= 0) return listMp;
            if (count == 1)
                CalOnePoint(polygon);
            Envelope initEnvelope = polygon.Extent;
            System.Random rd = new Random();//随机数
            double rd1 = 0, rd2 = 0; int sum = 0;
            bool isIn = false;
            double extentWidth = initEnvelope.XMax - initEnvelope.XMin;
            double extentHeight = initEnvelope.YMax - initEnvelope.YMin;
            while (sum != count)
            {
                rd1 = rd.NextDouble();
                rd2 = rd.NextDouble();
                double tmpX = initEnvelope.XMin + rd1 * extentWidth;
                double tmpY = initEnvelope.YMin + rd2 * extentHeight;
                MapPoint newPoint = new MapPoint(tmpX, tmpY);
                isIn = isInPolygon(polygon, newPoint);
                if (isIn)
                {
                    listMp.Add(newPoint);
                    sum++;
                }
            }
            return listMp;
        }


 /// <summary>
        /// 判断点是否在多边形内
        /// </summary>
        /// <returns></returns>
        private static bool isInPolygon(ESRI.ArcGIS.Client.Geometry.Polygon polygon,MapPoint mpoint)
        {
            bool _isIN = true;
            System.Random rd = new Random();

            MapPoint endPoint = new MapPoint();
            endPoint.Y = mpoint.Y;
            endPoint.X = polygon.Extent.XMin-100000;
            ILineSegment ls2 = new ILineSegment();
            ls2.StartPoint = mpoint;
            ls2.EndPoint = endPoint;

            System.Collections.ObjectModel.ObservableCollection<ESRI.ArcGIS.Client.Geometry.PointCollection> pc =
            polygon.Rings;
            ESRI.ArcGIS.Client.Geometry.PointCollection tmpPc;
            MapPoint tmpSMP,tmpEMP;
            ILineSegment ls1;
            int crossSum=0;
            for (int i = 0; i < pc.Count; i++)
            {
                tmpPc = pc[i];
                for (int j = 0; j < tmpPc.Count-1; j++)//顺时针,负为正
                {
                    tmpSMP = tmpPc[j]; tmpEMP = tmpPc[j + 1];
                    ls1 = new ILineSegment();
                    ls1.StartPoint = tmpSMP; ls1.EndPoint = tmpEMP;
                    if (ls1 == null || ls2 == null) continue;
                    bool iscross = isSegmentCrossing(ls1, ls2);
                    bool lsl1l2 = isSegmentCrossing(ls2, ls1);//l1是否穿过l2
                    if (iscross&&lsl1l2)
                        crossSum++;
                }
            }
            if (crossSum % 2 == 0)//偶数在多边形外
                _isIN = false;
            else
                _isIN = true;
            return _isIN;
        }
        /// <summary>
        /// 判断两线段是否相交是否相交
        /// </summary>
        /// <param name="ls1"></param>
        /// <param name="ls2"></param>
        /// <returns></returns>
        private static bool isSegmentCrossing(ILineSegment ls1, ILineSegment ls2)
        {
            bool iscross = false;
            //l2--l1
            double cj1 = calPointLoaction(ls2.StartPoint, ls1);
            double cj2 = calPointLoaction(ls2.EndPoint, ls1);
            if (cj1 > 0 && cj2 > 0)
                iscross = false;
            else if (cj1 < 0 && cj2 < 0)
                iscross = false;
            else
                iscross = true;
            return iscross;
        }
        /// <summary>
        /// 计算一个点在线段的左右
        /// </summary>
        /// <param name="point"></param>
        /// <param name="line"></param>
        /// <returns></returns>
        private static double calPointLoaction(MapPoint point, ILineSegment line)
        {
            double cj = 0;
            double ax = line.StartPoint.X - point.X;
            double ay = line.StartPoint.Y - point.Y;
            double bx = line.EndPoint.X - point.X;
            double by = line.EndPoint.Y - point.Y;
            cj = ax * by - bx * ay;
            return cj;
        }
效果图如下(貌似还可以呵呵):


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值