1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 05:34:47 +01:00

Use a shared CalibrationPoint implementation

This commit is contained in:
Martin Tůma 2019-03-07 01:08:51 +01:00
parent e2ad2e9d98
commit 060f940b75
6 changed files with 102 additions and 103 deletions

View File

@ -159,7 +159,8 @@ HEADERS += src/common/config.h \
src/data/area.h \ src/data/area.h \
src/map/obliquestereographic.h \ src/map/obliquestereographic.h \
src/GUI/coordinatesitem.h \ src/GUI/coordinatesitem.h \
src/map/rmap.h src/map/rmap.h \
src/map/calibrationpoint.h
SOURCES += src/main.cpp \ SOURCES += src/main.cpp \
src/common/coordinates.cpp \ src/common/coordinates.cpp \
src/common/rectc.cpp \ src/common/rectc.cpp \

View File

@ -0,0 +1,31 @@
#ifndef CALIBRATIONPOINT_H
#define CALIBRATIONPOINT_H
#include "transform.h"
#include "projection.h"
class CalibrationPoint {
public:
CalibrationPoint() {}
CalibrationPoint(PointD xy, PointD pp) : _xy(xy), _pp(pp) {}
CalibrationPoint(PointD xy, Coordinates c) : _xy(xy), _ll(c) {}
bool isValid() const
{
return !(_xy.isNull() || (_pp.isNull() && !_ll.isValid()));
}
ReferencePoint rp(const Projection &projection) const
{
return (_pp.isNull())
? ReferencePoint(_xy, projection.ll2xy(_ll))
: ReferencePoint(_xy, _pp);
}
private:
PointD _xy;
PointD _pp;
Coordinates _ll;
};
#endif // CALIBRATIONPOINT_H

View File

