JAVA+GDAL deployment in win and linux environment, jar package startup, related description, problem solving

Article directory

JAVA+GDAL in windows environment

1. GDAL download

Introduction to GDAL:

GDAL (Geospatial Data Abstraction Library) is an open source raster spatial data conversion library. It utilizes an abstract data model to express the various supported file formats. It also has a collection of command-line tools for data transformation and manipulation.

GDAL is developed using C++, so to use the GDAL library in the Java environment, you need to use the JNI (a way of Java cross-platform call) method to call the dll library. Therefore, we can download the source code of GDAL, and compile the available dll through Visual Studio according to the official website tutorial. But the easiest way is to use the compiled and generated dynamic dll library and jar package that meet the JNI standard. I recommend this website: http://www.gisinternals.com/archive.php to download the appropriate file.

java GDAL download : http://download.gisinternals.com/sdk.php

image-20220507105437998

image-20220507105841707

2. GDAL installation (copy after decompression)

image-20220507111815126

image-20220507112249301

Unzip the contents of the **gdal-release-1928-x64/bin/** directory in the downloaded compressed package to the jdk/bin directory (if you put the program in jdk/bin and still report an error, try putting it in the Native library load failed.directory jre/binor java工程根目录下)

Copy the gdalalljni.dll under r release-1928-x64/bin/gdal/java/ and other dlls in this directory to the root directory of the java project (if you put it in jdk/bin and run the program, you still get an error Native library load failed., try putting it jre/binin the directory or java工程根目录下), Copy gdal.jar to the java project and use maven to reference it . Now gdal for java has been placed in the maven library and can be imported directly

Local import, deprecated , it is recommended to use the maven library to import directly

<dependency>
    <groupId>org.gdal</groupId>
    <artifactId>gdal</artifactId>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/gdal.jar</systemPath>
</dependency>

maven library import

<dependency>
  <groupId>org.gdal</groupId>
  <artifactId>gdal</artifactId>
  <version>3.2.0</version>
</dependency>

3. GDAL test

import org.gdal.gdal.Band;
import org.gdal.gdal.Driver;
import org.gdal.gdal.gdal;
import org.gdal.gdal.Dataset;
import org.gdal.gdalconst.gdalconstConstants;


/**
 * @author xming
 * @createTime 2022/5/7 16:37
 * @description
 */
public class RasterGdalTest {
    
    
  private static final String FILE_PATH = "D:\\WeChat Files\\aion_my_god\\FileStorage\\File\\2022-05\\L18.tif";
  static {
    
    
    // 注册所有的驱动
    gdal.AllRegister();
    // 为了支持中文路径,请添加下面这句代码
    gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","YES");
    // 为了使属性表字段支持中文,请添加下面这句
    gdal.SetConfigOption("SHAPE_ENCODING","");
  }

  public static void main(String[] args) {
    
    
    // 读取影像数据
    Dataset dataset = gdal.Open(FILE_PATH, gdalconstConstants.GA_ReadOnly);
    if (dataset == null) {
    
    
      System.out.println("read fail!");
      return;
    }

    //  providing various methods for a format specific driver.
    Driver driver = dataset.GetDriver();
    System.out.println("driver name : " + driver.getLongName());

    // 读取影像信息
    int xSize = dataset.getRasterXSize();
    int ySzie = dataset.getRasterYSize();
    int rasterCount = dataset.getRasterCount();
    System.out.println("dataset xSize:" + xSize + ", ySzie = " + ySzie + ", rasterCount = " + rasterCount);

    Band band = dataset.GetRasterBand(1);
    //the data type of the band.
    int type = band.GetRasterDataType();
    System.out.println("data type = " + type + ", " + (type == gdalconstConstants.GDT_Byte));

    //Frees the native resource associated to a Dataset object and close the file.
    dataset.delete();

    gdal.GDALDestroyDriverManager();
  }
}

4. Jar package mode to run https://www.jianshu.com/p/6bce533f6595

Project resource structure

