linux 安装 GDAL 3.3.2

Linux(centos8)GDAL 2.2.1 升级为 GDAL 3.3.2

一、背景:

之前篇“ Linux(centos8)安装 GDAL 2.2.1”见:
Linux(centos8)系统安装编译GDAL 2.2.1 - 简书 (jianshu.com)
由于 GDAL 2.2.1 有在 dxfgeojson 过程中存在问题:

  • 问题1:
    多行文本类型,解析出来会出现特殊符号(各种cad中非标准的转义字符,比如C5...);
  • 问题2:
    已知线型转换坐标错误:
"SubClasses": "AcDbEntity:AcDbSpline",
"EntityHandle": "8172",
"Linetype": "ACAD_ISO03W100",
"Layer": "18-1.推测冲刷构造"

Image.png

已经在windows上的3.3.1版本验证过,不存在这类问题,所以现在要把linux上的gdal版本升级到最新的3.3.2

二、环境介绍:

linux系统:
[root@cumt gdal-2.2.1]# cat /proc/version 
Linux version 4.18.0-193.el8.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC)) #1 SMP Fri May 8 10:59:10 UTC 2020

三、安装步骤:

  1. 下载gdal-3.3.2
    # wget -c -P /storage/software/gdal http://download.osgeo.org/gdal/3.3.2/gdal-3.3.2.tar.gz
  2. 解压并进入gdal-3.3.2目录:
    # tar xvf gdal-3.3.2.tar.gz
    # cd /storage/software/gdal-3.3.2
  3. 执行配置:
    # ./configure
    # make
    # make install
  • 报错1:缺少 PROJ ,需要安装
configure: error: PROJ 6 symbols not found

见:linux 安装 PROJ - 简书 (jianshu.com)

  1. 安装升级成功之后,查看版本:
    # gdalinfo --version
    image.png

四、java集成gdal:

一、介绍:

我是java程序里调用了本地的gdal,所以按照官方要求:

  • 编译gdal 3.3.2 自带的javajar包依赖,然后我选择把它打到我的maven仓库中去再引入。
  • 需要配置一些动态链接库
    相关的 java 代码:
package com.hongyi.cms.gismap.util;

/**
 * java 集成 gdal,参考:https://blog.csdn.net/liqian_ken/article/details/109228081?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-9.base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-9.base
 *  ## 下载:https://www.gisinternals.com/query.html?content=filelist&file=release-1916-x64-gdal-3-3-1-mapserver-7-6-4.zip
 *  其中的:release-1916-x64-gdal-3-3-1-mapserver-7-6-4.zip 2021-07-31 21:57:57 51942 kB    Compiled binaries in a single .zip package
 *  ## java项目引入gdal依赖:
 *  1.把bin下所有dll文件复制到jdk/bin下,
 *  2.把bin/gdal/java/下的dll复制到jdk/bin下,
 *  3.把bin/gdal/java/下的gdal.jar添加到java项目的lib中(外引:F:\ckk\software\release-1916-x64-gdal-3-3-1-mapserver-7-6-4\bin\gdal\java\gdal.jar)。
 */
import com.hongyi.cms.gismap.util.file.operate.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.gdal.gdal.gdal;
import org.gdal.ogr.*;
import org.gdal.osr.SpatialReference;

/**
 * dxf 转 geojson
 */
@Slf4j
public class Cad2GeoJsonUtil {

    /**
     * dxf转geojson(矢量拆分)
     * @param inputPath
     * @param cadFileName
     * @param outputPath
     * @return
     */
    public static boolean dxf2GeoJson(String inputPath, String cadFileName, String outputPath){
        try {
            ogr.RegisterAll();
            // gdal.SetConfigOption 选项配置参见:https://trac.osgeo.org/gdal/wiki/ConfigOptions
            // 为了支持中文路径,请添加下面这句代码
            gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
            // 为了使属性表字段支持中文,请添加下面这句
            gdal.SetConfigOption("SHAPE_ENCODING", "");
            //设置DXF缺省编码
            gdal.SetConfigOption("DXF_ENCODING", "ASCII");

//        String inputPath = "F:\\ckk\\mapbox研究\\java集成gdal\\xjlmk.dxf";
            DataSource ds = ogr.Open(inputPath + cadFileName, 0);
            if (ds == null) {
                log.info("打开dxf文件失败!filePath="+inputPath + cadFileName);
                return false;
            }
            log.info("打开dxf文件成功!");

            // 拆分矢量文件为多个单要素矢量文件,注意拆分后的fid需要重置,
            String fieldName = null;
//        String saveFolderPath = "F:\\ckk\\mapbox研究\\java集成gdal\\xjlmk-1628561264202\\";// 生成的矢量文件保存目录
            String saveFolderPath = outputPath;// 生成的矢量文件保存目录

            boolean dirExists = FileUtil.judgeDirExists(saveFolderPath, true);
            if(!dirExists){
                log.error("dxf2GeoJson,文件目录创建失败!saveFolderPath ="+saveFolderPath);
                return false;
            }

            Driver dv = ogr.GetDriverByName("GeoJSON");
            if (dv == null) {
                log.error("打开GeoJSON驱动失败!");
                return false;
            }
            log.info("打开GeoJSON驱动成功!");

            Layer layer = ds.GetLayer(0);
            SpatialReference spatial = layer.GetSpatialRef();
            int geomType = layer.GetGeomType();
            FeatureDefn layerDefn = layer.GetLayerDefn();
            int fieldCount = layerDefn.GetFieldCount();
            Feature feature = layer.GetNextFeature();
            int count = 1;
            while(feature != null){
//                Feature featureCopy = feature.Clone();
                String outName = "", outLayerName = "";
                if(fieldName ==  null){
                    Long fid = feature.GetFID();
//                    int fid = feature.GetFID();
                    outName = String.valueOf(fid);
                    outLayerName = String.valueOf(fid);
                }else{
                    outLayerName = feature.GetFieldAsString(fieldName);
                    outName = outLayerName;
                }
                if(outName == null){
                    continue;
                }
                String outFileName = outName + ".geojson";
                int dir = count % 100;// 需要分页储存,因为geojson文件过多,严重影响写入和读取效率。
                String subDir = saveFolderPath + dir + "/";
                if(!FileUtil.judgeDirExists(subDir, true)){
                    log.error("dxf2GeoJson,文件子目录创建失败!subDir ="+subDir);
                    return false;
                }
                String outFilePath = subDir + outFileName;
                DataSource outData = dv.CreateDataSource(outFilePath);
                Layer outLayer = outData.CreateLayer(outLayerName, spatial, geomType);
                for(int i=0; i<fieldCount; i++){
                    FieldDefn fieldDefn = layerDefn.GetFieldDefn(i);
                    outLayer.CreateField(fieldDefn);
                }
//                outLayer = outData.GetLayer();
                feature.SetFID(0l);
                outLayer.CreateFeature(feature);
                feature = layer.GetNextFeature();
                // 此处不执行delete()的话,会导致json文件生成缺少结尾
                if (outLayer != null) {
                    outLayer.delete();
                }
                if (outData != null) {
                    outData.delete();
                }

                count++;
            }
            // 可选
//            gdal.GDALDestroyDriverManager();// 此处会导致 java bug
            System.out.println("dxf2GeoJson完毕!!");
            return true;
        }catch (Exception e){
            e.printStackTrace();
            log.error("异常:方法dxf2GeoJson!");
            return false;
        }finally {
//            if (ds != null) { // 此处会导致 java bug
//                ds.delete();
//            }
//            if (outLayer != null) {
//                outLayer.delete();
//            }
//            if (outData != null) {
//                outData.delete();
//            }
        }
    }

