关于MapControl和PageLayout地图同步的问题

  按照ArcMap的处理方式,地图和制图是分两个页面的,他们之间通过共享同一个Map对象来实现地图同步,具体做法就是在PageLayoutControl的PageLayoutReplaced事件发生时,将当前的活动地图指派给MapControl,然后在二者之间实现切换,基本做法如下:

        private void PageLayoutEvents_OnPageLayoutReplaced(object newPageLayout)
        {
            m_MapControl.Map = m_PageLayoutControl.ActiveView.FocusMap;
            if (m_bIsMapCtrActive)
            {
                //当MapControl的Map对象被替换后,需要重新激活MapControl
                ActiveMapControl();
            }
            else
            {
                //当PageLayoutControl的PageLayout对象被替换后,需要重新激活PageLayoutControl
                ActivePageLayoutControl();
            }
        }
        public void ActiveMapControl()
        {
            try
            {
                m_PageLayoutControl.ActiveView.Deactivate();
                //if (!m_MapControl.ActiveView.IsActive())    //如果在激活状态下重复激活,程序会崩溃
                m_MapControl.ActiveView.Activate(m_MapControl.hWnd);    //会触发ActiveView的ContentsChanged事件

                m_bIsMapCtrActive = true;
            }
            catch (System.Exception )
            {
            }
        }

        public void ActivePageLayoutControl()
        {
            try
            {
                m_MapControl.ActiveView.Deactivate();
                m_PageLayoutControl.ActiveView.Activate(m_PageLayoutControl.hWnd);
                m_bIsMapCtrActive = false;
            }
            catch (System.Exception)
            {
            }
        }

  在PageLayoutControl加载Mxd文档后,会发生PageLayoutReplaced事件,在此时,将其ActiveMap指派给地图控件,但是这里会出现两问题,一是Pagelayout中的图例、比例尺等会与地图失去关联,也就是缩放地图或调整地图时,图例、比例尺等地图整饰要素不会自动更新;另一个问题就是从地图切换到PageLayout时,地图会发生闪烁和跳动,地图的刷新总是慢一拍。实际上,我们在AE携带的示例代码MapAndPageLayoutSynchApp中可以看到,里面并不是简单的把PageLayout的ActieMap赋给MapControl,而是通过Maps和ReplaceMaps来执行一次地图替换后再执行地图的赋值操作,ArcGIS的帮助文档里没有讲为什么要这么做,我们也搞不清楚问什么要这么做,但是仿照这样的方式进行处理,却可以解决Map和图例、比例尺等失去关联的问题。如下:

        private void PageLayoutEvents_OnPageLayoutReplaced(object newPageLayout)
        {
            //////////////////////////////////////////////////////////////////////////
            //仿照AE范例代码MapAndPageLayoutSynchApp中的示例,解决图例、指北针、比例尺
            //失去关联的问题
            m_MapControl.ActiveView.Deactivate();
            m_PageLayoutControl.ActiveView.Activate(m_PageLayoutControl.hWnd);
            IMaps pMaps = GetMaps(m_PageLayoutControl.PageLayout);
            m_PageLayoutControl.PageLayout.ReplaceMaps(pMaps);
            //////////////////////////////////////////////////////////////////////////
            m_MapControl.Map = m_PageLayoutControl.ActiveView.FocusMap;
            if (m_bIsMapCtrActive)
            {
                //当MapControl的Map对象被替换后,需要重新激活MapControl
                ActiveMapControl();
            }
            else
            {
                //当PageLayoutControl的PageLayout对象被替换后,需要重新激活PageLayoutControl
                ActivePageLayoutControl();
            }
        }
        private IMaps GetMaps(IPageLayout pPageLayout)
        {
            IMaps pMaps = new Maps();
            IGraphicsContainer pGraphicsContainer = pPageLayout as IGraphicsContainer;
            pGraphicsContainer.Reset();
            IElement pElement = pGraphicsContainer.Next();
            while (pElement != null)
            {
                if (pElement is IMapFrame)
                {
                    IMapFrame pMapFrame = pElement as IMapFrame;
                    pMaps.Add(pMapFrame.Map);
                }
                pElement = pGraphicsContainer.Next();
            }
            return pMaps;
        }

  对于第二个问题,ArcGIS的开发文档中,也没有做出任何说明和解释。但是按照上面的处理方式,我们在地图控件和制图控件之间切换时不停的对二者的ActiveView执行激活和反激活。因为Map在制图控件中只是PageLayout的一个成员,因此在切换到地图时,Map被激活了, 而对于PageLayout来说,此时它里面的要素应该都是被DeActived的,反过来,切换到PageLaout时,Map理应被激活,但是又因为MapControl的DeActived而失活,对于包含多个地图的PageLayout来说,很容易出现制图要素没有完全被激活的现象,于是就会出现视图闪烁问题。针对这个问题,我们可以在切换到PageLayout时对PageLayout中的所有要素全部执行一遍激活操作。实验发现,样做的确可以解决问题,并且不会有任何问题,下面是处理代码:

        public void ActivePageLayoutControl()
        {
            try
            {
                m_MapControl.ActiveView.Deactivate();
                m_PageLayoutControl.ActiveView.Activate(m_PageLayoutControl.hWnd);

                IGraphicsContainer pGraphicsContainer = m_PageLayoutControl.GraphicsContainer;
                pGraphicsContainer.Reset();
                IElement pElement = pGraphicsContainer.Next();
                IDisplay pDisplay = m_PageLayoutControl.ActiveView.ScreenDisplay as IDisplay;
                while (pElement != null)
                {
                    pElement.Activate(pDisplay);
                    pElement = pGraphicsContainer.Next();
                }
                m_bIsMapCtrActive = false;
            }
            catch (System.Exception)
            {
            }
        }

