1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-27 21:24:47 +01:00

Use the correct axis order defaults for WMS/WMTS maps

This commit is contained in:
Martin Tůma 2018-04-05 20:38:23 +02:00
parent 3aa1ab4b4c
commit 81b3a517f8
22 changed files with 2023 additions and 1906 deletions

View File

@ -122,7 +122,9 @@ HEADERS += src/config.h \
src/map/wmts.h \ src/map/wmts.h \
src/map/wmsmap.h \ src/map/wmsmap.h \
src/map/wms.h \ src/map/wms.h \
src/map/crs.h src/map/crs.h \
src/map/coordinatesystem.h \
src/map/axisorder.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 \
@ -214,7 +216,8 @@ SOURCES += src/main.cpp \
src/map/wmts.cpp \ src/map/wmts.cpp \
src/map/wmsmap.cpp \ src/map/wmsmap.cpp \
src/map/wms.cpp \ src/map/wms.cpp \
src/map/crs.cpp src/map/crs.cpp \
src/map/coordinatesystem.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 \

File diff suppressed because it is too large Load Diff

6
src/map/axisorder.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef AXISORDER_H
#define AXISORDER_H
enum AxisOrder {Unknown, XY, YX};
#endif // AXISORDER_H

View File

@ -0,0 +1,35 @@
#include "coordinatesystem.h"
CoordinateSystem::CoordinateSystem(int code)
{
switch (code) {
case 1024:
case 1035:
case 1039:
case 4400:
case 4409:
case 4463:
case 4464:
case 4465:
case 4466:
case 4467:
case 4469:
case 4470:
case 4495:
case 4496:
case 4497:
case 4498:
case 4499:
_axisOrder = XY;
break;
case 4500:
case 4530:
case 4531:
case 4532:
_axisOrder = YX;
break;
default:
_axisOrder = Unknown;
break;
}
}

View File

@ -0,0 +1,20 @@
#ifndef COORDINATESYSTEM_H
#define COORDINATESYSTEM_H
#include "axisorder.h"
class CoordinateSystem
{
public:
CoordinateSystem() : _axisOrder(Unknown) {}
CoordinateSystem(int code);
bool isValid() const {return (_axisOrder != Unknown);}
AxisOrder axisOrder() const {return _axisOrder;}
private:
AxisOrder _axisOrder;
};
#endif // COORDINATESYSTEM_H

View File

@ -30,15 +30,14 @@ Projection CRS::projection(const QString &crs)
return Projection(); return Projection();
if ((pcs = PCS::pcs(epsg))) if ((pcs = PCS::pcs(epsg)))
return Projection(pcs->gcs(), pcs->method(), pcs->setup(), return Projection(pcs);
pcs->units());
else if ((gcs = GCS::gcs(epsg))) else if ((gcs = GCS::gcs(epsg)))
return Projection(gcs); return Projection(gcs);
else else
return Projection(); return Projection();
} else if (authority == "OGC") { } else if (authority == "OGC") {
if (code == "CRS84") if (code == "CRS84")
return Projection(GCS::gcs(4326)); return Projection(GCS::gcs(4326), AxisOrder::XY);
else else
return Projection(); return Projection();
} else } else

View File

@ -92,62 +92,62 @@ void GCS::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() < 10) { if (list.size() < 10) {
qWarning("%s: %d: Format error", qPrintable(path), ln); qWarning("%s:%d: Format error", qPrintable(path), ln);
continue; continue;
} }
int id = parameter(list[1], &res); int id = parameter(list[1], &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;
} }
int gd = parameter(list[2], &res); int gd = parameter(list[2], &res);
if (!res) { if (!res) {
qWarning("%s: %d: Invalid geodetic datum code", qPrintable(path), qWarning("%s:%d: Invalid geodetic datum code", qPrintable(path),
ln); ln);
continue; continue;
} }
int au = list[3].trimmed().toInt(&res); int au = list[3].trimmed().toInt(&res);
if (!res) { if (!res) {
qWarning("%s: %d: Invalid angular units code", qPrintable(path), qWarning("%s:%d: Invalid angular units code", qPrintable(path),
ln); ln);
continue; continue;
} }
int el = list[4].trimmed().toInt(&res); int el = list[4].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;
} }
int pm = list[5].trimmed().toInt(&res); int pm = list[5].trimmed().toInt(&res);
if (!res) { if (!res) {
qWarning("%s: %d: Invalid prime meridian code", qPrintable(path), qWarning("%s:%d: Invalid prime meridian code", qPrintable(path),
ln); ln);
continue; continue;
} }
int ct = list[6].trimmed().toInt(&res); int ct = list[6].trimmed().toInt(&res);
if (!res) { if (!res) {
qWarning("%s: %d: Invalid coordinates transformation code", qWarning("%s:%d: Invalid coordinates transformation code",
qPrintable(path), ln); qPrintable(path), ln);
continue; continue;
} }
double dx = list[7].trimmed().toDouble(&res); double dx = list[7].trimmed().toDouble(&res);
if (!res) { if (!res) {
qWarning("%s: %d: Invalid dx", qPrintable(path), ln); qWarning("%s:%d: Invalid dx", qPrintable(path), ln);
continue; continue;
} }
double dy = list[8].trimmed().toDouble(&res); double dy = list[8].trimmed().toDouble(&res);
if (!res) { if (!res) {
qWarning("%s: %d: Invalid dy", qPrintable(path), ln); qWarning("%s:%d: Invalid dy", qPrintable(path), ln);
continue; continue;
} }
double dz = list[9].trimmed().toDouble(&res); double dz = list[9].trimmed().toDouble(&res);
if (!res) { if (!res) {
qWarning("%s: %d: Invalid dz", qPrintable(path), ln); qWarning("%s:%d: Invalid dz", qPrintable(path), ln);
continue; continue;
} }
if (!(e = Ellipsoid::ellipsoid(el))) { if (!(e = Ellipsoid::ellipsoid(el))) {
qWarning("%s: %d: Unknown ellipsoid code", qPrintable(path), ln); qWarning("%s:%d: Unknown ellipsoid code", qPrintable(path), ln);
continue; continue;
} }
@ -157,7 +157,7 @@ void GCS::loadList(const QString &path)
datum = Datum(e, dx, dy, dz); datum = Datum(e, dx, dy, dz);
break; break;
default: default:
qWarning("%s: %d: Unknown coordinates transformation method", qWarning("%s:%d: Unknown coordinates transformation method",
qPrintable(path), ln); qPrintable(path), ln);
continue; continue;
} }
@ -166,7 +166,7 @@ void GCS::loadList(const QString &path)
if (gcs.isValid()) if (gcs.isValid())
_gcss.append(Entry(id, gd, list[0].trimmed(), gcs)); _gcss.append(Entry(id, gd, list[0].trimmed(), gcs));
else else
qWarning("%s: %d: Unknown prime meridian/angular units code", qWarning("%s:%d: Unknown prime meridian/angular units code",
qPrintable(path), ln); qPrintable(path), ln);
} }
} }

