GeoTrellis整体介绍

GeoTrellis是一个利用Apache Spark处理栅格数据的Scala库,专注于解决地理信息处理的扩展性、高性能及并行化问题。它支持数据的高效读写、地图运算、矢栅转换、渲染、ETL和分布式处理。GeoTrellis能处理TB级遥感影像数据,提供Catalog、DataSource等概念,并具备ETL工具,但不支持数据更新,只能分批处理。此外,它支持重投影、时间序列数据处理等功能。
摘要由CSDN通过智能技术生成

简介

GeoTrellis是一个基于Apache spark 的用于处理栅格数据的scala库和框架
1.可以高效的读/写和操作栅格,实现了地图运算和矢栅转换工具
2.可以将栅格数据渲染成PNG图片,元数据转换成JSON

GeoTrellis解决了三个核心的问题

1.创建可扩展的,高性能的地理信息处理WEB服务
2.创建分布式的地理信息处理服务,用来处理海量数据集
3.完成并行化地理信息处理操作,以利用多核架构的优势

GeoTrellis可以将数据(Tiff) 从本地,HDFS,S3中导入到本地,HDFS,Accumulo,HBASE,CASSANDRA,S3等,可选方式很多,而且是通过Spark集群并行处理,相当于GeoTrellis已经实现了分布式的瓦片切割。

GeoTrellis是针对大数据量栅格数据进行分布式空间计算的框架,所以无论采取何种操作,都是先将大块的数据切割成一定大小的小数据(瓦片),这是分治的思想,也是分布式计算的精髓。GeoTrellis的第一步就是要将数据切片(无论是存储在内存还是持久化),然而即使能力再大,在实际工作中也难以处理以下几种需求:
全球(大范围) 高分辨率遥感影像数据,数据量在TB级
局部地区数据更新
不同时间数据融合

可行的方案是执行更新操作或者分批处理,GeoTrellis框架中提供了数据的ETL接口,但是只能进行write操作,不能进行update操作,write操作会覆盖此图层中已有数据,边处数据无法凭借,导致数据缺失,所以只能分批处理写到不同的图层。

概念

Catalog
DataSource
TileSetRasterLayer
AccumuloAttributeStore / AccumuloValueReader // 读取Accumulo 瓦片数据
RasterExtent
GeoTiffReader
SinglebandGeoTiff // 读取单波段
MultibandGeoTiff // 读取多波段
LayerReader // 读取集群中整层的瓦片信息
GeoTiff
SpatialKey //每幅瓦片在Accumulo中对应的瓦片Key值,可以通过Key值获取到对应的瓦
​ // tileReader.readerSpatialKey, Tile.read(k)

SparkUtils
TileLayerMetadata
HadoopGeoTiffRDD //读取Tiff文件类
Reproject : 重投影

数据输入

  1. 栅格
    直接导入raster数据,通过ETL类生成金字塔,保存到Accumulo

单波段Tiff数据导入:
implicit val sc = SparkUtils.createSparkContext(“ETL SinglebandIngest”, new SparkConf(true)) Etl.ingest[ProjectedExtent, SpatialKey, Tile](args, ZCurveKeyIndexMethod) sc.stop()

多波段Tiff数据导入:
implicit val sc = SparkUtils.createSparkContext(“ETL MultibandIngest”, new SparkConf(true)) Etl.ingest[ProjectedExtent, SpatialKey, MultibandTile](args, ZCurveKeyIndexMethod) sc.stop()

GeoTrellis读取Tiff文件
HadoopGeoTiffRDD

  1. 矢量
    读取矢量文件 -> 矢量栅格化 -> 走栅格流程
    ShapeFileReader / ShapefileDataStore
    geotrellis.shapefile.ShapeFileReader.readSimpleFeatures(path)

Geometry数据栅格化
Rasterizer.rasterizeWithValue(features, re, 100)
Rasterizer.foreachCellByGeometry(feature.geometry, re)

数据读取

参考: https://www.cnblogs.com/shoufengwei/p/5422844.html

在application.conf 中配置一个catolog.json文件,其中记录DataSource信息,通过此信息获取数据

