ArcGIS Engine三维动画开发 来自:http://www.iarcgis.com/?p=826

ArcGIS Engine 三维开发

来自:http://www.iarcgis.com/?p=826

在三维中,经常使用的一个功能就是播放动画,也就是我们要对一条动画轨迹进行播放,而在ArcGIS Engine中做3D开发的时候,轨迹有两个对应的对象

IAnimationTrack和IAGAnimationTrack

如果在帮助中仔细查看还会发现更多跟这两个类似的区别,一个接口比另一个接口多两个字母AG,

IAnimationTracks和IAGAnimationTracks,IKeyframe和IAGKeyframe。

我们看下这些的描述

IAGKeyframe:访问运动对象的关键帧(Provides access to keyframes of animated objects. )

IKeyframe:访问运动对象的关键帧(Provides access to keyframes of animated objects.)

从描述上看,没有任何区别,那么为什么会有两个这样的接口,带AG的出来的比较晚,而且位于ESRI.ArcGIS.Animation中,而不带AG的是早期的接口位于ESRI.ArcGIS.Analyst3D中,而且这些接口的属性和方法都很类似:

Ikeyframe

IAGKeyframe

1.1     原因何在

既然两个接口提供的方法和接口很类似,为什么会有两套这样的接口呢?原来带AG的是后来出现的,而且是在9.2的时候增加的,在9.2的时候增加了Animation等类库,看下面的描述:

Animation and AnimationUI—Contain objects to work with animations in ArcMap, ArcScene, or ArcGlobe. An animation in ArcMap, ArcScene, or ArcGlobe is composed of animation tracks (AGAnimationTracks), which are further composed of keyframes (AGAnimationKeyframes) of the same type. Each keyframe stores properties of the animation objects. When an animation is played, keyframes are interpolated, and the interpolated properties are then applied to the animated objects to create the dynamic visual effect.

在帮助中,我们可以看到更多的信息,首先看到实现IAGAnimationTrack的接口有两个类即AGAnimationTrack和AnimationTrack,也就是说凡是带了AG的接口很多都被早期的对象继承,如下:

AGAnimationTrack类只实现了IAGAnimationTrack接口,如下图:

而AnimationTrack类不仅仅实现了1AnimationTrack接口,还实现了 1AGAnimationTrack接口,如下图:

1.1     后出现的不一定就节省力气

1.1.1   关键帧创建

在创建关键帧的时候两者差别不大,除了创建的时候的参数不一样,其他几乎没有变化,下面为使用IKeyframe创建的:

   IKeyframe pKeyframe = new GlobeCameraKeyframeClass();
            pKeyframe.Name = "Key" + Convert.ToString(_AnimationTrack.KeyframeCount + 1);
            IScene pScene = globe.Globe as IScene;
            pKeyframe.CaptureProperties(pScene, globe.GlobeDisplay.ActiveViewer.Camera);
            _AnimationTrack.InsertKeyframe(pKeyframe, -1);

            for (int index = 0; index < _AnimationTrack.KeyframeCount; index++)
            {
                _AnimationTrack.get_Keyframe(index).TimeStamp = (double)index / (double)(_AnimationTrack.KeyframeCount - 1);
            }

下面为使用IAGKeyframe创建的:

 public static void InsertKeyfr(IGlobe pGlobe, string pTrackName)
       {
           IAGAnimationTracks pTracks = pGlobe as IAGAnimationTracks;
           IAGAnimationTrack _AnimationTrack = GetAGAnimationTrack(pTracks, pTrackName);
           if (_AnimationTrack == null)
           {
             _AnimationTrack = new AGAnimationTrackClass();
             _AnimationTrack.Name = pTrackName;

             pTracks.AddTrack(_AnimationTrack);

           }

           IAGAnimationTrackKeyframes pAGKyeFrames = _AnimationTrack as IAGAnimationTrackKeyframes;
           IAGKeyframe pKeyframe = new GlobeCameraKeyframeClass();
           pKeyframe.Name = "Capture" + Convert.ToString(pAGKyeFrames.KeyframeCount + 1);
          IScene pScene = pGlobe.GlobeDisplay.Scene; //还可以直接转换
          pKeyframe.CaptureProperties(pGlobe as IAGAnimationContainer, pGlobe.GlobeDisplay.ActiveViewer.Camera);
          (_AnimationTrack as IAGAnimationTrackKeyframes).InsertKeyframe(pKeyframe, -1);

          for (int index = 0; index < pAGKyeFrames.KeyframeCount; index++)
           {
               pAGKyeFrames.get_Keyframe(index).TimeStamp = (double)index / (double)(pAGKyeFrames.KeyframeCount - 1);
           }
           //更新窗体;
       }

