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
2.2 配置Maven工程
maven配置文件中配置GeoTools仓库地址,引入GeoTools相关的常用jar包,gt-ogr-jni插件中注意排除gdal包,避免与自己下载的gdal包冲突(注意)。
使用systemPath的方式引入上一步下载的gdal.jar,拷贝gdal.jar到路径/lib/gdal.jar。
注意修改buil打包方式,配置includeSystemScope,打包时将会包含本地的gdal.jar。
相关配置如以下图片所示。
3.GeoTools方案
以下为使用GeoTools的gt-ogr-jni插件,读取Shapefile示例代码,读取其他GDAL/OGR支持的数据格式只需要修改驱动名称和数据路径即可。
实际在读取GDB数据时,遇到“Zero length BigInteger”内部数据类型转换错误,没有解决。
public static void testShapefile() {
Map
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();
}