GDAL简介
GDAL的一个用c++语言编写的库,用于处理地理信息相关的数据包括转换,识别数据,格式化数据以及解析同时提供第三方语言的SDK,包括python,java。java是需要使用jni接口调用实现方法,在window平台是DLL文件,在linux平台是so文件,最后需要使用和初始化服务。
windows中java环境配置步骤
1. 下载GDAL
进入网站http://www.gisinternals.com/release.php选择合适的版本下载。
下载后会得到一个压缩包,解压到你所选文件目录。
2. 配置系统环境变量
- 1 设置下GDAL的目录,方便其它地方用:
2.2添加path环境变量
2.3创建PROJ_LIB变量(配置这个是进行坐标系转换是可以调用proj库)
3. Springboot环境配置
-
pom文件中引入依赖
<dependency> <groupId>org.gdal</groupId> <artifactId>gdal</artifactId> <version>3.2.0</version> </dependency>
-
准备了一个栅格矢量化的demo测试
public static void main(String[] args) { String inRaster = "D:\\gdal\\class.tif"; String outShp = "D:\\gdal\\class.shp"; //注册驱动,否则下边执行报错 gdal.AllRegister(); //载入栅格,读取相关信息 Dataset rasterDataset = gdal.Open(inRaster, gdalconstConstants.GA_ReadOnly); //栅格转矢量需要的波段信息 Band band = rasterDataset.GetRasterBand(1); //设置坐标系 SpatialReference prj = new SpatialReference(); if (rasterDataset.GetProjectionRef().isEmpty()) { prj.ImportFromEPSG(4326); } else { //栅格数据的坐标系作为矢量化后的坐标系 prj.ImportFromWkt(rasterDataset.GetProjectionRef()); } //创建输出矢量 org.gdal.gdal.Driver driver = gdal.GetDriverByName("ESRI Shapefile"); Dataset shpDataset = driver.Create(outShp, rasterDataset.getRasterXSize(), rasterDataset.getRasterYSize(), 1, gdalconst.GDT_Byte); Layer layer = shpDataset.CreateLayer("layer", prj); FieldDefn field = new FieldDefn("value", ogr.OFTInteger);//创建一个字段用来存储栅格的像素值 layer.CreateField(field, 1); //矢量化 gdal.Polygonize(band, null, layer, 0); log.info("矢量化过程完成"); layer.SyncToDisk(); //释放资源 shpDataset.delete(); rasterDataset.delete(); }
docker中的java环境配置
1.镜像拉取及Dockerfile编写
在Linux上,gdal官网上没有编译好的包,要自己去下gdal的源码包,然后自己编译,后面会生成.so文件和jar包。我用的方法是拉去了gdal3.2的镜像,把jar包丢进去直接运行,下面贴出我的Dockerfile。
FROM osgeo/gdal:3.2.0
ENV work_dir /home
ENV LANG C.UTF-8
WORKDIR ${work_dir}
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./gdal-server-1.0.0.RELEASE.jar /home/gdal-server-1.0.0.RELEASE.jar
ENTRYPOINT java -jar -Xmx1536m /home/gdal-server-1.0.0.RELEASE.jar -D java.awt.headless=true
2.构建镜像
docker build -t {自定义名称}:{自定义版本} .
3.运行
docker run -d -v /home/gdal/images:/home/gdal/images -u root --privileged {容器id}
4.测试demo
配置bean,项目启动动态加载gdal进行测试
package com.telit.gdal.task;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.gdal.gdal.gdal;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.File;
/**
* @author ck
* @Description:用于检查centos下gdal环境是否配置正确
* @date 2024/5/11 16:38
*/
//@Component
@Slf4j
public class GdalLoaderEngine {
private static final String DefaultOsPath = "gdal.os.path";
/**
* gdal环境初始化
*/
@PostConstruct
public void init() {
//1.尝试从变量中获取gdal.os.path
String property = System.getProperty(DefaultOsPath);
boolean isOk = false;
boolean isWin = false;
if (StringUtils.isNotBlank(property)) {
log.info("-------GdalLoaderEngine1-------尝试从[{}]中获取gdal配置文件", property);
isOk = loadGdal(property);
}
//4.如果是Linux环境最后还没有则从/usr/lib 中加载
if (!isOk && !System.getProperty("os.name").toLowerCase().contains("win")) {
String filePath = "/usr/lib" + "/libgdaljni.so";
log.info("-------GdalLoaderEngine4.1-------尝试从[{}]中获取gdal配置文件", filePath);
isOk = loadGdal(filePath);
if (!isOk) {
filePath = "/usr/lib" + "/libgdalalljni.so";
log.info("-------GdalLoaderEngine4.2-------尝试从[{}]中获取gdal配置文件", filePath);
isOk = loadGdal(filePath);
}
}
//如果还没获取到配置文件 则打印错误日志
if (!isOk) {
log.error("-------GdalLoaderEngine-------获取gdal环境失败!!,请检查配置文件!!");
} else {
//注册gdal驱动
gdal.AllRegister();
log.info("-------GdalLoaderEngine------- 加载配置成功");
}
}
private static boolean loadGdal(String gdalPath) {
File file = new File(gdalPath);
if (!file.exists()) {
return false;
}
try {
//加载驱动
System.load(file.getAbsolutePath());
} catch (Exception e) {
return false;
}
return true;
}
}
成功打印日志
5.说明
1 拉取不到gdal3.7的镜像,目前用的是gdal3.2的
2 运行时加上 -u root --privileged 参数,不然目录挂载读取文件会有权限问题,猜测基础镜像应该有目录权限限制