1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-07-04 06:49:16 +02:00

Compare commits

..

26 Commits
11.7 ... 11.9

Author SHA1 Message Date
ac5f4cafeb Code cleanup 2022-11-17 13:26:45 +01:00
ccb0364e76 Some more missing ENC objects 2022-11-17 13:05:38 +01:00
414bdead17 Docks render style 2022-11-17 10:37:05 +01:00
8cf09a68d1 Some more missing ENC render style 2022-11-17 08:25:53 +01:00
e4c79d7275 Added missing dams and pylons rendering 2022-11-16 22:51:16 +01:00
a718f1e122 Properly handle non-ASCII characters
(Support for UCS-2 encoded files is still missing as there is no such sample
file available.)
2022-11-16 22:47:30 +01:00
6507764545 Version++ 2022-11-16 00:39:23 +01:00
bd2d66ecd3 Added traffic lines arrows 2022-11-14 22:29:27 +01:00
c09525f306 Fixed map order 2022-11-14 07:09:46 +01:00
5bc7487c3a Still wrong... Fixed the broken mask. 2022-11-11 11:26:15 +01:00
9b73b0f70e Fixed broken points ordering 2022-11-11 10:40:59 +01:00
4f1f3e569b Limit ENC maps zooms
+ somemore style adjustments
2022-11-10 23:53:34 +01:00
e4847ac243 Some more ENC objects to render 2022-11-10 09:43:14 +01:00
8b039cb9a7 Merge branch 'origin/master' into Weblate. 2022-11-10 07:34:02 +01:00
37bff3d50c Version++ 2022-11-10 07:33:51 +01:00
70941405ad Merge branch 'origin/master' into Weblate. 2022-11-09 23:13:26 +01:00
c96a0fd8f4 Added missing traffic separation line style 2022-11-09 23:12:40 +01:00
5ad8f762f7 Merge branch 'origin/master' into Weblate. 2022-11-09 21:38:28 +01:00
raf
297f5f13fb Translated using Weblate (Catalan)
Currently translated at 100.0% (466 of 466 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/ca/
2022-11-09 21:38:27 +01:00
985ccaf931 Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (466 of 466 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/nb_NO/
2022-11-09 21:38:27 +01:00
877d9331e4 ENC map style enhancement
+ code cleanup
2022-11-09 21:37:33 +01:00
9d8c23bc32 Fixed crash on ENC map unload 2022-11-09 21:37:05 +01:00
51dd85f973 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (466 of 466 strings)

Translation: GPXSee/Translations
Translate-URL: https://hosted.weblate.org/projects/gpxsee/translations/zh_Hans/
2022-11-08 13:04:32 +01:00
af688314fb Define symbols draw order 2022-11-08 01:16:38 +01:00
1946c3cc6f Image polygon lines 2022-11-08 00:38:45 +01:00
8ae8c3b0a3 Added missing 000 files association 2022-11-06 22:13:53 +01:00
19 changed files with 341 additions and 75 deletions

View File

@ -1,4 +1,4 @@
version: 11.7.{build} version: 11.9.{build}
configuration: configuration:
- Release - Release

View File

@ -3,7 +3,7 @@ unix:!macx:!android {
} else { } else {
TARGET = GPXSee TARGET = GPXSee
} }
VERSION = 11.7 VERSION = 11.9
QT += core \ QT += core \
gui \ gui \
@ -29,6 +29,7 @@ HEADERS += src/common/config.h \
src/GUI/pluginparameters.h \ src/GUI/pluginparameters.h \
src/common/garmin.h \ src/common/garmin.h \
src/common/coordinates.h \ src/common/coordinates.h \
src/common/linec.h \
src/common/range.h \ src/common/range.h \
src/common/rectc.h \ src/common/rectc.h \
src/common/textcodec.h \ src/common/textcodec.h \

View File

@ -172,6 +172,7 @@
<file alias="chimney.png">icons/map/marine/chimney.png</file> <file alias="chimney.png">icons/map/marine/chimney.png</file>
<file alias="platform.png">icons/map/marine/platform.png</file> <file alias="platform.png">icons/map/marine/platform.png</file>
<file alias="ferry-line.png">icons/map/marine/ferry-line.png</file> <file alias="ferry-line.png">icons/map/marine/ferry-line.png</file>
<file alias="dw-route-line.png">icons/map/marine/dw-route-line.png</file>
</qresource> </qresource>
<!-- Mapsforge rendertheme --> <!-- Mapsforge rendertheme -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -1216,7 +1216,7 @@
<message> <message>
<location filename="../src/map/maplist.cpp" line="158"/> <location filename="../src/map/maplist.cpp" line="158"/>
<source>Electronic Navigational Charts</source> <source>Electronic Navigational Charts</source>
<translation type="unfinished"></translation> <translation>Cartes Nàutiques Electròniques</translation>
</message> </message>
<message> <message>
<location filename="../src/map/maplist.cpp" line="159"/> <location filename="../src/map/maplist.cpp" line="159"/>

View File

@ -1246,7 +1246,7 @@
<message> <message>
<location filename="../src/map/maplist.cpp" line="158"/> <location filename="../src/map/maplist.cpp" line="158"/>
<source>Electronic Navigational Charts</source> <source>Electronic Navigational Charts</source>
<translation type="unfinished"></translation> <translation>Elektroniske sjøkart</translation>
</message> </message>
<message> <message>
<location filename="../src/map/maplist.cpp" line="165"/> <location filename="../src/map/maplist.cpp" line="165"/>

View File

@ -1240,7 +1240,7 @@
<message> <message>
<location filename="../src/map/maplist.cpp" line="158"/> <location filename="../src/map/maplist.cpp" line="158"/>
<source>Electronic Navigational Charts</source> <source>Electronic Navigational Charts</source>
<translation type="unfinished"></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../src/map/maplist.cpp" line="165"/> <location filename="../src/map/maplist.cpp" line="165"/>

View File

@ -37,7 +37,7 @@ Unicode true
; The name of the installer ; The name of the installer
Name "GPXSee" Name "GPXSee"
; Program version ; Program version
!define VERSION "11.7" !define VERSION "11.9"
; The file to write ; The file to write
OutFile "GPXSee-${VERSION}_x64.exe" OutFile "GPXSee-${VERSION}_x64.exe"
@ -181,13 +181,14 @@ Section "GPXSee" SEC_APP
!insertmacro FILE_ASSOCIATION_ADD "qct" "QuickChart Map File" 24 !insertmacro FILE_ASSOCIATION_ADD "qct" "QuickChart Map File" 24
!insertmacro FILE_ASSOCIATION_ADD "trk" "TwoNav Track File" 25 !insertmacro FILE_ASSOCIATION_ADD "trk" "TwoNav Track File" 25
!insertmacro FILE_ASSOCIATION_ADD "gemf" "GEMF Map File" 26 !insertmacro FILE_ASSOCIATION_ADD "gemf" "GEMF Map File" 26
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 27 !insertmacro FILE_ASSOCIATION_ADD "000" "IHO S-57 Electronic Navigation Chart" 27
!insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 27 !insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 28
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 28 !insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 28
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 29 !insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 29
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 30 !insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 30
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 31 !insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 31
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 32 !insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 32
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 33
WriteRegStr HKCR "Applications\GPXSee.exe\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\"" WriteRegStr HKCR "Applications\GPXSee.exe\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\""
WriteRegStr HKCR ".gpx\OpenWithList" "GPXSee.exe" "" WriteRegStr HKCR ".gpx\OpenWithList" "GPXSee.exe" ""
@ -237,6 +238,7 @@ Section "GPXSee" SEC_APP
WriteRegStr HKCR ".qct\OpenWithList" "GPXSee.exe" "" WriteRegStr HKCR ".qct\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".trk\OpenWithList" "GPXSee.exe" "" WriteRegStr HKCR ".trk\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".gemf\OpenWithList" "GPXSee.exe" "" WriteRegStr HKCR ".gemf\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".000\OpenWithList" "GPXSee.exe" ""
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
@ -392,6 +394,7 @@ Section "Uninstall"
!insertmacro FILE_ASSOCIATION_REMOVE "qct" !insertmacro FILE_ASSOCIATION_REMOVE "qct"
!insertmacro FILE_ASSOCIATION_REMOVE "trk" !insertmacro FILE_ASSOCIATION_REMOVE "trk"
!insertmacro FILE_ASSOCIATION_REMOVE "gemf" !insertmacro FILE_ASSOCIATION_REMOVE "gemf"
!insertmacro FILE_ASSOCIATION_REMOVE "000"
DeleteRegValue HKCR ".gpx\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".gpx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tcx\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".tcx\OpenWithList" "GPXSee.exe"
@ -440,6 +443,7 @@ Section "Uninstall"
DeleteRegValue HKCR ".qct\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".qct\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".trk\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".trk\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".gemf\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".gemf\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".000\OpenWithList" "GPXSee.exe"
DeleteRegKey HKCR "Applications\GPXSee.exe" DeleteRegKey HKCR "Applications\GPXSee.exe"
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)' System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'

