AE + GDAL实现影像按标准图幅分割(下)

  在上篇实现了遥感影像的切割,本篇讲切割前的准备。主要分为以下几步:

  (1)将影像的投影坐标转换为地理坐标,以便于之后的图幅划分。AE坐标转换函数如下

 1 private bool Proj2Geo(ISpatialReference pspr, double xProj, double yProj, ref double xGeo, ref double yGeo)
 2         {
 3             if (pspr is IGeographicCoordinateSystem)
 4                 return false;
 5             IProjectedCoordinateSystem pcs = pspr as IProjectedCoordinateSystem;
 6             ISpatialReference gspr = pcs.GeographicCoordinateSystem;
 7
 8             IPoint pt = new PointClass();
 9             pt.PutCoords(xProj, yProj);
10             pt.SpatialReference = pspr;
11             pt.Project(gspr);
12             xGeo = pt.X;
13             yGeo = pt.Y;
14
15             return true;
16         }
17
18         private bool Geo2Proj(ISpatialReference pspr, double xGeo, double yGeo, ref double xProj, ref double yProj)
19         {
20             if (pspr is IGeographicCoordinateSystem)
21                 return false;
22             IProjectedCoordinateSystem pcs = pspr as IProjectedCoordinateSystem;
23             ISpatialReference gspr = pcs.GeographicCoordinateSystem;
24
25             IPoint pt = new PointClass();
26             pt.PutCoords(xGeo, yGeo);
27             pt.SpatialReference = gspr;
28             pt.Project(pspr);
29             xProj = pt.X;
30             yProj = pt.Y;
31
32             return true;
33         }

  (2)计算包含影像的标准图幅的四至,首先我定义了一个格网类

 1 public class GridInfo
 2     {
 3         public double XMin;
 4         public double XMax;
 5         public double YMin;
 6         public double YMax;
 7         public int rows;
 8         public int cols;
 9
10         public void setGridInfo(double xMax, double xMin, double yMax, double yMin, int rowCount, int colCount)
11         {
12             XMax = xMax;
13             XMin = xMin;
14             YMax = yMax;
15             YMin = yMin;
16             rows = rowCount;
17             cols = colCount;
18         }
19     }

