📄 viewmap.cpp
字号:
break;
case CMapLayer::Center:
rect.left = nX - sz.cx/2;
rect.top = nY - sz.cy/2;
break;
}
rect.right = rect.left + sz.cx;
rect.bottom = rect.top + sz.cy;
// Check for overlap, do not display if string overlaps others
for (int i = 0; i < m_aRectText.GetSize(); i++)
{
if (rectI.IntersectRect(rect, m_aRectText[i]))
{
bDrawText = FALSE;
break;
}
}
// Check for overlap with existing text in this layer
for (i = 0; i < m_aRectTextL.GetSize(); i++)
{
if (rectI.IntersectRect(rect, m_aRectTextL[i].m_rect))
{
bDrawText = FALSE;
iOverlap = i;
break;
}
}
// Check for overlap with the edge of the page
if (rect.left < m_rect.left || rect.right > m_rect.right ||
rect.top < m_rect.top || rect.bottom > m_rect.bottom)
{
bDrawText = FALSE;
}
};
// If unable to fit the text then fry moving existing text
if (iOverlap != -1 && !bDrawText)
{
// Move overlapping text
CRectText rectT = m_aRectTextL[iOverlap];
m_aRectTextL.RemoveAt(iOverlap);
iPos = rectT.m_iPos+1;
if (CheckOverlap(pDC, pMapLayer, rectT.m_sText, rectT.m_nX, rectT.m_nY, rect,
iPos))
{
// Re-add
rectT.m_iPos = iPos;
rectT.m_rect = rect;
m_aRectTextL.Add(rectT);
// If successful, try to re-fit the text
iPos = 0;
bDrawText = CheckOverlap(pDC, pMapLayer, sText, nX, nY, rect, iPos);
}
// If not-restore the overlapping text
else
{
m_aRectTextL.Add(rectT);
}
}
return bDrawText;
}
///////////////////////////////////////////////////////////////////////////////
//
// If symbols have the option - 'best fit' then the symbol will be moved to
// different locations until a position where it does not overlap is found
//
void CViewMap::CheckOverlapSym(CDC* pDC, double dSize, double& dX, double& dY)
{
BOOL bOverlap = TRUE;
CRect rectI, rect;
CPoint pt;
CPoint ptCoord((int) dX, (int) dY);
// Determine the rectangle
CSize sz = CComboBoxSymbol::GetSymSize(pDC, dSize*1.5);
for (int iPos = 1; iPos <= 9 && bOverlap; iPos++)
{
bOverlap = FALSE;
switch (iPos)
{
case 1:
pt.x = ptCoord.x - sz.cx; pt.y = ptCoord.y - sz.cy;
break;
case 2:
pt.x = ptCoord.x - sz.cx; pt.y = ptCoord.y + sz.cy;
break;
case 3:
pt.x = ptCoord.x + sz.cx; pt.y = ptCoord.y + sz.cy;
break;
case 4:
pt.x = ptCoord.x + sz.cx; pt.y = ptCoord.y - sz.cy;
break;
case 5:
pt.x = ptCoord.x; pt.y = ptCoord.y - sz.cy;
break;
case 6:
pt.x = ptCoord.x + sz.cx; pt.y = ptCoord.y;
break;
case 7:
pt.x = ptCoord.x; pt.y = ptCoord.y + sz.cy;
break;
case 8:
pt.x = ptCoord.x - sz.cx; pt.y = ptCoord.y;
break;
case 9:
pt.x = ptCoord.x; pt.y = ptCoord.y;
break;
}
rect.left = pt.x - sz.cx/2;
rect.right = pt.x + sz.cx/2;
rect.top = pt.y - sz.cx/2;
rect.bottom = pt.y + sz.cy/2;
// Check for overlap, do not display if string overlaps others
for (int i = 0; i < m_aRectSym.GetSize(); i++)
{
if (rectI.IntersectRect(rect, m_aRectSym[i]))
{
bOverlap = TRUE;
break;
}
}
};
m_aRectSym.Add(rect);
dX = (rect.right + rect.left)/2;
dY = (rect.top + rect.bottom)/2;
}
///////////////////////////////////////////////////////////////////////////////
//
// OLD retained for backwards compatibility
//
int CViewMap::GetLineWidth(CDC* pDC, CMapLayer* pMapLayer)
{
if (pMapLayer->GetLineStyle() == PS_SOLID)
{
return (int)(pMapLayer->GetLineWidth() * pDC->GetDeviceCaps(LOGPIXELSX) / MMPERINCH /3);
} else
{
return 1;
}
}
/////////////////////////////////////////////////////////////////////////////
int CViewMap::GetLineWidth(CDC* pDC, int nLineStyle, int nLineWidth)
{
if (nLineStyle == PS_SOLID)
{
return (int)(nLineWidth * pDC->GetDeviceCaps(LOGPIXELSX) / MMPERINCH /3);
} else
{
return 1;
}
}
/////////////////////////////////////////////////////////////////////////////
//
// World to screen
//
int CViewMap::GetfXPos(long a)
{
return (int)(((a - m_dOffX) * m_dZoom / (m_dMaxX - m_dMinX) + 0.5) * (m_rectA.right - m_rectA.left)+ m_rectA.left);
}
int CViewMap::GetfYPos(long a)
{
return (int)(m_rectA.Height() - (((a - m_dOffY) * m_dZoom / (m_dMaxY - m_dMinY) + 0.5) *
(m_rectA.bottom - m_rectA.top)) + m_rectA.top);
}
///////////////////////////////////////////////////////////////////////////////
//
// Screen to world
long CViewMap::GetfXInv(int a)
{
return (long)(((((double)a - m_rectA.left) / (m_rectA.right - m_rectA.left)) - 0.5) * (m_dMaxX - m_dMinX) / m_dZoom + m_dOffX);
}
long CViewMap::GetfYInv(int a)
{
return (long)((((m_rectA.Height() - ((double)a - m_rectA.top)) / (m_rectA.bottom - m_rectA.top)) - 0.5) * (m_dMaxY - m_dMinY) / m_dZoom + m_dOffY);
}
///////////////////////////////////////////////////////////////////////////////
void CViewMap::OnSize(UINT nType, int cx, int cy)
{
CBDView::OnSize(nType, cx, cy);
GetClientRect(&m_rect);
DetermineAspect();
}
///////////////////////////////////////////////////////////////////////////////
//
// Determine the aspect ratio for printing or for drawing
//
void CViewMap::DetermineAspect(CDC* pDC)
{
// Allow for different shaped pixels
if (pDC == NULL) pDC = GetDC();
// Correct for aspect ratio
m_rectA = m_rect;
double dAspect = (m_dMaxX - m_dMinX) / (m_dMaxY - m_dMinY);
dAspect *= (double)pDC->GetDeviceCaps(LOGPIXELSX) / pDC->GetDeviceCaps(LOGPIXELSY);
if ((m_rect.right - m_rect.left) / (m_dMaxX - m_dMinX) >
(m_rect.bottom - m_rect.top) / (m_dMaxY - m_dMinY))
{
double dWidth = m_rect.Height() * dAspect;
m_rectA.left = m_rect.left + (m_rect.Width() - (int)dWidth)/2;
m_rectA.right = m_rectA.left + (int)dWidth;
}
else
{
double dHeight = m_rect.Width() / dAspect;
m_rectA.top = m_rect.top + (m_rect.Height() - (int)dHeight)/2;
m_rectA.bottom = m_rectA.top + (int)dHeight;
}
}
///////////////////////////////////////////////////////////////////////////////
//
// Returns the current scale, e.g. 1:50,000
int CViewMap::GetScale(CDC* pDC)
{
CRect rect = m_rect;
if (pDC->IsPrinting())
{
rect = m_rectP;
}
if (m_bCopy)
{
SetCopyRect(pDC);
rect = m_rect;
}
// Determine the scale range in meters
int nMin = (int)GetfXInv(rect.left);
int nMax = (int)GetfXInv(rect.right);
double dWidthW = nMax - nMin;
// Determine width of rectangle in metres on the screen or printer
double dPixelsPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
double dWidthS = (rect.Width() / dPixelsPerInch) * MMPERINCH / 1000;
// Tidy up
if (m_bCopy)
{
GetClientRect(&m_rect);
};
if (dWidthS == 0) return 0;
else return (int)(dWidthW / dWidthS);
}
///////////////////////////////////////////////////////////////////////////////
void CViewMap::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_pDoc->GetLayers()->GetSize() == 0) return;
// Add new point to polygon or polyline
if (m_nMapMode == pan)
{
m_ptPan = point;
return;
}
// Add points to array of lines
if (m_nMapMode == measure)
{
CLongCoord coord;
coord.x = GetfXInv(point.x);
coord.y = GetfYInv(point.y);
m_aMeasure.Add(coord);
// Remove last point
if (m_ptMeasure1.x != -1)
{
CDC* pDC = GetDC(); // DC changes each time retrieved
int nOldROP = pDC->SetROP2(R2_NOTXORPEN );
pDC->MoveTo(m_ptMeasure2);
pDC->LineTo(m_ptMeasure1);
pDC->SetROP2(nOldROP);
m_ptMeasure1 = CPoint(-1,-1);
m_ptMeasure2 = CPoint(-1,-1);
}
// Update tape without redrawing entire map
DrawTapeMeasure(GetDC());
return;
}
if (m_pMapLinesEdit != NULL)
{
CLongCoord coord;
coord.x = GetfXInv(point.x);
coord.y = GetfYInv(point.y);
// Snap
if (nFlags & MK_CONTROL)
{
SnapPoint(point, coord);
}
EditPolylines(coord, TRUE);
return;
}
// Add new point
if (m_pMapCoordEdit != NULL)
{
m_pMapCoordEdit->x = GetfXInv(point.x);
m_pMapCoordEdit->y = GetfYInv(point.y);
EditMode(FALSE);
return;
}
// If drag mode is selected then allow controls to be dragged
if (m_bDragMode)
{
CMapLayerObj* pMapLayerObj = HitTest(point, m_pEditMapLayer);
if (pMapLayerObj != NULL && pMapLayerObj->GetDataType() == BDCOORD)
{
m_pMapLayer = m_pDoc->GetLayers()->GetAt(m_pDoc->GetLayers()->GetDefault());
m_pEditMapObj = pMapLayerObj;
}
}
// Otherwise create the tracker
else
{
CreateTracker(point);
};
CBDView::OnLButtonDown(nFlags, point);
}
///////////////////////////////////////////////////////////////////////////////
//
// Snaps the point to the nearest node in the current layer, excluding edited
// object
//
void CViewMap::SnapPoint(CPoint point, CLongCoord& rCoord)
{
double dDistMin = DBL_MAX;
CPoint point1;
CLongCoord coordMin;
ASSERT(m_pMapLayer != NULL);
for (int i = 0; i < m_pMapLayer->GetSize(); i++)
{
CMapLayerObj* pMapLayerObj = m_pMapLayer->GetAt(i);
ASSERT(pMapLayerObj->GetDataType() == BDMAPLINES);
// Don't snap to lines being edited
if (pMapLayerObj != m_pEditMapObj)
{
CLongLines* pMapLines = (CLongLines*)pMapLayerObj->GetMapObject();
for (int j = 0; j < pMapLines->GetSize(); j++)
{
CLongCoord coordE = pMapLines->GetAt(j);
if (!coordE.IsNull())
{
point1.x = GetfXPos(coordE.x);
point1.y = GetfYPos(coordE.y);
double dDist = square(point1.x - point.x)+square(point1.y-point.y);
if (dDist < dDistMin)
{
dDistMin = dDist;
coordMin = coordE;
}
}
}
}
}
if (dDistMin < square(4*NODESIZE))
{
rCoord = coordMin;
}
}
///////////////////////////////////////////////////////////////////////////////
void CViewMap::EditPolylines(CLongCoord coord, BOOL bAdd)
{
CRect rect = CRect(0,0,0,0); // Refresh rect
CPoint point, point1;
CArray <CLongCoord, CLongCoord> aUpdate;
if (bAdd)
{
// If clicking on a node then select it
int iClosest = -1;
double dDistMin = DBL_MAX;
if (m_pMapLinesEdit->GetSize() > 0)
{
aUpdate.Add(m_pMapLinesEdit->GetAt(m_iEditPoint1));
aUpdate.Add(m_pMapLinesEdit->GetAt(m_iEditPoint2));
point.x = GetfXPos(coord.x);
point.y = GetfYPos(coord.y);
for (int i = 0; i < m_pMapLinesEdit->GetSize(); i++)
{
CLongCoord coordE = m_pMapLinesEdit->GetAt(i);
if (!coordE.IsNull())
{
point1.x =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -