PIE框架基本接口使用方法

本文介绍PIE SDK的图像处理功能,涵盖算法层、组件层、地图控件及常用方法,如图层管理、地图显示、图形绘制等。深入探讨了算法接口、数据读取、符号表示及自定义算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hello PIE(未完成)

算法层
+ SystemAlgo库

要服务于图像处理功能的开发, 定义了ISystemAlgo接口AlgoFactory类。 ISystemAlgo接口是算法的基础接口,它定义了算法实现的规则, AlgoFactory对象实现了对各种算法的同步或异步调用的管理和监视。

+ CommonAlgo库

其包含了PIE桌面版中几乎所有的图像处理的算法。

组件层
+ SystemUI库

定义了被PIE用户界面组件所使用的对象,ICommand、ICommandControl、ITool、 ITrackerCancel等接口

+ AxControls库
  • MapControl:主要用于地图数据的显示和分析, 其封装了一个Map对象,并提供了相应属性、方法和事件,用于管理控件的显示属性、 调整地图属性、 控制地图的显示范围、 管理数据图层、加载地图文档等。
    常用方法
    1).LoadPmdFile 方法
    该方法用于在地图空间中加在地图文档,参数为地图文档路径
void LoadPmdFile(String pmdPath);

2).AddLayerFromFile方法
该方法用于在地图控件中添加图层,参数为图层数据路径和新加涂层的索引

bool AddLayerFromFile(String filePath,int toIndex);

附:区别LoadPmdFileAddLayerFromFile,一般地图索引是随加载顺序依次递增
3).AddLayer方法
用于在地图控件中添加图层,参数为图层对象和新建图层索引

void AddLayer(ILayer layer, int toIndex);

附:

  • 区别AddLayer()AddLayerFromFile(),两者传递的参数不一样,后者传递的参数是路径,前者传递的是Layer对象,需要通过LayerFactory()函数来转化成Layer对象。

  • LayerFactory()无论是矢量栅格数据,使用这个函数都会成为一个Layer数据。

  • 使用方法 LayerFactory(加载路径,记录索引)


   private void toolStripButton1__AddData_Click(object sender, EventArgs e)
   {
       //选择文件
       OpenFileDialog openFileDialog = new OpenFileDialog();
       openFileDialog.Filter = "RasterFile|*.tif;*.tiff;*.img|ShapeFile|*.shp";
       openFileDialog.Multiselect = false;
       if (openFileDialog.ShowDialog() != DialogResult.OK) return;
       //加载图层
       string FilePath = "";//@"E:\PIE软件设计\2020 PIE-SDK二次开发组件包\PIE SDK NET 201906\02.样例数据\China\中国湖泊.tif";
       FilePath = openFileDialog.FileName;
       ILayer layer = LayerFactory.CreateDefaultLayer(FilePath);
       //刷新图层
       mapControlMain.AddLayer(layer, 0);
       mapControlMain.PartialRefresh(ViewDrawPhaseType.ViewAll);
   }

4).DeleteLayer方法
该方法用于在地图控件删除图层,参数为要删除图层的索引

void DeleteLayer(int index);

5).ClearLayers方法
该方法用于删除地图控件上的所有图层

void ClearLayers();

附:对于DeleteLayer和ClearLayer主要区别就是前者是一个个删,后者是把所有地图都清除了

6).DrawShape方法
该方法在地图上绘制图形,参数为图形形状和图形样式

void DrawShape(IGeometry shape, ISymbol symbol);
IPoint point =new PIE.Geometry.Point();//定义图形
point.PutCoords(120,38,0);
ISymbol symbol=new SimpleMarkerSymbol();//定义样式
mapControlMain.DrawShape(Point as IGeometry, symbol);

7).ToMapPoint方法
屏幕坐标转化为地图坐标,参数为屏幕X坐标和屏幕Y坐标

IPoint ToMapPoint(int x, int y);

8).CenterAt方法
设置地图显示中心点

void CenterAt(IPoint centerPoint)