    public static void main(String[] args) {
        // 注意:本地运行,需要修改pom文件中引入的gdal依赖,修改成windows用的那一版,临时注释掉linux用的那版依赖

        // 1.dxf 转 geojson
        boolean b = dxf2GeoJson("F:\\ckk\\mapbox研究\\java集成gdal\\", "葫芦素-最新.dxf", "E:\\storage\\spring" +
                "-cloud-service" +
                "\\gismap1\\784085395322318864\\test\\");
        System.out.println("bbbbbb==="+b);

    }


}
插一句,关于jdk的问题:

首先,因为我的jdk一直用的 openjdk version "1.8.0_302",版本老,在gdal运行时候会报错:

Caused by: javax.net.ssl.SSLHandshakeException: The server selected protocol version TLS10 is not accepted by client preferences [TLS12]

说是jdk版本的问题,需要注释掉 java.security 中的一些代码,这个我这边试了没行得通,现有的服务器上也正在跑着应用,所以没有进行jdk的更换。而是指定高版本的jdk即可

部署应用到linux上,/opt/jdk1.8.221/bin/java -jar AppGismap.jar 运行后,ogr.RegisterAll();这行报错:

    Native library load failed.
    java.lang.UnsatisfiedLinkError: no gdalalljni in java.library.path

“本地gdal依赖库加载失败!在java库路径中没有找到gdalalljni!!”

问题分析:

之前在windows上用java集成gdal是把一些dll动态链接库复制到jdkbin中,现在环境变成linux了,应该也需要一些.so之类的库,去研究一下官方说明:https://gdal.org/api/java/index.html
官方给的解决方案:在linux上绑定java编译GDAL/OGRhttps://trac.osgeo.org/gdal/wiki/GdalOgrInJavaBuildInstructionsUnix

实际解决过程:
  1. 修改 /storage/software/gdal/gdal-3.3.2/swig/java/java.opt 内容,指定 jdk 为:/opt/jdk1.8.221/
    主要是加这一行:JAVA_HOME = /opt/jdk1.8.221/,如下:
            # 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/
            JAVA_HOME = /opt/jdk1.8.221/
            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/linux
  1. 编译:在 /storage/software/gdal/gdal-2.2.1/swig/java/ 下执行 # make
    不要担心这个报错:./.libs/*.so error.
    我实际上报了这个错:ant: Command not found
    直接安装一下: # yum install ant
    然后重新执行: # make
    make成功,在当前文件夹下生成了 gdal.jar 和 一堆 *.so 文件。

  2. 添加动态链接库:
    /storage/software/gdal/gdal-3.3.2/swig/java/下的.so文件拷贝到/usr/local/lib/下去:
    执行:# cp /storage/software/gdal/gdal-3.3.2/swig/java/*.so /usr/local/lib/
    因为之前安装gdal的时候,配置的~/.bashrc中库指向的是/usr/local/lib,看看:

[root@cumt java]# cat ~/.bashrc
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi

export PATH=$PATH:/usr/local/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

4.gdal.jar打包到maven

  • gdal.jarlinux服务器上download到本机
    /storage/software/gdal/gdal-2.2.1/swig/java/下的gdal.jar拷贝到本地F:\ckk\newCoalProject20201026\目录下,重命名为gdal-linux-3.3.2.jar
  • 然后把jar打到本机的maven仓库中
    # mvn install:install-file -Dfile=F:\ckk\newCoalProject20201026\gdal-linux-3.3.2.jar -DgroupId=com.hongyi -DartifactId=gdal-linux -Dversion=3.3.2 -Dpackaging=jar
  • 然后在项目pom文件中引用:
       <dependency>
            <groupId>com.hongyi</groupId>
            <artifactId>gdal-linux</artifactId>
            <version>3.3.2</version>
        </dependency>

完毕。

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

推荐阅读更多精彩内容