25
src/common/linec.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef LINEC_H
#define LINEC_H
#include "coordinates.h"
class LineC
{
public:
LineC(const Coordinates &c1, const Coordinates &c2) : _c1(c1), _c2(c2) {}
const Coordinates &c1() const {return _c1;}
const Coordinates &c2() const {return _c2;}
Coordinates pointAt(double t) const
{
return Coordinates(
_c1.lon() + (_c2.lon() - _c1.lon()) * t,
_c1.lat() + (_c2.lat() - _c1.lat()) * t);
}
private:
Coordinates _c1, _c2;
};
#endif // LINEC_H

View File

@ -1,14 +1,20 @@
#ifndef ENC_ATTRIBUTES_H #ifndef ENC_ATTRIBUTES_H
#define ENC_ATTRIBUTES_H #define ENC_ATTRIBUTES_H
#define CATACH 8
#define CATBUA 10
#define CATHAF 30 #define CATHAF 30
#define CATLMK 35 #define CATLMK 35
#define CATMOR 40 #define CATMOR 40
#define CATTRK 54
#define CATREA 56 #define CATREA 56
#define CATWRK 71 #define CATWRK 71
#define DRVAL1 87 #define DRVAL1 87
#define ELEVAT 90 #define ELEVAT 90
#define OBJNAM 116 #define OBJNAM 116
#define ORIENT 117
#define RESTRN 131
#define VALDCO 174 #define VALDCO 174
#define WATLEV 187
#endif // ENC_ATTRIBUTES_H #endif // ENC_ATTRIBUTES_H

View File