1.1.1   关键帧获取

但是有的时候不带AG的比带了AG的方便,比如要获取一条轨迹的关键帧,使用IAnimationTrack接口的时候只需要下面两个步骤:

  • IAnimationTrack.KeyframeCount
  • IAnimationTrack.Keyframe

而IAGAnimationTrack接口则需要3个步骤:

  • IAGAnimationTrackKeyframes
  • IAGAnimationTrackKeyframes.KeyframeCount
  • IAGAnimationTrackKeyframes.Keyframe

1.1.2    播放动画

而在播放动画的饿时候使用IAnimationTracks,我们只需要用下面的步骤代码:

在播放的时候用下面的代码是可以实现动画播放的:

IAnimationTracks pTracks = globe.Globe as IAnimationTracks;
            for (int i = 0; i < pTracks.TrackCount; i++)
            {
               IAnimationTrack pTrack = pTracks.Tracks.get_Element(i) as IAnimationTrack;
               pTrack.IsEnabled = true;//设置为true 才可以播放这条轨迹
            }
               DateTime startTime = DateTime.Now;
               TimeSpan timeSpan;
               double elapsedTime;
               double duration = 10;
               bool play = true;
               do
               {
               		timeSpan = (DateTime.Now).Subtract(startTime);
               		elapsedTime = timeSpan.TotalSeconds;
                  if (elapsedTime > duration)
                  {
                      play = false;
                      elapsedTime = duration;
                   }
                  pTracks.ApplyTracks(globe.GlobeDisplay.ActiveViewer, elapsedTime, duration);
                  globe.GlobeDisplay.RefreshViewers();
               } while (play);

我们在前面说到了,带AG的接口提供的方法和属性和不带的非常类似,但下面的代码播放之后是不能实现动画播放的

 for (int i = 0; i < pTracks.TrackCount; i++)
           {
              IAGAnimationTrack pAnimationTrack = pTracks.AGTracks.get_Element(i) as IAGAnimationTrack;
              pAnimationTrack.IsEnabled = true;
           }
          DateTime startTime = DateTime.Now;
          TimeSpan timeSpan;
          double elapsedTime;
          double duration = 10;
          bool play = true;
          do
          {
              timeSpan = (DateTime.Now).Subtract(startTime);
              elapsedTime = timeSpan.TotalSeconds;
              if (elapsedTime > duration)
                {
                    play = false;
                    elapsedTime = duration;
                }
                pTracks.ApplyTracks(false, duration);
                this.globe.GlobeDisplay.RefreshViewers();
            } while (play);

如何才能播放呢,既然已经知道带AG的来自Animation库,那就应该在这个库中找,使用下面的接口:

如果对ArcGlobe的动画非常熟悉的朋友,应该知道这4个方法对应了播放工具上的四个操作,录制,破防。暂停和停止

private IAGAnimationEnvironment CreatAnimationEnvironment(IGlobe pGlobe)
        {
            DateTime startTime = DateTime.Now;

            Double playTimeInterval = 10;
                IBasicScene2 pBasicScene2 = pGlobe as IBasicScene2;
                _pAGAnimationEnvironment = pBasicScene2.AnimationExtension.AnimationEnvironment;
                _pAGAnimationEnvironment.IsIntervalPlay = true;
                _pAGAnimationEnvironment.PlayInAllViewers = true;
                _pAGAnimationEnvironment.PlayMode = esriAnimationPlayMode.esriAnimationPlayOnceForward;
                _pAGAnimationEnvironment.AnimationDuration = playTimeInterval;
                _pAGAnimationEnvironment.PlayType = esriAnimationPlayType.esriAnimationPlayTypeDuration;
                _pAGAnimationEnvironment.PlayTime = playTimeInterval;
                _pAGAnimationEnvironment.PutPlayInterval(0, playTimeInterval);//尤其关键,设置播放时间段。
                _pAGAnimationEnvironment.RestoreState = true;
                IArray pArr = new ArrayClass();

            return _pAGAnimationEnvironment;
        }

