2020-02-09 23:24:48 +01:00
|
|
|
#include <QXmlStreamReader>
|
|
|
|
#include <QDir>
|
|
|
|
#include "vectortile.h"
|
2021-04-10 15:27:40 +02:00
|
|
|
#include "gmapdata.h"
|
2020-02-09 23:24:48 +01:00
|
|
|
|
2021-04-10 15:27:40 +02:00
|
|
|
using namespace IMG;
|
2020-02-09 23:24:48 +01:00
|
|
|
|
|
|
|
static SubFile::Type tileType(const QString &suffix)
|
|
|
|
{
|
|
|
|
if (!suffix.compare("TRE"))
|
|
|
|
return SubFile::TRE;
|
|
|
|
else if (!suffix.compare("RGN"))
|
|
|
|
return SubFile::RGN;
|
|
|
|
else if (!suffix.compare("LBL"))
|
|
|
|
return SubFile::LBL;
|
|
|
|
else if (!suffix.compare("TYP"))
|
|
|
|
return SubFile::TYP;
|
|
|
|
else if (!suffix.compare("GMP"))
|
|
|
|
return SubFile::GMP;
|
|
|
|
else if (!suffix.compare("NET"))
|
|
|
|
return SubFile::NET;
|
|
|
|
else
|
|
|
|
return SubFile::Unknown;
|
|
|
|
}
|
|
|
|
|
2021-04-10 15:27:40 +02:00
|
|
|
void GMAPData::subProduct(QXmlStreamReader &reader, QString &dataDir,
|
2020-02-09 23:24:48 +01:00
|
|
|
QString &baseMap)
|
|
|
|
{
|
|
|
|
while (reader.readNextStartElement()) {
|
2020-12-22 22:09:09 +01:00
|
|
|
if (reader.name() == QLatin1String("Directory"))
|
2020-02-09 23:24:48 +01:00
|
|
|
dataDir = reader.readElementText();
|
2020-12-22 22:09:09 +01:00
|
|
|
else if (reader.name() == QLatin1String("BaseMap"))
|
2020-02-09 23:24:48 +01:00
|
|
|
baseMap = reader.readElementText();
|
|
|
|
else
|
|
|
|
reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-10 15:27:40 +02:00
|
|
|
void GMAPData::mapProduct(QXmlStreamReader &reader, QString &dataDir,
|
2020-02-09 23:24:48 +01:00
|
|
|
QString &typFile, QString &baseMap)
|
|
|
|
{
|
|
|
|
while (reader.readNextStartElement()) {
|
2020-12-22 22:09:09 +01:00
|
|
|
if (reader.name() == QLatin1String("Name"))
|
2020-02-09 23:24:48 +01:00
|
|
|
_name = reader.readElementText();
|
2020-12-22 22:09:09 +01:00
|
|
|
else if (reader.name() == QLatin1String("TYP"))
|
2020-02-09 23:24:48 +01:00
|
|
|
typFile = reader.readElementText();
|
2020-12-22 22:09:09 +01:00
|
|
|
else if (reader.name() == QLatin1String("SubProduct"))
|
2020-02-09 23:24:48 +01:00
|
|
|
subProduct(reader, dataDir, baseMap);
|
|
|
|
else
|
|
|
|
reader.skipCurrentElement();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-10 15:27:40 +02:00
|
|
|
bool GMAPData::readXML(const QString &path, QString &dataDir, QString &typFile,
|
2020-02-09 23:24:48 +01:00
|
|
|
QString &baseMap)
|
|
|
|
{
|
|
|
|
QFile file(path);
|
|
|
|
|
|
|
|
if (!file.open(QFile::ReadOnly | QFile::Text))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
QXmlStreamReader reader(&file);
|
|
|
|
if (reader.readNextStartElement()) {
|
2020-12-22 22:09:09 +01:00
|
|
|
if (reader.name() == QLatin1String("MapProduct"))
|
2020-02-09 23:24:48 +01:00
|
|
|
mapProduct(reader, dataDir, typFile, baseMap);
|
|
|
|
else
|
|
|
|
reader.raiseError("Not a GMAP XML file");
|
|
|
|
}
|
|
|
|
if (reader.error()) {
|
|
|
|
_errorString = QString("%1: %2").arg(reader.lineNumber())
|
|
|
|
.arg(reader.errorString());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-04-10 15:27:40 +02:00
|
|
|
bool GMAPData::loadTile(const QDir &dir, bool baseMap)
|
2020-02-09 23:24:48 +01:00
|
|
|
{
|
|
|
|
VectorTile *tile = new VectorTile();
|
|
|
|
|
|
|
|
QFileInfoList ml = dir.entryInfoList(QDir::Files);
|
|
|
|
for (int i = 0; i < ml.size(); i++) {
|
|
|
|
const QFileInfo &fi = ml.at(i);
|
2020-11-10 00:58:19 +01:00
|
|
|
SubFile::Type tt = tileType(fi.suffix());
|
|
|
|
if (VectorTile::isTileFile(tt)) {
|
|
|
|
_files.append(new QString(fi.absoluteFilePath()));
|
|
|
|
tile->addFile(_files.last(), tt);
|
|
|
|
}
|
2020-02-09 23:24:48 +01:00
|
|
|
}
|
|
|
|
|
2020-02-17 09:19:15 +01:00
|
|
|
if (!tile->init()) {
|
2020-02-09 23:24:48 +01:00
|
|
|
qWarning("%s: Invalid map tile", qPrintable(dir.path()));
|
|
|
|
delete tile;
|
|
|
|
return false;
|
|
|
|
}
|
2020-02-17 09:19:15 +01:00
|
|
|
if (baseMap)
|
|
|
|
tile->markAsBasemap();
|
2020-02-09 23:24:48 +01:00
|
|
|
|
|
|
|
double min[2], max[2];
|
|
|
|
min[0] = tile->bounds().left();
|
|
|
|
min[1] = tile->bounds().bottom();
|
|
|
|
max[0] = tile->bounds().right();
|
|
|
|
max[1] = tile->bounds().top();
|
|
|
|
_tileTree.Insert(min, max, tile);
|
|
|
|
|
|
|
|
_bounds |= tile->bounds();
|
2020-02-15 21:49:00 +01:00
|
|
|
if (tile->zooms().min() < _zooms.min())
|
|
|
|
_zooms.setMin(tile->zooms().min());
|
2020-02-09 23:24:48 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-04-10 15:27:40 +02:00
|
|
|
GMAPData::GMAPData(const QString &fileName) : _fileName(fileName)
|
2020-02-09 23:24:48 +01:00
|
|
|
{
|
2020-02-10 19:40:39 +01:00
|
|
|
QString dataDirPath, typFilePath, baseMapPath;
|
|
|
|
if (!readXML(fileName, dataDirPath, typFilePath, baseMapPath))
|
2020-02-09 23:24:48 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
QDir baseDir(QFileInfo(fileName).absoluteDir());
|
|
|
|
if (!baseDir.exists(dataDirPath)) {
|
|
|
|
_errorString = "Missing/invalid map data directory";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
QDir dataDir(baseDir.filePath(dataDirPath));
|
|
|
|
QFileInfoList ml = dataDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
|
|
|
|
2020-02-11 21:03:55 +01:00
|
|
|
|
|
|
|
QFileInfo baseMap(dataDir.filePath(baseMapPath));
|
|
|
|
_baseMap = !baseMapPath.isEmpty() && baseMap.exists();
|
|
|
|
|
2020-02-09 23:24:48 +01:00
|
|
|
for (int i = 0; i < ml.size(); i++) {
|
|
|
|
const QFileInfo &fi = ml.at(i);
|
2020-02-11 21:03:55 +01:00
|
|
|
if (fi.isDir())
|
|
|
|
loadTile(QDir(fi.absoluteFilePath()),
|
|
|
|
fi.absoluteFilePath() == baseMap.absoluteFilePath());
|
2020-02-09 23:24:48 +01:00
|
|
|
}
|
|
|
|
|
2020-11-10 00:58:19 +01:00
|
|
|
if (baseDir.exists(typFilePath)) {
|
|
|
|
_files.append(new QString(baseDir.filePath(typFilePath)));
|
|
|
|
_typ = new SubFile(_files.last());
|
|
|
|
}
|
2020-02-09 23:24:48 +01:00
|
|
|
|
|
|
|
if (!_tileTree.Count())
|
|
|
|
_errorString = "No usable map tile found";
|
|
|
|
else
|
|
|
|
_valid = true;
|
|
|
|
}
|
|
|
|
|
2021-04-10 15:27:40 +02:00
|
|
|
GMAPData::~GMAPData()
|
2020-11-10 00:58:19 +01:00
|
|
|
{
|
|
|
|
qDeleteAll(_files);
|
|
|
|
}
|
|
|
|
|
2021-04-10 15:27:40 +02:00
|
|
|
bool GMAPData::isGMAP(const QString &path)
|
2020-02-09 23:24:48 +01:00
|
|
|
{
|
|
|
|
QFile file(path);
|
|
|
|
|
|
|
|
if (!file.open(QFile::ReadOnly | QFile::Text))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
QXmlStreamReader reader(&file);
|
2020-12-22 22:09:09 +01:00
|
|
|
if (reader.readNextStartElement()
|
|
|
|
&& reader.name() == QLatin1String("MapProduct"))
|
2020-02-09 23:24:48 +01:00
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|