1
0
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:
Martin Tůma 2018-01-25 00:19:11 +01:00
parent 77c4eda385
commit 5698b4c9b0
19 changed files with 208 additions and 131 deletions

View File

@ -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 \

View File

@ -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;

View File

@ -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
View 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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;
};

View File

@ -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++) {

View File

@ -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;

View File

@ -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() << ", "

View File

@ -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);

View File

@ -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;