爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 16380|回复: 36

关于meteoinfo类库开发中的疑问

[复制链接]

新浪微博达人勋

发表于 2011-9-4 17:19:59 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
本帖最后由 孤蓝et 于 2011-10-3 13:29 编辑

        近期总算着手从VB6想C#转变,主要是有meteoinfo强大的气象分析类库做为后盾,使我有信心将以前做过和后续的开发向Meteoinfo类库转换。而且斑竹的Meteoinfo类库完整的demo程序,基本能给大家一个着手写基于meteoinfo类库开发的引子。不过作为C#初学者,对代码的阅读和理解毕竟有限,还是希望能通过学习,多做一些进步吧。之前在demo的基础上修改程序的过程中,也遇到不少问题,大部分是我不精通C#和meteoinfo的说明文档,但是斑竹还是给予细心的解答。所以希望我此处的提问、技术疑问能得到大家的帮助,也把自己的问题和解决方案写出来与大家分享。


1、demo程序中的default.mip中出现中文字符乱码情况。
解决方法(修改部分代码,在程序中加入<?xml version='1.0' encoding='gb2312'?>,或者在default.mip第一行加入<?xml version="1.0" encoding="gb2312"?>):

  1.          public void SaveProjFile(string aFile)
  2.         {
  3.             m_FileName = aFile;
  4.             XmlDocument doc = new XmlDocument();
  5.             doc.LoadXml("<?xml version='1.0' encoding='gb2312'?><MeteoInfo name='" + Path.GetFileNameWithoutExtension(aFile) + "' type='projectfile'></MeteoInfo>");
  6.             XmlElement root = doc.DocumentElement;            
  7.             //Add MapView content
  8.             frmMain.G_LayerLegend.MapView.ExportProjectXML(ref doc, root, m_FileName);               
  9.             //Save project file            
  10.             doc.Save(aFile);
  11.         }
复制代码

2、图层名称自定义
        demo程序中,比如绘制第一类数据的示例程序,默认情况,左侧图层列表中的名词前部写为“stationmodel_”,这部分字段假如我不需要,或者改为其他名称,能实现吗?      
          通过下述两句代码,即可实现图层名称的自定义。很简单。      
            aLayer.IsMaskout = true;
            aLayer.LayerName = "测试数据";

  1.         private void TSMI_MICAPS1_StationModel_Click(object sender, EventArgs e)
  2.         {
  3.             MICAPS1DataInfo aDataInfo = new MICAPS1DataInfo();
  4.             string aFile = Application.StartupPath + @"\Sample\09031417.000";
  5.             aDataInfo.ReadDataInfo(aFile);
  6.             LegendScheme aLS = LegendManage.CreateSingleSymbolLegendScheme(ShapeTypes.Point, Color.Blue, 12);
  7.             double[,] stationModelData = new double[10, 1];
  8.             Extent aExtent = new Extent();
  9.             stationModelData = aDataInfo.GetStationModelData(ref aExtent);
  10.             VectorLayer aLayer = new VectorLayer(ShapeTypes.Point);
  11.             aLayer = DrawMeteoData.CreateStationModelLayer(stationModelData,
  12.                     aDataInfo.UNDEF, aLS, "MICAPS1");
  13.             aLayer.IsMaskout = true;
  14.             aLayer.LayerName = "测试数据";
  15.             int aLayerHandle = G_LayerLegend.AddLayer(aLayer, true);
  16.         }
复制代码

3、地名显示【没有实现】
      目前meteoinfo支持丰富的地图文件,暂时不太熟需shp文件。所以我在着手考虑实现micaps 第17类数据的支持,来实现台站名的显示,这个在业务平台的开发中还算重要,能让预报人员明白相关台站的信息。此部分参照GIS相关知识或http://bbs.06climate.com/forum.p ... &extra=page%3D1中介绍的方法,目前本人未能实验成功。如有解决方案,立即呈上。

4、利用MICAPS第一类数据进行离散点分析。
读入数组的使用,stationmodel和stationdata的使用?以及等值线分析方法。

      今天看了许久的demo和meteoinfo class library help,忙活了一晚上也没有实现我需要的结果,为了实现打开micaps第一类数据后,自动分析温度等值线。我想参照TSMI_LLStShaded_Click,TSMI_MICAPS1_StationModel_Click这两部分的代码,看能不能合并实现我的想法,可是在数据读入就发现很没有头绪:
