使用Java处理各种GIS数据格式(gdb)

2020-08-12


1.简述

  Java处理GIS数据主要有两种思路:直接使用JNI方式调用gdal/ogr库;使用GeoTools的gt-ogr-jni插件,本质还是JNI方式调用gdal/ogr库。

  使用GeoTools的gt-ogr-jni插件,可以借助GeoTools库的强大封装,实现各种查询分析功能,使用更便捷。但是,实际使用发现gt-ogr-jni插件并不完善,对于shapefile、geojson之类的数据格式支持较好,对于FileGDB数据没有进行有效测试,内部会出错。

  直接使用JNI方式调用gdal/ogr库,需要对GIS数据集有更深入的理解,使用起来更为灵活,与GeoTools的数据封装转换需要自行实现。实际上gdal/ogr库已经封装的非常完善,使用也很便捷,在GeoTools的gt-ogr-jni插件处理有问题时,推荐采用此种方式。

2.环境配置

 2.1 配置GDAL库

1)GDAL库下载地址:http://www.gisinternals.com/release.php

2)下载合适版本,根据本机java版本确定是下载32位还是64位版本,解压bin文件夹到本机目录,如:C:\gdal-runtime

3)拷贝所有的jni.dll文件到GDAL解压目录,并添加目录路径到系统PATH环境变量,同时设置GDAL_DATA环境变量为:C:\gdal-runtime\gdal-data

图片1.png 

 

 2.2 配置Maven工程

  maven配置文件中配置GeoTools仓库地址,引入GeoTools相关的常用jar包,gt-ogr-jni插件中注意排除gdal包,避免与自己下载的gdal包冲突(注意)。

  使用systemPath的方式引入上一步下载的gdal.jar,拷贝gdal.jar到路径/lib/gdal.jar。

  注意修改buil打包方式,配置includeSystemScope,打包时将会包含本地的gdal.jar。

  相关配置如以下图片所示。

图片2.png

 

 图片3.png


 

 图片4.png

 图片5.png

图片6.png

 

3.GeoTools方案

  以下为使用GeoTools的gt-ogr-jni插件,读取Shapefile示例代码,读取其他GDAL/OGR支持的数据格式只需要修改驱动名称和数据路径即可。

  实际在读取GDB数据时,遇到“Zero length BigInteger”内部数据类型转换错误,没有解决。

public static void testShapefile() {
    MapconnectionParams =new HashMap();
    connectionParams.put("DriverName", "ESRI Shapefile");
    connectionParams.put("DatasourceName", "F:\\ljdata\\镇海区街道范围.shp");
    SimpleFeatureIterator it = null;
    try {
        DataStore dataStore = DataStoreFinder.getDataStore(connectionParams);
        SimpleFeatureSource source = dataStore.getFeatureSource("镇海区街道范围");
        it = source.getFeatures().features();

        while (it.hasNext()) {
            SimpleFeature feature = it.next();
            System.out.println(feature.getAttribute("FNAME"));
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        it.close();
    }
}

 

4.gdal/ogr方案

  以下为直接使用GDAL/OGR方式读取GDB格式数据,要读取其他格式的数据只需要更换驱动名称和数据源路径,可以支持shapefile、geojson、esrijson等等,OGR支持的数据格式:https://gdal.org/drivers/vector/index.html

  GDB格式数据有两类驱动:OpenFileGDB和FileGDB,OpenFileGDB驱动是GDAL自带的,可直接使用,只支持数据读取,FileGDB驱动需要另外安装,支持读取和写入。

public static void testGDB() {
    // 注册所有的驱动
    ogr.RegisterAll();
    // 为了支持中文路径,请添加下面这句代码
    gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
    // 为了使属性表字段支持中文,请添加下面这句
    gdal.SetConfigOption("SHAPE_ENCODING", "");

    String strDriverName = "OpenFileGDB";
    org.gdal.ogr.Driver oDriver = ogr.GetDriverByName(strDriverName);
    if (oDriver == null) {
        System.out.println(strDriverName + " 驱动不可用!");
        return;
    }
    String gdbPath = "F:\\ljdata\\phjg\\供地数据.gdb";
    DataSource ds = oDriver.Open(gdbPath);
    String dsName = ds.getName();
    int count = ds.GetLayerCount();
    String layerName = ds.GetLayerByIndex(0).GetName();
    Layer layer = ds.GetLayerByIndex(0);

    Long fcount = layer.GetFeatureCount();
    FeatureDefn featureDefn = layer.GetLayerDefn();
    int fildsCount = featureDefn.GetFieldCount();
    String fname1 = featureDefn.GetFieldDefn(1).GetName();

    layer.ResetReading();
    Feature feature = null;
    while ((feature = layer.GetNextFeature()) != null) {
        String DK_MC = feature.GetFieldAsString("DK_MC");
        org.gdal.ogr.Geometry geo = feature.GetGeometryRef();
        String wkt = geo.ExportToWkt();
        System.out.println(DK_MC + ":" + wkt);
        feature.delete();
    }
    featureDefn.delete();
    layer.delete();
    ds.delete();
}