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

            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));
                regionList.Add(region);
                points = points.Skip(index + 1).ToList();
            }

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

            // 只计算最大层,其余层通过缩小计算得出
            var tileRegionList = regionList.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 ZoomTask(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);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// 计算下载任务列表
        /// </summary>
        private void Calculate()
        {
            var minZoom = m_supportZooms.Min();
            var maxZoom = m_supportZooms.Max();

            // 只计算最大层,其余层通过缩小计算得出
            var tileRegionList = m_regions.Select(o => o.GetTileRegion(maxZoom));
            var segments       =
                tileRegionList.Aggregate(Enumerable.Empty <TileSegment>(), (current, region) => current.Concat(region.GetTileSegments())).ToList();

            // 每个Y值计算一次交点
            var zoomTask  = new ZoomTask(maxZoom);
            var pointDict = new ConcurrentDictionary <double, ConcurrentBag <TilePoint> >();

            foreach (var segment in segments)
            {
                foreach (var tp in segment.GetTilePointIntersectY())
                {
                    if (!pointDict.ContainsKey(tp.Y))
                    {
                        pointDict.TryAdd(tp.Y, new ConcurrentBag <TilePoint>());
                    }
                    pointDict[tp.Y].Add(tp);
                }
            }

            foreach (var group in pointDict)
            {
                var points = group.Value.OrderBy(o => o.X).ToList();
                for (var index = 0; index < points.Count; index += 2)
                {
                    var x1 = (long)Math.Floor(points[index].X);
                    var x2 = (long)Math.Floor(points[index + 1].X);

                    var task = new MapLine
                    {
                        StartX = x1,
                        EndX   = x2,
                        Y      = (long)group.Key,
                        Zoom   = maxZoom
                    };
                    zoomTask.AddTask(task);
                }
            }

            // 将线段两点加入任务组
            foreach (var s in segments)
            {
                zoomTask.AddTask(GetTaskFromTilePoint(s.Point1, maxZoom));
                zoomTask.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));

            foreach (var segment in segments)
            {
                foreach (var tp in segment.GetTilePointIntersectX())
                {
                    zoomTask.AddTask(GetTaskFromTilePoint(tp, maxZoom));
                }
            }

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

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