GDAL库学习笔记(1):无缝拼接Google卫星图
开工之前要先了解一下瓦片地图,瓦片地图金字塔模型是一种多分辨率层次模型,从瓦片金字塔的底层到顶层,分辨率越来越低,但表示的地理范围不变。实现原理就是,首先确定地图服务平台所要提供的缩放级别的数量N,把缩放级别最低、地图比例尺最大的地图图片作为金字塔的底层,即第0层,并对其进行分块,从地图图片的左上角开始,从左至右、从上到下进行切割,分割成相同大小(比如256x256像素)的正方形地图瓦片,形成第0层瓦片矩阵;在第O层地图图片的基础上,按每2x2像素合成为一个像素的方法生成第1层地图图片,并对其进行分块,分割成与下一层相同大小的正方形地图瓦片,形成第1层瓦片矩阵;采用同样的方法生成第2层瓦片矩阵;…;如此下去,直到第N一1层,构成整个瓦片金字塔。
在Google地图中,地图数据由大量的正方形图片组成。共有2级缩放比例,每个地图图片都有坐标值,由X和Y值构成。比例因子zoom取值范围是(0-22)。操作地图滑竿显示更大比例尺地图时,图片的数量发生裂变。两种模式在请求及响应的速度方面有明显的差异,基于地图瓦片服务框架的响应速度要快于传统的WebGIS,同时对地图服务器的负载也相应小一些。
现在可以开工,首先准备好瓦片地图,如果是用来学习研究的话,我们可以通过一些第三方工具(当然自己写一个也可以)从谷歌地图抓取瓦片地图存放到本地,例如以C:\googlemas\satelite\x\y.jpg的格式存放,其中x,y,z分别代瓦片所在的列、行、缩放等级。


有了这些图我们开始拼接了,关于gdal库的介绍的文章很多了,现在我主要是介绍如何用C#来拼接谷歌地图,废话不多说了,直接上代码:

