QGIS API Documentation 4.1.0-Master (60fea48833c)
Loading...
Searching...
No Matches
qgsmaptopixel.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaptopixel.cpp - description
3 -------------------
4 begin : Sat Jun 22 2002
5 copyright : (C) 2002 by Gary E.Sherman
6 email : sherman at mrcc.com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17#include "qgsmaptopixel.h"
18
19#include "qgsunittypes.h"
20
21#include <QPoint>
22#include <QTextStream>
23#include <QTransform>
24#include <QVector>
25
26QgsMapToPixel::QgsMapToPixel( double mapUnitsPerPixel, double xc, double yc, int width, int height, double rotation )
27 : mValid( true )
28 , mMapUnitsPerPixel( mapUnitsPerPixel )
29 , mWidth( width )
30 , mHeight( height )
31 , mRotation( rotation )
32 , mXCenter( xc )
33 , mYCenter( yc )
34 , mXMin( xc - ( mWidth * mMapUnitsPerPixel / 2.0 ) )
35 , mYMin( yc - ( mHeight * mMapUnitsPerPixel / 2.0 ) )
36{
37 Q_ASSERT( mapUnitsPerPixel > 0 );
38 updateMatrix();
39}
40
42 : mValid( true )
43 , mMapUnitsPerPixel( mapUnitsPerPixel )
44 , mWidth( 0 )
45 , mHeight( 0 )
46 , mXCenter( 0 )
47 , mYCenter( 0 )
48{
49 updateMatrix();
50}
51
52QgsMapToPixel QgsMapToPixel::fromScale( double scale, Qgis::DistanceUnit mapUnits, double dpi )
53{
54 const double metersPerPixel = 25.4 / dpi / 1000.0;
55 const double mapUnitsPerPixel = metersPerPixel * QgsUnitTypes::fromUnitToUnitFactor( Qgis::DistanceUnit::Meters, mapUnits );
56 return QgsMapToPixel( mapUnitsPerPixel * scale );
57}
58
60{
61 updateMatrix();
62}
63
64bool QgsMapToPixel::updateMatrix()
65{
66 const QTransform newMatrix = transform();
67
68 // https://github.com/qgis/QGIS/issues/20856
69 if ( !newMatrix.isInvertible() )
70 return false;
71
72 mMatrix = newMatrix;
73 return true;
74}
75
77{
78 mValid = true;
79
80 const double oldUnits = mMapUnitsPerPixel;
81 mMapUnitsPerPixel = mapUnitsPerPixel;
82 if ( !updateMatrix() )
83 {
84 mMapUnitsPerPixel = oldUnits;
85 }
86}
87
88void QgsMapToPixel::setMapRotation( double degrees, double cx, double cy )
89{
90 mValid = true;
91
92 const double oldRotation = mRotation;
93 const double oldXCenter = mXCenter;
94 const double oldYCenter = mYCenter;
95 const double oldWidth = mWidth;
96
97 mRotation = degrees;
98 mXCenter = cx;
99 mYCenter = cy;
100 if ( mWidth < 0 )
101 {
102 // set width not that we can compute it
103 mWidth = ( ( mXCenter - mXMin ) * 2 ) / mMapUnitsPerPixel;
104 }
105
106 if ( !updateMatrix() )
107 {
108 mRotation = oldRotation;
109 mXCenter = oldXCenter;
110 mYCenter = oldYCenter;
111 mWidth = oldWidth;
112 }
113}
114
115void QgsMapToPixel::setParameters( double mapUnitsPerPixel, double xc, double yc, int width, int height, double rotation, bool *ok )
116{
117 mValid = true;
118
119 const double oldMUPP = mMapUnitsPerPixel;
120 const double oldXCenter = mXCenter;
121 const double oldYCenter = mYCenter;
122 const double oldWidth = mWidth;
123 const double oldHeight = mHeight;
124 const double oldRotation = mRotation;
125 const double oldXMin = mXMin;
126 const double oldYMin = mYMin;
127
128 mMapUnitsPerPixel = mapUnitsPerPixel;
129 mXCenter = xc;
130 mYCenter = yc;
131 mWidth = width;
132 mHeight = height;
133 mRotation = rotation;
134 mXMin = xc - ( mWidth * mMapUnitsPerPixel / 2.0 );
135 mYMin = yc - ( mHeight * mMapUnitsPerPixel / 2.0 );
136
137 if ( !updateMatrix() )
138 {
139 mMapUnitsPerPixel = oldMUPP;
140 mXCenter = oldXCenter;
141 mYCenter = oldYCenter;
142 mWidth = oldWidth;
143 mHeight = oldHeight;
144 mRotation = oldRotation;
145 mXMin = oldXMin;
146 mYMin = oldYMin;
147 *ok = false;
148 }
149 else
150 {
151 *ok = true;
152 }
153}
154
155void QgsMapToPixel::setParameters( double mapUnitsPerPixel, double xc, double yc, int width, int height, double rotation )
156{
157 mValid = true;
158 bool ok;
159 setParameters( mapUnitsPerPixel, xc, yc, width, height, rotation, &ok );
160}
161
163{
164 QString rep;
165 QTextStream( &rep ) << "Map units/pixel: " << mMapUnitsPerPixel << " center: " << mXCenter << ',' << mYCenter << " rotation: " << mRotation << " size: " << mWidth << 'x' << mHeight;
166 return rep;
167}
168
169QTransform QgsMapToPixel::transform() const
170{
171 // NOTE: operations are done in the reverse order in which
172 // they are configured, so translation to geographical
173 // center happens first, then scaling, then rotation
174 // and finally translation to output viewport center
175
176 const double rotation = mapRotation();
177 if ( qgsDoubleNear( rotation, 0.0 ) )
178 {
179 //no rotation, return a simplified matrix
180 return QTransform::fromScale( 1.0 / mMapUnitsPerPixel, -1.0 / mMapUnitsPerPixel ).translate( -mXMin, -( mYMin + mHeight * mMapUnitsPerPixel ) );
181 }
182 else
183 {
184 const double cy = mapHeight() / 2.0;
185 const double cx = mapWidth() / 2.0;
186 return QTransform::fromTranslate( cx, cy ).rotate( rotation ).scale( 1 / mMapUnitsPerPixel, -1 / mMapUnitsPerPixel ).translate( -mXCenter, -mYCenter );
187 }
188}
DistanceUnit
Units of distance.
Definition qgis.h:5170
@ Meters
Meters.
Definition qgis.h:5171
int mapHeight() const
Returns current map height in pixels.
void setMapUnitsPerPixel(double mapUnitsPerPixel)
Sets the map units per pixel.
void setMapRotation(double degrees, double cx, double cy)
Sets map rotation in degrees (clockwise).
QgsMapToPixel()
Constructor for an invalid QgsMapToPixel.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
static QgsMapToPixel fromScale(double scale, Qgis::DistanceUnit mapUnits, double dpi=96)
Returns a new QgsMapToPixel created using a specified scale and distance unit.
QTransform transform() const
Returns a QTransform encapsulating the map to pixel conversion.
int mapWidth() const
Returns the current map width in pixels.
double mapRotation() const
Returns the current map rotation in degrees (clockwise).
void setParameters(double mapUnitsPerPixel, double centerX, double centerY, int widthPixels, int heightPixels, double rotation)
Sets parameters for use in transforming coordinates.
QString showParameters() const
Returns a string representation of the parameters used in the transform.
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6975