Use resource management gdal file, load gdal.jar through Maven, add gdal file in the web application resources directory, and then create two subfolders of linux and win32, the structure is as follows

img

Resource configuration gdal.jar, dynamic library file

Copy gdal.jar, lgdalalljni.dll from gdal\bin\gdal\java to project resources/gdal/win32

img

Start in the IDE and run normally. After being packaged into a jar package, it cannot be started directly, and the startup error is reported no gdaljni in java.library.path . The reason is that the local dynamic library gdalalljni is loaded incorrectly, and the gdalalljni dynamic library needs to be loaded

Write LibraryUtil.java dynamic library loading class

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;
/*
 * 动态库加载类:从资源加载动态库
 **/
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();
        }
    }
}

load dynamic library

  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"; //win下jni路径
            }
            else {
    
    
                file="/gdal/linux/libgdalalljni.so";//linux下jni路径
            }
            //从资源文件加载动态库
            LibraryUtil.loadFromResource(file);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

The dependent library is missing, and an error occurred when loading the gdalalljni library. Sort out the execution process:

- 检查java.library.path环境变量值
- 从java.library.path环境变量取第一个路径为目标路径D:\Program Files\Java\jdk1.8.0_231\bin
- 从目标路径判断是否存在gdalalljni.dll
- gdalalljni.dll不存在时从资源文件复制到目标路径
- System.loadLibrary载入gdalalljni.dll

Copy the gdalalljni.dll dependency library to the target path

Copy all the dlls under gdal\bin to the target path D:\Program Files\Java\jdk1.8.0_231\bin (that is, the directory where jdk is located)

img

Start the jar package again to run normally

Exception problem:

Reference library error java.lang.UnsatisfiedLinkError: no gdaljni in java.library.path

The project only references the gdal.jar package without any gdal_java dll, but the gdal dll file is not configured correctly, that is, the copy location of the gdal dll file is incorrect, resulting in the java program not being able to find the corresponding dll reference. Copy the dll to **%JAVA_HOME%/jdk/bin or %JAVA_HOME%/jre/bin** directory

Native library load failed.
java.lang.UnsatisfiedLinkError: no gdaljni in java.library.path
Exception in thread “main” java.lang.UnsatisfiedLinkError: org.gdal.gdal.gdalJNI.AllRegister()V
at org.gdal.gdal.gdalJNI.AllRegister(Native Method)
at org.gdal.gdal.gdal.AllRegister(gdal.java:499)
at cn.edu.pku.extremetool.Main.main(Main.java:21)

java.lang.UnsatisfiedLinkError: D:WorkSpaceeclipseWPMJunoExtremeToolgdaljni.dll:Can’t find dependent libraries

There is a reference to the gdal.jar package, and the gdaljni.dll file of release/gdal/java is also copied to the correct location, but the dll of GDAL itself is missing (that is, many dll files under release-1600-gdal/bin)

Native library load failed.
java.lang.UnsatisfiedLinkError: D:WorkSpaceeclipseWPMJunoExtremeToolgdaljni.dll: Can’t find dependent libraries
Exception in thread “main” java.lang.UnsatisfiedLinkError: org.gdal.gdal.gdalJNI.AllRegister()V
at org.gdal.gdal.gdalJNI.AllRegister(Native Method)
at org.gdal.gdal.gdal.AllRegister(gdal.java:499)

at cn.edu.pku.extremetool.Main.main(Main.java:21)

cannot find proj.db

Configure in the system environment variable, PROJ_LIB:C:Program FilesGDALprojlibproj.dbremember to restart or log off the computer after configuration to make the configuration take effect

img

变量名:PROJ_LIB
变量值:C:\Program Files\GDAL\projlibproj.db #修改为自己存储的projlibproj.db文件路径

If there is no such file, download gdal core and install it.

If it prompts that the DLL file (such as gdal304.dll) is missing, you need to configure the environment variable

Add the folder path containing dll (such as C:\gdal\bin) to the path variable, add the gdal-data folder (such as C:\gdal\bin\gdal-data) to the path or create a new GDAL_DATA variable

