Esempio n. 1
0
        /// <summary>
        /// 计算下载任务列表
        /// </summary>
        public void CalculateQuest()
        {
            // 先按多边形分组,一组点可能组成多个多边形
            var points = m_points;

            //while (points.Any())
            //{
            //    var index = points.ToList().LastIndexOf(points.First());
            //    if (index == 0)
            //    {
            //        if (points.Any())
            //        {
            //            File.AppendAllLines("points.txt", points.Select(o=>$"{o.X},{o.Y}"));
            //        }
            //        break;
            //    }

            //    var region = new MercatorRegion(points.Take(index + 1));
            //    m_mercatorRegions.Add(region);
            //    points = points.Skip(index + 1).ToList();
            //}

            if (!m_mercatorRegions.Any())
            {
                throw new ArgumentException("无法构建成多边形,请检查点是否闭合");
            }

            // 只计算最大层,其余层通过缩小计算得出
            var tileRegionList = m_mercatorRegions.Select(o => o.GetTileRegion(MaxZoom));
            var segments       = tileRegionList.Aggregate(Enumerable.Empty <TileSegment>(), (current, region) => current.Concat(region.GetTileSegments())).ToList();
            var minY           = (long)Math.Floor(segments.Min(o => o.MinY));
            var maxY           = (long)Math.Floor(segments.Max(o => o.MaxY));

            // 每个Y值计算一次交点
            var taskGroup = new MapZoom(MaxZoom);

            for (var i = minY; i <= maxY; i++)
            {
                var y             = i;
                var matchSegments = segments.Where(o => (o.MaxY >= y) && (o.MinY <= y));
                var intersectList = new List <TilePoint>();
                foreach (var s in matchSegments)
                {
                    intersectList.Add(s.IntersectY(y));
                }

                // 分解任务
                intersectList = intersectList.OrderBy(o => o.X).ToList();
                for (var index = 0; index < intersectList.Count; index += 2)
                {
                    var x1 = (long)Math.Floor(intersectList[index].X);
                    var x2 = (long)Math.Floor(intersectList[index + 1].X);

                    var task = new MapLine
                    {
                        StartX = x1,
                        EndX   = x2,
                        Y      = y,
                        Zoom   = MaxZoom
                    };
                    taskGroup.AddTask(task);
                }
            }

            // 将线段两点加入任务组
            foreach (var s in segments)
            {
                taskGroup.AddTask(GetTaskFromTilePoint(s.Point1, MaxZoom));
                taskGroup.AddTask(GetTaskFromTilePoint(s.Point2, MaxZoom));
            }

            // 将线段所有x轴点加入任务组
            var minX = (long)Math.Floor(segments.Min(o => o.MinX));
            var maxX = (long)Math.Floor(segments.Max(o => o.MaxX));

            for (var i = minX; i <= maxX; i++)
            {
                var x             = i;
                var matchSegments = segments.Where(o => (o.MaxX >= x) && (o.MinX <= x));
                foreach (var s in matchSegments)
                {
                    taskGroup.AddTask(GetTaskFromTilePoint(s.IntersectX(x), MaxZoom));
                }
            }

            // 整合任务组
            m_zoomTasks.Add(taskGroup);
            var tg = taskGroup;

            for (var index = MaxZoom - 1; index >= MinZoom; index--)
            {
                tg = tg.ScaleTo(index);
                m_zoomTasks.Add(tg);
            }
        }