geotrellis使用(十)缓冲区分析以及多种类型要素栅格化

目录

  1. 前言
  2. 缓冲区分析
  3. 多种类型要素栅格化
  4. 总结
  5. 参考链接

一、前言

       上两篇文章介绍了如何使用Geotrellis进行矢量数据栅格化以及栅格渲染,本文主要介绍栅格化过程中常用到的缓冲区分析以及同一范围内的多种类型要素栅格化。

       本文主要记录今天过程中碰到的两个问题,第一个问题就是线状要素在进行栅格化的时候只有单个像素,看不出应有的效果;第二个问题就是同一地区的数据既包含面状要素,又包含了线状要素,普通方式只能栅格化成两套数据。下面我为大家介绍解决这两个问题的方法(当然若有人有更好的方法,欢迎交流)。

二、缓冲区分析

       缓冲区分析在百度百科中的定义为:

缓冲区分析是指以点、线、面实体为基础,自动建立其周围一定宽度范围内的缓冲区多边形图层,然后建立该图层与目标图层的叠加,进行分析而得到所需结果。它是用来解决邻近度问题的空间分析工具之一。邻近度描述了地理空间中两个地物距离相近的程度。

       当然本文并不是教大家如何解决邻近度问题,只是简单的说明如何能够在栅格化的过程中将线状要素能够多外扩几个像素。

自己实现外扩像素

       由于本人非地理信息专业出身(甚至非计算机专业出身,没办法,置身码农把青春卖!)所以在遇到问题的时候并不懂什么缓冲区分析的高大上的词汇。首先想到的是我可以在矢量化的过程中外扩几个像素,这样不就实现了增强的效果,但是有个问题就是我如何知道线段的方向,先将就着来,我把线段点上下左右的像素全部赋予与改点相同的值,这样可以不用考虑方向,并且应该能达到效果。        说干就干,再一次认真研读GeotrellisReasterizer.scala的源代码,冥思苦想一阵之后,想到了方法,主要是要重写赋值的方法,实现代码如下:

def rasterize(geom: Geometry, rasterExtent: RasterExtent, value: Int) ={
      val cols = rasterExtent.cols
      val array = Array.ofDim[Int](rasterExtent.cols * rasterExtent.rows).fill(NODATA)
      val f = (col: Int, row: Int) => {
        array(row * cols + col) = value
        if (col > 0)
          array(row * cols + col - 1) = value
        if (col < cols - 1)
          array(row * cols + col + 1) = value
        if (row > 0)
          array((row - 1) * cols + col) = value
        if (row < rasterExtent.rows - 1)
          array((row + 1) * cols + col) = value
      }
      Rasterizer.foreachCellByGeometry(geom, rasterExtent)(f)
      ArrayTile(array, rasterExtent.cols, rasterExtent.rows)
    }

简单说来就是之前f函数中只有array(row * cols + col) = value一条语句,即实现当前点的像素点赋值,那么加上了判断不是边界之后,给上下左右的像素点都赋值即可实现,运行起来。

       得到的结果虽然看起来有点丑,但是总算解决了这个问题,然后把结果拿给老板看,老板什么话也没说,默默的甩给我https://gitter.im/geotrellis/geotrellis/archives/2016/02/22这么一个网址。好吧,老板果然是老板,这里也要介绍一下https://gitter.im/geotrellis/geotrellis/,这是Github中的Geotrellis项目交流群,在里面咨询问题,会有懂的人甚至作者解答,有点考验英语基础。

使用buffer函数

       在那个网页中,上来就有这么一段代码:

val points = Seq(
  Point(re.gridToMap(100,100)).buffer(30),
  Point(re.gridToMap(200,200)).buffer(30),
  Point(re.gridToMap(300,300)).buffer(30),
  Point(re.gridToMap(400,400)).buffer(30),
  Point(re.gridToMap(500,500)).buffer(30)
)

       根据这段代码尤其是buffer名称,可以知道其实在Geotrellis中缓冲区分析就是使对象调用buffer函数即可,参数表示缓冲的距离。赶紧拿来试验,非常成功,但是这里面却有几个需要注意的问题。

  1. 缓冲距离

       此处的缓冲距离经过实际测试发现与当前数据的坐标系相一致,即如果是WGS84地理坐标系,那么此处缓冲距离就是以经纬度为单位,大地坐标系此处就是以米为单位。

  1. 缓冲类型

       一般情况下只需要给点、线要素使用缓冲即可,这里就可以使用模式匹配,如下:

val geom = WKT.read(pro.getValue.toString) match {
                case geom: Point        =>    geom.buffer(bufferDistance)
                case geom: Line         =>    geom.buffer(bufferDistance)
                case geom: MultiLine    =>    geom.buffer(bufferDistance).toGeometry().get
                case geom               =>    geom
              }

       这里就仅为PointLine以及MultiLine类型进行了缓冲区设置,其他需要转换的可以用同样的方式进行匹配,展示一下最终的效果。

       其实查看buffer函数的定义,不难发现该函数实现的就是将要点线要素转换成了面要素。

       以上就实现了缓冲区分析,下面进行下一个主题多种类型要素栅格化。