It should be noted that both Java and GDAL are either X86 (Win32) or X64 (Win64), otherwise there may be compatibility issues.

Using the gdal of the maven central warehouse to report an error

java.lang.UnsatisfiedLinkError: org.gdal.gdal.gdalJNI.Dataset_SWIGUpcast(J)J
at org.gdal.gdal.gdalJNI.Dataset_SWIGUpcast(Native Method)

If there is no Native library load failed.indication that the dll has been configured correctly
, what is the reason for the above error?

—— The SWIG version is inconsistent. The gdal dll file
in the maven central warehouse gdal.jarand the gdal dll file we downloaded and used are not compiled by the same person/team! gisinternals is likely to use SWIG 1.3.4 version, while the SWIG version used by gdal in the maven repository is temporarily unknown, it may be SWIG 2.x version.
Solution
- find the dll file consistent with the gdal.jar in the maven warehouse - not found yet
- don't use the jar in the maven central warehouse, use the jar file provided by gisinternals !

related documents

Official website of GDAL project : http://www.gdal.org

The use of GDAL in Java : http://trac.osgeo.org/gdal/wiki/GdalOgrInJava

GDAL for Java API documentation : https://gdal.org/java/org/gdal/gdal/gdal.html

GDAL related use : https://www.jianshu.com/p/ecf1b369f195

gdal for java from installation to demo implementation of various cases : https://blog.csdn.net/qq_42522024/article/details/123838982?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2% 7Edefault%7ECTRLIST%7Edefault-1-123838982-blog-114399800.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-123838982-b log-114399800.pc_relevant_default&utm_relevant_index=2

Linux system compiles and publishes gdal project https://www.jianshu.com/p/ff4cf2b59613

Compile GDAL dependencies

1. Install sqlite3

wget https://www.sqlite.org/2020/sqlite-src-3310100.zip
unzip sqlite-src-3310100.zip
cd sqlite-src-3310100
bash ./configure --prefix=/usr/local/pgsql/plugin/sqlite3
make && make install
echo "/usr/local/pgsql/plugin/sqlite3/lib" > /etc/ld.so.conf.d/sqlite3.conf
ldconfig

2. Install json-c-0.13.1

wget https://github.com/json-c/json-c/archive/json-c-0.13.1-20180305.tar.gz
tar -xzvf  json-c-0.13.1-20180305.tar.gz
cd json-c-json-c-0.13.1-20180305
bash ./configure --prefix=/usr/local/pgsql/plugin/json-c
make && make install
echo "/usr/local/pgsql/plugin/json-c/lib" > /etc/ld.so.conf.d/json-c-0.13.1.conf
ldconfig

3. Compile protobuf-3.11.4, protobuf-c 1.3.3

  • compile protobuf-3.11.4
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.11.4/protobuf-cpp-3.11.4.tar.gz
tar -xzvf  protobuf-cpp-3.11.4.tar.gz
cd protobuf-3.11.4
bash ./configure
make && make install
  • compile protobuf-c 1.3.3
wget https://github.com/protobuf-c/protobuf-c/releases/download/v1.3.3/protobuf-c-1.3.3.tar.gz
tar -xzvf  protobuf-c-1.3.3.tar.gz
cd protobuf-c-1.3.3
./autogen.sh
bash ./configure
make && make install

When it cannot be found libprotobuf.so.22, vi /etc/profile#Add the following configuration

PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
export PKG_CONFIG_PATH

source /etc/profile# configuration takes effect

4. Install Proj 6.3.1

wget https://download.osgeo.org/proj/proj-6.3.1.tar.gz
tar -xf proj-6.3.1.tar.gz
cd proj-6.3.1
./configure --prefix=/usr/local/pgsql/plugin/proj
make && make install
echo "/usr/local/pgsql/plugin/proj/lib" > /etc/ld.so.conf.d/proj-6.3.1.conf
ldconfig

5. Install GEOS 3.8.0

