Qml地图开发实例(一):map组件

        通过Qml的map组件可以快速构建地图应用,设计中需要在地图上实时显示海量数据点(预计万点以上),考虑Qml、c++结合的方式,前端使用Qml显示,后端使用c++进行数据处理。由于刚接触Qml不久,本文主要记录作者急于求成的开发过程,边学边用,很多知识点存在理解不深的情况,若使用请慎重。

        急于求成的特点就是知识零散、不系统,所以Qml开发的基础过程本文略过不讲(讲不清楚),下面急入主题。

1、目标

        本节目标:

        使用Qml创建一个地图基础应用。地图放大、缩小、移动,增加标注线、矩形等图元。

        本节难度:★★★★★(万事开头难)

        葫芦在此

        如葫所示,内容包括

        1)地图背景

        2)左上角显示地图放大等级、鼠标点击位置

        3)三个区域圆圈,设置区域背景颜色

2、实现过程

        1)新建Quick工程

        2)创建完成后,打开main.qml,添加代码生成地图窗口。

import QtQml 2.12
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

import QtLocation 5.12
import QtPositioning 5.12

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello map")    //看的出来,这是专业标题
    visibility: Window.Maximized  // 设置窗口最大化

    Map {
        id: item_map
        anchors.fill: parent
        anchors.topMargin:0
        opacity: 0.99

        plugin: Plugin{
            //参见文档https://doc.qt.io/qt-5.12/qml-qtlocation-plugin.html

            //首选插件语言环境的有序列表,但是貌似没啥用
            locales: "zh-CN"

            //插件的名称
            //osm需要把openssl的dll放到运行目录
            //esri默认就能用,mapbox的我这里加载不了,here的不知道咋用
            //esri默认这个图成都那里不对(放大后)
            name: "osm" // "mapboxgl", "esri", "osm"...

            //首选插件名称的有序列表,设置了name值时无效
            //preferred: ["here","osm"]

            //选择附加到哪个服务插件时Plugin对象所需的功能集,设置了name值时无效
            //required: Plugin.AnyMappingFeatures | Plugin.AnyGeocodingFeatures
        }

        //初始中心点-成都
        center: QtPositioning.coordinate(centerLat, centerLon)
        //初始缩放等级
        zoomLevel: mapZoomReset
        //最大缩放等级
        maximumZoomLevel: 15
        //最小缩放等级
        minimumZoomLevel: 5
        //背景色,没有正常加载时显色的图块颜色
        color: "green"

        //自定义属性
        property real mapZoomReset : 12
        property var mouseCoord : center
        //可供在外部初始化
        property real centerLat : 30.67
        property real centerLon : 104.07

    }
}

        运行结果

        恭喜,第1步成功了!是的,借用的别人的代码(注释完整部分,感谢各路大神分享,丝滑剪切,开心微改)。

        核心内容:

        map组件:定义地图的中心,缩放等级,plugin等属性;

        plugin属性:选择加载的地图类别;

        4)继续,获取鼠标点击位置坐标

import QtQml 2.12
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

