Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsmaptopixel.h - 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 : : #ifndef QGSMAPTOPIXEL
18 : : #define QGSMAPTOPIXEL
19 : :
20 : : #include "qgis_core.h"
21 : : #include "qgis_sip.h"
22 : : #include <QTransform>
23 : : #include <vector>
24 : : #include "qgsunittypes.h"
25 : : #include "qgspointxy.h"
26 : :
27 : : #include <cassert>
28 : : #include <memory>
29 : :
30 : : class QPoint;
31 : :
32 : : /**
33 : : * \ingroup core
34 : : * \brief Perform transforms between map coordinates and device coordinates.
35 : : *
36 : : * This class can convert device coordinates to map coordinates and vice versa.
37 : : */
38 : 0 : class CORE_EXPORT QgsMapToPixel
39 : : {
40 : : public:
41 : :
42 : : /**
43 : : * Constructor
44 : : * \param mapUnitsPerPixel Map units per pixel
45 : : * \param centerX X coordinate of map center, in geographical units
46 : : * \param centerY Y coordinate of map center, in geographical units
47 : : * \param widthPixels Output width, in pixels
48 : : * \param heightPixels Output height, in pixels
49 : : * \param rotation clockwise rotation in degrees
50 : : * \since QGIS 2.8
51 : : */
52 : : QgsMapToPixel( double mapUnitsPerPixel, double centerX, double centerY, int widthPixels, int heightPixels, double rotation );
53 : :
54 : : /**
55 : : * Constructor
56 : : * \param mapUnitsPerPixel Map units per pixel
57 : : */
58 : : QgsMapToPixel( double mapUnitsPerPixel );
59 : :
60 : : /**
61 : : * Returns a new QgsMapToPixel created using a specified \a scale and distance unit.
62 : : * \param scale map scale denominator, e.g. 1000.0 for a 1:1000 map.
63 : : * \param dpi screen DPI
64 : : * \param mapUnits map units
65 : : * \returns matching QgsMapToPixel
66 : : * \since QGIS 3.0
67 : : */
68 : : static QgsMapToPixel fromScale( double scale, QgsUnitTypes::DistanceUnit mapUnits, double dpi = 96 );
69 : :
70 : : /**
71 : : * Constructor
72 : : *
73 : : * Use setParameters to fill
74 : : */
75 : : QgsMapToPixel();
76 : :
77 : : /**
78 : : * Transform the point \a p from map (world) coordinates to device coordinates.
79 : : * \param p Point to transform
80 : : * \returns QgsPointXY in device coordinates
81 : : */
82 : 0 : QgsPointXY transform( const QgsPointXY &p ) const
83 : : {
84 : 0 : qreal x = p.x();
85 : 0 : qreal y = p.y();
86 : 0 : transformInPlace( x, y );
87 : 0 : return QgsPointXY( x, y );
88 : : }
89 : :
90 : : /**
91 : : * Transform the point \a p from map (world) coordinates to device coordinates in place.
92 : : */
93 : : void transform( QgsPointXY *p ) const
94 : : {
95 : : qreal x = p->x();
96 : : qreal y = p->y();
97 : : transformInPlace( x, y );
98 : : p->set( x, y );
99 : : }
100 : :
101 : : /**
102 : : * Transform the point specified by x,y from map (world)
103 : : * coordinates to device coordinates
104 : : * \param x x coordinate o point to transform
105 : : * \param y y coordinate of point to transform
106 : : * \returns QgsPointXY in device coordinates
107 : : */
108 : 0 : QgsPointXY transform( qreal x, qreal y ) const
109 : : {
110 : 0 : transformInPlace( x, y );
111 : 0 : return QgsPointXY( x, y );
112 : : }
113 : :
114 : : /**
115 : : * Transforms device coordinates to map coordinates. Modifies the
116 : : * given coordinates in place. Intended as a fast way to do the
117 : : * transform.
118 : : */
119 : 0 : void transformInPlace( double &x, double &y ) const
120 : : {
121 : : qreal mx, my;
122 : 0 : mMatrix.map( static_cast< qreal >( x ), static_cast< qreal >( y ), &mx, &my );
123 : 0 : x = mx;
124 : 0 : y = my;
125 : 0 : }
126 : :
127 : : /**
128 : : * Transforms device coordinates to map coordinates. Modifies the
129 : : * given coordinates in place. Intended as a fast way to do the
130 : : * transform.
131 : : * \note Not available in Python bindings
132 : : */
133 : : void transformInPlace( float &x, float &y ) const SIP_SKIP
134 : : {
135 : : double mx = x, my = y;
136 : : transformInPlace( mx, my );
137 : : x = mx;
138 : : y = my;
139 : : }
140 : :
141 : : #ifndef SIP_RUN
142 : :
143 : : /**
144 : : * Transform device coordinates to map coordinates. Modifies the
145 : : * given coordinates in place. Intended as a fast way to do the
146 : : * transform.
147 : : * \note not available in Python bindings
148 : : */
149 : : template <class T> SIP_SKIP
150 : : void transformInPlace( QVector<T> &x, QVector<T> &y ) const
151 : : {
152 : : assert( x.size() == y.size() );
153 : : for ( int i = 0; i < x.size(); ++i )
154 : : transformInPlace( x[i], y[i] );
155 : : }
156 : : #endif
157 : :
158 : : //! Transform device coordinates to map (world) coordinates
159 : 0 : QgsPointXY toMapCoordinates( int x, int y ) const
160 : : {
161 : 0 : return toMapCoordinates( static_cast<double>( x ), static_cast<double>( y ) );
162 : : }
163 : :
164 : : //! Transform device coordinates to map (world) coordinates
165 : 0 : QgsPointXY toMapCoordinates( double x, double y ) const SIP_PYNAME( toMapCoordinatesF )
166 : : {
167 : : bool invertible;
168 : 0 : QTransform matrix = mMatrix.inverted( &invertible );
169 : 0 : assert( invertible );
170 : : qreal mx, my;
171 : 0 : matrix.map( static_cast< qreal >( x ), static_cast< qreal >( y ), &mx, &my );
172 : 0 : return QgsPointXY( mx, my );
173 : : }
174 : :
175 : : /**
176 : : * Transform device coordinates to map (world) coordinates
177 : : * \param p Point to be converted to map cooordinates
178 : : * \returns QgsPointXY in map coorndiates
179 : : */
180 : 0 : QgsPointXY toMapCoordinates( QPoint p ) const
181 : : {
182 : 0 : QgsPointXY mapPt = toMapCoordinates( static_cast<double>( p.x() ), static_cast<double>( p.y() ) );
183 : 0 : return QgsPointXY( mapPt );
184 : : }
185 : :
186 : : /**
187 : : * Transform device coordinates to map (world) coordinates
188 : : * \deprecated since QGIS 3.4 use toMapCoordinates instead
189 : : */
190 : : Q_DECL_DEPRECATED QgsPointXY toMapPoint( double x, double y ) const SIP_DEPRECATED
191 : : {
192 : : return toMapCoordinates( x, y );
193 : : }
194 : :
195 : : /**
196 : : * Set map units per pixel
197 : : * \param mapUnitsPerPixel Map units per pixel
198 : : */
199 : : void setMapUnitsPerPixel( double mapUnitsPerPixel );
200 : :
201 : : //! Returns current map units per pixel
202 : 0 : double mapUnitsPerPixel() const { return mMapUnitsPerPixel; }
203 : :
204 : : /**
205 : : * Returns current map width in pixels
206 : : * The information is only known if setRotation was used
207 : : * \since QGIS 2.8
208 : : */
209 : 0 : int mapWidth() const { return mWidth; }
210 : :
211 : : /**
212 : : * Returns current map height in pixels
213 : : * \since QGIS 2.8
214 : : */
215 : 0 : int mapHeight() const { return mHeight; }
216 : :
217 : : /**
218 : : * Set map rotation in degrees (clockwise)
219 : : * \param degrees clockwise rotation in degrees
220 : : * \param cx X ordinate of map center in geographical units
221 : : * \param cy Y ordinate of map center in geographical units
222 : : * \since QGIS 2.8
223 : : */
224 : : void setMapRotation( double degrees, double cx, double cy );
225 : :
226 : : /**
227 : : * Returns current map rotation in degrees (clockwise)
228 : : * \since QGIS 2.8
229 : : */
230 : 6 : double mapRotation() const { return mRotation; }
231 : :
232 : : /**
233 : : * Set parameters for use in transforming coordinates
234 : : * \param mapUnitsPerPixel Map units per pixel
235 : : * \param centerX X coordinate of map center, in geographical units
236 : : * \param centerY Y coordinate of map center, in geographical units
237 : : * \param widthPixels Output width, in pixels
238 : : * \param heightPixels Output height, in pixels
239 : : * \param rotation clockwise rotation in degrees
240 : : * \since QGIS 2.8
241 : : */
242 : : void setParameters( double mapUnitsPerPixel, double centerX, double centerY, int widthPixels, int heightPixels, double rotation );
243 : :
244 : : //! String representation of the parameters used in the transform
245 : : QString showParameters() const;
246 : :
247 : : /**
248 : : * Returns a QTransform encapsulating the map to pixel conversion.
249 : : */
250 : : QTransform transform() const;
251 : :
252 : : /**
253 : : * Returns the center x-coordinate for the transform.
254 : : * \see yCenter()
255 : : * \since QGIS 3.0
256 : : */
257 : 0 : double xCenter() const { return mXCenter; }
258 : :
259 : : /**
260 : : * Returns the center y-coordinate for the transform.
261 : : * \see xCenter()
262 : : * \since QGIS 3.0
263 : : */
264 : 0 : double yCenter() const { return mYCenter; }
265 : :
266 : 0 : bool operator==( const QgsMapToPixel &other ) const
267 : : {
268 : 0 : return mMapUnitsPerPixel == other.mMapUnitsPerPixel
269 : 0 : && mWidth == other.mWidth
270 : 0 : && mHeight == other.mHeight
271 : 0 : && mRotation == other.mRotation
272 : 0 : && mXCenter == other.mXCenter
273 : 0 : && mYCenter == other.mYCenter
274 : 0 : && mXMin == other.mXMin
275 : 0 : && mYMin == other.mYMin;
276 : : }
277 : :
278 : 0 : bool operator!=( const QgsMapToPixel &other ) const
279 : : {
280 : 0 : return !( *this == other );
281 : : }
282 : :
283 : : private:
284 : : double mMapUnitsPerPixel = 1;
285 : : int mWidth = 1;
286 : : int mHeight = 1;
287 : : double mRotation = 0.0;
288 : : double mXCenter = 0.5;
289 : : double mYCenter = 0.5;
290 : : double mXMin = 0;
291 : : double mYMin = 0;
292 : : QTransform mMatrix;
293 : :
294 : : bool updateMatrix();
295 : : };
296 : :
297 : :
298 : : #endif // QGSMAPTOPIXEL
|