- 积分
- 4182
- 贡献
-
- 精华
- 在线时间
- 小时
- 注册时间
- 2011-6-27
- 最后登录
- 1970-1-1
|
登录后查看更多精彩内容~
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
meteoinfo版主曾经在怀化论坛写过一篇关于使用MeteoinfoC.dll进行二次开发的详细过程,并发布Demo,由于怀化论坛改版原文图片丢失,幸好当时我在硬盘有保存那个帖子,故此处帮meteoinfo版主重新发布,文章版权仍归meteoinfo版主所有,本人仅是代为整理和发布。
《用MeteoInfoC.dll类库进行软件开发》原帖地址: http://bbs.121323.com/read.php?tid-52541.html
内容基本保持原来帖子的面貌,以下为正文:
由于MeteoInfoC.dll类库已经基本成形,在它的基础上开发的MeteoInfo功能也还算可以,所以利用这个帖子讲讲用MeteoInfoC.dll进行软件开发。
我会用一个C#的Demo程序进行讲解。开发环境:Microsoft Visual C# 2008 Express Edition (这是免费版本,可以在微软官方网站上下载)。需要的类库:MeteoInfoC.dll 和wContour.dll (如果想显示NetCDF格式数据还需要NetCDF4.dll)。
MeteoInfoC.dll是我用C#开发的气象数据显示分析类库,还具备一些简单的GIS功能。wContour.dll是我开发的等值线相关算法类库。两个类库结合使用可以方便的开发出功能比较强的气象软件(当然也可以开发其他相关软件)。下载见这里哦:http://bbs.06climate.com/forum.php?mod=viewthread&tid=989&fromuid=214
首先创建一个新的Project。
在References中引用MeteoInfoC.dll和wContour.dll类库。
在ToolBox中点击鼠标右键,点击Choose Items...菜单,在Choose ToolBox Items对话框中点中.Net Framwork Components选项,点击Browse...按钮并打开MeteoInfoC.dll文件,然后选中LayersLegend和MapView两个控件,点击OK。
在ToolBox栏中会出现选中的两个控件。
这部分主要介绍如何引用MeteoInfoC.dll类库及加载LayersLegend和MapView两个控件到ToolBox栏中。其实不用加载也可以在代码中直接使用这些控件。
在Form1中添加ToolStrip、StatusStrip和SplitContainer.
在splitContainer1的Panel1中添加LayersLegend控件,在Panel2中添加MapView控件,并将两个控件的Dock属性设置为Fill。将layersLegend1控件的MapView属性设置为mapView1(非常重要)。
在toolStrip1中添加一个按钮,命名为TSB_OpenFile。
在Form1的代码区添加MeteoInfoC的相关命名空间。
在TSB_OpenFile控件的Click事件中添加如下代码,实现打开shape文件和各种格式image文件的功能。
好,现在运行一下程序,打开country1.shp文件。图层名显示在layersLegend1控件中,地图数据显示在mapView1控件中。
用鼠标双击图层名,出现图层属性对话框,然后你可以修改图层的LegendScheme。
在试试打开一个图像文件GLOBALeb3colshade.jpg
OK,就这么简单。今天先到这里,改天再讲图形的放大、缩小、移动功能实现。
这一讲是关于图形缩放和移动的。
在toolStrip1控件中添加下图中的几个按钮(图标文件自己在网上找吧)。分别命名为TSB_None, TSB_ZoomIn, TSB_ZoomOut, TSB_FullExtent, TSB_ZoomToLayer。
在TSB_ZoomIn的Click事件中写入如下代码:
TSB_None, TSB_ZoomOut 和TSB_Pan的Click事件代码和上面的基本一样,只需要修改最后一行代码。当作大家的作业了。
在TSB_FullExtent和TSB_ZoomToLayer的Click事件中添加如下代码:- private void TSB_FullExent_Click(object sender, EventArgs e)
- {
- this.mapView1.ZoomToExtent(this.mapView1.ExtentV);
- }
- private void TSB_ZoomToLayer_Click(object sender, EventArgs e)
- {
- object aLayer = this.mapView1.GetLayerFromHandle(this.layersLegend1.SelectedLayer);
- if (aLayer == null)
- return;
- Extent aExtent = new Extent();
- if (aLayer.GetType() == typeof(VectorLayer))
- {
- VectorLayer sLayer = (VectorLayer)aLayer;
- aExtent = sLayer.Extent;
- }
- else
- {
- ImageLayer iLayer = (ImageLayer)aLayer;
- aExtent = iLayer.Extent;
- }
- this.mapView1.ZoomToExtent(aExtent);
- }
复制代码 好了,你已经拥有一个不错的地理底图功能了。我也该休息一下了。
在状态栏显示鼠标所在位置的经纬度。
在状态栏statusStrip1中添加一个StatusLabel控件,命名为TSSL_Coord。
在代码区添加一个MapView的MouseMove事件函数:- private void MapView_MouseMove(object sender, MouseEventArgs e)
- {
- double ProjX, ProjY;
- ProjX = 0;
- ProjY = 0;
- this.mapView1.MapExtentSetV.ScreenToProj(ref ProjX, ref ProjY, e.X, e.Y, this.mapView1.MapExtentSetV);
- this.TSSL_Coord.Text = "Lon: " + ProjX.ToString("0.00") + "; Lat: " + ProjY.ToString("0.00");
- }
复制代码 在frmMain(我将Form1改名为了frmMain)的Load事件中添加mapView1的MouseMove事件:- private void frmMain_Load(object sender, EventArgs e)
- {
- this.mapView1.MouseMove += new MouseEventHandler(this.MapView_MouseMove);
- }
复制代码 再运行程序会看见鼠标所在位置的经纬度显示在状态栏中。
查询图元属性:
在工具栏toolStrip1中添加一个ToolButton,命名为TSB_Identifer。在TSB_Identifer的Click事件中输入下面的代码:- private void TSB_Identifer_Click(object sender, EventArgs e)
- {
- for (int j = 0; j < toolStrip1.Items.Count; j++)
- {
- if (toolStrip1.Items[j].GetType() == typeof(ToolStripButton))
- {
- ToolStripButton aTSB = (ToolStripButton)toolStrip1.Items[j];
- if (aTSB.Checked)
- aTSB.Checked = false;
- }
- }
- ToolStripButton currentTool = (ToolStripButton)sender;
- currentTool.Checked = true;
- this.mapView1.Cursor = Cursors.Cross;
- }
复制代码 添加一个MapView的MouseDown事件函数:- private void MapView_MouseDown(object sender, MouseEventArgs e)
- {
- if (TSB_Identifer.Checked && e.Button == MouseButtons.Left)
- {
- double ProjX, ProjY;
- ProjX = 0;
- ProjY = 0;
- Single sX, sY;
- sX = e.X;
- sY = e.Y;
- this.mapView1.MapExtentSetV.ScreenToProj(ref ProjX, ref ProjY, e.X, e.Y, this.mapView1.MapExtentSetV);
- object aLayerObj = this.mapView1.GetLayerFromHandle(this.layersLegend1.SelectedLayer);
- if (aLayerObj.GetType() != typeof(VectorLayer))
- return;
- VectorLayer aLayer = (VectorLayer)aLayerObj;
- if (this.mapView1.Projection.IsLonLatMap)
- {
- if (ProjX < aLayer.Extent.minX)
- {
- if (aLayer.Extent.minX > -360 && aLayer.Extent.maxX > 0)
- {
- this.mapView1.MapExtentSetV.ProjToScreen(ProjX, ProjY, ref sX, ref sY, 360, this.mapView1.MapExtentSetV);
- }
- }
- if (ProjX > aLayer.Extent.maxX)
- {
- if (aLayer.Extent.maxX < 360 && aLayer.Extent.minX < 0)
- {
- this.mapView1.MapExtentSetV.ProjToScreen(ProjX, ProjY, ref sX, ref sY, -360, this.mapView1.MapExtentSetV);
- }
- }
- }
- int Buffer = 5;
- Extent aExtent = new Extent();
- this.mapView1.MapExtentSetV.ScreenToProj(ref ProjX, ref ProjY, sX - Buffer, sY + Buffer, this.mapView1.MapExtentSetV);
- aExtent.minX = ProjX;
- aExtent.minY = ProjY;
- this.mapView1.MapExtentSetV.ScreenToProj(ref ProjX, ref ProjY, sX + Buffer, sY - Buffer, this.mapView1.MapExtentSetV);
- aExtent.maxX = ProjX;
- aExtent.maxY = ProjY;
- List<int> SelectedShapes = new List<int>();
- if (aLayer.SelectShapes(aExtent, ref SelectedShapes))
- {
- string fieldStr, valueStr;
- int shapeIdx = SelectedShapes[0];
- string cellStr = "";
- if (aLayer.ShapeNum > 0)
- {
- for (int i = 0; i < aLayer.NumFields; i++)
- {
- fieldStr = aLayer.GetFieldName(i);
- valueStr = aLayer.GetCellValue(i, shapeIdx).ToString();
- cellStr = cellStr + Environment.NewLine + fieldStr + ": " + valueStr;
- }
- }
- MessageBox.Show(cellStr, "Identifer");
- }
- }
- }
复制代码 在frmMain的Loaded事件中添加mapView1的MouseDown事件:- private void frmMain_Load(object sender, EventArgs e)
- {
- this.mapView1.MouseMove += new MouseEventHandler(this.MapView_MouseMove);
- this.mapView1.MouseDown += new MouseEventHandler(this.MapView_MouseDown);
- }
复制代码 运行效果如下:
根据属性字段值进行标注:
在toolStrip1中添加一个ToolButton,命名为TSB_Label,在其Click事件中添加下面的代码:- private void TSB_Label_Click(object sender, EventArgs e)
- {
- //Get selected layer
- object aLayerObj = this.mapView1.GetLayerFromHandle(this.layersLegend1.SelectedLayer);
- if (aLayerObj.GetType() != typeof(VectorLayer))
- return;
- VectorLayer aLayer = (VectorLayer)aLayerObj;
- //Set label
- List<string> fieldNameList = aLayer.GetFieldNameList();
- string fieldName;
- if (aLayer.LayerName == "country1.shp")
- fieldName = fieldNameList[3]; //This is special for 'country1.shp'.
- else
- fieldName = fieldNameList[0];
- aLayer.LabelSetV.FieldName = fieldName;
- aLayer.LabelSetV.AvoidCollision = true;
- aLayer.LabelSetV.LabelAlignType = MeteoInfoC.Label.AlignType.Center;
- aLayer.LabelSetV.Offset = 0;
- aLayer.LabelSetV.LabelFont = new Font("Arial", 8);
- aLayer.LabelSetV.LabelColor = Color.Red;
- aLayer.LabelSetV.DrawShadow = false;
- aLayer.LabelSetV.ShadowColor = Color.White;
- aLayer.LabelSetV.DrawLabels = true;
- aLayer.LabelSetV.ColorByLegend = false;
- //Add labels
- aLayer.AddLabels();
- this.mapView1.PaintLayers();
- }
复制代码 运行效果如下:
前面讲的和气象不沾边,今天讲讲咱气象人关系的东西:用MICAPS1格式数据做站点填图。
在程序主界面上添加一个菜单栏,然后添加如下菜单项:
在代码区添加气象数据命名空间的引用:
using MeteoInfoC.Data.MeteoData;
在'StationModel'子菜单的Click事件中添加如下代码:- private void TSMI_MICAPS1_StationModel_Click(object sender, EventArgs e)
- {
- MICAPSData aMData = new MICAPSData();
- MICAPS1DataInfo aDataInfo = new MICAPS1DataInfo();
- string aFile = Application.StartupPath + @"\Sample\09031417.000";
- aDataInfo = aMData.ReadMicaps1(aFile);
- LegendManage CLegendManage = new LegendManage();
- LegendScheme aLS = CLegendManage.CreateSingleSymbolLegendScheme(ShapeType.Point, Color.Blue, 12);
- double[,] stationModelData = new double[10, 1];
- Extent aExtent = new Extent();
- stationModelData = aMData.GetStationModelData_M1(aDataInfo, ref aExtent);
- DrawMeteoData CDrawMeteoData = new DrawMeteoData();
- VectorLayer aLayer = new VectorLayer(ShapeType.Point);
- aLayer = CDrawMeteoData.CreateStationModelLayer(stationModelData,
- aDataInfo.UNDEF, aLS, "MICAPS1");
- aLayer.IsMaskout = true;
- this.layersLegend1.AddLayer(aLayer, true, true);
- }
复制代码 这就OK了。运行效果如下:
今天讲讲打开和保存项目文件。
业务软件通常需要在打开的时候加载一些相关的图层和设置,这个可以在frmMain的Load事件中一个个图层添加,并设置每个图层的Legendscheme等,很不灵活。项目文件可以将复杂的软件设置、图层管理等信息放在一个文件里,提供了极大的便利和灵活性。通常xml格式的文件很适合用作项目文件。MeteoInfoC.dll中MapView、LayersLegend、MapLayout等类中提供了以xml格式输出和读入相关设置的功能,可以方便的用于形成软件的项目文件。
在Demo程序中添加一个类ProjectFile,添加一个FileName变量和SaveProject、LoadProject方法。- public void SaveProjFile(string aFile)
- {
- m_FileName = aFile;
- XmlDocument doc = new XmlDocument();
- doc.LoadXml("<MeteoInfo name='" + Path.GetFileNameWithoutExtension(aFile) + "' type='projectfile'></MeteoInfo>");
- XmlElement root = doc.DocumentElement;
- //Add MapView content
- frmMain.G_LayerLegend.MapView.ExportProjectXML(ref doc, root, m_FileName);
- //Save project file
- doc.Save(aFile);
- }
- public void LoadProjFile(string aFile)
- {
- m_FileName = aFile;
- XmlDocument doc = new XmlDocument();
- doc.Load(aFile);
- XmlElement root = doc.DocumentElement;
- //Load elements
- frmMain.G_LayerLegend.MapView.LockViewUpdate = true;
-
- //Load MapView content
- frmMain.G_LayerLegend.ImportProjectXML(root);
-
- frmMain.G_LayerLegend.MapView.LockViewUpdate = false;
- frmMain.G_LayerLegend.MapView.PaintLayers();
- }
复制代码 在frmMain窗体中添加Project菜单和Open, Save, Save As子菜单。- private void TSMI_OpenProject_Click(object sender, EventArgs e)
- {
- OpenFileDialog aDlg = new OpenFileDialog();
- aDlg.Filter = "MeteoInfo Project File (*.mip)|*.mip";
- if (aDlg.ShowDialog() == DialogResult.OK)
- {
- string aFile = aDlg.FileName;
- if (G_LayerLegend.MapView.Layers.Layers.Count > 0)
- {
- G_LayerLegend.RemoveAllLayers();
- }
- Application.DoEvents();
- m_ProjectFile.LoadProjFile(aFile);
- this.Text = "MeteoInfoC Demo - " + Path.GetFileNameWithoutExtension(aFile);
- G_LayerLegend.MapView.ZoomToExtent(G_LayerLegend.MapView.ViewExtent);
- }
- }
- private void TSMI_SaveProjetFile_Click(object sender, EventArgs e)
- {
- if (File.Exists(m_ProjectFile.FileName))
- m_ProjectFile.SaveProjFile(m_ProjectFile.FileName);
- else
- {
- SaveFileDialog aDlg = new SaveFileDialog();
- aDlg.Filter = "MeteoInfo Project File (*.mip)|*.mip";
- if (aDlg.ShowDialog() == DialogResult.OK)
- {
- string aFile = aDlg.FileName;
- m_ProjectFile.SaveProjFile(aFile);
- this.Text = "MeteoInfoC Demo - " + Path.GetFileNameWithoutExtension(aFile);
- }
- }
- }
- private void TSMI_SaveAsProject_Click(object sender, EventArgs e)
- {
- SaveFileDialog aDlg = new SaveFileDialog();
- aDlg.Filter = "MeteoInfo Project File (*.mip)|*.mip";
- if (aDlg.ShowDialog() == DialogResult.OK)
- {
- string aFile = aDlg.FileName;
- m_ProjectFile.SaveProjFile(aFile);
- this.Text = "MeteoInfoC Demo - " + Path.GetFileNameWithoutExtension(aFile);
- }
- }
复制代码 如果想做软件打开时加载缺省项目文件如Default.mip,可以在frmMain的Load事件中添加相关代码。- //Open default project file
- string aFile = Application.StartupPath + "\\Default.mip";
- if (File.Exists(aFile))
- {
- m_ProjectFile.LoadProjFile(aFile);
- this.Text = "MeteoInfoC Demo - " + Path.GetFileNameWithoutExtension(aFile);
- }
复制代码 其中m_ProjectFile是一个ProjectFile类的对象,在frmMain的变量声明中定义:
private ProjectFile m_ProjectFile = new ProjectFile();
结束。内容我都从原来的帖子复制过来了。就这些啦。希望对大家有用吧。
|
评分
-
查看全部评分
|