前一篇随笔中记录了地图放大功能的实现,其中很多方法和这篇中要说的缩小很像,比如ControlsMapZoomOutTool和ControlsMapZoomOutFixedCommand。那在这篇中就忽略掉这两个方法的实现了,直接看看自定义缩小功能的实现代码
代码
public
MapZoomOut()
{
string [] res = GetType().Assembly.GetManifestResourceNames();
base .m_bitmap = new System.Drawing.Bitmap(GetType().Assembly.GetManifestResourceStream( " Commands.zoomout.bmp " ));
base .m_caption = " 缩小地图 " ;
base .m_category = " ToolBar " ;
base .m_message = " 缩小地图 " ;
base .m_name = " ToolBar_MapPan " ;
base .m_toolTip = " 缩小 " ;
m_ZoomOutStart = true ;
m_feedBack = null ;
try
{
base .m_cursor = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream( " Commands.ZoomOut.CUR " ));
}
catch (Exception ex)
{
}
}
public override void OnCreate( object hook)
{
m_HookHelper.Hook = hook;
try
{
m_pActiveView = m_HookHelper.ActiveView;
}
catch { }
}
public override void OnMouseDown( int Button, int Shift, int X, int Y)
{
if ( null == m_pActiveView) return ;
m_pPoint = m_pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
m_ZoomOutStart = true ;
m_feedBack = null ;
}
public override void OnMouseMove( int Button, int Shift, int X, int Y)
{
if ( null == m_pActiveView) return ;
if ( ! m_ZoomOutStart) return ;
if (m_feedBack == null )
{
m_feedBack = new NewEnvelopeFeedbackClass();
if (Button == 1 )
{
m_feedBack.Display = m_pActiveView.ScreenDisplay;
m_feedBack.Start(m_pPoint);
}
}
m_feedBack.MoveTo(m_pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y));
}
public override void OnMouseUp( int Button, int Shift, int X, int Y)
{
if ( null == m_pActiveView) return ;
if ( ! m_ZoomOutStart) return ;
IEnvelope m_pEnvelope = new EnvelopeClass();
if ( null == m_feedBack) // 点击缩小
{
m_pEnvelope = m_pActiveView.Extent;
m_pEnvelope.Expand( 2 , 2 , true );
m_pActiveView.Extent.CenterAt(m_pPoint);
}
else // 拉框缩小
{
IEnvelope m_pFeedEnvelope = new EnvelopeClass();
m_pFeedEnvelope = m_feedBack.Stop();
try
{
{
string [] res = GetType().Assembly.GetManifestResourceNames();
base .m_bitmap = new System.Drawing.Bitmap(GetType().Assembly.GetManifestResourceStream( " Commands.zoomout.bmp " ));
base .m_caption = " 缩小地图 " ;
base .m_category = " ToolBar " ;
base .m_message = " 缩小地图 " ;
base .m_name = " ToolBar_MapPan " ;
base .m_toolTip = " 缩小 " ;
m_ZoomOutStart = true ;
m_feedBack = null ;
try
{
base .m_cursor = new System.Windows.Forms.Cursor(GetType().Assembly.GetManifestResourceStream( " Commands.ZoomOut.CUR " ));
}
catch (Exception ex)
{
}
}
public override void OnCreate( object hook)
{
m_HookHelper.Hook = hook;
try
{
m_pActiveView = m_HookHelper.ActiveView;
}
catch { }
}
public override void OnMouseDown( int Button, int Shift, int X, int Y)
{
if ( null == m_pActiveView) return ;
m_pPoint = m_pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y);
m_ZoomOutStart = true ;
m_feedBack = null ;
}
public override void OnMouseMove( int Button, int Shift, int X, int Y)
{
if ( null == m_pActiveView) return ;
if ( ! m_ZoomOutStart) return ;
if (m_feedBack == null )
{
m_feedBack = new NewEnvelopeFeedbackClass();
if (Button == 1 )
{
m_feedBack.Display = m_pActiveView.ScreenDisplay;
m_feedBack.Start(m_pPoint);
}
}
m_feedBack.MoveTo(m_pActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(X, Y));
}
public override void OnMouseUp( int Button, int Shift, int X, int Y)
{
if ( null == m_pActiveView) return ;
if ( ! m_ZoomOutStart) return ;
IEnvelope m_pEnvelope = new EnvelopeClass();
if ( null == m_feedBack) // 点击缩小
{
m_pEnvelope = m_pActiveView.Extent;
m_pEnvelope.Expand( 2 , 2 , true );
m_pActiveView.Extent.CenterAt(m_pPoint);
}
else // 拉框缩小
{
IEnvelope m_pFeedEnvelope = new EnvelopeClass();
m_pFeedEnvelope = m_feedBack.Stop();
try
{
//这里是与放大代码不同的地方
double newWidth = m_pActiveView.Extent.Width * (m_pActiveView.Extent.Width / m_pFeedEnvelope.Width);
double newHeight = m_pActiveView.Extent.Height * (m_pActiveView.Extent.Height / m_pFeedEnvelope.Height);
double newXmin = m_pActiveView.Extent.XMin - ((m_pFeedEnvelope.XMin - m_pActiveView.Extent.XMin) * (m_pActiveView.Extent.Width / m_pFeedEnvelope.Width));
double newYmin = m_pActiveView.Extent.YMin - ((m_pFeedEnvelope.YMin - m_pActiveView.Extent.YMin) * (m_pActiveView.Extent.Height / m_pFeedEnvelope.Height));
m_pEnvelope.PutCoords(newXmin, newYmin, newXmin + newWidth, newYmin + newHeight);
}
catch
{
m_pEnvelope = m_pActiveView.Extent;
m_pEnvelope.Expand( 2 , 2 , true );
m_pActiveView.Extent.CenterAt(m_pPoint);
m_feedBack = null ;
m_ZoomOutStart = false ;
}
}
m_pActiveView.Extent = m_pEnvelope;
m_pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null , null );
m_feedBack = null ;
Marshal.ReleaseComObject(m_feedBack);
m_ZoomOutStart = false ;
}
public override void OnKeyDown( int keyCode, int Shift)
{
if (keyCode == 27 )
{
m_ZoomOutStart = false ;
base .m_cursor = System.Windows.Forms.Cursors.Default;
}
}
double newWidth = m_pActiveView.Extent.Width * (m_pActiveView.Extent.Width / m_pFeedEnvelope.Width);
double newHeight = m_pActiveView.Extent.Height * (m_pActiveView.Extent.Height / m_pFeedEnvelope.Height);
double newXmin = m_pActiveView.Extent.XMin - ((m_pFeedEnvelope.XMin - m_pActiveView.Extent.XMin) * (m_pActiveView.Extent.Width / m_pFeedEnvelope.Width));
double newYmin = m_pActiveView.Extent.YMin - ((m_pFeedEnvelope.YMin - m_pActiveView.Extent.YMin) * (m_pActiveView.Extent.Height / m_pFeedEnvelope.Height));
m_pEnvelope.PutCoords(newXmin, newYmin, newXmin + newWidth, newYmin + newHeight);
}
catch
{
m_pEnvelope = m_pActiveView.Extent;
m_pEnvelope.Expand( 2 , 2 , true );
m_pActiveView.Extent.CenterAt(m_pPoint);
m_feedBack = null ;
m_ZoomOutStart = false ;
}
}
m_pActiveView.Extent = m_pEnvelope;
m_pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null , null );
m_feedBack = null ;
Marshal.ReleaseComObject(m_feedBack);
m_ZoomOutStart = false ;
}
public override void OnKeyDown( int keyCode, int Shift)
{
if (keyCode == 27 )
{
m_ZoomOutStart = false ;
base .m_cursor = System.Windows.Forms.Cursors.Default;
}
}
可以看到缩小与放大不同之处
①:在点击缩放的时候m_pEnvelope.Expand(0.5,0.5,true) 和m_pEnvelope.Expand(2,2,true)的不同,应该很容易理解,打个比方,比如把当前的地图比作为1m*1m的标准地图,Expand(0.5,0.5,true),相当于是说将0.5m*0.5m的地图视图放大1m*1m的“地图框架”中,为了充满这个“地图框架”,应该要放大。(哈哈,应该可以这样理解),同样,缩小也就好理解了。
②:在拉框缩放的时候,放大中直接按照绘制的矩形框的大小进行放大,在缩小的时候,需要set new coordinate,就像屏幕的分辨率一样,重置到当前“屏幕”的大小(就是重定义ActiveView.Extent的Xmin,Ymin,Xmax,Ymax)。