2、JAVA集成GDAL-JAVA开发环境整合GDAL

一、 Windows部署GDAL
二、 JAVA开发环境整合GDAL
三、 部署Java集成gdal项目
四、 Linux系统编译、发布gdal项目

二、JAVA开发环境整合GDAL

1、新建一个SpringMvc或者SpringBoot项目

跳过这个过程,大家根据IDE自行完成

2、项目资源结构

采用资源管理gdal文件,通过Maven加载gdal.jar,在web应用resources目录下新增gdal文件件,再新建linux,win32两个子文件夹,结构如下


image.png

3、资源配置gdal.jar,动态库文件

Program Files\gdal\bin\gdal\java 复制 gdal.jar、lgdalalljni.dll 到项目 resources/gdal/win32

image.png

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

image.png

报错是本地动态库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

image.png

缺少依赖库,载入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

image.png

继续Run As->Java Appliction
image.png

到这里,恭喜恭喜,环境已经完全配置好了
ERROR 1: PROJ: proj_identify: Cannot find proj.db如果出现找不到proj.db文件, 配置环境变量 PROJ_LIB=D:\Program Files\gdal\bin\proj6\share

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容