网上看了不少AE+C#实现鹰眼的代码,各有各的不同,也都有各自的小缺陷,但鹰眼的原理基本上是弄明白了,总结一下:
1.要使鹰眼地图随主地图的改变而改变。这里关于鹰眼控件中地图保持全幅显示还是像google那样鹰眼地图比例尺也随主地图比例尺变化,就要看需求如何了;
2.在鹰眼中画框。这个情况也很多,看的几个例子都在这里有不同的小毛病,首先是框的大小,一般说来,框的大小应该是和主地图控件的大小成比例的,这样才真正准确的在鹰眼中体现了主地图的显示范围,要不要缩放?要视情况而定。google和百度里的那个框框大小是不变的,缩放的鹰眼中的地图,如果鹰眼固定比例尺显示,那框框就必须能缩放,但我想不能随比例尺一直缩小,那样框框会变成一个点,主地图可以无限缩放,但框框必须有上下界。然后是框框的拖动,这个必须有。其次是鼠标画框的问题,很多例子都提供了鼠标左(右)键在鹰眼中画框来指定主地图的显示范围,这个功能有一点争议是画的框与主地图控件比例不一致时,主地图的显示范围是不准确的。
所以鹰眼应该是怎样的,究竟是图变框不变(google)还是框变图不变,就要看用户需求了,以我的观点看,如果地图的比例尺变幅大,像google百度那样从街道到全国全球,就适合图变框不变,否则主图都显示到街道了,鹰眼还是全国范围,那框框估计都成一个像素了,鹰眼也失去了意义;如果地图比例尺的变幅较小,如地市范围到街道范围,这样的用框变图不变就可以了,但要注意小到一定程度就不能再小了,要不然同样不好看。
先这样吧,代码还没总结,总结好再贴上来,初学习,要加油!
代码补充:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.SystemUI;
//****************************************************************************************************************************
//
// Form1.cs
//
//axMapControl1为主地图控件
//axMapControl2为鹰眼地图控件
//button1退出
//button2打开mxd文档
//
//鹰眼中红框的长宽比始终与主控件成比例,不因鼠标拉框的形状改变红框形状。鹰眼中左键移动红框
//右键拉框改变显示范围。
//
//不足:1.随主控件地图不断放大,红框会缩小为点(可以设置一个比例尺为阈值,放大到阈值以上,
//红框不再缩小);2.移动红框后,鹰眼获得焦点,滚动鼠标会缩放鹰眼中的地图。
//
//****************************************************************************************************************************
namespace Test2_Overview
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
// 退出按钮
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
#region 主地图控件事件
private void axMapControl1_OnMapReplaced(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMapReplacedEvent e)
{
//当主地图中更换地图时,鹰眼中的地图也更换
axMapControl2.Map = new MapClass();
//添加主地图中的所有图层到鹰眼地图控件中
for (int i = 1; i <= axMapControl1.LayerCount; i++)
{
axMapControl2.AddLayer(axMapControl1.get_Layer(axMapControl1.LayerCount - i));
}
//设置鹰眼显示范围至数据的全局范围
axMapControl2.Extent = axMapControl1.FullExtent;
//刷新鹰眼地图控件
axMapControl2.Refresh();
}
private void axMapControl1_OnExtentUpdated(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnExtentUpdatedEvent e)
{
//得到新范围----------特别注意!
//IEnvelope pEnv = (IEnvelope)e.newEnvelope;//获得鼠标拉框的显示范围,这样红框会变形,不与主地图控件的形状成比例,拖动时也变形
IEnvelope pEnv = axMapControl1.Extent;//用当前主地图的extent赋给IEnvelope接口,然后绘框,可以保证鹰眼红框始终与主地图同比例缩放,也解决了拖动时红框变形问题
//将鹰眼地图设为绘图容器
IGraphicsContainer pGra = axMapControl2.Map as IGraphicsContainer;
//将该容器设为当前活动视图
IActiveView pAv = pGra as IActiveView;
//重新绘制前,清除之前绘制的图形元素
pGra.DeleteAllElements();
//将PEnv设置为矩形对象的几何图形
IRectangleElement pRectangleEle = new RectangleElementClass();
IElement pEle = pRectangleEle as IElement;
pEle.Geometry = pEnv;//---将当前显示范围作为绘图对象的几何形状,这就使得拉框缩放时,鹰眼红框的形状随拉框变化
//设置红框的Symbol
IRgbColor pColor = new RgbColorClass();
pColor.RGB = 255;
ILineSymbol pOutline = new SimpleLineSymbolClass();
pOutline.Color = pColor;
pOutline.Width = 1.3;
ISimpleFillSymbol pSimpleFillSymbol = new SimpleFillSymbolClass();
pSimpleFillSymbol.Outline = pOutline;
pSimpleFillSymbol.Style = esriSimpleFillStyle.esriSFSHollow;
//将矩形对象设为填充对象
IFillShapeElement pFillShapEle = pEle as IFillShapeElement;
//填充对象的符号为pSimpleFillSymbol
pFillShapEle.Symbol = pSimpleFillSymbol;
//添加红框到容器pGra
pGra.AddElement((IElement)pFillShapEle, 0);
//刷新
pAv.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
#endregion
#region 鹰眼地图控件事件
private void axMapControl2_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
{
if (e.button != 1) return;
IPoint pPoint = new PointClass();
//实时获取鼠标在地图中的坐标位置
pPoint.PutCoords(e.mapX, e.mapY);
//将此坐标设为主地图控件的中心点
axMapControl1.CenterAt(pPoint);
//刷新主地图控件以上一步坐标移动主地图
axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
private void axMapControl2_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
{
if (axMapControl2.Map.LayerCount != 0)
{
//左键移动
if (e.button == 1)
{
IPoint pPoint = new PointClass();
pPoint.PutCoords(e.mapX, e.mapY);
axMapControl1.CenterAt(pPoint);
axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
//右键画框
else if (e.button == 2)
{
//获取鼠标拉框的矩形轨迹,并将该范围赋给pEnvelope
IEnvelope pEnvelope = axMapControl2.TrackRectangle();
axMapControl1.Extent = pEnvelope;
axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
}
}
#endregion
// 打开地图文档文件
private void button2_Click(object sender, EventArgs e)
{
string sFileName;
openFileDialog1.Title = "Open Map Document";
openFileDialog1.Filter = "Map Documents(*.mxd;*.pmf)|*.mxd;*.pmf";
if (openFileDialog1.ShowDialog() == DialogResult.Cancel)
{
return;
}
if (openFileDialog1.FileName == "")
{
return;
}
else
{
sFileName = openFileDialog1.FileName;
}
if (axMapControl1.CheckMxFile(sFileName))
{
axMapControl1.LoadMxFile(sFileName);
axMapControl1.Extent = axMapControl1.FullExtent;
}
else
{
MessageBox.Show(sFileName + " is not valid ArcMap document");
}
}
}
}