张洋洋
2025-02-24 9804628abf554c3658345fc8fc9472cfb179fd5f
src/main/java/com/se/simu/helper/GdalHelper.java
@@ -1,23 +1,17 @@
package com.se.simu.helper;
import com.se.simu.domain.LayerVo;
import lombok.extern.slf4j.Slf4j;
import org.gdal.gdal.Band;
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.ogr.*;
import org.gdal.osr.CoordinateTransformation;
import org.gdal.osr.SpatialReference;
import org.gdal.osr.osr;
import java.io.File;
/**
 * GDAL帮助类
 *
 * @author WWW
 * @date 2024-07-16
 */
@Slf4j
@SuppressWarnings("ALL")
public class GdalHelper {
@@ -35,150 +29,55 @@
     * 初始化
     */
    public static void init(String gdalPath) {
        // 支持中文路径
        // 配置环境变量
        if (!StringHelper.isEmpty(gdalPath)) {
            if (WebHelper.isWin()) {
                gdal.SetConfigOption("GDAL_DATA", gdalPath + "/gdal-data");
                gdal.SetConfigOption("PROJ_LIB", gdalPath + "/proj7/share");
                //System.setProperty("PROJ_LIB", gdalPath + "/proj7/share")
                gdal.SetConfigOption("GDAL_DRIVER_PATH", gdalPath + "/gdalplugins");
                String path = System.getenv("PATH");
                if (!path.contains(gdalPath)) {
                    System.setProperty("PATH", path + ";" + gdalPath);
                }
            } else {
                //System.setProperty("java.library.path", 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 + "/gdal-data");
            gdal.SetConfigOption("PROJ_LIB", gdalPath + "/proj7/share");
            //System.setProperty("PROJ_LIB", gdalPath + "/proj7/share")
            gdal.SetConfigOption("GDAL_DRIVER_PATH", gdalPath + "/gdalplugins");
            String path = System.getenv("PATH");
            if (!path.contains(gdalPath)) {
                System.setProperty("PATH", path + ";" + gdalPath);
            }
        }
        // 注册所有的驱动
        gdal.AllRegister();
        ogr.RegisterAll();
        initSr();
    }
    /**
     * 初始化坐标系
     */
    public static void initSr() {
        try {
            SR4326 = new SpatialReference();
            SR4326.ImportFromEPSG(I4326);
            SR4326.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
            SR4490 = new SpatialReference();
            SR4490.ImportFromEPSG(I4490);
            SR4490.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
    }
    /**
     * 读取DEM边界
     */
    public static LayerVo readDemExtent(String file) {
        LayerVo layer = new LayerVo();
        Dataset ds = null;
    public static SpatialReference createSpatialReference(int epsg) {
        SpatialReference sr = new SpatialReference();
        sr.ImportFromEPSG(epsg);
        sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
        try {
            File f = new File(file);
            if (!f.exists() || f.isDirectory()) {
                return null;
            }
            ds = gdal.Open(file, gdalconst.GA_ReadOnly);
            if (null == ds) {
                return null;
            }
            Band band = ds.GetRasterBand(1);
            double[] mm = new double[2];
            band.ComputeRasterMinMax(mm);
            Geometry minPoint = getMinPoint(ds);
            Geometry maxPoint = getMaxPoint(ds);
            layer.setExtension(new LayerVo.Extension(minPoint.GetX(), minPoint.GetY(), maxPoint.GetX(), maxPoint.GetY(), mm[0], mm[1]));
            layer.setTerrain(new LayerVo.Terrain(band.getXSize(), band.getYSize()));
            layer.setWater(new LayerVo.Water(band.getXSize(), band.getYSize(), null));
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        } finally {
            if (null != ds) {
                ds.delete();
            }
        }
        return layer;
        return sr;
    }
    /**
     * 获取Dataset的最小点
     */
    private static 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);
    }
    /**
     * 获取Dataset的最大点
     */
    private static Geometry getMaxPoint(Dataset ds) {
        /*
         * transform[0] 左上角x坐标
         * transform[1] 东西方向分辨率
         * transform[2] 旋转角度, 0表示图像 "北方朝上"
         *
         * transform[3] 左上角y坐标
         * transform[4] 旋转角度, 0表示图像 "北方朝上"
         * transform[5] 南北方向分辨率
         */
        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 static 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(CGCS2000)) {
            point.TransformTo(SR4490);
        } else {
            point.TransformTo(SR4326);
        }
        point.SwapXY();
        return point;
    }
    /**
     * 创建金字塔
     */
    public static void createPyramid(String file) {
        Dataset ds = null;
        try {
@@ -188,11 +87,10 @@
            }
            ds = gdal.Open(file, gdalconst.GA_ReadOnly);
            if (null == ds) {
            if (null == ds || ds.getRasterCount() < 1 || null == ds.GetSpatialRef()) {
                return;
            }
            // 创建金字塔
            Band band = ds.GetRasterBand(1);
            if (0 == band.GetOverviewCount()) {
                ds.BuildOverviews("nearest", new int[]{2, 4, 6, 8, 16}, null);
@@ -205,4 +103,129 @@
            }
        }
    }
    public static void delete(Layer layer, DataSource dataSource, Driver driver) {
        try {
            if (null != layer) {
                layer.delete();
            }
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        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 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);
    }
    public static Geometry getMaxPoint(Dataset ds) {
        double[] transform = new double[6];
        ds.GetGeoTransform(transform);
        double xMax = transform[0] + (ds.getRasterYSize() * transform[1]);
        double yMax = transform[3];
        Geometry point = new Geometry(ogr.wkbPoint);
        point.AddPoint(xMax, yMax, 0);
        return Transform(ds, point);
    }
    public static 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(CGCS2000))
        //{
        //    point.TransformTo(sr4490);
        //}
        //else
        //{
        point.TransformTo(SR4326);
        //}
        //point.SwapXY();
        return point;
    }
    public static Geometry toWgs84(SpatialReference sr, double x, double y) {
        Geometry point = new Geometry(ogr.wkbPoint);
        point.AssignSpatialReference(sr);
        point.AddPoint(x, y);
        point.TransformTo(GdalHelper.SR4326);
        //point.SwapXY();
        return point;
    }
    public static int toWgs84(SpatialReference sr, Geometry g) {
        CoordinateTransformation ct = new CoordinateTransformation(sr, GdalHelper.SR4326);
        if (sr.IsProjected() != 1) {
            sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
        }
        return g.TransformTo(GdalHelper.SR4326);
    }
    public static double[] fromWgs84(SpatialReference sr, double x, double y) {
        CoordinateTransformation ct = new CoordinateTransformation(GdalHelper.SR4326, sr);
        if (sr.IsProjected() != 1) {
            sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
        }
        return ct.TransformPoint(x, y);
    }
    public static int fromWgs84(SpatialReference sr, Geometry g) {
        CoordinateTransformation ct = new CoordinateTransformation(GdalHelper.SR4326, sr);
        if (sr.IsProjected() != 1) {
            sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
        }
        return g.TransformTo(sr);
    }
    public static Geometry createPolygon(SpatialReference sr, Double minx, Double miny, Double maxx, Double maxy) {
        Geometry ring = new Geometry(ogr.wkbLinearRing);
        ring.AddPoint_2D(minx, maxy);
        ring.AddPoint_2D(maxx, maxy);
        ring.AddPoint_2D(maxx, miny);
        ring.AddPoint_2D(minx, miny);
        ring.AddPoint_2D(minx, maxy);
        Geometry poly = new Geometry(ogr.wkbPolygon);
        poly.AddGeometry(ring);
        if (null != sr) {
            poly.AssignSpatialReference(sr);
        }
        return poly;
    }
}