View File

@ -353,8 +353,7 @@ bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
.arg(kv.value(ProjectedCSTypeGeoKey).SHORT); .arg(kv.value(ProjectedCSTypeGeoKey).SHORT);
return false; return false;
} }
_projection = Projection(pcs->gcs(), pcs->method(), pcs->setup(), _projection = Projection(pcs);
pcs->units());
} else if (IS_SET(kv, ProjectionGeoKey)) { } else if (IS_SET(kv, ProjectionGeoKey)) {
const GCS *g = gcs(kv); const GCS *g = gcs(kv);
if (!g) if (!g)
@ -366,8 +365,7 @@ bool GeoTIFF::projectedModel(QMap<quint16, Value> &kv)
.arg(kv.value(ProjectionGeoKey).SHORT); .arg(kv.value(ProjectionGeoKey).SHORT);
return false; return false;
} }
_projection = Projection(pcs->gcs(), pcs->method(), pcs->setup(), _projection = Projection(pcs);
pcs->units());
} else { } else {
double lat0, lon0, scale, fe, fn, sp1, sp2; double lat0, lon0, scale, fe, fn, sp1, sp2;
@ -430,8 +428,8 @@ 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);
PCS pcs(g, m, setup, lu, CoordinateSystem());
_projection = Projection(g, m, setup, lu); _projection = Projection(&pcs);
} }
return true; return true;

View File

