• 地图数据和版式数据联动


    在ArcGIS二维中有数据视图和版式视图两种模式。两种视图可以切换显示。笔者在开始做Engine二次开发时,每次在数据和视图切换时,都拷贝数据,或者两个视图同事加载同一份数据。在切换时速度很慢,特别是数据量较大的时候。用户体验很差。

    但当仔细看ArcEngine自带的例子时,里面的例子中就有一个数据视图和版式视图数据同步的例子,我们可以参考ArcEngine提供的例子来写我们自己的同步代码。

    既然我们要做数据视图数据和版式视图数据的同步,我们首先要确定我们要同步那些信息,也就是公用哪些信息。两个视图模式公用的就是地图,也就是Layer的几何。不包含各各自的Element等信息。

    ArcGIS的二维地图数据的配置文件是Mxd文件,Mxd文件中存储着版式和数据视图所包含的信息。而且我们也要清楚版式视图是可以包含多个地图的,除了多个地图之外还包括对应的智能图饰,如指北针、图例、比例尺等。但只能一个地图时当前激活的,而当前激活的地图就是数据视图要显示的地图。首先我们打开一个Mxd文件。代码如下:

    View Code
    public override void OnClick()
            {
                base.OnClick();
                OpenFileDialog myOpenFileDialog = new OpenFileDialog();
                myOpenFileDialog.Filter = "Mxd文档|*.mxd";
                if (myOpenFileDialog.ShowDialog()!=true)
                {
                    return;
                }
                string myMxdFilePath = myOpenFileDialog.FileName;
                MapDocumentClass myMapDocument = new MapDocumentClass();
                myMapDocument.Open(myMxdFilePath,"");
                this._mapApplication.MapDocument = myMapDocument;
    
                this._mapApplication.MapControl.Refresh(esriViewDrawPhase.esriViewNone, null, null) ;
            }
    
    
    /// <summary>
            /// 地图文档对象
            /// </summary>
            public IMapDocument MapDocument
            {
                get { return this._mapDocument; }
                set
                {
                    this._mapDocument = value;
                    if (this._mapDocument != null)
                    {
                        this._controlsSynchronizer.PageLayoutControl.PageLayout = this._mapDocument.PageLayout;
                        List<IMap> myMapList = new List<IMap>();
                        for (int i = 0; i < this._mapDocument.MapCount; i++)
                        {
                            myMapList.Add(this._mapDocument.get_Map(i));
                        }
                        this._controlsSynchronizer.ReaplaceMaps(myMapList);
                        this.LayerTree.SetActiveView(this.ActiveView);
                    }
                }
            }
    
    
    /// <summary>
            /// 替换当前显示的地图
            /// </summary>
            /// <param name="pMap"></param>
            public void ReaplaceMaps(List<IMap> pMaps)
            {
                IMaps myMaps = new Maps();
                foreach (IMap myMap in pMaps)
                {
                    myMaps.Add(myMap);
                }
    
                MapActivePattern myActivePattern = this._activePattern;
    
                //只有当在PageLayoutControl被激活时,才能调用ReplaceMap方法。
                this.ActivatePageLayout();
                this.PageLayoutControl.PageLayout.ReplaceMaps(myMaps);
    
                //把map传递给mapControl
                this.MapControl.Map = this.PageLayoutControl.ActiveView.FocusMap;
    
                //保证一个处于激活状态
                if (myActivePattern == MapActivePattern.Map)
                {
                    this.ActivateMap();
                    this.MapControl.ActiveView.Refresh();
                }
                else
                {
                    this.ActivatePageLayout();
                    this.PageLayoutControl.ActiveView.Refresh();
                }
            }

    从上面的代码中,我们可以看到,打开一个地图文件,并保证两个视图地图数据同步需要三个步骤。
    1.打开Mxd文件,得到MapDocument对象。

    2.把读取到的地图对象中的版式对象PageLayout赋值给版式对象PageLayoutControl。

    3.第三步就是同步地图数据了。先从MapDocument中把地图对象都取出来,组成一个地图列表对象。然后调用PageLayout的ReplaceMaps函数替换当前版式中的地图,然后把当前版式数据中激活的地图赋给数据视图MapControl的Map。

    这样就保证了打开一个地图文件后,版式视图中激活的地图和数据视图展示的地图时一个对象,当我们对当前激活的地图有什么操作时,两者都可以响应。

    但有一点,数据视图和版式视图当前只能有一个被激活。所以一般我们在项目中都把数据视图UI和版式视图UI放在两个Tab页面中,当切换时分别调用二者的激活函数,代码如下:

    /// <summary>
            /// 激活map
            /// </summary>
            public void ActivateMap()
            {
                try
                {
                    if (this.PageLayoutControl.ActiveView.IsActive())
                    {
                        this.PageLayoutControl.ActiveView.Deactivate();
                        this.MapControl.ActiveView.Activate(this.MapControl.hWnd);
                    }
                    this._activePattern = MapActivePattern.Map;
                }
                catch (Exception ex)
                {
                    throw new Exception("激活地图模式错误。" + ex.Message);
                }
            }
    
    
    
            /// <summary>
            /// 激活版式视图
            /// </summary>
            public void ActivatePageLayout()
            {
                try
                {
                    if (this.MapControl.ActiveView.IsActive())
                    {
                        this.MapControl.ActiveView.Deactivate();
                        this.PageLayoutControl.ActiveView.Activate(this.PageLayoutControl.hWnd);
                    }
                    this._activePattern = MapActivePattern.PageLayout;
                     }
                catch (Exception ex)
                {
                    throw new Exception("激活版式模式错误。" + ex.Message);
                }
            }

    下面的代码是继承IMaps实现的Maps的代码,这个在PageLayout对象Replace函数会用到。Engine的例子代码中就有该类的定义。

    View Code
    // Copyright 2006 ESRI
    //
    // All rights reserved under the copyright laws of the United States
    // and applicable international laws, treaties, and conventions.
    //
    // You may freely redistribute and use this sample code, with or
    // without modification, provided you include the original copyright
    // notice and use restrictions.
    //
    // See use restrictions at /arcgis/developerkit/userestrictions.
    
    using System;
    using ESRI.ArcGIS.Carto;
    using System.Collections;
    
    
    namespace BM.AE.Engine
    {
      /// <summary>
      /// Implementation of interface IMaps which is eventually a collection of Maps
      /// </summary>
      public class Maps : IMaps, IDisposable
      {
        //class member - using internally an ArrayList to manage the Maps collection
        private ArrayList m_array = null;
    
        #region class constructor
        public Maps()
        {
          m_array = new ArrayList();
        }
        #endregion
    
        #region IDisposable Members
    
        /// <summary>
        /// Dispose the collection
        /// </summary>
        public void Dispose()
        {
          if (m_array != null)
          {
            m_array.Clear();
            m_array = null;
          }
        }
    
        #endregion
    
        #region IMaps Members
    
        /// <summary>
        /// Remove the Map at the given index
        /// </summary>
        /// <param name="Index"></param>
        public void RemoveAt(int Index)
        {
          if (Index > m_array.Count || Index < 0)
            throw new Exception("Maps::RemoveAt:\r\nIndex is out of range!");
    
          m_array.RemoveAt(Index);
        }
    
        /// <summary>
        /// Reset the Maps array
        /// </summary>
        public void Reset()
        {
          m_array.Clear();
        }
    
        /// <summary>
        /// Get the number of Maps in the collection
        /// </summary>
        public int Count
        {
          get
          {
            return m_array.Count;
          }
        }
    
        /// <summary>
        /// Return the Map at the given index
        /// </summary>
        /// <param name="Index"></param>
        /// <returns></returns>
        public IMap get_Item(int Index)
        {
          if (Index > m_array.Count || Index < 0)
            throw new Exception("Maps::get_Item:\r\nIndex is out of range!");
    
          return m_array[Index] as IMap;
        }
    
        /// <summary>
        /// Remove the instance of the given Map
        /// </summary>
        /// <param name="Map"></param>
        public void Remove(IMap Map)
        {
          m_array.Remove(Map);
        }
    
        /// <summary>
        /// Create a new Map, add it to the collection and return it to the caller
        /// </summary>
        /// <returns></returns>
        public IMap Create()
        {
          IMap newMap = new MapClass();
          m_array.Add(newMap);
    
          return newMap;
        }
    
        /// <summary>
        /// Add the given Map to the collection
        /// </summary>
        /// <param name="Map"></param>
        public void Add(IMap Map)
        {
          if (Map == null)
            throw new Exception("Maps::Add:\r\nNew Map is mot initialized!");
    
          m_array.Add(Map);
        }
    
        #endregion
      }
    }
  • 相关阅读:
    简单SSO(Single signon)的另类实现方式,钩子技术
    URL
    [恢]hdu 1287
    [恢]hdu 1220
    [恢]hdu 1015
    [恢]hdu 2095
    [恢]hdu 1862
    HDOJ 300!
    [恢]hdu 1029
    [恢]hdu 1016
  • 原文地址:https://www.cnblogs.com/xzbluemap/p/2848461.html
Copyright © 2020-2023  润新知