Skip to content

Commit

Permalink
Merge pull request #52849 from nirvn/qgsquick_maptoscreen
Browse files Browse the repository at this point in the history
[qgsquick] New map to screen class to tie QML items to the map canvas
  • Loading branch information
nirvn committed Apr 23, 2023
2 parents 2458023 + dcbaa61 commit 0f22e92
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/quickgui/CMakeLists.txt
Expand Up @@ -5,6 +5,7 @@ set(QGIS_QUICK_GUI_MOC_HDRS
qgsquickelevationprofilecanvas.h
qgsquickmapcanvasmap.h
qgsquickmapsettings.h
qgsquickmaptoscreen.h
qgsquickmaptransform.h
qgsquickutils.h
)
Expand All @@ -14,6 +15,7 @@ set(QGIS_QUICK_GUI_SRC
qgsquickelevationprofilecanvas.cpp
qgsquickmapcanvasmap.cpp
qgsquickmapsettings.cpp
qgsquickmaptoscreen.cpp
qgsquickmaptransform.cpp
qgsquickutils.cpp
)
Expand Down
117 changes: 117 additions & 0 deletions src/quickgui/qgsquickmaptoscreen.cpp
@@ -0,0 +1,117 @@
/***************************************************************************
qgsquickmaptoscreen.cpp
----------------------------------------------------
Date : 22.08.2018
Copyright : (C) 2018 by Denis Rouzaud
Email : denis (at) opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsquickmaptoscreen.h"
#include "qgspoint.h"

QgsQuickMapToScreen::QgsQuickMapToScreen( QObject *parent )
: QObject( parent )
{
}

void QgsQuickMapToScreen::setMapSettings( QgsQuickMapSettings *mapSettings )
{
if ( mMapSettings == mapSettings )
return;

if ( mMapSettings )
{
disconnect( mMapSettings, &QgsQuickMapSettings::extentChanged, this, &QgsQuickMapToScreen::transformPoint );
disconnect( mMapSettings, &QgsQuickMapSettings::rotationChanged, this, &QgsQuickMapToScreen::transformPoint );
disconnect( mMapSettings, &QgsQuickMapSettings::outputSizeChanged, this, &QgsQuickMapToScreen::transformPoint );
}

mMapSettings = mapSettings;

connect( mMapSettings, &QgsQuickMapSettings::extentChanged, this, &QgsQuickMapToScreen::transformPoint );
connect( mMapSettings, &QgsQuickMapSettings::rotationChanged, this, &QgsQuickMapToScreen::transformPoint );
connect( mMapSettings, &QgsQuickMapSettings::outputSizeChanged, this, &QgsQuickMapToScreen::transformPoint );

transformPoint();
transformDistance();

emit mapSettingsChanged();
}

QgsQuickMapSettings *QgsQuickMapToScreen::mapSettings() const
{
return mMapSettings;
}

void QgsQuickMapToScreen::setMapPoint( const QgsPoint &point )
{
if ( mMapPoint == point )
return;

mMapPoint = point;
emit mapPointChanged();
transformPoint();
}

QgsPoint QgsQuickMapToScreen::mapPoint() const
{
return mMapPoint;
}

QPointF QgsQuickMapToScreen::screenPoint() const
{
return mScreenPoint;
}

void QgsQuickMapToScreen::transformPoint()
{
if ( !mMapSettings )
{
mScreenPoint = QPointF();
}
else
{
mScreenPoint = mMapSettings->coordinateToScreen( mMapPoint );
}
emit screenPointChanged();
}

void QgsQuickMapToScreen::setMapDistance( const double distance )
{
if ( mMapDistance == distance )
return;

mMapDistance = distance;
emit mapDistanceChanged();
transformDistance();
}

double QgsQuickMapToScreen::mapDistance() const
{
return mMapDistance;
}

double QgsQuickMapToScreen::screenDistance() const
{
return mScreenDistance;
}

void QgsQuickMapToScreen::transformDistance()
{
if ( !mMapSettings || qgsDoubleNear( mMapDistance, 0.0 ) || qgsDoubleNear( mMapSettings->mapUnitsPerPoint(), 0.0 ) )
{
mScreenDistance = 0.0;
}
else
{
mScreenDistance = mMapDistance / mMapSettings->mapUnitsPerPoint();
}
emit screenDistanceChanged();
}
102 changes: 102 additions & 0 deletions src/quickgui/qgsquickmaptoscreen.h
@@ -0,0 +1,102 @@
/***************************************************************************
qgsquickmaptoscreen.h
----------------------------------------------------
Date : 22.08.2018
Copyright : (C) 2018 by Denis Rouzaud
Email : denis (at) opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSQUICKMAPTOSCREEN_H
#define QGSQUICKMAPTOSCREEN_H

#include "qgsquickmapsettings.h"

#include <QObject>
#include <QPointF>
#include <qgspoint.h>

/**
* \ingroup quick
*
* \brief The QgsQuickMapToScreen class transform map points to screen coordinates as
* well as distances from map to screen units. Screen points and/or distances will be
* automatically updated on map extent changes.
*
* \since QGIS 3.32
*/
class QUICK_EXPORT QgsQuickMapToScreen : public QObject
{
Q_OBJECT

//! Map settings used to define the map canvas CRS and detect any extent change
Q_PROPERTY( QgsQuickMapSettings *mapSettings READ mapSettings WRITE setMapSettings NOTIFY mapSettingsChanged )

//! Point in map coordinates
Q_PROPERTY( QgsPoint mapPoint READ mapPoint WRITE setMapPoint NOTIFY mapPointChanged )
//! Point in screen coordinates (read-only)
Q_PROPERTY( QPointF screenPoint READ screenPoint NOTIFY screenPointChanged )

//! Distance in map unit
Q_PROPERTY( double mapDistance READ mapDistance WRITE setMapDistance NOTIFY mapDistanceChanged )
//! Distance in screen coordinates (read-only)
Q_PROPERTY( double screenDistance READ screenDistance NOTIFY screenDistanceChanged )

public:

//! Creates a map to screen object
explicit QgsQuickMapToScreen( QObject *parent = nullptr );

//! \copydoc mapSettings
void setMapSettings( QgsQuickMapSettings *mapSettings );
//! \copydoc mapSettings
QgsQuickMapSettings *mapSettings() const;

//! \copydoc mapPoint
void setMapPoint( const QgsPoint &point );
//! \copydoc mapPoint
QgsPoint mapPoint() const;

//! \copydoc mapDistance
void setMapDistance( const double distance );
//! \copydoc mapDistance
double mapDistance() const;

//! \copydoc screenPoint
QPointF screenPoint() const;

//! \copydoc screenDistance
double screenDistance() const;

signals:

//! \copydoc mapSettings
void mapSettingsChanged();
//! \copydoc mapPoint
void mapPointChanged();
//! \copydoc mapDistance
void mapDistanceChanged();
//! \copydoc screenPoint
void screenPointChanged();
//! \copydoc screenDistance
void screenDistanceChanged();

private slots:
void transformPoint();
void transformDistance();

private:
QgsQuickMapSettings *mMapSettings = nullptr;
QgsPoint mMapPoint = QgsPoint();
double mMapDistance = 0.0;
QPointF mScreenPoint = QPointF();
double mScreenDistance = 0.0;
};