wget http://download.osgeo.org/geos/geos-3.8.0.tar.bz2
tar -jxf geos-3.8.0.tar.bz2
cd geos-3.8.0
./configure --prefix=/usr/local/pgsql/plugin/geos
make && make install
echo "/usr/local/pgsql/plugin/geos/lib" > /etc/ld.so.conf.d/geos-3.8.0.conf
ldconfig

6. Install SFCGAL 1.3.7

Since SFCGAL needs to rely on Boost, CGAL, GMP, and MPFR, the following four softwares need to be installed in total:
boost-devel.x86_64
gmp-devel.x86_64
mpfr-devel.x86_64
CGAL-4.14

6.1 Boost-1.5.3

yum install boost boost-devel

6.2 GMP-6.1.2

wget https://gmplib.org/download/gmp/gmp-6.1.2.tar.bz2
tar -jxvf gmp-6.1.2.tar.bz2
cd gmp-6.1.2
bash ./configure --enable-cxx
make && make install

6.3 MPFR-4.0.2

wget https://www.mpfr.org/mpfr-current/mpfr-4.0.2.tar.gz
tar -xzvf  mpfr-4.0.2.tar.gz
cd mpfr-4.0.2
./configure
make && make install

6.4 cgal-4.14

wget http://distfiles.macports.org/cgal/cgal-4.14.tar.xz
xz -d cgal-4.14.tar.xz 
tar xvf cgal-4.14.tar 
cd CGAL-4.14
mkdir build && cd build
cmake ..
make && make install

The following error occurs during installation

img

Solution: Modify the 44 lines of code in /usr/include/boost/cstdint.hpp to:

img

#if defined(BOOST_HAS_STDINT_H) \
&& (!defined(__GLIBC__) \
|| defined(__GLIBC_HAVE_LONG_LONG) \
|| (defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 17)))))

6.5 SFCGAL 1.3.7

wget  https://github.com/Oslandia/SFCGAL/archive/v1.3.7.tar.gz
tar -zxvf SFCGAL-1.3.7.tar.gz
cd SFCGAL-1.3.7  
mkdir build && cd build 
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/sfcgal ..
make  && make install
echo "/usr/local/sfcgal/lib64" > /etc/ld.so.conf.d/sfcgal-1.3.7.conf
ldconfig

7. pcre-8.44 installation

wget https://ftp.pcre.org/pub/pcre/pcre-8.44.tar.gz
tar -xzvf  pcre-8.44.tar.gz
cd pcre-8.44
./configure --enable-utf8 --prefix=/usr/local/pcre
make && make intall
echo "/usr/local/pcre/lib" > /etc/ld.so.conf.d/pcre-8.44.conf
ldconfig

8. libxml2-2.9.10 installation

wget http://xmlsoft.org/sources/libxml2-2.9.10.tar.gz
tar -xzvf  libxml2-2.9.10.tar.gz
cd libxml2-2.9.10
./configure --prefix=/usr/local/libxml2
make && make intall
echo "/usr/local/libxml2/lib" > /etc/ld.so.conf.d/libxml2-2.9.10.conf
ldconfig

9. Compile gdal.jar for java development, no development is required, you can skip it

wget https://mirrors.tuna.tsinghua.edu.cn/apache//ant/binaries/apache-ant-1.10.7-bin.tar.gz
tar -zxvf apache-ant-1.10.7-bin.tar.gz
mv apache-ant-1.10.7-bin /usr/local/ant

9.2、swig 4.0.1

wget http://prdownloads.sourceforge.net/swig/swig-4.0.1.tar.gz
tar -zxvf  swig-4.0.1.tar.gz
cd swig-4.0.1
bash ./configure --prefix=/usr/local/swig
make && make install

9.3, configuration profile

vim /etc/profile

ANT_HOME=/usr/local/ant
SWIG_HOME=/usr/local/swig

PATH=$ANT_HOME/bin:$SWIG_HOME/bin:$PATH

export ANT_HOME SWIG_HOME

