Compare commits
54 Commits
Author | SHA1 | Date | |
---|---|---|---|
fa03ecd419 | |||
609202fe57 | |||
f55d6d8501 | |||
731b309ac9 | |||
f85977d881 | |||
12e395270b | |||
45b637ba17 | |||
f139d33502 | |||
63e7735abe | |||
27122f94ef | |||
0644bb72a0 | |||
a4d14511de | |||
1225d350d4 | |||
a1d93cc548 | |||
80f5bbfbce | |||
70c9431ee4 | |||
de7664ccc7 | |||
9bd79a4104 | |||
f9abf21e6d | |||
fb4af33d89 | |||
9eb95daf09 | |||
d291e55bdb | |||
b5893cf506 | |||
8507fe3b52 | |||
79edd6e09d | |||
491c6c9a98 | |||
3c36db9f5a | |||
c4a750f5d4 | |||
e4d7f45103 | |||
c85b90d56d | |||
7babf734bf | |||
25ac235414 | |||
630a5cea83 | |||
a0de7f25c3 | |||
7c6174a8ee | |||
0f512d1269 | |||
246b46ffcb | |||
cc4cbcbeda | |||
64e0b492e6 | |||
52a8b1de5b | |||
5045c03953 | |||
515f1aeb27 | |||
dbb82d6f44 | |||
307a03d46c | |||
b7c03b4b9e | |||
2d1e0934ce | |||
0ff66bc897 | |||
3b68f497fe | |||
a04293b411 | |||
5a4de1cef0 | |||
99d3d8fd0a | |||
d579ce3482 | |||
67ce176b74 | |||
1a88527c60 |
@ -1,4 +1,4 @@
|
||||
version: 7.33.{build}
|
||||
version: 7.36.{build}
|
||||
|
||||
configuration:
|
||||
- Release
|
||||
|
@ -9,7 +9,7 @@ GPXSee is a Qt-based GPS log file viewer and analyzer that supports all common G
|
||||
* Support for DEM files (SRTM HGT).
|
||||
* Support for multiple tracks in one view.
|
||||
* Support for POI files.
|
||||
* Print/export to PDF.
|
||||
* Print/export to PDF/PNG.
|
||||
* Full-screen mode.
|
||||
* HiDPI/Retina displays & maps support.
|
||||
* Native GUI for Windows, Mac OS X and Linux.
|
||||
|
@ -3,7 +3,7 @@ unix:!macx {
|
||||
} else {
|
||||
TARGET = GPXSee
|
||||
}
|
||||
VERSION = 7.33
|
||||
VERSION = 7.36
|
||||
|
||||
QT += core \
|
||||
gui \
|
||||
@ -93,8 +93,10 @@ HEADERS += src/common/config.h \
|
||||
src/map/IMG/bitstream.h \
|
||||
src/map/IMG/deltastream.h \
|
||||
src/map/IMG/gmap.h \
|
||||
src/map/IMG/huffmanbuffer.h \
|
||||
src/map/IMG/huffmanstream.h \
|
||||
src/map/IMG/huffmantable.h \
|
||||
src/map/IMG/huffmantext.h \
|
||||
src/map/IMG/nodfile.h \
|
||||
src/map/IMG/mapdata.h \
|
||||
src/map/IMG/rastertile.h \
|
||||
@ -258,8 +260,10 @@ SOURCES += src/main.cpp \
|
||||
src/map/IMG/bitstream.cpp \
|
||||
src/map/IMG/deltastream.cpp \
|
||||
src/map/IMG/gmap.cpp \
|
||||
src/map/IMG/huffmanbuffer.cpp \
|
||||
src/map/IMG/huffmanstream.cpp \
|
||||
src/map/IMG/huffmantable.cpp \
|
||||
src/map/IMG/huffmantext.cpp \
|
||||
src/map/IMG/nodfile.cpp \
|
||||
src/map/IMG/mapdata.cpp \
|
||||
src/map/IMG/rastertile.cpp \
|
||||
|
@ -67,10 +67,12 @@
|
||||
<file alias="cinema-11.png">icons/POI/cinema-11.png</file>
|
||||
<file alias="clothing-store-11.png">icons/POI/clothing-store-11.png</file>
|
||||
<file alias="communications-tower-11.png">icons/POI/communications-tower-11.png</file>
|
||||
<file alias="convenience-11.png">icons/POI/convenience-11.png</file>
|
||||
<file alias="dam-11.png">icons/POI/dam-11.png</file>
|
||||
<file alias="danger-11.png">icons/POI/danger-11.png</file>
|
||||
<file alias="drinking-water-11.png">icons/POI/drinking-water-11.png</file>
|
||||
<file alias="fast-food-11.png">icons/POI/fast-food-11.png</file>
|
||||
<file alias="entrance-alt1-11.png">icons/POI/entrance-alt1-11.png</file>
|
||||
<file alias="fire-station-11.png">icons/POI/fire-station-11.png</file>
|
||||
<file alias="fitness-centre-11.png">icons/POI/fitness-centre-11.png</file>
|
||||
<file alias="fuel-11.png">icons/POI/fuel-11.png</file>
|
||||
@ -97,7 +99,6 @@
|
||||
<file alias="place-of-worship-11.png">icons/POI/place-of-worship-11.png</file>
|
||||
<file alias="police-11.png">icons/POI/police-11.png</file>
|
||||
<file alias="post-11.png">icons/POI/post-11.png</file>
|
||||
<file alias="prison-11.png">icons/POI/prison-11.png</file>
|
||||
<file alias="religious-christian-11.png">icons/POI/religious-christian-11.png</file>
|
||||
<file alias="religious-jewish-11.png">icons/POI/religious-jewish-11.png</file>
|
||||
<file alias="religious-muslim-11.png">icons/POI/religious-muslim-11.png</file>
|
||||
|
BIN
icons/POI/convenience-11.png
Normal file
After Width: | Height: | Size: 650 B |
BIN
icons/POI/entrance-alt1-11.png
Normal file
After Width: | Height: | Size: 611 B |
Before Width: | Height: | Size: 323 B |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 571 B After Width: | Height: | Size: 571 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
@ -1529,7 +1529,7 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="62"/>
|
||||
<source>cm</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>cm</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="68"/>
|
||||
|
@ -1272,7 +1272,7 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/optionsdialog.cpp" line="442"/>
|
||||
<source>Use segments</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Utiliser des segments</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/optionsdialog.cpp" line="481"/>
|
||||
@ -1529,7 +1529,7 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="62"/>
|
||||
<source>cm</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>cm</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="68"/>
|
||||
@ -1604,22 +1604,22 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="41"/>
|
||||
<source>Use anti-aliasing</source>
|
||||
<translation type="unfinished">Utiliser l'anticrénelage</translation>
|
||||
<translation>Utiliser l'anticrénelage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="45"/>
|
||||
<source>Image Setup</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Paramètres d'image</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="48"/>
|
||||
<source>Image width:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>largeur :</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="49"/>
|
||||
<source>Image height:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>hauteur :</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="50"/>
|
||||
|
@ -1529,7 +1529,7 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="62"/>
|
||||
<source>cm</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>cm</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="68"/>
|
||||
|
@ -1313,7 +1313,7 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/optionsdialog.cpp" line="442"/>
|
||||
<source>Use segments</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Usar segmentos</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/optionsdialog.cpp" line="481"/>
|
||||
@ -1529,7 +1529,7 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="62"/>
|
||||
<source>cm</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>cm</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="68"/>
|
||||
@ -1604,22 +1604,22 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="41"/>
|
||||
<source>Use anti-aliasing</source>
|
||||
<translation type="unfinished">Usar anti-aliasing</translation>
|
||||
<translation>Usar anti-aliasing</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="45"/>
|
||||
<source>Image Setup</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Configuração da Imagem</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="48"/>
|
||||
<source>Image width:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Largura da imagem:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="49"/>
|
||||
<source>Image height:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Altura da imagem:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="50"/>
|
||||
|
@ -531,7 +531,7 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="682"/>
|
||||
<source>GPXSee is distributed under the terms of the GNU General Public License version 3. For more info about GPXSee visit the project homepage at %1.</source>
|
||||
<translation>GPXSee распространяется в соответствиями с условиями версии 3 Стандартной Общественной Лицензии GNU. Для получения дополнительной информации о GPXSee посетите страницу проекта %1.</translation>
|
||||
<translation>GPXSee распространяется в соответствии с условиями GNU General Public License 3 версии. Для получения дополнительной информации о GPXSee посетите страницу проекта %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/gui.cpp" line="709"/>
|
||||
@ -1530,7 +1530,7 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="62"/>
|
||||
<source>cm</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>см</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="68"/>
|
||||
|
@ -1525,12 +1525,12 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="62"/>
|
||||
<source>in</source>
|
||||
<translation type="unfinished">дюйм</translation>
|
||||
<translation>in</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="62"/>
|
||||
<source>cm</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>см</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pdfexportdialog.cpp" line="68"/>
|
||||
@ -1605,22 +1605,22 @@
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="41"/>
|
||||
<source>Use anti-aliasing</source>
|
||||
<translation type="unfinished">Використовувати згладжування</translation>
|
||||
<translation>Використовувати згладжування</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="45"/>
|
||||
<source>Image Setup</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Налаштування зображення</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="48"/>
|
||||
<source>Image width:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Ширина зображення:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="49"/>
|
||||
<source>Image height:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>Висота зображення:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/GUI/pngexportdialog.cpp" line="50"/>
|
||||
|
@ -7,7 +7,7 @@
|
||||
; The name of the installer
|
||||
Name "GPXSee"
|
||||
; Program version
|
||||
!define VERSION "7.33"
|
||||
!define VERSION "7.36"
|
||||
|
||||
; The file to write
|
||||
OutFile "GPXSee-${VERSION}.exe"
|
||||
@ -17,6 +17,9 @@ SetCompressor /SOLID lzma
|
||||
; Required execution level
|
||||
RequestExecutionLevel admin
|
||||
|
||||
; Don't let the OS scale(blur) the installer GUI
|
||||
ManifestDPIAware true
|
||||
|
||||
; The default installation directory
|
||||
InstallDir "$PROGRAMFILES\GPXSee"
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
; The name of the installer
|
||||
Name "GPXSee"
|
||||
; Program version
|
||||
!define VERSION "7.33"
|
||||
!define VERSION "7.36"
|
||||
|
||||
; The file to write
|
||||
OutFile "GPXSee-${VERSION}_x64.exe"
|
||||
@ -17,6 +17,9 @@ SetCompressor /SOLID lzma
|
||||
; Required execution level
|
||||
RequestExecutionLevel admin
|
||||
|
||||
; Don't let the OS scale(blur) the installer GUI
|
||||
ManifestDPIAware true
|
||||
|
||||
; The default installation directory
|
||||
InstallDir "$PROGRAMFILES64\GPXSee"
|
||||
|
||||
|
@ -140,10 +140,9 @@ void GUI::createMapActions()
|
||||
|
||||
MapAction *GUI::createMapAction(Map *map)
|
||||
{
|
||||
MapAction *a = new MapAction(map);
|
||||
MapAction *a = new MapAction(map, _mapsActionGroup);
|
||||
a->setMenuRole(QAction::NoRole);
|
||||
a->setCheckable(true);
|
||||
a->setActionGroup(_mapsActionGroup);
|
||||
connect(a, SIGNAL(triggered()), this, SLOT(mapChanged()));
|
||||
|
||||
return a;
|
||||
|
@ -141,7 +141,7 @@
|
||||
#define PATH_AA_SETTING "pathAntiAliasing"
|
||||
#define PATH_AA_DEFAULT true
|
||||
#define GRAPH_AA_SETTING "graphAntiAliasing"
|
||||
#define GRAPH_AA_DEFAULT false
|
||||
#define GRAPH_AA_DEFAULT true
|
||||
#define ELEVATION_FILTER_SETTING "elevationFilter"
|
||||
#define ELEVATION_FILTER_DEFAULT 3
|
||||
#define SPEED_FILTER_SETTING "speedFilter"
|
||||
|
@ -15,4 +15,15 @@ inline double toWGS24(qint32 v)
|
||||
return toWGS32(LS(v, 8));
|
||||
}
|
||||
|
||||
inline quint8 vs(const quint8 b0)
|
||||
{
|
||||
static const quint8 sizes[] = {4, 1, 2, 1, 3, 1, 2, 1};
|
||||
return sizes[b0 & 0x07];
|
||||
}
|
||||
|
||||
inline quint8 bs(const quint8 val)
|
||||
{
|
||||
return (val + 7) >> 3;
|
||||
}
|
||||
|
||||
#endif // GARMIN_H
|
||||
|
@ -15,7 +15,8 @@ public:
|
||||
bool isNull() const
|
||||
{return _tl.isNull() && _br.isNull();}
|
||||
bool isValid() const
|
||||
{return (_tl.isValid() && _br.isValid() && _tl != _br);}
|
||||
{return (_tl.isValid() && _br.isValid()
|
||||
&& _tl.lat() > _br.lat() && _tl.lon() < _br.lon());}
|
||||
|
||||
Coordinates topLeft() const {return _tl;}
|
||||
Coordinates bottomRight() const {return _br;}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef RTREE_H
|
||||
#define RTREE_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <QtGlobal>
|
||||
@ -387,10 +386,10 @@ RTREE_TEMPLATE
|
||||
void RTREE_QUAL::Insert(const ELEMTYPE a_min[NUMDIMS],
|
||||
const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
#ifndef QT_NO_DEBUG
|
||||
for (int index=0; index<NUMDIMS; ++index)
|
||||
Q_ASSERT(a_min[index] <= a_max[index]);
|
||||
#endif //_DEBUG
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
Rect rect;
|
||||
|
||||
@ -407,10 +406,10 @@ RTREE_TEMPLATE
|
||||
void RTREE_QUAL::Remove(const ELEMTYPE a_min[NUMDIMS],
|
||||
const ELEMTYPE a_max[NUMDIMS], const DATATYPE& a_dataId)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
#ifndef QT_NO_DEBUG
|
||||
for (int index=0; index<NUMDIMS; ++index)
|
||||
Q_ASSERT(a_min[index] <= a_max[index]);
|
||||
#endif //_DEBUG
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
Rect rect;
|
||||
|
||||
@ -427,10 +426,10 @@ RTREE_TEMPLATE
|
||||
int RTREE_QUAL::Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS],
|
||||
bool a_resultCallback(DATATYPE a_data, void* a_context), void* a_context) const
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
#ifndef QT_NO_DEBUG
|
||||
for (int index=0; index<NUMDIMS; ++index)
|
||||
Q_ASSERT(a_min[index] <= a_max[index]);
|
||||
#endif //_DEBUG
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
Rect rect;
|
||||
|
||||
@ -636,10 +635,10 @@ bool RTREE_QUAL::InsertRect(Rect* a_rect, const DATATYPE& a_id, Node** a_root,
|
||||
{
|
||||
Q_ASSERT(a_rect && a_root);
|
||||
Q_ASSERT(a_level >= 0 && a_level <= (*a_root)->m_level);
|
||||
#ifdef _DEBUG
|
||||
#ifndef QT_NO_DEBUG
|
||||
for (int index=0; index < NUMDIMS; ++index)
|
||||
Q_ASSERT(a_rect->m_min[index] <= a_rect->m_max[index]);
|
||||
#endif //_DEBUG
|
||||
#endif // QT_NO_DEBUG
|
||||
|
||||
Node* newRoot;
|
||||
Node* newNode;
|
||||
|
@ -33,18 +33,18 @@ public:
|
||||
return false;
|
||||
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
if (_be)
|
||||
val = data;
|
||||
else {
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
*((char *)&val + i) = *((char*)&data + sizeof(T) - 1 - i);
|
||||
}
|
||||
if (_be)
|
||||
val = data;
|
||||
else {
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
*((char *)&val + i) = *((char*)&data + sizeof(T) - 1 - i);
|
||||
}
|
||||
#else
|
||||
if (_be) {
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
*((char *)&val + i) = *((char*)&data + sizeof(T) - 1 - i);
|
||||
} else
|
||||
val = data;
|
||||
if (_be) {
|
||||
for (size_t i = 0; i < sizeof(T); i++)
|
||||
*((char *)&val + i) = *((char*)&data + sizeof(T) - 1 - i);
|
||||
} else
|
||||
val = data;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -51,13 +51,13 @@ class FITParser::CTX {
|
||||
public:
|
||||
CTX(QFile *file, QVector<Waypoint> &waypoints)
|
||||
: file(file), waypoints(waypoints), len(0), endian(0), timestamp(0),
|
||||
lastWrite(0), ratio(NAN) {}
|
||||
ratio(NAN) {}
|
||||
|
||||
QFile *file;
|
||||
QVector<Waypoint> &waypoints;
|
||||
quint32 len;
|
||||
quint8 endian;
|
||||
quint32 timestamp, lastWrite;
|
||||
quint32 timestamp;
|
||||
MessageDefinition defs[16];
|
||||
qreal ratio;
|
||||
Trackpoint trackpoint;
|
||||
@ -361,14 +361,12 @@ bool FITParser::parseData(CTX &ctx, const MessageDefinition *def)
|
||||
ctx.ratio = ((qreal)front / (qreal)rear);
|
||||
}
|
||||
} else if (def->globalId == RECORD_MESSAGE) {
|
||||
if (ctx.timestamp > ctx.lastWrite
|
||||
&& ctx.trackpoint.coordinates().isValid()) {
|
||||
if (ctx.trackpoint.coordinates().isValid()) {
|
||||
ctx.trackpoint.setTimestamp(QDateTime::fromTime_t(ctx.timestamp
|
||||
+ 631065600));
|
||||
ctx.trackpoint.setRatio(ctx.ratio);
|
||||
ctx.segment.append(ctx.trackpoint);
|
||||
ctx.trackpoint = Trackpoint();
|
||||
ctx.lastWrite = ctx.timestamp;
|
||||
}
|
||||
} else if (def->globalId == COURSE_POINT)
|
||||
if (waypoint.coordinates().isValid())
|
||||
|
@ -12,6 +12,22 @@ bool BitStream1::flush()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BitStream1::readUInt24(quint32 &val)
|
||||
{
|
||||
quint8 b;
|
||||
|
||||
val = 0;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (!read(8, b))
|
||||
return false;
|
||||
val |= (b << (i * 8));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool BitStream4F::flush()
|
||||
{
|
||||
if (_length && !_file.seek(_hdl, _file.pos(_hdl) + _length))
|
||||
|
@ -12,6 +12,8 @@ public:
|
||||
bool flush();
|
||||
quint64 bitsAvailable() const {return (quint64)_length * 8 + _remaining;}
|
||||
|
||||
bool readUInt24(quint32 &val);
|
||||
|
||||
private:
|
||||
const SubFile &_file;
|
||||
SubFile::Handle &_hdl;
|
||||
|
@ -81,7 +81,11 @@ bool GMAP::loadTile(const QDir &dir, bool baseMap)
|
||||
QFileInfoList ml = dir.entryInfoList(QDir::Files);
|
||||
for (int i = 0; i < ml.size(); i++) {
|
||||
const QFileInfo &fi = ml.at(i);
|
||||
tile->addFile(fi.absoluteFilePath(), tileType(fi.suffix()));
|
||||
SubFile::Type tt = tileType(fi.suffix());
|
||||
if (VectorTile::isTileFile(tt)) {
|
||||
_files.append(new QString(fi.absoluteFilePath()));
|
||||
tile->addFile(_files.last(), tt);
|
||||
}
|
||||
}
|
||||
|
||||
if (!tile->init()) {
|
||||
@ -131,8 +135,10 @@ GMAP::GMAP(const QString &fileName) : _fileName(fileName)
|
||||
fi.absoluteFilePath() == baseMap.absoluteFilePath());
|
||||
}
|
||||
|
||||
if (baseDir.exists(typFilePath))
|
||||
_typ = new SubFile(baseDir.filePath(typFilePath));
|
||||
if (baseDir.exists(typFilePath)) {
|
||||
_files.append(new QString(baseDir.filePath(typFilePath)));
|
||||
_typ = new SubFile(_files.last());
|
||||
}
|
||||
|
||||
if (!_tileTree.Count())
|
||||
_errorString = "No usable map tile found";
|
||||
@ -140,6 +146,11 @@ GMAP::GMAP(const QString &fileName) : _fileName(fileName)
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
GMAP::~GMAP()
|
||||
{
|
||||
qDeleteAll(_files);
|
||||
}
|
||||
|
||||
bool GMAP::isGMAP(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
|
@ -10,6 +10,7 @@ class GMAP : public MapData
|
||||
{
|
||||
public:
|
||||
GMAP(const QString &fileName);
|
||||
~GMAP();
|
||||
|
||||
QString fileName() const {return _fileName;}
|
||||
|
||||
@ -25,6 +26,7 @@ private:
|
||||
bool loadTile(const QDir &dir, bool baseMap);
|
||||
|
||||
QString _fileName;
|
||||
QList<const QString*> _files;
|
||||
};
|
||||
|
||||
#endif // GMAP_H
|
||||
|
24
src/map/IMG/huffmanbuffer.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include "rgnfile.h"
|
||||
#include "huffmanbuffer.h"
|
||||
|
||||
bool HuffmanBuffer::load(const RGNFile *rgn, SubFile::Handle &rgnHdl)
|
||||
{
|
||||
quint32 recordSize, recordOffset = rgn->dictOffset();
|
||||
|
||||
for (int i = 0; i <= _id; i++) {
|
||||
if (!rgn->seek(rgnHdl, recordOffset))
|
||||
return false;
|
||||
if (!rgn->readVUInt32(rgnHdl, recordSize))
|
||||
return false;
|
||||
recordOffset = rgn->pos(rgnHdl) + recordSize;
|
||||
if (recordOffset > rgn->dictOffset() + rgn->dictSize())
|
||||
return false;
|
||||
};
|
||||
|
||||
resize(recordSize);
|
||||
for (int i = 0; i < QByteArray::size(); i++)
|
||||
if (!rgn->readUInt8(rgnHdl, *((quint8*)(data() + i))))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
21
src/map/IMG/huffmanbuffer.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef HUFFMANBUFFER_H
|
||||
#define HUFFMANBUFFER_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include "subfile.h"
|
||||
|
||||
class RGNFile;
|
||||
|
||||
class HuffmanBuffer : public QByteArray
|
||||
{
|
||||
public:
|
||||
HuffmanBuffer(quint8 id) : _id(id) {}
|
||||
|
||||
quint8 id() const {return _id;}
|
||||
bool load(const RGNFile *rgn, SubFile::Handle &rgnHdl);
|
||||
|
||||
private:
|
||||
quint8 _id;
|
||||
};
|
||||
|
||||
#endif // HUFFMANBUFFER_H
|
@ -1,17 +1,7 @@
|
||||
#include "common/garmin.h"
|
||||
#include "huffmantable.h"
|
||||
|
||||
|
||||
static quint8 vs(const quint8 b0)
|
||||
{
|
||||
static const quint8 sizes[] = {4, 1, 2, 1, 3, 1, 2, 1};
|
||||
return sizes[b0 & 0x07];
|
||||
}
|
||||
|
||||
static inline quint8 bs(const quint8 val)
|
||||
{
|
||||
return (val + 7) >> 3;
|
||||
}
|
||||
|
||||
static inline quint32 readVUint32(const quint8 *buffer, quint32 bytes)
|
||||
{
|
||||
quint32 val = 0;
|
||||
@ -22,10 +12,9 @@ static inline quint32 readVUint32(const quint8 *buffer, quint32 bytes)
|
||||
return val;
|
||||
}
|
||||
|
||||
bool HuffmanTable::load(const SubFile &file, SubFile::Handle &hdl,
|
||||
quint32 offset, quint32 size, quint32 id)
|
||||
bool HuffmanTable::load(const RGNFile *rgn, SubFile::Handle &rgnHdl)
|
||||
{
|
||||
if (!getBuffer(file, hdl, offset, size, id))
|
||||
if (!_buffer.load(rgn, rgnHdl))
|
||||
return false;
|
||||
|
||||
_s0 = (quint8)_buffer.at(0) & 0x0F;
|
||||
@ -42,31 +31,6 @@ bool HuffmanTable::load(const SubFile &file, SubFile::Handle &hdl,
|
||||
_s10 = _s14 + _s1c * _s1d;
|
||||
_s18 = _s10 + (_s1 << _s0);
|
||||
|
||||
_id = id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HuffmanTable::getBuffer(const SubFile &file, SubFile::Handle &hdl,
|
||||
quint32 offset, quint32 size, quint8 id)
|
||||
{
|
||||
quint32 recordSize, recordOffset = offset;
|
||||
|
||||
for (int i = 0; i <= id; i++) {
|
||||
if (!file.seek(hdl, recordOffset))
|
||||
return false;
|
||||
if (!file.readVUInt32(hdl, recordSize))
|
||||
return false;
|
||||
recordOffset = file.pos(hdl) + recordSize;
|
||||
if (recordOffset > offset + size)
|
||||
return false;
|
||||
};
|
||||
|
||||
_buffer.resize(recordSize);
|
||||
for (int i = 0; i < _buffer.size(); i++)
|
||||
if (!file.readUInt8(hdl, *((quint8*)(_buffer.data() + i))))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,31 +1,26 @@
|
||||
#ifndef HUFFMANTABLE_H
|
||||
#define HUFFMANTABLE_H
|
||||
|
||||
#include "subfile.h"
|
||||
#include "huffmanbuffer.h"
|
||||
|
||||
class RGNFile;
|
||||
|
||||
class HuffmanTable {
|
||||
public:
|
||||
HuffmanTable() : _s2(0) {}
|
||||
HuffmanTable(quint8 id) : _buffer(id) {}
|
||||
|
||||
bool load(const SubFile &file, SubFile::Handle &hdl, quint32 offset,
|
||||
quint32 size, quint32 id);
|
||||
bool isNull() const {return _s2 == 0;}
|
||||
bool load(const RGNFile *rgn, SubFile::Handle &rgnHdl);
|
||||
quint8 maxSymbolSize() const {return _s2;}
|
||||
quint32 symbol(quint32 data, quint8 &size) const;
|
||||
|
||||
quint8 id() const {return _id;}
|
||||
quint8 id() const {return _buffer.id();}
|
||||
|
||||
private:
|
||||
bool getBuffer(const SubFile &file, SubFile::Handle &hdl, quint32 offset,
|
||||
quint32 size, quint8 id);
|
||||
|
||||
QByteArray _buffer;
|
||||
HuffmanBuffer _buffer;
|
||||
quint8 _s0, _s1, _s2, _s3;
|
||||
quint8 *_s10, *_s14, *_s18;
|
||||
quint8 _s1c, _s1d, _s1e, _s1f, _s20;
|
||||
quint16 _s22;
|
||||
|
||||
quint8 _id;
|
||||
};
|
||||
|
||||
#endif // HUFFMANTABLE_H
|
||||
|
169
src/map/IMG/huffmantext.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
#include "common/garmin.h"
|
||||
#include "subfile.h"
|
||||
#include "huffmantext.h"
|
||||
|
||||
|
||||
static inline quint32 readVUint32(const quint8 *buffer, quint32 bytes)
|
||||
{
|
||||
quint32 val = 0;
|
||||
|
||||
for (quint32 i = 0; i < bytes; i++)
|
||||
val = val | (quint32)*(buffer - i) << ((bytes - i - 1) << 3);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
bool HuffmanText::load(const RGNFile *rgn, SubFile::Handle &rgnHdl)
|
||||
{
|
||||
if (!_buffer.load(rgn, rgnHdl))
|
||||
return false;
|
||||
|
||||
quint8 *buffer = (quint8 *)_buffer.constData();
|
||||
_b0 = buffer[0];
|
||||
_b1 = buffer[1];
|
||||
_b2 = buffer[2];
|
||||
_b3 = buffer[3];
|
||||
_vs = vs(buffer[4]);
|
||||
_bs3 = bs(_b3);
|
||||
_bs1 = bs(_b1);
|
||||
_mul = _bs1 + 1 + _vs;
|
||||
_bp1 = buffer + _vs + 4;
|
||||
_bp2 = _bp1 + _mul * _b2;
|
||||
_bp3 = _bp2 + ((_bs3 + 1) << (_b0 & 0xf));
|
||||
_bp4 = _bp3 - 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HuffmanText::fetch(const SubFile *file, SubFile::Handle &hdl,
|
||||
quint32 &data, quint32 &bits, quint32 &usedBits, quint32 &usedData) const
|
||||
{
|
||||
quint32 rs, ls, old;
|
||||
|
||||
bits = _b1 - bits;
|
||||
|
||||
if (usedBits < bits) {
|
||||
old = usedBits ? usedData >> (0x20 - usedBits) : 0;
|
||||
if (!file->readVUInt32SW(hdl, 4, usedData))
|
||||
return false;
|
||||
ls = bits - usedBits;
|
||||
rs = 0x20 - (bits - usedBits);
|
||||
old = usedData >> rs | old << ls;
|
||||
} else {
|
||||
ls = bits;
|
||||
rs = usedBits - bits;
|
||||
old = usedData >> (0x20 - bits);
|
||||
}
|
||||
|
||||
usedData = usedData << ls;
|
||||
data = data | old << (0x20 - _b1);
|
||||
usedBits = rs;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HuffmanText::decode(const SubFile *file, SubFile::Handle &hdl,
|
||||
QVector<quint8> &str) const
|
||||
{
|
||||
quint32 bits = 0;
|
||||
quint32 data = 0;
|
||||
quint32 usedBits = 0;
|
||||
quint32 usedData = 0;
|
||||
quint32 ls = 8;
|
||||
quint32 lo = _vs * 8 - 8;
|
||||
|
||||
|
||||
while (true) {
|
||||
if (!fetch(file, hdl, data, bits, usedBits, usedData))
|
||||
return false;
|
||||
|
||||
quint32 off = (data >> (0x20 - (_b0 & 0xf))) * (_bs3 + 1);
|
||||
quint32 sb = _bp2[off];
|
||||
quint32 ss = 0;
|
||||
quint32 sym = _b2 - 1;
|
||||
quint32 size;
|
||||
|
||||
if ((_b0 & 0xf) == 0 || (sb & 1) == 0) {
|
||||
if ((_b0 & 0xf) != 0) {
|
||||
ss = sb >> 1;
|
||||
sym = _bp2[off + 1];
|
||||
}
|
||||
|
||||
quint8 *tp = _bp1 + ss * _mul;
|
||||
quint32 sd = data >> (0x20 - _b1);
|
||||
while (ss < sym) {
|
||||
quint32 cnt = (sym + 1 + ss) >> 1;
|
||||
quint8 *prev = _bp1 + cnt * _mul;
|
||||
quint32 nd = readVUint32(prev + _bs1 - 1, _bs1);
|
||||
|
||||
if (sd <= nd) {
|
||||
sym = cnt - (sd < nd);
|
||||
if (sd < nd) {
|
||||
prev = tp;
|
||||
cnt = ss;
|
||||
}
|
||||
}
|
||||
tp = prev;
|
||||
ss = cnt;
|
||||
}
|
||||
|
||||
quint32 o1 = readVUint32(tp + _bs1 - 1, _bs1);
|
||||
tp = tp + _bs1;
|
||||
quint32 o2 = readVUint32(tp + _vs, _vs);
|
||||
size = tp[0];
|
||||
quint32 os = (sd - o1) >> (_b1 - size);
|
||||
|
||||
if ((_b0 & 0x10) == 0) {
|
||||
sym = readVUint32(_bp4 + (o2 + 1 + os) * _bs3, _bs3);
|
||||
} else {
|
||||
quint32 v = (os + o2) * _b3;
|
||||
quint32 idx = v >> 3;
|
||||
quint32 r = v & 7;
|
||||
quint32 shift = 8 - r;
|
||||
sym = _bp3[idx] >> r;
|
||||
if (shift < _b3) {
|
||||
quint32 sz = bs(_b3 - shift);
|
||||
quint32 val = readVUint32(_bp3 + idx + sz, sz);
|
||||
sym = sym | val << shift;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sym = readVUint32(_bp2 + off + _bs3, _bs3);
|
||||
size = (sb >> 1);
|
||||
}
|
||||
|
||||
if (_b1 < size)
|
||||
return false;
|
||||
data = data << size;
|
||||
bits = _b1 - size;
|
||||
|
||||
if ((_b3 & 7) == 0) {
|
||||
for (quint32 i = 0; i < (_b3 >> 3); i++) {
|
||||
str.append((quint8)sym);
|
||||
if (((quint8)sym == '\0'))
|
||||
return true;
|
||||
sym = sym >> 8;
|
||||
}
|
||||
} else {
|
||||
quint32 cnt = _b3;
|
||||
|
||||
if (ls <= _b3) {
|
||||
do {
|
||||
quint32 shift = ls;
|
||||
lo = sym << (8 - shift) | (quint32)((quint8)lo >> shift);
|
||||
sym = sym >> shift;
|
||||
str.append((uchar)lo);
|
||||
if (((uchar)lo == '\0'))
|
||||
return true;
|
||||
cnt = cnt - ls;
|
||||
ls = 8;
|
||||
} while (7 < cnt);
|
||||
ls = 8;
|
||||
}
|
||||
if (cnt != 0) {
|
||||
lo = sym << (8 - cnt) | (quint32)((quint8)lo >> cnt);
|
||||
ls = ls - cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
35
src/map/IMG/huffmantext.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef HUFFMANTEXT_H
|
||||
#define HUFFMANTEXT_H
|
||||
|
||||
#include "huffmanbuffer.h"
|
||||
|
||||
class HuffmanText
|
||||
{
|
||||
public:
|
||||
HuffmanText() : _buffer(0) {}
|
||||
|
||||
bool load(const RGNFile *rgn, SubFile::Handle &rgnHdl);
|
||||
bool decode(const SubFile *file, SubFile::Handle &hdl,
|
||||
QVector<quint8> &str) const;
|
||||
|
||||
private:
|
||||
bool fetch(const SubFile *file, SubFile::Handle &hdl, quint32 &data,
|
||||
quint32 &bits, quint32 &usedBits, quint32 &usedData) const;
|
||||
|
||||
HuffmanBuffer _buffer;
|
||||
|
||||
quint32 _b0;
|
||||
quint32 _b1;
|
||||
quint32 _b2;
|
||||
quint32 _b3;
|
||||
quint32 _vs;
|
||||
quint32 _bs3;
|
||||
quint32 _bs1;
|
||||
quint32 _mul;
|
||||
quint8 *_bp1;
|
||||
quint8 *_bp2;
|
||||
quint8 *_bp3;
|
||||
quint8 *_bp4;
|
||||
};
|
||||
|
||||
#endif // HUFFMANTEXT_H
|
@ -1,4 +1,6 @@
|
||||
#include <QTextCodec>
|
||||
#include "huffmantext.h"
|
||||
#include "rgnfile.h"
|
||||
#include "lblfile.h"
|
||||
|
||||
enum Charset {Normal, Symbol, Special};
|
||||
@ -55,21 +57,48 @@ static QString capitalized(const QString &str)
|
||||
}
|
||||
|
||||
|
||||
bool LBLFile::init(Handle &hdl)
|
||||
LBLFile::~LBLFile()
|
||||
{
|
||||
quint16 codepage;
|
||||
quint8 multiplier, poiMultiplier;
|
||||
delete _huffmanText;
|
||||
delete[] _table;
|
||||
}
|
||||
|
||||
if (!(seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
|
||||
&& readUInt32(hdl, _size) && readUInt8(hdl, multiplier)
|
||||
bool LBLFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
|
||||
{
|
||||
quint16 hdrLen, codepage;
|
||||
|
||||
if (!(seek(hdl, _gmpOffset) && readUInt16(hdl, hdrLen)
|
||||
&& seek(hdl, _gmpOffset + 0x15) && readUInt32(hdl, _offset)
|
||||
&& readUInt32(hdl, _size) && readUInt8(hdl, _multiplier)
|
||||
&& readUInt8(hdl, _encoding) && seek(hdl, _gmpOffset + 0x57)
|
||||
&& readUInt32(hdl, _poiOffset) && readUInt32(hdl, _poiSize)
|
||||
&& readUInt8(hdl, poiMultiplier) && seek(hdl, _gmpOffset + 0xAA)
|
||||
&& readUInt8(hdl, _poiMultiplier) && seek(hdl, _gmpOffset + 0xAA)
|
||||
&& readUInt16(hdl, codepage)))
|
||||
return false;
|
||||
|
||||
_multiplier = 1<<multiplier;
|
||||
_poiMultiplier = 1<<poiMultiplier;
|
||||
if (hdrLen >= 0x132) {
|
||||
quint32 offset, size;
|
||||
quint16 recordSize;
|
||||
if (!(seek(hdl, _gmpOffset + 0x124) && readUInt32(hdl, offset)
|
||||
&& readUInt32(hdl, size) && readUInt16(hdl, recordSize)))
|
||||
return false;
|
||||
|
||||
if (size && recordSize) {
|
||||
_table = new quint32[size / recordSize];
|
||||
if (!seek(hdl, offset))
|
||||
return false;
|
||||
for (quint32 i = 0; i < size / recordSize; i++) {
|
||||
if (!readVUInt32(hdl, recordSize, _table[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_encoding == 11) {
|
||||
_huffmanText = new HuffmanText();
|
||||
if (!_huffmanText->load(rgn, rgnHdl))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (codepage == 65001)
|
||||
_codec = QTextCodec::codecForName("UTF-8");
|
||||
@ -82,6 +111,14 @@ bool LBLFile::init(Handle &hdl)
|
||||
return true;
|
||||
}
|
||||
|
||||
void LBLFile::clear()
|
||||
{
|
||||
delete _huffmanText;
|
||||
delete[] _table;
|
||||
_huffmanText = 0;
|
||||
_table = 0;
|
||||
}
|
||||
|
||||
Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
{
|
||||
Label::Shield::Type shieldType = Label::Shield::None;
|
||||
@ -135,20 +172,16 @@ Label LBLFile::label6b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
}
|
||||
}
|
||||
|
||||
Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
Label LBLFile::str2label(const QVector<quint8> &str, bool capitalize) const
|
||||
{
|
||||
Label::Shield::Type shieldType = Label::Shield::None;
|
||||
QByteArray label, shieldLabel;
|
||||
QByteArray *bap = &label;
|
||||
quint8 c;
|
||||
|
||||
if (!seek(hdl, offset))
|
||||
return Label();
|
||||
for (int i = 0; i < str.size(); i++) {
|
||||
const quint8 &c = str.at(i);
|
||||
|
||||
while (true) {
|
||||
if (!readUInt8(hdl, c))
|
||||
return Label();
|
||||
if (!c || c == 0x1d)
|
||||
if (c == 0 || c == 0x1d)
|
||||
break;
|
||||
|
||||
if (c == 0x1c)
|
||||
@ -158,10 +191,10 @@ Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
bap = &label;
|
||||
else
|
||||
bap->append(' ');
|
||||
} else if (c <= 0x07) {
|
||||
} else if (c < 0x07) {
|
||||
shieldType = static_cast<Label::Shield::Type>(c);
|
||||
bap = &shieldLabel;
|
||||
} else if (bap == &shieldLabel && QChar(c).isSpace()) {
|
||||
} else if (bap == &shieldLabel && c == 0x20) {
|
||||
bap = &label;
|
||||
} else
|
||||
bap->append(c);
|
||||
@ -175,21 +208,74 @@ Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
Label::Shield(shieldType, shieldText));
|
||||
}
|
||||
|
||||
Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize)
|
||||
Label LBLFile::label8b(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
{
|
||||
if (!_multiplier && !init(hdl))
|
||||
return QString();
|
||||
QVector<quint8> str;
|
||||
quint8 c;
|
||||
|
||||
if (!seek(hdl, offset))
|
||||
return Label();
|
||||
|
||||
do {
|
||||
if (!readUInt8(hdl, c))
|
||||
return Label();
|
||||
str.append(c);
|
||||
} while (c);
|
||||
|
||||
return str2label(str, capitalize);
|
||||
}
|
||||
|
||||
Label LBLFile::labelHuffman(Handle &hdl, quint32 offset, bool capitalize) const
|
||||
{
|
||||
QVector<quint8> str;
|
||||
|
||||
if (!seek(hdl, offset))
|
||||
return Label();
|
||||
if (!_huffmanText->decode(this, hdl, str))
|
||||
return Label();
|
||||
if (!_table)
|
||||
return str2label(str, capitalize);
|
||||
|
||||
|
||||
QVector<quint8> str2;
|
||||
for (int i = 0; i < str.size(); i++) {
|
||||
quint32 val = _table[str.at(i)];
|
||||
if (val) {
|
||||
if (!seek(hdl, _offset + ((val & 0x7fffff) << _multiplier)))
|
||||
return Label();
|
||||
|
||||
if (str2.size() && str2.back() == '\0')
|
||||
str2[str2.size() - 1] = ' ';
|
||||
else if (str2.size())
|
||||
str2.append(' ');
|
||||
if (!_huffmanText->decode(this, hdl, str2))
|
||||
return Label();
|
||||
} else {
|
||||
if (str.at(i) == 7) {
|
||||
str2.append(0);
|
||||
break;
|
||||
}
|
||||
if (str2.size() && str2.back() == '\0')
|
||||
str2[str2.size() - 1] = ' ';
|
||||
str2.append(str.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
return str2label(str2, capitalize);
|
||||
}
|
||||
|
||||
Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize) const
|
||||
{
|
||||
quint32 labelOffset;
|
||||
if (poi) {
|
||||
quint32 poiOffset;
|
||||
if (!(_poiSize >= offset * _poiMultiplier
|
||||
&& seek(hdl, _poiOffset + offset * _poiMultiplier)
|
||||
if (!(_poiSize >= (offset << _poiMultiplier)
|
||||
&& seek(hdl, _poiOffset + (offset << _poiMultiplier))
|
||||
&& readUInt24(hdl, poiOffset) && (poiOffset & 0x3FFFFF)))
|
||||
return QString();
|
||||
labelOffset = _offset + (poiOffset & 0x3FFFFF) * _multiplier;
|
||||
labelOffset = _offset + ((poiOffset & 0x3FFFFF) << _multiplier);
|
||||
} else
|
||||
labelOffset = _offset + offset * _multiplier;
|
||||
labelOffset = _offset + (offset << _multiplier);
|
||||
|
||||
if (labelOffset > _offset + _size)
|
||||
return QString();
|
||||
@ -200,6 +286,8 @@ Label LBLFile::label(Handle &hdl, quint32 offset, bool poi, bool capitalize)
|
||||
case 9:
|
||||
case 10:
|
||||
return label8b(hdl, labelOffset, capitalize);
|
||||
case 11:
|
||||
return labelHuffman(hdl, labelOffset, capitalize);
|
||||
default:
|
||||
return Label();
|
||||
}
|
||||
|
@ -5,28 +5,40 @@
|
||||
#include "label.h"
|
||||
|
||||
class QTextCodec;
|
||||
class HuffmanText;
|
||||
class RGNFile;
|
||||
|
||||
class LBLFile : public SubFile
|
||||
{
|
||||
public:
|
||||
LBLFile(IMG *img)
|
||||
: SubFile(img), _codec(0), _offset(0), _size(0), _poiOffset(0),
|
||||
_poiSize(0), _poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
||||
LBLFile(const QString &path)
|
||||
: SubFile(path), _codec(0), _offset(0), _size(0), _poiOffset(0),
|
||||
_poiSize(0), _poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
||||
: SubFile(img), _huffmanText(0), _table(0), _codec(0), _offset(0),
|
||||
_size(0), _poiOffset(0), _poiSize(0), _poiMultiplier(0), _multiplier(0),
|
||||
_encoding(0) {}
|
||||
LBLFile(const QString *path)
|
||||
: SubFile(path), _huffmanText(0), _table(0), _codec(0), _offset(0),
|
||||
_size(0), _poiOffset(0), _poiSize(0), _poiMultiplier(0), _multiplier(0),
|
||||
_encoding(0) {}
|
||||
LBLFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
_codec(0), _offset(0), _size(0), _poiOffset(0), _poiSize(0),
|
||||
_poiMultiplier(0), _multiplier(0), _encoding(0) {}
|
||||
_huffmanText(0), _table(0), _codec(0), _offset(0), _size(0),
|
||||
_poiOffset(0), _poiSize(0), _poiMultiplier(0), _multiplier(0),
|
||||
_encoding(0) {}
|
||||
~LBLFile();
|
||||
|
||||
bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);
|
||||
void clear();
|
||||
|
||||
Label label(Handle &hdl, quint32 offset, bool poi = false,
|
||||
bool capitalize = true);
|
||||
bool capitalize = true) const;
|
||||
|
||||
private:
|
||||
bool init(Handle &hdl);
|
||||
|
||||
Label str2label(const QVector<quint8> &str, bool capitalize) const;
|
||||
Label label6b(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||
Label label8b(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||
Label labelHuffman(Handle &hdl, quint32 offset, bool capitalize) const;
|
||||
|
||||
HuffmanText *_huffmanText;
|
||||
quint32 *_table;
|
||||
|
||||
QTextCodec *_codec;
|
||||
quint32 _offset;
|
||||
|
@ -107,7 +107,7 @@ void MapData::load()
|
||||
else {
|
||||
QString typFile(ProgramPaths::typFile());
|
||||
if (!typFile.isEmpty()) {
|
||||
SubFile typ(typFile);
|
||||
SubFile typ(&typFile);
|
||||
_style = new Style(&typ);
|
||||
} else
|
||||
_style = new Style();
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
struct Poly {
|
||||
/* QPointF insted of Coordinates for performance reasons (no need to
|
||||
duplicate all the vectors for drawing). Note, that we do not want to
|
||||
ll2xy() the points in the IMG class as this can not be done in
|
||||
ll2xy() the points in the MapData class as this can not be done in
|
||||
parallel. */
|
||||
QVector<QPointF> points;
|
||||
Label label;
|
||||
@ -38,22 +38,12 @@ public:
|
||||
Coordinates coordinates;
|
||||
Label label;
|
||||
quint32 type;
|
||||
bool poi;
|
||||
quint64 id;
|
||||
|
||||
bool operator<(const Point &other) const
|
||||
{return id < other.id;}
|
||||
};
|
||||
|
||||
struct Polys {
|
||||
Polys() {}
|
||||
Polys(const QList<Poly> &polygons, const QList<Poly> &lines)
|
||||
: polygons(polygons), lines(lines) {}
|
||||
|
||||
QList<Poly> polygons;
|
||||
QList<Poly> lines;
|
||||
};
|
||||
|
||||
MapData();
|
||||
virtual ~MapData();
|
||||
|
||||
@ -88,15 +78,26 @@ protected:
|
||||
QString _errorString;
|
||||
|
||||
private:
|
||||
struct Polys {
|
||||
Polys() {}
|
||||
Polys(const QList<Poly> &polygons, const QList<Poly> &lines)
|
||||
: polygons(polygons), lines(lines) {}
|
||||
|
||||
QList<Poly> polygons;
|
||||
QList<Poly> lines;
|
||||
};
|
||||
|
||||
QCache<const SubDiv*, Polys> _polyCache;
|
||||
QCache<const SubDiv*, QList<Point> > _pointCache;
|
||||
|
||||
friend class VectorTile;
|
||||
friend class PolyCTX;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
inline QDebug operator<<(QDebug dbg, const MapData::Point &point)
|
||||
{
|
||||
dbg.nospace() << "Point(" << hex << point.type << ", " << point.label
|
||||
<< ", " << point.poi << ")";
|
||||
dbg.nospace() << "Point(" << hex << point.type << ", " << point.label << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "subdiv.h"
|
||||
#include "nodfile.h"
|
||||
#include "lblfile.h"
|
||||
#include "rgnfile.h"
|
||||
#include "netfile.h"
|
||||
|
||||
|
||||
@ -93,7 +94,7 @@ static bool seekToLine(BitStream4R &bs, quint8 line)
|
||||
}
|
||||
|
||||
static bool readLine(BitStream4R &bs, const SubDiv *subdiv,
|
||||
const HuffmanTable &table, IMG::Poly &poly)
|
||||
const HuffmanTable *table, MapData::Poly &poly)
|
||||
{
|
||||
quint32 v1, v2, v2b;
|
||||
if (!bs.readVuint32SM(v1, v2, v2b))
|
||||
@ -113,7 +114,7 @@ static bool readLine(BitStream4R &bs, const SubDiv *subdiv,
|
||||
poly.boundingRect = RectC(c, c);
|
||||
poly.points.append(QPointF(c.lon(), c.lat()));
|
||||
|
||||
HuffmanStreamR stream(bs, table);
|
||||
HuffmanStreamR stream(bs, *table);
|
||||
if (!stream.init())
|
||||
return false;
|
||||
qint32 lonDelta, latDelta;
|
||||
@ -132,8 +133,8 @@ static bool readLine(BitStream4R &bs, const SubDiv *subdiv,
|
||||
return stream.atEnd();
|
||||
}
|
||||
|
||||
static bool readNodeGeometry(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
NODFile::AdjacencyInfo &adj, IMG::Poly &poly, quint16 cnt = 0xFFFF)
|
||||
static bool readNodeGeometry(const NODFile *nod, SubFile::Handle &nodHdl,
|
||||
NODFile::AdjacencyInfo &adj, MapData::Poly &poly, quint16 cnt = 0xFFFF)
|
||||
{
|
||||
for (int i = 0; i <= cnt; i++) {
|
||||
int ret = nod->nextNode(nodHdl, adj);
|
||||
@ -151,7 +152,7 @@ static bool readNodeGeometry(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool skipNodes(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
static bool skipNodes(const NODFile *nod, SubFile::Handle &nodHdl,
|
||||
NODFile::AdjacencyInfo &adj, int cnt)
|
||||
{
|
||||
for (int i = 0; i < cnt; i++)
|
||||
@ -161,10 +162,10 @@ static bool skipNodes(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool readShape(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
NODFile::AdjacencyInfo &adj, BitStream4R &bs, const HuffmanTable &table,
|
||||
const SubDiv *subdiv, quint32 shift, IMG::Poly &poly, quint16 cnt = 0xFFFF,
|
||||
bool check = false)
|
||||
static bool readShape(const NODFile *nod, SubFile::Handle &nodHdl,
|
||||
NODFile::AdjacencyInfo &adj, BitStream4R &bs, const HuffmanTable *table,
|
||||
const SubDiv *subdiv, quint32 shift, MapData::Poly &poly,
|
||||
quint16 cnt = 0xFFFF, bool check = false)
|
||||
{
|
||||
quint32 v1, v2, v2b;
|
||||
if (!bs.readVuint32SM(v1, v2, v2b))
|
||||
@ -233,7 +234,7 @@ static bool readShape(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
}
|
||||
}
|
||||
|
||||
HuffmanStreamR stream(bs, table);
|
||||
HuffmanStreamR stream(bs, *table);
|
||||
if (!stream.init(lonSign, latSign, flags, extraBits))
|
||||
return false;
|
||||
qint32 lonDelta, latDelta;
|
||||
@ -345,36 +346,33 @@ static bool readShape(NODFile *nod, SubFile::Handle &nodHdl,
|
||||
}
|
||||
|
||||
|
||||
bool NETFile::linkLabel(Handle &hdl, quint32 offset, quint32 size, LBLFile *lbl,
|
||||
Handle &lblHdl, Label &label)
|
||||
NETFile::~NETFile()
|
||||
{
|
||||
delete _huffmanTable;
|
||||
}
|
||||
|
||||
bool NETFile::linkLabel(Handle &hdl, quint32 offset, quint32 size,
|
||||
const LBLFile *lbl, Handle &lblHdl, Label &label) const
|
||||
{
|
||||
if (!seek(hdl, offset))
|
||||
return false;
|
||||
BitStream1 bs(*this, hdl, size);
|
||||
|
||||
quint32 flags, b, labelPtr = 0;
|
||||
quint32 flags, labelPtr;
|
||||
if (!bs.read(8, flags))
|
||||
return false;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (!bs.read(8, b))
|
||||
return false;
|
||||
labelPtr |= (b << (i * 8));
|
||||
}
|
||||
if (!(flags & 1))
|
||||
return true;
|
||||
|
||||
if (lbl && (labelPtr & 0x3FFFFF)) {
|
||||
if (labelPtr & 0x400000) {
|
||||
quint32 lblOff;
|
||||
if (lblOffset(hdl, labelPtr & 0x3FFFFF, lblOff) && lblOff)
|
||||
label = lbl->label(lblHdl, lblOff);
|
||||
|
||||
} else
|
||||
label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
|
||||
}
|
||||
if (!bs.readUInt24(labelPtr))
|
||||
return false;
|
||||
if (labelPtr & 0x3FFFFF)
|
||||
label = lbl->label(lblHdl, labelPtr & 0x3FFFFF);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NETFile::init(Handle &hdl)
|
||||
bool NETFile::load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl)
|
||||
{
|
||||
quint16 hdrLen;
|
||||
|
||||
@ -387,31 +385,36 @@ bool NETFile::init(Handle &hdl)
|
||||
quint32 info;
|
||||
if (!(seek(hdl, _gmpOffset + 0x37) && readUInt32(hdl, info)))
|
||||
return false;
|
||||
_tableId = ((info >> 2) & 0xF);
|
||||
|
||||
if (!(seek(hdl, _gmpOffset + 0x43) && readUInt32(hdl, _linksOffset)
|
||||
&& readUInt32(hdl, _linksSize) && readUInt8(hdl, _linksShift)))
|
||||
return false;
|
||||
}
|
||||
|
||||
_init = true;
|
||||
quint8 tableId = ((info >> 2) & 0xF);
|
||||
if (_linksSize && (!rgn->huffmanTable() || rgn->huffmanTable()->id()
|
||||
!= tableId)) {
|
||||
_huffmanTable = new HuffmanTable(tableId);
|
||||
if (!_huffmanTable->load(rgn, rgnHdl))
|
||||
return false;
|
||||
}
|
||||
|
||||
_tp = _huffmanTable ? _huffmanTable : rgn->huffmanTable();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
NODFile *nod, Handle &nodHdl, LBLFile *lbl, Handle &lblHdl,
|
||||
const NODFile::BlockInfo blockInfo, quint8 linkId, quint8 lineId,
|
||||
const HuffmanTable &table, QList<IMG::Poly> *lines)
|
||||
void NETFile::clear()
|
||||
{
|
||||
if (!_init && !init(hdl))
|
||||
return false;
|
||||
delete _huffmanTable;
|
||||
_huffmanTable = 0;
|
||||
}
|
||||
|
||||
Q_ASSERT(_tableId == table.id());
|
||||
if (_tableId != table.id())
|
||||
return false;
|
||||
|
||||
IMG::Poly poly;
|
||||
bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
const NODFile *nod, Handle &nodHdl, const LBLFile *lbl, Handle &lblHdl,
|
||||
const NODFile::BlockInfo &blockInfo, quint8 linkId, quint8 lineId,
|
||||
QList<MapData::Poly> *lines) const
|
||||
{
|
||||
MapData::Poly poly;
|
||||
if (!nod->linkType(nodHdl, blockInfo, linkId, poly.type))
|
||||
return false;
|
||||
|
||||
@ -447,7 +450,7 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
|
||||
if (s69 == 1) {
|
||||
if (s68 == 1) {
|
||||
if (!readShape(nod, nodHdl, adj, bs, table, subdiv, shift, poly))
|
||||
if (!readShape(nod, nodHdl, adj, bs, _tp, subdiv, shift, poly))
|
||||
return false;
|
||||
} else {
|
||||
if (!readNodeGeometry(nod, nodHdl, adj, poly))
|
||||
@ -461,7 +464,7 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
if (i == lineId) {
|
||||
if (shape) {
|
||||
bool check = (i < ca.size()) ? (ca.at(i) & mask) : false;
|
||||
if (!readShape(nod, nodHdl, adj, bs, table, subdiv,
|
||||
if (!readShape(nod, nodHdl, adj, bs, _tp, subdiv,
|
||||
shift, poly, step, check))
|
||||
return false;
|
||||
} else {
|
||||
@ -485,23 +488,21 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
return false;
|
||||
if (!seekToLine(bs, lineId))
|
||||
return false;
|
||||
if (!readLine(bs, subdiv, table, poly))
|
||||
if (!readLine(bs, subdiv, _tp, poly))
|
||||
return false;
|
||||
}
|
||||
|
||||
linkLabel(hdl, linkOffset, _linksSize - (linkOffset - _linksOffset), lbl,
|
||||
lblHdl, poly.label);
|
||||
if (lbl)
|
||||
linkLabel(hdl, linkOffset, _linksSize - (linkOffset - _linksOffset),
|
||||
lbl, lblHdl, poly.label);
|
||||
|
||||
lines->append(poly);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NETFile::lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset)
|
||||
bool NETFile::lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset) const
|
||||
{
|
||||
if (!_init && !init(hdl))
|
||||
return false;
|
||||
|
||||
if (!(seek(hdl, _offset + (netOffset << _shift))
|
||||
&& readUInt24(hdl, lblOffset)))
|
||||
return false;
|
||||
|
@ -1,42 +1,44 @@
|
||||
#ifndef NETFILE_H
|
||||
#define NETFILE_H
|
||||
|
||||
#include "img.h"
|
||||
#include "subfile.h"
|
||||
#include "nodfile.h"
|
||||
|
||||
class NODFile;
|
||||
class LBLFile;
|
||||
class RGNFile;
|
||||
class SubDiv;
|
||||
class HuffmanTable;
|
||||
|
||||
class NETFile : public SubFile
|
||||
{
|
||||
public:
|
||||
NETFile(IMG *img) : SubFile(img), _offset(0), _size(0), _linksOffset(0),
|
||||
_linksSize(0), _shift(0), _linksShift(0), _init(false) {}
|
||||
NETFile(const QString &path) : SubFile(path), _offset(0), _size(0),
|
||||
_linksOffset(0), _linksSize(0), _shift(0), _linksShift(0),
|
||||
_init(false) {}
|
||||
NETFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
NETFile(IMG *img) : SubFile(img), _huffmanTable(0), _tp(0), _offset(0),
|
||||
_size(0), _linksOffset(0), _linksSize(0), _shift(0), _linksShift(0) {}
|
||||
NETFile(const QString *path) : SubFile(path), _huffmanTable(0), _tp(0),
|
||||
_offset(0), _size(0), _linksOffset(0), _linksSize(0), _shift(0),
|
||||
_linksShift(0), _init(false) {}
|
||||
_linksShift(0) {}
|
||||
NETFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
_huffmanTable(0), _tp(0), _offset(0), _size(0), _linksOffset(0),
|
||||
_linksSize(0), _shift(0), _linksShift(0) {}
|
||||
~NETFile();
|
||||
|
||||
bool lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset);
|
||||
bool link(const SubDiv *subdiv, quint32 shift, Handle &hdl, NODFile *nod,
|
||||
Handle &nodHdl, LBLFile *lbl, Handle &lblHdl,
|
||||
const NODFile::BlockInfo blockInfo, quint8 linkId, quint8 lineId,
|
||||
const HuffmanTable &table, QList<IMG::Poly> *lines);
|
||||
bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);
|
||||
void clear();
|
||||
|
||||
bool lblOffset(Handle &hdl, quint32 netOffset, quint32 &lblOffset) const;
|
||||
bool link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
const NODFile *nod, Handle &nodHdl, const LBLFile *lbl, Handle &lblHdl,
|
||||
const NODFile::BlockInfo &blockInfo, quint8 linkId, quint8 lineId,
|
||||
QList<MapData::Poly> *lines) const;
|
||||
|
||||
private:
|
||||
bool init(Handle &hdl);
|
||||
bool linkLabel(Handle &hdl, quint32 offset, quint32 size, LBLFile *lbl,
|
||||
Handle &lblHdl, Label &label);
|
||||
bool linkLabel(Handle &hdl, quint32 offset, quint32 size,
|
||||
const LBLFile *lbl, Handle &lblHdl, Label &label) const;
|
||||
|
||||
HuffmanTable *_huffmanTable;
|
||||
const HuffmanTable *_tp;
|
||||
quint32 _offset, _size, _linksOffset, _linksSize;
|
||||
quint8 _shift, _linksShift;
|
||||
quint8 _tableId;
|
||||
bool _init;
|
||||
};
|
||||
|
||||
#endif // NETFILE_H
|
||||
|
@ -81,14 +81,14 @@ static bool skipOptAdjData(BitStream1 &bs)
|
||||
}
|
||||
|
||||
|
||||
bool NODFile::init(Handle &hdl)
|
||||
bool NODFile::load(Handle &hdl)
|
||||
{
|
||||
quint16 hdrLen;
|
||||
|
||||
if (!(seek(hdl, _gmpOffset) && readUInt16(hdl, hdrLen)))
|
||||
return false;
|
||||
if (hdrLen < 0x7b)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
if (!(seek(hdl, _gmpOffset + 0x1d) && readUInt32(hdl, _flags)
|
||||
&& readUInt8(hdl, _blockShift) && readUInt8(hdl, _nodeShift)))
|
||||
@ -113,14 +113,6 @@ bool NODFile::init(Handle &hdl)
|
||||
return (_indexIdSize > 0);
|
||||
}
|
||||
|
||||
quint32 NODFile::indexIdSize(Handle &hdl)
|
||||
{
|
||||
if (!_indexIdSize && !init(hdl))
|
||||
return 0;
|
||||
|
||||
return _indexIdSize;
|
||||
}
|
||||
|
||||
bool NODFile::readBlock(Handle &hdl, quint32 blockOffset,
|
||||
BlockInfo &blockInfo) const
|
||||
{
|
||||
@ -494,7 +486,7 @@ bool NODFile::relAdjInfo(Handle &hdl, AdjacencyInfo &adj) const
|
||||
return true;
|
||||
}
|
||||
|
||||
int NODFile::nextNode(Handle &hdl, AdjacencyInfo &adjInfo)
|
||||
int NODFile::nextNode(Handle &hdl, AdjacencyInfo &adjInfo) const
|
||||
{
|
||||
if (adjInfo.nodeOffset == 0xFFFFFFFF)
|
||||
return 1;
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef NODFILE_H
|
||||
#define NODFILE_H
|
||||
|
||||
#include "img.h"
|
||||
#include "subfile.h"
|
||||
|
||||
class NODFile : public SubFile
|
||||
@ -57,7 +56,7 @@ public:
|
||||
NODFile(IMG *img) : SubFile(img), _indexOffset(0), _indexSize(0),
|
||||
_indexFlags(0), _blockOffset(0), _blockSize(0), _indexRecordSize(0),
|
||||
_blockRecordSize(0), _blockShift(0), _nodeShift(0), _indexIdSize(0) {}
|
||||
NODFile(const QString &path) : SubFile(path), _indexOffset(0), _indexSize(0),
|
||||
NODFile(const QString *path) : SubFile(path), _indexOffset(0), _indexSize(0),
|
||||
_indexFlags(0), _blockOffset(0), _blockSize(0), _indexRecordSize(0),
|
||||
_blockRecordSize(0), _blockShift(0), _nodeShift(0), _indexIdSize(0) {}
|
||||
NODFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
@ -65,16 +64,17 @@ public:
|
||||
_blockSize(0), _indexRecordSize(0), _blockRecordSize(0), _blockShift(0),
|
||||
_nodeShift(0), _indexIdSize(0) {}
|
||||
|
||||
quint32 indexIdSize(Handle &hdl);
|
||||
bool load(Handle &hdl);
|
||||
|
||||
quint32 indexIdSize() const {return _indexIdSize;}
|
||||
bool blockInfo(Handle &hdl, quint32 blockId, BlockInfo &blockInfo) const;
|
||||
bool linkInfo(Handle &hdl, const BlockInfo &blockInfo, quint32 linkId,
|
||||
LinkInfo &linkInfo) const;
|
||||
bool linkType(Handle &hdl, const BlockInfo &blockInfo, quint8 linkId,
|
||||
quint32 &type) const;
|
||||
int nextNode(Handle &hdl, AdjacencyInfo &adjInfo);
|
||||
int nextNode(Handle &hdl, AdjacencyInfo &adjInfo) const;
|
||||
|
||||
private:
|
||||
bool init(Handle &hdl);
|
||||
bool nodeInfo(Handle &hdl, const BlockInfo &blockInfo, quint32 nodeOffset,
|
||||
NodeInfo &nodeInfo) const;
|
||||
bool nodeOffset(Handle &hdl, const BlockInfo &blockInfo, quint8 nodeId,
|
||||
|
@ -28,7 +28,7 @@ static int minPOIZoom(Style::POIClass cl)
|
||||
case Style::Food:
|
||||
case Style::Shopping:
|
||||
case Style::Services:
|
||||
return 27;
|
||||
return 26;
|
||||
case Style::Accommodation:
|
||||
case Style::Recreation:
|
||||
return 25;
|
||||
@ -237,10 +237,28 @@ void RasterTile::drawTextItems(QPainter *painter,
|
||||
textItems.at(i)->paint(painter);
|
||||
}
|
||||
|
||||
static void removeDuplicitLabel(QList<TextItem *> &labels, const QString &text,
|
||||
const QRectF &tileRect)
|
||||
{
|
||||
for (int i = 0; i < labels.size(); i++) {
|
||||
TextItem *item = labels.at(i);
|
||||
if (tileRect.contains(item->boundingRect()) && *(item->text()) == text) {
|
||||
labels.removeAt(i);
|
||||
delete item;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
||||
{
|
||||
QRectF tileRect(_xy, _img.size());
|
||||
QSet<QString> set;
|
||||
QList<TextItem *> labels;
|
||||
|
||||
for (int i = 0; i < _polygons.size(); i++) {
|
||||
MapData::Poly &poly = _polygons[i];
|
||||
bool exists = set.contains(poly.label.text());
|
||||
|
||||
if (poly.label.text().isEmpty())
|
||||
continue;
|
||||
@ -253,12 +271,20 @@ void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
||||
centroid(poly.points).toPoint(), &poly.label.text(),
|
||||
poiFont(), 0, &style.brush().color());
|
||||
if (item->isValid() && !item->collides(textItems)
|
||||
&& rectNearPolygon(poly.points, item->boundingRect()))
|
||||
textItems.append(item);
|
||||
else
|
||||
&& !item->collides(labels)
|
||||
&& !(exists && tileRect.contains(item->boundingRect()))
|
||||
&& rectNearPolygon(poly.points, item->boundingRect())) {
|
||||
if (exists)
|
||||
removeDuplicitLabel(labels, poly.label.text(), tileRect);
|
||||
else
|
||||
set.insert(poly.label.text());
|
||||
labels.append(item);
|
||||
} else
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
textItems.append(labels);
|
||||
}
|
||||
|
||||
void RasterTile::processLines(QList<TextItem*> &textItems)
|
||||
@ -372,14 +398,15 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
|
||||
for (int i = 0; i < _points.size(); i++) {
|
||||
MapData::Point &point = _points[i];
|
||||
const Style::Point &style = _style->point(point.type);
|
||||
bool poi = Style::isPOI(point.type);
|
||||
|
||||
if (point.poi && _zoom < minPOIZoom(Style::poiClass(point.type)))
|
||||
if (poi && _zoom < minPOIZoom(Style::poiClass(point.type)))
|
||||
continue;
|
||||
|
||||
const QString *label = point.label.text().isEmpty()
|
||||
? 0 : &(point.label.text());
|
||||
const QImage *img = style.img().isNull() ? 0 : &style.img();
|
||||
const QFont *fnt = point.poi
|
||||
const QFont *fnt = poi
|
||||
? poiFont(style.textFontSize()) : font(style.textFontSize());
|
||||
const QColor *color = style.textColor().isValid()
|
||||
? &style.textColor() : 0;
|
||||
|
@ -24,6 +24,11 @@ static quint64 pointId(const QPoint &pos, quint32 type, quint32 labelPtr)
|
||||
return id;
|
||||
}
|
||||
|
||||
RGNFile::~RGNFile()
|
||||
{
|
||||
delete _huffmanTable;
|
||||
}
|
||||
|
||||
bool RGNFile::skipClassFields(Handle &hdl) const
|
||||
{
|
||||
quint8 flags;
|
||||
@ -96,7 +101,7 @@ bool RGNFile::skipGblFields(Handle &hdl, quint32 flags) const
|
||||
return seek(hdl, pos(hdl) + cnt);
|
||||
}
|
||||
|
||||
bool RGNFile::init(Handle &hdl)
|
||||
bool RGNFile::load(Handle &hdl)
|
||||
{
|
||||
quint16 hdrLen;
|
||||
|
||||
@ -125,24 +130,29 @@ bool RGNFile::init(Handle &hdl)
|
||||
}
|
||||
|
||||
if (hdrLen >= 0x7D) {
|
||||
quint32 dictOffset, dictSize, info;
|
||||
if (!(seek(hdl, _gmpOffset + 0x71) && readUInt32(hdl, dictOffset)
|
||||
&& readUInt32(hdl, dictSize) && readUInt32(hdl, info)))
|
||||
quint32 info;
|
||||
if (!(seek(hdl, _gmpOffset + 0x71) && readUInt32(hdl, _dictOffset)
|
||||
&& readUInt32(hdl, _dictSize) && readUInt32(hdl, info)))
|
||||
return false;
|
||||
|
||||
if (dictSize && dictOffset && (info & 0x1E))
|
||||
if (!_huffmanTable.load(*this, hdl, dictOffset, dictSize,
|
||||
((info >> 1) & 0xF) - 1))
|
||||
if (_dictSize && _dictOffset && (info & 0x1E)) {
|
||||
_huffmanTable = new HuffmanTable(((info >> 1) & 0xF) - 1);
|
||||
if (!_huffmanTable->load(this, hdl))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_init = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RGNFile::clear()
|
||||
{
|
||||
delete _huffmanTable;
|
||||
_huffmanTable = 0;
|
||||
}
|
||||
|
||||
bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl, NETFile *net,
|
||||
Handle &netHdl, QList<IMG::Poly> *polys) const
|
||||
{
|
||||
const SubDiv::Segment &segment = (segmentType == Line)
|
||||
@ -218,7 +228,7 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
}
|
||||
|
||||
bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
|
||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Poly> *polys) const
|
||||
{
|
||||
quint32 labelPtr, len;
|
||||
@ -246,13 +256,13 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
poly.type = 0x10000 | (quint16(type)<<8) | (subtype & 0x1F);
|
||||
labelPtr = 0;
|
||||
|
||||
if (!_huffmanTable.isNull()) {
|
||||
if (_huffmanTable) {
|
||||
pos = QPoint(LS(subdiv->lon(), 8) + LS(lon, 32-subdiv->bits()),
|
||||
LS(subdiv->lat(), 8) + LS(lat, (32-subdiv->bits())));
|
||||
|
||||
qint32 lonDelta, latDelta;
|
||||
BitStream4F bs(*this, hdl, len);
|
||||
HuffmanStreamF stream(bs, _huffmanTable);
|
||||
HuffmanStreamF stream(bs, *_huffmanTable);
|
||||
if (!stream.init(segmentType == Line))
|
||||
return false;
|
||||
|
||||
@ -329,7 +339,7 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
}
|
||||
|
||||
bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
|
||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Point> *points) const
|
||||
{
|
||||
const SubDiv::Segment &segment = (segmentType == IndexedPoint)
|
||||
@ -362,11 +372,9 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
point.type = (quint16)type<<8 | subtype;
|
||||
point.coordinates = Coordinates(toWGS24(pos.x()), toWGS24(pos.y()));
|
||||
point.id = pointId(pos, point.type, labelPtr & 0x3FFFFF);
|
||||
point.poi = labelPtr & 0x400000;
|
||||
if (lbl && (labelPtr & 0x3FFFFF))
|
||||
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi,
|
||||
!(point.type == 0x1400 || point.type == 0x1500
|
||||
|| point.type == 0x1e00));
|
||||
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, labelPtr & 0x400000,
|
||||
!(point.type == 0x1400 || point.type == 0x1500 || point.type == 0x1e00));
|
||||
|
||||
points->append(point);
|
||||
}
|
||||
@ -374,11 +382,12 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
|
||||
Handle &lblHdl, QList<IMG::Point> *points) const
|
||||
bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<IMG::Point> *points) const
|
||||
{
|
||||
const SubDiv::Segment &segment = subdiv->extPoints();
|
||||
|
||||
|
||||
if (!segment.isValid())
|
||||
return true;
|
||||
if (!seek(hdl, segment.offset()))
|
||||
@ -414,9 +423,8 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
|
||||
|
||||
point.coordinates = Coordinates(toWGS24(pos.x()), toWGS24(pos.y()));
|
||||
point.id = pointId(pos, point.type, labelPtr & 0x3FFFFF);
|
||||
point.poi = labelPtr & 0x400000;
|
||||
if (lbl && (labelPtr & 0x3FFFFF))
|
||||
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, point.poi);
|
||||
point.label = lbl->label(lblHdl, labelPtr & 0x3FFFFF, false);
|
||||
|
||||
points->append(point);
|
||||
}
|
||||
@ -425,30 +433,27 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
|
||||
}
|
||||
|
||||
bool RGNFile::links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
NETFile *net, Handle &netHdl, NODFile *nod, Handle &nodHdl, LBLFile *lbl,
|
||||
Handle &lblHdl, QList<IMG::Poly> *lines) const
|
||||
const NETFile *net, Handle &netHdl, const NODFile *nod, Handle &nodHdl,
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<IMG::Poly> *lines) const
|
||||
{
|
||||
quint32 size, blockIndexIdSize, blockIndexId;
|
||||
quint32 size, blockIndexId;
|
||||
quint8 flags;
|
||||
const SubDiv::Segment &segment = subdiv->roadReferences();
|
||||
|
||||
if (!net || !nod)
|
||||
return false;
|
||||
if (!segment.isValid())
|
||||
return true;
|
||||
if (!seek(hdl, segment.offset()))
|
||||
return false;
|
||||
|
||||
if (!net || !nod)
|
||||
return false;
|
||||
if (!(blockIndexIdSize = nod->indexIdSize(nodHdl)))
|
||||
return false;
|
||||
|
||||
while (pos(hdl) < segment.end()) {
|
||||
if (!readVUInt32(hdl, size))
|
||||
return false;
|
||||
|
||||
quint32 entryStart = pos(hdl);
|
||||
|
||||
if (!(readUInt8(hdl, flags) && readVUInt32(hdl, blockIndexIdSize,
|
||||
if (!(readUInt8(hdl, flags) && readVUInt32(hdl, nod->indexIdSize(),
|
||||
blockIndexId)))
|
||||
return false;
|
||||
|
||||
@ -496,10 +501,11 @@ bool RGNFile::links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
}
|
||||
|
||||
net->link(subdiv, shift, netHdl, nod, nodHdl, lbl, lblHdl,
|
||||
blockInfo, linkId, lineId, _huffmanTable, lines);
|
||||
blockInfo, linkId, lineId, lines);
|
||||
}
|
||||
|
||||
Q_ASSERT(entryStart + size == pos(hdl));
|
||||
if (entryStart + size != pos(hdl))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -548,7 +554,7 @@ QMap<RGNFile::SegmentType, SubDiv::Segment> RGNFile::segments(Handle &hdl,
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RGNFile::subdivInit(Handle &hdl, SubDiv *subdiv) const
|
||||
bool RGNFile::subdivInit(Handle &hdl, SubDiv *subdiv)
|
||||
{
|
||||
QMap<RGNFile::SegmentType, SubDiv::Segment> seg(segments(hdl, subdiv));
|
||||
SubDiv::Segment extPoints, extLines, extPolygons;
|
||||
|
@ -1,14 +1,13 @@
|
||||
#ifndef RGNFILE_H
|
||||
#define RGNFILE_H
|
||||
|
||||
#include "img.h"
|
||||
#include "subfile.h"
|
||||
#include "subdiv.h"
|
||||
#include "huffmantable.h"
|
||||
|
||||
class LBLFile;
|
||||
class NETFile;
|
||||
class NODFile;
|
||||
class HuffmanTable;
|
||||
|
||||
class RGNFile : public SubFile
|
||||
{
|
||||
@ -22,35 +21,41 @@ public:
|
||||
};
|
||||
|
||||
RGNFile(IMG *img)
|
||||
: SubFile(img), _offset(0), _size(0), _polygonsOffset(0),
|
||||
: SubFile(img), _huffmanTable(0), _offset(0), _size(0), _polygonsOffset(0),
|
||||
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
|
||||
_pointsSize(0), _init(false) {}
|
||||
RGNFile(const QString &path)
|
||||
: SubFile(path), _offset(0), _size(0), _polygonsOffset(0),
|
||||
_pointsSize(0) {}
|
||||
RGNFile(const QString *path)
|
||||
: SubFile(path), _huffmanTable(0), _offset(0), _size(0), _polygonsOffset(0),
|
||||
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
|
||||
_pointsSize(0), _init(false) {}
|
||||
RGNFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset), _offset(0),
|
||||
_size(0), _polygonsOffset(0), _polygonsSize(0), _linesOffset(0),
|
||||
_linesSize(0), _pointsOffset(0), _pointsSize(0), _init(false) {}
|
||||
_pointsSize(0) {}
|
||||
RGNFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset),
|
||||
_huffmanTable(0), _offset(0), _size(0), _polygonsOffset(0),
|
||||
_polygonsSize(0), _linesOffset(0), _linesSize(0), _pointsOffset(0),
|
||||
_pointsSize(0) {}
|
||||
~RGNFile();
|
||||
|
||||
bool initialized() const {return _init;}
|
||||
bool init(Handle &hdl);
|
||||
void clear();
|
||||
bool load(Handle &hdl);
|
||||
|
||||
bool polyObjects(Handle &hdl, const SubDiv *subdiv, SegmentType segmentType,
|
||||
LBLFile *lbl, Handle &lblHdl, NETFile *net, Handle &netHdl,
|
||||
QList<IMG::Poly> *polys) const;
|
||||
const LBLFile *lbl, Handle &lblHdl, NETFile *net, Handle &netHdl,
|
||||
QList<MapData::Poly> *polys) const;
|
||||
bool pointObjects(Handle &hdl, const SubDiv *subdiv, SegmentType segmentType,
|
||||
LBLFile *lbl, Handle &lblHdl, QList<IMG::Point> *points) const;
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<MapData::Point> *points) const;
|
||||
bool extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
SegmentType segmentType, LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Poly> *polys) const;
|
||||
bool extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
|
||||
Handle &lblHdl, QList<IMG::Point> *points) const;
|
||||
bool links(Handle &hdl, const SubDiv *subdiv, quint32 shift, NETFile *net,
|
||||
Handle &netHdl, NODFile *nod, Handle &nodHdl, LBLFile *lbl, Handle &lblHdl,
|
||||
QList<IMG::Poly> *lines) const;
|
||||
SegmentType segmentType, const LBLFile *lbl, Handle &lblHdl,
|
||||
QList<MapData::Poly> *polys) const;
|
||||
bool extPointObjects(Handle &hdl, const SubDiv *subdiv, const LBLFile *lbl,
|
||||
Handle &lblHdl, QList<MapData::Point> *points) const;
|
||||
bool links(Handle &hdl, const SubDiv *subdiv, quint32 shift,
|
||||
const NETFile *net, Handle &netHdl, const NODFile *nod, Handle &nodHdl,
|
||||
const LBLFile *lbl, Handle &lblHdl, QList<MapData::Poly> *lines) const;
|
||||
|
||||
bool subdivInit(Handle &hdl, SubDiv *subdiv) const;
|
||||
bool subdivInit(Handle &hdl, SubDiv *subdiv);
|
||||
|
||||
const HuffmanTable *huffmanTable() const {return _huffmanTable;}
|
||||
quint32 dictOffset() const {return _dictOffset;}
|
||||
quint32 dictSize() const {return _dictSize;}
|
||||
|
||||
private:
|
||||
QMap<SegmentType, SubDiv::Segment> segments(Handle &hdl, SubDiv *subdiv)
|
||||
@ -60,8 +65,12 @@ private:
|
||||
const;
|
||||
bool skipGblFields(Handle &hdl, quint32 flags) const;
|
||||
|
||||
HuffmanTable *_huffmanTable;
|
||||
|
||||
quint32 _offset;
|
||||
quint32 _size;
|
||||
quint32 _dictOffset;
|
||||
quint32 _dictSize;
|
||||
|
||||
quint32 _polygonsOffset;
|
||||
quint32 _polygonsSize;
|
||||
@ -75,10 +84,6 @@ private:
|
||||
quint32 _pointsSize;
|
||||
quint32 _pointsLclFlags[3];
|
||||
quint32 _pointsGblFlags;
|
||||
|
||||
HuffmanTable _huffmanTable;
|
||||
|
||||
bool _init;
|
||||
};
|
||||
|
||||
#endif // RGNFILE_H
|
||||
|
@ -39,9 +39,7 @@ void Style::defaultPolygonStyle()
|
||||
_polygons[TYPE(0x1f)] = Polygon(QBrush(QColor("#9ac269"),
|
||||
Qt::BDiagPattern));
|
||||
_polygons[TYPE(0x28)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x29)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x32)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x3b)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x3c)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x3d)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x3e)] = Polygon(QBrush("#9fc4e1"));
|
||||
@ -51,13 +49,12 @@ void Style::defaultPolygonStyle()
|
||||
_polygons[TYPE(0x42)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x43)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x44)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x45)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x46)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x47)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x48)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x49)] = Polygon(QBrush("#9fc4e1"));
|
||||
_polygons[TYPE(0x4b)] = Polygon(QBrush("#f1f0e5"), QPen("#f1f0e5"));
|
||||
_polygons[TYPE(0x4a)] = Polygon(QBrush("#f1f0e5"), QPen("#f1f0e5"));
|
||||
_polygons[TYPE(0x4b)] = Polygon(QBrush("#f1f0e5"), QPen("#f1f0e5"));
|
||||
_polygons[TYPE(0x4c)] = Polygon(QBrush("#9fc4e1", Qt::Dense6Pattern));
|
||||
_polygons[TYPE(0x4d)] = Polygon(QBrush("#ddf1fd"));
|
||||
_polygons[TYPE(0x4e)] = Polygon(QBrush("#f8f8f8"));
|
||||
@ -66,18 +63,73 @@ void Style::defaultPolygonStyle()
|
||||
_polygons[TYPE(0x51)] = Polygon(QBrush("#9fc4e1", Qt::Dense4Pattern));
|
||||
_polygons[TYPE(0x52)] = Polygon(QBrush("#cadfaf"));
|
||||
|
||||
_drawOrder << TYPE(0x4b) << TYPE(0x4a) << TYPE(0x01) << TYPE(0x02)
|
||||
<< TYPE(0x03) << TYPE(0x17) << TYPE(0x18) << TYPE(0x1a) << TYPE(0x28)
|
||||
<< TYPE(0x29) << TYPE(0x32) << TYPE(0x3b) << TYPE(0x3c) << TYPE(0x3d)
|
||||
<< TYPE(0x3e) << TYPE(0x3f) << TYPE(0x40) << TYPE(0x41) << TYPE(0x42)
|
||||
<< TYPE(0x43) << TYPE(0x44) << TYPE(0x45) << TYPE(0x46) << TYPE(0x47)
|
||||
<< TYPE(0x48) << TYPE(0x49) << TYPE(0x4c) << TYPE(0x4d) << TYPE(0x4e)
|
||||
<< TYPE(0x4f) << TYPE(0x50) << TYPE(0x51) << TYPE(0x52) << TYPE(0x14)
|
||||
<< TYPE(0x15) << TYPE(0x16) << TYPE(0x1e) << TYPE(0x1f) << TYPE(0x04)
|
||||
<< TYPE(0x05) << TYPE(0x06) << TYPE(0x07) << TYPE(0x08) << TYPE(0x09)
|
||||
<< TYPE(0x0a) << TYPE(0x0b) << TYPE(0x0c) << TYPE(0x0d) << TYPE(0x0e)
|
||||
<< TYPE(0x0f) << TYPE(0x10) << TYPE(0x11) << TYPE(0x12) << TYPE(0x19)
|
||||
<< TYPE(0x13);
|
||||
// NT types
|
||||
_polygons[0x10800] = _polygons[TYPE(0x01)];
|
||||
_polygons[0x10801] = _polygons[TYPE(0x02)];
|
||||
_polygons[0x10802] = _polygons[TYPE(0x03)];
|
||||
_polygons[0x10901] = _polygons[TYPE(0x04)];
|
||||
_polygons[0x10902] = _polygons[TYPE(0x05)];
|
||||
_polygons[0x10903] = _polygons[TYPE(0x06)];
|
||||
_polygons[0x10904] = _polygons[TYPE(0x07)];
|
||||
_polygons[0x10905] = _polygons[TYPE(0x08)];
|
||||
_polygons[0x10906] = _polygons[TYPE(0x09)];
|
||||
_polygons[0x10907] = _polygons[TYPE(0x0a)];
|
||||
_polygons[0x10908] = _polygons[TYPE(0x0b)];
|
||||
_polygons[0x10909] = _polygons[TYPE(0x0c)];
|
||||
_polygons[0x1090a] = _polygons[TYPE(0x0d)];
|
||||
_polygons[0x1090b] = _polygons[TYPE(0x0e)];
|
||||
_polygons[0x10900] = _polygons[TYPE(0x13)];
|
||||
_polygons[0x10a01] = _polygons[TYPE(0x14)];
|
||||
_polygons[0x10a02] = _polygons[TYPE(0x15)];
|
||||
_polygons[0x10a03] = _polygons[TYPE(0x16)];
|
||||
_polygons[0x10a04] = _polygons[TYPE(0x17)];
|
||||
_polygons[0x1090c] = _polygons[TYPE(0x18)];
|
||||
_polygons[0x1090d] = _polygons[TYPE(0x19)];
|
||||
_polygons[0x1090e] = _polygons[TYPE(0x1a)];
|
||||
_polygons[0x10a05] = _polygons[TYPE(0x1e)];
|
||||
_polygons[0x10a06] = _polygons[TYPE(0x1f)];
|
||||
_polygons[0x10b01] = _polygons[TYPE(0x28)];
|
||||
_polygons[0x10b02] = _polygons[TYPE(0x32)];
|
||||
_polygons[0x10b03] = _polygons[TYPE(0x3c)];
|
||||
_polygons[0x10b04] = _polygons[TYPE(0x3d)];
|
||||
_polygons[0x10b05] = _polygons[TYPE(0x3e)];
|
||||
_polygons[0x10b06] = _polygons[TYPE(0x3f)];
|
||||
_polygons[0x10b07] = _polygons[TYPE(0x40)];
|
||||
_polygons[0x10b08] = _polygons[TYPE(0x41)];
|
||||
_polygons[0x10b09] = _polygons[TYPE(0x42)];
|
||||
_polygons[0x10b0a] = _polygons[TYPE(0x43)];
|
||||
_polygons[0x10b0b] = _polygons[TYPE(0x44)];
|
||||
_polygons[0x10b0c] = _polygons[TYPE(0x46)];
|
||||
_polygons[0x10b0d] = _polygons[TYPE(0x47)];
|
||||
_polygons[0x10b0e] = _polygons[TYPE(0x48)];
|
||||
_polygons[0x10b0f] = _polygons[TYPE(0x49)];
|
||||
_polygons[0x10d01] = _polygons[TYPE(0x4b)];
|
||||
_polygons[0x10b10] = _polygons[TYPE(0x4c)];
|
||||
_polygons[0x10c00] = _polygons[TYPE(0x4d)];
|
||||
_polygons[0x10c01] = _polygons[TYPE(0x4e)];
|
||||
_polygons[0x10c02] = _polygons[TYPE(0x4f)];
|
||||
_polygons[0x10c03] = _polygons[TYPE(0x50)];
|
||||
_polygons[0x10c04] = _polygons[TYPE(0x51)];
|
||||
_polygons[0x10c05] = _polygons[TYPE(0x52)];
|
||||
|
||||
// Draw order
|
||||
_drawOrder << TYPE(0x4b) << 0x10d01 << 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
|
||||
<< TYPE(0x3e) << 0x10b05 << TYPE(0x3f) << 0x10b06 << TYPE(0x40) << 0x10b07
|
||||
<< TYPE(0x41) << 0x10b08 << TYPE(0x42) << 0x10b09 << TYPE(0x43) << 0x10b0a
|
||||
<< TYPE(0x44) << 0x10b0b << TYPE(0x46) << 0x10b0c << TYPE(0x47) << 0x10b0d
|
||||
<< TYPE(0x48) << 0x10b0e << TYPE(0x49) << 0x10b0f << TYPE(0x4c) << 0x10b10
|
||||
<< TYPE(0x4d) << 0x10c00 << TYPE(0x4e) << 0x10c01 << TYPE(0x4f) << 0x10c02
|
||||
<< TYPE(0x50) << 0x10c03 << TYPE(0x51) << 0x10c04 << TYPE(0x52) << 0x10c05
|
||||
<< TYPE(0x14) << 0x10a01 << TYPE(0x15) << 0x10a02 << TYPE(0x16) << 0x10a03
|
||||
<< TYPE(0x1e) << 0x10a05 << TYPE(0x1f) << 0x10a06 << TYPE(0x04) << 0x10901
|
||||
<< TYPE(0x05) << 0x10902 << TYPE(0x06) << 0x10903 << TYPE(0x07) << 0x10904
|
||||
<< TYPE(0x08) << 0x10905 << TYPE(0x09) << 0x10906 << TYPE(0x0a) << 0x10907
|
||||
<< TYPE(0x0b) << 0x10908 << TYPE(0x0c) << 0x10909 << TYPE(0x0d) << 0x1090a
|
||||
<< TYPE(0x0e) << 0x1090b << TYPE(0x0f) << TYPE(0x10) << TYPE(0x11)
|
||||
<< TYPE(0x12) << TYPE(0x19) << 0x1090d << TYPE(0x13) << 0x10900;
|
||||
}
|
||||
|
||||
static QImage railroad()
|
||||
@ -148,6 +200,22 @@ void Style::defaultLineStyle()
|
||||
//_lines[TYPE(0x28)] = Line(QPen(QColor("#5a5a5a"), 1, Qt::SolidLine));
|
||||
_lines[TYPE(0x29)] = Line(QPen(QColor("#5a5a5a"), 1, Qt::SolidLine));
|
||||
_lines[TYPE(0x29)].setTextFontSize(None);
|
||||
|
||||
// NT types
|
||||
_lines[0x10c00] = _lines[TYPE(0x14)];
|
||||
_lines[0x10a00] = _lines[TYPE(0x18)];
|
||||
_lines[0x10b04] = _lines[TYPE(0x1e)];
|
||||
_lines[0x10a01] = _lines[TYPE(0x1f)];
|
||||
_lines[0x10900] = _lines[TYPE(0x20)];
|
||||
_lines[0x10901] = _lines[TYPE(0x21)];
|
||||
_lines[0x10902] = _lines[TYPE(0x22)];
|
||||
_lines[0x10903] = _lines[TYPE(0x23)];
|
||||
_lines[0x10904] = _lines[TYPE(0x24)];
|
||||
_lines[0x10905] = _lines[TYPE(0x25)];
|
||||
_lines[0x10a02] = _lines[TYPE(0x26)];
|
||||
_lines[0x10c02] = _lines[TYPE(0x27)];
|
||||
//_lines[0x10c03] = _lines[TYPE(0x28)];
|
||||
_lines[0x10c04] = _lines[TYPE(0x29)];
|
||||
}
|
||||
|
||||
void Style::defaultPointStyle()
|
||||
@ -221,10 +289,13 @@ void Style::defaultPointStyle()
|
||||
_points[0x2d0b] = Point(QImage(":/airfield-11.png"));
|
||||
|
||||
_points[0x2e02] = Point(QImage(":/grocery-11.png"));
|
||||
_points[0x2e03] = Point(QImage(":/shop-11.png"));
|
||||
_points[0x2e05] = Point(QImage(":/pharmacy-11.png"));
|
||||
_points[0x2e06] = Point(QImage(":/convenience-11.png"));
|
||||
_points[0x2e07] = Point(QImage(":/clothing-store-11.png"));
|
||||
_points[0x2e08] = Point(QImage(":/garden-centre-11.png"));
|
||||
_points[0x2e09] = Point(QImage(":/furniture-11.png"));
|
||||
_points[0x2e0a] = Point(QImage(":/shop-11.png"));
|
||||
_points[0x2e0c] = Point(QImage(":/shop-11.png"));
|
||||
|
||||
_points[0x2f01] = Point(QImage(":/fuel-11.png"));
|
||||
@ -248,7 +319,8 @@ void Style::defaultPointStyle()
|
||||
_points[0x3001] = Point(QImage(":/police-11.png"));
|
||||
_points[0x3002] = Point(QImage(":/hospital-11.png"));
|
||||
_points[0x3003] = Point(QImage(":/town-hall-11.png"));
|
||||
_points[0x3007] = Point(QImage(":/prison-11.png"));
|
||||
_points[0x3006] = Point(QImage(":/entrance-alt1-11.png"));
|
||||
_points[0x3007] = Point(QImage(":/town-hall-11.png"));
|
||||
_points[0x3008] = Point(QImage(":/fire-station-11.png"));
|
||||
|
||||
_points[0x4000] = Point(QImage(":/golf-11.png"));
|
||||
@ -296,6 +368,87 @@ void Style::defaultPointStyle()
|
||||
_points[0x6513] = Point(QImage(":/wetland-11.png"));
|
||||
_points[0x6604] = Point(QImage(":/beach-11.png"));
|
||||
_points[0x6616] = Point(QImage(":/mountain-11.png"));
|
||||
|
||||
|
||||
// NT types
|
||||
_points[0x11401] = _points[TYPE(0x01)];
|
||||
_points[0x11402] = _points[TYPE(0x02)];
|
||||
_points[0x11403] = _points[TYPE(0x03)];
|
||||
_points[0x10b00] = _points[0x2a00];
|
||||
_points[0x10b01] = _points[0x2a01];
|
||||
_points[0x10b02] = _points[0x2a02];
|
||||
_points[0x10b03] = _points[0x2a03];
|
||||
_points[0x10b04] = _points[0x2a04];
|
||||
_points[0x10b05] = _points[0x2a05];
|
||||
_points[0x10b06] = _points[0x2a06];
|
||||
_points[0x10b07] = _points[0x2a07];
|
||||
_points[0x10b08] = _points[0x2a08];
|
||||
_points[0x10b09] = _points[0x2a09];
|
||||
_points[0x10b0a] = _points[0x2a0a];
|
||||
_points[0x10b0b] = _points[0x2a0b];
|
||||
_points[0x10b0c] = _points[0x2a0c];
|
||||
_points[0x10b0d] = _points[0x2a0d];
|
||||
_points[0x10b0e] = _points[0x2a0e];
|
||||
_points[0x10b0f] = _points[0x2a0f];
|
||||
_points[0x10b10] = _points[0x2a10];
|
||||
_points[0x10b11] = _points[0x2a11];
|
||||
_points[0x10c01] = _points[0x2b01];
|
||||
_points[0x10c02] = _points[0x2b02];
|
||||
_points[0x10c03] = _points[0x2b03];
|
||||
_points[0x10c04] = _points[0x2b04];
|
||||
_points[0x10d01] = _points[0x2c01];
|
||||
_points[0x10d02] = _points[0x2c02];
|
||||
_points[0x10d03] = _points[0x2c03];
|
||||
_points[0x10d04] = _points[0x2c04];
|
||||
_points[0x10d05] = _points[0x2c05];
|
||||
_points[0x10d06] = _points[0x2c06];
|
||||
_points[0x10d07] = _points[0x2c07];
|
||||
_points[0x10d08] = _points[0x2c08];
|
||||
_points[0x10d0a] = _points[0x2c0a];
|
||||
_points[0x10d0b] = _points[0x2c0b];
|
||||
_points[0x10d0d] = _points[0x2c0d];
|
||||
_points[0x10d0e] = _points[0x2c0e];
|
||||
_points[0x10d10] = _points[0x2c10];
|
||||
_points[0x10e01] = _points[0x2d01];
|
||||
_points[0x10e02] = _points[0x2d02];
|
||||
_points[0x10e03] = _points[0x2d03];
|
||||
_points[0x10e04] = _points[0x2d04];
|
||||
_points[0x10e05] = _points[0x2d05];
|
||||
_points[0x10e06] = _points[0x2d06];
|
||||
_points[0x10e07] = _points[0x2d07];
|
||||
_points[0x10e08] = _points[0x2d08];
|
||||
_points[0x10e09] = _points[0x2d09];
|
||||
_points[0x10e0a] = _points[0x2d0a];
|
||||
_points[0x10e0b] = _points[0x2d0b];
|
||||
_points[0x10f02] = _points[0x2e02];
|
||||
_points[0x10f03] = _points[0x2e03];
|
||||
_points[0x10f05] = _points[0x2e05];
|
||||
_points[0x10f06] = _points[0x2e06];
|
||||
_points[0x10f07] = _points[0x2e07];
|
||||
_points[0x10f08] = _points[0x2e08];
|
||||
_points[0x10f09] = _points[0x2e09];
|
||||
_points[0x10f0a] = _points[0x2e0a];
|
||||
_points[0x11001] = _points[0x2f01];
|
||||
_points[0x11002] = _points[0x2f02];
|
||||
_points[0x11003] = _points[0x2f03];
|
||||
_points[0x11004] = _points[0x2f04];
|
||||
_points[0x11005] = _points[0x2f05];
|
||||
_points[0x11006] = _points[0x2f06];
|
||||
_points[0x11007] = _points[0x2f07];
|
||||
_points[0x11008] = _points[0x2f08];
|
||||
_points[0x11009] = _points[0x2f09];
|
||||
_points[0x1100b] = _points[0x2f0b];
|
||||
_points[0x1100c] = _points[0x2f0c];
|
||||
_points[0x11010] = _points[0x2f10];
|
||||
_points[0x11012] = _points[0x2f12];
|
||||
_points[0x11013] = _points[0x2f13];
|
||||
_points[0x11017] = _points[0x2f17];
|
||||
_points[0x11101] = _points[0x3001];
|
||||
_points[0x11102] = _points[0x3002];
|
||||
_points[0x11103] = _points[0x3003];
|
||||
_points[0x11106] = _points[0x3006];
|
||||
_points[0x11107] = _points[0x3007];
|
||||
_points[0x11108] = _points[0x3008];
|
||||
}
|
||||
|
||||
static bool readBitmap(SubFile *file, SubFile::Handle &hdl, QImage &img,
|
||||
@ -985,19 +1138,26 @@ const Style::Point &Style::point(quint32 type) const
|
||||
|
||||
Style::POIClass Style::poiClass(quint32 type)
|
||||
{
|
||||
if ((type >= 0x2a00 && type < 0x2b00) || type == 0x2c0a || type == 0x2d02)
|
||||
if ((type >= 0x2a00 && type < 0x2b00) || type == 0x2c0a || type == 0x2d02
|
||||
|| (type & 0xffff00) == TYPE(0x10b))
|
||||
return Food;
|
||||
else if (type >= 0x2b00 && type < 0x2c00)
|
||||
else if ((type >= 0x2b00 && type < 0x2c00)
|
||||
|| (type & 0xffff00) == TYPE(0x10c))
|
||||
return Accommodation;
|
||||
else if (type >= 0x2c00 && type < 0x2e00)
|
||||
else if ((type >= 0x2c00 && type < 0x2e00)
|
||||
|| (type & 0xffff00) == TYPE(0x10d) || (type & 0xffff00) == TYPE(0x10e))
|
||||
return Recreation;
|
||||
else if (type >= 0x2e00 && type < 0x2f00)
|
||||
else if ((type >= 0x2e00 && type < 0x2f00)
|
||||
|| (type & 0xffff00) == TYPE(0x10f))
|
||||
return Shopping;
|
||||
else if ((type >= 0x2f00 && type < 0x2f0f) || type == 0x2f17)
|
||||
else if ((type >= 0x2f00 && type < 0x2f0f) || type == 0x2f17
|
||||
|| (type >= 0x11001 && type < 0x1100f))
|
||||
return Transport;
|
||||
else if (type >= 0x2f0f && type < 0x3000)
|
||||
else if ((type >= 0x2f0f && type < 0x3000)
|
||||
|| (type >= 0x1100f && type < 0x11100))
|
||||
return Services;
|
||||
else if (type >= 0x3000 && type < 0x3100)
|
||||
else if ((type >= 0x3000 && type < 0x3100)
|
||||
|| (type & 0xffff00) == TYPE(0x111))
|
||||
return Community;
|
||||
else if (type >= 0x4000 && type < 0x6000)
|
||||
return Elementary;
|
||||
|
@ -108,15 +108,19 @@ public:
|
||||
const Point &point(quint32 type) const;
|
||||
const QList<quint32> &drawOrder() const {return _drawOrder;}
|
||||
|
||||
static bool isPOI(quint32 type)
|
||||
{return !((type >= TYPE(0x01) && type <= TYPE(0x1f))
|
||||
|| (type >= 0x11400 && type < 0x11500));}
|
||||
static bool isContourLine(quint32 type)
|
||||
{return ((type >= TYPE(0x20) && type <= TYPE(0x25))
|
||||
|| (type & 0xffff00) == TYPE(0x109));}
|
||||
static bool isWaterArea(quint32 type)
|
||||
{return (type >= TYPE(0x3c) && type <= TYPE(0x44));}
|
||||
{return ((type >= TYPE(0x3c) && type <= TYPE(0x44))
|
||||
|| (type & 0xffff00) == TYPE(0x10b));}
|
||||
static bool isMilitaryArea(quint32 type)
|
||||
{return (type == TYPE(0x04));}
|
||||
{return (type == TYPE(0x04) || type == 0x10901);}
|
||||
static bool isNatureReserve(quint32 type)
|
||||
{return (type == TYPE(0x16));}
|
||||
{return (type == TYPE(0x16) || type == 0x10a03);}
|
||||
static bool isSpot(quint32 type)
|
||||
{return (type == TYPE(0x62) || type == TYPE(0x63));}
|
||||
static bool isSummit(quint32 type)
|
||||
|
@ -42,14 +42,12 @@ public:
|
||||
: _gmpOffset(0), _img(img), _blocks(new QVector<quint16>()), _path(0) {}
|
||||
SubFile(SubFile *gmp, quint32 offset) : _gmpOffset(offset), _img(gmp->_img),
|
||||
_blocks(gmp->_blocks), _path(gmp->_path) {}
|
||||
SubFile(const QString &path)
|
||||
: _gmpOffset(0), _img(0), _blocks(0), _path(new QString(path)) {}
|
||||
SubFile(const QString *path)
|
||||
: _gmpOffset(0), _img(0), _blocks(0), _path(path) {}
|
||||
~SubFile()
|
||||
{
|
||||
if (!_gmpOffset) {
|
||||
if (!_gmpOffset)
|
||||
delete _blocks;
|
||||
delete _path;
|
||||
}
|
||||
}
|
||||
|
||||
void addBlock(quint16 block) {_blocks->append(block);}
|
||||
@ -151,7 +149,7 @@ private:
|
||||
|
||||
IMG *_img;
|
||||
QVector<quint16> *_blocks;
|
||||
QString *_path;
|
||||
const QString *_path;
|
||||
};
|
||||
|
||||
#endif // SUBFILE_H
|
||||
|
@ -10,13 +10,18 @@ class QPainter;
|
||||
class TextItem
|
||||
{
|
||||
public:
|
||||
TextItem(const QString *text) : _text(text) {}
|
||||
virtual ~TextItem() {}
|
||||
|
||||
virtual QPainterPath shape() const = 0;
|
||||
virtual QRectF boundingRect() const = 0;
|
||||
virtual void paint(QPainter *painter) const = 0;
|
||||
|
||||
const QString *text() const {return _text;}
|
||||
bool collides(const QList<TextItem*> &list) const;
|
||||
|
||||
protected:
|
||||
const QString *_text;
|
||||
};
|
||||
|
||||
#endif // TEXTITEM_H
|
||||
|
@ -137,7 +137,7 @@ static bool reverse(const QPainterPath &path)
|
||||
|
||||
TextPathItem::TextPathItem(const QPolygonF &line, const QString *label,
|
||||
const QRect &tileRect, const QFont *font, const QColor *color)
|
||||
: _text(label), _font(font), _color(color)
|
||||
: TextItem(label), _font(font), _color(color)
|
||||
{
|
||||
qreal cw = font->pixelSize() * 0.7;
|
||||
qreal textWidth = _text->size() * cw;
|
||||
|
@ -8,7 +8,7 @@
|
||||
class TextPathItem : public TextItem
|
||||
{
|
||||
public:
|
||||
TextPathItem() : _text(0), _font(0), _color(0) {}
|
||||
TextPathItem() : TextItem(0), _font(0), _color(0) {}
|
||||
TextPathItem(const QPolygonF &line, const QString *label,
|
||||
const QRect &tileRect, const QFont *font, const QColor *color);
|
||||
|
||||
@ -19,7 +19,6 @@ public:
|
||||
void paint(QPainter *painter) const;
|
||||
|
||||
private:
|
||||
const QString *_text;
|
||||
const QFont *_font;
|
||||
const QColor *_color;
|
||||
QPainterPath _path;
|
||||
|
@ -17,7 +17,7 @@ static void expand(QRect &rect, int width)
|
||||
|
||||
TextPointItem::TextPointItem(const QPoint &point, const QString *text,
|
||||
const QFont *font, const QImage *img, const QColor *color,
|
||||
const QColor *bgColor) : _text(font ? text : 0), _font(font), _img(img),
|
||||
const QColor *bgColor) : TextItem(font ? text : 0), _font(font), _img(img),
|
||||
_color(color), _bgColor(bgColor)
|
||||
{
|
||||
if (_text) {
|
||||
|
@ -14,7 +14,7 @@ class QColor;
|
||||
class TextPointItem : public TextItem
|
||||
{
|
||||
public:
|
||||
TextPointItem() : _text(0), _font(0), _img(0) {}
|
||||
TextPointItem() : TextItem(0), _font(0), _img(0) {}
|
||||
TextPointItem(const QPoint &point, const QString *text, const QFont *font,
|
||||
const QImage *img, const QColor *color, const QColor *bgColor = 0);
|
||||
|
||||
@ -27,7 +27,6 @@ public:
|
||||
void setPos(const QPoint &point);
|
||||
|
||||
private:
|
||||
const QString *_text;
|
||||
const QFont *_font;
|
||||
const QImage *_img;
|
||||
const QColor *_color, *_bgColor;
|
||||
|
@ -5,7 +5,12 @@
|
||||
|
||||
static inline double RB(qint32 val)
|
||||
{
|
||||
return (val == -0x800000 || val == 0x800000) ? 180.0 : toWGS24(val);
|
||||
return (val == -0x800000 || val >= 0x800000) ? 180.0 : toWGS24(val);
|
||||
}
|
||||
|
||||
static inline double LB(qint32 val)
|
||||
{
|
||||
return (val <= -0x800000) ? -180.0 : toWGS24(val);
|
||||
}
|
||||
|
||||
static void demangle(quint8 *data, quint32 size, quint32 key)
|
||||
@ -60,7 +65,8 @@ bool TREFile::init()
|
||||
return false;
|
||||
_bounds = RectC(Coordinates(toWGS24(west), toWGS24(north)),
|
||||
Coordinates(RB(east), toWGS24(south)));
|
||||
Q_ASSERT(_bounds.left() <= _bounds.right());
|
||||
if (!_bounds.isValid())
|
||||
return false;
|
||||
|
||||
// Levels & subdivs info
|
||||
quint32 levelsOffset, levelsSize, subdivSize;
|
||||
@ -187,21 +193,27 @@ bool TREFile::load(int idx)
|
||||
|
||||
width &= 0x7FFF;
|
||||
width = LS(width, 24 - level.bits);
|
||||
height &= 0x7FFF;
|
||||
height = LS(height, 24 - level.bits);
|
||||
|
||||
s = new SubDiv(offset, lon, lat, level.level, level.bits, objects);
|
||||
sl.append(s);
|
||||
|
||||
double min[2], max[2];
|
||||
RectC bounds(Coordinates(toWGS24(lon - width), toWGS24(lat + height)),
|
||||
RectC bounds(Coordinates(LB(lon - width), toWGS24(lat + height)),
|
||||
Coordinates(RB(lon + width), toWGS24(lat - height)));
|
||||
Q_ASSERT(bounds.left() <= bounds.right());
|
||||
|
||||
min[0] = bounds.left();
|
||||
min[1] = bounds.bottom();
|
||||
max[0] = bounds.right();
|
||||
max[1] = bounds.top();
|
||||
|
||||
/* both mkgmap and cGPSmapper generate all kinds of broken subdiv bounds
|
||||
(zero lat/lon, zero width/height, ...) so we check only that the
|
||||
subdiv item does not break the rtree, not for full bounds validity. */
|
||||
if (!(min[0] <= max[0] && min[1] <= max[1]))
|
||||
goto error;
|
||||
|
||||
tree->Insert(min, max, s);
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ class TREFile : public SubFile
|
||||
{
|
||||
public:
|
||||
TREFile(IMG *img) : SubFile(img) {}
|
||||
TREFile(const QString &path) : SubFile(path) {}
|
||||
TREFile(const QString *path) : SubFile(path) {}
|
||||
TREFile(SubFile *gmp, quint32 offset) : SubFile(gmp, offset) {}
|
||||
~TREFile();
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
#include "vectortile.h"
|
||||
|
||||
|
||||
static void copyPolys(const RectC &rect, QList<IMG::Poly> *src,
|
||||
QList<IMG::Poly> *dst)
|
||||
static void copyPolys(const RectC &rect, QList<MapData::Poly> *src,
|
||||
QList<MapData::Poly> *dst)
|
||||
{
|
||||
for (int i = 0; i < src->size(); i++)
|
||||
if (rect.intersects(src->at(i).boundingRect))
|
||||
dst->append(src->at(i));
|
||||
}
|
||||
|
||||
static void copyPoints(const RectC &rect, QList<IMG::Point> *src,
|
||||
QList<IMG::Point> *dst)
|
||||
static void copyPoints(const RectC &rect, QList<MapData::Point> *src,
|
||||
QList<MapData::Point> *dst)
|
||||
{
|
||||
for (int j = 0; j < src->size(); j++)
|
||||
if (rect.contains(src->at(j).coordinates))
|
||||
@ -38,58 +38,6 @@ SubFile *VectorTile::file(SubFile::Type type)
|
||||
}
|
||||
}
|
||||
|
||||
SubFile *VectorTile::addFile(IMG *img, SubFile::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case SubFile::TRE:
|
||||
_tre = new TREFile(img);
|
||||
return _tre;
|
||||
case SubFile::RGN:
|
||||
_rgn = new RGNFile(img);
|
||||
return _rgn;
|
||||
case SubFile::LBL:
|
||||
_lbl = new LBLFile(img);
|
||||
return _lbl;
|
||||
case SubFile::NET:
|
||||
_net = new NETFile(img);
|
||||
return _net;
|
||||
case SubFile::NOD:
|
||||
_nod = new NODFile(img);
|
||||
return _nod;
|
||||
case SubFile::GMP:
|
||||
_gmp = new SubFile(img);
|
||||
return _gmp;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SubFile *VectorTile::addFile(const QString &path, SubFile::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case SubFile::TRE:
|
||||
_tre = new TREFile(path);
|
||||
return _tre;
|
||||
case SubFile::RGN:
|
||||
_rgn = new RGNFile(path);
|
||||
return _rgn;
|
||||
case SubFile::LBL:
|
||||
_lbl = new LBLFile(path);
|
||||
return _lbl;
|
||||
case SubFile::NET:
|
||||
_net = new NETFile(path);
|
||||
return _net;
|
||||
case SubFile::NOD:
|
||||
_nod = new NODFile(path);
|
||||
return _nod;
|
||||
case SubFile::GMP:
|
||||
_gmp = new SubFile(path);
|
||||
return _gmp;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool VectorTile::init()
|
||||
{
|
||||
if (_gmp && !initGMP())
|
||||
@ -120,23 +68,54 @@ bool VectorTile::initGMP()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VectorTile::load(SubFile::Handle &rgnHdl, SubFile::Handle &lblHdl,
|
||||
SubFile::Handle &netHdl, SubFile::Handle &nodHdl)
|
||||
{
|
||||
_loaded = -1;
|
||||
|
||||
if (!_rgn->load(rgnHdl))
|
||||
return false;
|
||||
if (_lbl && !_lbl->load(lblHdl, _rgn, rgnHdl))
|
||||
return false;
|
||||
if (_net && !_net->load(netHdl, _rgn, rgnHdl))
|
||||
return false;
|
||||
if (_nod && !_nod->load(nodHdl))
|
||||
return false;
|
||||
|
||||
_loaded = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VectorTile::clear()
|
||||
{
|
||||
_tre->clear();
|
||||
_rgn->clear();
|
||||
if (_lbl)
|
||||
_lbl->clear();
|
||||
if (_net)
|
||||
_net->clear();
|
||||
|
||||
_loaded = 0;
|
||||
}
|
||||
|
||||
void VectorTile::polys(const RectC &rect, int bits, bool baseMap,
|
||||
QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
|
||||
QCache<const SubDiv *, IMG::Polys> *polyCache) const
|
||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||
QCache<const SubDiv *, MapData::Polys> *polyCache)
|
||||
{
|
||||
SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl), netHdl(_net), nodHdl(_nod);
|
||||
|
||||
if (!_rgn->initialized() && !_rgn->init(rgnHdl))
|
||||
if (_loaded < 0 || (!_loaded && !load(rgnHdl, lblHdl, netHdl, nodHdl)))
|
||||
return;
|
||||
|
||||
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits, baseMap);
|
||||
for (int i = 0; i < subdivs.size(); i++) {
|
||||
SubDiv *subdiv = subdivs.at(i);
|
||||
|
||||
IMG::Polys *polys = polyCache->object(subdiv);
|
||||
MapData::Polys *polys = polyCache->object(subdiv);
|
||||
if (!polys) {
|
||||
quint32 shift = _tre->shift(subdiv->bits());
|
||||
QList<IMG::Poly> p, l;
|
||||
QList<MapData::Poly> p, l;
|
||||
|
||||
if (!subdiv->initialized() && !_rgn->subdivInit(rgnHdl, subdiv))
|
||||
continue;
|
||||
@ -154,7 +133,7 @@ void VectorTile::polys(const RectC &rect, int bits, bool baseMap,
|
||||
|
||||
copyPolys(rect, &p, polygons);
|
||||
copyPolys(rect, &l, lines);
|
||||
polyCache->insert(subdiv, new IMG::Polys(p, l));
|
||||
polyCache->insert(subdiv, new MapData::Polys(p, l));
|
||||
} else {
|
||||
copyPolys(rect, &(polys->polygons), polygons);
|
||||
copyPolys(rect, &(polys->lines), lines);
|
||||
@ -163,21 +142,21 @@ void VectorTile::polys(const RectC &rect, int bits, bool baseMap,
|
||||
}
|
||||
|
||||
void VectorTile::points(const RectC &rect, int bits, bool baseMap,
|
||||
QList<IMG::Point> *points, QCache<const SubDiv *,
|
||||
QList<IMG::Point> > *pointCache) const
|
||||
QList<MapData::Point> *points, QCache<const SubDiv *,
|
||||
QList<MapData::Point> > *pointCache)
|
||||
{
|
||||
SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl);
|
||||
SubFile::Handle rgnHdl(_rgn), lblHdl(_lbl), netHdl(_net), nodHdl(_nod);
|
||||
|
||||
if (!_rgn->initialized() && !_rgn->init(rgnHdl))
|
||||
if (_loaded < 0 || (!_loaded && !load(rgnHdl, lblHdl, netHdl, nodHdl)))
|
||||
return;
|
||||
|
||||
QList<SubDiv*> subdivs = _tre->subdivs(rect, bits, baseMap);
|
||||
for (int i = 0; i < subdivs.size(); i++) {
|
||||
SubDiv *subdiv = subdivs.at(i);
|
||||
|
||||
QList<IMG::Point> *pl = pointCache->object(subdiv);
|
||||
QList<MapData::Point> *pl = pointCache->object(subdiv);
|
||||
if (!pl) {
|
||||
QList<IMG::Point> p;
|
||||
QList<MapData::Point> p;
|
||||
|
||||
if (!subdiv->initialized() && !_rgn->subdivInit(rgnHdl, subdiv))
|
||||
continue;
|
||||
@ -189,7 +168,7 @@ void VectorTile::points(const RectC &rect, int bits, bool baseMap,
|
||||
_rgn->extPointObjects(rgnHdl, subdiv, _lbl, lblHdl, &p);
|
||||
|
||||
copyPoints(rect, &p, points);
|
||||
pointCache->insert(subdiv, new QList<IMG::Point>(p));
|
||||
pointCache->insert(subdiv, new QList<MapData::Point>(p));
|
||||
} else
|
||||
copyPoints(rect, pl, points);
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
#ifndef VECTORTILE_H
|
||||
#define VECTORTILE_H
|
||||
|
||||
#include "trefile.h"
|
||||
#include "trefile.h"
|
||||
#include "rgnfile.h"
|
||||
#include "lblfile.h"
|
||||
@ -10,7 +9,8 @@
|
||||
|
||||
class VectorTile {
|
||||
public:
|
||||
VectorTile() : _tre(0), _rgn(0), _lbl(0), _net(0), _nod(0), _gmp(0) {}
|
||||
VectorTile()
|
||||
: _tre(0), _rgn(0), _lbl(0), _net(0), _nod(0), _gmp(0), _loaded(0) {}
|
||||
~VectorTile()
|
||||
{
|
||||
delete _tre; delete _rgn; delete _lbl; delete _net; delete _nod;
|
||||
@ -19,21 +19,19 @@ public:
|
||||
|
||||
bool init();
|
||||
void markAsBasemap() {_tre->markAsBasemap();}
|
||||
void clear() {_tre->clear();}
|
||||
void clear();
|
||||
|
||||
const RectC &bounds() const {return _tre->bounds();}
|
||||
Range zooms() const {return _tre->zooms();}
|
||||
|
||||
SubFile *file(SubFile::Type type);
|
||||
SubFile *addFile(IMG *img, SubFile::Type type);
|
||||
SubFile *addFile(const QString &path, SubFile::Type type);
|
||||
|
||||
void polys(const RectC &rect, int bits, bool baseMap,
|
||||
QList<IMG::Poly> *polygons, QList<IMG::Poly> *lines,
|
||||
QCache<const SubDiv *, IMG::Polys> *polyCache) const;
|
||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||
QCache<const SubDiv *, MapData::Polys> *polyCache);
|
||||
void points(const RectC &rect, int bits, bool baseMap,
|
||||
QList<IMG::Point> *points, QCache<const SubDiv*,
|
||||
QList<IMG::Point> > *pointCache) const;
|
||||
QList<MapData::Point> *points, QCache<const SubDiv*,
|
||||
QList<MapData::Point> > *pointCache);
|
||||
|
||||
static bool isTileFile(SubFile::Type type)
|
||||
{
|
||||
@ -42,8 +40,37 @@ public:
|
||||
|| type == SubFile::NOD || type == SubFile::GMP);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
SubFile *addFile(T *container, SubFile::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case SubFile::TRE:
|
||||
_tre = new TREFile(container);
|
||||
return _tre;
|
||||
case SubFile::RGN:
|
||||
_rgn = new RGNFile(container);
|
||||
return _rgn;
|
||||
case SubFile::LBL:
|
||||
_lbl = new LBLFile(container);
|
||||
return _lbl;
|
||||
case SubFile::NET:
|
||||
_net = new NETFile(container);
|
||||
return _net;
|
||||
case SubFile::NOD:
|
||||
_nod = new NODFile(container);
|
||||
return _nod;
|
||||
case SubFile::GMP:
|
||||
_gmp = new SubFile(container);
|
||||
return _gmp;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool initGMP();
|
||||
bool load(SubFile::Handle &rgnHdl, SubFile::Handle &lblHdl,
|
||||
SubFile::Handle &netHdl, SubFile::Handle &nodHdl);
|
||||
|
||||
TREFile *_tre;
|
||||
RGNFile *_rgn;
|
||||
@ -51,6 +78,8 @@ private:
|
||||
NETFile *_net;
|
||||
NODFile *_nod;
|
||||
SubFile *_gmp;
|
||||
|
||||
int _loaded;
|
||||
};
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
|
@ -28,7 +28,7 @@ Projection CRS::projection(const QString &crs)
|
||||
return Projection();
|
||||
}
|
||||
|
||||
if (authority == "EPSG") {
|
||||
if (!authority.compare("EPSG", Qt::CaseInsensitive)) {
|
||||
epsg = code.toInt(&res);
|
||||
if (!res)
|
||||
return Projection();
|
||||
@ -39,7 +39,7 @@ Projection CRS::projection(const QString &crs)
|
||||
return Projection(gcs);
|
||||
else
|
||||
return Projection();
|
||||
} else if (authority == "OGC") {
|
||||
} else if (!authority.compare("OGC", Qt::CaseInsensitive)) {
|
||||
if (code == "CRS84")
|
||||
return Projection(GCS::gcs(4326), CoordinateSystem::XY);
|
||||
else
|
||||
|
@ -61,19 +61,19 @@
|
||||
((map).contains(key) && (map).value(key).SHORT != 32767)
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct GeoKeyHeader {
|
||||
quint16 KeyDirectoryVersion;
|
||||
quint16 KeyRevision;
|
||||
quint16 MinorRevision;
|
||||
quint16 NumberOfKeys;
|
||||
} Header;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct GeoKeyEntry {
|
||||
quint16 KeyID;
|
||||
quint16 TIFFTagLocation;
|
||||
quint16 Count;
|
||||
quint16 ValueOffset;
|
||||
} KeyEntry;
|
||||
};
|
||||
|
||||
|
||||
bool GeoTIFF::readEntry(TIFFFile &file, Ctx &ctx) const
|
||||
@ -196,8 +196,8 @@ bool GeoTIFF::readMatrix(TIFFFile &file, quint32 offset, double matrix[16]) cons
|
||||
|
||||
bool GeoTIFF::readKeys(TIFFFile &file, Ctx &ctx, QMap<quint16, Value> &kv) const
|
||||
{
|
||||
Header header;
|
||||
KeyEntry entry;
|
||||
GeoKeyHeader header;
|
||||
GeoKeyEntry entry;
|
||||
Value value;
|
||||
|
||||
if (!file.seek(ctx.keys))
|
||||
|
@ -136,6 +136,9 @@ void IMGMap::updateTransform()
|
||||
RectD prect(_dataBounds, _projection);
|
||||
_bounds = QRectF(_transform.proj2img(prect.topLeft()),
|
||||
_transform.proj2img(prect.bottomRight()));
|
||||
// Adjust the bounds of world maps to avoid problems with wrapping
|
||||
if (_dataBounds.left() == -180.0 || _dataBounds.right() == 180.0)
|
||||
_bounds.adjust(0.5, 0, -0.5, 0);
|
||||
}
|
||||
|
||||
QPointF IMGMap::ll2xy(const Coordinates &c)
|
||||
@ -194,7 +197,7 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
||||
|
||||
QRectF polyRect(ttl, QPointF(ttl.x() + TILE_SIZE,
|
||||
ttl.y() + TILE_SIZE));
|
||||
polyRect &= bounds().adjusted(0.5, 0.5, -0.5, -0.5);
|
||||
polyRect &= bounds();
|
||||
RectD polyRectD(_transform.img2proj(polyRect.topLeft()),
|
||||
_transform.img2proj(polyRect.bottomRight()));
|
||||
_data.at(n)->polys(polyRectD.toRectC(_projection, 4), _zoom,
|
||||
@ -204,7 +207,7 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
||||
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT,
|
||||
ttl.y() - TEXT_EXTENT), QPointF(ttl.x() + TILE_SIZE
|
||||
+ TEXT_EXTENT, ttl.y() + TILE_SIZE + TEXT_EXTENT));
|
||||
pointRect &= bounds().adjusted(0.5, 0.5, -0.5, -0.5);
|
||||
pointRect &= bounds();
|
||||
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
||||
_transform.img2proj(pointRect.bottomRight()));
|
||||
_data.at(n)->points(pointRectD.toRectC(_projection, 4),
|
||||
@ -241,7 +244,7 @@ void IMGMap::setProjection(const Projection &projection)
|
||||
|
||||
_projection = projection;
|
||||
// Limit the bounds for some well known Mercator projections
|
||||
// (GARMIN world maps have N/S bounds up to 90/-90!)
|
||||
// (world maps have N/S bounds up to 90/-90!)
|
||||
_dataBounds = (_projection == PCS::pcs(3857) || _projection == PCS::pcs(3395))
|
||||
? _data.first()->bounds() & OSM::BOUNDS : _data.first()->bounds();
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#define BLOCKCOUNT(size) \
|
||||
((size)/BLOCKSIZE + ((size) % BLOCKSIZE > 0 ? 1 : 0))
|
||||
|
||||
struct Header
|
||||
struct TARHeader
|
||||
{
|
||||
char name[100]; /* 0 */
|
||||
char mode[8]; /* 100 */
|
||||
@ -61,7 +61,7 @@ bool Tar::open()
|
||||
bool Tar::loadTar()
|
||||
{
|
||||
char buffer[BLOCKSIZE];
|
||||
struct Header *hdr = (struct Header*)&buffer;
|
||||
TARHeader *hdr = (TARHeader*)&buffer;
|
||||
quint64 size;
|
||||
qint64 ret;
|
||||
|
||||
@ -113,7 +113,7 @@ bool Tar::loadTmi(const QString &path)
|
||||
QByteArray Tar::file(const QString &name)
|
||||
{
|
||||
char buffer[BLOCKSIZE];
|
||||
struct Header *hdr = (struct Header*)&buffer;
|
||||
TARHeader *hdr = (TARHeader*)&buffer;
|
||||
quint64 size;
|
||||
|
||||
QMap<QString, quint64>::const_iterator it(_index.find(name));
|
||||
|