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

Compare commits

...

42 Commits
11.7 ... 11.10

Author SHA1 Message Date
07954b7d1a Prohibited areas 2022-11-26 19:22:09 +01:00
08dbb315cb Turning basins 2022-11-26 16:51:12 +01:00
82b8314b74 Some more ENC stuff 2022-11-26 15:14:41 +01:00
12b17487ac Some more ENC render style enhancements 2022-11-26 13:05:08 +01:00
a05098f502 Fixed render order 2022-11-25 23:23:08 +01:00
4cfb967e39 Some more ENC render style improvements 2022-11-25 23:20:35 +01:00
04f45013eb Some more inland wates ECDIS style fixes/improvements 2022-11-25 02:16:17 +01:00
0c8a77a4ca Fixed broken inland ECDIS styles 2022-11-24 09:34:03 +01:00
03c9dbd2a7 Back to Qt 6.4.0 2022-11-23 20:54:55 +01:00
2a2cd5ff59 Use Qt 6.4.1 for Android CI builds 2022-11-23 20:40:09 +01:00
3b134d52aa Distinguish some more OSs 2022-11-23 20:20:35 +01:00
5fbc95f206 Version++ 2022-11-20 08:43:12 +01:00
f47a5e50ad MORFAC & CRANES rendering 2022-11-19 23:55:17 +01:00
0c5076eaaf Added missing fences rendering 2022-11-19 16:15:50 +01:00
2438150679 Updated github action components 2022-11-19 13:20:46 +01:00
d04c070fe1 Fixed typo 2022-11-17 22:03:30 +01:00
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
38 changed files with 601 additions and 138 deletions

View File

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

View File

@ -26,12 +26,12 @@ jobs:
- name: Setup NDK path - name: Setup NDK path
run: echo "ANDROID_NDK_ROOT=${ANDROID_HOME}/ndk/23.1.7779620/" >> $GITHUB_ENV run: echo "ANDROID_NDK_ROOT=${ANDROID_HOME}/ndk/23.1.7779620/" >> $GITHUB_ENV
- name: Install Qt (Desktop) - name: Install Qt (Desktop)
uses: jurplel/install-qt-action@v2 uses: jurplel/install-qt-action@v3
with: with:
aqtversion: '==2.1.0' aqtversion: '==2.1.0'
version: '6.4.0' version: '6.4.0'
- name: Install Qt (Android) - name: Install Qt (Android)
uses: jurplel/install-qt-action@v2 uses: jurplel/install-qt-action@v3
with: with:
aqtversion: '==2.1.0' aqtversion: '==2.1.0'
version: '6.4.0' version: '6.4.0'
@ -47,7 +47,7 @@ jobs:
- name: Build project - name: Build project
run: make -j2 apk run: make -j2 apk
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: GPXSee-armv7.apk name: GPXSee-armv7.apk
path: android-build/build/outputs/apk/debug/android-build-debug.apk path: android-build/build/outputs/apk/debug/android-build-debug.apk

View File

@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get update sudo apt-get update

View File

@ -13,7 +13,7 @@ jobs:
- name: Set environment variables - name: Set environment variables
run: echo "PATH=/usr/local/opt/qt@5/bin:$PATH" >> $GITHUB_ENV run: echo "PATH=/usr/local/opt/qt@5/bin:$PATH" >> $GITHUB_ENV
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Install dependencies - name: Install dependencies
run: brew install qt5 run: brew install qt5
- name: Create localization - name: Create localization
@ -25,7 +25,7 @@ jobs:
- name: Create DMG - name: Create DMG
run: macdeployqt GPXSee.app -dmg run: macdeployqt GPXSee.app -dmg
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: GPXSee-qt5.dmg name: GPXSee-qt5.dmg
path: GPXSee.dmg path: GPXSee.dmg
@ -37,7 +37,7 @@ jobs:
- name: Set environment variables - name: Set environment variables
run: echo "PATH=/usr/local/opt/qt@6/bin:$PATH" >> $GITHUB_ENV run: echo "PATH=/usr/local/opt/qt@6/bin:$PATH" >> $GITHUB_ENV
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Install dependencies - name: Install dependencies
run: brew install qt6 run: brew install qt6
- name: Create localization - name: Create localization
@ -49,7 +49,7 @@ jobs:
- name: Create DMG - name: Create DMG
run: macdeployqt GPXSee.app -dmg run: macdeployqt GPXSee.app -dmg
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: GPXSee-qt6.dmg name: GPXSee-qt6.dmg
path: GPXSee.dmg path: GPXSee.dmg

View File

@ -10,7 +10,7 @@ GPS log file formats.
QuadTiles). QuadTiles).
* Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases, * Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases,
Garmin IMG/GMAP & JNX maps, TwoNav RMaps, GeoTIFF images, BSB charts, Garmin IMG/GMAP & JNX maps, TwoNav RMaps, GeoTIFF images, BSB charts,
ENC charts KMZ maps, AlpineQuest maps, Locus/OsmAnd/RMaps SQLite maps, ENC charts, KMZ maps, AlpineQuest maps, Locus/OsmAnd/RMaps SQLite maps,
Mapsforge vector maps, QCT maps, GEMF maps, Osmdroid SQLite maps, Orux maps, Mapsforge vector maps, QCT maps, GEMF maps, Osmdroid SQLite maps, Orux maps,
ESRI World-File georeferenced images). ESRI World-File georeferenced images).
* Elevation, speed, heart rate, cadence, power, temperature and gear ratio/shifts * Elevation, speed, heart rate, cadence, power, temperature and gear ratio/shifts

