📄 viewmap.cpp
字号:
//////////////////////////////////////////////////////
//
// NRDB Pro - Spatial database and mapping application
//
// Copyright (c) 1989-2004 Richard D. Alexander
//
// This program 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; either version 2
// of the License, or (at your option) any later version.
//
// This program 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.
//
// NRDB Pro is part of the Natural Resources Database Project
//
// Homepage: http://www.nrdb.co.uk/
// Users' Forum: http://nrdb.mypalawan.info/
//
#include "stdafx.h"
#include <afxpriv.h>
#include "nrdbpro.h"
#include "nrdb.h"
#include "docmap.h"
#include "viewmap.h"
#include "mainfrm.h"
#include "viewlegend.h"
#include "projctns.h"
#include "dlgeditattributes.h"
#include "dlgeditfeature.h"
#include "clip.h"
#include "definitions.h"
#include "comboboxpattern.h"
#include "comboboxsymbol.h"
#include "docsummary.h"
#include "dlgsearch.h"
#include "dlgimportdate.h"
#include "dlgdigitisetype.h"
#include "shapefile.h"
#include "dlgimageoptions.h"
#include "fileobj.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
///////////////////////////////////////////////////////////////////////////////
#define DEFAULT_ZOOM 0.8
#define MAX_ZOOM 4000000 // metres (400km / UTM zone)
#define MAX_ZOOMLATLON 40000000// circumference of earth
#define MAX_PAN 2000000
#define MIN_ZOOM 10 // metres
#define SYMSIZE 10
#define SCROLLRANGE 1000
#define MMPERINCH 25.4
#define FITTHRESH 1000
#define WIN98POLYLINE 16383
#define WIDELINELEN 1360
#define NODESIZE 2
/////////////////////////////////////////////////////////////////////////////
double inline square(double x) {return x*x;};
void inline swap(long& a, long &b) {long c=a;a=b;b=c;}
void inline swap(double& a, double &b) {double c=a;a=b;b=c;}
void inline DrawNode(CDC* pDC, CPoint point)
{
pDC->MoveTo(point.x-NODESIZE, point.y-NODESIZE);
pDC->LineTo(point.x+NODESIZE, point.y-NODESIZE);
pDC->LineTo(point.x+NODESIZE, point.y+NODESIZE);
pDC->LineTo(point.x-NODESIZE, point.y+NODESIZE);
pDC->LineTo(point.x-NODESIZE, point.y-NODESIZE);
};
///////////////////////////////////////////////////////////////////////////////
//
// Returns true if the point occurs inside the polygon
//
int InsidePolygon(CLongLines* pLongLines, long x, long y)
{
int i, j, c = 0;
// Search through each polygon
int i1 = 0;
for (int i2 = 0; i2 < pLongLines->GetSize(); i2++)
{
if (pLongLines->GetAt(i2).IsNull() || i2+1 == pLongLines->GetSize())
{
for (i = i1, j = i2-1; i < i2; j = i++)
{
CLongCoord& coordi = pLongLines->GetAt(i);
CLongCoord& coordj = pLongLines->GetAt(j);
if (
(
((coordi.y <= y) && (y < coordj.y )) ||
((coordj.y <= y) && (y < coordi.y))
) &&
(x < (coordj.x - coordi.x) * (y - coordi.y) / (coordj.y- coordi.y) + coordi.x))
c = !c;
}
// Return true if inside any polygon
if (c) return c;
i1 = i2+1;
};
};
return c;
}
/////////////////////////////////////////////////////////////////////////////
CString CViewMap::m_sLogoText;
CString CViewMap::m_sLogoFile;
/////////////////////////////////////////////////////////////////////////////
struct CDblPoint
{
double x;
double y;
};
/////////////////////////////////////////////////////////////////////////////
// CViewMap
IMPLEMENT_DYNCREATE(CViewMap, CBDView)
BEGIN_MESSAGE_MAP(CViewMap, CBDView)
//{{AFX_MSG_MAP(CViewMap)
ON_WM_SIZE()
ON_WM_LBUTTONDOWN()
ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomin)
ON_COMMAND(ID_VIEW_ZOOMNORMAL, OnViewZoomnormal)
ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomout)
ON_WM_TIMER()
ON_WM_MOUSEMOVE()
ON_WM_RBUTTONDOWN()
ON_WM_KILLFOCUS()
ON_WM_VSCROLL()
ON_WM_HSCROLL()
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
ON_WM_DESTROY()
ON_WM_RBUTTONUP()
ON_COMMAND(ID_MAP_EDITDATA, OnMapEditdata)
ON_COMMAND(ID_MAP_EDITFEATURE, OnMapEditfeature)
ON_COMMAND(ID_MAP_ADDFEATURE, OnMapAddFeature)
ON_UPDATE_COMMAND_UI(ID_MAP_ADDFEATURE, OnUpdateMapAddFeature)
ON_COMMAND(ID_MAP_SECTORALREPORT, OnMapSectoralReport)
ON_UPDATE_COMMAND_UI(ID_MAP_SECTORALREPORT, OnUpdateMapSectoralReport)
ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
ON_WM_PAINT()
ON_COMMAND(ID_EDIT_SEARCH, OnEditSearch)
ON_UPDATE_COMMAND_UI(ID_EDIT_SEARCH, OnUpdateEditSearch)
ON_UPDATE_COMMAND_UI(ID_MAP_EDITDATA, OnUpdateMapEditdata)
ON_UPDATE_COMMAND_UI(ID_MAP_EDITFEATURE, OnUpdateMapEditfeature)
ON_WM_KEYDOWN()
ON_WM_SETCURSOR()
ON_COMMAND(ID_MAP_EDITLINES, OnMapEditlines)
ON_UPDATE_COMMAND_UI(ID_MAP_EDITLINES, OnUpdateMapEditlines)
ON_COMMAND(ID_MAP_EDITPOINTS, OnMapEditpoints)
ON_UPDATE_COMMAND_UI(ID_MAP_EDITPOINTS, OnUpdateMapEditpoints)
ON_COMMAND(ID_MAP_PAN, OnMapPan)
ON_UPDATE_COMMAND_UI(ID_MAP_PAN, OnUpdateMapPan)
ON_COMMAND(ID_MAP_MEASURE, OnMapMeasure)
ON_UPDATE_COMMAND_UI(ID_MAP_MEASURE, OnUpdateMapMeasure)
ON_WM_LBUTTONDBLCLK()
ON_COMMAND(ID_MAP_UPDATE, OnMapUpdate)
ON_UPDATE_COMMAND_UI(ID_MAP_UPDATE, OnUpdateMapUpdate)
ON_WM_MOUSEWHEEL()
ON_WM_LBUTTONUP()
ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
ON_COMMAND(ID_MAP_VIEWFILE, OnMapViewfile)
ON_UPDATE_COMMAND_UI(ID_MAP_VIEWFILE, OnUpdateMapViewfile)
//}}AFX_MSG_MAP
ON_COMMAND(ID_FILE_PRINT_DIRECT, CBDView::OnFilePrint)
// Standard printing commands
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CViewMap construction/destruction
CViewMap::CViewMap()
{
m_dZoom = 1;
m_dZoomP = 1;
m_bDefaultExtentNull = FALSE;
// Must be called after m_bDefaultExtent is initialised
InitialiseMapView();
m_pRectTracker = NULL;
m_pEditMapObj = NULL;
m_pEditMapLayer = NULL;
m_menuedit.LoadMenu(IDR_MAPEDIT);
m_nCurPage = 0;
m_hDragCursor = LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURDRAG));
m_hDragCursor2 = LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURDRAG2));
m_hPanCursor = LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURPAN));
m_hCurSel = LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURSEL));
m_hCurIns = LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_CURINS));
m_bDragMode = FALSE;
m_bInsertMode = TRUE;
m_nMapMode = none;
m_ptPan = CPoint(-1,-1);
m_pMapLayerObj = NULL;
m_pMapLayer = NULL;
// Determine operating system
DWORD dw = GetVersion();
m_bWinNT = dw < 0x80000000;
m_bWideLine = TRUE;
m_pDoc = NULL;
m_pMapLinesEdit = NULL;
m_pMapCoordEdit = NULL;
m_nMode = none;
m_iEditPoint1 = 0;
m_iEditPoint2 = 0;
m_bAutoUpdate = TRUE;
m_bViewFile = FALSE;
m_bViewHotLink = FALSE;
}
///////////////////////////////////////////////////////////////////////////////
CViewMap::~CViewMap()
{
if (m_hDragCursor != NULL) DestroyCursor(m_hDragCursor);
if (m_hDragCursor2 != NULL) DestroyCursor(m_hDragCursor2);
if (m_hCurSel != NULL) DestroyCursor(m_hCurSel);
if (m_hCurIns != NULL) DestroyCursor(m_hCurIns);
if (m_hPanCursor != NULL) DestroyCursor(m_hPanCursor);
RemoveTracker();
}
///////////////////////////////////////////////////////////////////////////////
void CViewMap::InitialiseMapView()
{
// Determine the default projection
CBDProjection projection;
BOOL bFound = BDProjection(BDHandle(), &projection, BDGETINIT);
while (bFound)
{
if (projection.m_bDefault)
{
m_dMinX = projection.m_dMinEasting;
m_dMaxX = projection.m_dMaxEasting;
m_dMinY = projection.m_dMinNorthing;
m_dMaxY = projection.m_dMaxNorthing;
if (m_dMinX == NULL_DOUBLE || m_dMinY == NULL_DOUBLE ||
m_dMaxX == NULL_DOUBLE || m_dMaxY == NULL_DOUBLE)
{
m_bDefaultExtentNull = TRUE;
};
if (m_dMinX == m_dMaxX) {m_dMinX = 0; m_dMaxX = 1;}
if (m_dMinY == m_dMaxY) {m_dMinY = 0; m_dMaxY = 1;}
m_dOffX = (m_dMinX + m_dMaxX)/2;
m_dOffY = (m_dMinY + m_dMaxY)/2;
m_dOffXP = m_dOffX;
m_dOffYP = m_dOffY;
break;
};
bFound = BDGetNext(BDHandle());
}
BDEnd(BDHandle());
// If not found then use latitude/longitude as extent
if (!bFound)
{
m_dMinX = -180 * LATLONSCALE;
m_dMaxX = 180 * LATLONSCALE;
m_dMinY = -90 * LATLONSCALE;
m_dMaxY = 90 * LATLONSCALE;
m_dOffX = (m_dMinX + m_dMaxX)/2;
m_dOffY = (m_dMinY + m_dMaxY)/2;
m_dOffXP = m_dOffX;
m_dOffYP = m_dOffY;
}
// Reset logo text
m_sLogoText = "";
m_sLogoFile = "";
}
///////////////////////////////////////////////////////////////////////////////
BOOL CViewMap::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CBDView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
void CViewMap::OnInitialUpdate()
{
CBDView::OnInitialUpdate();
ShowScrollBar(SB_BOTH);
SetScrollRange(SB_VERT,0,SCROLLRANGE);
SetScrollRange(SB_HORZ,0,SCROLLRANGE);
SetScrollPos();
m_pDoc = GetDocument();
}
/////////////////////////////////////////////////////////////////////////////
//
// Draw into a specified device context
//
void CViewMap::DrawRect(CDC* pDC, CRect rect)
{
m_rect = rect;
DetermineAspect();
m_rectPaint.left = m_rectPaint.right = 0;
OnDraw(pDC);
GetClientRect(&m_rect);
DetermineAspect();
}
/////////////////////////////////////////////////////////////////////////////
void CViewMap::OnPaint()
{
CPaintDC dc(this); // device context for painting
OnPrepareDC(&dc);
m_rectPaint = dc.m_ps.rcPaint;
OnDraw(&dc);
if (m_bAutoUpdate == -1) m_bAutoUpdate = 0;
}
/////////////////////////////////////////////////////////////////////////////
void CViewMap::OnDraw(CDC* pDC)
{
CRect rect;
if (m_pDoc == NULL || !m_pDoc->IsKindOf(RUNTIME_CLASS(CDocMap))) return;
// Check for wideline capabilities
m_bWideLine = pDC->GetDeviceCaps(LINECAPS) & LC_WIDE;
// If a scale has been set then set the zoom to reflect this
if (m_pDoc->GetScale() != 0)
{
int nScale = GetScale(pDC);
m_dZoom = (m_dZoom * nScale) / m_pDoc->GetScale();
};
BeginWaitCursor();
// If copying then change aspect ratio
if (m_bCopy)
{
SetCopyRect(pDC);
}
// Fill the background color
GetClientRect(&rect);
pDC->FillSolidRect(&rect, pDC->GetBkColor());
// Draw the layers
if (m_pDoc->GetLayers()->GetSize() == 0)
{
DrawLogo(pDC);
} else
{
DrawLayers(pDC);
};
// Draw lines being edited
if (m_pMapLinesEdit != NULL)
{
DrawMapEditLines(pDC, m_pMapLinesEdit, m_pEditMapLayer);
};
// Draw tape measure
if (m_nMapMode == measure)
{
m_ptMeasure1 = CPoint(-1,-1);
m_ptMeasure2 = CPoint(-1,-1);
DrawTapeMeasure(pDC);
}
// Tidy Up
if (m_bCopy)
{
GetClientRect(&m_rect);
DetermineAspect();
};
EndWaitCursor();
// If requested to add a new feature then do so
if (m_nMode & addnew)
{
OnMapAddFeature();
// Remove add new flag
m_nMode = (m_nMode | addnew) ^ addnew;
};
// Reset
m_rectPaint = CRect(0,0,0,0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -