1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-10-06 06:43:22 +02: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/wmsmap.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 \
src/common/coordinates.cpp \
src/common/rectc.cpp \
@ -214,7 +216,8 @@ SOURCES += src/main.cpp \
src/map/wmts.cpp \
src/map/wmsmap.cpp \
src/map/wms.cpp \
src/map/crs.cpp
src/map/crs.cpp \
src/map/coordinatesystem.cpp
RESOURCES += gpxsee.qrc
TRANSLATIONS = lang/gpxsee_cs.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();
if ((pcs = PCS::pcs(epsg)))
return Projection(pcs->gcs(), pcs->method(), pcs->setup(),
pcs->units());
return Projection(pcs);
else if ((gcs = GCS::gcs(epsg)))
return Projection(gcs);
else
return Projection();
} else if (authority == "OGC") {
if (code == "CRS84")
return Projection(GCS::gcs(4326));
return Projection(GCS::gcs(4326), AxisOrder::XY);
else
return Projection();
} else

View File

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

View File

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

View File

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

View File

@ -15,9 +15,20 @@
MapSource::Config::Config() : type(TMS), zooms(ZOOM_MIN, ZOOM_MAX),
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)
{
const QXmlStreamAttributes &attr = reader.attributes();
@ -123,15 +134,14 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
} else if (reader.name() == "bounds") {
config.bounds = bounds(reader);
reader.skipCurrentElement();
} else if (reader.name() == "format") {
} else if (reader.name() == "format")
config.format = reader.readElementText();
} else if (reader.name() == "layer")
else if (reader.name() == "layer")
config.layer = reader.readElementText();
else if (reader.name() == "style")
config.style = reader.readElementText();
else if (reader.name() == "set") {
config.yx = (reader.attributes().value("axis") == "yx")
? true : false;
config.axisOrder = axisOrder(reader);
config.set = reader.readElementText();
} else if (reader.name() == "dimension") {
QXmlStreamAttributes attr = reader.attributes();
@ -141,8 +151,7 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
config.dimensions.append(QPair<QString, QString>(
attr.value("id").toString(), reader.readElementText()));
} else if (reader.name() == "crs") {
config.yx = (reader.attributes().value("axis") == "yx")
? true : false;
config.axisOrder = axisOrder(reader);
config.crs = reader.readElementText();
} else if (reader.name() == "authorization") {
QXmlStreamAttributes attr = reader.attributes();
@ -214,11 +223,11 @@ Map *MapSource::loadFile(const QString &path)
if (config.type == WMTS)
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));
else if (config.type == WMS)
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));
else
m = new OnlineMap(config.name, config.url, config.zooms, config.bounds);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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