三、多种类型要素栅格化

       同一个区域数据即包含面状要素又包含线状要素,显然在shape文件中以及数据库中我们都没有办法将其进行合并,而如果我们又不想得到两套栅格化的数据该如何是好呢?

       其实方法也很简单,只需要将要素拼接到同一个GeometryCollection中然后统一获取其RasterExtent即可,实现代码如下:

val features = mutable.ListBuffer[Geometry]()
    for (path <- paths) {
      val file = new File(path)
      if(file.exists()) {
        val shpDataStore = new ShapefileDataStore(new File(path).toURI().toURL())
        shpDataStore.setCharset(Charset.forName(charset))
        val featureSource = shpDataStore.getFeatureSource()
        val itertor = featureSource.getFeatures().features()
        while (itertor.hasNext()) {
          val feature = itertor.next()

          val p = feature.getProperties()
          val it = p.iterator()

          while (it.hasNext()) {
            val pro = it.next()
            if (pro.getName.getLocalPart.equals("the_geom")) {//get all geom from shp
              val geom = WKT.read(pro.getValue.toString) match {
                case geom: Point        =>    geom.buffer(resolution * bufferDistance)
                case geom: Line         =>    geom.buffer(resolution * bufferDistance)
                case geom: MultiLine    =>    geom.buffer(resolution * bufferDistance).toGeometry().get //0.0054932 * 7
                case geom               =>    geom
              }
              features += geom
            }
          }
        }
        itertor.close()
        shpDataStore.dispose()
      } else
        println(s"the file ${path} isn't exist")
    }

       以上代码实现的是逐个循环需要栅格化的文件,然后将每个geometry对象添加到features中,剩下的在前面的文章中已经介绍过,不再赘述。

四、总结

       以上讲述了如何进行缓冲区分析以及多种类型要素栅格化。虽然实现方法比较较难,但是在刚碰到这些问题的时候确实会让人摸不着头脑,本文简单记录之,仅为整理思路以及方便以后使用,如果能够帮助到一些苦苦探索的人当然是更好的。最后感谢在工作过程中给予了重大帮助和指导的吴老板!

五、参考链接

一、geotrellis使用初探 二、geotrellis使用(二)geotrellis-chatta-demo以及geotrellis框架数据读取方式初探 三、geotrellis使用(三)geotrellis数据处理过程分析 四、geotrellis使用(四)geotrellis数据处理部分细节 五、geotrellis使用(五)使用scala操作Accumulo 六、geotrellis使用(六)Scala并发(并行)编程 七、geotrellis使用(七)记录一次惨痛的bug调试经历以及求DEM坡度实践 八、geotrellis使用(八)矢量数据栅格化 九、geotrellis使用(九)使用geotrellis进行栅格渲染 十、geotrellis使用(十)缓冲区分析以及多种类型要素栅格化

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小樱的经验随笔

BugkuCTF 计算器

前言 写了这么久的web题,算是把它基础部分都刷完了一遍,以下的几天将持续更新BugkuCTF WEB部分的题解,为了不影响阅读,所以每道题的题解都以单独一篇文...

285100
来自专栏FreeBuf

一次编码WebShell bypass D盾的分析尝试

webshell是获得网站的控制权后方便进行之后的入侵行为的重要工具,一个好的webshell应该具备较好的隐蔽性能绕过检测,最近偶然间捕获到了一个webshe...

14220
来自专栏ImportSource

设计模式-搞个接口,留有余地,让你我不再尴尬

设计模式,Design Patterns,Pattern,翻译为“模式”总感觉不够接地气,用今天的话来说可以叫“套路”。设计模式就是写代码的过程中一些常规打法和...

378120
来自专栏码生

Swift2转Swift3

接触swift 已经有一年多的时间了,由最初的OC代码转为 swift 代码,然后从 swift 2.3 转为 swift 3。每次的转换都感觉是将项目整个的翻...

17750
来自专栏desperate633

Java程序员秋招面经大合集(BAT美团网易小米华为中兴等)

1, 自我介绍 2, 项目介绍 3, 项目架构 4, 项目难点 5, Synchronize关键字为什么jdk1.5后效率提高了 6, 线...

16220
来自专栏web前端教室

【蒙圈】自己写的Js,自己不认识了?

但是,下课之前我说,今天的作业,如何如何要求,格式什么样,标明用了多长时间,然后就有同学在学习群里问我,。。原话记不太清了,大概意思就是,自己写的看不明白了,还...

15640
来自专栏liuchengxu

代码健康: 减少嵌套, 降低复杂性

原文: Code Health: Reduce Nesting, Reduce Complexity

12320
来自专栏PPV课数据科学社区

数据流编程教程:R语言与DataFrame

DataFrame DataFrame 是一个表格或者类似二维数组的结构,它的各行表示一个实例,各列表示一个变量。 一. DataFrame数据流编程 ? 二....

503120
来自专栏落影的专栏

Audio Unit播放PCM文件

前言 相关文章: 使用VideoToolbox硬编码H.264 使用VideoToolbox硬解码H.264 使用AudioToolbox编码AAC 使...

55160
来自专栏web前端教室

如何阅读JS源码?读源码有什么好处

这几天在公司接手了一个项目,是之前其它组的,现在要继续完成它。那我要做的第一件事,就是熟悉代码。对,就是看别人写的JS代码。文档嘛,自然是没有的。 之前也有试过...

546100

扫码关注云+社区

领取腾讯云代金券