Compare commits
No commits in common. "master" and "13.34" have entirely different histories.
@ -1,4 +1,4 @@
|
||||
version: 13.39.{build}
|
||||
version: 13.34.{build}
|
||||
|
||||
configuration:
|
||||
- Release
|
||||
@ -8,7 +8,6 @@ image:
|
||||
|
||||
environment:
|
||||
NSISDIR: C:\Program Files (x86)\NSIS
|
||||
JOMDIR: C:\Qt\Tools\QtCreator\bin\jom
|
||||
matrix:
|
||||
- QTDIR: C:\Qt\5.15\msvc2019_64
|
||||
OPENSSLDIR: C:\OpenSSL-v111-Win64\bin
|
||||
@ -18,14 +17,14 @@ environment:
|
||||
|
||||
install:
|
||||
- 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
|
||||
|
||||
build_script:
|
||||
- cmd: |-
|
||||
lrelease gpxsee.pro
|
||||
qmake gpxsee.pro
|
||||
jom release
|
||||
nmake release
|
||||
|
||||
md installer
|
||||
copy release\GPXSee.exe installer
|
||||
|
2
.github/workflows/android.yml
vendored
@ -43,7 +43,7 @@ jobs:
|
||||
- name: Configure build
|
||||
run: qmake gpxsee.pro OPENSSL_PATH=android_openssl
|
||||
- name: Build project
|
||||
run: make -j4 apk
|
||||
run: make -j2 apk
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
9
.github/workflows/linux.yml
vendored
@ -8,10 +8,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
name: GPXSee
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
config: ['release', 'debug']
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@ -22,6 +19,6 @@ jobs:
|
||||
- name: Create localization
|
||||
run: lrelease gpxsee.pro
|
||||
- name: Configure build
|
||||
run: qmake CONFIG+=${{ matrix.config }} gpxsee.pro
|
||||
run: qmake gpxsee.pro
|
||||
- name: Build project
|
||||
run: make -j4
|
||||
run: make -j2
|
||||
|
2
.github/workflows/osx.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: '6.8.2'
|
||||
version: '6.8.1'
|
||||
modules: qtpositioning qtserialport qtimageformats
|
||||
- name: Create localization
|
||||
run: lrelease gpxsee.pro
|
||||
|
@ -5,9 +5,7 @@ GPS log file formats.
|
||||
## Features
|
||||
* 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,
|
||||
TwoNav (TRK, RTE, WPT), GPSDump WPT, Velocitek VTK, Vakaros VKX, 70mai GPS logs
|
||||
and geotagged JPEG files.
|
||||
* Opens geo URIs (RFC 5870).
|
||||
TwoNav (TRK, RTE, WPT), GPSDump WPT and geotagged JPEG files.
|
||||
* User-definable online maps (OpenStreetMap/Google tiles, WMTS, WMS, TMS,
|
||||
QuadTiles).
|
||||
* Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases,
|
||||
@ -30,8 +28,8 @@ GPS log file formats.
|
||||
|
||||
## Build
|
||||
Build requirements:
|
||||
* Qt5 >= 5.15 or Qt6 >= 6.2 (Android builds require Qt6)
|
||||
* C++11 or newer compiler (tested: msvc2022, gcc 11, clang/Apple LLVM version
|
||||
* Qt5 >= 5.11 or Qt6 >= 6.2 (Android builds require Qt6)
|
||||
* C++11 or newer compiler (tested: msvc2019, gcc 7.5.0, clang/Apple LLVM version
|
||||
10.0.0)
|
||||
|
||||
Build steps:
|
||||
|
@ -214,11 +214,10 @@
|
||||
</rule>
|
||||
|
||||
<!-- 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"/>
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="building" v="civic|office">
|
||||
<rule e="way" k="building" v="civic">
|
||||
<area fill="#cfc4b3" stroke="#cdccc4" stroke-width="0.1"/>
|
||||
<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"/>
|
||||
@ -404,7 +403,7 @@
|
||||
<rule e="way" k="*" v="*" zoom-min="14">
|
||||
<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">
|
||||
<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>
|
||||
@ -429,12 +428,6 @@
|
||||
<line stroke="#f7d9a6" stroke-width="1" stroke-linecap="butt"/>
|
||||
</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 e="way" k="highway" v="motorway|motorway_link">
|
||||
<rule e="way" k="tunnel" v="~|false|no">
|
||||
|
15
gpxsee.pro
@ -3,7 +3,8 @@ unix:!macx:!android {
|
||||
} else {
|
||||
TARGET = GPXSee
|
||||
}
|
||||
VERSION = 13.39
|
||||
VERSION = 13.34
|
||||
|
||||
|
||||
QT += core \
|
||||
gui \
|
||||
@ -117,11 +118,6 @@ HEADERS += src/common/config.h \
|
||||
src/data/gpsdumpparser.h \
|
||||
src/data/style.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/demloader.h \
|
||||
src/map/ENC/attributes.h \
|
||||
@ -347,9 +343,6 @@ SOURCES += src/main.cpp \
|
||||
src/GUI/pngexportdialog.cpp \
|
||||
src/GUI/projectioncombobox.cpp \
|
||||
src/GUI/passwordedit.cpp \
|
||||
src/data/txtparser.cpp \
|
||||
src/data/vkxparser.cpp \
|
||||
src/data/vtkparser.cpp \
|
||||
src/map/downloader.cpp \
|
||||
src/map/demloader.cpp \
|
||||
src/map/ENC/atlasdata.cpp \
|
||||
@ -565,9 +558,7 @@ win32 {
|
||||
icons/formats/trk.ico \
|
||||
icons/formats/gemf.ico \
|
||||
icons/formats/000.ico \
|
||||
icons/formats/031.ico \
|
||||
icons/formats/vtk.ico \
|
||||
icons/formats/vkx.ico
|
||||
icons/formats/031.ico
|
||||
DEFINES += _USE_MATH_DEFINES \
|
||||
NOGDI
|
||||
}
|
||||
|
@ -193,10 +193,6 @@
|
||||
<file alias="overfalls.png">icons/map/marine/overfalls.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-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="fog-signal.png">icons/map/marine/fog-signal.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="dw-anchorage.png">icons/map/marine/dw-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>
|
||||
|
||||
<!-- Patterns (Mapsforge) -->
|
||||
|
@ -32,5 +32,3 @@ trk:#cccccc
|
||||
gemf:#147085
|
||||
000:#000000
|
||||
031:#000000
|
||||
vtk:#632433
|
||||
vkx:#00ccff
|
||||
|
Before Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 331 KiB |
Before Width: | Height: | Size: 286 B After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 294 B After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 202 B After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 215 B After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 393 B After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 190 B After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 189 B After Width: | Height: | Size: 259 B |
Before Width: | Height: | Size: 269 B |
Before Width: | Height: | Size: 382 B After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 238 B After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 220 B After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 466 B |
Before Width: | Height: | Size: 417 B |
Before Width: | Height: | Size: 330 B |
Before Width: | Height: | Size: 330 B |
Before Width: | Height: | Size: 401 B After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 286 B After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 261 B After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 217 B |
Before Width: | Height: | Size: 212 B After Width: | Height: | Size: 139 B |
Before Width: | Height: | Size: 127 B |
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 239 B After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 275 B After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 266 B After Width: | Height: | Size: 4.3 KiB |
@ -21,12 +21,6 @@
|
||||
<data android:scheme="content" android:mimeType="image/jpeg"/>
|
||||
<data android:scheme="content" android:mimeType="image/tiff"/>
|
||||
</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.arguments" android:value="-- %%INSERT_APP_ARGUMENTS%% --"/>
|
||||
|
@ -15,9 +15,8 @@
|
||||
<li>Opens GPX, TCX, FIT, KML, IGC, NMEA, SIGMA SLF, Suunto SML, LOC,
|
||||
OziExplorer (PLT, WPT, RTE), GeoJSON, SeeYou CUP,
|
||||
Garmin GPI & CSV, TomTom OV2 & ITN, ONmove OMD/GHP,
|
||||
TwoNav (TRK, RTE, WPT), GPSDump WPT, Velocitek VTK,
|
||||
Vakaros VKX, 70mai GPS logs and geotagged JPEG files.</li>
|
||||
<li>Opens geo URIs (RFC 5870).</li>
|
||||
TwoNav (TRK, RTE, WPT), GPSDump WPT and geotagged JPEG
|
||||
files.</li>
|
||||
<li>User-definable online maps (OpenStreetMap/Google tiles, WMTS,
|
||||
WMS, TMS, QuadTiles).</li>
|
||||
<li>Offline maps (MBTiles, OziExplorer maps, TrekBuddy maps/atlases,
|
||||
@ -113,9 +112,5 @@
|
||||
<mimetype>application/vnd.iho.s57-catalogue</mimetype>
|
||||
<mimetype>application/vnd.gpsdump.wpt</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>
|
||||
</component>
|
||||
|
@ -11,9 +11,9 @@ Comment[ru]=Программа для просмотра и анализа GPS
|
||||
Comment[sv]=GPS-loggfilsläsare och analysator
|
||||
Comment[tr]=GPS günlük dosyası görüntüleyici ve analizcisi
|
||||
Comment[uk]=Переглядач та аналізатор GPS логів
|
||||
Exec=gpxsee %U
|
||||
Exec=gpxsee %F
|
||||
Icon=gpxsee
|
||||
Terminal=false
|
||||
Type=Application
|
||||
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
|
||||
|
@ -188,33 +188,6 @@
|
||||
<glob pattern="*.wpt"/>
|
||||
</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 -->
|
||||
|
||||
<mime-type type="application/vnd.garmin.img">
|
||||
|
@ -736,66 +736,6 @@
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
</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>
|
||||
|
||||
<key>UTImportedTypeDeclarations</key>
|
||||
@ -1729,8 +1669,6 @@
|
||||
<string>https://iho.int/uploads/user/pubs/standards/s-57/31Main.pdf</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>IHO S-57 Electronic Navigation Chart</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>icons/000.icns</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
@ -1752,8 +1690,6 @@
|
||||
<string>https://iho.int/uploads/user/pubs/standards/s-57/20ApB1.pdf</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>IHO S-57 Electronic Navigation Catalogue</string>
|
||||
<key>UTTypeIconFile</key>
|
||||
<string>icons/031.icns</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
@ -1768,73 +1704,6 @@
|
||||
<string>application/vnd.iho.s57-catalogue</string>
|
||||
</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>
|
||||
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
|
@ -18,18 +18,6 @@
|
||||
DeleteRegKey HKCR ".${EXT}"
|
||||
!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
|
||||
!macro LOCALIZATION LANG CODE
|
||||
Section "${LANG}"
|
||||
@ -49,7 +37,7 @@ Unicode true
|
||||
; The name of the installer
|
||||
Name "GPXSee"
|
||||
; Program version
|
||||
!define VERSION "13.39"
|
||||
!define VERSION "13.34"
|
||||
|
||||
; The file to write
|
||||
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 "000" "IHO S-57 Electronic Navigation Chart" 27
|
||||
!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 "vkx" "Vakaros VKX File" 30
|
||||
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 31
|
||||
!insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 31
|
||||
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 32
|
||||
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 33
|
||||
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 34
|
||||
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 35
|
||||
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 36
|
||||
|
||||
!insertmacro URI_ASSOCIATION_ADD "geo"
|
||||
!insertmacro FILE_ASSOCIATION_ADD "kml" "Keyhole Markup Language" 29
|
||||
!insertmacro FILE_ASSOCIATION_ADD "kmz" "KML geographic compressed data" 29
|
||||
!insertmacro FILE_ASSOCIATION_ADD "fit" "Flexible and Interoperable Data Transfer" 30
|
||||
!insertmacro FILE_ASSOCIATION_ADD "igc" "Flight Recorder Data Format" 31
|
||||
!insertmacro FILE_ASSOCIATION_ADD "nmea" "NMEA 0183 Data" 32
|
||||
!insertmacro FILE_ASSOCIATION_ADD "plt" "OziExplorer Track File" 33
|
||||
!insertmacro FILE_ASSOCIATION_ADD "rte" "OziExplorer Route File" 34
|
||||
|
||||
WriteRegStr HKCR "Applications\GPXSee.exe\shell\open\command" "" "$\"$INSTDIR\GPXSee.exe$\" $\"%1$\""
|
||||
WriteRegStr HKCR ".gpx\OpenWithList" "GPXSee.exe" ""
|
||||
@ -267,9 +251,6 @@ Section "GPXSee" SEC_APP
|
||||
WriteRegStr HKCR ".gemf\OpenWithList" "GPXSee.exe" ""
|
||||
WriteRegStr HKCR ".000\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)'
|
||||
|
||||
@ -444,10 +425,6 @@ Section "Uninstall"
|
||||
!insertmacro FILE_ASSOCIATION_REMOVE "gemf"
|
||||
!insertmacro FILE_ASSOCIATION_REMOVE "000"
|
||||
!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 ".tcx\OpenWithList" "GPXSee.exe"
|
||||
@ -499,9 +476,6 @@ Section "Uninstall"
|
||||
DeleteRegValue HKCR ".gemf\OpenWithList" "GPXSee.exe"
|
||||
DeleteRegValue HKCR ".000\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"
|
||||
|
||||
System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'
|
||||
|
@ -73,7 +73,9 @@ App::App(int &argc, char **argv) : QApplication(argc, argv)
|
||||
#if defined(Q_OS_WIN32) || defined(Q_OS_MAC)
|
||||
QIcon::setThemeName(APP_NAME);
|
||||
#endif // Q_OS_WIN32 || Q_OS_MAC
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
|
||||
QIcon::setFallbackThemeName(APP_NAME);
|
||||
#endif // QT 5.12
|
||||
|
||||
_gui = new GUI();
|
||||
|
||||
|
@ -25,6 +25,15 @@
|
||||
#define IW(item) ((item)->boundingRect().width())
|
||||
#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)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
@ -384,7 +393,7 @@ void GraphView::wheelEvent(QWheelEvent *e)
|
||||
return;
|
||||
_angleDelta = _angleDelta % (15 * 8);
|
||||
|
||||
QPointF pos = mapToScene(e->position().toPoint());
|
||||
QPointF pos = mapToScene(POS(e));
|
||||
QRectF gr(_grid->boundingRect());
|
||||
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(),
|
||||
r.y() * ngr.height())));
|
||||
QScrollBar *sb = horizontalScrollBar();
|
||||
sb->setSliderPosition(sb->sliderPosition() + npos.x()
|
||||
- e->position().toPoint().x());
|
||||
sb->setSliderPosition(sb->sliderPosition() + npos.x() - POS(e).x());
|
||||
|
||||
QGraphicsView::wheelEvent(e);
|
||||
}
|
||||
|
@ -1069,33 +1069,18 @@ void GUI::openDir()
|
||||
|
||||
bool GUI::openFile(const QString &fileName, bool tryUnknown, int &showError)
|
||||
{
|
||||
QString path;
|
||||
QFileInfo fi(fileName);
|
||||
QString canonicalFileName(fi.canonicalFilePath());
|
||||
|
||||
QUrl url(fileName);
|
||||
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))
|
||||
if (_files.contains(canonicalFileName))
|
||||
return true;
|
||||
|
||||
if (!loadFile(path, tryUnknown, showError))
|
||||
if (!loadFile(fileName, tryUnknown, showError))
|
||||
return false;
|
||||
|
||||
_files.append(canonicalPath);
|
||||
_files.append(canonicalFileName);
|
||||
#ifndef Q_OS_ANDROID
|
||||
_browser->setCurrent(path);
|
||||
_browser->setCurrent(fileName);
|
||||
#endif // Q_OS_ANDROID
|
||||
_fileActionGroup->setEnabled(true);
|
||||
// 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)
|
||||
_mapView->showExtendedInfo(true);
|
||||
#ifndef Q_OS_ANDROID
|
||||
updateRecentFiles(canonicalPath);
|
||||
updateRecentFiles(canonicalFileName);
|
||||
#endif // Q_OS_ANDROID
|
||||
|
||||
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)
|
||||
{
|
||||
Data data(fileName, tryUnknown);
|
||||
@ -1193,12 +1148,10 @@ void GUI::loadData(const Data &data)
|
||||
_time += track.time();
|
||||
_movingTime += track.movingTime();
|
||||
const QDateTime date = track.date().toTimeZone(_options.timeZone.zone());
|
||||
if (date.isValid()) {
|
||||
if (_dateRange.first.isNull() || _dateRange.first > date)
|
||||
_dateRange.first = date;
|
||||
if (_dateRange.second.isNull() || _dateRange.second < date)
|
||||
_dateRange.second = date;
|
||||
}
|
||||
if (_dateRange.first.isNull() || _dateRange.first > date)
|
||||
_dateRange.first = date;
|
||||
if (_dateRange.second.isNull() || _dateRange.second < date)
|
||||
_dateRange.second = date;
|
||||
}
|
||||
_trackCount += data.tracks().count();
|
||||
|
||||
@ -1897,13 +1850,7 @@ bool GUI::loadMapNode(const TreeNode<Map*> &node, MapAction *&action,
|
||||
|
||||
bool GUI::loadMap(const QString &fileName, MapAction *&action, int &showError)
|
||||
{
|
||||
QString path;
|
||||
QUrl url(fileName);
|
||||
|
||||
path = url.isLocalFile() ? url.toLocalFile() : fileName;
|
||||
|
||||
|
||||
TreeNode<Map*> maps(MapList::loadMaps(path, _mapView->inputProjection()));
|
||||
TreeNode<Map*> maps(MapList::loadMaps(fileName, _mapView->inputProjection()));
|
||||
QList<QAction*> existingActions(_mapsActionGroup->actions());
|
||||
|
||||
return loadMapNode(maps, action, existingActions, showError);
|
||||
@ -2500,8 +2447,12 @@ QGeoPositionInfoSource *GUI::positionSource(const Options &options)
|
||||
{
|
||||
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,
|
||||
options.pluginParams.value(options.plugin), this);
|
||||
#endif // QT 5.14
|
||||
if (source)
|
||||
source->setPreferredPositioningMethods(
|
||||
QGeoPositionInfoSource::SatellitePositioningMethods);
|
||||
|
@ -158,7 +158,6 @@ private:
|
||||
#endif // Q_OS_ANDROID
|
||||
bool openPOIFile(const QString &fileName);
|
||||
bool loadFile(const QString &fileName, bool tryUnknown, int &showError);
|
||||
bool loadURL(const QUrl &url, int &showError);
|
||||
void loadData(const Data &data);
|
||||
bool loadMapNode(const TreeNode<Map*> &node, MapAction *&action,
|
||||
const QList<QAction*> &existingActions, int &showError);
|
||||
|
@ -638,7 +638,11 @@ void MapView::wheelEvent(QWheelEvent *event)
|
||||
return;
|
||||
_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);
|
||||
#endif // QT 5.15
|
||||
|
||||
/* Do not call QGraphicsView::wheelEvent() here as this would shift the
|
||||
view ! */
|
||||
@ -1254,7 +1258,7 @@ void MapView::drawHillShading(bool draw)
|
||||
setMap(_map);
|
||||
}
|
||||
|
||||
void MapView::selectLayers(MapView::Layers layers)
|
||||
void MapView::selectLayers(Layers layers)
|
||||
{
|
||||
_layers = layers;
|
||||
|
||||
|
@ -136,7 +136,7 @@ public slots:
|
||||
void showMotionInfo(bool show);
|
||||
void useStyles(bool use);
|
||||
void drawHillShading(bool draw);
|
||||
void selectLayers(MapView::Layers layers);
|
||||
void selectLayers(Layers layers);
|
||||
|
||||
private slots:
|
||||
void updatePOI();
|
||||
|
@ -676,17 +676,21 @@ QWidget *OptionsDialog::createPositionPage()
|
||||
_positionPlugin = new QComboBox();
|
||||
_positionPlugin->addItems(plugins);
|
||||
_positionPlugin->setCurrentIndex(_positionPlugin->findText(_options.plugin));
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
_pluginParameters = new PluginParameters(_positionPlugin->currentText(),
|
||||
_options.pluginParams);
|
||||
connect(_positionPlugin, &QComboBox::currentTextChanged, _pluginParameters,
|
||||
&PluginParameters::setPlugin);
|
||||
#endif // QT 5.14
|
||||
|
||||
QFormLayout *pluginLayout = new QFormLayout();
|
||||
pluginLayout->addRow(tr("Plugin:"), _positionPlugin);
|
||||
|
||||
QVBoxLayout *sourceLayout = new QVBoxLayout();
|
||||
sourceLayout->addLayout(pluginLayout);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
sourceLayout->addWidget(_pluginParameters);
|
||||
#endif // QT 5.14
|
||||
sourceLayout->addStretch();
|
||||
|
||||
QWidget *sourceTab = new QWidget();
|
||||
@ -1005,7 +1009,9 @@ void OptionsDialog::accept()
|
||||
_options.hillshadingZFactor = _hillshadingZFactor->value();
|
||||
|
||||
_options.plugin = _positionPlugin->currentText();
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
_options.pluginParams = _pluginParameters->parameters();
|
||||
#endif // QT 5.14
|
||||
|
||||
_options.useOpenGL = _useOpenGL->isChecked();
|
||||
_options.enableHTTP2 = _enableHTTP2->isChecked();
|
||||
|
@ -193,7 +193,9 @@ private:
|
||||
QDoubleSpinBox *_hillshadingZFactor;
|
||||
// Position
|
||||
QComboBox *_positionPlugin;
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||
PluginParameters *_pluginParameters;
|
||||
#endif // QT 5.14
|
||||
// System
|
||||
QSpinBox *_pixmapCache;
|
||||
QSpinBox *_demCache;
|
||||
|
@ -10,6 +10,13 @@
|
||||
#include "markeritem.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
|
||||
|
||||
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,
|
||||
c2.lat()));
|
||||
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.moveTo(_map->ll2xy(Coordinates(-180, p.y())));
|
||||
} else {
|
||||
QLineF l(QPointF(c1.lon(), c1.lat()), QPointF(c2.lon() - 360,
|
||||
c2.lat()));
|
||||
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.moveTo(_map->ll2xy(Coordinates(180, p.y())));
|
||||
}
|
||||
|
@ -9,6 +9,9 @@
|
||||
#include <QVBoxLayout>
|
||||
#include <QFormLayout>
|
||||
#include <QApplication>
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
||||
#include <QDesktopWidget>
|
||||
#endif // QT 5.15
|
||||
#include "tooltip.h"
|
||||
#include "thumbnail.h"
|
||||
#include "flowlayout.h"
|
||||
@ -181,7 +184,11 @@ bool PopupFrame::eventFilter(QObject *o, QEvent *ev)
|
||||
|
||||
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();
|
||||
#endif // QT 5.15
|
||||
QPoint p(pos.x() + 2, pos.y() + 16);
|
||||
|
||||
if (p.x() + width() > screen.x() + screen.width())
|
||||
|
@ -64,7 +64,6 @@ GraphItem *SpeedGraph::loadGraph(const Graph &graph, const Track &track,
|
||||
if (primary) {
|
||||
_avg.append(QPointF(track.distance(), gi->avg()));
|
||||
_mavg.append(QPointF(track.distance(), gi->mavg()));
|
||||
_max.append(QPointF(track.distance(), gi->max()));
|
||||
}
|
||||
|
||||
return gi;
|
||||
@ -118,16 +117,6 @@ qreal SpeedGraph::avg() const
|
||||
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()
|
||||
{
|
||||
qDeleteAll(_tracks);
|
||||
@ -135,7 +124,6 @@ void SpeedGraph::clear()
|
||||
|
||||
_avg.clear();
|
||||
_mavg.clear();
|
||||
_max.clear();
|
||||
|
||||
GraphTab::clear();
|
||||
}
|
||||
|
@ -26,13 +26,12 @@ private:
|
||||
GraphItem *loadGraph(const Graph &graph, const Track &track,
|
||||
const QColor &color, bool primary);
|
||||
qreal avg() const;
|
||||
qreal max() const;
|
||||
qreal max() const {return bounds().bottom();}
|
||||
void setYUnits();
|
||||
void setInfo();
|
||||
|
||||
QVector<QPointF> _avg;
|
||||
QVector<QPointF> _mavg;
|
||||
QVector<QPointF> _max;
|
||||
|
||||
Units _units;
|
||||
TimeType _timeType;
|
||||
|
@ -7,18 +7,15 @@ RFC 4180 parser with the following enchancements:
|
||||
- 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;
|
||||
QByteArray field;
|
||||
|
||||
list.clear();
|
||||
|
||||
while (_device->getChar(&c)) {
|
||||
if (limit && ++len > limit)
|
||||
return false;
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (c == '\r')
|
||||
|
@ -9,7 +9,7 @@ public:
|
||||
CSV(QIODevice *device, char delimiter = ',')
|
||||
: _device(device), _delimiter(delimiter), _line(1) {}
|
||||
|
||||
bool readEntry(QByteArrayList &list, int limit = 4096);
|
||||
bool readEntry(QByteArrayList &list);
|
||||
bool atEnd() const {return _device->atEnd();}
|
||||
int line() const {return _line;}
|
||||
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
bool intersects(const RectC &r) const
|
||||
{return (right() >= r.left() && bottom() <= r.top() && left() <= r.right()
|
||||
&& 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()
|
||||
&& c.lat() >= bottom());}
|
||||
|
||||
|
@ -115,7 +115,7 @@ public:
|
||||
|
||||
/// Count the data elements in this container. This is slow as no internal
|
||||
/// counter is maintained.
|
||||
int Count() const;
|
||||
int Count();
|
||||
|
||||
|
||||
/// Iterator is not remove safe.
|
||||
@ -363,7 +363,7 @@ protected:
|
||||
void* a_context) const;
|
||||
void RemoveAllRec(Node* a_node);
|
||||
void Reset();
|
||||
void CountRec(Node* a_node, int& a_count) const;
|
||||
void CountRec(Node* a_node, int& a_count);
|
||||
|
||||
/// Root of tree
|
||||
Node* m_root;
|
||||
@ -473,7 +473,7 @@ int RTREE_QUAL::Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDI
|
||||
|
||||
|
||||
RTREE_TEMPLATE
|
||||
int RTREE_QUAL::Count() const
|
||||
int RTREE_QUAL::Count()
|
||||
{
|
||||
int count = 0;
|
||||
CountRec(m_root, count);
|
||||
@ -483,7 +483,7 @@ int RTREE_QUAL::Count() const
|
||||
|
||||
|
||||
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
|
||||
for (int index = 0; index < a_node->m_count; ++index)
|
||||
|
@ -2,7 +2,6 @@
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include "common/util.h"
|
||||
#include "map/crs.h"
|
||||
#include "gpxparser.h"
|
||||
#include "tcxparser.h"
|
||||
#include "csvparser.h"
|
||||
@ -23,9 +22,6 @@
|
||||
#include "onmoveparsers.h"
|
||||
#include "twonavparser.h"
|
||||
#include "gpsdumpparser.h"
|
||||
#include "txtparser.h"
|
||||
#include "vtkparser.h"
|
||||
#include "vkxparser.h"
|
||||
#include "data.h"
|
||||
|
||||
|
||||
@ -52,9 +48,6 @@ static OMDParser omd;
|
||||
static GHPParser ghp;
|
||||
static TwoNavParser twonav;
|
||||
static GPSDumpParser gpsdump;
|
||||
static TXTParser txt;
|
||||
static VTKParser vtk;
|
||||
static VKXParser vkx;
|
||||
|
||||
static QMultiMap<QString, Parser*> parsers()
|
||||
{
|
||||
@ -88,9 +81,6 @@ static QMultiMap<QString, Parser*> parsers()
|
||||
map.insert("rte", &twonav);
|
||||
map.insert("wpt", &twonav);
|
||||
map.insert("wpt", &gpsdump);
|
||||
map.insert("txt", &txt);
|
||||
map.insert("vtk", &vtk);
|
||||
map.insert("vkx", &vkx);
|
||||
|
||||
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()
|
||||
{
|
||||
return
|
||||
@ -250,9 +176,6 @@ QString Data::formats()
|
||||
+ qApp->translate("Data", "SLF files") + " (*.slf);;"
|
||||
+ qApp->translate("Data", "SML files") + " (*.sml);;"
|
||||
+ 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", "GPSDump files") + " (*.wpt);;"
|
||||
+ qApp->translate("Data", "All files") + " (*)";
|
||||
|
@ -14,7 +14,6 @@ class Data
|
||||
{
|
||||
public:
|
||||
Data(const QString &fileName, bool tryUnknown = true);
|
||||
Data(const QUrl &url);
|
||||
|
||||
bool isValid() const {return _valid;}
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
@ -467,7 +467,8 @@ bool FITParser::parseHeader(CTX &ctx)
|
||||
}
|
||||
|
||||
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(polygons);
|
||||
|
@ -541,7 +541,7 @@ void KMLParser::photoOverlay(const Ctx &ctx, QVector<Waypoint> &waypoints,
|
||||
Waypoint w;
|
||||
QMap<QString, PolygonStyle> unused;
|
||||
QMap<QString, LineStyle> unused2;
|
||||
static const QRegularExpression re("\\$\\[[^\\]]+\\]");
|
||||
static QRegularExpression re("\\$\\[[^\\]]+\\]");
|
||||
|
||||
while (_reader.readNextStartElement()) {
|
||||
if (_reader.name() == QLatin1String("name"))
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <QXmlStreamReader>
|
||||
#include "parser.h"
|
||||
|
||||
|
||||
class TCXParser : public Parser
|
||||
{
|
||||
public:
|
||||
|
@ -2,6 +2,13 @@
|
||||
#include "map/gcs.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)
|
||||
{
|
||||
QStringList l(str.split(QChar(0xBA)));
|
||||
@ -116,8 +123,7 @@ bool TwoNavParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||
}}
|
||||
break;
|
||||
case 'T':
|
||||
{QStringList list(codec.toString(line).split(' ',
|
||||
Qt::SkipEmptyParts));
|
||||
{QStringList list(codec.toString(line).split(' ', SKIP_EMPTY));
|
||||
if (list.size() < 4) {
|
||||
_errorString = "Parse error";
|
||||
return false;
|
||||
@ -153,8 +159,7 @@ bool TwoNavParser::parse(QFile *file, QList<TrackData> &tracks,
|
||||
tracks.last().last().append(t);}
|
||||
break;
|
||||
case 'W':
|
||||
{QStringList list(codec.toString(line).split(' ',
|
||||
Qt::SkipEmptyParts));
|
||||
{QStringList list(codec.toString(line).split(' ', SKIP_EMPTY));
|
||||
if (list.size() < 5) {
|
||||
_errorString = "Parse error";
|
||||
return false;
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -39,12 +39,15 @@ bool AtlasData::polyCb(MapEntry *map, void *context)
|
||||
ctx->cacheLock.unlock();
|
||||
|
||||
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->cache.insert(map->path, data);
|
||||
} else
|
||||
cached->polys(ctx->rect, ctx->polygons, ctx->lines);
|
||||
} else {
|
||||
cached->polygons(ctx->rect, ctx->polygons);
|
||||
cached->lines(ctx->rect, ctx->lines);
|
||||
}
|
||||
|
||||
ctx->cacheLock.unlock();
|
||||
map->lock.unlock();
|
||||
|
@ -10,18 +10,18 @@ namespace ENC {
|
||||
|
||||
typedef QCache<QString, MapData> MapCache;
|
||||
|
||||
class AtlasData : public Data
|
||||
class AtlasData
|
||||
{
|
||||
public:
|
||||
AtlasData(MapCache &cache, QMutex &cacheLock)
|
||||
: _cache(cache), _cacheLock(cacheLock) {}
|
||||
virtual ~AtlasData();
|
||||
~AtlasData();
|
||||
|
||||
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);
|
||||
virtual void points(const RectC &rect, QList<MapData::Point> *points);
|
||||
void points(const RectC &rect, QList<MapData::Point> *points);
|
||||
|
||||
private:
|
||||
struct MapEntry {
|
||||
|
@ -3,11 +3,9 @@
|
||||
|
||||
#define CATACH 8
|
||||
#define CATBUA 10
|
||||
#define CATCOV 18
|
||||
#define CATDIS 21
|
||||
#define CATHAF 30
|
||||
#define CATLMK 35
|
||||
#define CATLIT 37
|
||||
#define CATMFA 38
|
||||
#define CATMOR 40
|
||||
#define CATTRK 54
|
||||
@ -18,21 +16,16 @@
|
||||
#define CATWAT 69
|
||||
#define CATWED 70
|
||||
#define CATWRK 71
|
||||
#define COLOUR 75
|
||||
#define COMCHA 77
|
||||
#define CURVEL 84
|
||||
#define DRVAL1 87
|
||||
#define ELEVAT 90
|
||||
#define FUNCTN 94
|
||||
#define LITVIS 108
|
||||
#define OBJNAM 116
|
||||
#define ORIENT 117
|
||||
#define RESTRN 131
|
||||
#define SECTR1 136
|
||||
#define SECTR2 137
|
||||
#define TRAFIC 172
|
||||
#define VALDCO 174
|
||||
#define VALNMR 178
|
||||
#define VERCLR 181
|
||||
#define WATLEV 187
|
||||
|
||||
|
@ -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
|
@ -1,4 +1,3 @@
|
||||
#include <QtEndian>
|
||||
#include <QFile>
|
||||
#include <QRegularExpression>
|
||||
#include "common/util.h"
|
||||
@ -6,6 +5,13 @@
|
||||
|
||||
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 {
|
||||
char RecordLength[5];
|
||||
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);
|
||||
|
||||
for (int i = 0; i < _subFields->size(); i++)
|
||||
if (_subFields->at(i) == name)
|
||||
for (int i = 0; i < _subFields.size(); i++)
|
||||
if (_subFields.at(i) == name)
|
||||
return &v.at(i);
|
||||
|
||||
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;
|
||||
|
||||
@ -46,7 +52,7 @@ bool ISO8211::Field::subfield(quint32 name, int *val, int idx) const
|
||||
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;
|
||||
|
||||
@ -58,7 +64,7 @@ bool ISO8211::Field::subfield(quint32 name, uint *val, int idx) const
|
||||
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);
|
||||
if (!v)
|
||||
@ -95,7 +101,6 @@ int ISO8211::readDR(QVector<FieldDefinition> &fields)
|
||||
DR ddr;
|
||||
QByteArray fieldLen, fieldPos;
|
||||
int len, lenSize, posSize, tagSize, offset;
|
||||
char tag[4];
|
||||
|
||||
static_assert(sizeof(ddr) == 24, "Invalid DR alignment");
|
||||
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)
|
||||
return -1;
|
||||
|
||||
fields.resize((offset - 1 - sizeof(ddr)) / (lenSize + posSize + tagSize));
|
||||
fields.resize((offset - 1 - sizeof(DR)) / (lenSize + posSize + tagSize));
|
||||
fieldLen.resize(lenSize);
|
||||
fieldPos.resize(posSize);
|
||||
|
||||
for (int i = 0; i < fields.size(); 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(fieldPos.data(), posSize) != posSize)
|
||||
return -1;
|
||||
|
||||
r.tag = qFromLittleEndian<quint32>(tag);
|
||||
r.pos = offset + Util::str2int(fieldPos.constData(), posSize);
|
||||
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)
|
||||
{
|
||||
static const QRegularExpression re(
|
||||
"([0-9]*)(A|I|R|B|b11|b12|b14|b21|b22|b24)\\(*([0-9]*)\\)*");
|
||||
QByteArray ba(def.size, Qt::Initialization::Uninitialized);
|
||||
static QRegularExpression re("(\\d*)(\\w+)\\(*(\\d*)\\)*");
|
||||
QByteArray ba;
|
||||
bool repeat = false;
|
||||
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()))
|
||||
return false;
|
||||
|
||||
@ -150,9 +156,9 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
|
||||
repeat = true;
|
||||
list[1].remove(0, 1);
|
||||
}
|
||||
QList<QByteArray> tags(list.at(1).split('!'));
|
||||
|
||||
if (list.size() > 2) {
|
||||
QList<QByteArray> tags(list.at(1).split('!'));
|
||||
QRegularExpressionMatchIterator it = re.globalMatch(list.at(2));
|
||||
int tag = 0;
|
||||
|
||||
@ -182,17 +188,11 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
|
||||
SubFieldDefinition sfd(fieldType(typeStr, size));
|
||||
if (sfd.type() == Unknown)
|
||||
return false;
|
||||
if (tag >= tags.size())
|
||||
return false;
|
||||
defs[tag] = sfd;
|
||||
defTags[tag] = (tags.at(tag).length() == 4)
|
||||
? qFromLittleEndian<quint32>(tags.at(tag).constData()) : 0;
|
||||
defTags[tag] = tags.at(tag);
|
||||
tag++;
|
||||
}
|
||||
}
|
||||
|
||||
if (tag != tags.size())
|
||||
return false;
|
||||
}
|
||||
|
||||
fields = SubFields(defTags, defs, repeat);
|
||||
@ -218,10 +218,8 @@ bool ISO8211::readDDR()
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
SubFields 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")
|
||||
.arg(QString(tag));
|
||||
.arg(QString(fields.at(i).tag));
|
||||
return false;
|
||||
}
|
||||
_map.insert(fields.at(i).tag, def);
|
||||
@ -238,8 +236,9 @@ bool ISO8211::readDDR()
|
||||
bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
|
||||
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)
|
||||
&& _file.read(ba.data(), ba.size()) == ba.size()))
|
||||
return false;
|
||||
@ -249,7 +248,8 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
|
||||
const char *ep = ba.constData() + ba.size() - 1;
|
||||
|
||||
do {
|
||||
QVector<QVariant> row(fields.size());
|
||||
QVector<QVariant> row;
|
||||
row.resize(fields.size());
|
||||
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
const SubFieldDefinition &f = fields.at(i);
|
||||
@ -273,11 +273,11 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
|
||||
dp++;
|
||||
break;
|
||||
case S16:
|
||||
row[i] = QVariant(qFromLittleEndian<qint16>(dp));
|
||||
row[i] = QVariant(INT16(dp));
|
||||
dp += 2;
|
||||
break;
|
||||
case S32:
|
||||
row[i] = QVariant(qFromLittleEndian<qint32>(dp));
|
||||
row[i] = QVariant(INT32(dp));
|
||||
dp += 4;
|
||||
break;
|
||||
case U8:
|
||||
@ -285,11 +285,11 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
|
||||
dp++;
|
||||
break;
|
||||
case U16:
|
||||
row[i] = QVariant(qFromLittleEndian<quint16>(dp));
|
||||
row[i] = QVariant(UINT16(dp));
|
||||
dp += 2;
|
||||
break;
|
||||
case U32:
|
||||
row[i] = QVariant(qFromLittleEndian<quint32>(dp));
|
||||
row[i] = QVariant(UINT32(dp));
|
||||
dp += 4;
|
||||
break;
|
||||
default:
|
||||
@ -325,16 +325,13 @@ bool ISO8211::readRecord(Record &record)
|
||||
|
||||
FieldsMap::const_iterator it(_map.find(def.tag));
|
||||
if (it == _map.constEnd()) {
|
||||
QByteArray tag(sizeof(quint32), Qt::Initialization::Uninitialized);
|
||||
qToLittleEndian<quint32>(def.tag, tag.data());
|
||||
_errorString = QString("%1: unknown record").arg(QString(tag));
|
||||
_errorString = QString("%1: unknown record").arg(QString(def.tag));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!readUDA(pos, def, it->defs(), it->repeat(), data)) {
|
||||
QByteArray tag(sizeof(quint32), Qt::Initialization::Uninitialized);
|
||||
qToLittleEndian<quint32>(def.tag, tag.data());
|
||||
_errorString = QString("Error reading %1 record").arg(QString(tag));
|
||||
_errorString = QString("Error reading %1 record")
|
||||
.arg(QString(def.tag));
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -344,7 +341,8 @@ bool ISO8211::readRecord(Record &record)
|
||||
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++)
|
||||
if (record.at(i).tag() == name)
|
||||
|
@ -4,6 +4,13 @@
|
||||
#include <QFile>
|
||||
#include <QByteArray>
|
||||
#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 {
|
||||
|
||||
@ -15,22 +22,23 @@ public:
|
||||
class Field
|
||||
{
|
||||
public:
|
||||
Field() : _subFields(0) {}
|
||||
Field(quint32 tag, const QVector<quint32> &subFields, const Data &data)
|
||||
: _tag(tag), _subFields(&subFields), _data(data) {}
|
||||
Field() {}
|
||||
Field(const QByteArray &tag, const QVector<QByteArray> &subFields,
|
||||
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;}
|
||||
|
||||
bool subfield(quint32 name, int *val, int idx = 0) const;
|
||||
bool subfield(quint32 name, uint *val, int idx = 0) const;
|
||||
bool subfield(quint32 name, QByteArray *val, int idx = 0) const;
|
||||
bool subfield(const char *name, int *val, int idx = 0) const;
|
||||
bool subfield(const char *name, uint *val, int idx = 0) const;
|
||||
bool subfield(const char *name, QByteArray *val, int idx = 0) const;
|
||||
|
||||
private:
|
||||
const QVariant *data(quint32 name, int idx = 0) const;
|
||||
const QVariant *data(const QByteArray &name, int idx = 0) const;
|
||||
|
||||
quint32 _tag;
|
||||
const QVector<quint32> *_subFields;
|
||||
QByteArray _tag;
|
||||
QVector<QByteArray> _subFields;
|
||||
Data _data;
|
||||
};
|
||||
|
||||
@ -42,21 +50,14 @@ public:
|
||||
|
||||
const QString &errorString() const {return _errorString;}
|
||||
|
||||
static const Field *field(const Record &record, quint32 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);
|
||||
}
|
||||
static const Field *field(const Record &record, const QByteArray &name);
|
||||
|
||||
private:
|
||||
enum FieldType {Unknown, String, Array, S8, S16, S32, U8, U16, U32};
|
||||
|
||||
struct FieldDefinition
|
||||
{
|
||||
quint32 tag;
|
||||
QByteArray tag;
|
||||
int pos;
|
||||
int size;
|
||||
};
|
||||
@ -80,22 +81,22 @@ private:
|
||||
{
|
||||
public:
|
||||
SubFields() : _repeat(false) {}
|
||||
SubFields(const QVector<quint32> &tags,
|
||||
SubFields(const QVector<QByteArray> &tags,
|
||||
const QVector<SubFieldDefinition> &defs, bool 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;}
|
||||
|
||||
bool repeat() const {return _repeat;}
|
||||
|
||||
private:
|
||||
QVector<quint32> _tags;
|
||||
QVector<QByteArray> _tags;
|
||||
QVector<SubFieldDefinition> _defs;
|
||||
bool _repeat;
|
||||
};
|
||||
|
||||
typedef QMap<quint32, SubFields> FieldsMap;
|
||||
typedef QMap<QByteArray, SubFields> FieldsMap;
|
||||
|
||||
static SubFieldDefinition fieldType(const QString &str, int cnt);
|
||||
|
||||
@ -109,6 +110,14 @@ private:
|
||||
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
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include <QtEndian>
|
||||
#include "GUI/units.h"
|
||||
#include "objects.h"
|
||||
#include "attributes.h"
|
||||
@ -15,19 +14,6 @@ using namespace ENC;
|
||||
#define PRIM_L 2
|
||||
#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()
|
||||
{
|
||||
QMap<uint,uint> map;
|
||||
@ -104,20 +90,20 @@ static uint order(uint type)
|
||||
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;
|
||||
frid.subfield(RCID, &rcid);
|
||||
uint RCID = 0xFFFFFFFF;
|
||||
FRID.subfield("RCID", &RCID);
|
||||
|
||||
switch (prim) {
|
||||
switch (PRIM) {
|
||||
case PRIM_P:
|
||||
qWarning("%u: invalid point feature", rcid);
|
||||
qWarning("%u: invalid point feature", RCID);
|
||||
break;
|
||||
case PRIM_L:
|
||||
qWarning("%u: invalid line feature", rcid);
|
||||
qWarning("%u: invalid line feature", RCID);
|
||||
break;
|
||||
case PRIM_A:
|
||||
qWarning("%u: invalid area feature", rcid);
|
||||
qWarning("%u: invalid area feature", RCID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -146,7 +132,7 @@ static bool parseNAME(const ISO8211::Field *f, quint8 *type, quint32 *id,
|
||||
return false;
|
||||
|
||||
*type = (quint8)(*ba.constData());
|
||||
*id = qFromLittleEndian<quint32>(ba.constData() + 1);
|
||||
*id = UINT32(ba.constData() + 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -155,9 +141,9 @@ static const ISO8211::Field *SGXD(const ISO8211::Record &r)
|
||||
{
|
||||
const ISO8211::Field *f;
|
||||
|
||||
if ((f = ISO8211::field(r, SG2D)))
|
||||
if ((f = ISO8211::field(r, "SG2D")))
|
||||
return f;
|
||||
else if ((f = ISO8211::field(r, SG3D)))
|
||||
else if ((f = ISO8211::field(r, "SG3D")))
|
||||
return f;
|
||||
else
|
||||
return 0;
|
||||
@ -187,51 +173,29 @@ static bool polygonCb(const MapData::Poly *polygon, void *context)
|
||||
static bool polygonPointCb(const MapData::Poly *polygon, void *context)
|
||||
{
|
||||
QList<MapData::Point> *points = (QList<MapData::Point>*)context;
|
||||
uint type = polygon->type();
|
||||
uint baseType = type>>16;
|
||||
uint baseType = polygon->type()>>16;
|
||||
|
||||
if (baseType == TSSLPT || baseType == RCTLPT || baseType == I_TRNBSN
|
||||
|| baseType == BRIDGE || baseType == I_BRIDGE || baseType == BUAARE
|
||||
|| baseType == LNDARE || baseType == LNDRGN
|
||||
|| type == SUBTYPE(ACHARE, 2) || type == SUBTYPE(I_ACHARE, 2)
|
||||
|| type == SUBTYPE(ACHARE, 3) || type == SUBTYPE(I_ACHARE, 3)
|
||||
|| type == SUBTYPE(ACHARE, 9) || type == SUBTYPE(I_ACHARE, 9)
|
||||
|| type == SUBTYPE(I_BERTHS, 6)
|
||||
|| type == SUBTYPE(RESARE, 1) || type == SUBTYPE(I_RESARE, 1)
|
||||
|| type == SUBTYPE(RESARE, 2) || type == SUBTYPE(I_RESARE, 2)
|
||||
|| type == SUBTYPE(RESARE, 4) || type == SUBTYPE(I_RESARE, 4)
|
||||
|| type == SUBTYPE(RESARE, 5) || type == SUBTYPE(I_RESARE, 5)
|
||||
|| 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));
|
||||
if (!polygon->label().isEmpty() || baseType == TSSLPT || baseType == RCTLPT
|
||||
|| baseType == I_TRNBSN
|
||||
|| polygon->type() == SUBTYPE(ACHARE, 2)
|
||||
|| polygon->type() == SUBTYPE(ACHARE, 3)
|
||||
|| polygon->type() == SUBTYPE(ACHARE, 9)
|
||||
|| polygon->type() == SUBTYPE(I_ACHARE, 2)
|
||||
|| polygon->type() == SUBTYPE(I_ACHARE, 3)
|
||||
|| polygon->type() == SUBTYPE(I_ACHARE, 9)
|
||||
|| polygon->type() == SUBTYPE(I_BERTHS, 6))
|
||||
points->append(MapData::Point(polygon->type(), polygon->bounds().center(),
|
||||
polygon->label(), polygon->param()));
|
||||
|
||||
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;
|
||||
uint baseType = line->type()>>16;
|
||||
|
||||
if (baseType == RDOCAL || baseType == I_RDOCAL)
|
||||
points->append(MapData::Point(baseType, line->bounds().center(),
|
||||
line->attributes(), 1));
|
||||
|
||||
return true;
|
||||
return Coordinates(x / (double)COMF, y / (double)COMF);
|
||||
}
|
||||
|
||||
static Coordinates coordinates(int x, int y, uint comf)
|
||||
{
|
||||
return Coordinates(x / (double)comf, y / (double)comf);
|
||||
}
|
||||
|
||||
static Coordinates point(const ISO8211::Record &r, uint comf)
|
||||
static Coordinates point(const ISO8211::Record &r, uint COMF)
|
||||
{
|
||||
const ISO8211::Field *f = SGXD(r);
|
||||
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 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)
|
||||
return 0;
|
||||
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> ¶ms) : _type(type), _pos(c), _label(label)
|
||||
{
|
||||
uint catrea = attr.value(CATREA).toUInt();
|
||||
_id = ((quint64)order(type))<<32 | (uint)qHash(c);
|
||||
|
||||
if (!catrea) {
|
||||
uint restrn = attr.value(
|
||||
(type == RESARE) ? RESTRN : I_RESTRN).toUInt();
|
||||
|
||||
if (restrn == 1)
|
||||
return 2;
|
||||
else if (restrn == 7)
|
||||
return 17;
|
||||
else
|
||||
return 0;
|
||||
} else
|
||||
return catrea;
|
||||
}
|
||||
|
||||
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 (type>>16 == I_DISMAR && params.size()) {
|
||||
_label = hUnits((type>>8)&0xFF) + " " + QString::fromLatin1(params.at(0));
|
||||
_type = SUBTYPE(I_DISMAR, type & 0xFF);
|
||||
} else if ((type>>16 == I_RDOCAL || type>>16 == RDOCAL) && params.size() > 1) {
|
||||
if (!params.at(1).isEmpty())
|
||||
_label = QString("VHF ") + QString::fromLatin1(params.at(1));
|
||||
_param = QVariant(params.at(0).toDouble());
|
||||
} else if (type>>16 == CURENT && params.size() > 1) {
|
||||
if (!params.at(1).isEmpty())
|
||||
_label = QString::fromLatin1(params.at(1))
|
||||
+ QString::fromUtf8("\xE2\x80\x89kt");
|
||||
_param = QVariant(params.at(0).toDouble());
|
||||
} else if (type>>16 == I_SISTAT || type>>16 == SISTAT) {
|
||||
if (_label.isEmpty())
|
||||
_label = weed(_type & 0xFF);
|
||||
} else if (type == LNDELV) {
|
||||
_label = sistat(type & 0xFF);
|
||||
_type = TYPE(SISTAT);
|
||||
} else if (type>>16 == WEDKLP) {
|
||||
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");
|
||||
else
|
||||
_label += "\n(" + QString::fromLatin1(_attr.value(ELEVAT))
|
||||
_label += "\n(" + QString::fromLatin1(params.at(0))
|
||||
+ "\xE2\x80\x89m)";
|
||||
} else if (type == BRIDGE || type == I_BRIDGE) {
|
||||
double clr = _attr.value(VERCLR).toDouble();
|
||||
} else if ((type == TYPE(TSSLPT) || type == TYPE(RCTLPT)) && params.size())
|
||||
_param = QVariant(params.at(0).toDouble());
|
||||
}
|
||||
|
||||
MapData::Point::Point(uint type, const Coordinates &c, const QString &label,
|
||||
const QVariant ¶m) : _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> ¶ms, 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) {
|
||||
_label = QString::fromUtf8("\xE2\x86\x95") + UNIT_SPACE
|
||||
+ QString::number(clr) + UNIT_SPACE + hUnits(HUNI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
} else if (type>>16 == LNDARE || type>>16 == SEAARE || type>>16 == BERTHS
|
||||
|| type>>16 == I_BERTHS || type>>16 == BUAARE)
|
||||
_label = label;
|
||||
}
|
||||
|
||||
MapData::Line::Line(uint type, const QVector<Coordinates> &path,
|
||||
const Attributes &attr) : _path(path), _attr(attr)
|
||||
const QString &label, const QVector<QByteArray> ¶ms)
|
||||
: _type(type), _path(path), _label(label)
|
||||
{
|
||||
uint subtype = 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));
|
||||
if ((type == TYPE(DEPCNT) || type == TYPE(LNDELV)) && params.size())
|
||||
_label = QString::fromLatin1(params.at(0));
|
||||
}
|
||||
|
||||
RectC MapData::Line::bounds() const
|
||||
@ -491,10 +354,10 @@ RectC MapData::Line::bounds() const
|
||||
}
|
||||
|
||||
QVector<MapData::Sounding> MapData::soundings(const ISO8211::Record &r,
|
||||
uint comf, uint somf)
|
||||
uint COMF, uint SOMF)
|
||||
{
|
||||
QVector<Sounding> s;
|
||||
const ISO8211::Field *f = ISO8211::field(r, SG3D);
|
||||
const ISO8211::Field *f = ISO8211::field(r, "SG3D");
|
||||
if (!f)
|
||||
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 x = f->data().at(i).at(1).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;
|
||||
}
|
||||
|
||||
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;
|
||||
quint32 id;
|
||||
RecordMapIterator it;
|
||||
|
||||
const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
|
||||
if (!fspt || fspt->data().at(0).size() != 4)
|
||||
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
|
||||
if (!FSPT || FSPT->data().at(0).size() != 4)
|
||||
return QVector<Sounding>();
|
||||
|
||||
if (!parseNAME(fspt, &type, &id))
|
||||
if (!parseNAME(FSPT, &type, &id))
|
||||
return QVector<Sounding>();
|
||||
|
||||
if (type == RCNM_VI) {
|
||||
@ -534,21 +397,21 @@ QVector<MapData::Sounding> MapData::soundingGeometry(const ISO8211::Record &r,
|
||||
} else
|
||||
return QVector<Sounding>();
|
||||
|
||||
return soundings(it.value(), comf, somf);
|
||||
return soundings(it.value(), COMF, SOMF);
|
||||
}
|
||||
|
||||
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;
|
||||
quint32 id;
|
||||
RecordMapIterator it;
|
||||
|
||||
const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
|
||||
if (!fspt || fspt->data().at(0).size() != 4)
|
||||
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
|
||||
if (!FSPT || FSPT->data().at(0).size() != 4)
|
||||
return Coordinates();
|
||||
|
||||
if (!parseNAME(fspt, &type, &id))
|
||||
if (!parseNAME(FSPT, &type, &id))
|
||||
return Coordinates();
|
||||
|
||||
if (type == RCNM_VI) {
|
||||
@ -562,55 +425,55 @@ Coordinates MapData::pointGeometry(const ISO8211::Record &r,
|
||||
} else
|
||||
return Coordinates();
|
||||
|
||||
return point(it.value(), comf);
|
||||
return point(it.value(), COMF);
|
||||
}
|
||||
|
||||
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;
|
||||
Coordinates c[2];
|
||||
uint ornt;
|
||||
uint ORNT;
|
||||
quint8 type;
|
||||
quint32 id;
|
||||
|
||||
const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
|
||||
if (!fspt || fspt->data().at(0).size() != 4)
|
||||
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
|
||||
if (!FSPT || FSPT->data().at(0).size() != 4)
|
||||
return QVector<Coordinates>();
|
||||
|
||||
for (int i = 0; i < fspt->data().size(); i++) {
|
||||
if (!parseNAME(fspt, &type, &id, i) || type != RCNM_VE)
|
||||
for (int i = 0; i < FSPT->data().size(); i++) {
|
||||
if (!parseNAME(FSPT, &type, &id, i) || type != RCNM_VE)
|
||||
return QVector<Coordinates>();
|
||||
ornt = fspt->data().at(i).at(1).toUInt();
|
||||
ORNT = FSPT->data().at(i).at(1).toUInt();
|
||||
|
||||
RecordMapIterator it = ve.find(id);
|
||||
if (it == ve.constEnd())
|
||||
return QVector<Coordinates>();
|
||||
const ISO8211::Record &frid = it.value();
|
||||
const ISO8211::Field *vrpt = ISO8211::field(frid, VRPT);
|
||||
if (!vrpt || vrpt->data().size() != 2)
|
||||
const ISO8211::Record &FRID = it.value();
|
||||
const ISO8211::Field *VRPT = ISO8211::field(FRID, "VRPT");
|
||||
if (!VRPT || VRPT->data().size() != 2)
|
||||
return QVector<Coordinates>();
|
||||
|
||||
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>();
|
||||
|
||||
RecordMapIterator jt = vc.find(id);
|
||||
if (jt == vc.constEnd())
|
||||
return QVector<Coordinates>();
|
||||
c[j] = point(jt.value(), comf);
|
||||
c[j] = point(jt.value(), COMF);
|
||||
if (c[j].isNull())
|
||||
return QVector<Coordinates>();
|
||||
}
|
||||
|
||||
const ISO8211::Field *vertexes = SGXD(frid);
|
||||
if (ornt == 2) {
|
||||
const ISO8211::Field *vertexes = SGXD(FRID);
|
||||
if (ORNT == 2) {
|
||||
path.append(c[1]);
|
||||
if (vertexes) {
|
||||
for (int j = vertexes->data().size() - 1; j >= 0; j--) {
|
||||
const QVector<QVariant> &cv = vertexes->data().at(j);
|
||||
path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
|
||||
comf));
|
||||
COMF));
|
||||
}
|
||||
}
|
||||
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++) {
|
||||
const QVector<QVariant> &cv = vertexes->data().at(j);
|
||||
path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
|
||||
comf));
|
||||
COMF));
|
||||
}
|
||||
}
|
||||
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,
|
||||
const RecordMap &ve, uint comf)
|
||||
const RecordMap &ve, uint COMF)
|
||||
{
|
||||
Polygon path;
|
||||
QVector<Coordinates> v;
|
||||
Coordinates c[2];
|
||||
uint ornt, usag;
|
||||
uint ORNT, USAG;
|
||||
quint8 type;
|
||||
quint32 id;
|
||||
|
||||
const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
|
||||
if (!fspt || fspt->data().at(0).size() != 4)
|
||||
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
|
||||
if (!FSPT || FSPT->data().at(0).size() != 4)
|
||||
return Polygon();
|
||||
|
||||
for (int i = 0; i < fspt->data().size(); i++) {
|
||||
if (!parseNAME(fspt, &type, &id, i) || type != RCNM_VE)
|
||||
for (int i = 0; i < FSPT->data().size(); i++) {
|
||||
if (!parseNAME(FSPT, &type, &id, i) || type != RCNM_VE)
|
||||
return Polygon();
|
||||
ornt = fspt->data().at(i).at(1).toUInt();
|
||||
usag = fspt->data().at(i).at(2).toUInt();
|
||||
ORNT = FSPT->data().at(i).at(1).toUInt();
|
||||
USAG = FSPT->data().at(i).at(2).toUInt();
|
||||
|
||||
if (usag == 2 && path.isEmpty()) {
|
||||
if (USAG == 2 && path.isEmpty()) {
|
||||
path.append(v);
|
||||
v.clear();
|
||||
}
|
||||
@ -658,55 +521,55 @@ Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
|
||||
RecordMapIterator it = ve.find(id);
|
||||
if (it == ve.constEnd())
|
||||
return Polygon();
|
||||
const ISO8211::Record &frid = it.value();
|
||||
const ISO8211::Field *vrpt = ISO8211::field(frid, VRPT);
|
||||
if (!vrpt || vrpt->data().size() != 2)
|
||||
const ISO8211::Record &FRID = it.value();
|
||||
const ISO8211::Field *VRPT = ISO8211::field(FRID, "VRPT");
|
||||
if (!VRPT || VRPT->data().size() != 2)
|
||||
return Polygon();
|
||||
|
||||
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();
|
||||
|
||||
RecordMapIterator jt = vc.find(id);
|
||||
if (jt == vc.constEnd())
|
||||
return Polygon();
|
||||
c[j] = point(jt.value(), comf);
|
||||
c[j] = point(jt.value(), COMF);
|
||||
if (c[j].isNull())
|
||||
return Polygon();
|
||||
}
|
||||
|
||||
const ISO8211::Field *vertexes = SGXD(frid);
|
||||
if (ornt == 2) {
|
||||
const ISO8211::Field *vertexes = SGXD(FRID);
|
||||
if (ORNT == 2) {
|
||||
v.append(c[1]);
|
||||
if (usag == 3)
|
||||
if (USAG == 3)
|
||||
v.append(Coordinates());
|
||||
if (vertexes) {
|
||||
for (int j = vertexes->data().size() - 1; j >= 0; j--) {
|
||||
const QVector<QVariant> &cv = vertexes->data().at(j);
|
||||
v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
|
||||
comf));
|
||||
COMF));
|
||||
}
|
||||
}
|
||||
if (usag == 3)
|
||||
if (USAG == 3)
|
||||
v.append(Coordinates());
|
||||
v.append(c[0]);
|
||||
} else {
|
||||
v.append(c[0]);
|
||||
if (usag == 3)
|
||||
if (USAG == 3)
|
||||
v.append(Coordinates());
|
||||
if (vertexes) {
|
||||
for (int j = 0; j < vertexes->data().size(); j++) {
|
||||
const QVector<QVariant> &cv = vertexes->data().at(j);
|
||||
v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
|
||||
comf));
|
||||
COMF));
|
||||
}
|
||||
}
|
||||
if (usag == 3)
|
||||
if (USAG == 3)
|
||||
v.append(Coordinates());
|
||||
v.append(c[1]);
|
||||
}
|
||||
|
||||
if (usag == 2 && v.first() == v.last()) {
|
||||
if (USAG == 2 && v.first() == v.last()) {
|
||||
path.append(v);
|
||||
v.clear();
|
||||
}
|
||||
@ -718,86 +581,209 @@ Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
|
||||
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);
|
||||
if (!(attf && attf->data().at(0).size() == 2))
|
||||
return attr;
|
||||
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);
|
||||
attr.insert(av.at(0).toUInt(), av.at(1).toByteArray());
|
||||
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 == 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)
|
||||
{
|
||||
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,
|
||||
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));
|
||||
return (c.isNull() ? 0 : new Point(objl, c, attributes(r), huni));
|
||||
Coordinates c(pointGeometry(r, vi, vc, COMF));
|
||||
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,
|
||||
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));
|
||||
return (path.isEmpty() ? 0 : new Line(objl, path, attributes(r)));
|
||||
QVector<Coordinates> path(lineGeometry(r, vc, ve, COMF));
|
||||
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,
|
||||
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));
|
||||
return (path.isEmpty() ? 0 : new Poly(objl, path, attributes(r), huni));
|
||||
Polygon path(polyGeometry(r, vc, ve, COMF));
|
||||
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,
|
||||
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)
|
||||
return false;
|
||||
|
||||
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)
|
||||
return false;
|
||||
int rcnm = f.data().at(0).at(0).toInt();
|
||||
uint rcid = f.data().at(0).at(1).toUInt();
|
||||
int RCNM = f.data().at(0).at(0).toInt();
|
||||
uint RCID = f.data().at(0).at(1).toUInt();
|
||||
|
||||
switch (rcnm) {
|
||||
switch (RCNM) {
|
||||
case RCNM_VI:
|
||||
vi.insert(rcid, record);
|
||||
vi.insert(RCID, record);
|
||||
break;
|
||||
case RCNM_VC:
|
||||
vc.insert(rcid, record);
|
||||
vc.insert(RCID, record);
|
||||
break;
|
||||
case RCNM_VE:
|
||||
ve.insert(rcid, record);
|
||||
ve.insert(RCID, record);
|
||||
break;
|
||||
case RCNM_VF:
|
||||
vf.insert(rcid, record);
|
||||
vf.insert(RCID, record);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else if (tag == FRID) {
|
||||
} else if (ba == "FRID") {
|
||||
fe.append(record);
|
||||
} else if (tag == DSPM) {
|
||||
if (!(f.subfield(COMF, &comf) && f.subfield(SOMF, &somf)))
|
||||
} else if (ba == "DSPM") {
|
||||
if (!(f.subfield("COMF", &COMF) && f.subfield("SOMF", &SOMF)))
|
||||
return false;
|
||||
if (!f.subfield(HUNI, &huni))
|
||||
if (!f.subfield("HUNI", &HUNI))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -810,7 +796,7 @@ MapData::MapData(const QString &path)
|
||||
QVector<ISO8211::Record> fe;
|
||||
ISO8211 ddf(path);
|
||||
ISO8211::Record record;
|
||||
uint prim, objl, comf = 1, somf = 1, huni = 1;
|
||||
uint PRIM, OBJL, COMF = 1, SOMF = 1, HUNI = 1;
|
||||
Poly *poly;
|
||||
Line *line;
|
||||
Point *point;
|
||||
@ -820,7 +806,7 @@ MapData::MapData(const QString &path)
|
||||
if (!ddf.readDDR())
|
||||
return;
|
||||
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");
|
||||
|
||||
for (int i = 0; i < fe.size(); i++) {
|
||||
@ -829,39 +815,39 @@ MapData::MapData(const QString &path)
|
||||
|
||||
if (f.data().at(0).size() < 5)
|
||||
continue;
|
||||
prim = f.data().at(0).at(2).toUInt();
|
||||
objl = f.data().at(0).at(4).toUInt();
|
||||
PRIM = f.data().at(0).at(2).toUInt();
|
||||
OBJL = f.data().at(0).at(4).toUInt();
|
||||
|
||||
switch (prim) {
|
||||
switch (PRIM) {
|
||||
case PRIM_P:
|
||||
if (objl == SOUNDG) {
|
||||
QVector<Sounding> s(soundingGeometry(r, vi, vc, comf, somf));
|
||||
if (OBJL == SOUNDG) {
|
||||
QVector<Sounding> s(soundingGeometry(r, vi, vc, COMF, SOMF));
|
||||
for (int i = 0; i < s.size(); i++) {
|
||||
point = pointObject(s.at(i));
|
||||
pointBounds(point->pos(), min, max);
|
||||
_points.Insert(min, max, point);
|
||||
}
|
||||
} else {
|
||||
if ((point = pointObject(r, vi, vc, comf, objl, huni))) {
|
||||
if ((point = pointObject(r, vi, vc, COMF, OBJL))) {
|
||||
pointBounds(point->pos(), min, max);
|
||||
_points.Insert(min, max, point);
|
||||
} else
|
||||
warning(f, prim);
|
||||
warning(f, PRIM);
|
||||
}
|
||||
break;
|
||||
case PRIM_L:
|
||||
if ((line = lineObject(r, vc, ve, comf, objl))) {
|
||||
if ((line = lineObject(r, vc, ve, COMF, OBJL))) {
|
||||
rectcBounds(line->bounds(), min, max);
|
||||
_lines.Insert(min, max, line);
|
||||
} else
|
||||
warning(f, prim);
|
||||
warning(f, PRIM);
|
||||
break;
|
||||
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);
|
||||
_areas.Insert(min, max, poly);
|
||||
} else
|
||||
warning(f, prim);
|
||||
warning(f, PRIM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -882,22 +868,27 @@ MapData::~MapData()
|
||||
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];
|
||||
|
||||
rectcBounds(rect, min, max);
|
||||
_points.Search(min, max, pointCb, points);
|
||||
_areas.Search(min, max, polygonPointCb, points);
|
||||
_lines.Search(min, max, linePointCb, points);
|
||||
}
|
||||
|
||||
void MapData::polys(const RectC &rect, QList<Poly> *polygons,
|
||||
QList<Line> *lines)
|
||||
void MapData::lines(const RectC &rect, QList<Line> *lines) const
|
||||
{
|
||||
double min[2], max[2];
|
||||
|
||||
rectcBounds(rect, min, max);
|
||||
_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);
|
||||
}
|
||||
|
@ -1,23 +1,98 @@
|
||||
#ifndef ENC_MAPDATA_H
|
||||
#define ENC_MAPDATA_H
|
||||
|
||||
#include "common/rectc.h"
|
||||
#include "common/rtree.h"
|
||||
#include "common/polygon.h"
|
||||
#include "iso8211.h"
|
||||
#include "data.h"
|
||||
|
||||
namespace ENC {
|
||||
|
||||
class MapData : public Data
|
||||
class MapData
|
||||
{
|
||||
public:
|
||||
MapData(const QString &path);
|
||||
virtual ~MapData();
|
||||
class Poly {
|
||||
public:
|
||||
Poly(uint type, const Polygon &path, const QString &label,
|
||||
const QVector<QByteArray> ¶ms, uint HUNI);
|
||||
|
||||
virtual void polys(const RectC &rect, QList<Poly> *polygons,
|
||||
QList<Line> *lines);
|
||||
virtual void points(const RectC &rect, QList<Point> *points);
|
||||
RectC bounds() const {return _path.boundingRect();}
|
||||
const Polygon &path() const {return _path;}
|
||||
uint type() const {return _type;}
|
||||
const QString &label() const {return _label;}
|
||||
const QVariant ¶m() 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> ¶ms);
|
||||
|
||||
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> ¶ms);
|
||||
Point(uint type, const Coordinates &c, const QString &label,
|
||||
const QVariant ¶m);
|
||||
|
||||
const Coordinates &pos() const {return _pos;}
|
||||
uint type() const {return _type;}
|
||||
const QString &label() const {return _label;}
|
||||
const QVariant ¶m() 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:
|
||||
class Attr {
|
||||
public:
|
||||
Attr() : _subtype(0) {}
|
||||
Attr(uint subtype, const QString &label,
|
||||
const QVector<QByteArray> ¶ms)
|
||||
: _subtype(subtype), _label(label), _params(params) {}
|
||||
|
||||
unsigned subtype() const {return _subtype;}
|
||||
const QString &label() const {return _label;}
|
||||
const QVector<QByteArray> ¶ms() const {return _params;}
|
||||
|
||||
private:
|
||||
unsigned _subtype;
|
||||
QString _label;
|
||||
QVector<QByteArray> _params;
|
||||
};
|
||||
|
||||
struct Sounding {
|
||||
Sounding() : depth(NAN) {}
|
||||
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 Point*, double, 2> PointTree;
|
||||
|
||||
static QVector<Sounding> soundings(const ISO8211::Record &r, uint comf,
|
||||
uint somf);
|
||||
static QVector<Sounding> soundings(const ISO8211::Record &r, uint COMF,
|
||||
uint SOMF);
|
||||
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,
|
||||
const RecordMap &vi, const RecordMap &vc, uint comf);
|
||||
const RecordMap &vi, const RecordMap &vc, uint COMF);
|
||||
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,
|
||||
const RecordMap &ve, uint comf);
|
||||
static Attributes attributes(const ISO8211::Record &r);
|
||||
const RecordMap &ve, uint COMF);
|
||||
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 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,
|
||||
const RecordMap &ve, uint comf, uint objl);
|
||||
const RecordMap &ve, uint COMF, uint OBJL);
|
||||
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,
|
||||
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;
|
||||
LineTree _lines;
|
||||
|