//List存放了我路径轨迹的名称
    private void PlayAnimaiton(IGlobe pGlobe)
        {
            IAGAnimationTracks pAGAnimationTracks = pGlobe as IAGAnimationTracks;
            IAGAnimationUtils pAGAnimationUtils = new AGAnimationUtilsClass();
            IAGAnimationPlayer pAGAnimaitonPlayer = pAGAnimationUtils as IAGAnimationPlayer;
            _pAGAnimationEnvironment = CreatAnimationEnvironment(pGlobe);
            List pList = new List();
            if (checkedListBoxtracks.SelectedItems.Count > 0)
            {
                for (int j = 0; j < checkedListBoxtracks.CheckedItems.Count; j++)
                {
                    pList.Add(checkedListBoxtracks.CheckedItems[j].ToString());
                }
            }
            for (int i = 0; i < pAGAnimationTracks.TrackCount; i++)
            {
                IAGAnimationTrack pT=pAGAnimationTracks.AGTracks.get_Element(i) as IAGAnimationTrack;

                if (pList.Contains(pT.Name))
                {
                    pT.IsEnabled = true;
                }
                else
                {
                    pT.IsEnabled = false;
                }
            }

                pAGAnimaitonPlayer.PlayAnimation(pAGAnimationTracks, _pAGAnimationEnvironment, null);
            //pAGAnimationUtils.SaveAnimationFile(pAGAnimationTracks.AnimationObjectContainer, "C:\\test.asa", ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersion93);
        }

1.3 但后出现的比较灵活
在使用不带AG的播放动画是,播放结束后,是不能回到原来的状态,但是后者却可以,还有就是在播放的时候,前者是不能停止和暂停(除非播放结束或系统出现问题),但是后者却可以,还有就是后者提供了录制的功能,而前者没有。同时,后者在播放的时候,只要将播放环境接口IAGAnimationEnvironment中的信息设置OK后,就不用自己去写while循环用来判断时间。在创建关键帧的时候,我们往往都是创建路径,然后将帧插入到路径中,但是后者有有个默认的路径,下面的代码就是向默认的路径中捕获当前的视图,也就是ArcGlobe中的那个照相机的功能:

  ESRI.ArcGIS.Animation.IAGAnimationUtils pAnimationUtils = new ESRI.ArcGIS.Animation.AGAnimationUtilsClass();
  ESRI.ArcGIS.Animation.IAGAnimationTracks pAnimationTracks = (ESRI.ArcGIS.Animation.IAGAnimationTracks)globe;
  ESRI.ArcGIS.Analyst3D.IBasicScene2 pBasicScene2 = (ESRI.ArcGIS.Analyst3D.IBasicScene2)globe;
  ESRI.ArcGIS.Animation.IAGAnimationEnvironment pAnimationEnvironment = pBasicScene2.AnimationExtension.AnimationEnvironment;
  pAnimationUtils.CaptureCurrentView(pAnimationTracks, pAnimationEnvironment);

作者

刘宇

时间: 2024-10-17 00:04:21

ArcGIS Engine三维动画开发 来自:http://www.iarcgis.com/?p=826的相关文章

《ArcGIS Engine+C#实例开发教程》第八讲 属性数据表的查询显示

原文:<ArcGIS Engine+C#实例开发教程>第八讲 属性数据表的查询显示 第一讲 桌面GIS应用程序框架的建立 第二讲 菜单的添加及其实现 第三讲 MapControl与PageLayoutControl同步 第四讲 状态栏信息的添加与实现 第五讲 鹰眼的实现 第六讲 右键菜单添加与实现 教程Bug及优化方案1 第七讲 图层符号选择器的实现1 第七讲 图层符号选择器的实现2 第八讲 属性数据表的查询显示 摘要:这一讲中,我们将实现图层属性数据表的查询显示.在ArcMap中,单击图层右

《ArcGIS Engine+C#实例开发教程》第三讲 MapControl与PageLayoutControl同步

原文:<ArcGIS Engine+C#实例开发教程>第三讲 MapControl与PageLayoutControl同步 摘要:在ArcMap中,能够很方面地进行MapView和LayoutView两种视图的切换,而且二者之间的数据是同步显示的.关于两种视图同步的实现方法有多种,可以使用ObjectCopy对象进行数据硬拷贝,而比较简单的方法莫过于二者共享一份地图了,这也是最常用的方法.  教程目录: 第一讲 桌面GIS应用程序框架的建立 第二讲 菜单的添加及其实现 第三讲 MapContr

《ArcGIS Engine+C#实例开发教程》第四讲 状态栏信息的添加与实现