View File

@ -3,7 +3,7 @@ unix:!macx:!android {
} else { } else {
TARGET = GPXSee TARGET = GPXSee
} }
VERSION = 11.7 VERSION = 11.10
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,20 @@
<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>
<file alias="fence-line.png">icons/map/marine/fence-line.png</file>
<file alias="crane.png">icons/map/marine/crane.png</file>
<file alias="distance-mark.png">icons/map/marine/distance-mark.png</file>
<file alias="conveyor-line.png">icons/map/marine/conveyor-line.png</file>
<file alias="pipeline-overhead.png">icons/map/marine/pipeline-overhead.png</file>
<file alias="coast-guard.png">icons/map/marine/coast-guard.png</file>
<file alias="monument.png">icons/map/marine/monument.png</file>
<file alias="radio.png">icons/map/marine/radio.png</file>
<file alias="radar.png">icons/map/marine/radar.png</file>
<file alias="radar-transponder.png">icons/map/marine/radar-transponder.png</file>
<file alias="silo.png">icons/map/marine/silo.png</file>
<file alias="turning-basin.png">icons/map/marine/turning-basin.png</file>
<file alias="entry-prohibited-line.png">icons/map/marine/entry-prohibited-line.png</file>
</qresource> </qresource>
<!-- Mapsforge rendertheme --> <!-- Mapsforge rendertheme -->

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

BIN
icons/map/marine/crane.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
icons/map/marine/radar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

BIN
icons/map/marine/radio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

BIN
icons/map/marine/silo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

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.10"
; 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)'

View File

@ -7,12 +7,18 @@
#include "downloader.h" #include "downloader.h"
#if defined(Q_OS_LINUX) #if defined(Q_OS_ANDROID)
#define PLATFORM_STR "Android"
#elif defined(Q_OS_LINUX)
#define PLATFORM_STR "Linux" #define PLATFORM_STR "Linux"
#elif defined(Q_OS_WIN32) #elif defined(Q_OS_WIN32)
#define PLATFORM_STR "Windows" #define PLATFORM_STR "Windows"
#elif defined(Q_OS_MAC) #elif defined(Q_OS_MAC)
#define PLATFORM_STR "OS X" #define PLATFORM_STR "OS X"
#elif defined(Q_OS_BSD4)
#define PLATFORM_STR "BSD"
#elif defined(Q_OS_HAIKU)
#define PLATFORM_STR "Haiku"
#else #else
#define PLATFORM_STR "Unknown" #define PLATFORM_STR "Unknown"
#endif #endif

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,26 @@
#ifndef ENC_ATTRIBUTES_H #ifndef ENC_ATTRIBUTES_H
#define ENC_ATTRIBUTES_H #define ENC_ATTRIBUTES_H
#define CATACH 8
#define CATBUA 10
#define CATDIS 21
#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
#define I_CATACH 17000
#define I_RESTRN 17004
#define I_WTWDIS 17064
#define I_HUNITS 17103
#endif // ENC_ATTRIBUTES_H #endif // ENC_ATTRIBUTES_H

View File

