mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-28 05:34:47 +01:00
Improved rmap support
This commit is contained in:
parent
060f940b75
commit
172b2b1b14
@ -160,7 +160,8 @@ HEADERS += src/common/config.h \
|
|||||||
src/map/obliquestereographic.h \
|
src/map/obliquestereographic.h \
|
||||||
src/GUI/coordinatesitem.h \
|
src/GUI/coordinatesitem.h \
|
||||||
src/map/rmap.h \
|
src/map/rmap.h \
|
||||||
src/map/calibrationpoint.h
|
src/map/calibrationpoint.h \
|
||||||
|
src/map/color.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 \
|
||||||
|
18
src/map/color.h
Normal file
18
src/map/color.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef COLOR_H
|
||||||
|
#define COLOR_H
|
||||||
|
|
||||||
|
#include <QColor>
|
||||||
|
|
||||||
|
namespace Color
|
||||||
|
{
|
||||||
|
inline QRgb bgr2rgb(quint32 bgr)
|
||||||
|
{
|
||||||
|
quint32 b = (bgr & 0x000000FF);
|
||||||
|
quint32 g = (bgr & 0x0000FF00) >> 8;
|
||||||
|
quint32 r = (bgr & 0x00FF0000) >> 16;
|
||||||
|
|
||||||
|
return (0xFF000000 | r << 16 | g << 8 | b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // COLOR_H
|
@ -59,7 +59,7 @@ bool MapList::loadFile(const QString &path, bool *atlas, bool dir)
|
|||||||
map = new GeoTIFFMap(path, this);
|
map = new GeoTIFFMap(path, this);
|
||||||
else if (suffix == "mbtiles")
|
else if (suffix == "mbtiles")
|
||||||
map = new MBTilesMap(path, this);
|
map = new MBTilesMap(path, this);
|
||||||
else if (suffix == "rmap")
|
else if (suffix == "rmap" || suffix == "rtmap")
|
||||||
map = new RMap(path, this);
|
map = new RMap(path, this);
|
||||||
else
|
else
|
||||||
map = new OziMap(path, this);
|
map = new OziMap(path, this);
|
||||||
@ -117,13 +117,13 @@ QString MapList::formats()
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
tr("Supported files")
|
tr("Supported files")
|
||||||
+ " (*.jnx *.map *.mbtiles *.rmap *.tar *.tba *.tif *.tiff *.xml);;"
|
+ " (*.jnx *.map *.mbtiles *.rmap *.rtmap *.tar *.tba *.tif *.tiff *.xml);;"
|
||||||
+ tr("MBTiles maps") + " (*.mbtiles);;"
|
+ tr("MBTiles maps") + " (*.mbtiles);;"
|
||||||
+ tr("Garmin JNX maps") + " (*.jnx);;"
|
+ tr("Garmin JNX maps") + " (*.jnx);;"
|
||||||
+ tr("OziExplorer maps") + " (*.map);;"
|
+ tr("OziExplorer maps") + " (*.map);;"
|
||||||
+ tr("TrekBuddy maps/atlases") + " (*.tar *.tba);;"
|
+ tr("TrekBuddy maps/atlases") + " (*.tar *.tba);;"
|
||||||
+ tr("GeoTIFF images") + " (*.tif *.tiff);;"
|
+ tr("GeoTIFF images") + " (*.tif *.tiff);;"
|
||||||
+ tr("TwoNav maps") + " (*.rmap);;"
|
+ tr("TwoNav maps") + " (*.rmap *.rtmap);;"
|
||||||
+ tr("Online map sources") + " (*.xml)";
|
+ tr("Online map sources") + " (*.xml)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <QtEndian>
|
#include <QtEndian>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include "color.h"
|
||||||
#include "ozf.h"
|
#include "ozf.h"
|
||||||
|
|
||||||
|
|
||||||
@ -128,7 +129,7 @@ bool OZF::readHeaders()
|
|||||||
|
|
||||||
bool OZF::readTileTable()
|
bool OZF::readTileTable()
|
||||||
{
|
{
|
||||||
quint32 tableOffset, headerOffset, bgr0, w, h;
|
quint32 tableOffset, headerOffset, w, h;
|
||||||
quint16 x, y;
|
quint16 x, y;
|
||||||
int zooms;
|
int zooms;
|
||||||
|
|
||||||
@ -164,15 +165,9 @@ bool OZF::readTileTable()
|
|||||||
zoom.palette = QVector<quint32>(256);
|
zoom.palette = QVector<quint32>(256);
|
||||||
if (!read(&(zoom.palette[0]), sizeof(quint32) * 256))
|
if (!read(&(zoom.palette[0]), sizeof(quint32) * 256))
|
||||||
return false;
|
return false;
|
||||||
for (int i = 0; i < zoom.palette.size(); i++) {
|
for (int i = 0; i < zoom.palette.size(); i++)
|
||||||
bgr0 = qFromLittleEndian(zoom.palette.at(i));
|
zoom.palette[i] = Color::bgr2rgb(qFromLittleEndian(
|
||||||
|
zoom.palette.at(i)));
|
||||||
quint32 b = (bgr0 & 0x000000FF);
|
|
||||||
quint32 g = (bgr0 & 0x0000FF00) >> 8;
|
|
||||||
quint32 r = (bgr0 & 0x00FF0000) >> 16;
|
|
||||||
|
|
||||||
zoom.palette[i] = 0xFF000000 | r << 16 | g << 8 | b;
|
|
||||||
}
|
|
||||||
|
|
||||||
zoom.tiles = QVector<quint32>(zoom.dim.width() * zoom.dim.height() + 1);
|
zoom.tiles = QVector<quint32>(zoom.dim.width() * zoom.dim.height() + 1);
|
||||||
for (int i = 0; i < zoom.tiles.size(); i++)
|
for (int i = 0; i < zoom.tiles.size(); i++)
|
||||||
|
120
src/map/rmap.cpp
120
src/map/rmap.cpp
@ -3,6 +3,7 @@
|
|||||||
#include <QPixmapCache>
|
#include <QPixmapCache>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
|
#include <QtEndian>
|
||||||
#include "common/rectc.h"
|
#include "common/rectc.h"
|
||||||
#include "common/wgs84.h"
|
#include "common/wgs84.h"
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
@ -10,6 +11,7 @@
|
|||||||
#include "utm.h"
|
#include "utm.h"
|
||||||
#include "pcs.h"
|
#include "pcs.h"
|
||||||
#include "rectd.h"
|
#include "rectd.h"
|
||||||
|
#include "color.h"
|
||||||
#include "rmap.h"
|
#include "rmap.h"
|
||||||
|
|
||||||
|
|
||||||
@ -52,7 +54,7 @@ static Projection parseProjection(const QString &str, const GCS *gcs)
|
|||||||
int zone;
|
int zone;
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case 0:
|
case 0: // UTM
|
||||||
if (fields.size() < 4)
|
if (fields.size() < 4)
|
||||||
return Projection();
|
return Projection();
|
||||||
zone = fields.at(2).toInt(&ret);
|
zone = fields.at(2).toInt(&ret);
|
||||||
@ -62,11 +64,43 @@ static Projection parseProjection(const QString &str, const GCS *gcs)
|
|||||||
zone = -zone;
|
zone = -zone;
|
||||||
pcs = PCS(gcs, 9807, UTM::setup(zone), 9001);
|
pcs = PCS(gcs, 9807, UTM::setup(zone), 9001);
|
||||||
return Projection(&pcs);
|
return Projection(&pcs);
|
||||||
case 1:
|
case 1: // LatLon
|
||||||
return Projection(gcs);
|
return Projection(gcs);
|
||||||
case 2:
|
case 2: // Mercator
|
||||||
pcs = PCS(gcs, 1024, Projection::Setup(), 9001);
|
pcs = PCS(gcs, 1024, Projection::Setup(), 9001);
|
||||||
return Projection(&pcs);
|
return Projection(&pcs);
|
||||||
|
case 3: // Transversal Mercator
|
||||||
|
if (fields.size() < 7)
|
||||||
|
return Projection();
|
||||||
|
pcs = PCS(gcs, 9807, Projection::Setup(fields.at(3).toDouble(),
|
||||||
|
fields.at(2).toDouble(), fields.at(6).toDouble(),
|
||||||
|
fields.at(5).toDouble(), fields.at(4).toDouble(),
|
||||||
|
NAN, NAN), 9001);
|
||||||
|
return Projection(&pcs);
|
||||||
|
case 4: // Lambert 2SP
|
||||||
|
if (fields.size() < 8)
|
||||||
|
return Projection();
|
||||||
|
pcs = PCS(gcs, 9802, Projection::Setup(fields.at(4).toDouble(),
|
||||||
|
fields.at(5).toDouble(), NAN,
|
||||||
|
fields.at(6).toDouble(), fields.at(7).toDouble(),
|
||||||
|
fields.at(3).toDouble(), fields.at(2).toDouble()), 9001);
|
||||||
|
return Projection(&pcs);
|
||||||
|
case 6: // BGN (British National Grid)
|
||||||
|
pcs = PCS(gcs, 9807, Projection::Setup(49, -2, 0.999601, 400000,
|
||||||
|
-100000, NAN, NAN), 9001);
|
||||||
|
return Projection(&pcs);
|
||||||
|
case 12: // France Lambert II etendu
|
||||||
|
pcs = PCS(gcs, 9801, Projection::Setup(52, 0, 0.99987742, 600000,
|
||||||
|
2200000, NAN, NAN), 9001);
|
||||||
|
return Projection(&pcs);
|
||||||
|
case 14: // Swiss Grid
|
||||||
|
pcs = PCS(gcs, 9815, Projection::Setup(46.570866, 7.26225, 1.0,
|
||||||
|
600000, 200000, 90.0, 90.0), 9001);
|
||||||
|
return Projection(&pcs);
|
||||||
|
case 184: // Swedish Grid
|
||||||
|
pcs = PCS(gcs, 9807, Projection::Setup(0, 15.808278, 1, 1500000, 0,
|
||||||
|
NAN, NAN), 9001);
|
||||||
|
return Projection(&pcs);
|
||||||
default:
|
default:
|
||||||
return Projection();
|
return Projection();
|
||||||
}
|
}
|
||||||
@ -141,19 +175,45 @@ RMap::RMap(const QString &fileName, QObject *parent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint32 tmp, width, height;
|
quint32 unknown, type, subtype, obfuscated, width, height, bpp, tileWidth,
|
||||||
stream >> tmp >> tmp >> tmp;
|
tileHeight, paletteSize;
|
||||||
stream >> width >> height;
|
|
||||||
QSize imageSize(width, -height);
|
|
||||||
stream >> tmp >> tmp;
|
|
||||||
stream >> width >> height;
|
|
||||||
_tileSize = QSize(width, height);
|
|
||||||
quint64 IMPOffset;
|
quint64 IMPOffset;
|
||||||
stream >> IMPOffset;
|
|
||||||
stream >> tmp;
|
stream >> type;
|
||||||
|
if (type > 5)
|
||||||
|
stream >> subtype >> obfuscated;
|
||||||
|
else
|
||||||
|
obfuscated = 0;
|
||||||
|
stream >> width >> height >> bpp >> unknown >> tileWidth >> tileHeight
|
||||||
|
>> IMPOffset >> paletteSize;
|
||||||
|
CHECK(stream.status() == QDataStream::Ok);
|
||||||
|
|
||||||
|
if (!(type == 5 || (type >= 8 && type <= 10))) {
|
||||||
|
_errorString = QString::number(type) + ": unsupported map type";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (obfuscated) {
|
||||||
|
_errorString = "Obfuscated maps not supported";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize imageSize(width, -height);
|
||||||
|
_tileSize = QSize(tileWidth, tileHeight);
|
||||||
|
|
||||||
|
if (paletteSize) {
|
||||||
|
quint32 bgr;
|
||||||
|
CHECK(paletteSize <= 256);
|
||||||
|
|
||||||
|
_palette.resize(256);
|
||||||
|
for (int i = 0; i < (int)paletteSize; i++) {
|
||||||
|
stream >> bgr;
|
||||||
|
_palette[i] = Color::bgr2rgb(bgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qint32 zoomCount;
|
qint32 zoomCount;
|
||||||
stream >> zoomCount;
|
stream >> zoomCount;
|
||||||
CHECK(stream.status() == QDataStream::Ok);
|
CHECK(stream.status() == QDataStream::Ok && zoomCount);
|
||||||
|
|
||||||
QVector<quint64> zoomOffsets(zoomCount);
|
QVector<quint64> zoomOffsets(zoomCount);
|
||||||
for (int i = 0; i < zoomCount; i++)
|
for (int i = 0; i < zoomCount; i++)
|
||||||
@ -183,7 +243,7 @@ RMap::RMap(const QString &fileName, QObject *parent)
|
|||||||
|
|
||||||
CHECK(file.seek(IMPOffset));
|
CHECK(file.seek(IMPOffset));
|
||||||
quint32 IMPSize;
|
quint32 IMPSize;
|
||||||
stream >> tmp >> IMPSize;
|
stream >> unknown >> IMPSize;
|
||||||
CHECK(stream.status() == QDataStream::Ok);
|
CHECK(stream.status() == QDataStream::Ok);
|
||||||
|
|
||||||
QByteArray IMP(IMPSize + 1, 0);
|
QByteArray IMP(IMPSize + 1, 0);
|
||||||
@ -274,11 +334,37 @@ QPixmap RMap::tile(int x, int y)
|
|||||||
return QPixmap();
|
return QPixmap();
|
||||||
QDataStream stream(&_file);
|
QDataStream stream(&_file);
|
||||||
stream.setByteOrder(QDataStream::LittleEndian);
|
stream.setByteOrder(QDataStream::LittleEndian);
|
||||||
quint32 tag, len;
|
quint32 tag;
|
||||||
stream >> tag >> len;
|
stream >> tag;
|
||||||
if (stream.status() != QDataStream::Ok)
|
if (stream.status() != QDataStream::Ok)
|
||||||
return QPixmap();
|
return QPixmap();
|
||||||
|
|
||||||
|
if (tag == 2) {
|
||||||
|
if (_palette.isEmpty())
|
||||||
|
return QPixmap();
|
||||||
|
quint32 width, height, size;
|
||||||
|
stream >> width >> height >> size;
|
||||||
|
QSize tileSize(width, -height);
|
||||||
|
|
||||||
|
quint32 bes = qToBigEndian(tileSize.width() * tileSize.height());
|
||||||
|
QByteArray ba;
|
||||||
|
ba.resize(sizeof(bes) + size);
|
||||||
|
memcpy(ba.data(), &bes, sizeof(bes));
|
||||||
|
|
||||||
|
if (stream.readRawData(ba.data() + sizeof(bes), size) != (int)size)
|
||||||
|
return QPixmap();
|
||||||
|
QByteArray uba = qUncompress(ba);
|
||||||
|
if (uba.size() != tileSize.width() * tileSize.height())
|
||||||
|
return QPixmap();
|
||||||
|
QImage img((const uchar*)uba.constData(), tileSize.width(),
|
||||||
|
tileSize.height(), QImage::Format_Indexed8);
|
||||||
|
img.setColorTable(_palette);
|
||||||
|
|
||||||
|
return QPixmap::fromImage(img);
|
||||||
|
} else if (tag == 7) {
|
||||||
|
quint32 len;
|
||||||
|
stream >> len;
|
||||||
|
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
ba.resize(len);
|
ba.resize(len);
|
||||||
if (stream.readRawData(ba.data(), ba.size()) != ba.size())
|
if (stream.readRawData(ba.data(), ba.size()) != ba.size())
|
||||||
@ -286,6 +372,8 @@ QPixmap RMap::tile(int x, int y)
|
|||||||
|
|
||||||
QImage img(QImage::fromData(ba));
|
QImage img(QImage::fromData(ba));
|
||||||
return QPixmap::fromImage(img);
|
return QPixmap::fromImage(img);
|
||||||
|
} else
|
||||||
|
return QPixmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
void RMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define RMAP_H
|
#define RMAP_H
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QColor>
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
#include "projection.h"
|
#include "projection.h"
|
||||||
@ -54,6 +55,7 @@ private:
|
|||||||
qreal _mapRatio;
|
qreal _mapRatio;
|
||||||
QString _fileName;
|
QString _fileName;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
|
QVector<QRgb> _palette;
|
||||||
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
QString _errorString;
|
QString _errorString;
|
||||||
|
Loading…
Reference in New Issue
Block a user