micaps 第一类数据的读入方法
stationModelData = aDataInfo.GetStationModelData(ref aExtent);
经纬度的数据
StationData stationData = aDataInfo.GetStationData(0);
             //Read micaps_1 data info,将micaps 第一类数据使用linlatstationdata方法读入。
            //stationModelData[0, 0] stationModelData[1, 0] 经纬度
            //stationModelData[2, 0] stationModelData[3, 0] 风向 风俗
            //stationModelData[7, 0] 温度
            //stationModelData[8, 0] 露点
            //stationModelData[9, 0] 修正海平面气压

            //GetStationData,将micaps 第一类数据使用GetStationData方法读入。
            //GetStationData(1)  风向
            //GetStationData(2)  风速
            //GetStationData(3)  气压
            //GetStationData(11) 露点/相对湿度
            //GetStationData(14) 温度
            //stationData       得到符合要求的经纬度、数据记录。这个是程序用来绘制LATLON数据。

      我怎么能从stationModelData = aDataInfo.GetStationModelData(ref aExtent);里面找到经纬度、温度数据在数组的位置,然后赋值给S = ContourDraw.FilterDiscreteData_Radius(S, gridInterp.Radius,gridInterp.GridDataParaV.dataExtent, stationData.UNDEF);用来绘图?

以下代码即为我修改后的代码。大家可以试试。
  1.         private void TSMI_MICAPS1_StationModel_Click(object sender, EventArgs e)
  2.         {
  3.             MICAPS1DataInfo aDataInfo = new MICAPS1DataInfo();
  4.             string aFile = Application.StartupPath + @"\Sample\09031417.000";
  5.             aDataInfo.ReadDataInfo(aFile);

  6.             LegendScheme aLS = LegendManage.CreateSingleSymbolLegendScheme(ShapeTypes.Point, Color.Blue, 12);

  7.             double[,] stationModelData = new double[10, 1];
  8.             Extent aExtent = new Extent();
  9.             stationModelData = aDataInfo.GetStationModelData(ref aExtent);

  10.             //Read micaps_1 data info,将micaps 第一类数据使用linlatstationdata方法读入。
  11.             //stationModelData[0, 0] stationModelData[1, 0] 经纬度
  12.             //stationModelData[2, 0] stationModelData[3, 0] 风向 风俗
  13.             //stationModelData[7, 0] 温度
  14.             //stationModelData[8, 0] 露点
  15.             //stationModelData[9, 0] 修正海平面气压

  16.             VectorLayer aLayer = new VectorLayer(ShapeTypes.Point);
  17.             aLayer = DrawMeteoData.CreateStationModelLayer(stationModelData,
  18.                     aDataInfo.UNDEF, aLS, "MICAPS1");
  19.             aLayer.IsMaskout = true;
  20.             aLayer.LayerName = "测试数据";
  21.             int aLayerHandle = G_LayerLegend.AddLayer(aLayer, true);


  22.             //GetStationData,将micaps 第一类数据使用GetStationData方法读入。
  23.             //GetStationData(1)  风向
  24.             //GetStationData(2)  风速
  25.             //GetStationData(3)  气压
  26.             //GetStationData(11) 露点/相对湿度
  27.             //GetStationData(14) 温度
  28.             //stationData       得到符合要求的经纬度、数据记录。这个是程序用来绘制LATLON数据。
  29.             StationData stationData = aDataInfo.GetStationData(14);
  30.             double[,] S = stationData.Data;


  31.             

  32.             //Interpolate
  33.             GridDataPara aGDP = new GridDataPara();
  34.             aGDP.dataExtent.minX = 70;
  35.             aGDP.dataExtent.maxX = 100;
  36.             aGDP.dataExtent.minY = 33;
  37.             aGDP.dataExtent.maxY = 50;
  38.             aGDP.xNum = 30;
  39.             aGDP.yNum = 17;
  40.             GridInterpolation gridInterp = new GridInterpolation();
  41.             gridInterp.GridDataParaV = aGDP;

  42.             gridInterp.GridInterMethodV = GridInterMethod.IDW_Radius;
  43.             gridInterp.Radius = 2;
  44.             gridInterp.MinPointNum = 1;

  45.             double[] X = new double[1];
  46.             double[] Y = new double[1];
  47.             ContourDraw.CreateGridXY(gridInterp.GridDataParaV, ref X, ref Y);

  48.             S = ContourDraw.FilterDiscreteData_Radius(S, gridInterp.Radius,
  49.                 gridInterp.GridDataParaV.dataExtent, stationData.UNDEF);
  50.             GridData gridData = ContourDraw.InterpolateDiscreteData_Radius(S,
  51.                 X, Y, gridInterp.MinPointNum, gridInterp.Radius, stationData.UNDEF);


  52.             //Create legend scheme  等值线
  53.             bool hasNoData = true;
  54.             LegendScheme aLS_2 = LegendManage.CreateLegendSchemeFromGridData(gridData, LegendType.GraduatedColor,
  55.                 ShapeTypes.Polyline, ref hasNoData);
  56.             

  57.             //Create layer
  58.             VectorLayer aLayer_2 = new VectorLayer(ShapeTypes.Polyline);
  59.             aLayer_2 = DrawMeteoData.CreateContourLayer(gridData, aLS_2, "Rain");
  60.             aLayer_2.IsMaskout = true;
  61.             G_LayerLegend.AddLayer(aLayer_2, true);

  62.             //Create legend scheme  网格点 point
  63.             //Create legend scheme  填色 shade



  64.             this.Cursor = Cursors.Default;

  65.         }
