/// <summary> /// 计算地图的最大,最小区域范围(所有影像范围的一个交集) /// </summary> /// <param name="imageEnvelop"></param> /// <param name="mapEnvelop"></param> public static void getMapEnvelop(Envelop imageEnvelop, ref Envelop mapEnvelop) { mapEnvelop.East = Math.Max(mapEnvelop.East, imageEnvelop.East); mapEnvelop.West = Math.Min(mapEnvelop.West, imageEnvelop.West); mapEnvelop.North = Math.Max(mapEnvelop.North, imageEnvelop.North); mapEnvelop.South = Math.Min(mapEnvelop.South, imageEnvelop.South); }
/// <summary> /// 获得当前影像的范围 /// </summary> /// <param name="fileName"></param> /// <param name="isShapeFile"></param> /// <param name="gcsWkt"></param> /// <returns></returns> public static Envelop GetEnvelop(string fileName, bool isShapeFile, string gcsWkt) { ICoordinateSystem srcCoor = null; SharpMap.Layers.Layer layer = null; if (isShapeFile) { SharpMap.Layers.VectorLayer l = new SharpMap.Layers.VectorLayer(Path.GetFileNameWithoutExtension(fileName)); l.DataSource = new SharpMap.Data.Providers.ShapeFile(fileName, true); l.SRID = 4326; srcCoor = ((SharpMap.Data.Providers.ShapeFile)l.DataSource).CoordinateSystem; layer = l; } else { SharpMap.Layers.GdalRasterLayer l = new SharpMap.Layers.GdalRasterLayer(Path.GetFileNameWithoutExtension(fileName), fileName); l.SRID = 4326; l.Enabled = true; srcCoor = l.GetProjection(); layer = l; } Envelop envelop = new Envelop(); //if (srcCoor != null) //{ // CoordinateSystemFactory cFac = new CoordinateSystemFactory(); // ICoordinateSystem tarCoor = cFac.CreateFromWkt(gcsWkt); // ICoordinateTransformation transform = null; // try // { // transform = new CoordinateTransformationFactory().CreateFromCoordinateSystems(srcCoor, tarCoor); // } // catch (Exception e) // { // return new Envelop(); // } // SharpMap.Geometries.BoundingBox imageBox = GeometryTransform.TransformBox(layer.Envelope, transform.MathTransform); // envelop.North = imageBox.Top; // envelop.South = imageBox.Bottom; // envelop.West = imageBox.Left; // envelop.East = imageBox.Right; //} //else //{ envelop.East = layer.Envelope.Right; envelop.West = layer.Envelope.Left; envelop.North = layer.Envelope.Top; envelop.South = layer.Envelope.Bottom; //} return(envelop); }
/// <summary> /// 切影像瓦片 /// </summary> /// <param name="args">4个参数。 /// 参数1:输入影像路径; /// 参数2:输出路径 /// 参数3:起始层级 /// 参数4:切片层数</param> static void Main(string[] args) { DicLevelDegree.Add(0, 36); DicLevelDegree.Add(1, 18); DicLevelDegree.Add(2, 9); DicLevelDegree.Add(3, 4.5); DicLevelDegree.Add(4, 2.25); DicLevelDegree.Add(5, 1.125); DicLevelDegree.Add(6, 0.5625); DicLevelDegree.Add(7, 0.28125); DicLevelDegree.Add(8, 0.140625); DicLevelDegree.Add(9, 0.0703125); DicLevelDegree.Add(10, 0.03515625); DicLevelDegree.Add(11, 0.17578125); DicLevelDegree.Add(12, 0.008789063); DicLevelDegree.Add(13, 0.004394531); DicLevelDegree.Add(14, 0.002197266); DicLevelDegree.Add(15, 0.001098633); DicLevelDegree.Add(16, 0.000549316); /*级别 瓦片跨度 像素分辨率 列数 行数 瓦片个数 * (111322米/度) * 0 36 7827.34 10 5 50 * 1 18 3913.67 20 10 200 * 2 9 1956.835 40 20 800 * 3 4.5 978.4175 80 40 3200 * 4 2.25 489.20875 160 80 12800 * 5 1.125 244.604375 320 160 51200 * 6 0.5625 122.3021875 640 320 204800 * 7 0.28125 61.15109375 1280 640 819200 * 8 0.140625 30.57554688 2560 1280 3276800 * 9 0.0703125 15.28777344 5120 2560 13107200 * 10 0.03515625 7.643886719 10240 5120 52428800 * 11 0.017578125 3.821943359 20480 10240 209715200 * 12 0.008789063 1.91097168 40960 20480 838860800 * 13 0.004394531 0.95548584 81920 40960 3355443200 * 14 0.002197266 0.47774292 163840 81920 13421772800 * 15 0.001098633 0.23887146 327680 163840 53687091200 * 16 0.000549316 0.11943573 655360 327680 2.14748E+11 */ //args = new string[] { @"D:\testimage\testimage\worlddem.tif", @"D:\testimage\testimageoutFinal", "3", "1", "DEM" };//接收4个参数 string inputDir = Path.GetDirectoryName(args[0]); //1.输入文件夹路径 string outputDir = args[1]; //2.保存文件夹路径 int startlevel = Convert.ToInt16(args[2]); double lztsd = DicLevelDegree[startlevel]; //3.第0层每个格网的度数 int levelCount = Convert.ToInt32(args[3]); //4.总共要切分几层 if (args.Length < 4) { Console.WriteLine("输入参数不正确!示例: inputDir,outputDir,lztsd,levelCount"); } if (args.Length == 5 && args[4] == "DEM") { IsDEM = true; } object thislock = new object(); //安全锁,为了并行共享统一资源,而不发生抢的现象 Envelop mapEnvelop = new Envelop(); //获取地图的最大、最小范围 string[] files = new string[] { args[0] }; //Directory.GetFiles(inputDir,"*.jpg"); for (int fCount = 0; fCount < files.Length; fCount++) { try { string inputFile = files[fCount]; Envelop imageEnvelop = Dstile.GetEnvelop(inputFile, false, "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.2572326660126,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433],AUTHORITY[\"EPSG\",\"4326\"]]"); if (fCount == 0) { mapEnvelop.East = imageEnvelop.East; mapEnvelop.West = imageEnvelop.West; mapEnvelop.North = imageEnvelop.North; mapEnvelop.South = imageEnvelop.South; continue; } getMapEnvelop(imageEnvelop, ref mapEnvelop); } catch { } } //开始进行切图 for (int i = 0; i < levelCount; i++) { Level levelInfo = new Level(lztsd, startlevel + i);//存储当前Level的信息 int yCount = 0; int xCount = 0; int startX = 0; int startY = 0; string localpath = ""; //根据地图的最大最小范围,计算在当前层所处的起始格网号,和总共在该层占了几个格网 yCount = (int)((mapEnvelop.North - mapEnvelop.South) / levelInfo.LevelPerDegree + 1); xCount = (int)((mapEnvelop.East - mapEnvelop.West) / levelInfo.LevelPerDegree + 1); startX = (int)((mapEnvelop.West + 180) / levelInfo.LevelPerDegree); startY = (int)((mapEnvelop.South + 90) / levelInfo.LevelPerDegree); localpath = ""; localpath = outputDir + "\\" + levelInfo.LevelNumber.ToString(); //循环获取每个格网的缩略图 for (int y = startY; y <= startY + yCount; y++) { //创建文件夹 localpath = outputDir + "\\" + levelInfo.LevelNumber.ToString() + "\\" + string.Format("{0}", y); if (!Directory.Exists(localpath)) { Directory.CreateDirectory(localpath); } //存储单个格网的信息,当达到CPU内核个数的时候,就开始多核并行切图 Tile[] tiles = new Tile[CPUCORE]; int tileIndex = 0; for (int x = startX; x <= startX + xCount; x++) { #region 存储当前切片的相关信息 SharpMap.Map thismap = new SharpMap.Map(new Size(512, 512)); for (int fCount = 0; fCount < files.Length; fCount++) { string inputFile = files[fCount]; SharpMap.Layers.GdalGridRasterLayer layer; layer = new SharpMap.Layers.GdalGridRasterLayer(System.IO.Path.GetFileNameWithoutExtension(inputFile), inputFile, thislock); layer.SRID = 4326; layer.Enabled = true; thismap.Layers.Add(layer); } //设置Map的背景色为透明色 thismap.BackColor = System.Drawing.Color.Transparent; //图像的formate System.Drawing.Imaging.ImageCodecInfo imageEncoder = Dstile.GetEncoderInfo("image/png"); //图片的大小 thismap.Size = new System.Drawing.Size(512, 512); tiles[tileIndex] = new Tile(x, y, thismap, levelInfo.LevelPerDegree, levelInfo.LevelNumber, localpath); tileIndex++; #endregion //判断是否达到了CPU内核个数,若达到,则开始进行切图 if (tileIndex == CPUCORE) { Task[] tasks = new Task[CPUCORE]; //产生4个线程执行切图 for (int t = 0; t < tasks.Length; t++) { tasks[t] = new Task(argument => GenerateMap((Tile)argument), tiles[t]); tasks[t].Start(); } Task.WaitAll(tasks); tileIndex = 0; } } //判断,还剩几个没有做的任务,并行切图 if (tileIndex != 0) { Task[] tasks = new Task[tileIndex]; //产生tileIndex个线程执行切图 for (int t = 0; t < tasks.Length; t++) { tasks[t] = new Task(argument => GenerateMap((Tile)argument), tiles[t]); tasks[t].Start(); } Task.WaitAll(tasks); tileIndex = 0; } } //循环,开始切下一层数据,每下一层,都是上一层的1/2。 lztsd = lztsd / 2; } Console.WriteLine("切片完成!"); File.CreateText(string.Format(@"{0}\Dstile_Done.txt", outputDir)); }