一、 Windows部署GDAL
二、 JAVA开发环境整合GDAL
三、 部署Java集成gdal项目
四、 Linux系统编译、发布gdal项目
二、JAVA开发环境整合GDAL
1、新建一个SpringMvc或者SpringBoot项目
跳过这个过程,大家根据IDE自行完成
2、项目资源结构
采用资源管理gdal文件,通过Maven加载gdal.jar,在web应用resources目录下新增gdal文件件,再新建linux,win32两个子文件夹,结构如下
3、资源配置gdal.jar,动态库文件
从Program Files\gdal\bin\gdal\java 复制 gdal.jar、lgdalalljni.dll 到项目 resources/gdal/win32
4、Hello GDAL
(1) POM配置gdal路径
<properties>
……
<gdal.bindir>src/main/resources/gdal/win32</gdal.bindir>
</properties>
(2) POM配置gdal依赖
<dependency>
<groupId>org.gdal</groupId>
<artifactId>gdal</artifactId>
<version>3.7.4</version>
<scope>system</scope>
<systemPath>${project.basedir}/${gdal.bindir}/gdal.jar</systemPath>
</dependency>
(3)Hello GDAL
public static void main(String[] args) {
String shpFileName="\\usr\\test\\zzt_headCells.shp";
String geojsonFileName="\\usr\\test\\zzt_headCells.geojson";
shpToGeojson(shpFileName,geojsonFileName);
}
/**
* shp转换geojson
* @param shpFileName
* @param geojsonFileName
*/
public static void shpToGeojson(String shpFileName,String geojsonFileName) {
log.info("---gdal注册所有的驱动开始");
// 注册所有的驱动
ogr.RegisterAll();
log.info("---gdal注册所有的驱动结束");
// 为了支持中文路径,请添加下面这句代码
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","YES");
// 为了使属性表字段支持中文,请添加下面这句
gdal.SetConfigOption("SHAPE_ENCODING","");
//打开数据
DataSource ds = ogr.Open(shpFileName,0);
if (ds == null){
System.out.println("打开文件"+shpFileName+"失败!" );
return;
}
System.out.println("打开文件成功!" );
org.gdal.ogr.Driver dv = ogr.GetDriverByName("GeoJSON");
if (dv == null){
System.out.println("打开驱动失败!" );
return;
}
System.out.println("打开驱动成功!" );
//输出geojson的位置及文件名
dv.CopyDataSource(ds, geojsonFileName);
System.out.println("转换成功!");
}
Run As->Java Appliction
报错是本地动态库gdalalljni载入错误,需要加载gdalalljni动态库
(4)编写LibraryUtil.java动态库加载类
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
* 动态库加载类:从资源加载动态库
* @date: 20200401
* @author: yuzh
**/
public class LibraryUtil {
private static final Logger log = LoggerFactory.getLogger(LibraryUtil.class);
/**
* 从资源文件加载类
* * @param clazz jar中类
* @param file resources目录下文件全路径:/gdal/win32/gdalalljni.dll
*/
public static void loadFromResource(String file) throws IOException{
try {
//获取系统路径
String[] libraryPaths=initializePath("java.library.path");
log.info("---LibraryUtil-----java.library.path={}",StringUtil.join(";", libraryPaths));
if(libraryPaths==null||libraryPaths.length==0) {
log.info("---LibraryUtil--请设置环境变量java.library.path");
return;
}
String nativeTempDir=libraryPaths[0];
int sepIndex=file.lastIndexOf(File.separator);
if(sepIndex==-1) {
sepIndex=file.lastIndexOf("/");
}
String fileName=file.substring(sepIndex+1);
log.info("---LibraryUtil--从环境变量{}加载{}",nativeTempDir,fileName);
//系统库不存在,就从资源文件复制
File extractedLibFile = new File(nativeTempDir+File.separator +fileName);
if(!extractedLibFile.exists()){
//file resources目录下文件全路径:/gdal/windows/gdalalljni.dll
InputStream in = LibraryUtil.class.getResourceAsStream(file);
if(in==null) {
log.info("---LibraryUtil--资源文件不存在{}",file);
throw new FileNotFoundException(file);
}
saveFile(in,extractedLibFile);
//保存文件到java.library.path
log.info("---LibraryUtil--成功保存文件{}到{}",fileName,extractedLibFile.getPath());
}
//注意采用loadLibrary加载时mapLibraryName方法会根据系统补全名称
int startIndex=fileName.startsWith("lib")?3:0;
String libName=fileName.substring(startIndex,fileName.indexOf("."));
String mapLibraryName=System.mapLibraryName(libName);
log.info("---LibraryUtil--mapLibraryName={}",mapLibraryName);
//输出调试信息
log.info("---LibraryUtil--系统加载动态库{}开始",libName);
System.loadLibrary(libName);
log.info("---LibraryUtil--系统加载动态库{}完成",libName);
}
catch(Exception ex) {
log.error(ex.getMessage());
}
}
private static String[] initializePath(String propname) {
String ldpath = System.getProperty(propname, "");
String ps = File.pathSeparator;
int ldlen = ldpath.length();
int i, j, n;
// Count the separators in the path
i = ldpath.indexOf(ps);
n = 0;
while (i >= 0) {
n++;
i = ldpath.indexOf(ps, i + 1);
}
// allocate the array of paths - n :'s = n + 1 path elements
String[] paths = new String[n + 1];
// Fill the array with paths from the ldpath
n = i = 0;
j = ldpath.indexOf(ps);
while (j >= 0) {
if (j - i > 0) {
paths[n++] = ldpath.substring(i, j);
} else if (j - i == 0) {
paths[n++] = ".";
}
i = j + 1;
j = ldpath.indexOf(ps, i);
}
paths[n] = ldpath.substring(i, ldlen);
return paths;
}
public static void saveFile(InputStream in, File extractedLibFile) throws IOException{
BufferedInputStream reader = null;
FileOutputStream writer = null;
try {
//文件不存在创建文件,否则获取流报异常
createFile(extractedLibFile);
reader = new BufferedInputStream(in);
writer = new FileOutputStream(extractedLibFile);
byte[] buffer = new byte[1024];
while (reader.read(buffer) > 0){
writer.write(buffer);
buffer = new byte[1024];
}
} catch (IOException e){
throw e;
} finally {
if(in!=null)
in.close();
if(writer!=null)
writer.close();
}
}
/**
* 文件不存在创建文件,包括上级目录
*/
public static void createFile(File destFile) throws IOException{
File pfile = destFile.getParentFile();
if (!pfile.exists()) {
pfile.mkdirs();
}
if(!destFile.exists()){
destFile.createNewFile();
}
}
}
(5) Hello GDAL 调用
static {
log.info("---LibraryUtil--gdal载入动态库");
try {
//根据系统环境加载资源
String systemType = System.getProperty("os.name");
String file="";
boolean isWin=systemType.toLowerCase().indexOf("win")!=-1;
if(isWin) {
file="/gdal/win32/gdalalljni.dll";
}
else {
file="/gdal/linux/libgdalalljni.so";
}
//从资源文件加载动态库
LibraryUtil.loadFromResource(file);
} catch (Exception e) {
e.printStackTrace();
}
}
继续 Run As->Java Appliction
缺少依赖库,载入gdalalljni库时出错,梳理执行过程:
- 检查java.library.path环境变量值
- 从java.library.path环境变量取第一个路径为目标路径D:\Program Files\Java\jdk1.8.0_231\bin
- 从目标路径判断是否存在gdalalljni.dll
- gdalalljni.dll不存在时从资源文件复制到目标路径
- System.loadLibrary载入gdalalljni.dll
(5)复制gdalalljni.dll依赖库到目标路径
把 gdal\bin 下所有的dll复制到目标路径 D:\Program Files\Java\jdk1.8.0_231\bin
继续Run As->Java Appliction
到这里,恭喜恭喜,环境已经完全配置好了
ERROR 1: PROJ: proj_identify: Cannot find proj.db如果出现找不到proj.db文件, 配置环境变量 PROJ_LIB=D:\Program Files\gdal\bin\proj6\share