复制代码


后续完成这部分的修改,我会把我修改的demo程序共享出来,也想把自己使用meteoinfo做二次开发的过程写下来,能为其他人做一个借鉴把。也希望更多的人能使用这个类库开发更实用的业务平台。
感谢meteoinfo斑竹无私的奉献。

评分

参与人数 1金钱 +5 收起 理由
mofangbao + 5 鼓励一下

查看全部评分

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2011-9-4 17:39:45 | 显示全部楼层
赞一个先!

1、是正解,也很简单就不多说了。
2、文件名是可以用代码控制的,在aLayer.IsMaskout = true; 后加一行aLayer.LayerName = "..."即可。
3、其实就是个站点文件,可以参照我的站点文件绘制图形的帖子生成站点shape文件。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2011-9-4 20:57:32 | 显示全部楼层
感谢楼主和MeteoInfo 斑竹,很给力!
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2011-9-5 00:43:40 | 显示全部楼层

关于台站shp文件的制作,斑竹应该是推荐这个帖子吧?http://bbs.06climate.com/forum.p ... &extra=page%3D1
我看了下,通过这个方法是可以制作shp文件,但是输出的shp仅能实现台站的点的显示,我还需要显示台站的中文名?这个用这个方法实现不了吧?
好像看了以前的帖子,也的确没有找到您的这个软件有直接显示台站的名称的方法。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2011-9-5 08:19:55 | 显示全部楼层
孤蓝et 发表于 2011-9-5 00:43
关于台站shp文件的制作,斑竹应该是推荐这个帖子吧?http://bbs.06climate.com/forum.php?mod=viewthread ...

当然可以显示中文名,你的站点文本文件中不是有中文站名吗。用Excel编辑成MeteoInfo的Lon/Lat Station文本格式(具体见你提到的帖子),中文站名也作为一列就ok了,在MeteoInfo中绘图时选择Station Info,这样所有字段都会在shape文件中了。

或者你把micaps第17类站点文件作为附件放上,我来做一个shape文件共享给大家。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2011-9-5 10:54:06 | 显示全部楼层
MeteoInfo 发表于 2011-9-5 08:19
当然可以显示中文名,你的站点文本文件中不是有中文站名吗。用Excel编辑成MeteoInfo的Lon/Lat Station文本 ...



我尝试用excel转换了一下格式,但是在meteoinfo中打开数据出错咯。呵呵。我上传一下我的数据文件。
又麻烦您了。

==================
由于站点数据涉及国家保密数据,问题解决后我删除了原始站点数据
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2011-9-5 14:01:18 | 显示全部楼层
孤蓝et 发表于 2011-9-5 10:54
我尝试用excel转换了一下格式,但是在meteoinfo中打开数据出错咯。呵呵。我上传一下我的数据文件。
又 ...


大家尝试自己转换一下吧,这个涉及了国家保密数据,因此不便在这里公开分享,请大家的理解

评分

参与人数 1金钱 +10 收起 理由
mofangbao + 10 一直很给力

查看全部评分

密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2011-9-11 01:47:20 | 显示全部楼层
本帖最后由 孤蓝et 于 2011-9-11 01:59 编辑

      二次开发的讨论还是太少?惆怅,这C#还挺难入门。。。怪不得叫C#,横竖都是二。唉。。单纯发个牢骚。
4、读入数组的使用,stationmodel和stationdata的使用?以及等值线分析方法。
      今天看了许久的demo和meteoinfo class library help,忙活了一晚上也没有实现我需要的结果,为了实现打开micaps第一类数据后,自动分析温度等值线。我想参照TSMI_LLStShaded_Click,TSMI_MICAPS1_StationModel_Click这两部分的代码,看能不能合并实现我的想法,可是在数据读入就发现很没有头绪:
