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);

作者

刘宇

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

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

    原文:<ArcGIS Engine+C#实例开发教程>第七讲 图层符号选择器的实现2 摘要:在第七讲 图层符号选择器的实现的第一阶段中,我们完成了符号选择器窗体的创建与调用.在第二阶段中, ...

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

    原文:<ArcGIS Engine+C#实例开发教程>第八讲 属性数据表的查询显示 第一讲 桌面GIS应用程序框架的建立 第二讲 菜单的添加及其实现 第三讲 MapControl与Page ...

  3. 《ArcGIS Engine+C#实例开发教程》第六讲 右键菜单添加与实现

    原文:<ArcGIS Engine+C#实例开发教程>第六讲 右键菜单添加与实现 摘要:在这一讲中,大家将实现TOCControl控件和主地图控件的右键菜单.在AE开发中,右键菜单有两种实 ...

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

    原文:<ArcGIS Engine+C#实例开发教程>第四讲 状态栏信息的添加与实现 摘要:在上一讲中,我们完成了 MapControl 和PageLayoutControl两种视图的同步 ...

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

    原文:<ArcGIS Engine+C#实例开发教程>第五讲 鹰眼的实现 摘要:所谓的鹰眼,就是一个缩略地图,上面有一个矩形框,矩形框区域就是当前显示的地图区域,拖动矩形框可以改变当前地图 ...

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

    原文:<ArcGIS Engine+C#实例开发教程>第三讲 MapControl与PageLayoutControl同步 摘要:在ArcMap中,能够很方面地进行MapView和Layo ...

  7. 《ArcGIS Engine+C#实例开发教程》第二讲 菜单的添加及其实现

    原文:<ArcGIS Engine+C#实例开发教程>第二讲 菜单的添加及其实现 摘要:在上一讲中,我们实现了应用程序基本框架,其中有个小错误,在此先跟大家说明下.在“属性”选项卡中,我们 ...

  8. 《ArcGIS Engine+C#实例开发教程》

    原文:<ArcGIS Engine+C#实例开发教程> 摘要:<ArcGIS Engine+C#实例开发教程>,面向 ArcGIS Engine(以下简称AE)开发初学者,本教 ...

  9. 《ArcGIS Engine+C#实例开发教程》第一讲桌面GIS应用程序框架的建立

    原文:<ArcGIS Engine+C#实例开发教程>第一讲桌面GIS应用程序框架的建立 摘要:本讲主要是使用MapControl.PageLayoutControl.ToolbarCon ...

随机推荐

  1. html5shiv.js让吃屎的IE6、IE7、IE8支持html5去吧

    插件介绍 用于解决IE9以下版本浏览器对HTML5新增标签不识别,并导致CSS不起作用的问题.所以我们在使用过程中,想要让低版本的浏览器,即IE9以下的浏览器支持,那么这款html5shiv.js是一 ...

  2. python基础一 day6 序列操作集合

    列表删除:pop([index])有返回值 remove('元素‘)没有返回值 按元素删,元素是什么,就写什么,是数字就写数字,不要加引号,加引号就变成字符串了,没有就报错. 字典删除:pop( ’键 ...

  3. 【转】密码学 :CSP的概念

    转:[密码学]CSP的概念 CSP加密服务提供者(Cryptographic Service Provider)具有一下几个特点: CSP是真正执行密码运算的独立模块 物理上一个CSP由两部分组成:一 ...

  4. STL || HDU 1894 String Compare

    如果一个词包含再另一个词的前面(前缀),是一对前缀,求一共有多少对 *解法:STL万岁 #include<string>:https://www.cnblogs.com/SZxiaochu ...

  5. kubeadm1.14.1 安装Metrics Server

    Metrics API 介绍Metrics-Server之前,必须要提一下Metrics API的概念 Metrics API相比于之前的监控采集方式(hepaster)是一种新的思路,官方希望核心指 ...

  6. 解决 【xshell 5 不能使用退格键和Delete建】的问题

    ###按照图片操作即可 1,打开[文件],选择[打开]选项 2.在会话中,打开[属性] 3.点击左边[终端]下的[键盘]选项,按照如下设置 即可.

  7. webpack 之 loader

    loader简介 loader在webpack.config.js中进行配置,配置之后,会自动检测打包过程中引入的文件(import或require),通过test成功匹配被引入的文件名后,会对文件内 ...

  8. Verilog仿真事件队列

    1.分层的事件队列 2.执行事件的队列 3.仿真时间的计算 4.同一层事件,无先后顺序 这个点:觉得Verilog与systemVerilog比较,Verilog比较笼统,systemVerilog则 ...

  9. Mysql 锁总结

    锁 部分总结参考博客 http://b.codejs.cc/articles/2017/10/23/1508749325215.html http://blog.csdn.net/cug_jiang1 ...

  10. 杭电 1069 Monkey and Banana

    Description A group of researchers are designing an experiment to test the IQ of a monkey. They will ...