原文:<ArcGIS Engine+C#实例开发教程>第四讲 状态栏信息的添加与实现 摘要:在上一讲中,我们完成了 MapControl 和PageLayoutControl两种视图的同步工作,本讲我们将完成状态栏信息的添加与实现.应用程序的状态栏一般用来显示程序的当前状态,当前所使用的工具. GIS应用程序一般也在状态栏显示当前光标的坐标.比例尺等信息.学习完本讲内容,您将学会状态栏编程的基本方法,并且能够在我们的程序的状态栏中添加且显示以下信息:当前所用工具信息.当前比例尺.当前坐标.  

《ArcGIS Engine+C#实例开发教程》第五讲 鹰眼的实现

原文:<ArcGIS Engine+C#实例开发教程>第五讲 鹰眼的实现 摘要:所谓的鹰眼,就是一个缩略地图,上面有一个矩形框,矩形框区域就是当前显示的地图区域,拖动矩形框可以改变当前地图显示的位置,改变矩形框的大小,可以改变当前地图的显示区域大小,从起到导航的作用.鹰眼是地图浏览中常用的功能之一.关于鹰眼的实现方式,最常用的是用一个 MapControl控件显示地图全图,并在上面画一个红色矩形框表示当前地图的显示范围,并实现鹰眼 MapControl 与主窗体的 MapControl 互动.

《ArcGIS Engine+C#实例开发教程》第七讲 图层符号选择器的实现

原文:<ArcGIS Engine+C#实例开发教程>第七讲 图层符号选择器的实现 摘要:我们要实现的是图层符号选择器,与ArcMap中的Symbol Selector的类似.本讲较前几讲而言,些许有些复杂,不过只要仔细琢磨,认真操作,你就很容易实现如下所示的符号选择器.  教程目录: 第一讲 桌面GIS应用程序框架的建立 第二讲 菜单的添加及其实现 第三讲 MapControl与PageLayoutControl同步 第四讲 状态栏信息的添加与实现 第五讲 鹰眼的实现 第六讲 右键菜单添加与

ArcGIS Engine二次开发——计算shapefile面图层要素的面积

前几天,有个同事问我怎么计算面图层的面积,我也是好久没做AE的事情了,简单的查了查,告诉他用IArea接口.到了下午,他的这个问题依旧没有解决,继续求助于我.我百度了下,没有找到相应的文章,于是我意识到这个简单的事情,可能对于很多接触AE不深的人,真的是非常难得事情.最难的可能是不知道怎么做,就像我的同事一样.我很快就告诉他用IArea接口,他却惊讶的问我"你怎么知道的?",并说他也是查到"似乎是用这个接口",当然这是第一个层次的,属于还没入门,刚刚开始接触AE,所

ArcGIS Engine开发前基础知识(4)

ArcGIS不同开发方式的比较 关于GIS应用软件的开发,通常有三种方式:C/S架构.网络GIS和移动GIS.ArcGIS平台提供了对三种开发方式的支持,对于采用从C/S架构的大多数开发者来讲,首先想到的是ArcGIS Engine进行开发.实际上,并不是所有的系统都必须采用这种方式,上述的三种开发方式(VBA.DLL和Add-in)在很多的时候也可以考虑. 作为VB的子集,VBA方式采用Visual Basic语言规范,简单易学,开发者只需要关注自己需要而ArcGIS没有直接提供的功能.对于广

利用ArcGIS Engine、VS .NET和Windows控件开发GIS应用

原文:利用ArcGIS Engine.VS .NET和Windows控件开发GIS应用 此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署应用的方法和步骤. 你可以在下面的目录下找到相应的样例程序: <安装目录>\DeveloperKit\Samples\Developer_Guide_Scenarios\ ArcGIS_Engine\Building_an_ArcGIS_Control_Application\Map_Viewer 注:ArcGIS样

ArcGIS Engine开发前基础知识(1)

ArcGIS二次开发是当前gis领域的一项重要必不可少的技能.下面介绍它的基本功能 一.ArcGIS Engine功能 在使用之前首先安装和部署arcgis sdk,(在这里不在赘述相关知识)可以实现的功能主要有地图的基本操作.信息查询.专题地图制作.数据编辑.网络分析.空间统计分析.三维分析等. 1.地图的基本操作 地图的基本操作主要包括加载矢量.栅格数据,浏览缩放地图,保存地图,在地图上显示文本注记,绘制点线面几何体等. 2.信息查询 信息查询主要通过矩形圆形或多边形来选中地图上的要素,或者