📄 view_map_control.cpp
字号:
///////////////////////////////////////////////////////////
// //
// SAGA //
// //
// System for Automated Geoscientific Analyses //
// //
// User Interface //
// //
// Program: SAGA //
// //
//-------------------------------------------------------//
// //
// VIEW_Map_Control.cpp //
// //
// Copyright (C) 2005 by Olaf Conrad //
// //
//-------------------------------------------------------//
// //
// This file is part of 'SAGA - System for Automated //
// Geoscientific Analyses'. SAGA is free software; you //
// can redistribute it and/or modify it under the terms //
// of the GNU General Public License as published by the //
// Free Software Foundation; version 2 of the License. //
// //
// SAGA is distributed in the hope that it will be //
// useful, but WITHOUT ANY WARRANTY; without even the //
// implied warranty of MERCHANTABILITY or FITNESS FOR A //
// PARTICULAR PURPOSE. See the GNU General Public //
// License for more details. //
// //
// You should have received a copy of the GNU General //
// Public License along with this program; if not, //
// write to the Free Software Foundation, Inc., //
// 59 Temple Place - Suite 330, Boston, MA 02111-1307, //
// USA. //
// //
//-------------------------------------------------------//
// //
// contact: Olaf Conrad //
// Institute of Geography //
// University of Goettingen //
// Goldschmidtstr. 5 //
// 37077 Goettingen //
// Germany //
// //
// e-mail: oconrad@saga-gis.org //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#include <wx/window.h>
#include <wx/image.h>
#include "res_images.h"
#include "helper.h"
#include "dc_helper.h"
#include "wksp_map.h"
#include "wksp_module.h"
#include "wksp_grid.h"
#include "wksp_shapes.h"
#include "view_map.h"
#include "view_map_control.h"
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
#define GET_KEYS(e) ((e.LeftIsDown() ? MODULE_INTERACTIVE_KEY_LEFT : 0)\
|(e.MiddleIsDown() ? MODULE_INTERACTIVE_KEY_MIDDLE : 0)\
|(e.RightIsDown() ? MODULE_INTERACTIVE_KEY_RIGHT : 0)\
|(e.ShiftDown() ? MODULE_INTERACTIVE_KEY_SHIFT : 0)\
|(e.AltDown() ? MODULE_INTERACTIVE_KEY_ALT : 0)\
|(e.ControlDown() ? MODULE_INTERACTIVE_KEY_CTRL : 0))
//---------------------------------------------------------
#define STANDARD_ZOOM_FACTOR 150
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
BEGIN_EVENT_TABLE(CVIEW_Map_Control, wxPanel)
EVT_PAINT (CVIEW_Map_Control::On_Paint)
EVT_SIZE (CVIEW_Map_Control::On_Size)
EVT_KEY_DOWN (CVIEW_Map_Control::On_Key_Down)
EVT_MOTION (CVIEW_Map_Control::On_Mouse_Motion)
EVT_LEFT_DOWN (CVIEW_Map_Control::On_Mouse_LDown)
EVT_LEFT_UP (CVIEW_Map_Control::On_Mouse_LUp)
EVT_LEFT_DCLICK (CVIEW_Map_Control::On_Mouse_LDClick)
EVT_RIGHT_DOWN (CVIEW_Map_Control::On_Mouse_RDown)
EVT_RIGHT_UP (CVIEW_Map_Control::On_Mouse_RUp)
EVT_RIGHT_DCLICK (CVIEW_Map_Control::On_Mouse_RDClick)
END_EVENT_TABLE()
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
CVIEW_Map_Control::CVIEW_Map_Control(CVIEW_Map *pParent, CWKSP_Map *pMap)
: wxPanel(pParent, -1, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE)
{
SYS_Set_Color_BG_Window(this);
m_pParent = (CVIEW_Map *)pParent;
m_pMap = pMap;
m_Mode = -1;
Set_Mode(MAP_MODE_ZOOM);
m_Drag_Mode = MODULE_INTERACTIVE_DRAG_NONE;
}
//---------------------------------------------------------
CVIEW_Map_Control::~CVIEW_Map_Control(void)
{
_Distance_Reset();
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool CVIEW_Map_Control::Set_Mode(int Mode)
{
if( m_Mode != Mode )
{
if( m_Mode == MAP_MODE_DISTANCE )
{
_Distance_Reset();
}
m_Mode = Mode;
switch( m_Mode )
{
case MAP_MODE_ZOOM: default:
SetCursor(IMG_Get_Cursor(ID_IMG_CRS_SELECT));
break;
case MAP_MODE_PAN:
SetCursor(IMG_Get_Cursor(ID_IMG_CRS_HAND));
break;
case MAP_MODE_PAN_DOWN:
SetCursor(IMG_Get_Cursor(ID_IMG_CRS_HAND_GRAP));
break;
case MAP_MODE_SELECT:
SetCursor(IMG_Get_Cursor(ID_IMG_CRS_INFO));
break;
case MAP_MODE_DISTANCE:
SetCursor(IMG_Get_Cursor(ID_IMG_CRS_SELECT));
_Distance_Reset();
break;
}
return( true );
}
return( false );
}
//---------------------------------------------------------
inline void CVIEW_Map_Control::_Set_StatusBar(CSG_Point ptWorld)
{
STATUSBAR_Set_Text(wxString::Format(wxT("X%f"), ptWorld.Get_X()), STATUSBAR_VIEW_X);
STATUSBAR_Set_Text(wxString::Format(wxT("Y%f"), ptWorld.Get_Y()), STATUSBAR_VIEW_Y);
if( m_Mode == MAP_MODE_DISTANCE )
{
STATUSBAR_Set_Text(wxString::Format(wxT("D %f"), m_Distance + m_Distance_Move), STATUSBAR_VIEW_Z);
}
else if( Get_Active_Layer() )
{
STATUSBAR_Set_Text(wxString::Format(wxT("Z %s"), Get_Active_Layer()->Get_Value(ptWorld, _Get_World(2.0)).c_str()), STATUSBAR_VIEW_Z);
}
else
{
STATUSBAR_Set_Text(wxT("Z"), STATUSBAR_VIEW_Z);
}
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
inline wxRect CVIEW_Map_Control::_Get_Client(void)
{
return( wxRect(wxPoint(0, 0), GetClientSize()) );
}
//---------------------------------------------------------
inline wxPoint CVIEW_Map_Control::_Get_Client(TSG_Point Point)
{
wxRect rClient(_Get_Client());
CSG_Rect rWorld(m_pMap->Get_World(rClient));
double World2DC = (double)rClient.GetWidth() / rWorld.Get_XRange();
return( wxPoint( (int)(0.5 + (Point.x - rWorld.Get_XMin()) * World2DC),
rClient.GetHeight() - (int)(0.5 + (Point.y - rWorld.Get_YMin()) * World2DC)
));
}
//---------------------------------------------------------
inline CSG_Point CVIEW_Map_Control::_Get_World(wxPoint ptClient)
{
return( m_pMap->Get_World(_Get_Client(), ptClient) );
}
//---------------------------------------------------------
inline double CVIEW_Map_Control::_Get_World(double xClient)
{
wxRect rClient(_Get_Client());
CSG_Rect rWorld(m_pMap->Get_World(rClient));
return( xClient * rWorld.Get_XRange() / (double)rClient.GetWidth() );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
void CVIEW_Map_Control::_Draw_Inverse(wxPoint ptA, wxPoint ptB)
{
if( m_Drag_Mode != MODULE_INTERACTIVE_DRAG_NONE )
{
wxClientDC dc(this);
dc.SetLogicalFunction(wxINVERT);
switch( m_Drag_Mode )
{
case MODULE_INTERACTIVE_DRAG_LINE:
dc.DrawLine (ptA.x, ptA.y, ptB.x, ptB.y);
break;
case MODULE_INTERACTIVE_DRAG_BOX:
dc.DrawRectangle (ptA.x, ptA.y, ptB.x - ptA.x, ptB.y - ptA.y);
break;
case MODULE_INTERACTIVE_DRAG_CIRCLE:
dc.DrawCircle (ptA.x, ptA.y, (int)SG_Get_Distance(ptA.x, ptA.y, ptB.x, ptB.y));
break;
}
}
}
//---------------------------------------------------------
void CVIEW_Map_Control::_Draw_Inverse(wxPoint ptA, wxPoint ptB_Old, wxPoint ptB_New)
{
if( m_Drag_Mode != MODULE_INTERACTIVE_DRAG_NONE )
{
wxClientDC dc(this);
dc.SetLogicalFunction(wxINVERT);
switch( m_Drag_Mode )
{
case MODULE_INTERACTIVE_DRAG_LINE:
dc.DrawLine (ptA.x, ptA.y, ptB_Old.x, ptB_Old.y);
dc.DrawLine (ptA.x, ptA.y, ptB_New.x, ptB_New.y);
break;
case MODULE_INTERACTIVE_DRAG_BOX:
dc.DrawRectangle (ptA.x, ptA.y, ptB_Old.x - ptA.x, ptB_Old.y - ptA.y);
dc.DrawRectangle (ptA.x, ptA.y, ptB_New.x - ptA.x, ptB_New.y - ptA.y);
break;
case MODULE_INTERACTIVE_DRAG_CIRCLE:
dc.DrawCircle (ptA.x, ptA.y, (int)SG_Get_Distance(ptA.x, ptA.y, ptB_Old.x, ptB_Old.y));
dc.DrawCircle (ptA.x, ptA.y, (int)SG_Get_Distance(ptA.x, ptA.y, ptB_New.x, ptB_New.y));
break;
}
}
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool CVIEW_Map_Control::_Zoom(wxPoint A, wxPoint B)
{
CSG_Rect rWorld;
if( A.x == B.x && A.y == B.y )
{
return( _Zoom(_Get_World(A), true) );
}
rWorld.Assign(_Get_World(A), _Get_World(B));
m_pMap->Set_Extent(rWorld);
return( true );
}
bool CVIEW_Map_Control::_Zoom(CSG_Point ptCenter, bool bZoomIn)
{
CSG_Rect rWorld(m_pMap->Get_Extent());
rWorld.Move(ptCenter - rWorld.Get_Center());
if( bZoomIn )
{
rWorld.Deflate(STANDARD_ZOOM_FACTOR);
}
else
{
rWorld.Inflate(STANDARD_ZOOM_FACTOR);
}
m_pMap->Set_Extent(rWorld);
return( true );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
bool CVIEW_Map_Control::_Pan(wxPoint A, wxPoint B)
{
if( A.x != B.x || A.y != B.y )
{
wxClientDC dc(this);
dc.SetBackground(*wxWHITE_BRUSH);
dc.Clear();
dc.DrawBitmap(m_Bitmap, B.x - A.x, B.y - A.y, false);
return( true );
}
return( false );
}
//---------------------------------------------------------
bool CVIEW_Map_Control::_Move(wxPoint &A, wxPoint B)
{
if( A.x != B.x || A.y != B.y )
{
CSG_Rect rWorld;
rWorld.Assign(m_pMap->Get_Extent());
rWorld.Move(_Get_World(A) - _Get_World(B));
m_pMap->Set_Extent(rWorld);
A = B;
return( true );
}
return( false );
}
bool CVIEW_Map_Control::_Move(wxPoint ptMove)
{
return( _Move(ptMove, wxPoint(0, 0)) );
}
///////////////////////////////////////////////////////////
// //
// //
// //
///////////////////////////////////////////////////////////
//---------------------------------------------------------
void CVIEW_Map_Control::_Distance_Reset(void)
{
m_Distance_Pts.Clear();
m_Distance = 0.0;
m_Distance_Move = 0.0;
Refresh(false);
}
//---------------------------------------------------------
void CVIEW_Map_Control::_Distance_Add(wxPoint Point)
{
int n = m_Distance_Pts.Get_Count();
m_Distance_Pts.Add(_Get_World(Point));
if( n > 0 )
{
m_Distance += SG_Get_Distance(m_Distance_Pts[n], m_Distance_Pts[n - 1]);
}
m_Distance_Move = 0.0;
wxClientDC dc(this);
_Distance_Draw(dc);
}
//---------------------------------------------------------
void CVIEW_Map_Control::_Distance_Draw(wxDC &dc)
{
int n = m_Distance_Pts.Get_Count();
if( m_Mode == MAP_MODE_DISTANCE && n > 0 )
{
int i;
wxPoint A, B;
dc.SetPen(wxPen(*wxWHITE, 4));
for(i=1, A=_Get_Client(m_Distance_Pts[0]); i<n; i++)
{
B = A;
A = _Get_Client(m_Distance_Pts[i]);
dc.DrawLine(A.x, A.y, B.x, B.y);
}
dc.SetPen(wxPen(*wxBLACK, 2));
for(i=1, A=_Get_Client(m_Distance_Pts[0]); i<n; i++)
{
B = A;
A = _Get_Client(m_Distance_Pts[i]);
dc.DrawLine(A.x, A.y, B.x, B.y);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -