使用Element对象模拟车辆动态行驶
2013-07-16 10:57
225 查看
ArcEngine中也提供了支持模拟车辆动态行驶的方法,其主要原理是:首先获取得到车辆行驶的路径IPolyline对象,通过IConstructGeometryCollection接口将IPolyline对象按指定大小拆分得到沿行驶路径分布的众多IPoint对象,主要获取每个IPoint对象的坐标信息,使用一个IMarkerElement对象来在地图上表示车辆,表示车辆的图片通过IPictureMarkerSymbol接口来设置,其位置则通过各个IPoint对象表示;或者也可以直接通过IPictureElement对象来设计,但是IPictureElement对象无法设定车头行驶方向。最后根据车辆行驶车速通过一个时间控件逐点按时不断刷新Element对象,达到模拟车辆动态行驶的效果。
其C#实现代码如下:
以上代码尚存在一个问题:车辆的文本标注与车辆图片之间的距离随地图的缩放而产生变化,目前还没有发现能够同时支持图片和文本的Element对象,如果有就很好解决了!MakeMultiPoint()函数将车辆行驶路径按1m的距离拆分,并从IPolyLine对象中得到IPointCollecntion对象,Timer控件响应时,首先删除上次标记,再添加本状态下的标记,保证每次响应时一条路径上只有一个标记代表车辆行驶。
其C#实现代码如下:
private void timer1_Tick(object sender, EventArgs e) { try { //清空所有标记 pGraphicsContainer.DeleteAllElements(); double pPointX = 0, pPointY = 0; IPoint pPoint = new PointClass(); IRgbColor pColor = new RgbColorClass(); IPictureMarkerSymbol pPictureMarkerSymbol = new PictureMarkerSymbolClass(); IMarkerElement pMarkerElement = new MarkerElementClass(); ITextElement pTextElement = new TextElementClass(); ITextSymbol pTextSymbol = new TextSymbolClass(); IEnvelope pEnvelop = axMainMap.ActiveView.Extent; foreach (IPointCollection pPointCol in pPointColList) { double pAngle = 0; //记录车头方向 //当前路径到达终点则保留终点位置标记 if (num > pPointCol.PointCount - 1) pPoint = pPointCol.get_Point(pPointCol.PointCount - 1); else { pPoint = pPointCol.get_Point(num++); //根据路径方向计算车头方向,单位为° if (num != 1) { IPoint pFoward = pPointCol.get_Point(num - 2); //记录行驶的前一结点 if (pFoward.X - pPoint.X == 0) pAngle = 90; else pAngle = Math.Atan((pFoward.Y - pPoint.Y) / (pFoward.X - pPoint.X))*60; } } //方法一:创建IPictureElement,支持图片同步缩放 //IPictureElement pPictureElement = new JpgPictureElementClass(); //pPictureElement.ImportPictureFromFile(".//...//func.jpg"); //pPictureElement.SavePictureInDocument = true; //pPictureElement.MaintainAspectRatio = false; //IElement pEle = pPictureElement as IElement; //创建Polygon对象 //IEnvelope pEnv = new EnvelopeClass(); //pEnv.PutCoords(pPoint.X - 10, pPoint.Y - 10, pPoint.X + 60, pPoint.Y + 40); //pEle.Geometry = (IGeometry)pEnv; //方法二:禁止图片同步缩小 pPictureMarkerSymbol.Size = 10; //设置位图透明颜色 pColor.Red = 255; pColor.Green = 255; pColor.Blue = 255; pPictureMarkerSymbol.BitmapTransparencyColor = pColor; pPictureMarkerSymbol.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap, strRootPath + "\\LtMonitor\\Car.bmp"); //设置x,y偏移量 pPictureMarkerSymbol.YOffset = 2; //设置车头方向 pPictureMarkerSymbol.Angle = pAngle; //设置标记位置 pMarkerElement.Symbol = pPictureMarkerSymbol; ((IElement)pMarkerElement).Geometry = pPoint; pGraphicsContainer.AddElement((IElement)pMarkerElement, 0); //加载车名称标记 pTextElement.Text = "汽车"; //设置文本标记大小 pTextSymbol.Size = 6; //设置字体颜色 pColor.Red = 255; pColor.Green = 0; pColor.Blue = 0; pTextSymbol.Color = pColor; pTextElement.Symbol = pTextSymbol; //用于计算视图范围 pPointX += pPoint.X; pPointY += pPoint.Y; //设置文本标记位置 pPoint.Y = pPoint.Y - 20; pPoint.X = pPoint.X + 5; ((IElement)pTextElement).Geometry = pPoint; //向Element容器中加载IElement对象 pGraphicsContainer.AddElement((IElement)pTextElement, 0); } //如果导航点超出视图范围,则将移动地图 if (pPointX / pPointColList.Count > pEnvelop.XMax - 50) { pPoint.X = pPointX / pPointColList.Count; pPoint.Y = pPointY / pPointColList.Count; pEnvelop.CenterAt(pPoint); axMainMap.Extent = pEnvelop; } //局部刷新 axMainMap.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null); } catch { } } //提取行驶路径的点信息,等距划分,距离为1米 private void MakeMultiPoint(IGeometry pGeometry, int nPoints, ref IPointCollection pGeoCol) { if (pGeometry.GeometryType == esriGeometryType.esriGeometryPolyline) { IGeometryCollection pGeometryCollection; IConstructGeometryCollection pCGeometryCollection = new GeometryBagClass(); //等距均分 //pCGeometryCollection.ConstructDivideEqual((IPolyline)pGeometry, nPoints - 1, esriConstructDivideEnum.esriDivideIntoPolylines); //以定值划分,0.001的单位为Km pCGeometryCollection.ConstructDivideLength((IPolyline)pGeometry,0.001,true,esriConstructDivideEnum.esriDivideIntoPolylines); IEnumGeometry pEnumGeometry = (IEnumGeometry)pCGeometryCollection; pGeometryCollection = new MultipointClass(); IPolyline pPolyline = (IPolyline)pEnumGeometry.Next(); object Missing = Type.Missing; //提取指定值划分后的点信息 pGeometryCollection.AddGeometry(pPolyline.FromPoint, ref Missing, ref Missing); while (pPolyline != null) { pGeometryCollection.AddGeometry(pPolyline.ToPoint, ref Missing, ref Missing); pPolyline = (IPolyline)pEnumGeometry.Next(); } pGeoCol = (IPointCollection)pGeometryCollection; } }
以上代码尚存在一个问题:车辆的文本标注与车辆图片之间的距离随地图的缩放而产生变化,目前还没有发现能够同时支持图片和文本的Element对象,如果有就很好解决了!MakeMultiPoint()函数将车辆行驶路径按1m的距离拆分,并从IPolyLine对象中得到IPointCollecntion对象,Timer控件响应时,首先删除上次标记,再添加本状态下的标记,保证每次响应时一条路径上只有一个标记代表车辆行驶。
相关文章推荐
- 使用Javascript动态增加,删除表格(使用W3C对象模型)
- 使用Unity制作的,模拟了Scene视图查看对象的效果——查看器
- 打破依赖,使用模拟对象,桩对象,隔离框架
- 使用动态分区分配方式的模拟
- 如何使用动态共享对象的模式来安装PHP
- 使用反射、泛型和委托,动态调用对象的属性和方法——性能和灵活性兼备的方法
- 使用lightProbe来模拟动态物体的照明shader
- 使用Javascript动态增加,删除表格(使用DHTML对象模型)
- 使用模拟对象(Mock Object)技术进行测试驱动开发
- 静态成员函数、this指针、对象指针和动态对象使用小结
- 使用反射-动态创建对象及调用对象方法
- log4j2 不使用配置文件,动态生成logger对象
- ajax 动态传递jsp等页面使用id辨识传递对象
- iframe高度/宽度自适应(使用body而不是docuemntElement对象)
- php使用变量动态创建类的对象用法示例
- IOS性能调优系列:使用Zombies动态分析内存中的僵尸对象
- 如何使用动态共享对象的模式来安装PHP
- javascript---使用createElement动态创建HTML对象
- 使用CRectTracker类进行对象动态定位(二)
- 使用JS模拟出Map对象