原文地址:http://blog.csdn.net/giselite/article/details/24239509

时间: 2024-08-01 10:45:10

关于MapControl和PageLayout地图同步的问题的相关文章

一款已上市MMO手游地图同步方案总结

1. 客户端地图格子的相关知识 在2.5D的MMO游戏里,角色是通过3D的方式渲染,2D的地图是通过2D的方式显示,所以在客户端一般会有三个坐标系: a) 3D坐标系:所有需要3D渲染的角色和光效,都以3D坐标系中定位. b) 2D坐标系:用来定位和绘制固定的2D地图元素,比如草皮.马路等. c) 3D坐标里的格子坐标系:用来实现打掩码.自动寻路和进行一些坐标配置(比如NPC和怪物初始的位置).使用格子坐标,一是为了方便打掩码和进行自动寻路的计算(经典的A*寻路),二是为了更方便查找坐标的具体位

ArcEngine - 地图和布局同步

1,定义同步的类: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Engine.App_Code { 7 public class ControlsSynchronizer { 8 #region private field. 9 private ESRI.ArcGIS.Controls.IMapControl3 mapCtrl

《ArcGIS Engine+C#实例开发教程》第三讲 MapControl与PageLayoutControl同步

原文:<ArcGIS Engine+C#实例开发教程>第三讲 MapControl与PageLayoutControl同步 摘要:在ArcMap中,能够很方面地进行MapView和LayoutView两种视图的切换,而且二者之间的数据是同步显示的.关于两种视图同步的实现方法有多种,可以使用ObjectCopy对象进行数据硬拷贝,而比较简单的方法莫过于二者共享一份地图了,这也是最常用的方法.  教程目录: 第一讲 桌面GIS应用程序框架的建立 第二讲 菜单的添加及其实现 第三讲 MapContr

map与pagelayout同步新方法

本文转自: http://hi.baidu.com/murphy1314/blog/item/3d3144f319b19dcf0a46e0a4.html 前天写的那个MapControl和Pagelayout同步用IMaps接口来实现,今天我却又发现了一种更简便的方法,竟然可以不用到IMaps,省下好多功夫.(回想下例子竟然是一种误导...) 因为MapDocument就包含了map和pagelayout这两者,所以当用IMapDocument去打开的时候,可以直接把类包含的map和pagela

C#:MapControl基本操作代码整理

来自:http://www.cnblogs.com/shenchao/p/3591312.html using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Windows.Forms; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.esriSystem; using ESRI.

ArcGIS Engine开发之视图同步

数据视图与布局视图的同步 数据视图与布局视图的同步,首先要保证数据的一致性,其次就是数据显示范围的一致性.该同步主要涉及IMapControl接口的OnMapReplaced事件和OnAfterScreenDraw事件. 1)OnMapReplaced事件 OnMapReplaced事件发生在MapControl的地图被替换后,即在IMapControl接口的Map被另一个地图替换时触发该事件. 2)OnAfterScreenDraw事件 OnAfterScreenDraw事件发生在MapCon

百度地图、ECharts整合HT for Web网络拓扑图应用

直击现场 百度地图.ECharts整合HT for Web网络拓扑图应用 发表于3周前(2015-03-23 01:32)   阅读(1320) | 评论(5) 78人收藏此文章, 我要收藏 赞8 慕课网,程序员升职加薪神器,点击免费学习 摘要 前一篇谈及到了ECharts整合HT for Web的网络拓扑图应用,后来在ECharts的Demo中看到了有关空气质量的相关报表应用,就想将百度地图.ECharts和HT for Web三者结合起来也做一个类似空气质量报告的报表+拓扑图应用. high

Rplidar学习(五)—— rplidar使用cartographer_ros进行地图云生成

一.Cartographer简介 Cartographer是google开源的通用2D和3D定位与地图同步构建的SLAM工具,并提供ROS接口.官网地址:https://github.com/googlecartographer 二.安装方法 1.安装全部依赖项 sudo apt-get update sudo apt-get install -y cmake g++ git google-mock libboost-all-dev libeigen3-dev libgflags-dev lib

100offer举办的「寻找实干和坚持的技术力量」开源项目投票排名分析程序

由于100offer举办的「寻找实干和坚持的技术力量」开源项目投票活动没有按照票数排序的功能,所以本文写了个小程序来实现这个功能,代码如下: import org.jsoup.Jsoup; import org.jsoup.nodes.Element; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /**