2021-07-02 Qt Location开发系列教程 (三)

系列文章目录

2021-07-01 Qt Location开发系列教程 (一)
2021-07-01 Qt Location开发系列教程 (二)


前言

本章讲在map上绘制图形

一、绘制的几种方案

  • 使用Qt location 提供的绘制方法: MapPolygon MapPolyline MapRectangle MapCircle 更多可查看 官方手册 https://doc.qt.io/qt-5/qtlocation-qmlmodule.html

  • 另外也可以Map 绘制 qml 元素,如任意基于item的控件都可以添加到地图中,且可以随地图一起移动

二、使用步骤

1.绘制圆(点) MapCircle

import QtQuick 2.0
import QtQuick.Window 2.14
import QtLocation 5.6
import QtPositioning 5.6

Window {
    visible: true
    width: 800
    height: 600
    Map {
        id:map
        anchors.fill: parent
        plugin: Plugin { name: "esri" }
        center: QtPositioning.coordinate(34.23,108.87) // Oslo
        zoomLevel: 14
        Component.onCompleted: {
            for(let i = 0;i < supportedMapTypes.length;i++)
            {
                console.log(supportedMapTypes[i].name)
                if(supportedMapTypes[i].name === "World Imagery")
                {
                    activeMapType = supportedMapTypes[i];
                    break
                }
            }
            console.log("activeMapType: " + activeMapType.name)

            //添加一个圆
            map.addMapItem(circle)
        }
    }

    MapCircle {
        id: circle
        center: QtPositioning.coordinate(34.23,108.87)
        radius: 200000
        border.width: 3

		//鼠标按住后可移动
        MouseArea {
            anchors.fill: parent
            drag.target: parent
        }
    }
}

在这里插入图片描述
如果要添加一个点,可将圆的半径设置 为点的半径,设置圆颜色即可

    MapCircle {
        id: circle
        center: QtPositioning.coordinate(34.23,108.87)
        radius: 10
        border.width: 0
        color: "green"

        MouseArea {
            anchors.fill: parent
            drag.target: parent
        }
    }

在这里插入图片描述

2.绘制 多边形 MapPolygon

    MapPolygon
    {
        id:polygon
        border.width: 3
        color: "green"
        path: [QtPositioning.coordinate(34.23,108.87)
            ,QtPositioning.coordinate(34.23,108.97)
            ,QtPositioning.coordinate(34.63,108.67)
            ,QtPositioning.coordinate(34.33,108.87)]
    }

添加到Map

map.addMapItem(polygon)

在这里插入图片描述
在实际应用中,不一定在初始化的时候就知道所有点的坐标,根据业务需求可能随时添加或者删除点,
有提供了add和remove函数,可以随时添加或者删除
在这里插入图片描述
removeCoordinate函数只能删除某个坐标点,如果要删除所有点怎么办呢:可以循环遍历path一个一个删除,但这种操作麻烦,效率也不高,简单的办法是设置path = [] 这样就可以清空全部坐标点

3.绘制线 MapPolyline

这次我们先看手册:
在这里插入图片描述
和多边形一样,也提供了path,只需要将多个点添加到path中即可,此还提供了相对更多的坐标点操作函数

    MapPolyline{
        id:lines
        line.width: 3
        line.color:  "yellow"
        path: [QtPositioning.coordinate(34.23,108.87)
            ,QtPositioning.coordinate(34.23,108.97)
            ,QtPositioning.coordinate(34.63,108.67)
            ,QtPositioning.coordinate(34.33,108.87)]
    }

添加到地图

map.addMapItem(lines)

在这里插入图片描述

4. 绘制矩形 MapPolyline

在这里插入图片描述
这里和之前不同的是,矩形只需要左上角和右下角坐标即可

    MapRectangle {
        id:rect
        border.width: 3
        color: "red"
        topLeft: QtPositioning.coordinate(34.23,108.87)
        bottomRight: QtPositioning.coordinate(34.33,108.97)
    }

添加到map map.addMapItem(rect)
在这里插入图片描述