source /etc/profile

view version

ant -version
swig -version

Install GDAL 3.0.4

1. Compile

wget http://download.osgeo.org/gdal/3.0.4/gdal-3.0.4.tar.gz
tar -xf gdal-3.0.4.tar.gz
cd gdal-3.0.4
bash ./configure --prefix=/usr/local/pgsql/plugin/gdal --with-proj=/usr/local/pgsql/plugin/proj --with-geos=/usr/local/pgsql/plugin/geos/bin/geos-config --with-sqlite3=/usr/local/pgsql/plugin/sqlite3 --with-libjson-c=/usr/local/pgsql/plugin/json-c
make && make install
echo "/usr/local/pgsql/plugin/gdal/lib" > /etc/ld.so.conf.d/gdal-3.0.4.conf
ldconfig

2. Error

Mistake 1: Modify /usr/local/src/gdal-3.0.4/gcore/gdal_version.h.in to gdal_version.h

img

Error 2: When this error occurs, the sqlite3 generated file is usually under /usr/local/lib. After it must be removed, recompile the sqlite3 generated file and place it separately. For example, under usr/local/sqlite3, specify –with during gdal configuration -sqlite3

Clear statement: rm should be used with caution, and it must be confirmed clearly. The reason for deleting the library is because of this rm -rf /usr/local/lib/libsqlite3* /usr/local/bin/sqlite3 /usr/local/lib/pkgconfig/sqlite3. pc

img

Error 3: The json-c static library file is missing, which can be solved by specifying the path of the static library, but this is a temporary solution. It is best to recompile json-c to usr/local/json-c, and specify --with-libjson-c when configuring gdal

cd /usr/local/src/gdal-3.0.4/apps
/bin/sh /usr/local/src/gdal-3.0.4/libtool --mode=link --silent g++ -std=c++11  gdalserver.lo  /usr/local/src/gdal-3.0.4/libgdal.la /usr/local/lib/libjson-c.a -o gdalserver

img

Error 4: make: execvp: /usr/local/gdal-3.0.4/install-sh: Permission denied

看到这个问题,是不是很高兴,表明已经编译完成了,执行安装脚本,没权限
执行  chmod 777  install-sh,赋予最高权限

3 Configure GDAL environment variables

Configure gdal/lib, gdal/bin, gdal/data through vi /etc/profile, or you can download the profile locally and upload it after modification

GDAL_HOME=/usr/local/pgsql/plugin/gdal
GDAL_DATA=$GDAL_HOME/share/gdal

LD_LIBRARY_PATH=$GDAL_HOME/lib:/usr/local/lib64:$JRE_HOME/lib:$LD_LIBRARY_PATH

PATH=$GDAL_HOME/bin:$PATH

export ... PATH LD_LIBRARY_PATH GDAL_DATA

4 GDAL installation is complete, look at the version number and supported data formats

gdalinfo --version
ogr2ogr --formats

img

Compile and generate gdal.jar

Configure java.opt

修改文件:/usr/local/src/gdal-3.0.4/swig/java/java.opt,修改JAVA_HOME的值为java的根目录
JAVA_HOME = /usr/java/jdk1.8.0_221

compile

cd /usr/local/src/gdal-3.0.4/swig/java
make && make install

gdal environment configuration for JavaWeb applications

1. Organize the files and place the generated files in the gdal/java directory

