1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 11:45:53 +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/gcs.h"
#include "map/utm.h"
#include "map/projection.h"
#include "gpsdumpparser.h"
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)) {
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));
} 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));
} else if (!proj.compare("UNIVERSAL TRANSVERSE MERCATOR",
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));
} 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));
} 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));
} else {
_errorString = proj + ": Unknown/missing projection";

View File

@ -1,8 +1,9 @@
#include <QFile>
#include "common/csv.h"
#include "angularunits.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) {
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;
@ -87,13 +88,36 @@ static int projectionSetup(const QByteArrayList &list, Projection::Setup &setup)
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::defaults()
{
QMap<int, Conversion::Entry> map;
map.insert(3856, Entry("Popular Visualisation Pseudo-Mercator", 1024,
Projection::Setup(), 9001, 4400));
Setup(), 9001, 4400));
return map;
}
@ -159,7 +183,7 @@ bool Conversion::loadList(const QString &path)
csv.line());
continue;
}
if (!Projection::Method(transform).isValid()) {
if (!Method(transform).isValid()) {
qWarning("%s:%d: Unknown coordinate transformation code",
qPrintable(path), csv.line());
continue;
@ -170,7 +194,7 @@ bool Conversion::loadList(const QString &path)
continue;
}
Projection::Setup setup;
Setup setup;
int pn = projectionSetup(entry, setup);
if (pn) {
qWarning("%s: %d: Invalid projection parameter #%d",
@ -196,6 +220,21 @@ QList<KV<int, QString> > Conversion::list()
}
#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)
{
dbg.nospace() << "Conversion(" << conversion.method() << ", "

View File

@ -1,18 +1,81 @@
#ifndef CONVERSION_H
#define CONVERSION_H
#include "projection.h"
#include <cmath>
#include <QDebug>
#include <common/kv.h>
#include "coordinatesystem.h"
#include "linearunits.h"
class Conversion {
public:
Conversion() {}
Conversion(const Projection::Method &method,
const Projection::Setup &setup, const LinearUnits &units,
const CoordinateSystem &cs = CoordinateSystem()) : _method(method),
_setup(setup), _units(units), _cs(cs) {}
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) {}
const Projection::Method &method() const {return _method;}
const Projection::Setup &setup() const {return _setup;}
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;
};
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 CoordinateSystem &cs() const {return _cs;}
@ -34,30 +97,28 @@ public:
private:
class Entry {
public:
Entry(const QString &name, const Projection::Method &method,
const Projection::Setup &setup, const LinearUnits &units,
const CoordinateSystem &cs = CoordinateSystem())
: _name(name), _method(method), _setup(setup), _units(units),
_cs(cs) {}
Entry(const QString &name, const Method &method, const Setup &setup,
const LinearUnits &units, const CoordinateSystem &cs = CoordinateSystem())
: _name(name), _method(method), _setup(setup), _units(units), _cs(cs) {}
const QString &name() const {return _name;}
const Projection::Method &method() const {return _method;}
const Projection::Setup &setup() const {return _setup;}
const Method &method() const {return _method;}
const Setup &setup() const {return _setup;}
const LinearUnits &units() const {return _units;}
const CoordinateSystem &cs() const {return _cs;}
private:
QString _name;
Projection::Method _method;
Projection::Setup _setup;
Method _method;
Setup _setup;
LinearUnits _units;
CoordinateSystem _cs;
};
static QMap<int, Entry> defaults();
Projection::Method _method;
Projection::Setup _setup;
Method _method;
Setup _setup;
LinearUnits _units;
CoordinateSystem _cs;
@ -65,6 +126,8 @@ private:
};
#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);
#endif // QT_NO_DEBUG

View File

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

View File

@ -5,6 +5,7 @@
#include <QList>
#include "transform.h"
#include "projection.h"
#include "conversion.h"
class TIFFFile;
class GCS;
@ -49,7 +50,7 @@ private:
double &val) const;
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 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,
QString &projection, Projection::Setup &setup, QString &datum)
QString &projection, Conversion::Setup &setup, QString &datum)
{
bool res, utm = false;
int ln = 1, zone = 0;
@ -123,7 +123,7 @@ int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points,
setup = UTM::setup(zone);
else {
bool r[8];
setup = Projection::Setup(
setup = Conversion::Setup(
parameter(list[1], &r[1]), parameter(list[2], &r[2]),
parameter(list[3], &r[3], 1.0), parameter(list[4], &r[4]),
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,
QString &projection, Projection::Setup &setup, QString &datum)
QString &projection, Conversion::Setup &setup, QString &datum)
{
int el;
@ -161,7 +161,7 @@ bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
}
bool MapFile::createProjection(const QString &datum, const QString &name,
const Projection::Setup &setup)
const Conversion::Setup &setup)
{
PCS pcs;
@ -188,37 +188,37 @@ bool MapFile::createProjection(const QString &datum, const QString &name,
else if (name == "Polyconic (American)")
pcs = PCS(gcs, Conversion(9818, setup, 9001));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
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));
else {
_errorString = QString("%1: Unknown map projection").arg(name);
@ -250,7 +250,7 @@ MapFile::MapFile(QIODevice &file)
{
QList<CalibrationPoint> points;
QString ct, datum;
Projection::Setup setup;
Conversion::Setup setup;
if (!parseMapFile(file, points, ct, setup, datum))
return;

View File

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

View File

@ -75,93 +75,93 @@ static PointD corner2point(const QString &name, const QSize &size)
return PointD();
}
static Projection::Setup lcc2setup(const QStringList &list)
static Conversion::Setup lcc2setup(const QStringList &list)
{
double params[6];
bool ok;
if (list.size() < 7)
return Projection::Setup();
return Conversion::Setup();
for (int i = 1; i < 7; i++) {
params[i - 1] = list.at(i).toDouble(&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]);
}
static Projection::Setup laea2setup(const QStringList &list)
static Conversion::Setup laea2setup(const QStringList &list)
{
double params[2];
bool ok;
if (list.size() < 3)
return Projection::Setup();
return Conversion::Setup();
for (int i = 1; i < 3; i++) {
params[i - 1] = list.at(i).toDouble(&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];
bool ok;
if (list.size() < 4)
return Projection::Setup();
return Conversion::Setup();
for (int i = 1; i < 4; i++) {
params[i - 1] = list.at(i).toDouble(&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);
}
static Projection::Setup tm2setup(const QStringList &list)
static Conversion::Setup tm2setup(const QStringList &list)
{
double params[5];
bool ok;
if (list.size() < 6)
return Projection::Setup();
return Conversion::Setup();
for (int i = 1; i < 6; i++) {
params[i - 1] = list.at(i).toDouble(&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);
}
static Projection::Setup utm2setup(const QStringList &list)
static Conversion::Setup utm2setup(const QStringList &list)
{
bool ok;
if (list.size() < 2)
return Projection::Setup();
return Conversion::Setup();
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;
bool ok;
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);
return ok ? Projection::Setup(0, lon, NAN, 0, 0, NAN, NAN)
: Projection::Setup();
return ok ? Conversion::Setup(0, lon, NAN, 0, 0, NAN, NAN)
: Conversion::Setup();
}
static GCS createGCS(const QString &datum)
@ -180,7 +180,7 @@ static Projection createProjection(const GCS &gcs, const QString &name)
else if (pl.first() == "UTM")
pcs = PCS(gcs, Conversion(9807, utm2setup(pl), 9001));
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")
pcs = PCS(gcs, Conversion(9804, mercator2setup(pl), 9001));
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)")
pcs = PCS(gcs, Conversion(9818, polyconic2setup(pl), 9001));
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));
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));
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));
else
return Projection();