9).PartialRefresh方法
刷新当前地图显示控件,参数为刷新的类型
常用属性

1).FocusMap属性

2).ActiveView属性

3).Extent属性

4).FullExtent属性

5).SpatialReference属性

6).MapScale属性

实例代码:

private void toolStripButton1_SpatialReference_Click(object sender, EventArgs e)
    {
        IMap map = mapControlMain.ActiveView.FocusMap;
        string Srname = map.SpatialReference.ExportToPrettyWkt();
        MessageBox.Show(Srname);
    }

  1. TOCControl(图层树控件)以树状列表的形式展示地图的图层结构,并且允许用户来调整地图的显示样式、查看地图和图层的基本信息、控制地图的图层顺序、调整地图的显示范围等。

  1. PageLayoutControl( 制图控件)封装了一个PageLayout对象, 并提供了一些属性、方法和事件, 用来控制制图的外观、 管理制图元素(比例尺、指北针、 图例)、输出或打印制图成果等。

实战

命令相关接口

ICommand
ICommand下的方法

方法描述
RasterCommand()加载栅格数据
VectorCommand()加载矢量数据
ScientificDatasetCommand()加载科学数据集
FullExtentCommand()全图显示
CenterZoomInCommand()居中放大
CenterZoomOutCommand()居中缩小

ITool
ITool下的方法

方法描述
MapZoomInTool()拉框放大
MapZoomOutTool()拉框缩小
PanTool()平移漫游

功能封装为ITool或ICommand
个人感觉实现很多功能不是很方便

  1. 创建一个类
  2. 继承:BaseCommand
  3. 设置属性
  4. 重写一个OnClick()方法

加载数据的代码:

class AddData:BaseTool
{
    public AddData()
    {
        this.Caption = "加载数据";
        this.Name = "AddData";

    }
    public override void OnClick()
    {
        //选择文件
        OpenFileDialog openFileDialog = new OpenFileDialog();
        openFileDialog.Filter = "RasterFile|*.tif;*.tiff;*.img|ShapeFile|*.shp";
        openFileDialog.Multiselect = false;
        if (openFileDialog.ShowDialog() != DialogResult.OK) return;
        //加载图层
        string FilePath = "";//@"E:\PIE软件设计\2020 PIE-SDK二次开发组件包\PIE SDK NET 201906\02.样例数据\China\中国湖泊.tif";
        FilePath = openFileDialog.FileName;
        ILayer layer = LayerFactory.CreateDefaultLayer(FilePath);
        //刷新图层
        m_HookHelper.ActiveView.FocusMap.AddLayer(layer);//我的理解就是m_Hookhelper.ActiveView是与mapControlMain同类型但是加载数据时的另一种
        //mapControlMain.AddLayer(layer, 0);
        m_HookHelper.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll);
        //m.PartialRefresh(ViewDrawPhaseType.ViewAll);
    }
}
  1. 复制粘贴一些功能
  2. 将重写一些方法
  3. 在主函数中打入调用命令的代码

对于图层交互式命令运用ITool代码如下:

    ITool tool = new ZoomInTool();
    (tool as ICommand).OnCreate(mapControlMain);//将对象传给Hookhelper
    mapControlMain.CurrentTool = tool;

对于非交互式的运用ICommand代码如下:

    ICommand cmd = new AddData();
    cmd.OnCreate(mapControlMain);//将对象传给Hookhelper
    cmd.OnClick();

附:BaseCommand与DesktopCommand的区别:DesktopCommand在BaseCommand的基础上拓展了一个对象,IApplication,通过此对象可以调用BaseCommand不能调用主界面的内容,
如三大控件,进度条之类的。所以插件式开发常用到DesktopCommand类。
注意:组件是开发不能用到DesktopCommand命令,如果是用其中的HookHelper是空的

  • 在设置按钮图片的时候可以使用Properties调用文件夹中存取的图片。
    Properties.Resoures.Name

  • 为什么创建的BaseCommand可以用ICommand创建出来?因为BaseCommand是继承了
    ICommand

    public class BaseCommand : ICommand
    ICommand cmd = new AddData();