import QtLocation 5.12
import QtPositioning 5.12

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello map")    //看的出来,这是专业标题
    visibility: Window.Maximized  // 设置窗口最大化

    Map {
        id: item_map
        anchors.fill: parent
        anchors.topMargin:0
        opacity: 0.99

        plugin: Plugin{
            //参见文档https://doc.qt.io/qt-5.12/qml-qtlocation-plugin.html

            //首选插件语言环境的有序列表,但是貌似没啥用
            locales: "zh-CN"

            //插件的名称
            //osm需要把openssl的dll放到运行目录
            //esri默认就能用,mapbox的我这里加载不了,here的不知道咋用
            //esri默认这个图成都那里不对(放大后)
            name: "osm" // "mapboxgl", "esri", "osm"...

            //首选插件名称的有序列表,设置了name值时无效
            //preferred: ["here","osm"]

            //选择附加到哪个服务插件时Plugin对象所需的功能集,设置了name值时无效
            //required: Plugin.AnyMappingFeatures | Plugin.AnyGeocodingFeatures
        }

        //初始中心点-成都
        center: QtPositioning.coordinate(centerLat, centerLon)
        //初始缩放等级
        zoomLevel: mapZoomReset
        //最大缩放等级
        maximumZoomLevel: 15
        //最小缩放等级
        minimumZoomLevel: 5
        //背景色,没有正常加载时显色的图块颜色
        color: "green"

        //自定义属性
        property real mapZoomReset : 12
        property var mouseCoord : center
        //可供在外部初始化
        property real centerLat : 30.67
        property real centerLon : 104.07

        //信息提示框
        Rectangle{
           anchors.left: parent.left
           anchors.top: parent.top
           height: item_center.height+20
           width: item_center.width+20
           radius: 3
           color: "black"
           opacity: 0.8

           Text{
               id: item_center
               x: 10
               y: 10
               color: "white"
               font.pixelSize: 16
               font.bold: true
               //展示缩放等级 和 map的中心点经纬度
               text: "zoom level:"+Math.floor(item_map.zoomLevel)+
                     "  位置:"+item_map.mouseCoord.latitude+
                     "  "+item_map.mouseCoord.longitude
           }
        }

        //响应鼠标点击事件,鼠标点击时,显示鼠标位置坐标
        MouseArea {
            anchors.fill: parent
            onClicked: {
                var coord = item_map.toCoordinate(Qt.point(mouse.x, mouse.y));
                item_map.mouseCoord = coord;
                console.log("Latitude: " + coord.latitude + ", Longitude: " + coord.longitude);

                //发射信号
                mouse.accepted = true;
                //此处设置选定,用于改变其它item的focus状态
                focus = true;
            }

        }

    }
}

        运行结果

        恭喜,第2步成功了!是的,也是借用的别人的代码(再次感谢各路大神分享,开心加倍)。

        核心内容:

        Rectangle:左上角显示提示信息;

        MouseArea:响应鼠标事件,获取点击位置的坐标;

5)继续,增加区域圆圈

import QtQml 2.12
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

