1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-04-20 12:19:11 +02:00

Compare commits

..

No commits in common. "master" and "13.34" have entirely different histories.

128 changed files with 5875 additions and 7902 deletions

View File

@ -1,4 +1,4 @@
version: 13.39.{build} version: 13.34.{build}
configuration: configuration:
- Release - Release
@ -8,7 +8,6 @@ image:
environment: environment:
NSISDIR: C:\Program Files (x86)\NSIS NSISDIR: C:\Program Files (x86)\NSIS
JOMDIR: C:\Qt\Tools\QtCreator\bin\jom
matrix: matrix:
- QTDIR: C:\Qt\5.15\msvc2019_64 - QTDIR: C:\Qt\5.15\msvc2019_64
OPENSSLDIR: C:\OpenSSL-v111-Win64\bin OPENSSLDIR: C:\OpenSSL-v111-Win64\bin
@ -18,14 +17,14 @@ environment:
install: install:
- cmd: |- - cmd: |-
set PATH=%QTDIR%\bin;%NSISDIR%;%JOMDIR%;%PATH% set PATH=%QTDIR%\bin;%NSISDIR%;%PATH%
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat
build_script: build_script:
- cmd: |- - cmd: |-
lrelease gpxsee.pro lrelease gpxsee.pro
qmake gpxsee.pro qmake gpxsee.pro
jom release nmake release
md installer md installer
copy release\GPXSee.exe installer copy release\GPXSee.exe installer

View File

@ -43,7 +43,7 @@ jobs:
- name: Configure build - name: Configure build
run: qmake gpxsee.pro OPENSSL_PATH=android_openssl run: qmake gpxsee.pro OPENSSL_PATH=android_openssl
- name: Build project - name: Build project
run: make -j4 apk run: make -j2 apk
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:

View File

@ -8,10 +8,7 @@ on:
jobs: jobs:
build: build:
name: GPXSee name: GPXSee
runs-on: ubuntu-22.04 runs-on: ubuntu-20.04
strategy:
matrix:
config: ['release', 'debug']
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@ -22,6 +19,6 @@ jobs:
- name: Create localization - name: Create localization
run: lrelease gpxsee.pro run: lrelease gpxsee.pro
- name: Configure build - name: Configure build
run: qmake CONFIG+=${{ matrix.config }} gpxsee.pro run: qmake gpxsee.pro
- name: Build project - name: Build project
run: make -j4 run: make -j2

View File

@ -15,7 +15,7 @@ jobs:
- name: Install Qt - name: Install Qt
uses: jurplel/install-qt-action@v4 uses: jurplel/install-qt-action@v4
with: with:
version: '6.8.2' version: '6.8.1'
modules: qtpositioning qtserialport qtimageformats modules: qtpositioning qtserialport qtimageformats
- name: Create localization - name: Create localization
run: lrelease gpxsee.pro run: lrelease gpxsee.pro

View File

@ -5,9 +5,7 @@ GPS log file formats.
## Features ## Features
* Opens GPX, TCX, FIT, KML, NMEA, IGC, CUP, SIGMA SLF, Suunto SML, LOC, GeoJSON, * Opens GPX, TCX, FIT, KML, NMEA, IGC, CUP, SIGMA SLF, Suunto SML, LOC, GeoJSON,
OziExplorer (PLT, RTE, WPT), Garmin GPI&CSV, TomTom OV2&ITN, ONmove OMD/GHP, OziExplorer (PLT, RTE, WPT), Garmin GPI&CSV, TomTom OV2&ITN, ONmove OMD/GHP,
TwoNav (TRK, RTE, WPT), GPSDump WPT, Velocitek VTK, Vakaros VKX, 70mai GPS logs TwoNav (TRK, RTE, WPT), GPSDump WPT and geotagged JPEG files.
and geotagged JPEG files.
* Opens geo URIs (RFC 5870).
* User-definable online maps (OpenStreetMap/Google tiles, WMTS, WMS, TMS, * User-definable online maps (OpenStreetMap/Google tiles, WMTS, WMS, TMS,
QuadTiles). QuadTiles).
* Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases, * Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases,
@ -30,8 +28,8 @@ GPS log file formats.
## Build ## Build
Build requirements: Build requirements:
* Qt5 >= 5.15 or Qt6 >= 6.2 (Android builds require Qt6) * Qt5 >= 5.11 or Qt6 >= 6.2 (Android builds require Qt6)
* C++11 or newer compiler (tested: msvc2022, gcc 11, clang/Apple LLVM version * C++11 or newer compiler (tested: msvc2019, gcc 7.5.0, clang/Apple LLVM version
10.0.0) 10.0.0)
Build steps: Build steps:

View File

@ -214,11 +214,10 @@
</rule> </rule>
<!-- Buildings --> <!-- Buildings -->
<rule e="way" k="building" v="-|civic|office|cathedral|church|basilica"> <rule e="way" k="building" v="*">
<area fill="#dbd0b6" stroke="#cdccc4" stroke-width="0.1"/> <area fill="#dbd0b6" stroke="#cdccc4" stroke-width="0.1"/>
</rule> </rule>
<rule e="way" k="building" v="civic">
<rule e="way" k="building" v="civic|office">
<area fill="#cfc4b3" stroke="#cdccc4" stroke-width="0.1"/> <area fill="#cfc4b3" stroke="#cdccc4" stroke-width="0.1"/>
<rule e="way" k="*" v="*" zoom-min="16"> <rule e="way" k="*" v="*" zoom-min="16">
<caption fill="#000000" font-size="10" font-style="italic" k="name" stroke="#FFFFFF" stroke-width="2" priority="-10"/> <caption fill="#000000" font-size="10" font-style="italic" k="name" stroke="#FFFFFF" stroke-width="2" priority="-10"/>
@ -404,7 +403,7 @@
<rule e="way" k="*" v="*" zoom-min="14"> <rule e="way" k="*" v="*" zoom-min="14">
<pathText fill="#000000" font-size="10" k="name" priority="-5" stroke="#FFFFFF" stroke-width="2"/> <pathText fill="#000000" font-size="10" k="name" priority="-5" stroke="#FFFFFF" stroke-width="2"/>
<rule e="way" k="oneway" v="yes|true|1" zoom-min="16"> <rule e="way" k="oneway" v="yes|true|1" zoom-min="16">
<lineSymbol priority="-50" src=":/symbols/oneway.svg" symbol-width="16" symbol-height="8"/> <lineSymbol priority="-50" src=":/symbols/arrow.svg" symbol-width="16" symbol-height="8"/>
</rule> </rule>
</rule> </rule>
</rule> </rule>
@ -429,12 +428,6 @@
<line stroke="#f7d9a6" stroke-width="1" stroke-linecap="butt"/> <line stroke="#f7d9a6" stroke-width="1" stroke-linecap="butt"/>
</rule> </rule>
</rule> </rule>
<rule e="way" k="*" v="*" zoom-min="14">
<pathText fill="#000000" font-size="10" k="name" priority="-3" stroke="#FFFFFF" stroke-width="2"/>
<rule e="way" k="oneway" v="yes|true|1" zoom-min="16">
<lineSymbol priority="-50" src=":/symbols/oneway.svg" symbol-width="16" symbol-height="8"/>
</rule>
</rule>
</rule> </rule>
<rule e="way" k="highway" v="motorway|motorway_link"> <rule e="way" k="highway" v="motorway|motorway_link">
<rule e="way" k="tunnel" v="~|false|no"> <rule e="way" k="tunnel" v="~|false|no">

View File

@ -3,7 +3,8 @@ unix:!macx:!android {
} else { } else {
TARGET = GPXSee TARGET = GPXSee
} }
VERSION = 13.39 VERSION = 13.34
QT += core \ QT += core \
gui \ gui \
@ -117,11 +118,6 @@ HEADERS += src/common/config.h \
src/data/gpsdumpparser.h \ src/data/gpsdumpparser.h \
src/data/style.h \ src/data/style.h \
src/data/twonavparser.h \ src/data/twonavparser.h \
src/data/txtparser.h \
src/data/vkxparser.h \
src/data/vtkparser.h \
src/map/ENC/data.h \
src/map/IMG/light.h \
src/map/downloader.h \ src/map/downloader.h \
src/map/demloader.h \ src/map/demloader.h \
src/map/ENC/attributes.h \ src/map/ENC/attributes.h \
@ -347,9 +343,6 @@ SOURCES += src/main.cpp \
src/GUI/pngexportdialog.cpp \ src/GUI/pngexportdialog.cpp \
src/GUI/projectioncombobox.cpp \ src/GUI/projectioncombobox.cpp \
src/GUI/passwordedit.cpp \ src/GUI/passwordedit.cpp \
src/data/txtparser.cpp \
src/data/vkxparser.cpp \
src/data/vtkparser.cpp \
src/map/downloader.cpp \ src/map/downloader.cpp \
src/map/demloader.cpp \ src/map/demloader.cpp \
src/map/ENC/atlasdata.cpp \ src/map/ENC/atlasdata.cpp \
@ -565,9 +558,7 @@ win32 {
icons/formats/trk.ico \ icons/formats/trk.ico \
icons/formats/gemf.ico \ icons/formats/gemf.ico \
icons/formats/000.ico \ icons/formats/000.ico \
icons/formats/031.ico \ icons/formats/031.ico
icons/formats/vtk.ico \
icons/formats/vkx.ico
DEFINES += _USE_MATH_DEFINES \ DEFINES += _USE_MATH_DEFINES \
NOGDI NOGDI
} }

View File

@ -193,10 +193,6 @@
<file alias="overfalls.png">icons/map/marine/overfalls.png</file> <file alias="overfalls.png">icons/map/marine/overfalls.png</file>
<file alias="boarding-place.png">icons/map/marine/boarding-place.png</file> <file alias="boarding-place.png">icons/map/marine/boarding-place.png</file>
<file alias="light.png">icons/map/marine/light.png</file> <file alias="light.png">icons/map/marine/light.png</file>
<file alias="light-red.png">icons/map/marine/light-red.png</file>
<file alias="light-green.png">icons/map/marine/light-green.png</file>
<file alias="light-yellow.png">icons/map/marine/light-yellow.png</file>
<file alias="light-white.png">icons/map/marine/light-white.png</file>
<file alias="building.png">icons/map/marine/building.png</file> <file alias="building.png">icons/map/marine/building.png</file>
<file alias="fog-signal.png">icons/map/marine/fog-signal.png</file> <file alias="fog-signal.png">icons/map/marine/fog-signal.png</file>
<file alias="construction.png">icons/map/marine/construction.png</file> <file alias="construction.png">icons/map/marine/construction.png</file>
@ -214,9 +210,6 @@
<file alias="24h-anchorage.png">icons/map/marine/24h-anchorage.png</file> <file alias="24h-anchorage.png">icons/map/marine/24h-anchorage.png</file>
<file alias="dw-anchorage.png">icons/map/marine/dw-anchorage.png</file> <file alias="dw-anchorage.png">icons/map/marine/dw-anchorage.png</file>
<file alias="tanker-anchorage.png">icons/map/marine/tanker-anchorage.png</file> <file alias="tanker-anchorage.png">icons/map/marine/tanker-anchorage.png</file>
<file alias="nature-reserve-line.png">icons/map/marine/nature-reserve-line.png</file>
<file alias="sanctuary-line.png">icons/map/marine/sanctuary-line.png</file>
<file alias="fishing-farm.png">icons/map/marine/fishing-farm.png</file>
</qresource> </qresource>
<!-- Patterns (Mapsforge) --> <!-- Patterns (Mapsforge) -->

View File

@ -32,5 +32,3 @@ trk:#cccccc
gemf:#147085 gemf:#147085
000:#000000 000:#000000
031:#000000 031:#000000
vtk:#632433
vkx:#00ccff

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 B

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 B

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 B

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 B

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 401 B

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 B

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 B

After

Width:  |  Height:  |  Size: 4.3 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -21,12 +21,6 @@
<data android:scheme="content" android:mimeType="image/jpeg"/> <data android:scheme="content" android:mimeType="image/jpeg"/>
<data android:scheme="content" android:mimeType="image/tiff"/> <data android:scheme="content" android:mimeType="image/tiff"/>
</intent-filter> </intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="geo"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/> <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.arguments" android:value="-- %%INSERT_APP_ARGUMENTS%% --"/> <meta-data android:name="android.app.arguments" android:value="-- %%INSERT_APP_ARGUMENTS%% --"/>

View File

@ -15,9 +15,8 @@
<li>Opens GPX, TCX, FIT, KML, IGC, NMEA, SIGMA SLF, Suunto SML, LOC, <li>Opens GPX, TCX, FIT, KML, IGC, NMEA, SIGMA SLF, Suunto SML, LOC,
OziExplorer (PLT, WPT, RTE), GeoJSON, SeeYou CUP, OziExplorer (PLT, WPT, RTE), GeoJSON, SeeYou CUP,
Garmin GPI &amp; CSV, TomTom OV2 &amp; ITN, ONmove OMD/GHP, Garmin GPI &amp; CSV, TomTom OV2 &amp; ITN, ONmove OMD/GHP,
TwoNav (TRK, RTE, WPT), GPSDump WPT, Velocitek VTK, TwoNav (TRK, RTE, WPT), GPSDump WPT and geotagged JPEG
Vakaros VKX, 70mai GPS logs and geotagged JPEG files.</li> files.</li>
<li>Opens geo URIs (RFC 5870).</li>
<li>User-definable online maps (OpenStreetMap/Google tiles, WMTS, <li>User-definable online maps (OpenStreetMap/Google tiles, WMTS,
WMS, TMS, QuadTiles).</li> WMS, TMS, QuadTiles).</li>
<li>Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases, <li>Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases,
@ -113,9 +112,5 @@
<mimetype>application/vnd.iho.s57-catalogue</mimetype> <mimetype>application/vnd.iho.s57-catalogue</mimetype>
<mimetype>application/vnd.gpsdump.wpt</mimetype> <mimetype>application/vnd.gpsdump.wpt</mimetype>
<mimetype>application/vnd.gpstuner.gmi</mimetype> <mimetype>application/vnd.gpstuner.gmi</mimetype>
<mimetype>application/vnd.70mai.txt</mimetype>
<mimetype>application/vnd.velocitek.vtk</mimetype>
<mimetype>application/vnd.vakaros.vkx</mimetype>
<mimetype>x-scheme-handler/geo</mimetype>
</mimetypes> </mimetypes>
</component> </component>

View File

@ -11,9 +11,9 @@ Comment[ru]=Программа для просмотра и анализа GPS
Comment[sv]=GPS-loggfilsläsare och analysator Comment[sv]=GPS-loggfilsläsare och analysator
Comment[tr]=GPS günlük dosyası görüntüleyici ve analizcisi Comment[tr]=GPS günlük dosyası görüntüleyici ve analizcisi
Comment[uk]=Переглядач та аналізатор GPS логів Comment[uk]=Переглядач та аналізатор GPS логів
Exec=gpxsee %U Exec=gpxsee %F
Icon=gpxsee Icon=gpxsee
Terminal=false Terminal=false
Type=Application Type=Application
Categories=Graphics;Viewer;Education;Geography;Maps;Sports;Qt Categories=Graphics;Viewer;Education;Geography;Maps;Sports;Qt
MimeType=x-scheme-handler/geo;application/gpx+xml;application/vnd.garmin.tcx+xml;application/vnd.ant.fit;application/vnd.google-earth.kml+xml;application/vnd.fai.igc;application/vnd.nmea.nmea;application/vnd.oziexplorer.plt;application/vnd.oziexplorer.rte;application/vnd.oziexplorer.wpt;application/vnd.groundspeak.loc+xml;application/vnd.sigma.slf+xml;application/geo+json;application/vnd.naviter.seeyou.cup;application/vnd.garmin.gpi;application/vnd.suunto.sml+xml;image/jpeg;text/csv;application/vnd.garmin.img;application/vnd.garmin.jnx;application/vnd.garmin.gmap+xml;image/vnd.maptech.kap;application/vnd.oziexplorer.map;application/vnd.mapbox.mbtiles;application/vnd.twonav.rmap;application/vnd.trekbuddy.tba;application/vnd.gpxsee.map+xml;application/x-tar;image/tiff;application/vnd.google-earth.kmz;application/vnd.alpinequest.aqm;application/vnd.cgtk.gemf;application/vnd.rmaps.sqlite;application/vnd.osmdroid.sqlite;application/vnd.mapsforge.map;application/vnd.tomtom.ov2;application/vnd.tomtom.itn;application/vnd.esri.wld;application/vnd.onmove.omd;application/vnd.onmove.ghp;application/vnd.memory-map.qct;application/vnd.twonav.trk;application/vnd.twonav.rte;application/vnd.twonav.wpt;application/vnd.orux.map+xml;application/vnd.iho.s57-data;application/vnd.iho.s57-catalogue;application/vnd.gpsdump.wpt;application/vnd.gpstuner.gmi;application/vnd.70mai.txt;application/vnd.velocitek.vtk;application/vnd.vakaros.vkx MimeType=application/gpx+xml;application/vnd.garmin.tcx+xml;application/vnd.ant.fit;application/vnd.google-earth.kml+xml;application/vnd.fai.igc;application/vnd.nmea.nmea;application/vnd.oziexplorer.plt;application/vnd.oziexplorer.rte;application/vnd.oziexplorer.wpt;application/vnd.groundspeak.loc+xml;application/vnd.sigma.slf+xml;application/geo+json;application/vnd.naviter.seeyou.cup;application/vnd.garmin.gpi;application/vnd.suunto.sml+xml;image/jpeg;text/csv;application/vnd.garmin.img;application/vnd.garmin.jnx;application/vnd.garmin.gmap+xml;image/vnd.maptech.kap;application/vnd.oziexplorer.map;application/vnd.mapbox.mbtiles;application/vnd.twonav.rmap;application/vnd.trekbuddy.tba;application/vnd.gpxsee.map+xml;application/x-tar;image/tiff;application/vnd.google-earth.kmz;application/vnd.alpinequest.aqm;application/vnd.cgtk.gemf;application/vnd.rmaps.sqlite;application/vnd.osmdroid.sqlite;application/vnd.mapsforge.map;application/vnd.tomtom.ov2;application/vnd.tomtom.itn;application/vnd.esri.wld;application/vnd.onmove.omd;application/vnd.onmove.ghp;application/vnd.memory-map.qct;application/vnd.twonav.trk;application/vnd.twonav.rte;application/vnd.twonav.wpt;application/vnd.orux.map+xml;application/vnd.iho.s57-data;application/vnd.iho.s57-catalogue;application/vnd.gpsdump.wpt;application/vnd.gpstuner.gmi