后期插件开发界面搭建和集成,视频四应该是必看的

插件式大概步骤
  1. 写一个继承BaseCommand或DesktopCommand的类
  2. 在类中实现一些功能
  3. 将程序类型改成类库,输出路径为 PIEbin目录,解决方案平台x86。
  4. 在PIEApplication.xml文件中添加自己刚刚写的程序集的名称
  5. 打开PIE主程序,即PIEApplication.exe
组件式开发大致步骤
  • 搭建基本界面

    • menuStrip
    • toolStrip
    • SplitContaniner
    • tabControl(Alignment:Buttom)
  • 地图界面搭建

    • TOCControl(左边)
    • MapControl(右边地图模式)
    • LayoutControl(右边制图模式)
  • 三大控件的绑定

    • 第一步
      public Form1()
      {
          InitializeComponent();
          InitFrm();
      }
      private void InitFrm()
      {
          mapControl1.FocusMap = pageLayoutControl1.FocusMap;//绑定了mapControl和TocControl
          tocControl1.SetBuddyControl(pageLayoutControl1);//绑定了TocControl和图层树
      }
    

    Tip: SetBuddyControl函数最好绑定图层书与pageLayoutControl对象,绑定MapControl可能出现问题。

    • 第二步(解决切换难题)

      原理:不能让地图控件和制图控件同时激活;

      TabControl下的SelectedIndexChanged()写入判断代码:

          if (tabControl1.SelectedIndex == 0)
      {
              mapControl1.Activate();
              pageLayoutControl1.DeActivate();
              mapControl1.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll);
      }
          if (tabControl1.SelectedIndex == 1)
      {
              mapControl1.DeActivate();
              pageLayoutControl1.Activate();
              pageLayoutControl1.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll);
      }
    

    同时在初始话过程中只激活MapControl控件。

          private void InitFrm()
      {
          mapControl1.FocusMap = pageLayoutControl1.FocusMap;//绑定了mapControl和TocControl
          tocControl1.SetBuddyControl(pageLayoutControl1);//绑定了TocControl和图层树
          
          mapControl1.Activate();//不能使两个空间同时激活;
          pageLayoutControl1.DeActivate();
      }    
          
    

    官方博客对小白比较适用的:
    PIESDK技术博客
    PIESDK命令一览表
    完整搭建步骤见15,完整示例见链接里的百度网盘。

地图相关接口(未完成)

IMap
可以通过MapControl的FocusMap属性来获取图层的属性,返回值是一个结构体,里面存了一堆的string,如图
在这里插入图片描述

IActiveView
IMap定义了Map对象(图层)的数据管理监视功能,而IActiveView则定义了Map对象的数据显示功能。这个接口中经常用到的方法包括:

原型说明
void ZoomTo(IGeometry geometry)将视图平移到某集合对象的范围,参数为几何对象
void PartialRefresh(ViewDrawPhasetype dpType)刷新地图,参数为地图类型
IPoint ToMapPoint(System.Drawing.Point point)屏幕点转化为地图点,参数为屏幕点
System.Drawing.Point FromMapPoint(IPoint point)地图点转化为屏幕点,参数为地图点
属性描述
FullExtent获取或者设置地图全图范围
Extent获取或者设置地图视图范围

图层添加和删除的监视代码IActiveViewEvents

    private void FormMain_Load(object sender, EventArgs e)
    {
        IActiveViewEvents activeViewEvents = mapControlMain.ActiveView.FocusMap as IActiveViewEvents;
        activeViewEvents.OnLayerAdded += ActiveViewEvents_OnLayerAdded;//绑定
        activeViewEvents.OnLayerDeleted += ActiveViewEvents_OnLayerDeleted;
    }

关联函数:

/// <summary>
/// 图层删除事件
/// </summary>
/// <param name="layer"></param>
private void ActiveViewEvents_OnLayerDeleted(ILayer layer)
{
    string info = string.Format("{0}图层删除成功!", layer.Name);
    MessageBox.Show(info);
}

