Qt QML 在Map中使用实现二维螺旋曲线(螺旋曲线二)
Posted 火山上的企鹅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt QML 在Map中使用实现二维螺旋曲线(螺旋曲线二)相关的知识,希望对你有一定的参考价值。
GitHub 源码: QmlLearningPro
QT 其它文章请点击这里: QT 学习笔记
姊妹篇: Qt Widget使用QCustomPlot库实现二维螺旋曲线(螺旋曲线一)
一、演示
可输入半径和间距来调整螺旋曲线的圈数和大小,其中的距离为真实的地理距离,会随着缩放等级而变化的
具体公式可参考,上一篇的文章。
二、核心代码
● 前端核心代码:
FermatSpiralPath
id: fsPath
MapPolyline
line.width: 5
line.color: 'green'
path: fsPath.points
其中,FermatSpiralPath 为C++中一个类,在 main.cpp 中注册:
qmlRegisterType<FermatSpiralPath> ("cc.FermatSpiralPath", 1, 0, "FermatSpiralPath");
● 后端数据处理:
void FermatSpiralPath::SpiralPathAdd()
QGeoCoordinate corCenter(30.6562, 104.0657);
QGeoCoordinate cor;
_points.clear();
_points.append(QVariant::fromValue(corCenter));
double D_I = 0; //内径
double N = _radius/_spacing; //圈数
const int pointCount = 500;
for (int i=0; i<pointCount; ++i)
double phi = i/static_cast<double>(pointCount-1);
cor = corCenter.atDistanceAndAzimuth(D_I + _radius*phi, static_cast<double>(N*phi * 2*M_PI*M_RAD));
_points.append(QVariant::fromValue(cor));
pointsChanged();
已知一个坐标点,利用 atDistanceAndAzimuth 函数, 给定另一个坐标距该点的距离和方位角,就可以求出另一点的坐标位置了
三、完整代码
● 前端
main.qml:
//Demo.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtLocation 5.12
import QtPositioning 5.12
import QtQuick.Window 2.12
import cc.FermatSpiralPath 1.0
Window
visible: true
width: 640 * 1.5
height: 480 * 1.5
title: qsTr("螺旋曲线")
readonly property var coordinateHome: QtPositioning.coordinate(30.6562, 104.0657)
FermatSpiralPath
id: fsPath
Map
id: the_map
anchors.fill: parent
minimumZoomLevel: 4
maximumZoomLevel: 20
zoomLevel: 17
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: 10
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
MapPolyline
line.width: 5
line.color: 'green'
path: fsPath.points
Rectangle
anchors.top: parent.top
anchors.topMargin: 10
anchors.horizontalCenter: parent.horizontalCenter
width: grid.width + 10
height: grid.height + 10
color: "black"
radius: 4
Grid
id: grid
anchors.centerIn: parent
rows: 2
columns: 2
rowSpacing: 4
columnSpacing: 4
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
Label
id: radiusLabel
text: qsTr("输入半径:")
font.pointSize: 11
font.bold: true
color: "#B7FF4A"
TextField
id: radiusTF
font.family: "微软雅黑"
width: radiusLabel.width
verticalAlignment: Text.AlignVCenter
inputMethodHints: Qt.ImhFormattedNumbersOnly //只允许数字输入,包括小数点和负号
focus: true
placeholderText: qsTr("60")
color: "red"
selectByMouse: true //可以选择文本
validator: IntValidator bottom: 1; top: 100000;
onEditingFinished:
fsPath.radius = Number(text)
Label
id: spacingLabel
text: qsTr("输入间距:")
font.pointSize: 11
font.bold: true
color: "#B7FF4A"
TextField
id: spacingTF
verticalAlignment: Text.AlignVCenter
font.family: "微软雅黑"
width: radiusTF.width
selectByMouse: true
focus: true
placeholderText: qsTr("20")
color: "red"
validator: IntValidator bottom: 1; top: Number(radiusTF.text);
onEditingFinished:
fsPath.spacing = Number(text);
● 后端:
fermatspiralpath.cpp:
#include "fermatspiralpath.h"
#define M_PI (3.14159265358979323846)
#define M_RAD (180/M_PI)
FermatSpiralPath::FermatSpiralPath(void):
_radius(60),
_spacing(20)
SpiralPathAdd();
void FermatSpiralPath::SpiralPathAdd()
QGeoCoordinate corCenter(30.6562, 104.0657);
QGeoCoordinate cor;
_points.clear();
_points.append(QVariant::fromValue(corCenter));
double D_I = 0; //内径
double N = _radius/_spacing; //圈数
const int pointCount = 500;
for (int i=0; i<pointCount; ++i)
double phi = i/static_cast<double>(pointCount-1);
cor = corCenter.atDistanceAndAzimuth(D_I + _radius*phi, static_cast<double>(N*phi * 2*M_PI*M_RAD));
_points.append(QVariant::fromValue(cor));
pointsChanged();
void FermatSpiralPath::setRadius(const qreal &radius)
if( radius != 0.0)
_radius = radius;
SpiralPathAdd();
void FermatSpiralPath::setSpacing(const qreal &spacing)
if( spacing != 0.0)
_spacing = spacing;
SpiralPathAdd();
fermatspiralpath.h
#ifndef FERMATSPIRALPATH_H
#define FERMATSPIRALPATH_H
#include "qgeocoordinate.h"
#include "qvariant.h"
#include "math.h"
#include <QObject>
class FermatSpiralPath : public QObject
Q_OBJECT
public:
// FermatSpiralPath(QObject* parent);
FermatSpiralPath(void);
Q_PROPERTY(QVariantList points READ points NOTIFY pointsChanged)
Q_PROPERTY(qreal radius READ radius WRITE setRadius)
Q_PROPERTY(qreal spacing READ spacing WRITE setSpacing)
//read
QVariantList points(void) const return _points;
qreal radius(void) const return _radius;
qreal spacing(void) const return _spacing;
//write
void setRadius (const qreal& radius);
void setSpacing (const qreal& spacing);
void SpiralPathAdd();
signals:
void pointsChanged (void);
private:
QVariantList _points;
qreal _radius;
qreal _spacing;
;
#endif // FERMATSPIRALPATH_H
GitHub 源码: QmlLearningPro
QT 其它文章请点击这里: QT 学习笔记
以上是关于Qt QML 在Map中使用实现二维螺旋曲线(螺旋曲线二)的主要内容,如果未能解决你的问题,请参考以下文章
Qt Widget使用QCustomPlot库实现二维螺旋曲线(螺旋曲线一)
Qt Widget使用QCustomPlot库实现二维螺旋曲线(螺旋曲线一)