import QtLocation 5.12
import QtPositioning 5.12

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello map")    //看的出来,这是专业标题
    visibility: Window.Maximized  // 设置窗口最大化

    Map {
        id: item_map
        anchors.fill: parent
        anchors.topMargin:0
        opacity: 0.99

        plugin: Plugin{
            //参见文档https://doc.qt.io/qt-5.12/qml-qtlocation-plugin.html

            //首选插件语言环境的有序列表,但是貌似没啥用
            locales: "zh-CN"

            //插件的名称
            //osm需要把openssl的dll放到运行目录
            //esri默认就能用,mapbox的我这里加载不了,here的不知道咋用
            //esri默认这个图成都那里不对(放大后)
            name: "osm" // "mapboxgl", "esri", "osm"...

            //首选插件名称的有序列表,设置了name值时无效
            //preferred: ["here","osm"]

            //选择附加到哪个服务插件时Plugin对象所需的功能集,设置了name值时无效
            //required: Plugin.AnyMappingFeatures | Plugin.AnyGeocodingFeatures
        }

        //初始中心点-成都
        center: QtPositioning.coordinate(centerLat, centerLon)
        //初始缩放等级
        zoomLevel: mapZoomReset
        //最大缩放等级
        maximumZoomLevel: 15
        //最小缩放等级
        minimumZoomLevel: 5
        //背景色,没有正常加载时显色的图块颜色
        color: "green"

        //自定义属性
        property real mapZoomReset : 12
        property var mouseCoord : center
        //可供在外部初始化
        property real centerLat : 30.67
        property real centerLon : 104.07

        //设置背景色
        MapQuickItem{
           id: rad_bk
           zoomLevel: 10 //和缩放等级一起放大缩小
           coordinate: QtPositioning.coordinate(item_map.centerLat, item_map.centerLon)
           anchorPoint: Qt.point(sourceItem.width/2,sourceItem.height/2)
           sourceItem: Rectangle{
               width: 300
               height: 300
               radius: 150
               color: "green"
               opacity: 0.1 //使用透明度
           }
        }

        //画最外圆线
        MapQuickItem{
           id: rad_0
           zoomLevel: 10 //和缩放等级一起放大缩小
           coordinate: QtPositioning.coordinate(item_map.centerLat, item_map.centerLon)
           anchorPoint: Qt.point(sourceItem.width/2,sourceItem.height/2)
           sourceItem: Rectangle{
               width: 300
               height: 300
               radius: 150
               color: "transparent" //使用透明,只显示边框
               border.color: "green"
               border.width: 1
               opacity: 0.3
           }

        }

        //画中间圆线
        //在地图上显示任意Qt Quick对象
        MapQuickItem{
           id: rad_1
           //缩放等级默认0固定大小,否则会和缩放等级一起放大缩小
           zoomLevel: 10
           //指示的坐标点
           coordinate: QtPositioning.coordinate(item_map.centerLat, item_map.centerLon)
           //sourceItem左上角相对于coordinate的偏移
           anchorPoint: Qt.point(sourceItem.width/2,sourceItem.height/2)
           //Qt Quick对象
           sourceItem: Rectangle{
               width: 200
               height: 200
               radius: 100
               color: "transparent"
               border.color: "yellow"
               border.width: 1
               opacity: 1
           }
           //Qt5.14加了一个淡入属性autoFadeIn
        }

        //画最内圆线
        MapQuickItem{
           id: rad_2
           zoomLevel: 10 //和缩放等级一起放大缩小
           coordinate: QtPositioning.coordinate(item_map.centerLat, item_map.centerLon)
           anchorPoint: Qt.point(sourceItem.width/2,sourceItem.height/2)
           sourceItem: Rectangle{
               width: 100
               height: 100
               radius: 50
               color: "transparent" //背景透明,但边框不透明
               border.color: "red"
               border.width: 1
               opacity: 0.5
           }

        }

        //信息提示框
        Rectangle{
           anchors.left: parent.left
           anchors.top: parent.top
           height: item_center.height+20
           width: item_center.width+20
           radius: 3
           color: "black"
           opacity: 0.8

           Text{
               id: item_center
               x: 10
               y: 10
               color: "white"
               font.pixelSize: 16
               font.bold: true
               //展示缩放等级 和 map的中心点经纬度
               text: "zoom level:"+Math.floor(item_map.zoomLevel)+
                     "  位置:"+item_map.mouseCoord.latitude+
                     "  "+item_map.mouseCoord.longitude
           }
        }

        //响应鼠标点击事件,鼠标点击时,显示鼠标位置坐标
        MouseArea {
            anchors.fill: parent
            onClicked: {
                var coord = item_map.toCoordinate(Qt.point(mouse.x, mouse.y));
                item_map.mouseCoord = coord;
                console.log("Latitude: " + coord.latitude + ", Longitude: " + coord.longitude);

                //发射信号
                mouse.accepted = true;
                //此处设置选定,用于改变其它item的focus状态
                focus = true;
            }

        }

    }
}

        运行结果

        恭喜,第3步成功了!

        核心内容:

        MapQuickItem:地图内添加组件使用该模块,具有coordinate属性,通过设置坐标值进行位置定位。

        zoomLevel:设置不为0,则随地图进行缩放;设置为0则固定大小,不随地图缩放。

        圆圈设计:没有直接空心圆的组件,这里使用透明色、边框色、边框宽度进行配置,达到预期效果,比设计代码画空心圆省心不少(小坑一个)

        color: "transparent" //使用透明,只显示边框

        border.color: "green"

        border.width: 1

3、总结

        1)Qml快速构建地图应用,确实比较方便(比C++);

        2)主要组件:map、MapQuickItem,plugin、zoomLevel等属性;

        3)矩形、鼠标响应事件,与常规Qml处理相同;

        本节目标完成,加加油!

源码下载:

【免费】Qml地图应用示例,包括地图显示、区域线、获取鼠标位置等源程序资源-CSDN文库

        脚印--不断寻找的轮子最终可能是自己--

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值