Subversion Repositories public

Rev

Rev 159 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/***************************************************************************
 *   Copyright (C) 2007, 2008 by Andreas Theofilu                          *
 *   andreas@theosys.at                                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation version 3 of the License.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <iostream>
#include <qimage.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <qstring.h>
//#include <qcstring.h>
#include "transform.h"

using std::cout;
using std::cerr;
using std::clog;
using std::endl;

transform::transform(double _llat, double _llon, double _rlat, double _rlon)
{
        llat = _llat;
        llon = _llon;
        rlat = _rlat;
        rlon = _rlon;
        MapLatCtr = (rlat - llat) / 2.0 + llat;
        MapLonCtr = (llon - rlon) / 2.0 + rlon;
        MapXCtr = MapYCtr = 0;
        xscale = yscale = 0.0;
        width = height = 0;
}

transform::~transform()
{
}

/*
 * Set the dimensions in pixels of the image and calculate the scaling.
 */
void transform::setDimensions(int _width, int _height)
{
        width = _width;
        height = _height;
        MapXCtr = width / 2;
        MapYCtr = height / 2;
        xscale = (rlon - llon) / (double)width;
        yscale = -1.0 * ((llat - rlat) / (double)height);
        PixPerLatDeg = width / (llat - rlat);
        PixPerLonDeg = height / (rlon - llon);
}

/*
 * Set the scale of the image.
 * This function makes only a rudimentary check of the given values
 * and overwrites the previous values if no errors were found.
 */
void transform::setScale(double scx, double scy)
{
        if (scx <= 0.0 || scx > 1.0 || scy >= 0.0 || scy < -1.0)
           return;

        xscale = scx;
        yscale = scy;
}

/*
 * Return the current scale of X andd Y dimensions
 */
void transform::getScale(double *scx, double *scy)
{
        *scx = xscale;
        *scy = yscale;
}

/*
 * Calculate the pixel position on a raster map out of the
 * geo coordinates given in radian.
 */
/*bool transform::latLonToPix(double plat, double plon, int *px, int *py)
{
        if (plat < -180.0 || plat > 180.0 || plon < -180.0 || plon > 180.0)
           return false;

        if (px == 0 || py == 0)
           return false;

        *px = (int)(1.0 / (xscale * (plon - llon))) / width;
        *py = (int)(1.0 / (yscale * (rlat - plat))) / height;
clog << "px: " << *px << ", py: " << *py << endl;
        return true;
}
*/
bool transform::latLonToPix(double plat, double plon, int *px, int *py)
{
int x,y;
double lat, lon, xdist, ydist, dist, az, pixdist;

        if (plat < -180.0 || plat > 180.0 || plon < -180.0 || plon > 180.0)
           return false;

        if (px == 0 || py == 0)
           return false;

        lat = plat;
        lon = plon;
        ydist = PixPerLatDeg * (lat - MapLatCtr);
        xdist = PixPerLonDeg * (lon - MapLonCtr);
        az = atan(ydist / xdist);

        if (xdist < 0.0)
           az += M_PI;

        dist = (xdist * xdist) + (ydist * ydist);
        pixdist = sqrt(dist);
        x = (int)(MapXCtr + pixdist * cos(az));
        y = (int)(MapYCtr - pixdist * sin(az));
        *px = x;
        *py = y;
        return true;
}

/*
 * Calculate the offset inside an image. This value can be used in a
 * buffer as an index, for example.
 */
long transform::getOffset(double plat, double plon)
{
int x, y;

        latLonToPix(plat, plon, &x, &y);
        return ((long)width * (long)y + (long)x);
}

/*
 * Uses QT to load an image and cut a rectangular part of the image.
 * The function stores the new image in a temporary file. It appends "_tmp.png"
 * to the name of the new file. The new file is always a PNG file!
 *
 * FIXME: Currently the directory with the source image must be writeable.
 *        Otherwise the new temporary file can not be written!
 *        We should move the file into the /temp directory...
 */
bool transform::cutImage(double _llat, double _llon, double _rlat, double _rlon, QString fName)
{
int x, y, w, h, a, b;
QImage src, dst;

        if (!latLonToPix (_llat, _llon, &x, &y))
           return false;

        if (!latLonToPix (_rlat, _rlon, &a, &b))
           return false;

        if (!src.load (fName))
        {
           KMessageBox::error(0, i18n("Error loading image file %1!").arg(fName));
           return false;
        }

        w = a - x;
        h = b - y;

//      dst = QImage(w, h, 32);
//      dst.fill(0xc0c0c0);
//      bitBlt (&dst, 0, 0, &src, x, y, w, h, 0);
        dst = src.copy (x, y, w, h);

        if (!dst.save (fName + "_tmp.png", "PNG"))
        {
           KMessageBox::error(0, i18n("Error saving a temporary image file!"));
           return false;
        }

        return true;
}