此篇文章的重点是,Android 下 gdal 支持WMS,TMS Driver 遇到的坑,NDK下GDAL的编译请在百度上搜索。
把坑记录下来,供大家参考。先说要实现的功能,是要在android JNI 下利用GDAL 完成 GOOGLE 瓦片 的 RasterIO 读取,当然也能够完成WMS的读取。这是GDAL 中有关WMS的文档https://www.gdal.org/frmt_wms.html
编译环境如下:
ubuntu 16.04 LTS
android-ndk-r18b
GNU Make 4.1
代码版本如下:
gdal-2.2.3
curl-7.59.0
按照网上的办法顺利对GDAL进行了交叉编译,坑来了。
利用GDAL的CPLHTTPFetch测试网络抓取功能的时候,没抓取到文件。测试函数如下:
bool SaveUrl2File(const char* pszUrl, const char* pszFileName)
{
if (CPLHTTPEnabled() != TRUE)
return false;
CPLHTTPResult *pRest = CPLHTTPFetch(pszUrl, NULL);
if (pRest == NULL)
return false;
FILE *pFile = fopen(pszFileName, "wb");
if (pFile == NULL)
return false;
fwrite(pRest->pabyData, sizeof(GByte), pRest->nDataLen, pFile);
fclose(pFile);
CPLHTTPDestroyResult(pRest);
CPLHTTPCleanup();
return true;
}
查看错误信息,大概的意思是需要HTTPS支持,查资料得知,需要在编译curl的时候指定--with-ssl 才能支持HTTPS,然后就开始编译openssl库,本来应该是比较容易的一件事,结果整了足足一天,糟糕的是还没把ssl编译出来。我用的NDK版本比较高,编译器是clang,真是没搞出来,原因是和NDK版本有密切关系,貌似GCC比较容易,clang是google推荐编译器。之后就从网上找ssl库,arm64-v8a的ssl不太好找,还好在GITHUB上找到了。
这是成功在curl中集成ssl后的configure输出,注意最后一行Protocols 中要出现HTTPS,另外在编译curl的时候要指定ssl的库目录,和库名字,否则链接的时候可能会找不到库。
export LDFLAGS="-L/xxx/xxx/build64dr/openssl/lib" ,指定ssl库的搜索目录
export LIBS="-lssl -lcrypto -lz",指定ssl库名字
GDAL编译好后,开始测试 SaveUrl2File 函数,测试失败,提示SSL certificate problem: unable to get local issuer certificate,调用CPLSetConfigOption("GDAL_HTTP_UNSAFESSL", "YES");即可解决,原理就不说了。OK,GDAL在android下可以抓取网络数据了。
下来测试TMS Driver,TMS 用一个XML 配置文件来描述,GDALOpenEx打开 失败,提示无法识别坐标系,CPLSetConfigOption("GDAL_DATA", "/mnt/sdcard/XXX/data");可以解决,原理就不说了,
折腾了俩天,收工,遗憾的是ssl 的clang编译始终是没通过。
这是读取到的一份大图,神奇不,GDAL自动完成瓦片拼接,只要你内存足够大,内存不够大的用下载器吧,乔帮主的下载器还是不错的,虽然没用过 ,给扩散下 哈哈,李民录老师的 GDAL书也很棒,上面的测试代码来源于他的博客.