@ -2,6 +2,7 @@
#include "common/util.h" #include "common/util.h"
#include "objects.h" #include "objects.h"
#include "attributes.h" #include "attributes.h"
#include "style.h"
#include "mapdata.h" #include "mapdata.h"
using namespace ENC; using namespace ENC;
@ -15,6 +16,52 @@ using namespace ENC;
#define PRIM_L 2 #define PRIM_L 2
#define PRIM_A 3 #define PRIM_A 3
static QMap<uint,uint> orderMapInit()
{
QMap<uint,uint> map;
map.insert(SUBTYPE(BUAARE, 1), 1);
map.insert(SUBTYPE(BUAARE, 5), 2);
map.insert(SUBTYPE(BUAARE, 4), 3);
map.insert(SUBTYPE(BUAARE, 3), 4);
map.insert(SUBTYPE(BUAARE, 2), 5);
map.insert(SUBTYPE(BUAARE, 6), 6);
map.insert(SUBTYPE(BUAARE, 0), 7);
map.insert(TYPE(BCNISD), 8);
map.insert(TYPE(BCNLAT), 9);
map.insert(TYPE(BCNSAW), 10);
map.insert(TYPE(BCNSPP), 11);
map.insert(TYPE(BOYCAR), 12);
map.insert(TYPE(BOYINB), 13);
map.insert(TYPE(BOYISD), 14);
map.insert(TYPE(BOYLAT), 15);
map.insert(TYPE(BOYSAW), 16);
map.insert(TYPE(BOYSPP), 17);
map.insert(TYPE(MORFAC), 18);
map.insert(TYPE(OFSPLF), 19);
map.insert(TYPE(LIGHTS), 20);
map.insert(TYPE(OBSTRN), 21);
map.insert(TYPE(WRECKS), 22);
map.insert(TYPE(UWTROC), 23);
map.insert(TYPE(HRBFAC), 24);
map.insert(TYPE(PILPNT), 25);
map.insert(TYPE(ACHBRT), 26);
map.insert(TYPE(LNDELV), 27);
map.insert(TYPE(LNDMRK), 28);
map.insert(TYPE(SOUNDG), 0xFFFFFFFF);
return map;
}
static QMap<uint,uint> orderMap = orderMapInit();
static uint order(uint type)
{
uint st = ((type>>16) == BUAARE) ? type : (type & 0xFFFF0000);
QMap<uint, uint>::const_iterator it = orderMap.find(st);
return (it == orderMap.constEnd()) ? (type>>16) + 512 : it.value();
}
static void warning(const ISO8211::Field &FRID, uint PRIM) static void warning(const ISO8211::Field &FRID, uint PRIM)
{ {
uint RCID = 0xFFFFFFFF; uint RCID = 0xFFFFFFFF;
@ -132,6 +179,13 @@ static Coordinates point(const ISO8211::Record &r, uint COMF)
return coordinates(x, y, COMF); return coordinates(x, y, COMF);
} }
MapData::Point::Point(uint type, const Coordinates &c, const QString &label)
: _type(type), _pos(c), _label(label)
{
uint hash = (uint)qHash(QPair<double,double>(c.lon(), c.lat()));
_id = ((quint64)order(type))<<32 | hash;
}
QVector<MapData::Sounding> MapData::soundings(const ISO8211::Record &r, QVector<MapData::Sounding> MapData::soundings(const ISO8211::Record &r,
uint COMF, uint SOMF) uint COMF, uint SOMF)
{ {
@ -212,7 +266,7 @@ QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r,
{ {
QVector<Coordinates> path; QVector<Coordinates> path;
Coordinates c[2]; Coordinates c[2];
uint ORNT, MASK; uint ORNT;
quint8 type; quint8 type;
quint32 id; quint32 id;
@ -224,8 +278,6 @@ QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r,
if (!parseNAME(FSPT, &type, &id, i) || type != RCNM_VE) if (!parseNAME(FSPT, &type, &id, i) || type != RCNM_VE)
return QVector<Coordinates>(); return QVector<Coordinates>();
ORNT = FSPT->data().at(i).at(1).toUInt(); ORNT = FSPT->data().at(i).at(1).toUInt();
MASK = FSPT->data().at(i).at(3).toUInt();
Q_ASSERT(MASK != 1);
RecordMapIterator it = ve.find(id); RecordMapIterator it = ve.find(id);
if (it == ve.constEnd()) if (it == ve.constEnd())
@ -280,7 +332,7 @@ Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
Polygon path; Polygon path;
QVector<Coordinates> v; QVector<Coordinates> v;
Coordinates c[2]; Coordinates c[2];
uint ORNT, USAG, MASK; uint ORNT, USAG;
quint8 type; quint8 type;
quint32 id; quint32 id;
@ -293,8 +345,6 @@ Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
return Polygon(); return Polygon();
ORNT = FSPT->data().at(i).at(1).toUInt(); ORNT = FSPT->data().at(i).at(1).toUInt();
USAG = FSPT->data().at(i).at(2).toUInt(); USAG = FSPT->data().at(i).at(2).toUInt();
MASK = FSPT->data().at(i).at(3).toUInt();
Q_ASSERT(MASK != 1);
if (USAG == 2 && path.isEmpty()) { if (USAG == 2 && path.isEmpty()) {
path.append(v); path.append(v);
@ -370,12 +420,14 @@ MapData::Attr MapData::pointAttr(const ISO8211::Record &r, uint OBJL)
uint key = av.at(0).toUInt(); uint key = av.at(0).toUInt();
if (key == OBJNAM) if (key == OBJNAM)
label = av.at(1).toString(); label = QString::fromLatin1(av.at(1).toByteArray());
if ((OBJL == HRBFAC && key == CATHAF) if ((OBJL == HRBFAC && key == CATHAF)
|| (OBJL == LNDMRK && key == CATLMK) || (OBJL == LNDMRK && key == CATLMK)
|| (OBJL == WRECKS && key == CATWRK) || (OBJL == WRECKS && key == CATWRK)
|| (OBJL == MORFAC && key == CATMOR)) || (OBJL == MORFAC && key == CATMOR)
subtype = av.at(1).toString().toUInt(); || (OBJL == UWTROC && key == WATLEV)
|| (OBJL == BUAARE && key == CATBUA))
subtype = av.at(1).toByteArray().toUInt();
} }
return Attr(subtype, label); return Attr(subtype, label);
@ -395,10 +447,12 @@ MapData::Attr MapData::lineAttr(const ISO8211::Record &r, uint OBJL)
uint key = av.at(0).toUInt(); uint key = av.at(0).toUInt();
if (key == OBJNAM) if (key == OBJNAM)
label = av.at(1).toString(); label = QString::fromLatin1(av.at(1).toByteArray());
if ((OBJL == DEPCNT && key == VALDCO) if ((OBJL == DEPCNT && key == VALDCO)
|| (OBJL == LNDELV && key == ELEVAT)) || (OBJL == LNDELV && key == ELEVAT))
label = av.at(1).toString(); label = QString::fromLatin1(av.at(1).toByteArray());
if ((OBJL == RECTRC || OBJL == RCRTCL) && key == CATTRK)
subtype = av.at(1).toByteArray().toUInt();
} }
return Attr(subtype, label); return Attr(subtype, label);
@ -418,9 +472,17 @@ MapData::Attr MapData::polyAttr(const ISO8211::Record &r, uint OBJL)
uint key = av.at(0).toUInt(); uint key = av.at(0).toUInt();
if (OBJL == DEPARE && key == DRVAL1) if (OBJL == DEPARE && key == DRVAL1)
subtype = depthLevel(av.at(1).toString()); subtype = depthLevel(av.at(1).toByteArray());
else if (OBJL == RESARE && key == CATREA) else if ((OBJL == RESARE && key == CATREA)
subtype = av.at(1).toString().toUInt(); || (OBJL == ACHARE && key == CATACH))
subtype = av.at(1).toByteArray().toUInt();
else if (OBJL == RESARE && key == RESTRN) {
if (av.at(1).toByteArray().toUInt() == 1)
subtype = 2;
} else if (OBJL == TSSLPT && key == ORIENT) {
double angle = av.at(1).toByteArray().toDouble();
subtype = (uint)(angle * 10);
}
} }
return Attr(subtype, label); return Attr(subtype, label);
@ -557,7 +619,7 @@ bool MapData::bounds(const QVector<ISO8211::Record> &gv, Rect &b)
return true; return true;
} }
bool MapData::fetchBoundsAndName() MapData::MapData(const QString &path): _fileName(path)
{ {
QFile file(_fileName); QFile file(_fileName);
QVector<ISO8211::Record> gv; QVector<ISO8211::Record> gv;
@ -566,42 +628,34 @@ bool MapData::fetchBoundsAndName()
if (!file.open(QIODevice::ReadOnly)) { if (!file.open(QIODevice::ReadOnly)) {
_errorString = file.errorString(); _errorString = file.errorString();
return false; return;
} }
if (!ddf.readDDR(file)) { if (!ddf.readDDR(file)) {
_errorString = ddf.errorString(); _errorString = ddf.errorString();
return false; return;
} }
while (!file.atEnd()) { while (!file.atEnd()) {
ISO8211::Record record; ISO8211::Record record;
if (!ddf.readRecord(file, record)) { if (!ddf.readRecord(file, record)) {
_errorString = ddf.errorString(); _errorString = ddf.errorString();
return false; return;
} }
if (!processRecord(record, gv, COMF, _name)) if (!processRecord(record, gv, COMF, _name))
return false; return;
} }
Rect b; Rect b;
if (!bounds(gv, b)) { if (!bounds(gv, b)) {
_errorString = "Error fetching geometries bounds"; _errorString = "Error fetching geometries bounds";
return false; return;
} }
RectC br(Coordinates(b.minX() / (double)COMF, b.maxY() / (double)COMF), RectC br(Coordinates(b.minX() / (double)COMF, b.maxY() / (double)COMF),
Coordinates(b.maxX() / (double)COMF, b.minY() / (double)COMF)); Coordinates(b.maxX() / (double)COMF, b.minY() / (double)COMF));
if (!br.isValid()) { if (!br.isValid())
_errorString = "Invalid geometries bounds"; _errorString = "Invalid geometries bounds";
return false; else
} else
_bounds = br; _bounds = br;
return true;
}
MapData::MapData(const QString &path): _fileName(path)
{
fetchBoundsAndName();
} }
MapData::~MapData() MapData::~MapData()
@ -731,3 +785,41 @@ void MapData::polygons(const RectC &rect, QList<Poly*> *polygons)
rectcBounds(rect, min, max); rectcBounds(rect, min, max);
_areas.Search(min, max, polygonCb, polygons); _areas.Search(min, max, polygonCb, polygons);
} }
Range MapData::zooms() const
{
double size = qMin(_bounds.width(), _bounds.height());
if (size > 180)
return Range(0, 20);
else if (size > 90)
return Range(1, 20);
else if (size > 45)
return Range(2, 20);
else if (size > 22.5)
return Range(3, 20);
else if (size > 11.25)
return Range(4, 20);
else if (size > 5.625)
return Range(5, 20);
else if (size > 2.813)
return Range(6, 20);
else if (size > 1.406)
return Range(7, 20);
else if (size > 0.703)
return Range(8, 20);
else if (size > 0.352)
return Range(9, 20);
else if (size > 0.176)
return Range(10, 20);
else if (size > 0.088)
return Range(11, 20);
else if (size > 0.044)
return Range(12, 20);
else if (size > 0.022)
return Range(13, 20);
else if (size > 0.011)
return Range(14, 20);
else
return Range(15, 20);
}

