美文网首页
linux 安装 GDAL 3.3.2

linux 安装 GDAL 3.3.2

作者: 愤怒的阿昆达 | 来源:发表于2021-10-12 17:06 被阅读0次

    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>
    

    完毕。

    相关文章

      网友评论

          本文标题:linux 安装 GDAL 3.3.2

          本文链接:https://www.haomeiwen.com/subject/ejedoltx.html