一个简单的影像切片工具,生成xyz格式

使用C#调用gdal写了个简单的遥感影像切xyz工具,只能切tiff影像。界面没设计,代码没优化,也没上多线程,有兴趣的自己拿去改。

一个简单的影像切片工具,生成xyz格式

 

 

全部代码如下,切片逻辑参见 MapTile 这个方法 

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using GDAL = OSGeo.GDAL;
using OGR = OSGeo.OGR;
using System.IO;

namespace MapTileTool
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
           
        }

        private void HandleGeoTiffSelect(object sender, EventArgs e)
        {
            string title = "选择遥感影像";
            string filter = "tif文件(*.tif,*.tiff)|*.tif;*.tiff";
            string fileName = FileChooserSelect(title, filter);
            if (null != fileName) {
                this.tifTextBox.Text = fileName;
            }
        }
        private void HandleGeoTiffRest(object sender, EventArgs e)
        {
            this.tifTextBox.Text = ""; ;
        }

        private void HandleOutputSelect(object sender, EventArgs e)
        {
            string outputPath = FoloderChooserSelect("选择输出文件夹");
            if (null != outputPath) {
                this.outputTextBox.Text = outputPath;
            }
        }

        private void HandleOutputRest(object sender, EventArgs e)
        {
            this.outputTextBox.Text = "";
        }

        private void ExecuteMapTile(object sender, EventArgs e)
        {
            string geoTiffPath = tifTextBox.Text;
            string outputPath = outputTextBox.Text;
            string zMin = zMinTextBox.Text;
            string zMax = zMaxTextBox.Text;

            if (string.IsNullOrEmpty(geoTiffPath)
                || string.IsNullOrEmpty(outputPath)
                || string.IsNullOrEmpty(zMin)
                || string.IsNullOrEmpty(zMax)) {
                MessageBox.Show("信息填写有误");
                return;
            }

            try
            {
                int zMinLevel = Convert.ToInt32(zMin);
                int zMaxLevel = Convert.ToInt32(zMax);
                executeBtn.Enabled = false;
                consoleLabel.Text = "正在切片,请稍候。。。";
                MapTile(geoTiffPath, outputPath, zMinLevel, zMaxLevel);
                consoleLabel.Text = "恭喜,影像切片已完成";
                executeBtn.Enabled = true;
            }
            catch (Exception ex) {
                Console.WriteLine(ex.Message);
                consoleLabel.Text = "切图异常:" + ex.Message;
                executeBtn.Enabled = true;
            }

        }

        /**
         * 切片处理逻辑
         */
        private void MapTile(string geoTiffPath, string outputPath, int zMin, int zMax) {
            try
            {
                OGR.Ogr.RegisterAll();
                GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Gdal驱动注册失败:" + ex.Message);
            }

            OSGeo.GDAL.Dataset dataset = GDAL.Gdal.Open(geoTiffPath, OSGeo.GDAL.Access.GA_ReadOnly);
            int width = dataset.RasterXSize;
            int height = dataset.RasterYSize;
            int bandCount = dataset.RasterCount;
            double[] transform = new double[6];
            dataset.GetGeoTransform(transform);
            double lonMin = transform[0];
            double lonMax = transform[0] + (width * transform[1]);
            double latMin = transform[3] + (height * transform[5]);
            double latMax = transform[3];

            if (zMin < 6)
            {
                zMin = 6;
            }

            if (zMax > 18)
            {
                zMax = 18;
            }

            for (int z = zMin; z <= zMax; z++)
            {
                int tileRowMin = GetXyTileByZ(lonMin, latMax, z)[0];
                int tileRowMax = GetXyTileByZ(lonMax, latMin, z)[0];
                int tileColMin = GetXyTileByZ(lonMin, latMax, z)[1];
                int tileColMax = GetXyTileByZ(lonMax, latMin, z)[1];
                double tempLonMin = GetLngLatByXyz(tileRowMin, tileColMin, z)[0];
                double tempLonMax = GetLngLatByXyz(tileRowMin + 1, tileColMin, z)[0];
                double tempLatMin = GetLngLatByXyz(tileRowMin, tileColMin + 1, z)[1];
                double tempLatMax = GetLngLatByXyz(tileRowMin, tileColMin, z)[1];

                // 获取X轴方向分辨率
                double xResolution = (tempLonMax - tempLonMin) / 256;
                // 获取Y轴方向分辨率
                double yResolution = (tempLatMax - tempLatMin) / 256;

                for (int x = tileRowMin; x <= tileRowMax; x++)
                {
                    for (int y = tileColMin; y <= tileColMax; y++)
                    {
                        double tileLonMin = tempLonMin + (x - tileRowMin) * xResolution * 256;
                        double tileLatMax = tempLatMax - (y - tileColMin) * yResolution * 256;

                        try
                        {
                            double xTileMax = tileLonMin + 256 * xResolution;
                            double yTileMin = tileLatMax - 256 * yResolution;
                            List<int> positionMin = GetPosition(tileLonMin, tileLatMax, transform);
                            List<int> positionMax = GetPosition(xTileMax, yTileMin, transform);
                            Boolean contain = positionMin[0] < width && positionMin[0] >= 0
                                    && positionMin[1] < height && positionMin[1] >= 0
                                    && positionMax[0] < width && positionMax[0] >= 0
                                    && positionMax[1] < height && positionMax[1] >= 0;

                            Bitmap bitmap = new Bitmap(256, 256);
                            if (contain)
                            {
                                int xDistant = positionMax[0] - positionMin[0] + 1;
                                int yDistant = positionMax[1] - positionMin[1] + 1;
                                bitmap = new Bitmap(xDistant, yDistant);
                                if (bandCount == 1)
                                {
                                    float[] gs = new float[xDistant * yDistant];
                                    dataset.GetRasterBand(1).ReadRaster(positionMin[0], positionMin[1], xDistant, yDistant, gs, xDistant, yDistant, 0, 0);
                                    for (int i = 0; i < xDistant; i++)
                                    {
                                        for (int j = 0; j < yDistant; j++)
                                        {
                                            float g = gs[xDistant * j + i];
                                            if (g < 0)
                                            {
                                                continue;
                                            }
                                            int gray = (int)(255 * g);
                                            Color color = Color.FromArgb(gray, gray, gray);
                                            bitmap.SetPixel(i, j, color);
                                        }
                                    }

                                }
                                else
                                {
                                    int[] rs = new int[xDistant * yDistant];
                                    int[] gs = new int[xDistant * yDistant];
                                    int[] bs = new int[xDistant * xDistant];
                                    dataset.GetRasterBand(1).ReadRaster(positionMin[0], positionMin[1], xDistant, yDistant, rs, xDistant, yDistant, 0, 0);
                                    dataset.GetRasterBand(2).ReadRaster(positionMin[0], positionMin[1], xDistant, yDistant, gs, xDistant, yDistant, 0, 0);
                                    dataset.GetRasterBand(3).ReadRaster(positionMin[0], positionMin[1], xDistant, yDistant, bs, xDistant, yDistant, 0, 0);

                                    for (int i = 0; i < xDistant; i++)
                                    {
                                        for (int j = 0; j < yDistant; j++)
                                        {
                                            int r = rs[xDistant * j + i];
                                            int g = gs[xDistant * j + i];
                                            int b = bs[xDistant * j + i];
                                            if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
                                            {
                                                continue;
                                            }

                                            Color color = Color.FromArgb(r, g, b);
                                            bitmap.SetPixel(i, j, color);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                for (int i = 0; i < 256; i++)
                                {
                                    for (int j = 0; j < 256; j++)
                                    {
                                        double tileLon = tileLonMin + i * xResolution;
                                        double tileLat = tileLatMax - j * yResolution;
                                        List<int> position = GetPosition(tileLon, tileLat, transform);
                                        int xPosition = position[0];
                                        int yPosition = position[1];

                                        if (xPosition < 0 || yPosition < 0 || xPosition >= width || yPosition >= height)
                                        {
                                            continue;
                                        }
                                        Color color;
                                        if (bandCount == 1)
                                        {
                                            float[] values = new float[1];
                                            dataset.GetRasterBand(1).ReadRaster(xPosition, yPosition, 1, 1, values, 1, 1, 0, 0);
                                            if (values[0] < 0)
                                            {
                                                continue;
                                            }
                                            int gray = (int)(255 * values[0]);
                                            color = Color.FromArgb(gray, gray, gray);
                                        }
                                        else
                                        {
                                            int[] rs = new int[1];
                                            int[] gs = new int[1];
                                            int[] bs = new int[1];
                                            dataset.GetRasterBand(1).ReadRaster(xPosition, yPosition, 1, 1, rs, 1, 1, 0, 0 );
                                            dataset.GetRasterBand(2).ReadRaster(xPosition, yPosition, 1, 1, gs, 1, 1, 0, 0);
                                            dataset.GetRasterBand(3).ReadRaster(xPosition, yPosition, 1, 1, bs, 1, 1, 0, 0);
                                            int r = rs[0];
                                            int g = gs[0];
                                            int b = bs[0];
                                            if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255)
                                            {
                                                continue;
                                            }

                                            color = Color.FromArgb(r, g, b);
                                        }
                                        bitmap.SetPixel(i, j, color);
                                    }
                                }
                            }

                            try
                            {
                                String layerPath = outputPath + "/" + z + "/" + x;
                                if (!System.IO.Directory.Exists(layerPath))
                                {
                                    System.IO.Directory.CreateDirectory(layerPath);
                                }

                                String imagePath = layerPath + "/" + y + ".png";
                                bitmap.Save(imagePath);
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine("切图异常:" + e.Message);
                                consoleLabel.Text = "切图异常:" + e.Message;
                            }
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine("切图异常:" + e.Message);
                            consoleLabel.Text = "切图异常:" + e.Message;
                        }
                    }
                }
            }

        }


        /**
         * 获取行列号
         *
         * @param lng
         * @param lat
         * @param z
         */
        public static List<int> GetXyTileByZ(double lng, double lat, int z)
        {
            List<int> xy = new List<int>(2);
            int x = (int)Math.Floor((lng + 180) / 360 * Math.Pow(2, z));
            int y = (int)Math.Floor((1 - Math.Log(Math.Tan(Math.PI*lat/180) + 1 / Math.Cos( Math.PI*lat/180)) / Math.PI) / 2 * (Math.Pow(2, z)));
            xy.Add(x);
            xy.Add(y);
            return xy;
        }

        /**
         * 根据经纬度获取影像像素位置 
         */
        public static List<int> GetPosition(double lng, double lat, double[] transform)
        {
            double dTemp = transform[1] * transform[5] - transform[2] * transform[4];
            int xPix = (int)((transform[5] * (lng - transform[0]) - transform[2] * (lat - transform[3])) / dTemp);
            int yPix = (int)((transform[1] * (lat - transform[3]) - transform[4] * (lng - transform[0])) / dTemp);
            List<int> xy = new List<int>(2);
            xy.Add(xPix);
            xy.Add(yPix);
            return xy;
        }

        /**
         * 根据切片序列号获取经纬度坐标
         * @return
         */
        public static List<Double> GetLngLatByXyz(int x, int y, int z)
        {
            List<Double> xy = new List<Double>(2);
            double n = Math.Pow(2, z);
            double lng = x / n * 360.0 - 180.0;
            double lat = Math.Atan(Math.Sinh(Math.PI * (1 - 2 * y / n)));
            lat = lat * 180.0 / Math.PI;
            xy.Add(lng);
            xy.Add(lat);
            return xy;
        }


        /**
        * 选择文件控件
        */
        private static string FileChooserSelect(string title, string filter)
        {
            string fileName = "";
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Multiselect = true;
            fileDialog.Title = title;
            fileDialog.Filter = filter;
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                fileName = fileDialog.FileName;
            }

            return fileName;
        }

        /**
         * 选择文件夹控件
         */
        private static string FoloderChooserSelect(string title)
        {
            string folderPath = "";
            FolderBrowserDialog folderDialog = new FolderBrowserDialog();
            folderDialog.Description = title;
            if (folderDialog.ShowDialog() == DialogResult.OK)
            {
                folderPath = folderDialog.SelectedPath;
            }

            return folderPath;
        }
    }

}
 

上一篇:移动端下雪系统的实现


下一篇:1411. 给 N x 3 网格图涂色的方案数