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

全部代码如下,切片逻辑参见 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;
        }
    }

}

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

  1. [Winform]一个简单的账户管理工具

    最近一直觉得注册的账户越来越多,帐号密码神马的容易弄混.自己就折腾了一个简单的账户管理工具,其实实现也挺简单,将每个账户的密码及相关密码提示信息,经aes算法加密之后保存到数据库,当前登录用户可以查询 ...

  2. JNI开发笔记(四)--实现一个简单的JNI工程并生成so库

    实现一个简单的JNI工程并生成so库 引 前言 1. 编写C/h文件并添加到工程 2. 修改CmakeLists.txt文件 3. 编写native-lib.cpp文件 4. 在MainActivit ...

  3. 实现一个简单的压测工具

    公司开发了一些服务器程序:上生产前需要进行压力测试,测试点包括:并发数.响应时间.吞吐量等指标.领导说,能不能仿照LoadRunner实现一个简单的压测工具(并发数在10000以上,结果指标以曲线图的 ...

  4. [HDF5] 封装了一个简单的C++ HDF5工具库,实现常用数据类型的读写

    目录 一.开发环境 二.主要功能 三.文件结构 四.HDF5写数据到hdf5文件功能实现 五.HDF5读hdf5文件数据到程序中数据结构功能实现 六.头文件Hdf5Function.h 七.工具类 八 ...

  5. 虚拟桌面:一个简单的桌面管理工具

    转载请标明是引用于 http://blog.csdn.net/chenyujing1234 欢迎大家拍砖! 参考英文文章: <<Virtual Desktop: A Simple Desk ...

  6. SpringBoot + FFmpeg实现一个简单的M3U8切片转码系统

    使用大名鼎鼎的ffmpeg,把视频文件切片成m3u8,并且通过springboot,可以实现在线的点播. 想法 客户端上传视频到服务器,服务器对视频进行切片后,返回m3u8,封面等访问路径.可以在线的 ...

  7. 一个简单的monkey测试工具

    Monkey的概念: "猴子测试"是指没有测试经验的人甚至对计算机根本不了解的人(就像猴子一样)不需要知道程序的任何用户交互方面的知识,如果给他一个程序,他就会针对他看到的界面进行 ...

  8. 研究开源gpt-2-simple项目,跑一个简单的模型,然后生成一段对话。用的是 Intel(R) Core(TM) i7-9700,8核8线程,训练最小的模型200次跑1个小时20分钟

    目录 前言 1,关于gpt2的几个例子学习 2,使用docker配置环境 3,使用uget工具下载模型,文件大容易卡死 4,研究使用gpt2-simple执行demo,训练200次 5,总结 前言 本 ...

  9. php随机数怎么获取?一个简单的函数就能生成

    小美女建了一个站,有些页面相似度比较高,想添加一些字段来实现差异化,比如用php随机数生成从10到100之间随机一个数字.其实会php的朋友几十个字符就能实现了,如下代码所示,简单吧?10代表最小值, ...

最新文章

  1. matlab各名称,Matlab-Simulink各模块对应的中文名称及介绍
  2. Ubuntu 16.04卸载一些不必要的预装软件
  3. 求根节点到叶节点数字之和Python解法
  4. 软工网络15个人阅读作业2——提问题
  5. react+redux+node报错Tapable.plugin is deprecated. Use new API on `.h ooks` instead
  6. GitHub更新Fork代码
  7. 转 JMeter之修改Sampler响应数据的编码格式
  8. 三电系统集成技术杂谈
  9. webpower邮件营销平台可以带来什么?
  10. 语法分析——自顶向下分析方法
  11. 编码器/译码器(Verilog HDL)|计算机组成
  12. pink老师世纪佳缘作业
  13. (软考高级、高项)信息系统项目管理师(第三版)过关经验
  14. 【寒假每日一题2022】acw1934. 贝茜放慢脚步【二路归并】
  15. linux系统查看dns缓存,如何清空linux的DNS缓存
  16. MATLAB 数据分析方法(第2版)1.2 MATLAB基础概述
  17. 计算机技术应用体验,2018教师信息技术应用体验学习个人心得体会2篇
  18. Matlab 求方程的根
  19. 【Flutter】ListView 列表高级功能 ( RefreshIndicator 下拉刷新组件 )
  20. uniapp中tabbar设置报错文件查找失败,at mian.js:5

热门文章

  1. Android开发和调试
  2. 华三无线控制器配置802.1X认证
  3. The Performance 星球茶话会 - 第一期
  4. pycharm 自动生成文件注释和函数模板
  5. 修谱为什么选择数字家谱?80岁老人:这四个优势太给力
  6. 制作或从其他格式转换ico图标
  7. 网易PM599产品笔试题
  8. “中国芯”——飞凌嵌入式OKA40i-C开发板测评-全志工业级芯片A40i评测
  9. 畅聊吧!来Discord加入InterSystems开发者社区!
  10. SPIFLASH播放语音芯片HX8088方案