Qt QML 在Map中使用实现二维螺旋曲线(螺旋曲线二)

文章目录


GitHub 源码:     QmlLearningPro

QT 其它文章请点击这里:     QT 学习笔记

姊妹篇: xxx


一、演示

Qt QML 在Map中使用实现二维螺旋曲线(螺旋曲线二)
可输入半径和间距来调整螺旋曲线的圈数和大小,其中的距离为真实的地理距离,会随着缩放等级而变化的

具体公式可参考,上一篇的文章。

二、核心代码

● 前端核心代码:

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

上一篇:瑜伽CRM系统


下一篇:html第六节课