/// <summary>
/// 图层的添加事件
/// </summary>
/// <param name="layer"></param>
private void ActiveViewEvents_OnLayerAdded(ILayer layer)
{
    string info = string.Format("{0}图层添加成功!", layer.Name);
    MessageBox.Show(info);
}

Tip:为了保证监视始终进行,一般将监视命令写在初始化事件中。
ILayer
需要注意的是Layer对象本身没有装载数据,而仅仅是获得了数据的引用而已,是用于管理数据源的连接。在PIE中数据始终存放在文件中,新添加的图层也只是获得了地理数据的硬盘位置而已,而没有拥有数据。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BF9kEsOI-1596515492024)(./2020-07-26_152255.jpg)]
实现添加进的图层监控ILayerEvents

在添加数据按钮的地方写入监控的代码:

    private void ActiveViewEvents_OnLayerAdded(ILayer layer)
    {
        string info = string.Format("{0}图层添加成功!", layer.Name);
        MessageBox.Show(info);
        ILayerEvents ilayerEvents = layer as ILayerEvents;//写在这里面是因为每添加
        ilayerEvents.OnPropertyChanged += IlayerEvents_OnPropertyChanged;
        ilayerEvents.OnRenderChanged += IlayerEvents_OnRenderChanged;
        ilayerEvents.OnVisibilityChanged += IlayerEvents_OnVisibilityChanged;
    }

写入渲染按钮单机代码

    private void toolStripButton1_RGBRender_Click(object sender, EventArgs e)
    {
        ILayer layer = mapControlMain.GetLayer(0);
        //判断是否符合操作条件
        if (layer == null) return;
        if (layer.LayerType != LayerType.LayerTypeRasterLayer) return;
        //对渲染方式进行修改
        IRasterRGBRender rgbRender = new RasterRGBRender();//实例化对象
        /*rgbRender.UseBlueBand = true;//使用蓝光波段
        rgbRender.UseAlphaBand = true;//用透明波段
        rgbRender.RedBandIndex = 3;红光渲染索引号;*/
        rgbRender.SetBandIndices(3, 2, 1);//默认是1、2、3
        //把原来的渲染方式修改成实例化的渲染方式
        IRasterLayer rasterLayer = layer as IRasterLayer;
        rasterLayer.Render = rgbRender as IRasterRender;
        mapControlMain.PartialRefresh(ViewDrawPhaseType.ViewAll);
    }

关联事件

    private void IlayerEvents_OnRenderChanged(ILayer layer)
    {
        string render = (layer as IRasterLayer).Render.ToString().Trim();
        string info = string.Format("{0}图层渲染方式发生改变为{1}!", layer.Name,render);
        MessageBox.Show(info);
        if (layer.LayerType != LayerType.LayerTypeRasterLayer) return;
    }
数据相关接口

IFeatureDataset
是可以存储空间数据的对象类,它为FeatureLayer提供了数据支持, 它是一个空间实体的集合,这些实体就是要素,在一个要素数据集中,所有的要素都使用同样的字段结构。 IFeatureDataset接口是操作要素数据集时使用的主要接口,它定义了要素数据的读取、编辑、保存等规则。
IFeatureDataset中包含的类名

根据加载的Layer再获得FeatureData

IMap map =mapControlMain.FocusMap;
ILayer layer=mapControlMain.FocusMap;
IFeatureLayer fLayer=layer as IFeatureLayer;
IFeatureDataset fDataset =fLayer.FeatureClass.GetFeatureDataset();

反向: 根据FeatureDataset得到Layer

 ILayer layer = LayerFactory.CreateDefaultFeatureLayer(featureDataSet) as ILayer;

根据路径得到FeatureDataset

IFeatureDataset featureDataSet = DatasetFactory.OpenFeatureDataset(filePath);

GetNextFeature()获取下一个要素返回值为IFeature类型
IFeature接口
在这里插入图片描述
IFields接口