View File

@ -4,7 +4,7 @@
#include "pcs.h"
#include "prjfile.h"
static Projection::Method projectionMethod(const QString &name)
static Conversion::Method projectionMethod(const QString &name)
{
static const struct {
int id;
@ -30,10 +30,10 @@ static Projection::Method projectionMethod(const QString &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)
{
// latitude origin
@ -460,7 +460,7 @@ void PRJFile::primeMeridian(CTX &ctx, PrimeMeridian *pm, int *epsg)
*pm = PrimeMeridian(lon);
}
void PRJFile::parameter(CTX &ctx, Projection::Setup *setup)
void PRJFile::parameter(CTX &ctx, Conversion::Setup *setup)
{
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;
QString proj;
@ -490,7 +490,7 @@ void PRJFile::projection(CTX &ctx, Projection::Method *method)
optAuthority(ctx, &epsg);
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)
@ -521,8 +521,8 @@ void PRJFile::projectedCS(CTX &ctx, PCS *pcs)
int epsg = -1;
GCS gcs;
LinearUnits lu;
Projection::Method method;
Projection::Setup setup;
Conversion::Method method;
Conversion::Setup setup;
compare(ctx, PROJCS);
compare(ctx, LBRK);

View File

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

View File

@ -9,40 +9,16 @@
#include "proj/obliquestereographic.h"
#include "proj/polyconic.h"
#include "datum.h"
#include "gcs.h"
#include "pcs.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)
: _gcs(pcs.gcs()), _ct(0), _units(pcs.conversion().units()),
_cs(pcs.conversion().cs())
{
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()) {
case 1024:
@ -154,32 +130,3 @@ bool Projection::operator==(const Projection &p) const
return (*_ct == *p._ct && _gcs == p._gcs && _units == p._units
&& _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
#define PROJECTION_H
#include <QDebug>
#include <QtGlobal>
#include "common/coordinates.h"
#include "pointd.h"
#include "linearunits.h"
#include "coordinatesystem.h"
#include "gcs.h"
#include "ct.h"
#include "proj/latlon.h"
class PCS;
class CT;
class AngularUnits;
class Projection {
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(const Projection &p);
Projection(const PCS &pcs);
@ -87,8 +30,8 @@ public:
}
bool isValid() const
{
// We do not check the CoordinateSystem here as it is not always defined
// and except of WMTS/WMS it is not needed.
/* We do not check the CoordinateSystem here as it is not always defined
and except of WMTS/WMS it is not needed. */
return (_gcs.isValid() && _ct != 0 && _units.isValid());
}
bool isGeographic() const
@ -96,8 +39,16 @@ public:
return (dynamic_cast<const LatLon*>(_ct) != 0);
}
PointD ll2xy(const Coordinates &c) const;
Coordinates xy2ll(const PointD &p) const;
PointD ll2xy(const Coordinates &c) 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 CoordinateSystem &coordinateSystem() const {return _cs;}
@ -109,9 +60,4 @@ private:
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

View File

@ -58,37 +58,37 @@ static Projection parseProjection(const QString &str, const GCS &gcs)
case 1: // LatLon
return Projection(gcs);
case 2: // Mercator
return Projection(PCS(gcs, Conversion(1024, Projection::Setup(),
return Projection(PCS(gcs, Conversion(1024, Conversion::Setup(),
9001)));
case 3: // Transversal Mercator
if (fields.size() < 7)
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(6).toDouble(), fields.at(5).toDouble(),
fields.at(4).toDouble(), NAN, NAN), 9001)));
case 4: // Lambert 2SP
if (fields.size() < 8)
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(6).toDouble(), fields.at(7).toDouble(),
fields.at(3).toDouble(), fields.at(2).toDouble()), 9001)));
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)));
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)));
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)));
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,
NAN, NAN), 9001)));
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)));
default:
return Projection();

View File

@ -1,9 +1,10 @@
#include "common/coordinates.h"
#include "ellipsoid.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);
}

View File

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