–layoutScheme : tms/floating floating切瓦片的时候只有0层 , 相当于用floating处理的就是原始数据只将数据切割成256*256的块,层为0(具体x、y编号不需要操心,geotrellis会自动计算) tms会建立金字塔 ,用tms会将数据从最大层(此最大层根据数据的分辨率计算得出)切到第一层,调用的时候直接根据层进行调用

–pyramid : 加上此参数在 layoutScheme = tms的时候会建立金字塔

-I path=file:/… : 果此处的路径为文件,则单独导入此文件,如果为文件夹,则一次将整个路径导入,并且会自动拼接,瓦片不会有缝隙。geotrellis不但能够分布式瓦片切割,还能自动拼接 。

–layer : 此参数用于区分不同的数据,取数据的时候根据此项区分不同的数据
参考: https://www.cnblogs.com/shoufengwei/p/5468068.html

LayerReader : 读取整层瓦片信息,然后根据偏移得到点值

val r = reader.read[SpatialKey, Tile, TileLayerMetadata[SpatialKey]](layerId)
val mapTransform = r.metadata.mapTransform
val key = r.metadata.mapTransform(point)
val dataValues: Seq[Double] = r.asRasters().lookup(key).map(_.getDoubleValueAtPoint(point))
val value = if(dataValues == null || dataValues.length <= 0) 0 else dataValues.head

ValueReader : 首先找到对应瓦片,然后偏移得到此点

val key = attributeStore.readMetadata[TileLayerMetadata[SpatialKey]](layerId).mapTransform(point)
val (col, row) = attributeStore.readMetadata[TileLayerMetadata[SpatialKey]](layerId).toRasterExtent().mapToGrid(point)

//读取瓦片

    val tile: Tile =  tileReader.reader[SpatialKey, Tile](layerId).read(key)
    
    val tileCol = col - key.col * tile.cols
    val tileRow = row - key.row * tile.rows
    println(s"tileCol=${tileCol}   tileRow = ${tileRow}")
    tile.get(tileCol, tileRow)

多波段瓦片读取
val multiTile = tileReader.reader[SpatialKey, MultibandTile](LayerId(name, zoom)).read(key)

从多波段中获取单个波段
MultibandTile
multiTile.bands(bandNum)

直接读取整层数据
reader.readSpatialKey, Tile, TileLayerMetadata[SpatialKey]

为read方法添加一个LayerQuery对象
reader.read[SpatialKey, Tile, TileLayerMetadata[SpatialKey]](layerId, new LayerQuery[SpatialKey, TileLayerMetadata[SpatialKey]].where(Intersects(polygon)))

第二种方式的语法汤
reader.querySpatialKey, Tile, TileLayerMetadata[SpatialKey].where(Intersects(polygon)).result

数据输出

HBase
Accumulo

数据发布

参考: https://www.cnblogs.com/shoufengwei/p/5422844.html

IO(Http) ! Http.Bind(service, host, port)
需要使用以下语句系统遍自动的在host和相应的port上发起服务。
具体路由信息需要在service类中定义。service类需要继承Actor方法,并覆盖父类的receive方法。

ETL工具

参考:https://www.cnblogs.com/shoufengwei/p/5856323.html

geotrellis.spart.etl //处理ETL数据处理
ETL工作就是将数据切割成瓦片并镜像持久化,GeoTrellis支持数据放在内存中,或者放在Accumulo,HABSE等分布式数据库或者HDFS和普通文件系统中

geotrellis.Ingest 是调用Geotrellis内部数据导入的类,就是调用了ETL类进行数据自动上传

EtlConf是GeoTrellis中导入数据的配置类,需要创建EtlConf的实例,然后交给ETL即可完成数据导入,依赖Inputjson,output.json和 backend-profiles.json文件

输入:input.json //ETL输入
输出:output.json //ETL输出
保存:backend.json //数据保存

其他

PIPELINE 流水线
处理能力
瓦片切割
SHP转换JSON
矢量栅格化
矢量瓦片
生成金字塔

渲染图片

