1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-07-25 07:54:24 +02:00

Compare commits

..

54 Commits
7.33 ... 7.36

Author SHA1 Message Date
fa03ecd419 Use the propper array delete operator 2020-11-11 18:47:34 +01:00
609202fe57 Fixed broken QObject parenting 2020-11-11 18:46:26 +01:00
f55d6d8501 API cleanup 2020-11-10 20:14:59 +01:00
731b309ac9 Remove the special timestamps check from the FIT parser
(Use the common logic in the Track class instead)
2020-11-10 20:07:46 +01:00
f85977d881 Merge branch 'origin/master' into Weblate. 2020-11-10 01:04:34 +01:00
12e395270b Version++ 2020-11-10 01:04:28 +01:00
45b637ba17 Merge branch 'origin/master' into Weblate. 2020-11-10 00:58:58 +01:00
f139d33502 Huffman encoded labels
+ more or less related fixes/refactoring
2020-11-10 00:58:19 +01:00
63e7735abe Translated using Weblate (French)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fr/
2020-11-03 15:20:23 +01:00
27122f94ef Merge branch 'origin/master' into Weblate. 2020-11-02 20:16:38 +01:00
0644bb72a0 Broken subdivs are more common than one would expect... 2020-11-02 20:16:02 +01:00
a4d14511de Merge branch 'origin/master' into Weblate. 2020-11-02 00:19:09 +01:00
1225d350d4 Allow broken subdiv bounds produced by mkgmap 2020-11-02 00:18:27 +01:00
a1d93cc548 Merge branch 'origin/master' into Weblate. 2020-11-01 23:48:14 +01:00
80f5bbfbce Print a warning on invalid subdiv bounds 2020-11-01 23:47:44 +01:00
70c9431ee4 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-10-28 14:26:59 +01:00
de7664ccc7 Added PNG export info 2020-10-28 12:15:46 +01:00
9bd79a4104 Fixed broken tile bounds 2020-10-27 20:52:29 +01:00
f9abf21e6d Fixed warious bounds wrapping issues 2020-10-27 16:46:09 +01:00
fb4af33d89 Version++ 2020-10-27 11:49:07 +01:00
9eb95daf09 Translated using Weblate (Russian)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-10-24 01:05:33 +02:00
d291e55bdb Fixed label pointer parsing 2020-10-22 20:32:12 +02:00
b5893cf506 Fixed label text parsing
(use only space as whitespace separator)
2020-10-22 20:30:11 +02:00
8507fe3b52 Added missing collision detection 2020-10-22 01:16:23 +02:00
79edd6e09d Fixed missing reference 2020-10-21 21:21:35 +02:00
491c6c9a98 Do not let the OS rescale(blur) the windows installer 2020-10-21 21:19:15 +02:00
3c36db9f5a Use antialiased graphs as the default 2020-10-21 21:18:26 +02:00
c4a750f5d4 Merge branch 'origin/master' into Weblate. 2020-10-17 21:00:43 +02:00
e4d7f45103 Remove the right item from the list 2020-10-17 20:59:58 +02:00
c85b90d56d Merge branch 'origin/master' into Weblate. 2020-10-17 14:30:20 +02:00
7babf734bf Fixed memory leak 2020-10-17 14:30:06 +02:00
25ac235414 Merge branch 'origin/master' into Weblate. 2020-10-17 14:27:33 +02:00
630a5cea83 Improved polygon labels layout logic 2020-10-17 14:26:59 +02:00
a0de7f25c3 Merge branch 'origin/master' into Weblate. 2020-10-16 22:46:13 +02:00
7c6174a8ee Some more IMG POI style tweaking 2020-10-16 22:45:51 +02:00
0f512d1269 Merge branch 'origin/master' into Weblate. 2020-10-16 00:04:02 +02:00
246b46ffcb Translated using Weblate (Norwegian Bokmål)
Currently translated at 99.7% (373 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2020-10-16 00:04:02 +02:00
cc4cbcbeda Various IMG style enchancements 2020-10-16 00:03:26 +02:00
64e0b492e6 Merge branch 'origin/master' into Weblate. 2020-10-14 22:06:05 +02:00
52a8b1de5b Cosmetics 2020-10-14 22:05:48 +02:00
5045c03953 Merge branch 'origin/master' into Weblate. 2020-10-14 22:04:52 +02:00
515f1aeb27 Use propper structure names 2020-10-14 22:04:32 +02:00
dbb82d6f44 Translated using Weblate (Ukrainian)
Currently translated at 98.6% (369 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/uk/
2020-10-13 03:39:03 +02:00
307a03d46c Translated using Weblate (Finnish)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/fi/
2020-10-13 03:39:02 +02:00
b7c03b4b9e Merge branch 'origin/master' into Weblate. 2020-10-12 21:18:14 +02:00
2d1e0934ce Silenced clang indentation warning 2020-10-12 21:17:18 +02:00
0ff66bc897 Merge branch 'origin/master' into Weblate. 2020-10-12 20:05:30 +02:00
3b68f497fe Fixed ODR (One Definition Rule) violation 2020-10-12 20:05:17 +02:00
a04293b411 Merge branch 'origin/master' into Weblate. 2020-10-11 21:35:42 +02:00
5a4de1cef0 Accept case insensitive authorities names 2020-10-11 21:33:19 +02:00
99d3d8fd0a Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/pt_BR/
2020-10-10 15:26:41 +02:00
d579ce3482 Translated using Weblate (Russian)
Currently translated at 100.0% (374 of 374 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ru/
2020-10-09 05:22:55 +02:00
67ce176b74 Version++ 2020-10-09 05:12:19 +02:00
1a88527c60 Fixed icon paths 2020-10-08 23:16:09 +02:00
65 changed files with 1030 additions and 450 deletions

View File

@ -1,4 +1,4 @@
version: 7.33.{build}
version: 7.36.{build}
configuration:
- Release

View File

@ -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.

View File

@ -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 \

View File

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 323 B

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

Before

Width:  |  Height:  |  Size: 571 B

After

Width:  |  Height:  |  Size: 571 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -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"/>

View File

@ -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&apos;anticrénelage</translation>
<translation>Utiliser l&apos;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&apos;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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"

View File

@ -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"

View File

@ -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;

View File

@ -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"

View File

@ -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

View File

@ -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;}

View File

@ -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;

View File

@ -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;

View File

@ -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())

View File

@ -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))

View File

@ -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;

View File

@ -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);

View File

@ -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

View 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;
}

View 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

View File

@ -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;
}

View File

@ -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
View 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
View 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

View File

@ -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();
}

View File

@ -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;

View File

@ -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();

View File

@ -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();
}

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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();

View File

@ -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));