c#gdal解析气象数据生成等值线openlayers展示

c#gdal解析气象数据生成等值线openlayers展示

当前场景:
1. 下载的全球气象数据存储在txt文件中
2. 解析数据生成等值线txt文件,存储在mongodb中
3. 加载数据传给前端,openlayers渲染等值线

技术探讨思路:
1. 根据世界坐标系生成世界坐标点180*361
2. c#读取txt文件气压值或者其他等值线权重值,与上面坐标一一对应,x,y,m格式输出存储到新的txt文件中,每行一条数据
3. 调用gdal加载2中文件,调用gdal方法,设置对应参数,生成等值线bln文件
4. 解析bln等值线数据,提取等值线,根据自己需要的格式存储到txt文件中
5. 前端加载文件,解析成geojson数据展示

  • 生成坐标系
    /// <summary>
    
        /// 返回网格坐标
    
        /// </summary>
    
        /// <returns></returns>
    
        public List<COORD> BuildCoord() {
    
            List<COORD> lst = new List<COORD>();
    
            for (int i = 90; i>=-90; i--) {
    
                for (int m = 0; m < 180; m++) {
    
                    COORD coord = new COORD();
    
                    coord.x = m;
    
                    coord.y = i;
    
                    lst.Add(coord);
    
                }
    
                for (int m = -180; m < 0; m++)
    
                {
    
                    COORD coord = new COORD();
    
                    coord.x = m;
    
                    coord.y = i;
    
                    lst.Add(coord);
    
                }
    
            }
    
            return lst;
    
        }
  • 读取解析气象数据生成x,y,m文件
    ` ////// 读取文件中地面压力数据
    ///

    ///public List fileToString(String filePath)
    {
    filePath = System.Web.HttpContext.Current.Server.MapPath("~") + filePath;
    string strData = "";
    List outData = new List();
    try
    {
    //获取坐标点
    List c =BuildCoord();
    string line;
    // 创建一个 StreamReader 的实例来读取文件 ,using 语句也能关闭 StreamReader
    using (StreamReader sr = new StreamReader(filePath))
    {
    string lineData = sr.ReadLine();
    int count = 1;
    // 从文件读取并显示行,直到文件的末尾
    while ((line = sr.ReadLine()) != null)
    {
    strData = line.Trim();
    if (count ==5) {
    string l = line;
    var data = line.Split(' ');
    for (int i = 0; i < data.Length; i++) {
    XYZ d = new XYZ();
    d.x = c[i].x;
    d.y = c[i].y;
    d.m = double.Parse(data[i]);
    outData.Add(d);
    if (i == c.Count-1)
    {
    line = null;
    break;
    }
    }
    }
    count++;
    }
                sr.Close();
                sr.Dispose();
            }
    
        }
        catch (Exception e)
        {
            // 向用户显示出错消息
            Console.WriteLine("The file could not be read:");
            Console.WriteLine(e.Message);
        }
        return outData;
    }`
    
  • 调用gdal生成等值线,以geojson格式存储等值线数据
    `// 传入的文件格式如下
    // X Y Z
    // 112.536542357878 21.4983645627334 299.1500
    // 112.536542357878 21.5067224997793 299.1500
    // 112.536542357878 21.5150799564311 299.1502
    // 112.536542357878 21.5234369325389 299.1498
    // 112.536542357878 21.5317934279523 299.1501
    // 112.536542357878 21.5401494425214 299.1502
    // 文件第一行无实际作用,其余为点数据,一个点占一行

    public  string Create(string path, int rowCnt, int colCnt, double[] array = null)
    {
        string filename = Path.GetFileNameWithoutExtension(path);
        string filepath = Path.GetDirectoryName(path)+"\\";
        DateTime time1 = DateTime.Now;
        ///如果为true则将结果保存至数据库,便于通过geoserver查看结果
        ///如果为false则将结果保存至文件,并在数据库中插入一条记录
        string lineText = filepath+filename + ".txt";
        string grdfile = Guid.NewGuid().ToString() + ".grd";
        string blnfile = grdfile.Replace("grd", "bln");
        try
        {
            Surfer.Application app = new Surfer.Application();
            app.GridData2(DataFile: path,                   //数据文件地址
                xCol: 1,                                        //x为第一列数据
                yCol: 2,                                        //y为第二列数据
                zCol: 3,                                        //z为第三列数据
                DupMethod: Surfer.SrfDupMethod.srfDupAvg,
                //xMin: 112.536542357878,                       //x最小值
                //xMax: 113.434857642122,                       //x最大者
                //yMin: 21.4983645627334,                       //y最小值
                //yMax: 22.3317562252913,                       //y最大值
                Algorithm: Surfer.SrfGridAlgorithm.srfKriging,  //插值算法Kriging
                NumCols: rowCnt,                                //x方向插值数据量
                NumRows: colCnt,                                //y方向插值数据量
                OutGrid: filepath + grdfile,                        //返回文件为gridfile
                OutFmt: Surfer.SrfGridFormat.srfGridFmtAscii);  //返回文件编码为Ascii
    
            Surfer.IDocuments docs = app.Documents;
            Surfer.IPlotDocument Doc = (Surfer.IPlotDocument)docs.Add(Surfer.SrfDocTypes.srfDocPlot);//创建一个空白绘图文档
            Surfer.IShapes Shapes = Doc.Shapes;
    
            Surfer.IMapFrame contourMapFrame = Shapes.AddContourMap(filepath+ grdfile);//加载网格文件,这个是上面生成的grd文件
    
            Surfer.IContourMap contourMap = (Surfer.IContourMap)contourMapFrame.Overlays.Item(1);
            contourMap.SmoothContours = Surfer.SrfConSmoothType.srfConSmoothHigh;//平滑等值线边界当前设置不平滑
            if (array != null) contourMap.Levels.AutoGenerate(array[0], array[1], array[2]);//设置等值线间隔
            //string strWH = string.Format("width={0:f0},height={1:f0},KeepAspect=1,ColorDepth=32",540,420);//设置输出图片的高度和宽度
            //Doc.Export(@"C:\1.png", SelectionOnly: false, Options: strWH);//设置输出图片格式名
            Doc.Export(filepath + blnfile);//生成等值线文件
            Doc.Close(Surfer.SrfSaveTypes.srfSaveChangesNo);//不生成srf文件
            app.Quit();//退出
            System.GC.Collect(System.GC.GetGeneration(app));//释放
            File.Delete(filepath + grdfile);
            TimeSpan ts = DateTime.Now - time1;
    
            //导出geojson数据
    
            //  以下为读取入库,文件格式如下
            //  8,0 "299.1496"
            //  112.577002425616,22.33175623,0
            //  112.572474916,22.3275559359832,0
            //  112.563491762,22.3275559359832,0
            //  112.559036117616,22.3234223133,0
            //  112.554508608,22.3192220192832,0
            //  112.549981098384,22.3234223133,0
            //  112.545525454,22.3275559359832,0
            //  112.5365423,22.3275559359832,0
            //  第一行为:点个数,未知,高程值
            //  余下的行为点数据,一个点占一行
    
            if (!File.Exists(filepath + blnfile)) return "";
    
            FileStream fs = new FileStream(filepath + blnfile, FileMode.Open, FileAccess.ReadWrite);
            StreamReader sr = new StreamReader(fs, UnicodeEncoding.UTF8);
    
            Dictionary<string, double> dicZ = new Dictionary<string, double>();
            Dictionary<string, List<string>> dicLine = new Dictionary<string, List<string>>();
    
            double z = 0.0;
            int cnt = 0;
            int index = 0;
            string guid = "";
            string line = string.Empty;
    
            while ((line = sr.ReadLine()) != null)
            {
                if (line != null && line != "")
                {
                    if (line.IndexOf("\"") > -1)
                    {
                        index = 0;
                        string[] str = line.Split(' ');
                        cnt = Convert.ToInt32(str[0].Split(',')[0]);
                        z = Convert.ToDouble(str[1].Replace("\"", ""));
                        guid = Guid.NewGuid().ToString();
    
                        dicZ.Add(guid, z);
    
                        continue;
                    }
    
                    index++;
                    if (index <= cnt)
                    {
                        if (!dicLine.ContainsKey(guid))
                            dicLine.Add(guid, new List<string>());
    
                        dicLine[guid].Add(line);
                    }
                }
            }
            sr.Close();
            fs.Close();
            sr.Dispose();
            fs.Dispose();
    
            //string sql1 = "INSERT INTO contour_3d(guidid, taskid, type, height, ordernum, value, lineobj) VALUES('{0}','{1}','{2}',{3},{4},{5},{6})";
            //文件覆盖方式添加内容
            System.IO.StreamWriter file = new System.IO.StreamWriter(lineText, false);
            foreach (var v in dicLine)
            {
                //string lineGeoJson = "{ \"type\": \"LineString\", \"coordinates\": [ [100.0, 0.0], [101.0, 1.0] ],\"properties\":{\"m\":2} }";
                string lineobj = "{\"type\": \"Feature\",\"geometry\": { \"type\": \"LineString\", \"coordinates\": [";
                foreach (var p in v.Value)
                {
                    lineobj += string.Format("[{0},{1}],", p.Split(',')[0], p.Split(',')[1]);
                }
                lineobj = lineobj.Substring(0, lineobj.Length - 1);
                lineobj += "]},\"properties\":{\"m\":" + dicZ[v.Key] + "}}\r\n";
                file.Write(lineobj);
                //string str = string.Format(sql1, v.Key, taskid, type, high, order, dicZ[v.Key], lineobj);
                //DbHelperPostSQL.ExecuteSql(str);
    
            }
            file.Flush();
            //关闭文件
            file.Close();
            //释放对象
            file.Dispose();
            File.Delete(filepath + blnfile);
            return lineText;
        }
        catch (Exception ex)
        {
            //string msg = string.Format("{0}\t高度{1}\t顺序{2}\r\n", ex.Message, high, order);
            //File.AppendAllText(filename + "\\wholeText.txt", msg, System.Text.ASCIIEncoding.UTF8);
            return "";
        }
    
    }
    

    `

  • openlayers加载geojson数据添加到地图上
    var contourL = new ol.layer.Vector({
        source: new ol.source.Vector(),
        style: function (f, r) {
            var txt = f.getProperties().m;
            return new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color: '#00EEFF',
                    width: 2
                }),
                text: new ol.style.Text({
                    text: txt.toString()
                })
            })
        }
    });
    $.ajax({
        url: './Controller/Main.ashx?type=showcontour&path=' + p,
        type: 'get',
        dataType: 'json',
        success: function (data) {
            var gj = new ol.format.GeoJSON();
            var geoJsons = data;
            var ex = ol.extent.createEmpty();
            var fs = [];
            geoJsons.forEach(function (item) {
                var f = gj.readFeature(item);
                ex = ol.extent.containsExtent(f.getGeometry().getExtent(), ex);
                fs.push(f);
            })
            contourL.getSource().clear();
            contourL.getSource().addFeatures(fs);
            map.getView().fit(ex, map.getSize());
        },
        error: function (e) {
            console.log(e);
        }
    })

注:代码可联系下载,提供技术支持

2 Responses

  1. aman说道:

    我的邮箱地址:64524811@qq.com

  2. aman说道:

    求代码,如何联系

发表评论

您的电子邮箱地址不会被公开。

CAPTCHAis initialing...