麻辣GIS微信平台

更多 GIS 干货

微信关注不错过

VC++开发GIS系统(189)线上移点之类的设计及实现

继续VC++开发GIS系统的工作,本文介绍的是一个新的功能:线上移点。效果如图:

功能分析

  1. 选择一条线
  2. 左键选中一个线节点
  3. 按住选中的点移动,调用橡皮筋绘图
  4. 松开左键,记录下新的点的位置,并调用 lineUpdate

类的定义

在_malaLines.h中定义线上移点的类,代码如下:

/*
*线上移点
*/
class malalinesdll CmalaLinesMovePoint :public CmalaMouseAction
{
public:
    CmalaLinesMovePoint(CView* mView, malaScreen *pScreen, CString &fileFullPath);
    virtual ~CmalaLinesMovePoint();
    void LButtonDown(UINT nFlags, malaPoint point);
    void LButtonUp(UINT nFlags, malaPoint point);
    void MouseMove(UINT nFlags, malaPoint point);
private:
    bool m_Selected;
    vector<malaPoint>m_line;
    malaLinePro m_linepro;
    CmalaLinesSelect m_SelectLine;

    bool m_bDraw;
    bool m_Double;//标记是否是起点
    int m_Pos;
    malaPoint mPerPoint;//临时点

    malaScreen *m_Screen;
    CString mPath;//文件路径
};
  • m_Selected 用来定义线是否被选中
  • mSLine 记录选择的线
  • mSLinePro 记录选择线的属性
  • m_SelectLine 一个选择线对象,用来选择线
  • m_bDraw 记录左键是否按下
  • m_Double 标记是否是起点
  • m_Pos 记录点的序列位置
  • *m_Screen 屏幕坐标变换变量
  • mPath 文件路径

类的实现

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

/*
* 线上移点实现
*/
CmalaLinesMovePoint::CmalaLinesMovePoint(CView* mView, malaScreen *pScreen, CString &fileFullPath)
{
    mBaseView = mView;
    mPath = fileFullPath;
    m_Screen = pScreen;
    CmalaLinesSelect obj(mView, pScreen, fileFullPath);
    m_SelectLine = obj;
    m_Selected = FALSE;
    m_bDraw = FALSE;
    m_Pos = 0;
    m_Double = TRUE;
}

CmalaLinesMovePoint::~CmalaLinesMovePoint()
{
    if (m_line.size())
        m_line.clear();
}

void CmalaLinesMovePoint::LButtonDown(UINT nFlags, malaPoint point)
{
    if (!m_Selected)
        m_SelectLine.LButtonDown(nFlags, point);
    else
    {
        malaLogic math;
        m_Pos = math.getPointPosInLine(point, m_line);
        if (m_Pos >= 0)
        {
            m_bDraw = TRUE;
            if (m_Pos == 0)
            {
                m_Double = FALSE;
                mPerPoint = m_line[m_Pos + 1];
            }
            if (m_Pos == m_line.size() - 1)
            {
                m_Double = FALSE;
                mPerPoint = m_line[m_Pos - 1];
            }
            if (m_Double)
            {
                mPerPoint = m_line[m_Pos];
                //m_perPoint2 = m_line[m_Pos + 1];
            }
        }
    }
}

void CmalaLinesMovePoint::LButtonUp(UINT nFlags, malaPoint point)
{
    if (!m_Selected)
        m_SelectLine.LButtonUp(nFlags, point);

    if (m_bDraw)
    {
        m_bDraw = FALSE;
        m_line[m_Pos] = point;

        CLineIO lio;
        lio.lineUpdate(m_line, m_linepro, mPath);

        m_line.clear();
        m_SelectLine.m_Selected = FALSE;
        m_Double = TRUE;//+
        mBaseView->Invalidate(TRUE);//+
    }
    m_Selected = m_SelectLine.m_Selected;
    if (m_Selected)
    {
        m_line  = m_SelectLine.mLine;
        m_linepro = m_SelectLine.mLinePro;
    }
}

void CmalaLinesMovePoint::MouseMove(UINT nFlags, malaPoint point)
{
    malaCDC dc(mBaseView, *m_Screen);
    if (!m_Selected)
        m_SelectLine.MouseMove(nFlags, point);
    if (m_bDraw)
    {
        if (m_Double)
        {
            dc.lineDrawX(m_line[m_Pos - 1], mPerPoint, m_linepro);
            dc.lineDrawX(m_line[m_Pos - 1], point, m_linepro);

            dc.lineDrawX(m_line[m_Pos + 1], mPerPoint, m_linepro);
            dc.lineDrawX(m_line[m_Pos + 1], point, m_linepro);
        }
        else
        {
            if (m_Pos == 0)
            {
                dc.lineDrawX(m_line[m_Pos + 1], mPerPoint, m_linepro);
                dc.lineDrawX(m_line[m_Pos + 1], point, m_linepro);
            }
            else
            {
                dc.lineDrawX(m_line[m_Pos - 1], mPerPoint, m_linepro);
                dc.lineDrawX(m_line[m_Pos - 1], point, m_linepro);
            }
        }

        mPerPoint  = point;
    }
}

文中调用的 lineUpdate 函数可以参考文章《VC++开发GIS系统(173)移动线之更新一条线的属性函数定义及实现》。主要用来更新一条线的属性。

lineDrawX 函数可以参考文章《VC++开发GIS系统(152)输入线之画直线的函数》,主要用来橡皮筋绘图。

getPointPosInLine 函数可以参考文章《VC++开发GIS系统(188)线上移点之获取点在线的位置》,主要用于获取选中的点在线上的位置。

m_Pos 主要用来判断选中的点是不是起始点或者终点,这种情况下橡皮筋绘图要特殊处理。

m_Double 用来判断组成线的点的数量,小于等于2的时候要特殊处理。

详细代码可以参考:GitHub

相关阅读

麻辣GIS-Sailor

作者:

GIS爱好者,学GIS,更爱玩GIS。

声明

1.本文所分享的所有需要用户下载使用的内容(包括但不限于软件、数据、图片)来自于网络或者麻辣GIS粉丝自行分享,版权归该下载资源的合法拥有者所有,如有侵权请第一时间联系本站删除。

2.下载内容仅限个人学习使用,请切勿用作商用等其他用途,否则后果自负。

手机阅读
公众号关注
知识星球
手机阅读
麻辣GIS微信公众号关注
最新GIS干货
关注麻辣GIS知识星球
私享圈子

留言板(小编看到第一时间回复)