@ -1,6 +1,7 @@
#include <QIODevice> #include <QIODevice>
#include "utm.h" #include "utm.h"
#include "gcs.h" #include "gcs.h"
#include "pcs.h"
#include "mapfile.h" #include "mapfile.h"
@ -163,18 +164,21 @@ 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, QList<CalibrationPoint> &points)
{ {
PCS pcs;
if (name == "Mercator") if (name == "Mercator")
_projection = Projection(gcs, 1024, setup, 9001); pcs = PCS(gcs, 1024, setup, 9001);
else if (name == "Transverse Mercator") else if (name == "Transverse Mercator")
_projection = Projection(gcs, 9807, setup, 9001); pcs = PCS(gcs, 9807, setup, 9001);
else if (name == "Latitude/Longitude") else if (name == "Latitude/Longitude") {
_projection = Projection(gcs); _projection = Projection(gcs);
else if (name == "Lambert Conformal Conic") return true;
_projection = Projection(gcs, 9802, setup, 9001); } else if (name == "Lambert Conformal Conic")
pcs = PCS(gcs, 9802, setup, 9001);
else if (name == "Albers Equal Area") else if (name == "Albers Equal Area")
_projection = Projection(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")
_projection = Projection(gcs, 9820, setup, 9001); pcs = PCS(gcs, 9820, setup, 9001);
else if (name == "(UTM) Universal Transverse Mercator") { else if (name == "(UTM) Universal Transverse Mercator") {
int zone; int zone;
if (points.first().zone) if (points.first().zone)
@ -185,45 +189,47 @@ bool MapFile::createProjection(const GCS *gcs, const QString &name,
_errorString = "Can not determine UTM zone"; _errorString = "Can not determine UTM zone";
return false; return false;
} }
_projection = Projection(gcs, 9807, UTM::setup(zone), 9001); pcs = PCS(gcs, 9807, UTM::setup(zone), 9001);
} else if (name == "(NZTM2) New Zealand TM 2000") } else if (name == "(NZTM2) New Zealand TM 2000")
_projection = Projection(gcs, 9807, Projection::Setup(0, 173.0, 0.9996, pcs = PCS(gcs, 9807, Projection::Setup(0, 173.0, 0.9996, 1600000,
1600000, 10000000, NAN, NAN), 9001); 10000000, NAN, NAN), 9001);
else if (name == "(BNG) British National Grid") else if (name == "(BNG) British National Grid")
_projection = Projection(gcs, 9807, Projection::Setup(49, -2, 0.999601, pcs = PCS(gcs, 9807, Projection::Setup(49, -2, 0.999601, 400000,
400000, -100000, NAN, NAN), 9001); -100000, NAN, NAN), 9001);
else if (name == "(IG) Irish Grid") else if (name == "(IG) Irish Grid")
_projection = Projection(gcs, 9807, Projection::Setup(53.5, -8, pcs = PCS(gcs, 9807, Projection::Setup(53.5, -8, 1.000035, 200000,
1.000035, 200000, 250000, NAN, NAN), 9001); 250000, NAN, NAN), 9001);
else if (name == "(SG) Swedish Grid") else if (name == "(SG) Swedish Grid")
_projection = Projection(gcs, 9807, Projection::Setup(0, 15.808278, 1, pcs = PCS(gcs, 9807, Projection::Setup(0, 15.808278, 1, 1500000, 0, NAN,
1500000, 0, NAN, NAN), 9001); NAN), 9001);
else if (name == "(I) France Zone I") else if (name == "(I) France Zone I")
_projection = Projection(gcs, 9802, Projection::Setup(49.5, 2.337229, pcs = PCS(gcs, 9802, Projection::Setup(49.5, 2.337229, NAN, 600000,
NAN, 600000, 1200000, 48.598523, 50.395912), 9001); 1200000, 48.598523, 50.395912), 9001);
else if (name == "(II) France Zone II") else if (name == "(II) France Zone II")
_projection = Projection(gcs, 9802, Projection::Setup(46.8, 2.337229, pcs = PCS(gcs, 9802, Projection::Setup(46.8, 2.337229, NAN, 600000,
NAN, 600000, 2200000, 45.898919, 47.696014), 9001); 2200000, 45.898919, 47.696014), 9001);
else if (name == "(III) France Zone III") else if (name == "(III) France Zone III")
_projection = Projection(gcs, 9802, Projection::Setup(44.1, 2.337229, pcs = PCS(gcs, 9802, Projection::Setup(44.1, 2.337229, NAN, 600000,
NAN, 600000, 3200000, 43.199291, 44.996094), 9001); 3200000, 43.199291, 44.996094), 9001);
else if (name == "(IV) France Zone IV") else if (name == "(IV) France Zone IV")
_projection = Projection(gcs, 9802, Projection::Setup(42.165, 2.337229, pcs = PCS(gcs, 9802, Projection::Setup(42.165, 2.337229, NAN, 234.358,
NAN, 234.358, 4185861.369, 41.560388, 42.767663), 9001); 4185861.369, 41.560388, 42.767663), 9001);
else if (name == "(VICGRID) Victoria Australia") else if (name == "(VICGRID) Victoria Australia")
_projection = Projection(gcs, 9802, Projection::Setup(-37, 145, NAN, pcs = PCS(gcs, 9802, Projection::Setup(-37, 145, NAN, 2500000, 4500000,
2500000, 4500000, -36, -38), 9001); -36, -38), 9001);
else if (name == "(VG94) VICGRID94 Victoria Australia") else if (name == "(VG94) VICGRID94 Victoria Australia")
_projection = Projection(gcs, 9802, Projection::Setup(-37, 145, NAN, pcs = PCS(gcs, 9802, Projection::Setup(-37, 145, NAN, 2500000, 2500000,
2500000, 2500000, -36, -38), 9001); -36, -38), 9001);
else if (name == "(SUI) Swiss Grid") else if (name == "(SUI) Swiss Grid")
_projection = Projection(gcs, 9815, Projection::Setup(46.570866, pcs = PCS(gcs, 9815, Projection::Setup(46.570866, 7.26225, 1.0, 600000,
7.26225, 1.0, 600000, 200000, 90.0, 90.0), 9001); 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;
} }
_projection = Projection(&pcs);
return true; return true;
} }

View File

