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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容