ArcEngine动态追踪

年良骏
2023-12-01
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.MapControl;
using ESRI.ArcGIS.ToolbarControl;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Output;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesGDB;
namespace VehicleMove
{
    public partial class frmMain : Form
    {
        double dx = 116.315691;
        double dy = 39.991964;
        IActiveView pactiveview;
        public frmMain()
        {
            InitializeComponent();
            //
            timer1.Enabled = false;
            timer2.Enabled = false;
            timer3.Enabled = false;
            timer4.Enabled = false;
            timer5.Enabled = false;
            //
            this.axToolbarControl1.SetBuddyControl(this.axMapControl1);
            pactiveview = this.axMapControl1.ActiveView;
        }
        //方法1:缺点:有拖尾,除非每次刷新,但是刷新会出现不停闪烁   
        private void timer1_Tick(object sender, EventArgs e)
        {
            dx = dx + 0.001;
            dy = dy - 0.0001;
            MoveCar();
        }
        private void MoveCar()
        {
            //得到当前活动范围

            IActiveView pActiveView = axMapControl1.ActiveView;
            //开始画笔 
            pActiveView.ScreenDisplay.StartDrawing(pActiveView.ScreenDisplay.hDC, (short)esriScreenCache.esriNoScreenCache);
            IPoint ppoint;
            IGeometry pgeo;
            IPictureMarkerSymbol psymbol = new PictureMarkerSymbolClass();
            IRgbColor prgbcolor = new RgbColorClass();
            prgbcolor.Red = 0;
            prgbcolor.Green = 0;
            prgbcolor.Blue = 0;

            psymbol.BitmapTransparencyColor  = prgbcolor;
            psymbol.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap,@"E:\layers\2.bmp");
            psymbol.Size = 15;
            psymbol.Angle = 270;

            //ISimpleMarkerSymbol psimplesymbol = new SimpleMarkerSymbolClass();
            //psimplesymbol.Size = 10;
            //psimplesymbol.Color = (IColor)prgbcolor;

            ppoint = new PointClass();
            ppoint.PutCoords(dx,dy);
            pgeo = ppoint;

            pActiveView.ScreenDisplay.SetSymbol((ISymbol)psymbol);
            pActiveView.ScreenDisplay.DrawPoint(ppoint);
            //结束画笔
            pActiveView.ScreenDisplay.UpdateWindow();
            pActiveView.ScreenDisplay.FinishDrawing();
            //System.Object obj = psymbol;
            //this.axMapControl1.DrawShape(pgeo, ref obj);
         
            //this.axMapControl1.CenterAt(ppoint);
            IEnvelope penv = this.axMapControl1.Extent;
            penv.CenterAt(ppoint);
            this.axMapControl1.Extent = penv;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            this.timer1.Enabled = true;
            this.timer1.Interval = 1000;   
        }


