QML提供了MapPolyline用于在地图上绘制线段,该线段是实线,因此我使用Canvas自定义绘制的方式在地图上绘制线段,如图:
鼠标在地图上点击后,在点击位置添加图标 ,当有多个图标被添加到地图上后,计算各个图标间的距离,并创建一个新的虚线线段组件,连接两个图标点,显示距离数值。如果对自定义图标添加拖动属性,效果如图:
MapDashLine.qml属性:
- beginCoordinate:线段起始经纬度坐标
- endCoordinate:线段终点经纬度坐标
- lineDash:虚线样式
- lineColor:虚线颜色
- lineWidth:虚线粗细
- textColor:显示距离文字颜色
- textPixelSize:字体大小
MapDashLine.qml源码(我使用的是Qt5.15):
import QtQuick 2.15 import QtPositioning 5.15 Item { id:mapDashLine anchors.fill: parent property var beginCoordinate: QtPositioning.coordinate() property var endCoordinate: QtPositioning.coordinate() property var lineDash: [4,4] property color lineColor: "crimson" property int lineWidth: 2 property color textColor: "crimson" property int textPixelSize: 14 readonly property var mapItem: mapDashLine.parent Canvas{ id:myCanvas anchors.fill: parent onPaint: { if(!mapDashLine.beginCoordinate.isValid || !mapDashLine.endCoordinate.isValid) return var ctx = getContext("2d") ctx.clearRect(0,0,myCanvas.width,myCanvas.height) ctx.strokeStyle = mapDashLine.lineColor ctx.lineWidth = mapDashLine.lineWidth ctx.setLineDash(mapDashLine.lineDash) //**绘制虚线 ctx.beginPath() var beginPos = mapDashLine.mapItem.fromCoordinate(mapDashLine.beginCoordinate,false) ctx.moveTo(beginPos.x,beginPos.y) var endPos = mapDashLine.mapItem.fromCoordinate(mapDashLine.endCoordinate,false) ctx.lineTo(endPos.x,endPos.y) ctx.stroke() ctx.save() //**绘制文字 var azimuth = endCoordinate.azimuthTo(beginCoordinate) if(azimuth>=180) azimuth = azimuth - 180 var distance = endCoordinate.distanceTo(beginCoordinate) var text = (distance/1000).toFixed(0)+"Km" ctx.fillStyle = mapDashLine.textColor ctx.font = mapDashLine.textPixelSize+"px Arial" ctx.textAlign = "center" var centerX = (beginPos.x+endPos.x)/2 var centerY = (beginPos.y+endPos.y)/2 ctx.translate(centerX,centerY) ctx.rotate(azimuth*Math.PI/180-Math.PI/2) ctx.fillText(text,0,-mapDashLine.textPixelSize/2) ctx.restore() } } onBeginCoordinateChanged: { update() } onEndCoordinateChanged: { update() } onLineDashChanged: { update() } onLineColorChanged: { update() } onLineWidthChanged: { update() } onTextColorChanged: { update() } onTextPixelSizeChanged: { update() } Connections{ target: mapDashLine.mapItem function onZoomLevelChanged(){ update() } function onVisibleRegionChanged(){ update() } } function update(){ myCanvas.requestPaint() } }