geotrellis使用(十四)导出定制的GeoTiff
Geotrellis系列文章链接地址http://www.cnblogs.com/shoufengwei/p/5619419.html
目录
一、前言
最近一段时间比较忙,没能继续推进Geotrellis项目开发,周末和这两天抽空又实现了一个功能——导出自定义的Tiff文件。又恰巧碰上今天这么重要的日子,当然要写点东西来纪念一下,所以就有了这篇文章,闲话莫说,进入正题。
二、需求说明
很多时候我们需要从一块(或者很多块)大的Tiff中根据需要截取一部分数据,并且需要采用某种采样方式转成特定的投影,并转成需要的数据类型。当然有人会说这个很容易,用GDAL的gdaltransform等可以很容易的实现此功能,GDAL是很强大,但是前提是你的数据不能太大并且只能处理单块栅格数据。正因为有这些问题,所以我实现了使用Geotrellis来实现该功能,下面我就为大家分析实现方法。
之前讲了很多数据处理方式,其中。
三、实现方案
1.前台界面
前台就是一个简单的地图控件,外加几个选择器。地图控件主要为了浏览区域以及手工选取想要导出的Tiff的范围,选择器主要选择目标投影方式、数据类型以及采样方式。根据用户的选择将请求采用ajax的方式发送到后台进行处理。这块不是本文的重点,不在这里具体介绍。
2.数据导入
要想处理大数据或者处理多块栅格数据就不能直接处理栅格数据,可以先将栅格数据导入到Accumulo中,当然导入之后是一块块的瓦片,这部分在geotrellis使用(三)geotrellis数据处理过程分析一文中已经进行了详细介绍,这里还是要说明的是参数layoutScheme一定要选择floating,这样在Accumulo中保存的就是原始只是切割而未经过其他处理的数据。
3.读取数据
Accumulo中已经存储了需要的数据,并且后台接收到了前台用户选择的区域范围以及投影方式、数据类型、采样方式,这样我们就可以开始实现读取需要的数据,简单的说就是从Accumulo中取出与用户选定区域有交集的数据(瓦片),实现代码如下:
val raster = reader.read[SpatialKey, Tile, TileLayerMetadata[SpatialKey]](layerId)
val masked = raster.mask(polygon)
是不是很容易,就这两句话,其中reader是AccumuloLayerReader实例,layerId表示读取的层,polygon是用户选取的范围。首先从Accumulo中读出该层数据,然后与polygon做一个mask,得到的结果就是用户想要导出的数据。
4.数据转换
4.1 得到结果瓦片数据
首先将上述得到的瓦片集做一个拼接,这样就会得到一个大的瓦片,代码也很简单,如下:
val stitch = masked.stitch
val tile = stitch.tile
4.2 得到最终结果
之后要做的就是根据采样类型、投影方式以及数据类型将上述tile进行转换,代码如下:
val rep = tile.reproject(extent, srcCRS, dstCRS, method).tile
val res = rep.convert(cellType)
其中extent是瓦片的范围,可以用上述拼接对象stitch的stitch.extent得到,srcCRS是原始数据的投影类型,可以通过上述raster对象的raster.metadata.crs得到,dstCRS表示目标投影方式,即用户想要的投影方式,同样method表示采样方法,cellType表示数据类型,这三个的获取方式我会重点介绍。
4.3 获取dstCRS、resampleMethod、cellType
首先可以肯定的是前端传来的这三个参数都是字符串型的,这就要求后台将字符串转成相应的类型。
投影方式我这里投了个懒,传递的是EPSG CODE,EPSG是投影方式的一种数字编码,具体请见:http://www.epsg.org/。总之每一个EPSG编码对应了一种投影方式,像常见的经纬度投影的编码是4326,WebMercator的编码是3857。有了这个编码之后就可以很容易的得到投影方式,代码如下:
try{
CRS.fromEpsgCode(epsg)
}
catch {
case _ => CRS.fromEpsgCode(3857)
}
采样方式和数据类型就稍显麻烦,我这里采用了反射的方式获取对应实例,我将反射的代码进行了封装,代码如下L:
def getClassName(name: String, hasEndWith$: Boolean) = {
var className = name
if (hasEndWith$) {
if (!className.endsWith("$"))
className += "$"
}
else {
if (className.endsWith("$"))
className = className.substring(0, className.length - 1)
}
className
}
def getClassFor[T: ClassTag](name: String, hasEndWith$: Boolean) = {
val className = getClassName(name, hasEndWith$)
Try[Class[_ <: T]]({
val c = Class.forName(className, false, getClass.getClassLoader).asInstanceOf[Class[_ <: T]]
val t = implicitly[ClassTag[T]].runtimeClass
if (t.isAssignableFrom(c)) c else throw new ClassCastException(t + " is not assignable from " + c)
})
}
def getInstanceByReflact[T: ClassTag](name: String) = {
val classTry = getClassFor[T](name, true) recoverWith { case _ => getClassFor[T](name, false) }
classTry flatMap{
c =>
Try{
val module = c.getDeclaredField("MODULE$") //通过获得变量"MODULE$"来初始化
module.setAccessible(true)
val t = implicitly[ClassTag[T]].runtimeClass
module.get(null) match {
case null => throw new NullPointerException
case x if !t.isInstance(x) => throw new ClassCastException(name + " is not a subtype of " + t)
case x: T => x
}
} recover{ case i: InvocationTargetException if i.getTargetException ne null => throw i.getTargetException }
}
这段代码看上去很复杂,其实是做了很多判断加强程序稳定性用的的,主要功能就是一个类的全名(包含包名)创建其实例。
有了上述代码之后就可以将前台传来的字符串直接转换为相应的实例,获取采样方式的代码如下:
val resample = s"geotrellis.raster.resample.${resampleStr}"
val method = getInstanceByReflact[ResampleMethod](resample)
if(method.isSuccess) {
println(method.get.toString)
method.get
}
else {
Bilinear
}
前台只需传入采样方式名称即可,如Bilinear,这样就会自动获取其实例。
获取数据类型同理,代码如下:
val className = getCellTypeClassName(dataTypeStr)
val cellType = getInstanceByReflact[CellType](className)
if(cellType.isSuccess) {
cellType.get
}
else {
ByteConstantNoDataCellType
}
这样就可实现获取用户想要的投影方式、采样方法以及数据类型。
四、总结
以上就是使用Geotrellis实现导出定制的GeoTiff的方法,由于时间紧,可能还有很多没有注意的细节,会在后续中进一步研究,并更新该文或者另设新篇。在这里我也呼吁大家都来撰写技术博客,一来提高自己,进行技术总结;二来真的是可以帮助别人。最近在工作中碰到很多莫名其妙的BUG,但是基本都在一番搜索之后在别人的博客中找到了解决方案,所以在此也感谢那些愿意写博客的人,希望大家都能加入进来。
geotrellis使用(十四)导出定制的GeoTiff的更多相关文章
- SpringBoot入门教程(十四)导出Excel
用JavaPOI导出Excel时,我们会考虑到Excel版本及数据量的问题.针对不同的Excel版本,要采用不同的工具类.HSSFWorkbook:是操作Excel2003以前(包括2003)的版本, ...
- geotrellis使用(四)geotrellis数据处理部分细节
前面写了几篇博客介绍了Geotrellis的简单使用,具体链接在文后,今天我主要介绍一下Geotrellis在数据处理的过程中需要注意的细节,或者一些简单的经验技巧以供参考. 一.直接操作本地Geot ...
- WCF技术剖析之十四:泛型数据契约和集合数据契约(下篇)
原文:WCF技术剖析之十四:泛型数据契约和集合数据契约(下篇) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]在.NE ...
- spring boot 常见三十四问
Spring Boot 是微服务中最好的 Java 框架. 我们建议你能够成为一名 Spring Boot 的专家. 问题一 Spring Boot.Spring MVC 和 Spring 有什么区别 ...
- 我的MYSQL学习心得(十四) 备份和恢复
我的MYSQL学习心得(十四) 备份和恢复 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) ...
- SNF开发平台WinForm之十四-站内发送系统信息-SNF快速开发平台3.3-Spring.Net.Framework
1运行效果: 2开发实现: .组装站内信息发送实体对象. SNFService SNFService = new SNFService(); if (this.ucUser.SelectedIds ! ...
- 《sed的流艺术之四》-linux命令五分钟系列之二十四
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- 从零开始学习PYTHON3讲义(十四)写一个mp3播放器
<从零开始PYTHON3>第十四讲 通常来说,Python解释执行,运行速度慢,并不适合完整的开发游戏.随着电脑速度的快速提高,这种情况有所好转,但开发游戏仍然不是Python的重点工作. ...
- 实验十四 第九组 张燕~杨蓉庆~杨玲 Swing图形界面组件
实验十四 Swing图形界面组件 8-11-29 理论知识 Swing和MVC设计模式 (1)设计模式(Design pattern)是设计者一种流行的 思考设计问题的方法,是一套被反复使用,多数人 ...
随机推荐
- About_PHP读写文件
1.PHP部分文件操作函数:fopen ,fread ,filesize,fwrite,fclose 2.unlink() rmdir() 删除函数 unlink() 删除文件函数:unlink(路径 ...
- PHP:( && )逻辑与运算符使用说明
第一次看到以下语句的写法大惑不解 ($mCfg['LockChinaIp']==1 && (int)$_SESSION['AdminUserId']==0 && sub ...
- 使用Prerender.io为angular项目做SEO
现在的项目的为了更好的分工明确,降低耦合都开始采用前后端分离的形式进式开发,我们也采用这种开发形式,前端用angular开发.虽说刚开始也遇各种坑,但是后期熟悉了之后简直爽呆.一个比较大的坑就是SEO ...
- 在一定[min,max]区间,生成n个不重复的随机数的封装函数
引:生成一个[min,max]区间的一个随机数,随机数生成相关问题参考→链接 var ran=parseInt(Math.random()*(max-min+1)+min); //生成一个[min,m ...
- siteserver cms选择栏目搜索无效
标签必须以空格分开,且option 的value必须给id不能给名称
- SQL多表合并查询结果
两表合并查询,并同时展示及分页SELECT a.* FROM ( ( SELECT punycode, `domain`, 'Success' AS state, add_time, AS refun ...
- 性能分析工具-PerfView
Roslyn的PM(程序经理) Bill Chiles,Roslyn使用纯托管代码开发,但性能超过之前使用C++编写的原生实现,这有什么秘诀呢?他最近写了一篇文章叫做<Essential Per ...
- Webix JavaScript UI 库可以帮你构建跨平台的HTML5 和 CSS3 程序
XB 软件公司最近发布了JavaScript UI 库Webix ,其中包含的组件超过45个,用这些组件可以构建跟HTML5 和 CSS3 兼容的程序,这些程序不仅能在个人电脑上运行,还能用在iOS. ...
- 使用 WPF+ ASP.NET MVC 开发 在线客服系统 (一)
近段时间利用业余时间开发了一套在线客服系统,期间遇到过大大小小不少问题,好在都一一解决,最终效果也还可以,打算写一个系列的文章把开发过程详细的记录下来. 希望能够和更多的开发人员互相交流学习,也希望有 ...
- 可扩容分布式session方案
分布式session有以下几种方案: 1. 基于nfs(net filesystem)的session共享 将共享服务器目录mount各服务器的本地session目录,session读写受共享服务器i ...