根据比例尺计算格网的大小

 1 private GridInfo setGridInfoByScale(int scale)
 2         {
 3             GridInfo gridInfo = new GridInfo();
 4             double dxInSnd, dyInSnd;
 5             switch (scale)
 6             {
 7                 case 5000:
 8                     dxInSnd = Degree.Degree2Second(0.03125);
 9                     dyInSnd = Degree.Minute2Second(1.25);
10                     break;
11                 case 10000:
12                     dxInSnd = Degree.Degree2Second(0.0625);
13                     dyInSnd = Degree.Minute2Second(2.5);
14                     break;
15                 case 25000:
16                     dxInSnd = Degree.Minute2Second(7.5);
17                     dyInSnd = Degree.Minute2Second(5);
18                     break;
19                 case 50000:
20                     dxInSnd = Degree.Minute2Second(15);
21                     dyInSnd = Degree.Minute2Second(10);
22                     break;
23                 case 100000:
24                     dxInSnd = Degree.Minute2Second(30);
25                     dyInSnd = Degree.Minute2Second(20);
26                     break;
27                 case 250000:
28                     dxInSnd = Degree.Degree2Second(1.5);
29                     dyInSnd = Degree.Degree2Second(1);
30                     break;
31                 case 500000:
32                     dxInSnd = Degree.Degree2Second(3);
33                     dyInSnd = Degree.Degree2Second(2);
34                     break;
35                 case 1000000:
36                     dxInSnd = Degree.Degree2Second(6);
37                     dyInSnd = Degree.Degree2Second(4);
38                     break;
39                 default:
40                     dxInSnd = 0;
41                     dyInSnd = 0;
42                     break;
43             }
44
45             if (dxInSnd == dyInSnd && dxInSnd == 0.0)
46                 return null;
47
48             double pXMin = 0.0, pXMax = 0.0, pYMin = 0.0, pYMax = 0.0;
49             double gXMin = 0.0, gXMax = 0.0, gYMin = 0.0, gYMax = 0.0;
50             if (envelope.SpatialReference is IProjectedCoordinateSystem)
51             {
52                 Proj2Geo(envelope.SpatialReference, envelope.XMax, envelope.YMax, ref gXMax, ref gYMax);
53                 Proj2Geo(envelope.SpatialReference, envelope.XMin, envelope.YMin, ref gXMin, ref gYMin);
54             }
55             else
56             {
57                 gXMax = envelope.XMax; gXMin = envelope.XMin;
58                 gYMax = envelope.YMax; gYMin = envelope.YMin;
59             }
60             int cols =Convert.ToInt32(Math.Round(Degree.Degree2Second(180 - gXMin) / dxInSnd)) + 1;
61             gridInfo.XMin = 180 - Degree.Second2Degree(cols * dxInSnd);
62             cols = Convert.ToInt32(Math.Round(Degree.Degree2Second(180 - gXMax) / dxInSnd));
63             gridInfo.XMax = 180 - Degree.Second2Degree(cols * dxInSnd);
64
65             int rows = Convert.ToInt32(Math.Round(Degree.Degree2Second(gYMin) / dyInSnd));
66             gridInfo.YMin =Degree.Second2Degree(rows * dyInSnd);
67             rows = Convert.ToInt32(Math.Round(Degree.Degree2Second(gYMax) / dyInSnd)) + 1;
68             gridInfo.YMax =Degree.Second2Degree( rows * dyInSnd);
69
70             gridInfo.rows = Convert.ToInt32(Math.Round(Degree.Degree2Second(gridInfo.YMax - gridInfo.YMin) / dyInSnd));
71             gridInfo.cols = Convert.ToInt32(Math.Round(Degree.Degree2Second(gridInfo.XMax - gridInfo.XMin) / dxInSnd));
72
73             if (envelope.SpatialReference is IProjectedCoordinateSystem)
74             {
75                 Geo2Proj(envelope.SpatialReference, gridInfo.XMax, gridInfo.YMax, ref pXMax, ref pYMax);
76                 Geo2Proj(envelope.SpatialReference, gridInfo.XMin, gridInfo.YMin, ref pXMin, ref pYMin);
77                 gridInfo.XMax = pXMax; gridInfo.XMin = pXMin;
78                 gridInfo.YMax = pYMax; gridInfo.YMin = pYMin;
79             }
80
81             return gridInfo;
82         }

  (3)图幅命名类

 1 public class FrameName
 2     {
 3         private int scale;
 4         /// <summary>
 5         ///
 6         /// </summary>
 7         /// <param name="Scale">分数比例尺的分母(比例尺为1:50000则参数为50000)</param>
 8         public FrameName(int Scale)
 9         {
10             scale = Scale;
11         }
12
13         public String getFrameName(double longtitude, double latitude)
14         {
15             int baseRowCount=(int)(latitude / 4);
16             char baseChar = Convert.ToChar(‘A‘ + baseRowCount);
17             int baseNum = (int)(longtitude / 6) + 31;
18
19             if (scale == 1000000)
20                 return String.Format("{0}{1}", baseChar, baseNum);
21
22             char scaleChar = ‘E‘; //1:50000比例尺的代码为E,其他以后补充
23             switch (scale)
24             {
25                 case 500000:
26                     scaleChar=‘B‘;break;
27                 case 250000:
28                     scaleChar = ‘C‘;break;
29                 case 100000:
30                     scaleChar = ‘D‘;break;
31                 case 50000:
32                     scaleChar=‘E‘;break;
33                 case 25000:
34                     scaleChar = ‘F‘;break;
35                 case 10000:
36                     scaleChar = ‘G‘;break;
37                 case 5000:
38                     scaleChar = ‘H‘;break;
39             }
40
41             double dxInSnd, dyInSnd;
42             switch (scale)
43             {
44                 case 5000:
45                     dxInSnd = 0.03125;
46                     dyInSnd = 0.0208333333;
47                     break;
48                 case 10000:
49                     dxInSnd = 0.0625;
50                     dyInSnd = 0.0416666667;
51                     break;
52                 case 25000:
53                     dxInSnd = 0.125;
54                     dyInSnd = 0.0833333333;
55                     break;
56                 case 50000:
57                     dxInSnd = 0.25;
58                     dyInSnd = 0.1666666667;
59                     break;
60                 case 100000:
61                     dxInSnd = 0.5;
62                     dyInSnd = 0.3333333333;
63                     break;
64                 case 250000:
65                     dxInSnd = 1.5;
66                     dyInSnd = 1;
67                     break;
68                 case 500000:
69                     dxInSnd = 3;
70                     dyInSnd = 2;
71                     break;
72                 default:
73                     dxInSnd = 0;
74                     dyInSnd = 0;
75                     break;
76             }
77
78             if (dxInSnd == dyInSnd && dxInSnd == 0.0)
79                 return null;
80
81             int row = (int)(((baseRowCount + 1) * 4 - latitude)/dyInSnd) + 1;
82             //int row = 24-((int)(latitude / dyInSnd)) % 24;
83             int col = (int)((longtitude % 6) /dxInSnd) + 1;
84
85             return String.Format("{0}{1}{2}{3}{4}", baseChar, baseNum, scaleChar, row.ToString().PadLeft(3, ‘0‘), col.ToString().PadLeft(3, ‘0‘));
86         }
87
88     }

  (4)调用函数进行分割

 1 private void CreateFrame(GridInfo gridInfo, String outDir, int scale)
 2         {
 3             double xLength = (gridInfo.XMax - gridInfo.XMin) / gridInfo.cols;
 4             double yLength = (gridInfo.YMax - gridInfo.YMin) / gridInfo.rows;
 5             FrameName frameName = new FrameName(scale);
 6
 7             for (int i = 0; i < gridInfo.rows; i++)
 8             {
 9                 double yMin = gridInfo.YMin + i * yLength;
10                 double yMax = gridInfo.YMin + (i + 1) * yLength;
11                 for (int j = 0; j < gridInfo.cols; j++)
12                 {
13                     double xMin = gridInfo.XMin + j * xLength;
14                     double xMax = gridInfo.XMin + (j + 1) * xLength;
15                     String pszOutFile;
16
17                     if (envelope.SpatialReference is IProjectedCoordinateSystem)
18                     {
19                         double prjX = 0.0, prjY = 0.0;
20                         Proj2Geo(envelope.SpatialReference, (xMax + xMin) / 2, (yMax + yMin) / 2, ref prjX, ref prjY);
21                         pszOutFile = frameName.getFrameName(prjX,prjY);
22                     }
23                     else
24                         pszOutFile = frameName.getFrameName((xMax + xMin) / 2, (yMax + yMin) / 2);
25                     pszOutFile = outDir + "\\" + pszOutFile + ".tif";
26                     CutUpdateImageByAOIGDAL(rasterLyr.FilePath, pszOutFile, xMin, xMax, yMin, yMax, "GTiff");
27                 }
28             }
29         }

  通过这4步,一个简易的图幅分割工具就做好了。

