一. 背景
新公司项目需要在java语言测调用GDAL进行空间数据转换,MAC环境在java JNI调用方面报错,具体报错内容如下:
经过一些资料调查,通过手动编译的方式解决了该问题。
二. 基础环境
MAC intel 15.1
gcc@13: stable 13.3.0 (bottled)
GNU Make 3.81
hdf5@1.10
proj: stable 9.5.0 (bottled)
swing: 4.3.0
ant: 1.10.15
java version "1.8.0_271"
目标: 编译 gdal 3.0.0 并生成其对应的java动态库
三. 安装
brew安装
Homebrew是一款Mac OS平台下的软件包管理工具,拥有安装、卸载、更新、查看、搜索等很多实用的功能。简单的一条指令,就可以实现包管理,而不用你关心各种依赖和文件路径的情况,十分方便快捷。
我们需要安装brew,并将源切换至国内镜像。具体参考以下链接:
Mac brew更新国内源或重置官方源_brew update要多久-CSDN博客
基础依赖安装
- 使用
brew安装基础依赖 如gcc make hdf5 proj等 - 所有的安装过程大概分为 查询 安装 具体命令如下
brew search xxx
brew install xxx
- 安装完毕之后就可以在终端直接使用他们对应的命令了
- 依次安装基础依赖 版本号需要大于等于我列出的版本号(
gdal3.0.0其实需要的版本号比我目前列出的更低 但是brew直接安装的话 很多版本找不到。只能手动编译,有些包手动编译很麻烦,所以笔者这边根据目前我这个版本的brew可以提供的基础依赖版本进行了多次尝试....)
GDAL安装及动态库编译
- 新增环境变量
vim ~/.zshrc
# 新增如下变量
alias gcc='gcc-13'
alias g++='g++-13'
alias c++="c++-13"
export CC=/usr/local/bin/gcc-13
export CXX=/usr/local/bin/g++-13
source ~/.zshrc
- 解压下载文件并创建相关目录
cd ~
# 创建安装目录
mkdir software/gdal
# 创建编译后可执行文件安装目录
mkdir software/gdal/gdal
mv Download/gdal-3.0.0.tar.gz software/gdal
cd software/gdal
tar -xvf gdal-3.0.0.tar.gz
cd gdal-3.0.0
- 执行
<font style="color:#000000;">configure</font>
# 运行配置脚本,用于配置软件的编译和安装选项
./configure \
# 设置C++编译器的标志,这里指定使用C++11标准进行编译
CXXFLAGS="-std=c++11" \
# 指定软件安装的前缀路径,即安装后的文件将被放置在该目录下及其子目录中
--prefix=/Users/lijinxiong/software/gdal/gdal \
# 启用多线程支持,使软件在运行时能够利用多线程来提高性能
--with-threads \
# 禁用静态库的构建,通常意味着只生成动态库,这样可以在运行时共享库文件,节省磁盘空间等
--disable-static \
# 不包含与GRASS相关的功能或模块(GRASS可能是另一个地理信息相关软件等)
--without-grass \
# 启用对Jasper库的支持,Jasper库可能用于处理图像数据等相关功能
--with-jasper \
# 启用对LibTIFF库的支持,LibTIFF库常用于处理TIFF图像格式,可能用于软件中涉及到的图像相关操作
--with-libtiff \
# 启用对JPEG库的支持,用于处理JPEG图像格式的相关功能
--with-jpeg \
# 指定PROJ库的路径,PROJ库可能用于地理坐标转换等地理信息相关的操作,这里指定了其具体安装位置
--with-proj=/usr/local/Cellar/proj/9.5.0 \
# 启用对GeoTIFF库的支持,GeoTIFF库用于处理带有地理信息的TIFF图像格式,可能用于软件中的地理图像相关功能
--with-geotiff \
# 设置pcraster相关功能为内部实现(具体含义可能因软件上下文而异,pcraster可能是某种数据处理相关的模块)
--with-pcraster=internal \
# 启用对Expat库的支持,Expat库常用于处理XML数据等相关功能,可能用于软件中的数据解析等操作
--with-expat \
# 启用对Curl库的支持,Curl库用于进行网络请求等相关操作,可能用于软件从网络获取数据等功能
--with-curl \
# 启用对NetCDF库的支持,NetCDF库常用于处理科学数据格式,可能用于软件中的数据存储、读取等相关操作
--with-netcdf \
# 指定HDF5库的路径,HDF5库用于处理高性能数据格式,这里指定了其具体安装位置,可能用于软件中的数据处理相关功能
--with-hdf5=/usr/local/Cellar/hdf5@1.10/1.10.11 \
# 启用对OpenCL库的支持,OpenCL库用于进行并行计算等相关操作,可能用于软件中的计算密集型任务以提高性能
--with-opencl \
# 设置LibZ库相关功能为内部实现(LibZ库常用于压缩和解压缩操作,可能用于软件中的数据压缩等相关功能)
--with-libz=internal \
# 不包含与Python相关的功能或模块,即不构建或启用软件与Python交互的相关功能
--without-python \
# 禁用CAD驱动相关功能(CAD可能是计算机辅助设计相关,这里可能涉及到处理CAD格式数据等功能)
--disable-driver-cad \
# 不包含与Lerc库相关的功能或模块(Lerc库可能用于某种数据压缩或处理等功能)
--without-lerc \
# 启用对C++语言的支持,明确指定软件在编译时支持C++语言相关的功能实现
--enable-languages=c++ \
# 指定Java环境变量的路径,即设置软件与Java相关的功能将使用该路径下的Java环境,用于软件与Java交互的相关功能
--with-java=$JAVA_HOME
- 编译完毕,编译过程中出现
not found xxx依赖的话 缺少什么直接用brew安装什么,名字可能和brew中的不太一样,可根据百度解决。 make -j4并行编译源码
- 编译过程中可能因为某些依赖的版本过高造成编译报错,可根据实际情况进行版本降低,或者根据实际报错的源码处 查看该功能是否重要,属于哪个模块,是否可跳过,具体跳过的参数可以根据查询到的模块查看configure的源码进行查找。例如检查设置命令中的
--disable-driver-cad``--without-lerc都是这个原因。(最好的方式还是下载对应版本,但是懒得编译了😂) - 编译中....(二十分钟左右)
- 编译完毕
make install
- 编译
Java动态库
cd swing/java
# 修改java.opt
vim java.opt
# 修改如下
# Java Stuff
#JAVA_HOME = "C:\Program Files\Java\jdk1.6.0_16"
#JAVA_HOME = /usr/lib/jvm/java-6-openjdk/
#JAVA_HOME = /usr/lib/jvm/java-7-openjdk-amd64/
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/darwin
# 修改完成
# 修改构建文件 将里面的1.6 全部修改成1.8 一共有四处
vim build.xml
make
- 将动态库复制到
<font style="color:#000000;">/Library/Java/Extensions</font>
sudo rm -rf /Library/Java/Extensions/*
sudo cp libgdalalljni.* /Library/Java/Extensions/
- 新增环境变量
vim ~/.bash_profile
# 新增如下
export HDF5_DIR=/usr/local/opt/hdf5@1.10
export LD_LIBRARY_PATH=$HDF5_DIR/lib:$LD_LIBRARY_PATH
export GDAL_DIR=/Users/lijinxiong/software/gdal/gdal
export PATH=$GDAL_DIR/bin:$PATH
export LD_LIBRARY_PATH=$GDAL_DIR/lib:$LD_LIBRARY_PATH
export CPLUS_INCLUDE_PATH=$GDAL_DIR/include:$CPLUS_INCLUDE_PATH
export LIBRARY_PATH=$GDAL_DIR/lib:$LIBRARY_PATH
# end
source ~/.bash_profile
- 安装完毕
四. 验证
pom引入GDAL依赖
<dependency>
<groupId>org.gdal</groupId>
<artifactId>gdal</artifactId>
<version>3.0.0</version>
</dependency>
import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.Driver;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;
/**
* @author X_L
* @version 1.0.0
* @since 2024年11月10日 16:35:00
*/
public class Test {
public static void main(String[] args) {
// 注册所有的 GDAL 驱动
gdal.AllRegister();
// 获取 GTiff 驱动
Driver gtiffDriver = gdal.GetDriverByName("GTiff");
if (gtiffDriver == null) {
System.err.println("无法获取 GTiff 驱动。");
return;
}
// 创建一个新的图像数据集
int width = 256;
int height = 256;
Dataset dataset = gtiffDriver.Create("test.tif", width, height, 1, gdalconstConstants.GDT_Byte);
if (dataset == null) {
System.err.println("无法创建图像数据集。");
return;
}
// 获取数据集的第一个波段
Band band = dataset.GetRasterBand(1);
// 设置波段的值
byte[] data = new byte[width * height];
for (int i = 0; i < data.length; i++) {
int x = i % width;
int y = i / width;
int value = (x + y) % 256;
data[i] = (byte) value;
}
band.WriteRaster(0, 0, width, height, data);
// 释放资源
dataset.delete();
}
}
五. 参考资料
M1 mac 编译java gdal 3.0.4和3.6.3到指定目录_mac安装gdal-CSDN博客
gdal/CONTRIBUTING.md at release/3.0 · OSGeo/gdal
Past Releases — GDAL documentation
liunx下安装gdal,并编译部署供java项目调用_gdal 3.2.0 源码安装-CSDN博客
macos java 使用 GDAL_mob64ca12d9081f的技术博客_51CTO博客