View File

@ -5,6 +5,7 @@
#include "common/rectc.h" #include "common/rectc.h"
#include "common/rtree.h" #include "common/rtree.h"
#include "common/polygon.h" #include "common/polygon.h"
#include "common/range.h"
#include "iso8211.h" #include "iso8211.h"
namespace ENC { namespace ENC {
@ -52,12 +53,7 @@ public:
class Point { class Point {
public: public:
Point(uint type, const Coordinates &c, const QString &label) Point(uint type, const Coordinates &c, const QString &label);
: _type(type), _pos(c), _label(label)
{
uint hash = (uint)qHash(QPair<double,double>(c.lon(), c.lat()));
_id = ((quint64)type)<<32 | hash;
}
const Coordinates &pos() const {return _pos;} const Coordinates &pos() const {return _pos;}
uint type() const {return _type;} uint type() const {return _type;}
@ -78,6 +74,7 @@ public:
const QString &name() const {return _name;} const QString &name() const {return _name;}
RectC bounds() const {return _bounds;} RectC bounds() const {return _bounds;}
Range zooms() const;
void polygons(const RectC &rect, QList<Poly*> *polygons); void polygons(const RectC &rect, QList<Poly*> *polygons);
void lines(const RectC &rect, QList<Line*> *lines); void lines(const RectC &rect, QList<Line*> *lines);
@ -152,8 +149,6 @@ private:
typedef RTree<Line*, double, 2> LineTree; typedef RTree<Line*, double, 2> LineTree;
typedef RTree<Point*, double, 2> PointTree; typedef RTree<Point*, double, 2> PointTree;
bool fetchBoundsAndName();
static QVector<Sounding> soundings(const ISO8211::Record &r, uint COMF, static QVector<Sounding> soundings(const ISO8211::Record &r, uint COMF,
uint SOMF); uint SOMF);
static QVector<Sounding> soundingGeometry(const ISO8211::Record &r, static QVector<Sounding> soundingGeometry(const ISO8211::Record &r,

View File

@ -9,6 +9,7 @@
#define BCNLAT 7 #define BCNLAT 7
#define BCNSAW 8 #define BCNSAW 8
#define BCNSPP 9 #define BCNSPP 9
#define BERTHS 10
#define BRIDGE 11 #define BRIDGE 11
#define BUISGL 12 #define BUISGL 12
#define BUAARE 13 #define BUAARE 13
@ -22,13 +23,17 @@
#define CBLSUB 22 #define CBLSUB 22
#define CANALS 23 #define CANALS 23
#define COALNE 30 #define COALNE 30
#define DAMCON 38
#define DWRTPT 41
#define DEPARE 42 #define DEPARE 42
#define DEPCNT 43 #define DEPCNT 43
#define DRGARE 46 #define DRGARE 46
#define DRYDOC 47
#define DMPGRD 48 #define DMPGRD 48
#define DYKCON 49 #define DYKCON 49
#define FAIRWY 51 #define FAIRWY 51
#define FERYRT 53 #define FERYRT 53
#define FLODOC 57
#define GATCON 61 #define GATCON 61
#define HRBFAC 64 #define HRBFAC 64
#define LAKARE 69 #define LAKARE 69
@ -43,14 +48,20 @@
#define PILPNT 90 #define PILPNT 90
#define PIPSOL 94 #define PIPSOL 94
#define PONTON 95 #define PONTON 95
#define PRCARE 96
#define PYLONS 98
#define RAILWY 106 #define RAILWY 106
#define RCRTCL 108
#define RECTRC 109
#define RESARE 112 #define RESARE 112
#define RIVERS 114 #define RIVERS 114
#define ROADWY 116 #define ROADWY 116
#define SLCONS 122 #define SLCONS 122
#define SLOTOP 126 #define SLOTOP 126
#define SOUNDG 129 #define SOUNDG 129
#define TSELNE 145
#define TSSBND 146 #define TSSBND 146
#define TSSLPT 148
#define TSEZNE 150 #define TSEZNE 150
#define UWTROC 153 #define UWTROC 153
#define UNSARE 154 #define UNSARE 154

View File

@ -1,4 +1,6 @@
#include <QtMath>
#include <QPainter> #include <QPainter>
#include "common/linec.h"
#include "map/bitmapline.h" #include "map/bitmapline.h"
#include "map/textpointitem.h" #include "map/textpointitem.h"
#include "map/textpathitem.h" #include "map/textpathitem.h"
@ -8,9 +10,12 @@
using namespace ENC; using namespace ENC;
#define ICON_PADDING 2 #define ICON_PADDING 2
#define ARROW_SIZE 0.005
#define ECDIS(x) (((x)>TYPE(17000))?((x)-TYPE(17000)):(x)) #define ECDIS(x) (((x)>TYPE(17000))?((x)-TYPE(17000)):(x))
const float C1 = 0.866025f; /* sqrt(3)/2 */
static const QColor haloColor(Qt::white); static const QColor haloColor(Qt::white);
static struct { static struct {
@ -51,6 +56,36 @@ static const Style& style()
return s; return s;
} }
static double area(const QVector<Coordinates> &polygon)
{
double area = 0;
for (int i = 0; i < polygon.size(); i++) {
int j = (i + 1) % polygon.size();
area += polygon.at(i).lon() * polygon.at(j).lat();
area -= polygon.at(i).lat() * polygon.at(j).lon();
}
area /= 2.0;
return area;
}
static Coordinates centroid(const QVector<Coordinates> &polygon)
{
double cx = 0, cy = 0;
double factor = 1.0 / (6.0 * area(polygon));
for (int i = 0; i < polygon.size(); i++) {
int j = (i + 1) % polygon.size();
qreal f = (polygon.at(i).lon() * polygon.at(j).lat()
- polygon.at(j).lon() * polygon.at(i).lat());
cx += (polygon.at(i).lon() + polygon.at(j).lon()) * f;
cy += (polygon.at(i).lat() + polygon.at(j).lat()) * f;
}
return Coordinates(cx * factor, cy * factor);
}
QPainterPath RasterTile::painterPath(const Polygon &polygon) const QPainterPath RasterTile::painterPath(const Polygon &polygon) const
{ {
QPainterPath path; QPainterPath path;
@ -77,6 +112,48 @@ QPolygonF RasterTile::polyline(const QVector<Coordinates> &path) const
return polygon; return polygon;
} }
QPolygonF RasterTile::arrow(const Coordinates &c, qreal angle) const
{
Coordinates t[3], r[4];
QPolygonF polygon;
t[0] = c;
t[1] = Coordinates(t[0].lon() - qCos(angle - M_PI/3) * ARROW_SIZE,
t[0].lat() - qSin(angle - M_PI/3) * ARROW_SIZE);
t[2] = Coordinates(t[0].lon() - qCos(angle - M_PI + M_PI/3) * ARROW_SIZE,
t[0].lat() - qSin(angle - M_PI + M_PI/3) * ARROW_SIZE);
LineC l(t[1], t[2]);
r[0] = l.pointAt(0.25);
r[1] = l.pointAt(0.75);
r[2] = Coordinates(r[0].lon() - C1 * ARROW_SIZE * qCos(angle - M_PI/2),
r[0].lat() - C1 * ARROW_SIZE * qSin(angle - M_PI/2));
r[3] = Coordinates(r[1].lon() - C1 * ARROW_SIZE * qCos(angle - M_PI/2),
r[1].lat() - C1 * ARROW_SIZE * qSin(angle - M_PI/2));
polygon << ll2xy(t[0]) << ll2xy(t[2]) << ll2xy(r[1]) << ll2xy(r[3])
<< ll2xy(r[2]) << ll2xy(r[0]) << ll2xy(t[1]);
return polygon;
}
void RasterTile::drawArrows(QPainter *painter)
{
painter->setPen(QPen(QColor("#eb49eb"), 1));
painter->setBrush(QBrush("#80eb49eb"));
for (int i = 0; i < _polygons.size(); i++) {
const MapData::Poly *poly = _polygons.at(i);
if (poly->type()>>16 == TSSLPT) {
qreal angle = (poly->type() & 0xFFFF) / 10.0;
QPolygonF polygon(arrow(centroid(poly->path().first()),
deg2rad(180 - angle)));
painter->drawPolygon(polygon);
}
}
}
void RasterTile::drawPolygons(QPainter *painter) void RasterTile::drawPolygons(QPainter *painter)
{ {
const Style &s = style(); const Style &s = style();
@ -88,9 +165,15 @@ void RasterTile::drawPolygons(QPainter *painter)
continue; continue;
const Style::Polygon &style = s.polygon(ECDIS(poly->type())); const Style::Polygon &style = s.polygon(ECDIS(poly->type()));
painter->setPen(style.pen()); if (!style.img().isNull()) {
painter->setBrush(style.brush()); for (int i = 0; i < poly->path().size(); i++)
painter->drawPath(painterPath(poly->path())); BitmapLine::draw(painter, polyline(poly->path().at(i)),
style.img());
} else {
painter->setPen(style.pen());
painter->setBrush(style.brush());
painter->drawPath(painterPath(poly->path()));
}
} }
} }
} }
@ -192,6 +275,7 @@ void RasterTile::render()
drawPolygons(&painter); drawPolygons(&painter);
drawLines(&painter); drawLines(&painter);
drawArrows(&painter);
drawTextItems(&painter, textItems); drawTextItems(&painter, textItems);

View File

@ -32,10 +32,12 @@ private:
{return _transform.proj2img(_proj.ll2xy(c));} {return _transform.proj2img(_proj.ll2xy(c));}
QPainterPath painterPath(const Polygon &polygon) const; QPainterPath painterPath(const Polygon &polygon) const;
QPolygonF polyline(const QVector<Coordinates> &path) const; QPolygonF polyline(const QVector<Coordinates> &path) const;
QPolygonF arrow(const Coordinates &c, qreal angle) const;
void processPoints(QList<TextItem*> &textItems); void processPoints(QList<TextItem*> &textItems);
void processLines(QList<TextItem*> &textItems); void processLines(QList<TextItem*> &textItems);
void drawBitmapPath(QPainter *painter, const QImage &img, void drawBitmapPath(QPainter *painter, const QImage &img,
const Polygon &polygon); const Polygon &polygon);
void drawArrows(QPainter *painter);
void drawPolygons(QPainter *painter); void drawPolygons(QPainter *painter);
void drawLines(QPainter *painter); void drawLines(QPainter *painter);
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems); void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);