View File

@ -188,33 +188,6 @@
<glob pattern="*.wpt"/> <glob pattern="*.wpt"/>
</mime-type> </mime-type>
<mime-type type="application/vnd.70mai.txt">
<comment>70mai GPS Log File</comment>
<sub-class-of type="text/plain"/>
<generic-icon name="text/plain"/>
<magic>
<match type="string" offset="0" value="$V02"/>
</magic>
<glob pattern="*.txt"/>
</mime-type>
<mime-type type="application/vnd.velocitek.vtk">
<comment>Velocitek VTK File</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application/octet-stream"/>
<glob pattern="*.vtk"/>
</mime-type>
<mime-type type="application/vnd.vakaros.vkx">
<comment>Vakaros VKX File</comment>
<sub-class-of type="application/octet-stream"/>
<generic-icon name="application/octet-stream"/>
<magic>
<match type="byte" offset="0" value="0xFF"/>
</magic>
<glob pattern="*.vkx"/>
</mime-type>
<!-- Maps --> <!-- Maps -->
<mime-type type="application/vnd.garmin.img"> <mime-type type="application/vnd.garmin.img">

View File

@ -736,66 +736,6 @@
<key>CFBundleTypeRole</key> <key>CFBundleTypeRole</key>
<string>Viewer</string> <string>Viewer</string>
</dict> </dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>txt</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.70mai.txt</string>
</array>
<key>CFBundleTypeName</key>
<string>70mai GPS Log File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>vtk</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.velocitek.vtk</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/vtk.icns</string>
<key>CFBundleTypeName</key>
<string>Velocitek VTK File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>vkx</string>
</array>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>application/vnd.vakaros.vkx</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>icons/vkx.icns</string>
<key>CFBundleTypeName</key>
<string>Vakaros VKX File</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>geo</string>
</array>
<key>CFBundleURLName</key>
<string>org.geouri.geo</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
</array> </array>
<key>UTImportedTypeDeclarations</key> <key>UTImportedTypeDeclarations</key>
@ -1729,8 +1669,6 @@
<string>https://iho.int/uploads/user/pubs/standards/s-57/31Main.pdf</string> <string>https://iho.int/uploads/user/pubs/standards/s-57/31Main.pdf</string>
<key>UTTypeDescription</key> <key>UTTypeDescription</key>
<string>IHO S-57 Electronic Navigation Chart</string> <string>IHO S-57 Electronic Navigation Chart</string>
<key>UTTypeIconFile</key>
<string>icons/000.icns</string>
<key>UTTypeConformsTo</key> <key>UTTypeConformsTo</key>
<array> <array>
<string>public.data</string> <string>public.data</string>
@ -1752,8 +1690,6 @@
<string>https://iho.int/uploads/user/pubs/standards/s-57/20ApB1.pdf</string> <string>https://iho.int/uploads/user/pubs/standards/s-57/20ApB1.pdf</string>
<key>UTTypeDescription</key> <key>UTTypeDescription</key>
<string>IHO S-57 Electronic Navigation Catalogue</string> <string>IHO S-57 Electronic Navigation Catalogue</string>
<key>UTTypeIconFile</key>
<string>icons/031.icns</string>
<key>UTTypeConformsTo</key> <key>UTTypeConformsTo</key>
<array> <array>
<string>public.data</string> <string>public.data</string>
@ -1768,73 +1704,6 @@
<string>application/vnd.iho.s57-catalogue</string> <string>application/vnd.iho.s57-catalogue</string>
</dict> </dict>
</dict> </dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.70mai.txt</string>
<key>UTTypeReferenceURL</key>
<string>https://forum.mapillary.com/t/using-the-70mai-a810-dashcam-for-mapillary/9130/7?u=boris</string>
<key>UTTypeDescription</key>
<string>70mai GPS Log File</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>txt</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.70mai.txt</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.velocitek.vtk</string>
<key>UTTypeReferenceURL</key>
<string>https://github.com/velocitek/vtk_protocol</string>
<key>UTTypeDescription</key>
<string>Velocitek VTK File</string>
<key>UTTypeIconFile</key>
<string>icons/vtk.icns</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>vtk</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.velocitek.vtk</string>
</dict>
</dict>
<dict>
<key>UTTypeIdentifier</key>
<string>com.vakaros.vkx</string>
<key>UTTypeReferenceURL</key>
<string>https://github.com/vakaros/vkx</string>
<key>UTTypeDescription</key>
<string>Vakaros VKX File</string>
<key>UTTypeIconFile</key>
<string>icons/vkx.icns</string>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>vkx</string>
</array>
<key>public.mime-type</key>
<string>application/vnd.vakaros.vkx</string>
</dict>
</dict>
</array> </array>
<key>UTExportedTypeDeclarations</key> <key>UTExportedTypeDeclarations</key>

View File

@ -18,18 +18,6 @@
DeleteRegKey HKCR ".${EXT}" DeleteRegKey HKCR ".${EXT}"
!macroend !macroend
; URI association
!macro URI_ASSOCIATION_ADD PROTO
WriteRegStr HKCR "${PROTO}" "" "URL:${PROTO}"
WriteRegStr HKCR "${PROTO}" "URL Protocol" ""
WriteRegStr HKCR "${PROTO}\DefaultIcon" "" "$INSTDIR\GPXSee.exe,0"
WriteRegStr HKCR "${PROTO}\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\""
!macroend
!macro URI_ASSOCIATION_REMOVE PROTO
DeleteRegKey HKCR "${PROTO}"
!macroend
; Translations ; Translations
!macro LOCALIZATION LANG CODE !macro LOCALIZATION LANG CODE
Section "${LANG}" Section "${LANG}"
@ -49,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 "13.39" !define VERSION "13.34"
; The file to write ; The file to write
OutFile "GPXSee-${VERSION}_x64.exe" OutFile "GPXSee-${VERSION}_x64.exe"
@ -204,17 +192,13 @@ Section "GPXSee" SEC_APP
!insertmacro FILE_ASSOCIATION_ADD "gemf" "GEMF Map File" 26 !insertmacro FILE_ASSOCIATION_ADD "gemf" "GEMF Map File" 26
!insertmacro FILE_ASSOCIATION_ADD "000" "IHO S-57 Electronic Navigation Chart" 27 !insertmacro FILE_ASSOCIATION_ADD "000" "IHO S-57 Electronic Navigation Chart" 27
!insertmacro FILE_ASSOCIATION_ADD "031" "IHO S-57 Electronic Navigation Catalogue" 28 !insertmacro FILE_ASSOCIATION_ADD "031" "IHO S-57 Electronic Navigation Catalogue" 28
!insertmacro FILE_ASSOCIATION_ADD "vtk" "Velocitek VTK File" 29 !insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 29
!insertmacro FILE_ASSOCIATION_ADD "vkx" "Vakaros VKX File" 30 !insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 29
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 31 !insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 30
!insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 31 !insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 31
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 32 !insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 32
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 33 !insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 33
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 34 !insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 34
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 35
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 36
!insertmacro URI_ASSOCIATION_ADD "geo"
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" ""
@ -267,9 +251,6 @@ Section "GPXSee" SEC_APP
WriteRegStr HKCR ".gemf\OpenWithList" "GPXSee.exe" "" WriteRegStr HKCR ".gemf\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".000\OpenWithList" "GPXSee.exe" "" WriteRegStr HKCR ".000\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".031\OpenWithList" "GPXSee.exe" "" WriteRegStr HKCR ".031\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".txt\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".vtk\OpenWithList" "GPXSee.exe" ""
WriteRegStr HKCR ".vkx\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)'
@ -444,10 +425,6 @@ Section "Uninstall"
!insertmacro FILE_ASSOCIATION_REMOVE "gemf" !insertmacro FILE_ASSOCIATION_REMOVE "gemf"
!insertmacro FILE_ASSOCIATION_REMOVE "000" !insertmacro FILE_ASSOCIATION_REMOVE "000"
!insertmacro FILE_ASSOCIATION_REMOVE "031" !insertmacro FILE_ASSOCIATION_REMOVE "031"
!insertmacro FILE_ASSOCIATION_REMOVE "vtk"
!insertmacro FILE_ASSOCIATION_REMOVE "vkx"
!insertmacro URI_ASSOCIATION_REMOVE "geo"
DeleteRegValue HKCR ".gpx\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".gpx\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".tcx\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".tcx\OpenWithList" "GPXSee.exe"
@ -499,9 +476,6 @@ Section "Uninstall"
DeleteRegValue HKCR ".gemf\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".gemf\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".000\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".000\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".031\OpenWithList" "GPXSee.exe" DeleteRegValue HKCR ".031\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".txt\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".vtk\OpenWithList" "GPXSee.exe"
DeleteRegValue HKCR ".vkx\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

@ -73,7 +73,9 @@ App::App(int &argc, char **argv) : QApplication(argc, argv)
#if defined(Q_OS_WIN32) || defined(Q_OS_MAC) #if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
QIcon::setThemeName(APP_NAME); QIcon::setThemeName(APP_NAME);
#endif // Q_OS_WIN32 || Q_OS_MAC #endif // Q_OS_WIN32 || Q_OS_MAC
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
QIcon::setFallbackThemeName(APP_NAME); QIcon::setFallbackThemeName(APP_NAME);
#endif // QT 5.12
_gui = new GUI(); _gui = new GUI();

View File

@ -25,6 +25,15 @@
#define IW(item) ((item)->boundingRect().width()) #define IW(item) ((item)->boundingRect().width())
#define IH(item) ((item)->boundingRect().height()) #define IH(item) ((item)->boundingRect().height())
static inline QPoint POS(QWheelEvent *e)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
return e->pos();
#else // QT 5.15
return e->position().toPoint();
#endif // QT 5.15
}
static inline QPoint POS(QMouseEvent *e) static inline QPoint POS(QMouseEvent *e)
{ {
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@ -384,7 +393,7 @@ void GraphView::wheelEvent(QWheelEvent *e)
return; return;
_angleDelta = _angleDelta % (15 * 8); _angleDelta = _angleDelta % (15 * 8);
QPointF pos = mapToScene(e->position().toPoint()); QPointF pos = mapToScene(POS(e));
QRectF gr(_grid->boundingRect()); QRectF gr(_grid->boundingRect());
QPointF r(pos.x() / gr.width(), pos.y() / gr.height()); QPointF r(pos.x() / gr.width(), pos.y() / gr.height());
@ -395,8 +404,7 @@ void GraphView::wheelEvent(QWheelEvent *e)
QPointF npos(mapFromScene(QPointF(r.x() * ngr.width(), QPointF npos(mapFromScene(QPointF(r.x() * ngr.width(),
r.y() * ngr.height()))); r.y() * ngr.height())));
QScrollBar *sb = horizontalScrollBar(); QScrollBar *sb = horizontalScrollBar();
sb->setSliderPosition(sb->sliderPosition() + npos.x() sb->setSliderPosition(sb->sliderPosition() + npos.x() - POS(e).x());
- e->position().toPoint().x());
QGraphicsView::wheelEvent(e); QGraphicsView::wheelEvent(e);
} }

View File