@ -15,9 +15,20 @@
MapSource::Config::Config() : type(TMS), zooms(ZOOM_MIN, ZOOM_MAX), MapSource::Config::Config() : type(TMS), zooms(ZOOM_MIN, ZOOM_MAX),
bounds(Coordinates(BOUNDS_LEFT, BOUNDS_TOP), Coordinates(BOUNDS_RIGHT, bounds(Coordinates(BOUNDS_LEFT, BOUNDS_TOP), Coordinates(BOUNDS_RIGHT,
BOUNDS_BOTTOM)), format("image/png"), rest(false), yx(false) {} BOUNDS_BOTTOM)), format("image/png"), axisOrder(Unknown), rest(false) {}
static AxisOrder axisOrder(QXmlStreamReader &reader)
{
QXmlStreamAttributes attr = reader.attributes();
if (attr.value("axis") == "yx")
return AxisOrder::YX;
else if (attr.value("axis") == "xy")
return AxisOrder::XY;
else
return AxisOrder::Unknown;
}
Range MapSource::zooms(QXmlStreamReader &reader) Range MapSource::zooms(QXmlStreamReader &reader)
{ {
const QXmlStreamAttributes &attr = reader.attributes(); const QXmlStreamAttributes &attr = reader.attributes();
@ -123,15 +134,14 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
} else if (reader.name() == "bounds") { } else if (reader.name() == "bounds") {
config.bounds = bounds(reader); config.bounds = bounds(reader);
reader.skipCurrentElement(); reader.skipCurrentElement();
} else if (reader.name() == "format") { } else if (reader.name() == "format")
config.format = reader.readElementText(); config.format = reader.readElementText();
} else if (reader.name() == "layer") else if (reader.name() == "layer")
config.layer = reader.readElementText(); config.layer = reader.readElementText();
else if (reader.name() == "style") else if (reader.name() == "style")
config.style = reader.readElementText(); config.style = reader.readElementText();
else if (reader.name() == "set") { else if (reader.name() == "set") {
config.yx = (reader.attributes().value("axis") == "yx") config.axisOrder = axisOrder(reader);
? true : false;
config.set = reader.readElementText(); config.set = reader.readElementText();
} else if (reader.name() == "dimension") { } else if (reader.name() == "dimension") {
QXmlStreamAttributes attr = reader.attributes(); QXmlStreamAttributes attr = reader.attributes();
@ -141,8 +151,7 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
config.dimensions.append(QPair<QString, QString>( config.dimensions.append(QPair<QString, QString>(
attr.value("id").toString(), reader.readElementText())); attr.value("id").toString(), reader.readElementText()));
} else if (reader.name() == "crs") { } else if (reader.name() == "crs") {
config.yx = (reader.attributes().value("axis") == "yx") config.axisOrder = axisOrder(reader);
? true : false;
config.crs = reader.readElementText(); config.crs = reader.readElementText();
} else if (reader.name() == "authorization") { } else if (reader.name() == "authorization") {
QXmlStreamAttributes attr = reader.attributes(); QXmlStreamAttributes attr = reader.attributes();
@ -214,11 +223,11 @@ Map *MapSource::loadFile(const QString &path)
if (config.type == WMTS) if (config.type == WMTS)
m = new WMTSMap(config.name, WMTS::Setup(config.url, config.layer, m = new WMTSMap(config.name, WMTS::Setup(config.url, config.layer,
config.set, config.style, config.format, config.rest, config.yx, config.set, config.style, config.format, config.rest, config.axisOrder,
config.dimensions, config.authorization)); config.dimensions, config.authorization));
else if (config.type == WMS) else if (config.type == WMS)
m = new WMSMap(config.name, WMS::Setup(config.url, config.layer, m = new WMSMap(config.name, WMS::Setup(config.url, config.layer,
config.style, config.format, config.crs, config.yx, config.style, config.format, config.crs, config.axisOrder,
config.authorization)); config.authorization));
else else
m = new OnlineMap(config.name, config.url, config.zooms, config.bounds); m = new OnlineMap(config.name, config.url, config.zooms, config.bounds);

View File

@ -5,6 +5,7 @@
#include "common/range.h" #include "common/range.h"
#include "common/rectc.h" #include "common/rectc.h"
#include "downloader.h" #include "downloader.h"
#include "axisorder.h"
class Map; class Map;
class QXmlStreamReader; class QXmlStreamReader;
@ -33,8 +34,8 @@ private:
QString set; QString set;
QString format; QString format;
QString crs; QString crs;
AxisOrder axisOrder;
bool rest; bool rest;
bool yx;
QList<QPair<QString, QString> > dimensions; QList<QPair<QString, QString> > dimensions;
Authorization authorization; Authorization authorization;

View File

@ -81,7 +81,7 @@ static int projectionSetup(const QList<QByteArray> &list,
{ {
bool r1, r2, r3; bool r1, r2, r3;
for (int i = 6; i < 27; i += 3) { for (int i = 7; i < 28; i += 3) {
QString ks = list[i].trimmed(); QString ks = list[i].trimmed();
if (ks.isEmpty()) if (ks.isEmpty())
break; break;
@ -90,10 +90,10 @@ static int projectionSetup(const QList<QByteArray> &list,
double val = list[i+1].trimmed().toDouble(&r2); double val = list[i+1].trimmed().toDouble(&r2);
int un = list[i+2].trimmed().toInt(&r3); int un = list[i+2].trimmed().toInt(&r3);
if (!r1 || !r2 || !r3) if (!r1 || !r2 || !r3)
return (i - 6)/3 + 1; return (i - 7)/3 + 1;
if (!parameter(key, val, un, setup)) if (!parameter(key, val, un, setup))
return (i - 6)/3 + 1; return (i - 7)/3 + 1;
} }
return 0; return 0;
@ -136,49 +136,60 @@ 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() != 27) { if (list.size() != 28) {
qWarning("%s: %d: Format error", qPrintable(path), ln); qWarning("%s:%d: Format error", qPrintable(path), ln);
continue; continue;
} }
int id = list[1].trimmed().toInt(&res); int id = list[1].trimmed().toInt(&res);
if (!res) { if (!res) {
qWarning("%s: %d: Invalid PCS code", qPrintable(path), ln); qWarning("%s:%d: Invalid PCS code", qPrintable(path), ln);
continue; continue;
} }
int gcsid = 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;
} }
int proj = list[3].trimmed().toInt(&res); int proj = list[3].trimmed().toInt(&res);
if (!res) { if (!res) {
qWarning("%s: %d: Invalid projection code", qPrintable(path), ln); qWarning("%s:%d: Invalid projection code", qPrintable(path), ln);
continue; continue;
} }
int units = list[4].trimmed().toInt(&res); int units = list[4].trimmed().toInt(&res);
if (!res) { if (!res) {
qWarning("%s: %d: Invalid linear units code", qPrintable(path), ln); qWarning("%s:%d: Invalid linear units code", qPrintable(path), ln);
continue; continue;
} }
int transform = list[5].trimmed().toInt(&res); 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);
continue;
}
int cs = list[6].trimmed().toInt(&res);
if (!res) {
qWarning("%s:%d: Invalid coordinate system code",
qPrintable(path), ln); qPrintable(path), ln);
continue; continue;
} }
if (LinearUnits(units).isNull()) { if (!LinearUnits(units).isValid()) {
qWarning("%s: %d: Unknown linear units code", qPrintable(path), ln); qWarning("%s:%d: Unknown linear units code", qPrintable(path), ln);
continue; continue;
} }
if (Projection::Method(transform).isNull()) { if (!Projection::Method(transform).isValid()) {
qWarning("%s: %d: Unknown coordinate transformation code", qWarning("%s:%d: Unknown coordinate transformation code",
qPrintable(path), ln); qPrintable(path), ln);
continue; continue;
} }
if (!CoordinateSystem(cs).isValid()) {
qWarning("%s:%d: Unknown coordinate system code", qPrintable(path),
ln);
continue;
}
if (!(gcs = GCS::gcs(gcsid))) { if (!(gcs = GCS::gcs(gcsid))) {
qWarning("%s: %d: Unknown GCS code", qPrintable(path), ln); qWarning("%s:%d: Unknown GCS code", qPrintable(path), ln);
continue; continue;
} }
@ -189,7 +200,7 @@ void PCS::loadList(const QString &path)
continue; continue;
} }
PCS pcs(gcs, transform, setup, units); PCS pcs(gcs, transform, setup, units, cs);
_pcss.append(Entry(id, proj, pcs)); _pcss.append(Entry(id, proj, pcs));
} }
} }