View File

@ -36,10 +36,9 @@ void Style::defaultPolygonStyle()
_polygons[TYPE(OBSTRN)] = Polygon(Qt::NoBrush, QPen(QColor("#000000"), 1.5, _polygons[TYPE(OBSTRN)] = Polygon(Qt::NoBrush, QPen(QColor("#000000"), 1.5,
Qt::DotLine)); Qt::DotLine));
_polygons[TYPE(PONTON)] = Polygon(QBrush("#333333")); _polygons[TYPE(PONTON)] = Polygon(QBrush("#333333"));
_polygons[TYPE(DRYDOC)] = Polygon(QBrush("#333333"));
_polygons[TYPE(SLCONS)] = Polygon(Qt::NoBrush, QPen(QColor("#333333"), 1.5, _polygons[TYPE(SLCONS)] = Polygon(Qt::NoBrush, QPen(QColor("#333333"), 1.5,
Qt::DashLine)); Qt::DashLine));
_polygons[TYPE(ACHARE)] = Polygon(Qt::NoBrush, QPen(QColor("#e728e7"), 1,
Qt::DashDotLine));
_polygons[TYPE(LAKARE)] = Polygon(QBrush("#9fc4e1"), _polygons[TYPE(LAKARE)] = Polygon(QBrush("#9fc4e1"),
QPen(QColor("#000000"), 1)); QPen(QColor("#000000"), 1));
_polygons[TYPE(CANALS)] = Polygon(QBrush("#9fc4e1"), _polygons[TYPE(CANALS)] = Polygon(QBrush("#9fc4e1"),
@ -48,12 +47,25 @@ void Style::defaultPolygonStyle()
_polygons[TYPE(DYKCON)] = Polygon(QBrush(QColor("#9fc4e1"), _polygons[TYPE(DYKCON)] = Polygon(QBrush(QColor("#9fc4e1"),
Qt::Dense4Pattern), QPen(QColor("#000000"), 1)); Qt::Dense4Pattern), QPen(QColor("#000000"), 1));
_polygons[TYPE(AIRARE)] = Polygon(QBrush("#333333")); _polygons[TYPE(AIRARE)] = Polygon(QBrush("#333333"));
_polygons[SUBTYPE(RESARE, 9)] = Polygon(QBrush(QColor("#ff0000"),
Qt::BDiagPattern), QPen(QColor("#ff0000"), 1));
_polygons[TYPE(TSEZNE)] = Polygon(QBrush("#80fcb4fc")); _polygons[TYPE(TSEZNE)] = Polygon(QBrush("#80fcb4fc"));
_polygons[TYPE(DRGARE)] = Polygon(QBrush(QColor("#a0a0ff"), _polygons[TYPE(DRGARE)] = Polygon(QBrush(QColor("#a0a0ff"),
Qt::Dense4Pattern)); Qt::Dense4Pattern));
_polygons[TYPE(UNSARE)] = Polygon(QBrush("#999999")); _polygons[TYPE(UNSARE)] = Polygon(QBrush("#999999"));
_polygons[SUBTYPE(RESARE, 9)] = Polygon(QBrush(QColor("#ff0000"),
Qt::BDiagPattern));
_polygons[SUBTYPE(RESARE, 2)] = Polygon(QImage(":/marine/noanchor-line.png"));
_polygons[SUBTYPE(ACHARE, 1)] = Polygon(QImage(":/marine/anchor-line.png"));
_polygons[TYPE(PRCARE)] = Polygon(QBrush(QColor("#eb49eb"),
Qt::BDiagPattern));
_polygons[TYPE(DAMCON)] = Polygon(QBrush("#d98b21"), QPen(QColor("#000000"),
1));
_polygons[TYPE(DRYDOC)] = Polygon(QBrush("#ebab54"), QPen(QColor("#000000"),
1));
_polygons[TYPE(PYLONS)] = Polygon(QBrush("#a58140"), QPen(QColor("#000000"),
1));
_polygons[TYPE(FLODOC)] = Polygon(QBrush("#333333"), QPen(QColor("#000000"),
1));
_polygons[TYPE(DWRTPT)] = Polygon(QImage(":/marine/dw-route-line"));
_drawOrder _drawOrder
<< TYPE(M_COVR) << TYPE(LNDARE) << SUBTYPE(DEPARE, 0) << TYPE(M_COVR) << TYPE(LNDARE) << SUBTYPE(DEPARE, 0)
@ -62,12 +74,15 @@ void Style::defaultPolygonStyle()
<< SUBTYPE(DEPARE, 6) << TYPE(LAKARE) << TYPE(CANALS) << TYPE(DYKCON) << SUBTYPE(DEPARE, 6) << TYPE(LAKARE) << TYPE(CANALS) << TYPE(DYKCON)
<< TYPE(RIVERS) << TYPE(DRGARE) << TYPE(FAIRWY) << TYPE(BUAARE) << TYPE(RIVERS) << TYPE(DRGARE) << TYPE(FAIRWY) << TYPE(BUAARE)
<< TYPE(BUISGL) << TYPE(AIRARE) << TYPE(BRIDGE) << TYPE(SLCONS) << TYPE(BUISGL) << TYPE(AIRARE) << TYPE(BRIDGE) << TYPE(SLCONS)
<< TYPE(PONTON) << TYPE(DMPGRD) << TYPE(TSEZNE) << TYPE(OBSTRN) << TYPE(PONTON) << TYPE(FLODOC) << TYPE(DRYDOC) << TYPE(DAMCON)
<< TYPE(ACHARE) << SUBTYPE(RESARE, 9) << TYPE(154); << TYPE(PYLONS) << TYPE(DMPGRD) << TYPE(TSEZNE) << TYPE(OBSTRN)
<< TYPE(DWRTPT) << SUBTYPE(ACHARE, 1) << SUBTYPE(RESARE, 9)
<< SUBTYPE(RESARE, 2) << TYPE(PRCARE);
} }
void Style::defaultLineStyle() void Style::defaultLineStyle()
{ {
_lines[TYPE(BUISGL)] = Line(QPen(QColor("#966118"), 1.5));
_lines[TYPE(DEPCNT)] = Line(QPen(QColor("#659aef"), 1, Qt::SolidLine)); _lines[TYPE(DEPCNT)] = Line(QPen(QColor("#659aef"), 1, Qt::SolidLine));
_lines[TYPE(DEPCNT)].setTextColor(QColor("#558adf")); _lines[TYPE(DEPCNT)].setTextColor(QColor("#558adf"));
_lines[TYPE(DEPCNT)].setTextFontSize(Small); _lines[TYPE(DEPCNT)].setTextFontSize(Small);
@ -92,11 +107,22 @@ void Style::defaultLineStyle()
_lines[TYPE(RAILWY)] = Line(railroad()); _lines[TYPE(RAILWY)] = Line(railroad());
_lines[TYPE(ROADWY)] = Line(QPen(QColor("#000000"), 2, Qt::SolidLine)); _lines[TYPE(ROADWY)] = Line(QPen(QColor("#000000"), 2, Qt::SolidLine));
_lines[TYPE(GATCON)] = Line(QPen(QColor("#000000"), 2, Qt::SolidLine)); _lines[TYPE(GATCON)] = Line(QPen(QColor("#000000"), 2, Qt::SolidLine));
_lines[TYPE(TSELNE)] = Line(QPen(QColor("#80fcb4fc"), 4, Qt::SolidLine));
_lines[SUBTYPE(RECTRC, 1)] = Line(QPen(QColor("#000000"), 0, Qt::SolidLine));
_lines[SUBTYPE(RECTRC, 2)] = Line(QPen(QColor("#000000"), 0, Qt::DashLine));
_lines[SUBTYPE(RCRTCL, 1)] = Line(QPen(QColor("#eb49eb"), 0, Qt::SolidLine));
_lines[SUBTYPE(RCRTCL, 2)] = Line(QPen(QColor("#eb49eb"), 0, Qt::DashLine));
_lines[TYPE(FAIRWY)] = Line(QPen(QColor("#888888"), 1, Qt::DashDotDotLine));
_lines[TYPE(BERTHS)] = Line(QPen(QColor("#333333"), 2));
} }
void Style::defaultPointStyle() void Style::defaultPointStyle()
{ {
_points[TYPE(BUAARE)].setTextFontSize(Large); _points[SUBTYPE(BUAARE, 1)].setTextFontSize(Large);
_points[SUBTYPE(BUAARE, 5)].setTextFontSize(Large);
_points[SUBTYPE(BUAARE, 3)].setTextFontSize(Small);
_points[SUBTYPE(BUAARE, 6)].setTextFontSize(Small);
_points[SUBTYPE(BUAARE, 0)].setTextFontSize(Small);
_points[TYPE(SOUNDG)].setTextFontSize(Small); _points[TYPE(SOUNDG)].setTextFontSize(Small);
_points[TYPE(LIGHTS)] = Point(QImage(":/marine/light-major.png"), Small); _points[TYPE(LIGHTS)] = Point(QImage(":/marine/light-major.png"), Small);
_points[TYPE(BOYCAR)] = Point(QImage(":/marine/buoy.png"), Small); _points[TYPE(BOYCAR)] = Point(QImage(":/marine/buoy.png"), Small);
@ -114,19 +140,28 @@ void Style::defaultPointStyle()
_points[SUBTYPE(LNDMRK, 17)] = Point(QImage(":/marine/tower.png")); _points[SUBTYPE(LNDMRK, 17)] = Point(QImage(":/marine/tower.png"));
_points[TYPE(LNDELV)] = Point(QImage(":/marine/triangulation-point.png")); _points[TYPE(LNDELV)] = Point(QImage(":/marine/triangulation-point.png"));
_points[TYPE(OBSTRN)] = Point(QImage(":/marine/obstruction.png"), Small); _points[TYPE(OBSTRN)] = Point(QImage(":/marine/obstruction.png"), Small);
_points[TYPE(WRECKS)] = Point(QImage(":/marine/wreck.png"), Small);
_points[SUBTYPE(WRECKS, 1)] = Point(QImage(":/marine/wreck.png"), Small); _points[SUBTYPE(WRECKS, 1)] = Point(QImage(":/marine/wreck.png"), Small);
_points[SUBTYPE(WRECKS, 2)] = Point(QImage(":/marine/wreck-dangerous.png"), _points[SUBTYPE(WRECKS, 2)] = Point(QImage(":/marine/wreck-dangerous.png"),
Small); Small);
_points[SUBTYPE(WRECKS, 3)] = Point(QImage(":/marine/wreck.png"), Small); _points[SUBTYPE(WRECKS, 3)] = Point(QImage(":/marine/wreck.png"), Small);
_points[SUBTYPE(WRECKS, 4)] = Point(QImage(":/marine/wreck.png"), Small); _points[SUBTYPE(WRECKS, 4)] = Point(QImage(":/marine/wreck.png"), Small);
_points[SUBTYPE(WRECKS, 5)] = Point(QImage(":/marine/wreck-exposed.png")); _points[SUBTYPE(WRECKS, 5)] = Point(QImage(":/marine/wreck-exposed.png"));
_points[TYPE(UWTROC)] = Point(QImage(":/marine/rock-dangerous.png"), Small); _points[SUBTYPE(UWTROC, 1)] = Point(QImage(":/marine/rock-exposed.png"),
Small);
_points[SUBTYPE(UWTROC, 2)] = Point(QImage(":/marine/rock-exposed.png"),
Small);
_points[SUBTYPE(UWTROC, 3)] = Point(QImage(":/marine/rock-dangerous.png"),
Small);
_points[SUBTYPE(UWTROC, 4)] = Point(QImage(":/marine/rock-dangerous.png"),
Small);
_points[SUBTYPE(UWTROC, 5)] = Point(QImage(":/marine/rock-dangerous.png"),
Small);
_points[SUBTYPE(HRBFAC, 5)] = Point(QImage(":/marine/yacht-harbor.png")); _points[SUBTYPE(HRBFAC, 5)] = Point(QImage(":/marine/yacht-harbor.png"));
_points[TYPE(ACHBRT)] = Point(QImage(":/marine/anchorage.png")); _points[TYPE(ACHBRT)] = Point(QImage(":/marine/anchorage.png"));
_points[TYPE(OFSPLF)] = Point(QImage(":/marine/platform.png")); _points[TYPE(OFSPLF)] = Point(QImage(":/marine/platform.png"));
_points[TYPE(PILPNT)] = Point(QImage(":/marine/pile.png"), Small); _points[TYPE(PILPNT)] = Point(QImage(":/marine/pile.png"), Small);
_points[SUBTYPE(MORFAC, 1)] = Point(QImage(":/marine/pile.png"), Small); _points[SUBTYPE(MORFAC, 1)] = Point(QImage(":/marine/pile.png"), Small);
_points[SUBTYPE(MORFAC, 3)] = Point(QImage(":/marine/pile.png"), Small);
_points[SUBTYPE(MORFAC, 5)] = Point(QImage(":/marine/pile.png"), Small); _points[SUBTYPE(MORFAC, 5)] = Point(QImage(":/marine/pile.png"), Small);
_points[SUBTYPE(MORFAC, 7)] = Point(QImage(":/marine/mooring-buoy.png"), _points[SUBTYPE(MORFAC, 7)] = Point(QImage(":/marine/mooring-buoy.png"),
Small); Small);

View File

@ -29,13 +29,18 @@ public:
{ {
_pen = (pen == Qt::NoPen) ? QPen(_brush, 0) : pen; _pen = (pen == Qt::NoPen) ? QPen(_brush, 0) : pen;
} }
Polygon(const QImage &img)
: _brush(Qt::NoBrush), _pen(Qt::NoPen), _img(img.convertToFormat(
QImage::Format_ARGB32_Premultiplied)) {}
const QPen &pen() const {return _pen;} const QPen &pen() const {return _pen;}
const QBrush &brush() const {return _brush;} const QBrush &brush() const {return _brush;}
const QImage &img() const {return _img;}
private: private:
QBrush _brush; QBrush _brush;
QPen _pen; QPen _pen;
QImage _img;
}; };
class Line { class Line {

View File

@ -11,7 +11,6 @@
using namespace ENC; using namespace ENC;
static Range ZOOMS = Range(0, 20);
ENCMap::ENCMap(const QString &fileName, QObject *parent) ENCMap::ENCMap(const QString &fileName, QObject *parent)
: Map(fileName, parent), _data(fileName), _projection(PCS::pcs(3857)), : Map(fileName, parent), _data(fileName), _projection(PCS::pcs(3857)),
@ -30,6 +29,7 @@ void ENCMap::load()
void ENCMap::unload() void ENCMap::unload()
{ {
cancelJobs(true);
_data.clear(); _data.clear();
} }
@ -38,8 +38,8 @@ int ENCMap::zoomFit(const QSize &size, const RectC &rect)
if (rect.isValid()) { if (rect.isValid()) {
RectD pr(rect, _projection, 10); RectD pr(rect, _projection, 10);
_zoom = ZOOMS.min(); _zoom = _data.zooms().min();
for (int i = ZOOMS.min() + 1; i <= ZOOMS.max(); i++) { for (int i = _data.zooms().min() + 1; i <= _data.zooms().max(); i++) {
Transform t(transform(i)); Transform t(transform(i));
QRectF r(t.proj2img(pr.topLeft()), t.proj2img(pr.bottomRight())); QRectF r(t.proj2img(pr.topLeft()), t.proj2img(pr.bottomRight()));
if (size.width() < r.width() || size.height() < r.height()) if (size.width() < r.width() || size.height() < r.height())
@ -47,7 +47,7 @@ int ENCMap::zoomFit(const QSize &size, const RectC &rect)
_zoom = i; _zoom = i;
} }
} else } else
_zoom = ZOOMS.max(); _zoom = _data.zooms().max();
updateTransform(); updateTransform();
@ -56,18 +56,18 @@ int ENCMap::zoomFit(const QSize &size, const RectC &rect)
int ENCMap::zoomIn() int ENCMap::zoomIn()
{ {
cancelJobs(); cancelJobs(false);
_zoom = qMin(_zoom + 1, ZOOMS.max()); _zoom = qMin(_zoom + 1, _data.zooms().max());
updateTransform(); updateTransform();
return _zoom; return _zoom;
} }
int ENCMap::zoomOut() int ENCMap::zoomOut()
{ {
cancelJobs(); cancelJobs(false);
_zoom = qMax(_zoom - 1, ZOOMS.min()); _zoom = qMax(_zoom - 1, _data.zooms().min());
updateTransform(); updateTransform();
return _zoom; return _zoom;
} }
@ -141,10 +141,10 @@ void ENCMap::jobFinished(ENCMapJob *job)
emit tilesLoaded(); emit tilesLoaded();
} }
void ENCMap::cancelJobs() void ENCMap::cancelJobs(bool wait)
{ {
for (int i = 0; i < _jobs.size(); i++) for (int i = 0; i < _jobs.size(); i++)
_jobs.at(i)->cancel(); _jobs.at(i)->cancel(wait);
} }
QString ENCMap::key(int zoom, const QPoint &xy) const QString ENCMap::key(int zoom, const QPoint &xy) const

View File

@ -23,7 +23,12 @@ public:
_future = QtConcurrent::map(_tiles, &ENC::RasterTile::render); _future = QtConcurrent::map(_tiles, &ENC::RasterTile::render);
_watcher.setFuture(_future); _watcher.setFuture(_future);
} }
void cancel() {_future.cancel();} void cancel(bool wait)
{
_future.cancel();
if (wait)
_future.waitForFinished();
}
const QList<ENC::RasterTile> &tiles() const {return _tiles;} const QList<ENC::RasterTile> &tiles() const {return _tiles;}
signals: signals:
@ -82,7 +87,7 @@ private:
bool isRunning(int zoom, const QPoint &xy) const; bool isRunning(int zoom, const QPoint &xy) const;
void runJob(ENCMapJob *job); void runJob(ENCMapJob *job);
void removeJob(ENCMapJob *job); void removeJob(ENCMapJob *job);
void cancelJobs(); void cancelJobs(bool wait);
QString key(int zoom, const QPoint &xy) const; QString key(int zoom, const QPoint &xy) const;
ENC::MapData _data; ENC::MapData _data;