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

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

 private bool Proj2Geo(ISpatialReference pspr, double xProj, double yProj, ref double xGeo, ref double yGeo)
{
if (pspr is IGeographicCoordinateSystem)
return false;
IProjectedCoordinateSystem pcs = pspr as IProjectedCoordinateSystem;
ISpatialReference gspr = pcs.GeographicCoordinateSystem; IPoint pt = new PointClass();
pt.PutCoords(xProj, yProj);
pt.SpatialReference = pspr;
pt.Project(gspr);
xGeo = pt.X;
yGeo = pt.Y; return true;
} private bool Geo2Proj(ISpatialReference pspr, double xGeo, double yGeo, ref double xProj, ref double yProj)
{
if (pspr is IGeographicCoordinateSystem)
return false;
IProjectedCoordinateSystem pcs = pspr as IProjectedCoordinateSystem;
ISpatialReference gspr = pcs.GeographicCoordinateSystem; IPoint pt = new PointClass();
pt.PutCoords(xGeo, yGeo);
pt.SpatialReference = gspr;
pt.Project(pspr);
xProj = pt.X;
yProj = pt.Y; return true;
}

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

 public class GridInfo
{
public double XMin;
public double XMax;
public double YMin;
public double YMax;
public int rows;
public int cols; public void setGridInfo(double xMax, double xMin, double yMax, double yMin, int rowCount, int colCount)
{
XMax = xMax;
XMin = xMin;
YMax = yMax;
YMin = yMin;
rows = rowCount;
cols = colCount;
}
}

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

 private GridInfo setGridInfoByScale(int scale)
{
GridInfo gridInfo = new GridInfo();
double dxInSnd, dyInSnd;
switch (scale)
{
case :
dxInSnd = Degree.Degree2Second(0.03125);
dyInSnd = Degree.Minute2Second(1.25);
break;
case :
dxInSnd = Degree.Degree2Second(0.0625);
dyInSnd = Degree.Minute2Second(2.5);
break;
case :
dxInSnd = Degree.Minute2Second(7.5);
dyInSnd = Degree.Minute2Second();
break;
case :
dxInSnd = Degree.Minute2Second();
dyInSnd = Degree.Minute2Second();
break;
case :
dxInSnd = Degree.Minute2Second();
dyInSnd = Degree.Minute2Second();
break;
case :
dxInSnd = Degree.Degree2Second(1.5);
dyInSnd = Degree.Degree2Second();
break;
case :
dxInSnd = Degree.Degree2Second();
dyInSnd = Degree.Degree2Second();
break;
case :
dxInSnd = Degree.Degree2Second();
dyInSnd = Degree.Degree2Second();
break;
default:
dxInSnd = ;
dyInSnd = ;
break;
} if (dxInSnd == dyInSnd && dxInSnd == 0.0)
return null; double pXMin = 0.0, pXMax = 0.0, pYMin = 0.0, pYMax = 0.0;
double gXMin = 0.0, gXMax = 0.0, gYMin = 0.0, gYMax = 0.0;
if (envelope.SpatialReference is IProjectedCoordinateSystem)
{
Proj2Geo(envelope.SpatialReference, envelope.XMax, envelope.YMax, ref gXMax, ref gYMax);
Proj2Geo(envelope.SpatialReference, envelope.XMin, envelope.YMin, ref gXMin, ref gYMin);
}
else
{
gXMax = envelope.XMax; gXMin = envelope.XMin;
gYMax = envelope.YMax; gYMin = envelope.YMin;
}
int cols =Convert.ToInt32(Math.Round(Degree.Degree2Second( - gXMin) / dxInSnd)) + ;
gridInfo.XMin = - Degree.Second2Degree(cols * dxInSnd);
cols = Convert.ToInt32(Math.Round(Degree.Degree2Second( - gXMax) / dxInSnd));
gridInfo.XMax = - Degree.Second2Degree(cols * dxInSnd); int rows = Convert.ToInt32(Math.Round(Degree.Degree2Second(gYMin) / dyInSnd));
gridInfo.YMin =Degree.Second2Degree(rows * dyInSnd);
rows = Convert.ToInt32(Math.Round(Degree.Degree2Second(gYMax) / dyInSnd)) + ;
gridInfo.YMax =Degree.Second2Degree( rows * dyInSnd); gridInfo.rows = Convert.ToInt32(Math.Round(Degree.Degree2Second(gridInfo.YMax - gridInfo.YMin) / dyInSnd));
gridInfo.cols = Convert.ToInt32(Math.Round(Degree.Degree2Second(gridInfo.XMax - gridInfo.XMin) / dxInSnd)); if (envelope.SpatialReference is IProjectedCoordinateSystem)
{
Geo2Proj(envelope.SpatialReference, gridInfo.XMax, gridInfo.YMax, ref pXMax, ref pYMax);
Geo2Proj(envelope.SpatialReference, gridInfo.XMin, gridInfo.YMin, ref pXMin, ref pYMin);
gridInfo.XMax = pXMax; gridInfo.XMin = pXMin;
gridInfo.YMax = pYMax; gridInfo.YMin = pYMin;
} return gridInfo;
}

  (3)图幅命名类

 public class FrameName
{
private int scale;
/// <summary>
///
/// </summary>
/// <param name="Scale">分数比例尺的分母(比例尺为1:50000则参数为50000)</param>
public FrameName(int Scale)
{
scale = Scale;
} public String getFrameName(double longtitude, double latitude)
{
int baseRowCount=(int)(latitude / );
char baseChar = Convert.ToChar('A' + baseRowCount);
int baseNum = (int)(longtitude / ) + ; if (scale == )
return String.Format("{0}{1}", baseChar, baseNum); char scaleChar = 'E'; //1:50000比例尺的代码为E,其他以后补充
switch (scale)
{
case :
scaleChar='B';break;
case :
scaleChar = 'C';break;
case :
scaleChar = 'D';break;
case :
scaleChar='E';break;
case :
scaleChar = 'F';break;
case :
scaleChar = 'G';break;
case :
scaleChar = 'H';break;
} double dxInSnd, dyInSnd;
switch (scale)
{
case :
dxInSnd = 0.03125;
dyInSnd = 0.0208333333;
break;
case :
dxInSnd = 0.0625;
dyInSnd = 0.0416666667;
break;
case :
dxInSnd = 0.125;
dyInSnd = 0.0833333333;
break;
case :
dxInSnd = 0.25;
dyInSnd = 0.1666666667;
break;
case :
dxInSnd = 0.5;
dyInSnd = 0.3333333333;
break;
case :
dxInSnd = 1.5;
dyInSnd = ;
break;
case :
dxInSnd = ;
dyInSnd = ;
break;
default:
dxInSnd = ;
dyInSnd = ;
break;
} if (dxInSnd == dyInSnd && dxInSnd == 0.0)
return null; int row = (int)(((baseRowCount + ) * - latitude)/dyInSnd) + ;
//int row = 24-((int)(latitude / dyInSnd)) % 24;
int col = (int)((longtitude % ) /dxInSnd) + ; return String.Format("{0}{1}{2}{3}{4}", baseChar, baseNum, scaleChar, row.ToString().PadLeft(, ''), col.ToString().PadLeft(, ''));
} }

  (4)调用函数进行分割

 private void CreateFrame(GridInfo gridInfo, String outDir, int scale)
{
double xLength = (gridInfo.XMax - gridInfo.XMin) / gridInfo.cols;
double yLength = (gridInfo.YMax - gridInfo.YMin) / gridInfo.rows;
FrameName frameName = new FrameName(scale); for (int i = ; i < gridInfo.rows; i++)
{
double yMin = gridInfo.YMin + i * yLength;
double yMax = gridInfo.YMin + (i + ) * yLength;
for (int j = ; j < gridInfo.cols; j++)
{
double xMin = gridInfo.XMin + j * xLength;
double xMax = gridInfo.XMin + (j + ) * xLength;
String pszOutFile; if (envelope.SpatialReference is IProjectedCoordinateSystem)
{
double prjX = 0.0, prjY = 0.0;
Proj2Geo(envelope.SpatialReference, (xMax + xMin) / , (yMax + yMin) / , ref prjX, ref prjY);
pszOutFile = frameName.getFrameName(prjX,prjY);
}
else
pszOutFile = frameName.getFrameName((xMax + xMin) / , (yMax + yMin) / );
pszOutFile = outDir + "\\" + pszOutFile + ".tif";
CutUpdateImageByAOIGDAL(rasterLyr.FilePath, pszOutFile, xMin, xMax, yMin, yMax, "GTiff");
}
}
}

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

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

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

    最近有个项目,其中有个功能是要将遥感影像按标准图幅分割,一开始用AE的接口,慢的让人抓狂,就改用GDAL,速度提升很大.我主要通过http://blog.csdn.net/liminlu0314/学习 ...

  2. 【GIS】GDAL Python 影像裁剪

    # -*- coding: utf-8 -*- """ Created on Fri Nov 30 11:45:03 2018 @author: Administrato ...

  3. C#+GDAL读取影像(1)

    环境:VS2010,C#,GDAL1.7 读取影像: using System; using System.Collections.Generic; using System.ComponentMod ...

  4. GDAL读取影像并插值

    影像读取 并缩放 读取大影像某一部分,并缩放到指定大小,我们有时会用如下代码: #include "gdal.h" #include "gdal_priv.h" ...

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

    一.概述 遥感影像和地理坐标进行关联的方式一般有好几种,一种是直接给出了仿射变换系数,即6个參数,左上角地理坐标,纵横方向上的分辨率,以及旋转系数.在这样的情况下,求出某一像素点的地理坐标非常easy ...

  6. gdal 遥感影像水体数据提取

  7. [APUE]标准IO库(下)

    一.标准IO的效率 对比以下四个程序的用户CPU.系统CPU与时钟时间对比 程序1:系统IO 程序2:标准IO getc版本 程序3:标准IO fgets版本 结果: [注:该表截取自APUE,上表中 ...

  8. python标准模块(下)

    Python 系统标准模块(shutil.logging.shelve.configparser.subprocess.xml.yaml.自定义模块) 目录: shutil logging模块 she ...

  9. 标准WPS框架下的空间信息处理服务部署方法

    笔者第一篇博客里面曾介绍过将专题图制作功能发布为WPS,但随着后面的研究,才发现那时候发布的不是真正WPS框架下的服务,而只是通过Servlet将其发布为可调用的网络服务,所以今天再具体介绍一下真正的 ...

随机推荐

  1. Python thread local

    由于GIL的原因,笔者在日常开发中几乎没有用到python的多线程.如果需要并发,一般使用多进程,对于IO Bound这种情况,使用协程也是不错的注意.但是在python很多的网络库中,都支持多线程, ...

  2. 读书笔记 effective c++ Item 16 成对使用new和delete时要用相同的形式

    1. 一个错误释放内存的例子 下面的场景会有什么错? std::]; ... delete stringArray 一切看上去都是有序的.new匹配了一个delete.但有一些地方确实是错了.程序的行 ...

  3. 解析jQuery中extend方法--用法《一》

    extend方法在jQuery中是一个很重要的方法,jQuey内部用它来扩展属性方法.常用语jQuery插件开发. jQuery提供了两个方法,$.extend和$.fn.extend,两个方法内部实 ...

  4. 20130620—ant和java杂学随笔

    ant知识点: 1.使用属性定义相对路径的时候,一定要使用location,而不要去使用value  对于<property></property>中location和valu ...

  5. CSS 3 过渡效果之jquery 的fadeIn ,fadeOut

    .div { visibility: hidden; opacity: 0; transition: visibility 0s linear 0.5s,opacity 0.5s linear; } ...

  6. js实现二级联动下拉列表菜单

    二级联动下拉列表菜单的难点在于对后台返回的数据进行解析,不多逼逼,直接上代码 上图是后台返回的数据 实现代码如下: var deviceNotExist = true;//防止数据重复 if(data ...

  7. MyBatis的类型自定义映射

    背景 利用MyBatis将数据库的时间类型映射成Java8的时间类型,引申对不同类型的自定义映射 实现方法 1.实现MyBatis中TypeHandler接口 @MappedTypes(value = ...

  8. “使用多target来构建大量相似App”,唐巧大神理论验证(附工程代码地址)

    无意间看到巧神的文章时,感觉非常兴奋,此文章正好解决了公司目前项目的痛点. 读到以下关键一段时,不甚明了,故自己做了实验分享给有缘人. "我们的每个课程的资源文件都具有相同的文件名,例如首页 ...

  9. 使用Spring构建RMI服务器和客户端

    上一篇文章我们实用JDK原生API构造了简单RMI应用,本篇将实用Spring框架来构造RMI的应用,实用Spring你会体验到简单,不需要那么多的条条框框,因为Spring给你做了很多封装. 项目构 ...

  10. React组件开发(一)初识React

    *React不属于MVC.MVVM,只是单纯的V层. *React核心是组件(提高代码复用率.降低测试难度.代码复杂度). *自动dom操作,状态对应内容. *React核心js文件:react.js ...