geotrellis使用(三)geotrellis数据处理过程分析
之前简单介绍了geotrellis的工作过程以及一个简单的demo,最近在此demo的基础上实现了SRTM DEM数据的实时分析以及高程实时处理,下面我就以我实现的上述功能为例,简单介绍一下geotrellis的数据处理过程。
一、原始数据处理
geotrellis支持geotiff的栅格数据(矢量数据还未研究),可以将geotiff直接缓存至hadoop框架下的Accumulo NOSQL数据库,并建立金字塔等,具体处理过程在geotrellis.spark.etl.Etl类中。具体代码如下:
def ingest[
I: Component[?, ProjectedExtent]: TypeTag: ? => TilerKeyMethods[I, K],
K: SpatialComponent: Boundable: TypeTag,
V <: CellGrid: TypeTag: Stitcher: (? => TileReprojectMethods[V]): (? => CropMethods[V]): (? => TileMergeMethods[V]): (? => TilePrototypeMethods[V])
](
args: Seq[String], keyIndexMethod: KeyIndexMethod[K], modules: Seq[TypedModule] = Etl.defaultModules
)(implicit sc: SparkContext) = {
implicit def classTagK = ClassTag(typeTag[K].mirror.runtimeClass(typeTag[K].tpe)).asInstanceOf[ClassTag[K]]
implicit def classTagV = ClassTag(typeTag[V].mirror.runtimeClass(typeTag[V].tpe)).asInstanceOf[ClassTag[V]] /* parse command line arguments */
val etl = Etl(args)
/* load source tiles using input module specified */
val sourceTiles = etl.load[I, V]
/* perform the reprojection and mosaicing step to fit tiles to LayoutScheme specified */
val (zoom, tiled) = etl.tile(sourceTiles)
/* save and optionally pyramid the mosaiced layer */
etl.save[K, V](LayerId(etl.conf.layerName(), zoom), tiled, keyIndexMethod)
重要的就是参数args,geotrellis根据不同的参数将数据进行不同的处理。具体的参数信息在https://github.com/geotrellis/geotrellis/blob/master/docs/spark-etl/spark-etl-intro.md
中均有介绍,这里介绍一些重要的配置。
二、发起服务
要对外提供数据,系统首先要能够发起服务,geotrellis建立一个服务也很容易,只需要使用以下语句系统遍自动的在host和相应的port上发起服务。
IO(Http) ! Http.Bind(service, host, port)
具体路由信息需要在service类中定义。service类需要继承Actor方法,并覆盖父类的receive方法。
override def receive = runRoute(serviceRoute)
def serviceRoute = get {
pathPrefix("gt") {
pathPrefix("tms")(tms) ~
path("geoTiff")(geoTiff)
} ~
pathEndOrSingleSlash {
getFromFile(staticPath + "/index.html")
} ~
pathPrefix("") {
getFromDirectory(staticPath)
}
}
以上就是建立了service的路由匹配表以及具体的控制器。当只请求IP及相应端口时会请求index.html,请求gt/tms时交给tms控制器,gt/geotiff交给geotiff控制器,其他会去匹配静态地址,如图片、
js、css等。
三、瓦片调用
WOLayer = new L.tileLayer(server +
'gt/tms/{z}/{x}/{y}', {
format: 'image/png',
});
WOLayer.addTo(map);
前台便会请求后台的tms控制器,tms控制器定义如下:
tms获取到请求的x、y、z、值,并从Accumulo中取出相应的瓦片交给leaftlet,leaflet将瓦片数据放到合适的位置,便完成了瓦片的加载,从Accumulo中取出瓦片的的大致代码如下:
val tile: Tile = tileReader.reader[SpatialKey, Tile](LayerId(LayerName, zoom)).read(key)
其中tileReader是一个AccumuloValueReader对象,很明显看出此对象是一个有关Accumulo的对象,其中包含Accumulo的用户密码等。LayerName就是上文中导入数据时候设置的layer参数对应的值。key是个SpatialKey对象,val key = SpatialKey(x, y),记录了瓦片x、y编号值。读到瓦片之后将数据发送到前台的代码如下:
respondWithMediaType(MediaTypes.`image/png`) {
val result = tile.renderPng().bytes
complete(result)
}
其实就是调用Tile类的renderPng方法,然后将Png数据转换成bytes发送到前端。
四、高级瓦片调用
val maskedTile = {
val poly = maskz.parseGeoJson[Polygon]
val extent: Extent = attributeStore.read[TileLayerMetadata[SpatialKey]](LayerId(LayerName, zoom), Fields.metadata).mapTransform(key)
tile.mask(extent, poly.geom)
}
其中maskz是前端想要显示内容的区域(Polygon),attributeStore是AccumuloAttributeStore对象,同样可以看出是一个操作Accumulo的对象,attributeStore主要完成的功能就是读取当前瓦片的extent即外接矩形范围。通过调用Tile类的mask方法将请求的polygon与extent做交集,只取相交的部分的数据,再将此数据发到前端,在前端便能看到只显示设定区域内瓦片的效果。
五、统计分析
val layerId = LayerId(layer, 0)
val raster = reader.read[SpatialKey, Tile, TileLayerMetadata[SpatialKey]](layerId)
val masked = raster.mask(polygon)
val mapTransform = masked.metadata.mapTransform
val maps = masked map { case (k: SpatialKey, tile: Tile) =>
val extent: Extent = mapTransform(k)
val hist: Histogram[Int] = tile.polygonalHistogram(extent, extent.toPolygon()) var max, min = hist.maxValue().getOrElse(0)
var count:Long = 0
var sum : Double = 0
hist.foreach((s1:Int, s2:Long) => {
if (max < s1) max = s1
if (min > s1) min = s1
sum += s1 * s2
count += s2
})
(max, min, sum, count)
}
val (max, min, sum, count) = maps reduce { case ((z1, a1, s1, c1), (z2, a2, s2, c2)) => (Math.max(z1, z2), Math.min(a1, a2), s1 + s2, c1 + c2) }
val avg = sum / count
val layerId = LayerId(layer, 0)表示取的是导入数据的第0层,由于使用floating方式此处必须是0。reader是一个AccumuloLayerReader对象,此处与上面的AccumuloVlaueReader不同之处在于上文中取固定key值得瓦片,此处需要根据范围进行选择,masked就是根据polygon筛选出的结果,是一个RDD[(SpatialKey, Tile)]对象,即存储着范围内的所有瓦片以及其编号信息。对masked进行map操作,获取其单个瓦片的extent,以及polygon内的统计信息,算出最大值,最小值以及高程加权和。最后对结果进行reduce操作,获取整体的最大值、最小值、平均值。(此处平均值算法可能不妥,希望有更好建议的能够留言,感激!)。将计算到的结果发到前端,前端就能实时显示统计分析结果。
六、结尾
geotrellis的功能非常强大,此处只是冰山一脚,后续还会进行相关研究,经验心得会及时总结到这里,以使自己理解的更加透彻,如果能帮助到其他人也是极好的!
七、参考链接
一、geotrellis使用初探
二、geotrellis使用(二)geotrellis-chatta-demo以及geotrellis框架数据读取方式初探
三、geotrellis使用(三)geotrellis数据处理过程分析
geotrellis使用(三)geotrellis数据处理过程分析的更多相关文章
- TCP 协议三次握手过程分析
TCP 协议三次握手过程分析 TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: ...
- jmeter BeanShell断言(三)数据处理
在做接口测试时,对响应数据的校验是非常重要的部分:在使用Jmeter进行接口测试时,有多种respone校验方式,比如响应断言.BeanShell断言等等,BeanShell断言可以自定义断言,自由灵 ...
- TCP协议三次握手过程分析【图解,简单清晰】
转自:http://www.cnblogs.com/rootq/articles/1377355.html TCP(Transmission Control Protocol) 传输控制协议 TCP是 ...
- TCP协议三次握手过程分析
TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...
- TCP协议三次握手过程分析(改)
TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标 ...
- 三 Hive 数据处理 自定义函数UDF和Transform
三 Hive 自定义函数UDF和Transform 开篇提示: 快速链接beeline的方式: ./beeline -u jdbc:hive2://hadoop1:10000 -n hadoop 1 ...
- SSMP一次请求数据处理过程分析
控制器代码 @RequestMapping("/changeUserPwd") public TranMessage changeUserPwd(String oriPwd, St ...
- geotrellis使用(四)geotrellis数据处理部分细节
前面写了几篇博客介绍了Geotrellis的简单使用,具体链接在文后,今天我主要介绍一下Geotrellis在数据处理的过程中需要注意的细节,或者一些简单的经验技巧以供参考. 一.直接操作本地Geot ...
- geotrellis使用(三十)使用geotrellis读取PostGIS空间数据
前言 最近事情很多,各种你想不到的事情--such as singing and dancing--再加上最近又研究docker上瘾,所以geotrellis看上去似乎没有关注,其实我一直在脑中思考着 ...
随机推荐
- 安装使用Oracle OSWbb/OSWbba工具
OSWbb是收集数据,OSWbba 是分析数据,在OSWbb4.0以后,OSWbba已经绑定在OSWbb内. 1.创建目录,上传/解压安装包 [oracle@std ~]$ mkdir oswbb [ ...
- 【转】最大流EK算法
转自:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html 图-1 如图-1所示,在这个运输网络中,源点S和汇点T分别是1,7 ...
- 【转】WriteMessage的信息在AutoCAD中命令行中实时显示
之前程序中有段发送信息到命令行上显示的代码,如下: ed.WriteMessage("开始标注横断面高程,请稍候!"); 但是发现命令行中并不马上显示,代码也明明运 ...
- Spket在Eclipse下的安装和配置(图文教程)
一.Spket简介 Spket是一个RIA的开发工具,具有代码自动完成.语法高亮.内容概要等功能,可以帮助开发人员高效的编写JavaScript程序. 效果图: 二.安装Spket 1.去官网(htt ...
- MapleSim助力长臂挖掘机建模问题解决
1.问题描述 一家机械零部件设计公司需要一个挖掘机模型,验证他们的零部件是否匹配完整的挖掘机系统.由于他们是一个零部件供应商,公司没有足够的资源和研发人员使用传统的工具创建一个完整系统的详细模型.然而 ...
- 基于 Jenkins 快速搭建持续集成环境
什么是持续集成 随着软件开发复杂度的不断提高,团队开发成员间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题.尤其是近些年来,敏捷(Agile) 在软件工程领域越来越红火 ...
- CSP的今世与未来
一.从两个工具说起 最近Google又推出了两款有关CSP利用的小工具,其一为CSP Evaluator,这是一个能够评估你当前输入的CSP能否帮助你有效避免XSS攻击的工具,其用法非常简单,在输入框 ...
- 一步步学习javascript基础篇(3):Object、Function等引用类型
我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...
- 【腾讯Bugly干货分享】微信小程序开发思考总结——腾讯“信用卡还款”项目实践
本文来自于腾讯bugly开发者社区,未经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/58212d0fa7a7574c4f4cc3c5 作者:peggy 小程序概述 1 ...
- 如何在Visual Studio 工程之间共享静态内容 (js, css, img, etc.)
第一步: 文件夹上点击右键 -> Add -> Existing Item,单击选中文件,不要点击“Add”按钮,而是在“Add”按钮右边有个向下的小箭头,点击这个箭头,再点击“Add ...