QML Map中测距??QtLocation轻量级地图应用学*

发布时间:2021-06-16 01:58:16



QML Map中测距
1. 实现思路2. 实现代码及git链接



本文转载于:QML QtLocation轻量级地图应用学*:实现测距功能



所有的热爱都要不遗余力,真正喜欢它便给它更高的优先级,和更多的时间吧!


QML其它文章请点击这里: ????QT QUICK QML 学*笔记



1. 实现思路

参照百度or高德地图的测距功能,主要由两种元素组成,标记点和连线。

其中连线很好解决,Qt 提供了 MapPolyline 类型,可以用来绘制折线,并且提供了增删的便捷函数:

对于标记点,我们可以用 MapQuickItem 来实现,里面包含一个标记圆圈、长度Text、删除按钮。对于一组 MapQuickItem,我使用 MapItemView 来管理。而求两个坐标点的距离,直接调用的 coordinate 类型的 distanceTo 函数,总长直接遍历求距离就行了。


接下来就是封装一个 Ruler 的组件,实现多次测距的绘制。每次开始测距时,通过 createObject 动态创建一个 Ruler 组件,然后往里面添加坐标点。坐标点我是在 Map 上放了一个 MouseArea ,然后用 Map 的 toCoordinate 方法把 point 转换成坐标点。


此外,如果要自己计算两点距离,可以参考网上球面两点距离的公式,如:


上面参考的表示法应该是十进制的,如果是度分秒的形式,可以先转化下:


2. 实现代码及git链接

下面是实现效果:

有一点还没解决,那就是 MapPolyline 这种图元设置 layer 实现*滑效果的话,放大之后很卡。另外就是,一个 Ruler 所有元素被删之后我也没有析构它。


Ruler组件的实现代码:


//MapRuler.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtLocation 5.12
import QtPositioning 5.12

// 一次测距里包含多个标记点以及连线
MapItemGroup{
id: control

MapPolyline {
id: item_line
line.color: "red"
line.width: 2
//*滑后放大有点卡
//layer.enabled: true
//layer.smooth: true
//layer.samples: 8
function getDistanceCount(){
var distance_count=0;
for(var i=1;i
distance_count+=item_line.coordinateAt(i).distanceTo(item_line.coordinateAt(i-1));
}
return Math.round(distance_count);
}
}

MapItemView{
id: item_view
add: Transition {}
remove: Transition {}
model: ListModel{
id: item_model
}
delegate: MapQuickItem{
id: ietm_delegate
sourceItem: Rectangle {
width: 14
height: 14
radius: 7
color: "white"
border.width: 2
border.color: "red"
Rectangle{
anchors.left: parent.right
anchors.top: parent.bottom
width: item_text.width+5+5+14+5
height: item_text.height+10
border.color: "gray"
Text {
id: item_text
x: 5
anchors.verticalCenter: parent.verticalCenter
text: index<=0
? "起点"
: (index==item_model.count-1)
? ("总长 "+item_line.getDistanceCount()/1000+" km")
:(Math.round(ietm_delegate.coordinate.distanceTo(item_line.coordinateAt(index-1)))/1000+" km")
}
Rectangle{
width: 14
height: 14
anchors.right: parent.right
anchors.rightMargin: 5
anchors.verticalCenter: parent.verticalCenter
border.color: "red"
Text {
color: "red"
anchors.centerIn: parent
text: "+"
rotation: 45
}
MouseArea{
anchors.fill: parent
onClicked: {
//最后一个全部删除,否则一个一个的删除
//为0的时候发送信号给group请求删除
if(index==item_model.count-1){
item_line.path=[];
item_model.clear();
//control.destroy();
}else{
item_line.removeCoordinate(index);
item_model.remove(index);
}
}
}
}
}

//Component.onDestruction: console.log("destory item");
}
//通过listmodel来设置数据
coordinate{
latitude: latitudeval
longitude: longitudeval
}
anchorPoint: Qt.point(sourceItem.width/2, sourceItem.height/2)
}
}

function appendPoint(coord){
//var coord=the_map.toCoordinate(Qt.point(mouseX,mouseY),false);
//console.log("area",coord.latitude,coord.longitude);
item_model.append({"latitudeval":coord.latitude,"longitudeval":coord.longitude});
item_line.addCoordinate(coord);
//mouse_area._closePath=false;
//console.log("ruler append",item_model.count,item_line.pathLength())
}

function followMouse(coord){
if(item_line.pathLength()<=0)
return;
if(item_line.pathLength()===item_model.count){
item_line.addCoordinate(coord);
}else{
item_line.replaceCoordinate(item_line.pathLength()-1,coord);
}
}

function closePath(){
while(item_line.pathLength()>item_model.count){
item_line.removeCoordinate(item_line.pathLength()-1);
}
}
}

