mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-27 21:24:47 +01:00
Added support for KMZ maps
This commit is contained in:
parent
97bea8c56c
commit
d01a5a7e42
@ -7,6 +7,7 @@ VERSION = 8.0
|
||||
|
||||
QT += core \
|
||||
gui \
|
||||
gui-private \
|
||||
network \
|
||||
sql \
|
||||
concurrent \
|
||||
@ -101,6 +102,7 @@ HEADERS += src/common/config.h \
|
||||
src/map/IMG/textpointitem.h \
|
||||
src/map/bsbmap.h \
|
||||
src/map/invalidmap.h \
|
||||
src/map/kmzmap.h \
|
||||
src/map/polyconic.h \
|
||||
src/map/projection.h \
|
||||
src/map/ellipsoid.h \
|
||||
@ -276,6 +278,7 @@ SOURCES += src/main.cpp \
|
||||
src/map/IMG/textpathitem.cpp \
|
||||
src/map/IMG/textpointitem.cpp \
|
||||
src/map/bsbmap.cpp \
|
||||
src/map/kmzmap.cpp \
|
||||
src/map/maplist.cpp \
|
||||
src/map/onlinemap.cpp \
|
||||
src/map/downloader.cpp \
|
||||
|
449
src/map/kmzmap.cpp
Normal file
449
src/map/kmzmap.cpp
Normal file
@ -0,0 +1,449 @@
|
||||
/*
|
||||
WARNING: This code uses internal Qt API - the QZipReader class for reading
|
||||
ZIP files - and things may break if Qt changes the API. For Qt5 this is not
|
||||
a problem as we can "see the feature" now and there are no changes in all
|
||||
the supported Qt5 versions up to the last one (5.15). In Qt6 the class
|
||||
might change or even disappear in the feature, but this is very unlikely
|
||||
as there were no changes for several years and The Qt Company's politics
|
||||
is: "do not invest any resources to any desktop platform stuff unless
|
||||
absolutely necessary". There is an issue (QTBUG-3897) since year 2009 to
|
||||
include the ZIP reader into the public API, which aptly ilustrates the
|
||||
effort The Qt Company is willing to make about anything desktop related...
|
||||
*/
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QXmlStreamReader>
|
||||
#include <QImage>
|
||||
#include <QImageReader>
|
||||
#include <QBuffer>
|
||||
#include <QPainter>
|
||||
#include <private/qzipreader_p.h>
|
||||
#include "pcs.h"
|
||||
#include "image.h"
|
||||
#include "kmzmap.h"
|
||||
|
||||
|
||||
#define ZOOM_THRESHOLD 0.9
|
||||
|
||||
#define TL(m) ((m).bbox.topLeft())
|
||||
#define BR(m) ((m).bbox.bottomRight())
|
||||
|
||||
const Projection &KMZMap::Overlay::projection()
|
||||
{
|
||||
static Projection p = Projection(PCS::pcs(3857));
|
||||
return p;
|
||||
}
|
||||
|
||||
KMZMap::Overlay::Overlay(const QString &path, const QSize &size,
|
||||
const RectC &bbox, double rotation) : path(path), size(size), bbox(bbox),
|
||||
rotation(rotation), img(0)
|
||||
{
|
||||
ReferencePoint tl(PointD(0, 0), projection().ll2xy(bbox.topLeft()));
|
||||
ReferencePoint br(PointD(size.width(), size.height()),
|
||||
projection().ll2xy(bbox.bottomRight()));
|
||||
|
||||
transform = Transform(tl, br);
|
||||
}
|
||||
|
||||
qreal KMZMap::Overlay::resolution(const QRectF &rect) const
|
||||
{
|
||||
qreal cy = rect.center().y();
|
||||
QPointF cl(rect.left(), cy);
|
||||
QPointF cr(rect.right(), cy);
|
||||
|
||||
qreal ds = xy2ll(cl).distanceTo(xy2ll(cr));
|
||||
qreal ps = QLineF(cl, cr).length();
|
||||
|
||||
return ds/ps;
|
||||
}
|
||||
|
||||
void KMZMap::Overlay::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
||||
{
|
||||
if (img) {
|
||||
if (rotation) {
|
||||
painter->save();
|
||||
painter->rotate(-rotation);
|
||||
img->draw(painter, rect.adjusted(-10, -10, 10, 10), flags);
|
||||
painter->restore();
|
||||
} else
|
||||
img->draw(painter, rect, flags);
|
||||
}
|
||||
}
|
||||
|
||||
void KMZMap::Overlay::load(QZipReader *zip)
|
||||
{
|
||||
if (!img) {
|
||||
QByteArray ba(zip->fileData(path));
|
||||
img = new Image(QImage::fromData(ba));
|
||||
}
|
||||
}
|
||||
|
||||
void KMZMap::Overlay::unload()
|
||||
{
|
||||
delete img;
|
||||
img = 0;
|
||||
}
|
||||
|
||||
|
||||
bool KMZMap::resCmp(const Overlay &m1, const Overlay &m2)
|
||||
{
|
||||
qreal r1, r2;
|
||||
|
||||
r1 = m1.resolution(m1.bounds());
|
||||
r2 = m2.resolution(m2.bounds());
|
||||
|
||||
return r1 > r2;
|
||||
}
|
||||
|
||||
bool KMZMap::xCmp(const Overlay &m1, const Overlay &m2)
|
||||
{
|
||||
return TL(m1).lon() < TL(m2).lon();
|
||||
}
|
||||
|
||||
bool KMZMap::yCmp(const Overlay &m1, const Overlay &m2)
|
||||
{
|
||||
return TL(m1).lat() > TL(m2).lat();
|
||||
}
|
||||
|
||||
void KMZMap::computeZooms()
|
||||
{
|
||||
std::sort(_maps.begin(), _maps.end(), resCmp);
|
||||
|
||||
_zooms.append(Zoom(0, _maps.count() - 1));
|
||||
for (int i = 1; i < _maps.count(); i++) {
|
||||
qreal last = _maps.at(i-1).resolution(_maps.at(i).bounds());
|
||||
qreal cur = _maps.at(i).resolution(_maps.at(i).bounds());
|
||||
if (cur < last * ZOOM_THRESHOLD) {
|
||||
_zooms.last().last = i-1;
|
||||
_zooms.append(Zoom(i, _maps.count() - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KMZMap::computeBounds()
|
||||
{
|
||||
QVector<QPointF> offsets(_maps.count());
|
||||
|
||||
for (int z = 0; z < _zooms.count(); z++) {
|
||||
QList<Overlay> m;
|
||||
for (int i = _zooms.at(z).first; i <= _zooms.at(z).last; i++)
|
||||
m.append(_maps.at(i));
|
||||
|
||||
std::sort(m.begin(), m.end(), xCmp);
|
||||
offsets[_maps.indexOf(m.first())].setX(0);
|
||||
for (int i = 1; i < m.size(); i++) {
|
||||
qreal w = m.first().ll2xy(TL(m.at(i))).x();
|
||||
offsets[_maps.indexOf(m.at(i))].setX(w);
|
||||
}
|
||||
|
||||
std::sort(m.begin(), m.end(), yCmp);
|
||||
offsets[_maps.indexOf(m.first())].setY(0);
|
||||
for (int i = 1; i < m.size(); i++) {
|
||||
qreal h = m.first().ll2xy(TL(m.at(i))).y();
|
||||
offsets[_maps.indexOf(m.at(i))].setY(h);
|
||||
}
|
||||
}
|
||||
|
||||
_bounds = QVector<Bounds>(_maps.count());
|
||||
for (int i = 0; i < _maps.count(); i++)
|
||||
_bounds[i] = Bounds(_maps.at(i).bbox,
|
||||
QRectF(offsets.at(i), _maps.at(i).size));
|
||||
}
|
||||
|
||||
|
||||
double KMZMap::number(QXmlStreamReader &reader)
|
||||
{
|
||||
bool res;
|
||||
double ret = reader.readElementText().toDouble(&res);
|
||||
if (!res)
|
||||
reader.raiseError(QString("Invalid %1").arg(reader.name().toString()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QString KMZMap::icon(QXmlStreamReader &reader)
|
||||
{
|
||||
QString href;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("href"))
|
||||
href = reader.readElementText();
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
return href;
|
||||
}
|
||||
|
||||
RectC KMZMap::latLonBox(QXmlStreamReader &reader, double *rotation)
|
||||
{
|
||||
double top = NAN, bottom = NAN, right = NAN, left = NAN;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("north"))
|
||||
top = number(reader);
|
||||
else if (reader.name() == QLatin1String("south"))
|
||||
bottom = number(reader);
|
||||
else if (reader.name() == QLatin1String("west"))
|
||||
left = number(reader);
|
||||
else if (reader.name() == QLatin1String("east"))
|
||||
right = number(reader);
|
||||
else if (reader.name() == QLatin1String("rotation"))
|
||||
*rotation = number(reader);
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
return RectC(Coordinates(left, top), Coordinates(right, bottom));
|
||||
}
|
||||
|
||||
void KMZMap::groundOverlay(QXmlStreamReader &reader, QZipReader &zip)
|
||||
{
|
||||
QString image;
|
||||
RectC rect;
|
||||
double rotation = 0;
|
||||
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("Icon"))
|
||||
image = icon(reader);
|
||||
else if (reader.name() == QLatin1String("LatLonBox"))
|
||||
rect = latLonBox(reader, &rotation);
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
|
||||
if (rect.isValid()) {
|
||||
QByteArray ba(zip.fileData(image));
|
||||
QBuffer img(&ba);
|
||||
QImageReader ir(&img);
|
||||
QSize size(ir.size());
|
||||
|
||||
if (size.isValid())
|
||||
_maps.append(Overlay(image, size, rect, rotation));
|
||||
else
|
||||
reader.raiseError(image + ": Invalid image file");
|
||||
} else
|
||||
reader.raiseError("Invalid LatLonBox");
|
||||
}
|
||||
|
||||
void KMZMap::document(QXmlStreamReader &reader, QZipReader &zip)
|
||||
{
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("Document"))
|
||||
document(reader, zip);
|
||||
else if (reader.name() == QLatin1String("GroundOverlay"))
|
||||
groundOverlay(reader, zip);
|
||||
else if (reader.name() == QLatin1String("Folder"))
|
||||
folder(reader, zip);
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
void KMZMap::folder(QXmlStreamReader &reader, QZipReader &zip)
|
||||
{
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("Placemark"))
|
||||
groundOverlay(reader, zip);
|
||||
else if (reader.name() == QLatin1String("Folder"))
|
||||
folder(reader, zip);
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
void KMZMap::kml(QXmlStreamReader &reader, QZipReader &zip)
|
||||
{
|
||||
while (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("Document"))
|
||||
document(reader, zip);
|
||||
else if (reader.name() == QLatin1String("GroundOverlay"))
|
||||
groundOverlay(reader, zip);
|
||||
else if (reader.name() == QLatin1String("Folder"))
|
||||
folder(reader, zip);
|
||||
else
|
||||
reader.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
KMZMap::KMZMap(const QString &fileName, QObject *parent)
|
||||
: Map(fileName, parent), _zip(0)
|
||||
{
|
||||
QZipReader zip(fileName, QIODevice::ReadOnly);
|
||||
QByteArray xml(zip.fileData("doc.kml"));
|
||||
QXmlStreamReader reader(xml);
|
||||
|
||||
if (reader.readNextStartElement()) {
|
||||
if (reader.name() == QLatin1String("kml"))
|
||||
kml(reader, zip);
|
||||
else
|
||||
reader.raiseError("Not a KMZ file");
|
||||
}
|
||||
|
||||
if (reader.error()) {
|
||||
_errorString = "doc.kml:" + QString::number(reader.lineNumber()) + ": "
|
||||
+ reader.errorString();
|
||||
return;
|
||||
}
|
||||
if (_maps.isEmpty()) {
|
||||
_errorString = "No usable GroundOverlay found";
|
||||
return;
|
||||
}
|
||||
|
||||
computeZooms();
|
||||
computeBounds();
|
||||
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
QString KMZMap::name() const
|
||||
{
|
||||
QFileInfo fi(path());
|
||||
return fi.fileName();
|
||||
}
|
||||
|
||||
QRectF KMZMap::bounds()
|
||||
{
|
||||
QSizeF s(0, 0);
|
||||
|
||||
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).last; i++) {
|
||||
if (_bounds.at(i).xy.right() > s.width())
|
||||
s.setWidth(_bounds.at(i).xy.right());
|
||||
if (_bounds.at(i).xy.bottom() > s.height())
|
||||
s.setHeight(_bounds.at(i).xy.bottom());
|
||||
}
|
||||
|
||||
return QRectF(QPointF(0, 0), s);
|
||||
}
|
||||
|
||||
int KMZMap::zoomFit(const QSize &size, const RectC &br)
|
||||
{
|
||||
_zoom = 0;
|
||||
_mapIndex = -1;
|
||||
|
||||
if (!br.isValid()) {
|
||||
_zoom = _zooms.size() - 1;
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
for (int z = 0; z < _zooms.count(); z++) {
|
||||
for (int i = _zooms.at(z).first; i <= _zooms.at(z).last; i++) {
|
||||
if (!_bounds.at(i).ll.contains(br.center()))
|
||||
continue;
|
||||
|
||||
QRect sbr = QRectF(_maps.at(i).ll2xy(br.topLeft()),
|
||||
_maps.at(i).ll2xy(br.bottomRight())).toRect().normalized();
|
||||
|
||||
if (sbr.size().width() > size.width()
|
||||
|| sbr.size().height() > size.height())
|
||||
return _zoom;
|
||||
|
||||
_zoom = z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
void KMZMap::setZoom(int zoom)
|
||||
{
|
||||
_mapIndex = -1;
|
||||
_zoom = zoom;
|
||||
}
|
||||
|
||||
int KMZMap::zoomIn()
|
||||
{
|
||||
_zoom = qMin(_zoom + 1, _zooms.size() - 1);
|
||||
_mapIndex = -1;
|
||||
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
int KMZMap::zoomOut()
|
||||
{
|
||||
_zoom = qMax(_zoom - 1, 0);
|
||||
_mapIndex = -1;
|
||||
|
||||
return _zoom;
|
||||
}
|
||||
|
||||
QPointF KMZMap::ll2xy(const Coordinates &c)
|
||||
{
|
||||
if (_mapIndex < 0 || !_bounds.at(_mapIndex).ll.contains(c)) {
|
||||
_mapIndex = _zooms.at(_zoom).first;
|
||||
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).last; i++) {
|
||||
if (_bounds.at(i).ll.contains(c)) {
|
||||
_mapIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPointF p = _maps.at(_mapIndex).ll2xy(c);
|
||||
return p + _bounds.at(_mapIndex).xy.topLeft();
|
||||
}
|
||||
|
||||
Coordinates KMZMap::xy2ll(const QPointF &p)
|
||||
{
|
||||
int idx = _zooms.at(_zoom).first;
|
||||
|
||||
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).last; i++) {
|
||||
if (_bounds.at(i).xy.contains(p)) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QPointF p2 = p - _bounds.at(idx).xy.topLeft();
|
||||
return _maps.at(idx).xy2ll(p2);
|
||||
}
|
||||
|
||||
void KMZMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
||||
{
|
||||
// All in one map
|
||||
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).last; i++) {
|
||||
if (_bounds.at(i).xy.contains(rect)) {
|
||||
draw(painter, rect, i, flags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Multiple maps
|
||||
for (int i = _zooms.at(_zoom).first; i <= _zooms.at(_zoom).last; i++) {
|
||||
QRectF ir = rect.intersected(_bounds.at(i).xy);
|
||||
if (!ir.isNull())
|
||||
draw(painter, ir, i, flags);
|
||||
}
|
||||
}
|
||||
|
||||
void KMZMap::load()
|
||||
{
|
||||
Q_ASSERT(!_zip);
|
||||
_zip = new QZipReader(path(), QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
void KMZMap::unload()
|
||||
{
|
||||
for (int i = 0; i < _maps.count(); i++)
|
||||
_maps[i].unload();
|
||||
|
||||
delete _zip;
|
||||
_zip = 0;
|
||||
}
|
||||
|
||||
void KMZMap::draw(QPainter *painter, const QRectF &rect, int mapIndex,
|
||||
Flags flags)
|
||||
{
|
||||
Overlay &map = _maps[mapIndex];
|
||||
const QPointF offset = _bounds.at(mapIndex).xy.topLeft();
|
||||
QRectF pr = QRectF(rect.topLeft() - offset, rect.size());
|
||||
|
||||
map.load(_zip);
|
||||
|
||||
painter->save();
|
||||
painter->translate(offset);
|
||||
map.draw(painter, pr, flags);
|
||||
painter->restore();
|
||||
}
|
115
src/map/kmzmap.h
Normal file
115
src/map/kmzmap.h
Normal file
@ -0,0 +1,115 @@
|
||||
#ifndef KMZMAP_H
|
||||
#define KMZMAP_H
|
||||
|
||||
#include "projection.h"
|
||||
#include "transform.h"
|
||||
#include "rectd.h"
|
||||
#include "map.h"
|
||||
|
||||
class QXmlStreamReader;
|
||||
class QZipReader;
|
||||
class Image;
|
||||
|
||||
class KMZMap : public Map
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KMZMap(const QString &fileName, QObject *parent = 0);
|
||||
|
||||
QString name() const;
|
||||
|
||||
QRectF bounds();
|
||||
|
||||
int zoom() const {return _zoom;}
|
||||
void setZoom(int zoom);
|
||||
int zoomFit(const QSize &size, const RectC &br);
|
||||
int zoomIn();
|
||||
int zoomOut();
|
||||
|
||||
QPointF ll2xy(const Coordinates &c);
|
||||
Coordinates xy2ll(const QPointF &p);
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect, Flags flags);
|
||||
|
||||
void load();
|
||||
void unload();
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
QString errorString() const {return _errorString;}
|
||||
|
||||
private:
|
||||
struct Overlay {
|
||||
QString path;
|
||||
QSize size;
|
||||
RectC bbox;
|
||||
double rotation;
|
||||
Image *img;
|
||||
|
||||
Transform transform;
|
||||
|
||||
Overlay(const QString &path, const QSize &size, const RectC &bbox,
|
||||
double rotation);
|
||||
bool operator==(const Overlay &other) const
|
||||
{return path == other.path;}
|
||||
|
||||
QPointF ll2xy(const Coordinates &c) const
|
||||
{return QPointF(transform.proj2img(projection().ll2xy(c)));}
|
||||
Coordinates xy2ll(const QPointF &p) const
|
||||
{return projection().xy2ll(transform.img2proj(p));}
|
||||
|
||||
QRectF bounds() const {return QRectF(QPointF(0, 0), size);}
|
||||
qreal resolution(const QRectF &rect) const;
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect, Flags flags);
|
||||
|
||||
void load(QZipReader *zip);
|
||||
void unload();
|
||||
|
||||
static const Projection &projection();
|
||||
};
|
||||
|
||||
struct Zoom {
|
||||
int first;
|
||||
int last;
|
||||
|
||||
Zoom() : first(-1), last(-1) {}
|
||||
Zoom(int first, int last) : first(first), last(last) {}
|
||||
};
|
||||
|
||||
struct Bounds {
|
||||
RectC ll;
|
||||
QRectF xy;
|
||||
|
||||
Bounds() {}
|
||||
Bounds(const RectC &ll, const QRectF &xy) : ll(ll), xy(xy) {}
|
||||
};
|
||||
|
||||
void kml(QXmlStreamReader &reader, QZipReader &zip);
|
||||
void document(QXmlStreamReader &reader, QZipReader &zip);
|
||||
void folder(QXmlStreamReader &reader, QZipReader &zip);
|
||||
void groundOverlay(QXmlStreamReader &reader, QZipReader &zip);
|
||||
RectC latLonBox(QXmlStreamReader &reader, double *rotation);
|
||||
QString icon(QXmlStreamReader &reader);
|
||||
double number(QXmlStreamReader &reader);
|
||||
|
||||
void draw(QPainter *painter, const QRectF &rect, int mapIndex, Flags flags);
|
||||
void computeZooms();
|
||||
void computeBounds();
|
||||
|
||||
static bool resCmp(const Overlay &m1, const Overlay &m2);
|
||||
static bool xCmp(const Overlay &m1, const Overlay &m2);
|
||||
static bool yCmp(const Overlay &m1, const Overlay &m2);
|
||||
|
||||
QList<Overlay> _maps;
|
||||
QVector<Zoom> _zooms;
|
||||
QVector<Bounds> _bounds;
|
||||
int _zoom;
|
||||
int _mapIndex;
|
||||
QZipReader *_zip;
|
||||
|
||||
bool _valid;
|
||||
QString _errorString;
|
||||
};
|
||||
|
||||
#endif // KMZMAP_H
|
@ -11,6 +11,7 @@
|
||||
#include "imgmap.h"
|
||||
#include "IMG/gmap.h"
|
||||
#include "bsbmap.h"
|
||||
#include "kmzmap.h"
|
||||
#include "invalidmap.h"
|
||||
#include "maplist.h"
|
||||
|
||||
@ -47,6 +48,8 @@ Map *MapList::loadFile(const QString &path, bool *terminate)
|
||||
map = new OziMap(path);
|
||||
else if (suffix == "kap")
|
||||
map = new BSBMap(path);
|
||||
else if (suffix == "kmz")
|
||||
map = new KMZMap(path);
|
||||
|
||||
return map ? map : new InvalidMap(path, "Unknown file format");
|
||||
}
|
||||
@ -96,6 +99,7 @@ QString MapList::formats()
|
||||
+ " (*.gmap *.gmapi *.img *.xml);;"
|
||||
+ qApp->translate("MapList", "Garmin JNX maps") + " (*.jnx);;"
|
||||
+ qApp->translate("MapList", "BSB nautical charts") + " (*.kap);;"
|
||||
+ qApp->translate("MapList", "KMZ maps") + " (*.kmz);;"
|
||||
+ qApp->translate("MapList", "OziExplorer maps") + " (*.map);;"
|
||||
+ qApp->translate("MapList", "MBTiles maps") + " (*.mbtiles);;"
|
||||
+ qApp->translate("MapList", "TrekBuddy maps/atlases") + " (*.tar *.tba);;"
|
||||
@ -107,8 +111,8 @@ QString MapList::formats()
|
||||
QStringList MapList::filter()
|
||||
{
|
||||
QStringList filter;
|
||||
filter << "*.gmap" << "*.gmapi" << "*.img" << "*.jnx" << "*.kap" << "*.map"
|
||||
<< "*.mbtiles" << "*.rmap" << "*.rtmap" << "*.tar" << "*.tba" << "*.tif"
|
||||
<< "*.tiff" << "*.xml";
|
||||
filter << "*.gmap" << "*.gmapi" << "*.img" << "*.jnx" << "*.kap" << "*.kmz"
|
||||
<< "*.map" << "*.mbtiles" << "*.rmap" << "*.rtmap" << "*.tar" << "*.tba"
|
||||
<< "*.tif" << "*.tiff" << "*.xml";
|
||||
return filter;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user