在这里插入图片描述
IFeature接口底下的方法

GetValue()可以传入索引或者字段名就可以实现读取操作
GetFields()读取当前要素的所有字段
GetFieldIndex可以将字段名转换成索引号
IField接口

IGeometry接口
实现空间数据的可视化,图形显示,是PIE空间分析和运算功能的基础。
在这里插入图片描述

结构表示

数据相关功能

矢量数据的读取

private void toolStripButton1_RenderRead_Click(object sender, EventArgs e)
        {
            //1、获取数据
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "shpFile|*.shp";
            if (openFileDialog.ShowDialog() != DialogResult.OK) return;
            string filePath = openFileDialog.FileName;

            //2、根据数据的到FeatureDataSet
            IFeatureDataset featureDataSet = DatasetFactory.OpenFeatureDataset(filePath);
            //3、根据字段获得字段索引
            IFields fields = featureDataSet.GetFields();
            int index = fields.GetFieldIndex("NAME");
            if (index == null) return;
            //4、根据字段索引遍历FeatureDataset,获取对应的Feature的字段值(value)
            IFeature feature = featureDataSet.GetNextFeature();
            string strValue = "";
            while (feature!=null)
            {
                strValue+=feature.GetValue(index).ToString()+"\r\n";
                feature = featureDataSet.GetNextFeature();
            }
            //5、信息显示:加载到视图并刷新
            MessageBox.Show(strValue, "省会城市的名字");
            ILayer layer = LayerFactory.CreateDefaultFeatureLayer(featureDataSet) as ILayer;
            mapControlMain_RenderRead.ActiveView.FocusMap.AddLayer(layer);
            mapControlMain_RenderRead.PartialRefresh(ViewDrawPhaseType.ViewAll);
            
        }

栅格数据的读取

  • 方式一 通过路径读取OpenRasterDataset(Path)
  • 方式二 通过RasterLayerDataset属性获取

IRasterDataset接口
在这里插入图片描述

  • FullName指全路径
  • GetRasterX\YSize()获取长宽
  • Read读操作
    bool Read(int nx, int ny, int nWid, int nHei, object pData, int nBufXSize, int nBufYSize, PixelDataType eBufType, int nBandCount, int[] pBandMap);
          //   nx:   栅格x坐标
          //   ny: 栅格y坐标
          //   nWid:读取的宽度
          //   nHei:读取的高度
          //   ptr:读取出的数据,要求必须是数组或指针
          //   nBufXSize: 目标宽度
          //   nBufYSize: 目标高度
          //   eBufType:读取类型
          //   nBandCount:波段数
          //   pBandMap:波段映射
          //   返回结果:  是否成功
    
  • Write写操作
    void WorldToPixel_Ex(double dblX, double dblY, ref double lCol, ref double lRow);
          //   nx: 栅格x坐标
          //   ny: 栅格y坐标
          //   nWid: 写入的宽度
          //   nHei:写入的高度
          //   pData:数据缓冲
          //   nBufXSize:缓冲宽度
          //   nBufYSize: 缓冲高度
          //   eBufType:写入类型
          //   nBandCount: 波段数
          //   pBandMap:波段映射
          //   返回结果: 是否成功
    
  • GetBandCount()得到波段书
  • GetRasterBand()通过索引获取波段
  • AddRasterBand()添加波段
  • PixelToWorld_Ex()像素坐标转地图坐标
  • WorldToPixel_Ex()世界坐标转像素坐标

栅格数据的读取代码:

