geotrellis使用(十七)使用缓冲区分析的方式解决单瓦片计算边缘值问题

Geotrellis系列文章链接地址http://www.cnblogs.com/shoufengwei/p/5619419.html

目录

  1. 前言
  2. 需求分析
  3. 实现方案
  4. 总结

一、前言

       最近真的是日理千机,但是再忙也要抽出时间进行总结。上一篇文章讲了使用缓冲区分析的方式解决投影变换中边缘数据值计算的问题(见geotrellis使用(十六)使用缓冲区分析的方式解决投影变换中边缘数据值计算的问题)。实际中往往还有一种需求就是对单个瓦片进行操作,比如求坡度等,如果这时候直接计算,同样会出现边缘值计算的问题,这种情况也可以使用上一篇文章中讲到的方法进行处理。

二、需求分析

       假如我们想在前台地图中实时显示坡度图像,有两种方式:第一种是在DEM数据导入Accumulo之前先求坡度(可以使用传统的GDAl、也可以使用Geotrellis),然后再导入;第二种是直接将DEM数据导入Accumulo中,后台实时计算每幅瓦片的坡度,然后渲染到前台。两种方式各有各的好处,采用第一种方式,整体处理简单,显示的速度快,但是Accumulo中要存两份数据。第二种方式,实现起来稍显复杂,显示的速度稍慢,但是Accumulo中只存了一份数据。由于Geotrellis基于Spark集群,所以如果集群足够优秀,处理速度不是很重要的问题,但是如果我们需要对同一个数据进行多种操作,或者根据用户的需求来进行操作,那么就没有办法完成数据的预处理工作,只能进行实时计算,如果计算只针对瓦片中的单一像素则还不涉及到边缘值的问题,而如果需要进行插值采样等操作(如求坡度、山影等),这时候就会出现上文中讲到的瓦片边缘值计算的问题。本文就为大家讲解如何使用缓冲区分析的方式解决单瓦片计算边缘值问题。

三、实现方案

       至于求坡度等的具体算法不在这里介绍,都是很成熟的算法,并且Geotrellis中也已经实现了一些算法,只需调用相应的函数即可。有关缓冲区分析等也在之前的文章介绍过多次,不在这里赘述。

1.数据读取

       此处读的数据为没有进行过任何处理的原始DEM数据,具体读写数据也在之前的文章中介绍过,详情见geotrellis使用(三)geotrellis数据处理过程分析等文章。

       但是此处不同的是我们为了完成边缘值计算,就需要将单幅瓦片周围的八幅瓦片同时读入,即需要读9幅瓦片,这个我们只需要根据当前瓦片的key值算出周围瓦片key值,然后逐一读取即可。获取9幅瓦片key值的代码如下:

val keys = 
for (i <- -1 to 1; j <- -1 to 1)
    yield {
        val col = key.col + i
        val row = key.row + j
        SpatialKey(col, row)
      }

       逐一读取瓦片代码如下:

val tiles =
keys.map { k =>
  tileReader.reader[SpatialKey, Tile](layerId).read(k)
}

       其中tileReader为AccumuloValueReader实例,layerId包含当前数据存放layer以及层级zoom。

       将9幅瓦片拼接成1幅瓦片代码如下:

val pairs = keys zip tiles
val pieces = pairs.map { case (key, tile) => tile ->((key.col - mincol) * 256, (key.row - minrow) * 256) }
implicitly[Stitcher[Tile]].stitch(pieces, 256 * 3, 256 * 3)

       其中mincol为keys中的col最小值,minrow为keys中的row最小值,循环遍历keys即可求出。这样就实现了将9幅瓦片拼成1幅,完成数据读取工作。

2.瓦片处理

       上一步得到了拼接好的“大瓦片”,这里在Geotrellis中与之前的“小瓦片”一样的都是Tile实例,采用与之前数据处理相同的处理方式即可,唯一需要注意的是瓦片不在是256*256,而变成了原来的3倍。处理完之后原来边缘值计算有问题的地方,这样就被巧妙的避开了。

3.裁剪结果

       数据处理完之后下一步要做的就是将瓦片重新裁剪成256*256。实现代码如下:

val startcol = tile.cols / 2 - 256 / 2
val startrow = tile.rows / 2 - 256 / 2
val endcol = tile.cols / 2 + 256 / 2 - 1
val endrow = tile.rows / 2 + 256 / 2 - 1
tile.crop(startcol, startrow, endcol, endrow)

       因为要从“大瓦片”的中间取出256*256像素,所以需要按照上面的公式求出开始以及结束的像素偏移。这样就得到了边缘值没有问题的瓦片。

四、总结

       以上就是通过使用缓冲区分析的方式解决单瓦片计算边缘值问题。有些地方还可以优化,比如取的时候不要取9幅瓦片,只取比当前瓦片稍微向外扩展几个像素值等,具体由读者自行思考。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ChaMd5安全团队

三个有趣的脱壳例子

最近看了youtube上的一些视频教程,看到了几个有趣的脱壳方式。这里介绍下。具体的视频教程在MalwareAnalysisForHedgehogs和hashe...

41350
来自专栏東雲研究所

启用 TCP BBR 拥塞控制算法

自从 Linux 内核 4.9 开始已经封装了这个新的 TCP 控制算法 BBR。

1K90
来自专栏祝威廉

Spark新愿景:让深度学习变得更加易于使用

Spark成功的实现了当年的承诺,让数据处理变得更容易,现在,雄心勃勃的Databricks公司展开了一个新的愿景:让深度学习变得更容易。 当然牛好吹,也是要做...

10420
来自专栏腾讯云serverless的专栏

使用 Serverless 进行 AI 预测推理

本文演示如何使用腾讯云的 SCF 无服务器云函数来实现 AI Serving 能力。

6.2K610
来自专栏大数据文摘

手把手:我的深度学习模型训练好了,然后要做啥?

39320
来自专栏AI研习社

谷歌发布 TensorFlow 1.6.0,针对 CUDA 9.0 和 cuDNN 7 预构建二进制文件

日前,谷歌发布 TensorFlow 1.6.0 正式版,带来了多项更新和优化,雷锋网 AI 研习社将谷歌官方介绍编译如下: ? 重大改进: 针对 CUD...

442100
来自专栏量子位

简化深度学习实践流程:新鲜出炉的TensorFlow项目模板来了

林鳞 编译自 GitHub 量子位 出品 | 公众号 QbitAI 新的TensorFlow项目模板来了。 昨天,用户mrgemy95在Reddit上发帖,称这...

45240
来自专栏机器之心

教程 | 如何使用Keras、Redis、Flask和Apache把深度学习模型部署到生产环境?

1.3K110
来自专栏Python小屋

Python使用matplotlib进行可视化时精确控制图例位置

在进行数据可视化或者科学计算可视化时,显示图例会显得很高大上,但是如果能够精确控制图例的显示位置,无疑会显得档次更高。 本文以matplotlib.pyplot...

36460
来自专栏人工智能

从零开始:TensorFlow机器学习模型快速部署指南

选自Hive Blog 作者:Bowei 机器之心编译 参与:李亚洲、李泽南 本文将介绍一种将训练后的机器学习模型快速部署到生产种的方式。如果你已使用 Tens...

54970

扫码关注云+社区

领取腾讯云代金券