9#include "GeoSceneTileDataset.h"
10#include "GeoSceneEquirectTileProjection.h"
11#include "GeoSceneMercatorTileProjection.h"
12#include "GeoSceneTypes.h"
14#include "DownloadPolicy.h"
15#include "MarbleDebug.h"
16#include "MarbleDirs.h"
17#include "ServerLayout.h"
26GeoSceneTileDataset::GeoSceneTileDataset(
const QString &name)
27 : GeoSceneAbstractDataset(
name)
30 , m_storageLayoutMode(
Marble)
31 , m_serverLayout(new MarbleServerLayout(this))
32 , m_levelZeroColumns(defaultLevelZeroColumns)
33 , m_levelZeroRows(defaultLevelZeroRows)
34 , m_minimumTileLevel(0)
35 , m_maximumTileLevel(-1)
36 , m_tileProjection(new GeoSceneEquirectTileProjection())
39 , m_nextUrl(m_downloadUrls.constEnd())
41 m_tileProjection->setLevelZeroColumns(m_levelZeroColumns);
42 m_tileProjection->setLevelZeroRows(m_levelZeroRows);
45GeoSceneTileDataset::~GeoSceneTileDataset()
47 qDeleteAll(m_downloadPolicies);
48 delete m_serverLayout;
49 delete m_tileProjection;
52const char *GeoSceneTileDataset::nodeType()
const
54 return GeoSceneTypes::GeoSceneTileDatasetType;
57QString GeoSceneTileDataset::sourceDir()
const
62void GeoSceneTileDataset::setSourceDir(
const QString &sourceDir)
64 m_sourceDir = sourceDir;
67QString GeoSceneTileDataset::installMap()
const
72void GeoSceneTileDataset::setInstallMap(
const QString &installMap)
74 m_installMap = installMap;
77GeoSceneTileDataset::StorageLayout GeoSceneTileDataset::storageLayout()
const
79 return m_storageLayoutMode;
82void GeoSceneTileDataset::setStorageLayout(
const StorageLayout layout)
84 m_storageLayoutMode = layout;
87void GeoSceneTileDataset::setServerLayout(
const ServerLayout *layout)
89 delete m_serverLayout;
90 m_serverLayout = layout;
93const ServerLayout *GeoSceneTileDataset::serverLayout()
const
95 return m_serverLayout;
98int GeoSceneTileDataset::levelZeroColumns()
const
100 return m_levelZeroColumns;
103void GeoSceneTileDataset::setLevelZeroColumns(
const int columns)
105 m_levelZeroColumns = columns;
106 m_tileProjection->setLevelZeroColumns(m_levelZeroColumns);
109int GeoSceneTileDataset::levelZeroRows()
const
111 return m_levelZeroRows;
114void GeoSceneTileDataset::setLevelZeroRows(
const int rows)
116 m_levelZeroRows = rows;
117 m_tileProjection->setLevelZeroRows(m_levelZeroRows);
120int GeoSceneTileDataset::maximumTileLevel()
const
122 return m_maximumTileLevel;
125void GeoSceneTileDataset::setMaximumTileLevel(
const int maximumTileLevel)
127 m_maximumTileLevel = maximumTileLevel;
130int GeoSceneTileDataset::minimumTileLevel()
const
132 return m_minimumTileLevel;
135void GeoSceneTileDataset::setMinimumTileLevel(
int level)
137 m_minimumTileLevel =
level;
140void GeoSceneTileDataset::setTileLevels(
const QString &tileLevels)
143 m_tileLevels.clear();
148 for (
const QString &value : values) {
149 bool canParse(
false);
150 int const tileLevel = value.trimmed().toInt(&canParse);
151 if (canParse && tileLevel >= 0 && tileLevel < 100) {
152 m_tileLevels << tileLevel;
154 mDebug() <<
"Cannot parse tile level part " << value <<
" in " << tileLevels <<
", ignoring it.";
158 if (!m_tileLevels.isEmpty()) {
159 std::sort(m_tileLevels.begin(), m_tileLevels.end());
160 m_minimumTileLevel = m_tileLevels.first();
161 m_maximumTileLevel = m_tileLevels.last();
165QList<int> GeoSceneTileDataset::tileLevels()
const
170QList<QUrl> GeoSceneTileDataset::downloadUrls()
const
172 return m_downloadUrls;
175const QSize GeoSceneTileDataset::tileSize()
const
177 if (m_tileSize.isEmpty()) {
178 const TileId id(0, 0, 0, 0);
179 QString const fileName = relativeTileFileName(
id);
181 QString const path = dirInfo.isAbsolute() ? fileName : MarbleDirs::path(fileName);
185 if (testTile.isNull()) {
186 mDebug() <<
"Tile size is missing in dgml and no base tile found in " << themeStr();
187 mDebug() <<
"Using default tile size " << c_defaultTileSize;
188 m_tileSize =
QSize(c_defaultTileSize, c_defaultTileSize);
190 m_tileSize = testTile.size();
193 if (m_tileSize.isEmpty()) {
194 mDebug() <<
"Tile width or height cannot be 0. Falling back to default tile size.";
195 m_tileSize =
QSize(c_defaultTileSize, c_defaultTileSize);
199 Q_ASSERT(!m_tileSize.isEmpty());
203GeoDataLatLonBox GeoSceneTileDataset::latLonBox()
const
208void GeoSceneTileDataset::setLatLonBox(
const GeoDataLatLonBox &box)
213void GeoSceneTileDataset::setTileSize(
const QSize &tileSize)
216 mDebug() <<
"Ignoring invalid tile size " << tileSize;
218 m_tileSize = tileSize;
222void GeoSceneTileDataset::setTileProjection(GeoSceneAbstractTileProjection::Type projectionType)
224 if (m_tileProjection->type() == projectionType) {
228 delete m_tileProjection;
229 if (projectionType == GeoSceneAbstractTileProjection::Mercator) {
230 m_tileProjection =
new GeoSceneMercatorTileProjection();
232 m_tileProjection =
new GeoSceneEquirectTileProjection();
235 m_tileProjection->setLevelZeroColumns(m_levelZeroColumns);
236 m_tileProjection->setLevelZeroRows(m_levelZeroRows);
239const GeoSceneAbstractTileProjection *GeoSceneTileDataset::tileProjection()
const
241 return m_tileProjection;
244GeoSceneAbstractTileProjection::Type GeoSceneTileDataset::tileProjectionType()
const
246 return m_tileProjection->type();
251QUrl GeoSceneTileDataset::downloadUrl(
const TileId &
id)
const
254 if (m_downloadUrls.empty()) {
256 mDebug() <<
"No download URL specified for tiles stored in " << m_sourceDir <<
", falling back to " << defaultUrl.
toString();
257 return m_serverLayout->downloadUrl(defaultUrl,
id);
258 }
else if (m_downloadUrls.size() == 1) {
259 return m_serverLayout->downloadUrl(*m_nextUrl,
id);
261 if (m_nextUrl == m_downloadUrls.constEnd()) {
262 m_nextUrl = m_downloadUrls.constBegin();
264 const QUrl url = m_serverLayout->downloadUrl(*m_nextUrl,
id);
270void GeoSceneTileDataset::addDownloadUrl(
const QUrl &url)
272 m_downloadUrls.append(url);
274 m_nextUrl = m_downloadUrls.constBegin();
277QString GeoSceneTileDataset::relativeTileFileName(
const TileId &
id)
const
283 switch (m_storageLayoutMode) {
284 case GeoSceneTileDataset::Marble:
285 relFileName = QStringLiteral(
"%1/%2/%3/%3_%4.%5")
292 case GeoSceneTileDataset::OpenStreetMap:
293 relFileName = QStringLiteral(
"%1/%2/%3/%4.%5").
arg(themeStr()).
arg(
id.zoomLevel()).
arg(
id.x()).
arg(
id.y()).
arg(suffix);
295 case GeoSceneTileDataset::TileMapService:
296 relFileName = QStringLiteral(
"%1/%2/%3/%4.%5")
300 .
arg((1 <<
id.zoomLevel()) -
id.y() - 1)
308QString GeoSceneTileDataset::themeStr()
const
311 return dirInfo.isAbsolute() ? sourceDir() :
QLatin1StringView(
"maps/") + sourceDir();
316 return m_downloadPolicies;
319void GeoSceneTileDataset::addDownloadPolicy(
const DownloadUsage usage,
const int maximumConnections)
321 auto const policy =
new DownloadPolicy(DownloadPolicyKey(hostNames(), usage));
322 policy->setMaximumConnections(maximumConnections);
323 m_downloadPolicies.append(policy);
324 mDebug() <<
"added download policy" << hostNames() << usage << maximumConnections;
330 result.
reserve(m_downloadUrls.size());
334 for (; pos !=
end; ++pos)
335 result.
append((*pos).host());
QString path(const QString &relativePath)
QStringView level(QStringView ifopt)
QString name(StandardAction id)
const QList< QKeySequence > & end()
Binds a QML item to a specific geodetic location in screen coordinates.
void append(QList< T > &&value)
void reserve(qsizetype size)
bool isEmpty() const const
QString arg(Args &&... args) const const
bool isEmpty() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QString toLower() const const
QString toString(FormattingOptions options) const const