VC++开发GIS系统(170)选择线之类的实现

前文VC++开发GIS系统(169)选择线之类的定义介绍了选择线类的定义,本文继续介绍这个类人实现方法。代码如下:

类的实现

在_malaLines.cpp中实现上述代码,如下:

/*
* 选择线实现
*/
vector<malaPoint> CmalaLinesSelect::mLine;
malaLinePro CmalaLinesSelect::mLinePro;
CView* CmalaLinesSelect::m_StaticView = NULL;
malaScreen* CmalaLinesSelect::m_Screen = NULL;

CmalaLinesSelect::CmalaLinesSelect()
{

}

CmalaLinesSelect::CmalaLinesSelect(CView* mView, malaScreen *pScreen, CString &fileFullPath)
{
    mBaseView = mView;
    m_StaticView = mView;
    mPath = fileFullPath;

    m_bDraw = FALSE;
    m_Selected = FALSE;
    m_Screen = pScreen;
}

CmalaLinesSelect::~CmalaLinesSelect()
{

}

void CmalaLinesSelect::LButtonDown(UINT nFlags, malaPoint point)
{
    m_bDraw = TRUE;
    m_ptOrigin = m_perPoint = point;
}

void CmalaLinesSelect::LButtonUp(UINT nFlags, malaPoint point)
{
    m_bDraw = FALSE;
    malaCDC dc(mBaseView, *m_Screen);
    dc.drawRectNULLFill(m_ptOrigin, point);
    if (m_ptOrigin.x > point.x)
    {
        m_rect.xmax = m_ptOrigin.x;
        m_rect.xmin = point.x;
    }
    else
    {
        m_rect.xmin = m_ptOrigin.x;
        m_rect.xmax = point.x;
    }

    if (m_ptOrigin.y > point.y)
    {
        m_rect.ymax = m_ptOrigin.y;
        m_rect.ymin = point.y;
    }
    else
    {
        m_rect.ymin = m_ptOrigin.y;
        m_rect.ymax = point.y;
    }
    //先获取所有符合条件的点
    CLineIO pio;
    vector<malaLineFile>allLines;
    pio.getAllLines(*m_Screen, allLines, mPath);
    //再查找是否被选中
    malaLogic tlog;
    for (size_t j = 0; j < allLines.size(); j++)
    {
        //先获取一条线的外接矩形
        if (tlog.isLineInRect(m_rect, allLines[j].mLine))
        {
            mLine = allLines[j].mLine;
            mLinePro = allLines[j].mLinePro;
            
            SetTimer(mBaseView->m_hWnd, 1, 500, TimerLine);
            if (MessageBox(mBaseView->m_hWnd, L"选择该线吗?", L"提示", MB_YESNO | MB_ICONQUESTION) == IDYES)
            {
                malaCDC dc(mBaseView, *m_Screen);
                dc.lineDrawAll(mLine, mLinePro);
                KillTimer(mBaseView->m_hWnd, 1);
                //绘制选中标志
                for (size_t k = 0; k < mLine.size(); k++)
                {
                    malaPointPro tpPointPro;
                    tpPointPro.pointRadio = mLinePro.lineWidth+2;
                    tpPointPro.pointColor = mLinePro.lineColor;
                    
                    dc.drawSelectRectPoint(mLine[k], tpPointPro);
                }
                
                m_Selected = TRUE;
                break;
            }
            malaCDC dc(mBaseView, *m_Screen);
            dc.lineDrawAll(mLine, mLinePro);
            KillTimer(mBaseView->m_hWnd, 1);
            //mBaseView->InvalidateRect(CRect(A, B), TRUE);
        }
    }
}

void CmalaLinesSelect::MouseMove(UINT nFlags, malaPoint point)
{
    if (m_bDraw)
    {
        malaCDC dc(mBaseView, *m_Screen);
        dc.drawRectNULLFill(m_ptOrigin, m_perPoint);
        dc.drawRectNULLFill(m_ptOrigin, point);
        m_perPoint = point;
    }
}

代码解析

因为定义了静态变量,所以在类的实现的时候需要先赋值

vector<malaPoint> CmalaLinesSelect::mLine;
malaLinePro CmalaLinesSelect::mLinePro;
CView* CmalaLinesSelect::m_StaticView = NULL;
malaScreen* CmalaLinesSelect::m_Screen = NULL;

关于静态变量,推荐参考:C++中Static作用和使用方法。这里实现的橡皮筋绘图和放大地图中所用的一致,可以参考:VC++开发GIS系统(110)放大地图之简析橡皮筋绘图

这里比较关键的是在LButtonUp的时候,先获取当前所有的线,并遍历所有的线。如果点在所拉矩形框中(用到了isLineInRect函数,参考:VC++开发GIS系统(168)选择线之判断折线与矩形相交算法),使用SetTimer,每隔500ms调用一次函数TimerLine,实现线的闪烁。如果是要选中的线,则使用KillTimer关闭闪烁,然后使用依次调用drawSelectRectPoint函数绘制出线的骨骼(也就是线的每一个节点),实现机理可以参考文章《VC++开发GIS系统(126)选择点之闪烁原理及实现

最后效果如下:

详细代码可以参考:GitHub

VC++开发GIS系统(169)选择线之类的定义 VC++开发GIS系统(171)选择线之菜单响应

作者:,GIS爱好者。
分享本文,请您带上本文链接
分享到:

发表评论