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 Widget使用QCustomPlot库实现二维螺旋曲线(螺旋曲线一)

以上是关于Qt QML 在Map中使用实现二维螺旋曲线(螺旋曲线二)的主要内容,如果未能解决你的问题,请参考以下文章

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

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

Qt Widget使用QCustomPlot库实现二维螺旋曲线(螺旋曲线一)

Qt Widget使用QCustomPlot库实现二维螺旋曲线(螺旋曲线一)

Qt Widget使用QCustomPlot库实现二维螺旋曲线(螺旋曲线一)

Qt Widget使用QCustomPlot库实现二维螺旋曲线(螺旋曲线一)