之前的博客中我们已经介绍了关于ArcGIS FileGDB数据是什么,在这里我们就暂时不做重复了
1. 安装GDAL,在官网上下载安装文件(记得与电脑版本、JDK版本保持一致)
https://gdal.org/index.html
链接:https://pan.baidu.com/s/1WFbx9ap3ixukysanWRujJg
提取码:zaqz
–来自百度网盘超级会员V4的分享
2. Java 使用GDAL 读取FileGDB
2.1 Maven配置
<dependencys>
<dependency>
<groupId>org.gdal</groupId>
<artifactId>gdal</artifactId>
<version>1.11.2</version>
</dependency>
</dependencys>
具体可参考:https://blog.csdn.net/weixin_42504649/article/details/114217332
2.2 代码片段
2.2.1 读取GDB
import org.gdal.gdal.gdal;
import org.gdal.ogr.*;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
/**
* @Classname GDALHelper
* @Description GDAL读取GDB
* @Date 2021/4/19 16:27
* @Created by xiaocai
*/
public class GDALHelper {
static {
gdal.AllRegister();
}
public static void main(String[] args) {
Driver driver = ogr.GetDriverByName("OpenFileGDB");
DataSource dataSource = driver.Open("C:\\Users\\xiaocai\\Desktop\\XYBASE.gdb", 0);
for (int i = 0; i < dataSource.GetLayerCount(); i++) {
//获取图层
Layer layer = dataSource.GetLayer(i);
System.out.println(i + "\t" + layer.GetName());
do {//获取图层下的要素
Feature feature = layer.GetNextFeature();
if (null == feature) {
break;
}
//获取样式,这里是空,待确定
System.out.println(feature.GetStyleString());
//获取geometry
System.out.println(feature.GetGeometryRef().ExportToWkt());//也可以ExportToWkb() gml等等
//获取属性
for (int p = 0; p < feature.GetFieldCount(); p++) {
System.out.println(feature.GetFieldDefnRef(p).GetName()
+ "\t" +
getProperty(feature, p));
}
System.out.println("---------");
} while (true);
}
}
private static Object getProperty(Feature feature, int index) {
int type = feature.GetFieldType(index);
PropertyGetter propertyGetter;
if (type < 0 || type >= propertyGetters.length) {
propertyGetter = stringPropertyGetter;
} else {
propertyGetter = propertyGetters[type];
}
try {
return propertyGetter.get(feature, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 属性获取器
*/
@FunctionalInterface
private interface PropertyGetter {
Object get(Feature feature, int index);
}
private static final PropertyGetter stringPropertyGetter = (feature, index) -> feature.GetFieldAsString(index);
/**
* feature.GetFieldType(index)得到一个属性类型的int值,该值对应具体类型
*/
private static final PropertyGetter[] propertyGetters = new PropertyGetter[]{
(feature, index) -> feature.GetFieldAsInteger(index),//0 Integer
(feature, index) -> feature.GetFieldAsIntegerList(index),//1 IntegerList
(feature, index) -> feature.GetFieldAsDouble(index),//2 Real
(feature, index) -> feature.GetFieldAsDoubleList(index),//3 RealList
stringPropertyGetter,//4 String
(feature, index) -> feature.GetFieldAsStringList(index),//5 StringList
stringPropertyGetter,//6 (unknown)
stringPropertyGetter,//7 (unknown)
(feature, index) -> feature.GetFieldAsBinary(index),//8 Binary
(feature, index) -> {
int[] pnYear = new int[1];
int[] pnMonth = new int[1];
int[] pnDay = new int[1];
int[] pnHour = new int[1];
int[] pnMinute = new int[1];
float[] pfSecond = new float[1];
int[] pnTZFlag = new int[1];
feature.GetFieldAsDateTime(index, pnYear, pnMonth, pnDay, pnHour, pnMinute, pfSecond, pnTZFlag);
Date date = Date.valueOf(LocalDate.of(pnYear[0], pnMonth[0], pnDay[0]));
return date;
},//9 Date
(feature, index) -> {
int[] pnYear = new int[1];
int[] pnMonth = new int[1];
int[] pnDay = new int[1];
int[] pnHour = new int[1];
int[] pnMinute = new int[1];
float[] pfSecond = new float[1];
int[] pnTZFlag = new int[1];
feature.GetFieldAsDateTime(index, pnYear, pnMonth, pnDay, pnHour, pnMinute, pfSecond, pnTZFlag);
float fSecond = pfSecond[0];
int s = (int) fSecond;
int ns = (int) (1000000000 * fSecond - s);
Time time = Time.valueOf(LocalTime.of(pnHour[0], pnMinute[0], s, ns));
return time;
},// 10 Time
(feature, index) -> {
int[] pnYear = new int[1];
int[] pnMonth = new int[1];
int[] pnDay = new int[1];
int[] pnHour = new int[1];
int[] pnMinute = new int[1];
float[] pfSecond = new float[1];
int[] pnTZFlag = new int[1];
feature.GetFieldAsDateTime(index, pnYear, pnMonth, pnDay, pnHour, pnMinute, pfSecond, pnTZFlag);
float fSecond = pfSecond[0];
int s = (int) fSecond;
int ns = (int) (1000000000 * fSecond - s);
LocalDateTime localDateTime = LocalDateTime.of(
LocalDate.of(pnYear[0], pnMonth[0], pnDay[0]),
LocalTime.of(pnHour[0], pnMinute[0], s, ns)
);
Timestamp timestamp = Timestamp.valueOf(localDateTime);
return timestamp;
},//11 DateTime
(feature, index) -> feature.GetFieldAsInteger64(index),//12 Integer64
(feature, index) -> feature.GetFieldAsIntegerList(index),//13 Integer64List
//>=14 (unknown)
};
}
2.2.2 在PostGIS中创建要素类
System.out.println(String.format("%s %s ", layer.GetName(), layer.GetGeomType()));
if (layer.GetGeomType() == ogr.wkbPoint||layer.GetGeomType()==ogr.wkbPointM||layerGetGeomType()==ogr.wkbPointZM) {
pCreateLayer = pgDataSource.CreateLayer(layer.GetName(), layer.GetSpatialRef(), ogr.wkbPoint, null);
} else if (layer.GetGeomType() ==ogr.wkbLineString||layer.GetGeomType() ==ogrwkbMultiLineString||layer.GetGeomType() ==ogr.wkbMultiLineStringM||layer.GetGeomTyp() ==ogr.wkbMultiLineStringZM) {
pCreateLayer = pgDataSource.CreateLayer(layer.GetName(), layer.GetSpatialRef(), ogr.wkbMultiLineString, null);
} else {
pCreateLayer = pgDataSource.CreateLayer(layer.GetName(), layer.GetSpatialRef(), ogr.wkbMultiPolygon, null);
}
FeatureDefn pFeatureDefn = layer.GetLayerDefn();
int iFieldCount = pFeatureDefn.GetFieldCount();
for (int iAttr = 0; iAttr < iFieldCount; iAttr++) {
FieldDefn oField = pFeatureDefn.GetFieldDefn(iAttr);
if (!oField.GetName().toUpperCase().equals("SHAPE_LENGTH") && !oField.GetName().toUpperCase().equals("SHAPE_AREA")) {
pCreateLayer.CreateField(oField);
}
}
pgDataSource.FlushCache();
pgDataSource.FlushCache();
比较关键,需要同步缓存到数据库,否则在变量释放前是找不到数据的
2.2.3. 插入要素类到PostGIS中
public void inputGDBFeaClass2PostGIS(Layer layer, Layer pPGLayer, Connection connection) {
PreparedStatement preparedStatement = null;
try{
int index = 0;
Map<String, Object> mapValues = new LinkedHashMap<>();
String strInsertSql = getPgClassInsertSql(layer.GetName(), layer, mapValues,pPGLayer);
preparedStatement = connection.prepareStatement(strInsertSql);
Feature oFeature = null;
// FeatureDefn pCreateFeatureDefn =pPGLayer.GetLayerDefn();
// 下面开始遍历图层中的要素
while ((oFeature = layer.GetNextFeature()) != null) {
//获取属性
for (int p = 0; p < oFeature.GetFieldCount(); p++) {
if(mapValues.containsKey(oFeature.GetFieldDefnRef(p).GetName().toLowerCase()))
{
mapValues.put(oFeature.GetFieldDefnRef(p).GetName().toLowerCase(),getProperty(oFeature, p));
}
}
// 带高程信息转为二维平面数据
Geometry pGeometry=oFeature.GetGeometryRef();
pGeometry.FlattenTo2D();
mapValues.put("wkb_geometry",pGeometry.ExportToWkt());
Integer MapIndex = 1;
for (String key : mapValues.keySet()) {
if(key.toString().equals("wkb_geometry"))
{
preparedStatement.setString(MapIndex++, String.format("SRID=4528;%s",mapValues.get(key).toString()));
}
else
{
preparedStatement.setObject(MapIndex++, mapValues.get(key));
}
}
preparedStatement.addBatch();
index++;
if (index % 10000 == 0) {
System.out.println(index);
preparedStatement.executeBatch();
preparedStatement.clearBatch();
}
}
preparedStatement.executeBatch();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
private String getPgClassInsertSql(String strLayerName, Layer pSouceLayer, Map<String, Object> mapValues, Layer pPGTargetLayer) {
List<String> listValues = new ArrayList<>();
FeatureDefn pSourceFeatureDefn = pSouceLayer.GetLayerDefn();
FeatureDefn pPGTargetFeatureDefn = pPGTargetLayer.GetLayerDefn();
for (int i = 0; i < pSourceFeatureDefn.GetFieldCount(); i++) {
FieldDefn pSourceFieldDefn = pSourceFeatureDefn.GetFieldDefn(i);
if (pPGTargetFeatureDefn.GetFieldIndex(pSourceFieldDefn.GetName()) >= 0) {
mapValues.put(pSourceFieldDefn.GetName().toLowerCase().toString(), null);
listValues.add("?");
}
}
mapValues.put("wkb_geometry", null);
listValues.add("st_geomfromText(?)");
String strInsertSql = String.format("insert into %s(%s) values(%s)", strLayerName, String.join(",", mapValues.keySet()), String.join(",", listValues));
return strInsertSql;
}