在 Window 中调用下面组件来展示 Demo:


//Demo.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtLocation 5.12
import QtPositioning 5.12

//地图自定义
Item{
id: control
//地图的模式
// 0:普通浏览
// 1:测距
property int mapMode: 0
property MapRuler currentRuler: null

property alias map: the_map
clip: true

onMapModeChanged: {
console.log("map mode",mapMode);
if(control.mapMode!=1&¤tRuler){
currentRuler.closePath();
currentRuler=null;
}
}

//缩放等级,维度,精度
function viewPoint(zoomLevel,latitude,longitude){
the_map.zoomLevel=zoomLevel;
the_map.center=QtPositioning.coordinate(latitude, longitude);
}


Row{
RadioButton{
text: "Normal"
checked: true
onCheckedChanged: if(checked)control.mapMode=0;
}
RadioButton{
text: "Ruler"
onCheckedChanged: if(checked)control.mapMode=1;
}
}

Map {
id: the_map
anchors.fill: parent
anchors.topMargin: 40
minimumZoomLevel: 4
maximumZoomLevel: 16
zoomLevel: 10
center: QtPositioning.coordinate(30.6562, 104.0657)

plugin: Plugin {
name: "esri" //"esri" "mapbox" "osm" "here"
}

//显示缩放等级与center
Rectangle{
anchors{
left: the_map.left
bottom: the_map.bottom
margins: 5
}

width: content.width+20
height: content.height+10
Text {
id: content
x: 10
y: 5
font.pixelSize: 14
text: "Zoom Level "+Math.floor(the_map.zoomLevel)+" Center:"+the_map.center.latitude+" "+the_map.center.longitude

}
}

MouseArea{
id: map_mouse
anchors.fill: parent
enabled: control.mapMode!=0

//画了一个点后跟随鼠标,除非双击
hoverEnabled: true
onClicked: {
// 1 测距
if(control.mapMode===1){
if(!currentRuler){
currentRuler=ruler_comp.createObject(the_map);
if(currentRuler)
the_map.addMapItemGroup(currentRuler);
}
if(currentRuler){
var coord=the_map.toCoordinate(Qt.point(mouseX,mouseY),false);
currentRuler.appendPoint(coord);
}
}
}
onDoubleClicked: {
// 1 测距
if(control.mapMode===1){
if(currentRuler){
currentRuler.closePath();
currentRuler=null;
}
}
}
onPositionChanged: {
// 1 测距
if(control.mapMode===1){
if(currentRuler){
var coord=the_map.toCoordinate(Qt.point(mouseX,mouseY),false);
currentRuler.followMouse(coord);
}
}
}
}
}

Component{
id: ruler_comp
MapRuler{

}
}
}

代码 github 链接:https://github.com/gongjianbo/MyQtLocation

