mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 03:35:53 +01:00
Use a PCS file format more compatible with the EPSG PCS database
This commit is contained in:
parent
1739625896
commit
23e4e66c1b
@ -114,7 +114,8 @@ HEADERS += src/config.h \
|
|||||||
src/data/str2int.h \
|
src/data/str2int.h \
|
||||||
src/map/gcs.h \
|
src/map/gcs.h \
|
||||||
src/map/angularunits.h \
|
src/map/angularunits.h \
|
||||||
src/map/primemeridian.h
|
src/map/primemeridian.h \
|
||||||
|
src/map/linearunits.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 \
|
||||||
@ -198,7 +199,8 @@ SOURCES += src/main.cpp \
|
|||||||
src/map/projection.cpp \
|
src/map/projection.cpp \
|
||||||
src/map/gcs.cpp \
|
src/map/gcs.cpp \
|
||||||
src/map/angularunits.cpp \
|
src/map/angularunits.cpp \
|
||||||
src/map/primemeridian.cpp
|
src/map/primemeridian.cpp \
|
||||||
|
src/map/linearunits.cpp
|
||||||
RESOURCES += gpxsee.qrc
|
RESOURCES += gpxsee.qrc
|
||||||
TRANSLATIONS = lang/gpxsee_cs.ts \
|
TRANSLATIONS = lang/gpxsee_cs.ts \
|
||||||
lang/gpxsee_sv.ts \
|
lang/gpxsee_sv.ts \
|
||||||
|
4728
pkg/pcs.csv
4728
pkg/pcs.csv
File diff suppressed because it is too large
Load Diff
@ -61,7 +61,7 @@ Coordinates Datum::fromWGS84(const Coordinates &c) const
|
|||||||
|
|
||||||
QDebug operator<<(QDebug dbg, const Datum &datum)
|
QDebug operator<<(QDebug dbg, const Datum &datum)
|
||||||
{
|
{
|
||||||
dbg.nospace() << "Datum(" << datum.ellipsoid() << ", " << datum.dx() << ", "
|
dbg.nospace() << "Datum(" << *datum.ellipsoid() << ", " << datum.dx() << ", "
|
||||||
<< datum.dy() << ", " << datum.dz() << ")";
|
<< datum.dy() << ", " << datum.dz() << ")";
|
||||||
return dbg.maybeSpace();
|
return dbg.maybeSpace();
|
||||||
}
|
}
|
||||||
|
27
src/map/linearunits.cpp
Normal file
27
src/map/linearunits.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "linearunits.h"
|
||||||
|
|
||||||
|
LinearUnits::LinearUnits(int code)
|
||||||
|
{
|
||||||
|
switch (code) {
|
||||||
|
case 9001:
|
||||||
|
_f = 1.0;
|
||||||
|
break;
|
||||||
|
case 9002:
|
||||||
|
_f = 0.3048;
|
||||||
|
break;
|
||||||
|
case 9003:
|
||||||
|
_f = 12.0 / 39.37;
|
||||||
|
break;
|
||||||
|
case 9040:
|
||||||
|
_f = 36.0 / 39.370147;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_f = NAN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug dbg, const LinearUnits &lu)
|
||||||
|
{
|
||||||
|
dbg.nospace() << "LinearUnits(" << lu._f << ")";
|
||||||
|
return dbg.maybeSpace();
|
||||||
|
}
|
31
src/map/linearunits.h
Normal file
31
src/map/linearunits.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef LINEARUNITS_H
|
||||||
|
#define LINEARUNITS_H
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
class LinearUnits
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LinearUnits() : _f(NAN) {}
|
||||||
|
LinearUnits(int code);
|
||||||
|
|
||||||
|
bool isNull() const {return std::isnan(_f);}
|
||||||
|
bool isValid() const {return !std::isnan(_f);}
|
||||||
|
|
||||||
|
double toMeters(double val) const {return val * _f;}
|
||||||
|
double fromMeters(double val) const {return val / _f;}
|
||||||
|
|
||||||
|
friend bool operator==(const LinearUnits &lu1, const LinearUnits &lu2);
|
||||||
|
friend QDebug operator<<(QDebug dbg, const LinearUnits &lu);
|
||||||
|
|
||||||
|
private:
|
||||||
|
double _f;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(const LinearUnits &lu1, const LinearUnits &lu2)
|
||||||
|
{return (lu1._f == lu2._f);}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug dbg, const LinearUnits &lu);
|
||||||
|
|
||||||
|
#endif // LINEARUNITS_H
|
141
src/map/pcs.cpp
141
src/map/pcs.cpp
@ -1,4 +1,5 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include "angularunits.h"
|
||||||
#include "pcs.h"
|
#include "pcs.h"
|
||||||
|
|
||||||
|
|
||||||
@ -17,15 +18,72 @@ private:
|
|||||||
|
|
||||||
QList<PCS::Entry> PCS::_pcss;
|
QList<PCS::Entry> PCS::_pcss;
|
||||||
|
|
||||||
static double parameter(const QString &str, bool *res)
|
static bool parameter(int key, double val, int units, Projection::Setup &setup)
|
||||||
{
|
{
|
||||||
QString field = str.trimmed();
|
switch (key) {
|
||||||
if (field.isEmpty()) {
|
case 8801:
|
||||||
*res = true;
|
case 8821:
|
||||||
return NAN;
|
{AngularUnits au(units);
|
||||||
|
if (au.isNull())
|
||||||
|
return false;
|
||||||
|
setup.setLongitudeOrigin(au.toDegrees(val));}
|
||||||
|
return true;
|
||||||
|
case 8802:
|
||||||
|
case 8822:
|
||||||
|
{AngularUnits au(units);
|
||||||
|
if (au.isNull())
|
||||||
|
return false;
|
||||||
|
setup.setLatitudeOrigin(au.toDegrees(val));}
|
||||||
|
return true;
|
||||||
|
case 8805:
|
||||||
|
setup.setScale(val);
|
||||||
|
return true;
|
||||||
|
case 8806:
|
||||||
|
case 8826:
|
||||||
|
{LinearUnits lu(units);
|
||||||
|
if (lu.isNull())
|
||||||
|
return false;
|
||||||
|
setup.setFalseEasting(lu.toMeters(val));}
|
||||||
|
return true;
|
||||||
|
case 8807:
|
||||||
|
case 8827:
|
||||||
|
{LinearUnits lu(units);
|
||||||
|
if (lu.isNull())
|
||||||
|
return false;
|
||||||
|
setup.setFalseNorthing(lu.toMeters(val));}
|
||||||
|
return true;
|
||||||
|
case 8823:
|
||||||
|
{AngularUnits au(units);
|
||||||
|
if (au.isNull())
|
||||||
|
return false;
|
||||||
|
setup.setStandardParallel1(au.toDegrees(val));}
|
||||||
|
return true;
|
||||||
|
case 8824:
|
||||||
|
{AngularUnits au(units);
|
||||||
|
if (au.isNull())
|
||||||
|
return false;
|
||||||
|
setup.setStandardParallel2(au.toDegrees(val));}
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int projectionSetup(const QList<QByteArray> &list,
|
||||||
|
Projection::Setup &setup)
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
|
||||||
|
for (int i = 6; i < 27; i += 3) {
|
||||||
|
int key = list[i].trimmed().toInt(&res);
|
||||||
|
double val = list[i+1].trimmed().toDouble(&res);
|
||||||
|
int un = list[i+2].trimmed().toInt(&res);
|
||||||
|
|
||||||
|
if (!parameter(key, val, un, setup))
|
||||||
|
return (i - 6)/3;
|
||||||
}
|
}
|
||||||
|
|
||||||
return field.toDouble(res);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -51,7 +109,8 @@ void PCS::loadList(const QString &path)
|
|||||||
{
|
{
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
bool res;
|
bool res;
|
||||||
int ln = 0;
|
int ln = 0, pn;
|
||||||
|
const GCS *gcs;
|
||||||
|
|
||||||
if (!file.open(QFile::ReadOnly)) {
|
if (!file.open(QFile::ReadOnly)) {
|
||||||
qWarning("Error opening PCS file: %s: %s", qPrintable(path),
|
qWarning("Error opening PCS file: %s: %s", qPrintable(path),
|
||||||
@ -64,7 +123,7 @@ void PCS::loadList(const QString &path)
|
|||||||
|
|
||||||
QByteArray line = file.readLine();
|
QByteArray line = file.readLine();
|
||||||
QList<QByteArray> list = line.split(',');
|
QList<QByteArray> list = line.split(',');
|
||||||
if (list.size() != 12) {
|
if (list.size() != 27) {
|
||||||
qWarning("%s: %d: Format error", qPrintable(path), ln);
|
qWarning("%s: %d: Format error", qPrintable(path), ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -74,7 +133,7 @@ void PCS::loadList(const QString &path)
|
|||||||
qWarning("%s: %d: Invalid PCS code", qPrintable(path), ln);
|
qWarning("%s: %d: Invalid PCS code", qPrintable(path), ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int gcs = list[2].trimmed().toInt(&res);
|
int gcsid = list[2].trimmed().toInt(&res);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
qWarning("%s: %d: Invalid GCS code", qPrintable(path), ln);
|
qWarning("%s: %d: Invalid GCS code", qPrintable(path), ln);
|
||||||
continue;
|
continue;
|
||||||
@ -84,58 +143,42 @@ void PCS::loadList(const QString &path)
|
|||||||
qWarning("%s: %d: Invalid projection code", qPrintable(path), ln);
|
qWarning("%s: %d: Invalid projection code", qPrintable(path), ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int transform = list[4].trimmed().toInt(&res);
|
int units = list[4].trimmed().toInt(&res);
|
||||||
|
if (!res) {
|
||||||
|
qWarning("%s: %d: Invalid linear units code", qPrintable(path), ln);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int transform = list[5].trimmed().toInt(&res);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
qWarning("%s: %d: Invalid coordinate transformation code",
|
qWarning("%s: %d: Invalid coordinate transformation code",
|
||||||
qPrintable(path), ln);
|
qPrintable(path), ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
double lat0 = parameter(list[5], &res);
|
|
||||||
if (!res) {
|
Projection::Setup setup;
|
||||||
qWarning("%s: %d: Invalid latitude origin", qPrintable(path), ln);
|
if ((pn = projectionSetup(list, setup))) {
|
||||||
continue;
|
qWarning("%s: %d: Invalid projection parameter #%d",
|
||||||
}
|
qPrintable(path), ln, pn);
|
||||||
double lon0 = parameter(list[6], &res);
|
|
||||||
if (!res) {
|
|
||||||
qWarning("%s: %d: Invalid longitude origin", qPrintable(path), ln);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double scale = parameter(list[7], &res);
|
|
||||||
if (!res) {
|
|
||||||
qWarning("%s: %d: Invalid scale", qPrintable(path), ln);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double fe = parameter(list[8], &res);
|
|
||||||
if (!res) {
|
|
||||||
qWarning("%s: %d: Invalid false easting", qPrintable(path), ln);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double fn = parameter(list[9], &res);
|
|
||||||
if (!res) {
|
|
||||||
qWarning("%s: %d: Invalid false northing", qPrintable(path), ln);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double sp1 = parameter(list[10], &res);
|
|
||||||
if (!res) {
|
|
||||||
qWarning("%s: %d: Invalid standard parallel #1", qPrintable(path),
|
|
||||||
ln);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
double sp2 = parameter(list[11], &res);
|
|
||||||
if (!res) {
|
|
||||||
qWarning("%s: %d: Invalid standard parallel #2", qPrintable(path),
|
|
||||||
ln);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_pcss.append(Entry(id, proj, PCS(GCS::gcs(gcs), transform,
|
if (!(gcs = GCS::gcs(gcsid))) {
|
||||||
Projection::Setup(lat0, lon0, scale, fe, fn, sp1, sp2))));
|
qWarning("%s: %d: Unknown GCS code", qPrintable(path), ln);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PCS pcs(gcs, transform, setup, units);
|
||||||
|
if (!pcs.isValid())
|
||||||
|
qWarning("%s: %d: Unknown coordinate transformation/linear units code",
|
||||||
|
qPrintable(path), ln);
|
||||||
|
else
|
||||||
|
_pcss.append(Entry(id, proj, pcs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug dbg, const PCS &pcs)
|
QDebug operator<<(QDebug dbg, const PCS &pcs)
|
||||||
{
|
{
|
||||||
dbg.nospace() << "PCS(" << *pcs.gcs() << ", " << pcs.method()
|
dbg.nospace() << "PCS(" << *pcs.gcs() << ", " << pcs.method() << ", "
|
||||||
<< ", " << pcs.setup() << ")";
|
<< pcs.units() << ", " << pcs.setup() << ")";
|
||||||
return dbg.maybeSpace();
|
return dbg.maybeSpace();
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,28 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include "gcs.h"
|
#include "gcs.h"
|
||||||
|
#include "linearunits.h"
|
||||||
#include "projection.h"
|
#include "projection.h"
|
||||||
|
|
||||||
class PCS
|
class PCS
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PCS() : _gcs(0) {}
|
PCS() : _gcs(0) {}
|
||||||
PCS(const GCS *gcs, const Projection::Method &m, const Projection::Setup &s)
|
PCS(const GCS *gcs, const Projection::Method &method,
|
||||||
: _gcs(gcs), _method(m), _setup(s) {}
|
const Projection::Setup &setup, const LinearUnits &units)
|
||||||
|
: _gcs(gcs), _method(method), _setup(setup), _units(units) {}
|
||||||
PCS(const GCS *gcs, int proj);
|
PCS(const GCS *gcs, int proj);
|
||||||
|
|
||||||
const GCS *gcs() const {return _gcs;}
|
const GCS *gcs() const {return _gcs;}
|
||||||
const Projection::Method &method() const {return _method;}
|
const Projection::Method &method() const {return _method;}
|
||||||
const Projection::Setup &setup() const {return _setup;}
|
const Projection::Setup &setup() const {return _setup;}
|
||||||
|
const LinearUnits &units() const {return _units;}
|
||||||
|
|
||||||
bool isNull() const
|
bool isNull() const
|
||||||
{return (_gcs->isNull() && _method.isNull() && _setup.isNull());}
|
{return (_gcs->isNull() && _units.isNull() && _method.isNull()
|
||||||
|
&& _setup.isNull());}
|
||||||
|
bool isValid() const
|
||||||
|
{return (_gcs->isValid() && _units.isValid() && _method.isValid());}
|
||||||
|
|
||||||
static void loadList(const QString &path);
|
static void loadList(const QString &path);
|
||||||
static const PCS *pcs(int id);
|
static const PCS *pcs(int id);
|
||||||
@ -31,6 +37,7 @@ private:
|
|||||||
const GCS *_gcs;
|
const GCS *_gcs;
|
||||||
Projection::Method _method;
|
Projection::Method _method;
|
||||||
Projection::Setup _setup;
|
Projection::Setup _setup;
|
||||||
|
LinearUnits _units;
|
||||||
|
|
||||||
static QList<Entry> _pcss;
|
static QList<Entry> _pcss;
|
||||||
static GCS _nullGCS;
|
static GCS _nullGCS;
|
||||||
|
@ -30,6 +30,14 @@ public:
|
|||||||
double standardParallel1() const {return _standardParallel1;}
|
double standardParallel1() const {return _standardParallel1;}
|
||||||
double standardParallel2() const {return _standardParallel2;}
|
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)
|
bool isNull() const {return std::isnan(_latitudeOrigin)
|
||||||
&& std::isnan(_longitudeOrigin) && std::isnan(_scale)
|
&& std::isnan(_longitudeOrigin) && std::isnan(_scale)
|
||||||
&& std::isnan(_falseEasting) && std::isnan(_falseNorthing)
|
&& std::isnan(_falseEasting) && std::isnan(_falseNorthing)
|
||||||
@ -52,6 +60,7 @@ public:
|
|||||||
|
|
||||||
int id() const {return _id;}
|
int id() const {return _id;}
|
||||||
bool isNull() const {return (_id == 0);}
|
bool isNull() const {return (_id == 0);}
|
||||||
|
bool isValid() const {return !isNull();}
|
||||||
private:
|
private:
|
||||||
int _id;
|
int _id;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user