View File

@ -5,6 +5,7 @@
#include <QList> #include <QList>
#include "gcs.h" #include "gcs.h"
#include "linearunits.h" #include "linearunits.h"
#include "coordinatesystem.h"
#include "projection.h" #include "projection.h"
class PCS class PCS
@ -12,18 +13,20 @@ class PCS
public: public:
PCS() : _gcs(0) {} PCS() : _gcs(0) {}
PCS(const GCS *gcs, const Projection::Method &method, PCS(const GCS *gcs, const Projection::Method &method,
const Projection::Setup &setup, const LinearUnits &units) const Projection::Setup &setup, const LinearUnits &units,
: _gcs(gcs), _method(method), _setup(setup), _units(units) {} const CoordinateSystem &cs = CoordinateSystem())
: _gcs(gcs), _method(method), _setup(setup), _units(units), _cs(cs) {}
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;} const LinearUnits &units() const {return _units;}
const CoordinateSystem &coordinateSystem() const {return _cs;}
bool isNull() const bool isNull() const
{return (_gcs->isNull() && _units.isNull() && _method.isNull() {return (_gcs->isNull() && _units.isNull() && _method.isNull()
&& _setup.isNull());} && _setup.isNull());}
bool isValid() const bool isValid() const
{return (_gcs->isValid() && _units.isValid() && _method.isValid());} {return (_gcs->isValid() && _units.isValid() && _method.isValid());}
@ -38,6 +41,7 @@ private:
Projection::Method _method; Projection::Method _method;
Projection::Setup _setup; Projection::Setup _setup;
LinearUnits _units; LinearUnits _units;
CoordinateSystem _cs;
static QList<Entry> _pcss; static QList<Entry> _pcss;
}; };

View File

