mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 03:35:53 +01:00
Redesigned CRS logic (including CSV files structure)
This commit is contained in:
parent
aec052edaf
commit
e5199f8648
7502
data/csv/pcs.csv
7502
data/csv/pcs.csv
File diff suppressed because it is too large
Load Diff
1706
data/csv/projections.csv
Normal file
1706
data/csv/projections.csv
Normal file
File diff suppressed because it is too large
Load Diff
@ -125,6 +125,7 @@ HEADERS += src/common/config.h \
|
|||||||
src/map/ENC/style.h \
|
src/map/ENC/style.h \
|
||||||
src/map/IMG/section.h \
|
src/map/IMG/section.h \
|
||||||
src/map/IMG/zoom.h \
|
src/map/IMG/zoom.h \
|
||||||
|
src/map/conversion.h \
|
||||||
src/map/encmap.h \
|
src/map/encmap.h \
|
||||||
src/map/ENC/iso8211.h \
|
src/map/ENC/iso8211.h \
|
||||||
src/map/gemfmap.h \
|
src/map/gemfmap.h \
|
||||||
@ -335,6 +336,7 @@ SOURCES += src/main.cpp \
|
|||||||
src/map/ENC/mapdata.cpp \
|
src/map/ENC/mapdata.cpp \
|
||||||
src/map/ENC/rastertile.cpp \
|
src/map/ENC/rastertile.cpp \
|
||||||
src/map/ENC/style.cpp \
|
src/map/ENC/style.cpp \
|
||||||
|
src/map/conversion.cpp \
|
||||||
src/map/encmap.cpp \
|
src/map/encmap.cpp \
|
||||||
src/map/ENC/iso8211.cpp \
|
src/map/ENC/iso8211.cpp \
|
||||||
src/map/gemfmap.cpp \
|
src/map/gemfmap.cpp \
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "common/downloader.h"
|
#include "common/downloader.h"
|
||||||
#include "map/ellipsoid.h"
|
#include "map/ellipsoid.h"
|
||||||
#include "map/gcs.h"
|
#include "map/gcs.h"
|
||||||
|
#include "map/conversion.h"
|
||||||
#include "map/pcs.h"
|
#include "map/pcs.h"
|
||||||
#include "data/dem.h"
|
#include "data/dem.h"
|
||||||
#include "data/waypoint.h"
|
#include "data/waypoint.h"
|
||||||
@ -172,11 +173,21 @@ void App::loadDatums()
|
|||||||
|
|
||||||
void App::loadPCSs()
|
void App::loadPCSs()
|
||||||
{
|
{
|
||||||
|
QString projectionsFile(ProgramPaths::projectionsFile());
|
||||||
QString pcsFile(ProgramPaths::pcsFile());
|
QString pcsFile(ProgramPaths::pcsFile());
|
||||||
|
|
||||||
|
if (!QFileInfo::exists(projectionsFile)) {
|
||||||
|
qWarning("No projections file found.");
|
||||||
|
projectionsFile = QString();
|
||||||
|
}
|
||||||
if (!QFileInfo::exists(pcsFile)) {
|
if (!QFileInfo::exists(pcsFile)) {
|
||||||
qWarning("No PCS file found.");
|
qWarning("No PCS file found.");
|
||||||
qWarning("Maps based on a projection different from EPSG:3857 won't work.");
|
pcsFile = QString();
|
||||||
} else
|
}
|
||||||
|
|
||||||
|
if (!projectionsFile.isNull() && !pcsFile.isNull()) {
|
||||||
|
Conversion::loadList(projectionsFile);
|
||||||
PCS::loadList(pcsFile);
|
PCS::loadList(pcsFile);
|
||||||
|
} else
|
||||||
|
qWarning("Maps based on a projection different from EPSG:3857 won't work.");
|
||||||
}
|
}
|
||||||
|
@ -2745,7 +2745,8 @@ void GUI::loadOptions()
|
|||||||
_mapView->useOpenGL(true);
|
_mapView->useOpenGL(true);
|
||||||
_mapView->setDevicePixelRatio(devicePixelRatioF(),
|
_mapView->setDevicePixelRatio(devicePixelRatioF(),
|
||||||
_options.hidpiMap ? devicePixelRatioF() : 1.0);
|
_options.hidpiMap ? devicePixelRatioF() : 1.0);
|
||||||
_mapView->setOutputProjection(CRS::projection(_options.outputProjection));
|
_mapView->setOutputProjection(CRS::projection(4326,
|
||||||
|
_options.outputProjection));
|
||||||
_mapView->setInputProjection(CRS::projection(_options.inputProjection));
|
_mapView->setInputProjection(CRS::projection(_options.inputProjection));
|
||||||
_mapView->setTimeZone(_options.timeZone.zone());
|
_mapView->setTimeZone(_options.timeZone.zone());
|
||||||
_mapView->setPositionSource(_positionSource);
|
_mapView->setPositionSource(_positionSource);
|
||||||
@ -2859,7 +2860,8 @@ void GUI::updateOptions(const Options &options)
|
|||||||
_mapView->setDevicePixelRatio(devicePixelRatioF(),
|
_mapView->setDevicePixelRatio(devicePixelRatioF(),
|
||||||
options.hidpiMap ? devicePixelRatioF() : 1.0);
|
options.hidpiMap ? devicePixelRatioF() : 1.0);
|
||||||
if (options.outputProjection != _options.outputProjection)
|
if (options.outputProjection != _options.outputProjection)
|
||||||
_mapView->setOutputProjection(CRS::projection(options.outputProjection));
|
_mapView->setOutputProjection(CRS::projection(4326,
|
||||||
|
options.outputProjection));
|
||||||
if (options.inputProjection != _options.inputProjection)
|
if (options.inputProjection != _options.inputProjection)
|
||||||
_mapView->setInputProjection(CRS::projection(options.inputProjection));
|
_mapView->setInputProjection(CRS::projection(options.inputProjection));
|
||||||
if (options.timeZone != _options.timeZone) {
|
if (options.timeZone != _options.timeZone) {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <QSysInfo>
|
#include <QSysInfo>
|
||||||
#include <QButtonGroup>
|
#include <QButtonGroup>
|
||||||
#include <QGeoPositionInfoSource>
|
#include <QGeoPositionInfoSource>
|
||||||
|
#include "map/pcs.h"
|
||||||
#include "icons.h"
|
#include "icons.h"
|
||||||
#include "infolabel.h"
|
#include "infolabel.h"
|
||||||
#include "colorbox.h"
|
#include "colorbox.h"
|
||||||
@ -52,18 +53,20 @@ void OptionsDialog::automaticPauseDetectionSet(bool set)
|
|||||||
|
|
||||||
QWidget *OptionsDialog::createMapPage()
|
QWidget *OptionsDialog::createMapPage()
|
||||||
{
|
{
|
||||||
_outputProjection = new ProjectionComboBox();
|
_outputProjection = new ProjectionComboBox(GCS::WGS84List()
|
||||||
|
+ Conversion::list());
|
||||||
_outputProjection->setCurrentIndex(_outputProjection->findData(
|
_outputProjection->setCurrentIndex(_outputProjection->findData(
|
||||||
_options.outputProjection));
|
_options.outputProjection));
|
||||||
_inputProjection = new ProjectionComboBox();
|
_inputProjection = new ProjectionComboBox(GCS::list() + PCS::list());
|
||||||
_inputProjection->setCurrentIndex(_inputProjection->findData(
|
_inputProjection->setCurrentIndex(_inputProjection->findData(
|
||||||
_options.inputProjection));
|
_options.inputProjection));
|
||||||
|
|
||||||
InfoLabel *inInfo = new InfoLabel(tr("Select the proper projection of maps"
|
InfoLabel *inInfo = new InfoLabel(tr("Select the proper coordinate "
|
||||||
" without a projection definition (JNX, KMZ and world file maps)."));
|
"reference system (CRS) of maps without a CRS definition "
|
||||||
InfoLabel *outInfo = new InfoLabel(tr("Select the desired projection of"
|
"(JNX, KMZ and World file maps)."));
|
||||||
" vector maps (IMG and Mapsforge maps). The projection must be valid for"
|
InfoLabel *outInfo = new InfoLabel(tr("Select the desired projection of "
|
||||||
" the whole map area."));
|
"vector maps (IMG, Mapsforge and ENC maps). The projection must be valid "
|
||||||
|
"for the whole map area."));
|
||||||
|
|
||||||
_hidpi = new QRadioButton(tr("High-resolution"));
|
_hidpi = new QRadioButton(tr("High-resolution"));
|
||||||
_lodpi = new QRadioButton(tr("Standard"));
|
_lodpi = new QRadioButton(tr("Standard"));
|
||||||
|
@ -1,21 +1,16 @@
|
|||||||
#include "map/pcs.h"
|
|
||||||
#include "projectioncombobox.h"
|
#include "projectioncombobox.h"
|
||||||
|
|
||||||
ProjectionComboBox::ProjectionComboBox(QWidget *parent) : QComboBox(parent)
|
ProjectionComboBox::ProjectionComboBox(const QList<KV<int, QString> > &list,
|
||||||
|
QWidget *parent) : QComboBox(parent)
|
||||||
{
|
{
|
||||||
setSizeAdjustPolicy(AdjustToMinimumContentsLengthWithIcon);
|
setSizeAdjustPolicy(AdjustToMinimumContentsLengthWithIcon);
|
||||||
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||||
|
|
||||||
int last = -1;
|
QList<KV<int, QString> > projs(list);
|
||||||
QList<KV<int, QString> > projections(GCS::list() + PCS::list());
|
std::sort(projs.begin(), projs.end());
|
||||||
std::sort(projections.begin(), projections.end());
|
|
||||||
for (int i = 0; i < projections.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
const KV<int, QString> &proj = projections.at(i);
|
const KV<int, QString> &proj = projs.at(i);
|
||||||
// There may be duplicit EPSG codes with different names
|
|
||||||
if (proj.key() == last)
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
last = proj.key();
|
|
||||||
QString text = QString::number(proj.key()) + " - " + proj.value();
|
QString text = QString::number(proj.key()) + " - " + proj.value();
|
||||||
addItem(text, QVariant(proj.key()));
|
addItem(text, QVariant(proj.key()));
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
#define PROJECTIONCOMBOBOX_H
|
#define PROJECTIONCOMBOBOX_H
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
#include <QList>
|
||||||
|
#include "common/kv.h"
|
||||||
|
|
||||||
class ProjectionComboBox : public QComboBox
|
class ProjectionComboBox : public QComboBox
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ProjectionComboBox(QWidget *parent = 0);
|
ProjectionComboBox(const QList<KV<int, QString> > &list, QWidget *parent = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PROJECTIONCOMBOBOX_H
|
#endif // PROJECTIONCOMBOBOX_H
|
||||||
|
@ -256,7 +256,7 @@ SETTING(printMovingTime, "printMovingTime", false );
|
|||||||
SETTING(printItemCount, "printItemCount", true );
|
SETTING(printItemCount, "printItemCount", true );
|
||||||
SETTING(separateGraphPage, "separateGraphPage", false );
|
SETTING(separateGraphPage, "separateGraphPage", false );
|
||||||
SETTING(sliderColor, "sliderColor", QColor(Qt::red) );
|
SETTING(sliderColor, "sliderColor", QColor(Qt::red) );
|
||||||
SETTING(outputProjection, "outputProjection", 3857 );
|
SETTING(outputProjection, "outputProjection", 3856 );
|
||||||
SETTING(inputProjection, "inputProjection", 4326 );
|
SETTING(inputProjection, "inputProjection", 4326 );
|
||||||
SETTING(hidpiMap, "HiDPIMap", true );
|
SETTING(hidpiMap, "HiDPIMap", true );
|
||||||
SETTING(poiPath, "poiPath", "" );
|
SETTING(poiPath, "poiPath", "" );
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
#define STYLE_DIR "style"
|
#define STYLE_DIR "style"
|
||||||
#define SYMBOLS_DIR "symbols"
|
#define SYMBOLS_DIR "symbols"
|
||||||
|
|
||||||
#define ELLIPSOID_FILE "ellipsoids.csv"
|
#define ELLIPSOIDS_FILE "ellipsoids.csv"
|
||||||
|
#define PROJECTIONS_FILE "projections.csv"
|
||||||
#define GCS_FILE "gcs.csv"
|
#define GCS_FILE "gcs.csv"
|
||||||
#define PCS_FILE "pcs.csv"
|
#define PCS_FILE "pcs.csv"
|
||||||
#define TYP_FILE "style.typ"
|
#define TYP_FILE "style.typ"
|
||||||
@ -131,7 +132,7 @@ QString ProgramPaths::translationsDir()
|
|||||||
|
|
||||||
QString ProgramPaths::ellipsoidsFile()
|
QString ProgramPaths::ellipsoidsFile()
|
||||||
{
|
{
|
||||||
return QDir(csvDir()).filePath(ELLIPSOID_FILE);
|
return QDir(csvDir()).filePath(ELLIPSOIDS_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ProgramPaths::gcsFile()
|
QString ProgramPaths::gcsFile()
|
||||||
@ -139,6 +140,11 @@ QString ProgramPaths::gcsFile()
|
|||||||
return QDir(csvDir()).filePath(GCS_FILE);
|
return QDir(csvDir()).filePath(GCS_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ProgramPaths::projectionsFile()
|
||||||
|
{
|
||||||
|
return QDir(csvDir()).filePath(PROJECTIONS_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
QString ProgramPaths::pcsFile()
|
QString ProgramPaths::pcsFile()
|
||||||
{
|
{
|
||||||
return QDir(csvDir()).filePath(PCS_FILE);
|
return QDir(csvDir()).filePath(PCS_FILE);
|
||||||
|
@ -15,6 +15,7 @@ namespace ProgramPaths
|
|||||||
QString translationsDir();
|
QString translationsDir();
|
||||||
QString ellipsoidsFile();
|
QString ellipsoidsFile();
|
||||||
QString gcsFile();
|
QString gcsFile();
|
||||||
|
QString projectionsFile();
|
||||||
QString pcsFile();
|
QString pcsFile();
|
||||||
QString typFile();
|
QString typFile();
|
||||||
QString renderthemeFile();
|
QString renderthemeFile();
|
||||||
|
@ -304,20 +304,20 @@ bool BSBMap::createProjection(const QString &datum, const QString &proj,
|
|||||||
|
|
||||||
if (!proj.compare("MERCATOR", Qt::CaseInsensitive)) {
|
if (!proj.compare("MERCATOR", Qt::CaseInsensitive)) {
|
||||||
Projection::Setup setup(0, c.lon(), NAN, 0, 0, NAN, NAN);
|
Projection::Setup setup(0, c.lon(), NAN, 0, 0, NAN, NAN);
|
||||||
pcs = PCS(gcs, 9804, setup, 9001);
|
pcs = PCS(gcs, Conversion(9804, setup, 9001));
|
||||||
} else if (!proj.compare("TRANSVERSE MERCATOR", Qt::CaseInsensitive)) {
|
} else if (!proj.compare("TRANSVERSE MERCATOR", Qt::CaseInsensitive)) {
|
||||||
Projection::Setup setup(0, params[1], params[2], 0, 0, NAN, NAN);
|
Projection::Setup setup(0, params[1], params[2], 0, 0, NAN, NAN);
|
||||||
pcs = PCS(gcs, 9807, setup, 9001);
|
pcs = PCS(gcs, Conversion(9807, setup, 9001));
|
||||||
} else if (!proj.compare("UNIVERSAL TRANSVERSE MERCATOR",
|
} else if (!proj.compare("UNIVERSAL TRANSVERSE MERCATOR",
|
||||||
Qt::CaseInsensitive)) {
|
Qt::CaseInsensitive)) {
|
||||||
Projection::Setup setup(0, params[0], 0.9996, 500000, 0, NAN, NAN);
|
Projection::Setup setup(0, params[0], 0.9996, 500000, 0, NAN, NAN);
|
||||||
pcs = PCS(gcs, 9807, setup, 9001);
|
pcs = PCS(gcs, Conversion(9807, setup, 9001));
|
||||||
} else if (!proj.compare("LAMBERT CONFORMAL CONIC", Qt::CaseInsensitive)) {
|
} else if (!proj.compare("LAMBERT CONFORMAL CONIC", Qt::CaseInsensitive)) {
|
||||||
Projection::Setup setup(0, params[0], NAN, 0, 0, params[2], params[3]);
|
Projection::Setup setup(0, params[0], NAN, 0, 0, params[2], params[3]);
|
||||||
pcs = PCS(gcs, 9802, setup, 9001);
|
pcs = PCS(gcs, Conversion(9802, setup, 9001));
|
||||||
} else if (!proj.compare("POLYCONIC", Qt::CaseInsensitive)) {
|
} else if (!proj.compare("POLYCONIC", Qt::CaseInsensitive)) {
|
||||||
Projection::Setup setup(0, params[0], NAN, 0, 0, NAN, NAN);
|
Projection::Setup setup(0, params[0], NAN, 0, 0, NAN, NAN);
|
||||||
pcs = PCS(gcs, 9818, setup, 9001);
|
pcs = PCS(gcs, Conversion(9818, setup, 9001));
|
||||||
} else {
|
} else {
|
||||||
_errorString = proj + ": Unknown/missing projection";
|
_errorString = proj + ": Unknown/missing projection";
|
||||||
return false;
|
return false;
|
||||||
|
203
src/map/conversion.cpp
Normal file
203
src/map/conversion.cpp
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
#include <QFile>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int projectionSetup(const QList<QByteArray> &list,
|
||||||
|
Projection::Setup &setup)
|
||||||
|
{
|
||||||
|
bool r1, r2, r3;
|
||||||
|
|
||||||
|
for (int i = 5; i < 26; i += 3) {
|
||||||
|
QString ks = list[i].trimmed();
|
||||||
|
if (ks.isEmpty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
int key = ks.toInt(&r1);
|
||||||
|
double val = list[i+1].trimmed().toDouble(&r2);
|
||||||
|
int un = list[i+2].trimmed().toInt(&r3);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
QMap<int, Entry>::const_iterator it = _conversions.find(id);
|
||||||
|
|
||||||
|
if (it == _conversions.constEnd())
|
||||||
|
return Conversion();
|
||||||
|
else {
|
||||||
|
const Entry &e = it.value();
|
||||||
|
return Conversion(e.method(), e.setup(), e.units(), e.cs());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Conversion::loadList(const QString &path)
|
||||||
|
{
|
||||||
|
QFile file(path);
|
||||||
|
bool res;
|
||||||
|
int ln = 0, pn;
|
||||||
|
|
||||||
|
|
||||||
|
if (!file.open(QFile::ReadOnly)) {
|
||||||
|
qWarning("Error opening projections file: %s: %s", qPrintable(path),
|
||||||
|
qPrintable(file.errorString()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!file.atEnd()) {
|
||||||
|
ln++;
|
||||||
|
|
||||||
|
QByteArray line = file.readLine(4096);
|
||||||
|
QList<QByteArray> list = line.split(',');
|
||||||
|
if (list.size() != 26) {
|
||||||
|
qWarning("%s:%d: Format error", qPrintable(path), ln);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString name(list.at(0).trimmed());
|
||||||
|
int proj = list.at(1).trimmed().toInt(&res);
|
||||||
|
if (!res) {
|
||||||
|
qWarning("%s:%d: Invalid projection code", qPrintable(path), ln);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int units = list.at(2).trimmed().toInt(&res);
|
||||||
|
if (!res) {
|
||||||
|
qWarning("%s:%d: Invalid linear units code", qPrintable(path), ln);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int transform = list.at(3).trimmed().toInt(&res);
|
||||||
|
if (!res) {
|
||||||
|
qWarning("%s:%d: Invalid coordinate transformation code",
|
||||||
|
qPrintable(path), ln);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int cs = list.at(4).trimmed().toInt(&res);
|
||||||
|
if (!res) {
|
||||||
|
qWarning("%s:%d: Invalid coordinate system code",
|
||||||
|
qPrintable(path), ln);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!LinearUnits(units).isValid()) {
|
||||||
|
qWarning("%s:%d: Unknown linear units code", qPrintable(path), ln);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!Projection::Method(transform).isValid()) {
|
||||||
|
qWarning("%s:%d: Unknown coordinate transformation code",
|
||||||
|
qPrintable(path), ln);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!CoordinateSystem(cs).isValid()) {
|
||||||
|
qWarning("%s:%d: Unknown coordinate system code", qPrintable(path),
|
||||||
|
ln);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Projection::Setup setup;
|
||||||
|
if ((pn = projectionSetup(list, setup))) {
|
||||||
|
qWarning("%s: %d: Invalid projection parameter #%d",
|
||||||
|
qPrintable(path), ln, pn);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_conversions.insert(proj, Entry(name, transform, setup, units, cs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<KV<int, QString> > Conversion::list()
|
||||||
|
{
|
||||||
|
QList<KV<int, QString> > list;
|
||||||
|
|
||||||
|
for (QMap<int, Entry>::const_iterator it = _conversions.constBegin();
|
||||||
|
it != _conversions.constEnd(); ++it)
|
||||||
|
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
|
71
src/map/conversion.h
Normal file
71
src/map/conversion.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#ifndef CONVERSION_H
|
||||||
|
#define CONVERSION_H
|
||||||
|
|
||||||
|
#include "projection.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) {}
|
||||||
|
|
||||||
|
const Projection::Method &method() const {return _method;}
|
||||||
|
const Projection::Setup &setup() const {return _setup;}
|
||||||
|
const LinearUnits &units() const {return _units;}
|
||||||
|
const CoordinateSystem &cs() const {return _cs;}
|
||||||
|
|
||||||
|
bool isNull() const {
|
||||||
|
return (_units.isNull() && _method.isNull() && _setup.isNull()
|
||||||
|
&& _cs.isNull());
|
||||||
|
}
|
||||||
|
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. The projection setup is
|
||||||
|
always valid as we do not have any checks for it. */
|
||||||
|
return (_units.isValid() && _method.isValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loadList(const QString &path);
|
||||||
|
static Conversion conversion(int id);
|
||||||
|
static QList<KV<int, QString> > list();
|
||||||
|
|
||||||
|
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) {}
|
||||||
|
|
||||||
|
const QString &name() const {return _name;}
|
||||||
|
const Projection::Method &method() const {return _method;}
|
||||||
|
const Projection::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;
|
||||||
|
LinearUnits _units;
|
||||||
|
CoordinateSystem _cs;
|
||||||
|
};
|
||||||
|
|
||||||
|
static QMap<int, Entry> defaults();
|
||||||
|
|
||||||
|
Projection::Method _method;
|
||||||
|
Projection::Setup _setup;
|
||||||
|
LinearUnits _units;
|
||||||
|
CoordinateSystem _cs;
|
||||||
|
|
||||||
|
static QMap<int, Entry> _conversions;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG
|
||||||
|
QDebug operator<<(QDebug dbg, const Conversion &conversion);
|
||||||
|
#endif // QT_NO_DEBUG
|
||||||
|
|
||||||
|
#endif // CONVERSION_H
|
@ -58,9 +58,24 @@ Projection CRS::projection(int id)
|
|||||||
if (!pcs.isNull())
|
if (!pcs.isNull())
|
||||||
return Projection(pcs);
|
return Projection(pcs);
|
||||||
|
|
||||||
|
// Geographic 2D projections
|
||||||
GCS gcs(GCS::gcs(id));
|
GCS gcs(GCS::gcs(id));
|
||||||
if (!gcs.isNull())
|
if (!gcs.isNull())
|
||||||
return Projection(gcs);
|
return Projection(gcs);
|
||||||
|
|
||||||
return Projection();
|
return Projection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Projection CRS::projection(int gcsId, int projId)
|
||||||
|
{
|
||||||
|
Conversion proj(Conversion::conversion(projId));
|
||||||
|
if (!proj.isNull())
|
||||||
|
return Projection(PCS(GCS::gcs(gcsId), proj));
|
||||||
|
|
||||||
|
// Geographic 2D projections
|
||||||
|
GCS gcs(GCS::gcs(projId));
|
||||||
|
if (!gcs.isNull())
|
||||||
|
return Projection(gcs);
|
||||||
|
|
||||||
|
return Projection();
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ namespace CRS
|
|||||||
{
|
{
|
||||||
Projection projection(const QString &crs);
|
Projection projection(const QString &crs);
|
||||||
Projection projection(int id);
|
Projection projection(int id);
|
||||||
|
Projection projection(int gcsId, int projId);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CRS_H
|
#endif // CRS_H
|
||||||
|
@ -52,17 +52,17 @@ void Ellipsoid::loadList(const QString &path)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int id = list[1].trimmed().toInt(&res);
|
int id = list.at(1).trimmed().toInt(&res);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
qWarning("%s: %d: Invalid ellipsoid code", qPrintable(path), ln);
|
qWarning("%s: %d: Invalid ellipsoid code", qPrintable(path), ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
double radius = list[2].trimmed().toDouble(&res);
|
double radius = list.at(2).trimmed().toDouble(&res);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
qWarning("%s: %d: Invalid radius", qPrintable(path), ln);
|
qWarning("%s: %d: Invalid radius", qPrintable(path), ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
double flattening = list[3].trimmed().toDouble(&res);
|
double flattening = list.at(3).trimmed().toDouble(&res);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
qWarning("%s: %d: Invalid flattening", qPrintable(path), ln);
|
qWarning("%s: %d: Invalid flattening", qPrintable(path), ln);
|
||||||
continue;
|
continue;
|
||||||
|
@ -227,7 +227,7 @@ void ENCMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
|
|||||||
|
|
||||||
void ENCMap::setOutputProjection(const Projection &projection)
|
void ENCMap::setOutputProjection(const Projection &projection)
|
||||||
{
|
{
|
||||||
if (projection == _projection)
|
if (!projection.isValid() || projection == _projection)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_projection = projection;
|
_projection = projection;
|
||||||
|
@ -235,11 +235,21 @@ QList<KV<int, QString> > GCS::list()
|
|||||||
{
|
{
|
||||||
QList<KV<int, QString> > list;
|
QList<KV<int, QString> > list;
|
||||||
|
|
||||||
for (int i = 0; i < _gcss.size(); i++)
|
for (int i = 0; i < _gcss.size(); i++) {
|
||||||
if (_gcss.at(i).id())
|
const Entry &e = _gcss.at(i);
|
||||||
list.append(KV<int, QString>(_gcss.at(i).id(), _gcss.at(i).name()
|
if (!e.id() || (i && e.id() == list.last().key()))
|
||||||
+ " / Geographic 2D"));
|
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;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ public:
|
|||||||
|
|
||||||
static void loadList(const QString &path);
|
static void loadList(const QString &path);
|
||||||
static QList<KV<int, QString> > list();
|
static QList<KV<int, QString> > list();
|
||||||
|
static QList<KV<int, QString> > WGS84List();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Entry;
|
class Entry;
|
||||||
|
@ -370,14 +370,13 @@ bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
|
|||||||
GCS gcs(geographicCS(kv));
|
GCS gcs(geographicCS(kv));
|
||||||
if (gcs.isNull())
|
if (gcs.isNull())
|
||||||
return false;
|
return false;
|
||||||
PCS pcs(PCS::pcs(gcs, kv.value(ProjectionGeoKey).SHORT));
|
Conversion c(Conversion::conversion(kv.value(ProjectionGeoKey).SHORT));
|
||||||
if (pcs.isNull()) {
|
if (c.isNull()) {
|
||||||
_errorString = QString("%1: unknown projection code")
|
_errorString = QString("%1: unknown projection code")
|
||||||
.arg(kv.value(GeographicTypeGeoKey).SHORT)
|
|
||||||
.arg(kv.value(ProjectionGeoKey).SHORT);
|
.arg(kv.value(ProjectionGeoKey).SHORT);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_projection = Projection(pcs);
|
_projection = Projection(PCS(gcs, c));
|
||||||
} else {
|
} else {
|
||||||
double lat0, lon0, scale, fe, fn, sp1, sp2;
|
double lat0, lon0, scale, fe, fn, sp1, sp2;
|
||||||
|
|
||||||
@ -454,7 +453,7 @@ bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
|
|||||||
fe = NAN;
|
fe = NAN;
|
||||||
|
|
||||||
Projection::Setup setup(lat0, lon0, scale, fe, fn, sp1, sp2);
|
Projection::Setup setup(lat0, lon0, scale, fe, fn, sp1, sp2);
|
||||||
_projection = Projection(PCS(gcs, method, setup, lu));
|
_projection = Projection(PCS(gcs, Conversion(method, setup, lu)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -270,7 +270,7 @@ void IMGMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
|
|||||||
|
|
||||||
void IMGMap::setOutputProjection(const Projection &projection)
|
void IMGMap::setOutputProjection(const Projection &projection)
|
||||||
{
|
{
|
||||||
if (projection == _projection)
|
if (!projection.isValid() || projection == _projection)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_projection = projection;
|
_projection = projection;
|
||||||
|
@ -269,7 +269,7 @@ void JNXMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
|
|
||||||
void JNXMap::setInputProjection(const Projection &projection)
|
void JNXMap::setInputProjection(const Projection &projection)
|
||||||
{
|
{
|
||||||
if (projection == _projection)
|
if (!projection.isValid() || projection == _projection)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_projection = projection;
|
_projection = projection;
|
||||||
|
@ -471,7 +471,7 @@ void KMZMap::unload()
|
|||||||
|
|
||||||
void KMZMap::setInputProjection(const Projection &projection)
|
void KMZMap::setInputProjection(const Projection &projection)
|
||||||
{
|
{
|
||||||
if (projection == _projection)
|
if (!projection.isValid() || projection == _projection)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_projection = projection;
|
_projection = projection;
|
||||||
|
@ -175,51 +175,51 @@ bool MapFile::createProjection(const QString &datum, const QString &name,
|
|||||||
_projection = Projection(gcs);
|
_projection = Projection(gcs);
|
||||||
return true;
|
return true;
|
||||||
} else if (name == "Mercator")
|
} else if (name == "Mercator")
|
||||||
pcs = PCS(gcs, 1024, setup, 9001);
|
pcs = PCS(gcs, Conversion(1024, setup, 9001));
|
||||||
else if (name == "Transverse Mercator"
|
else if (name == "Transverse Mercator"
|
||||||
|| name == "(UTM) Universal Transverse Mercator")
|
|| name == "(UTM) Universal Transverse Mercator")
|
||||||
pcs = PCS(gcs, 9807, setup, 9001);
|
pcs = PCS(gcs, Conversion(9807, setup, 9001));
|
||||||
else if (name == "Lambert Conformal Conic")
|
else if (name == "Lambert Conformal Conic")
|
||||||
pcs = PCS(gcs, 9802, setup, 9001);
|
pcs = PCS(gcs, Conversion(9802, setup, 9001));
|
||||||
else if (name == "Albers Equal Area")
|
else if (name == "Albers Equal Area")
|
||||||
pcs = PCS(gcs, 9822, setup, 9001);
|
pcs = PCS(gcs, Conversion(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, Conversion(9820, setup, 9001));
|
||||||
else if (name == "Polyconic (American)")
|
else if (name == "Polyconic (American)")
|
||||||
pcs = PCS(gcs, 9818, setup, 9001);
|
pcs = PCS(gcs, Conversion(9818, setup, 9001));
|
||||||
else if (name == "(NZTM2) New Zealand TM 2000")
|
else if (name == "(NZTM2) New Zealand TM 2000")
|
||||||
pcs = PCS(gcs, 9807, Projection::Setup(0, 173.0, 0.9996, 1600000,
|
pcs = PCS(gcs, Conversion(9807, Projection::Setup(0, 173.0, 0.9996,
|
||||||
10000000, NAN, NAN), 9001);
|
1600000, 10000000, NAN, NAN), 9001));
|
||||||
else if (name == "(BNG) British National Grid")
|
else if (name == "(BNG) British National Grid")
|
||||||
pcs = PCS(gcs, 9807, Projection::Setup(49, -2, 0.999601, 400000,
|
pcs = PCS(gcs, Conversion(9807, Projection::Setup(49, -2, 0.999601,
|
||||||
-100000, NAN, NAN), 9001);
|
400000, -100000, NAN, NAN), 9001));
|
||||||
else if (name == "(IG) Irish Grid")
|
else if (name == "(IG) Irish Grid")
|
||||||
pcs = PCS(gcs, 9807, Projection::Setup(53.5, -8, 1.000035, 200000,
|
pcs = PCS(gcs, Conversion(9807, Projection::Setup(53.5, -8, 1.000035,
|
||||||
250000, NAN, NAN), 9001);
|
200000, 250000, NAN, NAN), 9001));
|
||||||
else if (name == "(SG) Swedish Grid")
|
else if (name == "(SG) Swedish Grid")
|
||||||
pcs = PCS(gcs, 9807, Projection::Setup(0, 15.808278, 1, 1500000, 0, NAN,
|
pcs = PCS(gcs, Conversion(9807, Projection::Setup(0, 15.808278, 1,
|
||||||
NAN), 9001);
|
1500000, 0, NAN, NAN), 9001));
|
||||||
else if (name == "(I) France Zone I")
|
else if (name == "(I) France Zone I")
|
||||||
pcs = PCS(gcs, 9802, Projection::Setup(49.5, 2.337229, NAN, 600000,
|
pcs = PCS(gcs, Conversion(9802, Projection::Setup(49.5, 2.337229, NAN,
|
||||||
1200000, 48.598523, 50.395912), 9001);
|
600000, 1200000, 48.598523, 50.395912), 9001));
|
||||||
else if (name == "(II) France Zone II")
|
else if (name == "(II) France Zone II")
|
||||||
pcs = PCS(gcs, 9802, Projection::Setup(46.8, 2.337229, NAN, 600000,
|
pcs = PCS(gcs, Conversion(9802, Projection::Setup(46.8, 2.337229, NAN,
|
||||||
2200000, 45.898919, 47.696014), 9001);
|
600000, 2200000, 45.898919, 47.696014), 9001));
|
||||||
else if (name == "(III) France Zone III")
|
else if (name == "(III) France Zone III")
|
||||||
pcs = PCS(gcs, 9802, Projection::Setup(44.1, 2.337229, NAN, 600000,
|
pcs = PCS(gcs, Conversion(9802, Projection::Setup(44.1, 2.337229, NAN,
|
||||||
3200000, 43.199291, 44.996094), 9001);
|
600000, 3200000, 43.199291, 44.996094), 9001));
|
||||||
else if (name == "(IV) France Zone IV")
|
else if (name == "(IV) France Zone IV")
|
||||||
pcs = PCS(gcs, 9802, Projection::Setup(42.165, 2.337229, NAN, 234.358,
|
pcs = PCS(gcs, Conversion(9802, Projection::Setup(42.165, 2.337229, NAN,
|
||||||
4185861.369, 41.560388, 42.767663), 9001);
|
234.358, 4185861.369, 41.560388, 42.767663), 9001));
|
||||||
else if (name == "(VICGRID) Victoria Australia")
|
else if (name == "(VICGRID) Victoria Australia")
|
||||||
pcs = PCS(gcs, 9802, Projection::Setup(-37, 145, NAN, 2500000, 4500000,
|
pcs = PCS(gcs, Conversion(9802, Projection::Setup(-37, 145, NAN,
|
||||||
-36, -38), 9001);
|
2500000, 4500000, -36, -38), 9001));
|
||||||
else if (name == "(VG94) VICGRID94 Victoria Australia")
|
else if (name == "(VG94) VICGRID94 Victoria Australia")
|
||||||
pcs = PCS(gcs, 9802, Projection::Setup(-37, 145, NAN, 2500000, 2500000,
|
pcs = PCS(gcs, Conversion(9802, Projection::Setup(-37, 145, NAN,
|
||||||
-36, -38), 9001);
|
2500000, 2500000, -36, -38), 9001));
|
||||||
else if (name == "(SUI) Swiss Grid")
|
else if (name == "(SUI) Swiss Grid")
|
||||||
pcs = PCS(gcs, 9815, Projection::Setup(46.570866, 7.26225, 1.0, 600000,
|
pcs = PCS(gcs, Conversion(9815, Projection::Setup(46.570866, 7.26225,
|
||||||
200000, 90.0, 90.0), 9001);
|
1.0, 600000, 200000, 90.0, 90.0), 9001));
|
||||||
else {
|
else {
|
||||||
_errorString = QString("%1: Unknown map projection").arg(name);
|
_errorString = QString("%1: Unknown map projection").arg(name);
|
||||||
return false;
|
return false;
|
||||||
|
@ -230,7 +230,7 @@ void MapsforgeMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
|
|||||||
|
|
||||||
void MapsforgeMap::setOutputProjection(const Projection &projection)
|
void MapsforgeMap::setOutputProjection(const Projection &projection)
|
||||||
{
|
{
|
||||||
if (projection == _projection)
|
if (!projection.isValid() || projection == _projection)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_projection = projection;
|
_projection = projection;
|
||||||
|
@ -178,28 +178,28 @@ static Projection createProjection(const GCS &gcs, const QString &name)
|
|||||||
if (pl.first() == "Latitude/Longitude")
|
if (pl.first() == "Latitude/Longitude")
|
||||||
return Projection(gcs);
|
return Projection(gcs);
|
||||||
else if (pl.first() == "UTM")
|
else if (pl.first() == "UTM")
|
||||||
pcs = PCS(gcs, 9807, utm2setup(pl), 9001);
|
pcs = PCS(gcs, Conversion(9807, utm2setup(pl), 9001));
|
||||||
else if (pl.first() == "Mercator")
|
else if (pl.first() == "Mercator")
|
||||||
pcs = PCS(gcs, 1024, Projection::Setup(), 9001);
|
pcs = PCS(gcs, Conversion(1024, Projection::Setup(), 9001));
|
||||||
else if (pl.first() == "Mercator Ellipsoidal")
|
else if (pl.first() == "Mercator Ellipsoidal")
|
||||||
pcs = PCS(gcs, 9804, mercator2setup(pl), 9001);
|
pcs = PCS(gcs, Conversion(9804, mercator2setup(pl), 9001));
|
||||||
else if (pl.first() == "Transverse Mercator")
|
else if (pl.first() == "Transverse Mercator")
|
||||||
pcs = PCS(gcs, 9807, tm2setup(pl), 9001);
|
pcs = PCS(gcs, Conversion(9807, tm2setup(pl), 9001));
|
||||||
else if (pl.first() == "Lambert Conformal Conic")
|
else if (pl.first() == "Lambert Conformal Conic")
|
||||||
pcs = PCS(gcs, 9802, lcc2setup(pl), 9001);
|
pcs = PCS(gcs, Conversion(9802, lcc2setup(pl), 9001));
|
||||||
else if (pl.first() == "(A)Lambert Azimuthual Equal Area")
|
else if (pl.first() == "(A)Lambert Azimuthual Equal Area")
|
||||||
pcs = PCS(gcs, 9820, laea2setup(pl), 9001);
|
pcs = PCS(gcs, Conversion(9820, laea2setup(pl), 9001));
|
||||||
else if (pl.first() == "Polyconic (American)")
|
else if (pl.first() == "Polyconic (American)")
|
||||||
pcs = PCS(gcs, 9818, polyconic2setup(pl), 9001);
|
pcs = PCS(gcs, Conversion(9818, polyconic2setup(pl), 9001));
|
||||||
else if (pl.first() == "(IG) Irish Grid")
|
else if (pl.first() == "(IG) Irish Grid")
|
||||||
pcs = PCS(gcs, 9807, Projection::Setup(53.5, -8, 1.000035, 200000,
|
pcs = PCS(gcs, Conversion(9807, Projection::Setup(53.5, -8, 1.000035,
|
||||||
250000, NAN, NAN), 9001);
|
200000, 250000, NAN, NAN), 9001));
|
||||||
else if (pl.first() == "(SUI) Swiss Grid")
|
else if (pl.first() == "(SUI) Swiss Grid")
|
||||||
pcs = PCS(gcs, 9815, Projection::Setup(46.570866, 7.26225, 1.0, 600000,
|
pcs = PCS(gcs, Conversion(9815, Projection::Setup(46.570866, 7.26225,
|
||||||
200000, 90.0, 90.0), 9001);
|
1.0, 600000, 200000, 90.0, 90.0), 9001));
|
||||||
else if (pl.first() == "Rijksdriehoeksmeting")
|
else if (pl.first() == "Rijksdriehoeksmeting")
|
||||||
pcs = PCS(gcs, 9809, Projection::Setup(52.1561605555556,
|
pcs = PCS(gcs, Conversion(9809, Projection::Setup(52.1561605555556,
|
||||||
5.38763888888889, 0.9999079, 155000, 463000, NAN, NAN), 9001);
|
5.38763888888889, 0.9999079, 155000, 463000, NAN, NAN), 9001));
|
||||||
else
|
else
|
||||||
return Projection();
|
return Projection();
|
||||||
|
|
||||||
|
195
src/map/pcs.cpp
195
src/map/pcs.cpp
@ -2,145 +2,32 @@
|
|||||||
#include "angularunits.h"
|
#include "angularunits.h"
|
||||||
#include "pcs.h"
|
#include "pcs.h"
|
||||||
|
|
||||||
|
QMap<int, PCS::Entry> PCS::_pcss = defaults();
|
||||||
|
|
||||||
class PCS::Entry {
|
QMap<int, PCS::Entry> PCS::defaults()
|
||||||
public:
|
|
||||||
Entry(const QString &name, int id, int proj, const PCS &pcs)
|
|
||||||
: _name(name), _id(id), _proj(proj), _pcs(pcs) {}
|
|
||||||
|
|
||||||
const QString &name() const {return _name;}
|
|
||||||
int id() const {return _id;}
|
|
||||||
int proj() const {return _proj;}
|
|
||||||
const PCS &pcs() const {return _pcs;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString _name;
|
|
||||||
int _id, _proj;
|
|
||||||
PCS _pcs;
|
|
||||||
};
|
|
||||||
|
|
||||||
QList<PCS::Entry> PCS::_pcss = defaults();
|
|
||||||
|
|
||||||
QList<PCS::Entry> PCS::defaults()
|
|
||||||
{
|
{
|
||||||
QList<PCS::Entry> list;
|
QMap<int, Entry> map;
|
||||||
list.append(PCS::Entry("WGS 84 / Pseudo-Mercator", 3857, 3856,
|
map.insert(3857, Entry("WGS 84 / Pseudo-Mercator", 4326, 3856));
|
||||||
PCS(GCS::WGS84(), 1024, Projection::Setup(0, 0, NAN, 0, 0, NAN, NAN),
|
return map;
|
||||||
9001, 4499)));
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int projectionSetup(const QList<QByteArray> &list,
|
|
||||||
Projection::Setup &setup)
|
|
||||||
{
|
|
||||||
bool r1, r2, r3;
|
|
||||||
|
|
||||||
for (int i = 7; i < 28; i += 3) {
|
|
||||||
QString ks = list[i].trimmed();
|
|
||||||
if (ks.isEmpty())
|
|
||||||
break;
|
|
||||||
|
|
||||||
int key = ks.toInt(&r1);
|
|
||||||
double val = list[i+1].trimmed().toDouble(&r2);
|
|
||||||
int un = list[i+2].trimmed().toInt(&r3);
|
|
||||||
if (!r1 || !r2 || !r3)
|
|
||||||
return (i - 7)/3 + 1;
|
|
||||||
|
|
||||||
if (!parameter(key, val, un, setup))
|
|
||||||
return (i - 7)/3 + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PCS PCS::pcs(int id)
|
PCS PCS::pcs(int id)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _pcss.size(); i++)
|
QMap<int, Entry>::const_iterator it = _pcss.find(id);
|
||||||
if (_pcss.at(i).id() == id)
|
|
||||||
return _pcss.at(i).pcs();
|
|
||||||
|
|
||||||
return PCS();
|
if (it == _pcss.constEnd())
|
||||||
}
|
return PCS();
|
||||||
|
else {
|
||||||
PCS PCS::pcs(const GCS &gcs, int proj)
|
const Entry &e = it.value();
|
||||||
{
|
return PCS(GCS::gcs(e.gcs()), Conversion::conversion(e.proj()));
|
||||||
for (int i = 0; i < _pcss.size(); i++)
|
}
|
||||||
if (_pcss.at(i).proj() == proj && _pcss.at(i).pcs().gcs() == gcs)
|
|
||||||
return _pcss.at(i).pcs();
|
|
||||||
|
|
||||||
return PCS();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCS::loadList(const QString &path)
|
void PCS::loadList(const QString &path)
|
||||||
{
|
{
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
bool res;
|
bool res;
|
||||||
int ln = 0, pn;
|
int ln = 0;
|
||||||
|
|
||||||
|
|
||||||
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),
|
||||||
@ -153,7 +40,7 @@ void PCS::loadList(const QString &path)
|
|||||||
|
|
||||||
QByteArray line = file.readLine(4096);
|
QByteArray line = file.readLine(4096);
|
||||||
QList<QByteArray> list = line.split(',');
|
QList<QByteArray> list = line.split(',');
|
||||||
if (list.size() != 28) {
|
if (list.size() != 4) {
|
||||||
qWarning("%s:%d: Format error", qPrintable(path), ln);
|
qWarning("%s:%d: Format error", qPrintable(path), ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -164,7 +51,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 gcsid = list.at(2).trimmed().toInt(&res);
|
int gcs = list.at(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;
|
||||||
@ -174,53 +61,13 @@ 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 units = list.at(4).trimmed().toInt(&res);
|
|
||||||
if (!res) {
|
|
||||||
qWarning("%s:%d: Invalid linear units code", qPrintable(path), ln);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int transform = list.at(5).trimmed().toInt(&res);
|
|
||||||
if (!res) {
|
|
||||||
qWarning("%s:%d: Invalid coordinate transformation code",
|
|
||||||
qPrintable(path), ln);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
int cs = list[6].trimmed().toInt(&res);
|
|
||||||
if (!res) {
|
|
||||||
qWarning("%s:%d: Invalid coordinate system code",
|
|
||||||
qPrintable(path), ln);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!LinearUnits(units).isValid()) {
|
if (GCS::gcs(gcs).isNull()) {
|
||||||
qWarning("%s:%d: Unknown linear units code", qPrintable(path), ln);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!Projection::Method(transform).isValid()) {
|
|
||||||
qWarning("%s:%d: Unknown coordinate transformation code",
|
|
||||||
qPrintable(path), ln);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!CoordinateSystem(cs).isValid()) {
|
|
||||||
qWarning("%s:%d: Unknown coordinate system code", qPrintable(path),
|
|
||||||
ln);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
GCS gcs(GCS::gcs(gcsid));
|
|
||||||
if (gcs.isNull()) {
|
|
||||||
qWarning("%s:%d: Unknown GCS code", qPrintable(path), ln);
|
qWarning("%s:%d: Unknown GCS code", qPrintable(path), ln);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Projection::Setup setup;
|
_pcss.insert(id, Entry(name, gcs, proj));
|
||||||
if ((pn = projectionSetup(list, setup))) {
|
|
||||||
qWarning("%s: %d: Invalid projection parameter #%d",
|
|
||||||
qPrintable(path), ln, pn);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PCS pcs(gcs, transform, setup, units, cs);
|
|
||||||
_pcss.append(Entry(name, id, proj, pcs));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,8 +75,9 @@ QList<KV<int, QString> > PCS::list()
|
|||||||
{
|
{
|
||||||
QList<KV<int, QString> > list;
|
QList<KV<int, QString> > list;
|
||||||
|
|
||||||
for (int i = 0; i < _pcss.size(); i++)
|
for (QMap<int, Entry>::const_iterator it = _pcss.constBegin();
|
||||||
list.append(KV<int, QString>(_pcss.at(i).id(), _pcss.at(i).name()));
|
it != _pcss.constEnd(); ++it)
|
||||||
|
list.append(KV<int, QString>(it.key(), it.value().name()));
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@ -237,8 +85,7 @@ QList<KV<int, QString> > PCS::list()
|
|||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
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.conversion() << ")";
|
||||||
<< pcs.units() << ", " << pcs.setup() << ")";
|
|
||||||
return dbg.space();
|
return dbg.space();
|
||||||
}
|
}
|
||||||
#endif // QT_NO_DEBUG
|
#endif // QT_NO_DEBUG
|
||||||
|
@ -2,56 +2,51 @@
|
|||||||
#define PCS_H
|
#define PCS_H
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QList>
|
#include <QMap>
|
||||||
#include "common/kv.h"
|
#include "common/kv.h"
|
||||||
#include "gcs.h"
|
#include "gcs.h"
|
||||||
#include "linearunits.h"
|
#include "linearunits.h"
|
||||||
#include "coordinatesystem.h"
|
#include "coordinatesystem.h"
|
||||||
#include "projection.h"
|
#include "conversion.h"
|
||||||
|
|
||||||
class PCS
|
class PCS
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PCS() {}
|
PCS() {}
|
||||||
PCS(const GCS &gcs, const Projection::Method &method,
|
PCS(const GCS &gcs, const Conversion &conversion)
|
||||||
const Projection::Setup &setup, const LinearUnits &units,
|
: _gcs(gcs), _conversion(conversion) {}
|
||||||
const CoordinateSystem &cs = CoordinateSystem())
|
|
||||||
: _gcs(gcs), _method(method), _setup(setup), _units(units), _cs(cs) {}
|
|
||||||
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 Conversion &conversion() const {return _conversion;}
|
||||||
const Projection::Setup &setup() const {return _setup;}
|
|
||||||
const LinearUnits &units() const {return _units;}
|
|
||||||
const CoordinateSystem &coordinateSystem() const {return _cs;}
|
|
||||||
|
|
||||||
bool isNull() const {
|
bool isNull() const {return (_gcs.isNull() && _conversion.isNull());}
|
||||||
return (_gcs.isNull() && _units.isNull() && _method.isNull()
|
bool isValid() const {return (_gcs.isValid() && _conversion.isValid());}
|
||||||
&& _setup.isNull() && _cs.isNull());
|
|
||||||
}
|
|
||||||
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.
|
|
||||||
return (_gcs.isValid() && _units.isValid() && _method.isValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void loadList(const QString &path);
|
static void loadList(const QString &path);
|
||||||
static PCS pcs(int id);
|
static PCS pcs(int id);
|
||||||
static PCS pcs(const GCS &gcs, int proj);
|
|
||||||
static QList<KV<int, QString> > list();
|
static QList<KV<int, QString> > list();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Entry;
|
class Entry {
|
||||||
|
public:
|
||||||
|
Entry(const QString &name, int gcs, int proj)
|
||||||
|
: _name(name), _gcs(gcs), _proj(proj) {}
|
||||||
|
|
||||||
static QList<Entry> defaults();
|
const QString &name() const {return _name;}
|
||||||
|
int proj() const {return _proj;}
|
||||||
|
int gcs() const {return _gcs;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString _name;
|
||||||
|
int _gcs, _proj;
|
||||||
|
};
|
||||||
|
|
||||||
|
static QMap<int, Entry> defaults();
|
||||||
|
|
||||||
GCS _gcs;
|
GCS _gcs;
|
||||||
Projection::Method _method;
|
Conversion _conversion;
|
||||||
Projection::Setup _setup;
|
|
||||||
LinearUnits _units;
|
|
||||||
CoordinateSystem _cs;
|
|
||||||
|
|
||||||
static QList<Entry> _pcss;
|
static QMap<int, Entry> _pcss;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
|
@ -537,7 +537,7 @@ void PRJFile::projectedCS(CTX &ctx, PCS *pcs)
|
|||||||
optProjectedCS(ctx, &epsg);
|
optProjectedCS(ctx, &epsg);
|
||||||
compare(ctx, RBRK);
|
compare(ctx, RBRK);
|
||||||
|
|
||||||
*pcs = (epsg > 0) ? PCS::pcs(epsg) : PCS(gcs, method, setup, lu);
|
*pcs = (epsg > 0) ? PCS::pcs(epsg) : PCS(gcs, Conversion(method, setup, lu));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PRJFile::axisType(CTX &ctx)
|
void PRJFile::axisType(CTX &ctx)
|
||||||
|
@ -39,13 +39,13 @@ Projection::Method::Method(int id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Projection::Projection(const PCS &pcs)
|
Projection::Projection(const PCS &pcs)
|
||||||
: _gcs(pcs.gcs()), _ct(0), _units(pcs.units()), _cs(pcs.coordinateSystem()),
|
: _gcs(pcs.gcs()), _ct(0), _units(pcs.conversion().units()),
|
||||||
_geographic(false)
|
_cs(pcs.conversion().cs()), _geographic(false)
|
||||||
{
|
{
|
||||||
const Ellipsoid &ellipsoid = _gcs.datum().ellipsoid();
|
const Ellipsoid &ellipsoid = _gcs.datum().ellipsoid();
|
||||||
const Projection::Setup &setup = pcs.setup();
|
const Projection::Setup &setup = pcs.conversion().setup();
|
||||||
|
|
||||||
switch (pcs.method().id()) {
|
switch (pcs.conversion().method().id()) {
|
||||||
case 1024:
|
case 1024:
|
||||||
_ct = new WebMercator();
|
_ct = new WebMercator();
|
||||||
break;
|
break;
|
||||||
|
@ -37,7 +37,7 @@ static CalibrationPoint parseCalibrationPoint(const QString &str)
|
|||||||
|
|
||||||
static Projection parseProjection(const QString &str, const GCS &gcs)
|
static Projection parseProjection(const QString &str, const GCS &gcs)
|
||||||
{
|
{
|
||||||
QStringList fields(str.split(","));
|
QStringList fields(str.split(','));
|
||||||
if (fields.isEmpty())
|
if (fields.isEmpty())
|
||||||
return Projection();
|
return Projection();
|
||||||
bool ret;
|
bool ret;
|
||||||
@ -55,40 +55,42 @@ static Projection parseProjection(const QString &str, const GCS &gcs)
|
|||||||
return Projection();
|
return Projection();
|
||||||
if (fields.at(3) == "S")
|
if (fields.at(3) == "S")
|
||||||
zone = -zone;
|
zone = -zone;
|
||||||
return Projection(PCS(gcs, 9807, UTM::setup(zone), 9001));
|
return Projection(PCS(gcs, Conversion(9807, UTM::setup(zone), 9001)));
|
||||||
case 1: // LatLon
|
case 1: // LatLon
|
||||||
return Projection(gcs);
|
return Projection(gcs);
|
||||||
case 2: // Mercator
|
case 2: // Mercator
|
||||||
return Projection(PCS(gcs, 1024, Projection::Setup(), 9001));
|
return Projection(PCS(gcs, Conversion(1024, Projection::Setup(),
|
||||||
|
9001)));
|
||||||
case 3: // Transversal Mercator
|
case 3: // Transversal Mercator
|
||||||
if (fields.size() < 7)
|
if (fields.size() < 7)
|
||||||
return Projection();
|
return Projection();
|
||||||
return Projection(PCS(gcs, 9807, Projection::Setup(
|
return Projection(PCS(gcs, Conversion(9807, Projection::Setup(
|
||||||
fields.at(3).toDouble(), fields.at(2).toDouble(),
|
fields.at(3).toDouble(), fields.at(2).toDouble(),
|
||||||
fields.at(6).toDouble(), fields.at(5).toDouble(),
|
fields.at(6).toDouble(), fields.at(5).toDouble(),
|
||||||
fields.at(4).toDouble(), NAN, NAN), 9001));
|
fields.at(4).toDouble(), NAN, NAN), 9001)));
|
||||||
case 4: // Lambert 2SP
|
case 4: // Lambert 2SP
|
||||||
if (fields.size() < 8)
|
if (fields.size() < 8)
|
||||||
return Projection();
|
return Projection();
|
||||||
return Projection(PCS(gcs, 9802, Projection::Setup(
|
return Projection(PCS(gcs, Conversion(9802, Projection::Setup(
|
||||||
fields.at(4).toDouble(), fields.at(5).toDouble(), NAN,
|
fields.at(4).toDouble(), fields.at(5).toDouble(), NAN,
|
||||||
fields.at(6).toDouble(), fields.at(7).toDouble(),
|
fields.at(6).toDouble(), fields.at(7).toDouble(),
|
||||||
fields.at(3).toDouble(), fields.at(2).toDouble()), 9001));
|
fields.at(3).toDouble(), fields.at(2).toDouble()), 9001)));
|
||||||
case 6: // BGN (British National Grid)
|
case 6: // BGN (British National Grid)
|
||||||
return Projection(PCS(gcs, 9807, Projection::Setup(49, -2, 0.999601,
|
return Projection(PCS(gcs, Conversion(9807, Projection::Setup(49,
|
||||||
400000, -100000, NAN, NAN), 9001));
|
-2, 0.999601, 400000, -100000, NAN, NAN), 9001)));
|
||||||
case 12: // France Lambert II etendu
|
case 12: // France Lambert II etendu
|
||||||
return Projection(PCS(gcs, 9801, Projection::Setup(52, 0,
|
return Projection(PCS(gcs, Conversion(9801, Projection::Setup(52, 0,
|
||||||
0.99987742, 600000, 2200000, NAN, NAN), 9001));
|
0.99987742, 600000, 2200000, NAN, NAN), 9001)));
|
||||||
case 14: // Swiss Grid
|
case 14: // Swiss Grid
|
||||||
return Projection(PCS(gcs, 9815, Projection::Setup(46.570866,
|
return Projection(PCS(gcs, Conversion(9815, Projection::Setup(
|
||||||
7.26225, 1.0, 600000, 200000, 90.0, 90.0), 9001));
|
46.570866, 7.26225, 1.0, 600000, 200000, 90.0, 90.0), 9001)));
|
||||||
case 108: // Dutch RD grid
|
case 108: // Dutch RD grid
|
||||||
return Projection(PCS(gcs, 9809, Projection::Setup(52.15616055555555,
|
return Projection(PCS(gcs, Conversion(9809, Projection::Setup(
|
||||||
5.38763888888889, 0.9999079, 155000, 463000, NAN, NAN), 9001));
|
52.15616055555555, 5.38763888888889, 0.9999079, 155000, 463000,
|
||||||
|
NAN, NAN), 9001)));
|
||||||
case 184: // Swedish Grid
|
case 184: // Swedish Grid
|
||||||
return Projection(PCS(gcs, 9807, Projection::Setup(0, 15.808278, 1,
|
return Projection(PCS(gcs, Conversion(9807, Projection::Setup(0,
|
||||||
1500000, 0, NAN, NAN), 9001));
|
15.808278, 1, 1500000, 0, NAN, NAN), 9001)));
|
||||||
default:
|
default:
|
||||||
return Projection();
|
return Projection();
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ void WorldFileMap::unload()
|
|||||||
|
|
||||||
void WorldFileMap::setInputProjection(const Projection &projection)
|
void WorldFileMap::setInputProjection(const Projection &projection)
|
||||||
{
|
{
|
||||||
if (_hasPRJ || projection == _projection)
|
if (_hasPRJ || !projection.isValid() || projection == _projection)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_projection = projection;
|
_projection = projection;
|
||||||
|
Loading…
Reference in New Issue
Block a user