mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-27 21:24:47 +01:00
Fixed another bunch of GeoTIFF handling bugs
This commit is contained in:
parent
77c4eda385
commit
5698b4c9b0
@ -115,7 +115,8 @@ HEADERS += src/config.h \
|
||||
src/map/gcs.h \
|
||||
src/map/angularunits.h \
|
||||
src/map/primemeridian.h \
|
||||
src/map/linearunits.h
|
||||
src/map/linearunits.h \
|
||||
src/map/ct.h
|
||||
SOURCES += src/main.cpp \
|
||||
src/common/coordinates.cpp \
|
||||
src/common/rectc.cpp \
|
||||
|
@ -2,15 +2,17 @@
|
||||
#define ALBERSEQUAL_H
|
||||
|
||||
#include "ellipsoid.h"
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
|
||||
class AlbersEqual : public Projection
|
||||
class AlbersEqual : public CT
|
||||
{
|
||||
public:
|
||||
AlbersEqual(const Ellipsoid *ellipsoid, double standardParallel1,
|
||||
double standardParallel2, double latitudeOrigin, double longitudeOrigin,
|
||||
double falseEasting, double falseNorthing);
|
||||
|
||||
virtual CT *clone() const {return new AlbersEqual(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
|
@ -5,14 +5,14 @@
|
||||
static double sDMS2deg(double val)
|
||||
{
|
||||
double angle;
|
||||
char *decimal;
|
||||
char str[13];
|
||||
const char *decimal;
|
||||
|
||||
if (val < -999.9 || val > 999.9)
|
||||
return NAN;
|
||||
|
||||
sprintf(str, "%.7f", qAbs(val));
|
||||
decimal = strchr(str,'.');
|
||||
QString qstr(QString::number(qAbs(val), 'f', 7));
|
||||
const char *str = qstr.toLatin1().constData();
|
||||
decimal = strrchr(str, '.');
|
||||
int deg = str2int(str, decimal - str);
|
||||
int min = str2int(decimal + 1, 2);
|
||||
int sec = str2int(decimal + 3, 2);
|
||||
|
17
src/map/ct.h
Normal file
17
src/map/ct.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef CT_H
|
||||
#define CT_H
|
||||
|
||||
#include <QPointF>
|
||||
#include "common/coordinates.h"
|
||||
|
||||
class CT {
|
||||
public:
|
||||
virtual ~CT() {}
|
||||
|
||||
virtual CT *clone() const = 0;
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const = 0;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const = 0;
|
||||
};
|
||||
|
||||
#endif // CT_H
|
@ -46,7 +46,8 @@ static Coordinates molodensky(const Coordinates &c, const Datum &from,
|
||||
Datum::Datum(const Ellipsoid *ellipsoid, double dx, double dy,
|
||||
double dz) : _ellipsoid(ellipsoid), _dx(dx), _dy(dy), _dz(dz)
|
||||
{
|
||||
_WGS84 = (*this == WGS84) ? true : false;
|
||||
_WGS84 = (*_ellipsoid == *WGS84.ellipsoid() && _dx == WGS84.dx()
|
||||
&& _dy == WGS84.dy() && _dz == WGS84.dz()) ? true : false;
|
||||
}
|
||||
|
||||
Coordinates Datum::toWGS84(const Coordinates &c) const
|
||||
|
@ -325,25 +325,26 @@ bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
|
||||
.arg(kv.value(ProjectedCSTypeGeoKey).SHORT);
|
||||
return false;
|
||||
}
|
||||
_gcs = pcs->gcs();
|
||||
_projection = Projection::projection(_gcs->datum(), pcs->method(),
|
||||
pcs->setup());
|
||||
_projection = Projection(pcs->gcs(), pcs->method(), pcs->setup(),
|
||||
pcs->units());
|
||||
} else if (IS_SET(kv, ProjectionGeoKey)) {
|
||||
if (!(_gcs = gcs(kv)))
|
||||
const GCS *g = gcs(kv);
|
||||
if (!g)
|
||||
return false;
|
||||
const PCS *pcs;
|
||||
if (!(pcs = PCS::pcs(_gcs, kv.value(ProjectionGeoKey).SHORT))) {
|
||||
const PCS *pcs = PCS::pcs(g, kv.value(ProjectionGeoKey).SHORT);
|
||||
if (!pcs) {
|
||||
_errorString = QString("%1: unknown projection code")
|
||||
.arg(kv.value(GeographicTypeGeoKey).SHORT)
|
||||
.arg(kv.value(ProjectionGeoKey).SHORT);
|
||||
return false;
|
||||
}
|
||||
_projection = Projection::projection(_gcs->datum(), pcs->method(),
|
||||
pcs->setup());
|
||||
_projection = Projection(pcs->gcs(), pcs->method(), pcs->setup(),
|
||||
pcs->units());
|
||||
} else {
|
||||
if (!(_gcs = gcs(kv)))
|
||||
const GCS *g = gcs(kv);
|
||||
if (!g)
|
||||
return false;
|
||||
Projection::Method m = method(kv);
|
||||
Projection::Method m(method(kv));
|
||||
if (m.isNull())
|
||||
return false;
|
||||
|
||||
@ -366,7 +367,8 @@ bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
|
||||
au.toDegrees(kv.value(ProjStdParallel1GeoKey).DOUBLE),
|
||||
au.toDegrees(kv.value(ProjStdParallel2GeoKey).DOUBLE)
|
||||
);
|
||||
_projection = Projection::projection(_gcs->datum(), m, setup);
|
||||
|
||||
_projection = Projection(g, m, setup, lu);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -374,10 +376,11 @@ bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
|
||||
|
||||
bool GeoTIFF::geographicModel(QMap<quint16, Value> &kv)
|
||||
{
|
||||
if (!(_gcs = gcs(kv)))
|
||||
const GCS *g = gcs(kv);
|
||||
if (!g)
|
||||
return false;
|
||||
|
||||
_projection = new LatLon(_gcs->angularUnits());
|
||||
_projection = Projection(g);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -8,20 +8,17 @@
|
||||
#include "projection.h"
|
||||
#include "tifffile.h"
|
||||
#include "transform.h"
|
||||
#include "linearunits.h"
|
||||
|
||||
class GeoTIFF
|
||||
{
|
||||
public:
|
||||
GeoTIFF() : _projection(0) {}
|
||||
|
||||
bool load(const QString &path);
|
||||
|
||||
const GCS *gcs() const {return _gcs;}
|
||||
Projection *projection() const {return _projection;}
|
||||
const QTransform &transform() const {return _transform;}
|
||||
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
const Projection &projection() const {return _projection;}
|
||||
const QTransform &transform() const {return _transform;}
|
||||
|
||||
private:
|
||||
union Value {
|
||||
quint16 SHORT;
|
||||
@ -56,8 +53,7 @@ private:
|
||||
bool projectedModel(QMap<quint16, Value> &kv);
|
||||
|
||||
QTransform _transform;
|
||||
const GCS *_gcs;
|
||||
Projection *_projection;
|
||||
Projection _projection;
|
||||
|
||||
QString _errorString;
|
||||
};
|
||||
|
@ -2,14 +2,16 @@
|
||||
#define LAMBERTAZIMUTHAL_H
|
||||
|
||||
#include "ellipsoid.h"
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
|
||||
class LambertAzimuthal : public Projection
|
||||
class LambertAzimuthal : public CT
|
||||
{
|
||||
public:
|
||||
LambertAzimuthal(const Ellipsoid *ellipsoid, double latitudeOrigin,
|
||||
double longitudeOrigin, double falseEasting, double falseNorthing);
|
||||
|
||||
virtual CT *clone() const {return new LambertAzimuthal(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
#define LAMBERTCONIC_H
|
||||
|
||||
#include "ellipsoid.h"
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
|
||||
class LambertConic1 : public Projection
|
||||
class LambertConic1 : public CT
|
||||
{
|
||||
public:
|
||||
LambertConic1() {}
|
||||
@ -12,6 +12,8 @@ public:
|
||||
double longitudeOrigin, double scale, double falseEasting,
|
||||
double falseNorthing);
|
||||
|
||||
virtual CT *clone() const {return new LambertConic1(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
@ -28,13 +30,15 @@ private:
|
||||
double _rho_olat;
|
||||
};
|
||||
|
||||
class LambertConic2 : public Projection
|
||||
class LambertConic2 : public CT
|
||||
{
|
||||
public:
|
||||
LambertConic2(const Ellipsoid *ellipsoid, double standardParallel1,
|
||||
double standardParallel2, double latitudeOrigin, double longitudeOrigin,
|
||||
double falseEasting, double falseNorthing);
|
||||
|
||||
virtual CT *clone() const {return new LambertConic2(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
|
@ -1,14 +1,16 @@
|
||||
#ifndef LATLON_H
|
||||
#define LATLON_H
|
||||
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
#include "angularunits.h"
|
||||
|
||||
class LatLon : public Projection
|
||||
class LatLon : public CT
|
||||
{
|
||||
public:
|
||||
LatLon(const AngularUnits &au) : _au(au) {}
|
||||
|
||||
virtual CT *clone() const {return new LatLon(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const
|
||||
{return QPointF(_au.fromDegrees(c.lon()), _au.fromDegrees(c.lat()));}
|
||||
virtual Coordinates xy2ll(const QPointF &p) const
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <QDebug>
|
||||
#include <QPointF>
|
||||
|
||||
class LinearUnits
|
||||
{
|
||||
@ -14,7 +15,11 @@ public:
|
||||
bool isValid() const {return !std::isnan(_f);}
|
||||
|
||||
double toMeters(double val) const {return val * _f;}
|
||||
QPointF toMeters(const QPointF &p) const
|
||||
{return QPointF(p.x() * _f, p.y() * _f);}
|
||||
double fromMeters(double val) const {return val / _f;}
|
||||
QPointF fromMeters(const QPointF &p) const
|
||||
{return QPointF(p.x() / _f, p.y() /_f);}
|
||||
|
||||
friend bool operator==(const LinearUnits &lu1, const LinearUnits &lu2);
|
||||
friend QDebug operator<<(QDebug dbg, const LinearUnits &lu);
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include "latlon.h"
|
||||
#include "utm.h"
|
||||
#include "gcs.h"
|
||||
#include "mapfile.h"
|
||||
@ -150,31 +149,31 @@ bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MapFile::createDatum(const QString &datum)
|
||||
const GCS *MapFile::createGCS(const QString &datum)
|
||||
{
|
||||
if (!(_gcs = GCS::gcs(datum))) {
|
||||
_errorString = QString("%1: Unknown datum").arg(datum);
|
||||
return false;
|
||||
}
|
||||
const GCS *gcs;
|
||||
|
||||
return true;
|
||||
if (!(gcs = GCS::gcs(datum)))
|
||||
_errorString = QString("%1: Unknown datum").arg(datum);
|
||||
|
||||
return gcs;
|
||||
}
|
||||
|
||||
bool MapFile::createProjection(const QString &name,
|
||||
bool MapFile::createProjection(const GCS *gcs, const QString &name,
|
||||
const Projection::Setup &setup, QList<CalibrationPoint> &points)
|
||||
{
|
||||
if (name == "Mercator")
|
||||
_projection = Projection::projection(_gcs->datum(), 1024, setup);
|
||||
_projection = Projection(gcs, 1024, setup, 9001);
|
||||
else if (name == "Transverse Mercator")
|
||||
_projection = Projection::projection(_gcs->datum(), 9807, setup);
|
||||
_projection = Projection(gcs, 9807, setup, 9001);
|
||||
else if (name == "Latitude/Longitude")
|
||||
_projection = new LatLon(9102);
|
||||
_projection = Projection(gcs);
|
||||
else if (name == "Lambert Conformal Conic")
|
||||
_projection = Projection::projection(_gcs->datum(), 9802, setup);
|
||||
_projection = Projection(gcs, 9802, setup, 9001);
|
||||
else if (name == "Albers Equal Area")
|
||||
_projection = Projection::projection(_gcs->datum(), 9822, setup);
|
||||
_projection = Projection(gcs, 9822, setup, 9001);
|
||||
else if (name == "(A)Lambert Azimuthual Equal Area")
|
||||
_projection = Projection::projection(_gcs->datum(), 9820, setup);
|
||||
_projection = Projection(gcs, 9820, setup, 9001);
|
||||
else if (name == "(UTM) Universal Transverse Mercator") {
|
||||
int zone;
|
||||
if (points.first().zone)
|
||||
@ -183,44 +182,39 @@ bool MapFile::createProjection(const QString &name,
|
||||
zone = UTM::zone(points.first().ll);
|
||||
else {
|
||||
_errorString = "Can not determine UTM zone";
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
_projection = Projection::projection(_gcs->datum(), 9807,
|
||||
UTM::setup(zone));
|
||||
_projection = Projection(gcs, 9807, UTM::setup(zone), 9001);
|
||||
} else if (name == "(NZTM2) New Zealand TM 2000")
|
||||
_projection = Projection::projection(_gcs->datum(), 9807,
|
||||
Projection::Setup(0, 173.0, 0.9996, 1600000, 10000000, NAN, NAN));
|
||||
_projection = Projection(gcs, 9807, Projection::Setup(0, 173.0, 0.9996,
|
||||
1600000, 10000000, NAN, NAN), 9001);
|
||||
else if (name == "(BNG) British National Grid")
|
||||
_projection = Projection::projection(_gcs->datum(), 9807,
|
||||
Projection::Setup(49, -2, 0.999601, 400000, -100000, NAN, NAN));
|
||||
_projection = Projection(gcs, 9807, Projection::Setup(49, -2, 0.999601,
|
||||
400000, -100000, NAN, NAN), 9001);
|
||||
else if (name == "(IG) Irish Grid")
|
||||
_projection = Projection::projection(_gcs->datum(), 9807,
|
||||
Projection::Setup(53.5, -8, 1.000035, 200000, 250000, NAN, NAN));
|
||||
_projection = Projection(gcs, 9807, Projection::Setup(53.5, -8,
|
||||
1.000035, 200000, 250000, NAN, NAN), 9001);
|
||||
else if (name == "(SG) Swedish Grid")
|
||||
_projection = Projection::projection(_gcs->datum(), 9807,
|
||||
Projection::Setup(0, 15.808278, 1, 1500000, 0, NAN, NAN));
|
||||
_projection = Projection(gcs, 9807, Projection::Setup(0, 15.808278, 1,
|
||||
1500000, 0, NAN, NAN), 9001);
|
||||
else if (name == "(I) France Zone I")
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(49.5, 2.337229, NAN, 600000, 1200000, 48.598523,
|
||||
50.395912));
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(49.5, 2.337229,
|
||||
NAN, 600000, 1200000, 48.598523, 50.395912), 9001);
|
||||
else if (name == "(II) France Zone II")
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(46.8, 2.337229, NAN, 600000, 2200000, 45.898919,
|
||||
47.696014));
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(46.8, 2.337229,
|
||||
NAN, 600000, 2200000, 45.898919, 47.696014), 9001);
|
||||
else if (name == "(III) France Zone III")
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(44.1, 2.337229, NAN, 600000, 3200000, 43.199291,
|
||||
44.996094));
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(44.1, 2.337229,
|
||||
NAN, 600000, 3200000, 43.199291, 44.996094), 9001);
|
||||
else if (name == "(IV) France Zone IV")
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(42.165, 2.337229, NAN, 234.358, 4185861.369,
|
||||
41.560388, 42.767663));
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(42.165, 2.337229,
|
||||
NAN, 234.358, 4185861.369, 41.560388, 42.767663), 9001);
|
||||
else if (name == "(VICGRID) Victoria Australia")
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(-37, 145, NAN, 2500000, 4500000, -36, -38));
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(-37, 145, NAN,
|
||||
2500000, 4500000, -36, -38), 9001);
|
||||
else if (name == "(VG94) VICGRID94 Victoria Australia")
|
||||
_projection = Projection::projection(_gcs->datum(), 9802,
|
||||
Projection::Setup(-37, 145, NAN, 2500000, 2500000, -36, -38));
|
||||
_projection = Projection(gcs, 9802, Projection::Setup(-37, 145, NAN,
|
||||
2500000, 2500000, -36, -38), 9001);
|
||||
else {
|
||||
_errorString = QString("%1: Unknown map projection").arg(name);
|
||||
return false;
|
||||
@ -235,7 +229,7 @@ bool MapFile::computeTransformation(QList<CalibrationPoint> &points)
|
||||
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
if (points.at(i).rp.pp.isNull())
|
||||
points[i].rp.pp = _projection->ll2xy(points.at(i).ll);
|
||||
points[i].rp.pp = _projection.ll2xy(points.at(i).ll);
|
||||
|
||||
rp.append(points.at(i).rp);
|
||||
}
|
||||
@ -254,14 +248,15 @@ bool MapFile::computeTransformation(QList<CalibrationPoint> &points)
|
||||
bool MapFile::load(QIODevice &file)
|
||||
{
|
||||
QList<CalibrationPoint> points;
|
||||
QString projection, datum;
|
||||
QString ct, datum;
|
||||
Projection::Setup setup;
|
||||
const GCS *gcs;
|
||||
|
||||
if (!parseMapFile(file, points, projection, setup, datum))
|
||||
if (!parseMapFile(file, points, ct, setup, datum))
|
||||
return false;
|
||||
if (!createDatum(datum))
|
||||
if (!(gcs = createGCS(datum)))
|
||||
return false;
|
||||
if (!createProjection(projection, setup, points))
|
||||
if (!createProjection(gcs, ct, setup, points))
|
||||
return false;
|
||||
if (!computeTransformation(points))
|
||||
return false;
|
||||
|
@ -11,17 +11,15 @@ class MapFile
|
||||
{
|
||||
public:
|
||||
bool load(QIODevice &file);
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
const GCS *gcs() const {return _gcs;}
|
||||
Projection *projection() const {return _projection;}
|
||||
const Projection &projection() const {return _projection;}
|
||||
const QTransform &transform() const {return _transform;}
|
||||
|
||||
const QString &name() const {return _name;}
|
||||
const QString &image() const {return _image;}
|
||||
const QSize &size() const {return _size;}
|
||||
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
private:
|
||||
struct CalibrationPoint {
|
||||
ReferencePoint rp;
|
||||
@ -33,8 +31,8 @@ private:
|
||||
QString &projection, Projection::Setup &setup, QString &datum);
|
||||
bool parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
|
||||
QString &projection, Projection::Setup &setup, QString &datum);
|
||||
bool createDatum(const QString &datum);
|
||||
bool createProjection(const QString &projection,
|
||||
const GCS *createGCS(const QString &datum);
|
||||
bool createProjection(const GCS *gcs, const QString &projection,
|
||||
const Projection::Setup &setup, QList<CalibrationPoint> &points);
|
||||
bool computeTransformation(QList<CalibrationPoint> &points);
|
||||
|
||||
@ -42,8 +40,7 @@ private:
|
||||
QString _image;
|
||||
QSize _size;
|
||||
|
||||
const GCS *_gcs;
|
||||
Projection *_projection;
|
||||
Projection _projection;
|
||||
QTransform _transform;
|
||||
|
||||
QString _errorString;
|
||||
|
@ -1,11 +1,13 @@
|
||||
#ifndef MERCATOR_H
|
||||
#define MERCATOR_H
|
||||
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
|
||||
class Mercator : public Projection
|
||||
class Mercator : public CT
|
||||
{
|
||||
public:
|
||||
virtual CT *clone() const {return new Mercator(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
};
|
||||
|
@ -112,7 +112,6 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
|
||||
_valid = false;
|
||||
_img = 0;
|
||||
_projection = 0;
|
||||
_resolution = 0.0;
|
||||
_zoom = 0;
|
||||
_scale = QPointF(1.0, 1.0);
|
||||
@ -138,7 +137,6 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
_name = mf.name();
|
||||
_size = mf.size();
|
||||
_imgPath = mf.image();
|
||||
_gcs = mf.gcs();
|
||||
_projection = mf.projection();
|
||||
_transform = mf.transform();
|
||||
}
|
||||
@ -152,7 +150,6 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
_name = mf.name();
|
||||
_size = mf.size();
|
||||
_imgPath = mf.image();
|
||||
_gcs = mf.gcs();
|
||||
_projection = mf.projection();
|
||||
_transform = mf.transform();
|
||||
}
|
||||
@ -164,7 +161,6 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
|
||||
} else {
|
||||
_name = fi.fileName();
|
||||
_imgPath = fileName;
|
||||
_gcs = gt.gcs();
|
||||
_projection = gt.projection();
|
||||
_transform = gt.transform();
|
||||
}
|
||||
@ -207,7 +203,6 @@ OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
|
||||
|
||||
_valid = false;
|
||||
_img = 0;
|
||||
_projection = 0;
|
||||
_resolution = 0.0;
|
||||
_zoom = 0;
|
||||
_scale = QPointF(1.0, 1.0);
|
||||
@ -230,7 +225,6 @@ OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
|
||||
|
||||
_name = mf.name();
|
||||
_size = mf.size();
|
||||
_gcs = mf.gcs();
|
||||
_projection = mf.projection();
|
||||
_transform = mf.transform();
|
||||
|
||||
@ -244,7 +238,6 @@ OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
|
||||
OfflineMap::~OfflineMap()
|
||||
{
|
||||
delete _img;
|
||||
delete _projection;
|
||||
}
|
||||
|
||||
void OfflineMap::load()
|
||||
@ -363,19 +356,19 @@ void OfflineMap::draw(QPainter *painter, const QRectF &rect)
|
||||
QPointF OfflineMap::ll2xy(const Coordinates &c)
|
||||
{
|
||||
if (_ozf.isOpen()) {
|
||||
QPointF p(_transform.map(_projection->ll2xy(_gcs->fromWGS84(c))));
|
||||
QPointF p(_transform.map(_projection.ll2xy(c)));
|
||||
return QPointF(p.x() * _scale.x(), p.y() * _scale.y());
|
||||
} else
|
||||
return _transform.map(_projection->ll2xy(_gcs->fromWGS84(c)));
|
||||
return _transform.map(_projection.ll2xy(c));
|
||||
}
|
||||
|
||||
Coordinates OfflineMap::xy2ll(const QPointF &p)
|
||||
{
|
||||
if (_ozf.isOpen()) {
|
||||
return _gcs->toWGS84(_projection->xy2ll(_inverted.map(QPointF(p.x()
|
||||
/ _scale.x(), p.y() / _scale.y()))));
|
||||
return _projection.xy2ll(_inverted.map(QPointF(p.x() / _scale.x(),
|
||||
p.y() / _scale.y())));
|
||||
} else
|
||||
return _gcs->toWGS84(_projection->xy2ll(_inverted.map(p)));
|
||||
return _projection.xy2ll(_inverted.map(p));
|
||||
}
|
||||
|
||||
QRectF OfflineMap::bounds() const
|
||||
@ -402,8 +395,8 @@ qreal OfflineMap::zoomFit(const QSize &size, const RectC &br)
|
||||
if (!br.isValid())
|
||||
rescale(0);
|
||||
else {
|
||||
QRect sbr(QRectF(_transform.map(_projection->ll2xy(br.topLeft())),
|
||||
_transform.map(_projection->ll2xy(br.bottomRight())))
|
||||
QRect sbr(QRectF(_transform.map(_projection.ll2xy(br.topLeft())),
|
||||
_transform.map(_projection.ll2xy(br.bottomRight())))
|
||||
.toRect().normalized());
|
||||
|
||||
for (int i = 0; i < _ozf.zooms(); i++) {
|
||||
|
@ -2,10 +2,9 @@
|
||||
#define OFFLINEMAP_H
|
||||
|
||||
#include <QTransform>
|
||||
#include "common/coordinates.h"
|
||||
#include "gcs.h"
|
||||
#include "projection.h"
|
||||
#include "transform.h"
|
||||
#include "linearunits.h"
|
||||
#include "map.h"
|
||||
#include "tar.h"
|
||||
#include "ozf.h"
|
||||
@ -45,7 +44,7 @@ public:
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
QPointF ll2pp(const Coordinates &c) const
|
||||
{return _projection->ll2xy(c);}
|
||||
{return _projection.ll2xy(c);}
|
||||
QPointF xy2pp(const QPointF &p) const
|
||||
{return _inverted.map(p);}
|
||||
QPointF pp2xy(const QPointF &p) const
|
||||
@ -65,9 +64,7 @@ private:
|
||||
|
||||
QString _name;
|
||||
|
||||
QSize _size;
|
||||
const GCS *_gcs;
|
||||
Projection *_projection;
|
||||
Projection _projection;
|
||||
QTransform _transform, _inverted;
|
||||
|
||||
OZF _ozf;
|
||||
@ -77,6 +74,7 @@ private:
|
||||
QString _imgPath;
|
||||
QSize _tileSize;
|
||||
QString _tileName;
|
||||
QSize _size;
|
||||
|
||||
int _zoom;
|
||||
qreal _resolution;
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "lambertconic.h"
|
||||
#include "albersequal.h"
|
||||
#include "lambertazimuthal.h"
|
||||
#include "latlon.h"
|
||||
#include "gcs.h"
|
||||
#include "projection.h"
|
||||
|
||||
|
||||
@ -24,42 +26,85 @@ Projection::Method::Method(int id)
|
||||
}
|
||||
}
|
||||
|
||||
Projection *Projection::projection(const Datum &datum, const Method &method,
|
||||
const Setup &setup)
|
||||
Projection::Projection(const GCS *gcs, const Method &method, const Setup &setup,
|
||||
const LinearUnits &units) : _gcs(gcs), _units(units)
|
||||
{
|
||||
const Ellipsoid *ellipsoid = datum.ellipsoid();
|
||||
const Ellipsoid *ellipsoid = _gcs->datum().ellipsoid();
|
||||
|
||||
switch (method.id()) {
|
||||
case 9807:
|
||||
return new TransverseMercator(ellipsoid, setup.latitudeOrigin(),
|
||||
_ct = new TransverseMercator(ellipsoid, setup.latitudeOrigin(),
|
||||
setup.longitudeOrigin(), setup.scale(), setup.falseEasting(),
|
||||
setup.falseNorthing());
|
||||
break;
|
||||
case 1024:
|
||||
case 9841:
|
||||
return new Mercator();
|
||||
_ct = new Mercator();
|
||||
break;
|
||||
case 9802:
|
||||
return new LambertConic2(ellipsoid, setup.standardParallel1(),
|
||||
_ct = new LambertConic2(ellipsoid, setup.standardParallel1(),
|
||||
setup.standardParallel2(), setup.latitudeOrigin(),
|
||||
setup.longitudeOrigin(), setup.falseEasting(),
|
||||
setup.falseNorthing());
|
||||
break;
|
||||
case 9801:
|
||||
return new LambertConic1(ellipsoid, setup.latitudeOrigin(),
|
||||
_ct = new LambertConic1(ellipsoid, setup.latitudeOrigin(),
|
||||
setup.longitudeOrigin(), setup.scale(), setup.falseEasting(),
|
||||
setup.falseNorthing());
|
||||
break;
|
||||
case 9820:
|
||||
return new LambertAzimuthal(ellipsoid, setup.latitudeOrigin(),
|
||||
_ct = new LambertAzimuthal(ellipsoid, setup.latitudeOrigin(),
|
||||
setup.longitudeOrigin(), setup.falseEasting(),
|
||||
setup.falseNorthing());
|
||||
break;
|
||||
case 9822:
|
||||
return new AlbersEqual(ellipsoid, setup.standardParallel1(),
|
||||
_ct = new AlbersEqual(ellipsoid, setup.standardParallel1(),
|
||||
setup.standardParallel2(), setup.latitudeOrigin(),
|
||||
setup.longitudeOrigin(), setup.falseEasting(),
|
||||
setup.falseNorthing());
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
_ct = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Projection::Projection(const GCS *gcs) : _gcs(gcs)
|
||||
{
|
||||
_ct = new LatLon(gcs->angularUnits());
|
||||
_units = LinearUnits(9001);
|
||||
}
|
||||
|
||||
Projection::Projection(const Projection &p)
|
||||
{
|
||||
_gcs = p._gcs;
|
||||
_units = p._units;
|
||||
_ct = p._ct->clone();
|
||||
}
|
||||
|
||||
Projection::~Projection()
|
||||
{
|
||||
delete _ct;
|
||||
}
|
||||
|
||||
Projection &Projection::operator=(const Projection &p)
|
||||
{
|
||||
_gcs = p._gcs;
|
||||
_units = p._units;
|
||||
_ct = p._ct->clone();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QPointF Projection::ll2xy(const Coordinates &c) const
|
||||
{
|
||||
return _units.fromMeters(_ct->ll2xy(_gcs->fromWGS84(c)));
|
||||
}
|
||||
|
||||
Coordinates Projection::xy2ll(const QPointF &p) const
|
||||
{
|
||||
return _gcs->toWGS84(_ct->xy2ll(_units.toMeters(p)));
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Projection::Setup &setup)
|
||||
{
|
||||
dbg.nospace() << "Setup(" << setup.latitudeOrigin() << ", "
|
||||
|
@ -4,8 +4,11 @@
|
||||
#include <QPointF>
|
||||
#include <QDebug>
|
||||
#include "common/coordinates.h"
|
||||
#include "linearunits.h"
|
||||
|
||||
class Datum;
|
||||
class GCS;
|
||||
class CT;
|
||||
class AngularUnits;
|
||||
|
||||
class Projection {
|
||||
public:
|
||||
@ -65,13 +68,22 @@ public:
|
||||
int _id;
|
||||
};
|
||||
|
||||
virtual ~Projection() {}
|
||||
Projection() : _gcs(0), _ct(0) {}
|
||||
Projection(const Projection &p);
|
||||
Projection(const GCS *gcs, const Method &method, const Setup &setup,
|
||||
const LinearUnits &units);
|
||||
Projection(const GCS *gcs);
|
||||
~Projection();
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const = 0;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const = 0;
|
||||
Projection &operator=(const Projection &p);
|
||||
|
||||
static Projection *projection(const Datum &datum, const Method &method,
|
||||
const Setup &setup);
|
||||
QPointF ll2xy(const Coordinates &c) const;
|
||||
Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
private:
|
||||
const GCS * _gcs;
|
||||
CT *_ct;
|
||||
LinearUnits _units;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug dbg, const Projection::Setup &setup);
|
||||
|
@ -1,16 +1,18 @@
|
||||
#ifndef TRANSVERSEMERCATOR_H
|
||||
#define TRANSVERSEMERCATOR_H
|
||||
|
||||
#include "projection.h"
|
||||
#include "ct.h"
|
||||
#include "ellipsoid.h"
|
||||
|
||||
class TransverseMercator : public Projection
|
||||
class TransverseMercator : public CT
|
||||
{
|
||||
public:
|
||||
TransverseMercator(const Ellipsoid *ellipsoid, double latitudeOrigin,
|
||||
double longitudeOrigin, double scale, double falseEasting,
|
||||
double falseNorthing);
|
||||
|
||||
virtual CT *clone() const {return new TransverseMercator(*this);}
|
||||
|
||||
virtual QPointF ll2xy(const Coordinates &c) const;
|
||||
virtual Coordinates xy2ll(const QPointF &p) const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user