/// <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); } }
/// <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); } }