158 |
andreas |
1 |
/***************************************************************************
|
|
|
2 |
* Copyright (C) 2007, 2008 by Andreas Theofilu *
|
|
|
3 |
* andreas@theosys.at *
|
|
|
4 |
* *
|
|
|
5 |
* This program is free software; you can redistribute it and/or modify *
|
|
|
6 |
* it under the terms of the GNU General Public License as published by *
|
|
|
7 |
* the Free Software Foundation version 3 of the License. *
|
|
|
8 |
* *
|
|
|
9 |
* This program is distributed in the hope that it will be useful, *
|
|
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
12 |
* GNU General Public License for more details. *
|
|
|
13 |
* *
|
|
|
14 |
* You should have received a copy of the GNU General Public License *
|
|
|
15 |
* along with this program; if not, write to the *
|
|
|
16 |
* Free Software Foundation, Inc., *
|
|
|
17 |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
|
18 |
***************************************************************************/
|
|
|
19 |
|
|
|
20 |
#include <iostream>
|
159 |
andreas |
21 |
#include <qimage.h>
|
|
|
22 |
#include <kmessagebox.h>
|
|
|
23 |
#include <klocale.h>
|
|
|
24 |
#include <qstring.h>
|
|
|
25 |
#include <qcstring.h>
|
158 |
andreas |
26 |
#include "transform.h"
|
|
|
27 |
|
|
|
28 |
using std::cout;
|
|
|
29 |
using std::cerr;
|
|
|
30 |
using std::clog;
|
|
|
31 |
using std::endl;
|
|
|
32 |
|
|
|
33 |
transform::transform(double _llat, double _llon, double _rlat, double _rlon)
|
|
|
34 |
{
|
|
|
35 |
llat = _llat;
|
|
|
36 |
llon = _llon;
|
|
|
37 |
rlat = _rlat;
|
|
|
38 |
rlon = _rlon;
|
|
|
39 |
MapLatCtr = (rlat - llat) / 2.0 + llat;
|
|
|
40 |
MapLonCtr = (llon - rlon) / 2.0 + rlon;
|
|
|
41 |
MapXCtr = MapYCtr = 0;
|
|
|
42 |
xscale = yscale = 0.0;
|
|
|
43 |
width = height = 0;
|
|
|
44 |
}
|
|
|
45 |
|
|
|
46 |
transform::~transform()
|
|
|
47 |
{
|
|
|
48 |
}
|
|
|
49 |
|
|
|
50 |
/*
|
|
|
51 |
* Set the dimensions in pixels of the image and calculate the scaling.
|
|
|
52 |
*/
|
|
|
53 |
void transform::setDimensions(int _width, int _height)
|
|
|
54 |
{
|
|
|
55 |
width = _width;
|
|
|
56 |
height = _height;
|
|
|
57 |
MapXCtr = width / 2;
|
|
|
58 |
MapYCtr = height / 2;
|
159 |
andreas |
59 |
xscale = (rlon - llon) / (double)width;
|
|
|
60 |
yscale = -1.0 * ((llat - rlat) / (double)height);
|
158 |
andreas |
61 |
PixPerLatDeg = width / (llat - rlat);
|
|
|
62 |
PixPerLonDeg = height / (rlon - llon);
|
|
|
63 |
}
|
|
|
64 |
|
|
|
65 |
/*
|
|
|
66 |
* Set the scale of the image.
|
|
|
67 |
* This function makes only a rudimentary check of the given values
|
|
|
68 |
* and overwrites the previous values if no errors were found.
|
|
|
69 |
*/
|
|
|
70 |
void transform::setScale(double scx, double scy)
|
|
|
71 |
{
|
|
|
72 |
if (scx <= 0.0 || scx > 1.0 || scy >= 0.0 || scy < -1.0)
|
|
|
73 |
return;
|
|
|
74 |
|
|
|
75 |
xscale = scx;
|
|
|
76 |
yscale = scy;
|
|
|
77 |
}
|
|
|
78 |
|
|
|
79 |
/*
|
|
|
80 |
* Return the current scale of X andd Y dimensions
|
|
|
81 |
*/
|
|
|
82 |
void transform::getScale(double *scx, double *scy)
|
|
|
83 |
{
|
|
|
84 |
*scx = xscale;
|
|
|
85 |
*scy = yscale;
|
|
|
86 |
}
|
|
|
87 |
|
|
|
88 |
/*
|
|
|
89 |
* Calculate the pixel position on a raster map out of the
|
|
|
90 |
* geo coordinates given in radian.
|
|
|
91 |
*/
|
159 |
andreas |
92 |
/*bool transform::latLonToPix(double plat, double plon, int *px, int *py)
|
|
|
93 |
{
|
|
|
94 |
if (plat < -180.0 || plat > 180.0 || plon < -180.0 || plon > 180.0)
|
|
|
95 |
return false;
|
|
|
96 |
|
|
|
97 |
if (px == 0 || py == 0)
|
|
|
98 |
return false;
|
|
|
99 |
|
|
|
100 |
*px = (int)(1.0 / (xscale * (plon - llon))) / width;
|
|
|
101 |
*py = (int)(1.0 / (yscale * (rlat - plat))) / height;
|
|
|
102 |
clog << "px: " << *px << ", py: " << *py << endl;
|
|
|
103 |
return true;
|
|
|
104 |
}
|
|
|
105 |
*/
|
158 |
andreas |
106 |
bool transform::latLonToPix(double plat, double plon, int *px, int *py)
|
|
|
107 |
{
|
|
|
108 |
int x,y;
|
|
|
109 |
double lat, lon, xdist, ydist, dist, az, pixdist;
|
|
|
110 |
|
159 |
andreas |
111 |
if (plat < -180.0 || plat > 180.0 || plon < -180.0 || plon > 180.0)
|
|
|
112 |
return false;
|
|
|
113 |
|
|
|
114 |
if (px == 0 || py == 0)
|
|
|
115 |
return false;
|
|
|
116 |
|
158 |
andreas |
117 |
lat = plat;
|
|
|
118 |
lon = plon;
|
|
|
119 |
ydist = PixPerLatDeg * (lat - MapLatCtr);
|
|
|
120 |
xdist = PixPerLonDeg * (lon - MapLonCtr);
|
|
|
121 |
az = atan(ydist / xdist);
|
|
|
122 |
|
|
|
123 |
if (xdist < 0.0)
|
|
|
124 |
az += M_PI;
|
|
|
125 |
|
|
|
126 |
dist = (xdist * xdist) + (ydist * ydist);
|
|
|
127 |
pixdist = sqrt(dist);
|
|
|
128 |
x = (int)(MapXCtr + pixdist * cos(az));
|
|
|
129 |
y = (int)(MapYCtr - pixdist * sin(az));
|
|
|
130 |
*px = x;
|
|
|
131 |
*py = y;
|
|
|
132 |
return true;
|
|
|
133 |
}
|
|
|
134 |
|
|
|
135 |
/*
|
|
|
136 |
* Calculate the offset inside an image. This value can be used in a
|
|
|
137 |
* buffer as an index, for example.
|
|
|
138 |
*/
|
|
|
139 |
long transform::getOffset(double plat, double plon)
|
|
|
140 |
{
|
|
|
141 |
int x, y;
|
|
|
142 |
|
|
|
143 |
latLonToPix(plat, plon, &x, &y);
|
|
|
144 |
return ((long)width * (long)y + (long)x);
|
|
|
145 |
}
|
159 |
andreas |
146 |
|
|
|
147 |
/*
|
|
|
148 |
* Uses QT to load an image and cut a rectangular part of the image.
|
|
|
149 |
* The function stores the new image in a temporary file. It appends "_tmp.png"
|
|
|
150 |
* to the name of the new file. The new file is always a PNG file!
|
|
|
151 |
*
|
|
|
152 |
* FIXME: Currently the directory with the source image must be writeable.
|
|
|
153 |
* Otherwise the new temporary file can not be written!
|
|
|
154 |
* We should move the file into the /temp directory...
|
|
|
155 |
*/
|
|
|
156 |
bool transform::cutImage(double _llat, double _llon, double _rlat, double _rlon, QString fName)
|
|
|
157 |
{
|
|
|
158 |
int x, y, w, h, a, b;
|
|
|
159 |
QImage src, dst;
|
|
|
160 |
|
|
|
161 |
if (!latLonToPix (_llat, _llon, &x, &y))
|
|
|
162 |
return false;
|
|
|
163 |
|
|
|
164 |
if (!latLonToPix (_rlat, _rlon, &a, &b))
|
|
|
165 |
return false;
|
|
|
166 |
|
|
|
167 |
if (!src.load (fName))
|
|
|
168 |
{
|
|
|
169 |
KMessageBox::error(0, i18n("Error loading image file " + fName + "!"));
|
|
|
170 |
return false;
|
|
|
171 |
}
|
|
|
172 |
|
|
|
173 |
w = a - x;
|
|
|
174 |
h = b - y;
|
|
|
175 |
|
|
|
176 |
dst.create(w, h, 32);
|
|
|
177 |
dst.fill(0xc0c0c0);
|
|
|
178 |
bitBlt (&dst, 0, 0, &src, x, y, w, h, 0);
|
|
|
179 |
|
|
|
180 |
if (!dst.save (fName + "_tmp.png", "PNG"))
|
|
|
181 |
{
|
|
|
182 |
KMessageBox::error(0, i18n("Error saving a temporary image file!"));
|
|
|
183 |
return false;
|
|
|
184 |
}
|
|
|
185 |
|
|
|
186 |
return true;
|
|
|
187 |
}
|