1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-30 22:51:16 +01:00

Refactoring

Moved Projection::Method and Projection::Setup to the Conversion class
This commit is contained in:
Martin Tůma 2024-03-19 22:39:42 +01:00
parent bd8d2267c7
commit a48b46d0fb
16 changed files with 293 additions and 291 deletions

View File

@ -2,6 +2,7 @@
#include "map/pcs.h" #include "map/pcs.h"
#include "map/gcs.h" #include "map/gcs.h"
#include "map/utm.h" #include "map/utm.h"
#include "map/projection.h"
#include "gpsdumpparser.h" #include "gpsdumpparser.h"
static double dms2dd(const QStringList &dms) static double dms2dd(const QStringList &dms)

View File

@ -303,20 +303,20 @@ bool BSBMap::createProjection(const QString &datum, const QString &proj,
} }
if (!proj.compare("MERCATOR", Qt::CaseInsensitive)) { if (!proj.compare("MERCATOR", Qt::CaseInsensitive)) {
Projection::Setup setup(0, c.lon(), NAN, 0, 0, NAN, NAN); Conversion::Setup setup(0, c.lon(), NAN, 0, 0, NAN, NAN);
pcs = PCS(gcs, Conversion(9804, setup, 9001)); pcs = PCS(gcs, Conversion(9804, setup, 9001));
} else if (!proj.compare("TRANSVERSE MERCATOR", Qt::CaseInsensitive)) { } else if (!proj.compare("TRANSVERSE MERCATOR", Qt::CaseInsensitive)) {
Projection::Setup setup(0, params[1], params[2], 0, 0, NAN, NAN); Conversion::Setup setup(0, params[1], params[2], 0, 0, NAN, NAN);
pcs = PCS(gcs, Conversion(9807, setup, 9001)); pcs = PCS(gcs, Conversion(9807, setup, 9001));
} else if (!proj.compare("UNIVERSAL TRANSVERSE MERCATOR", } else if (!proj.compare("UNIVERSAL TRANSVERSE MERCATOR",
Qt::CaseInsensitive)) { Qt::CaseInsensitive)) {
Projection::Setup setup(0, params[0], 0.9996, 500000, 0, NAN, NAN); Conversion::Setup setup(0, params[0], 0.9996, 500000, 0, NAN, NAN);
pcs = PCS(gcs, Conversion(9807, setup, 9001)); pcs = PCS(gcs, Conversion(9807, setup, 9001));
} else if (!proj.compare("LAMBERT CONFORMAL CONIC", Qt::CaseInsensitive)) { } else if (!proj.compare("LAMBERT CONFORMAL CONIC", Qt::CaseInsensitive)) {
Projection::Setup setup(0, params[0], NAN, 0, 0, params[2], params[3]); Conversion::Setup setup(0, params[0], NAN, 0, 0, params[2], params[3]);
pcs = PCS(gcs, Conversion(9802, setup, 9001)); pcs = PCS(gcs, Conversion(9802, setup, 9001));
} else if (!proj.compare("POLYCONIC", Qt::CaseInsensitive)) { } else if (!proj.compare("POLYCONIC", Qt::CaseInsensitive)) {
Projection::Setup setup(0, params[0], NAN, 0, 0, NAN, NAN); Conversion::Setup setup(0, params[0], NAN, 0, 0, NAN, NAN);
pcs = PCS(gcs, Conversion(9818, setup, 9001)); pcs = PCS(gcs, Conversion(9818, setup, 9001));
} else { } else {
_errorString = proj + ": Unknown/missing projection"; _errorString = proj + ": Unknown/missing projection";

View File

@ -1,8 +1,9 @@
#include <QFile> #include <QFile>
#include "common/csv.h" #include "common/csv.h"
#include "angularunits.h"
#include "conversion.h" #include "conversion.h"
static bool parameter(int key, double val, int units, Projection::Setup &setup) static bool parameter(int key, double val, int units, Conversion::Setup &setup)
{ {
switch (key) { switch (key) {
case 8801: case 8801:
@ -65,7 +66,7 @@ static bool parameter(int key, double val, int units, Projection::Setup &setup)
} }
} }
static int projectionSetup(const QByteArrayList &list, Projection::Setup &setup) static int projectionSetup(const QByteArrayList &list, Conversion::Setup &setup)
{ {
bool r1, r2, r3; bool r1, r2, r3;
@ -87,13 +88,36 @@ static int projectionSetup(const QByteArrayList &list, Projection::Setup &setup)
return 0; return 0;
} }
Conversion::Method::Method(int id)
{
switch (id) {
case 1024:
case 1041:
case 9801:
case 9802:
case 9804:
case 9807:
case 9809:
case 9815:
case 9818:
case 9819:
case 9820:
case 9822:
case 9829:
_id = id;
break;
default:
_id = 0;
}
}
QMap<int, Conversion::Entry> Conversion::_conversions = defaults(); QMap<int, Conversion::Entry> Conversion::_conversions = defaults();
QMap<int, Conversion::Entry> Conversion::defaults() QMap<int, Conversion::Entry> Conversion::defaults()
{ {
QMap<int, Conversion::Entry> map; QMap<int, Conversion::Entry> map;
map.insert(3856, Entry("Popular Visualisation Pseudo-Mercator", 1024, map.insert(3856, Entry("Popular Visualisation Pseudo-Mercator", 1024,
Projection::Setup(), 9001, 4400)); Setup(), 9001, 4400));
return map; return map;
} }
@ -159,7 +183,7 @@ bool Conversion::loadList(const QString &path)
csv.line()); csv.line());
continue; continue;
} }
if (!Projection::Method(transform).isValid()) { if (!Method(transform).isValid()) {
qWarning("%s:%d: Unknown coordinate transformation code", qWarning("%s:%d: Unknown coordinate transformation code",
qPrintable(path), csv.line()); qPrintable(path), csv.line());
continue; continue;
@ -170,7 +194,7 @@ bool Conversion::loadList(const QString &path)
continue; continue;
} }
Projection::Setup setup; Setup setup;
int pn = projectionSetup(entry, setup); int pn = projectionSetup(entry, setup);
if (pn) { if (pn) {
qWarning("%s: %d: Invalid projection parameter #%d", qWarning("%s: %d: Invalid projection parameter #%d",
@ -196,6 +220,21 @@ QList<KV<int, QString> > Conversion::list()
} }
#ifndef QT_NO_DEBUG #ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const Conversion::Setup &setup)
{
dbg.nospace() << "Setup(" << setup.latitudeOrigin() << ", "
<< setup.longitudeOrigin() << ", " << setup.scale() << ", "
<< setup.falseEasting() << ", " << setup.falseNorthing() << ", "
<< setup.standardParallel1() << ", " << setup.standardParallel2() << ")";
return dbg.space();
}
QDebug operator<<(QDebug dbg, const Conversion::Method &method)
{
dbg.nospace() << "Method(" << method.id() << ")";
return dbg.space();
}
QDebug operator<<(QDebug dbg, const Conversion &conversion) QDebug operator<<(QDebug dbg, const Conversion &conversion)
{ {
dbg.nospace() << "Conversion(" << conversion.method() << ", " dbg.nospace() << "Conversion(" << conversion.method() << ", "

View File

@ -1,18 +1,81 @@
#ifndef CONVERSION_H #ifndef CONVERSION_H
#define CONVERSION_H #define CONVERSION_H
#include "projection.h" #include <cmath>
#include <QDebug>
#include <common/kv.h>
#include "coordinatesystem.h"
#include "linearunits.h"
class Conversion { class Conversion {
public: public:
Conversion() {} class Setup {
Conversion(const Projection::Method &method, public:
const Projection::Setup &setup, const LinearUnits &units, Setup() : _latitudeOrigin(NAN), _longitudeOrigin(NAN), _scale(NAN),
const CoordinateSystem &cs = CoordinateSystem()) : _method(method), _falseEasting(NAN), _falseNorthing(NAN), _standardParallel1(NAN),
_setup(setup), _units(units), _cs(cs) {} _standardParallel2(NAN) {}
Setup(double latitudeOrigin, double longitudeOrigin, double scale,
double falseEasting, double falseNorthing, double standardParallel1,
double standardParallel2) : _latitudeOrigin(latitudeOrigin),
_longitudeOrigin(longitudeOrigin), _scale(scale),
_falseEasting(falseEasting), _falseNorthing(falseNorthing),
_standardParallel1(standardParallel1),
_standardParallel2(standardParallel2) {}
const Projection::Method &method() const {return _method;} double latitudeOrigin() const {return _latitudeOrigin;}
const Projection::Setup &setup() const {return _setup;} double longitudeOrigin() const {return _longitudeOrigin;}
double scale() const {return _scale;}
double falseEasting() const {return _falseEasting;}
double falseNorthing() const {return _falseNorthing;}
double standardParallel1() const {return _standardParallel1;}
double standardParallel2() const {return _standardParallel2;}
void setLatitudeOrigin(double val) {_latitudeOrigin = val;}
void setLongitudeOrigin(double val) {_longitudeOrigin = val;}
void setScale(double val) {_scale = val;}
void setFalseEasting(double val) {_falseEasting = val;}
void setFalseNorthing(double val) {_falseNorthing = val;}
void setStandardParallel1(double val) {_standardParallel1 = val;}
void setStandardParallel2(double val) {_standardParallel2 = val;}
bool isNull() const
{
return std::isnan(_latitudeOrigin)
&& std::isnan(_longitudeOrigin) && std::isnan(_scale)
&& std::isnan(_falseEasting) && std::isnan(_falseNorthing)
&& std::isnan(_standardParallel1)
&& std::isnan(_standardParallel2);
}
private:
double _latitudeOrigin;
double _longitudeOrigin;
double _scale;
double _falseEasting;
double _falseNorthing;
double _standardParallel1;
double _standardParallel2;
};
class Method {
public:
Method() : _id(0) {}
Method(int id);
int id() const {return _id;}
bool isNull() const {return (_id == 0);}
bool isValid() const {return !isNull();}
private:
int _id;
};
Conversion() {}
Conversion(const Method &method, const Setup &setup,
const LinearUnits &units, const CoordinateSystem &cs = CoordinateSystem())
: _method(method), _setup(setup), _units(units), _cs(cs) {}
const Method &method() const {return _method;}
const Setup &setup() const {return _setup;}
const LinearUnits &units() const {return _units;} const LinearUnits &units() const {return _units;}
const CoordinateSystem &cs() const {return _cs;} const CoordinateSystem &cs() const {return _cs;}
@ -34,30 +97,28 @@ public:
private: private:
class Entry { class Entry {
public: public:
Entry(const QString &name, const Projection::Method &method, Entry(const QString &name, const Method &method, const Setup &setup,
const Projection::Setup &setup, const LinearUnits &units, const LinearUnits &units, const CoordinateSystem &cs = CoordinateSystem())
const CoordinateSystem &cs = CoordinateSystem()) : _name(name), _method(method), _setup(setup), _units(units), _cs(cs) {}
: _name(name), _method(method), _setup(setup), _units(units),
_cs(cs) {}
const QString &name() const {return _name;} const QString &name() const {return _name;}
const Projection::Method &method() const {return _method;} const Method &method() const {return _method;}
const Projection::Setup &setup() const {return _setup;} const Setup &setup() const {return _setup;}
const LinearUnits &units() const {return _units;} const LinearUnits &units() const {return _units;}
const CoordinateSystem &cs() const {return _cs;} const CoordinateSystem &cs() const {return _cs;}
private: private:
QString _name; QString _name;
Projection::Method _method; Method _method;
Projection::Setup _setup; Setup _setup;
LinearUnits _units; LinearUnits _units;
CoordinateSystem _cs; CoordinateSystem _cs;
}; };
static QMap<int, Entry> defaults(); static QMap<int, Entry> defaults();
Projection::Method _method; Method _method;
Projection::Setup _setup; Setup _setup;
LinearUnits _units; LinearUnits _units;
CoordinateSystem _cs; CoordinateSystem _cs;
@ -65,6 +126,8 @@ private:
}; };
#ifndef QT_NO_DEBUG #ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const Conversion::Setup &setup);
QDebug operator<<(QDebug dbg, const Conversion::Method &method);
QDebug operator<<(QDebug dbg, const Conversion &conversion); QDebug operator<<(QDebug dbg, const Conversion &conversion);
#endif // QT_NO_DEBUG #endif // QT_NO_DEBUG

View File

@ -321,38 +321,38 @@ GCS GeoTIFF::geographicCS(QMap<quint16, Value> &kv)
return gcs; return gcs;
} }
Projection::Method GeoTIFF::coordinateTransformation(QMap<quint16, Value> &kv) Conversion::Method GeoTIFF::coordinateTransformation(QMap<quint16, Value> &kv)
{ {
if (!IS_SET(kv, ProjCoordTransGeoKey)) { if (!IS_SET(kv, ProjCoordTransGeoKey)) {
_errorString = "Missing coordinate transformation method"; _errorString = "Missing coordinate transformation method";
return Projection::Method(); return Conversion::Method();
} }
switch (kv.value(ProjCoordTransGeoKey).SHORT) { switch (kv.value(ProjCoordTransGeoKey).SHORT) {
case CT_TransverseMercator: case CT_TransverseMercator:
return Projection::Method(9807); return Conversion::Method(9807);
case CT_ObliqueMercator: case CT_ObliqueMercator:
return Projection::Method(9815); return Conversion::Method(9815);
case CT_Mercator: case CT_Mercator:
return Projection::Method(9804); return Conversion::Method(9804);
case CT_LambertConfConic_2SP: case CT_LambertConfConic_2SP:
return Projection::Method(9802); return Conversion::Method(9802);
case CT_LambertConfConic_1SP: case CT_LambertConfConic_1SP:
return Projection::Method(9801); return Conversion::Method(9801);
case CT_LambertAzimEqualArea: case CT_LambertAzimEqualArea:
return Projection::Method(9820); return Conversion::Method(9820);
case CT_AlbersEqualArea: case CT_AlbersEqualArea:
return Projection::Method(9822); return Conversion::Method(9822);
case CT_PolarStereographic: case CT_PolarStereographic:
return Projection::Method(9829); return Conversion::Method(9829);
case CT_ObliqueStereographic: case CT_ObliqueStereographic:
return Projection::Method(9809); return Conversion::Method(9809);
case CT_Polyconic: case CT_Polyconic:
return Projection::Method(9818); return Conversion::Method(9818);
default: default:
_errorString = QString("%1: unknown coordinate transformation method") _errorString = QString("%1: unknown coordinate transformation method")
.arg(kv.value(ProjCoordTransGeoKey).SHORT); .arg(kv.value(ProjCoordTransGeoKey).SHORT);
return Projection::Method(); return Conversion::Method();
} }
} }
@ -383,7 +383,7 @@ bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
GCS gcs(geographicCS(kv)); GCS gcs(geographicCS(kv));
if (gcs.isNull()) if (gcs.isNull())
return false; return false;
Projection::Method method(coordinateTransformation(kv)); Conversion::Method method(coordinateTransformation(kv));
if (method.isNull()) if (method.isNull())
return false; return false;
@ -452,7 +452,7 @@ bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
else else
fe = NAN; fe = NAN;
Projection::Setup setup(lat0, lon0, scale, fe, fn, sp1, sp2); Conversion::Setup setup(lat0, lon0, scale, fe, fn, sp1, sp2);
_projection = Projection(PCS(gcs, Conversion(method, setup, lu))); _projection = Projection(PCS(gcs, Conversion(method, setup, lu)));
} }

