目录
一、前言
之前版本是0.9或者0.10.1、0.10.2,最近发现更新成为1.0.0-2077839。1.0应该也能称之为正式版了吧。发现其中有很多变化,在这里为大家简单介绍。
二、变化情况介绍
2.1 数据导入变化
之前数据导入参数基本都要写在命令行,刚查看之前写的博客发现没有介绍数据导入的,只有一个老版的调用本地数据的,本文就在这里简单介绍Geotrellis的数据导入。
Geotrellis可以将数据(Tiff)从本地、HDFS、S3中导入到本地、HDFS、Accumulo、HBASE、CASSANDRA、S3等,可选方式很多,而且是通过Spark集群并行处理,其实相当于Geotrellis已经实现了分布式的瓦片切割。老版的命令如下:
spark-submit --class geotrellis.Ingest --driver-memory=2G jarpath
--input hadoop --format geotiff --cache NONE -I path=filepath
--output accumulo -O instance=accumuloinstance table=tablename user=username
password=password zookeeper=zookeeper --layer layername --crs EPSG:3857 --layoutScheme floating
其中geotrellis.Ingest是一个调用Geotrellis内部数据导入的类,就是调用了ETL类进行数据自动上传。代码如下:
implicit val sc = SparkUtils.createSparkContext("Ingest", new SparkConf(true))
Etl.ingest[ProjectedExtent, SpatialKey, Tile](args, ZCurveKeyIndexMethod)
sc.stop()
如果是多波段数据将Tile换成MultibandTile即可。接着说上面的脚本,input表示数据输入方式,如果是本地和HDFS就写hadoop,如果是S3就写s3。format是数据类型,单波段tiff为geotiff,多波段tiff为multiband-geotiff。path为数据存放路径。output指定输出存放位置。后面是该位置的一些配置。具体非常复杂,可以参考https://github.com/pomadchin/geotrellis/blob/master/docs/spark-etl/spark-etl-intro.md。
上面的数据导入配置看上去是不是很乱,并且完全没有组织,1.0版进行了很大的改进,将配置信息基本都写在了json文件里。1.0版数据导入命令如下:
spark-submit \
--class geotrellis.dataimport.DataIngest --driver-memory=2G $JAR \
--input "file:///input.json" \
--output "file://output.json" \
--backend-profiles "file://backend-profiles.json"
看上去是不是很清爽,将配置信息写在了三个文件里,下面逐一介绍这三个文件。
input表示输入信息的配置,其json文件如下:
[
{
"name": "landsat",
"format": "geotiff",
"backend": {
"type": "hadoop",
"path": "file:///datapath/"
},
"cache": "NONE"
}
]
这是一个json数组可以写多个。name相当于旧版的layername,format不变,type相当于旧版的input,path不变。
output表示输出信息的配置,其json文件如下:
{
"backend": {
"type": "accumulo",
"path": "through",
"profile": "accumulo-201"
},
"reprojectMethod": "buffered",
"cellSize": {
"width": 256.0,
"height": 256.0
},
"tileSize": 256,
"pyramid": true,
"resampleMethod": "nearest-neighbor",
"keyIndexMethod": {
"type": "zorder"
},
"layoutScheme": "zoomed",
"cellType":"int8",
"crs": "EPSG:3857"
}
大部分意思与旧版相同,主要是backend中的信息,type相当于旧版的output,path相当于table,profile表示accumulo或其他输出方式的配置,具体写在backend-profiles.json文件中。
backend-profiles中存放数据库等配置信息,其json文件如下:
{
"backend-profiles": [
{
"name": "accumulo-201",
"type": "accumulo",
"zookeepers": "zookeeper",
"instance": "accumulo-instance",
"user": "username",
"password": "password"
},
{
"name": "cassandra-local",
"type": "cassandra",
"allowRemoteDCsForLocalConsistencyLevel": false,
"localDc": "datacenter1",
"usedHostsPerRemoteDc": 0,
"hosts": "localhost",
"replicationStrategy": "SimpleStrategy",
"replicationFactor": 1,
"user": "",
"password": ""
}
]
}
backend-profiles节点下可以存放多个数据库配置信息,其中name就是output.json文件中的backend.profile。
2.2 性能提升
1.0版本明显做了很多优化,代码也变的更整洁清晰,带来的结果是性能明显提升。比如数据导入之前导入数据比较费时,且经常失败,1.0版更加稳定,并且速度明显提升。数据读取以及处理的速度也有所提升,我的系统中原来需要90ms处理的数据,现在可能只需要60ms左右,原来需要600ms处理的现在也只需要300ms左右。其实下面要讲的更是一个性能方面的提升。
2.3 LayerReader读取整层数据的变化
比如我们希望能够实现用户选择任意区域数据(以SRTM为例)并能够自动拼接、下载该区域的SRTM数据,首先我们需要将全球的SRTM数据导入Geotrellis中,然后当有用户请求的时候读出SRTM的数据,进行拼接等操作。旧版的时候我们就需要将整层数据读出,然后根据用户输入的范围调用mask方法进行掩码操作。而新版大大改进了这一点,我们可以直接取出用户输入范围内的数据。下面我为大家介绍使用LayerReader读取整层数据的三种实现方式。
第一种方式直接读取整层数据。代码如下:
reader.read[SpatialKey, Tile, TileLayerMetadata[SpatialKey]](layerId)
其中reader是FilteringLayerReader[LayerId]对象,下同,从名字就能看出应该是1.0版新加的带有过滤的层读取类(旧版为AccumuloLayerReader类),layerId为读取的层的信息,下同。适用该方式就会将该layerId的整层数据读出。
第二种方式为read方法添加一个LayerQuery对象。实现代码如下:
reader.read[SpatialKey, Tile, TileLayerMetadata[SpatialKey]](layerId, new LayerQuery[SpatialKey, TileLayerMetadata[SpatialKey]].where(Intersects(polygon)))
其实就是用where语句加了一个过滤条件,Intersects(polygon)表示条件是与polygon相交,polygon是用户选择的范围,并且需要跟原始数据采用同一投影,此处有个小bug,就是仅支持MultiPolygon,如果是Polygon对象需要使用MultiPolygon(polygon)进行简单封装,下同。这样就能实现只读取该层中的与polygon相交的数据。
第三种方式就是第二种方式的语法糖,写起来更加简单方法。代码如下:
reader.query[SpatialKey, Tile, TileLayerMetadata[SpatialKey]](layerId).where(Intersects(polygon)).result
以上就是实现整层数据读取的三种方式,如果需要处理的上述业务需求,最好采用后两种方式,进行实际测试,效率提高10倍左右。但是后两种方式有个小bug:如果polygon与层中的数据相交的瓦片(源数据在Accumulo等数据库中存放的方式是256*256的瓦片)是较小的区域,可能该瓦片不会被取出,即会被过滤掉,Geotrellis毕竟是一个新的框架,我们应该包容其中的BUG,寻找合适的方式绕过BUG实现我们的需求。
三、总结
本文简单介绍了1.0版Geotrellis中的变化,不难看出Geotrellis正在快速的向前推进,我相信假以时日,一定会变的更加完善、更加好用,我对Geotrellis的未来充满信心。