From eae46d5f2a51e9127c1c909d2fc1110970e1b7c9 Mon Sep 17 00:00:00 2001 From: John Michael Burke Date: Tue, 30 Jul 2024 17:05:06 -0700 Subject: [PATCH 1/5] Fix map view feature --- resources/SolutionTab.qml | 10 +--------- swiftnav_console/main.py | 32 +++++++++++++------------------- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/resources/SolutionTab.qml b/resources/SolutionTab.qml index 86b074e63..14125a7e7 100644 --- a/resources/SolutionTab.qml +++ b/resources/SolutionTab.qml @@ -57,15 +57,7 @@ MainTab { SolutionTabComponents.SolutionVelocityTab { } - Rectangle { - width: parent.width - height: parent.height - Loader { - sourceComponent: Globals.enableMap ? solutionMap : null - } - } - - property Component solutionMap: SolutionTabComponents.SolutionMapTab { + SolutionTabComponents.SolutionMapTab { } } } diff --git a/swiftnav_console/main.py b/swiftnav_console/main.py index 5c57809e5..e08b695ba 100644 --- a/swiftnav_console/main.py +++ b/swiftnav_console/main.py @@ -44,10 +44,10 @@ from PySide6.QtWidgets import QApplication, QSplashScreen # type: ignore -from PySide6.QtCore import QObject, QUrl, QThread, QTimer, Slot, Signal, Qt, QLocale +from PySide6.QtCore import QCoreApplication, QLoggingCategory, QObject, QUrl, QThread, QTimer, Slot, Signal, Qt, QLocale from PySide6 import QtCharts # pylint: disable=unused-import -from PySide6 import QtQml, QtCore +from PySide6 import QtQml from PySide6.QtGui import QFontDatabase, QIcon, QPixmap @@ -166,6 +166,8 @@ solution_velocity_update, ) +from .solution_map import SolutionMap + from .status_bar import ( status_bar_update, StatusBarData, @@ -258,9 +260,6 @@ capnp.remove_import_hook() # pylint: disable=no-member -MAP_ENABLED = [False] -SolutionMap = QObject - class BackendMessageReceiver(QObject): # pylint: disable=too-many-instance-attributes _request_quit: Signal = Signal() @@ -356,8 +355,7 @@ def _process_message_buffer(self, buffer): data = settings_table_update() SettingsTableEntries.post_data_update(data) ConnectionData.post_connection_state_update(app_state) - if MAP_ENABLED[0]: - SolutionMap.clear() + SolutionMap.clear() elif m.which == Message.Union.ConnectionNotification: data = m.connectionNotification.message ConnectionData.post_connection_message_update(data) @@ -372,10 +370,9 @@ def _process_message_buffer(self, buffer): data[Keys.AVAILABLE_UNITS][:] = m.solutionPositionStatus.availableUnits data[Keys.SOLUTION_LINE] = m.solutionPositionStatus.lineData - if MAP_ENABLED[0]: - SolutionMap.send_pos(m.solutionPositionStatus) + SolutionMap.send_pos(m.solutionPositionStatus) SolutionPositionPoints.post_data_update(data) - elif m.which == Message.Union.SolutionProtectionLevel and MAP_ENABLED[0]: + elif m.which == Message.Union.SolutionProtectionLevel: SolutionMap.send_prot_lvl(m.solutionProtectionLevel) elif m.which == Message.Union.SolutionTableStatus: data = solution_table_update() @@ -672,7 +669,6 @@ def handle_cli_arguments(args: argparse.Namespace, globals_: QObject): globals_.setProperty("showFileConnection", True) # type: ignore if args.enable_map: globals_.setProperty("enableMap", True) # type: ignore - MAP_ENABLED[0] = True if args.enable_ntrip: globals_.setProperty("enableNtrip", True) # type: ignore try: @@ -775,14 +771,17 @@ def main(passed_args: Optional[Tuple[str, ...]] = None) -> int: found_help_arg = True args_main, _ = parser.parse_known_args(passed_args) if args_main.no_high_dpi: - QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_Use96Dpi) # type: ignore + QCoreApplication.setAttribute(Qt.AA_Use96Dpi) # type: ignore if args_main.qmldebug: sys.argv.append("-qmljsdebugger=port:10002,block") debug = QQmlDebuggingEnabler() # pylint: disable=unused-variable QLocale.setDefault(QLocale.c()) - QtCore.QCoreApplication.setAttribute(QtCore.Qt.ApplicationAttribute.AA_ShareOpenGLContexts) - QtCore.QCoreApplication.setAttribute(QtCore.Qt.ApplicationAttribute.AA_UseDesktopOpenGL) + # Silence webengine context logging. + web_engine_context_log = QLoggingCategory("qt.webenginecontext") + web_engine_context_log.setFilterRules("*.info=false") + QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_ShareOpenGLContexts) + QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL) QtWebEngineQuick.initialize() app = QApplication(sys.argv) app.setWindowIcon(QIcon(":/images/icon.ico")) @@ -795,11 +794,6 @@ def main(passed_args: Optional[Tuple[str, ...]] = None) -> int: QQuickStyle.setStyle("Material") # We specifically *don't* want the RobotoCondensed-Bold.ttf font so we get the right look when bolded. - if MAP_ENABLED[0]: - global SolutionMap # pylint: disable=global-statement - from .solution_map import SolutionMap as SolutionMap_ # pylint: disable=import-outside-toplevel - - SolutionMap = SolutionMap_ # type: ignore qmlRegisterType(ConnectionData, "SwiftConsole", 1, 0, "ConnectionData") # type: ignore qmlRegisterType(AdvancedImuPoints, "SwiftConsole", 1, 0, "AdvancedImuPoints") # type: ignore From 5e52ddc87172e1b8491a6139faaff5678ec6f5f3 Mon Sep 17 00:00:00 2001 From: John Michael Burke Date: Tue, 30 Jul 2024 18:55:02 -0700 Subject: [PATCH 2/5] clippy --- console_backend/src/tabs/baseline_tab.rs | 2 +- console_backend/src/tabs/solution_tab/solution_position_tab.rs | 2 +- swiftnav_console/main.py | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/console_backend/src/tabs/baseline_tab.rs b/console_backend/src/tabs/baseline_tab.rs index 036028e1c..64ce41fa3 100644 --- a/console_backend/src/tabs/baseline_tab.rs +++ b/console_backend/src/tabs/baseline_tab.rs @@ -149,7 +149,7 @@ impl BaselineTab { /// # Parameters /// - `mode_string`: The mode string to attempt to prepare data for frontend. /// - `update_current`: Indicating whether the current solution should be updated by - /// this modes last n/e entry. + /// this modes last n/e entry. fn _synchronize_plot_data_by_mode(&mut self, mode_string: &str, update_current: bool) { let mode_idx = match self.mode_strings.iter().position(|x| *x == *mode_string) { Some(idx) => idx, diff --git a/console_backend/src/tabs/solution_tab/solution_position_tab.rs b/console_backend/src/tabs/solution_tab/solution_position_tab.rs index 3b7f48a5a..5e82afbbd 100644 --- a/console_backend/src/tabs/solution_tab/solution_position_tab.rs +++ b/console_backend/src/tabs/solution_tab/solution_position_tab.rs @@ -752,7 +752,7 @@ impl SolutionPositionTab { /// # Parameters /// - `mode_string`: The mode string to attempt to prepare data for frontend. /// - `update_current`: Indicating whether the current solution should be updated by - /// this modes last lat/lon entry. + /// this modes last lat/lon entry. fn _synchronize_plot_data_by_mode(&mut self, mode_string: &str, update_current: bool) { let idx = match self.mode_strings.iter().position(|x| x == mode_string) { Some(idx) => idx, diff --git a/swiftnav_console/main.py b/swiftnav_console/main.py index e08b695ba..94cfaa29c 100644 --- a/swiftnav_console/main.py +++ b/swiftnav_console/main.py @@ -778,7 +778,7 @@ def main(passed_args: Optional[Tuple[str, ...]] = None) -> int: QLocale.setDefault(QLocale.c()) # Silence webengine context logging. - web_engine_context_log = QLoggingCategory("qt.webenginecontext") + web_engine_context_log = QLoggingCategory("qt.webenginecontext") # type: ignore web_engine_context_log.setFilterRules("*.info=false") QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_ShareOpenGLContexts) QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL) @@ -794,7 +794,6 @@ def main(passed_args: Optional[Tuple[str, ...]] = None) -> int: QQuickStyle.setStyle("Material") # We specifically *don't* want the RobotoCondensed-Bold.ttf font so we get the right look when bolded. - qmlRegisterType(ConnectionData, "SwiftConsole", 1, 0, "ConnectionData") # type: ignore qmlRegisterType(AdvancedImuPoints, "SwiftConsole", 1, 0, "AdvancedImuPoints") # type: ignore qmlRegisterType(AdvancedMagnetometerPoints, "SwiftConsole", 1, 0, "AdvancedMagnetometerPoints") # type: ignore From b6585321217050c8ae78aa8a3bdf41b71f17b336 Mon Sep 17 00:00:00 2001 From: John Michael Burke Date: Tue, 30 Jul 2024 20:01:49 -0700 Subject: [PATCH 3/5] revert unnecessary changes --- swiftnav_console/main.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/swiftnav_console/main.py b/swiftnav_console/main.py index 94cfaa29c..3bf120525 100644 --- a/swiftnav_console/main.py +++ b/swiftnav_console/main.py @@ -44,10 +44,10 @@ from PySide6.QtWidgets import QApplication, QSplashScreen # type: ignore -from PySide6.QtCore import QCoreApplication, QLoggingCategory, QObject, QUrl, QThread, QTimer, Slot, Signal, Qt, QLocale +from PySide6.QtCore import QLoggingCategory, QObject, QUrl, QThread, QTimer, Slot, Signal, Qt, QLocale from PySide6 import QtCharts # pylint: disable=unused-import -from PySide6 import QtQml +from PySide6 import QtQml, QtCore from PySide6.QtGui import QFontDatabase, QIcon, QPixmap @@ -771,7 +771,7 @@ def main(passed_args: Optional[Tuple[str, ...]] = None) -> int: found_help_arg = True args_main, _ = parser.parse_known_args(passed_args) if args_main.no_high_dpi: - QCoreApplication.setAttribute(Qt.AA_Use96Dpi) # type: ignore + QtCore.QCoreApplication.setAttribute(Qt.AA_Use96Dpi) # type: ignore if args_main.qmldebug: sys.argv.append("-qmljsdebugger=port:10002,block") debug = QQmlDebuggingEnabler() # pylint: disable=unused-variable @@ -780,8 +780,8 @@ def main(passed_args: Optional[Tuple[str, ...]] = None) -> int: # Silence webengine context logging. web_engine_context_log = QLoggingCategory("qt.webenginecontext") # type: ignore web_engine_context_log.setFilterRules("*.info=false") - QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_ShareOpenGLContexts) - QCoreApplication.setAttribute(Qt.ApplicationAttribute.AA_UseDesktopOpenGL) + QtCore.QCoreApplication.setAttribute(QtCore.Qt.ApplicationAttribute.AA_ShareOpenGLContexts) + QtCore.QCoreApplication.setAttribute(QtCore.Qt.ApplicationAttribute.AA_UseDesktopOpenGL) QtWebEngineQuick.initialize() app = QApplication(sys.argv) app.setWindowIcon(QIcon(":/images/icon.ico")) From 7ceb8bdae28307ee59c6d40edd31724523bc39bb Mon Sep 17 00:00:00 2001 From: John Michael Burke Date: Wed, 31 Jul 2024 11:40:04 -0700 Subject: [PATCH 4/5] Mute errors when map not available --- resources/SolutionTab.qml | 1 + resources/web/map/js/trajectory_raw.js | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/resources/SolutionTab.qml b/resources/SolutionTab.qml index 14125a7e7..46efa2a23 100644 --- a/resources/SolutionTab.qml +++ b/resources/SolutionTab.qml @@ -58,6 +58,7 @@ MainTab { } SolutionTabComponents.SolutionMapTab { + visible: Globals.enableMap } } } diff --git a/resources/web/map/js/trajectory_raw.js b/resources/web/map/js/trajectory_raw.js index 0007801ff..ffc805773 100644 --- a/resources/web/map/js/trajectory_raw.js +++ b/resources/web/map/js/trajectory_raw.js @@ -130,7 +130,9 @@ function setupLayers() { } function syncCrumbCoords(){ - map.getSource('breadcrumb').setData({ + let breadcrumb = map.getSource('breadcrumb'); + if (breadcrumb === undefined) return; + breadcrumb.setData({ type: 'Feature', geometry: { type: 'LineString', @@ -142,10 +144,12 @@ function syncCrumbCoords(){ function syncLayers() { // sync route datas with stored points for (let i = 0; i < lines.length; i++) { - map.getSource(`route${i}`).setData(data[i]); + let route = map.getSource(`route${i}`); + if (route !== undefined) route.setData(data[i]); } // clear protection, since its only one point and temporary - map.getSource('prot').setData({ + let prot = map.getSource('prot'); + if (prot !== undefined) prot.setData({ type: 'FeatureCollection', features: [] }); From fb18a5807820746aa91ec8a49466e7a3785e76f3 Mon Sep 17 00:00:00 2001 From: John Michael Burke Date: Wed, 31 Jul 2024 12:56:35 -0700 Subject: [PATCH 5/5] Reenable map always --- console_backend/src/cli_options.rs | 4 ---- resources/Constants/Globals.qml | 1 - resources/SolutionTab.qml | 3 +-- resources/web/map/js/trajectory_raw.js | 30 +++++++++++++++++++++----- swiftnav_console/main.py | 3 --- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/console_backend/src/cli_options.rs b/console_backend/src/cli_options.rs index b332a06cd..922086177 100644 --- a/console_backend/src/cli_options.rs +++ b/console_backend/src/cli_options.rs @@ -109,10 +109,6 @@ pub struct CliOptions { #[clap(long)] pub show_file_connection: bool, - /// Enable map. - #[clap(long)] - pub enable_map: bool, - /// Enable ntrip client #[clap(long)] pub enable_ntrip: bool, diff --git a/resources/Constants/Globals.qml b/resources/Constants/Globals.qml index 012777154..1db2d579e 100644 --- a/resources/Constants/Globals.qml +++ b/resources/Constants/Globals.qml @@ -33,7 +33,6 @@ QtObject { property int initialSubTabIndex: 0 // Signals property bool showCsvLog: false property bool showFileio: false - property bool enableMap: false property int height: 600 property int minimumHeight: 600 property int width: 1000 diff --git a/resources/SolutionTab.qml b/resources/SolutionTab.qml index 46efa2a23..c6949212f 100644 --- a/resources/SolutionTab.qml +++ b/resources/SolutionTab.qml @@ -30,7 +30,7 @@ import "SolutionTabComponents" as SolutionTabComponents MainTab { id: solutionTab - subTabNames: Globals.enableMap ? ["Position", "Velocity", "Map"] : ["Position", "Velocity"] + subTabNames: ["Position", "Velocity", "Map"] curSubTabIndex: 0 SplitView { @@ -58,7 +58,6 @@ MainTab { } SolutionTabComponents.SolutionMapTab { - visible: Globals.enableMap } } } diff --git a/resources/web/map/js/trajectory_raw.js b/resources/web/map/js/trajectory_raw.js index ffc805773..29e39cc47 100644 --- a/resources/web/map/js/trajectory_raw.js +++ b/resources/web/map/js/trajectory_raw.js @@ -2,16 +2,21 @@ import mapboxGlStyleSwitcher from 'https://cdn.skypack.dev/mapbox-gl-style-switc const lines = ["#FF0000", "#FF00FF", "#00FFFF", "#0000FF", "#00FF00", "#000000"]; const LNG_KM = 111.320, LAT_KM = 110.574; +const mapContainer = 'map'; +const mapStyle = "mapbox://styles/mapbox/light-v11?optimize=true"; +const mapCenter = [-122.486052, 37.830348]; // Initial focus coordinate +const mapZoom = 16; +const mapPerformanceMetricsCollection = false; function decode(r){var n=r,t=[0,10,13,34,38,92],e=new Uint8Array(1.75*n.length|0),f=0,o=0,a=0;function i(r){o|=(r<<=1)>>>a,8<=(a+=7)&&(e[f++]=o,o=r<<7-(a-=8)&255)}for(var u=0;u>>8&7)&&i(t[c]),i(127&d)):i(d)}r=new Uint8Array(e,0,f);var s=new TextDecoder().decode(r);while (s.slice(-1)=="\x00") s=s.slice(0,-1); return s;} mapboxgl.accessToken = decode("@ACCESS_TOKEN@"); var map = new mapboxgl.Map({ - container: 'map', - style: "mapbox://styles/mapbox/light-v11?optimize=true", - center: [-122.486052, 37.830348], // Initial focus coordinate - zoom: 16, - performanceMetricsCollection: false, + container: mapContainer, + style: mapStyle, + center: mapCenter, + zoom: mapZoom, + performanceMetricsCollection: mapPerformanceMetricsCollection, }); var focusCurrent = false; @@ -243,3 +248,18 @@ map.on('load', () => { console.log("loaded"); setupLayers(); }); + +map.on('error', () => { + if (mapboxgl.accessToken != "@ACCESS_TOKEN@") { + console.log("Attempting to use local environment variable MAPBOX_TOKEN"); + mapboxgl.accessToken = "@ACCESS_TOKEN@"; + map.remove(); + map = new mapboxgl.Map({ + container: mapContainer, + style: mapStyle, + center: mapCenter, + zoom: mapZoom, + performanceMetricsCollection: mapPerformanceMetricsCollection, + }); + } +}); diff --git a/swiftnav_console/main.py b/swiftnav_console/main.py index 3bf120525..c9ccc9243 100644 --- a/swiftnav_console/main.py +++ b/swiftnav_console/main.py @@ -667,8 +667,6 @@ def handle_cli_arguments(args: argparse.Namespace, globals_: QObject): globals_.setProperty("width", args.width) # type: ignore if args.show_file_connection: globals_.setProperty("showFileConnection", True) # type: ignore - if args.enable_map: - globals_.setProperty("enableMap", True) # type: ignore if args.enable_ntrip: globals_.setProperty("enableNtrip", True) # type: ignore try: @@ -729,7 +727,6 @@ def main(passed_args: Optional[Tuple[str, ...]] = None) -> int: parser.add_argument("--record-capnp-recording", action="store_true") parser.add_argument("--debug-with-no-backend", action="store_true") parser.add_argument("--show-fileio", action="store_true") - parser.add_argument("--enable-map", action="store_true") parser.add_argument("--show-file-connection", action="store_true") parser.add_argument("--no-prompts", action="store_true") parser.add_argument("--use-opengl", action="store_true")