2 #include "common/rectc.h"
3 #include "common/wgs84.h"
6 #include "tileloader.h"
11 #define CAPABILITIES_FILE "capabilities.xml"
13 bool WMTSMap::loadWMTS()
15 QString file
= tilesDir() + "/" + CAPABILITIES_FILE
;
17 WMTS
wmts(file
, _setup
);
18 if (!wmts
.isValid()) {
19 _errorString
= wmts
.errorString();
23 _bounds
= wmts
.bounds();
24 _zooms
= wmts
.zooms();
25 _projection
= wmts
.projection();
26 _tileLoader
->setUrl(wmts
.tileUrl());
28 if (_setup
.coordinateSystem().axisOrder() == CoordinateSystem::Unknown
)
29 _cs
= _projection
.coordinateSystem();
31 _cs
= _setup
.coordinateSystem();
38 WMTSMap::WMTSMap(const QString
&name
, const WMTS::Setup
&setup
, QObject
*parent
)
39 : Map(parent
), _name(name
), _setup(setup
), _zoom(0), _valid(false)
41 if (!QDir().mkpath(tilesDir())) {
42 _errorString
= "Error creating tiles dir";
46 _tileLoader
= new TileLoader(this);
47 _tileLoader
->setDir(tilesDir());
48 _tileLoader
->setAuthorization(_setup
.authorization());
49 connect(_tileLoader
, SIGNAL(finished()), this, SIGNAL(loaded()));
54 void WMTSMap::clearCache()
56 _tileLoader
->clearCache();
60 qWarning("%s: %s\n", qPrintable(_name
), qPrintable(_errorString
));
63 QString
WMTSMap::tilesDir() const
65 return QString(TILES_DIR
+ "/" + _name
);
68 double WMTSMap::sd2res(double scaleDenominator
) const
70 return scaleDenominator
* 0.28e-3 * _projection
.units().fromMeters(1.0);
73 void WMTSMap::updateTransform()
75 const WMTS::Zoom
&z
= _zooms
.at(_zoom
);
77 PointD topLeft
= (_cs
.axisOrder() == CoordinateSystem::YX
)
78 ? PointD(z
.topLeft().y(), z
.topLeft().x()) : z
.topLeft();
80 double pixelSpan
= sd2res(z
.scaleDenominator());
81 if (_projection
.isGeographic())
82 pixelSpan
/= deg2rad(WGS84_RADIUS
);
83 PointD
tileSpan(z
.tile().width() * pixelSpan
, z
.tile().height() * pixelSpan
);
84 PointD
bottomRight(topLeft
.x() + tileSpan
.x() * z
.matrix().width(),
85 topLeft
.y() - tileSpan
.y() * z
.matrix().height());
87 ReferencePoint
tl(PointD(0, 0), topLeft
);
88 ReferencePoint
br(PointD(z
.tile().width() * z
.matrix().width(),
89 z
.tile().height() * z
.matrix().height()), bottomRight
);
90 _transform
= Transform(tl
, br
);
93 QRectF
WMTSMap::bounds() const
95 const WMTS::Zoom
&z
= _zooms
.at(_zoom
);
96 QRectF tileBounds
, bounds
;
98 tileBounds
= (z
.limits().isNull()) ?
99 QRectF(QPointF(0, 0), QSize(z
.tile().width() * z
.matrix().width(),
100 z
.tile().height() * z
.matrix().height()))
101 : QRectF(QPointF(z
.limits().left() * z
.tile().width(), z
.limits().top()
102 * z
.tile().height()), QSize(z
.tile().width() * z
.limits().width(),
103 z
.tile().height() * z
.limits().height()));
105 bounds
= _bounds
.isValid() ? QRectF(ll2xy(_bounds
.topLeft()),
106 ll2xy(_bounds
.bottomRight())) : QRectF();
108 return _bounds
.isValid() ? tileBounds
.intersected(bounds
) : tileBounds
;
111 int WMTSMap::zoomFit(const QSize
&size
, const RectC
&rect
)
113 if (rect
.isValid()) {
114 PointD
tl(_projection
.ll2xy(rect
.topLeft()));
115 PointD
br(_projection
.ll2xy(rect
.bottomRight()));
116 PointD
sc((br
.x() - tl
.x()) / size
.width(), (tl
.y() - br
.y())
118 double resolution
= qMax(qAbs(sc
.x()), qAbs(sc
.y()));
119 if (_projection
.isGeographic())
120 resolution
*= deg2rad(WGS84_RADIUS
);
123 for (int i
= 0; i
< _zooms
.size(); i
++) {
124 if (sd2res(_zooms
.at(i
).scaleDenominator()) < resolution
)
129 _zoom
= _zooms
.size() - 1;
135 void WMTSMap::setZoom(int zoom
)
141 int WMTSMap::zoomIn()
143 _zoom
= qMin(_zoom
+ 1, _zooms
.size() - 1);
148 int WMTSMap::zoomOut()
150 _zoom
= qMax(_zoom
- 1, 0);
155 void WMTSMap::draw(QPainter
*painter
, const QRectF
&rect
, bool block
)
157 const WMTS::Zoom
&z
= _zooms
.at(_zoom
);
158 QPoint tl
= QPoint((int)floor(rect
.left() / (qreal
)z
.tile().width()),
159 (int)floor(rect
.top() / (qreal
)z
.tile().height()));
160 QPoint br
= QPoint((int)ceil(rect
.right() / (qreal
)z
.tile().width()),
161 (int)ceil(rect
.bottom() / (qreal
)z
.tile().height()));
164 for (int i
= tl
.x(); i
< br
.x(); i
++)
165 for (int j
= tl
.y(); j
< br
.y(); j
++)
166 tiles
.append(Tile(QPoint(i
, j
), z
.id()));
169 _tileLoader
->loadTilesSync(tiles
);
171 _tileLoader
->loadTilesAsync(tiles
);
173 for (int i
= 0; i
< tiles
.count(); i
++) {
175 QPoint
tp(t
.xy().x() * z
.tile().width(), t
.xy().y() * z
.tile().height());
176 if (!t
.pixmap().isNull())
177 painter
->drawPixmap(tp
, t
.pixmap());
181 QPointF
WMTSMap::ll2xy(const Coordinates
&c
) const
183 return _transform
.proj2img(_projection
.ll2xy(c
));
186 Coordinates
WMTSMap::xy2ll(const QPointF
&p
) const
188 return _projection
.xy2ll(_transform
.img2proj(p
));