private void toolStripButton1_RasterRead_Click(object sender, EventArgs e)
        {
            //1、栅格数据读取并转换为RasterDataset
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "RasterFile|*.tif;*.tiff;*.img";
            if (openFileDialog.ShowDialog() != DialogResult.OK) return;
            string filePath = openFileDialog.FileName;

            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.Filter = "RasterFile|*.tif;*.tiff;*.img";
            if (saveDialog.ShowDialog() != DialogResult.OK) return;

            ILayer layer = LayerFactory.CreateDefaultLayer(filePath);
            mapControlMain_RenderRead.ActiveView.FocusMap.AddLayer(layer);
            mapControlMain_RenderRead.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll);

            //方式一
            IRasterDataset rasterDataset = DatasetFactory.OpenRasterDataset(filePath, OpenMode.ReadOnly);
            if (rasterDataset == null) return;
            //方式二
            IRasterDataset rDataset = (layer as RasterLayer).Dataset;
            if (rasterDataset == null) return;
            //2、读取制定大小的RasterDataset
            int xSize = rasterDataset.GetRasterXSize();//栅格宽度
            int ySize = rasterDataset.GetRasterYSize();//栅格高度
            int bandcount = rasterDataset.GetBandCount();//波段数量
            PixelDataType type = rasterDataset.GetRasterBand(0).GetRasterDataType();//数据类型
            Byte[] arr = new byte[xSize * ySize * bandcount];//数据缓冲数组

            int[] listMap = new int[bandcount];//波段映射

            for(int i = 0; i < bandcount; i++)
            {
                listMap[i] = i + 1;
            }

            bool result = rasterDataset.Read(0, 0, xSize, ySize, arr, xSize, ySize, type, bandcount, listMap);
            if (result == false) return;

            //int a_height = 320;
            //int a_width = 330;
            //int x0 = 1440;
            //int y0 = 160;
            //3、创建新的栅格数据集
            IRasterDataset newDataset = DatasetFactory.CreateRasterDataset(saveDialog.FileName, xSize, ySize, bandcount, type, "GTiff", null);
            if (newDataset == null) return;
            result=newDataset.Write(0, 0, xSize, ySize, arr, xSize, ySize, type, bandcount, listMap);
            if (result == false) return;

            //4、设置新的栅格数据集的空间参考和放射六参数
            newDataset.SpatialReference = rasterDataset.SpatialReference;
            double[] geo = rasterDataset.GetGeoTransform();
            newDataset.SetGeoTransform(geo);
            //5、将读取的结果显示到地图中并刷新

            ILayer layer1 = LayerFactory.CreateDefaultRasterLayer(newDataset) as ILayer;
            mapControlMain_RenderRead.ActiveView.FocusMap.AddLayer(layer1);
            mapControlMain_RenderRead.PartialRefresh(ViewDrawPhaseType.ViewAll);
        }

Tips

  • 如果要裁剪图像那么在Read就要动手脚
  • 栅格坐标系从左上角开始
  • 空间参考的结构如图所示:

在这里插入图片描述

其中第0 3分别为x和y的坐标,2 4分别代表旋转角度,1 5分别为x和y方向的分辨率.

绘制几何图形 (这里写得不是很详细😅)
在这里插入图片描述

元素相关接口

IElement接口
在PIE中,可以显示在Map上的数据包括分为两大类,即地理数据和图形Element(元素) ,所有元素都实现了IElement接口, Element根据表现形式不同,可以分成不同的种类,所以IElement有众多的子类。
|在这里插入图片描述

IElement的众多子类

在这里插入图片描述

ISymbol
ISymbol定义了PIE中符号的表示, GIS中离散的实体分为点、线、面三种, PIE中使用三种类型的符号MarkerSymbol、 LineSymbol、FillSymbol表示,此外还有TextSymbol用于文字标注,同一种类型的渲染方式也是千变万化的,所以PIE根据
符号的类型和渲染特性分成了众多的符号。
在这里插入图片描述

例子

算法相关接口和类
在这里插入图片描述
架构图

ISystemAlgo接口:负责算法的实现

ISystemAlgoEvent接口:负责算法的监控
IsystemAlgo常用的属性有

    //
    // 摘要:
    //     描述
    string Description { get; set; }
    //
    // 摘要:
    //     名称
    string Name { get; set; }
    //
    // 摘要:
    //     参数
    object Params { get; set; }

    //
    // 摘要:
    //     执行算法
    //
    // 返回结果:
    //     是否执行成功
    bool Execute();

