您的位置:首页 > 其它

使用Element对象模拟车辆动态行驶

2013-07-16 10:57 225 查看
ArcEngine中也提供了支持模拟车辆动态行驶的方法,其主要原理是:首先获取得到车辆行驶的路径IPolyline对象,通过IConstructGeometryCollection接口将IPolyline对象按指定大小拆分得到沿行驶路径分布的众多IPoint对象,主要获取每个IPoint对象的坐标信息,使用一个IMarkerElement对象来在地图上表示车辆,表示车辆的图片通过IPictureMarkerSymbol接口来设置,其位置则通过各个IPoint对象表示;或者也可以直接通过IPictureElement对象来设计,但是IPictureElement对象无法设定车头行驶方向。最后根据车辆行驶车速通过一个时间控件逐点按时不断刷新Element对象,达到模拟车辆动态行驶的效果。

其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控件响应时,首先删除上次标记,再添加本状态下的标记,保证每次响应时一条路径上只有一个标记代表车辆行驶。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ArcEngine