zoukankan      html  css  js  c++  java
  • 如何用Delphi进行ArcObjects的应用开发

     

    如何用Delphi进行ArcObjects的应用开发

       

    一、 ArcObjects简介
    软件重用是业界追求的目标,人们一直希望能够像搭积木一样随意地装配应用程序;组件对象就充当了积木的角色。所谓组件对象,实际上就是预先定义好的、能完成一定功能的服务或接口。Microsoft's Component Object Model (组件对象模型,简称COM)是组件对象之间互相接口的规范。凡是遵循COM接口规范的对象彼此之间能相互通信和交互,即使这些对象是由不同的厂商用不同的语言编写,在不同的Windows版本甚至在不同的机器上建立。 

    ArcObjectsESRI公司提供的一套基于COM技术的组件库。ArcGIS(tm) 软件家族中的ArcMap(tm)ArcCatalog(tm)and ArcScene(tm)应用程序就是由ArcObjects构建而成的。COM本质上仍然是客户/服务器模式,如A”所示,客户(通常是应用程序)请求创建COM对象并通过COM对象的接口操纵COM对象,服务器根据客户的请求创建并管理COM对象。COM是个二进制规范,它与源代码无关,我们可以使用任何支持COM的编程语言(如Visual BasicVisual C++Delpi等)做ArcObjects的应用开发。不过,目前的ArcObjects不是独立的SDK,所以要用ArcObjects开发独立的应用系统,必须要在已装有ArcInfo(tm)ArcEditor(tm)  ArcView(tm)的环境下进行,以获取软件使用的许可。

    二、 Delphi编程环境下ArcObjects的开发过程
    由于随机带的ArcObjects开发帮助手册(ArcObjects Developer Help)以及ESRI
    公司主页上的ArcScripts里提供的大部分编程指导和例程都是用Visual BasicVisual C++编写的,为了让习惯于用Delphi工作的程序员们能方便地使用ArcObjects 进行独立的应用开发,下面我们用Delphi 5 + ArcObjects来构造一个简单的GIS应用程序作为示例,以供参考。这个应用程序会实现一些如:图形数据的加载,地图的放大、缩小、漫游、全景显示及在地图上添加点状图形标记的功能。

    说明:如过以前已做过第一、二步的工作可以跳过,直接从 第三步入手。
    第一步:引入ArcObjects 类型库文件
    使用Delphi 5.0“Project | Import Type Library……”菜单项打开“Import Type Library”对话框,从其类型库文件列表框中找到“ESRI Object Library Version 1.0,即为“%ARCHOME%\bin\esriCore.olb”文件。接下来操作需要注意,这时在“Class Name”列表里罗列了所有esriCore.olb实现类的类名,由于其中的部分类名与DelphiVCL组件库里定义的类名有重复,为了避免产生冲突,建议把上述列表里罗列的所有类名由原来的以“T”开头改为以“Tesri” 开头,最后按“Create Unit”,这样在“Unit dir name”编辑栏处指定的目录里会生成一个名为“esriCore_TLB.pas”的该类型库的Object Pascal外套文件,从中可以看出该类型库中的所有GUID常量、类型、接口和CoClass组件类。

    第二步:引入ArcObjects 地图控件
    使用“Component | Import ActiveX Control……”菜单项打开“Import ActiveX”对话框,从其ActiveX控件列表框中找到“ESRI ArcObjects Controls 8.1Version1.0并按“Install……”按钮,然后一路确认。这样在Palette控件面板的ActiveX页面上就会出现一个“TMapControl”类型的ActiveX控件。

    第三步:功能实现
    1 . 准备工作
    先使用“File | New Application……”菜单项建立一个新的工程,然后选中Palette控件面板的ActiveX页面上  “MapControl”控件,用鼠标拖放到新建工程的窗体上,MapControlName属性设为MapControlAlign属性设为alClient ShowScrollbars属性设为False。最后在unit1单元interface部分的uses字句后添加上对“esriCore_TLB”的引用,这很关键,否则编译器找不到相关的InterfaceCoClass的声明。2. MapControl控件上加载图层
    这里介绍使用的是shapefile格式的数据。给Form1窗体添加一个加载shapefile文件的全局方法AddShpLayer,实现代码如下:
    function TForm1.AddShpLayer(FilePath,FileName: String): String;
    var
      pWFactory: IWorkspaceFactory;
      pPropertySet: IPropertySet;
      pWorkspace: IWorkspace;
      pFWorkspace: IFeatureWorkspace;
      pFClass: IFeatureClass;
      pFLayer: IFeatureLayer;
    begin
      try
        pWFactory := CoShapefileWorkspaceFactory.Create as IWorkspaceFactory;
        pPropertySet := CoPropertySet.Create as IPropertySet;
        pPropertySet.SetProperty('DATABASE',FilePath);
        pWFactory.Open(pPropertySet,self.Handle,pWorkspace);
        pFWorkspace := pWorkspace as IFeatureWorkspace;
        Delete(FileName,Length(FileName)-3,4);
        pFWorkspace.OpenFeatureClass(FileName,pFClass);
        pFLayer := coFeatureLayer.Create as IFeatureLayer;
        pFLayer.Set_FeatureClass(pFClass);
        pFLayer.Set_Name(FileName);
        MapControl1.AddLayer(pFLayer);
        result := FileName;
      except
       on E: Exception do result := '';
      end;
    end;

    然后在窗体Form1OnCreate事件里加入以下的代码:
    AddShpLayer('D:\GISData\','STATES.shp')
    这时按F9运行程序(此前确保D:\GISData\STATES.shp图层文件存在,即至少包括D:\GISData\STATES.shpD:\GISData\STATES.shxD:\GISData\STATES.dbf三个文件),就会发现STATES图层已经加入到了Mapcontrol控件里。

    3. 地图的放大、缩小、漫游和全景显示
    Mapcontrol控件的onMouseDown事件里加入以下的代码:
    procedure TForm1.MapControlMouseDown(Sender: TObject; button, shift, x,
      y: Integer; mapX, mapY: Double);
    var
      envlp: IEnvelope;
      bIsEmpty: wordbool;
    begin
      //Mapcontrol上按下鼠标左键后做拉框操作,实现地图放大功能
      if (Button = 1) and (Shift = 0) then 
      begin
        MapControl.MousePointer := esriPointerZoomIn;
        envlp := MapControl.TrackRectangle;
        envlp.Get_IsEmpty(bIsEmpty);
        if not bIsEmpty then
          MapControl.Extent := envlp
        exit
      end;
      //按下Shift键的同时在Mapcontrol上按下鼠标左键在做点击操作,实现地图缩小功能
      if (Button = 1) and (Shift = 1) then 
      begin
        MapControl.MousePointer := esriPointerZoomOut;
        envlp := MapControl.Extent;
        envlp.Expand(2,2,False);
        MapControl.Extent := envlp;
        exit;
      end;
      //Mapcontrol上按下鼠标右键键后做拖动操作,实现地图漫游功能
      if (Button = 2) and (Shift = 0) then 
      begin
        MapControl.MousePointer := esriPointerPanning;
        MapControl.Pan;
        MapControl.MousePointer := esriPointerPan;
        exit;
      end;
    end;

    Mapcontrol控件的OnDoubleClick事件里加入以下的代码:
    procedure TForm1.MapControl1DoubleClick(Sender: TObject; button, shift, x,
      y: Integer; mapX, mapY: Double);
    begin
        // Mapcontrol上双击,实现地图全景显示功能
        MapControl1.Extent := MapControl1.FullExtent;
    end;

    4. 地图上添加点状图形标记的功能
    先声明两个窗体Form1的私有变量:
        F_MultiPoint: IMultiPoint;
        F_Pts: IPointCollection;
    再在窗体Form1OnCreate事件里加入以下的代码:
        F_MultiPoint := CoMultiPoint.Create as IMultiPoint;
        F_Pts := F_MultiPoint as IPointCollection;
    然后给Form1窗体添加一个的用于添加点状图形标记的全局的方法DrawPoint
    实现代码如下:
    procedure TForm1.DrawPoint;
    var
      pt_cnt,i: integer;
      sym: ICharacterMarkerSymbol;
      pt: IPoint;
      ft: TFont;
      oleft: variant;
      ScreenDisplay: IScreenDisplay;
    ActiveView: IActiveView;
    begin
      ActiveView := MapControl.ActiveView;
      ActiveView.Get_ScreenDisplay(ScreenDisplay);
      F_Pts.Get_PointCount(pt_cnt);
      if pt_cnt > 0 then
      begin
        ScreenDisplay.StartDrawing(0,0);
        for i := 0 to pt_cnt-1 do
        begin
          F_Pts.Get_Point(i,pt);
          sym := coCharacterMarkerSymbol.Create as ICharacterMarkerSymbol;
          sym.Set_Size(30);
          ft := TFont.Create;
          ft.Size := 40;
          ft.Name := 'Wingdings';
          oleft := FontToOleFont(ft);
          sym.Set_Font(IFontDisp(IDispatch(oleft)));
          sym.Set_CharacterIndex(i+33);
          ScreenDisplay.SetSymbol(sym as ISymbol);
          ScreenDisplay.DrawPoint(pt);
        end;
        ScreenDisplay.FinishDrawing;
      end;
    end;

    然后在Mapcontrol控件的onMouseDown事件里加入以下的代码:
      //按下Shift键的同时在Mapcontrol上按下鼠标右键在做点击操作,
      //实现在地图上添加点状图形标记的功能
      if (Button = 2) and (Shift = 1) then 
      begin
        pt := mapcontrol1.ToMapPoint(x,y);
        F_Pts.AddPoint(pt,EmptyParam,EmptyParam);
        DrawPoint;
        exit;
      end;
    最后,在Mapcontrol控件的OnAfterDraw事件里加入以下的代码:
      procedure TForm1.MapControlAfterDraw(Sender: TObject; const
    display: IDisplay; phase: TOleEnum);
      begin
        DrawPoint; //用于刷新添加在地图上的点状图形标
      end;
    这样,一个包含了一些简单的GIS功能的应用程序就完成了(按F9可以运行)。

    三、 结束语
    希望以上的这个小例程能给习惯于用Delphi工作的ArcObjects程序开发者一点启发,从而开发出各种强大的GIS应用系统来。

  • 相关阅读:
    【BZOJ2138】stone
    【ARC076F】 Exhausted
    [SDOI2018]战略游戏
    CF536D Tavas in Kansas
    [JSOI2018]战争
    ###学习《C++ Primer》- 5
    ###学习《C++ Primer》- 4
    ###Linux基础
    ###Linux基础
    ###Linux基础
  • 原文地址:https://www.cnblogs.com/heavyhe/p/4547278.html
Copyright © 2011-2022 走看看