@ -6,6 +6,7 @@
#include "lambertazimuthal.h" #include "lambertazimuthal.h"
#include "latlon.h" #include "latlon.h"
#include "gcs.h" #include "gcs.h"
#include "pcs.h"
#include "projection.h" #include "projection.h"
@ -27,12 +28,13 @@ Projection::Method::Method(int id)
} }
} }
Projection::Projection(const GCS *gcs, const Method &method, const Setup &setup, Projection::Projection(const PCS *pcs) : _gcs(pcs->gcs()), _units(pcs->units()),
const LinearUnits &units) : _gcs(gcs), _units(units), _geographic(false) _geographic(false)
{ {
const Ellipsoid *ellipsoid = _gcs->datum().ellipsoid(); const Ellipsoid *ellipsoid = _gcs->datum().ellipsoid();
const Projection::Setup &setup = pcs->setup();
switch (method.id()) { switch (pcs->method().id()) {
case 1024: case 1024:
case 9841: case 9841:
_ct = new Mercator(); _ct = new Mercator();
@ -68,9 +70,12 @@ Projection::Projection(const GCS *gcs, const Method &method, const Setup &setup,
default: default:
_ct = 0; _ct = 0;
} }
_axisOrder = pcs->coordinateSystem().axisOrder();
} }
Projection::Projection(const GCS *gcs) : _gcs(gcs), _geographic(true) Projection::Projection(const GCS *gcs, AxisOrder axisOrder)
: _gcs(gcs), _axisOrder(axisOrder), _geographic(true)
{ {
_ct = new LatLon(gcs->angularUnits()); _ct = new LatLon(gcs->angularUnits());
_units = LinearUnits(9001); _units = LinearUnits(9001);
@ -82,6 +87,7 @@ Projection::Projection(const Projection &p)
_units = p._units; _units = p._units;
_ct = p._ct ? p._ct->clone() : 0; _ct = p._ct ? p._ct->clone() : 0;
_geographic = p._geographic; _geographic = p._geographic;
_axisOrder = p._axisOrder;
} }
Projection::~Projection() Projection::~Projection()
@ -95,6 +101,7 @@ Projection &Projection::operator=(const Projection &p)
_units = p._units; _units = p._units;
_ct = p._ct ? p._ct->clone() : 0; _ct = p._ct ? p._ct->clone() : 0;
_geographic = p._geographic; _geographic = p._geographic;
_axisOrder = p._axisOrder;
return *this; return *this;
} }

View File

@ -5,8 +5,10 @@
#include <QDebug> #include <QDebug>
#include "common/coordinates.h" #include "common/coordinates.h"
#include "linearunits.h" #include "linearunits.h"
#include "axisorder.h"
class GCS; class GCS;
class PCS;
class CT; class CT;
class AngularUnits; class AngularUnits;
@ -70,9 +72,8 @@ public:
Projection() : _gcs(0), _ct(0), _geographic(false) {} Projection() : _gcs(0), _ct(0), _geographic(false) {}
Projection(const Projection &p); Projection(const Projection &p);
Projection(const GCS *gcs, const Method &method, const Setup &setup, Projection(const PCS *pcs);
const LinearUnits &units); Projection(const GCS *gcs, AxisOrder axisOrder = YX);
Projection(const GCS *gcs);
~Projection(); ~Projection();
Projection &operator=(const Projection &p); Projection &operator=(const Projection &p);
@ -85,11 +86,13 @@ public:
Coordinates xy2ll(const QPointF &p) const; Coordinates xy2ll(const QPointF &p) const;
const LinearUnits &units() const {return _units;} const LinearUnits &units() const {return _units;}
AxisOrder axisOrder() const {return _axisOrder;}
private: private:
const GCS *_gcs; const GCS *_gcs;
const CT *_ct; const CT *_ct;
LinearUnits _units; LinearUnits _units;
AxisOrder _axisOrder;
bool _geographic; bool _geographic;
}; };

View File

@ -7,6 +7,7 @@
#include "common/rectc.h" #include "common/rectc.h"
#include "projection.h" #include "projection.h"
#include "downloader.h" #include "downloader.h"
#include "axisorder.h"
class QXmlStreamReader; class QXmlStreamReader;
@ -17,10 +18,10 @@ public:
{ {
public: public:
Setup(const QString &url, const QString &layer, const QString &style, Setup(const QString &url, const QString &layer, const QString &style,
const QString &format, const QString &crs, bool yx, const QString &format, const QString &crs, AxisOrder axisOrder,
const Authorization &authorization = Authorization()) const Authorization &authorization = Authorization())
: _url(url), _layer(layer), _style(style), _format(format), _crs(crs), : _url(url), _layer(layer), _style(style), _format(format), _crs(crs),
_yx(yx), _authorization(authorization) {} _axisOrder(axisOrder), _authorization(authorization) {}
const QString &url() const {return _url;} const QString &url() const {return _url;}
const Authorization &authorization() const {return _authorization;} const Authorization &authorization() const {return _authorization;}
@ -28,7 +29,7 @@ public:
const QString &style() const {return _style;} const QString &style() const {return _style;}
const QString &format() const {return _format;} const QString &format() const {return _format;}
const QString &crs() const {return _crs;} const QString &crs() const {return _crs;}
bool yx() const {return _yx;} AxisOrder axisOrder() const {return _axisOrder;}
private: private:
QString _url; QString _url;
@ -36,7 +37,7 @@ public:
QString _style; QString _style;
QString _format; QString _format;
QString _crs; QString _crs;
bool _yx; AxisOrder _axisOrder;
Authorization _authorization; Authorization _authorization;
}; };

View File