@ -1069,33 +1069,18 @@ void GUI::openDir()
bool GUI::openFile(const QString &fileName, bool tryUnknown, int &showError) bool GUI::openFile(const QString &fileName, bool tryUnknown, int &showError)
{ {
QString path; QFileInfo fi(fileName);
QString canonicalFileName(fi.canonicalFilePath());
QUrl url(fileName); if (_files.contains(canonicalFileName))
if (url.scheme() == "geo") {
if (loadURL(url, showError)) {
_fileActionGroup->setEnabled(true);
_reloadFileAction->setEnabled(false);
return true;
} else if (showError)
return false;
} else if (url.isLocalFile())
path = url.toLocalFile();
else
path = fileName;
QFileInfo fi(path);
QString canonicalPath(fi.canonicalFilePath());
if (_files.contains(canonicalPath))
return true; return true;
if (!loadFile(path, tryUnknown, showError)) if (!loadFile(fileName, tryUnknown, showError))
return false; return false;
_files.append(canonicalPath); _files.append(canonicalFileName);
#ifndef Q_OS_ANDROID #ifndef Q_OS_ANDROID
_browser->setCurrent(path); _browser->setCurrent(fileName);
#endif // Q_OS_ANDROID #endif // Q_OS_ANDROID
_fileActionGroup->setEnabled(true); _fileActionGroup->setEnabled(true);
// Explicitly enable the reload action as it may be disabled by loadMapDir() // Explicitly enable the reload action as it may be disabled by loadMapDir()
@ -1108,42 +1093,12 @@ bool GUI::openFile(const QString &fileName, bool tryUnknown, int &showError)
if (_files.count() > 1) if (_files.count() > 1)
_mapView->showExtendedInfo(true); _mapView->showExtendedInfo(true);
#ifndef Q_OS_ANDROID #ifndef Q_OS_ANDROID
updateRecentFiles(canonicalPath); updateRecentFiles(canonicalFileName);
#endif // Q_OS_ANDROID #endif // Q_OS_ANDROID
return true; return true;
} }
bool GUI::loadURL(const QUrl &url, int &showError)
{
Data data(url);
if (data.isValid()) {
loadData(data);
return true;
} else {
if (showError) {
QString error = tr("Error loading geo URI:") + "\n" + url.toString()
+ ": " + data.errorString();
if (showError > 1) {
QMessageBox message(QMessageBox::Critical, APP_NAME, error,
QMessageBox::Ok, this);
QCheckBox checkBox(tr("Don't show again"));
message.setCheckBox(&checkBox);
message.exec();
if (checkBox.isChecked())
showError = 0;
} else
QMessageBox::critical(this, APP_NAME, error);
} else
qWarning("%s: %s", qUtf8Printable(url.toString()),
qUtf8Printable(data.errorString()));
return false;
}
}
bool GUI::loadFile(const QString &fileName, bool tryUnknown, int &showError) bool GUI::loadFile(const QString &fileName, bool tryUnknown, int &showError)
{ {
Data data(fileName, tryUnknown); Data data(fileName, tryUnknown);
@ -1193,13 +1148,11 @@ void GUI::loadData(const Data &data)
_time += track.time(); _time += track.time();
_movingTime += track.movingTime(); _movingTime += track.movingTime();
const QDateTime date = track.date().toTimeZone(_options.timeZone.zone()); const QDateTime date = track.date().toTimeZone(_options.timeZone.zone());
if (date.isValid()) {
if (_dateRange.first.isNull() || _dateRange.first > date) if (_dateRange.first.isNull() || _dateRange.first > date)
_dateRange.first = date; _dateRange.first = date;
if (_dateRange.second.isNull() || _dateRange.second < date) if (_dateRange.second.isNull() || _dateRange.second < date)
_dateRange.second = date; _dateRange.second = date;
} }
}
_trackCount += data.tracks().count(); _trackCount += data.tracks().count();
for (int i = 0; i < data.routes().count(); i++) for (int i = 0; i < data.routes().count(); i++)
@ -1897,13 +1850,7 @@ bool GUI::loadMapNode(const TreeNode<Map*> &node, MapAction *&action,
bool GUI::loadMap(const QString &fileName, MapAction *&action, int &showError) bool GUI::loadMap(const QString &fileName, MapAction *&action, int &showError)
{ {
QString path; TreeNode<Map*> maps(MapList::loadMaps(fileName, _mapView->inputProjection()));
QUrl url(fileName);
path = url.isLocalFile() ? url.toLocalFile() : fileName;
TreeNode<Map*> maps(MapList::loadMaps(path, _mapView->inputProjection()));
QList<QAction*> existingActions(_mapsActionGroup->actions()); QList<QAction*> existingActions(_mapsActionGroup->actions());
return loadMapNode(maps, action, existingActions, showError); return loadMapNode(maps, action, existingActions, showError);
@ -2500,8 +2447,12 @@ QGeoPositionInfoSource *GUI::positionSource(const Options &options)
{ {
QGeoPositionInfoSource *source; QGeoPositionInfoSource *source;
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
source = QGeoPositionInfoSource::createSource(options.plugin, this);
#else // QT 5.14
source = QGeoPositionInfoSource::createSource(options.plugin, source = QGeoPositionInfoSource::createSource(options.plugin,
options.pluginParams.value(options.plugin), this); options.pluginParams.value(options.plugin), this);
#endif // QT 5.14
if (source) if (source)
source->setPreferredPositioningMethods( source->setPreferredPositioningMethods(
QGeoPositionInfoSource::SatellitePositioningMethods); QGeoPositionInfoSource::SatellitePositioningMethods);

View File

@ -158,7 +158,6 @@ private:
#endif // Q_OS_ANDROID #endif // Q_OS_ANDROID
bool openPOIFile(const QString &fileName); bool openPOIFile(const QString &fileName);
bool loadFile(const QString &fileName, bool tryUnknown, int &showError); bool loadFile(const QString &fileName, bool tryUnknown, int &showError);
bool loadURL(const QUrl &url, int &showError);
void loadData(const Data &data); void loadData(const Data &data);
bool loadMapNode(const TreeNode<Map*> &node, MapAction *&action, bool loadMapNode(const TreeNode<Map*> &node, MapAction *&action,
const QList<QAction*> &existingActions, int &showError); const QList<QAction*> &existingActions, int &showError);

View File

@ -638,7 +638,11 @@ void MapView::wheelEvent(QWheelEvent *event)
return; return;
_wheelDelta = _wheelDelta % (15 * 8); _wheelDelta = _wheelDelta % (15 * 8);
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
zoom((delta > 0) ? 1 : -1, event->pos(), shift);
#else // QT 5.15
zoom((delta > 0) ? 1 : -1, event->position().toPoint(), shift); zoom((delta > 0) ? 1 : -1, event->position().toPoint(), shift);
#endif // QT 5.15
/* Do not call QGraphicsView::wheelEvent() here as this would shift the /* Do not call QGraphicsView::wheelEvent() here as this would shift the
view ! */ view ! */
@ -1254,7 +1258,7 @@ void MapView::drawHillShading(bool draw)
setMap(_map); setMap(_map);
} }
void MapView::selectLayers(MapView::Layers layers) void MapView::selectLayers(Layers layers)
{ {
_layers = layers; _layers = layers;

View File

@ -136,7 +136,7 @@ public slots:
void showMotionInfo(bool show); void showMotionInfo(bool show);
void useStyles(bool use); void useStyles(bool use);
void drawHillShading(bool draw); void drawHillShading(bool draw);
void selectLayers(MapView::Layers layers); void selectLayers(Layers layers);
private slots: private slots:
void updatePOI(); void updatePOI();

View File

@ -676,17 +676,21 @@ QWidget *OptionsDialog::createPositionPage()
_positionPlugin = new QComboBox(); _positionPlugin = new QComboBox();
_positionPlugin->addItems(plugins); _positionPlugin->addItems(plugins);
_positionPlugin->setCurrentIndex(_positionPlugin->findText(_options.plugin)); _positionPlugin->setCurrentIndex(_positionPlugin->findText(_options.plugin));
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
_pluginParameters = new PluginParameters(_positionPlugin->currentText(), _pluginParameters = new PluginParameters(_positionPlugin->currentText(),
_options.pluginParams); _options.pluginParams);
connect(_positionPlugin, &QComboBox::currentTextChanged, _pluginParameters, connect(_positionPlugin, &QComboBox::currentTextChanged, _pluginParameters,
&PluginParameters::setPlugin); &PluginParameters::setPlugin);
#endif // QT 5.14
QFormLayout *pluginLayout = new QFormLayout(); QFormLayout *pluginLayout = new QFormLayout();
pluginLayout->addRow(tr("Plugin:"), _positionPlugin); pluginLayout->addRow(tr("Plugin:"), _positionPlugin);
QVBoxLayout *sourceLayout = new QVBoxLayout(); QVBoxLayout *sourceLayout = new QVBoxLayout();
sourceLayout->addLayout(pluginLayout); sourceLayout->addLayout(pluginLayout);
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
sourceLayout->addWidget(_pluginParameters); sourceLayout->addWidget(_pluginParameters);
#endif // QT 5.14
sourceLayout->addStretch(); sourceLayout->addStretch();
QWidget *sourceTab = new QWidget(); QWidget *sourceTab = new QWidget();
@ -1005,7 +1009,9 @@ void OptionsDialog::accept()
_options.hillshadingZFactor = _hillshadingZFactor->value(); _options.hillshadingZFactor = _hillshadingZFactor->value();
_options.plugin = _positionPlugin->currentText(); _options.plugin = _positionPlugin->currentText();
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
_options.pluginParams = _pluginParameters->parameters(); _options.pluginParams = _pluginParameters->parameters();
#endif // QT 5.14
_options.useOpenGL = _useOpenGL->isChecked(); _options.useOpenGL = _useOpenGL->isChecked();
_options.enableHTTP2 = _enableHTTP2->isChecked(); _options.enableHTTP2 = _enableHTTP2->isChecked();

View File

@ -193,7 +193,9 @@ private:
QDoubleSpinBox *_hillshadingZFactor; QDoubleSpinBox *_hillshadingZFactor;
// Position // Position
QComboBox *_positionPlugin; QComboBox *_positionPlugin;
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
PluginParameters *_pluginParameters; PluginParameters *_pluginParameters;
#endif // QT 5.14
// System // System
QSpinBox *_pixmapCache; QSpinBox *_pixmapCache;
QSpinBox *_demCache; QSpinBox *_demCache;

View File

@ -10,6 +10,13 @@
#include "markeritem.h" #include "markeritem.h"
#include "pathitem.h" #include "pathitem.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
#define INTERSECTS intersect
#else // QT 5.15
#define INTERSECTS intersects
#endif // QT 5.15
#define GEOGRAPHICAL_MILE 1855.3248 #define GEOGRAPHICAL_MILE 1855.3248
Units PathItem::_units = Metric; Units PathItem::_units = Metric;
@ -72,14 +79,14 @@ bool PathItem::addSegment(const Coordinates &c1, const Coordinates &c2)
QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() + 360, QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() + 360,
c2.lat())); c2.lat()));
QLineF dl(QPointF(180, -90), QPointF(180, 90)); QLineF dl(QPointF(180, -90), QPointF(180, 90));
l.intersects(dl, &p); l.INTERSECTS(dl, &p);
_painterPath.lineTo(_map->ll2xy(Coordinates(180, p.y()))); _painterPath.lineTo(_map->ll2xy(Coordinates(180, p.y())));
_painterPath.moveTo(_map->ll2xy(Coordinates(-180, p.y()))); _painterPath.moveTo(_map->ll2xy(Coordinates(-180, p.y())));
} else { } else {
QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() - 360, QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() - 360,
c2.lat())); c2.lat()));
QLineF dl(QPointF(-180, -90), QPointF(-180, 90)); QLineF dl(QPointF(-180, -90), QPointF(-180, 90));
l.intersects(dl, &p); l.INTERSECTS(dl, &p);
_painterPath.lineTo(_map->ll2xy(Coordinates(-180, p.y()))); _painterPath.lineTo(_map->ll2xy(Coordinates(-180, p.y())));
_painterPath.moveTo(_map->ll2xy(Coordinates(180, p.y()))); _painterPath.moveTo(_map->ll2xy(Coordinates(180, p.y())));
} }

View File

