mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 03:35:53 +01:00
Switched to XML defined online map sources
This commit is contained in:
parent
8a7edcfd8d
commit
aa07b20aa4
@ -40,7 +40,7 @@ build_script:
|
|||||||
|
|
||||||
copy pkg\pcs.csv installer
|
copy pkg\pcs.csv installer
|
||||||
|
|
||||||
copy pkg\maps.txt installer
|
copy pkg\maps.xml installer
|
||||||
|
|
||||||
copy licence.txt installer
|
copy licence.txt installer
|
||||||
|
|
||||||
|
@ -115,7 +115,8 @@ HEADERS += src/config.h \
|
|||||||
src/map/angularunits.h \
|
src/map/angularunits.h \
|
||||||
src/map/primemeridian.h \
|
src/map/primemeridian.h \
|
||||||
src/map/linearunits.h \
|
src/map/linearunits.h \
|
||||||
src/map/ct.h
|
src/map/ct.h \
|
||||||
|
src/map/omd.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 \
|
||||||
@ -200,7 +201,8 @@ SOURCES += src/main.cpp \
|
|||||||
src/map/gcs.cpp \
|
src/map/gcs.cpp \
|
||||||
src/map/angularunits.cpp \
|
src/map/angularunits.cpp \
|
||||||
src/map/primemeridian.cpp \
|
src/map/primemeridian.cpp \
|
||||||
src/map/linearunits.cpp
|
src/map/linearunits.cpp \
|
||||||
|
src/map/omd.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 \
|
||||||
@ -216,7 +218,7 @@ macx {
|
|||||||
icons/fit.icns \
|
icons/fit.icns \
|
||||||
icons/igc.icns \
|
icons/igc.icns \
|
||||||
icons/nmea.icns \
|
icons/nmea.icns \
|
||||||
pkg/maps.txt \
|
pkg/maps.xml \
|
||||||
pkg/ellipsoids.csv \
|
pkg/ellipsoids.csv \
|
||||||
pkg/gcs.csv \
|
pkg/gcs.csv \
|
||||||
pkg/pcs.csv
|
pkg/pcs.csv
|
||||||
|
@ -83,7 +83,7 @@ Section "GPXSee" SEC_APP
|
|||||||
|
|
||||||
; Put the files there
|
; Put the files there
|
||||||
File "gpxsee.exe"
|
File "gpxsee.exe"
|
||||||
File "maps.txt"
|
File "maps.xml"
|
||||||
File "ellipsoids.csv"
|
File "ellipsoids.csv"
|
||||||
File "gcs.csv"
|
File "gcs.csv"
|
||||||
File "pcs.csv"
|
File "pcs.csv"
|
||||||
|
@ -90,7 +90,7 @@ Section "GPXSee" SEC_APP
|
|||||||
|
|
||||||
; Put the files there
|
; Put the files there
|
||||||
File "gpxsee.exe"
|
File "gpxsee.exe"
|
||||||
File "maps.txt"
|
File "maps.xml"
|
||||||
File "ellipsoids.csv"
|
File "ellipsoids.csv"
|
||||||
File "gcs.csv"
|
File "gcs.csv"
|
||||||
File "pcs.csv"
|
File "pcs.csv"
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
Open Topo Map https://a.tile.opentopomap.org/$z/$x/$y.png 17
|
|
||||||
4UMaps http://4umaps.eu/$z/$x/$y.png 15
|
|
||||||
Open Street Map http://tile.openstreetmap.org/$z/$x/$y.png 19
|
|
||||||
USGS Topo https://navigator.er.usgs.gov/tiles/tcr.cgi/$z/$x/$y.png 15
|
|
||||||
USGS Imagery https://navigator.er.usgs.gov/tiles/aerial_Imagery.cgi/$z/$x/$y 15
|
|
28
pkg/maps.xml
Normal file
28
pkg/maps.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<omd>
|
||||||
|
<map>
|
||||||
|
<name>Open Topo Map</name>
|
||||||
|
<url>https://a.tile.opentopomap.org/$z/$x/$y.png</url>
|
||||||
|
<zoom max="17"/>
|
||||||
|
</map>
|
||||||
|
<map>
|
||||||
|
<name>4UMaps</name>
|
||||||
|
<url>http://4umaps.eu/$z/$x/$y.png</url>
|
||||||
|
<zoom min="2" max="15"/>
|
||||||
|
<bounds bottom="-65"/>
|
||||||
|
</map>
|
||||||
|
<map>
|
||||||
|
<name>Open Street Map</name>
|
||||||
|
<url>http://tile.openstreetmap.org/$z/$x/$y.png</url>
|
||||||
|
</map>
|
||||||
|
<map>
|
||||||
|
<name>USGS Topo</name>
|
||||||
|
<url>https://navigator.er.usgs.gov/tiles/tcr.cgi/$z/$x/$y.png</url>
|
||||||
|
<zoom min="2" max="15"/>
|
||||||
|
</map>
|
||||||
|
<map>
|
||||||
|
<name>USGS Imagery</name>
|
||||||
|
<url>https://navigator.er.usgs.gov/tiles/aerial_Imagery.cgi/$z/$x/$y</url>
|
||||||
|
<zoom min="2" max="15"/>
|
||||||
|
</map>
|
||||||
|
</omd>
|
@ -108,13 +108,8 @@ void GUI::loadMaps()
|
|||||||
else if (QFile::exists(GLOBAL_MAP_DIR))
|
else if (QFile::exists(GLOBAL_MAP_DIR))
|
||||||
offline = GLOBAL_MAP_DIR;
|
offline = GLOBAL_MAP_DIR;
|
||||||
|
|
||||||
if (!offline.isNull()) {
|
if (!offline.isNull() && !_ml->loadDir(offline))
|
||||||
if (!_ml->loadDir(offline)) {
|
qWarning(qPrintable(_ml->errorString()));
|
||||||
qWarning("Error reading map dir: %s",
|
|
||||||
qPrintable(_ml->errorString()));
|
|
||||||
_ml->clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_map = new EmptyMap(this);
|
_map = new EmptyMap(this);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#define ELLIPSOID_FILE QString("ellipsoids.csv")
|
#define ELLIPSOID_FILE QString("ellipsoids.csv")
|
||||||
#define GCS_FILE QString("gcs.csv")
|
#define GCS_FILE QString("gcs.csv")
|
||||||
#define PCS_FILE QString("pcs.csv")
|
#define PCS_FILE QString("pcs.csv")
|
||||||
#define MAP_FILE QString("maps.txt")
|
|
||||||
#define MAP_DIR QString("maps")
|
#define MAP_DIR QString("maps")
|
||||||
#define POI_DIR QString("POI")
|
#define POI_DIR QString("POI")
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ int MapFile::parse(QIODevice &device, QList<CalibrationPoint> &points,
|
|||||||
ln++;
|
ln++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return (ln == 1) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
|
bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
|
||||||
@ -136,13 +136,13 @@ bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
|
|||||||
int el;
|
int el;
|
||||||
|
|
||||||
if (!device.open(QIODevice::ReadOnly)) {
|
if (!device.open(QIODevice::ReadOnly)) {
|
||||||
_errorString = QString("Error opening map file: %1")
|
_errorString = QString("Error opening file: %1")
|
||||||
.arg(device.errorString());
|
.arg(device.errorString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((el = parse(device, points, projection, setup, datum))) {
|
if ((el = parse(device, points, projection, setup, datum))) {
|
||||||
_errorString = QString("Map file parse error on line %1").arg(el);
|
_errorString = QString("Parse error on line %1").arg(el);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,70 +4,30 @@
|
|||||||
#include "atlas.h"
|
#include "atlas.h"
|
||||||
#include "offlinemap.h"
|
#include "offlinemap.h"
|
||||||
#include "onlinemap.h"
|
#include "onlinemap.h"
|
||||||
|
#include "omd.h"
|
||||||
#include "maplist.h"
|
#include "maplist.h"
|
||||||
|
|
||||||
|
|
||||||
#define ZOOM_MAX 18
|
bool MapList::loadList(const QString &path, bool dir)
|
||||||
#define ZOOM_MIN 2
|
|
||||||
|
|
||||||
Map *MapList::loadListEntry(const QByteArray &line)
|
|
||||||
{
|
{
|
||||||
int max;
|
OMD omd;
|
||||||
|
|
||||||
QList<QByteArray> list = line.split('\t');
|
if (!omd.loadFile(path)) {
|
||||||
if (list.size() < 2)
|
if (dir)
|
||||||
return 0;
|
_errorString += path + ": " + omd.errorString() + "\n";
|
||||||
|
else
|
||||||
QByteArray ba1 = list.at(0).trimmed();
|
_errorString = omd.errorString();
|
||||||
QByteArray ba2 = list.at(1).trimmed();
|
|
||||||
if (ba1.isEmpty() || ba2.isEmpty())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (list.size() == 3) {
|
|
||||||
bool ok;
|
|
||||||
max = QString(list.at(2).trimmed()).toInt(&ok);
|
|
||||||
if (!ok)
|
|
||||||
return 0;
|
|
||||||
} else
|
|
||||||
max = ZOOM_MAX;
|
|
||||||
|
|
||||||
return new OnlineMap(QString::fromUtf8(ba1.data(), ba1.size()),
|
|
||||||
QString::fromLatin1(ba2.data(), ba2.size()), Range(ZOOM_MIN, max), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MapList::loadList(const QString &path)
|
|
||||||
{
|
|
||||||
QFile file(path);
|
|
||||||
QList<Map*> maps;
|
|
||||||
|
|
||||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
|
||||||
_errorString = file.errorString();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ln = 0;
|
_maps += omd.maps();
|
||||||
while (!file.atEnd()) {
|
for (int i = 0; i < omd.maps().size(); i++)
|
||||||
ln++;
|
omd.maps()[i]->setParent(this);
|
||||||
QByteArray line = file.readLine();
|
|
||||||
Map *map = loadListEntry(line);
|
|
||||||
|
|
||||||
if (map)
|
|
||||||
maps.append(map);
|
|
||||||
else {
|
|
||||||
for (int i = 0; i < maps.count(); i++)
|
|
||||||
delete maps.at(i);
|
|
||||||
_errorString = QString("Invalid map list entry on line %1.")
|
|
||||||
.arg(QString::number(ln));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_maps += maps;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapList::loadMap(const QString &path)
|
bool MapList::loadMap(const QString &path, bool dir)
|
||||||
{
|
{
|
||||||
OfflineMap *map = new OfflineMap(path, this);
|
OfflineMap *map = new OfflineMap(path, this);
|
||||||
|
|
||||||
@ -75,13 +35,16 @@ bool MapList::loadMap(const QString &path)
|
|||||||
_maps.append(map);
|
_maps.append(map);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
_errorString = map->errorString();
|
if (dir)
|
||||||
|
_errorString += path + ": " + map->errorString() + "\n";
|
||||||
|
else
|
||||||
|
_errorString = map->errorString();
|
||||||
delete map;
|
delete map;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapList::loadAtlas(const QString &path)
|
bool MapList::loadAtlas(const QString &path, bool dir)
|
||||||
{
|
{
|
||||||
Atlas *atlas = new Atlas(path, this);
|
Atlas *atlas = new Atlas(path, this);
|
||||||
|
|
||||||
@ -89,39 +52,45 @@ bool MapList::loadAtlas(const QString &path)
|
|||||||
_maps.append(atlas);
|
_maps.append(atlas);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
_errorString = atlas->errorString();
|
if (dir)
|
||||||
|
_errorString += path + ": " + atlas->errorString() + "\n";
|
||||||
|
else
|
||||||
|
_errorString = atlas->errorString();
|
||||||
delete atlas;
|
delete atlas;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapList::loadFile(const QString &path, bool *atlas)
|
bool MapList::loadFile(const QString &path, bool *atlas, bool dir)
|
||||||
{
|
{
|
||||||
QFileInfo fi(path);
|
QFileInfo fi(path);
|
||||||
QString suffix = fi.suffix().toLower();
|
QString suffix = fi.suffix().toLower();
|
||||||
|
|
||||||
if (Atlas::isAtlas(path)) {
|
if (Atlas::isAtlas(path)) {
|
||||||
if (atlas)
|
*atlas = true;
|
||||||
*atlas = true;
|
return loadAtlas(path, dir);
|
||||||
return loadAtlas(path);
|
} else if (suffix == "xml") {
|
||||||
} else if (suffix == "txt") {
|
*atlas = false;
|
||||||
if (atlas)
|
return loadList(path, dir);
|
||||||
*atlas = false;
|
|
||||||
return loadList(path);
|
|
||||||
} else {
|
} else {
|
||||||
if (atlas)
|
*atlas = false;
|
||||||
*atlas = false;
|
return loadMap(path, dir);
|
||||||
return loadMap(path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MapList::loadFile(const QString &path)
|
||||||
|
{
|
||||||
|
bool atlas;
|
||||||
|
return loadFile(path, &atlas, false);
|
||||||
|
}
|
||||||
|
|
||||||
bool MapList::loadDir(const QString &path)
|
bool MapList::loadDir(const QString &path)
|
||||||
{
|
{
|
||||||
QDir md(path);
|
QDir md(path);
|
||||||
md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
md.setSorting(QDir::DirsLast);
|
md.setSorting(QDir::DirsLast);
|
||||||
QFileInfoList ml = md.entryInfoList();
|
QFileInfoList ml = md.entryInfoList();
|
||||||
bool atlas;
|
bool atlas, ret = true;
|
||||||
|
|
||||||
for (int i = 0; i < ml.size(); i++) {
|
for (int i = 0; i < ml.size(); i++) {
|
||||||
const QFileInfo &fi = ml.at(i);
|
const QFileInfo &fi = ml.at(i);
|
||||||
@ -129,19 +98,16 @@ bool MapList::loadDir(const QString &path)
|
|||||||
|
|
||||||
if (fi.isDir() && fi.fileName() != "set") {
|
if (fi.isDir() && fi.fileName() != "set") {
|
||||||
if (!loadDir(fi.absoluteFilePath()))
|
if (!loadDir(fi.absoluteFilePath()))
|
||||||
return false;
|
ret = false;
|
||||||
} else if (filter().contains("*." + suffix)) {
|
} else if (filter().contains("*." + suffix)) {
|
||||||
if (!loadFile(fi.absoluteFilePath(), &atlas)) {
|
if (!loadFile(fi.absoluteFilePath(), &atlas, true))
|
||||||
_errorString.prepend(QString("%1: ")
|
ret = false;
|
||||||
.arg(fi.canonicalFilePath()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (atlas)
|
if (atlas)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapList::clear()
|
void MapList::clear()
|
||||||
@ -153,14 +119,16 @@ void MapList::clear()
|
|||||||
|
|
||||||
QString MapList::formats()
|
QString MapList::formats()
|
||||||
{
|
{
|
||||||
return tr("Supported files (*.txt *.map *.tba *.tar *.tif *.tiff)") + ";;"
|
return tr("Supported files (*.map *.tar *.tba *.tif *.tiff *.xml)") + ";;"
|
||||||
+ tr("Offline maps (*.map *.tba *.tar *.tif *.tiff)") + ";;"
|
+ tr("OziExplorer maps (*.map)") + ";;"
|
||||||
+ tr("Online map lists (*.txt)");
|
+ tr("TrekBuddy maps/atlases (*.tar *.tba)") + ";;"
|
||||||
|
+ tr("GeoTIFF images (*.tif *.tiff)") + ";;"
|
||||||
|
+ tr("Online map definitions (*.xml)");
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList MapList::filter()
|
QStringList MapList::filter()
|
||||||
{
|
{
|
||||||
QStringList filter;
|
QStringList filter;
|
||||||
filter << "*.map" << "*.tba" << "*.tar" << "*.txt" << "*.tif" << "*.tiff";
|
filter << "*.map" << "*.tba" << "*.tar" << "*.xml" << "*.tif" << "*.tiff";
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ class MapList : public QObject
|
|||||||
public:
|
public:
|
||||||
MapList(QObject *parent = 0) : QObject(parent) {}
|
MapList(QObject *parent = 0) : QObject(parent) {}
|
||||||
|
|
||||||
bool loadFile(const QString &path, bool *atlas = 0);
|
bool loadFile(const QString &path);
|
||||||
bool loadDir(const QString &path);
|
bool loadDir(const QString &path);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
@ -25,11 +25,13 @@ public:
|
|||||||
static QStringList filter();
|
static QStringList filter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool loadFile(const QString &path, bool *atlas, bool dir);
|
||||||
|
|
||||||
Map *loadListEntry(const QByteArray &line);
|
Map *loadListEntry(const QByteArray &line);
|
||||||
|
|
||||||
bool loadList(const QString &path);
|
bool loadList(const QString &path, bool dir);
|
||||||
bool loadMap(const QString &path);
|
bool loadMap(const QString &path, bool dir);
|
||||||
bool loadAtlas(const QString &path);
|
bool loadAtlas(const QString &path, bool dir);
|
||||||
|
|
||||||
QList<Map*> _maps;
|
QList<Map*> _maps;
|
||||||
QString _errorString;
|
QString _errorString;
|
||||||
|
190
src/map/omd.cpp
Normal file
190
src/map/omd.cpp
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
#include <QFile>
|
||||||
|
#include <QXmlStreamReader>
|
||||||
|
#include "onlinemap.h"
|
||||||
|
#include "omd.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define ZOOM_MAX 19
|
||||||
|
#define ZOOM_MIN 0
|
||||||
|
#define BOUNDS_LEFT -180
|
||||||
|
#define BOUNDS_TOP 85.0511
|
||||||
|
#define BOUNDS_RIGHT 180
|
||||||
|
#define BOUNDS_BOTTOM -85.0511
|
||||||
|
|
||||||
|
Range OMD::zooms(QXmlStreamReader &reader)
|
||||||
|
{
|
||||||
|
const QXmlStreamAttributes &attr = reader.attributes();
|
||||||
|
int min, max;
|
||||||
|
bool res;
|
||||||
|
|
||||||
|
if (attr.hasAttribute("min")) {
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||||
|
min = attr.value("min").toString().toInt(&res);
|
||||||
|
#else // QT_VERSION < 5
|
||||||
|
min = attr.value("min").toInt(&res);
|
||||||
|
#endif // QT_VERSION < 5
|
||||||
|
if (!res || (min < ZOOM_MIN || min > ZOOM_MAX)) {
|
||||||
|
reader.raiseError("Invalid minimal zoom level");
|
||||||
|
return Range();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
min = ZOOM_MIN;
|
||||||
|
|
||||||
|
if (attr.hasAttribute("max")) {
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||||
|
max = attr.value("max").toString().toInt(&res);
|
||||||
|
#else // QT_VERSION < 5
|
||||||
|
max = attr.value("max").toInt(&res);
|
||||||
|
#endif // QT_VERSION < 5
|
||||||
|
if (!res || (max < ZOOM_MIN || max > ZOOM_MAX)) {
|
||||||
|
reader.raiseError("Invalid maximal zoom level");
|
||||||
|
return Range();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
max = ZOOM_MAX;
|
||||||
|
|
||||||
|
if (min > max || max < min) {
|
||||||
|
reader.raiseError("Invalid maximal/minimal zoom level combination");
|
||||||
|
return Range();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Range(min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
RectC OMD::bounds(QXmlStreamReader &reader)
|
||||||
|
{
|
||||||
|
const QXmlStreamAttributes &attr = reader.attributes();
|
||||||
|
double top, left, bottom, right;
|
||||||
|
bool res;
|
||||||
|
|
||||||
|
if (attr.hasAttribute("top")) {
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||||
|
top = attr.value("top").toString().toDouble(&res);
|
||||||
|
#else // QT_VERSION < 5
|
||||||
|
top = attr.value("top").toDouble(&res);
|
||||||
|
#endif // QT_VERSION < 5
|
||||||
|
if (!res || (top < BOUNDS_BOTTOM || top > BOUNDS_TOP)) {
|
||||||
|
reader.raiseError("Invalid bounds top value");
|
||||||
|
return RectC();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
top = BOUNDS_TOP;
|
||||||
|
|
||||||
|
if (attr.hasAttribute("bottom")) {
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||||
|
bottom = attr.value("bottom").toString().toDouble(&res);
|
||||||
|
#else // QT_VERSION < 5
|
||||||
|
bottom = attr.value("bottom").toDouble(&res);
|
||||||
|
#endif // QT_VERSION < 5
|
||||||
|
if (!res || (bottom < BOUNDS_BOTTOM || bottom > BOUNDS_TOP)) {
|
||||||
|
reader.raiseError("Invalid bounds bottom value");
|
||||||
|
return RectC();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
bottom = BOUNDS_BOTTOM;
|
||||||
|
|
||||||
|
if (attr.hasAttribute("left")) {
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||||
|
left = attr.value("left").toString().toDouble(&res);
|
||||||
|
#else // QT_VERSION < 5
|
||||||
|
left = attr.value("left").toDouble(&res);
|
||||||
|
#endif // QT_VERSION < 5
|
||||||
|
if (!res || (left < BOUNDS_LEFT || left > BOUNDS_RIGHT)) {
|
||||||
|
reader.raiseError("Invalid bounds left value");
|
||||||
|
return RectC();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
left = BOUNDS_LEFT;
|
||||||
|
|
||||||
|
if (attr.hasAttribute("right")) {
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
|
||||||
|
right = attr.value("right").toString().toDouble(&res);
|
||||||
|
#else // QT_VERSION < 5
|
||||||
|
right = attr.value("right").toDouble(&res);
|
||||||
|
#endif // QT_VERSION < 5
|
||||||
|
if (!res || (right < BOUNDS_LEFT || right > BOUNDS_RIGHT)) {
|
||||||
|
reader.raiseError("Invalid bounds right value");
|
||||||
|
return RectC();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
right = BOUNDS_RIGHT;
|
||||||
|
|
||||||
|
if (bottom > top || top < bottom) {
|
||||||
|
reader.raiseError("Invalid bottom/top bounds combination");
|
||||||
|
return RectC();
|
||||||
|
}
|
||||||
|
if (left > right || right < left) {
|
||||||
|
reader.raiseError("Invalid left/right bounds combination");
|
||||||
|
return RectC();
|
||||||
|
}
|
||||||
|
|
||||||
|
return RectC(Coordinates(left, top), Coordinates(right, bottom));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OMD::map(QXmlStreamReader &reader)
|
||||||
|
{
|
||||||
|
QString name, url;
|
||||||
|
Range z(ZOOM_MIN, ZOOM_MAX);
|
||||||
|
RectC b(Coordinates(BOUNDS_LEFT, BOUNDS_TOP),
|
||||||
|
Coordinates(BOUNDS_RIGHT, BOUNDS_BOTTOM));
|
||||||
|
|
||||||
|
while (reader.readNextStartElement()) {
|
||||||
|
if (reader.name() == "name")
|
||||||
|
name = reader.readElementText();
|
||||||
|
else if (reader.name() == "url")
|
||||||
|
url = reader.readElementText();
|
||||||
|
else if (reader.name() == "zoom") {
|
||||||
|
z = zooms(reader);
|
||||||
|
reader.skipCurrentElement();
|
||||||
|
} else if (reader.name() == "bounds") {
|
||||||
|
b = bounds(reader);
|
||||||
|
reader.skipCurrentElement();
|
||||||
|
} else
|
||||||
|
reader.skipCurrentElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
_maps.append(new OnlineMap(name, url, z, b));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OMD::omd(QXmlStreamReader &reader)
|
||||||
|
{
|
||||||
|
while (reader.readNextStartElement()) {
|
||||||
|
if (reader.name() == "map")
|
||||||
|
map(reader);
|
||||||
|
else
|
||||||
|
reader.skipCurrentElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OMD::loadFile(const QString &path)
|
||||||
|
{
|
||||||
|
QFile file(path);
|
||||||
|
QXmlStreamReader reader;
|
||||||
|
|
||||||
|
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
|
_errorString = file.errorString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.setDevice(&file);
|
||||||
|
|
||||||
|
if (reader.readNextStartElement()) {
|
||||||
|
if (reader.name() == "omd")
|
||||||
|
omd(reader);
|
||||||
|
else
|
||||||
|
reader.raiseError("Not an online map definitions file");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reader.error())
|
||||||
|
_errorString = QString("%1: %2").arg(reader.lineNumber())
|
||||||
|
.arg(reader.errorString());
|
||||||
|
|
||||||
|
return !reader.error();
|
||||||
|
}
|
||||||
|
|
||||||
|
OMD::~OMD()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < _maps.size(); i++)
|
||||||
|
if (!_maps.at(i)->parent())
|
||||||
|
delete _maps.at(i);
|
||||||
|
}
|
31
src/map/omd.h
Normal file
31
src/map/omd.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef OMD_H
|
||||||
|
#define OMD_H
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include "common/range.h"
|
||||||
|
#include "common/rectc.h"
|
||||||
|
|
||||||
|
class Map;
|
||||||
|
class QXmlStreamReader;
|
||||||
|
|
||||||
|
class OMD
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~OMD();
|
||||||
|
|
||||||
|
bool loadFile(const QString &path);
|
||||||
|
const QString &errorString() const {return _errorString;}
|
||||||
|
|
||||||
|
const QList<Map*> &maps() const {return _maps;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RectC bounds(QXmlStreamReader &reader);
|
||||||
|
Range zooms(QXmlStreamReader &reader);
|
||||||
|
void map(QXmlStreamReader &reader);
|
||||||
|
void omd(QXmlStreamReader &reader);
|
||||||
|
|
||||||
|
QString _errorString;
|
||||||
|
QList<Map*> _maps;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // OMD_H
|
@ -46,13 +46,11 @@ static bool loadTileFile(Tile &tile, const QString &file)
|
|||||||
Downloader *OnlineMap::downloader;
|
Downloader *OnlineMap::downloader;
|
||||||
|
|
||||||
OnlineMap::OnlineMap(const QString &name, const QString &url,
|
OnlineMap::OnlineMap(const QString &name, const QString &url,
|
||||||
const Range &zooms, QObject *parent) : Map(parent)
|
const Range &zooms, const RectC &bounds, QObject *parent)
|
||||||
|
: Map(parent), _name(name), _url(url), _zooms(zooms), _bounds(bounds)
|
||||||
{
|
{
|
||||||
_name = name;
|
|
||||||
_url = url;
|
|
||||||
_block = false;
|
_block = false;
|
||||||
_zooms = zooms;
|
_zoom = _zooms.max();
|
||||||
_zoom = zooms.max();
|
|
||||||
|
|
||||||
QString path = TILES_DIR + QString("/") + name;
|
QString path = TILES_DIR + QString("/") + name;
|
||||||
if (!QDir().mkpath(path))
|
if (!QDir().mkpath(path))
|
||||||
@ -167,7 +165,7 @@ void OnlineMap::clearCache()
|
|||||||
|
|
||||||
QRectF OnlineMap::bounds() const
|
QRectF OnlineMap::bounds() const
|
||||||
{
|
{
|
||||||
return QRectF(ll2xy(Coordinates(-180, 85)), ll2xy(Coordinates(180, -85)));
|
return QRectF(ll2xy(_bounds.topLeft()), ll2xy(_bounds.bottomRight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int OnlineMap::limitZoom(int zoom) const
|
int OnlineMap::limitZoom(int zoom) const
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "common/coordinates.h"
|
#include "common/coordinates.h"
|
||||||
#include "common/range.h"
|
#include "common/range.h"
|
||||||
|
#include "common/rectc.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ class OnlineMap : public Map
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
OnlineMap(const QString &name, const QString &url, const Range &zooms,
|
OnlineMap(const QString &name, const QString &url, const Range &zooms,
|
||||||
QObject *parent = 0);
|
const RectC &bounds, QObject *parent = 0);
|
||||||
|
|
||||||
const QString &name() const {return _name;}
|
const QString &name() const {return _name;}
|
||||||
|
|
||||||
@ -57,10 +58,11 @@ private:
|
|||||||
void loadTilesSync(QList<Tile> &list);
|
void loadTilesSync(QList<Tile> &list);
|
||||||
int limitZoom(int zoom) const;
|
int limitZoom(int zoom) const;
|
||||||
|
|
||||||
Range _zooms;
|
|
||||||
int _zoom;
|
|
||||||
QString _name;
|
QString _name;
|
||||||
QString _url;
|
QString _url;
|
||||||
|
Range _zooms;
|
||||||
|
RectC _bounds;
|
||||||
|
int _zoom;
|
||||||
bool _block;
|
bool _block;
|
||||||
|
|
||||||
static Downloader *downloader;
|
static Downloader *downloader;
|
||||||
|
Loading…
Reference in New Issue
Block a user