geotrellis使用(十五)使用Bokeh进行栅格数据可视化统计
目录
Geotrellis系列文章链接地址http://www.cnblogs.com/shoufengwei/p/5619419.html
目录
一、前言
之前有篇文章介绍了使用Bokeh-scala进行数据可视化(见http://www.cnblogs.com/shoufengwei/p/5722360.html),其实当时选择Bokeh的部分原因就是Bokeh支持大数据量的可视化,有点“大数据”的意思,总之这刚好能与Geotrellis结合起来进行一些地理信息方面的大数据可视化统计工作。
比如我们可以实现统计一大块区域内的DEM高程分布情况,将每个高程值出现多少次进行简单的可视化,最终效果如下图所示。下面为大家分析实现方法。
二、实现方案
简单来说就是使用Geotrellis读取前端传入的区域内的数据,然后根据高程值进行分类,最后使用Bokeh进行可视化。下面逐一说明。
1.读取数据
首先要将数据导入到Accumulo中,layoutScheme选择floating,这一块介绍过多次了,不再赘述。
从Accumulo中读取数据在上一篇文章中也已经做了介绍,大同小异,在这里要简单一点,实现代码如下:
val layerId = LayerId(layerName, 0)
val raster = reader.read[SpatialKey, Tile, TileLayerMetadata[SpatialKey]](layerId)
val polygon = maskz.parseGeoJson[Polygon].reproject(LatLng, raster.metadata.crs)
val masked = raster.mask(polygon)
val tile = masked.stitch.tile
通过以上语句就能将用户输入区域的数据拼接成一个大瓦片。
2.根据高程分类
得到瓦片之后要进行高程分类,首先定义一个可变的map对象,然后从最小值到最大值都映射为0添加到map中,最后循环每一个瓦片值更新map对象,代码如下:
var map = scala.collection.mutable.Map[Double, Double]()
val (min, max) = tile.findMinMax
for (i <- min to max)
if (!map.contains(i))
map += i.toDouble -> 0.0
tile.histogram.foreach { (key, value) => {
map(key.toDouble) = map(key.toDouble) + value
}
}
3.使用bokeh进行可视化
之后要做的就是根据采样类型、投影方式以及数据类型将上述tile进行转换,代码如下:
object source extends ColumnDataSource {
val x = column(map.keys.toIndexedSeq)
val y = column(map.values.toIndexedSeq)
}
val xdr = new DataRange1d()
val ydr = new DataRange1d()
import source._
val plot = BokehHelper.getPlot(xdr, ydr, Pan | WheelZoom | Crosshair)
BokehHelper.plotBasic(plot)
BokehHelper.setCircleGlyph(plot, x, y, source)
plot.title("栅格数据分析")
BokehHelper.save2Document(plot)
其中source类中map就是上述求出的高程值与出现次数对应的映射。BokehHelper类就是在使用Bokeh-scala进行数据可视化一文中我封装的帮助类,具体可以参考该文。这样就完成了对区域内高程进行分类、统计、可视化。
三、总结
转载自:http://www.cnblogs.com/shoufengwei/p/5775417.html