VC++开发GIS系统(220)选择区之类的定义及实现

前文介绍了GIS中的2个常用的算法:判断矩形是否与多边形相交判断直线是否与多边形相交,本文利用这2个算法实现选择区。

类的定义

在_malaPolygon.h中定义下面的类

/*
* 选择区
*/
class malapolygondll CmalaPolysSelect :public CmalaMouseAction
{
public:
    CmalaPolysSelect();
    CmalaPolysSelect(CView* mView, malaScreen *pScreen, CString &fileFullPath);
    ~CmalaPolysSelect();
    void LButtonDown(UINT nFlags, malaPoint point);
    void LButtonUp(UINT nFlags, malaPoint point);
    void MouseMove(UINT nFlags, malaPoint point);

public:
    malaRect m_rect;
    malaPoint m_ptOrigin;
    malaPoint m_perPoint;
    static vector<malaPoint> mSPoly;//存放当前编辑的区;
    static malaPolyPro mSPolyPro;//存放当前编辑的区属性
    static malaScreen *m_Screen;
    static CView* m_StaticView;

    CString mPath;//文件路径
    bool m_bDraw;
    bool m_Selected;
public:

    inline static void CALLBACK TimerPoly(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
    {
        malaCDC dc(m_StaticView, *m_Screen);
        dc.polyDrawAutoX(mSPoly, mSPolyPro);
    }
};

其中这里和文章《VC++开发GIS系统(127)选择点类的设计》《VC++开发GIS系统(128)选择点类的实现》实现的机理很相似,在这里就不做过多的介绍了,如有什么问题可以在本文留言。其中这里也用到了一个回调函数,可以参考:VC++开发GIS系统(125)选择点之CALLBACK回调函数

类的实现

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

/*
* 选择区实现
*/
vector<malaPoint> CmalaPolysSelect::mSPoly;
malaPolyPro CmalaPolysSelect::mSPolyPro;
CView* CmalaPolysSelect::m_StaticView = NULL;
malaScreen* CmalaPolysSelect::m_Screen = NULL;

CmalaPolysSelect::CmalaPolysSelect()
{

}

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

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

CmalaPolysSelect::~CmalaPolysSelect()
{

}

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

void CmalaPolysSelect::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;
    }
    //先获取所有符合条件的区
    CPolyIO pio;
    vector<malaPolyFile>allPolys;
    pio.getAllPolys(*m_Screen, allPolys, mPath);
    //再查找是否被选中
    malaLogic tlog;
    for (size_t j = 0; j < allPolys.size(); j++)
    {
        if ((allPolys[j].mPolyPro.polyStyle == 0 && tlog.isPolyInRect(m_rect, allPolys[j].mPoly)) || (allPolys[j].mPolyPro.polyStyle == 1 && tlog.isRectIntersect(m_rect,tlog.getRect(allPolys[j].mPoly))))
        {
            mSPoly = allPolys[j].mPoly;
            mSPolyPro = allPolys[j].mPolyPro;

            SetTimer(mBaseView->m_hWnd, 1, 500, TimerPoly);
            if (MessageBox(mBaseView->m_hWnd, L"选择该区吗?", L"提示", MB_YESNO | MB_ICONQUESTION) == IDYES)
            {
                malaCDC dc(mBaseView, *m_Screen);
                dc.polyDrawAuto(mSPoly, mSPolyPro);
                KillTimer(mBaseView->m_hWnd, 1);
                //绘制选中标志
                for (size_t k = 0; k < mSPoly.size(); k++)
                {
                    malaPointPro tpPointPro;
                    tpPointPro.pointRadio = mSPolyPro.borderWidth + 2;
                    tpPointPro.pointColor = mSPolyPro.borderColor;

                    dc.drawSelectRectPoint(mSPoly[k], tpPointPro);
                }
                if (mSPolyPro.polyStyle == 1)
                {
                    malaPolyPro tpolypro = mSPolyPro;
                    tpolypro.fillColor = RGB(0, 139, 139);
                    tpolypro.borderColor = RGB(255, 0, 0);
                    tpolypro.borderStyle = 0;
                    tpolypro.fillStyle = 6;
                    dc.polyDraw(mSPoly, tpolypro);
                }
                m_Selected = TRUE;
                break;
            }
            KillTimer(mBaseView->m_hWnd, 1);
        }
    }
}

void CmalaPolysSelect::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;
    }

}

这里主要实现的功能还是选中的线闪烁,确认选择后,绘制出线的骷髅(也就是线的每一个节点),实现机理可以参考文章《VC++开发GIS系统(126)选择点之闪烁原理及实现

效果如下:

详细代码可以参考:GitHub

VC++开发GIS系统(219)判断矩形是否与多边形相交 VC++开发GIS系统(221)选择区之菜单响应

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

发表评论