GDAL,我暗恋你很久了!
初识GDAL
GDAL(Geospatial Data Abstraction Library),是一个用于矢量和栅格格式数据之间的转换器。由
GIS的基础设施-GDAL
个人认为,GDAL可以称为GIS的基础设施 ,为什么这么说呢?因为GDAL无论是在开源GIS软件还是商业GIS软件中都得到了广泛的应用。我们通过下表来看看,哪些软件都在使用GDAL。
| 软件名称 | 用途 |
|---|---|
| A popular GIS platform. | |
| Image viewer for very large JPEG 2000 and ECW files. | |
| a open source software server written in Java that allows users to share and edit geospatial data. | |
| A 3D world viewer. | |
| A GIS and Image Processing Windows Desktop application. Uses GDAL to import/export/warp raster data. | |
| Software for creating terrain models and ortho images from planetary stereo images. | |
| A cross platform desktop GIS. | |
| The Skyline suite of interactive applications allows you to build, view, query and analyze customized, virtual 3D landscapes. | |
| Expose OGR layer as PostgreSQL foreign tables. | |
| spatial database extender for PostgreSQL: The raster loader and many of the raster SQL functions rely on GDAL. | |
| Point Cloud Data Abstraction Library | |
| A raster/vector open source GIS that uses GDAL for raster/vector import and export (via r.in.gdal/r.out.gdal) | |
| Multiplatform virtual globe library to quickly and easily create interactive visualizations of 3D globes, map and geographical information. | |
| A free software environment for statistical computing and graphics, with bindings to GDAL via the rgdal package. | |
| wind model for fire behavior modeling. |
知道大家英语好,就不翻译了哦!单词都很简单~
GDAL与OGR的关系
OGR曾经是一个独立的矢量IO库,灵感来自于OpenGIS Simple Features,它是从GDAL中分离出来的。在GDAL 2.0版本中,GDAL和OGR组件被集成在一起。
OGR过去是OpenGIS简单特性参考实现的缩写。然而,由于OGR不完全符合OpenGIS简单特性规范,并且没有被批准作为该规范的参考实现,因此名称改为OGR简单特性库。这个名字中OGR的唯一含义是历史性的。在库的源代码中,OGR也是用于类名、文件名等的前缀。
搭建GDAL开发环境
1. 搭建GDAL的Windows开发环境
由于在实际开发中,我们大多都是使用Windows机器来进行工作,因此搭建windows的开发环境就显得格外重要。但是在windows平台下编译GDAL步骤较为繁琐,且存在一定的坑,对于非C/C++/Qt开发人员来说需要额外的精力去学习和摸索。如果你感兴趣的话,可以参考这篇博主的文章完成
为了节省时间,并且能够多快好省的直接进入GDAL的学习环节,我们这里使用别人编译好的GDAL jar包和动态链接库文件。
下载的页面会跳转至GISInternals页面,关于这个网站的介绍如下所示:
About GISInternals
GISInternals is an online system for creating daily built binary packages for the
GISInternals 是一个在线系统,用于为 GDAL 和 MapServer 项目创建每日构建的二进制包。 2007年已经提供了这个系统的源头,作为osgeo buildbot的Windows buildslaves。目前形式的构建系统(提供可下载的包)已经在2009年建立起来了。截至目前,该系统一直在不断改进 通过添加越来越多的包,让这些开源项目的用户和开发人员的生活更轻松。 在此期间,访问者数量和下载量持续增长,该站点已被全球 160 多个国家/地区访问。
由此可见GISInternals网站是一个专门用于构建GDAL和MapServer工具网站。
进入下载页面选择合适的版本,我们这里选择release-1900-x64-gdal-2-3-1-mapserver-7-2-0.zip的版本,下载好之后,解压文件后文件列表如下所示:



值得需要注意的是下载早期的编译好的版本,该目录下会是4个.dll文件,分别是

这里无论是你下载的早期版本,比如:release-1600-x64-gdal-2-1-3-mapserver-7-0-4,还是新版本,比如:release-1916-x64-gdal-3-3-3-mapserver-7-6-4都是可以的,新版本会有更多的新功能和新接口可以去探索和使用。
-
然后把gdal.jar包文件放到你的java工程的libs目录下,使用maven的gav坐标把这个jar包引入你的maven工程里面,如下图所示,至于这里面的vesion你可以随便填写,这个无所谓。
-
<dependency>
<groupId>org.gdal</groupId>
<artifactId>gdal</artifactId>
<version>1.9.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/gdal.jar</systemPath>
</dependency>
至此,windows环境下的gdal 环境搭建就完成了,稍后我们会进行实战操作···
2. 搭建GDAL 的CentOS运行环境
我们编写好的应用程序,经过严格的测试之后都会上线运行在CentOS服务器上,当然了,你可能会使用其它类型的OS服务器,但这里我们一CentOS 7版本为例,因为centOS更有代表性。
你可以在公众号后台私信 gdal,获取在CentOS 7平台编译gdal需要的依赖包。依赖包如下图:

如果这个版本你觉得比较低,你也可以去
-
编译Proj
#进入gdal所在目录开始执行以下命令:
[root@wb gdal]# tar -zxvf proj-4.9.3.tar.gz
[root@wb gdal]# cd proj-4.9.3/
[root@wb proj-4.9.3]# ./configure
[root@wb proj-4.9.3]# make
[root@wb proj-4.9.3]# make install -
编译Geos
#进入Geos目录,开始执行以下命令:
[root@wb gdal]# tar -jxvf geos-3.6.2.tar.bz2
[root@wb gdal]# cd geos-3.6.2/
[root@wb geos-3.6.2]# ./configure
[root@wb geos-3.6.2]# make
[root@wb geos-3.6.2]# make instal -
编译gdal
#进入gdal目录,开始执行以下命令:
[root@bogon gdal]# tar -zxvf gdal-2.1.3.tar.gz
[root@bogon gdal]# cd gdal-2.1.3
[root@bogon gdal-2.1.3]# ./configure
[root@bogon gdal-2.1.3]# make
[root@bogon gdal-2.1.3]# make install经过一段时间编译完成后,编辑 swig/java/java.opt,配置 JAVA_HOME 路径。
JAVA_HOME = /usr/java/jdk1.8.0_151
JAVADOC=$(JAVA_HOME)/bin/javadoc
JAVAC=$(JAVA_HOME)/bin/javac
JAVA=$(JAVA_HOME)/bin/java
JAR=$(JAVA_HOME)/bin/jar
JAVA_INCLUDE=-I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
之后编译 gdal 的 java 库:
[root@wb gdal-2.1.3]#cd swig/java
[root@wb java]# make
编译完成后,在 “……/gdal-2.1.3/swig/java”目录 下生成 gdal.jar 和
libgdalconstjni.so、libgdaljni.so、libogrjni.so、libosrjni.so 等 4 个 so 文件。
拷贝 4 个 so 文件到 java.library.path 路径中。
-
添加GDAL_DATA
添加 GDAL_DATA 环境变量:
[root@centos7]# vim /etc/profile
在最后插入一行,内容如下:
export GDAL_DATA=/usr/share/gdal
让配置生效:
[root@centos7]# source /etc/profile
其中,/usr/share/gdal 内容如下,若无可将“……/gdal-2.1.3/data”复制到此
处:

至此,我们已经在CentOS平台下编译好了gdal运行环境,如果你有任何问题,可以私信我交流。
GDAL开发实战
你可以选择新建一个SpringBoot工程,也可以使用你已有的工程,前提是你得完成前面我们提到的环境搭建的工作,确保我们能在SpringBoot工程中可以引用gdal的功能接口;
为了方便起见,我建议你使用已有的SpringBoot工程进行开始我们的学习,我自己就是在一个专门进行新技术学习的SpringBoot工程里面进行学习。
实战1 读取影像的元信息
在下面的代码中,我们对影响做了元信息的提取,并对影像的元信息进行了简单的处理和组装,并返回这些结果。
package com.bin.utils.gis;
import com.alibaba.fastjson.JSONObject;
import com.geovis.bin.utils.DateUtil;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.Driver;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;
import java.io.File;
/**
* @Author Wangb
* @Date 2021/11/6 22:08.
*/
public class GDALUtil {
/**
* 读取影像元信息
*
* @param fileName
* @return
*/
public static JSONObject parseImage(String fileName) {
JSONObject result = new JSONObject();
try {
//gdal使用前的所必须要有的注册语句
gdal.AllRegister();
long start = System.currentTimeMillis();
// 读取影像数据
Dataset dataset = gdal.Open(fileName, gdalconstConstants.GA_ReadOnly);
if (dataset == null) {
System.err.println("GDALOpen failed - " + gdal.GetLastErrorNo());
System.err.println(gdal.GetLastErrorMsg());
return null;
}
Driver driver = dataset.GetDriver();
//System.out.println("Driver: " + driver.getShortName() + "/" + driver.getLongName());
// 读取影像信息
String satellite_type = "CAR-" + fileName.substring(103, 105);
resultJp2.put("卫星名称",satellite_type);
result.put("参考坐标系标识", dataset.GetProjectionRef());
result.put("坐标系标识", dataset.GetProjection());
result.put("类型", driver.getShortName());
result.put("列", dataset.getRasterXSize());
result.put("行", dataset.getRasterYSize());
result.put("band", dataset.getRasterCount());
result.put("pixelsType", dataset.GetRasterBand(1).getDataType());// 像素类型
double[] transform = dataset.GetGeoTransform();
result.put("MinX", transform[0]);
result.put("MaxX", (transform[0] + dataset.getRasterXSize() * transform[1]));
result.put("MinY", (transform[3] - 