📄 viewmap.cpp
字号:
mapstyle.m_crLine = RGB(255,0,0);
}
CPen pen(mapstyle.m_nLineStyle, GetLineWidth(pDC,mapstyle.m_nLineStyle, mapstyle.m_nLineWidth), mapstyle.m_crLine);
CPen* pPenOld = pDC->SelectObject(&pen);
// Create brush
CBrush brush;
CComboBoxPattern::CreateBrush(brush, mapstyle.m_nPattern, mapstyle.m_nHatch, mapstyle.m_crFill);
CBrush* pBrushOld = pDC->SelectObject(&brush);
// Set the background mode to transparent
pDC->SetBkMode(TRANSPARENT);
CLongLines* pMapLines = (CLongLines*)pMapLayerObj->GetMapObject();
// Plot the coordinates
for (int i = 0; i < pMapLines->GetSize(); i++)
{
CLongCoord coord = pMapLines->GetAt(i);
if (!coord.IsNull())
{
point.x = (int)GetfXPos(coord.x);
point.y = (int)GetfYPos(coord.y);
if (aPoints.GetSize() == 0 || CPoint(aPoints[aPoints.GetSize()-1]) != CPoint(point))
{
aPoints.Add(point);
// Clip polylgons
if (!m_bWinNT && pMapLayer->GetPolygon())
{
aPoints.RemoveAll();
ClipPolygon(i, pMapLines, aPoints);
bNewLine = TRUE;
}
// Clip polylines
if (!m_bWinNT && !pMapLayer->GetPolygon() && aPoints.GetSize() > 1)
{
int n = aPoints.GetSize();
ClipToRect(m_rect,aPoints[n-2].x, aPoints[n-1].x, aPoints[n-2].y, aPoints[n-1].y,
nClipped, bOut);
if (!bOut)
{
aPoints.RemoveAll();
aPoints.Add(point);
};
if (nClipped & ClippedTo)
{
bNewLine = TRUE;
}
}
}
}
if (bNewLine || coord.IsNull() || i+1 == pMapLines->GetSize())
{
// Draw polylines
if (aPoints.GetSize() > 1)
{
// If polygon is too long for win98 then draw it as a polyline
if (pMapLayer->GetPolygon())
{
// Support for multi-part polygons
aPolyPoints.Append(aPoints);
aPolyCounts.Add(aPoints.GetSize());
} else
{
DrawLines(pDC, aPoints.GetData(), aPoints.GetSize());
};
};
// Tidy up
aPoints.RemoveAll();
if (!coord.IsNull()) aPoints.Add(point);
bNewLine = FALSE;
}
};
// Plot the multipart polygons
if (pMapLayer->GetPolygon() && aPolyPoints.GetSize() > 0)
{
BOOL bOK = TRUE;
if (aPolyCounts.GetSize() > 1)
{
bOK = pDC->PolyPolygon(aPolyPoints.GetData(), aPolyCounts.GetData(), aPolyCounts.GetSize());
} else
{
bOK = pDC->Polygon(aPolyPoints.GetData(), aPolyPoints.GetSize());
}
// If drawing a polygon fails draw as a polyline
if (!bOK)
{
POINT* pPoints = aPolyPoints.GetData();
for (int i = 0; i < aPolyCounts.GetSize(); i++)
{
DrawLines(pDC, pPoints, aPolyCounts[i]);
pPoints += aPolyCounts[i];
};
}
}
// Tidy up
pDC->SetBkMode(OPAQUE);
pDC->SelectObject(pPenOld);
pDC->SelectObject(pBrushOld);
}
///////////////////////////////////////////////////////////////////////////////
void CViewMap::DrawLines(CDC* pDC, POINT* pPoints, int nPoints)
{
// For Win95/98/ME must split into parts. For device contexts not supporting wide lines,
// the parts must be even smaller
if (!m_bWinNT)
{
int nSizeT = nPoints;
int nSize = min(nSizeT, m_bWideLine ? WIDELINELEN : WIN98POLYLINE);
while (nSize > 0)
{
pDC->Polyline(pPoints, nSize);
pPoints += nSize;
nSizeT -= nSize;
nSize = min(nSizeT, m_bWideLine ? WIDELINELEN : WIN98POLYLINE);
}
} else
{
pDC->Polyline(pPoints, nPoints);
};
}
///////////////////////////////////////////////////////////////////////////////
//
// Draw lines whilst editing
//
void CViewMap::DrawMapEditLines(CDC* pDC, CLongLines* pMapLines, CMapLayer* pMapLayer)
{
CPoint point, point1;
// First create the current pen
CMapStyle mapstyle;
GetStyle(pMapLayer, m_pEditMapObj, 0, mapstyle);
COLORREF crPen1 = mapstyle.m_crLine;
COLORREF crPen2 = RGB(255-GetRValue(crPen1),255-GetGValue(crPen1),255-GetBValue(crPen1));
if (crPen2 == RGB(255,255,255)) crPen2 = RGB(255,0,0);
CPen pen1(pMapLayer->GetLineStyle(), GetLineWidth(pDC,pMapLayer), crPen1);
CPen pen2(pMapLayer->GetLineStyle(), GetLineWidth(pDC,pMapLayer), crPen2);
CPen* pPenOld = pDC->SelectObject(&pen1);
// Now draw the lines (don't worry about clipping?)
for (int i = 0; i < pMapLines->GetSize(); i++)
{
if (!pMapLines->GetAt(i).IsNull())
{
CLongCoord coord = pMapLines->GetAt(i);
point.x = (int)GetfXPos(coord.x);
point.y = (int)GetfYPos(coord.y);
// Draw a cross at each point
DrawNode(pDC, point);
// Draw a line from the last point
if (i > 0 && !pMapLines->GetAt(i-1).IsNull())
{
pDC->MoveTo(point1.x, point1.y);
pDC->LineTo(point.x, point.y);
}
point1 = point;
};
}
// Reset pen
pDC->SelectObject(pPenOld);
pPenOld = pDC->SelectObject(&pen2);
// Draw the selected points in different colour at end so not overpainted
// for polygons
if (pMapLines->GetSize() > 0)
{
if (!pMapLines->GetAt(m_iEditPoint1).IsNull())
{
CLongCoord coord = pMapLines->GetAt(m_iEditPoint1);
point.x = (int)GetfXPos(coord.x);
point.y = (int)GetfYPos(coord.y);
DrawNode(pDC, point);
if (pMapLines->GetSize() > m_iEditPoint2 &&
!pMapLines->GetAt(m_iEditPoint2).IsNull())
{
CLongCoord coord = pMapLines->GetAt(m_iEditPoint2);
point1.x = (int)GetfXPos(coord.x);
point1.y = (int)GetfYPos(coord.y);
pDC->MoveTo(point1.x, point1.y);
pDC->LineTo(point.x, point.y);
};
};
};
// Tidy up
pDC->SelectObject(pPenOld);
}
///////////////////////////////////////////////////////////////////////////////
void CViewMap::DrawWireFrame(CDC *pDC, CMapLayer *pMapLayer, CMapLayerObj *pMapLayerObj)
{
GetExtent(pMapLayer, pMapLayerObj);
CRect rectE = pMapLayerObj->GetExtent();
CRect rect;
rect.left = GetfXPos(rectE.left);
rect.top = GetfYPos(rectE.top);
rect.right = GetfXPos(rectE.right);
rect.bottom = GetfYPos(rectE.bottom);
DrawRect(pDC, &rect, pMapLayer->GetColourLine(), PS_DOT, 1);
}
///////////////////////////////////////////////////////////////////////////////
void CViewMap::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
BOOL bAdjust = TRUE;
// Handle keys whilst editing
if (m_pMapLinesEdit != NULL)
{
if (nChar == VK_LEFT)
{
if (m_iEditPoint1-1 >= 0 && !m_pMapLinesEdit->GetAt(m_iEditPoint1-1).IsNull()) m_iEditPoint1--;
if ((m_iEditPoint2-1 > m_iEditPoint1 || m_iEditPoint1 == 0) &&
m_iEditPoint2-1 >= 0) m_iEditPoint2--;
}
if (nChar == VK_RIGHT)
{
if (m_iEditPoint2+1 < m_pMapLinesEdit->GetSize() && !m_pMapLinesEdit->GetAt(m_iEditPoint2+1).IsNull()) m_iEditPoint2++;
if (!(m_iEditPoint1 == 0 && m_iEditPoint2 == 1) &&
m_iEditPoint1+1 < m_pMapLinesEdit->GetSize() && !m_pMapLinesEdit->GetAt(m_iEditPoint1+1).IsNull()) m_iEditPoint1++;
}
else if (nChar == VK_DELETE)
{
EditPolylines(CLongCoord(), FALSE);
}
else if (nChar == VK_INSERT)
{
if (m_pMapLinesEdit->GetSize() > 0)
{
m_iEditPoint1 = m_pMapLinesEdit->GetSize()-1;
if (!m_pMapLinesEdit->GetAt(m_iEditPoint1).IsNull())
{
CLongCoord coord;
coord.SetNull();
m_pMapLinesEdit->InsertAt(m_iEditPoint1, coord);
m_iEditPoint1++;
}
m_iEditPoint2 = m_iEditPoint1;
bAdjust = FALSE;
};
}
// For polygons, ensure that m_iEditPoint1 <> m_iEditPoint2 i.e. cannot add
// a point to the end of the polygon
if (bAdjust) AdjustEditParams();
// Update view
DrawMapEditLines(GetDC(), m_pMapLinesEdit, m_pEditMapLayer);
};
CBDView::OnKeyDown(nChar, nRepCnt, nFlags);
}
///////////////////////////////////////////////////////////////////////////////
//
// Determines if the current maplines need to be drawn in the current view
//
BOOL CViewMap::IsVisible(CDC* pDC, CMapLayerObj *pMapLayerObj, BOOL bText)
{
CRect rect, rectI, rectV;
CRect& rectE = pMapLayerObj->GetExtent();
if (rectE.left == 0 && rectE.right == 0) return FALSE;
rect.left = (int)GetfXPos(rectE.left);
rect.top = (int)GetfYPos(rectE.top);
rect.right = (int)GetfXPos(rectE.right);
rect.bottom = (int)GetfYPos(rectE.bottom);
if (rect.top > rect.bottom) swap(rect.top, rect.bottom);
if (rect.left == rect.right) rect.right++;
if (rect.top == rect.bottom) rect.bottom++;
rectV = m_rect;
// Text not included in extent so isn't redrawn if use m_rectPaint
if (!bText && m_rectPaint.left != m_rectPaint.right && !pDC->IsPrinting()) rectV = m_rectPaint;
return rectI.IntersectRect(rect, rectV);
}
/////////////////////////////////////////////////////////////////////////////
//
// Clip the polygon to the display rectangle
//
//
void CViewMap::ClipPolygon(int& iPos, CLongLines* pMapLines, CArray <POINT, POINT>& aPoints)
{
CPoint point1, point2, point;
BOOL bOut;
int nClipped;
CArray <POINT, POINT> aClipPoints;
// Copy data to aPoints
while (iPos < pMapLines->GetSize() && !pMapLines->GetAt(iPos).IsNull())
{
CLongCoord coord = pMapLines->GetAt(iPos++);
point.x = (int)GetfXPos(coord.x);
point.y = (int)GetfYPos(coord.y);
if (aPoints.GetSize() == 0 || CPoint(aPoints[aPoints.GetSize()-1]) != CPoint(point))
{
aPoints.Add(point);
};
}
// If line does not form a polygon then add first point to end
if (CPoint(aPoints[0]) != CPoint(aPoints[aPoints.GetSize()-1]))
{
aPoints.Add(aPoints[0]);
}
// Optimization
aClipPoints.SetSize(aPoints.GetSize());
// Need to have two buffers as the clipped version may be larger than the
// previous. In order to be efficient, these are swapped at the end of
// each loop
// Clip to each edge separately
for (int j = 1; j <= 4; j++)
{
int k = 0;
for (int i = 0; i < aPoints.GetSize(); i++)
{
point2 = aPoints[i];
point = point2; // Unclipped
if (i > 0)
{
// Clip to each vertex
if (j == clipright) ClipToLine(point1.x, point1.y, point2.x, point2.y, m_rect.right, clipright, nClipped, bOut);
else if (j == clipleft) ClipToLine(point1.x, point1.y, point2.x, point2.y, m_rect.left, clipleft, nClipped, bOut);
else if (j == cliptop) ClipToLine(point1.y, point1.x, point2.y, point2.x, m_rect.top, cliptop, nClipped, bOut);
else if (j == clipbottom) ClipToLine(point1.y, point1.x, point2.y, point2.x, m_rect.bottom, clipbottom, nClipped, bOut);
// Add points to array
if (bOut)
{
if (nClipped & ClippedFrom)
{
aClipPoints.SetAtGrow(k++, point1);
}
aClipPoints.SetAtGrow(k++, point2);
}
};
point1 = point;
};
if (k > 0)
{
aClipPoints.SetAtGrow(k++, aClipPoints[0]);
};
// Copy the array onto the next loop
aClipPoints.SetSize(k);
aPoints.Copy(aClipPoints);
}
}
/////////////////////////////////////////////////////////////////////////////
//
// Draws the text associated with map lines or coordinates
//
void CViewMap::DrawLineText(CDC* pDC, CMapLayer* pMapLayer)
{
BOOL bDrawText = TRUE;
// Determine the color
if (pMapLayer->GetTextPos() == -1)
{
bDrawText = FALSE;
}
if (bDrawText)
{
for (int j = 0; j < pMapLayer->GetSize(); j++)
{
CMapLayerObj* pMapLayerObj = pMapLayer->GetAt(j);
// Optimization, don't attempt to fit if no text
if (pMapLayerObj->GetText()[0] != '\0' && IsVisible(pDC, pMapLayerObj, TRUE))
{
// Draw any associated text
CLongLines* pMapLines = NULL;
if (pMapLayerObj->GetDataType() == BDMAPLINES)
{
pMapLines = (CLongLines*)pMapLayerObj->GetMapObject();
}
if (pMapLines == NULL || pMapLines->GetSize() > 0)
{
int x = GetfXPos(pMapLayerObj->GetCentreX());
int y = GetfYPos(pMapLayerObj->GetCentreY());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -