QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
27 double xc,
28 double yc,
29 int width,
30 int height,
31 double rotation )
32 : mValid( true )
33 , mMapUnitsPerPixel( mapUnitsPerPixel )
34 , mWidth( width )
35 , mHeight( height )
36 , mRotation( rotation )
37 , mXCenter( xc )
38 , mYCenter( yc )
39 , mXMin( xc - ( mWidth * mMapUnitsPerPixel / 2.0 ) )
40 , mYMin( yc - ( mHeight * mMapUnitsPerPixel / 2.0 ) )
41{
42 Q_ASSERT( mapUnitsPerPixel > 0 );
43 updateMatrix();
44}
45
47 : mValid( true )
48 , mMapUnitsPerPixel( mapUnitsPerPixel )
49 , mWidth( 0 )
50 , mHeight( 0 )
51 , mXCenter( 0 )
52 , mYCenter( 0 )
53{
54 updateMatrix();
55}
56
57QgsMapToPixel QgsMapToPixel::fromScale( double scale, Qgis::DistanceUnit mapUnits, double dpi )
58{
59 const double metersPerPixel = 25.4 / dpi / 1000.0;
60 const double mapUnitsPerPixel = metersPerPixel * QgsUnitTypes::fromUnitToUnitFactor( Qgis::DistanceUnit::Meters, mapUnits );
61 return QgsMapToPixel( mapUnitsPerPixel * scale );
62}
63
65{
66 updateMatrix();
67}
68
69bool QgsMapToPixel::updateMatrix()
70{
71 const QTransform newMatrix = transform();
72
73 // https://github.com/qgis/QGIS/issues/20856
74 if ( !newMatrix.isInvertible() )
75 return false;
76
77 mMatrix = newMatrix;
78 return true;
79}
80
82{
83 mValid = true;
84
85 const double oldUnits = mMapUnitsPerPixel;
86 mMapUnitsPerPixel = mapUnitsPerPixel;
87 if ( !updateMatrix() )
88 {
89 mMapUnitsPerPixel = oldUnits;
90 }
91}
92
93void QgsMapToPixel::setMapRotation( double degrees, double cx, double cy )
94{
95 mValid = true;
96
97 const double oldRotation = mRotation;
98 const double oldXCenter = mXCenter;
99 const double oldYCenter = mYCenter;
100 const double oldWidth = mWidth;
101
102 mRotation = degrees;
103 mXCenter = cx;
104 mYCenter = cy;
105 if ( mWidth < 0 )
106 {
107 // set width not that we can compute it
108 mWidth = ( ( mXCenter - mXMin ) * 2 ) / mMapUnitsPerPixel;
109 }
110
111 if ( !updateMatrix() )
112 {
113 mRotation = oldRotation;
114 mXCenter = oldXCenter;
115 mYCenter = oldYCenter;
116 mWidth = oldWidth;
117 }
118}
119
121 double xc,
122 double yc,
123 int width,
124 int height,
125 double rotation,
126 bool *ok )
127{
128 mValid = true;
129
130 const double oldMUPP = mMapUnitsPerPixel;
131 const double oldXCenter = mXCenter;
132 const double oldYCenter = mYCenter;
133 const double oldWidth = mWidth;
134 const double oldHeight = mHeight;
135 const double oldRotation = mRotation;
136 const double oldXMin = mXMin;
137 const double oldYMin = mYMin;
138
139 mMapUnitsPerPixel = mapUnitsPerPixel;
140 mXCenter = xc;
141 mYCenter = yc;
142 mWidth = width;
143 mHeight = height;
144 mRotation = rotation;
145 mXMin = xc - ( mWidth * mMapUnitsPerPixel / 2.0 );
146 mYMin = yc - ( mHeight * mMapUnitsPerPixel / 2.0 );
147
148 if ( !updateMatrix() )
149 {
150 mMapUnitsPerPixel = oldMUPP;
151 mXCenter = oldXCenter;
152 mYCenter = oldYCenter;
153 mWidth = oldWidth;
154 mHeight = oldHeight;
155 mRotation = oldRotation;
156 mXMin = oldXMin;
157 mYMin = oldYMin;
158 *ok = false;
159 }
160 else
161 {
162 *ok = true;
163 }
164}
165
167 double xc,
168 double yc,
169 int width,
170 int height,
171 double rotation )
172{
173 mValid = true;
174 bool ok;
175 setParameters( mapUnitsPerPixel, xc, yc, width, height, rotation, &ok );
176}
177
179{
180 QString rep;
181 QTextStream( &rep ) << "Map units/pixel: " << mMapUnitsPerPixel
182 << " center: " << mXCenter << ',' << mYCenter
183 << " rotation: " << mRotation
184 << " size: " << mWidth << 'x' << mHeight;
185 return rep;
186}
187
188QTransform QgsMapToPixel::transform() const
189{
190 // NOTE: operations are done in the reverse order in which
191 // they are configured, so translation to geographical
192 // center happens first, then scaling, then rotation
193 // and finally translation to output viewport center
194
195 const double rotation = mapRotation();
196 if ( qgsDoubleNear( rotation, 0.0 ) )
197 {
198 //no rotation, return a simplified matrix
199 return QTransform::fromScale( 1.0 / mMapUnitsPerPixel, -1.0 / mMapUnitsPerPixel )
200 .translate( -mXMin, - ( mYMin + mHeight * mMapUnitsPerPixel ) );
201 }
202 else
203 {
204 const double cy = mapHeight() / 2.0;
205 const double cx = mapWidth() / 2.0;
206 return QTransform::fromTranslate( cx, cy )
207 .rotate( rotation )
208 .scale( 1 / mMapUnitsPerPixel, -1 / mMapUnitsPerPixel )
209 .translate( -mXCenter, -mYCenter );
210 }
211}
212
DistanceUnit
Units of distance.
Definition qgis.h:5013
@ Meters
Meters.
Definition qgis.h:5014
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:6607