mkdir -p /usr/local/pgsql/plugin/gdal/java
cp /usr/local/src/gdal-3.0.4/swig/java/gdal.jar  /usr/local/pgsql/plugin/gdal/java
cp /usr/local/src/gdal-3.0.4/swig/java/.libs/*.so /usr/local/pgsql/plugin/gdal/java

2. Under centos, java.library.path=/usr/java/packages/lib/amd64, put libgdalalljni.so to this directory, javaWeb project loads libgdalalljni.so dynamic library from here

cp /usr/local/src/gdal-3.0.4/swig/java/.libs/*.so /usr/java/packages/lib/amd64

3. Copy the gdal.jar file generated in /swig/java to jre/lib/ext, and jvm starts loading

cp /usr/local/src/gdal-3.0.4/swig/java/gdal.jar  /usr/java/jdk1.8.0_221/jre/lib/ext

vi /etc/profile
CLASS_PATH=$JAVA_HOME/jre/lib/ext/gdal.jar:$CLASS_PATH
source /etc/profile

4. Copy the gdal.jar and libgdalalljni.so files to the project resources/gdal/linux in the /usr/local/gdal-3.0.4/swig/java/ directory

img

5. Start JavaWeb and have a look

Problems that may arise

错误1: java.lang.UnsatisfiedLinkError: Native Library /usr/java/packages/lib/amd64/libgdalalljni.so already loaded in another classloader

jvm启动时已经加载过libgdalalljni.so,不能能再次加载了,在linux系统上无需代码加载libgdalalljni.so

Error 2: libpq.so.5: cannot open shared object file: No such file or directory The reason is that the pg library is not set to the system dynamic library configuration, please set ld.so.conf

echo '/usr/local/pgsql/lib' >> /etc/ld.so.conf
ldconfig

错误3:nested exception is java.lang.UnsatisfiedLinkError: org.gdal.ogr.ogrJNI.RegisterAll()V

gdal.jar未放置到/usr/java/jdk1.8.0_221/jre/lib/ext

vi /etc/profile
CLASS_PATH=$JAVA_HOME/jre/lib/ext/gdal.jar:$CLASS_PATH
source /etc/profile

Related information

https://blog.csdn.net/qq_42522024/article/details/123838982

1. Connect to the data source

1.1. Before connecting

/*
准备工作
*/
gdal.AllRegister();
//注册所有驱动
ogr.RegisterAll();
//支持中文路径
gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
//属性表支持中文
gdal.SetConfigOption("SHAPE_ENCODING", "CP936");

1.2. Data source driver

/*
5种主要驱动程序的名称
 */
public class DriverName {
    
    
    
    //String connShp = "D:\\DIST\\Code\\Project\\zhenjiang\\镇江shp\\五角星.shp";
    public static final String shp = "ESRI Shapefile";
    
    //String connGdb = "D:\\DIST\\geoData\\shpFile\\unionResult.gdb";
    public static final String gdb = "FileGDB";//或者OpenFileGDB
    
    //String connPg = "PG:dbname=dggis host=192.168.200.34 port=30013 user=sde password=sde";
    public static final String postgreSQL = "PostgreSQL";
    
    //String connStr = "OCI:sde/sde:SYS.Yjjbnt";//连接本地库可以忽略数据库实例
    //String connSde = "OCI:gis_qf/[email protected]/orcl:CHDYZT.JSFAFW";
    //String connStr = "OCI:rcgtkjgh/[email protected]:1521/orcl:RCGTKJGH.DELSH_STBHHX";
    public static final String sde = "OCI";
    
    //String connMdb = "D:\\DIST\\geoData\\shpFile\\test.mdb";
    public static final String mdb = "PGeo";
}

1.3, the basic process of connecting data sources

/*
连接数据源的基本过程
*/
1、根据驱动名称获取驱动
    Driver driver = ogr.GetDriverByName(driverName);
2、通过驱动打开数据源
    DataSource dataSource = driver.Open(FilePath, 0);//文件路径或者连接字符串,0表示不更新数据集,为只读
3、获取数据源里的图层
    dataSource.GetLayer(index:)//根据id获取
    dataSource.GetLayer(layerName:"")//根据名称获取
4、获取图层里的要素
    //读取GDB里面的图层时,获取Feature得用GetNextFeature()方法,不能根据GetFeature(long fid)	
    layer.GetFeature(int:);//根据id

	layer.ResetReading();//把要素读取顺序重置为从第一个开始
	layer.GetNextFeature();

1.4. Read the basic information of the data

读取图层数量:
        int layerCount = dataSource.GetLayerCount();
图层名称
        String layerName = layer.GetName();
图层要素数量
        long featureCount = layer.GetFeatureCount();
图层空间参考信息
        SpatialReference s = layer.GetSpatialRef();
图层的属性表结构
        FeatureDefn featureDefn = layer.GetLayerDefn();
属性表字段数量
        int fieldCount = featureDefn.GetFieldCount();
属性表的属性字段
        FieldDefn fieldDefn = featureDefn.GetFieldDefn(i1);//根据索引获取
属性字段类型
        int fieldType = fieldDefn.GetFieldType();
        String fieldTypeName = fieldDefn.GetFieldTypeName(fieldType);
属性字段名称
        String fieldName = fieldDefn.GetName();
获取FID
        long fid = feature.GetFID();//这个是通过Feature来获取的
获取Geometry
    	Geometry geometry = feature.GetGeometryRef();
    	String geoJson = geometry.ExportToJson();
{
    
     "type": "Polygon", "coordinates": [ [ [ 119.456586303, 32.063698523000028, 0.0 ], [ 119.468721554000012, 32.045852565000018, 0.0 ], [ 119.490850540999986, 32.040141859000016, 0.0 ], [ 119.472290745, 32.028006608, 0.0 ], [ 119.478001451999944, 32.003736104999973, 0.0 ], [ 119.457300141000019, 32.023723577999988, 0.0 ], [ 119.43659882999998, 32.002308428999982, 0.0 ], [ 119.443023375000053, 32.025865093, 0.0 ], [ 119.422322064000014, 32.034431152000025, 0.0 ], [ 119.445878728000025, 32.043711050000013, 0.0 ], [ 119.456586303, 32.063698523000028, 0.0 ] ] ] }
获取图层范围
		double[] extent = layer.GetExtent();//返回4个坐标点

2. About projection

SpatialReference spatialReference = layer.GetSpatialRef();//获取图层的空间信息
//设定空间信息
//通过EPSG
SpatialReference spatialReference = new SpatialReference();
spatialReference.ImportFromEPSG(4490);
//通过WKT字符串
String strwkt = "GEOGCS[\"GCS_North_American_1927\"," +
                "DATUM[\"North_American_Datum_1927\"," +
                "SPHEROID[\"Clarke_1866\",6378206.4,294.9786982]]," +
                "PRIMEM[\"Greenwich\",0]," +
                "UNIT[\"Degree\",0.0174532925199433]]";
SpatialReference spatialReference = new SpatialReference(strwkt);

The projection information is as follows (WKT string):

PROJCS[“CGCS2000 / 3-degree Gauss-Kruger CM 117E”, //投影名称
GEOGCS[“China Geodetic Coordinate System 2000”, //地理坐标系名称
DATUM[“China_2000”, //水平基准面
SPHEROID[“CGCS2000”,6378137,298.257222101,//椭球体、长半轴,反偏率
AUTHORITY[“EPSG”,“1024”]],
AUTHORITY[“EPSG”,“1043”]],
PRIMEM[“Greenwich”,0, //中央经线Greenwich,0度标准子午线
AUTHORITY[“EPSG”,“8901”]],
UNIT[“degree”,0.0174532925199433, //指定测量使用的单位。在地理坐标系下使用角度。
AUTHORITY[“EPSG”,“9122”]],
AUTHORITY[“EPSG”,“4490”]],
PROJECTION[“Transverse_Mercator”], //投影方式
PARAMETER[“latitude_of_origin”,0], //PARAMETER表示投影参数,0表示纬度起点为0度
PARAMETER[“central_meridian”,117], //投影带的中央经线是东经117度
PARAMETER[“scale_factor”,1], //中央经线的长度比是1
PARAMETER[“false_easting”,500000], //坐标纵轴向西移动500km
PARAMETER[“false_northing”,0], //横轴没有平移
UNIT[“metre”,1, //指定测量使用的单位,指定米为测量单位
AUTHORITY[“EPSG”,“9001”]],
AXIS[“Northing”,NORTH],
AXIS[“Easting”,EAST],
AUTHORITY[“EPSG”,“4548”]]

