| | |
| | | package com.lf.server.helper; |
| | | |
| | | import com.lf.server.entity.all.BaseGeoEntity; |
| | | import com.lf.server.entity.all.StaticData; |
| | | import com.lf.server.mapper.all.GeomBaseMapper; |
| | | import com.lf.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.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; |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * GDB帮助类 |
| | |
| | | public class GdbHelper { |
| | | private final static Log log = LogFactory.getLog(GdbHelper.class); |
| | | |
| | | private final static String OBJECT ="java.lang.Object"; |
| | | |
| | | /** |
| | | * 销毁资源 |
| | | */ |
| | | 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<String> getTabNames(String filePath) { |
| | | List<String> list = new ArrayList<>(); |
| | | |
| | | Driver driver = null; |
| | | DataSource dataSource = null; |
| | | try { |
| | | org.gdal.ogr.Driver driver = ogr.GetDriverByName("OpenFileGDB"); |
| | | if (driver == null) { |
| | | driver = ogr.GetDriverByName("OpenFileGDB"); |
| | | if (null == driver) { |
| | | log.error("GdbHelper.getTabNames: OpenFileGDB is null"); |
| | | return list; |
| | | } |
| | | |
| | | DataSource dataSource = driver.Open(filePath, 0); |
| | | 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(); |
| | | } |
| | | |
| | | driver.delete(); |
| | | } catch (Exception ex) { |
| | | log.error(ex.getMessage(), ex); |
| | | } finally { |
| | | GdbHelper.delete(dataSource, driver); |
| | | } |
| | | |
| | | return list; |
| | |
| | | */ |
| | | public static <T> List<T> readData(Class clazz, String filePath, String layerName) { |
| | | List<T> list = new ArrayList<>(); |
| | | |
| | | Driver driver = null; |
| | | DataSource dataSource = null; |
| | | try { |
| | | org.gdal.ogr.Driver driver = ogr.GetDriverByName("OpenFileGDB"); |
| | | if (driver == null) { |
| | | driver = ogr.GetDriverByName("OpenFileGDB"); |
| | | if (null == driver) { |
| | | return list; |
| | | } |
| | | |
| | | DataSource dataSource = driver.Open(filePath, 0); |
| | | 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(); |
| | | } |
| | | |
| | | driver.delete(); |
| | | } catch (Exception ex) { |
| | | log.error(ex.getMessage(), ex); |
| | | } finally { |
| | | GdbHelper.delete(dataSource, driver); |
| | | } |
| | | |
| | | return list; |
| | |
| | | public static <T> void readLayer(Class clazz, Layer layer, List<T> list) { |
| | | try { |
| | | Field gField = getGeomField(clazz); |
| | | Map<Integer, Field> map = getFieldMapper(clazz, layer); |
| | | if (map.size() == 0) { |
| | | |
| | | Map<Integer, Field> map = new HashMap<>(3); |
| | | getFieldMapper(clazz, layer, map); |
| | | if (map.isEmpty() || 0 == layer.GetFeatureCount()) { |
| | | return; |
| | | } |
| | | |
| | |
| | | } catch (Exception ex) { |
| | | log.error(ex.getMessage(), ex); |
| | | } finally { |
| | | if (null != layer) { |
| | | layer.delete(); |
| | | } |
| | | GdbHelper.delete(layer); |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | private static Field getGeomField(Class clazz) { |
| | | try { |
| | | Field gField = clazz.getDeclaredField("geom"); |
| | | Field gField = clazz.getSuperclass().getDeclaredField("geom"); |
| | | gField.setAccessible(true); |
| | | |
| | | return gField; |
| | |
| | | /** |
| | | * 获取字段映射 |
| | | */ |
| | | private static <T> Map<Integer, Field> getFieldMapper(Class clazz, Layer layer) { |
| | | Map<Integer, Field> map = new HashMap<>(3); |
| | | |
| | | private static void getFieldMapper(Class clazz, Layer layer, Map<Integer, Field> 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 ("gid".equals(name)) { |
| | | if (StaticData.READ_EXCLUDE_FIELDS.contains(name)) { |
| | | continue; |
| | | } |
| | | |
| | |
| | | // |
| | | } |
| | | } |
| | | |
| | | if (!OBJECT.equals(clazz.getSuperclass().getName())) { |
| | | getFieldMapper(clazz.getSuperclass(), layer, map); |
| | | } |
| | | } catch (Exception ex) { |
| | | // |
| | | } |
| | | |
| | | return map; |
| | | } |
| | | |
| | | /** |
| | |
| | | * 设置值 |
| | | */ |
| | | private static <T> 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": |
| | | switch (field.getType().getName()) { |
| | | case "java.math.BigDecimal": |
| | | case "java.lang.Double": |
| | | case "double": |
| | | field.set(t, f.GetFieldAsDouble(i)); |
| | | break; |
| | | case "class java.lang.Long": |
| | | case "java.lang.Long": |
| | | case "long": |
| | | field.set(t, f.GetFieldAsInteger64(i)); |
| | | break; |
| | | case "class java.lang.Integer": |
| | | case "java.lang.Integer": |
| | | case "int": |
| | | field.set(t, f.GetFieldAsInteger(i)); |
| | | break; |
| | | case "class java.sql.Timestamp": |
| | | case "java.sql.Timestamp": |
| | | field.set(t, getTimestamp(f, i)); |
| | | break; |
| | | default: |
| | |
| | | |
| | | /** |
| | | * 设置 geom 字段值 |
| | | * |
| | | * <p> |
| | | * wkbUnknown = 0, |
| | | * wkbPoint = 1, |
| | | * wkbLineString = 2, |
| | |
| | | * wkbLinearRing = 101 |
| | | */ |
| | | private static <T> void setGeom(T t, Feature f, Field gField) throws Exception { |
| | | Geometry geometry = f.GetGeometryRef(); |
| | | if (null != geometry) { |
| | | String wkt = geometry.ExportToWkt(); |
| | | switch (geometry.GetGeometryType()) { |
| | | String geo = "null"; |
| | | if (null != f.GetGeometryRef()) { |
| | | String wkt = f.GetGeometryRef().ExportToWkt(); |
| | | switch (f.GetGeometryRef().GetGeometryType()) { |
| | | case 2: |
| | | wkt = wkt.replace("LINESTRING (", "MultiLINESTRING ((") + ")"; |
| | | wkt = wkt.replace("LINESTRING (", "MULTILINESTRING ((") + ")"; |
| | | break; |
| | | case 3: |
| | | wkt = wkt.replace("POLYGON (", "LINESTRINGPOLYGON ((") + ")"; |
| | | wkt = wkt.replace("POLYGON (", "MULTIPOLYGON ((") + ")"; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | gField.set(t, String.format("ST_GeomFromText('%s')", wkt)); |
| | | geo = String.format("ST_GeomFromText('%s')", wkt); |
| | | } |
| | | |
| | | gField.set(t, geo); |
| | | } |
| | | |
| | | /** |
| | |
| | | LocalTime.of(pnHour[0], pnMinute[0], s, ns) |
| | | ); |
| | | |
| | | Timestamp timestamp = Timestamp.valueOf(localDateTime); |
| | | return Timestamp.valueOf(localDateTime); |
| | | } |
| | | |
| | | return timestamp; |
| | | /** |
| | | * 创建GDB |
| | | */ |
| | | public static void createGdb(String filePath, Map<String, List<?>> map) { |
| | | Driver driver = null; |
| | | DataSource dataSource = null; |
| | | try { |
| | | driver = ogr.GetDriverByName("FileGDB"); |
| | | if (null == driver) { |
| | | return; |
| | | } |
| | | dataSource = driver.CreateDataSource(filePath, null); |
| | | if (null == dataSource) { |
| | | return; |
| | | } |
| | | |
| | | for (String key : map.keySet()) { |
| | | Layer layer = null; |
| | | try { |
| | | GeomBaseMapper baseMapper = ClassHelper.getGeoBaseMapper(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<Field> fields = new ArrayList<>(); |
| | | fields.add(getGeomField(clazz)); |
| | | getFields(clazz, fields); |
| | | addLayerField(layer, fields); |
| | | |
| | | setLayerData(layer, fields, map.get(key)); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | } finally { |
| | | if (null != layer) { |
| | | layer.delete(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | dataSource.SyncToDisk(); |
| | | dataSource.FlushCache(); |
| | | } catch (Exception ex) { |
| | | log.error(ex.getMessage(), ex); |
| | | } finally { |
| | | GdbHelper.delete(dataSource, driver); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 创建图层 |
| | | */ |
| | | private static Layer createLayer(DataSource dataSource, GeomBaseMapper baseMapper ) { |
| | | String tab = BaseQueryService.getTabName(baseMapper); |
| | | if (StringHelper.isNull(tab)) { |
| | | return null; |
| | | } |
| | | |
| | | String geomType = baseMapper.selectGeometryType(tab); |
| | | if (StringHelper.isEmpty(geomType)) { |
| | | return null; |
| | | } |
| | | |
| | | Integer srid = baseMapper.selectSrid(tab); |
| | | SpatialReference sr = new SpatialReference(); |
| | | sr.ImportFromEPSG(null == srid ? 4326 : srid); |
| | | |
| | | return dataSource.CreateLayer(tab, sr, getGeomType(geomType), null); |
| | | } |
| | | |
| | | /** |
| | | * 获取Geom类别 |
| | | */ |
| | | private static Integer getGeomType(String geomType) { |
| | | if (StringHelper.isEmpty(geomType)) { |
| | | return ogr.wkbUnknown; |
| | | } |
| | | |
| | | switch (geomType) { |
| | | case "ST_Point": |
| | | return ogr.wkbPoint; |
| | | 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; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取字段 |
| | | */ |
| | | private static void getFields(Class clazz, List<Field> list) { |
| | | try { |
| | | Field[] fields = clazz.getDeclaredFields(); |
| | | for (Field f : fields) { |
| | | if (StaticData.GDB_EXCLUDE_FIELDS.contains(f.getName())) { |
| | | continue; |
| | | } |
| | | |
| | | f.setAccessible(true); |
| | | list.add(f); |
| | | } |
| | | |
| | | if (!OBJECT.equals(clazz.getSuperclass().getName())) { |
| | | getFields(clazz.getSuperclass(), list); |
| | | } |
| | | } catch (Exception ex) { |
| | | // |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 添加图层字段 |
| | | */ |
| | | private static void addLayerField(Layer layer, List<Field> list) { |
| | | for (int i = 1, 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); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取字段类型 |
| | | */ |
| | | 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; |
| | | default: |
| | | return ogr.OFTString; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 设置图层数据 |
| | | */ |
| | | private static <T> void setLayerData(Layer layer, List<Field> fields, List<T> list) throws Exception { |
| | | for (T t : list) { |
| | | Feature f = new Feature(layer.GetLayerDefn()); |
| | | |
| | | BaseGeoEntity geoEntity = (BaseGeoEntity) t; |
| | | Geometry geom = Geometry.CreateFromWkt(geoEntity.getGeom()); |
| | | f.SetGeometry(geom); |
| | | |
| | | for (int i = 1, 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": |
| | | 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 time = (Timestamp) field.get(t); |
| | | setTimestamp(f, i, time); |
| | | break; |
| | | default: |
| | | String str = (String) val; |
| | | f.SetField(i, str); |
| | | break; |
| | | } |
| | | } |
| | | layer.CreateFeature(f); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 设置Timestamp |
| | | */ |
| | | @SuppressWarnings("AlibabaRemoveCommentedCode") |
| | | private static void setTimestamp(Feature f, int i, Timestamp time) { |
| | | if (null == time) { |
| | | return; |
| | | } |
| | | |
| | | //Calendar now = Calendar.getInstance(); |
| | | //now.setTimeInMillis(time.getTime()); |
| | | // f.SetField(i, now.get(Calendar.YEAR), now.get(Calendar.MONTH) + 1, now.get(Calendar.DATE), now.get(Calendar.HOUR), now.get(Calendar.MINUTE), now.get(Calendar.SECOND), 8); |
| | | |
| | | LocalDateTime local = time.toLocalDateTime(); |
| | | f.SetField(i, local.getYear(), local.getMonthValue(), local.getDayOfMonth(), local.getHour(), local.getMinute(), local.getSecond(), 8); |
| | | } |
| | | } |