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