package com.moon.server.helper; import com.moon.server.entity.all.BaseGeoEntity; import com.moon.server.entity.all.StaticData; import com.moon.server.mapper.all.BasicMapper; import com.moon.server.mapper.all.GeomBaseMapper; import com.moon.server.service.all.BaseQueryService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.gdal.ogr.*; import org.gdal.osr.SpatialReference; import java.lang.reflect.Field; import java.math.BigDecimal; import java.sql.Timestamp; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.util.*; /** * GDB帮助类 * @author WWW */ public class GdbHelper { private final static Log log = LogFactory.getLog(GdbHelper.class); /** * 销毁资源 */ public static void delete(Layer layer) { try { if (null != layer) { layer.delete(); } } catch (Exception ex) { log.error(ex.getMessage(), ex); } } /** * 销毁资源 */ public static void delete(DataSource dataSource, Driver driver) { try { if (null != dataSource) { dataSource.delete(); } } catch (Exception ex) { log.error(ex.getMessage(), ex); } try { if (null != driver) { driver.delete(); } } catch (Exception ex) { log.error(ex.getMessage(), ex); } } /** * 销毁资源 */ public static void delete(Layer layer, DataSource dataSource, Driver driver) { delete(layer); delete(dataSource, driver); } /** * 获取表名 */ public static List getTabNames(String filePath) { List list = new ArrayList<>(); Driver driver = null; DataSource dataSource = null; try { // driver = ogr.GetDriverByName("OpenFileGDB") driver = ogr.GetDriverByName("FileGDB"); if (null == driver) { log.error("GdbHelper.getTabNames.driver is null."); return list; } dataSource = driver.Open(filePath, 0); if (null == dataSource) { log.error("GdbHelper.getTabNames.dataSource is null. " + filePath); return list; } for (int i = 0, count = dataSource.GetLayerCount(); i < count; i++) { Layer layer = dataSource.GetLayer(i); list.add(layer.GetName()); layer.delete(); } } catch (Exception ex) { log.error(ex.getMessage(), ex); } finally { GdbHelper.delete(dataSource, driver); } return list; } /** * 读取数据 */ public static List readData(Class clazz, String filePath, String layerName) { List list = new ArrayList<>(); Driver driver = null; DataSource dataSource = null; try { // driver = ogr.GetDriverByName("OpenFileGDB") driver = ogr.GetDriverByName("FileGDB"); if (null == driver) { return list; } 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(); } } catch (Exception ex) { log.error(ex.getMessage(), ex); } finally { GdbHelper.delete(dataSource, driver); } return list; } /** * 读取图层 */ public static void readLayer(Class clazz, Layer layer, List list) { try { Field gField = getGeomField(clazz); Map map = new HashMap<>(3); getFieldMapper(clazz, layer, map); if (map.isEmpty() || 0 == layer.GetFeatureCount()) { return; } do { Feature f = layer.GetNextFeature(); if (null == f) { break; } T t = (T) clazz.newInstance(); readFeature(t, f, map, gField); list.add(t); } while (true); } catch (Exception ex) { log.error(ex.getMessage(), ex); } finally { GdbHelper.delete(layer); } } /** * 获取 geom 字段 */ private static Field getGeomField(Class clazz) { try { Field gField = clazz.getSuperclass().getDeclaredField("geom"); gField.setAccessible(true); return gField; } catch (Exception ex) { return null; } } /** * 获取字段映射 */ private static void getFieldMapper(Class clazz, Layer layer, Map map) { 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 (StaticData.READ_EXCLUDE_FIELDS.contains(name)) { continue; } Field field = clazz.getDeclaredField(name); field.setAccessible(true); map.put(i, field); } catch (Exception e) { // } } if (!StaticData.OBJECT.equals(clazz.getSuperclass().getName())) { getFieldMapper(clazz.getSuperclass(), layer, map); } } catch (Exception ex) { // } } /** * 读取Feature */ private static void readFeature(T t, Feature f, Map map, Field gField) { for (Integer i : map.keySet()) { try { Field field = map.get(i); setValue(t, f, field, i); } catch (Exception e) { log.error(e.getMessage(), e); } } if (null != gField) { setGeom(t, f, gField); } } /** * 设置值 */ public static void setValue(T t, Feature f, Field field, Integer i) throws Exception { switch (field.getType().getName()) { case "java.math.BigDecimal": double dd = f.GetFieldAsDouble(i); field.set(t, BigDecimal.valueOf(dd)); break; case "java.lang.Double": case "double": field.set(t, f.GetFieldAsDouble(i)); break; case "java.lang.Long": case "long": field.set(t, f.GetFieldAsInteger64(i)); break; case "java.lang.Integer": case "int": field.set(t, f.GetFieldAsInteger(i)); break; case "java.sql.Timestamp": Timestamp ts = getTimestamp(f, i); if (null != ts) { field.set(t, ts); } break; case "java.time.LocalDate": LocalDate ld = getLocalDate(f, i); if (null != ld) { field.set(t, ld); } 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) { try { String geo = "null"; if (null != f.GetGeometryRef()) { String wkt = f.GetGeometryRef().ExportToWkt(); // f.GetGeometryRef().GetGeometryType() if (wkt.contains(StaticData.LINESTRING) && !wkt.contains(StaticData.MULTILINESTRING)) { wkt = wkt.replace("LINESTRING (", "MULTILINESTRING ((") + ")"; } if (wkt.contains(StaticData.POLYGON) && !wkt.contains(StaticData.MULTIPOLYGON)) { wkt = wkt.replace("POLYGON (", "MULTIPOLYGON ((") + ")"; } wkt = wkt.replace(" 0,", ",").replace(" 0)", ")"); geo = String.format("ST_GeomFromText('%s')", wkt); } gField.set(t, geo); } catch (Exception ex) { log.error(ex.getMessage(), ex); } } /** * 获取 Timestamp */ public 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); if (pnYear[0] > StaticData.I2050 || pnMonth[0] > StaticData.I12 || pnDay[0] > StaticData.I31 || pnHour[0] > StaticData.I24 || pnMinute[0] > StaticData.I60) { return null; } LocalDateTime localDateTime = LocalDateTime.of( LocalDate.of(pnYear[0], pnMonth[0], pnDay[0]), LocalTime.of(pnHour[0], pnMinute[0], s, ns) ); return Timestamp.valueOf(localDateTime); } /** * 获取 LocalDate */ public static LocalDate getLocalDate(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); if (pnYear[0] > StaticData.I2050 || pnMonth[0] > StaticData.I12 || pnDay[0] > StaticData.I31) { return null; } return LocalDate.of(pnYear[0], pnMonth[0], pnDay[0]); } /** * 创建GDB */ public static void createGdb(String filePath, Map> map) throws Exception { Driver driver = null; DataSource dataSource = null; try { driver = ogr.GetDriverByName("FileGDB"); if (null == driver) { log.error("GdbHelper.createGdb.driver(FileGDB) is null."); return; } dataSource = driver.CreateDataSource(filePath, null); if (null == dataSource) { log.error("GdbHelper.createGdb.dataSource is null. " + filePath); return; } for (String key : map.keySet()) { Layer layer = null; try { BasicMapper baseMapper = ClassHelper.getBasicMapper(key); if (null == baseMapper) { continue; } layer = createLayer(dataSource, baseMapper); if (null == layer) { continue; } String className = ClassHelper.getClassName(baseMapper); Class clazz = ClassHelper.getEntityClass(className); if (null == clazz) { continue; } List fields = new ArrayList<>(); getFields(clazz, fields, StaticData.GDB_EXCLUDE_FIELDS); addLayerField(layer, fields); setLayerData(layer, fields, map.get(key)); } finally { if (null != layer) { layer.delete(); } } } dataSource.SyncToDisk(); dataSource.FlushCache(); } catch (Exception ex) { log.error(ex.getMessage(), ex); throw ex; } finally { GdbHelper.delete(dataSource, driver); } } /** * 创建图层 */ private static Layer createLayer(DataSource dataSource, BasicMapper baseMapper ) { String tab = BaseQueryService.getTabName(baseMapper); if (StringHelper.isNull(tab)) { return null; } Integer srid = null; String geomType = null; if (baseMapper instanceof GeomBaseMapper) { GeomBaseMapper geomMapper = (GeomBaseMapper) baseMapper; geomType = geomMapper.selectGeometryType(tab); srid = geomMapper.selectSrid(tab); } SpatialReference sr = new SpatialReference(); sr.ImportFromEPSG(null == srid ? 4490 : srid); return dataSource.CreateLayer(tab.replace(".", "_"), sr, getGeomType(geomType), null); } /** * 获取Geom类别 */ private static Integer getGeomType(String geomType) { if (StringHelper.isEmpty(geomType)) { return ogr.wkbPoint; } switch (geomType) { case "ST_Point": return ogr.wkbPoint; case "ST_MultiPoint": return ogr.wkbMultiPoint; case "ST_LineString": return ogr.wkbLineString; case "ST_MultiLineString": return ogr.wkbMultiLineString; case "ST_Polygon": return ogr.wkbPolygon; case "ST_MultiPolygon": return ogr.wkbMultiPolygon; default: return ogr.wkbUnknown; } } /** * 获取字段 */ public static void getFields(Class clazz, List list, List excludeFields) { try { Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { if (excludeFields.contains(f.getName())) { continue; } f.setAccessible(true); list.add(f); } if (!StaticData.OBJECT.equals(clazz.getSuperclass().getName())) { getFields(clazz.getSuperclass(), list, excludeFields); } } catch (Exception ex) { // } } /** * 添加图层字段 */ public static void addLayerField(Layer layer, List list) { for (int i = 0, c = list.size(); i < c; i++) { Field f = list.get(i); int fieldType = getFieldType(f); FieldDefn fd = new FieldDefn(f.getName(), fieldType); layer.CreateField(fd, i + 1); } } /** * 获取字段类型 */ private static Integer getFieldType(Field f) { switch (f.getType().getName()) { case "java.math.BigDecimal": case "java.lang.Double": case "double": return ogr.OFTReal; case "java.lang.Long": case "long": return ogr.OFTInteger64; case "java.lang.Integer": case "int": return ogr.OFTInteger; case "java.sql.Timestamp": return ogr.OFTDateTime; case "java.time.LocalDate": return ogr.OFTDate; default: return ogr.OFTString; } } /** * 设置图层数据 */ private static void setLayerData(Layer layer, List fields, List list) throws Exception { for (T t : list) { Feature f = new Feature(layer.GetLayerDefn()); if (t instanceof BaseGeoEntity) { BaseGeoEntity geoEntity = (BaseGeoEntity) t; if (!StringHelper.isEmpty(geoEntity.getGeom())) { Geometry geom = Geometry.CreateFromWkt(geoEntity.getGeom()); f.SetGeometry(geom); } } setFeatureData(f, fields, t); layer.CreateFeature(f); } } /** * 设置要素的数据 */ public static void setFeatureData(Feature f, List fields, T t) throws Exception { for (int i = 0, c = fields.size(); i < c; i++) { Field field = fields.get(i); Object val = field.get(t); if (null == val) { continue; } switch (field.getType().getName()) { case "java.math.BigDecimal": BigDecimal big = (BigDecimal) val; f.SetField(i, big.doubleValue()); break; case "java.lang.Double": case "double": double d = (double) val; f.SetField(i, d); break; case "java.lang.Long": case "long": long l = (long) val; f.SetField(i, l); break; case "java.lang.Integer": case "int": int n = (int) val; f.SetField(i, n); break; case "java.sql.Timestamp": Timestamp timestamp = (Timestamp) field.get(t); setTimestamp(f, i, timestamp); break; case "java.time.LocalDate": LocalDate localDate = (LocalDate) field.get(t); setLocalDate(f, i, localDate); break; default: String str = (String) val; f.SetField(i, str); break; } } } /** * 设置Timestamp */ private static void setTimestamp(Feature f, int i, Timestamp time) { if (null == time) { return; } LocalDateTime local = time.toLocalDateTime(); f.SetField(i, local.getYear(), local.getMonthValue(), local.getDayOfMonth(), local.getHour(), local.getMinute(), local.getSecond(), 8); } /** * 设置LocalDate */ private static void setLocalDate(Feature f, int i, LocalDate local) { if (null == local) { return; } f.SetField(i, local.getYear(), local.getMonthValue(), local.getDayOfMonth(), 0, 0, 0, 8); } }