Execute()下填写算法的执行步骤,返回结果为bool型,true为执行成功、false为执行失败。

IsystemAlgoEvent为算法监控接口,其框架为

    //
    // 摘要:
    //     ISystemAlgoEvents系统算法事件接口
    public interface ISystemAlgoEvents
    {
        //
        // 摘要:
        //     执行完成事件
        event OnExecuteCompletedEventHandler OnExecuteCompleted;
        //
        // 摘要:
        //     进度变化事件
        event OnProgressChangedEventHandler OnProgressChanged;
    }

可以看出ISystemAlgoEvents有两种监控:

  1. 监控算法是否完成
  2. 监控算法的进程(可以调用进度体属性)

BaseSystemAlgo是一个类,用于自定义算法。他的出现是方便的定义新的算法,因为接口是需要实现接口的所有方法。而类不需要。一下是BaseSystemAlgo的原码框架:

    public class BaseSystemAlgo : ISystemAlgo, ISystemAlgoEvents
    {
    //.....
    }

可以看出来BaseSystemAlgo继承了ISystemAlgo, ISystemAlgoEvents的两个接口。
AlgoFactory:实现算法管理

已有算法的调用(以裁剪算法为例子)

插件式开发的算法都需要继承PIE.Framework.DesktopCommand
基本步骤

  • 算法创建

    • 参数设置(PIE的自带算法是带有参数子类的,声明一个参数类,给他赋值)

      DataPreImgClip_Exchange_Info info = new DataPreImgClip_Exchange_Info();
          info.InputFilePath = @"E:\PIE软件设计\2020 PIE-SDK二次开发组件包\PIE SDK NET 201906\02.样例数据\World\World.tif";
          info.OutputFilePath = @"E:\PIE软件设计\2020 PIE-SDK二次开发组件包\PIE SDK NET 201906\02.样例数据\World\China.tif";
          info.XStart = 1440;
          info.XEnd = 1770;
          info.YStart = 160;
          info.YEnd = 480;
      
          info.Type = 0;
          info.listBands = new List<int>() { 0, 1, 2 };
          info.FileType = "GTiff";
      
    • 算法创建

      
      ISystemAlgo algo = AlgoFactory.Instance().CreateAlgo("PIE.CommonAlgo.dll","PIE.CommonAlgo.ImageClipAlgo");
              if (algo == null) return;
      

      格式为:AlgoFactory.Instance().CreateAlgo(A,B)
      需要注意的是:
      A:程序集名称“PIE.CommonAlgo.dll”
      B:命名空间+类名“PIE.CommonAlgo.ISODataClassificationAlgo”
      最后把刚刚的参数类赋值给算法的参数子类。

  • 算法执行
    算法执行分两种:同步执行、异步执行。
    同步执行ExcuteAlgo、异步执行AsynExcuteAlgo
    通过SystemAlgo.AlgoFactory.Instance().AsynExcuteAlgo(algo)
    实现异步调用,也可通过ExcuteAlgo实现同步调用;
    已有算法的调用中:算法的执行就是算法监控事件,监控算法的,因为其实已有的算法,所以执行事件一般和创建写在同一个类里。

        ISystemAlgoEvents algoEvents = algo as ISystemAlgoEvents;
        algoEvents.OnExecuteCompleted += AlgoEvents_OnExecuteCompleted;
        algoEvents.OnProgressChanged += AlgoEvents_OnProgressChanged;
        PIE.AxControls.IStatusBar status = m_Application.StatusBar;
        status.ShowProgress(0, 100, "");
        Application.DoEvents();//处理在消息中的所有Windows信息;
        AlgoFactory.Instance().AsynExecuteAlgo(algo);
    

    另外还有写下两个关联函数:

    关联函数

    private int AlgoEvents_OnProgressChanged(double complete, string msg, ISystemAlgo algo)
        {
            PIE.AxControls.IStatusBar status = m_Application.StatusBar;
            status.UpdateProgress((int)complete, msg);
            return 0;
        }
        /// <summary>
        /// 算法的完成事件
        /// </summary>
        /// <param name="algo"></param>
        private void AlgoEvents_OnExecuteCompleted(ISystemAlgo algo)
        {
            DataPreImgClip_Exchange_Info info = (DataPreImgClip_Exchange_Info)algo.Params;
            ILayer layer = LayerFactory.CreateDefaultLayer(info.OutputFilePath);
            m_HookHelper.ActiveView.FocusMap.AddLayer(layer);
          
            ISystemAlgoEvents algoEvents = algo as ISystemAlgoEvents;
            algoEvents.OnExecuteCompleted -= AlgoEvents_OnExecuteCompleted;//解绑
            algoEvents.OnProgressChanged -= AlgoEvents_OnProgressChanged;//解绑
    
            PIE.AxControls.IStatusBar status = m_Application.StatusBar;
            status.UpdateProgress(100, "");
            status.HideProgress();
            status.UpdateProgress(0, "");
            m_HookHelper.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll);
        }
    

    为了避免不必要的麻烦务必在算法完成时对监控函数解绑。

