Subversion Repositories public

Rev

Rev 158 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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
}