5. 多个图形的组合

官方有提供 MapItemGroup ,将所有需要组合的图形全部添加到MapItemGroup中即可,这个偷个赖,我就不写了,直接看官方文档,很全面也很简单https://doc.qt.io/qt-5/qml-qtlocation-mapitemgroup.html

import QtQuick 2.4
import QtPositioning 5.6
import QtLocation 5.9

MapItemGroup {
    id: itemGroup
    property alias position: mainCircle.center
    property var radius: 100 * 1000
    property var borderHeightPct : 0.3

    MapCircle {
        id: mainCircle
        center : QtPositioning.coordinate(40, 0)
        radius: itemGroup.radius * (1.0 + borderHeightPct)
        opacity: 0.05
        visible: true
        color: 'blue'

        MouseArea{
            anchors.fill: parent
            drag.target: parent
            id: maItemGroup
        }
    }

    MapCircle {
        id: groupCircle
        center: itemGroup.position
        radius: itemGroup.radius
        color: 'crimson'

        onCenterChanged: {
            groupPolyline.populateBorder();
        }
    }

    MapPolyline {
        id: groupPolyline
        line.color: 'green'
        line.width: 3

        function populateBorder() {
            groupPolyline.path = [] // clearing the path
            var waveLength = 8.0;
            var waveAmplitude = groupCircle.radius * borderHeightPct;
            for (var i=0; i <= 360; i++) {
                var wavePhase = (i/360.0 * 2.0 * Math.PI )* waveLength
                var waveHeight = (Math.cos(wavePhase) + 1.0) / 2.0
                groupPolyline.addCoordinate(groupCircle.center.atDistanceAndAzimuth(groupCircle.radius + waveAmplitude * waveHeight , i))
            }
        }

        Component.onCompleted: {
            populateBorder()
        }
    }
}

添加到地图

Map {
    id: map
    PolygonGroup {
        id: polygonGroup
        position: QtPositioning.coordinate(63,-18)
    }
}

在这里插入图片描述

6. 抗锯齿

在这里插入图片描述

在这里插入图片描述
图2是加了抗锯齿的,效果会好很多,在map中添加如下代码即可

        // The code below enables SSAA
        layer.enabled: true
        layer.smooth: true
        property int w : width
        property int h : height
        property int pr: Screen.devicePixelRatio
        layer.textureSize: Qt.size(w  * 2 * pr, h * 2 * pr)

这段代码是在官方手册中发现的:https://doc.qt.io/qt-5/location-plugin-itemsoverlay.html

遇到的坑

一般Map在初始化时都会习惯的 anchors.fill :parent 覆盖parent,但这会出现个问题,就是窗口在放大缩小时,里面已经绘制的元素不会随地图移动
在这里插入图片描述
在这里插入图片描述
这里需要移动一下地图,已绘制的元素才会恢复到本身应有的位置,但这并不合理,找了很久才知道怎么解决 覆盖parent,采用依靠在parent的bottom,自己去关联map大小

Window {
    visible: true
    width: 800
    height: 600
    Map {
        id:map
        //覆盖parent,采用依靠在parent的bottom,自己去关联map大小
//        anchors.fill: parent
        width: parent.width
        height: parent.height
        anchors.bottom:parent.bottom
        
        plugin: Plugin { name: "esri" }
        center: QtPositioning.coordinate(34.23,108.87) // Oslo
        zoomLevel: 14
        Component.onCompleted: {
            for(let i = 0;i < supportedMapTypes.length;i++)
            {
                console.log(supportedMapTypes[i].name)
                if(supportedMapTypes[i].name === "World Imagery")
                {
                    activeMapType = supportedMapTypes[i];
                    break
                }
            }
            console.log("activeMapType: " + activeMapType.name)

            //添加一个圆
//            map.addMapItem(circle)
//            map.addMapItem(polygon)
//            map.addMapItem(lines)
            map.addMapItem(rect)
        }
    }

总结

map中最基本的绘图就先这些,下一章节再说在map上绘制qml控件,如image,rectangle

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值