mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-27 21:24:47 +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/huffmantext.h \
|
||||||
src/map/IMG/nodfile.h \
|
src/map/IMG/nodfile.h \
|
||||||
src/map/IMG/mapdata.h \
|
src/map/IMG/mapdata.h \
|
||||||
|
src/map/IMG/raster.h \
|
||||||
src/map/IMG/rastertile.h \
|
src/map/IMG/rastertile.h \
|
||||||
src/map/IMG/textpathitem.h \
|
src/map/IMG/textpathitem.h \
|
||||||
src/map/IMG/textpointitem.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) {
|
if (_encoding == 11) {
|
||||||
_huffmanText = new HuffmanText();
|
_huffmanText = new HuffmanText();
|
||||||
if (!_huffmanText->load(rgn, rgnHdl))
|
if (!_huffmanText->load(rgn, rgnHdl))
|
||||||
@ -283,3 +300,32 @@ Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize) con
|
|||||||
return Label();
|
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,
|
Label label(Handle &hdl, quint32 offset, bool poi = false,
|
||||||
bool capitalize = true) const;
|
bool capitalize = true) const;
|
||||||
|
|
||||||
|
quint8 imageIdSize() const {return _imgOffsetIdSize;}
|
||||||
|
QByteArray readImage(Handle &hdl, quint32 id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Label str2label(const QVector<quint8> &str, bool capitalize) const;
|
Label str2label(const QVector<quint8> &str, bool capitalize) const;
|
||||||
Label label6b(Handle &hdl, quint32 offset, bool capitalize) const;
|
Label label6b(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||||
@ -43,6 +46,13 @@ private:
|
|||||||
quint32 _size;
|
quint32 _size;
|
||||||
quint32 _poiOffset;
|
quint32 _poiOffset;
|
||||||
quint32 _poiSize;
|
quint32 _poiSize;
|
||||||
|
quint32 _imgOffsetsOffset;
|
||||||
|
quint32 _imgOffsetsCount;
|
||||||
|
quint32 _imgOffsetsRecordSize;
|
||||||
|
quint32 _imgOffsetsFlags;
|
||||||
|
quint32 _imgOffset;
|
||||||
|
quint32 _imgSize;
|
||||||
|
quint8 _imgOffsetIdSize;
|
||||||
quint8 _poiMultiplier;
|
quint8 _poiMultiplier;
|
||||||
quint8 _multiplier;
|
quint8 _multiplier;
|
||||||
quint8 _encoding;
|
quint8 _encoding;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "common/rtree.h"
|
#include "common/rtree.h"
|
||||||
#include "common/range.h"
|
#include "common/range.h"
|
||||||
#include "label.h"
|
#include "label.h"
|
||||||
|
#include "raster.h"
|
||||||
|
|
||||||
class Style;
|
class Style;
|
||||||
class SubDiv;
|
class SubDiv;
|
||||||
@ -25,6 +26,7 @@ public:
|
|||||||
parallel. */
|
parallel. */
|
||||||
QVector<QPointF> points;
|
QVector<QPointF> points;
|
||||||
Label label;
|
Label label;
|
||||||
|
Raster raster;
|
||||||
quint32 type;
|
quint32 type;
|
||||||
RectC boundingRect;
|
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,11 +217,26 @@ void RasterTile::drawPolygons(QPainter *painter)
|
|||||||
const MapData::Poly &poly = _polygons.at(i);
|
const MapData::Poly &poly = _polygons.at(i);
|
||||||
if (poly.type != _style->drawOrder().at(n))
|
if (poly.type != _style->drawOrder().at(n))
|
||||||
continue;
|
continue;
|
||||||
const Style::Polygon &style = _style->polygon(poly.type);
|
|
||||||
|
|
||||||
painter->setPen(style.pen());
|
if (poly.raster.isValid()) {
|
||||||
painter->setBrush(style.brush());
|
RectC r(poly.raster.rect());
|
||||||
painter->drawPolygon(poly.points);
|
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());
|
||||||
|
painter->setBrush(style.brush());
|
||||||
|
painter->drawPolygon(poly.points);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,8 @@ RGNFile::~RGNFile()
|
|||||||
delete _huffmanTable;
|
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;
|
quint8 flags;
|
||||||
quint32 rs;
|
quint32 rs;
|
||||||
@ -56,6 +57,22 @@ bool RGNFile::skipClassFields(Handle &hdl) const
|
|||||||
break;
|
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);
|
return seek(hdl, pos(hdl) + rs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,7 +170,7 @@ void RGNFile::clear()
|
|||||||
|
|
||||||
bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
||||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
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)
|
const SubDiv::Segment &segment = (segmentType == Line)
|
||||||
? subdiv->lines() : subdiv->polygons();
|
? subdiv->lines() : subdiv->polygons();
|
||||||
@ -169,7 +186,7 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
|||||||
quint16 len;
|
quint16 len;
|
||||||
|
|
||||||
while (pos(hdl) < segment.end()) {
|
while (pos(hdl) < segment.end()) {
|
||||||
IMG::Poly poly;
|
MapData::Poly poly;
|
||||||
|
|
||||||
if (!(readUInt8(hdl, type) && readUInt24(hdl, labelPtr)
|
if (!(readUInt8(hdl, type) && readUInt24(hdl, labelPtr)
|
||||||
&& readInt16(hdl, lon) && readInt16(hdl, lat)))
|
&& 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,
|
bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
||||||
QList<IMG::Poly> *polys) const
|
QList<MapData::Poly> *polys) const
|
||||||
{
|
{
|
||||||
quint32 labelPtr, len;
|
quint32 labelPtr, len;
|
||||||
quint8 type, subtype;
|
quint8 type, subtype;
|
||||||
@ -244,7 +261,7 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (pos(hdl) < segment.end()) {
|
while (pos(hdl) < segment.end()) {
|
||||||
IMG::Poly poly;
|
MapData::Poly poly;
|
||||||
QPoint pos;
|
QPoint pos;
|
||||||
|
|
||||||
if (!(readUInt8(hdl, type) && readUInt8(hdl, subtype)
|
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))
|
if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
|
||||||
return false;
|
return false;
|
||||||
if (subtype & 0x80 && !skipClassFields(hdl))
|
if (subtype & 0x80 && !readClassFields(hdl, segmentType, &poly, lbl,
|
||||||
|
&lblHdl))
|
||||||
return false;
|
return false;
|
||||||
if (subtype & 0x40 && !skipLclFields(hdl, segmentType == Line
|
if (subtype & 0x40 && !skipLclFields(hdl, segmentType == Line
|
||||||
? _linesLclFlags : _polygonsLclFlags))
|
? _linesLclFlags : _polygonsLclFlags))
|
||||||
@ -340,7 +358,7 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
|||||||
|
|
||||||
bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
||||||
QList<IMG::Point> *points) const
|
QList<MapData::Point> *points) const
|
||||||
{
|
{
|
||||||
const SubDiv::Segment &segment = (segmentType == IndexedPoint)
|
const SubDiv::Segment &segment = (segmentType == IndexedPoint)
|
||||||
? subdiv->idxPoints() : subdiv->points();
|
? subdiv->idxPoints() : subdiv->points();
|
||||||
@ -352,7 +370,7 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (pos(hdl) < segment.end()) {
|
while (pos(hdl) < segment.end()) {
|
||||||
IMG::Point point;
|
MapData::Point point;
|
||||||
quint8 type, subtype;
|
quint8 type, subtype;
|
||||||
qint16 lon, lat;
|
qint16 lon, lat;
|
||||||
quint32 labelPtr;
|
quint32 labelPtr;
|
||||||
@ -383,7 +401,7 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RGNFile::extPointObjects(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();
|
const SubDiv::Segment &segment = subdiv->extPoints();
|
||||||
|
|
||||||
@ -394,7 +412,7 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
while (pos(hdl) < segment.end()) {
|
while (pos(hdl) < segment.end()) {
|
||||||
IMG::Point point;
|
MapData::Point point;
|
||||||
qint16 lon, lat;
|
qint16 lon, lat;
|
||||||
quint8 type, subtype;
|
quint8 type, subtype;
|
||||||
quint32 labelPtr = 0;
|
quint32 labelPtr = 0;
|
||||||
@ -405,7 +423,7 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
|
|||||||
|
|
||||||
if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
|
if (subtype & 0x20 && !readUInt24(hdl, labelPtr))
|
||||||
return false;
|
return false;
|
||||||
if (subtype & 0x80 && !skipClassFields(hdl))
|
if (subtype & 0x80 && !readClassFields(hdl, Point))
|
||||||
return false;
|
return false;
|
||||||
if (subtype & 0x40 && !skipLclFields(hdl, _pointsLclFlags))
|
if (subtype & 0x40 && !skipLclFields(hdl, _pointsLclFlags))
|
||||||
return false;
|
return false;
|
||||||
@ -434,7 +452,7 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
|
|||||||
|
|
||||||
bool RGNFile::links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
bool RGNFile::links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||||
const NETFile *net, Handle &netHdl, const NODFile *nod, Handle &nodHdl,
|
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;
|
quint32 size, blockIndexId;
|
||||||
quint8 flags;
|
quint8 flags;
|
||||||
|
@ -60,9 +60,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
QMap<SegmentType, SubDiv::Segment> segments(Handle &hdl, SubDiv *subdiv)
|
QMap<SegmentType, SubDiv::Segment> segments(Handle &hdl, SubDiv *subdiv)
|
||||||
const;
|
const;
|
||||||
bool skipClassFields(Handle &hdl) const;
|
bool readClassFields(Handle &hdl, SegmentType segmentType,
|
||||||
bool skipLclFields(Handle &hdl, const quint32 flags[3])
|
MapData::Poly *poly = 0, const LBLFile *lbl = 0, Handle *lblHdl = 0) const;
|
||||||
const;
|
bool skipLclFields(Handle &hdl, const quint32 flags[3]) const;
|
||||||
bool skipGblFields(Handle &hdl, quint32 flags) const;
|
bool skipGblFields(Handle &hdl, quint32 flags) const;
|
||||||
|
|
||||||
HuffmanTable *_huffmanTable;
|
HuffmanTable *_huffmanTable;
|
||||||
|
@ -113,7 +113,8 @@ void Style::defaultPolygonStyle()
|
|||||||
_polygons[0x10c05] = _polygons[TYPE(0x52)];
|
_polygons[0x10c05] = _polygons[TYPE(0x52)];
|
||||||
|
|
||||||
// Draw order
|
// 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(0x02) << 0x10801 << TYPE(0x03) << 0x10802 << TYPE(0x17) << 0x10a04
|
||||||
<< TYPE(0x18) << 0x1090c << TYPE(0x1a) << 0x1090e << TYPE(0x28) << 0x10b01
|
<< TYPE(0x18) << 0x1090c << TYPE(0x1a) << 0x1090e << TYPE(0x28) << 0x10b01
|
||||||
<< TYPE(0x32) << 0x10b02 << TYPE(0x3c) << 0x10b03 << TYPE(0x3d) << 0x10b04
|
<< TYPE(0x32) << 0x10b02 << TYPE(0x3c) << 0x10b03 << TYPE(0x3d) << 0x10b04
|
||||||
|
Loading…
Reference in New Issue
Block a user