package com.se.simu.helper;
|
|
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.*;
|
import org.gdal.osr.CoordinateTransformation;
|
import org.gdal.osr.SpatialReference;
|
import org.gdal.osr.osr;
|
|
import java.io.File;
|
|
/**
|
* GDAL帮助类
|
*
|
* @author WWW
|
* @date 2024-09-12
|
*/
|
@Slf4j
|
@SuppressWarnings("ALL")
|
public class GdalHelper {
|
public final static int I4326 = 4326;
|
|
public final static int I4490 = 4490;
|
|
public static SpatialReference SR4326;
|
|
public static SpatialReference SR4490;
|
|
public final static String CGCS2000 = "CGCS2000";
|
|
/**
|
* 初始化
|
*/
|
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");
|
|
// 注册所有的驱动
|
gdal.AllRegister();
|
ogr.RegisterAll();
|
initSr();
|
}
|
|
/**
|
* 初始化坐标系
|
* <p>
|
* https://blog.csdn.net/CallmeAdo/article/details/127558139
|
*/
|
public static void initSr() {
|
try {
|
SR4326 = new SpatialReference();
|
SR4326.ImportFromEPSG(I4326);
|
// 对于lat/long顺序的地理CRS,数据仍然是long/lat顺序的
|
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);
|
}
|
}
|
|
public static SpatialReference createSpatialReference(int epsg) {
|
SpatialReference sr = new SpatialReference();
|
sr.ImportFromEPSG(epsg);
|
sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
|
|
return sr;
|
}
|
|
/**
|
* 创建金字塔
|
*/
|
public static void createPyramid(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() < 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);
|
}
|
} catch (Exception ex) {
|
log.error(ex.getMessage(), ex);
|
} finally {
|
if (null != ds) {
|
ds.delete();
|
}
|
}
|
}
|
|
/**
|
* 销毁资源
|
*/
|
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)
|
{
|
/*
|
* 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.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;
|
}
|
|
/**
|
* 转换为WGS84坐标
|
*/
|
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;
|
}
|
|
/**
|
* WGS84转换为目标坐标
|
*/
|
public static double[] fromWgs84(SpatialReference sr, double x, double y) {
|
// https://blog.csdn.net/weixin_34910922/article/details/129208661
|
CoordinateTransformation ct = new CoordinateTransformation(GdalHelper.SR4326, sr);
|
if (sr.IsProjected() != 1) {
|
sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
|
}
|
|
return ct.TransformPoint(x, y);
|
}
|
|
/**
|
* WGS84转换为目标坐标
|
*/
|
public static int fromWgs84(SpatialReference sr, Geometry point) {
|
// https://blog.csdn.net/weixin_34910922/article/details/129208661
|
CoordinateTransformation ct = new CoordinateTransformation(GdalHelper.SR4326, sr);
|
if (sr.IsProjected() != 1) {
|
sr.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER);
|
}
|
|
return point.TransformTo(sr);
|
}
|
}
|