版权声明:本文为博主原创文章,转载请注明原文出处!
写作时间:2020年12月4日周末
Sentinel数据处理工具包SNAP Python开发环境搭建
这篇博文主要探索安装SNAP工具包并且使用Python接口进行开发过程中搭建开发环境所踩的坑。不得不说欧空局SANP官方提供的资料太少,而且不全面。当然有问题你可以去Forum提问,可是回不回答就是另外一回事了!
下面言归正传说说如何搭建SNAP Python开发环境用于处理Sentinel卫星数据吧!(这篇文章主要谈开发环境搭建,具体数据处理可以关注后续博文。)
安装思路是:首先从SNAP官网安装提供的二进制包(截至目前最新版本是7.0.0),然后再进行相应的配置即可。对于二进制包的安装没什么可说的,可是环境的配置到处是坑,按照官网的教程根本不可能走通的。
下面主要谈一下具体如何处理这些问题。
安装问题
官网提供了两种形式的Python环境配置(参见Configure Python to use the SNAP-Python (snappy) interface):第一,在安装二进制包过程中可以选择Python安装目录,SANP安装包自动帮你设置;第二,安装好以后,自己手动进行设置。
我刚开始是选择第二种方式进行的,第二种方式需要手动编译安装Python接口,但是我从来没有编译成功过。(错误提示:AttributeError: ‘list’ object has no attribute ‘join’
,然而根本不知道该怎么解决,论坛中也有人遇到这样的错误)
所以我就删掉了装好的SNAP包,重新安装。在安装过程中选择自己提前安装好的Python路径。我是使用Conda提前安装了一个3.6版本的Python环境(conda create -n snap python=3.6
)。在安装SNAP过程中根据安装向导进行设置即可。
注意:SNAP安装过程中安装向导提示要求Python是2.7,3.3或者3.4版本(官方教程中说是支持2.7,3.3或者3.6版本,不知道哪个是对的)。
安装即算完成了。然后根据官方的教程进行测试,首先切换目录到SNAP Python接口snappy所在目录,macOS下在~/.snap/snap-python
,不同操作系统在用户目录下的.snap
文件夹中找即可。然后在控制台调用我们刚才安装SNAP过程中设置的Python命令。如果我们是使用Conda安装的Python,直接conda activate snap
即可。
1 | cd <cd <snappy-dir> |
在snap-python
目录,我们可以使用如下代码进行测试Python开发接口是否正常工作。
1 | from snappy import ProductIO |
然而,测试过程中你会发现有很多问题,而官方教程中根本没提供解决方案。下面细细说一下我遇到的问题以及解决方案。
缺包问题
运行以后的错误提示如下:ImportError: No module named jpyutil
,这显然是Python找不到包的缘故。那没有的话,我们安装一个即可(需要安装JPY包,一个用于Java和Python语言直接相互调用的桥接库)。
安装过程中,我直接使用pip install jpy
进行安装,结果又有新的错误。
后来,我发现JPY的GitHub网站上提供了编译好的二进制安装包,根据自己的的平台和Python版本选择合适的WHL二进制文件下载,下载以后直接使用pip install <jpy.whl>
命令安装即可(jpy.whl
换成你自己下载好的文件路径)。
JDK版本问题
缺包问题解决以后,继续进行测试,结果提示找不到JDK的动态链接库,根据错误提示,我发现snappy查找的Python版本跟我系统设置的JAVA_HOME
路径中的JDK不一致。可能程序中使用了自己定义好JDK版本(1.8.0_112),而没有选择使用环境变量中提供的版本。
所以我根据错误提示我下载了1.8.0_112版本的JDK二进制包进行安装,JDK的问题就算解决了。
Java JDK官方网站提供的一般是最新的版本,要下载老旧的JDK可以通过网站Oracle Java Archive选择自己的操作系统平台进行二进制包的下载安装,不要忘了提前申请一个Oracle的账号。
环境变量问题
JDK版本问题解决以后,继续进行测试。结果又提示找不到SANP_HOME
路径,我们在环境变量中设置SANP_HOME
变量指向到SNAP的安装目录即可。Windows下可以通过This PC
属性进行设置,Linux可以在~/.bashrc
文件中进行设置,macOS在~/.bash_profile
进行设置。我的设置如下:
1 | export SNAP_HOME=/Applications/snap |
最后,我们再继续进行测试,终于看到输出结果了:
1 | ['radiance_1', 'radiance_2', 'radiance_3', 'radiance_4', 'radiance_5', 'radiance_6', 'radiance_7', 'radiance_8', 'radiance_9', 'radiance_10', 'radiance_11', 'radiance_12', 'radiance_13', 'radiance_14', 'radiance_15', 'l1_flags', 'detector_index'] |
关于snappy接口的具体使用,欢迎关注我的后续文章!