void SaveBitmapBuffered(Dataset src, Dataset dst, int x, int y)
{
if (src.RasterCount < 3) {
System.Environment.Exit(-1);
} // Get the GDAL Band objects from the Dataset
Band redBand = src.GetRasterBand(1);
Band greenBand = src.GetRasterBand(2);
Band blueBand = src.GetRasterBand(3); // Get the width and height of the raster
int width = redBand.XSize;
int height = redBand.YSize; byte[] r = new byte[width * height];
byte[] g = new byte[width * height];
byte[] b = new byte[width * height]; redBand.ReadRaster(0, 0, width, height, r, width, height, 0, 0);
greenBand.ReadRaster(0, 0, width, height, g, width, height, 0, 0);
blueBand.ReadRaster(0, 0, width, height, b, width, height, 0, 0); Band wrb = dst.GetRasterBand(1);
wrb.WriteRaster(x * width, y * height, width, height, r, width, height, 0, 0);
Band wgb = dst.GetRasterBand(2);
wgb.WriteRaster(x * width, y * height, width, height, g, width, height, 0, 0);
Band wbb = dst.GetRasterBand(3);
wbb.WriteRaster(x * width, y * height, width, height, b, width, height, 0, 0);
} /// <summary>
/// 拼接瓦片
/// </summary>
/// <param name="tilesBounds"></param>
/// <param name="tilePath"></param>
/// <param name="outPutFileName"></param>
public void CombineTiles(TilesBounds tilesBounds, string tilePath, string outPutFileName)
{
if (File.Exists(outPutFileName))
{
File.Delete(outPutFileName);
}
int imageWidth = 256 * (tilesBounds.maxCol - tilesBounds.minCol + 1);
int imageHeight = 256 * (tilesBounds.maxRow - tilesBounds.minRow + 1); //Register driver(s).
Gdal.AllRegister();
Driver driver = Gdal.GetDriverByName("GTiff");
Dataset destDataset = driver.Create(outPutFileName, imageWidth, imageHeight, 3, DataType.GDT_Byte, null); for (int col = tilesBounds.minCol; col <= tilesBounds.maxCol; col++)
{
for (int row = tilesBounds.minRow; row <= tilesBounds.maxRow; row++)
{
try
{
string sourceFileName = tilePath + tilesBounds.zoomLevel.ToString() + "\\" + col.ToString() + "\\" + row.ToString() + ".jpg";
if (File.Exists(sourceFileName))
{
Dataset sourceDataset = Gdal.Open(sourceFileName, Access.GA_ReadOnly);
if (sourceDataset != null)
{
SaveBitmapBuffered(sourceDataset, destDataset, col - tilesBounds.minCol, row - tilesBounds.minRow);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
destDataset.Dispose(); } //调用
TilesBounds tilesBounds = new TilesBounds();
tilesBounds.minCol = 107901;
tilesBounds.maxCol = 107926;
tilesBounds.minRow = 49652;
tilesBounds.maxRow = 49668;
tilesBounds.zoomLevel = 17;
string outPutFileName = "c:\\北京卫星图" + tilesBounds.zoomLevel.ToString() + ".tif";
string tilePath = "C:\\googlemaps\\\satelite\\";
CombineTiles(tilesBounds, tilePath, outPutFileName);

ok,大功告成了,看看效果图吧。

GDAL库学习笔记(1):无缝拼接Google卫星图的更多相关文章
- numpy, matplotlib库学习笔记
Numpy库学习笔记: 1.array() 创建数组或者转化数组 例如,把列表转化为数组 >>>Np.array([1,2,3,4,5]) Array([1,2,3,4,5]) ...
- muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor
目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...
- muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制
目录 muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制 eventfd的使用 eventfd系统函数 使用示例 EventLoop对eventfd的封装 工作时序 runInLoo ...
- muduo网络库学习笔记(三)TimerQueue定时器队列
目录 muduo网络库学习笔记(三)TimerQueue定时器队列 Linux中的时间函数 timerfd简单使用介绍 timerfd示例 muduo中对timerfd的封装 TimerQueue的结 ...
- C++STL标准库学习笔记(三)multiset
C++STL标准库学习笔记(三)multiset STL中的平衡二叉树数据结构 前言: 在这个笔记中,我把大多数代码都加了注释,我的一些想法和注解用蓝色字体标记了出来,重点和需要关注的地方用红色字体标 ...
- 【python】numpy库和matplotlib库学习笔记
Numpy库 numpy:科学计算包,支持N维数组运算.处理大型矩阵.成熟的广播函数库.矢量运算.线性代数.傅里叶变换.随机数生成,并可与C++/Fortran语言无缝结合.树莓派Python v3默 ...
- C++STL标准库学习笔记(一)sort
前言: 近来在学习STL标准库,做一份笔记并整理好,方便自己梳理知识.以后查找,也方便他人学习,两全其美,快哉快哉! 这里我会以中国大学慕课上北京大学郭炜老师的<程序设计与算法(一)C语言程序设 ...
- Java学习笔记(四)——google java编程风格指南(上)
[前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...
- Java学习笔记(五)——google java编程风格指南(中)
[前面的话] 年后开始正式上班,计划着想做很多事情,但是总会有这样那样的打扰,不知道是自己要求太高还是自我的奋斗意识不够?接下来好好加油.好好学学技术,好好学习英语,好好学习做点自己喜欢的事情,趁着自 ...
随机推荐
- ipython的notebook
ipython是增强的python交互式shell.而notebook是在浏览器上运行ipython ubuntu下安装: sudo apt-get install ipython3 sudo apt ...
- 变形课(DFS hdu 1181)
变形课 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submis ...
- ubuntu 中c 语言编程(学习)
ubuntu下c编程 c编程中相关文件后缀 .a 静态库(archive .c C源代码(需要编译预处理) .h C源代码头文件 .i C源代码 (不需要编译预处理) ...
- VS_QT中配置qDebug输出
在使用qt_create时可以使用qDebug进行调试输出.在VS中也可以使用.但需要配置.配置过程如下图所示: 一.首先右击工程名,选择最后一个选项“Properties” 二.然后选择Linker ...
- QTableView中嵌入复选框CheckBox 的四种方法总结
搜索了一下,QTableView中嵌入复选框CheckBox方法有四种: 第一种不能之前显示,必须双击/选中后才能显示,不适用. 第二种比较简单,通常用这种方法. 第三种只适合静态显示静态数据用 第四 ...
- 关于Redis的一些常识
http://blog.csdn.net/mengxianhua/article/details/8961713 关于Redis的一些常识 2013-05-22 18:00 13315人阅读 评论(0 ...
- [置顶] SPL讲解(4)--Criteria操作篇
概念 以前一篇文章中,描述了实体Entity的操作,很明显,仅仅实体的操作是远远不够的.如:我们经常会根据查询条件从数据库中获取记录集并绑定到DataGrid上,会根据条件进行批量的Update和De ...
- [转]ActiveMQ 即时通讯服务 浅析
一. 概述与介绍 ActiveMQ 是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provide ...
- JQuery中阻止事件冒泡方式及其区别
JQuery 提供了两种方式来阻止事件冒泡. 方式一:event.stopPropagation(); $("#div1").mousedown(function( ...
- IEEE发布2016年度编程语言排行榜
C 语言占据榜首,但大数据类是最大赢家. IEEE Spectrum 的第三次"最受欢迎编程语言"交互式排行榜新鲜出炉.因为不可能顾及到每一个程序员的想法,Spectrum 使用多 ...