@ -194,7 +194,7 @@ bool ISO8211::readDDR(QFile &file)
int len = readDR(file, fields); int len = readDR(file, fields);
if (len < 0) { if (len < 0) {
_errorString = "Not a ENC file"; _errorString = "Not a ISO8211 file";
return false; return false;
} }

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,63 @@ 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(TYPE(CGUSTA), 0);
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(RDOSTA), 8);
map.insert(TYPE(RADSTA), 9);
map.insert(TYPE(RTPBCN), 10);
map.insert(TYPE(BCNISD), 11);
map.insert(TYPE(BCNLAT), 12);
map.insert(TYPE(I_BCNLAT), 12);
map.insert(TYPE(BCNSAW), 13);
map.insert(TYPE(BCNSPP), 14);
map.insert(TYPE(BOYCAR), 15);
map.insert(TYPE(BOYINB), 16);
map.insert(TYPE(BOYISD), 17);
map.insert(TYPE(BOYLAT), 18);
map.insert(TYPE(I_BOYLAT), 18);
map.insert(TYPE(BOYSAW), 19);
map.insert(TYPE(BOYSPP), 20);
map.insert(TYPE(MORFAC), 21);
map.insert(TYPE(OFSPLF), 22);
map.insert(TYPE(LIGHTS), 23);
map.insert(TYPE(OBSTRN), 24);
map.insert(TYPE(WRECKS), 25);
map.insert(TYPE(UWTROC), 26);
map.insert(TYPE(HRBFAC), 27);
map.insert(TYPE(PILPNT), 28);
map.insert(TYPE(ACHBRT), 29);
map.insert(TYPE(I_ACHBRT), 29);
map.insert(TYPE(CRANES), 30);
map.insert(TYPE(I_CRANES), 30);
map.insert(TYPE(LNDMRK), 31);
map.insert(TYPE(SILTNK), 32);
map.insert(TYPE(LNDELV), 33);
map.insert(TYPE(I_DISMAR), 0xFFFFFFFE);
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;
@ -95,9 +153,26 @@ static bool polygonCb(MapData::Poly *polygon, void *context)
return true; return true;
} }
static uint depthLevel(const QString &str) static Coordinates coordinates(int x, int y, uint COMF)
{ {
double minDepth = str.isEmpty() ? -1 : str.toDouble(); return Coordinates(x / (double)COMF, y / (double)COMF);
}
static Coordinates point(const ISO8211::Record &r, uint COMF)
{
const ISO8211::Field *f = SGXD(r);
if (!f)
return Coordinates();
int y = f->data().at(0).at(0).toInt();
int x = f->data().at(0).at(1).toInt();
return coordinates(x, y, COMF);
}
static uint depthLevel(const QByteArray &ba)
{
double minDepth = ba.isEmpty() ? -1 : ba.toDouble();
if (minDepth < 0) if (minDepth < 0)
return 0; return 0;
@ -115,21 +190,65 @@ static uint depthLevel(const QString &str)
return 6; return 6;
} }
static Coordinates coordinates(int x, int y, uint COMF) static QString hUnits(uint type)
{ {
return Coordinates(x / (double)COMF, y / (double)COMF); switch (type) {
case 1:
return "m";
case 2:
return "ft";
case 3:
return "km";
case 4:
return "hm";
case 5:
return "mi";
case 6:
return "nm";
default:
return QString();
}
} }
static Coordinates point(const ISO8211::Record &r, uint COMF) MapData::Point::Point(uint type, const Coordinates &c, const QString &label,
const QByteArray &param) : _type(type), _pos(c), _label(label)
{ {
const ISO8211::Field *f = SGXD(r); uint hash = (uint)qHash(QPair<double,double>(c.lon(), c.lat()));
if (!f) _id = ((quint64)order(type))<<32 | hash;
return Coordinates();
int y = f->data().at(0).at(0).toInt(); if ((type & 0xFFFF0000) == TYPE(I_DISMAR)) {
int x = f->data().at(0).at(1).toInt(); _label = hUnits((type>>8)&0xFF) + " " + QString::fromLatin1(param);
_type = SUBTYPE(I_DISMAR, type & 0xFF);
}
}
return coordinates(x, y, COMF); MapData::Poly::Poly(uint type, const Polygon &path, const QByteArray &param)
: _type(type), _path(path)
{
if (type == TYPE(DEPARE))
_type = SUBTYPE(DEPARE, depthLevel(param));
else if (type == TYPE(TSSLPT)) {
double angle = param.toDouble();
_type = SUBTYPE(TSSLPT, (uint)(angle * 10));
}
}
MapData::Line::Line(uint type, const QVector<Coordinates> &path,
const QString &label, const QByteArray &param) : _type(type), _path(path),
_label(label)
{
if (type == TYPE(DEPCNT) || type == TYPE(LNDELV))
_label = QString::fromLatin1(param);
}
RectC MapData::Line::bounds() const
{
RectC b;
for (int i = 0; i < _path.size(); i++)
b = b.united(_path.at(i));
return b;
} }
QVector<MapData::Sounding> MapData::soundings(const ISO8211::Record &r, QVector<MapData::Sounding> MapData::soundings(const ISO8211::Record &r,
@ -212,7 +331,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 +343,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 +397,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 +410,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);
@ -359,6 +474,7 @@ Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
MapData::Attr MapData::pointAttr(const ISO8211::Record &r, uint OBJL) MapData::Attr MapData::pointAttr(const ISO8211::Record &r, uint OBJL)
{ {
QString label; QString label;
QByteArray param;
uint subtype = 0; uint subtype = 0;
const ISO8211::Field *ATTF = r.field("ATTF"); const ISO8211::Field *ATTF = r.field("ATTF");
@ -370,20 +486,31 @@ 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();
else if (OBJL == I_DISMAR && key == CATDIS)
subtype |= av.at(1).toByteArray().toUInt();
else if (OBJL == I_DISMAR && key == I_HUNITS)
subtype |= av.at(1).toByteArray().toUInt() << 8;
if (OBJL == I_DISMAR && key == I_WTWDIS)
param = av.at(1).toByteArray();
} }
return Attr(subtype, label); return Attr(subtype, label, param);
} }
MapData::Attr MapData::lineAttr(const ISO8211::Record &r, uint OBJL) MapData::Attr MapData::lineAttr(const ISO8211::Record &r, uint OBJL)
{ {
QString label; QString label;
QByteArray param;
uint subtype = 0; uint subtype = 0;
const ISO8211::Field *ATTF = r.field("ATTF"); const ISO8211::Field *ATTF = r.field("ATTF");
@ -395,18 +522,23 @@ 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 == RECTRC || OBJL == RCRTCL) && key == CATTRK)
subtype = av.at(1).toByteArray().toUInt();
if ((OBJL == DEPCNT && key == VALDCO) if ((OBJL == DEPCNT && key == VALDCO)
|| (OBJL == LNDELV && key == ELEVAT)) || (OBJL == LNDELV && key == ELEVAT))
label = av.at(1).toString(); param = av.at(1).toByteArray();
} }
return Attr(subtype, label); return Attr(subtype, label, param);
} }
MapData::Attr MapData::polyAttr(const ISO8211::Record &r, uint OBJL) MapData::Attr MapData::polyAttr(const ISO8211::Record &r, uint OBJL)
{ {
QString label; QString label;
QByteArray param;
uint subtype = 0; uint subtype = 0;
const ISO8211::Field *ATTF = r.field("ATTF"); const ISO8211::Field *ATTF = r.field("ATTF");
@ -417,18 +549,30 @@ MapData::Attr MapData::polyAttr(const ISO8211::Record &r, uint OBJL)
const QVector<QVariant> &av = ATTF->data().at(i); const QVector<QVariant> &av = ATTF->data().at(i);
uint key = av.at(0).toUInt(); uint key = av.at(0).toUInt();
if (OBJL == DEPARE && key == DRVAL1) if ((OBJL == RESARE && key == CATREA)
subtype = depthLevel(av.at(1).toString()); || (OBJL == I_RESARE && key == CATREA)
else if (OBJL == RESARE && key == CATREA) || (OBJL == ACHARE && key == CATACH)
subtype = av.at(1).toString().toUInt(); || (OBJL == I_ACHARE && key == I_CATACH))
subtype = av.at(1).toByteArray().toUInt();
else if ((OBJL == RESARE && key == RESTRN)
|| (OBJL == I_RESARE && key == I_RESTRN)) {
if (av.at(1).toByteArray().toUInt() == 1)
subtype = 2;
if (av.at(1).toByteArray().toUInt() == 7)
subtype = 17;
}
if ((OBJL == TSSLPT && key == ORIENT)
|| (OBJL == DEPARE && key == DRVAL1))
param = av.at(1).toByteArray();
} }
return Attr(subtype, label); return Attr(subtype, label, param);
} }
MapData::Point *MapData::pointObject(const Sounding &s) MapData::Point *MapData::pointObject(const Sounding &s)
{ {
return new Point(SOUNDG<<16, s.c, QString::number(s.depth)); return new Point(TYPE(SOUNDG), s.c, QString::number(s.depth), QByteArray());
} }
MapData::Point *MapData::pointObject(const ISO8211::Record &r, MapData::Point *MapData::pointObject(const ISO8211::Record &r,
@ -437,8 +581,8 @@ MapData::Point *MapData::pointObject(const ISO8211::Record &r,
Coordinates c(pointGeometry(r, vi, vc, COMF)); Coordinates c(pointGeometry(r, vi, vc, COMF));
Attr attr(pointAttr(r, OBJL)); Attr attr(pointAttr(r, OBJL));
return (c.isNull() ? 0 : new Point(OBJL<<16|attr.subtype(), c, return (c.isNull() ? 0 : new Point(SUBTYPE(OBJL,attr.subtype()), c,
attr.label())); attr.label(), attr.param()));
} }
MapData::Line *MapData::lineObject(const ISO8211::Record &r, MapData::Line *MapData::lineObject(const ISO8211::Record &r,
@ -447,8 +591,8 @@ MapData::Line *MapData::lineObject(const ISO8211::Record &r,
QVector<Coordinates> path(lineGeometry(r, vc, ve, COMF)); QVector<Coordinates> path(lineGeometry(r, vc, ve, COMF));
Attr attr(lineAttr(r, OBJL)); Attr attr(lineAttr(r, OBJL));
return (path.isEmpty() ? 0 : new Line(OBJL<<16|attr.subtype(), path, return (path.isEmpty() ? 0 : new Line(SUBTYPE(OBJL, attr.subtype()), path,
attr.label())); attr.label(), attr.param()));
} }
MapData::Poly *MapData::polyObject(const ISO8211::Record &r, MapData::Poly *MapData::polyObject(const ISO8211::Record &r,
@ -457,7 +601,8 @@ MapData::Poly *MapData::polyObject(const ISO8211::Record &r,
Polygon path(polyGeometry(r, vc, ve, COMF)); Polygon path(polyGeometry(r, vc, ve, COMF));
Attr attr(polyAttr(r, OBJL)); Attr attr(polyAttr(r, OBJL));
return (path.isEmpty() ? 0 : new Poly(OBJL<<16|attr.subtype(), path)); return (path.isEmpty() ? 0 : new Poly(SUBTYPE(OBJL, attr.subtype()), path,
attr.param()));
} }
bool MapData::processRecord(const ISO8211::Record &record, bool MapData::processRecord(const ISO8211::Record &record,
@ -557,7 +702,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 +711,36 @@ 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)) {
_errorString = "Invalid S-57 record";
return;
} }
if (!processRecord(record, gv, COMF, _name))
return false;
} }
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 +870,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, 10);
else if (size > 90)
return Range(1, 11);
else if (size > 45)
return Range(2, 12);
else if (size > 22.5)
return Range(3, 13);
else if (size > 11.25)
return Range(4, 14);
else if (size > 5.625)
return Range(5, 15);
else if (size > 2.813)
return Range(6, 16);
else if (size > 1.406)
return Range(7, 17);
else if (size > 0.703)
return Range(8, 18);
else if (size > 0.352)
return Range(9, 19);
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 {
@ -14,8 +15,7 @@ class MapData
public: public:
class Poly { class Poly {
public: public:
Poly(uint type, const Polygon &path) Poly(uint type, const Polygon &path, const QByteArray &param);
: _type(type), _path(path) {}
RectC bounds() const {return _path.boundingRect();} RectC bounds() const {return _path.boundingRect();}
const Polygon &path() const {return _path;} const Polygon &path() const {return _path;}
@ -28,18 +28,10 @@ public:
class Line { class Line {
public: public:
Line(uint type, const QVector<Coordinates> &path, const QString &label) Line(uint type, const QVector<Coordinates> &path, const QString &label,
: _type(type), _path(path), _label(label) {} const QByteArray &param);
RectC bounds() const RectC bounds() const;
{
RectC b;
for (int i = 0; i < _path.size(); i++)
b = b.united(_path.at(i));
return b;
}
const QVector<Coordinates> &path() const {return _path;} const QVector<Coordinates> &path() const {return _path;}
uint type() const {return _type;} uint type() const {return _type;}
const QString &label() const {return _label;} const QString &label() const {return _label;}
@ -52,12 +44,8 @@ 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) const QByteArray &param);
{
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 +66,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);
@ -127,15 +116,17 @@ private:
class Attr { class Attr {
public: public:
Attr() : _subtype(0) {} Attr() : _subtype(0) {}
Attr(uint subtype, const QString &label = QString()) Attr(uint subtype, const QString &label, const QByteArray &param)
: _subtype(subtype), _label(label) {} : _subtype(subtype), _label(label), _param(param) {}
unsigned subtype() const {return _subtype;} unsigned subtype() const {return _subtype;}
const QString &label() const {return _label;} const QString &label() const {return _label;}
const QByteArray &param() const {return _param;}
private: private:
unsigned _subtype; unsigned _subtype;
QString _label; QString _label;
QByteArray _param;
}; };
struct Sounding { struct Sounding {
@ -152,8 +143,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
@ -21,40 +22,83 @@
#define CBLOHD 21 #define CBLOHD 21
#define CBLSUB 22 #define CBLSUB 22
#define CANALS 23 #define CANALS 23
#define CGUSTA 29
#define COALNE 30 #define COALNE 30
#define CONVYR 34
#define CRANES 35
#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 FNCLNE 52
#define FERYRT 53 #define FERYRT 53
#define FLODOC 57
#define GATCON 61 #define GATCON 61
#define HRBFAC 64 #define HRBFAC 64
#define HULKES 65
#define LAKARE 69 #define LAKARE 69
#define LNDARE 71 #define LNDARE 71
#define LNDELV 72 #define LNDELV 72
#define LNDMRK 74 #define LNDMRK 74
#define LIGHTS 75 #define LIGHTS 75
#define LOKBSN 79
#define MORFAC 84 #define MORFAC 84
#define NAVLNE 85 #define NAVLNE 85
#define OBSTRN 86 #define OBSTRN 86
#define OFSPLF 87 #define OFSPLF 87
#define PILPNT 90 #define PILPNT 90
#define PIPOHD 93
#define PIPSOL 94 #define PIPSOL 94
#define PONTON 95 #define PONTON 95
#define PRCARE 96
#define PYLONS 98
#define RADSTA 102
#define RTPBCN 103
#define RDOSTA 105
#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 SILTNK 125
#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
#define WRECKS 159 #define WRECKS 159
#define M_COVR 302 #define M_COVR 302
#define I_ACHBRT 17000
#define I_ACHARE 17001
#define I_DISMAR 17004
#define I_RESARE 17005
#define I_BERTHS 17010
#define I_BRIDGE 17011
#define I_CBLOHD 17012
#define I_FERYRT 17013
#define I_LOKBSN 17016
#define I_HULKES 17020
#define I_PONTON 17021
#define I_PIPOHD 17024
#define I_FLODOC 17025
#define I_BCNLAT 17028
#define I_BOYLAT 17029
#define I_CRANES 17030
#define I_GATCON 17031
#define I_SLCONS 17032
#define I_WTWAXS 17051
#define I_TERMNL 17064
#define I_TRNBSN 17065
#endif // ENC_OBJECTS_H #endif // ENC_OBJECTS_H

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,8 +10,9 @@
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)) const float C1 = 0.866025f; /* sqrt(3)/2 */
static const QColor haloColor(Qt::white); static const QColor haloColor(Qt::white);
@ -51,6 +54,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 +110,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();
@ -84,13 +159,19 @@ void RasterTile::drawPolygons(QPainter *painter)
for (int n = 0; n < s.drawOrder().size(); n++) { for (int n = 0; n < s.drawOrder().size(); n++) {
for (int i = 0; i < _polygons.size(); i++) { for (int i = 0; i < _polygons.size(); i++) {
const MapData::Poly *poly = _polygons.at(i); const MapData::Poly *poly = _polygons.at(i);
if (ECDIS(poly->type()) != s.drawOrder().at(n)) if (poly->type() != s.drawOrder().at(n))
continue; continue;
const Style::Polygon &style = s.polygon(ECDIS(poly->type())); const Style::Polygon &style = s.polygon(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()));
}
} }
} }
} }
@ -103,7 +184,7 @@ void RasterTile::drawLines(QPainter *painter)
for (int i = 0; i < _lines.size(); i++) { for (int i = 0; i < _lines.size(); i++) {
const MapData::Line *line = _lines.at(i); const MapData::Line *line = _lines.at(i);
const Style::Line &style = s.line(ECDIS(line->type())); const Style::Line &style = s.line(line->type());
if (!style.img().isNull()) { if (!style.img().isNull()) {
BitmapLine::draw(painter, polyline(line->path()), style.img()); BitmapLine::draw(painter, polyline(line->path()), style.img());
@ -129,14 +210,14 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
for (int i = 0; i < _points.size(); i++) { for (int i = 0; i < _points.size(); i++) {
const MapData::Point *point = _points.at(i); const MapData::Point *point = _points.at(i);
const Style::Point &style = s.point(ECDIS(point->type())); const Style::Point &style = s.point(point->type());
const QString *label = point->label().isEmpty() ? 0 : &(point->label()); const QString *label = point->label().isEmpty() ? 0 : &(point->label());
const QImage *img = style.img().isNull() ? 0 : &style.img(); const QImage *img = style.img().isNull() ? 0 : &style.img();
const QFont *fnt = font(style.textFontSize()); const QFont *fnt = font(style.textFontSize());
const QColor *color = &style.textColor(); const QColor *color = &style.textColor();
const QColor *hColor = Style::isSounding(ECDIS(point->type())) const QColor *hColor = (Style::isSounding(point->type())
? 0 : &haloColor; || Style::isDistanceMark(point->type())) ? 0 : &haloColor;
if ((!label || !fnt) && !img) if ((!label || !fnt) && !img)
continue; continue;
@ -156,7 +237,7 @@ void RasterTile::processLines(QList<TextItem*> &textItems)
for (int i = 0; i < _lines.size(); i++) { for (int i = 0; i < _lines.size(); i++) {
const MapData::Line *line = _lines.at(i); const MapData::Line *line = _lines.at(i);
const Style::Line &style = s.line(ECDIS(line->type())); const Style::Line &style = s.line(line->type());
if (style.img().isNull() && style.pen() == Qt::NoPen) if (style.img().isNull() && style.pen() == Qt::NoPen)
continue; continue;
@ -192,6 +273,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

@ -22,6 +22,7 @@ void Style::defaultPolygonStyle()
_polygons[TYPE(BUISGL)] = Polygon(QBrush("#d98b21"), _polygons[TYPE(BUISGL)] = Polygon(QBrush("#d98b21"),
QPen(QColor("#966118"), 1.5)); QPen(QColor("#966118"), 1.5));
_polygons[TYPE(BRIDGE)] = Polygon(QBrush("#a58140")); _polygons[TYPE(BRIDGE)] = Polygon(QBrush("#a58140"));
_polygons[TYPE(I_BRIDGE)] = Polygon(QBrush("#a58140"));
_polygons[SUBTYPE(DEPARE, 0)] = Polygon(QBrush("#98c064")); _polygons[SUBTYPE(DEPARE, 0)] = Polygon(QBrush("#98c064"));
_polygons[SUBTYPE(DEPARE, 1)] = Polygon(QBrush("#a0a0ff")); _polygons[SUBTYPE(DEPARE, 1)] = Polygon(QBrush("#a0a0ff"));
_polygons[SUBTYPE(DEPARE, 2)] = Polygon(QBrush("#b0b0ff")); _polygons[SUBTYPE(DEPARE, 2)] = Polygon(QBrush("#b0b0ff"));
@ -35,11 +36,17 @@ void Style::defaultPolygonStyle()
Qt::DashDotDotLine)); Qt::DashDotDotLine));
_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(UWTROC)] = Polygon(Qt::NoBrush, QPen(QColor("#000000"), 1.5,
Qt::DotLine));
_polygons[TYPE(PONTON)] = Polygon(QBrush("#333333")); _polygons[TYPE(PONTON)] = Polygon(QBrush("#333333"));
_polygons[TYPE(I_PONTON)] = Polygon(QBrush("#333333"));
_polygons[TYPE(HULKES)] = Polygon(QBrush("#333333"));
_polygons[TYPE(I_HULKES)] = 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, _polygons[TYPE(I_SLCONS)] = Polygon(Qt::NoBrush, QPen(QColor("#333333"), 1.5,
Qt::DashDotLine)); Qt::DashLine));
_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,37 +55,81 @@ 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(I_RESARE, 2)] = Polygon(QImage(":/marine/noanchor-line.png"));
_polygons[SUBTYPE(RESARE, 17)] = Polygon(
QImage(":/marine/entry-prohibited-line.png"));
_polygons[SUBTYPE(I_RESARE, 17)] = Polygon(
QImage(":/marine/entry-prohibited-line.png"));
_polygons[SUBTYPE(ACHARE, 1)] = Polygon(QImage(":/marine/anchor-line.png"));
_polygons[SUBTYPE(I_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(I_FLODOC)] = Polygon(QBrush("#333333"),
QPen(QColor("#000000"), 1));
_polygons[TYPE(DWRTPT)] = Polygon(QImage(":/marine/dw-route-line.png"));
_polygons[TYPE(MORFAC)] = Polygon(QBrush("#e8e064"), QPen(QColor("#000000"),
2));
_polygons[TYPE(GATCON)] = Polygon(QBrush("#000000"));
_polygons[TYPE(I_GATCON)] = Polygon(QBrush("#000000"));
_polygons[TYPE(I_TERMNL)] = Polygon(QBrush(QColor("#b8b04b")),
QPen(QColor("#966118")));
_polygons[TYPE(SILTNK)] = Polygon(QBrush("#d98b21"), QPen(QColor("#966118"),
2));
_polygons[TYPE(LOKBSN)] = Polygon(QBrush(QColor("#333333"),
Qt::Dense7Pattern));
_polygons[TYPE(I_LOKBSN)] = Polygon(QBrush(QColor("#333333"),
Qt::Dense7Pattern));
_drawOrder _drawOrder
<< TYPE(M_COVR) << TYPE(LNDARE) << SUBTYPE(DEPARE, 0) << TYPE(M_COVR) << TYPE(LNDARE) << SUBTYPE(DEPARE, 0)
<< SUBTYPE(DEPARE, 1) << SUBTYPE(DEPARE, 2) << SUBTYPE(DEPARE, 3) << SUBTYPE(DEPARE, 1) << SUBTYPE(DEPARE, 2) << SUBTYPE(DEPARE, 3)
<< TYPE(UNSARE) << SUBTYPE(DEPARE, 4) << SUBTYPE(DEPARE, 5) << TYPE(UNSARE) << SUBTYPE(DEPARE, 4) << SUBTYPE(DEPARE, 5)
<< 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(LOKBSN)
<< TYPE(BUISGL) << TYPE(AIRARE) << TYPE(BRIDGE) << TYPE(SLCONS) << TYPE(I_LOKBSN) << TYPE(BUAARE) << TYPE(BUISGL) << TYPE(SILTNK)
<< TYPE(PONTON) << TYPE(DMPGRD) << TYPE(TSEZNE) << TYPE(OBSTRN) << TYPE(AIRARE) << TYPE(BRIDGE) << TYPE(I_BRIDGE) << TYPE(I_TERMNL)
<< TYPE(ACHARE) << SUBTYPE(RESARE, 9) << TYPE(154); << TYPE(SLCONS) << TYPE(I_SLCONS) << TYPE(PONTON) << TYPE(I_PONTON)
<< TYPE(HULKES) << TYPE(I_HULKES) << TYPE(FLODOC) << TYPE(I_FLODOC)
<< TYPE(DRYDOC) << TYPE(DAMCON) << TYPE(PYLONS) << TYPE(MORFAC)
<< TYPE(GATCON) << TYPE(I_GATCON) << TYPE(DMPGRD) << TYPE(TSEZNE)
<< TYPE(OBSTRN) << TYPE(UWTROC) << TYPE(DWRTPT) << SUBTYPE(ACHARE, 1)
<< SUBTYPE(I_ACHARE, 1) << SUBTYPE(RESARE, 9) << SUBTYPE(RESARE, 2)
<< SUBTYPE(I_RESARE, 2) << SUBTYPE(RESARE, 17) << SUBTYPE(I_RESARE, 17)
<< 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);
_lines[TYPE(CBLOHD)] = Line(QImage(":/marine/cable-line.png")); _lines[TYPE(CBLOHD)] = Line(QImage(":/marine/cable-line.png"));
_lines[TYPE(I_CBLOHD)] = Line(QImage(":/marine/cable-line.png"));
_lines[TYPE(BRIDGE)] = Line(QPen(QColor("#a58140"), 3, Qt::SolidLine)); _lines[TYPE(BRIDGE)] = Line(QPen(QColor("#a58140"), 3, Qt::SolidLine));
_lines[TYPE(I_BRIDGE)] = Line(QPen(QColor("#a58140"), 3, Qt::SolidLine));
_lines[TYPE(CBLSUB)] = Line(QImage(":/marine/cable.png")); _lines[TYPE(CBLSUB)] = Line(QImage(":/marine/cable.png"));
_lines[TYPE(CBLSUB)].setTextFontSize(Small); _lines[TYPE(CBLSUB)].setTextFontSize(Small);
_lines[TYPE(PIPSOL)] = Line(QImage(":/marine/pipeline.png")); _lines[TYPE(PIPSOL)] = Line(QImage(":/marine/pipeline.png"));
_lines[TYPE(NAVLNE)] = Line(QPen(QColor("#eb49eb"), 1, Qt::DashLine)); _lines[TYPE(NAVLNE)] = Line(QPen(QColor("#eb49eb"), 1, Qt::DashLine));
_lines[TYPE(COALNE)] = Line(QPen(QColor("#000000"), 1, Qt::SolidLine)); _lines[TYPE(COALNE)] = Line(QPen(QColor("#000000"), 1, Qt::SolidLine));
_lines[TYPE(SLCONS)] = Line(QPen(QColor("#000000"), 2, Qt::SolidLine)); _lines[TYPE(SLCONS)] = Line(QPen(QColor("#000000"), 2, Qt::SolidLine));
_lines[TYPE(I_SLCONS)] = Line(QPen(QColor("#000000"), 2, Qt::SolidLine));
_lines[TYPE(PONTON)] = Line(QPen(QColor("#333333"), 1, Qt::SolidLine)); _lines[TYPE(PONTON)] = Line(QPen(QColor("#333333"), 1, Qt::SolidLine));
_lines[TYPE(DYKCON)] = Line(QPen(QColor("#333333"), 2, Qt::SolidLine)); _lines[TYPE(DYKCON)] = Line(QPen(QColor("#333333"), 2, Qt::SolidLine));
_lines[TYPE(RIVERS)] = Line(QPen(QColor("#000000"), 1, Qt::SolidLine)); _lines[TYPE(RIVERS)] = Line(QPen(QColor("#000000"), 1, Qt::SolidLine));
@ -89,47 +140,91 @@ void Style::defaultLineStyle()
_lines[TYPE(SLOTOP)] = Line(QPen(QColor("#797420"), 1, Qt::SolidLine)); _lines[TYPE(SLOTOP)] = Line(QPen(QColor("#797420"), 1, Qt::SolidLine));
_lines[TYPE(OBSTRN)] = Line(QPen(QColor("#000000"), 1.5, Qt::DotLine)); _lines[TYPE(OBSTRN)] = Line(QPen(QColor("#000000"), 1.5, Qt::DotLine));
_lines[TYPE(FERYRT)] = Line(QImage(":/marine/ferry-line.png")); _lines[TYPE(FERYRT)] = Line(QImage(":/marine/ferry-line.png"));
_lines[TYPE(I_FERYRT)] = Line(QImage(":/marine/ferry-line.png"));
_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(I_GATCON)] = Line(QPen(QColor("#000000"), 2, Qt::SolidLine));
_lines[TYPE(TSELNE)] = Line(QPen(QColor("#80fcb4fc"), 4, Qt::SolidLine));
_lines[TYPE(I_WTWAXS)] = Line(QPen(QColor("#000000"), 0, Qt::DashLine));
_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));
_lines[TYPE(I_BERTHS)] = Line(QPen(QColor("#333333"), 2));
_lines[TYPE(FNCLNE)] = Line(QImage(":/marine/fence-line.png"));
_lines[TYPE(CONVYR)] = Line(QImage(":/marine/conveyor-line.png"));
_lines[TYPE(PIPOHD)] = Line(QImage(":/marine/pipeline-overhead.png"));
_lines[TYPE(I_PIPOHD)] = Line(QImage(":/marine/pipeline-overhead.png"));
_lines[TYPE(CANALS)] = Line(QPen(QColor("#9fc4e1"), 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);
_points[TYPE(BOYINB)] = Point(QImage(":/marine/buoy.png"), Small); _points[TYPE(BOYINB)] = Point(QImage(":/marine/buoy.png"), Small);
_points[TYPE(BOYISD)] = Point(QImage(":/marine/buoy.png"), Small); _points[TYPE(BOYISD)] = Point(QImage(":/marine/buoy.png"), Small);
_points[TYPE(BOYLAT)] = Point(QImage(":/marine/buoy.png"), Small); _points[TYPE(BOYLAT)] = Point(QImage(":/marine/buoy.png"), Small);
_points[TYPE(I_BOYLAT)] = Point(QImage(":/marine/buoy.png"), Small);
_points[TYPE(BOYSAW)] = Point(QImage(":/marine/buoy.png"), Small); _points[TYPE(BOYSAW)] = Point(QImage(":/marine/buoy.png"), Small);
_points[TYPE(BOYSPP)] = Point(QImage(":/marine/buoy.png"), Small); _points[TYPE(BOYSPP)] = Point(QImage(":/marine/buoy.png"), Small);
_points[TYPE(BCNISD)] = Point(QImage(":/marine/beacon.png"), Small); _points[TYPE(BCNISD)] = Point(QImage(":/marine/beacon.png"), Small);
_points[TYPE(BCNLAT)] = Point(QImage(":/marine/beacon.png"), Small); _points[TYPE(BCNLAT)] = Point(QImage(":/marine/beacon.png"), Small);
_points[TYPE(I_BCNLAT)] = Point(QImage(":/marine/beacon.png"), Small);
_points[TYPE(BCNSAW)] = Point(QImage(":/marine/beacon.png"), Small); _points[TYPE(BCNSAW)] = Point(QImage(":/marine/beacon.png"), Small);
_points[TYPE(BCNSPP)] = Point(QImage(":/marine/beacon.png"), Small); _points[TYPE(BCNSPP)] = Point(QImage(":/marine/beacon.png"), Small);
_points[SUBTYPE(LNDMRK, 3)] = Point(QImage(":/marine/chimney.png")); _points[SUBTYPE(LNDMRK, 3)] = Point(QImage(":/marine/chimney.png"));
_points[SUBTYPE(LNDMRK, 9)] = Point(QImage(":/marine/monument.png"));
_points[SUBTYPE(LNDMRK, 20)] = Point(QImage(":/marine/church.png")); _points[SUBTYPE(LNDMRK, 20)] = Point(QImage(":/marine/church.png"));
_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(I_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);
_points[TYPE(CRANES)] = Point(QImage(":/marine/crane.png"));
_points[TYPE(I_CRANES)] = Point(QImage(":/marine/crane.png"));
_points[SUBTYPE(I_DISMAR, 1)] = Point(QImage(":/marine/distance-mark.png"));
_points[SUBTYPE(I_DISMAR, 1)].setTextColor(QColor("#ffffff"));
_points[SUBTYPE(I_DISMAR, 1)].setTextFontSize(Small);
_points[TYPE(CGUSTA)] = Point(QImage(":/marine/coast-guard.png"));
_points[TYPE(RDOSTA)] = Point(QImage(":/marine/radio.png"));
_points[TYPE(RADSTA)] = Point(QImage(":/marine/radar.png"));
_points[TYPE(RTPBCN)] = Point(QImage(":/marine/radar-transponder.png"));
_points[TYPE(SILTNK)] = Point(QImage(":/marine/silo.png"));
_points[TYPE(I_TRNBSN)] = Point(QImage(":/marine/turning-basin.png"));
} }
Style::Style() Style::Style()
@ -139,7 +234,7 @@ Style::Style()
defaultPointStyle(); defaultPointStyle();
} }
const Style::Line &Style::line(quint32 type) const const Style::Line &Style::line(uint type) const
{ {
static Line null; static Line null;
@ -147,7 +242,7 @@ const Style::Line &Style::line(quint32 type) const
return (it == _lines.constEnd()) ? null : *it; return (it == _lines.constEnd()) ? null : *it;
} }
const Style::Polygon &Style::polygon(quint32 type) const const Style::Polygon &Style::polygon(uint type) const
{ {
static Polygon null; static Polygon null;
@ -155,7 +250,7 @@ const Style::Polygon &Style::polygon(quint32 type) const
return (it == _polygons.constEnd()) ? null : *it; return (it == _polygons.constEnd()) ? null : *it;
} }
const Style::Point &Style::point(quint32 type) const const Style::Point &Style::point(uint type) const
{ {
static Point null; static Point null;

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 {
@ -84,11 +89,13 @@ public:
const Line &line(uint type) const; const Line &line(uint type) const;
const Polygon &polygon(uint type) const; const Polygon &polygon(uint type) const;
const Point &point(quint32 type) const; const Point &point(uint type) const;
const QVector<uint> &drawOrder() const {return _drawOrder;} const QVector<uint> &drawOrder() const {return _drawOrder;}
static bool isSounding(quint32 type) static bool isSounding(uint type)
{return type == TYPE(SOUNDG);} {return type == TYPE(SOUNDG);}
static bool isDistanceMark(uint type)
{return (type & 0xFFFF0000) == TYPE(I_DISMAR);}
private: private:
void defaultPolygonStyle(); void defaultPolygonStyle();

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;