2023-04-13 08:39:33 +02:00
|
|
|
#include <QFile>
|
2023-04-15 03:18:52 +02:00
|
|
|
#include "common/csv.h"
|
2023-04-13 08:39:33 +02:00
|
|
|
#include "conversion.h"
|
|
|
|
|
|
|
|
static bool parameter(int key, double val, int units, Projection::Setup &setup)
|
|
|
|
{
|
|
|
|
switch (key) {
|
|
|
|
case 8801:
|
|
|
|
case 8811:
|
|
|
|
case 8821:
|
|
|
|
case 8832:
|
|
|
|
{AngularUnits au(units);
|
|
|
|
if (au.isNull())
|
|
|
|
return false;
|
|
|
|
setup.setLatitudeOrigin(au.toDegrees(val));}
|
|
|
|
return true;
|
|
|
|
case 8802:
|
|
|
|
case 8812:
|
|
|
|
case 8822:
|
|
|
|
case 8833:
|
|
|
|
{AngularUnits au(units);
|
|
|
|
if (au.isNull())
|
|
|
|
return false;
|
|
|
|
setup.setLongitudeOrigin(au.toDegrees(val));}
|
|
|
|
return true;
|
|
|
|
case 8805:
|
|
|
|
case 8815:
|
|
|
|
case 8819:
|
|
|
|
setup.setScale(val);
|
|
|
|
return true;
|
|
|
|
case 8806:
|
|
|
|
case 8816:
|
|
|
|
case 8826:
|
|
|
|
{LinearUnits lu(units);
|
|
|
|
if (lu.isNull())
|
|
|
|
return false;
|
|
|
|
setup.setFalseEasting(lu.toMeters(val));}
|
|
|
|
return true;
|
|
|
|
case 8807:
|
|
|
|
case 8817:
|
|
|
|
case 8827:
|
|
|
|
{LinearUnits lu(units);
|
|
|
|
if (lu.isNull())
|
|
|
|
return false;
|
|
|
|
setup.setFalseNorthing(lu.toMeters(val));}
|
|
|
|
return true;
|
|
|
|
case 8813:
|
|
|
|
case 8818:
|
|
|
|
case 8823:
|
|
|
|
{AngularUnits au(units);
|
|
|
|
if (au.isNull())
|
|
|
|
return false;
|
|
|
|
setup.setStandardParallel1(au.toDegrees(val));}
|
|
|
|
return true;
|
|
|
|
case 1036:
|
|
|
|
case 8814:
|
|
|
|
case 8824:
|
|
|
|
{AngularUnits au(units);
|
|
|
|
if (au.isNull())
|
|
|
|
return false;
|
|
|
|
setup.setStandardParallel2(au.toDegrees(val));}
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-15 03:18:52 +02:00
|
|
|
static int projectionSetup(const QByteArrayList &list, Projection::Setup &setup)
|
2023-04-13 08:39:33 +02:00
|
|
|
{
|
|
|
|
bool r1, r2, r3;
|
|
|
|
|
|
|
|
for (int i = 5; i < 26; i += 3) {
|
2023-04-15 03:18:52 +02:00
|
|
|
const QByteArray &ks = list.at(i);
|
2023-04-13 08:39:33 +02:00
|
|
|
if (ks.isEmpty())
|
|
|
|
break;
|
|
|
|
|
|
|
|
int key = ks.toInt(&r1);
|
2023-04-15 03:18:52 +02:00
|
|
|
double val = list.at(i+1).toDouble(&r2);
|
|
|
|
int un = list.at(i+2).toInt(&r3);
|
2023-04-13 08:39:33 +02:00
|
|
|
if (!r1 || !r2 || !r3)
|
|
|
|
return (i - 5)/3 + 1;
|
|
|
|
|
|
|
|
if (!parameter(key, val, un, setup))
|
|
|
|
return (i - 5)/3 + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 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));
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
Conversion Conversion::conversion(int id)
|
|
|
|
{
|
2023-12-26 14:14:08 +01:00
|
|
|
QMap<int, Entry>::const_iterator it(_conversions.find(id));
|
2023-04-13 08:39:33 +02:00
|
|
|
|
|
|
|
if (it == _conversions.constEnd())
|
|
|
|
return Conversion();
|
|
|
|
else {
|
|
|
|
const Entry &e = it.value();
|
|
|
|
return Conversion(e.method(), e.setup(), e.units(), e.cs());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-15 03:18:52 +02:00
|
|
|
bool Conversion::loadList(const QString &path)
|
2023-04-13 08:39:33 +02:00
|
|
|
{
|
|
|
|
QFile file(path);
|
2023-04-15 03:18:52 +02:00
|
|
|
CSV csv(&file);
|
|
|
|
QByteArrayList entry;
|
2023-04-13 08:39:33 +02:00
|
|
|
bool res;
|
|
|
|
|
|
|
|
if (!file.open(QFile::ReadOnly)) {
|
|
|
|
qWarning("Error opening projections file: %s: %s", qPrintable(path),
|
|
|
|
qPrintable(file.errorString()));
|
2023-04-15 03:18:52 +02:00
|
|
|
return false;
|
2023-04-13 08:39:33 +02:00
|
|
|
}
|
|
|
|
|
2023-04-15 03:18:52 +02:00
|
|
|
while (!csv.atEnd()) {
|
|
|
|
if (!csv.readEntry(entry) || entry.size() < 26) {
|
|
|
|
qWarning("%s:%d: Parse error", qPrintable(path), csv.line());
|
|
|
|
return false;
|
2023-04-13 08:39:33 +02:00
|
|
|
}
|
|
|
|
|
2023-04-15 03:18:52 +02:00
|
|
|
QString name(entry.at(0));
|
|
|
|
int proj = entry.at(1).toInt(&res);
|
2023-04-13 08:39:33 +02:00
|
|
|
if (!res) {
|
2023-04-15 03:18:52 +02:00
|
|
|
qWarning("%s:%d: Invalid projection code", qPrintable(path),
|
|
|
|
csv.line());
|
2023-04-13 08:39:33 +02:00
|
|
|
continue;
|
|
|
|
}
|
2023-04-15 03:18:52 +02:00
|
|
|
int units = entry.at(2).toInt(&res);
|
2023-04-13 08:39:33 +02:00
|
|
|
if (!res) {
|
2023-04-15 03:18:52 +02:00
|
|
|
qWarning("%s:%d: Invalid linear units code", qPrintable(path),
|
|
|
|
csv.line());
|
2023-04-13 08:39:33 +02:00
|
|
|
continue;
|
|
|
|
}
|
2023-04-15 03:18:52 +02:00
|
|
|
int transform = entry.at(3).toInt(&res);
|
2023-04-13 08:39:33 +02:00
|
|
|
if (!res) {
|
|
|
|
qWarning("%s:%d: Invalid coordinate transformation code",
|
2023-04-15 03:18:52 +02:00
|
|
|
qPrintable(path), csv.line());
|
2023-04-13 08:39:33 +02:00
|
|
|
continue;
|
|
|
|
}
|
2023-04-15 03:18:52 +02:00
|
|
|
int cs = entry.at(4).toInt(&res);
|
2023-04-13 08:39:33 +02:00
|
|
|
if (!res) {
|
|
|
|
qWarning("%s:%d: Invalid coordinate system code",
|
2023-04-15 03:18:52 +02:00
|
|
|
qPrintable(path), csv.line());
|
2023-04-13 08:39:33 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!LinearUnits(units).isValid()) {
|
2023-04-15 03:18:52 +02:00
|
|
|
qWarning("%s:%d: Unknown linear units code", qPrintable(path),
|
|
|
|
csv.line());
|
2023-04-13 08:39:33 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!Projection::Method(transform).isValid()) {
|
|
|
|
qWarning("%s:%d: Unknown coordinate transformation code",
|
2023-04-15 03:18:52 +02:00
|
|
|
qPrintable(path), csv.line());
|
2023-04-13 08:39:33 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!CoordinateSystem(cs).isValid()) {
|
|
|
|
qWarning("%s:%d: Unknown coordinate system code", qPrintable(path),
|
2023-04-15 03:18:52 +02:00
|
|
|
csv.line());
|
2023-04-13 08:39:33 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Projection::Setup setup;
|
2023-04-15 03:18:52 +02:00
|
|
|
int pn = projectionSetup(entry, setup);
|
|
|
|
if (pn) {
|
2023-04-13 08:39:33 +02:00
|
|
|
qWarning("%s: %d: Invalid projection parameter #%d",
|
2023-04-15 03:18:52 +02:00
|
|
|
qPrintable(path), csv.line(), pn);
|
2023-04-13 08:39:33 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
_conversions.insert(proj, Entry(name, transform, setup, units, cs));
|
|
|
|
}
|
2023-04-15 03:18:52 +02:00
|
|
|
|
|
|
|
return true;
|
2023-04-13 08:39:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
QList<KV<int, QString> > Conversion::list()
|
|
|
|
{
|
|
|
|
QList<KV<int, QString> > list;
|
|
|
|
|
|
|
|
for (QMap<int, Entry>::const_iterator it = _conversions.constBegin();
|
2023-12-26 14:14:08 +01:00
|
|
|
it != _conversions.constEnd(); ++it)
|
2023-04-13 08:39:33 +02:00
|
|
|
list.append(KV<int, QString>(it.key(), it.value().name()));
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef QT_NO_DEBUG
|
|
|
|
QDebug operator<<(QDebug dbg, const Conversion &conversion)
|
|
|
|
{
|
|
|
|
dbg.nospace() << "Conversion(" << conversion.method() << ", "
|
|
|
|
<< conversion.units() << ", " << conversion.setup() << ")";
|
|
|
|
return dbg.space();
|
|
|
|
}
|
|
|
|
#endif // QT_NO_DEBUG
|