管道基础大数据平台系统开发-【CS】-ExportMap
1
13693261870
2024-09-03 a9b99add3e1baa7fc49049247b8bf071e70a6005
DataLoader/CS/GdalHelper.cs
@@ -1,17 +1,17 @@
using OSGeo.GDAL;
using DataLoader.Model;
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 DataLoader.CS
{
    public class GdalHelper
    {
        #region 成员变量+构造函数+初始化
        private static bool isInited = false;
        private static GdalHelper instance = null;
@@ -20,10 +20,17 @@
        public static SpatialReference sr4326 = null;
        public static SpatialReference sr4490 = null;
        public static SpatialReference sr104903 = null;
        public static string MOON200 = "GCS_Moon_2000";
        public static List<string> EPSGS = new List<string>() { "EPSG:4326", "EPSG:4490", "ESRI:104903" };
        /// <summary>
        /// 构造函数
        /// </summary>
        private GdalHelper()
        {
            lock (obj)
@@ -34,6 +41,9 @@
                    sr4326 = new SpatialReference(null);
                    sr4326.ImportFromEPSG(4326);
                    sr4490 = new SpatialReference(null);
                    sr4490.ImportFromEPSG(4490);
                    string wkt = "GEOGCS[\"GCS_Moon_2000\",\r\n" +
                        "    DATUM[\"D_Moon_2000\",\r\n" +
@@ -53,6 +63,9 @@
            }
        }
        /// <summary>
        /// 实例
        /// </summary>
        public static GdalHelper Instance
        {
            get
@@ -66,12 +79,15 @@
            }
        }
        /// <summary>
        /// 注册GDAL
        /// </summary>
        public void RegisterGDal()
        {
            string gdalData = Path.Combine(StaticData.BasePath, "gdal-data");
            string gdalData = Path.Combine(Tools.BaseDir, "gdal-data");
            Environment.SetEnvironmentVariable("GDAL_DATA", gdalData);
            string proj7 = Path.Combine(StaticData.BasePath, "proj7\\share");
            string proj7 = Path.Combine(Tools.BaseDir, "proj7\\share");
            Environment.SetEnvironmentVariable("PROJ_LIB", proj7);
            Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // NO,YES
@@ -80,57 +96,192 @@
            Ogr.RegisterAll();
            Gdal.AllRegister();
        }
        #endregion
        public void ReadTiff()
        #region 读取栅格信息
        /// <summary>
        /// 读取栅格信息
        /// </summary>
        public void ReadRasterInfo(ViewData vd)
        {
            string tif = "D:\\Moon\\data\\dom_tif\\moon.tif";
            Dataset ds = null;
            try
            {
                ds = Gdal.Open(vd.FilePath, Access.GA_ReadOnly);
                if (null == ds || ds.RasterCount == 0 || null == ds.GetSpatialRef()) return;
            Dataset ds = Gdal.Open(tif, Access.GA_ReadOnly);
            int x = ds.RasterXSize;
            int y = ds.RasterYSize;
                vd.Meta.gridsize = string.Format("{0},{1}", ds.RasterXSize, ds.RasterYSize); // 行列数
            SpatialReference sr = ds.GetSpatialRef();
            string srName = sr.GetName(); // GCS_Moon_2000
            // string code = sr4326.GetAuthorityCode(null); // 4326
            if (MOON200 != srName) return;
                SpatialReference sr = ds.GetSpatialRef();
                vd.Meta.coor_sys = sr.GetName(); // 坐标系统
                if (MOON200 == vd.Meta.coor_sys)
                {
                    vd.Meta.epsg = "ESRI:104903"; // EPSG编码
                }
                else
                {
                    string code = sr.GetAuthorityCode(null); // PROJCS、GEOGCS、GEOGCS|UNIT 或 NULL
                    vd.Meta.epsg = string.IsNullOrEmpty(code) ? null : "EPSG:" + code; // EPSG编码
                }
            double[] lt = ImageToGeoSpace(ds, 0, 0); // -179.99998351102391, 89.999983511056882
            double[] rb = ImageToGeoSpace(ds, x, y); // 179.999788852709, -89.9999026708093
                vd.Meta.bands = ds.RasterCount.ToString(); // 波段数
                vd.Meta.band_type = Enum.GetName(typeof(DataType), ds.GetRasterBand(1).DataType); // 数据类型
                ColorTable ct = ds.GetRasterBand(1).GetRasterColorTable();
                vd.Meta.ct = null == ct ? null : ct.ToString(); // 数据颜色表
                vd.Meta.h_datum = null; // 高程基准
                setMinAndMax(ds, vd.Meta); // 设置最值
            string polygon = string.Format("", "");
                double[] tr = new double[6];
                ds.GetGeoTransform(tr);
                vd.Meta.resolution = string.Format("{0},{1}", tr[1], Math.Abs(tr[5])); // 分辨率
                if (tr[0] == 0.0 && tr[1] == 1.0 && tr[2] == 0.0 && tr[3] == 0.0 && tr[4] == 0.0 && tr[5] == 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 (({0} {1},{2} {3},{4} {5},{6} {7},{0} {1}))')", xmin, ymax, xmax, ymax, xmax, ymin, xmin, ymin);
                vd.Meta.geom = geom; // 四至范围
            }
            catch (Exception ex)
            {
                LogOut.Error(ex.StackTrace);
            }
            finally
            {
                if (ds != null) ds.Dispose();
            }
        }
        // 从地理空间转换到像素空间
        private int[] Geo2ImageSpace(Dataset ds, double x, double y)
        {
            double[] transform = new double[6];
            ds.GetGeoTransform(transform); // 影像坐标变换参数
            int col = (int)((y * transform[1] - x * transform[4] + transform[0] * transform[4] - transform[3] * transform[1]) / (transform[5] * transform[1] - transform[2] * transform[4])); // 像素所在列
            int row = (int)((x - transform[0] - col * transform[2]) / transform[1]); // 像素所在行
            return new int[] { row, col };
        }
        // 从地理空间转换到像素空间
        private int[] Geo2ImageSpace(double[] transform, double x, double y)
        {
            int col = (int)((y * transform[1] - x * transform[4] + transform[0] * transform[4] - transform[3] * transform[1]) / (transform[5] * transform[1] - transform[2] * transform[4])); // 像素所在列
            int row = (int)((x - transform[0] - col * transform[2]) / transform[1]); // 像素所在行
            return new int[] { row, col };
        }
        // 从像素空间转换到地理空间
        private double[] ImageToGeoSpace(Dataset ds, int row, int col)
        /// <summary>
        /// 获取Dataset的最小点
        /// </summary>
        private Geometry GetMinPoint(Dataset ds)
        {
            double[] transform = new double[6];
            ds.GetGeoTransform(transform);
            double x = transform[0] + row * transform[1] + col * transform[2];
            double y = transform[3] + row * transform[4] + col * transform[5];
            double xMin = transform[0];
            double yMin = transform[3] - ds.RasterYSize * transform[1];
            return new double[] { x, y };
            Geometry point = new Geometry(wkbGeometryType.wkbPoint);
            point.AddPoint(xMin, yMin, 0);
            return Transform(ds, point);
        }
        /// <summary>
        /// 获取Dataset的最大点
        /// </summary>
        private 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.RasterXSize * transform[1]);
            double yMax = transform[3];
            Geometry point = new Geometry(wkbGeometryType.wkbPoint);
            point.AddPoint(xMax, yMax, 0);
            return Transform(ds, point);
        }
        /// <summary>
        /// 坐标转换
        /// </summary>
        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("CGCS2000"))
            {
                point.TransformTo(sr4490);
            }
            else
            {
                point.TransformTo(sr4326);
            }
            point.SwapXY();
            return point;
        }
        /// <summary>
        /// 创建多边形
        /// </summary>
        public Geometry CreatePolygon(double xmin, double xmax, double ymin, double ymax, SpatialReference sr)
        {
            string kwt = string.Format("POLYGON (({0} {1},{2} {3},{4} {5},{6} {7},{0} {1}))", xmin, ymax, xmax, ymax, xmax, ymin, xmin, ymin);
            Geometry geo = Geometry.CreateFromWkt(kwt);
            geo.AssignSpatialReference(sr);
            return geo;
        }
        /// <summary>
        /// 设置最值
        /// GDALRasterBand::GetHistogram ​​统计直方图
        /// </summary>
        private void setMinAndMax(Dataset ds, SysMeta meta)
        {
            List<double> minList = new List<double>();
            List<double> maxList = new List<double>();
            for (int i = 1; i <= ds.RasterCount; i++)
            {
                int hasval;
                double min, max;
                ds.GetRasterBand(i).GetMinimum(out min, out hasval);
                ds.GetRasterBand(i).GetMaximum(out max, out hasval);
                minList.Add(min);
                maxList.Add(max);
            }
            meta.min = string.Join(",", minList.ToArray());
            meta.max = string.Join(",", maxList.ToArray());
        }
        #endregion
        public void CsTransform(double x, double y, int epsg)
        {
            SpatialReference srs = new SpatialReference(null);
            srs.ImportFromEPSG(epsg);
            Geometry point = new Geometry(wkbGeometryType.wkbPoint);
            point.AddPoint(x, y, 0);
            point.AssignSpatialReference(srs);
            if (srs.GetName().Contains("CGCS2000"))
            {
                point.TransformTo(sr4490);
            }
            else
            {
                point.TransformTo(sr4326);
            }
            point.SwapXY();
            double[] xy = new double[] { point.GetX(0), point.GetY(0) };
        }
    }
}