0
点赞
收藏
分享

微信扫一扫

SkeyeGisMap地图扩展(一)

1、扩展地图

  • 1、注意事项:
    在任何时候都不要直接操作地图节点(即 ​​Map*Node​​ ), 因为地图节点位于渲染线程。
    要操作地图节点, 正确的做法有三种:
  • 自定义节点:

可将节点继承 ​​QObject​​, 然后使用线程安全的信号槽操作即可。

  • 自定义事件:

继承 ​​MapEvent​​​ 并使用 ​​MapItem::pushEvent()​​​ 推送到地图中, 然后在 ​​processUserEvent()​​ 中处理事件。

  • 适当加锁来保证操作为线程安全即可, 但阻塞渲染线程通常不是一个好主意。
  • 2、继承 ​​MapItem​​:
    ​MapItem​​ 有两个虚函数, 这两个函数调用位于渲染线程:
  • ​void preLoadProcess()​​: 预加载处理{每次重新加载地图时触发}。

要启用它需要 ​​setProcessFlag(ProcessFlag::UsePreLoadProcess, true);​

  • ​void processUserEvent(MapEvent *)​​: 处理用户事件, 对于用户自定义事件时会调用它。

要启用它需要 ​​setProcessFlag(ProcessFlag::UseUserEvent, true);​

  • 3、使用图层管理形状:
    在 ​​MapItem​​ 中有一个根节点 ​​MapRootNode​​, 它是整个地图的根, 要获取它请使用 ​​MapItem::rootMap()​​ 。
    ​MapRootNode​​​ 不负责管理任何形状节点, 它只负责管理图层。
    其中, 有两种类型的图层:
  • 世界图层 ​​WorldLayer​

世界图层即无关任何地图变换的图层, 因此, 如果使用此图层则用户必须自己处理变换。

另外, 所有世界图层位于变换图层之上(视觉层级)。

  • 变换图层 ​​TransformLayer​

变换图层即包含所有地图变换的图层, 因此, 如果使用此图层则所有形状都会包含地图变换。

地图的变换矩阵使用 ​​MapRootNode::transformMatrix()​​ 获取。

而地图图层负责管理形状, 要向其中添加形状请使用 ​​MapLayerNode::appendShape()​​。

2、添加形状

想要在 ​​SkeyeGisMap​​​ 中添加形状, 必须扩展地图, 因此我们先继承 ​​MapItem​​:

class AddShapeExample: public MapItem
{
public:
AddShapeExample()
{
setProcessFlag(MapItem::ProcessFlag::UsePreLoadProcess);
}

virtual void preLoadProcess() override
{
auto assistant = rootMap()->assistant();

//创建一个矩形
auto leftTop = assistant->mapToDisplay(CoordinateReference::lonlatToWorld({ 40.0365, 90.7359 }));
auto leftBottom = assistant->mapToDisplay(CoordinateReference::lonlatToWorld({ 24.9160, 94.8131 }));
auto rightTop = assistant->mapToDisplay(CoordinateReference::lonlatToWorld({ 43.1443, 116.2369 }));
auto rightBottom = assistant->mapToDisplay(CoordinateReference::lonlatToWorld({ 26.7637, 116.6262 }));
QPolygonF polygon;
polygon << leftTop << leftBottom << rightBottom << rightTop << leftTop;

//添加到最后一个图层中
auto lastLayer = rootMap()->lastLayer();
if (lastLayer)
lastLayer->appendShape(new MapPolygonNode(polygon, Qt::black, 2, QColor("#a0b80000")));
}
};

我们在 ​​preLoadProcess()​​ 中添加形状:

首先是矩形的四个点, 我们先用 ​​CoordinateReference::lonlatToWorld()​​​ 将经纬度转换为世界坐标, 然后使用 ​​MapAssistant::mapToDisplay()​​ 将世界坐标转换为显示坐标。

注意: ​​CoordinateReference::lonlatToWorld()​​的参数, x为纬度, y为经度。

接着我们获取到最后一个图层 ​​rootMap()->lastLayer()​​​, 创建 ​​MapPolygonNode​​ 多边形节点加入进去即可。

3、效果展示

SkeyeGisMap地图扩展(一)_线程安全

源码地址: ​​https://gitee.com/visual-opening/skeyegismap/tree/master/coremap/example​​

举报

相关推荐

0 条评论