View File

@ -5,6 +5,7 @@
#include <QList> #include <QList>
#include "transform.h" #include "transform.h"
#include "projection.h" #include "projection.h"
#include "conversion.h"
class TIFFFile; class TIFFFile;
class GCS; class GCS;
@ -49,7 +50,7 @@ private:
double &val) const; double &val) const;
GCS geographicCS(QMap<quint16, Value> &kv); GCS geographicCS(QMap<quint16, Value> &kv);
Projection::Method coordinateTransformation(QMap<quint16, Value> &kv); Conversion::Method coordinateTransformation(QMap<quint16, Value> &kv);
bool geographicModel(QMap<quint16, Value> &kv); bool geographicModel(QMap<quint16, Value> &kv);
bool projectedModel(QMap<quint16, Value> &kv); bool projectedModel(QMap<quint16, Value> &kv);

View File

@ -17,7 +17,7 @@ static double parameter(const QString &str, bool *res, double dflt = 0.0)
} }
int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points, int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points,
QString &projection, Projection::Setup &setup, QString &datum) QString &projection, Conversion::Setup &setup, QString &datum)
{ {
bool res, utm = false; bool res, utm = false;
int ln = 1, zone = 0; int ln = 1, zone = 0;
@ -123,7 +123,7 @@ int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points,
setup = UTM::setup(zone); setup = UTM::setup(zone);
else { else {
bool r[8]; bool r[8];
setup = Projection::Setup( setup = Conversion::Setup(
parameter(list[1], &r[1]), parameter(list[2], &r[2]), parameter(list[1], &r[1]), parameter(list[2], &r[2]),
parameter(list[3], &r[3], 1.0), parameter(list[4], &r[4]), parameter(list[3], &r[3], 1.0), parameter(list[4], &r[4]),
parameter(list[5], &r[5]), parameter(list[6], &r[6]), parameter(list[5], &r[5]), parameter(list[6], &r[6]),
@ -143,7 +143,7 @@ int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points,
} }
bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points, bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
QString &projection, Projection::Setup &setup, QString &datum) QString &projection, Conversion::Setup &setup, QString &datum)
{ {
int el; int el;
@ -161,7 +161,7 @@ bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
} }
bool MapFile::createProjection(const QString &datum, const QString &name, bool MapFile::createProjection(const QString &datum, const QString &name,
const Projection::Setup &setup) const Conversion::Setup &setup)
{ {
PCS pcs; PCS pcs;
@ -188,37 +188,37 @@ bool MapFile::createProjection(const QString &datum, const QString &name,
else if (name == "Polyconic (American)") else if (name == "Polyconic (American)")
pcs = PCS(gcs, Conversion(9818, setup, 9001)); pcs = PCS(gcs, Conversion(9818, setup, 9001));
else if (name == "(NZTM2) New Zealand TM 2000") else if (name == "(NZTM2) New Zealand TM 2000")
pcs = PCS(gcs, Conversion(9807, Projection::Setup(0, 173.0, 0.9996, pcs = PCS(gcs, Conversion(9807, Conversion::Setup(0, 173.0, 0.9996,
1600000, 10000000, NAN, NAN), 9001)); 1600000, 10000000, NAN, NAN), 9001));
else if (name == "(BNG) British National Grid") else if (name == "(BNG) British National Grid")
pcs = PCS(gcs, Conversion(9807, Projection::Setup(49, -2, 0.999601, pcs = PCS(gcs, Conversion(9807, Conversion::Setup(49, -2, 0.999601,
400000, -100000, NAN, NAN), 9001)); 400000, -100000, NAN, NAN), 9001));
else if (name == "(IG) Irish Grid") else if (name == "(IG) Irish Grid")
pcs = PCS(gcs, Conversion(9807, Projection::Setup(53.5, -8, 1.000035, pcs = PCS(gcs, Conversion(9807, Conversion::Setup(53.5, -8, 1.000035,
200000, 250000, NAN, NAN), 9001)); 200000, 250000, NAN, NAN), 9001));
else if (name == "(SG) Swedish Grid") else if (name == "(SG) Swedish Grid")
pcs = PCS(gcs, Conversion(9807, Projection::Setup(0, 15.808278, 1, pcs = PCS(gcs, Conversion(9807, Conversion::Setup(0, 15.808278, 1,
1500000, 0, NAN, NAN), 9001)); 1500000, 0, NAN, NAN), 9001));
else if (name == "(I) France Zone I") else if (name == "(I) France Zone I")
pcs = PCS(gcs, Conversion(9802, Projection::Setup(49.5, 2.337229, NAN, pcs = PCS(gcs, Conversion(9802, Conversion::Setup(49.5, 2.337229, NAN,
600000, 1200000, 48.598523, 50.395912), 9001)); 600000, 1200000, 48.598523, 50.395912), 9001));
else if (name == "(II) France Zone II") else if (name == "(II) France Zone II")
pcs = PCS(gcs, Conversion(9802, Projection::Setup(46.8, 2.337229, NAN, pcs = PCS(gcs, Conversion(9802, Conversion::Setup(46.8, 2.337229, NAN,
600000, 2200000, 45.898919, 47.696014), 9001)); 600000, 2200000, 45.898919, 47.696014), 9001));
else if (name == "(III) France Zone III") else if (name == "(III) France Zone III")
pcs = PCS(gcs, Conversion(9802, Projection::Setup(44.1, 2.337229, NAN, pcs = PCS(gcs, Conversion(9802, Conversion::Setup(44.1, 2.337229, NAN,
600000, 3200000, 43.199291, 44.996094), 9001)); 600000, 3200000, 43.199291, 44.996094), 9001));
else if (name == "(IV) France Zone IV") else if (name == "(IV) France Zone IV")
pcs = PCS(gcs, Conversion(9802, Projection::Setup(42.165, 2.337229, NAN, pcs = PCS(gcs, Conversion(9802, Conversion::Setup(42.165, 2.337229, NAN,
234.358, 4185861.369, 41.560388, 42.767663), 9001)); 234.358, 4185861.369, 41.560388, 42.767663), 9001));
else if (name == "(VICGRID) Victoria Australia") else if (name == "(VICGRID) Victoria Australia")
pcs = PCS(gcs, Conversion(9802, Projection::Setup(-37, 145, NAN, pcs = PCS(gcs, Conversion(9802, Conversion::Setup(-37, 145, NAN,
2500000, 4500000, -36, -38), 9001)); 2500000, 4500000, -36, -38), 9001));
else if (name == "(VG94) VICGRID94 Victoria Australia") else if (name == "(VG94) VICGRID94 Victoria Australia")
pcs = PCS(gcs, Conversion(9802, Projection::Setup(-37, 145, NAN, pcs = PCS(gcs, Conversion(9802, Conversion::Setup(-37, 145, NAN,
2500000, 2500000, -36, -38), 9001)); 2500000, 2500000, -36, -38), 9001));
else if (name == "(SUI) Swiss Grid") else if (name == "(SUI) Swiss Grid")
pcs = PCS(gcs, Conversion(9815, Projection::Setup(46.570866, 7.26225, pcs = PCS(gcs, Conversion(9815, Conversion::Setup(46.570866, 7.26225,
1.0, 600000, 200000, 90.0, 90.0), 9001)); 1.0, 600000, 200000, 90.0, 90.0), 9001));
else { else {
_errorString = QString("%1: Unknown map projection").arg(name); _errorString = QString("%1: Unknown map projection").arg(name);
@ -250,7 +250,7 @@ MapFile::MapFile(QIODevice &file)
{ {
QList<CalibrationPoint> points; QList<CalibrationPoint> points;
QString ct, datum; QString ct, datum;
Projection::Setup setup; Conversion::Setup setup;
if (!parseMapFile(file, points, ct, setup, datum)) if (!parseMapFile(file, points, ct, setup, datum))
return; return;

View File

@ -3,6 +3,7 @@
#include "transform.h" #include "transform.h"
#include "projection.h" #include "projection.h"
#include "conversion.h"
#include "calibrationpoint.h" #include "calibrationpoint.h"
class QIODevice; class QIODevice;
@ -26,11 +27,11 @@ public:
private: private:
int parse(QIODevice &device, QList<CalibrationPoint> &points, int parse(QIODevice &device, QList<CalibrationPoint> &points,
QString &projection, Projection::Setup &setup, QString &datum); QString &projection, Conversion::Setup &setup, QString &datum);
bool parseMapFile(QIODevice &device, QList<CalibrationPoint> &points, bool parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
QString &projection, Projection::Setup &setup, QString &datum); QString &projection, Conversion::Setup &setup, QString &datum);
bool createProjection(const QString &datum, const QString &projection, bool createProjection(const QString &datum, const QString &projection,
const Projection::Setup &setup); const Conversion::Setup &setup);
bool computeTransformation(const QList<CalibrationPoint> &points); bool computeTransformation(const QList<CalibrationPoint> &points);
QString _name; QString _name;

View File

@ -75,93 +75,93 @@ static PointD corner2point(const QString &name, const QSize &size)
return PointD(); return PointD();
} }
static Projection::Setup lcc2setup(const QStringList &list) static Conversion::Setup lcc2setup(const QStringList &list)
{ {
double params[6]; double params[6];
bool ok; bool ok;
if (list.size() < 7) if (list.size() < 7)
return Projection::Setup(); return Conversion::Setup();
for (int i = 1; i < 7; i++) { for (int i = 1; i < 7; i++) {
params[i - 1] = list.at(i).toDouble(&ok); params[i - 1] = list.at(i).toDouble(&ok);
if (!ok) if (!ok)
return Projection::Setup(); return Conversion::Setup();
} }
return Projection::Setup(params[0], params[1], NAN, params[4], return Conversion::Setup(params[0], params[1], NAN, params[4],
params[5], params[2], params[3]); params[5], params[2], params[3]);
} }
static Projection::Setup laea2setup(const QStringList &list) static Conversion::Setup laea2setup(const QStringList &list)
{ {
double params[2]; double params[2];
bool ok; bool ok;
if (list.size() < 3) if (list.size() < 3)
return Projection::Setup(); return Conversion::Setup();
for (int i = 1; i < 3; i++) { for (int i = 1; i < 3; i++) {
params[i - 1] = list.at(i).toDouble(&ok); params[i - 1] = list.at(i).toDouble(&ok);
if (!ok) if (!ok)
return Projection::Setup(); return Conversion::Setup();
} }
return Projection::Setup(params[1], params[0], NAN, 0, 0, NAN, NAN); return Conversion::Setup(params[1], params[0], NAN, 0, 0, NAN, NAN);
} }
static Projection::Setup polyconic2setup(const QStringList &list) static Conversion::Setup polyconic2setup(const QStringList &list)
{ {
double params[3]; double params[3];
bool ok; bool ok;
if (list.size() < 4) if (list.size() < 4)
return Projection::Setup(); return Conversion::Setup();
for (int i = 1; i < 4; i++) { for (int i = 1; i < 4; i++) {
params[i - 1] = list.at(i).toDouble(&ok); params[i - 1] = list.at(i).toDouble(&ok);
if (!ok) if (!ok)
return Projection::Setup(); return Conversion::Setup();
} }
return Projection::Setup(NAN, params[0], NAN, params[1], params[2], NAN, return Conversion::Setup(NAN, params[0], NAN, params[1], params[2], NAN,
NAN); NAN);
} }
static Projection::Setup tm2setup(const QStringList &list) static Conversion::Setup tm2setup(const QStringList &list)
{ {
double params[5]; double params[5];
bool ok; bool ok;
if (list.size() < 6) if (list.size() < 6)
return Projection::Setup(); return Conversion::Setup();
for (int i = 1; i < 6; i++) { for (int i = 1; i < 6; i++) {
params[i - 1] = list.at(i).toDouble(&ok); params[i - 1] = list.at(i).toDouble(&ok);
if (!ok) if (!ok)
return Projection::Setup(); return Conversion::Setup();
} }
return Projection::Setup(params[1], params[0], params[2], params[3], return Conversion::Setup(params[1], params[0], params[2], params[3],
params[4], NAN, NAN); params[4], NAN, NAN);
} }
static Projection::Setup utm2setup(const QStringList &list) static Conversion::Setup utm2setup(const QStringList &list)
{ {
bool ok; bool ok;
if (list.size() < 2) if (list.size() < 2)
return Projection::Setup(); return Conversion::Setup();
int zone = list.at(1).toInt(&ok); int zone = list.at(1).toInt(&ok);
return ok ? UTM::setup(zone) : Projection::Setup(); return ok ? UTM::setup(zone) : Conversion::Setup();
} }
static Projection::Setup mercator2setup(const QStringList &list) static Conversion::Setup mercator2setup(const QStringList &list)
{ {
double lon; double lon;
bool ok; bool ok;
if (list.size() < 2) if (list.size() < 2)
return Projection::Setup(0, 0, NAN, 0, 0, NAN, NAN); return Conversion::Setup(0, 0, NAN, 0, 0, NAN, NAN);
lon = list.at(1).toDouble(&ok); lon = list.at(1).toDouble(&ok);
return ok ? Projection::Setup(0, lon, NAN, 0, 0, NAN, NAN) return ok ? Conversion::Setup(0, lon, NAN, 0, 0, NAN, NAN)
: Projection::Setup(); : Conversion::Setup();
} }
static GCS createGCS(const QString &datum) static GCS createGCS(const QString &datum)
@ -180,7 +180,7 @@ static Projection createProjection(const GCS &gcs, const QString &name)
else if (pl.first() == "UTM") else if (pl.first() == "UTM")
pcs = PCS(gcs, Conversion(9807, utm2setup(pl), 9001)); pcs = PCS(gcs, Conversion(9807, utm2setup(pl), 9001));
else if (pl.first() == "Mercator") else if (pl.first() == "Mercator")
pcs = PCS(gcs, Conversion(1024, Projection::Setup(), 9001)); pcs = PCS(gcs, Conversion(1024, Conversion::Setup(), 9001));
else if (pl.first() == "Mercator Ellipsoidal") else if (pl.first() == "Mercator Ellipsoidal")
pcs = PCS(gcs, Conversion(9804, mercator2setup(pl), 9001)); pcs = PCS(gcs, Conversion(9804, mercator2setup(pl), 9001));
else if (pl.first() == "Transverse Mercator") else if (pl.first() == "Transverse Mercator")
@ -192,13 +192,13 @@ static Projection createProjection(const GCS &gcs, const QString &name)
else if (pl.first() == "Polyconic (American)") else if (pl.first() == "Polyconic (American)")
pcs = PCS(gcs, Conversion(9818, polyconic2setup(pl), 9001)); pcs = PCS(gcs, Conversion(9818, polyconic2setup(pl), 9001));
else if (pl.first() == "(IG) Irish Grid") else if (pl.first() == "(IG) Irish Grid")
pcs = PCS(gcs, Conversion(9807, Projection::Setup(53.5, -8, 1.000035, pcs = PCS(gcs, Conversion(9807, Conversion::Setup(53.5, -8, 1.000035,
200000, 250000, NAN, NAN), 9001)); 200000, 250000, NAN, NAN), 9001));
else if (pl.first() == "(SUI) Swiss Grid") else if (pl.first() == "(SUI) Swiss Grid")
pcs = PCS(gcs, Conversion(9815, Projection::Setup(46.570866, 7.26225, pcs = PCS(gcs, Conversion(9815, Conversion::Setup(46.570866, 7.26225,
1.0, 600000, 200000, 90.0, 90.0), 9001)); 1.0, 600000, 200000, 90.0, 90.0), 9001));
else if (pl.first() == "Rijksdriehoeksmeting") else if (pl.first() == "Rijksdriehoeksmeting")
pcs = PCS(gcs, Conversion(9809, Projection::Setup(52.1561605555556, pcs = PCS(gcs, Conversion(9809, Conversion::Setup(52.1561605555556,
5.38763888888889, 0.9999079, 155000, 463000, NAN, NAN), 9001)); 5.38763888888889, 0.9999079, 155000, 463000, NAN, NAN), 9001));
else else
return Projection(); return Projection();

View File

@ -4,7 +4,7 @@
#include "pcs.h" #include "pcs.h"
#include "prjfile.h" #include "prjfile.h"
static Projection::Method projectionMethod(const QString &name) static Conversion::Method projectionMethod(const QString &name)
{ {
static const struct { static const struct {
int id; int id;
@ -30,10 +30,10 @@ static Projection::Method projectionMethod(const QString &name)
qWarning("%s: unknown projection", qPrintable(name)); qWarning("%s: unknown projection", qPrintable(name));
return Projection::Method(); return Conversion::Method();
} }
static void setParameter(Projection::Setup *setup, const QString &name, static void setParameter(Conversion::Setup *setup, const QString &name,
double val) double val)
{ {
// latitude origin // latitude origin
@ -460,7 +460,7 @@ void PRJFile::primeMeridian(CTX &ctx, PrimeMeridian *pm, int *epsg)
*pm = PrimeMeridian(lon); *pm = PrimeMeridian(lon);
} }
void PRJFile::parameter(CTX &ctx, Projection::Setup *setup) void PRJFile::parameter(CTX &ctx, Conversion::Setup *setup)
{ {
QString name; QString name;
@ -478,7 +478,7 @@ void PRJFile::parameter(CTX &ctx, Projection::Setup *setup)
} }
} }
void PRJFile::projection(CTX &ctx, Projection::Method *method) void PRJFile::projection(CTX &ctx, Conversion::Method *method)
{ {
int epsg = -1; int epsg = -1;
QString proj; QString proj;
@ -490,7 +490,7 @@ void PRJFile::projection(CTX &ctx, Projection::Method *method)
optAuthority(ctx, &epsg); optAuthority(ctx, &epsg);
compare(ctx, RBRK); compare(ctx, RBRK);
*method = (epsg > 0) ? Projection::Method(epsg) : projectionMethod(proj); *method = (epsg > 0) ? Conversion::Method(epsg) : projectionMethod(proj);
} }
void PRJFile::optProjectedCS2(CTX &ctx, int *epsg) void PRJFile::optProjectedCS2(CTX &ctx, int *epsg)
@ -521,8 +521,8 @@ void PRJFile::projectedCS(CTX &ctx, PCS *pcs)
int epsg = -1; int epsg = -1;
GCS gcs; GCS gcs;
LinearUnits lu; LinearUnits lu;
Projection::Method method; Conversion::Method method;
Projection::Setup setup; Conversion::Setup setup;
compare(ctx, PROJCS); compare(ctx, PROJCS);
compare(ctx, LBRK); compare(ctx, LBRK);

View File

@ -2,6 +2,7 @@
#define PRJFILE_H #define PRJFILE_H
#include <QFile> #include <QFile>
#include "conversion.h"
#include "projection.h" #include "projection.h"
class Datum; class Datum;
@ -57,8 +58,8 @@ private:
void geographicCS(CTX &ctx, GCS *gcs); void geographicCS(CTX &ctx, GCS *gcs);
void projectedCS(CTX &ctx, PCS *pcs); void projectedCS(CTX &ctx, PCS *pcs);
void compdCS(CTX &ctx); void compdCS(CTX &ctx);
void projection(CTX &ctx, Projection::Method *method); void projection(CTX &ctx, Conversion::Method *method);
void parameter(CTX &ctx, Projection::Setup *setup); void parameter(CTX &ctx, Conversion::Setup *setup);
void datum(CTX &ctx, Datum *dtm, int *epsg); void datum(CTX &ctx, Datum *dtm, int *epsg);
void verticalDatum(CTX &ctx); void verticalDatum(CTX &ctx);
void unit(CTX &ctx, double *val, int *epsg); void unit(CTX &ctx, double *val, int *epsg);

View File

@ -9,40 +9,16 @@
#include "proj/obliquestereographic.h" #include "proj/obliquestereographic.h"
#include "proj/polyconic.h" #include "proj/polyconic.h"
#include "datum.h" #include "datum.h"
#include "gcs.h"
#include "pcs.h" #include "pcs.h"
#include "projection.h" #include "projection.h"
Projection::Method::Method(int id)
{
switch (id) {
case 1024:
case 1041:
case 9801:
case 9802:
case 9804:
case 9807:
case 9809:
case 9815:
case 9818:
case 9819:
case 9820:
case 9822:
case 9829:
_id = id;
break;
default:
_id = 0;
}
}
Projection::Projection(const PCS &pcs) Projection::Projection(const PCS &pcs)
: _gcs(pcs.gcs()), _ct(0), _units(pcs.conversion().units()), : _gcs(pcs.gcs()), _ct(0), _units(pcs.conversion().units()),
_cs(pcs.conversion().cs()) _cs(pcs.conversion().cs())
{ {
const Ellipsoid &ellipsoid = _gcs.datum().ellipsoid(); const Ellipsoid &ellipsoid = _gcs.datum().ellipsoid();
const Projection::Setup &setup = pcs.conversion().setup(); const Conversion::Setup &setup = pcs.conversion().setup();
switch (pcs.conversion().method().id()) { switch (pcs.conversion().method().id()) {
case 1024: case 1024:
@ -154,32 +130,3 @@ bool Projection::operator==(const Projection &p) const
return (*_ct == *p._ct && _gcs == p._gcs && _units == p._units return (*_ct == *p._ct && _gcs == p._gcs && _units == p._units
&& _cs == p._cs); && _cs == p._cs);
} }
PointD Projection::ll2xy(const Coordinates &c) const
{
Q_ASSERT(isValid());
return _units.fromMeters(_ct->ll2xy(_gcs.fromWGS84(c)));
}
Coordinates Projection::xy2ll(const PointD &p) const
{
Q_ASSERT(isValid());
return _gcs.toWGS84(_ct->xy2ll(_units.toMeters(p)));
}
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const Projection::Setup &setup)
{
dbg.nospace() << "Setup(" << setup.latitudeOrigin() << ", "
<< setup.longitudeOrigin() << ", " << setup.scale() << ", "
<< setup.falseEasting() << ", " << setup.falseNorthing() << ", "
<< setup.standardParallel1() << ", " << setup.standardParallel2() << ")";
return dbg.space();
}
QDebug operator<<(QDebug dbg, const Projection::Method &method)
{
dbg.nospace() << "Method(" << method.id() << ")";
return dbg.space();
}
#endif // QT_NO_DEBUG

View File

@ -1,76 +1,19 @@
#ifndef PROJECTION_H #ifndef PROJECTION_H
#define PROJECTION_H #define PROJECTION_H
#include <QDebug> #include <QtGlobal>
#include "common/coordinates.h" #include "common/coordinates.h"
#include "pointd.h" #include "pointd.h"
#include "linearunits.h" #include "linearunits.h"
#include "coordinatesystem.h" #include "coordinatesystem.h"
#include "gcs.h" #include "gcs.h"
#include "ct.h"
#include "proj/latlon.h" #include "proj/latlon.h"
class PCS; class PCS;
class CT;
class AngularUnits;
class Projection { class Projection {
public: public:
class Setup {
public:
Setup() : _latitudeOrigin(NAN), _longitudeOrigin(NAN), _scale(NAN),
_falseEasting(NAN), _falseNorthing(NAN), _standardParallel1(NAN),
_standardParallel2(NAN) {}
Setup(double latitudeOrigin, double longitudeOrigin, double scale,
double falseEasting, double falseNorthing, double standardParallel1,
double standardParallel2) : _latitudeOrigin(latitudeOrigin),
_longitudeOrigin(longitudeOrigin), _scale(scale),
_falseEasting(falseEasting), _falseNorthing(falseNorthing),
_standardParallel1(standardParallel1),
_standardParallel2(standardParallel2) {}
double latitudeOrigin() const {return _latitudeOrigin;}
double longitudeOrigin() const {return _longitudeOrigin;}
double scale() const {return _scale;}
double falseEasting() const {return _falseEasting;}
double falseNorthing() const {return _falseNorthing;}
double standardParallel1() const {return _standardParallel1;}
double standardParallel2() const {return _standardParallel2;}
void setLatitudeOrigin(double val) {_latitudeOrigin = val;}
void setLongitudeOrigin(double val) {_longitudeOrigin = val;}
void setScale(double val) {_scale = val;}
void setFalseEasting(double val) {_falseEasting = val;}
void setFalseNorthing(double val) {_falseNorthing = val;}
void setStandardParallel1(double val) {_standardParallel1 = val;}
void setStandardParallel2(double val) {_standardParallel2 = val;}
bool isNull() const {return std::isnan(_latitudeOrigin)
&& std::isnan(_longitudeOrigin) && std::isnan(_scale)
&& std::isnan(_falseEasting) && std::isnan(_falseNorthing)
&& std::isnan(_standardParallel1) && std::isnan(_standardParallel2);}
private:
double _latitudeOrigin;
double _longitudeOrigin;
double _scale;
double _falseEasting;
double _falseNorthing;
double _standardParallel1;
double _standardParallel2;
};
class Method {
public:
Method() : _id(0) {}
Method(int id);
int id() const {return _id;}
bool isNull() const {return (_id == 0);}
bool isValid() const {return !isNull();}
private:
int _id;
};
Projection() : _ct(0) {} Projection() : _ct(0) {}
Projection(const Projection &p); Projection(const Projection &p);
Projection(const PCS &pcs); Projection(const PCS &pcs);
@ -87,8 +30,8 @@ public:
} }
bool isValid() const bool isValid() const
{ {
// We do not check the CoordinateSystem here as it is not always defined /* We do not check the CoordinateSystem here as it is not always defined
// and except of WMTS/WMS it is not needed. and except of WMTS/WMS it is not needed. */
return (_gcs.isValid() && _ct != 0 && _units.isValid()); return (_gcs.isValid() && _ct != 0 && _units.isValid());
} }
bool isGeographic() const bool isGeographic() const
@ -96,8 +39,16 @@ public:
return (dynamic_cast<const LatLon*>(_ct) != 0); return (dynamic_cast<const LatLon*>(_ct) != 0);
} }
PointD ll2xy(const Coordinates &c) const; PointD ll2xy(const Coordinates &c) const
Coordinates xy2ll(const PointD &p) const; {
Q_ASSERT(isValid());
return _units.fromMeters(_ct->ll2xy(_gcs.fromWGS84(c)));
}
Coordinates xy2ll(const PointD &p) const
{
Q_ASSERT(isValid());
return _gcs.toWGS84(_ct->xy2ll(_units.toMeters(p)));
}
const LinearUnits &units() const {return _units;} const LinearUnits &units() const {return _units;}
const CoordinateSystem &coordinateSystem() const {return _cs;} const CoordinateSystem &coordinateSystem() const {return _cs;}
@ -109,9 +60,4 @@ private:
CoordinateSystem _cs; CoordinateSystem _cs;
}; };
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const Projection::Setup &setup);
QDebug operator<<(QDebug dbg, const Projection::Method &method);
#endif // QT_NO_DEBUG
#endif // PROJECTION_H #endif // PROJECTION_H

View File

@ -58,37 +58,37 @@ static Projection parseProjection(const QString &str, const GCS &gcs)
case 1: // LatLon case 1: // LatLon
return Projection(gcs); return Projection(gcs);
case 2: // Mercator case 2: // Mercator
return Projection(PCS(gcs, Conversion(1024, Projection::Setup(), return Projection(PCS(gcs, Conversion(1024, Conversion::Setup(),
9001))); 9001)));
case 3: // Transversal Mercator case 3: // Transversal Mercator
if (fields.size() < 7) if (fields.size() < 7)
return Projection(); return Projection();
return Projection(PCS(gcs, Conversion(9807, Projection::Setup( return Projection(PCS(gcs, Conversion(9807, Conversion::Setup(
fields.at(3).toDouble(), fields.at(2).toDouble(), fields.at(3).toDouble(), fields.at(2).toDouble(),
fields.at(6).toDouble(), fields.at(5).toDouble(), fields.at(6).toDouble(), fields.at(5).toDouble(),
fields.at(4).toDouble(), NAN, NAN), 9001))); fields.at(4).toDouble(), NAN, NAN), 9001)));
case 4: // Lambert 2SP case 4: // Lambert 2SP
if (fields.size() < 8) if (fields.size() < 8)
return Projection(); return Projection();
return Projection(PCS(gcs, Conversion(9802, Projection::Setup( return Projection(PCS(gcs, Conversion(9802, Conversion::Setup(
fields.at(4).toDouble(), fields.at(5).toDouble(), NAN, fields.at(4).toDouble(), fields.at(5).toDouble(), NAN,
fields.at(6).toDouble(), fields.at(7).toDouble(), fields.at(6).toDouble(), fields.at(7).toDouble(),
fields.at(3).toDouble(), fields.at(2).toDouble()), 9001))); fields.at(3).toDouble(), fields.at(2).toDouble()), 9001)));
case 6: // BGN (British National Grid) case 6: // BGN (British National Grid)
return Projection(PCS(gcs, Conversion(9807, Projection::Setup(49, return Projection(PCS(gcs, Conversion(9807, Conversion::Setup(49,
-2, 0.999601, 400000, -100000, NAN, NAN), 9001))); -2, 0.999601, 400000, -100000, NAN, NAN), 9001)));
case 12: // France Lambert II etendu case 12: // France Lambert II etendu
return Projection(PCS(gcs, Conversion(9801, Projection::Setup(52, 0, return Projection(PCS(gcs, Conversion(9801, Conversion::Setup(52, 0,
0.99987742, 600000, 2200000, NAN, NAN), 9001))); 0.99987742, 600000, 2200000, NAN, NAN), 9001)));
case 14: // Swiss Grid case 14: // Swiss Grid
return Projection(PCS(gcs, Conversion(9815, Projection::Setup( return Projection(PCS(gcs, Conversion(9815, Conversion::Setup(
46.570866, 7.26225, 1.0, 600000, 200000, 90.0, 90.0), 9001))); 46.570866, 7.26225, 1.0, 600000, 200000, 90.0, 90.0), 9001)));
case 108: // Dutch RD grid case 108: // Dutch RD grid
return Projection(PCS(gcs, Conversion(9809, Projection::Setup( return Projection(PCS(gcs, Conversion(9809, Conversion::Setup(
52.15616055555555, 5.38763888888889, 0.9999079, 155000, 463000, 52.15616055555555, 5.38763888888889, 0.9999079, 155000, 463000,
NAN, NAN), 9001))); NAN, NAN), 9001)));
case 184: // Swedish Grid case 184: // Swedish Grid
return Projection(PCS(gcs, Conversion(9807, Projection::Setup(0, return Projection(PCS(gcs, Conversion(9807, Conversion::Setup(0,
15.808278, 1, 1500000, 0, NAN, NAN), 9001))); 15.808278, 1, 1500000, 0, NAN, NAN), 9001)));
default: default:
return Projection(); return Projection();

View File

@ -1,9 +1,10 @@
#include "common/coordinates.h"
#include "ellipsoid.h" #include "ellipsoid.h"
#include "utm.h" #include "utm.h"
Projection::Setup UTM::setup(int zone) Conversion::Setup UTM::setup(int zone)
{ {
return Projection::Setup(0, (qAbs(zone) - 1)*6 - 180 + 3, 0.9996, 500000, return Conversion::Setup(0, (qAbs(zone) - 1)*6 - 180 + 3, 0.9996, 500000,
zone < 0 ? 10000000 : 0, 0, 0); zone < 0 ? 10000000 : 0, 0, 0);
} }

View File

@ -1,12 +1,14 @@
#ifndef UTM_H #ifndef UTM_H
#define UTM_H #define UTM_H
#include "projection.h" #include "conversion.h"
class Coordinates;
namespace UTM namespace UTM
{ {
int zone(const Coordinates &c); int zone(const Coordinates &c);
Projection::Setup setup(int zone); Conversion::Setup setup(int zone);
} }
#endif // UTM_H #endif // UTM_H