Exemplo n.º 1
0
        /// <summary>
        /// 计算瓦片地图的行列号范围
        /// </summary>
        /// <param name="startcoord">左下角经纬度</param>
        /// <param name="endcoord">右上角经纬度</param>
        /// <param name="z">地图层级</param>
        /// <returns></returns>
        public Tuple <int, int, int, int> GetTileBound(LatLngPoint startcoord, LatLngPoint endcoord, int z)
        {
            PointF StartMCPoint   = CoordTransferHelper.LatLng2Mercator(startcoord);
            Point  StartTilePoint = GetTileCoord(StartMCPoint, z);
            PointF EndPoint       = CoordTransferHelper.LatLng2Mercator(endcoord);
            Point  EndTilePoint   = GetTileCoord(EndPoint, z);

            return(new Tuple <int, int, int, int>(StartTilePoint.X, StartTilePoint.Y, EndTilePoint.X, EndTilePoint.Y));
        }
Exemplo n.º 2
0
        /// <summary>
        /// 瓦片地图拼接函数
        /// 百度地图和高德地图瓦片地图组织形式不一样,用maptype加以区别
        /// </summary>
        /// <param name="folder_list">文件夹列表</param>
        /// <param name="savepath">保存路径</param>
        /// <param name="maptype">0为百度地图,1为高德地图</param>
        WebApiResult <string> ParallelWriteImage(DirectoryInfo[] folder_list, String savepath, int maptype, string crstype, int maxSize)
        {
            FileInfo[] file = new FileInfo[] { };
            foreach (var folder in folder_list)
            {
                FileInfo[] a = GetFileList(folder);
                file = JoinArray(file, a);
            }

            List <List <FileInfo> > file_list_blocks = new List <List <FileInfo> >();

            deSplice(file, maxSize, ref file_list_blocks);
            var count = file_list_blocks.Count;

            //计算Total并更新
            threadlog.Total = file_list_blocks.Count;
            new Log <BaiduTileSplicingResult>(threadlog);
            log.Count = threadlog.Total;
            new Log <BaiduTileSplicingResult>(log);

            //利用GDAL创建结果影像,并写入瓦片数据
            Gdal.AllRegister();                                   //驱动注册
            Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); //中文路径支持
            Driver pDriver = Gdal.GetDriverByName("GTIFF");

            int num = 0;

            //分块拼接影像
            foreach (var file_list_block in file_list_blocks)
            {
                if (num < current)
                {
                    num++;
                    continue;
                }
                //if (num == 6) Pause<BaiduTileSplicingResult>(this.Result_gaode.GUID);

                if (maptype == 0)
                {
                    if (Log <BaiduTileSplicingResult> .GetThreadLogEntity(this.Result_baidu.GUID).IsPaused)
                    {
                        threadlog.Current  = current;
                        threadlog.Status   = "暂停";
                        threadlog.TStatus  = 4;
                        threadlog.IsPaused = true;
                        new Log <BaiduTileSplicingResult>(threadlog);

                        log.Status  = "未完成";
                        log.Current = current;
                        new Log <BaiduTileSplicingResult>(log);
                        return(null);
                    }
                }
                else
                {
                    if (Log <BaiduTileSplicingResult> .GetThreadLogEntity(this.Result_gaode.GUID).IsPaused)
                    {
                        threadlog.Current  = current;
                        threadlog.Status   = "暂停";
                        threadlog.TStatus  = 4;
                        threadlog.IsPaused = true;
                        new Log <BaiduTileSplicingResult>(threadlog);

                        log.Status  = "未完成";
                        log.Current = current;
                        new Log <BaiduTileSplicingResult>(log);
                        return(null);
                    }
                }

                FileInfo[] file_list_array = file_list_block.ToArray <FileInfo>();
                if (file_list_array.Length > 1)
                {
                    //获取分块的坐标信息和范围信息
                    List <Point> TilePoints = GetTileCoor(file_list_array);
                    Tuple <int, int, int, int> TileBoundary = GetBoundary(TilePoints);

                    //定义存储文件名
                    string level = file_list_block[0].DirectoryName.Substring(0, file_list_block[0].DirectoryName.LastIndexOf("\\")).Split('$')[0];
                    level = level.Substring(level.LastIndexOf("\\"));
                    string savedir = savepath + level;

                    //判断存储路径是否存在
                    if (!Directory.Exists(savedir))
                    {
                        Directory.CreateDirectory(savedir);
                    }
                    string dstPath = savedir + '\\' + file_list_block.First <FileInfo>().DirectoryName.Split('\\').Last() + "-" + file_list_block.First <FileInfo>().Name.Split('.').First() + "_" + file_list_block.Last <FileInfo>().DirectoryName.Split('\\').Last() + "-" + file_list_block.Last <FileInfo>().Name.Split('.').First() + ".tif";
                    if (File.Exists(dstPath))
                    {
                        continue;
                    }
                    string tfwPath = savedir + '\\' + file_list_block.First <FileInfo>().DirectoryName.Split('\\').Last() + "-" + file_list_block.First <FileInfo>().Name.Split('.').First() + "_" + file_list_block.Last <FileInfo>().DirectoryName.Split('\\').Last() + "-" + file_list_block.Last <FileInfo>().Name.Split('.').First() + ".tfw";
                    if (File.Exists(tfwPath))
                    {
                        continue;
                    }

                    //计算图像的宽度和高度,定义图像的Dataset
                    int     bufWidth   = (TileBoundary.Item3 - TileBoundary.Item1 + 1) * 256;
                    int     bufHeight  = (TileBoundary.Item4 - TileBoundary.Item2 + 1) * 256;
                    Dataset dstDataset = pDriver.Create(dstPath, bufWidth, bufHeight, 3, DataType.GDT_Byte, new String[] { "BIGTIFF=IF_NEEDED" });

                    //生成.tfw文件
                    StreamWriter writer = new StreamWriter(new FileStream(tfwPath, FileMode.Create, FileAccess.Write), Encoding.ASCII);
                    if (maptype == 0)
                    {
                        int z = int.Parse(level.Substring(1));
                        //计算瓦片地图左上角墨卡托坐标
                        double mcx   = TileBoundary.Item1 * 256 * Math.Pow(2, (18 - z));
                        double mcy   = (TileBoundary.Item4 + 1) * 256 * Math.Pow(2, (18 - z));
                        double sizex = 256 * Math.Pow(2, (18 - z));
                        double sizey = sizex;

                        if (crstype == "BD09")
                        {
                            var F = CoordTransferHelper.Mercator2LatLng(new PointF((float)mcx, (float)mcy));
                            mcx = F.Lat;
                            mcy = F.Lng;
                            double r1 = (TileBoundary.Item3 + 1) * 256 * Math.Pow(2, (18 - z));
                            double r2 = TileBoundary.Item2 * 256 * Math.Pow(2, (18 - z));
                            F     = CoordTransferHelper.Mercator2LatLng(new PointF((float)r1, (float)r2));
                            sizex = Math.Abs(mcx - F.Lat) / (TileBoundary.Item3 - TileBoundary.Item1 + 1);
                            sizey = Math.Abs(mcy - F.Lng) / (TileBoundary.Item4 - TileBoundary.Item2 + 1);
                        }

                        writer.WriteLine(sizex);
                        writer.WriteLine(0.000000);
                        writer.WriteLine(0.000000);
                        writer.WriteLine(-1 * sizey);
                        writer.WriteLine(mcx);
                        writer.WriteLine(mcy);
                    }
                    if (maptype == 1)
                    {
                        int    z      = int.Parse(level.Substring(1));
                        Point  TileP  = new Point(TileBoundary.Item1, TileBoundary.Item2);
                        Point  PixelP = new Point(0, 0);
                        var    P      = CoordTransferHelper.PixelXY2LatLng(TileP, PixelP, z);
                        double mcx    = P.Lat;
                        double mcy    = P.Lng;

                        P = CoordTransferHelper.PixelXY2LatLng(new Point(TileBoundary.Item3, TileBoundary.Item4), new Point(256, 256), z);
                        double sizex = Math.Abs(mcx - P.Lat) / (TileBoundary.Item3 - TileBoundary.Item1 + 1);
                        double sizey = Math.Abs(mcy - P.Lng) / (TileBoundary.Item4 - TileBoundary.Item2 + 1);

                        writer.WriteLine(sizex);
                        writer.WriteLine(0.000000);
                        writer.WriteLine(0.000000);
                        writer.WriteLine(sizey);
                        writer.WriteLine(mcx);
                        writer.WriteLine(mcy);
                    }
                    writer.Close();

                    //遍历分块列表中所有影像,读取瓦片图像信息写入分块影像
                    for (int i = 0; i < file_list_array.Length; i++)
                    {
                        //打开瓦片地图,获取瓦片地图的宽度、高度、波段、位数信息
                        Dataset img     = Gdal.Open(file_list_array[i].FullName, Access.GA_ReadOnly);
                        int     Width   = img.RasterXSize;
                        int     Height  = img.RasterYSize;
                        int     BandNum = img.RasterCount;
                        int     Depth   = Gdal.GetDataTypeSize(img.GetRasterBand(1).DataType);

                        //读取瓦片地图的数据信息
                        Byte[] buf = new Byte[Width * Height * BandNum];
                        CPLErr err = img.ReadRaster(0, 0, Width, Height, buf, Width, Height, BandNum, null, 0, 0, 0);
                        if (err == CPLErr.CE_Failure)
                        {
                            string message = string.Format("{0}图像读取失败!", file_list_array[i].Name);

                            return(new WebApiResult <string>()
                            {
                                success = 1, msg = message
                            });
                        }

                        //获取瓦片地图在拼接影像中的起始坐标信息
                        int OrgX = -9999, OrgY = -9999;
                        if (maptype == 0)
                        {
                            OrgX = (TilePoints[i].X - TileBoundary.Item1) * 256;
                            OrgY = (TileBoundary.Item4 - TilePoints[i].Y) * 256;
                        }
                        else if (maptype == 1)
                        {
                            OrgX = (TilePoints[i].X - TileBoundary.Item1) * 256;
                            OrgY = (TilePoints[i].Y - TileBoundary.Item2) * 256;
                        }
                        if (OrgX == -9999 || OrgY == -9999)
                        {
                            return new WebApiResult <string>()
                                   {
                                       success = 1, msg = "坐标错误"
                                   }
                        }
                        ;;
                        err = dstDataset.WriteRaster(OrgX, OrgY, Width, Height, buf, Width, Height, BandNum, null, 0, 0, 0);
                        if (err == CPLErr.CE_Failure)
                        {
                            string message = string.Format("结果图像{0}输出数据失败!", file_list_block.First <FileInfo>().Name + "_" + file_list_block.Last <FileInfo>().Name + ".tif");

                            return(new WebApiResult <string>()
                            {
                                success = 1, msg = message
                            });
                        }
                        img.Dispose();
                    }
                    dstDataset.Dispose();
                }
                else
                {
                    //定义存储文件名
                    string level = file_list_block[0].DirectoryName.Substring(0, file_list_block[0].DirectoryName.LastIndexOf("\\")).Split('_')[0];
                    level = level.Substring(level.LastIndexOf("\\"));
                    string savedir = savepath + level;

                    //判断存储路径是否存在
                    if (!Directory.Exists(savedir))
                    {
                        Directory.CreateDirectory(savedir);
                    }
                    string dstPath = savedir + '\\' + file_list_block.First <FileInfo>().DirectoryName.Split('\\').Last() + "-" + file_list_block.First <FileInfo>().Name.Split('.').First() + "_" + file_list_block.Last <FileInfo>().DirectoryName.Split('\\').Last() + "-" + file_list_block.Last <FileInfo>().Name.Split('.').First() + ".tif";
                    if (File.Exists(dstPath))
                    {
                        continue;
                    }

                    File.Copy(file_list_array[0].FullName.ToString(), dstPath);
                }

                current++;
                num++;
                if (maptype == 0)
                {
                    threadlog = Log <BaiduTileSplicingResult> .GetThreadLogEntity(this.Result_baidu.GUID);
                }
                else
                {
                    threadlog = Log <BaiduTileSplicingResult> .GetThreadLogEntity(this.Result_gaode.GUID);
                }
                threadlog.Current = current;
                new Log <BaiduTileSplicingResult>(threadlog);
            }
            pDriver.Deregister();
            Gdal.GDALDestroyDriverManager();

            return(new WebApiResult <string>()
            {
                success = 1, msg = "瓦片拼接完成!"
            });
        }