Skip to content

Commit 14c6656

Browse files
committedApr 23, 2023
[qgsquick] New map to screen class to tie QML items to the map canvas
1 parent 2d4f1a8 commit 14c6656

File tree

4 files changed

+239
-1
lines changed

4 files changed

+239
-1
lines changed
 

‎src/quickgui/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ set(QGIS_QUICK_GUI_MOC_HDRS
55
qgsquickelevationprofilecanvas.h
66
qgsquickmapcanvasmap.h
77
qgsquickmapsettings.h
8+
qgsquickmaptoscreen.h
89
qgsquickmaptransform.h
910
qgsquickutils.h
1011
)
@@ -14,6 +15,7 @@ set(QGIS_QUICK_GUI_SRC
1415
qgsquickelevationprofilecanvas.cpp
1516
qgsquickmapcanvasmap.cpp
1617
qgsquickmapsettings.cpp
18+
qgsquickmaptoscreen.cpp
1719
qgsquickmaptransform.cpp
1820
qgsquickutils.cpp
1921
)

‎src/quickgui/qgsquickmaptoscreen.cpp

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/***************************************************************************
2+
qgsquickmaptoscreen.cpp
3+
----------------------------------------------------
4+
Date : 22.08.2018
5+
Copyright : (C) 2018 by Denis Rouzaud
6+
Email : denis (at) opengis.ch
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsquickmaptoscreen.h"
17+
#include "qgspoint.h"
18+
19+
QgsQuickMapToScreen::QgsQuickMapToScreen( QObject *parent )
20+
: QObject( parent )
21+
{
22+
}
23+
24+
void QgsQuickMapToScreen::setMapSettings( QgsQuickMapSettings *mapSettings )
25+
{
26+
if ( mMapSettings == mapSettings )
27+
return;
28+
29+
if ( mMapSettings )
30+
{
31+
disconnect( mMapSettings, &QgsQuickMapSettings::extentChanged, this, &QgsQuickMapToScreen::transformPoint );
32+
disconnect( mMapSettings, &QgsQuickMapSettings::rotationChanged, this, &QgsQuickMapToScreen::transformPoint );
33+
disconnect( mMapSettings, &QgsQuickMapSettings::outputSizeChanged, this, &QgsQuickMapToScreen::transformPoint );
34+
}
35+
36+
mMapSettings = mapSettings;
37+
38+
connect( mMapSettings, &QgsQuickMapSettings::extentChanged, this, &QgsQuickMapToScreen::transformPoint );
39+
connect( mMapSettings, &QgsQuickMapSettings::rotationChanged, this, &QgsQuickMapToScreen::transformPoint );
40+
connect( mMapSettings, &QgsQuickMapSettings::outputSizeChanged, this, &QgsQuickMapToScreen::transformPoint );
41+
42+
transformPoint();
43+
transformDistance();
44+
45+
emit mapSettingsChanged();
46+
}
47+
48+
QgsQuickMapSettings *QgsQuickMapToScreen::mapSettings() const
49+
{
50+
return mMapSettings;
51+
}
52+
53+
void QgsQuickMapToScreen::setMapPoint( const QgsPoint &point )
54+
{
55+
if ( mMapPoint == point )
56+
return;
57+
58+
mMapPoint = point;
59+
emit mapPointChanged();
60+
transformPoint();
61+
}
62+
63+
QgsPoint QgsQuickMapToScreen::mapPoint() const
64+
{
65+
return mMapPoint;
66+
}
67+
68+
QPointF QgsQuickMapToScreen::screenPoint() const
69+
{
70+
return mScreenPoint;
71+
}
72+
73+
void QgsQuickMapToScreen::transformPoint()
74+
{
75+
if ( !mMapSettings )
76+
{
77+
mScreenPoint = QPointF();
78+
}
79+
else
80+
{
81+
mScreenPoint = mMapSettings->coordinateToScreen( mMapPoint );
82+
}
83+
emit screenPointChanged();
84+
}
85+
86+
void QgsQuickMapToScreen::setMapDistance( const double distance )
87+
{
88+
if ( mMapDistance == distance )
89+
return;
90+
91+
mMapDistance = distance;
92+
emit mapDistanceChanged();
93+
transformDistance();
94+
}
95+
96+
double QgsQuickMapToScreen::mapDistance() const
97+
{
98+
return mMapDistance;
99+
}
100+
101+
double QgsQuickMapToScreen::screenDistance() const
102+
{
103+
return mScreenDistance;
104+
}
105+
106+
void QgsQuickMapToScreen::transformDistance()
107+
{
108+
if ( !mMapSettings || qgsDoubleNear( mMapDistance, 0.0 ) || qgsDoubleNear( mMapSettings->mapUnitsPerPoint(), 0.0 ) )
109+
{
110+
mScreenDistance = 0.0;
111+
}
112+
else
113+
{
114+
mScreenDistance = mMapDistance / mMapSettings->mapUnitsPerPoint();
115+
}
116+
emit screenDistanceChanged();
117+
}

‎src/quickgui/qgsquickmaptoscreen.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/***************************************************************************
2+
qgsquickmaptoscreen.h
3+
----------------------------------------------------
4+
Date : 22.08.2018
5+
Copyright : (C) 2018 by Denis Rouzaud
6+
Email : denis (at) opengis.ch
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSQUICKMAPTOSCREEN_H
17+
#define QGSQUICKMAPTOSCREEN_H
18+
19+
#include "qgsquickmapsettings.h"
20+
21+
#include <QObject>
22+
#include <QPointF>
23+
#include <qgspoint.h>
24+
25+
/**
26+
* \ingroup quick
27+
*
28+
* @brief The QgsQuickMapToScreen class transform map points to screen coordinates as
29+
* well as distances from map to screen units. Screen points and/or distances will be
30+
* automatically updated on map extent changes.
31+
*
32+
* \since QGIS 3.32
33+
*/
34+
class QUICK_EXPORT QgsQuickMapToScreen : public QObject
35+
{
36+
Q_OBJECT
37+
38+
//! Map settings used to define the map canvas CRS and detect any extent change
39+
Q_PROPERTY( QgsQuickMapSettings *mapSettings READ mapSettings WRITE setMapSettings NOTIFY mapSettingsChanged )
40+
41+
//! Point in map coordinates
42+
Q_PROPERTY( QgsPoint mapPoint READ mapPoint WRITE setMapPoint NOTIFY mapPointChanged )
43+
//! Point in screen coordinates (read-only)
44+
Q_PROPERTY( QPointF screenPoint READ screenPoint NOTIFY screenPointChanged )
45+
46+
//! Distance in map unit
47+
Q_PROPERTY( double mapDistance READ mapDistance WRITE setMapDistance NOTIFY mapDistanceChanged )
48+
//! Distance in screen coordinates (read-only)
49+
Q_PROPERTY( double screenDistance READ screenDistance NOTIFY screenDistanceChanged )
50+
51+
public:
52+
53+
explicit QgsQuickMapToScreen( QObject *parent = nullptr );
54+
55+
//! \copydoc mapSettings
56+
void setMapSettings( QgsQuickMapSettings *mapSettings );
57+
//! \copydoc mapSettings
58+
QgsQuickMapSettings *mapSettings() const;
59+
60+
//! \copydoc mapPoint
61+
void setMapPoint( const QgsPoint &point );
62+
//! \copydoc mapPoint
63+
QgsPoint mapPoint() const;
64+
65+
//! \copydoc mapDistance
66+
void setMapDistance( const double distance );
67+
//! \copydoc mapDistance
68+
double mapDistance() const;
69+
70+
//! \copydoc screenPoint
71+
QPointF screenPoint() const;
72+
73+
//! \copydoc screenDistance
74+
double screenDistance() const;
75+
76+
signals:
77+
78+
//! \copydoc mapSettings
79+
void mapSettingsChanged();
80+
//! \copydoc mapPoint
81+
void mapPointChanged();
82+
//! \copydoc mapDistance
83+
void mapDistanceChanged();
84+
//! \copydoc screenPoint
85+
void screenPointChanged();
86+
//! \copydoc screenDistance
87+
void screenDistanceChanged();
88+
89+
private slots:
90+
void transformPoint();
91+
void transformDistance();
92+
93+
private:
94+
QgsQuickMapSettings *mMapSettings = nullptr;
95+
QgsPoint mMapPoint = QgsPoint();
96+
double mMapDistance = 0.0;
97+
QPointF mScreenPoint = QPointF();
98+
double mScreenDistance = 0.0;
99+
};
100+
101+
#endif // QGSQUICKMAPTOSCREEN_H

‎tests/src/quickgui/testqgsquickmapsettings.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@
1515
#include <QObject>
1616
#include <QApplication>
1717

18+
#include "qgis.h"
1819
#include "qgsapplication.h"
1920
#include "qgstest.h"
20-
#include "qgis.h"
21+
#include "qgspoint.h"
2122
#include "qgsunittypes.h"
2223

2324
#include "qgsquickmapsettings.h"
25+
#include "qgsquickmaptoscreen.h"
2426

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

3234
void test_project_existency();
35+
void test_map_to_screen();
3336
};
3437

3538
void TestQgsQuickMapSettings::test_project_existency()
@@ -39,5 +42,20 @@ void TestQgsQuickMapSettings::test_project_existency()
3942
delete settings;
4043
}
4144

45+
void TestQgsQuickMapSettings::test_map_to_screen()
46+
{
47+
QgsQuickMapSettings *settings = new QgsQuickMapSettings();
48+
settings->setOutputSize( QSize( 10, 10 ) );
49+
settings->setExtent( QgsRectangle( 0, 0, 10, 10 ) );
50+
51+
QgsPoint point( 5, 5 );
52+
53+
QgsQuickMapToScreen *mapToScreen = new QgsQuickMapToScreen();
54+
mapToScreen->setMapSettings( settings );
55+
mapToScreen->setMapPoint( point );
56+
57+
QCOMPARE( mapToScreen->screenPoint(), QPointF( 5, 5 ) );
58+
}
59+
4260
QGSTEST_MAIN( TestQgsQuickMapSettings )
4361
#include "testqgsquickmapsettings.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.