@ -9,6 +9,9 @@
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QFormLayout> #include <QFormLayout>
#include <QApplication> #include <QApplication>
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
#include <QDesktopWidget>
#endif // QT 5.15
#include "tooltip.h" #include "tooltip.h"
#include "thumbnail.h" #include "thumbnail.h"
#include "flowlayout.h" #include "flowlayout.h"
@ -181,7 +184,11 @@ bool PopupFrame::eventFilter(QObject *o, QEvent *ev)
void PopupFrame::place(const QPoint &pos, QWidget *w) void PopupFrame::place(const QPoint &pos, QWidget *w)
{ {
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
QRect screen = QApplication::desktop()->screenGeometry(w);
#else // QT 5.15
QRect screen = w->screen()->geometry(); QRect screen = w->screen()->geometry();
#endif // QT 5.15
QPoint p(pos.x() + 2, pos.y() + 16); QPoint p(pos.x() + 2, pos.y() + 16);
if (p.x() + width() > screen.x() + screen.width()) if (p.x() + width() > screen.x() + screen.width())

View File

@ -64,7 +64,6 @@ GraphItem *SpeedGraph::loadGraph(const Graph &graph, const Track &track,
if (primary) { if (primary) {
_avg.append(QPointF(track.distance(), gi->avg())); _avg.append(QPointF(track.distance(), gi->avg()));
_mavg.append(QPointF(track.distance(), gi->mavg())); _mavg.append(QPointF(track.distance(), gi->mavg()));
_max.append(QPointF(track.distance(), gi->max()));
} }
return gi; return gi;
@ -118,16 +117,6 @@ qreal SpeedGraph::avg() const
return (sum / w); return (sum / w);
} }
qreal SpeedGraph::max() const
{
qreal mv = 0;
for (int i = 0; i < _max.size(); i++)
mv = qMax(mv, _max.at(i).y());
return mv;
}
void SpeedGraph::clear() void SpeedGraph::clear()
{ {
qDeleteAll(_tracks); qDeleteAll(_tracks);
@ -135,7 +124,6 @@ void SpeedGraph::clear()
_avg.clear(); _avg.clear();
_mavg.clear(); _mavg.clear();
_max.clear();
GraphTab::clear(); GraphTab::clear();
} }

View File

@ -26,13 +26,12 @@ private:
GraphItem *loadGraph(const Graph &graph, const Track &track, GraphItem *loadGraph(const Graph &graph, const Track &track,
const QColor &color, bool primary); const QColor &color, bool primary);
qreal avg() const; qreal avg() const;
qreal max() const; qreal max() const {return bounds().bottom();}
void setYUnits(); void setYUnits();
void setInfo(); void setInfo();
QVector<QPointF> _avg; QVector<QPointF> _avg;
QVector<QPointF> _mavg; QVector<QPointF> _mavg;
QVector<QPointF> _max;
Units _units; Units _units;
TimeType _timeType; TimeType _timeType;

View File

@ -7,18 +7,15 @@ RFC 4180 parser with the following enchancements:
- allows LF line ends in addition to CRLF line ends - allows LF line ends in addition to CRLF line ends
*/ */
bool CSV::readEntry(QByteArrayList &list, int limit) bool CSV::readEntry(QByteArrayList &list)
{ {
int state = 0, len = 0; int state = 0;
char c; char c;
QByteArray field; QByteArray field;
list.clear(); list.clear();
while (_device->getChar(&c)) { while (_device->getChar(&c)) {
if (limit && ++len > limit)
return false;
switch (state) { switch (state) {
case 0: case 0:
if (c == '\r') if (c == '\r')

View File

@ -9,7 +9,7 @@ public:
CSV(QIODevice *device, char delimiter = ',') CSV(QIODevice *device, char delimiter = ',')
: _device(device), _delimiter(delimiter), _line(1) {} : _device(device), _delimiter(delimiter), _line(1) {}
bool readEntry(QByteArrayList &list, int limit = 4096); bool readEntry(QByteArrayList &list);
bool atEnd() const {return _device->atEnd();} bool atEnd() const {return _device->atEnd();}
int line() const {return _line;} int line() const {return _line;}

View File

@ -53,7 +53,7 @@ public:
bool intersects(const RectC &r) const bool intersects(const RectC &r) const
{return (right() >= r.left() && bottom() <= r.top() && left() <= r.right() {return (right() >= r.left() && bottom() <= r.top() && left() <= r.right()
&& top() >= r.bottom());} && top() >= r.bottom());}
bool contains(const Coordinates &c) const bool contains(const Coordinates&c) const
{return (c.lon() >= left() && c.lon() <= right() && c.lat() <= top() {return (c.lon() >= left() && c.lon() <= right() && c.lat() <= top()
&& c.lat() >= bottom());} && c.lat() >= bottom());}

View File

@ -115,7 +115,7 @@ public:
/// Count the data elements in this container. This is slow as no internal /// Count the data elements in this container. This is slow as no internal
/// counter is maintained. /// counter is maintained.
int Count() const; int Count();
/// Iterator is not remove safe. /// Iterator is not remove safe.
@ -363,7 +363,7 @@ protected:
void* a_context) const; void* a_context) const;
void RemoveAllRec(Node* a_node); void RemoveAllRec(Node* a_node);
void Reset(); void Reset();
void CountRec(Node* a_node, int& a_count) const; void CountRec(Node* a_node, int& a_count);
/// Root of tree /// Root of tree
Node* m_root; Node* m_root;
@ -473,7 +473,7 @@ int RTREE_QUAL::Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDI
RTREE_TEMPLATE RTREE_TEMPLATE
int RTREE_QUAL::Count() const int RTREE_QUAL::Count()
{ {
int count = 0; int count = 0;
CountRec(m_root, count); CountRec(m_root, count);
@ -483,7 +483,7 @@ int RTREE_QUAL::Count() const
RTREE_TEMPLATE RTREE_TEMPLATE
void RTREE_QUAL::CountRec(Node* a_node, int& a_count) const void RTREE_QUAL::CountRec(Node* a_node, int& a_count)
{ {
if (a_node->IsInternalNode()) { // not a leaf node if (a_node->IsInternalNode()) { // not a leaf node
for (int index = 0; index < a_node->m_count; ++index) for (int index = 0; index < a_node->m_count; ++index)

View File

@ -2,7 +2,6 @@
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include "common/util.h" #include "common/util.h"
#include "map/crs.h"
#include "gpxparser.h" #include "gpxparser.h"
#include "tcxparser.h" #include "tcxparser.h"
#include "csvparser.h" #include "csvparser.h"
@ -23,9 +22,6 @@
#include "onmoveparsers.h" #include "onmoveparsers.h"
#include "twonavparser.h" #include "twonavparser.h"
#include "gpsdumpparser.h" #include "gpsdumpparser.h"
#include "txtparser.h"
#include "vtkparser.h"
#include "vkxparser.h"
#include "data.h" #include "data.h"
@ -52,9 +48,6 @@ static OMDParser omd;
static GHPParser ghp; static GHPParser ghp;
static TwoNavParser twonav; static TwoNavParser twonav;
static GPSDumpParser gpsdump; static GPSDumpParser gpsdump;
static TXTParser txt;
static VTKParser vtk;
static VKXParser vkx;
static QMultiMap<QString, Parser*> parsers() static QMultiMap<QString, Parser*> parsers()
{ {
@ -88,9 +81,6 @@ static QMultiMap<QString, Parser*> parsers()
map.insert("rte", &twonav); map.insert("rte", &twonav);
map.insert("wpt", &twonav); map.insert("wpt", &twonav);
map.insert("wpt", &gpsdump); map.insert("wpt", &gpsdump);
map.insert("txt", &txt);
map.insert("vtk", &vtk);
map.insert("vkx", &vkx);
return map; return map;
} }
@ -164,70 +154,6 @@ Data::Data(const QString &fileName, bool tryUnknown)
} }
} }
Data::Data(const QUrl &url)
{
bool caOk, cbOk, ccOk;
Projection proj(GCS::WGS84());
_valid = false;
QStringList parts(url.path().split(';'));
if (parts.size() < 1) {
_errorString = "Syntax error";
return;
}
QStringList coords(parts.at(0).split(','));
if (coords.size() < 2 || coords.size() > 3) {
_errorString = "Syntax error";
return;
}
double ca = coords.at(0).toDouble(&caOk);
double cb = coords.at(1).toDouble(&cbOk);
double cc = NAN;
if (!(caOk && cbOk)) {
_errorString = "Invalid coordinates";
return;
}
if (coords.size() > 2) {
cc = coords.at(2).toDouble(&ccOk);
if (!ccOk) {
_errorString = "Invalid elevation";
return;
}
}
if (parts.size() > 1) {
QStringList crsp(parts.at(1).split('='));
if (crsp.size() != 2) {
_errorString = "Syntax error";
return;
}
if (!crsp.at(0).compare("crs", Qt::CaseInsensitive)) {
if (crsp.at(1).compare("wgs84", Qt::CaseInsensitive)) {
proj = CRS::projection(crsp.at(1));
if (!proj.isValid()) {
_errorString = "Unknown CRS";
return;
}
}
}
}
CoordinateSystem::AxisOrder ao = proj.coordinateSystem().axisOrder();
PointD p(ao == CoordinateSystem::XY ? PointD(ca, cb) : PointD(cb, ca));
Coordinates c(proj.xy2ll(p));
if (!c.isValid()) {
_errorString = "Invalid coordinates";
return;
}
Waypoint w(c);
w.setElevation(cc);
_waypoints.append(w);
_valid = true;
}
QString Data::formats() QString Data::formats()
{ {
return return
@ -250,9 +176,6 @@ QString Data::formats()
+ qApp->translate("Data", "SLF files") + " (*.slf);;" + qApp->translate("Data", "SLF files") + " (*.slf);;"
+ qApp->translate("Data", "SML files") + " (*.sml);;" + qApp->translate("Data", "SML files") + " (*.sml);;"
+ qApp->translate("Data", "TCX files") + " (*.tcx);;" + qApp->translate("Data", "TCX files") + " (*.tcx);;"
+ qApp->translate("Data", "70mai GPS log files") + " (*.txt);;"
+ qApp->translate("Data", "VKX files") + " (*.vkx);;"
+ qApp->translate("Data", "VTK files") + " (*.vtk);;"
+ qApp->translate("Data", "TwoNav files") + " (*.rte *.trk *.wpt);;" + qApp->translate("Data", "TwoNav files") + " (*.rte *.trk *.wpt);;"
+ qApp->translate("Data", "GPSDump files") + " (*.wpt);;" + qApp->translate("Data", "GPSDump files") + " (*.wpt);;"
+ qApp->translate("Data", "All files") + " (*)"; + qApp->translate("Data", "All files") + " (*)";

View File

@ -14,7 +14,6 @@ class Data
{ {
public: public:
Data(const QString &fileName, bool tryUnknown = true); Data(const QString &fileName, bool tryUnknown = true);
Data(const QUrl &url);
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
const QString &errorString() const {return _errorString;} const QString &errorString() const {return _errorString;}

View File

@ -467,7 +467,8 @@ bool FITParser::parseHeader(CTX &ctx)
} }
bool FITParser::parse(QFile *file, QList<TrackData> &tracks, bool FITParser::parse(QFile *file, QList<TrackData> &tracks,
QList<RouteData> &routes, QList<Area> &polygons, QVector<Waypoint> &waypoints) QList<RouteData> &routes,
QList<Area> &polygons, QVector<Waypoint> &waypoints)
{ {
Q_UNUSED(routes); Q_UNUSED(routes);
Q_UNUSED(polygons); Q_UNUSED(polygons);

View File

@ -541,7 +541,7 @@ void KMLParser::photoOverlay(const Ctx &ctx, QVector<Waypoint> &waypoints,
Waypoint w; Waypoint w;
QMap<QString, PolygonStyle> unused; QMap<QString, PolygonStyle> unused;
QMap<QString, LineStyle> unused2; QMap<QString, LineStyle> unused2;
static const QRegularExpression re("\\$\\[[^\\]]+\\]"); static QRegularExpression re("\\$\\[[^\\]]+\\]");
while (_reader.readNextStartElement()) { while (_reader.readNextStartElement()) {
if (_reader.name() == QLatin1String("name")) if (_reader.name() == QLatin1String("name"))

View File

@ -4,6 +4,7 @@
#include <QXmlStreamReader> #include <QXmlStreamReader>
#include "parser.h" #include "parser.h"
class TCXParser : public Parser class TCXParser : public Parser
{ {
public: public:

View File

@ -2,6 +2,13 @@
#include "map/gcs.h" #include "map/gcs.h"
#include "twonavparser.h" #include "twonavparser.h"
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
#define SKIP_EMPTY QString::SkipEmptyParts
#else // Qt 5.14
#define SKIP_EMPTY Qt::SkipEmptyParts
#endif
static double lon(const QString &str) static double lon(const QString &str)
{ {
QStringList l(str.split(QChar(0xBA))); QStringList l(str.split(QChar(0xBA)));
@ -116,8 +123,7 @@ bool TwoNavParser::parse(QFile *file, QList<TrackData> &tracks,
}} }}
break; break;
case 'T': case 'T':
{QStringList list(codec.toString(line).split(' ', {QStringList list(codec.toString(line).split(' ', SKIP_EMPTY));
Qt::SkipEmptyParts));
if (list.size() < 4) { if (list.size() < 4) {
_errorString = "Parse error"; _errorString = "Parse error";
return false; return false;
@ -153,8 +159,7 @@ bool TwoNavParser::parse(QFile *file, QList<TrackData> &tracks,
tracks.last().last().append(t);} tracks.last().last().append(t);}
break; break;
case 'W': case 'W':
{QStringList list(codec.toString(line).split(' ', {QStringList list(codec.toString(line).split(' ', SKIP_EMPTY));
Qt::SkipEmptyParts));
if (list.size() < 5) { if (list.size() < 5) {
_errorString = "Parse error"; _errorString = "Parse error";
return false; return false;

View File

@ -1,80 +0,0 @@
#include <QTimeZone>
#include "common/csv.h"
#include "txtparser.h"
static Coordinates coordinates(const QByteArrayList &entry)
{
bool lonOk, latOk;
double lon = entry.at(3).toDouble(&lonOk);
double lat = entry.at(2).toDouble(&latOk);
return (lonOk && latOk) ? Coordinates(lon, lat) : Coordinates();
}
bool TXTParser::parse(QFile *file, QList<TrackData> &tracks,
QList<RouteData> &routes, QList<Area> &polygons, QVector<Waypoint> &waypoints)
{
Q_UNUSED(routes);
Q_UNUSED(polygons);
Q_UNUSED(waypoints);
CSV csv(file);
QByteArrayList entry;
SegmentData *sg = 0;
_errorLine = 1;
_errorString.clear();
while (!csv.atEnd()) {
if (!csv.readEntry(entry)) {
_errorString = "CSV parse error";
_errorLine = csv.line() - 1;
return false;
}
if (entry.size() == 1) {
if (entry.at(0) == "$V02") {
tracks.append(TrackData(SegmentData()));
sg = &tracks.last().last();
} else {
_errorString = "Invalid track start marker";
_errorLine = csv.line() - 1;
return false;
}
} else {
if (!sg) {
_errorString = "Missing start marker";
_errorLine = csv.line() - 1;
return false;
}
if (entry.size() == 13 && entry.at(1) == "A") {
Coordinates c(coordinates(entry));
if (!c.isValid()) {
_errorString = "Invalid coordinates";
_errorLine = csv.line() - 1;
return false;
}
Trackpoint tp(c);
bool ok;
qulonglong ts = entry.at(0).toULongLong(&ok);
if (!ok) {
_errorString = "Invalid timestamp";
_errorLine = csv.line() - 1;
return false;
}
tp.setTimestamp(QDateTime::fromSecsSinceEpoch(ts,
QTimeZone::utc()));
uint speed = entry.at(5).toULong(&ok);
if (ok)
tp.setSpeed(speed * 0.01);
if (c != Coordinates(0, 0))
sg->append(tp);
}
}
}
return true;
}

View File

@ -1,18 +0,0 @@
#ifndef TXTPARSER_H
#define TXTPARSER_H
#include "parser.h"
class TXTParser : public Parser
{
bool parse(QFile *file, QList<TrackData> &tracks, QList<RouteData> &routes,
QList<Area> &polygons, QVector<Waypoint> &waypoints);
QString errorString() const {return _errorString;}
int errorLine() const {return _errorLine;}
private:
QString _errorString;
int _errorLine;
};
#endif // TXTPARSER_H

View File

@ -1,151 +0,0 @@
#include "vkxparser.h"
static bool readTrackPoint(QDataStream &stream, SegmentData &segment)
{
quint64 time;
qint32 lat, lon;
quint32 unused;
float speed, alt;
stream >> time >> lat >> lon;
if (stream.status() != QDataStream::Ok)
return false;
if (stream.readRawData((char*)&speed, 4) != 4)
return false;
stream >> unused;
if (stream.readRawData((char*)&alt, 4) != 4)
return false;
stream >> unused >> unused >> unused >> unused;
if (stream.status() != QDataStream::Ok)
return false;
Trackpoint t(Coordinates(lon / 1e7, lat / 1e7));
if (!t.coordinates().isValid())
return false;
t.setTimestamp(QDateTime::fromMSecsSinceEpoch(time));
t.setSpeed(speed);
t.setElevation(alt);
segment.append(t);
return true;
}
bool VKXParser::skip(QDataStream &stream, quint8 key, int len)
{
if (stream.skipRawData(len) != len) {
_errorString = "Invalid 0x" + QString::number(key, 16) + " row";
return false;
}
return true;
}
bool VKXParser::parse(QFile *file, QList<TrackData> &tracks,
QList<RouteData> &routes, QList<Area> &polygons, QVector<Waypoint> &waypoints)
{
Q_UNUSED(routes);
Q_UNUSED(polygons);
Q_UNUSED(waypoints);
quint8 key;
quint64 hdr;
SegmentData segment;
QDataStream stream(file);
stream.setByteOrder(QDataStream::LittleEndian);
stream >> hdr;
if ((hdr & 0xFF) != 0xFF) {
_errorString = "Not a Vakaros VKX file";
return false;
}
while (stream.status() == QDataStream::Ok) {
stream >> key;
if (stream.status() != QDataStream::Ok)
break;
switch (key) {
case 0x01:
if (!skip(stream, key, 32))
return false;
break;
case 0x02:
if (!readTrackPoint(stream, segment)) {
_errorString = "Invalid 0x2 row";
return false;
}
break;
case 0x03:
if (!skip(stream, key, 20))
return false;
break;
case 0x04:
if (!skip(stream, key, 13))
return false;
break;
case 0x05:
if (!skip(stream, key, 17))
return false;
break;
case 0x06:
if (!skip(stream, key, 18))
return false;
break;
case 0x07:
if (!skip(stream, key, 12))
return false;
break;
case 0x08:
if (!skip(stream, key, 13))
return false;
break;
case 0x0A:
case 0x0B:
if (!skip(stream, key, 16))
return false;
break;
case 0x0C:
if (!skip(stream, key, 12))
return false;
break;
case 0x0E:
case 0x0F:
if (!skip(stream, key, 16))
return false;
break;
case 0x10:
if (!skip(stream, key, 12))
return false;
break;
case 0x20:
if (!skip(stream, key, 13))
return false;
break;
case 0x21:
if (!skip(stream, key, 52))
return false;
break;
case 0xFE:
if (!skip(stream, key, 2))
return false;
break;
case 0xFF:
if (!skip(stream, key, 7))
return false;
break;
default:
_errorString = "Unknown row key: 0x" + QString::number(key, 16);
return false;
}
}
if (stream.status() != QDataStream::ReadPastEnd) {
_errorString = "Unexpected EOF";
return false;
}
tracks.append(segment);
return true;
}

View File

@ -1,27 +0,0 @@
#ifndef VKXPARSER_H
#define VKXPARSER_H
#include "parser.h"
class QDataStream;
class VKXParser : public Parser
{
public:
VKXParser()
{
static_assert(sizeof(float) == 4, "Invalid float size");
}
bool parse(QFile *file, QList<TrackData> &tracks, QList<RouteData> &routes,
QList<Area> &polygons, QVector<Waypoint> &waypoints);
QString errorString() const {return _errorString;}
int errorLine() const {return 0;}
private:
bool skip(QDataStream &stream, quint8 key, int len);
QString _errorString;
};
#endif // VKXPARSER_H

View File

@ -1,217 +0,0 @@
#include <QtEndian>
#include <QTimeZone>
#include "vtkparser.h"
#define TYPE(tag) (tag & 0x07)
#define FIELD(tag) (tag >> 3)
#define VARINT 0
#define I64 1
#define LEN 2
#define I32 5
struct CTX
{
CTX(const QByteArray &ba)
: bp(ba.constData()), be(bp + ba.size()), tag(0) {}
const char *bp;
const char *be;
quint32 tag;
};
static inline qint32 zigzag32decode(quint32 value)
{
return static_cast<qint32>((value >> 1u) ^ static_cast<quint32>(
-static_cast<qint32>(value & 1u)));
}
template<typename T>
static bool varint(CTX &ctx, T &val)
{
unsigned int shift = 0;
val = 0;
while (ctx.bp < ctx.be) {
val |= ((quint8)*ctx.bp & 0x7F) << shift;
shift += 7;
if (!((quint8)*ctx.bp++ & 0x80))
return true;
}
return false;
}
static bool length(CTX &ctx, qint32 &val)
{
if (TYPE(ctx.tag) != LEN)
return false;
if (!varint(ctx, val))
return false;
return (val >= 0);
}
static bool skip(CTX &ctx)
{
qint32 len = 0;
switch (TYPE(ctx.tag)) {
case VARINT:
return varint(ctx, len);
case I64:
len = 8;
break;
case LEN:
if (!varint(ctx, len) || len < 0)
return false;
break;
case I32:
len = 4;
break;
default:
return false;
}
if (ctx.bp + len > ctx.be)
return false;
ctx.bp += len;
return true;
}
static bool trackpoint(CTX &ctx, Trackpoint &t)
{
qint32 len, lon = 0xFFFFFFF, lat = 0xFFFFFFF;
quint32 val, seconds = 0, centiSeconds = 0, speed = 0;
if (!length(ctx, len))
return false;
const char *ee = ctx.bp + len;
if (ee > ctx.be)
return false;
while (ctx.bp < ee) {
if (!varint(ctx, ctx.tag))
return false;
switch (FIELD(ctx.tag)) {
case 1:
if (TYPE(ctx.tag) != VARINT)
return false;
if (!varint(ctx, seconds))
return false;
break;
case 2:
if (TYPE(ctx.tag) != VARINT)
return false;
if (!varint(ctx, centiSeconds))
return false;
break;
case 3:
if (TYPE(ctx.tag) != VARINT)
return false;
if (!varint(ctx, val))
return false;
lat = zigzag32decode(val);
break;
case 4:
if (TYPE(ctx.tag) != VARINT)
return false;
if (!varint(ctx, val))
return false;
lon = zigzag32decode(val);
break;
case 5:
if (TYPE(ctx.tag) != VARINT)
return false;
if (!varint(ctx, speed))
return false;
break;
default:
if (!skip(ctx))
return false;
}
}
t.setCoordinates(Coordinates(lon / 1e7, lat / 1e7));
t.setTimestamp(QDateTime::fromMSecsSinceEpoch(
((qint64)seconds * 1000) + ((qint64)centiSeconds * 10),
QTimeZone::utc()));
t.setSpeed(speed * 0.051444);
return (ctx.bp == ee);
}
static bool record(CTX &ctx, Trackpoint &t)
{
while (ctx.bp < ctx.be) {
if (!varint(ctx, ctx.tag))
return false;
switch (FIELD(ctx.tag)) {
case 1:
if (!trackpoint(ctx, t))
return false;
break;
default:
if (!skip(ctx))
return false;
}
}
return (ctx.bp == ctx.be);
}
bool VTKParser::parse(QFile *file, QList<TrackData> &tracks,
QList<RouteData> &routes, QList<Area> &polygons, QVector<Waypoint> &waypoints)
{
Q_UNUSED(routes);
Q_UNUSED(polygons);
Q_UNUSED(waypoints);
qint64 len;
quint16 recordLen;
QByteArray ba;
SegmentData segment;
Trackpoint t;
_errorString = "";
while (true) {
if ((len = file->read((char*)&recordLen, sizeof(recordLen)))
!= sizeof(recordLen)) {
if (!len)
break;
else {
_errorString = "Error reading VTK record size";
return false;
}
}
recordLen = qFromLittleEndian(recordLen);
ba.resize(recordLen);
if (file->read(ba.data(), ba.size()) != ba.size()) {
_errorString = "Error reading VTK record";
return false;
}
CTX ctx(ba);
t.setCoordinates(Coordinates());
if (!record(ctx, t)) {
_errorString = "Invalid VTK record";
return false;
} else {
if (t.coordinates().isValid())
segment.append(t);
else if (!t.coordinates().isNull()) {
_errorString = "Invalid VTK record coordinates";
return false;
}
}
}
tracks.append(segment);
return true;
}

View File

@ -1,18 +0,0 @@
#ifndef VTKPARSER_H
#define VTKPARSER_H
#include "parser.h"
class VTKParser : public Parser
{
public:
bool parse(QFile *file, QList<TrackData> &tracks, QList<RouteData> &routes,
QList<Area> &polygons, QVector<Waypoint> &waypoints);
QString errorString() const {return _errorString;}
int errorLine() const {return 0;}
private:
QString _errorString;
};
#endif // VTKPARSER_H

View File

@ -39,12 +39,15 @@ bool AtlasData::polyCb(MapEntry *map, void *context)
ctx->cacheLock.unlock(); ctx->cacheLock.unlock();
MapData *data = new MapData(map->path); MapData *data = new MapData(map->path);
data->polys(ctx->rect, ctx->polygons, ctx->lines); data->polygons(ctx->rect, ctx->polygons);
data->lines(ctx->rect, ctx->lines);
ctx->cacheLock.lock(); ctx->cacheLock.lock();
ctx->cache.insert(map->path, data); ctx->cache.insert(map->path, data);
} else } else {
cached->polys(ctx->rect, ctx->polygons, ctx->lines); cached->polygons(ctx->rect, ctx->polygons);
cached->lines(ctx->rect, ctx->lines);
}
ctx->cacheLock.unlock(); ctx->cacheLock.unlock();
map->lock.unlock(); map->lock.unlock();

View File

@ -10,18 +10,18 @@ namespace ENC {
typedef QCache<QString, MapData> MapCache; typedef QCache<QString, MapData> MapCache;
class AtlasData : public Data class AtlasData
{ {
public: public:
AtlasData(MapCache &cache, QMutex &cacheLock) AtlasData(MapCache &cache, QMutex &cacheLock)
: _cache(cache), _cacheLock(cacheLock) {} : _cache(cache), _cacheLock(cacheLock) {}
virtual ~AtlasData(); ~AtlasData();
void addMap(const RectC &bounds, const QString &path); void addMap(const RectC &bounds, const QString &path);
virtual void polys(const RectC &rect, QList<MapData::Poly> *polygons, void polys(const RectC &rect, QList<MapData::Poly> *polygons,
QList<MapData::Line> *lines); QList<MapData::Line> *lines);
virtual void points(const RectC &rect, QList<MapData::Point> *points); void points(const RectC &rect, QList<MapData::Point> *points);
private: private:
struct MapEntry { struct MapEntry {

View File

@ -3,11 +3,9 @@
#define CATACH 8 #define CATACH 8
#define CATBUA 10 #define CATBUA 10
#define CATCOV 18
#define CATDIS 21 #define CATDIS 21
#define CATHAF 30 #define CATHAF 30
#define CATLMK 35 #define CATLMK 35
#define CATLIT 37
#define CATMFA 38 #define CATMFA 38
#define CATMOR 40 #define CATMOR 40
#define CATTRK 54 #define CATTRK 54
@ -18,21 +16,16 @@
#define CATWAT 69 #define CATWAT 69
#define CATWED 70 #define CATWED 70
#define CATWRK 71 #define CATWRK 71
#define COLOUR 75
#define COMCHA 77 #define COMCHA 77
#define CURVEL 84 #define CURVEL 84
#define DRVAL1 87 #define DRVAL1 87
#define ELEVAT 90 #define ELEVAT 90
#define FUNCTN 94 #define FUNCTN 94
#define LITVIS 108
#define OBJNAM 116 #define OBJNAM 116
#define ORIENT 117 #define ORIENT 117
#define RESTRN 131 #define RESTRN 131
#define SECTR1 136
#define SECTR2 137
#define TRAFIC 172 #define TRAFIC 172
#define VALDCO 174 #define VALDCO 174
#define VALNMR 178
#define VERCLR 181 #define VERCLR 181
#define WATLEV 187 #define WATLEV 187

View File

@ -1,79 +0,0 @@
#ifndef ENC_DATA_H
#define ENC_DATA_H
#include "common/rectc.h"
#include "common/polygon.h"
namespace ENC {
class Data
{
public:
typedef QMap<uint, QByteArray> Attributes;
class Poly {
public:
Poly(uint type, const Polygon &path, const Attributes &attr, uint HUNI);
RectC bounds() const {return _path.boundingRect();}
const Polygon &path() const {return _path;}
uint type() const {return _type;}
const Attributes &attributes() const {return _attr;}
uint HUNI() const {return _HUNI;}
private:
uint _type;
Polygon _path;
Attributes _attr;
uint _HUNI;
};
class Line {
public:
Line(uint type, const QVector<Coordinates> &path, const Attributes &attr);
RectC bounds() const;
const QVector<Coordinates> &path() const {return _path;}
uint type() const {return _type;}
const QString &label() const {return _label;}
const Attributes &attributes() const {return _attr;}
private:
uint _type;
QVector<Coordinates> _path;
QString _label;
Attributes _attr;
};
class Point {
public:
Point(uint type, const Coordinates &c, const Attributes &attr,
uint HUNI, bool polygon = false);
Point(uint type, const Coordinates &s, const QString &label);
const Coordinates &pos() const {return _pos;}
uint type() const {return _type;}
const QString &label() const {return _label;}
const Attributes &attributes() const {return _attr;}
bool polygon() const {return _polygon;}
bool operator<(const Point &other) const
{return _id < other._id;}
private:
uint _type;
Coordinates _pos;
QString _label;
quint64 _id;
Attributes _attr;
bool _polygon;
};
virtual void polys(const RectC &rect, QList<Data::Poly> *polygons,
QList<Data::Line> *lines) = 0;
virtual void points(const RectC &rect, QList<Data::Point> *points) = 0;
};
}
#endif // ENC_DATA_H

View File

@ -1,4 +1,3 @@
#include <QtEndian>
#include <QFile> #include <QFile>
#include <QRegularExpression> #include <QRegularExpression>
#include "common/util.h" #include "common/util.h"
@ -6,6 +5,13 @@
using namespace ENC; using namespace ENC;
#define UINT16(x) \
(((quint16)*(const uchar*)(x)) \
| ((quint16)(*((const uchar*)(x) + 1)) << 8))
#define INT32(x) ((qint32)UINT32(x))
#define INT16(x) ((qint16)UINT16(x))
struct DR { struct DR {
char RecordLength[5]; char RecordLength[5];
char InterchangeLevel; char InterchangeLevel;
@ -23,18 +29,18 @@ struct DR {
}; };
const QVariant *ISO8211::Field::data(quint32 name, int idx) const const QVariant *ISO8211::Field::data(const QByteArray &name, int idx) const
{ {
const QVector<QVariant> &v = _data.at(idx); const QVector<QVariant> &v = _data.at(idx);
for (int i = 0; i < _subFields->size(); i++) for (int i = 0; i < _subFields.size(); i++)
if (_subFields->at(i) == name) if (_subFields.at(i) == name)
return &v.at(i); return &v.at(i);
return 0; return 0;
} }
bool ISO8211::Field::subfield(quint32 name, int *val, int idx) const bool ISO8211::Field::subfield(const char *name, int *val, int idx) const
{ {
bool ok; bool ok;
@ -46,7 +52,7 @@ bool ISO8211::Field::subfield(quint32 name, int *val, int idx) const
return ok; return ok;
} }
bool ISO8211::Field::subfield(quint32 name, uint *val, int idx) const bool ISO8211::Field::subfield(const char *name, uint *val, int idx) const
{ {
bool ok; bool ok;
@ -58,7 +64,7 @@ bool ISO8211::Field::subfield(quint32 name, uint *val, int idx) const
return ok; return ok;
} }
bool ISO8211::Field::subfield(quint32 name, QByteArray *val, int idx) const bool ISO8211::Field::subfield(const char *name, QByteArray *val, int idx) const
{ {
const QVariant *v = data(name, idx); const QVariant *v = data(name, idx);
if (!v) if (!v)
@ -95,7 +101,6 @@ int ISO8211::readDR(QVector<FieldDefinition> &fields)
DR ddr; DR ddr;
QByteArray fieldLen, fieldPos; QByteArray fieldLen, fieldPos;
int len, lenSize, posSize, tagSize, offset; int len, lenSize, posSize, tagSize, offset;
char tag[4];
static_assert(sizeof(ddr) == 24, "Invalid DR alignment"); static_assert(sizeof(ddr) == 24, "Invalid DR alignment");
if (_file.read((char*)&ddr, sizeof(ddr)) != sizeof(ddr)) if (_file.read((char*)&ddr, sizeof(ddr)) != sizeof(ddr))
@ -110,19 +115,20 @@ int ISO8211::readDR(QVector<FieldDefinition> &fields)
if (len < 0 || offset < 0 || lenSize < 0 || posSize < 0 || tagSize < 0) if (len < 0 || offset < 0 || lenSize < 0 || posSize < 0 || tagSize < 0)
return -1; return -1;
fields.resize((offset - 1 - sizeof(ddr)) / (lenSize + posSize + tagSize)); fields.resize((offset - 1 - sizeof(DR)) / (lenSize + posSize + tagSize));
fieldLen.resize(lenSize); fieldLen.resize(lenSize);
fieldPos.resize(posSize); fieldPos.resize(posSize);
for (int i = 0; i < fields.size(); i++) { for (int i = 0; i < fields.size(); i++) {
FieldDefinition &r = fields[i]; FieldDefinition &r = fields[i];
if (_file.read(tag, sizeof(tag)) != tagSize r.tag.resize(tagSize);
if (_file.read(r.tag.data(), tagSize) != tagSize
|| _file.read(fieldLen.data(), lenSize) != lenSize || _file.read(fieldLen.data(), lenSize) != lenSize
|| _file.read(fieldPos.data(), posSize) != posSize) || _file.read(fieldPos.data(), posSize) != posSize)
return -1; return -1;
r.tag = qFromLittleEndian<quint32>(tag);
r.pos = offset + Util::str2int(fieldPos.constData(), posSize); r.pos = offset + Util::str2int(fieldPos.constData(), posSize);
r.size = Util::str2int(fieldLen.constData(), lenSize); r.size = Util::str2int(fieldLen.constData(), lenSize);
@ -135,13 +141,13 @@ int ISO8211::readDR(QVector<FieldDefinition> &fields)
bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields) bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
{ {
static const QRegularExpression re( static QRegularExpression re("(\\d*)(\\w+)\\(*(\\d*)\\)*");
"([0-9]*)(A|I|R|B|b11|b12|b14|b21|b22|b24)\\(*([0-9]*)\\)*"); QByteArray ba;
QByteArray ba(def.size, Qt::Initialization::Uninitialized);
bool repeat = false; bool repeat = false;
QVector<SubFieldDefinition> defs; QVector<SubFieldDefinition> defs;
QVector<quint32> defTags; QVector<QByteArray> defTags;
ba.resize(def.size);
if (!(_file.seek(def.pos) && _file.read(ba.data(), ba.size()) == ba.size())) if (!(_file.seek(def.pos) && _file.read(ba.data(), ba.size()) == ba.size()))
return false; return false;
@ -150,9 +156,9 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
repeat = true; repeat = true;
list[1].remove(0, 1); list[1].remove(0, 1);
} }
QList<QByteArray> tags(list.at(1).split('!'));
if (list.size() > 2) { if (list.size() > 2) {
QList<QByteArray> tags(list.at(1).split('!'));
QRegularExpressionMatchIterator it = re.globalMatch(list.at(2)); QRegularExpressionMatchIterator it = re.globalMatch(list.at(2));
int tag = 0; int tag = 0;
@ -182,17 +188,11 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
SubFieldDefinition sfd(fieldType(typeStr, size)); SubFieldDefinition sfd(fieldType(typeStr, size));
if (sfd.type() == Unknown) if (sfd.type() == Unknown)
return false; return false;
if (tag >= tags.size())
return false;
defs[tag] = sfd; defs[tag] = sfd;
defTags[tag] = (tags.at(tag).length() == 4) defTags[tag] = tags.at(tag);
? qFromLittleEndian<quint32>(tags.at(tag).constData()) : 0;
tag++; tag++;
} }
} }
if (tag != tags.size())
return false;
} }
fields = SubFields(defTags, defs, repeat); fields = SubFields(defTags, defs, repeat);
@ -218,10 +218,8 @@ bool ISO8211::readDDR()
for (int i = 0; i < fields.size(); i++) { for (int i = 0; i < fields.size(); i++) {
SubFields def; SubFields def;
if (!readDDA(fields.at(i), def)) { if (!readDDA(fields.at(i), def)) {
QByteArray tag(sizeof(quint32), Qt::Initialization::Uninitialized);
qToLittleEndian<quint32>(fields.at(i).tag, tag.data());
_errorString = QString("Error reading %1 DDA field") _errorString = QString("Error reading %1 DDA field")
.arg(QString(tag)); .arg(QString(fields.at(i).tag));
return false; return false;
} }
_map.insert(fields.at(i).tag, def); _map.insert(fields.at(i).tag, def);
@ -238,8 +236,9 @@ bool ISO8211::readDDR()
bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def, bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
const QVector<SubFieldDefinition> &fields, bool repeat, Data &data) const QVector<SubFieldDefinition> &fields, bool repeat, Data &data)
{ {
QByteArray ba(def.size, Qt::Initialization::Uninitialized); QByteArray ba;
ba.resize(def.size);
if (!(_file.seek(pos + def.pos) if (!(_file.seek(pos + def.pos)
&& _file.read(ba.data(), ba.size()) == ba.size())) && _file.read(ba.data(), ba.size()) == ba.size()))
return false; return false;
@ -249,7 +248,8 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
const char *ep = ba.constData() + ba.size() - 1; const char *ep = ba.constData() + ba.size() - 1;
do { do {
QVector<QVariant> row(fields.size()); QVector<QVariant> row;
row.resize(fields.size());
for (int i = 0; i < fields.size(); i++) { for (int i = 0; i < fields.size(); i++) {
const SubFieldDefinition &f = fields.at(i); const SubFieldDefinition &f = fields.at(i);
@ -273,11 +273,11 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
dp++; dp++;
break; break;
case S16: case S16:
row[i] = QVariant(qFromLittleEndian<qint16>(dp)); row[i] = QVariant(INT16(dp));
dp += 2; dp += 2;
break; break;
case S32: case S32:
row[i] = QVariant(qFromLittleEndian<qint32>(dp)); row[i] = QVariant(INT32(dp));
dp += 4; dp += 4;
break; break;
case U8: case U8:
@ -285,11 +285,11 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
dp++; dp++;
break; break;
case U16: case U16:
row[i] = QVariant(qFromLittleEndian<quint16>(dp)); row[i] = QVariant(UINT16(dp));
dp += 2; dp += 2;
break; break;
case U32: case U32:
row[i] = QVariant(qFromLittleEndian<quint32>(dp)); row[i] = QVariant(UINT32(dp));
dp += 4; dp += 4;
break; break;
default: default:
@ -325,16 +325,13 @@ bool ISO8211::readRecord(Record &record)
FieldsMap::const_iterator it(_map.find(def.tag)); FieldsMap::const_iterator it(_map.find(def.tag));
if (it == _map.constEnd()) { if (it == _map.constEnd()) {
QByteArray tag(sizeof(quint32), Qt::Initialization::Uninitialized); _errorString = QString("%1: unknown record").arg(QString(def.tag));
qToLittleEndian<quint32>(def.tag, tag.data());
_errorString = QString("%1: unknown record").arg(QString(tag));
return false; return false;
} }
if (!readUDA(pos, def, it->defs(), it->repeat(), data)) { if (!readUDA(pos, def, it->defs(), it->repeat(), data)) {
QByteArray tag(sizeof(quint32), Qt::Initialization::Uninitialized); _errorString = QString("Error reading %1 record")
qToLittleEndian<quint32>(def.tag, tag.data()); .arg(QString(def.tag));
_errorString = QString("Error reading %1 record").arg(QString(tag));
return false; return false;
} }
@ -344,7 +341,8 @@ bool ISO8211::readRecord(Record &record)
return true; return true;
} }
const ISO8211::Field *ISO8211::field(const Record &record, quint32 name)
const ISO8211::Field *ISO8211::field(const Record &record, const QByteArray &name)
{ {
for (int i = 0; i < record.size(); i++) for (int i = 0; i < record.size(); i++)
if (record.at(i).tag() == name) if (record.at(i).tag() == name)

View File

@ -4,6 +4,13 @@
#include <QFile> #include <QFile>
#include <QByteArray> #include <QByteArray>
#include <QVariant> #include <QVariant>
#include <QDebug>
#define UINT32(x) \
(((quint32)*(const uchar*)(x)) \
| ((quint32)(*((const uchar*)(x) + 1)) << 8) \
| ((quint32)(*((const uchar*)(x) + 2)) << 16) \
| ((quint32)(*((const uchar*)(x) + 3)) << 24))
namespace ENC { namespace ENC {
@ -15,22 +22,23 @@ public:
class Field class Field
{ {
public: public:
Field() : _subFields(0) {} Field() {}
Field(quint32 tag, const QVector<quint32> &subFields, const Data &data) Field(const QByteArray &tag, const QVector<QByteArray> &subFields,
: _tag(tag), _subFields(&subFields), _data(data) {} const Data &data) : _tag(tag), _subFields(subFields), _data(data) {}
quint32 tag() const {return _tag;} const QByteArray &tag() const {return _tag;}
const QVector<QByteArray> &subFields() const {return _subFields;}
const Data &data() const {return _data;} const Data &data() const {return _data;}
bool subfield(quint32 name, int *val, int idx = 0) const; bool subfield(const char *name, int *val, int idx = 0) const;
bool subfield(quint32 name, uint *val, int idx = 0) const; bool subfield(const char *name, uint *val, int idx = 0) const;
bool subfield(quint32 name, QByteArray *val, int idx = 0) const; bool subfield(const char *name, QByteArray *val, int idx = 0) const;
private: private:
const QVariant *data(quint32 name, int idx = 0) const; const QVariant *data(const QByteArray &name, int idx = 0) const;
quint32 _tag; QByteArray _tag;
const QVector<quint32> *_subFields; QVector<QByteArray> _subFields;
Data _data; Data _data;
}; };
@ -42,21 +50,14 @@ public:
const QString &errorString() const {return _errorString;} const QString &errorString() const {return _errorString;}
static const Field *field(const Record &record, quint32 name); static const Field *field(const Record &record, const QByteArray &name);
static constexpr quint32 NAME(const char str[4])
{
return static_cast<quint32>(str[0])
+ (static_cast<quint32>(str[1]) << 8)
+ (static_cast<quint32>(str[2]) << 16)
+ (static_cast<quint32>(str[3]) << 24);
}
private: private:
enum FieldType {Unknown, String, Array, S8, S16, S32, U8, U16, U32}; enum FieldType {Unknown, String, Array, S8, S16, S32, U8, U16, U32};
struct FieldDefinition struct FieldDefinition
{ {
quint32 tag; QByteArray tag;
int pos; int pos;
int size; int size;
}; };
@ -80,22 +81,22 @@ private:
{ {
public: public:
SubFields() : _repeat(false) {} SubFields() : _repeat(false) {}
SubFields(const QVector<quint32> &tags, SubFields(const QVector<QByteArray> &tags,
const QVector<SubFieldDefinition> &defs, bool repeat) const QVector<SubFieldDefinition> &defs, bool repeat)
: _tags(tags), _defs(defs), _repeat(repeat) {} : _tags(tags), _defs(defs), _repeat(repeat) {}
const QVector<quint32> &tags() const {return _tags;} const QVector<QByteArray> &tags() const {return _tags;}
const QVector<SubFieldDefinition> &defs() const {return _defs;} const QVector<SubFieldDefinition> &defs() const {return _defs;}
bool repeat() const {return _repeat;} bool repeat() const {return _repeat;}
private: private:
QVector<quint32> _tags; QVector<QByteArray> _tags;
QVector<SubFieldDefinition> _defs; QVector<SubFieldDefinition> _defs;
bool _repeat; bool _repeat;
}; };
typedef QMap<quint32, SubFields> FieldsMap; typedef QMap<QByteArray, SubFields> FieldsMap;
static SubFieldDefinition fieldType(const QString &str, int cnt); static SubFieldDefinition fieldType(const QString &str, int cnt);
@ -109,6 +110,14 @@ private:
QString _errorString; QString _errorString;
}; };
#ifndef QT_NO_DEBUG
inline QDebug operator<<(QDebug dbg, const ISO8211::Field &field)
{
dbg.nospace() << "Field(" << field.tag() << ", " << field.subFields() << ")";
return dbg.space();
}
#endif // QT_NO_DEBUG
} }
#endif // ENC_ISO8211_H #endif // ENC_ISO8211_H

View File

@ -1,4 +1,3 @@
#include <QtEndian>
#include "GUI/units.h" #include "GUI/units.h"
#include "objects.h" #include "objects.h"
#include "attributes.h" #include "attributes.h"
@ -15,19 +14,6 @@ using namespace ENC;
#define PRIM_L 2 #define PRIM_L 2
#define PRIM_A 3 #define PRIM_A 3
constexpr quint32 RCID = ISO8211::NAME("RCID");
constexpr quint32 SG2D = ISO8211::NAME("SG2D");
constexpr quint32 SG3D = ISO8211::NAME("SG3D");
constexpr quint32 FSPT = ISO8211::NAME("FSPT");
constexpr quint32 VRPT = ISO8211::NAME("VRPT");
constexpr quint32 ATTF = ISO8211::NAME("ATTF");
constexpr quint32 VRID = ISO8211::NAME("VRID");
constexpr quint32 FRID = ISO8211::NAME("FRID");
constexpr quint32 DSPM = ISO8211::NAME("DSPM");
constexpr quint32 COMF = ISO8211::NAME("COMF");
constexpr quint32 SOMF = ISO8211::NAME("SOMF");
constexpr quint32 HUNI = ISO8211::NAME("HUNI");
static QMap<uint,uint> orderMapInit() static QMap<uint,uint> orderMapInit()
{ {
QMap<uint,uint> map; QMap<uint,uint> map;
@ -104,20 +90,20 @@ static uint order(uint type)
return (it == orderMap.constEnd()) ? (type>>16) + 512 : it.value(); 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;
frid.subfield(RCID, &rcid); FRID.subfield("RCID", &RCID);
switch (prim) { switch (PRIM) {
case PRIM_P: case PRIM_P:
qWarning("%u: invalid point feature", rcid); qWarning("%u: invalid point feature", RCID);
break; break;
case PRIM_L: case PRIM_L:
qWarning("%u: invalid line feature", rcid); qWarning("%u: invalid line feature", RCID);
break; break;
case PRIM_A: case PRIM_A:
qWarning("%u: invalid area feature", rcid); qWarning("%u: invalid area feature", RCID);
break; break;
} }
} }
@ -146,7 +132,7 @@ static bool parseNAME(const ISO8211::Field *f, quint8 *type, quint32 *id,
return false; return false;
*type = (quint8)(*ba.constData()); *type = (quint8)(*ba.constData());
*id = qFromLittleEndian<quint32>(ba.constData() + 1); *id = UINT32(ba.constData() + 1);
return true; return true;
} }
@ -155,9 +141,9 @@ static const ISO8211::Field *SGXD(const ISO8211::Record &r)
{ {
const ISO8211::Field *f; const ISO8211::Field *f;
if ((f = ISO8211::field(r, SG2D))) if ((f = ISO8211::field(r, "SG2D")))
return f; return f;
else if ((f = ISO8211::field(r, SG3D))) else if ((f = ISO8211::field(r, "SG3D")))
return f; return f;
else else
return 0; return 0;
@ -187,51 +173,29 @@ static bool polygonCb(const MapData::Poly *polygon, void *context)
static bool polygonPointCb(const MapData::Poly *polygon, void *context) static bool polygonPointCb(const MapData::Poly *polygon, void *context)
{ {
QList<MapData::Point> *points = (QList<MapData::Point>*)context; QList<MapData::Point> *points = (QList<MapData::Point>*)context;
uint type = polygon->type(); uint baseType = polygon->type()>>16;
uint baseType = type>>16;
if (baseType == TSSLPT || baseType == RCTLPT || baseType == I_TRNBSN if (!polygon->label().isEmpty() || baseType == TSSLPT || baseType == RCTLPT
|| baseType == BRIDGE || baseType == I_BRIDGE || baseType == BUAARE || baseType == I_TRNBSN
|| baseType == LNDARE || baseType == LNDRGN || polygon->type() == SUBTYPE(ACHARE, 2)
|| type == SUBTYPE(ACHARE, 2) || type == SUBTYPE(I_ACHARE, 2) || polygon->type() == SUBTYPE(ACHARE, 3)
|| type == SUBTYPE(ACHARE, 3) || type == SUBTYPE(I_ACHARE, 3) || polygon->type() == SUBTYPE(ACHARE, 9)
|| type == SUBTYPE(ACHARE, 9) || type == SUBTYPE(I_ACHARE, 9) || polygon->type() == SUBTYPE(I_ACHARE, 2)
|| type == SUBTYPE(I_BERTHS, 6) || polygon->type() == SUBTYPE(I_ACHARE, 3)
|| type == SUBTYPE(RESARE, 1) || type == SUBTYPE(I_RESARE, 1) || polygon->type() == SUBTYPE(I_ACHARE, 9)
|| type == SUBTYPE(RESARE, 2) || type == SUBTYPE(I_RESARE, 2) || polygon->type() == SUBTYPE(I_BERTHS, 6))
|| type == SUBTYPE(RESARE, 4) || type == SUBTYPE(I_RESARE, 4) points->append(MapData::Point(polygon->type(), polygon->bounds().center(),
|| type == SUBTYPE(RESARE, 5) || type == SUBTYPE(I_RESARE, 5) polygon->label(), polygon->param()));
|| type == SUBTYPE(RESARE, 6) || type == SUBTYPE(I_RESARE, 6)
|| type == SUBTYPE(RESARE, 7) || type == SUBTYPE(I_RESARE, 7)
|| type == SUBTYPE(RESARE, 9) || type == SUBTYPE(I_RESARE, 9)
|| type == SUBTYPE(RESARE, 12) || type == SUBTYPE(I_RESARE, 12)
|| type == SUBTYPE(RESARE, 17) || type == SUBTYPE(I_RESARE, 17)
|| type == SUBTYPE(RESARE, 22) || type == SUBTYPE(I_RESARE, 22)
|| type == SUBTYPE(RESARE, 23) || type == SUBTYPE(I_RESARE, 23))
points->append(MapData::Point(baseType, polygon->bounds().center(),
polygon->attributes(), polygon->HUNI(), true));
return true; return true;
} }
static bool linePointCb(const MapData::Line *line, void *context) static Coordinates coordinates(int x, int y, uint COMF)
{ {
QList<MapData::Point> *points = (QList<MapData::Point>*)context; return Coordinates(x / (double)COMF, y / (double)COMF);
uint baseType = line->type()>>16;
if (baseType == RDOCAL || baseType == I_RDOCAL)
points->append(MapData::Point(baseType, line->bounds().center(),
line->attributes(), 1));
return true;
} }
static Coordinates coordinates(int x, int y, uint comf) static Coordinates point(const ISO8211::Record &r, uint COMF)
{
return Coordinates(x / (double)comf, y / (double)comf);
}
static Coordinates point(const ISO8211::Record &r, uint comf)
{ {
const ISO8211::Field *f = SGXD(r); const ISO8211::Field *f = SGXD(r);
if (!f) if (!f)
@ -240,11 +204,13 @@ static Coordinates point(const ISO8211::Record &r, uint comf)
int y = f->data().at(0).at(0).toInt(); int y = f->data().at(0).at(0).toInt();
int x = f->data().at(0).at(1).toInt(); int x = f->data().at(0).at(1).toInt();
return coordinates(x, y, comf); return coordinates(x, y, COMF);
} }
static uint depthLevel(double minDepth) static uint depthLevel(const QByteArray &ba)
{ {
double minDepth = ba.isEmpty() ? -1 : ba.toDouble();
if (minDepth < 0) if (minDepth < 0)
return 0; return 0;
else if (minDepth < 2) else if (minDepth < 2)
@ -309,175 +275,72 @@ static QString weed(uint type)
} }
} }
static uint restrictionCategory(uint type, const MapData::Attributes &attr) MapData::Point::Point(uint type, const Coordinates &c, const QString &label,
const QVector<QByteArray> &params) : _type(type), _pos(c), _label(label)
{ {
uint catrea = attr.value(CATREA).toUInt(); _id = ((quint64)order(type))<<32 | (uint)qHash(c);
if (!catrea) { if (type>>16 == I_DISMAR && params.size()) {
uint restrn = attr.value( _label = hUnits((type>>8)&0xFF) + " " + QString::fromLatin1(params.at(0));
(type == RESARE) ? RESTRN : I_RESTRN).toUInt(); _type = SUBTYPE(I_DISMAR, type & 0xFF);
} else if ((type>>16 == I_RDOCAL || type>>16 == RDOCAL) && params.size() > 1) {
if (restrn == 1) if (!params.at(1).isEmpty())
return 2; _label = QString("VHF ") + QString::fromLatin1(params.at(1));
else if (restrn == 7) _param = QVariant(params.at(0).toDouble());
return 17; } else if (type>>16 == CURENT && params.size() > 1) {
else if (!params.at(1).isEmpty())
return 0; _label = QString::fromLatin1(params.at(1))
} else + QString::fromUtf8("\xE2\x80\x89kt");
return catrea; _param = QVariant(params.at(0).toDouble());
} } else if (type>>16 == I_SISTAT || type>>16 == SISTAT) {
MapData::Point::Point(uint type, const Coordinates &c, const QString &label)
: _type(SUBTYPE(type, 0)), _pos(c), _label(label), _polygon(false)
{
_id = ((quint64)order(_type))<<32 | (uint)qHash(c);
}
MapData::Point::Point(uint type, const Coordinates &c, const Attributes &attr,
uint HUNI, bool polygon) : _pos(c), _attr(attr), _polygon(polygon)
{
uint subtype = 0;
if (type == HRBFAC)
subtype = CATHAF;
else if (type == I_HRBFAC)
subtype = I_CATHAF;
else if (type == LNDMRK)
subtype = CATLMK;
else if (type == WRECKS)
subtype = CATWRK;
else if (type == MORFAC)
subtype = CATMOR;
else if (type == UWTROC)
subtype = WATLEV;
else if (type == BUAARE)
subtype = CATBUA;
else if (type == SMCFAC)
subtype = CATSCF;
else if (type == BUISGL)
subtype = FUNCTN;
else if (type == WATTUR)
subtype = CATWAT;
else if (type == RDOCAL)
subtype = TRAFIC;
else if (type == I_RDOCAL)
subtype = TRAFIC;
else if (type == SILTNK)
subtype = CATSIL;
else if (type == WEDKLP)
subtype = CATWED;
else if (type == LIGHTS)
subtype = CATLIT;
else if (type == I_DISMAR)
subtype = CATDIS;
else if (type == I_BERTHS)
subtype = I_CATBRT;
else if (type == ACHARE)
subtype = CATACH;
else if (type == I_ACHARE)
subtype = I_CATACH;
else if (type == MARKUL)
subtype = CATMFA;
QList<QByteArray> list(_attr.value(subtype).split(','));
std::sort(list.begin(), list.end());
_type = (type == RESARE || type == I_RESARE)
? SUBTYPE(type, restrictionCategory(type, _attr))
: SUBTYPE(type, list.first().toUInt());
_id = ((quint64)order(_type))<<32 | (uint)qHash(c);
_label = QString::fromLatin1(_attr.value(OBJNAM));
if (type == I_DISMAR) {
if (_attr.contains(I_WTWDIS) && _attr.contains(I_HUNITS))
_label = hUnits(_attr.value(I_HUNITS).toUInt()) + " "
+ QString::fromLatin1(_attr.value(I_WTWDIS));
} else if (type == I_RDOCAL || type == RDOCAL) {
QByteArray cc(_attr.value(COMCHA));
if (!cc.isEmpty())
_label = QString("VHF ") + QString::fromLatin1(cc);
} else if (type == CURENT) {
QByteArray cv(_attr.value(CURVEL));
if (!cv.isEmpty())
_label = QString::fromLatin1(cv) + QString::fromUtf8("\xE2\x80\x89kt");
} else if (type == SISTAT) {
if (_label.isEmpty() && _attr.contains(CATSIT))
_label = sistat(_attr.value(CATSIT).toUInt());
} else if (type == I_SISTAT) {
if (_label.isEmpty() && _attr.contains(I_CATSIT))
_label = sistat(_attr.value(I_CATSIT).toUInt());
} else if (type == WEDKLP) {
if (_label.isEmpty()) if (_label.isEmpty())
_label = weed(_type & 0xFF); _label = sistat(type & 0xFF);
} else if (type == LNDELV) { _type = TYPE(SISTAT);
} else if (type>>16 == WEDKLP) {
if (_label.isEmpty()) if (_label.isEmpty())
_label = QString::fromLatin1(_attr.value(ELEVAT)) _label = weed(type & 0xFF);
} else if (type>>16 == LNDELV && params.size()) {
if (_label.isEmpty())
_label = QString::fromLatin1(params.at(0))
+ QString::fromUtf8("\xE2\x80\x89m"); + QString::fromUtf8("\xE2\x80\x89m");
else else
_label += "\n(" + QString::fromLatin1(_attr.value(ELEVAT)) _label += "\n(" + QString::fromLatin1(params.at(0))
+ "\xE2\x80\x89m)"; + "\xE2\x80\x89m)";
} else if (type == BRIDGE || type == I_BRIDGE) { } else if ((type == TYPE(TSSLPT) || type == TYPE(RCTLPT)) && params.size())
double clr = _attr.value(VERCLR).toDouble(); _param = QVariant(params.at(0).toDouble());
}
MapData::Point::Point(uint type, const Coordinates &c, const QString &label,
const QVariant &param) : _type(type), _pos(c), _label(label), _param(param)
{
_id = ((quint64)order(type))<<32 | (uint)qHash(c);
}
MapData::Poly::Poly(uint type, const Polygon &path, const QString &label,
const QVector<QByteArray> &params, uint HUNI) : _type(type), _path(path)
{
if (type == TYPE(DEPARE) && params.size())
_type = SUBTYPE(DEPARE, depthLevel(params.at(0)));
else if ((type == TYPE(TSSLPT) || type == TYPE(RCTLPT)) && params.size())
_param = QVariant(params.at(0).toDouble());
else if ((type == TYPE(BRIDGE) || type == TYPE(I_BRIDGE))
&& params.size()) {
double clr = params.at(0).toDouble();
if (clr > 0) { if (clr > 0) {
_label = QString::fromUtf8("\xE2\x86\x95") + UNIT_SPACE _label = QString::fromUtf8("\xE2\x86\x95") + UNIT_SPACE
+ QString::number(clr) + UNIT_SPACE + hUnits(HUNI); + QString::number(clr) + UNIT_SPACE + hUnits(HUNI);
} }
} } else if (type>>16 == LNDARE || type>>16 == SEAARE || type>>16 == BERTHS
} || type>>16 == I_BERTHS || type>>16 == BUAARE)
_label = label;
MapData::Poly::Poly(uint type, const Polygon &path, const Attributes &attr,
uint HUNI) : _path(path), _attr(attr), _HUNI(HUNI)
{
uint subtype = 0;
if (type == ACHARE)
subtype = CATACH;
else if (type == I_ACHARE)
subtype = I_CATACH;
else if (type == HRBFAC)
subtype = CATHAF;
else if (type == MARKUL)
subtype = CATMFA;
else if (type == I_BERTHS)
subtype = I_CATBRT;
else if (type == M_COVR)
subtype = CATCOV;
switch (type) {
case DEPARE:
_type = SUBTYPE(type, depthLevel(_attr.value(DRVAL1).toDouble()));
break;
case RESARE:
case I_RESARE:
_type = SUBTYPE(type, restrictionCategory(type, attr));
break;
default:
_type = SUBTYPE(type, _attr.value(subtype).toUInt());
}
} }
MapData::Line::Line(uint type, const QVector<Coordinates> &path, MapData::Line::Line(uint type, const QVector<Coordinates> &path,
const Attributes &attr) : _path(path), _attr(attr) const QString &label, const QVector<QByteArray> &params)
: _type(type), _path(path), _label(label)
{ {
uint subtype = 0; if ((type == TYPE(DEPCNT) || type == TYPE(LNDELV)) && params.size())
_label = QString::fromLatin1(params.at(0));
if (type == RECTRC)
subtype = CATTRK;
else if (type == RCRTCL)
subtype = CATTRK;
else if (type == RDOCAL)
subtype = TRAFIC;
else if (type == I_RDOCAL)
subtype = TRAFIC;
_type = SUBTYPE(type, _attr.value(subtype).toUInt());
if (type == DEPCNT)
_label = QString::fromLatin1(_attr.value(VALDCO));
else if (type == LNDELV)
_label = QString::fromLatin1(_attr.value(ELEVAT));
else
_label = QString::fromLatin1(_attr.value(OBJNAM));
} }
RectC MapData::Line::bounds() const RectC MapData::Line::bounds() const
@ -491,10 +354,10 @@ RectC MapData::Line::bounds() const
} }
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)
{ {
QVector<Sounding> s; QVector<Sounding> s;
const ISO8211::Field *f = ISO8211::field(r, SG3D); const ISO8211::Field *f = ISO8211::field(r, "SG3D");
if (!f) if (!f)
return QVector<Sounding>(); return QVector<Sounding>();
@ -503,24 +366,24 @@ QVector<MapData::Sounding> MapData::soundings(const ISO8211::Record &r,
int y = f->data().at(i).at(0).toInt(); int y = f->data().at(i).at(0).toInt();
int x = f->data().at(i).at(1).toInt(); int x = f->data().at(i).at(1).toInt();
int z = f->data().at(i).at(2).toInt(); int z = f->data().at(i).at(2).toInt();
s.append(Sounding(coordinates(x, y, comf), z / (double)somf)); s.append(Sounding(coordinates(x, y, COMF), z / (double)SOMF));
} }
return s; return s;
} }
QVector<MapData::Sounding> MapData::soundingGeometry(const ISO8211::Record &r, QVector<MapData::Sounding> MapData::soundingGeometry(const ISO8211::Record &r,
const RecordMap &vi, const RecordMap &vc, uint comf, uint somf) const RecordMap &vi, const RecordMap &vc, uint COMF, uint SOMF)
{ {
quint8 type; quint8 type;
quint32 id; quint32 id;
RecordMapIterator it; RecordMapIterator it;
const ISO8211::Field *fspt = ISO8211::field(r, FSPT); const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
if (!fspt || fspt->data().at(0).size() != 4) if (!FSPT || FSPT->data().at(0).size() != 4)
return QVector<Sounding>(); return QVector<Sounding>();
if (!parseNAME(fspt, &type, &id)) if (!parseNAME(FSPT, &type, &id))
return QVector<Sounding>(); return QVector<Sounding>();
if (type == RCNM_VI) { if (type == RCNM_VI) {
@ -534,21 +397,21 @@ QVector<MapData::Sounding> MapData::soundingGeometry(const ISO8211::Record &r,
} else } else
return QVector<Sounding>(); return QVector<Sounding>();
return soundings(it.value(), comf, somf); return soundings(it.value(), COMF, SOMF);
} }
Coordinates MapData::pointGeometry(const ISO8211::Record &r, Coordinates MapData::pointGeometry(const ISO8211::Record &r,
const RecordMap &vi, const RecordMap &vc, uint comf) const RecordMap &vi, const RecordMap &vc, uint COMF)
{ {
quint8 type; quint8 type;
quint32 id; quint32 id;
RecordMapIterator it; RecordMapIterator it;
const ISO8211::Field *fspt = ISO8211::field(r, FSPT); const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
if (!fspt || fspt->data().at(0).size() != 4) if (!FSPT || FSPT->data().at(0).size() != 4)
return Coordinates(); return Coordinates();
if (!parseNAME(fspt, &type, &id)) if (!parseNAME(FSPT, &type, &id))
return Coordinates(); return Coordinates();
if (type == RCNM_VI) { if (type == RCNM_VI) {
@ -562,55 +425,55 @@ Coordinates MapData::pointGeometry(const ISO8211::Record &r,
} else } else
return Coordinates(); return Coordinates();
return point(it.value(), comf); return point(it.value(), COMF);
} }
QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r, QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r,
const RecordMap &vc, const RecordMap &ve, uint comf) const RecordMap &vc, const RecordMap &ve, uint COMF)
{ {
QVector<Coordinates> path; QVector<Coordinates> path;
Coordinates c[2]; Coordinates c[2];
uint ornt; uint ORNT;
quint8 type; quint8 type;
quint32 id; quint32 id;
const ISO8211::Field *fspt = ISO8211::field(r, FSPT); const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
if (!fspt || fspt->data().at(0).size() != 4) if (!FSPT || FSPT->data().at(0).size() != 4)
return QVector<Coordinates>(); return QVector<Coordinates>();
for (int i = 0; i < fspt->data().size(); i++) { for (int i = 0; i < FSPT->data().size(); i++) {
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();
RecordMapIterator it = ve.find(id); RecordMapIterator it = ve.find(id);
if (it == ve.constEnd()) if (it == ve.constEnd())
return QVector<Coordinates>(); return QVector<Coordinates>();
const ISO8211::Record &frid = it.value(); const ISO8211::Record &FRID = it.value();
const ISO8211::Field *vrpt = ISO8211::field(frid, VRPT); const ISO8211::Field *VRPT = ISO8211::field(FRID, "VRPT");
if (!vrpt || vrpt->data().size() != 2) if (!VRPT || VRPT->data().size() != 2)
return QVector<Coordinates>(); return QVector<Coordinates>();
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
if (!parseNAME(vrpt, &type, &id, j) || type != RCNM_VC) if (!parseNAME(VRPT, &type, &id, j) || type != RCNM_VC)
return QVector<Coordinates>(); return QVector<Coordinates>();
RecordMapIterator jt = vc.find(id); RecordMapIterator jt = vc.find(id);
if (jt == vc.constEnd()) if (jt == vc.constEnd())
return QVector<Coordinates>(); return QVector<Coordinates>();
c[j] = point(jt.value(), comf); c[j] = point(jt.value(), COMF);
if (c[j].isNull()) if (c[j].isNull())
return QVector<Coordinates>(); return QVector<Coordinates>();
} }
const ISO8211::Field *vertexes = SGXD(frid); const ISO8211::Field *vertexes = SGXD(FRID);
if (ornt == 2) { if (ORNT == 2) {
path.append(c[1]); path.append(c[1]);
if (vertexes) { if (vertexes) {
for (int j = vertexes->data().size() - 1; j >= 0; j--) { for (int j = vertexes->data().size() - 1; j >= 0; j--) {
const QVector<QVariant> &cv = vertexes->data().at(j); const QVector<QVariant> &cv = vertexes->data().at(j);
path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(), path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
comf)); COMF));
} }
} }
path.append(c[0]); path.append(c[0]);
@ -620,7 +483,7 @@ QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r,
for (int j = 0; j < vertexes->data().size(); j++) { for (int j = 0; j < vertexes->data().size(); j++) {
const QVector<QVariant> &cv = vertexes->data().at(j); const QVector<QVariant> &cv = vertexes->data().at(j);
path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(), path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
comf)); COMF));
} }
} }
path.append(c[1]); path.append(c[1]);
@ -631,26 +494,26 @@ QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r,
} }
Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc, Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
const RecordMap &ve, uint comf) const RecordMap &ve, uint COMF)
{ {
Polygon path; Polygon path;
QVector<Coordinates> v; QVector<Coordinates> v;
Coordinates c[2]; Coordinates c[2];
uint ornt, usag; uint ORNT, USAG;
quint8 type; quint8 type;
quint32 id; quint32 id;
const ISO8211::Field *fspt = ISO8211::field(r, FSPT); const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
if (!fspt || fspt->data().at(0).size() != 4) if (!FSPT || FSPT->data().at(0).size() != 4)
return Polygon(); return Polygon();
for (int i = 0; i < fspt->data().size(); i++) { for (int i = 0; i < FSPT->data().size(); i++) {
if (!parseNAME(fspt, &type, &id, i) || type != RCNM_VE) if (!parseNAME(FSPT, &type, &id, i) || type != RCNM_VE)
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();
if (usag == 2 && path.isEmpty()) { if (USAG == 2 && path.isEmpty()) {
path.append(v); path.append(v);
v.clear(); v.clear();
} }
@ -658,55 +521,55 @@ Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
RecordMapIterator it = ve.find(id); RecordMapIterator it = ve.find(id);
if (it == ve.constEnd()) if (it == ve.constEnd())
return Polygon(); return Polygon();
const ISO8211::Record &frid = it.value(); const ISO8211::Record &FRID = it.value();
const ISO8211::Field *vrpt = ISO8211::field(frid, VRPT); const ISO8211::Field *VRPT = ISO8211::field(FRID, "VRPT");
if (!vrpt || vrpt->data().size() != 2) if (!VRPT || VRPT->data().size() != 2)
return Polygon(); return Polygon();
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
if (!parseNAME(vrpt, &type, &id, j) || type != RCNM_VC) if (!parseNAME(VRPT, &type, &id, j) || type != RCNM_VC)
return Polygon(); return Polygon();
RecordMapIterator jt = vc.find(id); RecordMapIterator jt = vc.find(id);
if (jt == vc.constEnd()) if (jt == vc.constEnd())
return Polygon(); return Polygon();
c[j] = point(jt.value(), comf); c[j] = point(jt.value(), COMF);
if (c[j].isNull()) if (c[j].isNull())
return Polygon(); return Polygon();
} }
const ISO8211::Field *vertexes = SGXD(frid); const ISO8211::Field *vertexes = SGXD(FRID);
if (ornt == 2) { if (ORNT == 2) {
v.append(c[1]); v.append(c[1]);
if (usag == 3) if (USAG == 3)
v.append(Coordinates()); v.append(Coordinates());
if (vertexes) { if (vertexes) {
for (int j = vertexes->data().size() - 1; j >= 0; j--) { for (int j = vertexes->data().size() - 1; j >= 0; j--) {
const QVector<QVariant> &cv = vertexes->data().at(j); const QVector<QVariant> &cv = vertexes->data().at(j);
v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(), v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
comf)); COMF));
} }
} }
if (usag == 3) if (USAG == 3)
v.append(Coordinates()); v.append(Coordinates());
v.append(c[0]); v.append(c[0]);
} else { } else {
v.append(c[0]); v.append(c[0]);
if (usag == 3) if (USAG == 3)
v.append(Coordinates()); v.append(Coordinates());
if (vertexes) { if (vertexes) {
for (int j = 0; j < vertexes->data().size(); j++) { for (int j = 0; j < vertexes->data().size(); j++) {
const QVector<QVariant> &cv = vertexes->data().at(j); const QVector<QVariant> &cv = vertexes->data().at(j);
v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(), v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
comf)); COMF));
} }
} }
if (usag == 3) if (USAG == 3)
v.append(Coordinates()); v.append(Coordinates());
v.append(c[1]); v.append(c[1]);
} }
if (usag == 2 && v.first() == v.last()) { if (USAG == 2 && v.first() == v.last()) {
path.append(v); path.append(v);
v.clear(); v.clear();
} }
@ -718,86 +581,209 @@ Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
return path; return path;
} }
MapData::Attributes MapData::attributes(const ISO8211::Record &r) MapData::Attr MapData::pointAttr(const ISO8211::Record &r, uint OBJL)
{ {
Attributes attr; QString label;
QVector<QByteArray> params(2);
uint subtype = 0;
const ISO8211::Field *attf = ISO8211::field(r, ATTF); const ISO8211::Field *ATTF = ISO8211::field(r, "ATTF");
if (!(attf && attf->data().at(0).size() == 2)) if (!(ATTF && ATTF->data().at(0).size() == 2))
return attr; return Attr();
for (int i = 0; i < attf->data().size(); i++) { for (int i = 0; i < ATTF->data().size(); i++) {
const QVector<QVariant> &av = attf->data().at(i); const QVector<QVariant> &av = ATTF->data().at(i);
attr.insert(av.at(0).toUInt(), av.at(1).toByteArray()); uint key = av.at(0).toUInt();
if (key == OBJNAM)
label = QString::fromLatin1(av.at(1).toByteArray());
if ((OBJL == HRBFAC && key == CATHAF)
|| (OBJL == I_HRBFAC && key == I_CATHAF)
|| (OBJL == LNDMRK && key == CATLMK)
|| (OBJL == WRECKS && key == CATWRK)
|| (OBJL == MORFAC && key == CATMOR)
|| (OBJL == UWTROC && key == WATLEV)
|| (OBJL == BUAARE && key == CATBUA)
|| (OBJL == SMCFAC && key == CATSCF)
|| (OBJL == BUISGL && key == FUNCTN)
|| (OBJL == WATTUR && key == CATWAT)
|| (OBJL == SISTAT && key == CATSIT)
|| (OBJL == I_SISTAT && key == I_CATSIT)
|| (OBJL == RDOCAL && key == TRAFIC)
|| (OBJL == I_RDOCAL && key == TRAFIC)
|| (OBJL == SILTNK && key == CATSIL)
|| (OBJL == WEDKLP && key == CATWED))
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)
|| (OBJL == RDOCAL && key == ORIENT)
|| (OBJL == I_RDOCAL && key == ORIENT)
|| (OBJL == CURENT && key == ORIENT)
|| (OBJL == LNDELV && key == ELEVAT)
|| (OBJL == TSSLPT && key == ORIENT)
|| (OBJL == RCTLPT && key == ORIENT))
params[0] = av.at(1).toByteArray();
if ((OBJL == I_RDOCAL && key == COMCHA)
|| (OBJL == RDOCAL && key == COMCHA)
|| (OBJL == CURENT && key == CURVEL))
params[1] = av.at(1).toByteArray();
} }
return attr; return Attr(subtype, label, params);
}
MapData::Attr MapData::lineAttr(const ISO8211::Record &r, uint OBJL)
{
QString label;
QVector<QByteArray> params(1);
uint subtype = 0;
const ISO8211::Field *ATTF = ISO8211::field(r, "ATTF");
if (!(ATTF && ATTF->data().at(0).size() == 2))
return Attr();
for (int i = 0; i < ATTF->data().size(); i++) {
const QVector<QVariant> &av = ATTF->data().at(i);
uint key = av.at(0).toUInt();
if (key == OBJNAM)
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)
|| (OBJL == LNDELV && key == ELEVAT))
params[0] = av.at(1).toByteArray();
}
return Attr(subtype, label, params);
}
MapData::Attr MapData::polyAttr(const ISO8211::Record &r, uint OBJL)
{
QString label;
QVector<QByteArray> params(1);
uint subtype = 0;
const ISO8211::Field *ATTF = ISO8211::field(r, "ATTF");
if (!(ATTF && ATTF->data().at(0).size() == 2))
return Attr();
for (int i = 0; i < ATTF->data().size(); i++) {
const QVector<QVariant> &av = ATTF->data().at(i);
uint key = av.at(0).toUInt();
if (key == OBJNAM)
label = QString::fromLatin1(av.at(1).toByteArray());
if ((OBJL == RESARE && key == CATREA)
|| (OBJL == I_RESARE && key == CATREA)
|| (OBJL == ACHARE && key == CATACH)
|| (OBJL == I_ACHARE && key == I_CATACH)
|| (OBJL == HRBFAC && key == CATHAF)
|| (OBJL == MARKUL && key == CATMFA)
|| (OBJL == I_BERTHS && key == I_CATBRT))
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 == RCTLPT && key == ORIENT)
|| (OBJL == DEPARE && key == DRVAL1))
params[0] = av.at(1).toByteArray();
if ((OBJL == BRIDGE && key == VERCLR)
|| (OBJL == I_BRIDGE && key == VERCLR))
params[0] = av.at(1).toByteArray();
}
return Attr(subtype, label, params);
} }
MapData::Point *MapData::pointObject(const Sounding &s) MapData::Point *MapData::pointObject(const Sounding &s)
{ {
return new Point(SOUNDG, s.c, QString::number(s.depth)); return new Point(TYPE(SOUNDG), s.c, QString::number(s.depth),
QVector<QByteArray>());
} }
MapData::Point *MapData::pointObject(const ISO8211::Record &r, MapData::Point *MapData::pointObject(const ISO8211::Record &r,
const RecordMap &vi, const RecordMap &vc, uint comf, uint objl, uint huni) const RecordMap &vi, const RecordMap &vc, uint COMF, uint OBJL)
{ {
Coordinates c(pointGeometry(r, vi, vc, comf)); Coordinates c(pointGeometry(r, vi, vc, COMF));
return (c.isNull() ? 0 : new Point(objl, c, attributes(r), huni)); Attr attr(pointAttr(r, OBJL));
return (c.isNull() ? 0 : new Point(SUBTYPE(OBJL,attr.subtype()), c,
attr.label(), attr.params()));
} }
MapData::Line *MapData::lineObject(const ISO8211::Record &r, MapData::Line *MapData::lineObject(const ISO8211::Record &r,
const RecordMap &vc, const RecordMap &ve, uint comf, uint objl) const RecordMap &vc, const RecordMap &ve, uint COMF, uint OBJL)
{ {
QVector<Coordinates> path(lineGeometry(r, vc, ve, comf)); QVector<Coordinates> path(lineGeometry(r, vc, ve, COMF));
return (path.isEmpty() ? 0 : new Line(objl, path, attributes(r))); Attr attr(lineAttr(r, OBJL));
return (path.isEmpty() ? 0 : new Line(SUBTYPE(OBJL, attr.subtype()), path,
attr.label(), attr.params()));
} }
MapData::Poly *MapData::polyObject(const ISO8211::Record &r, MapData::Poly *MapData::polyObject(const ISO8211::Record &r,
const RecordMap &vc, const RecordMap &ve, uint comf, uint objl, uint huni) const RecordMap &vc, const RecordMap &ve, uint COMF, uint OBJL, uint HUNI)
{ {
Polygon path(polyGeometry(r, vc, ve, comf)); Polygon path(polyGeometry(r, vc, ve, COMF));
return (path.isEmpty() ? 0 : new Poly(objl, path, attributes(r), huni)); Attr attr(polyAttr(r, OBJL));
return (path.isEmpty() ? 0 : new Poly(SUBTYPE(OBJL, attr.subtype()), path,
attr.label(), attr.params(), HUNI));
} }
bool MapData::processRecord(const ISO8211::Record &record, bool MapData::processRecord(const ISO8211::Record &record,
QVector<ISO8211::Record> &fe, RecordMap &vi, RecordMap &vc, RecordMap &ve, QVector<ISO8211::Record> &fe, RecordMap &vi, RecordMap &vc, RecordMap &ve,
RecordMap &vf, uint &comf, uint &somf, uint &huni) RecordMap &vf, uint &COMF, uint &SOMF, uint &HUNI)
{ {
if (record.size() < 2) if (record.size() < 2)
return false; return false;
const ISO8211::Field &f = record.at(1); const ISO8211::Field &f = record.at(1);
quint32 tag = f.tag(); const QByteArray &ba = f.tag();
if (tag == VRID) { if (ba == "VRID") {
if (f.data().at(0).size() < 2) if (f.data().at(0).size() < 2)
return false; return false;
int rcnm = f.data().at(0).at(0).toInt(); int RCNM = f.data().at(0).at(0).toInt();
uint rcid = f.data().at(0).at(1).toUInt(); uint RCID = f.data().at(0).at(1).toUInt();
switch (rcnm) { switch (RCNM) {
case RCNM_VI: case RCNM_VI:
vi.insert(rcid, record); vi.insert(RCID, record);
break; break;
case RCNM_VC: case RCNM_VC:
vc.insert(rcid, record); vc.insert(RCID, record);
break; break;
case RCNM_VE: case RCNM_VE:
ve.insert(rcid, record); ve.insert(RCID, record);
break; break;
case RCNM_VF: case RCNM_VF:
vf.insert(rcid, record); vf.insert(RCID, record);
break; break;
default: default:
return false; return false;
} }
} else if (tag == FRID) { } else if (ba == "FRID") {
fe.append(record); fe.append(record);
} else if (tag == DSPM) { } else if (ba == "DSPM") {
if (!(f.subfield(COMF, &comf) && f.subfield(SOMF, &somf))) if (!(f.subfield("COMF", &COMF) && f.subfield("SOMF", &SOMF)))
return false; return false;
if (!f.subfield(HUNI, &huni)) if (!f.subfield("HUNI", &HUNI))
return false; return false;
} }
@ -810,7 +796,7 @@ MapData::MapData(const QString &path)
QVector<ISO8211::Record> fe; QVector<ISO8211::Record> fe;
ISO8211 ddf(path); ISO8211 ddf(path);
ISO8211::Record record; ISO8211::Record record;
uint prim, objl, comf = 1, somf = 1, huni = 1; uint PRIM, OBJL, COMF = 1, SOMF = 1, HUNI = 1;
Poly *poly; Poly *poly;
Line *line; Line *line;
Point *point; Point *point;
@ -820,7 +806,7 @@ MapData::MapData(const QString &path)
if (!ddf.readDDR()) if (!ddf.readDDR())
return; return;
while (ddf.readRecord(record)) while (ddf.readRecord(record))
if (!processRecord(record, fe, vi, vc, ve, vf, comf, somf, huni)) if (!processRecord(record, fe, vi, vc, ve, vf, COMF, SOMF, HUNI))
qWarning("Invalid S-57 record"); qWarning("Invalid S-57 record");
for (int i = 0; i < fe.size(); i++) { for (int i = 0; i < fe.size(); i++) {
@ -829,39 +815,39 @@ MapData::MapData(const QString &path)
if (f.data().at(0).size() < 5) if (f.data().at(0).size() < 5)
continue; continue;
prim = f.data().at(0).at(2).toUInt(); PRIM = f.data().at(0).at(2).toUInt();
objl = f.data().at(0).at(4).toUInt(); OBJL = f.data().at(0).at(4).toUInt();
switch (prim) { switch (PRIM) {
case PRIM_P: case PRIM_P:
if (objl == SOUNDG) { if (OBJL == SOUNDG) {
QVector<Sounding> s(soundingGeometry(r, vi, vc, comf, somf)); QVector<Sounding> s(soundingGeometry(r, vi, vc, COMF, SOMF));
for (int i = 0; i < s.size(); i++) { for (int i = 0; i < s.size(); i++) {
point = pointObject(s.at(i)); point = pointObject(s.at(i));
pointBounds(point->pos(), min, max); pointBounds(point->pos(), min, max);
_points.Insert(min, max, point); _points.Insert(min, max, point);
} }
} else { } else {
if ((point = pointObject(r, vi, vc, comf, objl, huni))) { if ((point = pointObject(r, vi, vc, COMF, OBJL))) {
pointBounds(point->pos(), min, max); pointBounds(point->pos(), min, max);
_points.Insert(min, max, point); _points.Insert(min, max, point);
} else } else
warning(f, prim); warning(f, PRIM);
} }
break; break;
case PRIM_L: case PRIM_L:
if ((line = lineObject(r, vc, ve, comf, objl))) { if ((line = lineObject(r, vc, ve, COMF, OBJL))) {
rectcBounds(line->bounds(), min, max); rectcBounds(line->bounds(), min, max);
_lines.Insert(min, max, line); _lines.Insert(min, max, line);
} else } else
warning(f, prim); warning(f, PRIM);
break; break;
case PRIM_A: case PRIM_A:
if ((poly = polyObject(r, vc, ve, comf, objl, huni))) { if ((poly = polyObject(r, vc, ve, COMF, OBJL, HUNI))) {
rectcBounds(poly->bounds(), min, max); rectcBounds(poly->bounds(), min, max);
_areas.Insert(min, max, poly); _areas.Insert(min, max, poly);
} else } else
warning(f, prim); warning(f, PRIM);
break; break;
} }
} }
@ -882,22 +868,27 @@ MapData::~MapData()
delete _points.GetAt(pit); delete _points.GetAt(pit);
} }
void MapData::points(const RectC &rect, QList<Point> *points) void MapData::points(const RectC &rect, QList<Point> *points) const
{ {
double min[2], max[2]; double min[2], max[2];
rectcBounds(rect, min, max); rectcBounds(rect, min, max);
_points.Search(min, max, pointCb, points); _points.Search(min, max, pointCb, points);
_areas.Search(min, max, polygonPointCb, points); _areas.Search(min, max, polygonPointCb, points);
_lines.Search(min, max, linePointCb, points);
} }
void MapData::polys(const RectC &rect, QList<Poly> *polygons, void MapData::lines(const RectC &rect, QList<Line> *lines) const
QList<Line> *lines)
{ {
double min[2], max[2]; double min[2], max[2];
rectcBounds(rect, min, max); rectcBounds(rect, min, max);
_lines.Search(min, max, lineCb, lines); _lines.Search(min, max, lineCb, lines);
}
void MapData::polygons(const RectC &rect, QList<Poly> *polygons) const
{
double min[2], max[2];
rectcBounds(rect, min, max);
_areas.Search(min, max, polygonCb, polygons); _areas.Search(min, max, polygonCb, polygons);
} }

