mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 03:35:53 +01:00
Added support for raster polygon backgrounds
This commit is contained in:
parent
6ba7493b59
commit
bf613f1b6d
@ -97,6 +97,7 @@ HEADERS += src/common/config.h \
|
||||
src/map/IMG/huffmantext.h \
|
||||
src/map/IMG/nodfile.h \
|
||||
src/map/IMG/mapdata.h \
|
||||
src/map/IMG/raster.h \
|
||||
src/map/IMG/rastertile.h \
|
||||
src/map/IMG/textpathitem.h \
|
||||
src/map/IMG/textpointitem.h \
|
||||
|
@ -93,6 +93,23 @@ bool LBLFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
|
||||
}
|
||||
}
|
||||
|
||||
if (hdrLen >= 0x19A) {
|
||||
quint32 size;
|
||||
if (!(seek(hdl, _gmpOffset + 0x184) && readUInt32(hdl, _imgOffsetsOffset)
|
||||
&& readUInt32(hdl, size) && readUInt16(hdl, _imgOffsetsRecordSize)
|
||||
&& readUInt32(hdl, _imgOffsetsFlags) && readUInt32(hdl, _imgOffset)
|
||||
&& readUInt32(hdl, _imgSize)))
|
||||
return false;
|
||||
_imgOffsetsCount = size ? size / _imgOffsetsRecordSize : 0;
|
||||
|
||||
quint32 maxId = _imgOffsetsCount - 1;
|
||||
_imgOffsetIdSize = 0;
|
||||
do {
|
||||
_imgOffsetIdSize++;
|
||||
maxId = maxId >> 8;
|
||||
} while (maxId != 0);
|
||||
}
|
||||
|
||||
if (_encoding == 11) {
|
||||
_huffmanText = new HuffmanText();
|
||||
if (!_huffmanText->load(rgn, rgnHdl))
|
||||
@ -283,3 +300,32 @@ Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize) con
|
||||
return Label();
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray LBLFile::readImage(Handle &hdl, quint32 id) const
|
||||
{
|
||||
quint32 offset, nextOffset, size;
|
||||
|
||||
if (!_imgOffsetsCount || id >= _imgOffsetsCount)
|
||||
return QByteArray();
|
||||
|
||||
if (!(seek(hdl, _imgOffsetsOffset + id * _imgOffsetsRecordSize)
|
||||
&& readVUInt32(hdl, _imgOffsetsRecordSize, offset)))
|
||||
return QByteArray();
|
||||
if (id == _imgOffsetsCount - 1)
|
||||
nextOffset = _imgSize;
|
||||
else {
|
||||
if (!readVUInt32(hdl, _imgOffsetsRecordSize, nextOffset))
|
||||
return QByteArray();
|
||||
}
|
||||
size = nextOffset - offset;
|
||||
|
||||
if (!seek(hdl, _imgOffset + offset))
|
||||
return QByteArray();
|
||||
QByteArray ba;
|
||||
ba.resize(size);
|
||||
for (quint32 i = 0; i < size; i++)
|
||||
if (!readUInt8(hdl, *(ba.data() + i)))
|
||||
return QByteArray();
|
||||
|
||||
return ba;
|
||||
}
|
||||
|
@ -30,6 +30,9 @@ public:
|
||||
Label label(Handle &hdl, quint32 offset, bool poi = false,
|
||||
bool capitalize = true) const;
|
||||
|
||||
quint8 imageIdSize() const {return _imgOffsetIdSize;}
|
||||
QByteArray readImage(Handle &hdl, quint32 id) const;
|
||||
|
||||
private:
|
||||
Label str2label(const QVector<quint8> &str, bool capitalize) const;
|
||||
Label label6b(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||
@ -43,6 +46,13 @@ private:
|
||||
quint32 _size;
|
||||
quint32 _poiOffset;
|
||||
quint32 _poiSize;
|
||||
quint32 _imgOffsetsOffset;
|
||||
quint32 _imgOffsetsCount;
|
||||
quint32 _imgOffsetsRecordSize;
|
||||
quint32 _imgOffsetsFlags;
|
||||
quint32 _imgOffset;
|
||||
quint32 _imgSize;
|
||||
quint8 _imgOffsetIdSize;
|
||||
quint8 _poiMultiplier;
|
||||
quint8 _multiplier;
|
||||
quint8 _encoding;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "common/rtree.h"
|
||||
#include "common/range.h"
|
||||
#include "label.h"
|
||||
#include "raster.h"
|
||||
|
||||
class Style;
|
||||
class SubDiv;
|
||||
@ -25,6 +26,7 @@ public:
|
||||
parallel. */
|
||||
QVector<QPointF> points;
|
||||
Label label;
|
||||
Raster raster;
|
||||
quint32 type;
|
||||
RectC boundingRect;
|
||||
|
||||
|
37
src/map/IMG/raster.h
Normal file
37
src/map/IMG/raster.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef RASTER_H
|
||||
#define RASTER_H
|
||||
|
||||
#include <QRect>
|
||||
#include <QByteArray>
|
||||
#include <QDebug>
|
||||
#include "common/rectc.h"
|
||||
#include "common/garmin.h"
|
||||
|
||||
class Raster {
|
||||
public:
|
||||
Raster() {}
|
||||
Raster(const QByteArray &img, const QRect &rect) : _img(img), _rect(rect) {}
|
||||
|
||||
const QByteArray &img() const {return _img;}
|
||||
const RectC rect() const
|
||||
{
|
||||
return RectC(Coordinates(toWGS32(_rect.left()), toWGS32(_rect.top())),
|
||||
Coordinates(toWGS32(_rect.right()), toWGS32(_rect.bottom())));
|
||||
}
|
||||
bool isValid() const {return !_img.isNull();}
|
||||
|
||||
private:
|
||||
QByteArray _img;
|
||||
QRect _rect;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
inline QDebug operator<<(QDebug dbg, const Raster &raster)
|
||||
{
|
||||
dbg.nospace() << "Raster(" << raster.img().size() << ", " << raster.rect()
|
||||
<< ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
#endif // RASTER_H
|
@ -217,6 +217,20 @@ void RasterTile::drawPolygons(QPainter *painter)
|
||||
const MapData::Poly &poly = _polygons.at(i);
|
||||
if (poly.type != _style->drawOrder().at(n))
|
||||
continue;
|
||||
|
||||
if (poly.raster.isValid()) {
|
||||
RectC r(poly.raster.rect());
|
||||
QPointF tl(_map->ll2xy(r.topLeft()));
|
||||
QPointF br(_map->ll2xy(r.bottomRight()));
|
||||
QSize size(QRectF(tl, br).toRect().size());
|
||||
|
||||
painter->drawImage(tl, QImage::fromData(poly.raster.img()).
|
||||
scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
|
||||
//painter->setPen(Qt::blue);
|
||||
//painter->setBrush(Qt::NoBrush);
|
||||
//painter->drawRect(QRectF(tl, br));
|
||||
} else {
|
||||
const Style::Polygon &style = _style->polygon(poly.type);
|
||||
|
||||
painter->setPen(style.pen());
|
||||
@ -225,6 +239,7 @@ void RasterTile::drawPolygons(QPainter *painter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RasterTile::drawLines(QPainter *painter)
|
||||
{
|
||||
|
@ -29,7 +29,8 @@ RGNFile::~RGNFile()
|
||||
delete _huffmanTable;
|
||||
}
|
||||
|
||||
bool RGNFile::skipClassFields(Handle &hdl) const
|
||||
bool RGNFile::readClassFields(Handle &hdl, SegmentType segmentType,
|
||||
MapData::Poly *poly, const LBLFile *lbl, Handle *lblHdl) const
|
||||
{
|
||||
quint8 flags;
|
||||
quint32 rs;
|
||||
@ -56,6 +57,22 @@ bool RGNFile::skipClassFields(Handle &hdl) const
|
||||
break;
|
||||
}
|
||||
|
||||
if (segmentType == Polygon && poly->type == 0x10613
|
||||
&& lbl && rs >= lbl->imageIdSize() + 16U) {
|
||||
quint32 id;
|
||||
quint32 top, right, bottom, left;
|
||||
|
||||
if (!(readVUInt32(hdl, lbl->imageIdSize(), id)
|
||||
&& readUInt32(hdl, top) && readUInt32(hdl, right)
|
||||
&& readUInt32(hdl, bottom) && readUInt32(hdl, left)))
|
||||
return false;
|
||||
|
||||
poly->raster = Raster(lbl->readImage(*lblHdl, id),
|
||||
QRect(QPoint(left, top), QPoint(right, bottom)));
|
||||
|
||||
rs -= lbl->imageIdSize() + 16;
|
||||
}
|
||||
|
||||
return seek(hdl, pos(hdl) + rs);
|
||||
}
|
||||
|
||||
@ -153,7 +170,7 @@ void RGNFile::clear()
|
||||
|
||||
bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
||||
Handle &netHdl, QList<IMG::Poly> *polys) const
|
||||
Handle &netHdl, QList<MapData::Poly> *polys) const
|
||||
{
|
||||
const SubDiv::Segment &segment = (segmentType == Line)
|
||||
? subdiv->lines() : subdiv->polygons();
|
||||
@ -169,7 +186,7 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
quint16 len;
|
||||
|
||||
while (pos(hdl) < segment.end()) {
|
||||
IMG::Poly poly;
|
||||
MapData::Poly poly;
|
||||
|
||||
if (!(readUInt8(hdl, type) && readUInt24(hdl, labelPtr)
|
||||
&& readInt16(hdl, lon) && readInt16(hdl, lat)))
|
||||
@ -229,7 +246,7 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
|
||||
bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Poly> *polys) const
|
||||
QList<MapData::Poly> *polys) const
|
||||
{
|
||||
quint32 labelPtr, len;
|
||||
quint8 type, subtype;
|
||||
@ -244,7 +261,7 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
return false;
|
||||
|
||||
while (pos(hdl) < segment.end()) {
|
||||
IMG::Poly poly;
|
||||
MapData::Poly poly;
|
||||
QPoint pos;
|
||||
|
||||
if (!(readUInt8(hdl, type) && readUInt8(hdl, subtype)
|
||||
@ -319,7 +336,8 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
|
||||
if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
|
||||
return false;
|
||||
if (subtype & 0x80 && !skipClassFields(hdl))
|
||||
if (subtype & 0x80 && !readClassFields(hdl, segmentType, &poly, lbl,
|
||||
&lblHdl))
|
||||
return false;
|
||||
if (subtype & 0x40 && !skipLclFields(hdl, segmentType == Line
|
||||
? _linesLclFlags : _polygonsLclFlags))
|
||||
@ -340,7 +358,7 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
|
||||
bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Point> *points) const
|
||||
QList<MapData::Point> *points) const
|
||||
{
|
||||
const SubDiv::Segment &segment = (segmentType == IndexedPoint)
|
||||
? subdiv->idxPoints() : subdiv->points();
|
||||
@ -352,7 +370,7 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
return false;
|
||||
|
||||
while (pos(hdl) < segment.end()) {
|
||||
IMG::Point point;
|
||||
MapData::Point point;
|
||||
quint8 type, subtype;
|
||||
qint16 lon, lat;
|
||||
quint32 labelPtr;
|
||||
@ -383,7 +401,7 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
}
|
||||
|
||||
bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<IMG::Point> *points) const
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<MapData::Point> *points) const
|
||||
{
|
||||
const SubDiv::Segment &segment = subdiv->extPoints();
|
||||
|
||||
@ -394,7 +412,7 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
return false;
|
||||
|
||||
while (pos(hdl) < segment.end()) {
|
||||
IMG::Point point;
|
||||
MapData::Point point;
|
||||
qint16 lon, lat;
|
||||
quint8 type, subtype;
|
||||
quint32 labelPtr = 0;
|
||||
@ -405,7 +423,7 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
|
||||
if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
|
||||
return false;
|
||||
if (subtype & 0x80 && !skipClassFields(hdl))
|
||||
if (subtype & 0x80 && !readClassFields(hdl, Point))
|
||||
return false;
|
||||
if (subtype & 0x40 && !skipLclFields(hdl, _pointsLclFlags))
|
||||
return false;
|
||||
@ -434,7 +452,7 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
|
||||
bool RGNFile::links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
const NETFile *net, Handle &netHdl, const NODFile *nod, Handle &nodHdl,
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<IMG::Poly> *lines) const
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<MapData::Poly> *lines) const
|
||||
{
|
||||
quint32 size, blockIndexId;
|
||||
quint8 flags;
|
||||
|
@ -60,9 +60,9 @@ public:
|
||||
private:
|
||||
QMap<SegmentType, SubDiv::Segment> segments(Handle &hdl, SubDiv *subdiv)
|
||||
const;
|
||||
bool skipClassFields(Handle &hdl) const;
|
||||
bool skipLclFields(Handle &hdl, const quint32 flags[3])
|
||||
const;
|
||||
bool readClassFields(Handle &hdl, SegmentType segmentType,
|
||||
MapData::Poly *poly = 0, const LBLFile *lbl = 0, Handle *lblHdl = 0) const;
|
||||
bool skipLclFields(Handle &hdl, const quint32 flags[3]) const;
|
||||
bool skipGblFields(Handle &hdl, quint32 flags) const;
|
||||
|
||||
HuffmanTable *_huffmanTable;
|
||||
|
@ -113,7 +113,8 @@ void Style::defaultPolygonStyle()
|
||||
_polygons[0x10c05] = _polygons[TYPE(0x52)];
|
||||
|
||||
// Draw order
|
||||
_drawOrder << TYPE(0x4b) << 0x10d01 << TYPE(0x4a) << TYPE(0x01) << 0x10800
|
||||
_drawOrder
|
||||
<< TYPE(0x4b) << 0x10d01 << 0x10613 << TYPE(0x4a) << TYPE(0x01) << 0x10800
|
||||
<< TYPE(0x02) << 0x10801 << TYPE(0x03) << 0x10802 << TYPE(0x17) << 0x10a04
|
||||
<< TYPE(0x18) << 0x1090c << TYPE(0x1a) << 0x1090e << TYPE(0x28) << 0x10b01
|
||||
<< TYPE(0x32) << 0x10b02 << TYPE(0x3c) << 0x10b03 << TYPE(0x3d) << 0x10b04
|
||||
|
Loading…
Reference in New Issue
Block a user