package com.lf.server.helper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.gdal.gdal.Band; import org.gdal.gdal.Driver; import org.gdal.gdal.gdal; import org.gdal.gdal.Dataset; import org.gdal.gdalconst.gdalconstConstants; import org.gdal.ogr.*; import org.gdal.osr.SpatialReference; import java.io.File; import java.sql.Time; 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; /** * GDAL帮助类 * @author WWW */ @SuppressWarnings("ALL") public class GdalHelper { private final static Log log = LogFactory.getLog(GdalHelper.class); public static void init(String gdalPath) { // 支持中文路径 gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // 属性表支持中文:CP936 gdal.SetConfigOption("SHAPE_ENCODING", ""); gdal.SetConfigOption("PGEO_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s"); gdal.SetConfigOption("MDB_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb, *.accdb);DBQ=%s"); // 配置环境变量 if (!StringHelper.isEmpty(gdalPath)) { gdal.SetConfigOption("GDAL_DATA", gdalPath + File.separator + "gdal-data"); gdal.SetConfigOption("PROJ_LIB", gdalPath + File.separator + "proj7" + File.separator + "share"); //System.setProperty("PROJ_LIB", gdalPath + File.separator + "proj7" + File.separator + "share") gdal.SetConfigOption("GDAL_DRIVER_PATH", gdalPath + File.separator + "gdalplugins"); String path = System.getenv("PATH"); if (!path.contains(gdalPath)) { System.setProperty("PATH", path + ";" + gdalPath); } } // 注册所有的驱动 gdal.AllRegister(); ogr.RegisterAll(); } /** * 读取tif文件 * * @param fileName */ public static void readTif(String fileName) { // 读取影像数据 Dataset dataset = gdal.Open(fileName, gdalconstConstants.GA_ReadOnly); if (dataset == null) { System.out.println("read fail!"); return; } // providing various methods for a format specific driver. Driver driver = dataset.GetDriver(); System.out.println("driver name: " + driver.getLongName()); // 读取影像信息 int xSize = dataset.getRasterXSize(); int ySzie = dataset.getRasterYSize(); int rasterCount = dataset.getRasterCount(); System.out.println("dataset xSize: " + xSize + ", ySzie = " + ySzie + ", rasterCount = " + rasterCount); Band band = dataset.GetRasterBand(1); // the data type of the band. int type = band.GetRasterDataType(); System.out.println("data type = " + type + ", " + (type == gdalconstConstants.GDT_Byte)); // Frees the native resource associated to a Dataset object and close the file. dataset.delete(); gdal.GDALDestroyDriverManager(); } /** * 读取shp文件 * * @param filePath */ public static void readShp(String filePath) { try { org.gdal.ogr.Driver driver = ogr.GetDriverByName("ESRI shapefile"); if (driver == null) { System.out.println(" ESRI shapefile驱动不可用!\n"); System.out.println("fail"); } DataSource dataSource = driver.Open(filePath); Layer layer = dataSource.GetLayer(0); String layerName = layer.GetName(); System.out.println("图层名称:" + layerName); SpatialReference spatialReference = layer.GetSpatialRef(); // System.out.println(spatialReference) System.out.println("空间参考坐标系:" + spatialReference.GetAttrValue("AUTHORITY", 0) + spatialReference.GetAttrValue("AUTHORITY", 1)); double[] layerExtent = layer.GetExtent(); System.out.println("图层范围:minx:" + layerExtent[0] + ",maxx:" + layerExtent[1] + ",miny:" + layerExtent[2] + ",maxy:" + layerExtent[3]); FeatureDefn featureDefn = layer.GetLayerDefn(); Map fieldMap = new HashMap(5); for (int i = 0, count = featureDefn.GetFieldCount(); i < count; i++) { FieldDefn fieldDefn = featureDefn.GetFieldDefn(i); //得到属性字段类型 int fieldType = fieldDefn.GetFieldType(); String fieldTypeName = fieldDefn.GetFieldTypeName(fieldType); //得到属性字段名称 String fieldName = fieldDefn.GetName(); fieldMap.put(fieldTypeName, fieldName); } long featureCount = layer.GetFeatureCount(); System.out.println("图层要素个数:" + featureCount); for (int i = 0; i < featureCount; i++) { Feature feature = layer.GetFeature(i); Object[] arr = fieldMap.values().toArray(); for (int k = 0; k < arr.length; k++) { String value = feature.GetFieldAsString(arr[k].toString()); System.out.print(" 属性名称:" + arr[k].toString() + ",属性值:" + value); } System.out.println(); break; } } catch (Exception ex) { log.error(ex.getMessage(), ex); } } public static void getLayerDto(String filePath) { org.gdal.ogr.Driver driver = ogr.GetDriverByName("OpenFileGDB"); if (driver == null) { return; } List list = new ArrayList<>(); List> mapList = new ArrayList<>(); DataSource dataSource = null; try { dataSource = driver.Open(filePath, 0); int num = dataSource.GetLayerCount(); for (int i = 0; i < num; i++) { // 获取图层 Layer layer = dataSource.GetLayer(i); // 表名称 String strlayerName = layer.GetName(); // 获取图层要数个数 long count = layer.GetFeatureCount(); if (0 != count) { do { // 获取图层下的要素 Feature feature = layer.GetNextFeature(); if (null == feature) { break; } // 获取边界坐标 Geometry geometry = feature.GetGeometryRef(); if (geometry != null) { String geometryJson = geometry.ExportToJson(); String str = geometryJson.substring(geometryJson.lastIndexOf(":") + 1, geometryJson.length()); if (!" [ [ ] ] }".equals(str)) { String s1 = str.substring(7, str.length() - 8); String[] split = s1.replaceAll(" ", "").replaceAll("\\[", "").replaceAll("]", "").split(","); List xList = new ArrayList(); List yList = new ArrayList(); Map map1 = new HashMap(5); for (int j = 0; j < split.length; j++) { if (j != (split.length - 1) && j % 2 == 0) { map1.put(split[j], split[j + 1]); } } mapList.add(map1); } } Map map = new HashMap(5); //获取属性 for (int p = 0; p < feature.GetFieldCount(); p++) { map.put(feature.GetFieldDefnRef(p).GetName(), getProperty(feature, p)); } list.add(map); feature.delete(); } while (true); } //layerDto.setLayerName(strlayerName); //layerDto.setList(list); //layerDto.setCount(count); //layerDto.setMap(mapList); } } catch (Exception ex) { log.error(ex.getMessage(), ex); } finally { if (dataSource != null) { dataSource.delete(); } } } /** * 读取gdb文件 * * @param filePath */ public static void readGdb(String filePath) { try { org.gdal.ogr.Driver driver = ogr.GetDriverByName("OpenFileGDB"); if (driver == null) { return; } DataSource dataSource = driver.Open(filePath, 0); for (int i = 0, count = dataSource.GetLayerCount(); i < count; 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,也可以ExportToWkb() gml等等 System.out.println(feature.GetGeometryRef().ExportToWkt()); // 获取属性 System.out.println("----------------------------------"); for (int p = 0; p < feature.GetFieldCount(); p++) { System.out.println(feature.GetFieldDefnRef(p).GetName() + "\t" + getProperty(feature, p)); } System.out.println("----------------------------------"); break; } while (true); } } catch (Exception ex) { log.error(ex.getMessage(), ex); } } public static Object getProperty(Feature feature, int index) { int type = feature.GetFieldType(index); PropertyGetter propertyGetter; if (type < 0 || type >= PROPERTY_GETTERS.length) { propertyGetter = STRING_PROPERTY_GETTER; } else { propertyGetter = PROPERTY_GETTERS[type]; } try { return propertyGetter.get(feature, index); } catch (Exception ex) { // ex.printStackTrace() log.error(ex.getMessage(), ex); return null; } } /** * 属性获取器 */ @FunctionalInterface private interface PropertyGetter { /** * 获取属性 * * @param feature * @param index * @return */ Object get(Feature feature, int index); } private static final PropertyGetter STRING_PROPERTY_GETTER = (feature, index) -> feature.GetFieldAsString(index); /** * feature.GetFieldType(index)得到一个属性类型的int值,该值对应具体类型 */ private static final PropertyGetter[] PROPERTY_GETTERS = new PropertyGetter[]{ // 0-Integer (feature, index) -> feature.GetFieldAsInteger(index), // 1-IntegerList (feature, index) -> feature.GetFieldAsIntegerList(index), // 2-Real (feature, index) -> feature.GetFieldAsDouble(index), // 3-RealList (feature, index) -> feature.GetFieldAsDoubleList(index), // 4-String STRING_PROPERTY_GETTER, // 5-StringList (feature, index) -> feature.GetFieldAsStringList(index), // 6-unknown STRING_PROPERTY_GETTER, // 7-unknown STRING_PROPERTY_GETTER, // 8-Binary (feature, index) -> feature.GetFieldAsBinary(index), // 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); java.sql.Date date = java.sql.Date.valueOf(LocalDate.of(pnYear[0], pnMonth[0], pnDay[0])); return date; }, // 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); Time time = Time.valueOf(LocalTime.of(pnHour[0], pnMinute[0], s, ns)); return time; }, // 11-DateTime (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; }, // 12-Integer64 (feature, index) -> feature.GetFieldAsInteger64(index), // 13 Integer64List (feature, index) -> feature.GetFieldAsIntegerList(index) // >=14 (unknown) }; }