using OSGeo.GDAL;
using OSGeo.OGR;
using OSGeo.OSR;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SimuTools.Tools
{
public class GdalHelper
{
private static bool isInited;
private static GdalHelper instance;
private static readonly object obj = new object();
public static SpatialReference sr4326 { set; get; }
public static SpatialReference sr4490 { set; get; }
public static readonly String CGCS2000 = "CGCS2000";
///
/// 构造函数
///
private GdalHelper()
{
lock (obj)
{
if (!isInited)
{
RegisterGDal();
sr4326 = new SpatialReference(null);
sr4326.ImportFromEPSG(4326);
sr4490 = new SpatialReference(null);
sr4490.ImportFromEPSG(4490);
isInited = true;
}
}
}
///
/// 实例
///
public static GdalHelper Instance
{
get
{
lock (obj)
{
if (null == instance)
{
instance = new GdalHelper();
}
return instance;
}
}
}
///
/// 注册GDAL
///
public void RegisterGDal()
{
string gdalData = Path.Combine(Handle.BaseDir, "gdal-data");
Environment.SetEnvironmentVariable("GDAL_DATA", gdalData);
string proj7 = Path.Combine(Handle.BaseDir, "proj7\\share");
Environment.SetEnvironmentVariable("PROJ_LIB", proj7);
Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // NO,YES
Gdal.SetConfigOption("SHAPE_ENCODING", ""); // 空,gb2312,CP936
Ogr.RegisterAll();
Gdal.AllRegister();
}
/**
* 获取Dataset的最小点
*/
private static Geometry GetMinPoint(Dataset ds)
{
double[] transform = new double[6];
ds.GetGeoTransform(transform);
double xMin = transform[0];
double yMin = transform[3] - ds.RasterYSize * transform[1];
Geometry point = new Geometry(wkbGeometryType.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.RasterYSize * transform[1]);
double yMax = transform[3];
Geometry point = new Geometry(wkbGeometryType.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 void CreatePyramid(String file)
{
Dataset ds = null;
try
{
if (!File.Exists(file)) return;
ds = Gdal.Open(file, Access.GA_ReadOnly);
if (null == ds) return;
Band band = ds.GetRasterBand(1);
if (0 == band.GetOverviewCount())
{
ds.BuildOverviews("nearest", new int[] { 2, 4, 6, 8, 16 });
}
}
catch (Exception ex)
{
LogOut.Error(ex.Message);
}
finally
{
if (null != ds) ds.Dispose();
}
}
}
}