@ -78,7 +78,6 @@ bool WMSMap::loadWMS()
return false; return false;
} }
_yx = (_setup.yx() && wms.version() >= "1.3.0") ? true : false;
_projection = wms.projection(); _projection = wms.projection();
RectC bb = wms.boundingBox().normalized(); RectC bb = wms.boundingBox().normalized();
_boundingBox = QRectF(_projection.ll2xy(Coordinates(bb.topLeft().lon(), _boundingBox = QRectF(_projection.ll2xy(Coordinates(bb.topLeft().lon(),
@ -87,6 +86,14 @@ bool WMSMap::loadWMS()
_tileLoader = TileLoader(tileUrl(wms.version()), tilesDir(), _tileLoader = TileLoader(tileUrl(wms.version()), tilesDir(),
_setup.authorization()); _setup.authorization());
if (wms.version() >= "1.3.0") {
if (_setup.axisOrder() == Unknown)
_axisOrder = _projection.axisOrder();
else
_axisOrder = _setup.axisOrder();
} else
_axisOrder = XY;
computeZooms(wms.scaleDenominator()); computeZooms(wms.scaleDenominator());
updateTransform(); updateTransform();
@ -94,8 +101,8 @@ bool WMSMap::loadWMS()
} }
WMSMap::WMSMap(const QString &name, const WMS::Setup &setup, QObject *parent) WMSMap::WMSMap(const QString &name, const WMS::Setup &setup, QObject *parent)
: Map(parent), _name(name), _setup(setup), _zoom(0), _block(false), : Map(parent), _name(name), _setup(setup), _zoom(0), _axisOrder(Unknown),
_valid(false) _block(false), _valid(false)
{ {
if (!QDir().mkpath(tilesDir())) { if (!QDir().mkpath(tilesDir())) {
_errorString = "Error creating tiles dir"; _errorString = "Error creating tiles dir";
@ -214,7 +221,7 @@ void WMSMap::draw(QPainter *painter, const QRectF &rect)
j * TILE_SIZE))); j * TILE_SIZE)));
QPointF tbr(_transform.img2proj(QPointF(i * TILE_SIZE + TILE_SIZE QPointF tbr(_transform.img2proj(QPointF(i * TILE_SIZE + TILE_SIZE
- 1, j * TILE_SIZE + TILE_SIZE - 1))); - 1, j * TILE_SIZE + TILE_SIZE - 1)));
QRectF bbox = _yx QRectF bbox = (_axisOrder == YX)
? QRectF(QPointF(tbr.y(), tbr.x()), QPointF(ttl.y(), ttl.x())) ? QRectF(QPointF(tbr.y(), tbr.x()), QPointF(ttl.y(), ttl.x()))
: QRectF(ttl, tbr); : QRectF(ttl, tbr);

View File

@ -64,7 +64,7 @@ private:
QVector<qreal> _zooms; QVector<qreal> _zooms;
int _zoom; int _zoom;
QRectF _boundingBox; QRectF _boundingBox;
bool _yx; AxisOrder _axisOrder;
bool _block; bool _block;
bool _valid; bool _valid;

View File

@ -14,7 +14,7 @@
Downloader *WMTS::_downloader = 0; Downloader *WMTS::_downloader = 0;
WMTS::TileMatrix WMTS::tileMatrix(QXmlStreamReader &reader, bool yx) WMTS::TileMatrix WMTS::tileMatrix(QXmlStreamReader &reader)
{ {
TileMatrix matrix; TileMatrix matrix;
@ -26,10 +26,7 @@ WMTS::TileMatrix WMTS::tileMatrix(QXmlStreamReader &reader, bool yx)
else if (reader.name() == "TopLeftCorner") { else if (reader.name() == "TopLeftCorner") {
QString str = reader.readElementText(); QString str = reader.readElementText();
QTextStream ts(&str); QTextStream ts(&str);
if (yx) ts >> matrix.topLeft.rx() >> matrix.topLeft.ry();
ts >> matrix.topLeft.ry() >> matrix.topLeft.rx();
else
ts >> matrix.topLeft.rx() >> matrix.topLeft.ry();
} else if (reader.name() == "TileWidth") } else if (reader.name() == "TileWidth")
matrix.tile.setWidth(reader.readElementText().toInt()); matrix.tile.setWidth(reader.readElementText().toInt());
else if (reader.name() == "TileHeight") else if (reader.name() == "TileHeight")
@ -59,7 +56,7 @@ void WMTS::tileMatrixSet(QXmlStreamReader &reader, CTX &ctx)
else if (reader.name() == "SupportedCRS") else if (reader.name() == "SupportedCRS")
crs = reader.readElementText(); crs = reader.readElementText();
else if (reader.name() == "TileMatrix") else if (reader.name() == "TileMatrix")
matrixes.insert(tileMatrix(reader, ctx.setup.yx())); matrixes.insert(tileMatrix(reader));
else else
reader.skipCurrentElement(); reader.skipCurrentElement();
} }

View File

@ -9,6 +9,7 @@
#include "common/rectc.h" #include "common/rectc.h"
#include "projection.h" #include "projection.h"
#include "downloader.h" #include "downloader.h"
#include "axisorder.h"
class QXmlStreamReader; class QXmlStreamReader;
@ -19,11 +20,11 @@ public:
{ {
public: public:
Setup(const QString &url, const QString &layer, const QString &set, Setup(const QString &url, const QString &layer, const QString &set,
const QString &style, const QString &format, bool rest, bool yx, const QString &style, const QString &format, bool rest,
const QList<QPair<QString, QString> > &dimensions, AxisOrder axisOrder, const QList<QPair<QString, QString> > &dimensions,
const Authorization &authorization = Authorization()) : const Authorization &authorization = Authorization()) :
_url(url), _layer(layer), _set(set), _style(style), _format(format), _url(url), _layer(layer), _set(set), _style(style), _format(format),
_rest(rest), _yx(yx), _dimensions(dimensions), _rest(rest), _axisOrder(axisOrder), _dimensions(dimensions),
_authorization(authorization) {} _authorization(authorization) {}
const QString &url() const {return _url;} const QString &url() const {return _url;}
@ -33,7 +34,7 @@ public:
const QString &style() const {return _style;} const QString &style() const {return _style;}
const QString &format() const {return _format;} const QString &format() const {return _format;}
bool rest() const {return _rest;} bool rest() const {return _rest;}
bool yx() const {return _yx;} AxisOrder axisOrder() const {return _axisOrder;}
const QList<QPair<QString, QString> > &dimensions() const const QList<QPair<QString, QString> > &dimensions() const
{return _dimensions;} {return _dimensions;}
@ -44,7 +45,7 @@ public:
QString _style; QString _style;
QString _format; QString _format;
bool _rest; bool _rest;
bool _yx; AxisOrder _axisOrder;
QList<QPair<QString, QString> > _dimensions; QList<QPair<QString, QString> > _dimensions;
Authorization _authorization; Authorization _authorization;
}; };
@ -131,7 +132,7 @@ private:
RectC wgs84BoundingBox(QXmlStreamReader &reader); RectC wgs84BoundingBox(QXmlStreamReader &reader);
MatrixLimits tileMatrixLimits(QXmlStreamReader &reader); MatrixLimits tileMatrixLimits(QXmlStreamReader &reader);
TileMatrix tileMatrix(QXmlStreamReader &reader, bool yx); TileMatrix tileMatrix(QXmlStreamReader &reader);
QSet<MatrixLimits> tileMatrixSetLimits(QXmlStreamReader &reader); QSet<MatrixLimits> tileMatrixSetLimits(QXmlStreamReader &reader);
QString style(QXmlStreamReader &reader); QString style(QXmlStreamReader &reader);
void tileMatrixSet(QXmlStreamReader &reader, CTX &ctx); void tileMatrixSet(QXmlStreamReader &reader, CTX &ctx);

View File

@ -26,14 +26,19 @@ bool WMTSMap::loadWMTS()
_tileLoader = TileLoader(wmts.tileUrl(), tilesDir(), _tileLoader = TileLoader(wmts.tileUrl(), tilesDir(),
_setup.authorization()); _setup.authorization());
if (_setup.axisOrder() == Unknown)
_axisOrder = _projection.axisOrder();
else
_axisOrder = _setup.axisOrder();
updateTransform(); updateTransform();
return true; return true;
} }
WMTSMap::WMTSMap(const QString &name, const WMTS::Setup &setup, QObject *parent) WMTSMap::WMTSMap(const QString &name, const WMTS::Setup &setup, QObject *parent)
: Map(parent), _name(name), _setup(setup), _zoom(0), _block(false), : Map(parent), _name(name), _setup(setup), _zoom(0), _axisOrder(Unknown),
_valid(false) _block(false), _valid(false)
{ {
if (!QDir().mkpath(tilesDir())) { if (!QDir().mkpath(tilesDir())) {
_errorString = "Error creating tiles dir"; _errorString = "Error creating tiles dir";
@ -67,15 +72,18 @@ void WMTSMap::updateTransform()
const WMTS::Zoom &z = _zooms.at(_zoom); const WMTS::Zoom &z = _zooms.at(_zoom);
ReferencePoint tl, br; ReferencePoint tl, br;
QPointF topLeft = (_axisOrder == YX)
? QPointF(z.topLeft().y(), z.topLeft().x()) : z.topLeft();
qreal pixelSpan = sd2res(z.scaleDenominator()); qreal pixelSpan = sd2res(z.scaleDenominator());
if (_projection.isGeographic()) if (_projection.isGeographic())
pixelSpan /= deg2rad(WGS84_RADIUS); pixelSpan /= deg2rad(WGS84_RADIUS);
QPointF tileSpan(z.tile().width() * pixelSpan, z.tile().height() * pixelSpan); QPointF tileSpan(z.tile().width() * pixelSpan, z.tile().height() * pixelSpan);
QPointF bottomRight(z.topLeft().x() + tileSpan.x() * z.matrix().width(), QPointF bottomRight(topLeft.x() + tileSpan.x() * z.matrix().width(),
z.topLeft().y() - tileSpan.y() * z.matrix().height()); topLeft.y() - tileSpan.y() * z.matrix().height());
tl.xy = QPoint(0, 0); tl.xy = QPoint(0, 0);
tl.pp = z.topLeft(); tl.pp = topLeft;
br.xy = QPoint(z.tile().width() * z.matrix().width(), br.xy = QPoint(z.tile().width() * z.matrix().width(),
z.tile().height() * z.matrix().height()); z.tile().height() * z.matrix().height());
br.pp = bottomRight; br.pp = bottomRight;

View File

@ -61,6 +61,7 @@ private:
Projection _projection; Projection _projection;
Transform _transform; Transform _transform;
int _zoom; int _zoom;
AxisOrder _axisOrder;
bool _block; bool _block;
bool _valid; bool _valid;