利用动态图层实现数据的实时显示(arcEngine IDynamiclayer)
marine 原文利用动态图层实现数据的实时显示(arcEngine IDynamiclayer)
说明:最近一个项目用到这方面知识,文章主要来至网络,后期会加入自己的开发心得。(以下的代码实例中,地图开样子是采用ADF开发)
1 前言
不刷新地图而能让数据实时显示,这在ArcGIS中已经不在是一个困扰我们的难题,在ArcGIS Engine的开发过程中,每一次更新数据后都需要刷新才能,更改大量数据并不断的刷新,让用户在静静的等待,这不是很痛苦吗?为此ArcGIS提供了一个动态图层,专门用于解决这样问题。
ArcGIS 显示子系统管理着要素的显示和刷新,异步刷新显示和大量数据的渲染使得CPU的利用率增大,这可能导致显示延迟等问题.我们看一下ArcGIS 显示子系统的结构图,从这张图我们更能清楚的看到ArcGIS的显示原理:
动态显示技术将渲染大量的数据从CPU端移动到了显卡上,利用了显卡的性能,这明显提高了显示性能.动态显示技术提供同步显示机制使得大量的动态数据以及高频率刷新的操作可以在瞬间完成。
2 动态图层介绍
动态图层是一个自定义图层,因此至少应该继承ILayer,IDynamiclayer和IGeoDataset这三个接口,好在Esri提供了一个BaseDynamicLayer这个抽象类,该接口已经继承了我们所说的相关接口,因此我们只需要在实现动态图层的时候继承该类就行.
3 和动态显示相关的接口
在了解了动态显示原理之后,我们看下ArcGIS Engine为动态显示,提供了那些接口,以下是主要的相关接口:
l IDynamicMap—该接口提供Enable属性用来控制动态显示是否可用,这个接口和我们地图是一一对应的.但我们要使用动态图层的时候,必须用该接口开启动态显示功能,也就是Enable属性设置为true。
l IDynamicLayer—该接口和Ialyer以及IGeoDataset接口写作完成动态显示,也就是符号的绘制等,此接口提供了自定义图层动态显示内容的机制
l IDynamicScreenDisplay—该接口控制是否启用动态显示
l IDynamicGlyph—这个接口用来处理资源,这些资源可以是线,点,文本,这些资源作为符号将被动显示。
l IDynamicGlyphFactory—该接口用来管理动态符号,用此接口可以创建,删除动态符号,这些符号就是我们上面所提到的IDynamicGlyph的内容
l IDynamicSymbolProperties—该接口用来管理显示符号的大小,比例尺,颜色等.
l IDynamicDisplay— IDynamicDisplay提供了在地图上描绘几何图形的绘图机制,并且提供了访问动态符号工厂对象.在地图上绘制不同的几何图形,该接口和IDynamicSymbolProperties接口协同,使用IDynamicSymbolProperties来设置的动态符号,然后使用IDynamicDisplay绘制形状。IDynamicDisplay接口其实是下面几何绘图回调函数的参数IDynamicLayer.DrawDynamicLayer; IDynamicMapEvents.BeforeDynamicDraw; IDynamicMapEvents.AfterDynamicDraw.
4 动态绘制模式
动态图层有两种绘制模式,如下:
- · 重写 IDynamicLayer.DrawDynamicLayer方法
- · 通过动态地图的事件:
IDynamicMapEvents.BeforeDynamicDraw
IDynamicMapEvents.AfterDynamicDraw
5 绘图选择
·使用动态显示API
·使用OPengl API
6 绘制动态图层
动态图层,有两种不同的绘图方式,因此有两个绘图阶段 :立即阶段和编译阶段。在每一个阶段,每产生一组新的绘制命令,DrawDynamicLayer方法需要遍历图层的底层数据结构,并为每个项目生成相应的绘图命令,在编译阶段的绘图命令被编译成内部专用的一个清单列表。
每一个绘图周期内,动态地图检查每个动态层的状态。如果一个动态层需要重新绘制(动态图层需要重新生成新的绘图命令),动态地图根据相应的绘图阶段调用动态层的DrawDynamicLayer方法,为动态层将产生一套新的绘图命令。如果有多于一个需要重新生成绘图命令的动态图层,则整个动态显示需要重新绘制。
动态图层是主动显示方式,也就是说他有一个固定的绘图周期,在每一个绘图周期内,都会检查动态图层的ditry 属性,如果有一个动态图层是dity的,那么都会在所有的动态图层上绘制。动态图层主要有以下两个阶段:
Immediate—不存储绘图命令. 如果它报告其当前的阶段是脏,在这种情况下,绘制命令,将立即执行
Compiled—在一个清单中存储绘图命令. 动态显示将使用这个清单列表绘图,当dity 改变了这个清单列表就重新创建。在编译阶段,如果它报告编译阶段是脏的并且它重新编译的速度间隔已经过去了,当这连个条件同时满足的时候,将重新编译显示列表和动态层的绘图命令。
动态图层绘制需要实现下面的方法和熟悉:
DrawDynamicLayer |
在一个给定的阶段向具体的设备绘制图层. |
指示动态图层从上一个指定的绘制阶段是否发生改变 |
|
重新编译速率是在编译阶段调用绘图方法的时间间隔。 |
当重新绘制的时候,动态显示遍历动态图层并按照下面的步骤:
通过检查立即阶段的DynamicLayerDirty以重新编译是否需要,如果任何一个动态图层在理解阶段设置了ditry标志,所有的动态图层都会在立即阶段调用DrawDynamicLayer方法
在立即阶段直接调用DrawDynamicLayer方法
通过检查编译阶段的DynamicLayerDirty和DynamicRecompileRate属性确定编译是不是需要
如果需要的话,在编译阶段通过调用DrawDynamicLayer方法重新编译这个图层
在编译阶段通过显示裂变绘图
7 使用动态图层
动态图层是一个自定义的图层,当我们定义了这个动态图层之后,他就和一个普通的图层一样,需要添加到一个地图中,然后我们就可以在上面绘制符号和图形等,要使用一个动态图层,按下面的步骤就可以完成:
1开启动态显示功能;
2 创建自定义的动态图层并重写相关的绘图方法(上面提到的第一种方式);
3在Map中添加自定义的动态图层;
4 实时数据的传递.
7.1 开启动态地图功能
void InitMap()
{
IAGSServerObjectName pServerObjectName = GetMapServer("http://services.arcgisonline.com/ArcGIS/services", "ESRI_Imagery_World_2D", false);
IName pName = (IName)pServerObjectName;
IAGSServerObject pServerObject = (IAGSServerObject)pName.Open();
IMapServer pMapServer = (IMapServer)pServerObject;
ESRI.ArcGIS.Carto.IMapServerLayer pMapServerLayer = new ESRI.ArcGIS.Carto.MapServerLayerClass();
pMapServerLayer.ServerConnect(pServerObjectName, pMapServer.DefaultMapName);
axMapControl1.AddLayer(pMapServerLayer as ILayer);
axMapControl1.Refresh();
pActvie = axMapControl1.Map as IActiveView;
IDynamicMap pDynamicMap = pActvie.FocusMap as IDynamicMap;
pDynamicMap.DynamicMapEnabled = true;
pDynamicMap.DynamicDrawRate = ;
}
7.2 重写DrawDynamicLayer
定义自定义的动态图层并重写DrawDynamicLayer方法。
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Timers;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.ADF.Connection.Local;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.SystemUI;
namespace QARFlight
{
public sealed class FlightDynamicLayer : BaseDynamicLayer
{
public bool m_bOnce = true;
private IDynamicGlyph m_myGlyph = null;
IDynamicGlyph m_lineGlyph = null;
private IDynamicSymbolProperties2 m_dynamicSymbolProps = null;
private IDynamicSymbolProperties2 m_ldynamicSymbolProps = null;
private IPoint m_point = null;
private Timer m_updateTimer = null;
public double Course;
public FlightDynamicLayer()
: base()
{
base.m_sName = "My Dynamic layer";
m_updateTimer = new Timer();
m_updateTimer.Enabled = false;
m_updateTimer.Elapsed += new ElapsedEventHandler(OnTimerElapsed);
}
public void Draw(IPoint pPoint)
{
this.m_point = pPoint;
}
IPointCollection pPointCollection;
///
///更新飞机的位置和姿态
///
///
///
///
public void Update(double x, double y, double Course)
{
if (this.m_point == null)
{
m_point = new PointClass();
pPointCollection = new PolylineClass() as IPointCollection;
}
this.m_point.X = x;
this.m_point.Y = y;
this.Course = Course;
pPointCollection.AddPoint(this.m_point);
}
///
///获取线的渲染符号
///
public ESRI.ArcGIS.Display.ISimpleLineSymbol GetSimpleLineSymbol(ESRI.ArcGIS.Display.IRgbColor rgbColor, System.Double inWidth, ESRI.ArcGIS.Display.esriSimpleLineStyle inStyle)
{
if (rgbColor == null)
{
return null;
}
ESRI.ArcGIS.Display.ISimpleLineSymbol simpleLineSymbol = new ESRI.ArcGIS.Display.SimpleLineSymbolClass();
simpleLineSymbol.Style = inStyle;
simpleLineSymbol.Color = rgbColor;
simpleLineSymbol.Width = inWidth;
return simpleLineSymbol;
}
public override void DrawDynamicLayer(esriDynamicDrawPhase DynamicDrawPhase, IDisplay Display, IDynamicDisplay DynamicDisplay)
{
if (DynamicDrawPhase != esriDynamicDrawPhase.esriDDPImmediate)
return;
if (!m_bValid || !m_visible)
return;
IEnvelope visibleExtent = Display.DisplayTransformation.FittedBounds;
IDynamicGlyphFactory dynamicGlyphFactory = null;
if (m_bOnce)
{
dynamicGlyphFactory = DynamicDisplay.DynamicGlyphFactory;
m_dynamicSymbolProps = DynamicDisplay as IDynamicSymbolProperties2;
m_ldynamicSymbolProps = DynamicDisplay as IDynamicSymbolProperties2;
IDynamicGlyphFactory2 dynamicGlyphFactory2 = dynamicGlyphFactory as IDynamicGlyphFactory2;
IPictureMarkerSymbol pPicture = new PictureMarkerSymbolClass();
if (this.Course < )
{
this.Course = Math.Abs(this.Course);
}
pPicture.Angle = Course;
pPicture.Size = ;
pPicture.BitmapTransparencyColor = ESRI.ArcGIS.ADF.Connection.Local.Converter.ToRGBColor(Color.FromArgb(, , )) as IColor;
pPicture.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap, @".\plane.bmp");
m_myGlyph = dynamicGlyphFactory.CreateDynamicGlyph(pPicture as ISymbol);
m_updateTimer.Enabled = true;
m_bOnce = false;
ISimpleLineSymbol pSimpleLineSym = GetSimpleLineSymbol(ESRI.ArcGIS.ADF.Connection.Local.Converter.ToRGBColor(Color.FromArgb(, , )) as IRgbColor, , esriSimpleLineStyle.esriSLSSolid);
m_lineGlyph = dynamicGlyphFactory.CreateDynamicGlyph((ISymbol)pSimpleLineSym);
}
m_dynamicSymbolProps.set_DynamicGlyph(esriDynamicSymbolType.esriDSymbolMarker, m_myGlyph);
m_dynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 1.0f);
m_dynamicSymbolProps.set_RotationAlignment(esriDynamicSymbolType.esriDSymbolMarker, esriDynamicSymbolRotationAlignment.esriDSRAScreen);
DynamicDisplay.DrawMarker(m_point);
if (pPointCollection.PointCount > )
{
m_ldynamicSymbolProps.set_DynamicGlyph(esriDynamicSymbolType.esriDSymbolLine, m_lineGlyph);
m_ldynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolLine, 1.0f, 1.0f);
DynamicDisplay.DrawPolyline(pPointCollection);
}
//绘制完毕
base.m_bIsImmediateDirty = false;
}
void OnTimerElapsed(object sender, ElapsedEventArgs e)
{
//确保下一个绘图周期
base.m_bIsImmediateDirty = true;
}
}
}
自定义动态图层
7.3 加载动态图层
FlightDynamicLayer pFlightLayer = new FlightDynamicLayer();
Global.MainForm.pActvie.FocusMap.AddLayer(pFlightLayer as ILayer);
7.4 动态绘制数据
pFlightLayer.Update(point.X, point.Y, Course);
public IAGSServerObjectName GetMapServer(string pHostOrUrl, string pServiceName, bool pIsLAN)
{
//设置连接属性
IPropertySet pPropertySet = new PropertySetClass();
if (pIsLAN)
pPropertySet.SetProperty("machine", pHostOrUrl);
else
pPropertySet.SetProperty("url", pHostOrUrl);
//打开连接
IAGSServerConnectionFactory pFactory = new AGSServerConnectionFactory();
IAGSEnumServerObjectName pServerObjectNames = pConnection.ServerObjectNames;
pServerObjectNames.Reset();
IAGSServerObjectName ServerObjectName = pServerObjectNames.Next();
while (ServerObjectName != null)
{
if ((ServerObjectName.Name.ToLower() == pServiceName.ToLower()) &&
(ServerObjectName.Type == "MapServer") )
{
break;
}
ServerObjectName = pServerObjectNames.Next();
}
//返回对象
return ServerObjectName;
}
pFlightLayer.Update(point.X, point.Y, Course);
public IAGSServerObjectName GetMapServer(string pHostOrUrl, string pServiceName, bool pIsLAN)
{
//设置连接属性
IPropertySet pPropertySet = new PropertySetClass();
if (pIsLAN)
pPropertySet.SetProperty("machine", pHostOrUrl);
else
pPropertySet.SetProperty("url", pHostOrUrl);
//打开连接
IAGSServerConnectionFactory pFactory = new AGSServerConnectionFactory();
IAGSEnumServerObjectName pServerObjectNames = pConnection.ServerObjectNames;
pServerObjectNames.Reset();
IAGSServerObjectName ServerObjectName = pServerObjectNames.Next();
while (ServerObjectName != null)
{
if ((ServerObjectName.Name.ToLower() == pServiceName.ToLower()) &&
(ServerObjectName.Type == "MapServer") )
{
break;
}
ServerObjectName = pServerObjectNames.Next();
}
//返回对象
return ServerObjectName;
}
利用动态图层实现数据的实时显示(arcEngine IDynamiclayer)的更多相关文章
- python ros 订阅imu数据,实时显示欧拉角
#!/usr/bin/env python # -*- coding: utf- -*- import rospy import math from sensor_msgs.msg import Im ...
- 基于STM32的脉搏心率检测仪(OLED可以实时显示脉冲波形)
—设计完整,功能可全部实现,有完整报告文档说明.程序以及pcb文件— 可作为:课程设计,STM32实践学习,电子制作等 设计所实现的功能: 利用STM32的AD采集功能实时采集心率传感器信号输出引脚输 ...
- 【转】ArcGIS Server 10.1 动态图层—更改风格
在 ArcGIS Server REST API中我们可以通过向Graphicslayer中添加临时图元的方法来完成对显示结果的渲染:如果仅仅是更改原有地图服务显示风格,在ArcGIS10.1下使用动 ...
- html页面下拉列表中动态添加后台数据(格式化数据,显示出数据的层次感)
html页面下拉列表中动态添加后台数据(格式化数据,显示出数据的层次感) 效果图: 运行原理和技术: 当页面加载完毕,利用jquery向后台发送ajax请求,去后台拼接<select>&l ...
- 关于ArcGIS动态图层空间内栅格数据,JS前端显示颜色不正确的解决方案
ArcGIS的动态空间,可承载Table,Shp,Raster等数据. 我们的需求是,每天客户有新的卫星数据,但是不同类型,有多波段Landsat卫星数据,有Modis数据等.不定期更新到共享文件夹, ...
- jquery+ajax 实现text框模糊搜索并可利用listbox实时显示模糊搜索列表结果
功能描述: text框中输入,text框下面的listbox中实时显示依据输入的内容进行模糊搜索的结果 js代码 $j(function() { $j("input[id='txtCos'] ...
- 实时显示数据 SignalR 及时消息提醒( 立即向其推送内容)
实时显示数据 SignalR 及时消息提醒( 立即向其推送内容) http://www.cnblogs.com/Leo_wl/p/5634910.html <!--Reference the ...
- 微信小程序(五) 利用模板动态加载数据
利用模板动态加载数据,其实是对上一节静态数据替换成动态数据:
- 利用Flume将MySQL表数据准实时抽取到HDFS
转自:http://blog.csdn.net/wzy0623/article/details/73650053 一.为什么要用到Flume 在以前搭建HAWQ数据仓库实验环境时,我使用Sqoop抽取 ...
随机推荐
- 第一个C#控制台程序
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Kinect开发 —— 基础知识
转自:http://www.cnblogs.com/yangecnu/archive/2012/04/02/KinectSDK_Application_Fundamentals_Part2.html ...
- [Angular] How to get Store state in ngrx Effect
For example, what you want to do is navgiate from current item to next or previous item. In your com ...
- VMware虚拟机XP系统安装
转载:http://jingyan.baidu.com/article/54b6b9c00e2f452d593b4762.html
- js08--函数1
函数当成类看当成匿名对象看,都是跟java吻合的,只有当成函数看(函数自己可以执行)跟java区别在这里. function fact(){} var F = fact ; 函数名是函数对象的地址,是 ...
- 26.event跨进程通信
以id创建事件 ] = "myevent"; HANDLE event = CreateEventA(NULL, FALSE, FALSE, name); 设置事件 SetEven ...
- 转一篇对EJB理解的文章
1. 我们不禁要问,什么是"服务集群"?什么是"企业级开发"? 既然说了EJB 是为了"服务集群"和"企业级开发",那么 ...
- BZOJ3626: [LNOI2014]LCA(树链剖分+线段树)
Description 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1.设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先.有q ...
- Django项目之Web端电商网站的实战开发(二)
说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家! 接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/8 ...
- 【Educational Codeforces Round 35 D】Inversion Counting
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 排列中交换任意两个数字. 排列的逆序对个数的奇偶性会发生变化. 翻转这个过程其实就是len/2对数字发生交换. 交换了偶数次的话,不 ...