package com.lf.server.helper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.gdal.ogr.*; import java.lang.reflect.Field; import java.sql.Timestamp; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * GDB帮助类 * @author WWW */ public class GdbHelper { private final static Log log = LogFactory.getLog(GdbHelper.class); public static List excludeFields = new ArrayList(); static { excludeFields.add("gid"); excludeFields.add("shape_leng"); } /** * 获取表名 */ public static List getTabNames(String filePath) { List list = new ArrayList<>(); try { org.gdal.ogr.Driver driver = ogr.GetDriverByName("OpenFileGDB"); if (null == driver) { return list; } DataSource dataSource = driver.Open(filePath, 0); if (null == dataSource) { return list; } for (int i = 0, count = dataSource.GetLayerCount(); i < count; i++) { Layer layer = dataSource.GetLayer(i); list.add(layer.GetName()); layer.delete(); } dataSource.delete(); driver.delete(); } catch (Exception ex) { log.error(ex.getMessage(), ex); } return list; } /** * 读取数据 */ public static List readData(Class clazz, String filePath, String layerName) { List list = new ArrayList<>(); try { org.gdal.ogr.Driver driver = ogr.GetDriverByName("OpenFileGDB"); if (null == driver) { return list; } DataSource dataSource = driver.Open(filePath, 0); if (null == dataSource) { return list; } for (int i = 0, count = dataSource.GetLayerCount(); i < count; i++) { Layer layer = dataSource.GetLayer(i); if (layer.GetName().equals(layerName)) { GdbHelper.readLayer(clazz, layer, list); break; } layer.delete(); } dataSource.delete(); driver.delete(); } catch (Exception ex) { log.error(ex.getMessage(), ex); } return list; } /** * 读取图层 */ public static void readLayer(Class clazz, Layer layer, List list) { try { Field gField = getGeomField(clazz); Map map = getFieldMapper(clazz, layer); if (map.size() == 0) { return; } if (1 > layer.GetFeatureCount()) { return; } do { Feature f = layer.GetNextFeature(); if (null == f) { break; } T t = (T) clazz.newInstance(); if (readFeature(t, f, map, gField)) { list.add(t); } } while (true); } catch (Exception ex) { log.error(ex.getMessage(), ex); } finally { if (null != layer) { layer.delete(); } } } /** * 获取 geom 字段 */ private static Field getGeomField(Class clazz) { try { Field gField = clazz.getDeclaredField("geom"); gField.setAccessible(true); return gField; } catch (Exception ex) { return null; } } /** * 获取字段映射 */ private static Map getFieldMapper(Class clazz, Layer layer) { Map map = new HashMap<>(3); try { FeatureDefn fd = layer.GetLayerDefn(); for (int i = 0, count = fd.GetFieldCount(); i < count; i++) { FieldDefn fieldDefn = fd.GetFieldDefn(i); try { String name = fieldDefn.GetName().toLowerCase(); if (excludeFields.contains(name)){ continue; } Field field = clazz.getDeclaredField(name); field.setAccessible(true); map.put(i, field); } catch (Exception e) { // } } } catch (Exception ex) { // } return map; } /** * 读取Feature */ private static boolean readFeature(T t, Feature f, Map map, Field gField) { try { for (Integer i : map.keySet()) { Field field = map.get(i); setValue(t, f, field, i); } if (null != gField) { setGeom(t, f, gField); } return true; } catch (Exception ex) { return false; } } /** * 设置值 */ private static void setValue(T t, Feature f, Field field, Integer i) throws Exception { switch (field.getType().toString()) { case "class java.math.BigDecimal": case "class java.lang.Double": case "double": field.set(t, f.GetFieldAsDouble(i)); break; case "class java.lang.Long": case "long": field.set(t, f.GetFieldAsInteger64(i)); break; case "class java.lang.Integer": case "int": field.set(t, f.GetFieldAsInteger(i)); break; case "class java.sql.Timestamp": field.set(t, getTimestamp(f, i)); break; default: field.set(t, f.GetFieldAsString(i)); break; } } /** * 设置 geom 字段值 *

* wkbUnknown = 0, * wkbPoint = 1, * wkbLineString = 2, * wkbPolygon = 3, * wkbMultiPoint = 4, * wkbMultiLineString = 5, * wkbMultiPolygon = 6, * wkbGeometryCollection = 7, * wkbNone = 100, * wkbLinearRing = 101 */ private static void setGeom(T t, Feature f, Field gField) throws Exception { Geometry geometry = f.GetGeometryRef(); if (null != geometry) { String wkt = geometry.ExportToWkt(); switch (geometry.GetGeometryType()) { case 2: wkt = wkt.replace("LINESTRING (", "MULTILINESTRING ((") + ")"; break; case 3: wkt = wkt.replace("POLYGON (", "MULTIPOLYGON ((") + ")"; break; default: break; } gField.set(t, String.format("ST_GeomFromText('%s')", wkt)); } } /** * 获取 Timestamp */ private static Timestamp getTimestamp(Feature f, int 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]; f.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; } }