1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-03-18 20:47:46 +01:00
GPXSee/src/map/gcs.cpp

265 lines
6.0 KiB
C++
Raw Normal View History

#include <QFile>
#include "common/csv.h"
#include "gcs.h"
class GCS::Entry {
public:
Entry(int id, int gd, const QString &name, const GCS &gcs)
: _id(id), _gd(gd), _name(name), _gcs(gcs) {}
Entry(int id) : _id(id) {}
int id() const {return _id;}
int gd() const {return _gd;}
const QString &name() const {return _name;}
const GCS &gcs() const {return _gcs;}
bool operator<(const Entry &other) const
{return _id < other._id;}
private:
int _id, _gd;
QString _name;
GCS _gcs;
};
static int parameter(const QByteArray &str, bool *res)
{
if (str.isEmpty()) {
*res = true;
return 0;
}
return str.toInt(res);
}
static double parameterd(const QByteArray &str, bool *res)
{
if (str.isEmpty()) {
*res = true;
return NAN;
}
return str.toDouble(res);
}
QList<GCS::Entry> GCS::_gcss = defaults();
const GCS &GCS::WGS84()
{
2018-07-26 23:51:11 +02:00
static GCS g(Datum::WGS84(), 8901, 9122);
return g;
}
QList<GCS::Entry> GCS::defaults()
{
QList<GCS::Entry> list;
2022-08-08 00:20:30 +02:00
list.append(GCS::Entry(4326, 6326, "WGS 1984", WGS84()));
list.append(GCS::Entry(4326, 6326, "WGS 84", WGS84()));
2020-11-27 01:11:50 +01:00
list.append(GCS::Entry(4326, 6326, "WGS84", WGS84()));
return list;
}
GCS GCS::gcs(int id)
{
// There are GCSs without EPSG code (id = 0) in the list!
if (!id)
return GCS();
QList<GCS::Entry>::iterator it = std::lower_bound(
_gcss.begin(), _gcss.end(), id);
2024-07-01 08:58:12 +02:00
return (it == _gcss.end() || id != it->id()) ? GCS() : it->gcs();
}
GCS GCS::gcs(int geodeticDatum, int primeMeridian, int angularUnits)
{
for (int i = 0; i < _gcss.size(); i++) {
const Entry &e = _gcss.at(i);
if (e.gd() == geodeticDatum && e.gcs().primeMeridian() == primeMeridian
&& e.gcs().angularUnits() == angularUnits)
2021-06-17 21:58:25 +02:00
return e.gcs();
}
return GCS();
}
GCS GCS::gcs(const QString &name)
{
for (int i = 0; i < _gcss.size(); i++)
if (_gcss.at(i).name() == name)
2021-06-17 21:58:25 +02:00
return _gcss.at(i).gcs();
return GCS();
}
bool GCS::loadList(const QString &path)
{
QFile file(path);
CSV csv(&file);
QByteArrayList entry;
bool res;
if (!file.open(QFile::ReadOnly)) {
2025-01-04 00:18:27 +01:00
qWarning("%s: %s", qUtf8Printable(path),
qUtf8Printable(file.errorString()));
return false;
}
while (!csv.atEnd()) {
if (!csv.readEntry(entry)) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Parse error", qUtf8Printable(path), csv.line());
return false;
}
if (entry.size() < 14) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid column count", qUtf8Printable(path),
csv.line() - 1);
return false;
}
int id = parameter(entry.at(1), &res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid GCS code", qUtf8Printable(path),
csv.line() - 1);
continue;
}
int gd = parameter(entry.at(2), &res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid geodetic datum code", qUtf8Printable(path),
csv.line() - 1);
continue;
}
int au = entry.at(3).toInt(&res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid angular units code", qUtf8Printable(path),
csv.line() - 1);
continue;
}
int el = entry.at(4).toInt(&res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid ellipsoid code", qUtf8Printable(path),
csv.line() - 1);
continue;
}
int pm = entry.at(5).toInt(&res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid prime meridian code", qUtf8Printable(path),
csv.line() - 1);
continue;
}
int ct = entry.at(6).toInt(&res);
if (!res) {
qWarning("%s:%d: Invalid coordinates transformation code",
2025-01-04 00:18:27 +01:00
qUtf8Printable(path), csv.line() - 1);
continue;
}
double dx = entry.at(7).toDouble(&res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid dx", qUtf8Printable(path), csv.line() - 1);
continue;
}
double dy = entry.at(8).toDouble(&res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid dy", qUtf8Printable(path), csv.line() - 1);
continue;
}
double dz = entry.at(9).toDouble(&res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid dz", qUtf8Printable(path), csv.line() - 1);
continue;
}
double rx = parameterd(entry.at(10), &res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid rx", qUtf8Printable(path), csv.line() - 1);
continue;
}
double ry = parameterd(entry.at(11), &res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid ry", qUtf8Printable(path), csv.line() - 1);
continue;
}
double rz = parameterd(entry.at(12), &res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid rz", qUtf8Printable(path), csv.line() - 1);
continue;
}
double ds = parameterd(entry.at(13), &res);
if (!res) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Invalid ds", qUtf8Printable(path), csv.line() - 1);
continue;
}
2021-06-17 21:58:25 +02:00
const Ellipsoid &e = Ellipsoid::ellipsoid(el);
if (e.isNull()) {
2025-01-04 00:18:27 +01:00
qWarning("%s:%d: Unknown ellipsoid code", qUtf8Printable(path),
csv.line() - 1);
continue;
}
Datum datum;
switch (ct) {
case 9603:
datum = Datum(e, dx, dy, dz);
break;
case 9606:
datum = Datum(e, dx, dy, dz, -rx, -ry, -rz, ds);
break;
case 9607:
datum = Datum(e, dx, dy, dz, rx, ry, rz, ds);
break;
default:
qWarning("%s:%d: Unknown coordinates transformation method",
2025-01-04 00:18:27 +01:00
qUtf8Printable(path), csv.line() - 1);
continue;
}
if (!datum.isValid()) {
qWarning("%s:%d: Invalid coordinates transformation parameters",
2025-01-04 00:18:27 +01:00
qUtf8Printable(path), csv.line() - 1);
continue;
}
GCS gcs(datum, pm, au);
if (gcs.isValid())
_gcss.append(Entry(id, gd, entry.at(0), gcs));
else
qWarning("%s:%d: Unknown prime meridian/angular units code",
2025-01-04 00:18:27 +01:00
qUtf8Printable(path), csv.line() - 1);
}
std::sort(_gcss.begin(), _gcss.end());
return true;
}
QList<KV<int, QString> > GCS::list()
{
QList<KV<int, QString> > list;
for (int i = 0; i < _gcss.size(); i++) {
const Entry &e = _gcss.at(i);
if (!e.id() || (!list.isEmpty() && e.id() == list.last().key()))
continue;
list.append(KV<int, QString>(e.id(), e.name() + " / Geographic 2D"));
}
return list;
}
QList<KV<int, QString> > GCS::WGS84List()
{
QList<KV<int, QString> > list;
list.append(KV<int, QString>(4326, "Geographic 2D"));
return list;
}
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const GCS &gcs)
{
dbg.nospace() << "GCS(" << gcs.datum() << ", " << gcs.primeMeridian()
<< ", " << gcs.angularUnits() << ")";
2018-01-21 11:19:46 +01:00
return dbg.space();
}
#endif // QT_NO_DEBUG