Geotrellis系列文章連接地址http://www.cnblogs.com/shoufengwei/p/5619419.htmlhtml
最近真的是日理千機,可是再忙也要抽出時間進行總結。上一篇文章講了使用緩衝區分析的方式解決投影變換中邊緣數據值計算的問題(見geotrellis使用(十六)使用緩衝區分析的方式解決投影變換中邊緣數據值計算的問題)。實際中每每還有一種需求就是對單個瓦片進行操做,好比求坡度等,若是這時候直接計算,一樣會出現邊緣值計算的問題,這種狀況也可使用上一篇文章中講到的方法進行處理。算法
假如咱們想在前臺地圖中實時顯示坡度圖像,有兩種方式:第一種是在DEM數據導入Accumulo以前先求坡度(可使用傳統的GDAl、也可使用Geotrellis),而後再導入;第二種是直接將DEM數據導入Accumulo中,後臺實時計算每幅瓦片的坡度,而後渲染到前臺。兩種方式各有各的好處,採用第一種方式,總體處理簡單,顯示的速度快,可是Accumulo中要存兩份數據。第二種方式,實現起來稍顯複雜,顯示的速度稍慢,可是Accumulo中只存了一份數據。因爲Geotrellis基於Spark集羣,因此若是集羣足夠優秀,處理速度不是很重要的問題,可是若是咱們須要對同一個數據進行多種操做,或者根據用戶的需求來進行操做,那麼就沒有辦法完成數據的預處理工做,只能進行實時計算,若是計算只針對瓦片中的單一像素則還不涉及到邊緣值的問題,而若是須要進行插值採樣等操做(如求坡度、山影等),這時候就會出現上文中講到的瓦片邊緣值計算的問題。本文就爲你們講解如何使用緩衝區分析的方式解決單瓦片計算邊緣值問題。函數
至於求坡度等的具體算法不在這裏介紹,都是很成熟的算法,而且Geotrellis中也已經實現了一些算法,只需調用相應的函數便可。有關緩衝區分析等也在以前的文章介紹過屢次,不在這裏贅述。優化
1.數據讀取scala
此處讀的數據爲沒有進行過任何處理的原始DEM數據,具體讀寫數據也在以前的文章中介紹過,詳情見geotrellis使用(三)geotrellis數據處理過程分析等文章。code
可是此處不一樣的是咱們爲了完成邊緣值計算,就須要將單幅瓦片周圍的八幅瓦片同時讀入,即須要讀9幅瓦片,這個咱們只須要根據當前瓦片的key值算出周圍瓦片key值,而後逐一讀取便可。獲取9幅瓦片key值的代碼以下:htm
val keys = for (i <- -1 to 1; j <- -1 to 1) yield { val col = key.col + i val row = key.row + j SpatialKey(col, row) }
逐一讀取瓦片代碼以下:blog
val tiles = keys.map { k => tileReader.reader[SpatialKey, Tile](layerId).read(k) }
其中tileReader爲AccumuloValueReader實例,layerId包含當前數據存放layer以及層級zoom。ip
將9幅瓦片拼接成1幅瓦片代碼以下:ci
val pairs = keys zip tiles val pieces = pairs.map { case (key, tile) => tile ->((key.col - mincol) * 256, (key.row - minrow) * 256) } implicitly[Stitcher[Tile]].stitch(pieces, 256 * 3, 256 * 3)
其中mincol爲keys中的col最小值,minrow爲keys中的row最小值,循環遍歷keys便可求出。這樣就實現了將9幅瓦片拼成1幅,完成數據讀取工做。
2.瓦片處理
上一步獲得了拼接好的「大瓦片」,這裏在Geotrellis中與以前的「小瓦片」同樣的都是Tile實例,採用與以前數據處理相同的處理方式便可,惟一須要注意的是瓦片不在是256*256,而變成了原來的3倍。處理完以後原來邊緣值計算有問題的地方,這樣就被巧妙的避開了。
3.裁剪結果
數據處理完以後下一步要作的就是將瓦片從新裁剪成256*256。實現代碼以下:
val startcol = tile.cols / 2 - 256 / 2 val startrow = tile.rows / 2 - 256 / 2 val endcol = tile.cols / 2 + 256 / 2 - 1 val endrow = tile.rows / 2 + 256 / 2 - 1 tile.crop(startcol, startrow, endcol, endrow)
由於要從「大瓦片」的中間取出256*256像素,因此須要按照上面的公式求出開始以及結束的像素偏移。這樣就獲得了邊緣值沒有問題的瓦片。
以上就是經過使用緩衝區分析的方式解決單瓦片計算邊緣值問題。有些地方還能夠優化,好比取的時候不要取9幅瓦片,只取比當前瓦片稍微向外擴展幾個像素值等,具體由讀者自行思考。