View File

@ -1,23 +1,98 @@
#ifndef ENC_MAPDATA_H #ifndef ENC_MAPDATA_H
#define ENC_MAPDATA_H #define ENC_MAPDATA_H
#include "common/rectc.h"
#include "common/rtree.h" #include "common/rtree.h"
#include "common/polygon.h"
#include "iso8211.h" #include "iso8211.h"
#include "data.h"
namespace ENC { namespace ENC {
class MapData : public Data class MapData
{ {
public: public:
MapData(const QString &path); class Poly {
virtual ~MapData(); public:
Poly(uint type, const Polygon &path, const QString &label,
const QVector<QByteArray> &params, uint HUNI);
virtual void polys(const RectC &rect, QList<Poly> *polygons, RectC bounds() const {return _path.boundingRect();}
QList<Line> *lines); const Polygon &path() const {return _path;}
virtual void points(const RectC &rect, QList<Point> *points); uint type() const {return _type;}
const QString &label() const {return _label;}
const QVariant &param() const {return _param;}
private:
uint _type;
Polygon _path;
QString _label;
QVariant _param;
};
class Line {
public:
Line(uint type, const QVector<Coordinates> &path, const QString &label,
const QVector<QByteArray> &params);
RectC bounds() const;
const QVector<Coordinates> &path() const {return _path;}
uint type() const {return _type;}
const QString &label() const {return _label;}
private:
uint _type;
QVector<Coordinates> _path;
QString _label;
};
class Point {
public:
Point(uint type, const Coordinates &c, const QString &label,
const QVector<QByteArray> &params);
Point(uint type, const Coordinates &c, const QString &label,
const QVariant &param);
const Coordinates &pos() const {return _pos;}
uint type() const {return _type;}
const QString &label() const {return _label;}
const QVariant &param() const {return _param;}
bool operator<(const Point &other) const
{return _id < other._id;}
private:
uint _type;
Coordinates _pos;
QString _label;
quint64 _id;
QVariant _param;
};
MapData(const QString &path);
~MapData();
void polygons(const RectC &rect, QList<Poly> *polygons) const;
void lines(const RectC &rect, QList<Line> *lines) const;
void points(const RectC &rect, QList<Point> *points) const;
private: private:
class Attr {
public:
Attr() : _subtype(0) {}
Attr(uint subtype, const QString &label,
const QVector<QByteArray> &params)
: _subtype(subtype), _label(label), _params(params) {}
unsigned subtype() const {return _subtype;}
const QString &label() const {return _label;}
const QVector<QByteArray> &params() const {return _params;}
private:
unsigned _subtype;
QString _label;
QVector<QByteArray> _params;
};
struct Sounding { struct Sounding {
Sounding() : depth(NAN) {} Sounding() : depth(NAN) {}
Sounding(const Coordinates &c, double depth) : c(c), depth(depth) {} Sounding(const Coordinates &c, double depth) : c(c), depth(depth) {}
@ -32,28 +107,30 @@ private:
typedef RTree<const Line*, double, 2> LineTree; typedef RTree<const Line*, double, 2> LineTree;
typedef RTree<const Point*, double, 2> PointTree; typedef RTree<const Point*, double, 2> PointTree;
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,
const RecordMap &vi, const RecordMap &vc, uint comf, uint somf); const RecordMap &vi, const RecordMap &vc, uint COMF, uint SOMF);
static Coordinates pointGeometry(const ISO8211::Record &r, static Coordinates pointGeometry(const ISO8211::Record &r,
const RecordMap &vi, const RecordMap &vc, uint comf); const RecordMap &vi, const RecordMap &vc, uint COMF);
static QVector<Coordinates> lineGeometry(const ISO8211::Record &r, static QVector<Coordinates> lineGeometry(const ISO8211::Record &r,
const RecordMap &vc, const RecordMap &ve, uint comf); const RecordMap &vc, const RecordMap &ve, uint COMF);
static Polygon polyGeometry(const ISO8211::Record &r, const RecordMap &vc, static Polygon polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
const RecordMap &ve, uint comf); const RecordMap &ve, uint COMF);
static Attributes attributes(const ISO8211::Record &r); static Attr pointAttr(const ISO8211::Record &r, uint OBJL);
static Attr lineAttr(const ISO8211::Record &r, uint OBJL);
static Attr polyAttr(const ISO8211::Record &r, uint OBJL);
static Point *pointObject(const Sounding &s); static Point *pointObject(const Sounding &s);
static Point *pointObject(const ISO8211::Record &r, const RecordMap &vi, static Point *pointObject(const ISO8211::Record &r, const RecordMap &vi,
const RecordMap &vc, uint comf, uint objl, uint huni); const RecordMap &vc, uint COMF, uint OBJL);
static Line *lineObject(const ISO8211::Record &r, const RecordMap &vc, static Line *lineObject(const ISO8211::Record &r, const RecordMap &vc,
const RecordMap &ve, uint comf, uint objl); const RecordMap &ve, uint COMF, uint OBJL);
static Poly *polyObject(const ISO8211::Record &r, const RecordMap &vc, static Poly *polyObject(const ISO8211::Record &r, const RecordMap &vc,
const RecordMap &ve, uint comf, uint objl, uint huni); const RecordMap &ve, uint COMF, uint OBJL, uint HUNI);
static bool processRecord(const ISO8211::Record &record, static bool processRecord(const ISO8211::Record &record,
QVector<ISO8211::Record> &fe, RecordMap &vi, RecordMap &vc, RecordMap &ve, QVector<ISO8211::Record> &fe, RecordMap &vi, RecordMap &vc, RecordMap &ve,
RecordMap &vf, uint &comf, uint &somf, uint &huni); RecordMap &vf, uint &COMF, uint &SOMF, uint &HUNI);
PolygonTree _areas; PolygonTree _areas;
LineTree _lines; LineTree _lines;

Some files were not shown because too many files have changed in this diff Show More