micaps 第一类数据的读入方法
stationModelData = aDataInfo.GetStationModelData(ref aExtent);
经纬度的数据
StationData stationData = aDataInfo.GetStationData(0);
      我怎么能从stationModelData = aDataInfo.GetStationModelData(ref aExtent);里面找到经纬度、温度数据在数组的位置,然后赋值给S = ContourDraw.FilterDiscreteData_Radius(S, gridInterp.Radius,gridInterp.GridDataParaV.dataExtent, stationData.UNDEF);用来绘图?
      
      莫名,说明我还没有彻底看透C#中的数组赋值问题,同样也没有真正读懂里面的程序思路。求版主的解答~_~,万分感谢啊。。。
  1.         private void TSMI_LLStShaded_Click(object sender, EventArgs e)
  2.         {
  3.             this.Cursor = Cursors.WaitCursor;

  4.             //Read data info
  5.             LonLatStationDataInfo aDataInfo = new LonLatStationDataInfo();
  6.             string aFile = Application.StartupPath + "\\Sample\\rain_2008072220.csv";
  7.             aDataInfo.ReadDataInfo(aFile);

  8.             //Get station data
  9.             StationData stationData = aDataInfo.GetStationData(0);

  10.             //Interpolate
  11.             GridDataPara aGDP = new GridDataPara();
  12.             aGDP.dataExtent.minX = 60;
  13.             aGDP.dataExtent.maxX = 140;
  14.             aGDP.dataExtent.minY = -20;
  15.             aGDP.dataExtent.maxY = 60;
  16.             aGDP.xNum = 80;
  17.             aGDP.yNum = 80;
  18.             GridInterpolation gridInterp = new GridInterpolation();
  19.             gridInterp.GridDataParaV = aGDP;

  20.             gridInterp.GridInterMethodV = GridInterMethod.IDW_Radius;
  21.             gridInterp.Radius = 2;
  22.             gridInterp.MinPointNum = 1;

  23.             double[] X = new double[1];
  24.             double[] Y = new double[1];
  25.             ContourDraw.CreateGridXY(gridInterp.GridDataParaV, ref X, ref Y);
  26.             double[,] S = stationData.Data;
  27.             S = ContourDraw.FilterDiscreteData_Radius(S, gridInterp.Radius,
  28.                 gridInterp.GridDataParaV.dataExtent, stationData.UNDEF);
  29.             GridData gridData = ContourDraw.InterpolateDiscreteData_Radius(S,
  30.                 X, Y, gridInterp.MinPointNum, gridInterp.Radius, stationData.UNDEF);

  31.             //Create legend scheme
  32.             bool hasNoData = true;
  33.             LegendScheme aLS = LegendManage.CreateLegendSchemeFromGridData(gridData, LegendType.GraduatedColor,
  34.                 ShapeTypes.Polygon, ref hasNoData);
  35.             ((PolygonBreak)aLS.breakList[0]).DrawFill = false;

  36.             //Create layer
  37.             VectorLayer aLayer = new VectorLayer(ShapeTypes.Polygon);
  38.             aLayer = DrawMeteoData.CreateShadedLayer(gridData, aLS, "Rain");
  39.             aLayer.IsMaskout = true;
  40.             G_LayerLegend.AddLayer(aLayer, true);

  41.             this.Cursor = Cursors.Default;
  42.         }
复制代码


密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2011-9-11 10:18:26 | 显示全部楼层
本帖最后由 MeteoInfo 于 2011-9-11 10:24 编辑
孤蓝et 发表于 2011-9-11 01:47
二次开发的讨论还是太少?惆怅,这C#还挺难入门。。。怪不得叫C#,横竖都是二。唉。。单纯发个牢骚。 ...

如果你只是要对micaps第一类数据中的某个变量进行操作,不要用MICAPS1DataInfo的GetStationModelData方法(这个是为了站点填图用的),用GetStationData(vIdx)就可以了,参数是变量的次序(也就是第几个变量)。变量名称及次序可以在MeteoInfo桌面软件中打开一个micaps第一类数据查一下。后续的插值及生成等值线图层就和TSMI_LLStShaded_Click中的代码没什么两样了。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2011-10-3 13:18:35 | 显示全部楼层
本帖最后由 孤蓝et 于 2011-10-3 13:19 编辑

继续研究地名显示。
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表