系列文章目录
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