@ -5,12 +5,12 @@
#include "mapfile.h" #include "mapfile.h"
static double parameter(const QString &str, bool *res, double def = 0.0) static double parameter(const QString &str, bool *res, double dflt = 0.0)
{ {
QString field = str.trimmed(); QString field = str.trimmed();
if (field.isEmpty()) { if (field.isEmpty()) {
*res = true; *res = true;
return def; return dflt;
} }
return field.toDouble(res); return field.toDouble(res);
@ -19,8 +19,9 @@ static double parameter(const QString &str, bool *res, double def = 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, Projection::Setup &setup, QString &datum)
{ {
bool res, r[8]; bool res, utm = false;
int ln = 1; int ln = 1, zone = 0;
while (!device.atEnd()) { while (!device.atEnd()) {
QByteArray line = device.readLine(); QByteArray line = device.readLine();
@ -38,20 +39,19 @@ int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points,
else { else {
QList<QByteArray> list = line.split(','); QList<QByteArray> list = line.split(',');
QString key(list.at(0).trimmed()); QString key(list.at(0).trimmed());
bool ll = true; bool pp = true;
if (key.startsWith("Point") && list.count() == 17 if (key.startsWith("Point") && list.count() == 17
&& !list.at(2).trimmed().isEmpty()) { && !list.at(2).trimmed().isEmpty()) {
CalibrationPoint p; PointD xy;
xy.rx() = list.at(2).trimmed().toInt(&res);
int x = list.at(2).trimmed().toInt(&res);
if (!res) if (!res)
return ln; return ln;
int y = list.at(3).trimmed().toInt(&res); xy.ry() = list.at(3).trimmed().toInt(&res);
if (!res) if (!res)
return ln; return ln;
Coordinates c;
bool ll = true;
int latd = list.at(6).trimmed().toInt(&res); int latd = list.at(6).trimmed().toInt(&res);
if (!res) if (!res)
ll = false; ll = false;
@ -72,31 +72,34 @@ int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points,
lond = -lond; lond = -lond;
lonm = -lonm; lonm = -lonm;
} }
if (ll)
c = Coordinates(lond + lonm/60.0, latd + latm/60.0);
p.zone = list.at(13).trimmed().toInt(&res); PointD pp;
if (!res)
p.zone = 0;
double ppx = list.at(14).trimmed().toDouble(&res); double ppx = list.at(14).trimmed().toDouble(&res);
if (!res) if (res)
pp = false; pp.rx() = ppx;
double ppy = list.at(15).trimmed().toDouble(&res); double ppy = list.at(15).trimmed().toDouble(&res);
if (!res) if (res)
pp = false; pp.ry() = ppy;
if (list.at(16).trimmed() == "S")
p.zone = -p.zone;
p.rp.setXY(PointD(x, y)); if (c.isValid())
if (ll) { points.append(CalibrationPoint(xy, c));
p.ll = Coordinates(lond + lonm/60.0, latd + latm/60.0); else if (pp.isValid())
if (p.ll.isValid()) points.append(CalibrationPoint(xy, pp));
points.append(p); else
else
return ln;
} else if (pp) {
p.rp.setPP(PointD(ppx, ppy));
points.append(p);
} else
return ln; return ln;
if (utm && !zone) {
zone = list.at(13).trimmed().toInt(&res);
if (res) {
if (list.at(16).trimmed() == "S")
zone = -zone;
} else {
if (c.isValid())
zone = UTM::zone(c);
}
}
} else if (key == "IWH") { } else if (key == "IWH") {
if (list.count() < 4) if (list.count() < 4)
return ln; return ln;
@ -111,19 +114,25 @@ int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points,
if (list.count() < 2) if (list.count() < 2)
return ln; return ln;
projection = list.at(1); projection = list.at(1);
utm = (projection == "(UTM) Universal Transverse Mercator");
} else if (key == "Projection Setup") { } else if (key == "Projection Setup") {
if (list.count() < 8) if (list.count() < 8)
return ln; return ln;
setup = Projection::Setup( if (utm && zone)
parameter(list[1], &r[1]), parameter(list[2], &r[2]), setup = UTM::setup(zone);
parameter(list[3], &r[3], 1.0), parameter(list[4], &r[4]), else {
parameter(list[5], &r[5]), parameter(list[6], &r[6]), bool r[8];
parameter(list[7], &r[7])); setup = Projection::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]),
parameter(list[7], &r[7]));
for (int i = 1; i < 8; i++) for (int i = 1; i < 8; i++)
if (!r[i]) if (!r[i])
return ln; return ln;
}
} }
} }
@ -144,12 +153,12 @@ bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
return false; return false;
} }
if ((el = parse(device, points, projection, setup, datum))) { if ((el = parse(device, points, projection, setup, datum)))
_errorString = QString("Parse error on line %1").arg(el); _errorString = QString("Parse error on line %1").arg(el);
return false;
}
return true; device.close();
return (!el);
} }
const GCS *MapFile::createGCS(const QString &datum) const GCS *MapFile::createGCS(const QString &datum)
@ -163,35 +172,25 @@ const GCS *MapFile::createGCS(const QString &datum)
} }
bool MapFile::createProjection(const GCS *gcs, const QString &name, bool MapFile::createProjection(const GCS *gcs, const QString &name,
const Projection::Setup &setup, QList<CalibrationPoint> &points) const Projection::Setup &setup)
{ {
PCS pcs; PCS pcs;
if (name == "Mercator") if (name == "Latitude/Longitude") {
pcs = PCS(gcs, 1024, setup, 9001);
else if (name == "Transverse Mercator")
pcs = PCS(gcs, 9807, setup, 9001);
else if (name == "Latitude/Longitude") {
_projection = Projection(gcs); _projection = Projection(gcs);
return true; return true;
} else if (name == "Lambert Conformal Conic") } else if (name == "Mercator")
pcs = PCS(gcs, 1024, setup, 9001);
else if (name == "Transverse Mercator"
|| name == "(UTM) Universal Transverse Mercator")
pcs = PCS(gcs, 9807, setup, 9001);
else if (name == "Lambert Conformal Conic")
pcs = PCS(gcs, 9802, setup, 9001); pcs = PCS(gcs, 9802, setup, 9001);
else if (name == "Albers Equal Area") else if (name == "Albers Equal Area")
pcs = PCS(gcs, 9822, setup, 9001); pcs = PCS(gcs, 9822, setup, 9001);
else if (name == "(A)Lambert Azimuthual Equal Area") else if (name == "(A)Lambert Azimuthual Equal Area")
pcs = PCS(gcs, 9820, setup, 9001); pcs = PCS(gcs, 9820, setup, 9001);
else if (name == "(UTM) Universal Transverse Mercator") { else if (name == "(NZTM2) New Zealand TM 2000")
int zone;
if (points.first().zone)
zone = points.first().zone;
else if (!points.first().ll.isNull())
zone = UTM::zone(points.first().ll);
else {
_errorString = "Can not determine UTM zone";
return false;
}
pcs = PCS(gcs, 9807, UTM::setup(zone), 9001);
} else if (name == "(NZTM2) New Zealand TM 2000")
pcs = PCS(gcs, 9807, Projection::Setup(0, 173.0, 0.9996, 1600000, pcs = PCS(gcs, 9807, Projection::Setup(0, 173.0, 0.9996, 1600000,
10000000, NAN, NAN), 9001); 10000000, NAN, NAN), 9001);
else if (name == "(BNG) British National Grid") else if (name == "(BNG) British National Grid")
@ -234,16 +233,12 @@ bool MapFile::createProjection(const GCS *gcs, const QString &name,
return true; return true;
} }
bool MapFile::computeTransformation(QList<CalibrationPoint> &points) bool MapFile::computeTransformation(const QList<CalibrationPoint> &points)
{ {
QList<ReferencePoint> rp; QList<ReferencePoint> rp;
for (int i = 0; i < points.size(); i++) { for (int i = 0; i < points.size(); i++)
if (points.at(i).rp.pp().isNull()) rp.append(points.at(i).rp(_projection));
points[i].rp.setPP(_projection.ll2xy(points.at(i).ll));
rp.append(points.at(i).rp);
}
_transform = Transform(rp); _transform = Transform(rp);
if (!_transform.isValid()) { if (!_transform.isValid()) {
@ -265,7 +260,7 @@ MapFile::MapFile(QIODevice &file)
return; return;
if (!(gcs = createGCS(datum))) if (!(gcs = createGCS(datum)))
return; return;
if (!createProjection(gcs, ct, setup, points)) if (!createProjection(gcs, ct, setup))
return; return;
if (!computeTransformation(points)) if (!computeTransformation(points))
return; return;

View File

@ -3,6 +3,7 @@
#include "transform.h" #include "transform.h"
#include "projection.h" #include "projection.h"
#include "calibrationpoint.h"
class QIODevice; class QIODevice;
class GCS; class GCS;
@ -24,20 +25,14 @@ public:
const QSize &size() const {return _size;} const QSize &size() const {return _size;}
private: private:
struct CalibrationPoint {
ReferencePoint rp;
Coordinates ll;
int zone;
};
int parse(QIODevice &device, QList<CalibrationPoint> &points, int parse(QIODevice &device, QList<CalibrationPoint> &points,
QString &projection, Projection::Setup &setup, QString &datum); QString &projection, Projection::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, Projection::Setup &setup, QString &datum);
const GCS *createGCS(const QString &datum); const GCS *createGCS(const QString &datum);
bool createProjection(const GCS *gcs, const QString &projection, bool createProjection(const GCS *gcs, const QString &projection,
const Projection::Setup &setup, QList<CalibrationPoint> &points); const Projection::Setup &setup);
bool computeTransformation(QList<CalibrationPoint> &points); bool computeTransformation(const QList<CalibrationPoint> &points);
QString _name; QString _name;
QString _image; QString _image;

View File

@ -18,6 +18,7 @@ public:
double &ry() {return _y;} double &ry() {return _y;}
bool isNull() const {return std::isnan(_x) && std::isnan(_y);} bool isNull() const {return std::isnan(_x) && std::isnan(_y);}
bool isValid() const {return !(std::isnan(_x) || std::isnan(_y));}
QPointF toPointF() const {return QPointF((qreal)_x, (qreal)_y);} QPointF toPointF() const {return QPointF((qreal)_x, (qreal)_y);}

View File

@ -6,7 +6,7 @@
#include "common/rectc.h" #include "common/rectc.h"
#include "common/wgs84.h" #include "common/wgs84.h"
#include "common/config.h" #include "common/config.h"
#include "transform.h" #include "calibrationpoint.h"
#include "utm.h" #include "utm.h"
#include "pcs.h" #include "pcs.h"
#include "rectd.h" #include "rectd.h"
@ -20,30 +20,6 @@
return; \ return; \
} }
class CalibrationPoint {
public:
CalibrationPoint() {}
CalibrationPoint(PointD xy, PointD pp) : _xy(xy), _pp(pp) {}
CalibrationPoint(PointD xy, Coordinates c) : _xy(xy), _ll(c) {}
bool isValid() const
{
return !(_xy.isNull() || (_pp.isNull() && !_ll.isValid()));
}
ReferencePoint rp(const Projection &projection) const
{
return (_pp.isNull())
? ReferencePoint(_xy, projection.ll2xy(_ll))
: ReferencePoint(_xy, _pp);
}
private:
PointD _xy;
PointD _pp;
Coordinates _ll;
};
static CalibrationPoint parseCalibrationPoint(const QString &str) static CalibrationPoint parseCalibrationPoint(const QString &str)
{ {
QStringList fields(str.split(",")); QStringList fields(str.split(","));