文章目录
GitHub 源码: QmlLearningPro
QT 其它文章请点击这里: QT 学习笔记
姊妹篇: xxx
一、演示
可输入半径和间距来调整螺旋曲线的圈数和大小,其中的距离为真实的地理距离,会随着缩放等级而变化的
具体公式可参考,上一篇的文章。
二、核心代码
● 前端核心代码:
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 学习笔记
姊妹篇: xxx