3. Attribute query

3.1 Query by layer layer

//查询没有发生错误则返回0,注意此时的layer只包含 满足条件的要素
int result = layer.SetAttributeFilter("YSDM='3002020100'");//属性查询时注意不能用字段别名
//参数设为null表示清空查询
layer.SetAttributeFilter(null);

3.2 Query through the data source datasource

Layer queryLayer = dataSource.ExecuteSQL("select * from union5 where YSDM='3002020100'");

4. Geoprocessing

/**
 * 两个图层之间的地理处理操作
 * @param inputLayer:输入图层
 * @param queryLayer:求交图层
 * @param resultLayer:返回结果图层
 * @param spatialFilter:地理处理操作
 */
public static void spatialQuery(Layer inputLayer,Layer queryLayer,Layer resultLayer,int spatialFilter){
    
    

    Vector v = new Vector(4);
    v.add("SKIP_FAILURES=YES");//跳过处理过程中出现的错误
    v.add("PROMOTE_TO_MULTI=NO");//Polygon不转为MultiPolygon,如果设为YES则会
    v.add("INPUT_PREFIX=1_");//输入图层在属性表中的字段前缀
    v.add("METHOD_PREFIX=2_");//求交图层的字段前缀
    switch (spatialFilter){
    
    
        //相交
        case 0:
            inputLayer.Intersection(queryLayer,resultLayer,v,null);
            break;
        //合并
        case 1:
            inputLayer.Union(queryLayer,resultLayer,v,null);
    }

}

5. Create layers

/**
 * 创建矢量图层
 * @param driverName:驱动名称
 * @param path:图层保存路径,要和驱动匹配
 * @param layerName:图层名称
 * @param spatialReference:图层空间参考
 * @return 返回创建好的图层
 */
public static Layer createLayer(String driverName, String path, String layerName, SpatialReference spatialReference) {
    
    
    Layer result = null;

    Driver driver = ogr.GetDriverByName(driverName);
    if (driver == null) {
    
    
        log.info(driverName + "不可用");
        System.out.println(driverName + "不可用");
        return null;
    }
    DataSource dataSource = null;
    //这里需要判断一下path是否已经存在,存在的话先删除再创建(如果是已存在的gdb,则直接打开)
    File file = new File(path);
    if (file.exists()) {
    
    
        if (file.isFile()) {
    
    
            file.delete();
            dataSource = driver.CreateDataSource(path, null);
        } else if (file.isDirectory()) {
    
    
            dataSource = driver.Open(path, 1);
            //GDB中存在同名图层则删除
            for (int i = 0; i < dataSource.GetLayerCount(); i++) {
    
    
                Layer layer = dataSource.GetLayer(i);
                if (layerName.equals(layer.GetName())) {
    
    
                    dataSource.DeleteLayer(i);
                    dataSource.FlushCache();
                }
            }
        }
    } else {
    
    
        dataSource = driver.CreateDataSource(path, null);
    }
    if (dataSource == null) {
    
    
        log.info("数据源创建/打开失败");
        System.out.println("数据源创建/打开失败");
        return null;
    }
    result = dataSource.CreateLayer(layerName, spatialReference, ogr.wkbPolygon, null);
    if (result == null) {
    
    
        log.info(layerName + "创建失败");
        System.out.println(layerName + "创建失败");
        return null;
    }
    log.info("【"+layerName+"】" + "创建成功");
    return result;
}

6. Create elements

/**
 * 传入Geometry创建Feature,这里不定义属性字段
 * @param layer
 * @param geometry
 */
public static void createFeatureByGeometry(Layer layer, Geometry geometry) {
    
    
    FeatureDefn featureDefn = layer.GetLayerDefn();
    Feature feature = new Feature(featureDefn);
    feature.SetGeometry(geometry);
    layer.CreateFeature(feature);
}

Guess you like

Origin blog.csdn.net/qq_43961619/article/details/124627871