#endif // QGSQUICKMAPTOSCREEN_H
20 changes: 19 additions & 1 deletion tests/src/quickgui/testqgsquickmapsettings.cpp
Expand Up @@ -15,12 +15,14 @@
#include <QObject>
#include <QApplication>

#include "qgis.h"
#include "qgsapplication.h"
#include "qgstest.h"
#include "qgis.h"
#include "qgspoint.h"
#include "qgsunittypes.h"

#include "qgsquickmapsettings.h"
#include "qgsquickmaptoscreen.h"

class TestQgsQuickMapSettings: public QObject
{
Expand All @@ -30,6 +32,7 @@ class TestQgsQuickMapSettings: public QObject
void cleanup() {} // will be called after every testfunction.

void test_project_existency();
void test_map_to_screen();
};

void TestQgsQuickMapSettings::test_project_existency()
Expand All @@ -39,5 +42,20 @@ void TestQgsQuickMapSettings::test_project_existency()
delete settings;
}

void TestQgsQuickMapSettings::test_map_to_screen()
{
QgsQuickMapSettings *settings = new QgsQuickMapSettings();
settings->setOutputSize( QSize( 10, 10 ) );
settings->setExtent( QgsRectangle( 0, 0, 10, 10 ) );

QgsPoint point( 5, 5 );

QgsQuickMapToScreen *mapToScreen = new QgsQuickMapToScreen();
mapToScreen->setMapSettings( settings );
mapToScreen->setMapPoint( point );

QCOMPARE( mapToScreen->screenPoint(), QPointF( 5, 5 ) );
}

QGSTEST_MAIN( TestQgsQuickMapSettings )
#include "testqgsquickmapsettings.moc"

0 comments on commit 0f22e92

Please sign in to comment.