基于瓦片:
渲染为JPG:renderJpg
渲染为PNG: renderPng
颜色表: ColorMap
Options[classBoundaryType noDataColor fallbackColor strict ]
ColorMap.fromQuantileBreaks

获取瓦片/合并瓦片

参考:https://www.cnblogs.com/shoufengwei/p/5753753.html

获取polygon对应瓦片:val masked = raster.mask(polygon)

合并瓦片:val stitch = masked.stitch val tile = stitch.tile

重采样/投影/数据类型

参考:https://www.cnblogs.com/shoufengwei/p/5753753.html

val rep = tile.reproject(extent, srcCRS, dstCRS, method).tile val res = rep.convert(cellType) 

瓦片裁剪
tile.crop(startcol, startrow, endcol, endrow)

栅格切片
COG
FileCOGLayerWriter COGLayer
COGLayerMetadata
FileCOGValueReader

时序数据处理

导入数据文件,需要添加时间头
通过gdal添加时间头
gdal_edit -mo TIFFTAG_DATETIME=“time” yourtiff.tif

通过GeoTrellis添加时间头信息

val tiff = SinglebandGeoTiff(path) tiff.tags.headTags + (Tags.TIFFTAG_DATETIME -> time) val newtiff = new SinglebandGeoTiff(tiff.tile, tiff.extent, tiff.crs, Tags(map, tiff.tags.bandTags), tiff.options) newtiff.write(newTiffPath) 

改变导入参数
普通tiff数据导入的时候条用ETL类的方式:
Etl.ingestProjectedExtent, SpatialKey, Tile

时间序列数据导入时:
Etl.ingestTemporalProjectedExtent, SpaceTimeKey, Tile
主要添加时间支持,ProjectedExtent 变为 TemporalProjectExtent,SpatialKey变为SpaceTimeKey,如果是多波段的需要将Tile替换为 MultibandTile。

改变导入参数
修改input.json中只需要将format由geotiff改为temporal-geotiff;output.json中需要将keyIndexMethod中的内容改成如下方式:

"keyIndexMethod":{   
"type":"zorder", 
"temporalResolution": 86400000, 
"timeTag":"TIFFTAG_DATETIME", 
"timeFormat":"yyyy:MM:dd HH:mm:ss" 
} 

其中temporalResolution表示时间精度,理论上来说,设置此值表示当你根据时间查询的时候在这个精度范围内的数据都应该能够查询出来
到此,时间序列数据已经导入到accumulo中。

获取对应时间序列瓦片
前台将请求时间,瓦片的x,y,z传入后台,根据这四个参数查询,相较普通查询,多添加了饿时间条件

val dt = DateTimeFormat.forPattern("yyyy:MM:dd HH:mm:ss").parseDateTime(time)
val key = SpaceTimeKey(x, y, dt)
val layerId = LayerId(name, zoom)
respondWithMediaType(MediaTypes.`image/png`) {
val result = {
  val tile = tileReader.reader[SpaceTimeKey, Tile](layerId).read(key)
  tile.renderPng.bytes
}
complete(result)
}

name标示数据导入是存放的名字,tileReader为AccumuloValueReader实例

这样就能将用户请求的时间以及x、y、z瓦片数据渲染之后发送到前台,这里还需要强调的是Geotrellis中时间处理采用joda开源框架 。

分析能力

数据分析
坡度:Slope 读取瓦片,调用tile.slope 即可实现坡度
缓冲区: Buffer
栅格化几何:

Rasterizer.foreachCellByGeometry(geom, rasterExtent)(f)  
ArrayTile(array, rasterExtent.cols, rasterExtent.rows) 

统计分析
高程信息:tile.histogram

tile.histogram.foreach { (key, value) => { map(key.toDouble) = map(key.toDouble) + value } 

参考

weishoufeng: https://blog.csdn.net/luoye4321/article/category/9294349
https://blog.csdn.net/qq_32432081?t=1
https://www.cnblogs.com/shoufengwei/p/5619419.html

转载

https://www.it610.com/article/1304061019752009728.htm

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Freedom3568

技术域不存在英雄主义,不进则退

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值