        //方法2:用element实现移动
        private IElement pelement, pelement1, pelement2;
        //第一种,文字图元,需要找到能够代表汽车的字体,并用上去才好
        private void DrawTextElement(IPoint pPoint)
        {
            IGraphicsContainer pGraphicsContainer;
            pGraphicsContainer = (IGraphicsContainer)(this.axMapControl1.ActiveView);

            pGraphicsContainer.DeleteAllElements();

            ITextElement ptextelement = new TextElementClass();
            ptextelement.Text = "0";
            pelement = (IElement)ptextelement;
            ptextelement.ScaleText = true;

            pelement.Geometry = pPoint;
            IFormattedTextSymbol ptextsymbol = new TextSymbolClass();
            下面三句是文字显示的背景框,去掉就单独显示文字了
            //ICallout pcallout = new BalloonCalloutClass();
            //ptextsymbol.Background = (ITextBackground)pcallout;
            //pcallout.AnchorPoint = pPoint;
            ptextsymbol.Font.Size = 15;
            ptextelement.Symbol = ptextsymbol;

            pGraphicsContainer.AddElement(pelement, 0);
            pelement.Activate(this.axMapControl1.ActiveView.ScreenDisplay);
          
            pactiveview.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pelement, null);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextelement);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextsymbol);
            return ;
        }
        private void MoveTextElement(IPoint pPoint)
        {
            如果有文字背景框,需要把背景框的锚点设置好
            //ITextElement ptextelement = (ITextElement)pelement;
            //ITextSymbol ptextsym =  ptextelement.Symbol;

            //IFormattedTextSymbol ptextsymbol = (IFormattedTextSymbol)ptextsym;
            //ICallout pcallout = (ICallout)(ptextsymbol.Background);
            //pcallout.AnchorPoint = pPoint;
            

            pelement.Geometry = pPoint;
            IGraphicsContainer pGraphicsContainer;
            pGraphicsContainer = (IGraphicsContainer)(this.axMapControl1.ActiveView);
            pGraphicsContainer.UpdateElement(pelement);
            this.axMapControl1.CenterAt(pPoint);
           // pactiveview.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pelement, null);
            //pelement.Activate(this.axMapControl1.ActiveView.ScreenDisplay);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextelement);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextsymbol);
            return ;
        }
        private void timer2_Tick(object sender, EventArgs e)
        {
            dx = dx + 0.001;
            dy = dy - 0.0001;
            IPoint pp = new PointClass();
            pp.PutCoords(dx, dy);
            MoveTextElement(pp);
        }
        private void button2_Click(object sender, EventArgs e)
        {   
            IPoint pp = new PointClass();
            pp.PutCoords(dx, dy);
            DrawTextElement(pp);
            timer2.Enabled = true;
            timer2.Interval = 1000;
        }
        //第二种,位图图片的图元:ppictureelement
        private void DrawPictureElement(IPoint pPoint)
        {
            IGraphicsContainer pGraphicsContainer;
            pGraphicsContainer = (IGraphicsContainer)(this.axMapControl1.ActiveView);
            pGraphicsContainer.Reset();
            //pGraphicsContainer.DeleteAllElements();

            IPictureElement ppictureelement = new BmpPictureElementClass();
            ppictureelement.ImportPictureFromFile(@"e:\layers\1.bmp");
            ppictureelement.MaintainAspectRatio = false;


            pelement1 = (IElement)ppictureelement;
            //IEnvelope pEnv = new EnvelopeClass();
            //pEnv.PutCoords(pPoint.X - 10, pPoint.Y - 10, pPoint.X + 60, pPoint.Y + 40);
            //pEle.Geometry = (IGeometry)pEnv;
            ITopologicalOperator pTopo = pPoint as ITopologicalOperator;
            IGeometry pBuffer = pTopo.Buffer(0.005);//建立4个地图单位的缓冲区
            IGeometry pGeometry = pBuffer.Envelope;//确定鼠标周围隐藏的选择框

            pelement1.Geometry = pGeometry;

            pGraphicsContainer.AddElement(pelement1, 0);
            pelement.Activate(this.axMapControl1.ActiveView.ScreenDisplay);

            pactiveview.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pelement1, null);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextelement);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextsymbol);
            return;
        }
        private void MovePictureElement(IPoint pPoint)
        {
            ITopologicalOperator pTopo = pPoint as ITopologicalOperator;
            IGeometry pBuffer = pTopo.Buffer(0.002);//建立4个地图单位的缓冲区
            IGeometry pGeometry = pBuffer.Envelope;//确定鼠标周围隐藏的选择
            pelement1.Geometry = pGeometry;

            IGraphicsContainer pGraphicsContainer;
            pGraphicsContainer = (IGraphicsContainer)(this.axMapControl1.ActiveView);
            pGraphicsContainer.UpdateElement(pelement1);
            this.axMapControl1.CenterAt(pPoint);
            // pactiveview.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pelement, null);
            //pelement.Activate(this.axMapControl1.ActiveView.ScreenDisplay);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextelement);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextsymbol);
            return;
        }
        private void timer3_Tick(object sender, EventArgs e)
        {
            dx = dx + 0.001;
            dy = dy - 0.0001;
            IPoint pp = new PointClass();
            pp.PutCoords(dx, dy);
            MovePictureElement(pp);
        }
        private void button3_Click(object sender, EventArgs e)
        {
            IPoint pp = new PointClass();
            pp.PutCoords(dx, dy);
            DrawPictureElement(pp);
            timer3.Enabled = true;
            timer3.Interval = 1000;
        }
        //第三种,点图元的形式,pmarkerelement
        private void DrawMarkerElement(IPoint pPoint)
        {
            IGraphicsContainer pGraphicsContainer;
            pGraphicsContainer = (IGraphicsContainer)(this.axMapControl1.ActiveView);
            pGraphicsContainer.Reset();
            //pGraphicsContainer.DeleteAllElements();

            IMarkerElement pmarkerelement = new MarkerElementClass();
            pelement2 = (IElement)pmarkerelement;
            IGeometry pGeometry = pPoint;
            pelement2.Geometry = pGeometry;

            IPictureMarkerSymbol ppicmarksymbol = new PictureMarkerSymbolClass();
            //IRgbColor prgbcolor = new RgbColorClass();
            //prgbcolor.Red = 255;
            //prgbcolor.Green = 255;
            //prgbcolor.Blue = 255;
            //ppicmarksymbol.BitmapTransparencyColor = prgbcolor;
            ppicmarksymbol.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap,@"e:\layers\2.bmp");
            ppicmarksymbol.Size = 20;
            //0-360度,逆时针转动
            ppicmarksymbol.Angle = 270;
            pmarkerelement.Symbol = ppicmarksymbol;


            pGraphicsContainer.AddElement(pelement2, 0);
            pelement2.Activate(this.axMapControl1.ActiveView.ScreenDisplay);

            pactiveview.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pelement2, null);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextelement);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextsymbol);
            return;
        }
        private void MoveMarkerElement(IPoint pPoint)
        {

            pelement2.Geometry = pPoint;

            IGraphicsContainer pGraphicsContainer;
            pGraphicsContainer = (IGraphicsContainer)(this.axMapControl1.ActiveView);
            pGraphicsContainer.UpdateElement(pelement2);
            this.axMapControl1.CenterAt(pPoint);
            // pactiveview.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pelement, null);
            //pelement.Activate(this.axMapControl1.ActiveView.ScreenDisplay);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextelement);
            //System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ptextsymbol);
            return;
        }
        private void timer4_Tick(object sender, EventArgs e)
        {
            dx = dx + 0.001;
            dy = dy - 0.0001;
            IPoint pp = new PointClass();
            pp.PutCoords(dx, dy);
            MoveMarkerElement(pp);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            IPoint pp = new PointClass();
            pp.PutCoords(dx, dy);
            DrawMarkerElement(pp);
            timer4.Enabled = true;
            timer4.Interval = 1000;
        }
        //方法3,用内存图层,画点的方法
        //创建内存图层,比创建实体图层,效率要快要几倍:已经过测试,查找路径后者花费4500毫秒,内存图层花费780毫秒。
        //可独立运行程序(不知道为什么,有问题。),创建空图层,默认为北京54的经纬度坐标系,itype=0,表示点,1:线,2:面
        private IFeature pthisfeature;
        public IFeatureWorkspace CreateEmptyLayerInmemeory(string slayername, ESRI.ArcGIS.Geometry.ISpatialReference pspatialreference, int itype)
        {
            //打开工作空间
            const string strShapeFieldName = "SHAPE";
            IWorkspaceFactory pWSF = new InMemoryWorkspaceFactoryClass();
            ESRI.ArcGIS.Geodatabase.IWorkspaceName pworkspacename = pWSF.Create("", "MyWorkspace", null, 0);
            ESRI.ArcGIS.esriSystem.IName pname = (IName)pworkspacename;
            //ESRI.ArcGIS.Geodatabase.IWorkspace pworkspace =(IWorkspace)(pname.Open());
            IFeatureWorkspace pfeatureworkspace = (IFeatureWorkspace)(pname.Open());//;(IFeatureWorkspace)pworkspace;

            try
            {
                //IFeatureLayer player = null;
                //IFeatureClass pclass = null;
                //为esriFieldTypeGeometry类型的字段创建几何定义,包括类型和空间参照 
                IGeometryDef pGeoDef = new GeometryDefClass();     //The geometry definition for the field if IsGeometry is TRUE.
                IGeometryDefEdit pGeoDefEdit = (IGeometryDefEdit)pGeoDef;
                if (itype == 0)
                {
                    pGeoDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;
                }
                else
                {
                    if (itype == 1)
                    {
                        pGeoDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolyline;
                    }
                    else
                    {
                        pGeoDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolygon;
                    }
                }
                if (pspatialreference != null)
                {
                    pspatialreference.SetDomain(-180, 180, -90, 90);
                    pGeoDefEdit.SpatialReference_2 = pspatialreference;
                }
                else
                {
                    //pGeoDefEdit.SpatialReference_2 = new UnknownCoordinateSystemClass();
                    ISpatialReferenceFactory3 pspatialRefFac = new SpatialReferenceEnvironmentClass();
                    ISpatialReference pspatialRef = pspatialRefFac.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984);//esriSRGeoCS_Beijing1954
                    pspatialRef.SetDomain(-180, 180, -90, 90);
                    pGeoDefEdit.SpatialReference_2 = pspatialRef;
                }
                //设置字段集
                IFields pFields = new FieldsClass();
                IFieldsEdit pFieldsEdit = (IFieldsEdit)pFields;
                //设置字段
                IField pField = new FieldClass();
                IFieldEdit pFieldEdit = (IFieldEdit)pField;
                //for (int i = 0; i < PropertyFields.FieldCount; i++)//输入PropertyFields
                //{
                //    pFieldsEdit.AddField(PropertyFields.get_Field(i));
                //}
                //创建类型为几何类型的字段0
                pFieldEdit.Name_2 = strShapeFieldName;
                pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;//esriFieldTypeGeometry;
                pFieldEdit.GeometryDef_2 = pGeoDef;
                pFieldsEdit.AddField(pField);
                //添加其他的字段1:nodeid,2:x,3:y
                if (itype == 0)
                {
                    pField = new FieldClass();
                    pFieldEdit = (IFieldEdit)pField;
                    pFieldEdit.Name_2 = "ID";
                    pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
                    pFieldsEdit.AddField(pField);

                    pField = new FieldClass();
                    pFieldEdit = (IFieldEdit)pField;
                    pFieldEdit.Name_2 = "X";
                    pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
                    pFieldEdit.Precision_2 = 10;//数值长度
                    pFieldEdit.Scale_2 = 6;//小数点后保留位数
                    pFieldsEdit.AddField(pField);

                    pField = new FieldClass();
                    pFieldEdit = (IFieldEdit)pField;
                    pFieldEdit.Name_2 = "Y";
                    pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
                    pFieldEdit.Precision_2 = 10;//数值长度
                    pFieldEdit.Scale_2 = 6;//小数点后保留位数
                    pFieldsEdit.AddField(pField);

                    pField = new FieldClass();
                    pFieldEdit = (IFieldEdit)pField;
                    pFieldEdit.Name_2 = "NAME";
                    pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
                    pFieldEdit.Length_2 = 30;
                    pFieldsEdit.AddField(pField);
                    //添加标记字段,0表示既是起点也是终点,1表示只作起点,2表示只作终点
                    pField = new FieldClass();
                    pFieldEdit = (IFieldEdit)pField;
                    pFieldEdit.Name_2 = "flag";
                    pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
                    pFieldsEdit.AddField(pField);
                }
                else
                {
                    pField = new FieldClass();
                    pFieldEdit = (IFieldEdit)pField;
                    pFieldEdit.Name_2 = "ID";
                    pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
                    pFieldsEdit.AddField(pField);

                    pField = new FieldClass();
                    pFieldEdit = (IFieldEdit)pField;
                    pFieldEdit.Name_2 = "name";
                    pFieldEdit.Length_2 = 50;
                    pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
                    pFieldsEdit.AddField(pField);

                    pField = new FieldClass();
                    pFieldEdit = (IFieldEdit)pField;
                    pFieldEdit.Name_2 = "firstnode";
                    pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
                    pFieldsEdit.AddField(pField);

                    pField = new FieldClass();
                    pFieldEdit = (IFieldEdit)pField;
                    pFieldEdit.Name_2 = "endnode";
                    pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
                    pFieldsEdit.AddField(pField);

                    pField = new FieldClass();
                    pFieldEdit = (IFieldEdit)pField;
                    pFieldEdit.Name_2 = "shunxu";
                    pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
                    pFieldsEdit.AddField(pField);
                }
                //创建shapefile
                IFeatureClass pfclass = pfeatureworkspace.CreateFeatureClass(slayername, pFields, null, null, esriFeatureType.esriFTSimple, strShapeFieldName, "");//C#里 null 取代VB里的Nothing
                IDataset pdataset = (IDataset)pfclass;
                pdataset.BrowseName = slayername;
                //player = new FeatureLayerClass();
                //player.Name = slayername;
                //player.FeatureClass = pfclass;
            }
            catch (System.Exception ex)
            {

            }

            return pfeatureworkspace;
        }
        IFeatureClass pvehicleclass;
        IFeatureLayer pvehiclelayer;
        private void CreateVehicleFeature()
        {
            IFeatureWorkspace pvehicleworkspace = CreateEmptyLayerInmemeory("vehicle", null, 0);
            pvehicleclass= pvehicleworkspace.OpenFeatureClass("vehicle");
            pvehiclelayer = new FeatureLayerClass();
            pvehiclelayer.FeatureClass = pvehicleclass;
           // IFeature pfeature;
            IDataset pdataset = (IDataset)pvehiclelayer;
            IWorkspaceEdit pworkspaceedit = (IWorkspaceEdit)(pdataset.Workspace);
            pworkspaceedit.StartEditing(true);
            pworkspaceedit.StartEditOperation();
            pthisfeature = pvehicleclass.CreateFeature();
            IPoint ppoint = new PointClass();
            ppoint.PutCoords(dx,dy);
            pthisfeature.Shape = (IGeometry)ppoint;
            pthisfeature.Store();
            pworkspaceedit.StopEditOperation();
            pworkspaceedit.StopEditing(true);
            //add
            PointRender(pvehiclelayer);
            this.axMapControl1.AddLayer(pvehiclelayer);
        }
        public void PointRender(IFeatureLayer player)
        {
            IGeoFeatureLayer pgeolayer = (IGeoFeatureLayer)player;
            IFeatureRenderer pfeaturerender = pgeolayer.Renderer;
            IFeatureClass pfeatureclass = player.FeatureClass;
            ISimpleRenderer psimplerender = new SimpleRendererClass();
            psimplerender.Description = "简单渲染";
            psimplerender.Label = "ID";

            //ISimpleMarkerSymbol pMarkerSymbol;
            //ISymbol pSymbol;
            //IRgbColor pRgbColor;
            //pMarkerSymbol = new SimpleMarkerSymbol();
            //pMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;//esriSimpleMarkerStyle.esriSMSCircle;
            //pMarkerSymbol.Size = 8;
            //IRgbColor poutcolor = new RgbColorClass();
            //poutcolor.RGB = System.Drawing.Color.FromArgb(0, 0, 0).ToArgb();
            //pMarkerSymbol.OutlineColor = poutcolor;
            //pMarkerSymbol.OutlineSize = 1;
            //pMarkerSymbol.Outline = true;
            //pRgbColor = new RgbColor();
            //pRgbColor.RGB = System.Drawing.Color.FromArgb(0, 255, 0).ToArgb();
            //pMarkerSymbol.Color = pRgbColor;
            //pSymbol = (ISymbol)pMarkerSymbol;
            //pSymbol.ROP2 = esriRasterOpCode.esriROPCopyPen;//esriROPNotXOrPen;
            IPictureMarkerSymbol ppicmarksymbol = new PictureMarkerSymbolClass();
            ppicmarksymbol.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap, @"e:\layers\2.bmp");
            ppicmarksymbol.Size = 20;
            //0-360度,逆时针转动
            ppicmarksymbol.Angle = 270;

            psimplerender.Symbol = (ISymbol)ppicmarksymbol;
            pgeolayer.Renderer = (IFeatureRenderer)psimplerender;
            pactiveview.PartialRefresh(esriViewDrawPhase.esriViewGraphics, player, null);
        }
        private void UpdateVehicleLoc(double dx,double dy)
        {
            IFeatureCursor pfeaturecursor = pvehicleclass.Update(null, false);
            pthisfeature = pfeaturecursor.NextFeature();
            if (pthisfeature != null)
            {
                IDataset pdataset = (IDataset)pvehiclelayer;
                IWorkspaceEdit pworkspaceedit = (IWorkspaceEdit)(pdataset.Workspace);
                pworkspaceedit.StartEditing(true);
                pworkspaceedit.StartEditOperation();
                IPoint ppoint = new PointClass();
                ppoint.PutCoords(dx, dy);
                pthisfeature.Shape = (IGeometry)ppoint;
                pthisfeature.Store();
                pworkspaceedit.StopEditOperation();
                pworkspaceedit.StopEditing(true);
                this.axMapControl1.CenterAt(ppoint);
            }
            
        }

        private void timer5_Tick(object sender, EventArgs e)
        {
            dx = dx + 0.001;
            dy = dy - 0.0001;
            UpdateVehicleLoc(dx, dy);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            CreateVehicleFeature();
            timer5.Enabled = true;
            timer5.Interval = 1000;
        }
    }
}

转载于:https://www.cnblogs.com/dengshiwei/p/4258672.html

 类似资料: