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