目錄
一、前言
今天要介紹的絕對是華麗的干貨。比如我們從互聯網上下載到了一系列(每天或者月平均等)的MODIS數據,我們怎么能夠對比同一區域不同時間的數據情況,采用傳統的方法可能只能將所有要參考的數據用ArcGIS等打開,然后費勁的一一對比等,不僅操作繁瑣,搞不好日期等還會對應錯。本文就是介紹使用Geotrellis動態加載時間序列數據,使我們能夠自由選擇日期瀏覽或者像動畫一樣循環展示一系列數據。直接進入干貨。
二、實現方法
2.1 前台界面
前台與以往保持不變,但是你需要保證能夠提供請求時間的時間序列范圍,如想實現根據用戶輸入的日期展示當期數據,那么你需要提供一個日期選擇器;如果你想動態加載系列數據那么你必須能夠提供這一系列的日期范圍,並能夠自動改變日期。總之你需要將日期作為一個參數發送到后台已達到請求該日期數據的效果。
2.2 數據准備
這一塊與以往變化比較大,首先要對tiff數據進行預處理,重投影等自不需要多言,主要是要給tiff加個時間頭信息。有兩種方式,可以使用GDAL或者自己寫程序,分布介紹如下:
1、使用GDAL實現添加時間頭信息
只需要一條命令即可:
gdal_edit -mo TIFFTAG_DATETIME="time" yourtiff.tif
上述命令就會給tiff文件添加一個名為TIFFTAG_DATETIME的頭文件信息,time表示你想添加的時間,需要符合ISO標准,否則你需要在導入數據的時候指定時間格式。
2、使用Geotrellis實現添加時間頭信息
主要步驟為讀取tiff文件、修添加時間頭信息、保存新的tiff文件。代碼如下:
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)
代碼同樣很簡單,但是說實話不如GDAL來的方便,僅供參考。
2.3 時間序列數據導入
數據准備好之后我們就可以開始着手導入,這里面有很多需要改變的地方。
1、改變數據導入類
普通tiff數據導入的時候調用ETL類的方式如下:
Etl.ingest[ProjectedExtent, SpatialKey, Tile](args)
但是到了時間序列數據就要變為:
Etl.ingest[TemporalProjectedExtent, SpaceTimeKey, Tile](args)
主要是添加時間支持,ProjectedExtent變為TemporalProjectedExtent,SpatialKey變為SpaceTimeKey,當然如果是多波段還需要將Tile替換為MultibandTile。
2、改變導入參數
在geotrellis使用(二十)geotrellis1.0版本新功能及變化介紹一文中已經介紹過了1.0版Geotrellis導入數據的方式變為json文件,這里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表示時間精度,理論上來說,設置此值表示當你根據時間查詢的時候在這個精度范圍內的數據都應該能夠查詢出來,但是實際上好像並不是這樣,不知道是其bug還是我操作方式有問題,需要后續進一步研究;timeTag指定時間頭字段名稱;timeFormat指定時間格式。
完成以上步驟之后即可將時間序列數據導入到accumulo中。
2.4 獲取對應時間數據瓦片
前台將請求的時間已經瓦片的x、y、z編號傳入后台,后台接收到之后根據此四個參數進行查詢,相較普通tiff數據實際上只是多添加了時間條件。請求瓦片代碼如下:
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開源框架,關於其用法大家可以網上自行搜索。最后為大家附上兩張截圖,當然如果是動畫效果會更好,由於沒有錄制,僅提供兩張截圖以達到展示動態的效果。
三、總結
本文為大家簡單介紹了如何動態加載時間序列數據,同樣讀者可以根據自己的需求任意發揮想象,達到自己需要的效果。比如可以實現動態展示全球洋流、大氣、農作物、植被等變化情況。凡是在一段時間內有變化的數據,當我們搜集到足夠多的數據並添加時間標簽之后即可將其“動”起來,我想這種展示效果一定很棒。
Geotrellis系列文章鏈接地址http://www.cnblogs.com/shoufengwei/p/5619419.html