所以对于已有算法的实现,相当于一个类中同时包含算法的声明(参数声明,和算法声明),算法监控,算法调用

新算法的构建(以图像复制粘贴算法为例)
在这里插入图片描述
算法构建的步骤如图所示

附上对应部分的代码:
新建算法的参数定义、算法定义、算法调用和监控是写在三个不同的类或结构体里的

参数定义

    public class AlgoParams
    {
        public string InputFile { get; set; }

        public string OutputFile { get; set; }

    }

在同一命名空间下写一个存放该算法参数的类;

算法定义

/// <summary>
    /// 自定义算法
    /// </summary>
    public class DemoAlgo:BaseSystemAlgo
    {
        private AlgoParams m_Params;
        /// <summary>
        /// 算法参数
        /// </summary>
        public override object Params
        {
            get
            {
                return m_Params;
            }
            set
            {
                m_Params = (AlgoParams)value;
            }
        }
        public override bool Execute()
        {
            System.IO.File.Copy(m_Params.InputFile,m_Params.OutputFile,true);
            return true;
        }
    }

定义算法需要继承BaseSystemAlgo

  • 定义参数字段,类型为刚刚创的参数类,重写Params方法。
  • 写构造函数(空就行)。
  • 写执行函数,具体而言就是你的算法想实现什么功能,记得返回值类型是是否执行成功。

调用算法

    public class CopyFileCommand : PIE.Framework.DesktopCommand
    {
        public CopyFileCommand()
        {

        }
        public override void OnClick()
        {
            //1、参数的设置
            AlgoParams info = new AlgoParams();
            info.InputFile = @"H:\Program Files (x86)\ENVI\IDL71\examples\data\boulder.tif";
            info.OutputFile = @"C:\Users\lenovo\Desktop\Copy.tif";
            //2、算法创建
            ISystemAlgo Algo = AlgoFactory.Instance().CreateAlgo("ImgProcess.dll", "ImgProcess.DemoAlgo");
            Algo.Params = info;
            if (Algo == null) return;
            bool result =AlgoFactory.Instance().ExecuteAlgo(Algo);
            //3、算法执行
            if (result)
            {
                System.Windows.Forms.MessageBox.Show("文件复制成功");
            }
        }

    }

调用算法的与已有算法调用写法一模一样:

  • 参数设置
  • 算法创建
  • 算法执行(执行就包括监控)

Attention:

  • 需要注意以上例子中的CopyFileCommand是写在xml文件的identity中的,表示按钮需要调用的文件名称
  • CreateAlgo("ImgProcess.dll", "ImgProcess.DemoAlgo");
    • 前一项是命名空间。
    • 后一项是算法文件即第二步定义的算法类的名称。
  1. 算法实现
  2. 普通函数的调用
  3. 作为算法的插件
  4. 修改配置,增加按钮
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值