时间: 2024-12-22 17:28:46

AE + GDAL实现影像按标准图幅分割(下)的相关文章

AE + GDAL实现影像按标准图幅分割(上)

最近有个项目,其中有个功能是要将遥感影像按标准图幅分割,一开始用AE的接口,慢的让人抓狂,就改用GDAL,速度提升很大.我主要通过http://blog.csdn.net/liminlu0314/学习GDAL.本篇主要记录GDAL实现分割的代码,下篇用AE写个demo. 1 int CutImageByGDAL(const char* pszInFile,const char* pszOutFile,double XMin,double XMax,double YMin,double YMax,

利用GDAL实现影像的几何校正

一.概述 遥感影像和地理坐标进行关联的方式一般有好几种,一种是直接给出了仿射变换系数,即6个参数,左上角地理坐标,纵横方向上的分辨率,以及旋转系数.在这种情况下,求出某一像素点的地理坐标非常容易,直接用公式可以求出,具体代码如下: void CPL_STDCALL GDALApplyGeoTransform(double *padfGeoTransform, double dfPixel, double dfLine, double *pdfGeoX, double *pdfGeoY ) { *

一款兼容性很好的标准二级css下拉菜单

<!DOCTYPE html PUBliC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN"> <head> <meta ht

GDAL开源库在WIN8.1环境下的编译安装

最近因为实验需要,要在windows环境下利用GDAL进行开发,故尝试了一下编译GDAL. 参考链接1:http://blog.csdn.net/liminlu0314/article/details/6937194 参考链接2:http://malagis.com/win7-vs2010-gdal.html 首先在GDAL官网上找到了下载链接,得到了最新的1.11.2版本的源代码,解压到D盘.根据参考链接1的内容进行编译. 打开命令行,切换到GDAL源码目录,输入nmake -f makefi

python标准模块(下)

Python 系统标准模块(shutil.logging.shelve.configparser.subprocess.xml.yaml.自定义模块) 目录: shutil logging模块 shelve configparser subprocess xml处理 yaml处理 自定义模块 一,系统标准模块: 1.shutil:是一种高层次的文件操作工具,类似于高级API,而且主要强大之处在于其对文件的复制与删除操作更是比较支持好,是高级的文件.文件夹.压缩包处理模块,而且是系统的标准自带模块

[APUE]标准IO库(下)

一.标准IO的效率 对比以下四个程序的用户CPU.系统CPU与时钟时间对比 程序1:系统IO 程序2:标准IO getc版本 程序3:标准IO fgets版本 结果: [注:该表截取自APUE,上表中"表3-1中的最佳时间即<程序1>","表3-1中的单字节时间指的是<程序1>中BUFSIZE为1时运行时间结果",fgetc/fputc版本程序这里没放出] 对于三个标准IO版本的每一个其用户CPU时间都大于最佳read版本,因为每次读一个字符

STL笔记(6)标准库:标准库中的排序算法

STL笔记(6)标准库:标准库中的排序算法 标准库:标准库中的排序算法The Standard Librarian: Sorting in the Standard Library Matthew Austern http://www.cuj.com/experts/1908/austern.htm?topic=experts 用泛型算法进行排序    C++标准24章有一个小节叫“Sorting and related operations”.它包含了很多对已序区间进行的操作,和三个排序用泛型

【GDAL】聊聊GDAL的数据模型

GDAL是个非常优秀的GIS数据操作库,最近在和实习生介绍GDAL的简单使用,顺手写下记录 本篇记录栅格数据,代码环境为C# 在GDAL中,栅格数据大致是以一个Dataset对应一个栅格数据文件(.Tif/GeoTiff格式),而这个栅格中的各种信息被包含在Dataset的对象中作为属性. 基本上一个栅格数据在GDAL的数据模型中存储是基于波段的方式,一般一个单波段数据在GDAL中读取后,所得到的Dataset中仅包含一个Band对象,而BandCount属性也为1.多波段数据类似,即是说在GD

基于GDAL库,读取.grd文件(以海洋地形数据为例)C++版

技术背景 海洋地形数据主要是通过美国全球地形起伏数据(GMT)获得,数据格式为grd(GSBG)二进制数据,打开软件通过是Surfer软件,surfer软件可进行数据的编辑处理,以及进一步的可视化表达等功能操作:由于Surfer软件不支持二次开发,没有提供相应的SDK供开发者进行使用,所以这一切只能通过相应类似的技术进行实现,首先,数据的读取,如何通过编程实现数据的读取操作呢?这里就要说一下GIS软件所使用的一个开源库-GDAL,GDAL库的具体解释资料,请查阅官方网站[https://www.