package com.moon.server.service.data; import com.moon.server.entity.all.StaticData; import com.moon.server.entity.data.MetaFileEntity; import com.moon.server.helper.GeoHelper; import com.moon.server.helper.StringHelper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.gdal.gdal.ColorTable; import org.gdal.gdal.Dataset; import org.gdal.gdal.gdal; import org.gdal.gdalconst.gdalconst; import org.gdal.ogr.Geometry; import org.gdal.ogr.ogr; import org.gdal.osr.SpatialReference; import org.springframework.stereotype.Service; import java.io.File; import java.util.ArrayList; import java.util.List; @Service @SuppressWarnings("ALL") public class ReadRasterService { private final static Log log = LogFactory.getLog(ReadRasterService.class); public void readRasterInfo(MetaFileEntity mf, String file) { Dataset ds = null; try { File f = new File(file); if (!f.exists() || f.isDirectory()) { return; } ds = gdal.Open(file, gdalconst.GA_ReadOnly); if (null == ds || ds.getRasterCount() == 0 || null == ds.GetSpatialRef()) { return; } SpatialReference sr = ds.GetSpatialRef(); mf.setCoorSys(sr.GetName()); if (StaticData.MOON200.equals(mf.getCoorSys())) { mf.setEpsg("ESRI:" + StaticData.I104903); } else { String code = sr.GetAuthorityCode(null); mf.setEpsg(StringHelper.isEmpty(code) ? null : "EPSG:" + code); } mf.setGridsize(String.format("%d,%d", ds.getRasterXSize(), ds.getRasterYSize())); mf.setBands(String.valueOf(ds.getRasterCount())); int dataType = ds.GetRasterBand(1).GetRasterDataType(); mf.setBandType(getDataType(dataType)); ColorTable colorTable = ds.GetRasterBand(1).GetRasterColorTable(); mf.setCt(null == colorTable ? null : colorTable.toString()); mf.sethDatum(null); setMinAndMax(ds, mf); double[] tr = new double[6]; ds.GetGeoTransform(tr); mf.setResolution(String.format("%f,%f", tr[1], Math.abs(tr[5]))); if (tr[StaticData.I0] == 0.0 && tr[StaticData.I1] == 1.0 && tr[StaticData.I2] == 0.0 && tr[StaticData.I3] == 0.0 && tr[StaticData.I4] == 0.0 && tr[StaticData.I5] == 1.0) { return; } Geometry minPoint = getMinPoint(ds); Geometry maxPoint = getMaxPoint(ds); double xmin = minPoint.GetX(0); double ymin = minPoint.GetY(0); double xmax = maxPoint.GetX(0); double ymax = maxPoint.GetY(0); String geom = String.format("ST_GeomFromText('POLYGON ((%f %f,%f %f,%f %f,%f %f,%f %f))')", xmin, ymax, xmax, ymax, xmax, ymin, xmin, ymin, xmin, ymax); mf.setGeom(geom); } catch (Exception ex) { log.error(ex.getMessage(), ex); } finally { if (null != ds) { ds.delete(); } } } private String getDataType(int dataType) { if (dataType == gdalconst.GDT_Byte) { return "GDT_Byte"; } if (dataType == gdalconst.GDT_UInt16) { return "GDT_UInt16"; } if (dataType == gdalconst.GDT_Int16) { return "GDT_Int16"; } if (dataType == gdalconst.GDT_UInt32) { return "GDT_UInt32"; } if (dataType == gdalconst.GDT_Int32) { return "GDT_Int32"; } if (dataType == gdalconst.GDT_Float32) { return "GDT_Float32"; } if (dataType == gdalconst.GDT_Float64) { return "GDT_Float64"; } if (dataType == gdalconst.GDT_CInt16) { return "GDT_CInt16"; } if (dataType == gdalconst.GDT_CInt32) { return "GDT_CInt32"; } if (dataType == gdalconst.GDT_CFloat32) { return "GDT_CFloat32"; } if (dataType == gdalconst.GDT_CFloat64) { return "GDT_CFloat64"; } return null; } private Geometry getMinPoint(Dataset ds) { double[] transform = new double[6]; ds.GetGeoTransform(transform); double xMin = transform[0]; double yMin = transform[3] - ds.getRasterYSize() * transform[1]; Geometry point = new Geometry(ogr.wkbPoint); point.AddPoint(xMin, yMin, 0); return transform(ds, point); } private Geometry getMaxPoint(Dataset ds) { double[] transform = new double[6]; ds.GetGeoTransform(transform); double xMax = transform[0] + (ds.getRasterXSize() * transform[1]); double yMax = transform[3]; Geometry point = new Geometry(ogr.wkbPoint); point.AddPoint(xMax, yMax, 0); return transform(ds, point); } private Geometry transform(Dataset ds, Geometry point) { point.AssignSpatialReference(ds.GetSpatialRef()); if (ds.GetSpatialRef().IsGeographic() > 0) { return point; } String srsName = ds.GetSpatialRef().GetName(); if (srsName.contains(StaticData.CGCS2000)) { point.TransformTo(GeoHelper.sr4490); } else { point.TransformTo(GeoHelper.sr4326); } point.SwapXY(); return point; } private void setMinAndMax(Dataset ds, MetaFileEntity mf) { List minList = new ArrayList<>(); List maxList = new ArrayList<>(); for (int i = 1; i <= ds.getRasterCount(); i++) { Double[] min = new Double[1]; Double[] max = new Double[1]; ds.GetRasterBand(i).GetMinimum(min); ds.GetRasterBand(i).GetMaximum(max); minList.add(min[0]); maxList.add(max[0]); } mf.setMin(StringHelper.join(minList, ",")); mf.setMax(StringHelper.join(maxList, ",")); } }