版權聲明:本文爲博主原創文章,轉載請註明原文出處!
寫作時間:2010年4月10日晚
ESA SNAP工具包Java接口的使用
歐盟的SNAP工具包提供了對Sentinel衛星數據的處理功能。
SANP使用Java編寫,UI界面使用了NetBeans框架。
如果要進行批處理的話,還提供了基於圖的Graph Processing Framework (GPF)處理模式。
此外,SNAP還貼心的提供了Python接口snappy(對Java API的封裝)。
參考資料:https://senbox.atlassian.net/wiki/spaces/SNAP/overview
但是我使用官方提供的安裝包安裝好以後,Python接口用不了,所以我想着還不如就用原生的Java接口。
首先,從GitHub下載SNAP的源碼進行編譯,主要下載了snap-engine,snap-desktop,s1tbx和s2tbx這四個工程,依次進行編譯(最新版本爲8.0.0-SNAPSHOT)。
例如對snap-engine的編譯命令如下:
cd snap
git clone https://github.com/senbox-org/snap-engine.git
cd snap-engine
mvn clean install -DskipTests=true
編譯中主要問題是一些第三方庫下載特別慢或者根本下載不下來,這時候你需要科學上網手動下載需要的依賴包,再次進行編譯。
編譯完這四個包以後,我們新建Maven工程進行代碼測試。下面代碼使用Better Java (Kotlin)進行示範,我把註釋加進了代碼中方便理解。
package cn.demo
import java.nio.file.Paths
import org.esa.snap.core.dataio.ProductIO
fun main(args: Array<String>) {
val path = Paths.get("S2B_MSIL1C_20200304T032629_N0209_R018_T48SYC_20200304T075000.zip")
// 通過文件獲得讀取數據的Reader
val reader = ProductIO.getProductReaderForInput(path.toFile())
// 通過這個Reader對象來讀取Sentinel數據產品Product
val product = reader.readProductNodes(path.toFile(), null)
// 通過這個Product對象來讀取波段中存儲的數據
val band = product.getBand("B1")
// 數據不是自動加載的,需要手動加載一下
if (!band.hasRasterData()) {
band.loadRasterData()
}
// 獲取波段數據,數據是以一維數組的形式存儲的,主要使用PixelInterleavedSampleModel這類進行控制像素交替方式存儲
// 有興趣的可以參考java.awt.image.PixelInterleavedSampleModel
val data = band.rasterData
assert(band.rasterHeight * band.rasterWidth == data.numElems)
}
代碼運行過程中,提示找不到OpenJPEG的庫(Sentinel-2 SAFE格式的文件中是以JPG圖像格式保存各個波段的觀測數據的),最後我通過代碼調試發現,SNAP中對OpenJPEG庫的路徑定義在~/.snap/auxdata/openjpeg/8.0.0-SNAPSHOT/
目錄下,而我的本地沒有該目錄(雖然/usr/local/bin
目錄中有OpenJPEG庫,但是SNAP不是在這個目錄中尋找的),所以程序會報錯。
解決的方案是我由於本來安裝的SNAP桌面版(7.0.0),該版本在~/.snap/auxdata/openjpeg/7.0.0/
目錄下存放了OpenJPEG庫,所以拷貝該版本的庫修改名稱爲8.0.0-SNAPSHOT
即可,程序正常運行。
總得來說,SNAP提供的參考資料不多,有問題只能取Forum中提問。所以我覺得還是使用GDAL讀取Sentinel數據,然後再進行進一步操作方便些。