目录
一前言
之前有篇文章介绍了使用 Bokeh-scala 进行数据可视化 (见), 其实当时选择 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 类就是在一文中我封装的帮助类, 具体可以参考该文这样就完成了对区域内高程进行分类统计可视化
三总结
看似对高程进行统计分析可视化没有太大的意义, 这里介绍的其实只是一种思路方法, 我们可以对任意的栅格数据进行上述操作, 如土壤水域资源环境等等, 所以思想高于一切
来源: http://www.cnblogs.com/shoufengwei/p/5775417.html