相关文档

  • 结婚请朋友夫妻怎么写
  • 校园文明口号精选多篇
  • 简单的小动物童话故事
  • 我的第一堂课初二作文800字
  • qt获取combobox的值_Qt官方示例嵌套甜甜圈
  • 台湾的蝴蝶谷课文反思
  • 2020年农历三月三可以回娘家吗三月三不能在娘家是什么说法
  • 铁路局竞争上岗优秀演讲稿
  • 初中语文试卷题目
  • 液晶显示器老是闪屏怎么回事
  • 煤矿冬季三防的应急救援预案
  • 中秋节领导讲话稿范文节日快乐
  • 莫言《卖白菜》读后感范文(精选6篇)
  • 英语口语学习基本技巧
  • Windows Server 2012 R2 IIS8.5+PHP+MySQL环境搭建教程
  • 梦见买水果是什么意思 周公解梦
  • ActiveMQ消息队列的使用及应用
  • 羽毛球扣杀技巧介绍
  • 访问邀请函范文
  • 最新行政机关公文格式
  • 一件难忘的小事
  • 酒店承包经营合同书范文3篇
  • ***“三严三实”精神学习心得体会
  • springboot使用 freemarker shiro标签
  • 最新交谊舞教学视频完整版
  • 女人脸色红润的养血方法
  • 国考公务员逻辑判断题及答案
  • 宋明理学课件
  • 船舶管理协议模板
  • 苹果最近删除里的照片删了还能恢复吗
  • 猜你喜欢

  • 企业安全生产费用提取和使用管理办法财企〔2012〕16号
  • 五年级美术下册《欢乐陶吧》PPT课件
  • java过滤器命名_java 过滤指定后缀文件
  • ps美白技巧给照片美白
  • 小学生易懂的名人名言30句
  • 道德与法治八年级上册《走进社会生活 第二课 网络生活新空间 合理利用网络》_3
  • 上海帮友劳务服务有限公司(企业信用报告)- 天眼查
  • 鸿门宴分段段意
  • 七年级英语下册 Unit7 It’s raining 第1课时Section A1a_2d课件新版人教新目标版
  • 工作计划/工作计划范文
  • 消除水泵振动的方法
  • Dubbo 源码学习系列(五) 优化篇《工厂模式在Dubbo中的应用》
  • 三年级上册语文课件-第3单元 10.在牛肚子里旅行|人教(部编版) (共33张PPT)
  • 舞阳县舞泉镇供销社企业信用报告-天眼查
  • 高三叙事作文:那抹微笑1
  • 公司运营管理
  • 上海金柯育网络技术有限公司企业信用报告-天眼查
  • 大棚蔬菜预防病害巧办法棚室内防病要以降低湿度为中心
  • 石榴管理技术要点分析
  • 【最新推荐】中考化学复习:初中化学学习方法漫谈-实用word文档 (2页)
  • 小议公路路基施工技术及防护措施
  • 安徽牡丹网贸易有限公司(企业信用报告)- 天眼查
  • 冷若冰霜怎么造句的例子
  • 对爸爸妈妈说的话作文400字之三
  • 《引领现代生活的消费伦理学》阅读练习及答案
  • 保安队年终工作总结与保安队长2018年个人工作总结汇编
  • 一种云
  • 北京兴宝龙物资有限公司企业信用报告-天眼查
  • 初二想象作文《拯救地球》1500字(共19页PPT)
  • 让所有人都知道我-品味生活_感悟人生_市场营销哲理小故事
  • 一个34岁出来面试还被拒绝的Android程序员有多惨?
  • 消防机器人项目可行性研究报告(立项模板)
  • 【20XX年中考作文范文】改变一点点
  • 北京大学行政管理考研模拟题合集及答案解析
  • 单位办公用品购置申请表
  • 扬州医保卡余额查询
  • 写景作文 关于多彩的夏天的700字作文:多彩的夏天-精品
  • 中考语文之文言文中的词类活用归纳分析
  • 供销社八项规定自查报告与供销社关心下一代工作报告汇编
  • 我的同桌_六年级作文_11
  • 高一数学人教A版必修1课件:3.1.1 方程的根与函数的零点
  • 福建省莆田市第七中学2019-2020学年高二化学上学期期末考试试题
  • 电脑版