mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 03:50:05 +00:00 
			
		
		
		
	Merge pull request #153 from dpaulat/feature/maplibre-native-qt
Update MapLibre Native Qt
This commit is contained in:
		
						commit
						69e92848d2
					
				
					 96 changed files with 1236 additions and 626 deletions
				
			
		
							
								
								
									
										17
									
								
								.github/workflows/ci.yml
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.github/workflows/ci.yml
									
										
									
									
										vendored
									
									
								
							|  | @ -28,7 +28,7 @@ jobs: | |||
|             compiler: msvc | ||||
|             msvc_arch: x64 | ||||
|             msvc_version: 2022 | ||||
|             qt_version: 6.6.1 | ||||
|             qt_version: 6.6.2 | ||||
|             qt_arch: win64_msvc2019_64 | ||||
|             qt_modules: qtimageformats qtmultimedia qtpositioning | ||||
|             qt_tools: '' | ||||
|  | @ -44,7 +44,7 @@ jobs: | |||
|             env_cc: gcc-11 | ||||
|             env_cxx: g++-11 | ||||
|             compiler: gcc | ||||
|             qt_version: 6.6.1 | ||||
|             qt_version: 6.6.2 | ||||
|             qt_arch: gcc_64 | ||||
|             qt_modules: qtimageformats qtmultimedia qtpositioning | ||||
|             qt_tools: '' | ||||
|  | @ -136,8 +136,8 @@ jobs: | |||
|         objcopy --strip-debug --strip-unneeded supercell-wx | ||||
|         cd .. | ||||
|         cd lib/ | ||||
|         objcopy --only-keep-debug libQMapLibreGL.so libQMapLibreGL.so.debug | ||||
|         objcopy --strip-debug --strip-unneeded libQMapLibreGL.so | ||||
|         objcopy --only-keep-debug libQMapLibre.so libQMapLibre.so.debug | ||||
|         objcopy --strip-debug --strip-unneeded libQMapLibre.so | ||||
| 
 | ||||
|     - name: Install Supercell Wx | ||||
|       shell: pwsh | ||||
|  | @ -229,4 +229,11 @@ jobs: | |||
|       env: | ||||
|         MAPBOX_API_KEY:   ${{ secrets.MAPBOX_API_KEY }} | ||||
|         MAPTILER_API_KEY: ${{ secrets.MAPTILER_API_KEY }} | ||||
|       run: ctest -C ${{ matrix.build_type }} --exclude-regex mbgl-test-runner | ||||
|       run: ctest -C ${{ matrix.build_type }} --exclude-regex test_mln.* | ||||
| 
 | ||||
|     - name: Upload Test Logs | ||||
|       if: ${{ !cancelled() }} | ||||
|       uses: actions/upload-artifact@v4 | ||||
|       with: | ||||
|         name: supercell-wx-test-logs-${{ matrix.name }} | ||||
|         path: ${{ github.workspace }}/build/Testing/ | ||||
|  |  | |||
							
								
								
									
										9
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							|  | @ -1,6 +1,3 @@ | |||
| [submodule "external/mapbox-gl-native"] | ||||
| 	path = external/mapbox-gl-native | ||||
| 	url = https://github.com/dpaulat/maplibre-gl-native.git | ||||
| [submodule "external/cmake-conan"] | ||||
| 	path = external/cmake-conan | ||||
| 	url = https://github.com/conan-io/cmake-conan.git | ||||
|  | @ -34,3 +31,9 @@ | |||
| [submodule "external/textflowcpp"] | ||||
| 	path = external/textflowcpp | ||||
| 	url = https://github.com/catchorg/textflowcpp.git | ||||
| [submodule "external/maplibre-native-qt"] | ||||
| 	path = external/maplibre-native-qt | ||||
| 	url = https://github.com/dpaulat/maplibre-native-qt.git | ||||
| [submodule "external/maplibre-native"] | ||||
| 	path = external/maplibre-native | ||||
| 	url = https://github.com/dpaulat/maplibre-gl-native.git | ||||
|  |  | |||
|  | @ -67,6 +67,7 @@ Supercell Wx uses assets from the following sources: | |||
| | [Font Awesome Free](https://fontawesome.com/) | CC BY 4.0 License | | ||||
| | [Inconsolata](https://fonts.google.com/specimen/Inconsolata) | SIL Open Font License | | ||||
| | [NOAA's Weather and Climate Toolkit](https://www.ncdc.noaa.gov/wct/) | Public Domain | Default Color Tables | | ||||
| | [Roboto Flex](https://fonts.google.com/specimen/Roboto+Flex) | SIL Open Font License | | ||||
| | [Supercell thunderstorm with dramatic clouds](https://www.shutterstock.com/image-photo/supercell-thunderstorm-dramatic-clouds-1354353521) | Shutterstock Standard License | Photo by John Sirlin | ||||
| 
 | ||||
| Services | ||||
|  |  | |||
|  | @ -48,3 +48,5 @@ add_subdirectory(external) | |||
| add_subdirectory(wxdata) | ||||
| add_subdirectory(scwx-qt) | ||||
| add_subdirectory(test) | ||||
| 
 | ||||
| set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER CMakePredefinedTargets) | ||||
|  |  | |||
							
								
								
									
										4
									
								
								external/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								external/CMakeLists.txt
									
										
									
									
										vendored
									
									
								
							|  | @ -8,7 +8,7 @@ set_property(DIRECTORY | |||
|              date.cmake | ||||
|              hsluv-c.cmake | ||||
|              imgui.cmake | ||||
|              mapbox-gl-native.cmake | ||||
|              maplibre-native-qt.cmake | ||||
|              stb.cmake | ||||
|              textflowcpp.cmake | ||||
|              units.cmake) | ||||
|  | @ -17,7 +17,7 @@ include(aws-sdk-cpp.cmake) | |||
| include(date.cmake) | ||||
| include(hsluv-c.cmake) | ||||
| include(imgui.cmake) | ||||
| include(mapbox-gl-native.cmake) | ||||
| include(maplibre-native-qt.cmake) | ||||
| include(stb.cmake) | ||||
| include(textflowcpp.cmake) | ||||
| include(units.cmake) | ||||
|  |  | |||
							
								
								
									
										1
									
								
								external/mapbox-gl-native
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								external/mapbox-gl-native
									
										
									
									
										vendored
									
									
								
							|  | @ -1 +0,0 @@ | |||
| Subproject commit 3e85454fe5e571e7b235131912bb867ef9d75c3c | ||||
							
								
								
									
										48
									
								
								external/mapbox-gl-native.cmake
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										48
									
								
								external/mapbox-gl-native.cmake
									
										
									
									
										vendored
									
									
								
							|  | @ -1,48 +0,0 @@ | |||
| cmake_minimum_required(VERSION 3.20) | ||||
| set(PROJECT_NAME scwx-mbgl) | ||||
| 
 | ||||
| set(gtest_disable_pthreads ON) | ||||
| set(MLN_WITH_QT ON) | ||||
| set(MLN_QT_WITH_INTERNAL_ICU ON) | ||||
| add_subdirectory(mapbox-gl-native) | ||||
| 
 | ||||
| find_package(ZLIB) | ||||
| target_include_directories(mbgl-core PRIVATE ${ZLIB_INCLUDE_DIRS}) | ||||
| target_link_libraries(mbgl-core INTERFACE ${ZLIB_LIBRARIES}) | ||||
| 
 | ||||
| if (MSVC) | ||||
|     # Produce PDB file for debug | ||||
|     target_compile_options(mbgl-core PRIVATE "$<$<CONFIG:Release>:/Zi>") | ||||
|     target_compile_options(qmaplibregl PRIVATE "$<$<CONFIG:Release>:/Zi>") | ||||
|     target_link_options(qmaplibregl PRIVATE "$<$<CONFIG:Release>:/DEBUG>") | ||||
|     target_link_options(qmaplibregl PRIVATE "$<$<CONFIG:Release>:/OPT:REF>") | ||||
|     target_link_options(qmaplibregl PRIVATE "$<$<CONFIG:Release>:/OPT:ICF>") | ||||
| else() | ||||
|     target_compile_options(mbgl-core PRIVATE "$<$<CONFIG:Release>:-g>") | ||||
|     target_compile_options(qmaplibregl PRIVATE "$<$<CONFIG:Release>:-g>") | ||||
| endif() | ||||
| 
 | ||||
| set(MBGL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mapbox-gl-native/include | ||||
|                      ${CMAKE_CURRENT_SOURCE_DIR}/mapbox-gl-native/platform/qt/include PARENT_SCOPE) | ||||
| 
 | ||||
| set_target_properties(mbgl-qt PROPERTIES EXCLUDE_FROM_ALL True) | ||||
| set_target_properties(mbgl-test-runner PROPERTIES EXCLUDE_FROM_ALL True) | ||||
| 
 | ||||
| set_target_properties(mbgl-benchmark PROPERTIES FOLDER mbgl/exclude) | ||||
| set_target_properties(mbgl-render-test PROPERTIES FOLDER mbgl/exclude) | ||||
| set_target_properties(mbgl-test PROPERTIES FOLDER mbgl/exclude) | ||||
| set_target_properties(mbgl-vendor-benchmark PROPERTIES FOLDER mbgl/exclude) | ||||
| set_target_properties(mbgl-vendor-googletest PROPERTIES FOLDER mbgl/exclude) | ||||
| set_target_properties(mbgl-core-license PROPERTIES FOLDER mbgl/exclude) | ||||
| set_target_properties(mbgl-qt PROPERTIES FOLDER mbgl/exclude) | ||||
| set_target_properties(mbgl-test-runner PROPERTIES FOLDER mbgl/exclude) | ||||
| 
 | ||||
| if (TARGET mbgl-qt-docs) | ||||
|     set_target_properties(mbgl-qt-docs PROPERTIES FOLDER mbgl/exclude) | ||||
| endif() | ||||
| 
 | ||||
| set_target_properties(mbgl-core PROPERTIES FOLDER mbgl) | ||||
| set_target_properties(mbgl-vendor-csscolorparser PROPERTIES FOLDER mbgl) | ||||
| set_target_properties(mbgl-vendor-nunicode PROPERTIES FOLDER mbgl) | ||||
| set_target_properties(mbgl-vendor-parsedate PROPERTIES FOLDER mbgl) | ||||
| set_target_properties(qmaplibregl PROPERTIES FOLDER mbgl) | ||||
							
								
								
									
										1
									
								
								external/maplibre-native
									
										
									
									
										vendored
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								external/maplibre-native
									
										
									
									
										vendored
									
									
										Submodule
									
								
							|  | @ -0,0 +1 @@ | |||
| Subproject commit 6932d9b49cf01ac75b79aff9f9a9f0f9ce97a9ae | ||||
							
								
								
									
										1
									
								
								external/maplibre-native-qt
									
										
									
									
										vendored
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								external/maplibre-native-qt
									
										
									
									
										vendored
									
									
										Submodule
									
								
							|  | @ -0,0 +1 @@ | |||
| Subproject commit fe734916414ce761e053dafaeecafeb19d51509c | ||||
							
								
								
									
										47
									
								
								external/maplibre-native-qt.cmake
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								external/maplibre-native-qt.cmake
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | |||
| cmake_minimum_required(VERSION 3.20) | ||||
| set(PROJECT_NAME scwx-mln) | ||||
| 
 | ||||
| set(gtest_disable_pthreads ON) | ||||
| set(MLN_WITH_QT ON) | ||||
| set(MLN_QT_WITH_INTERNAL_ICU ON) | ||||
| set(MLN_QT_WITH_LOCATION OFF) | ||||
| set(MLN_CORE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/maplibre-native) | ||||
| add_subdirectory(maplibre-native-qt) | ||||
| 
 | ||||
| find_package(ZLIB) | ||||
| target_include_directories(mbgl-core PRIVATE ${ZLIB_INCLUDE_DIRS}) | ||||
| target_link_libraries(mbgl-core INTERFACE ${ZLIB_LIBRARIES}) | ||||
| 
 | ||||
| if (MSVC) | ||||
|     # Produce PDB file for debug | ||||
|     target_compile_options(mbgl-core PRIVATE "$<$<CONFIG:Release>:/Zi>") | ||||
|     target_compile_options(Core PRIVATE "$<$<CONFIG:Release>:/Zi>") | ||||
|     target_link_options(Core PRIVATE "$<$<CONFIG:Release>:/DEBUG>") | ||||
|     target_link_options(Core PRIVATE "$<$<CONFIG:Release>:/OPT:REF>") | ||||
|     target_link_options(Core PRIVATE "$<$<CONFIG:Release>:/OPT:ICF>") | ||||
| else() | ||||
|     target_compile_options(mbgl-core PRIVATE "$<$<CONFIG:Release>:-g>") | ||||
|     target_compile_options(Core PRIVATE "$<$<CONFIG:Release>:-g>") | ||||
| endif() | ||||
| 
 | ||||
| set(MLN_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/maplibre-native/include | ||||
|                      ${CMAKE_CURRENT_SOURCE_DIR}/maplibre-native-qt/src/core/include | ||||
|                      ${CMAKE_CURRENT_BINARY_DIR}/maplibre-native-qt/src/core/include PARENT_SCOPE) | ||||
| 
 | ||||
| set_target_properties(test_mln_core PROPERTIES EXCLUDE_FROM_ALL True) | ||||
| set_target_properties(test_mln_widgets PROPERTIES EXCLUDE_FROM_ALL True) | ||||
| set_target_properties(Widgets PROPERTIES EXCLUDE_FROM_ALL True) | ||||
| 
 | ||||
| set_target_properties(test_mln_core PROPERTIES FOLDER mln/exclude) | ||||
| set_target_properties(test_mln_widgets PROPERTIES FOLDER mln/exclude) | ||||
| set_target_properties(Widgets PROPERTIES FOLDER mln/exclude) | ||||
| 
 | ||||
| set_target_properties(Core PROPERTIES FOLDER mln) | ||||
| set_target_properties(mbgl-core PROPERTIES FOLDER mln) | ||||
| set_target_properties(mbgl-vendor-csscolorparser PROPERTIES FOLDER mln) | ||||
| set_target_properties(mbgl-vendor-nunicode PROPERTIES FOLDER mln) | ||||
| set_target_properties(mbgl-vendor-parsedate PROPERTIES FOLDER mln) | ||||
| 
 | ||||
| if (TARGET mbgl-vendor-sqlite) | ||||
|     set_target_properties(mbgl-vendor-sqlite PROPERTIES FOLDER mln) | ||||
| endif() | ||||
|  | @ -25,6 +25,7 @@ out VertexData | |||
|    vec3  texCoord; | ||||
|    vec4  color; | ||||
|    ivec2 timeRange; | ||||
|    bool  displayed; | ||||
| } vsOut; | ||||
| 
 | ||||
| smooth out vec3 texCoord; | ||||
|  | @ -41,6 +42,9 @@ vec2 latLngToScreenCoordinate(in vec2 latLng) | |||
| 
 | ||||
| void main() | ||||
| { | ||||
|    // Always set displayed to true | ||||
|    vsOut.displayed = true; | ||||
| 
 | ||||
|    // Pass the threshold and time range to the geometry shader | ||||
|    vsOut.threshold = aThreshold; | ||||
|    vsOut.timeRange = aTimeRange; | ||||
|  |  | |||
|  | @ -16,12 +16,16 @@ out VertexData | |||
|    vec3  texCoord; | ||||
|    vec4  color; | ||||
|    ivec2 timeRange; | ||||
|    bool  displayed; | ||||
| } vsOut; | ||||
| 
 | ||||
| smooth out vec4 color; | ||||
| 
 | ||||
| void main() | ||||
| { | ||||
|    // Always set displayed to true | ||||
|    vsOut.displayed = true; | ||||
| 
 | ||||
|    // Pass the threshold and time range to the geometry shader | ||||
|    vsOut.threshold = aThreshold; | ||||
|    vsOut.timeRange = aTimeRange; | ||||
|  |  | |||
|  | @ -7,20 +7,42 @@ layout (location = 1) in vec2  aXYOffset; | |||
| layout (location = 2) in vec3  aTexCoord; | ||||
| layout (location = 3) in vec4  aModulate; | ||||
| layout (location = 4) in float aAngleDeg; | ||||
| layout (location = 5) in int   aDisplayed; | ||||
| 
 | ||||
| uniform mat4 uMVPMatrix; | ||||
| 
 | ||||
| out VertexData | ||||
| { | ||||
|    int   threshold; | ||||
|    vec3  texCoord; | ||||
|    vec4  color; | ||||
|    ivec2 timeRange; | ||||
|    bool  displayed; | ||||
| } vsOut; | ||||
| 
 | ||||
| smooth out vec3 texCoord; | ||||
| smooth out vec4 color; | ||||
| 
 | ||||
| void main() | ||||
| { | ||||
|    // Always set threshold and time range to zero | ||||
|    vsOut.threshold = 0; | ||||
|    vsOut.timeRange = ivec2(0, 0); | ||||
| 
 | ||||
|    // Pass displayed to the geometry shader | ||||
|    vsOut.displayed = (aDisplayed != 0); | ||||
| 
 | ||||
|    // Pass the texture coordinate and color modulate to the geometry and | ||||
|    // fragment shaders | ||||
|    vsOut.texCoord = aTexCoord; | ||||
|    vsOut.color    = aModulate; | ||||
|    texCoord       = aTexCoord; | ||||
|    color          = aModulate; | ||||
| 
 | ||||
|    // Rotate clockwise | ||||
|    float angle  = aAngleDeg * DEG2RAD; | ||||
|    mat2  rotate = mat2(cos(angle), -sin(angle), | ||||
|                        sin(angle), cos(angle)); | ||||
| 
 | ||||
|    gl_Position = uMVPMatrix * vec4(aVertex + rotate * aXYOffset, 0.0f, 1.0f); | ||||
|    texCoord    = aTexCoord; | ||||
|    color       = aModulate; | ||||
| } | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ in VertexData | |||
|    vec3  texCoord; | ||||
|    vec4  color; | ||||
|    ivec2 timeRange; | ||||
|    bool  displayed; | ||||
| } gsIn[]; | ||||
| 
 | ||||
| smooth out vec3 texCoord; | ||||
|  | @ -19,7 +20,8 @@ smooth out vec4 color; | |||
| 
 | ||||
| void main() | ||||
| { | ||||
|    if ((gsIn[0].threshold <= 0 ||            // If Threshold: 0 was specified, no threshold | ||||
|    if (gsIn[0].displayed && | ||||
|        (gsIn[0].threshold <= 0 ||            // If Threshold: 0 was specified, no threshold | ||||
|         gsIn[0].threshold >= uMapDistance || // If Threshold is above current map distance | ||||
|         gsIn[0].threshold >= 999) &&         // If Threshold: 999 was specified (or greater), no threshold | ||||
|        (gsIn[0].timeRange[0] == 0 ||              // If there is no start time specified | ||||
|  |  | |||
							
								
								
									
										
											BIN
										
									
								
								scwx-qt/res/fonts/RobotoFlex-Regular.ttf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								scwx-qt/res/fonts/RobotoFlex-Regular.ttf
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										1
									
								
								scwx-qt/res/textures/images/mapbox-logo.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								scwx-qt/res/textures/images/mapbox-logo.svg
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| After Width: | Height: | Size: 8.7 KiB | 
							
								
								
									
										13
									
								
								scwx-qt/res/textures/images/maptiler-logo.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								scwx-qt/res/textures/images/maptiler-logo.svg
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| After Width: | Height: | Size: 16 KiB | 
|  | @ -28,6 +28,7 @@ find_package(QT NAMES Qt6 | |||
|                         OpenGL | ||||
|                         OpenGLWidgets | ||||
|                         Positioning | ||||
|                         Svg | ||||
|                         Widgets REQUIRED) | ||||
| 
 | ||||
| find_package(Qt${QT_VERSION_MAJOR} | ||||
|  | @ -38,6 +39,7 @@ find_package(Qt${QT_VERSION_MAJOR} | |||
|                         OpenGL | ||||
|                         OpenGLWidgets | ||||
|                         Positioning | ||||
|                         Svg | ||||
|                         Widgets | ||||
|              REQUIRED) | ||||
| 
 | ||||
|  | @ -470,7 +472,10 @@ set_target_properties(release_translations PROPERTIES FOLDER qt) | |||
| set_target_properties(scwx-qt_lrelease     PROPERTIES FOLDER qt) | ||||
| set_target_properties(scwx-qt_lupdate      PROPERTIES FOLDER qt) | ||||
| set_target_properties(scwx-qt_other_files  PROPERTIES FOLDER qt) | ||||
| 
 | ||||
| if (TARGET update_translations) | ||||
|     set_target_properties(update_translations PROPERTIES FOLDER qt) | ||||
| endif() | ||||
| 
 | ||||
| set_target_properties(scwx-qt_generate_counties_db PROPERTIES FOLDER generate) | ||||
| set_target_properties(scwx-qt_generate_versions    PROPERTIES FOLDER generate) | ||||
|  | @ -496,7 +501,7 @@ endif() | |||
| target_include_directories(scwx-qt PUBLIC ${scwx-qt_SOURCE_DIR}/source | ||||
|                                           ${FTGL_INCLUDE_DIR} | ||||
|                                           ${IMGUI_INCLUDE_DIRS} | ||||
|                                           ${MBGL_INCLUDE_DIR} | ||||
|                                           ${MLN_INCLUDE_DIRS} | ||||
|                                           ${STB_INCLUDE_DIR} | ||||
|                                           ${TEXTFLOWCPP_INCLUDE_DIR}) | ||||
| 
 | ||||
|  | @ -552,9 +557,10 @@ target_link_libraries(scwx-qt PUBLIC Qt${QT_VERSION_MAJOR}::Widgets | |||
|                                      Qt${QT_VERSION_MAJOR}::OpenGLWidgets | ||||
|                                      Qt${QT_VERSION_MAJOR}::Multimedia | ||||
|                                      Qt${QT_VERSION_MAJOR}::Positioning | ||||
|                                      Qt${QT_VERSION_MAJOR}::Svg | ||||
|                                      Boost::json | ||||
|                                      Boost::timer | ||||
|                                      qmaplibregl | ||||
|                                      QMapLibre::Core | ||||
|                                      $<$<CXX_COMPILER_ID:MSVC>:opengl32> | ||||
|                                      Fontconfig::Fontconfig | ||||
|                                      GeographicLib::GeographicLib | ||||
|  | @ -570,11 +576,11 @@ target_link_libraries(supercell-wx PRIVATE scwx-qt | |||
|                                            wxdata) | ||||
| 
 | ||||
| # Set DT_RUNPATH for Linux targets | ||||
| set_target_properties(qmaplibregl  PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") | ||||
| set_target_properties(Core         PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") # QMapLibre::Core | ||||
| set_target_properties(supercell-wx PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") | ||||
| 
 | ||||
| install(TARGETS supercell-wx | ||||
|                 qmaplibregl | ||||
|                 Core # QMapLibre::Core | ||||
|         RUNTIME_DEPENDENCIES | ||||
|           PRE_EXCLUDE_REGEXES "api-ms-" "ext-ms-" "qt6" | ||||
|           POST_EXCLUDE_REGEXES ".*system32/.*\\.dll" | ||||
|  | @ -587,8 +593,8 @@ install(TARGETS supercell-wx | |||
| 
 | ||||
| # NO_TRANSLATIONS is needed for Qt 6.5.0 (will be fixed in 6.5.1) | ||||
| # https://bugreports.qt.io/browse/QTBUG-112204 | ||||
| qt_generate_deploy_app_script(TARGET qmaplibregl | ||||
|                               OUTPUT_SCRIPT deploy_script_qmaplibregl | ||||
| qt_generate_deploy_app_script(TARGET Core # QMapLibre::Core | ||||
|                               OUTPUT_SCRIPT deploy_script_qmaplibre_core | ||||
|                               NO_TRANSLATIONS | ||||
|                               NO_UNSUPPORTED_PLATFORM_ERROR) | ||||
| 
 | ||||
|  | @ -597,7 +603,7 @@ qt_generate_deploy_app_script(TARGET supercell-wx | |||
|                               NO_TRANSLATIONS | ||||
|                               NO_UNSUPPORTED_PLATFORM_ERROR) | ||||
| 
 | ||||
| install(SCRIPT ${deploy_script_qmaplibregl} | ||||
| install(SCRIPT ${deploy_script_qmaplibre_core} | ||||
|         COMPONENT supercell-wx) | ||||
| 
 | ||||
| install(SCRIPT ${deploy_script_scwx} | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
|         <file>res/fonts/din1451alt.ttf</file> | ||||
|         <file>res/fonts/din1451alt_g.ttf</file> | ||||
|         <file>res/fonts/Inconsolata-Regular.ttf</file> | ||||
|         <file>res/fonts/RobotoFlex-Regular.ttf</file> | ||||
|         <file>res/icons/scwx-64.png</file> | ||||
|         <file>res/icons/scwx-256.ico</file> | ||||
|         <file>res/icons/scwx-256.png</file> | ||||
|  | @ -69,5 +70,7 @@ | |||
|         <file>res/textures/lines/default-1x7.png</file> | ||||
|         <file>res/textures/lines/test-pattern.png</file> | ||||
|         <file>res/textures/images/crosshairs-24.png</file> | ||||
|         <file>res/textures/images/mapbox-logo.svg</file> | ||||
|         <file>res/textures/images/maptiler-logo.svg</file> | ||||
|     </qresource> | ||||
| </RCC> | ||||
|  |  | |||
|  | @ -43,18 +43,18 @@ DrawItem::DrawItem(DrawItem&&) noexcept            = default; | |||
| DrawItem& DrawItem::operator=(DrawItem&&) noexcept = default; | ||||
| 
 | ||||
| void DrawItem::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& /* params */) | ||||
|    const QMapLibre::CustomLayerRenderParameters& /* params */) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void DrawItem::Render(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
| void DrawItem::Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                       bool /* textureAtlasChanged */) | ||||
| { | ||||
|    Render(params); | ||||
| } | ||||
| 
 | ||||
| bool DrawItem::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& /* params */, | ||||
|    const QMapLibre::CustomLayerRenderParameters& /* params */, | ||||
|    const QPointF& /* mouseLocalPos */, | ||||
|    const QPointF& /* mouseGlobalPos */, | ||||
|    const glm::vec2& /* mouseCoords */, | ||||
|  | @ -66,7 +66,7 @@ bool DrawItem::RunMousePicking( | |||
| } | ||||
| 
 | ||||
| void DrawItem::UseDefaultProjection( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    GLint                                         uMVPMatrixLocation) | ||||
| { | ||||
|    glm::mat4 projection = glm::ortho(0.0f, | ||||
|  | @ -79,7 +79,7 @@ void DrawItem::UseDefaultProjection( | |||
| } | ||||
| 
 | ||||
| void DrawItem::UseRotationProjection( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    GLint                                         uMVPMatrixLocation) | ||||
| { | ||||
|    glm::mat4 projection = glm::ortho(0.0f, | ||||
|  | @ -96,7 +96,7 @@ void DrawItem::UseRotationProjection( | |||
| } | ||||
| 
 | ||||
| void DrawItem::UseMapProjection( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    GLint                                         uMVPMatrixLocation, | ||||
|    GLint                                         uMapScreenCoordLocation) | ||||
| { | ||||
|  |  | |||
|  | @ -6,8 +6,8 @@ | |||
| 
 | ||||
| #include <memory> | ||||
| 
 | ||||
| #include <QMapLibreGL/QMapLibreGL> | ||||
| #include <glm/gtc/type_ptr.hpp> | ||||
| #include <qmaplibre.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -31,8 +31,8 @@ public: | |||
|    DrawItem& operator=(DrawItem&&) noexcept; | ||||
| 
 | ||||
|    virtual void Initialize() = 0; | ||||
|    virtual void Render(const QMapLibreGL::CustomLayerRenderParameters& params); | ||||
|    virtual void Render(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    virtual void Render(const QMapLibre::CustomLayerRenderParameters& params); | ||||
|    virtual void Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                        bool textureAtlasChanged); | ||||
|    virtual void Deinitialize() = 0; | ||||
| 
 | ||||
|  | @ -49,7 +49,7 @@ public: | |||
|     * @return true if the draw item was picked, otherwise false | ||||
|     */ | ||||
|    virtual bool | ||||
|    RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    RunMousePicking(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const QPointF&                                mouseLocalPos, | ||||
|                    const QPointF&                                mouseGlobalPos, | ||||
|                    const glm::vec2&                              mouseCoords, | ||||
|  | @ -58,12 +58,12 @@ public: | |||
| 
 | ||||
| protected: | ||||
|    void | ||||
|    UseDefaultProjection(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    UseDefaultProjection(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                         GLint uMVPMatrixLocation); | ||||
|    void | ||||
|    UseRotationProjection(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    UseRotationProjection(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                          GLint uMVPMatrixLocation); | ||||
|    void UseMapProjection(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    void UseMapProjection(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                          GLint uMVPMatrixLocation, | ||||
|                          GLint uMapScreenCoordLocation); | ||||
| 
 | ||||
|  |  | |||
|  | @ -243,7 +243,7 @@ void GeoIcons::Initialize() | |||
|    p->dirty_ = true; | ||||
| } | ||||
| 
 | ||||
| void GeoIcons::Render(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
| void GeoIcons::Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                       bool textureAtlasChanged) | ||||
| { | ||||
|    if (!p->visible_) | ||||
|  | @ -732,7 +732,7 @@ void GeoIcons::Impl::Update(bool textureAtlasChanged) | |||
| } | ||||
| 
 | ||||
| bool GeoIcons::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    const QPointF& /* mouseLocalPos */, | ||||
|    const QPointF&   mouseGlobalPos, | ||||
|    const glm::vec2& mouseCoords, | ||||
|  |  | |||
|  | @ -33,12 +33,12 @@ public: | |||
|    void set_thresholded(bool thresholded); | ||||
| 
 | ||||
|    void Initialize() override; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                bool textureAtlasChanged) override; | ||||
|    void Deinitialize() override; | ||||
| 
 | ||||
|    bool | ||||
|    RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    RunMousePicking(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const QPointF&                                mouseLocalPos, | ||||
|                    const QPointF&                                mouseGlobalPos, | ||||
|                    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -218,7 +218,7 @@ void GeoLines::Initialize() | |||
|    p->dirty_ = true; | ||||
| } | ||||
| 
 | ||||
| void GeoLines::Render(const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
| void GeoLines::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    if (!p->visible_) | ||||
|    { | ||||
|  | @ -513,7 +513,7 @@ void GeoLines::Impl::Update() | |||
| } | ||||
| 
 | ||||
| bool GeoLines::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    const QPointF& /* mouseLocalPos */, | ||||
|    const QPointF&   mouseGlobalPos, | ||||
|    const glm::vec2& mouseCoords, | ||||
|  |  | |||
|  | @ -32,11 +32,11 @@ public: | |||
|    void set_thresholded(bool thresholded); | ||||
| 
 | ||||
|    void Initialize() override; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters& params) override; | ||||
|    void Deinitialize() override; | ||||
| 
 | ||||
|    bool | ||||
|    RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    RunMousePicking(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const QPointF&                                mouseLocalPos, | ||||
|                    const QPointF&                                mouseGlobalPos, | ||||
|                    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| #include <scwx/qt/gl/draw/icons.hpp> | ||||
| #include <scwx/qt/types/icon_types.hpp> | ||||
| #include <scwx/qt/util/maplibre.hpp> | ||||
| #include <scwx/qt/util/texture_atlas.hpp> | ||||
| #include <scwx/qt/util/tooltip.hpp> | ||||
|  | @ -8,6 +7,7 @@ | |||
| #include <execution> | ||||
| 
 | ||||
| #include <boost/unordered/unordered_flat_map.hpp> | ||||
| #include <boost/unordered/unordered_flat_set.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -25,7 +25,7 @@ static constexpr std::size_t kNumRectangles        = 1; | |||
| static constexpr std::size_t kNumTriangles         = kNumRectangles * 2; | ||||
| static constexpr std::size_t kVerticesPerTriangle  = 3; | ||||
| static constexpr std::size_t kVerticesPerRectangle = kVerticesPerTriangle * 2; | ||||
| static constexpr std::size_t kPointsPerVertex      = 9; | ||||
| static constexpr std::size_t kPointsPerVertex      = 10; | ||||
| static constexpr std::size_t kPointsPerTexCoord    = 3; | ||||
| static constexpr std::size_t kIconBufferLength = | ||||
|    kNumTriangles * kVerticesPerTriangle * kPointsPerVertex; | ||||
|  | @ -35,12 +35,15 @@ static constexpr std::size_t kTextureBufferLength = | |||
| struct IconDrawItem : types::EventHandler | ||||
| { | ||||
|    boost::gil::rgba32f_pixel_t modulate_ {1.0f, 1.0f, 1.0f, 1.0f}; | ||||
|    bool                        visible_ {true}; | ||||
|    double                      x_ {}; | ||||
|    double                      y_ {}; | ||||
|    units::degrees<double>      angle_ {}; | ||||
|    std::string                 iconSheet_ {}; | ||||
|    std::size_t                 iconIndex_ {}; | ||||
|    std::string                 hoverText_ {}; | ||||
| 
 | ||||
|    std::shared_ptr<types::IconInfo> iconInfo_ {}; | ||||
| }; | ||||
| 
 | ||||
| class Icons::Impl | ||||
|  | @ -69,7 +72,12 @@ public: | |||
|    ~Impl() {} | ||||
| 
 | ||||
|    void        UpdateBuffers(); | ||||
|    static void UpdateSingleBuffer(const std::shared_ptr<IconDrawItem>& di, | ||||
|                                   std::size_t                  iconIndex, | ||||
|                                   std::vector<float>&          iconBuffer, | ||||
|                                   std::vector<IconHoverEntry>& hoverIcons); | ||||
|    void        UpdateTextureBuffer(); | ||||
|    void        UpdateModifiedIconBuffers(); | ||||
|    void        Update(bool textureAtlasChanged); | ||||
| 
 | ||||
|    std::shared_ptr<GlContext> context_; | ||||
|  | @ -78,11 +86,14 @@ public: | |||
|    bool dirty_ {false}; | ||||
|    bool lastTextureAtlasChanged_ {false}; | ||||
| 
 | ||||
|    boost::unordered_flat_set<std::shared_ptr<IconDrawItem>> dirtyIcons_ {}; | ||||
| 
 | ||||
|    std::mutex iconMutex_; | ||||
| 
 | ||||
|    boost::unordered_flat_map<std::string, types::IconInfo> | ||||
|    boost::unordered_flat_map<std::string, std::shared_ptr<types::IconInfo>> | ||||
|       currentIconSheets_ {}; | ||||
|    boost::unordered_flat_map<std::string, types::IconInfo> newIconSheets_ {}; | ||||
|    boost::unordered_flat_map<std::string, std::shared_ptr<types::IconInfo>> | ||||
|       newIconSheets_ {}; | ||||
| 
 | ||||
|    std::vector<std::shared_ptr<IconDrawItem>> currentIconList_ {}; | ||||
|    std::vector<std::shared_ptr<IconDrawItem>> newIconList_ {}; | ||||
|  | @ -120,6 +131,7 @@ void Icons::Initialize() | |||
| 
 | ||||
|    p->shaderProgram_ = p->context_->GetShaderProgram( | ||||
|       {{GL_VERTEX_SHADER, ":/gl/texture2d_array.vert"}, | ||||
|        {GL_GEOMETRY_SHADER, ":/gl/threshold.geom"}, | ||||
|        {GL_FRAGMENT_SHADER, ":/gl/texture2d_array.frag"}}); | ||||
| 
 | ||||
|    p->uMVPMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMVPMatrix"); | ||||
|  | @ -167,6 +179,15 @@ void Icons::Initialize() | |||
|                             reinterpret_cast<void*>(8 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(4); | ||||
| 
 | ||||
|    // aAngle
 | ||||
|    gl.glVertexAttribPointer(5, | ||||
|                             1, | ||||
|                             GL_FLOAT, | ||||
|                             GL_FALSE, | ||||
|                             kPointsPerVertex * sizeof(float), | ||||
|                             reinterpret_cast<void*>(9 * sizeof(float))); | ||||
|    gl.glEnableVertexAttribArray(5); | ||||
| 
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[1]); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, 0u, nullptr, GL_DYNAMIC_DRAW); | ||||
| 
 | ||||
|  | @ -182,7 +203,7 @@ void Icons::Initialize() | |||
|    p->dirty_ = true; | ||||
| } | ||||
| 
 | ||||
| void Icons::Render(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
| void Icons::Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    bool textureAtlasChanged) | ||||
| { | ||||
|    if (!p->visible_) | ||||
|  | @ -243,17 +264,19 @@ void Icons::StartIconSheets() | |||
|    p->newIconSheets_.clear(); | ||||
| } | ||||
| 
 | ||||
| void Icons::AddIconSheet(const std::string& name, | ||||
| std::shared_ptr<types::IconInfo> Icons::AddIconSheet(const std::string& name, | ||||
|                                                      std::size_t  iconWidth, | ||||
|                                                      std::size_t  iconHeight, | ||||
|                                                      std::int32_t hotX, | ||||
|                                                      std::int32_t hotY) | ||||
| { | ||||
|    // Populate icon sheet map
 | ||||
|    p->newIconSheets_.emplace(std::piecewise_construct, | ||||
|    return p->newIconSheets_ | ||||
|       .emplace(std::piecewise_construct, | ||||
|                std::tuple {name}, | ||||
|                              std::forward_as_tuple(types::IconInfo { | ||||
|                                 name, iconWidth, iconHeight, hotX, hotY})); | ||||
|                std::forward_as_tuple(std::make_shared<types::IconInfo>( | ||||
|                   name, iconWidth, iconHeight, hotX, hotY))) | ||||
|       .first->second; | ||||
| } | ||||
| 
 | ||||
| void Icons::FinishIconSheets() | ||||
|  | @ -261,7 +284,7 @@ void Icons::FinishIconSheets() | |||
|    // Update icon sheets
 | ||||
|    for (auto& iconSheet : p->newIconSheets_) | ||||
|    { | ||||
|       iconSheet.second.UpdateTextureInfo(); | ||||
|       iconSheet.second->UpdateTextureInfo(); | ||||
|    } | ||||
| 
 | ||||
|    std::unique_lock lock {p->iconMutex_}; | ||||
|  | @ -290,12 +313,20 @@ std::shared_ptr<IconDrawItem> Icons::AddIcon() | |||
|    return p->newIconList_.emplace_back(std::make_shared<IconDrawItem>()); | ||||
| } | ||||
| 
 | ||||
| void Icons::SetIconVisible(const std::shared_ptr<IconDrawItem>& di, | ||||
|                            bool                                 visible) | ||||
| { | ||||
|    di->visible_ = visible; | ||||
|    p->dirtyIcons_.insert(di); | ||||
| } | ||||
| 
 | ||||
| void Icons::SetIconTexture(const std::shared_ptr<IconDrawItem>& di, | ||||
|                            const std::string&                   iconSheet, | ||||
|                            std::size_t                          iconIndex) | ||||
| { | ||||
|    di->iconSheet_ = iconSheet; | ||||
|    di->iconIndex_ = iconIndex; | ||||
|    p->dirtyIcons_.insert(di); | ||||
| } | ||||
| 
 | ||||
| void Icons::SetIconLocation(const std::shared_ptr<IconDrawItem>& di, | ||||
|  | @ -304,12 +335,14 @@ void Icons::SetIconLocation(const std::shared_ptr<IconDrawItem>& di, | |||
| { | ||||
|    di->x_ = x; | ||||
|    di->y_ = y; | ||||
|    p->dirtyIcons_.insert(di); | ||||
| } | ||||
| 
 | ||||
| void Icons::SetIconAngle(const std::shared_ptr<IconDrawItem>& di, | ||||
|                          units::angle::degrees<double>        angle) | ||||
| { | ||||
|    di->angle_ = angle; | ||||
|    p->dirtyIcons_.insert(di); | ||||
| } | ||||
| 
 | ||||
| void Icons::SetIconModulate(const std::shared_ptr<IconDrawItem>& di, | ||||
|  | @ -319,18 +352,21 @@ void Icons::SetIconModulate(const std::shared_ptr<IconDrawItem>& di, | |||
|                     modulate[1] / 255.0f, | ||||
|                     modulate[2] / 255.0f, | ||||
|                     modulate[3] / 255.0f}; | ||||
|    p->dirtyIcons_.insert(di); | ||||
| } | ||||
| 
 | ||||
| void Icons::SetIconModulate(const std::shared_ptr<IconDrawItem>& di, | ||||
|                             boost::gil::rgba32f_pixel_t          modulate) | ||||
| { | ||||
|    di->modulate_ = modulate; | ||||
|    p->dirtyIcons_.insert(di); | ||||
| } | ||||
| 
 | ||||
| void Icons::SetIconHoverText(const std::shared_ptr<IconDrawItem>& di, | ||||
|                              const std::string&                   text) | ||||
| { | ||||
|    di->hoverText_ = text; | ||||
|    p->dirtyIcons_.insert(di); | ||||
| } | ||||
| 
 | ||||
| void Icons::FinishIcons() | ||||
|  | @ -373,9 +409,10 @@ void Icons::Impl::UpdateBuffers() | |||
|       } | ||||
| 
 | ||||
|       auto& icon    = it->second; | ||||
|       di->iconInfo_ = icon; | ||||
| 
 | ||||
|       // Validate icon
 | ||||
|       if (di->iconIndex_ >= icon.numIcons_) | ||||
|       if (di->iconIndex_ >= icon->numIcons_) | ||||
|       { | ||||
|          // No icon found
 | ||||
|          logger_->warn("Invalid icon index: {}", di->iconIndex_); | ||||
|  | @ -385,17 +422,33 @@ void Icons::Impl::UpdateBuffers() | |||
|       // Icon is valid, add to valid icon list
 | ||||
|       newValidIconList_.push_back(di); | ||||
| 
 | ||||
|       // Update icon buffer
 | ||||
|       UpdateSingleBuffer( | ||||
|          di, newValidIconList_.size() - 1, newIconBuffer_, newHoverIcons_); | ||||
|    } | ||||
| 
 | ||||
|    // All icons have been updated
 | ||||
|    dirtyIcons_.clear(); | ||||
| } | ||||
| 
 | ||||
| void Icons::Impl::UpdateSingleBuffer(const std::shared_ptr<IconDrawItem>& di, | ||||
|                                      std::size_t                  iconIndex, | ||||
|                                      std::vector<float>&          iconBuffer, | ||||
|                                      std::vector<IconHoverEntry>& hoverIcons) | ||||
| { | ||||
|    auto& icon = di->iconInfo_; | ||||
| 
 | ||||
|    // Base X/Y offsets in pixels
 | ||||
|    const float x = static_cast<float>(di->x_); | ||||
|    const float y = static_cast<float>(di->y_); | ||||
| 
 | ||||
|    // Icon size
 | ||||
|       const float iw = static_cast<float>(icon.iconWidth_); | ||||
|       const float ih = static_cast<float>(icon.iconHeight_); | ||||
|    const float iw = static_cast<float>(icon->iconWidth_); | ||||
|    const float ih = static_cast<float>(icon->iconHeight_); | ||||
| 
 | ||||
|    // Hot X/Y (zero-based icon center)
 | ||||
|       const float hx = static_cast<float>(icon.hotX_); | ||||
|       const float hy = static_cast<float>(icon.hotY_); | ||||
|    const float hx = static_cast<float>(icon->hotX_); | ||||
|    const float hy = static_cast<float>(icon->hotY_); | ||||
| 
 | ||||
|    // Final X/Y offsets in pixels
 | ||||
|    const float lx = std::roundf(-hx); | ||||
|  | @ -413,18 +466,43 @@ void Icons::Impl::UpdateBuffers() | |||
|    const float mc2 = di->modulate_[2]; | ||||
|    const float mc3 = di->modulate_[3]; | ||||
| 
 | ||||
|       newIconBuffer_.insert(newIconBuffer_.end(), | ||||
|                             { | ||||
|                                // Icon
 | ||||
|                                x, y, lx, by, mc0, mc1, mc2, mc3, a, // BL
 | ||||
|                                x, y, lx, ty, mc0, mc1, mc2, mc3, a, // TL
 | ||||
|                                x, y, rx, by, mc0, mc1, mc2, mc3, a, // BR
 | ||||
|                                x, y, rx, by, mc0, mc1, mc2, mc3, a, // BR
 | ||||
|                                x, y, rx, ty, mc0, mc1, mc2, mc3, a, // TR
 | ||||
|                                x, y, lx, ty, mc0, mc1, mc2, mc3, a  // TL
 | ||||
|                             }); | ||||
|    // Visibility
 | ||||
|    const float v = static_cast<float>(di->visible_); | ||||
| 
 | ||||
|       if (!di->hoverText_.empty() || di->event_ != nullptr) | ||||
|    // Icon initializer list data
 | ||||
|    const auto iconData = { | ||||
|       // Icon
 | ||||
|       x, y, lx, by, mc0, mc1, mc2, mc3, a, v, // BL
 | ||||
|       x, y, lx, ty, mc0, mc1, mc2, mc3, a, v, // TL
 | ||||
|       x, y, rx, by, mc0, mc1, mc2, mc3, a, v, // BR
 | ||||
|       x, y, rx, by, mc0, mc1, mc2, mc3, a, v, // BR
 | ||||
|       x, y, rx, ty, mc0, mc1, mc2, mc3, a, v, // TR
 | ||||
|       x, y, lx, ty, mc0, mc1, mc2, mc3, a, v  // TL
 | ||||
|    }; | ||||
| 
 | ||||
|    // Buffer position data
 | ||||
|    auto iconBufferPosition = iconBuffer.end(); | ||||
|    auto iconBufferOffset   = iconIndex * kIconBufferLength; | ||||
| 
 | ||||
|    if (iconBufferOffset < iconBuffer.size()) | ||||
|    { | ||||
|       iconBufferPosition = iconBuffer.begin() + iconBufferOffset; | ||||
|    } | ||||
| 
 | ||||
|    if (iconBufferPosition == iconBuffer.cend()) | ||||
|    { | ||||
|       iconBuffer.insert(iconBufferPosition, iconData); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       std::copy(iconData.begin(), iconData.end(), iconBufferPosition); | ||||
|    } | ||||
| 
 | ||||
|    auto hoverIt = std::find_if(hoverIcons.begin(), | ||||
|                                hoverIcons.end(), | ||||
|                                [&di](auto& entry) { return entry.di_ == di; }); | ||||
| 
 | ||||
|    if (di->visible_ && (!di->hoverText_.empty() || di->event_ != nullptr)) | ||||
|    { | ||||
|       const units::angle::radians<double> radians = angle; | ||||
| 
 | ||||
|  | @ -438,8 +516,21 @@ void Icons::Impl::UpdateBuffers() | |||
|       const glm::vec2 obl = rotate * glm::vec2 {lx, by}; | ||||
|       const glm::vec2 obr = rotate * glm::vec2 {rx, by}; | ||||
| 
 | ||||
|          newHoverIcons_.emplace_back(IconHoverEntry {di, otl, otr, obl, obr}); | ||||
|       if (hoverIt == hoverIcons.end()) | ||||
|       { | ||||
|          hoverIcons.emplace_back(IconHoverEntry {di, otl, otr, obl, obr}); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          hoverIt->otl_ = otl; | ||||
|          hoverIt->otr_ = otr; | ||||
|          hoverIt->obl_ = obl; | ||||
|          hoverIt->obr_ = obr; | ||||
|       } | ||||
|    } | ||||
|    else if (hoverIt != hoverIcons.end()) | ||||
|    { | ||||
|       hoverIcons.erase(hoverIt); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
|  | @ -477,7 +568,7 @@ void Icons::Impl::UpdateTextureBuffer() | |||
|       auto& icon = it->second; | ||||
| 
 | ||||
|       // Validate icon
 | ||||
|       if (di->iconIndex_ >= icon.numIcons_) | ||||
|       if (di->iconIndex_ >= icon->numIcons_) | ||||
|       { | ||||
|          // No icon found
 | ||||
|          logger_->error("Invalid icon index: {}", di->iconIndex_); | ||||
|  | @ -503,17 +594,17 @@ void Icons::Impl::UpdateTextureBuffer() | |||
|       } | ||||
| 
 | ||||
|       // Texture coordinates
 | ||||
|       const std::size_t iconRow    = (di->iconIndex_) / icon.columns_; | ||||
|       const std::size_t iconColumn = (di->iconIndex_) % icon.columns_; | ||||
|       const std::size_t iconRow    = (di->iconIndex_) / icon->columns_; | ||||
|       const std::size_t iconColumn = (di->iconIndex_) % icon->columns_; | ||||
| 
 | ||||
|       const float iconX = iconColumn * icon.scaledWidth_; | ||||
|       const float iconY = iconRow * icon.scaledHeight_; | ||||
|       const float iconX = iconColumn * icon->scaledWidth_; | ||||
|       const float iconY = iconRow * icon->scaledHeight_; | ||||
| 
 | ||||
|       const float ls = icon.texture_.sLeft_ + iconX; | ||||
|       const float rs = ls + icon.scaledWidth_; | ||||
|       const float tt = icon.texture_.tTop_ + iconY; | ||||
|       const float bt = tt + icon.scaledHeight_; | ||||
|       const float r  = static_cast<float>(icon.texture_.layerId_); | ||||
|       const float ls = icon->texture_.sLeft_ + iconX; | ||||
|       const float rs = ls + icon->scaledWidth_; | ||||
|       const float tt = icon->texture_.tTop_ + iconY; | ||||
|       const float bt = tt + icon->scaledHeight_; | ||||
|       const float r  = static_cast<float>(icon->texture_.layerId_); | ||||
| 
 | ||||
|       // clang-format off
 | ||||
|       textureBuffer_.insert( | ||||
|  | @ -531,17 +622,47 @@ void Icons::Impl::UpdateTextureBuffer() | |||
|    } | ||||
| } | ||||
| 
 | ||||
| void Icons::Impl::UpdateModifiedIconBuffers() | ||||
| { | ||||
|    // Update buffers for modified icons
 | ||||
|    for (auto& di : dirtyIcons_) | ||||
|    { | ||||
|       // Find modified icon in the current list
 | ||||
|       auto it = | ||||
|          std::find(currentIconList_.cbegin(), currentIconList_.cend(), di); | ||||
| 
 | ||||
|       // Ignore invalid icons
 | ||||
|       if (it == currentIconList_.cend()) | ||||
|       { | ||||
|          continue; | ||||
|       } | ||||
| 
 | ||||
|       auto iconIndex = std::distance(currentIconList_.cbegin(), it); | ||||
| 
 | ||||
|       UpdateSingleBuffer(di, iconIndex, currentIconBuffer_, currentHoverIcons_); | ||||
|    } | ||||
| 
 | ||||
|    // Clear list of modified icons
 | ||||
|    if (!dirtyIcons_.empty()) | ||||
|    { | ||||
|       dirtyIcons_.clear(); | ||||
|       dirty_ = true; | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| void Icons::Impl::Update(bool textureAtlasChanged) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = context_->gl(); | ||||
| 
 | ||||
|    UpdateModifiedIconBuffers(); | ||||
| 
 | ||||
|    // If the texture atlas has changed
 | ||||
|    if (dirty_ || textureAtlasChanged || lastTextureAtlasChanged_) | ||||
|    { | ||||
|       // Update texture coordinates
 | ||||
|       for (auto& iconSheet : currentIconSheets_) | ||||
|       { | ||||
|          iconSheet.second.UpdateTextureInfo(); | ||||
|          iconSheet.second->UpdateTextureInfo(); | ||||
|       } | ||||
| 
 | ||||
|       // Update OpenGL texture buffer data
 | ||||
|  | @ -575,7 +696,7 @@ void Icons::Impl::Update(bool textureAtlasChanged) | |||
| } | ||||
| 
 | ||||
| bool Icons::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    const QPointF&                                mouseLocalPos, | ||||
|    const QPointF&                                mouseGlobalPos, | ||||
|    const glm::vec2& /* mouseCoords */, | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| 
 | ||||
| #include <scwx/qt/gl/gl_context.hpp> | ||||
| #include <scwx/qt/gl/draw/draw_item.hpp> | ||||
| #include <scwx/qt/types/icon_types.hpp> | ||||
| 
 | ||||
| #include <boost/gil.hpp> | ||||
| #include <units/angle.h> | ||||
|  | @ -32,12 +33,12 @@ public: | |||
|    Icons& operator=(Icons&&) noexcept; | ||||
| 
 | ||||
|    void Initialize() override; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                bool textureAtlasChanged) override; | ||||
|    void Deinitialize() override; | ||||
| 
 | ||||
|    bool | ||||
|    RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    RunMousePicking(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const QPointF&                                mouseLocalPos, | ||||
|                    const QPointF&                                mouseGlobalPos, | ||||
|                    const glm::vec2&                              mouseCoords, | ||||
|  | @ -69,8 +70,10 @@ public: | |||
|     * Default is -1 to center the icon. | ||||
|     * @param [in] hotY The zero-based center of the each icon in the icon sheet. | ||||
|     * Default is -1 to center the icon. | ||||
|     * | ||||
|     * @return Icon info | ||||
|     */ | ||||
|    void AddIconSheet(const std::string& name, | ||||
|    std::shared_ptr<types::IconInfo> AddIconSheet(const std::string& name, | ||||
|                                                  std::size_t  iconWidth  = 0, | ||||
|                                                  std::size_t  iconHeight = 0, | ||||
|                                                  std::int32_t hotX       = -1, | ||||
|  | @ -93,6 +96,12 @@ public: | |||
|     */ | ||||
|    std::shared_ptr<IconDrawItem> AddIcon(); | ||||
| 
 | ||||
|    /**
 | ||||
|     * @param [in] di Icon draw item | ||||
|     * @param [in] visible Visibility of the icon | ||||
|     */ | ||||
|    void SetIconVisible(const std::shared_ptr<IconDrawItem>& di, bool visible); | ||||
| 
 | ||||
|    /**
 | ||||
|     * Sets the texture of an icon. | ||||
|     * | ||||
|  | @ -100,7 +109,7 @@ public: | |||
|     * @param [in] iconSheet The name of the icon sheet in the texture atlas | ||||
|     * @param [in] iconIndex The zero-based index of the icon in the icon sheet | ||||
|     */ | ||||
|    static void SetIconTexture(const std::shared_ptr<IconDrawItem>& di, | ||||
|    void SetIconTexture(const std::shared_ptr<IconDrawItem>& di, | ||||
|                        const std::string&                   iconSheet, | ||||
|                        std::size_t                          iconIndex); | ||||
| 
 | ||||
|  | @ -111,7 +120,7 @@ public: | |||
|     * @param [in] x The x location of the icon in pixels. | ||||
|     * @param [in] y The y location of the icon in pixels. | ||||
|     */ | ||||
|    static void | ||||
|    void | ||||
|    SetIconLocation(const std::shared_ptr<IconDrawItem>& di, double x, double y); | ||||
| 
 | ||||
|    /**
 | ||||
|  | @ -120,7 +129,7 @@ public: | |||
|     * @param [in] di Icon draw item | ||||
|     * @param [in] angle Angle in degrees | ||||
|     */ | ||||
|    static void SetIconAngle(const std::shared_ptr<IconDrawItem>& di, | ||||
|    void SetIconAngle(const std::shared_ptr<IconDrawItem>& di, | ||||
|                      units::angle::degrees<double>        angle); | ||||
| 
 | ||||
|    /**
 | ||||
|  | @ -129,7 +138,7 @@ public: | |||
|     * @param [in] di Icon draw item | ||||
|     * @param [in] modulate Modulate color | ||||
|     */ | ||||
|    static void SetIconModulate(const std::shared_ptr<IconDrawItem>& di, | ||||
|    void SetIconModulate(const std::shared_ptr<IconDrawItem>& di, | ||||
|                         boost::gil::rgba8_pixel_t            modulate); | ||||
| 
 | ||||
|    /**
 | ||||
|  | @ -138,7 +147,7 @@ public: | |||
|     * @param [in] di Icon draw item | ||||
|     * @param [in] modulate Modulate color | ||||
|     */ | ||||
|    static void SetIconModulate(const std::shared_ptr<IconDrawItem>& di, | ||||
|    void SetIconModulate(const std::shared_ptr<IconDrawItem>& di, | ||||
|                         boost::gil::rgba32f_pixel_t          modulate); | ||||
| 
 | ||||
|    /**
 | ||||
|  | @ -147,7 +156,7 @@ public: | |||
|     * @param [in] di Icon draw item | ||||
|     * @param [in] text Hover text | ||||
|     */ | ||||
|    static void SetIconHoverText(const std::shared_ptr<IconDrawItem>& di, | ||||
|    void SetIconHoverText(const std::shared_ptr<IconDrawItem>& di, | ||||
|                          const std::string&                   text); | ||||
| 
 | ||||
|    /**
 | ||||
|  |  | |||
|  | @ -103,8 +103,7 @@ void LinkedVectors::Initialize() | |||
|    p->geoLines_->Initialize(); | ||||
| } | ||||
| 
 | ||||
| void LinkedVectors::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
| void LinkedVectors::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    if (!p->visible_) | ||||
|    { | ||||
|  | @ -337,7 +336,7 @@ void LinkedVectors::FinishVectors() | |||
| } | ||||
| 
 | ||||
| bool LinkedVectors::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    const QPointF&                                mouseLocalPos, | ||||
|    const QPointF&                                mouseGlobalPos, | ||||
|    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -43,11 +43,11 @@ public: | |||
|    void set_thresholded(bool thresholded); | ||||
| 
 | ||||
|    void Initialize() override; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters& params) override; | ||||
|    void Deinitialize() override; | ||||
| 
 | ||||
|    bool | ||||
|    RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    RunMousePicking(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const QPointF&                                mouseLocalPos, | ||||
|                    const QPointF&                                mouseGlobalPos, | ||||
|                    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -255,7 +255,7 @@ void PlacefileIcons::Initialize() | |||
| } | ||||
| 
 | ||||
| void PlacefileIcons::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    bool                                          textureAtlasChanged) | ||||
| { | ||||
|    std::unique_lock lock {p->iconMutex_}; | ||||
|  | @ -685,7 +685,7 @@ void PlacefileIcons::Impl::Update(bool textureAtlasChanged) | |||
| } | ||||
| 
 | ||||
| bool PlacefileIcons::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    const QPointF& /* mouseLocalPos */, | ||||
|    const QPointF&   mouseGlobalPos, | ||||
|    const glm::vec2& mouseCoords, | ||||
|  |  | |||
|  | @ -31,12 +31,12 @@ public: | |||
|    void set_thresholded(bool thresholded); | ||||
| 
 | ||||
|    void Initialize() override; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                bool textureAtlasChanged) override; | ||||
|    void Deinitialize() override; | ||||
| 
 | ||||
|    bool | ||||
|    RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    RunMousePicking(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const QPointF&                                mouseLocalPos, | ||||
|                    const QPointF&                                mouseGlobalPos, | ||||
|                    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -224,7 +224,7 @@ void PlacefileImages::Initialize() | |||
| } | ||||
| 
 | ||||
| void PlacefileImages::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    bool                                          textureAtlasChanged) | ||||
| { | ||||
|    std::unique_lock lock {p->imageMutex_}; | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ public: | |||
|    void set_thresholded(bool thresholded); | ||||
| 
 | ||||
|    void Initialize() override; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                bool textureAtlasChanged) override; | ||||
|    void Deinitialize() override; | ||||
| 
 | ||||
|  |  | |||
|  | @ -213,7 +213,7 @@ void PlacefileLines::Initialize() | |||
| } | ||||
| 
 | ||||
| void PlacefileLines::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    std::unique_lock lock {p->lineMutex_}; | ||||
| 
 | ||||
|  | @ -496,7 +496,7 @@ void PlacefileLines::Impl::Update() | |||
| } | ||||
| 
 | ||||
| bool PlacefileLines::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    const QPointF& /* mouseLocalPos */, | ||||
|    const QPointF&   mouseGlobalPos, | ||||
|    const glm::vec2& mouseCoords, | ||||
|  |  | |||
|  | @ -29,11 +29,11 @@ public: | |||
|    void set_thresholded(bool thresholded); | ||||
| 
 | ||||
|    void Initialize() override; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters& params) override; | ||||
|    void Deinitialize() override; | ||||
| 
 | ||||
|    bool | ||||
|    RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    RunMousePicking(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const QPointF&                                mouseLocalPos, | ||||
|                    const QPointF&                                mouseGlobalPos, | ||||
|                    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -221,7 +221,7 @@ void PlacefilePolygons::Initialize() | |||
| } | ||||
| 
 | ||||
| void PlacefilePolygons::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    if (!p->currentBuffer_.empty()) | ||||
|    { | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ public: | |||
|    void set_thresholded(bool thresholded); | ||||
| 
 | ||||
|    void Initialize() override; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters& params) override; | ||||
|    void Deinitialize() override; | ||||
| 
 | ||||
|    /**
 | ||||
|  |  | |||
|  | @ -34,9 +34,9 @@ public: | |||
|    ~Impl() {} | ||||
| 
 | ||||
|    void RenderTextDrawItem( | ||||
|       const QMapLibreGL::CustomLayerRenderParameters&           params, | ||||
|       const QMapLibre::CustomLayerRenderParameters&             params, | ||||
|       const std::shared_ptr<const gr::Placefile::TextDrawItem>& di); | ||||
|    void RenderText(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    void RenderText(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const std::string&                            text, | ||||
|                    const std::string&                            hoverText, | ||||
|                    boost::gil::rgba8_pixel_t                     color, | ||||
|  | @ -98,8 +98,7 @@ void PlacefileText::set_thresholded(bool thresholded) | |||
| 
 | ||||
| void PlacefileText::Initialize() {} | ||||
| 
 | ||||
| void PlacefileText::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
| void PlacefileText::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    std::unique_lock lock {p->listMutex_}; | ||||
| 
 | ||||
|  | @ -128,7 +127,7 @@ void PlacefileText::Render( | |||
| } | ||||
| 
 | ||||
| void PlacefileText::Impl::RenderTextDrawItem( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters&           params, | ||||
|    const QMapLibre::CustomLayerRenderParameters&             params, | ||||
|    const std::shared_ptr<const gr::Placefile::TextDrawItem>& di) | ||||
| { | ||||
|    // If no time has been selected, use the current time
 | ||||
|  | @ -191,7 +190,7 @@ void PlacefileText::Impl::RenderTextDrawItem( | |||
| } | ||||
| 
 | ||||
| void PlacefileText::Impl::RenderText( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    const std::string&                            text, | ||||
|    const std::string&                            hoverText, | ||||
|    boost::gil::rgba8_pixel_t                     color, | ||||
|  | @ -238,7 +237,7 @@ void PlacefileText::Deinitialize() | |||
| } | ||||
| 
 | ||||
| bool PlacefileText::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& /* params */, | ||||
|    const QMapLibre::CustomLayerRenderParameters& /* params */, | ||||
|    const QPointF& /* mouseLocalPos */, | ||||
|    const QPointF& mouseGlobalPos, | ||||
|    const glm::vec2& /* mouseCoords */, | ||||
|  |  | |||
|  | @ -34,11 +34,11 @@ public: | |||
|    void set_thresholded(bool thresholded); | ||||
| 
 | ||||
|    void Initialize() override; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters& params) override; | ||||
|    void Deinitialize() override; | ||||
| 
 | ||||
|    bool | ||||
|    RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    RunMousePicking(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const QPointF&                                mouseLocalPos, | ||||
|                    const QPointF&                                mouseGlobalPos, | ||||
|                    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -169,7 +169,7 @@ void PlacefileTriangles::Initialize() | |||
| } | ||||
| 
 | ||||
| void PlacefileTriangles::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    if (!p->currentBuffer_.empty()) | ||||
|    { | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ public: | |||
|    void set_thresholded(bool thresholded); | ||||
| 
 | ||||
|    void Initialize() override; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters& params) override; | ||||
|    void Deinitialize() override; | ||||
| 
 | ||||
|    /**
 | ||||
|  |  | |||
|  | @ -122,7 +122,7 @@ void Rectangle::Initialize() | |||
|    p->dirty_ = true; | ||||
| } | ||||
| 
 | ||||
| void Rectangle::Render(const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
| void Rectangle::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    if (p->visible_) | ||||
|    { | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ public: | |||
|    Rectangle& operator=(Rectangle&&) noexcept; | ||||
| 
 | ||||
|    void Initialize() override; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters& params) override; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters& params) override; | ||||
|    void Deinitialize() override; | ||||
| 
 | ||||
|    void SetBorder(float width, boost::gil::rgba8_pixel_t color); | ||||
|  |  | |||
|  | @ -120,8 +120,11 @@ public: | |||
| 
 | ||||
|       std::string mapProviderApiKey = map::GetMapProviderApiKey(mapProvider_); | ||||
| 
 | ||||
|       settings_.resetToTemplate(mapProviderInfo.settingsTemplate_); | ||||
|       if (mapProvider_ == map::MapProvider::Mapbox) | ||||
|       { | ||||
|          settings_.setProviderTemplate(mapProviderInfo.providerTemplate_); | ||||
|          settings_.setApiKey(QString {mapProviderApiKey.c_str()}); | ||||
|       } | ||||
|       settings_.setCacheDatabasePath(QString {cacheDbPath.c_str()}); | ||||
|       settings_.setCacheDatabaseMaximumSize(20 * 1024 * 1024); | ||||
| 
 | ||||
|  | @ -165,7 +168,7 @@ public: | |||
|    boost::asio::thread_pool threadPool_ {1u}; | ||||
| 
 | ||||
|    MainWindow*         mainWindow_; | ||||
|    QMapLibreGL::Settings settings_; | ||||
|    QMapLibre::Settings settings_; | ||||
|    map::MapProvider    mapProvider_; | ||||
|    map::MapWidget*     activeMap_; | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ | |||
| #include <boost/range/irange.hpp> | ||||
| #include <boost/timer/timer.hpp> | ||||
| #include <fmt/chrono.h> | ||||
| #include <QMapLibreGL/QMapLibreGL> | ||||
| #include <qmaplibre.hpp> | ||||
| 
 | ||||
| #if defined(_MSC_VER) | ||||
| #   pragma warning(pop) | ||||
|  | @ -423,7 +423,7 @@ void RadarProductManager::Initialize() | |||
|    const GeographicLib::Geodesic& geodesic( | ||||
|       util::GeographicLib::DefaultGeodesic()); | ||||
| 
 | ||||
|    const QMapLibreGL::Coordinate radar(p->radarSite_->latitude(), | ||||
|    const QMapLibre::Coordinate radar(p->radarSite_->latitude(), | ||||
|                                      p->radarSite_->longitude()); | ||||
| 
 | ||||
|    const float gateSize = gate_size(); | ||||
|  |  | |||
|  | @ -28,7 +28,8 @@ static void LoadTextures(); | |||
| static const std::vector<std::pair<types::Font, std::string>> fontNames_ { | ||||
|    {types::Font::din1451alt, ":/res/fonts/din1451alt.ttf"}, | ||||
|    {types::Font::din1451alt_g, ":/res/fonts/din1451alt_g.ttf"}, | ||||
|    {types::Font::Inconsolata_Regular, ":/res/fonts/Inconsolata-Regular.ttf"}}; | ||||
|    {types::Font::Inconsolata_Regular, ":/res/fonts/Inconsolata-Regular.ttf"}, | ||||
|    {types::Font::RobotoFlex_Regular, ":/res/fonts/RobotoFlex-Regular.ttf"}}; | ||||
| 
 | ||||
| void Initialize() | ||||
| { | ||||
|  |  | |||
|  | @ -24,22 +24,22 @@ static const std::string logPrefix_ = "scwx::qt::map::alert_layer"; | |||
| static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||
| 
 | ||||
| static std::vector<std::string> | ||||
| AddAlertLayer(std::shared_ptr<QMapLibreGL::Map> map, | ||||
| AddAlertLayer(std::shared_ptr<QMapLibre::Map> map, | ||||
|               awips::Phenomenon               phenomenon, | ||||
|               bool                            alertActive, | ||||
|               const QString&                  beforeLayer); | ||||
| static QMapLibreGL::Feature | ||||
| static QMapLibre::Feature | ||||
| CreateFeature(const awips::CodedLocation& codedLocation); | ||||
| static QMapLibreGL::Coordinate | ||||
| static QMapLibre::Coordinate | ||||
| GetMapboxCoordinate(const common::Coordinate& coordinate); | ||||
| static QMapLibreGL::Coordinates | ||||
| static QMapLibre::Coordinates | ||||
|                GetMapboxCoordinates(const awips::CodedLocation& codedLocation); | ||||
| static QString GetSourceId(awips::Phenomenon phenomenon, bool alertActive); | ||||
| static QString GetSuffix(awips::Phenomenon phenomenon, bool alertActive); | ||||
| 
 | ||||
| static const QVariantMap kEmptyFeatureCollection_ { | ||||
|    {"type", "geojson"}, | ||||
|    {"data", QVariant::fromValue(std::list<QMapLibreGL::Feature> {})}}; | ||||
|    {"data", QVariant::fromValue(std::list<QMapLibre::Feature> {})}}; | ||||
| static const std::vector<awips::Phenomenon> kAlertPhenomena_ { | ||||
|    awips::Phenomenon::Marine, | ||||
|    awips::Phenomenon::FlashFlood, | ||||
|  | @ -87,7 +87,7 @@ class AlertLayerHandler : public QObject | |||
| 
 | ||||
|    static std::shared_ptr<AlertLayerHandler> Instance(); | ||||
| 
 | ||||
|    std::list<QMapLibreGL::Feature>* FeatureList(awips::Phenomenon phenomenon, | ||||
|    std::list<QMapLibre::Feature>* FeatureList(awips::Phenomenon phenomenon, | ||||
|                                               bool              alertActive); | ||||
| 
 | ||||
|    void HandleAlert(const types::TextEventKey& key, size_t messageIndex); | ||||
|  | @ -103,7 +103,7 @@ class AlertLayerHandler : public QObject | |||
|    std::unordered_multimap<types::TextEventKey, | ||||
|                            std::tuple<awips::Phenomenon, | ||||
|                                       bool, | ||||
|                                       std::list<QMapLibreGL::Feature>::iterator, | ||||
|                                       std::list<QMapLibre::Feature>::iterator, | ||||
|                                       std::chrono::system_clock::time_point>, | ||||
|                            types::TextEventHash<types::TextEventKey>> | ||||
|                      featureMap_; | ||||
|  | @ -166,16 +166,16 @@ std::vector<std::string> AlertLayer::AddLayers(awips::Phenomenon  phenomenon, | |||
|    return layers; | ||||
| } | ||||
| 
 | ||||
| std::list<QMapLibreGL::Feature>* | ||||
| std::list<QMapLibre::Feature>* | ||||
| AlertLayerHandler::FeatureList(awips::Phenomenon phenomenon, bool alertActive) | ||||
| { | ||||
|    std::list<QMapLibreGL::Feature>* featureList = nullptr; | ||||
|    std::list<QMapLibre::Feature>* featureList = nullptr; | ||||
| 
 | ||||
|    auto key = std::make_pair(phenomenon, alertActive); | ||||
|    auto it  = alertSourceMap_.find(key); | ||||
|    if (it != alertSourceMap_.cend()) | ||||
|    { | ||||
|       featureList = reinterpret_cast<std::list<QMapLibreGL::Feature>*>( | ||||
|       featureList = reinterpret_cast<std::list<QMapLibre::Feature>*>( | ||||
|          it->second["data"].data()); | ||||
|    } | ||||
| 
 | ||||
|  | @ -371,7 +371,7 @@ std::shared_ptr<AlertLayerHandler> AlertLayerHandler::Instance() | |||
| } | ||||
| 
 | ||||
| static std::vector<std::string> | ||||
| AddAlertLayer(std::shared_ptr<QMapLibreGL::Map> map, | ||||
| AddAlertLayer(std::shared_ptr<QMapLibre::Map> map, | ||||
|               awips::Phenomenon               phenomenon, | ||||
|               bool                            alertActive, | ||||
|               const QString&                  beforeLayer) | ||||
|  | @ -401,16 +401,16 @@ AddAlertLayer(std::shared_ptr<QMapLibreGL::Map> map, | |||
| 
 | ||||
|    const float opacity = outlineColor[3] / 255.0f; | ||||
| 
 | ||||
|    map->addLayer({{"id", bgLayerId}, {"type", "line"}, {"source", sourceId}}, | ||||
|                  beforeLayer); | ||||
|    map->addLayer( | ||||
|       bgLayerId, {{"type", "line"}, {"source", sourceId}}, beforeLayer); | ||||
|    map->setLayoutProperty(bgLayerId, "line-join", "round"); | ||||
|    map->setLayoutProperty(bgLayerId, "line-cap", "round"); | ||||
|    map->setPaintProperty(bgLayerId, "line-color", "rgba(0, 0, 0, 255)"); | ||||
|    map->setPaintProperty(bgLayerId, "line-opacity", QString("%1").arg(opacity)); | ||||
|    map->setPaintProperty(bgLayerId, "line-width", "5"); | ||||
| 
 | ||||
|    map->addLayer({{"id", fgLayerId}, {"type", "line"}, {"source", sourceId}}, | ||||
|                  beforeLayer); | ||||
|    map->addLayer( | ||||
|       fgLayerId, {{"type", "line"}, {"source", sourceId}}, beforeLayer); | ||||
|    map->setLayoutProperty(fgLayerId, "line-join", "round"); | ||||
|    map->setLayoutProperty(fgLayerId, "line-cap", "round"); | ||||
|    map->setPaintProperty(fgLayerId, | ||||
|  | @ -426,33 +426,33 @@ AddAlertLayer(std::shared_ptr<QMapLibreGL::Map> map, | |||
|    return {bgLayerId.toStdString(), fgLayerId.toStdString()}; | ||||
| } | ||||
| 
 | ||||
| static QMapLibreGL::Feature | ||||
| static QMapLibre::Feature | ||||
| CreateFeature(const awips::CodedLocation& codedLocation) | ||||
| { | ||||
|    auto mapboxCoordinates = GetMapboxCoordinates(codedLocation); | ||||
| 
 | ||||
|    return {QMapLibreGL::Feature::PolygonType, | ||||
|            std::initializer_list<QMapLibreGL::CoordinatesCollection> { | ||||
|               std::initializer_list<QMapLibreGL::Coordinates> { | ||||
|                  {mapboxCoordinates}}}}; | ||||
|    return QMapLibre::Feature { | ||||
|       QMapLibre::Feature::PolygonType, | ||||
|       std::initializer_list<QMapLibre::CoordinatesCollection> { | ||||
|          std::initializer_list<QMapLibre::Coordinates> {{mapboxCoordinates}}}}; | ||||
| } | ||||
| 
 | ||||
| static QMapLibreGL::Coordinate | ||||
| static QMapLibre::Coordinate | ||||
| GetMapboxCoordinate(const common::Coordinate& coordinate) | ||||
| { | ||||
|    return {coordinate.latitude_, coordinate.longitude_}; | ||||
| } | ||||
| 
 | ||||
| static QMapLibreGL::Coordinates | ||||
| static QMapLibre::Coordinates | ||||
| GetMapboxCoordinates(const awips::CodedLocation& codedLocation) | ||||
| { | ||||
|    auto                   scwxCoordinates = codedLocation.coordinates(); | ||||
|    QMapLibreGL::Coordinates mapboxCoordinates(scwxCoordinates.size() + 1u); | ||||
|    QMapLibre::Coordinates mapboxCoordinates(scwxCoordinates.size() + 1u); | ||||
| 
 | ||||
|    std::transform(scwxCoordinates.cbegin(), | ||||
|                   scwxCoordinates.cend(), | ||||
|                   mapboxCoordinates.begin(), | ||||
|                   [](auto& coordinate) -> QMapLibreGL::Coordinate | ||||
|                   [](auto& coordinate) -> QMapLibre::Coordinate | ||||
|                   { return GetMapboxCoordinate(coordinate); }); | ||||
| 
 | ||||
|    mapboxCoordinates.back() = GetMapboxCoordinate(scwxCoordinates.front()); | ||||
|  |  | |||
|  | @ -116,7 +116,7 @@ void ColorTableLayer::Initialize() | |||
| } | ||||
| 
 | ||||
| void ColorTableLayer::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl               = context()->gl(); | ||||
|    auto                 radarProductView = context()->radar_product_view(); | ||||
|  | @ -181,6 +181,12 @@ void ColorTableLayer::Render( | |||
|       gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_[0]); | ||||
|       gl.glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); | ||||
|       gl.glDrawArrays(GL_TRIANGLES, 0, 6); | ||||
| 
 | ||||
|       context()->set_color_table_margins(QMargins {0, 0, 0, 10}); | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       context()->set_color_table_margins(QMargins {}); | ||||
|    } | ||||
| 
 | ||||
|    SCWX_GL_CHECK_ERROR(); | ||||
|  | @ -200,6 +206,8 @@ void ColorTableLayer::Deinitialize() | |||
|    p->vao_                = GL_INVALID_INDEX; | ||||
|    p->vbo_                = {GL_INVALID_INDEX}; | ||||
|    p->texture_            = GL_INVALID_INDEX; | ||||
| 
 | ||||
|    context()->set_color_table_margins(QMargins {}); | ||||
| } | ||||
| 
 | ||||
| } // namespace map
 | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ public: | |||
|    ~ColorTableLayer(); | ||||
| 
 | ||||
|    void Initialize() override final; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters&) override final; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters&) override final; | ||||
|    void Deinitialize() override final; | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -44,7 +44,7 @@ void DrawLayer::Initialize() | |||
|    } | ||||
| } | ||||
| 
 | ||||
| void DrawLayer::Render(const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
| void DrawLayer::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = p->context_->gl(); | ||||
|    p->textureAtlas_        = p->context_->GetTextureAtlas(); | ||||
|  | @ -77,7 +77,7 @@ void DrawLayer::Deinitialize() | |||
| } | ||||
| 
 | ||||
| bool DrawLayer::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    const QPointF&                                mouseLocalPos, | ||||
|    const QPointF&                                mouseGlobalPos, | ||||
|    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -19,12 +19,11 @@ public: | |||
|    virtual ~DrawLayer(); | ||||
| 
 | ||||
|    virtual void Initialize() override; | ||||
|    virtual void | ||||
|    Render(const QMapLibreGL::CustomLayerRenderParameters&) override; | ||||
|    virtual void Render(const QMapLibre::CustomLayerRenderParameters&) override; | ||||
|    virtual void Deinitialize() override; | ||||
| 
 | ||||
|    virtual bool | ||||
|    RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    RunMousePicking(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const QPointF&                                mouseLocalPos, | ||||
|                    const QPointF&                                mouseGlobalPos, | ||||
|                    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ GenericLayer::GenericLayer(std::shared_ptr<MapContext> context) : | |||
| GenericLayer::~GenericLayer() = default; | ||||
| 
 | ||||
| bool GenericLayer::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& /* params */, | ||||
|    const QMapLibre::CustomLayerRenderParameters& /* params */, | ||||
|    const QPointF& /* mouseLocalPos */, | ||||
|    const QPointF& /* mouseGlobalPos */, | ||||
|    const glm::vec2& /* mousePos */, | ||||
|  |  | |||
|  | @ -7,8 +7,8 @@ | |||
| #include <memory> | ||||
| 
 | ||||
| #include <QObject> | ||||
| #include <QMapLibreGL/QMapLibreGL> | ||||
| #include <glm/gtc/type_ptr.hpp> | ||||
| #include <qmaplibre.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -28,7 +28,7 @@ public: | |||
|    virtual ~GenericLayer(); | ||||
| 
 | ||||
|    virtual void Initialize()                                          = 0; | ||||
|    virtual void Render(const QMapLibreGL::CustomLayerRenderParameters&) = 0; | ||||
|    virtual void Render(const QMapLibre::CustomLayerRenderParameters&) = 0; | ||||
|    virtual void Deinitialize()                                        = 0; | ||||
| 
 | ||||
|    /**
 | ||||
|  | @ -44,7 +44,7 @@ public: | |||
|     * @return true if a draw item was picked, otherwise false | ||||
|     */ | ||||
|    virtual bool | ||||
|    RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    RunMousePicking(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const QPointF&                                mouseLocalPos, | ||||
|                    const QPointF&                                mouseGlobalPos, | ||||
|                    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -34,8 +34,7 @@ void LayerWrapper::initialize() | |||
|    p->layer_->Initialize(); | ||||
| } | ||||
| 
 | ||||
| void LayerWrapper::render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
| void LayerWrapper::render(const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    p->layer_->Render(params); | ||||
| } | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ namespace map | |||
| 
 | ||||
| class LayerWrapperImpl; | ||||
| 
 | ||||
| class LayerWrapper : public QMapLibreGL::CustomLayerHostInterface | ||||
| class LayerWrapper : public QMapLibre::CustomLayerHostInterface | ||||
| { | ||||
| public: | ||||
|    explicit LayerWrapper(std::shared_ptr<GenericLayer> layer); | ||||
|  | @ -24,7 +24,7 @@ public: | |||
|    LayerWrapper& operator=(LayerWrapper&&) noexcept; | ||||
| 
 | ||||
|    void initialize() override final; | ||||
|    void render(const QMapLibreGL::CustomLayerRenderParameters&) override final; | ||||
|    void render(const QMapLibre::CustomLayerRenderParameters&) override final; | ||||
|    void deinitialize() override final; | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -20,14 +20,19 @@ public: | |||
| 
 | ||||
|    ~Impl() {} | ||||
| 
 | ||||
|    std::weak_ptr<QMapLibreGL::Map> map_ {}; | ||||
|    std::weak_ptr<QMapLibre::Map> map_ {}; | ||||
|    MapSettings                   settings_ {}; | ||||
|    float                         pixelRatio_ {1.0f}; | ||||
|    common::RadarProductGroup     radarProductGroup_ { | ||||
|       common::RadarProductGroup::Unknown}; | ||||
|    std::string                            radarProduct_ {"???"}; | ||||
|    int16_t                                radarProductCode_ {0}; | ||||
|    QMapLibreGL::CustomLayerRenderParameters renderParameters_ {}; | ||||
|    QMapLibre::CustomLayerRenderParameters renderParameters_ {}; | ||||
| 
 | ||||
|    MapProvider mapProvider_ {MapProvider::Unknown}; | ||||
|    std::string mapCopyrights_ {}; | ||||
| 
 | ||||
|    QMargins colorTableMargins_ {}; | ||||
| 
 | ||||
|    std::shared_ptr<view::OverlayProductView> overlayProductView_ {nullptr}; | ||||
|    std::shared_ptr<view::RadarProductView>   radarProductView_; | ||||
|  | @ -43,16 +48,31 @@ MapContext::~MapContext() = default; | |||
| MapContext::MapContext(MapContext&&) noexcept            = default; | ||||
| MapContext& MapContext::operator=(MapContext&&) noexcept = default; | ||||
| 
 | ||||
| std::weak_ptr<QMapLibreGL::Map> MapContext::map() const | ||||
| std::weak_ptr<QMapLibre::Map> MapContext::map() const | ||||
| { | ||||
|    return p->map_; | ||||
| } | ||||
| 
 | ||||
| std::string MapContext::map_copyrights() const | ||||
| { | ||||
|    return p->mapCopyrights_; | ||||
| } | ||||
| 
 | ||||
| MapProvider MapContext::map_provider() const | ||||
| { | ||||
|    return p->mapProvider_; | ||||
| } | ||||
| 
 | ||||
| MapSettings& MapContext::settings() | ||||
| { | ||||
|    return p->settings_; | ||||
| } | ||||
| 
 | ||||
| QMargins MapContext::color_table_margins() const | ||||
| { | ||||
|    return p->colorTableMargins_; | ||||
| } | ||||
| 
 | ||||
| float MapContext::pixel_ratio() const | ||||
| { | ||||
|    return p->pixelRatio_; | ||||
|  | @ -84,16 +104,31 @@ int16_t MapContext::radar_product_code() const | |||
|    return p->radarProductCode_; | ||||
| } | ||||
| 
 | ||||
| QMapLibreGL::CustomLayerRenderParameters MapContext::render_parameters() const | ||||
| QMapLibre::CustomLayerRenderParameters MapContext::render_parameters() const | ||||
| { | ||||
|    return p->renderParameters_; | ||||
| } | ||||
| 
 | ||||
| void MapContext::set_map(const std::shared_ptr<QMapLibreGL::Map>& map) | ||||
| void MapContext::set_map(const std::shared_ptr<QMapLibre::Map>& map) | ||||
| { | ||||
|    p->map_ = map; | ||||
| } | ||||
| 
 | ||||
| void MapContext::set_map_copyrights(const std::string& copyrights) | ||||
| { | ||||
|    p->mapCopyrights_ = copyrights; | ||||
| } | ||||
| 
 | ||||
| void MapContext::set_map_provider(MapProvider provider) | ||||
| { | ||||
|    p->mapProvider_ = provider; | ||||
| } | ||||
| 
 | ||||
| void MapContext::set_color_table_margins(const QMargins& margins) | ||||
| { | ||||
|    p->colorTableMargins_ = margins; | ||||
| } | ||||
| 
 | ||||
| void MapContext::set_overlay_product_view( | ||||
|    const std::shared_ptr<view::OverlayProductView>& overlayProductView) | ||||
| { | ||||
|  | @ -128,7 +163,7 @@ void MapContext::set_radar_product_code(int16_t radarProductCode) | |||
| } | ||||
| 
 | ||||
| void MapContext::set_render_parameters( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    p->renderParameters_ = params; | ||||
| } | ||||
|  |  | |||
|  | @ -1,9 +1,11 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <scwx/qt/gl/gl_context.hpp> | ||||
| #include <scwx/qt/map/map_provider.hpp> | ||||
| #include <scwx/common/products.hpp> | ||||
| 
 | ||||
| #include <QMapLibreGL/QMapLibreGL> | ||||
| #include <qmaplibre.hpp> | ||||
| #include <QMargins> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -35,17 +37,23 @@ public: | |||
|    MapContext(MapContext&&) noexcept; | ||||
|    MapContext& operator=(MapContext&&) noexcept; | ||||
| 
 | ||||
|    std::weak_ptr<QMapLibreGL::Map>           map() const; | ||||
|    std::weak_ptr<QMapLibre::Map>             map() const; | ||||
|    std::string                               map_copyrights() const; | ||||
|    MapProvider                               map_provider() const; | ||||
|    MapSettings&                              settings(); | ||||
|    QMargins                                  color_table_margins() const; | ||||
|    float                                     pixel_ratio() const; | ||||
|    std::shared_ptr<view::OverlayProductView> overlay_product_view() const; | ||||
|    std::shared_ptr<view::RadarProductView>   radar_product_view() const; | ||||
|    common::RadarProductGroup                 radar_product_group() const; | ||||
|    std::string                               radar_product() const; | ||||
|    int16_t                                   radar_product_code() const; | ||||
|    QMapLibreGL::CustomLayerRenderParameters  render_parameters() const; | ||||
|    QMapLibre::CustomLayerRenderParameters    render_parameters() const; | ||||
| 
 | ||||
|    void set_map(const std::shared_ptr<QMapLibreGL::Map>& map); | ||||
|    void set_map(const std::shared_ptr<QMapLibre::Map>& map); | ||||
|    void set_map_copyrights(const std::string& copyrights); | ||||
|    void set_map_provider(MapProvider provider); | ||||
|    void set_color_table_margins(const QMargins& margins); | ||||
|    void set_overlay_product_view( | ||||
|       const std::shared_ptr<view::OverlayProductView>& overlayProductView); | ||||
|    void set_pixel_ratio(float pixelRatio); | ||||
|  | @ -54,8 +62,8 @@ public: | |||
|    void set_radar_product_group(common::RadarProductGroup radarProductGroup); | ||||
|    void set_radar_product(const std::string& radarProduct); | ||||
|    void set_radar_product_code(int16_t radarProductCode); | ||||
|    void set_render_parameters( | ||||
|       const QMapLibreGL::CustomLayerRenderParameters& params); | ||||
|    void | ||||
|    set_render_parameters(const QMapLibre::CustomLayerRenderParameters& params); | ||||
| 
 | ||||
| private: | ||||
|    class Impl; | ||||
|  |  | |||
|  | @ -26,77 +26,155 @@ static const std::unordered_map<MapProvider, MapProviderInfo> mapProviderInfo_ { | |||
|     MapProviderInfo { | ||||
|        .mapProvider_ {MapProvider::Mapbox}, | ||||
|        .cacheDbName_ {"mbgl-cache.db"}, | ||||
|        .settingsTemplate_ { | ||||
|           QMapLibreGL::Settings::SettingsTemplate::MapboxSettings}, | ||||
|        .mapStyles_ {{.name_ {"Streets"}, | ||||
|        .providerTemplate_ { | ||||
|           QMapLibre::Settings::ProviderTemplate::MapboxProvider}, | ||||
|        .mapStyles_ { | ||||
|           {.name_ {"Streets"}, | ||||
|            .url_ {"mapbox://styles/mapbox/streets-v11"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|                     {.name_ {"Outdoors"}, | ||||
|                      .url_ {"mapbox://styles/mapbox/outdoors-v11"}, | ||||
|           {.name_ {"American Memory"}, | ||||
|            .url_ { | ||||
|               "mapbox://styles/mapbox-map-design/cl4orrp5e000p14ldwenm7xsf"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Basic"}, | ||||
|            .url_ { | ||||
|               "mapbox://styles/mapbox-map-design/cl4whef7m000714pc44f3qaxs"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Basic Overcast"}, | ||||
|            .url_ { | ||||
|               "mapbox://styles/mapbox-map-design/cl4whev1w002w16s9mgoliotw"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Blueprint"}, | ||||
|            .url_ { | ||||
|               "mapbox://styles/mapbox-map-design/cks97e1e37nsd17nzg7p0308g"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Bubble"}, | ||||
|            .url_ { | ||||
|               "mapbox://styles/mapbox-map-design/cl4wxue5j000c14r17uqrjpqb"}, | ||||
|            .drawBelow_ {"com\\.mapbox\\.annotations\\.points"}}, | ||||
|           {.name_ {"Cali Terrain"}, | ||||
|            .url_ {"mapbox://styles/mapbox/cjerxnqt3cgvp2rmyuxbeqme7"}, | ||||
|            .drawBelow_ {"major roads casing"}}, | ||||
|           {.name_ {"Dark"}, | ||||
|            .url_ {"mapbox://styles/mapbox/dark-v10"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Decimal"}, | ||||
|            .url_ { | ||||
|               "mapbox://styles/mapbox-map-design/ck4014y110wt61ctt07egsel6"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Frank"}, | ||||
|            .url_ { | ||||
|               "mapbox://styles/mapbox-map-design/ckshxkppe0gge18nz20i0nrwq"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Ice Cream"}, | ||||
|            .url_ {"mapbox://styles/mapbox/cj7t3i5yj0unt2rmt3y4b5e32"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Le Shine"}, | ||||
|            .url_ {"mapbox://styles/mapbox/cjcunv5ae262f2sm9tfwg8i0w"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Light"}, | ||||
|            .url_ {"mapbox://styles/mapbox/light-v10"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|                     {.name_ {"Dark"}, | ||||
|                      .url_ {"mapbox://styles/mapbox/dark-v10"}, | ||||
|           {.name_ {"Mineral"}, | ||||
|            .url_ {"mapbox://styles/mapbox/cjtep62gq54l21frr1whf27ak"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Minimo"}, | ||||
|            .url_ { | ||||
|               "mapbox://styles/mapbox-map-design/cksjc2nsq1bg117pnekb655h1"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Moonlight"}, | ||||
|            .url_ {"mapbox://styles/mapbox/cj3kbeqzo00022smj7akz3o1e"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Navigation Guidance Day"}, | ||||
|            .url_ {"mapbox://styles/mapbox/navigation-guidance-day-v4"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Navigation Guidance Night"}, | ||||
|            .url_ {"mapbox://styles/mapbox/navigation-guidance-night-v4"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Neon glow"}, | ||||
|            .url_ { | ||||
|               "mapbox://styles/mapbox-map-design/cl4gxqwi5001415l381n7qwak"}, | ||||
|            .drawBelow_ {"settlement-minor-label"}}, | ||||
|           {.name_ {"North Star"}, | ||||
|            .url_ {"mapbox://styles/mapbox/cj44mfrt20f082snokim4ungi"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Outdoors"}, | ||||
|            .url_ {"mapbox://styles/mapbox/outdoors-v11"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Pencil"}, | ||||
|            .url_ { | ||||
|               "mapbox://styles/mapbox-map-design/cks9iema71es417mlrft4go2k"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Satellite"}, | ||||
|            .url_ {"mapbox://styles/mapbox/satellite-v9"}, | ||||
|            .drawBelow_ {"com.mapbox.annotations.points"}}, | ||||
|           {.name_ {"Satellite Streets"}, | ||||
|            .url_ {"mapbox://styles/mapbox/satellite-streets-v11"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}, | ||||
|           {.name_ {"Standard Oil Company"}, | ||||
|            .url_ { | ||||
|               "mapbox://styles/mapbox-map-design/ckr0svm3922ki18qntevm857n"}, | ||||
|            .drawBelow_ {mapboxDrawBelow_}}}}}, | ||||
|    {MapProvider::MapTiler, | ||||
|     MapProviderInfo { | ||||
|        .mapProvider_ {MapProvider::MapTiler}, | ||||
|        .cacheDbName_ {"maptiler-cache.db"}, | ||||
|        .settingsTemplate_ { | ||||
|           QMapLibreGL::Settings::SettingsTemplate::MapTilerSettings}, | ||||
|        .providerTemplate_ { | ||||
|           QMapLibre::Settings::ProviderTemplate::MapTilerProvider}, | ||||
|        .mapStyles_ { | ||||
|           {.name_ {"Satellite"}, | ||||
|            .url_ {"maptiler://maps/hybrid"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/hybrid/style.json"}, | ||||
|            .drawBelow_ {"tunnel"}}, | ||||
|           {.name_ {"Streets"}, | ||||
|            .url_ {"maptiler://maps/streets-v2"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/streets-v2/style.json"}, | ||||
|            .drawBelow_ {"aeroway"}}, | ||||
|           {.name_ {"Streets Dark"}, | ||||
|            .url_ {"maptiler://maps/streets-v2-dark"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/streets-v2-dark/style.json"}, | ||||
|            .drawBelow_ {"aeroway"}}, | ||||
|           {.name_ {"Backdrop"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/backdrop/style.json"}, | ||||
|            .drawBelow_ {"Aeroway"}}, | ||||
|           {.name_ {"Basic"}, | ||||
|            .url_ {"maptiler://maps/basic-v2"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/basic-v2/style.json"}, | ||||
|            .drawBelow_ {"railway_transit_tunnel", "Transit tunnel"}}, | ||||
|           {.name_ {"Bright"}, | ||||
|            .url_ {"maptiler://maps/bright-v2"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/bright-v2/style.json"}, | ||||
|            .drawBelow_ {"ferry"}}, | ||||
|           {.name_ {"Dataviz"}, | ||||
|            .url_ {"maptiler://maps/dataviz"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/dataviz/style.json"}, | ||||
|            .drawBelow_ {"aeroway"}}, | ||||
|           {.name_ {"Dataviz Dark"}, | ||||
|            .url_ {"maptiler://maps/dataviz-dark"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/dataviz-dark/style.json"}, | ||||
|            .drawBelow_ {"aeroway"}}, | ||||
|           {.name_ {"Landscape"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/landscape/style.json"}, | ||||
|            .drawBelow_ {"Runway"}}, | ||||
|           {.name_ {"Outdoor"}, | ||||
|            .url_ {"maptiler://maps/outdoor-v2"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/outdoor-v2/style.json"}, | ||||
|            .drawBelow_ {"aeroway_runway", "Aeroway"}}, | ||||
|           {.name_ {"Swisstopo"}, | ||||
|            .url_ {"maptiler://maps/ch-swisstopo-lbm"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/ch-swisstopo-lbm/style.json"}, | ||||
|            .drawBelow_ {"pattern_landcover_vineyard", "Vineyard pattern"}}, | ||||
|           {.name_ {"Swisstopo Dark"}, | ||||
|            .url_ {"maptiler://maps/ch-swisstopo-lbm-dark"}, | ||||
|            .url_ { | ||||
|               "https://api.maptiler.com/maps/ch-swisstopo-lbm-dark/style.json"}, | ||||
|            .drawBelow_ {"pattern_landcover_vineyard", "Vineyard pattern"}}, | ||||
|           {.name_ {"Swisstopo Grey"}, | ||||
|            .url_ {"maptiler://maps/ch-swisstopo-lbm-grey"}, | ||||
|            .url_ { | ||||
|               "https://api.maptiler.com/maps/ch-swisstopo-lbm-grey/style.json"}, | ||||
|            .drawBelow_ {"pattern_landcover_vineyard", "Vineyard pattern"}}, | ||||
|           {.name_ {"Swisstopo Vivid"}, | ||||
|            .url_ {"maptiler://maps/ch-swisstopo-lbm-vivid"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/ch-swisstopo-lbm-vivid/" | ||||
|                   "style.json"}, | ||||
|            .drawBelow_ {"pattern_landcover_vineyard", "Vineyard pattern"}}, | ||||
|           {.name_ {"Topo"}, | ||||
|            .url_ {"maptiler://maps/topo-v2"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/topo-v2/style.json"}, | ||||
|            .drawBelow_ {"aeroway_runway", "Runway"}}, | ||||
|           {.name_ {"Topo Dark"}, | ||||
|            .url_ {"maptiler://maps/topo-v2-dark"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/topo-v2-dark/style.json"}, | ||||
|            .drawBelow_ {"aeroway_runway", "Runway"}}, | ||||
|           {.name_ {"Winter"}, | ||||
|            .url_ {"maptiler://maps/winter-v2"}, | ||||
|            .url_ {"https://api.maptiler.com/maps/winter-v2/style.json"}, | ||||
|            .drawBelow_ {"aeroway_runway", "Aeroway"}}}}}, | ||||
|    {MapProvider::Unknown, MapProviderInfo {}}}; | ||||
| 
 | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| 
 | ||||
| #include <string> | ||||
| 
 | ||||
| #include <QMapLibreGL/settings.hpp> | ||||
| #include <QMapLibre/Settings> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -34,7 +34,7 @@ struct MapProviderInfo | |||
| { | ||||
|    MapProvider                           mapProvider_ {MapProvider::Unknown}; | ||||
|    std::string                           cacheDbName_ {}; | ||||
|    QMapLibreGL::Settings::SettingsTemplate settingsTemplate_ {}; | ||||
|    QMapLibre::Settings::ProviderTemplate providerTemplate_ {}; | ||||
|    std::vector<MapStyle>                 mapStyles_ {}; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -30,6 +30,8 @@ | |||
| 
 | ||||
| #include <backends/imgui_impl_opengl3.h> | ||||
| #include <backends/imgui_impl_qt.hpp> | ||||
| #include <boost/algorithm/string/erase.hpp> | ||||
| #include <boost/algorithm/string/trim.hpp> | ||||
| #include <boost/asio/post.hpp> | ||||
| #include <boost/asio/thread_pool.hpp> | ||||
| #include <boost/uuid/random_generator.hpp> | ||||
|  | @ -44,6 +46,7 @@ | |||
| #include <QKeyEvent> | ||||
| #include <QMouseEvent> | ||||
| #include <QString> | ||||
| #include <QTextDocument> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -62,7 +65,7 @@ class MapWidgetImpl : public QObject | |||
| public: | ||||
|    explicit MapWidgetImpl(MapWidget*                 widget, | ||||
|                           std::size_t                id, | ||||
|                           const QMapLibreGL::Settings& settings) : | ||||
|                           const QMapLibre::Settings& settings) : | ||||
|        id_ {id}, | ||||
|        uuid_ {boost::uuids::random_generator()()}, | ||||
|        context_ {std::make_shared<MapContext>()}, | ||||
|  | @ -94,11 +97,13 @@ public: | |||
|       overlayProductView->SetAutoRefresh(autoRefreshEnabled_); | ||||
|       overlayProductView->SetAutoUpdate(autoUpdateEnabled_); | ||||
| 
 | ||||
|       // Initialize context
 | ||||
|       context_->set_overlay_product_view(overlayProductView); | ||||
| 
 | ||||
|       auto& generalSettings = settings::GeneralSettings::Instance(); | ||||
| 
 | ||||
|       // Initialize context
 | ||||
|       context_->set_map_provider( | ||||
|          GetMapProvider(generalSettings.map_provider().GetValue())); | ||||
|       context_->set_overlay_product_view(overlayProductView); | ||||
| 
 | ||||
|       SetRadarSite(generalSettings.default_radar_site().GetValue()); | ||||
| 
 | ||||
|       // Create ImGui Context
 | ||||
|  | @ -110,9 +115,6 @@ public: | |||
|       // Initialize ImGui Qt backend
 | ||||
|       ImGui_ImplQt_Init(); | ||||
| 
 | ||||
|       // Set Map Provider Details
 | ||||
|       mapProvider_ = GetMapProvider(generalSettings.map_provider().GetValue()); | ||||
| 
 | ||||
|       ConnectSignals(); | ||||
|    } | ||||
| 
 | ||||
|  | @ -143,6 +145,7 @@ public: | |||
|    void AddLayers(); | ||||
|    void AddPlacefileLayer(const std::string& placefileName, | ||||
|                           const std::string& before); | ||||
|    void ConnectMapSignals(); | ||||
|    void ConnectSignals(); | ||||
|    void ImGuiCheckFonts(); | ||||
|    void InitializeNewRadarProductView(const std::string& colorPalette); | ||||
|  | @ -170,9 +173,8 @@ public: | |||
|    std::shared_ptr<MapContext> context_; | ||||
| 
 | ||||
|    MapWidget*                      widget_; | ||||
|    MapProvider                       mapProvider_; | ||||
|    QMapLibreGL::Settings             settings_; | ||||
|    std::shared_ptr<QMapLibreGL::Map> map_; | ||||
|    QMapLibre::Settings             settings_; | ||||
|    std::shared_ptr<QMapLibre::Map> map_; | ||||
|    std::list<std::string>          layerList_; | ||||
| 
 | ||||
|    std::vector<std::shared_ptr<GenericLayer>> genericLayers_ {}; | ||||
|  | @ -229,7 +231,7 @@ public slots: | |||
|    void Update(); | ||||
| }; | ||||
| 
 | ||||
| MapWidget::MapWidget(std::size_t id, const QMapLibreGL::Settings& settings) : | ||||
| MapWidget::MapWidget(std::size_t id, const QMapLibre::Settings& settings) : | ||||
|     p(std::make_unique<MapWidgetImpl>(this, id, settings)) | ||||
| { | ||||
|    if (settings::GeneralSettings::Instance().anti_aliasing_enabled().GetValue()) | ||||
|  | @ -246,10 +248,34 @@ MapWidget::MapWidget(std::size_t id, const QMapLibreGL::Settings& settings) : | |||
| 
 | ||||
| MapWidget::~MapWidget() | ||||
| { | ||||
|    // Make sure we have a valid context so we can delete the QMapLibreGL.
 | ||||
|    // Make sure we have a valid context so we can delete the QMapLibre.
 | ||||
|    makeCurrent(); | ||||
| } | ||||
| 
 | ||||
| void MapWidgetImpl::ConnectMapSignals() | ||||
| { | ||||
|    connect(map_.get(), | ||||
|            &QMapLibre::Map::needsRendering, | ||||
|            this, | ||||
|            &MapWidgetImpl::Update); | ||||
|    connect(map_.get(), | ||||
|            &QMapLibre::Map::copyrightsChanged, | ||||
|            this, | ||||
|            [this](const QString& copyrightsHtml) | ||||
|            { | ||||
|               QTextDocument document {}; | ||||
|               document.setHtml(copyrightsHtml); | ||||
| 
 | ||||
|               // HTML cannot currently be included in ImGui windows. Where links
 | ||||
|               // can't be included, remove "Improve this map".
 | ||||
|               std::string copyrights {document.toPlainText().toStdString()}; | ||||
|               boost::erase_all(copyrights, "Improve this map"); | ||||
|               boost::trim_right(copyrights); | ||||
| 
 | ||||
|               context_->set_map_copyrights(copyrights); | ||||
|            }); | ||||
| } | ||||
| 
 | ||||
| void MapWidgetImpl::ConnectSignals() | ||||
| { | ||||
|    connect(placefileManager_.get(), | ||||
|  | @ -725,7 +751,8 @@ void MapWidget::SetInitialMapStyle(const std::string& styleName) | |||
| 
 | ||||
| void MapWidget::SetMapStyle(const std::string& styleName) | ||||
| { | ||||
|    const auto& mapProviderInfo = GetMapProviderInfo(p->mapProvider_); | ||||
|    const auto  mapProvider     = p->context_->map_provider(); | ||||
|    const auto& mapProviderInfo = GetMapProviderInfo(mapProvider); | ||||
|    auto&       styles          = mapProviderInfo.mapStyles_; | ||||
| 
 | ||||
|    for (size_t i = 0u; i < styles.size(); ++i) | ||||
|  | @ -737,7 +764,7 @@ void MapWidget::SetMapStyle(const std::string& styleName) | |||
| 
 | ||||
|          logger_->debug("Updating style: {}", styles[i].name_); | ||||
| 
 | ||||
|          p->map_->setStyleUrl(styles[i].url_.c_str()); | ||||
|          util::maplibre::SetMapStyleUrl(p->context_, styles[i].url_); | ||||
| 
 | ||||
|          if (++p->currentStyleIndex_ == styles.size()) | ||||
|          { | ||||
|  | @ -756,14 +783,16 @@ qreal MapWidget::pixelRatio() | |||
| 
 | ||||
| void MapWidget::changeStyle() | ||||
| { | ||||
|    const auto& mapProviderInfo = GetMapProviderInfo(p->mapProvider_); | ||||
|    const auto  mapProvider     = p->context_->map_provider(); | ||||
|    const auto& mapProviderInfo = GetMapProviderInfo(mapProvider); | ||||
|    auto&       styles          = mapProviderInfo.mapStyles_; | ||||
| 
 | ||||
|    p->currentStyle_ = &styles[p->currentStyleIndex_]; | ||||
| 
 | ||||
|    logger_->debug("Updating style: {}", styles[p->currentStyleIndex_].name_); | ||||
| 
 | ||||
|    p->map_->setStyleUrl(styles[p->currentStyleIndex_].url_.c_str()); | ||||
|    util::maplibre::SetMapStyleUrl(p->context_, | ||||
|                                   styles[p->currentStyleIndex_].url_); | ||||
| 
 | ||||
|    if (++p->currentStyleIndex_ == styles.size()) | ||||
|    { | ||||
|  | @ -987,8 +1016,8 @@ void MapWidgetImpl::AddLayer(const std::string&            id, | |||
|                              std::shared_ptr<GenericLayer> layer, | ||||
|                              const std::string&            before) | ||||
| { | ||||
|    // QMapLibreGL::addCustomLayer will take ownership of the std::unique_ptr
 | ||||
|    std::unique_ptr<QMapLibreGL::CustomLayerHostInterface> pHost = | ||||
|    // QMapLibre::addCustomLayer will take ownership of the std::unique_ptr
 | ||||
|    std::unique_ptr<QMapLibre::CustomLayerHostInterface> pHost = | ||||
|       std::make_unique<LayerWrapper>(layer); | ||||
| 
 | ||||
|    try | ||||
|  | @ -1131,12 +1160,9 @@ void MapWidget::initializeGL() | |||
|    p->imGuiRendererInitialized_ = true; | ||||
| 
 | ||||
|    p->map_.reset( | ||||
|       new QMapLibreGL::Map(nullptr, p->settings_, size(), pixelRatio())); | ||||
|       new QMapLibre::Map(nullptr, p->settings_, size(), pixelRatio())); | ||||
|    p->context_->set_map(p->map_); | ||||
|    connect(p->map_.get(), | ||||
|            &QMapLibreGL::Map::needsRendering, | ||||
|            p.get(), | ||||
|            &MapWidgetImpl::Update); | ||||
|    p->ConnectMapSignals(); | ||||
| 
 | ||||
|    // Set default location to radar site
 | ||||
|    std::shared_ptr<config::RadarSite> radarSite = | ||||
|  | @ -1160,10 +1186,8 @@ void MapWidget::initializeGL() | |||
|       SetMapStyle(p->initialStyleName_); | ||||
|    } | ||||
| 
 | ||||
|    connect(p->map_.get(), | ||||
|            &QMapLibreGL::Map::mapChanged, | ||||
|            this, | ||||
|            &MapWidget::mapChanged); | ||||
|    connect( | ||||
|       p->map_.get(), &QMapLibre::Map::mapChanged, this, &MapWidget::mapChanged); | ||||
| } | ||||
| 
 | ||||
| void MapWidget::paintGL() | ||||
|  | @ -1192,7 +1216,7 @@ void MapWidget::paintGL() | |||
|    // Update pixel ratio
 | ||||
|    p->context_->set_pixel_ratio(pixelRatio()); | ||||
| 
 | ||||
|    // Render QMapLibreGL Map
 | ||||
|    // Render QMapLibre Map
 | ||||
|    p->map_->resize(size()); | ||||
|    p->map_->setFramebufferObject(defaultFramebufferObject(), | ||||
|                                  size() * pixelRatio()); | ||||
|  | @ -1243,7 +1267,7 @@ void MapWidgetImpl::ImGuiCheckFonts() | |||
| 
 | ||||
| void MapWidgetImpl::RunMousePicking() | ||||
| { | ||||
|    const QMapLibreGL::CustomLayerRenderParameters params = | ||||
|    const QMapLibre::CustomLayerRenderParameters params = | ||||
|       context_->render_parameters(); | ||||
| 
 | ||||
|    auto coordinate = map_->coordinateForPixel(lastPos_); | ||||
|  | @ -1318,11 +1342,11 @@ void MapWidgetImpl::RunMousePicking() | |||
|    lastItemPicked_ = itemPicked; | ||||
| } | ||||
| 
 | ||||
| void MapWidget::mapChanged(QMapLibreGL::Map::MapChange mapChange) | ||||
| void MapWidget::mapChanged(QMapLibre::Map::MapChange mapChange) | ||||
| { | ||||
|    switch (mapChange) | ||||
|    { | ||||
|    case QMapLibreGL::Map::MapChangeDidFinishLoadingStyle: | ||||
|    case QMapLibre::Map::MapChangeDidFinishLoadingStyle: | ||||
|       p->UpdateLoadedStyle(); | ||||
|       p->AddLayers(); | ||||
|       break; | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ | |||
| #include <chrono> | ||||
| #include <memory> | ||||
| 
 | ||||
| #include <QMapLibreGL/QMapLibreGL> | ||||
| #include <qmaplibre.hpp> | ||||
| 
 | ||||
| #include <QOpenGLWidget> | ||||
| #include <QPropertyAnimation> | ||||
|  | @ -33,7 +33,7 @@ class MapWidget : public QOpenGLWidget | |||
|    Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
|    explicit MapWidget(std::size_t id, const QMapLibreGL::Settings&); | ||||
|    explicit MapWidget(std::size_t id, const QMapLibre::Settings&); | ||||
|    ~MapWidget(); | ||||
| 
 | ||||
|    void DumpLayerList() const; | ||||
|  | @ -139,7 +139,7 @@ private: | |||
|    friend class MapWidgetImpl; | ||||
| 
 | ||||
| private slots: | ||||
|    void mapChanged(QMapLibreGL::Map::MapChange); | ||||
|    void mapChanged(QMapLibre::Map::MapChange); | ||||
| 
 | ||||
| signals: | ||||
|    void Level3ProductsChanged(); | ||||
|  |  | |||
|  | @ -2,8 +2,10 @@ | |||
| #include <scwx/qt/gl/draw/geo_icons.hpp> | ||||
| #include <scwx/qt/gl/draw/icons.hpp> | ||||
| #include <scwx/qt/gl/draw/rectangle.hpp> | ||||
| #include <scwx/qt/manager/font_manager.hpp> | ||||
| #include <scwx/qt/manager/position_manager.hpp> | ||||
| #include <scwx/qt/map/map_settings.hpp> | ||||
| #include <scwx/qt/settings/general_settings.hpp> | ||||
| #include <scwx/qt/types/texture_types.hpp> | ||||
| #include <scwx/qt/view/radar_product_view.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
|  | @ -40,14 +42,38 @@ static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | |||
| class OverlayLayerImpl | ||||
| { | ||||
| public: | ||||
|    explicit OverlayLayerImpl(std::shared_ptr<MapContext> context) : | ||||
|    explicit OverlayLayerImpl(OverlayLayer*               self, | ||||
|                              std::shared_ptr<MapContext> context) : | ||||
|        self_ {self}, | ||||
|        activeBoxOuter_ {std::make_shared<gl::draw::Rectangle>(context)}, | ||||
|        activeBoxInner_ {std::make_shared<gl::draw::Rectangle>(context)}, | ||||
|        geoIcons_ {std::make_shared<gl::draw::GeoIcons>(context)}, | ||||
|        icons_ {std::make_shared<gl::draw::Icons>(context)} | ||||
|    { | ||||
|       auto& generalSettings = settings::GeneralSettings::Instance(); | ||||
| 
 | ||||
|       showMapAttributionCallbackUuid_ = | ||||
|          generalSettings.show_map_attribution().RegisterValueChangedCallback( | ||||
|             [this](const bool&) { Q_EMIT self_->NeedsRendering(); }); | ||||
|       showMapLogoCallbackUuid_ = | ||||
|          generalSettings.show_map_logo().RegisterValueChangedCallback( | ||||
|             [this](const bool&) { Q_EMIT self_->NeedsRendering(); }); | ||||
|    } | ||||
|    ~OverlayLayerImpl() = default; | ||||
| 
 | ||||
|    ~OverlayLayerImpl() | ||||
|    { | ||||
|       auto& generalSettings = settings::GeneralSettings::Instance(); | ||||
| 
 | ||||
|       generalSettings.show_map_attribution().UnregisterValueChangedCallback( | ||||
|          showMapAttributionCallbackUuid_); | ||||
|       generalSettings.show_map_logo().UnregisterValueChangedCallback( | ||||
|          showMapLogoCallbackUuid_); | ||||
|    } | ||||
| 
 | ||||
|    OverlayLayer* self_; | ||||
| 
 | ||||
|    boost::uuids::uuid showMapAttributionCallbackUuid_; | ||||
|    boost::uuids::uuid showMapLogoCallbackUuid_; | ||||
| 
 | ||||
|    std::shared_ptr<manager::PositionManager> positionManager_ { | ||||
|       manager::PositionManager::Instance()}; | ||||
|  | @ -66,13 +92,22 @@ public: | |||
|       types::GetTextureName(types::ImageTexture::CardinalPoint24)}; | ||||
|    const std::string& compassIconName_ { | ||||
|       types::GetTextureName(types::ImageTexture::Compass24)}; | ||||
| 
 | ||||
|    const std::string& mapboxLogoImageName_ { | ||||
|       types::GetTextureName(types::ImageTexture::MapboxLogo)}; | ||||
|    const std::string& mapTilerLogoImageName_ { | ||||
|       types::GetTextureName(types::ImageTexture::MapTilerLogo)}; | ||||
| 
 | ||||
|    std::shared_ptr<gl::draw::IconDrawItem> compassIcon_ {}; | ||||
|    bool                                    compassIconDirty_ {false}; | ||||
|    double                                  lastBearing_ {0.0}; | ||||
| 
 | ||||
|    std::shared_ptr<gl::draw::IconDrawItem> mapLogoIcon_ {}; | ||||
| 
 | ||||
|    bool     firstRender_ {true}; | ||||
|    double   lastWidth_ {0.0}; | ||||
|    double   lastHeight_ {0.0}; | ||||
|    float    lastFontSize_ {0.0f}; | ||||
|    QMargins lastColorTableMargins_ {}; | ||||
| 
 | ||||
|    std::string sweepTimeString_ {}; | ||||
|    bool        sweepTimeNeedsUpdate_ {true}; | ||||
|  | @ -80,7 +115,7 @@ public: | |||
| }; | ||||
| 
 | ||||
| OverlayLayer::OverlayLayer(std::shared_ptr<MapContext> context) : | ||||
|     DrawLayer(context), p(std::make_unique<OverlayLayerImpl>(context)) | ||||
|     DrawLayer(context), p(std::make_unique<OverlayLayerImpl>(this, context)) | ||||
| { | ||||
|    AddDrawItem(p->activeBoxOuter_); | ||||
|    AddDrawItem(p->activeBoxInner_); | ||||
|  | @ -130,12 +165,13 @@ void OverlayLayer::Initialize() | |||
|    p->icons_->StartIconSheets(); | ||||
|    p->icons_->AddIconSheet(p->cardinalPointIconName_); | ||||
|    p->icons_->AddIconSheet(p->compassIconName_); | ||||
|    p->icons_->AddIconSheet(p->mapboxLogoImageName_)->SetAnchor(0.0f, 1.0f); | ||||
|    p->icons_->AddIconSheet(p->mapTilerLogoImageName_)->SetAnchor(0.0f, 1.0f); | ||||
|    p->icons_->FinishIconSheets(); | ||||
| 
 | ||||
|    p->icons_->StartIcons(); | ||||
|    p->compassIcon_ = p->icons_->AddIcon(); | ||||
|    gl::draw::Icons::SetIconTexture( | ||||
|       p->compassIcon_, p->cardinalPointIconName_, 0); | ||||
|    p->icons_->SetIconTexture(p->compassIcon_, p->cardinalPointIconName_, 0); | ||||
|    gl::draw::Icons::RegisterEventHandler( | ||||
|       p->compassIcon_, | ||||
|       [this](QEvent* ev) | ||||
|  | @ -144,18 +180,16 @@ void OverlayLayer::Initialize() | |||
|          { | ||||
|          case QEvent::Type::Enter: | ||||
|             // Highlight icon on mouse enter
 | ||||
|             gl::draw::Icons::SetIconModulate( | ||||
|             p->icons_->SetIconModulate( | ||||
|                p->compassIcon_, | ||||
|                boost::gil::rgba32f_pixel_t {1.5f, 1.5f, 1.5f, 1.0f}); | ||||
|             p->compassIconDirty_ = true; | ||||
|             break; | ||||
| 
 | ||||
|          case QEvent::Type::Leave: | ||||
|             // Restore icon on mouse leave
 | ||||
|             gl::draw::Icons::SetIconModulate( | ||||
|             p->icons_->SetIconModulate( | ||||
|                p->compassIcon_, | ||||
|                boost::gil::rgba32f_pixel_t {1.0f, 1.0f, 1.0f, 1.0f}); | ||||
|             p->compassIconDirty_ = true; | ||||
|             break; | ||||
| 
 | ||||
|          case QEvent::Type::MouseButtonPress: | ||||
|  | @ -179,6 +213,17 @@ void OverlayLayer::Initialize() | |||
|             break; | ||||
|          } | ||||
|       }); | ||||
| 
 | ||||
|    p->mapLogoIcon_ = p->icons_->AddIcon(); | ||||
|    if (context()->map_provider() == MapProvider::Mapbox) | ||||
|    { | ||||
|       p->icons_->SetIconTexture(p->mapLogoIcon_, p->mapboxLogoImageName_, 0); | ||||
|    } | ||||
|    else if (context()->map_provider() == MapProvider::MapTiler) | ||||
|    { | ||||
|       p->icons_->SetIconTexture(p->mapLogoIcon_, p->mapTilerLogoImageName_, 0); | ||||
|    } | ||||
| 
 | ||||
|    p->icons_->FinishIcons(); | ||||
| 
 | ||||
|    connect(p->positionManager_.get(), | ||||
|  | @ -204,8 +249,7 @@ void OverlayLayer::Initialize() | |||
|            }); | ||||
| } | ||||
| 
 | ||||
| void OverlayLayer::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
| void OverlayLayer::Render(const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl               = context()->gl(); | ||||
|    auto                 radarProductView = context()->radar_product_view(); | ||||
|  | @ -258,42 +302,29 @@ void OverlayLayer::Render( | |||
|        ImGui::GetFontSize() != p->lastFontSize_) | ||||
|    { | ||||
|       // Set the compass icon in the upper right, below the sweep time window
 | ||||
|       gl::draw::Icons::SetIconLocation(p->compassIcon_, | ||||
|       p->icons_->SetIconLocation(p->compassIcon_, | ||||
|                                  params.width - 24, | ||||
|                                        params.height - | ||||
|                                           (ImGui::GetFontSize() + 32)); | ||||
|       p->compassIconDirty_ = true; | ||||
|                                  params.height - (ImGui::GetFontSize() + 32)); | ||||
|    } | ||||
|    if (params.bearing != p->lastBearing_) | ||||
|    { | ||||
|       if (params.bearing == 0.0) | ||||
|       { | ||||
|          // Use cardinal point icon when bearing is oriented north-up
 | ||||
|          gl::draw::Icons::SetIconTexture( | ||||
|          p->icons_->SetIconTexture( | ||||
|             p->compassIcon_, p->cardinalPointIconName_, 0); | ||||
|          gl::draw::Icons::SetIconAngle(p->compassIcon_, | ||||
|          p->icons_->SetIconAngle(p->compassIcon_, | ||||
|                                  units::angle::degrees<double> {0.0}); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          // Use rotated compass icon when bearing is rotated away from north-up
 | ||||
|          gl::draw::Icons::SetIconTexture( | ||||
|             p->compassIcon_, p->compassIconName_, 0); | ||||
|          gl::draw::Icons::SetIconAngle( | ||||
|          p->icons_->SetIconTexture(p->compassIcon_, p->compassIconName_, 0); | ||||
|          p->icons_->SetIconAngle( | ||||
|             p->compassIcon_, | ||||
|             units::angle::degrees<double> {-45 - params.bearing}); | ||||
|       } | ||||
| 
 | ||||
|       // Mark icon for re-drawing
 | ||||
|       p->compassIconDirty_ = true; | ||||
|    } | ||||
|    if (p->compassIconDirty_) | ||||
|    { | ||||
|       // Update icon render buffers
 | ||||
|       p->icons_->FinishIcons(); | ||||
|    } | ||||
| 
 | ||||
|    DrawLayer::Render(params); | ||||
| 
 | ||||
|    if (radarProductView != nullptr) | ||||
|    { | ||||
|  | @ -356,10 +387,53 @@ void OverlayLayer::Render( | |||
|       ImGui::End(); | ||||
|    } | ||||
| 
 | ||||
|    auto& generalSettings = settings::GeneralSettings::Instance(); | ||||
| 
 | ||||
|    QMargins colorTableMargins = context()->color_table_margins(); | ||||
|    if (colorTableMargins != p->lastColorTableMargins_ || p->firstRender_) | ||||
|    { | ||||
|       // Draw map logo with a 10x10 indent from the bottom left
 | ||||
|       p->icons_->SetIconLocation(p->mapLogoIcon_, | ||||
|                                  10 + colorTableMargins.left(), | ||||
|                                  10 + colorTableMargins.bottom()); | ||||
|       p->icons_->FinishIcons(); | ||||
|    } | ||||
|    p->icons_->SetIconVisible(p->mapLogoIcon_, | ||||
|                              generalSettings.show_map_logo().GetValue()); | ||||
| 
 | ||||
|    DrawLayer::Render(params); | ||||
| 
 | ||||
|    auto mapCopyrights = context()->map_copyrights(); | ||||
|    if (mapCopyrights.length() > 0 && | ||||
|        generalSettings.show_map_attribution().GetValue()) | ||||
|    { | ||||
|       auto attributionFont = manager::FontManager::Instance().GetImGuiFont( | ||||
|          types::FontCategory::Attribution); | ||||
| 
 | ||||
|       ImGui::SetNextWindowPos(ImVec2 {static_cast<float>(params.width), | ||||
|                                       static_cast<float>(params.height) - | ||||
|                                          colorTableMargins.bottom()}, | ||||
|                               ImGuiCond_Always, | ||||
|                               ImVec2 {1.0f, 1.0f}); | ||||
|       ImGui::SetNextWindowBgAlpha(0.5f); | ||||
|       ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2 {3.0f, 2.0f}); | ||||
|       ImGui::PushFont(attributionFont->font()); | ||||
|       ImGui::Begin("Attribution", | ||||
|                    nullptr, | ||||
|                    ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | | ||||
|                       ImGuiWindowFlags_AlwaysAutoResize); | ||||
|       ImGui::TextUnformatted(mapCopyrights.c_str()); | ||||
|       ImGui::End(); | ||||
|       ImGui::PopFont(); | ||||
|       ImGui::PopStyleVar(); | ||||
|    } | ||||
| 
 | ||||
|    p->firstRender_           = false; | ||||
|    p->lastWidth_             = params.width; | ||||
|    p->lastHeight_            = params.height; | ||||
|    p->lastBearing_           = params.bearing; | ||||
|    p->lastFontSize_          = ImGui::GetFontSize(); | ||||
|    p->lastColorTableMargins_ = colorTableMargins; | ||||
| 
 | ||||
|    SCWX_GL_CHECK_ERROR(); | ||||
| } | ||||
|  | @ -393,7 +467,7 @@ void OverlayLayer::Deinitialize() | |||
| } | ||||
| 
 | ||||
| bool OverlayLayer::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    const QPointF&                                mouseLocalPos, | ||||
|    const QPointF&                                mouseGlobalPos, | ||||
|    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -13,16 +13,18 @@ class OverlayLayerImpl; | |||
| 
 | ||||
| class OverlayLayer : public DrawLayer | ||||
| { | ||||
|    Q_DISABLE_COPY_MOVE(OverlayLayer) | ||||
| 
 | ||||
| public: | ||||
|    explicit OverlayLayer(std::shared_ptr<MapContext> context); | ||||
|    ~OverlayLayer(); | ||||
| 
 | ||||
|    void Initialize() override final; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters&) override final; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters&) override final; | ||||
|    void Deinitialize() override final; | ||||
| 
 | ||||
|    bool RunMousePicking( | ||||
|       const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|       const QMapLibre::CustomLayerRenderParameters& params, | ||||
|       const QPointF&                                mouseLocalPos, | ||||
|       const QPointF&                                mouseGlobalPos, | ||||
|       const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -139,7 +139,7 @@ void OverlayProductLayer::Initialize() | |||
| } | ||||
| 
 | ||||
| void OverlayProductLayer::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = context()->gl(); | ||||
| 
 | ||||
|  | @ -436,7 +436,7 @@ std::string OverlayProductLayer::Impl::BuildHoverText( | |||
| } | ||||
| 
 | ||||
| bool OverlayProductLayer::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    const QPointF&                                mouseLocalPos, | ||||
|    const QPointF&                                mouseGlobalPos, | ||||
|    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -16,11 +16,11 @@ public: | |||
|    ~OverlayProductLayer(); | ||||
| 
 | ||||
|    void Initialize() override final; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters&) override final; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters&) override final; | ||||
|    void Deinitialize() override final; | ||||
| 
 | ||||
|    bool RunMousePicking( | ||||
|       const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|       const QMapLibre::CustomLayerRenderParameters& params, | ||||
|       const QPointF&                                mouseLocalPos, | ||||
|       const QPointF&                                mouseGlobalPos, | ||||
|       const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -124,7 +124,7 @@ void PlacefileLayer::Initialize() | |||
| } | ||||
| 
 | ||||
| void PlacefileLayer::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = context()->gl(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -25,7 +25,7 @@ public: | |||
|    void set_placefile_name(const std::string& placefileName); | ||||
| 
 | ||||
|    void Initialize() override final; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters&) override final; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters&) override final; | ||||
|    void Deinitialize() override final; | ||||
| 
 | ||||
|    void ReloadData(); | ||||
|  |  | |||
|  | @ -261,7 +261,7 @@ void RadarProductLayer::UpdateSweep() | |||
| } | ||||
| 
 | ||||
| void RadarProductLayer::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = context()->gl(); | ||||
| 
 | ||||
|  | @ -329,7 +329,7 @@ void RadarProductLayer::Deinitialize() | |||
| } | ||||
| 
 | ||||
| bool RadarProductLayer::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& /* params */, | ||||
|    const QMapLibre::CustomLayerRenderParameters& /* params */, | ||||
|    const QPointF& /* mouseLocalPos */, | ||||
|    const QPointF& mouseGlobalPos, | ||||
|    const glm::vec2& /* mouseCoords */, | ||||
|  |  | |||
|  | @ -18,11 +18,11 @@ public: | |||
|    ~RadarProductLayer(); | ||||
| 
 | ||||
|    void Initialize() override final; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters&) override final; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters&) override final; | ||||
|    void Deinitialize() override final; | ||||
| 
 | ||||
|    virtual bool | ||||
|    RunMousePicking(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    RunMousePicking(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                    const QPointF&                                mouseLocalPos, | ||||
|                    const QPointF&                                mouseGlobalPos, | ||||
|                    const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -15,12 +15,12 @@ namespace map | |||
| static const std::string logPrefix_ = "scwx::qt::map::radar_range_layer"; | ||||
| static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||
| 
 | ||||
| static std::shared_ptr<QMapLibreGL::Feature> | ||||
| GetRangeCircle(float range, QMapLibreGL::Coordinate center); | ||||
| static std::shared_ptr<QMapLibre::Feature> | ||||
| GetRangeCircle(float range, QMapLibre::Coordinate center); | ||||
| 
 | ||||
| void RadarRangeLayer::Add(std::shared_ptr<QMapLibreGL::Map> map, | ||||
| void RadarRangeLayer::Add(std::shared_ptr<QMapLibre::Map> map, | ||||
|                           float                           range, | ||||
|                           QMapLibreGL::Coordinate           center, | ||||
|                           QMapLibre::Coordinate           center, | ||||
|                           const QString&                  before) | ||||
| { | ||||
|    static const QString layerId = QString::fromStdString(types::GetLayerName( | ||||
|  | @ -37,31 +37,30 @@ void RadarRangeLayer::Add(std::shared_ptr<QMapLibreGL::Map> map, | |||
|       map->removeSource("rangeCircleSource"); | ||||
|    } | ||||
| 
 | ||||
|    std::shared_ptr<QMapLibreGL::Feature> rangeCircle = | ||||
|    std::shared_ptr<QMapLibre::Feature> rangeCircle = | ||||
|       GetRangeCircle(range, center); | ||||
| 
 | ||||
|    map->addSource( | ||||
|       "rangeCircleSource", | ||||
|       {{"type", "geojson"}, {"data", QVariant::fromValue(*rangeCircle)}}); | ||||
|    map->addLayer( | ||||
|       {{"id", layerId}, {"type", "line"}, {"source", "rangeCircleSource"}}, | ||||
|       before); | ||||
|       layerId, {{"type", "line"}, {"source", "rangeCircleSource"}}, before); | ||||
|    map->setPaintProperty(layerId, "line-color", "rgba(128, 128, 128, 128)"); | ||||
| } | ||||
| 
 | ||||
| void RadarRangeLayer::Update(std::shared_ptr<QMapLibreGL::Map> map, | ||||
| void RadarRangeLayer::Update(std::shared_ptr<QMapLibre::Map> map, | ||||
|                              float                           range, | ||||
|                              QMapLibreGL::Coordinate           center) | ||||
|                              QMapLibre::Coordinate           center) | ||||
| { | ||||
|    std::shared_ptr<QMapLibreGL::Feature> rangeCircle = | ||||
|    std::shared_ptr<QMapLibre::Feature> rangeCircle = | ||||
|       GetRangeCircle(range, center); | ||||
| 
 | ||||
|    map->updateSource("rangeCircleSource", | ||||
|                      {{"data", QVariant::fromValue(*rangeCircle)}}); | ||||
| } | ||||
| 
 | ||||
| static std::shared_ptr<QMapLibreGL::Feature> | ||||
| GetRangeCircle(float range, QMapLibreGL::Coordinate center) | ||||
| static std::shared_ptr<QMapLibre::Feature> | ||||
| GetRangeCircle(float range, QMapLibre::Coordinate center) | ||||
| { | ||||
|    const GeographicLib::Geodesic& geodesic( | ||||
|       util::GeographicLib::DefaultGeodesic()); | ||||
|  | @ -71,7 +70,7 @@ GetRangeCircle(float range, QMapLibreGL::Coordinate center) | |||
| 
 | ||||
|    float angle = -angleDeltaH; | ||||
| 
 | ||||
|    QMapLibreGL::Coordinates geometry; | ||||
|    QMapLibre::Coordinates geometry; | ||||
| 
 | ||||
|    for (uint16_t azimuth = 0; azimuth <= 720; ++azimuth) | ||||
|    { | ||||
|  | @ -90,11 +89,11 @@ GetRangeCircle(float range, QMapLibreGL::Coordinate center) | |||
|       angle += angleDelta; | ||||
|    } | ||||
| 
 | ||||
|    std::shared_ptr<QMapLibreGL::Feature> rangeCircle = | ||||
|       std::make_shared<QMapLibreGL::Feature>( | ||||
|          QMapLibreGL::Feature::LineStringType, | ||||
|          std::initializer_list<QMapLibreGL::CoordinatesCollection> { | ||||
|             std::initializer_list<QMapLibreGL::Coordinates> {geometry}}); | ||||
|    std::shared_ptr<QMapLibre::Feature> rangeCircle = | ||||
|       std::make_shared<QMapLibre::Feature>( | ||||
|          QMapLibre::Feature::LineStringType, | ||||
|          std::initializer_list<QMapLibre::CoordinatesCollection> { | ||||
|             std::initializer_list<QMapLibre::Coordinates> {geometry}}); | ||||
| 
 | ||||
|    return rangeCircle; | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <QMapLibreGL/QMapLibreGL> | ||||
| #include <qmaplibre.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -11,13 +11,13 @@ namespace map | |||
| namespace RadarRangeLayer | ||||
| { | ||||
| 
 | ||||
| void Add(std::shared_ptr<QMapLibreGL::Map> map, | ||||
| void Add(std::shared_ptr<QMapLibre::Map> map, | ||||
|          float                           range, | ||||
|          QMapLibreGL::Coordinate           center, | ||||
|          QMapLibre::Coordinate           center, | ||||
|          const QString&                  before = QString()); | ||||
| void Update(std::shared_ptr<QMapLibreGL::Map> map, | ||||
| void Update(std::shared_ptr<QMapLibre::Map> map, | ||||
|             float                           range, | ||||
|             QMapLibreGL::Coordinate           center); | ||||
|             QMapLibre::Coordinate           center); | ||||
| 
 | ||||
| } // namespace RadarRangeLayer
 | ||||
| } // namespace map
 | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ | |||
| #include <scwx/common/geographic.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| // #include <GeographicLib/Geodesic.hpp>
 | ||||
| #include <imgui.h> | ||||
| #include <mbgl/util/constants.hpp> | ||||
| 
 | ||||
|  | @ -26,7 +25,7 @@ public: | |||
|    explicit Impl(RadarSiteLayer* self) : self_ {self} {} | ||||
|    ~Impl() = default; | ||||
| 
 | ||||
|    void RenderRadarSite(const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    void RenderRadarSite(const QMapLibre::CustomLayerRenderParameters& params, | ||||
|                         std::shared_ptr<config::RadarSite>& radarSite); | ||||
| 
 | ||||
|    RadarSiteLayer* self_; | ||||
|  | @ -58,7 +57,7 @@ void RadarSiteLayer::Initialize() | |||
| } | ||||
| 
 | ||||
| void RadarSiteLayer::Render( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
|    const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    gl::OpenGLFunctions& gl = context()->gl(); | ||||
| 
 | ||||
|  | @ -90,7 +89,7 @@ void RadarSiteLayer::Render( | |||
| } | ||||
| 
 | ||||
| void RadarSiteLayer::Impl::RenderRadarSite( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|    const QMapLibre::CustomLayerRenderParameters& params, | ||||
|    std::shared_ptr<config::RadarSite>&           radarSite) | ||||
| { | ||||
|    const std::string windowName = fmt::format("radar-site-{}", radarSite->id()); | ||||
|  | @ -158,7 +157,7 @@ void RadarSiteLayer::Deinitialize() | |||
| } | ||||
| 
 | ||||
| bool RadarSiteLayer::RunMousePicking( | ||||
|    const QMapLibreGL::CustomLayerRenderParameters& /* params */, | ||||
|    const QMapLibre::CustomLayerRenderParameters& /* params */, | ||||
|    const QPointF& /* mouseLocalPos */, | ||||
|    const QPointF& mouseGlobalPos, | ||||
|    const glm::vec2& /* mouseCoords */, | ||||
|  |  | |||
|  | @ -19,11 +19,11 @@ public: | |||
|    ~RadarSiteLayer(); | ||||
| 
 | ||||
|    void Initialize() override final; | ||||
|    void Render(const QMapLibreGL::CustomLayerRenderParameters&) override final; | ||||
|    void Render(const QMapLibre::CustomLayerRenderParameters&) override final; | ||||
|    void Deinitialize() override final; | ||||
| 
 | ||||
|    bool RunMousePicking( | ||||
|       const QMapLibreGL::CustomLayerRenderParameters& params, | ||||
|       const QMapLibre::CustomLayerRenderParameters& params, | ||||
|       const QPointF&                                mouseLocalPos, | ||||
|       const QPointF&                                mouseGlobalPos, | ||||
|       const glm::vec2&                              mouseCoords, | ||||
|  |  | |||
|  | @ -46,6 +46,8 @@ public: | |||
|       mapProvider_.SetDefault(defaultMapProviderValue); | ||||
|       mapboxApiKey_.SetDefault("?"); | ||||
|       maptilerApiKey_.SetDefault("?"); | ||||
|       showMapAttribution_.SetDefault(true); | ||||
|       showMapLogo_.SetDefault(true); | ||||
|       theme_.SetDefault(defaultThemeValue); | ||||
|       trackLocation_.SetDefault(false); | ||||
|       updateNotificationsEnabled_.SetDefault(true); | ||||
|  | @ -142,6 +144,8 @@ public: | |||
|    SettingsVariable<std::string>                mapProvider_ {"map_provider"}; | ||||
|    SettingsVariable<std::string> mapboxApiKey_ {"mapbox_api_key"}; | ||||
|    SettingsVariable<std::string> maptilerApiKey_ {"maptiler_api_key"}; | ||||
|    SettingsVariable<bool>        showMapAttribution_ {"show_map_attribution"}; | ||||
|    SettingsVariable<bool>        showMapLogo_ {"show_map_logo"}; | ||||
|    SettingsVariable<std::string> theme_ {"theme"}; | ||||
|    SettingsVariable<bool>        trackLocation_ {"track_location"}; | ||||
|    SettingsVariable<bool> updateNotificationsEnabled_ {"update_notifications"}; | ||||
|  | @ -163,6 +167,8 @@ GeneralSettings::GeneralSettings() : | |||
|                       &p->mapProvider_, | ||||
|                       &p->mapboxApiKey_, | ||||
|                       &p->maptilerApiKey_, | ||||
|                       &p->showMapAttribution_, | ||||
|                       &p->showMapLogo_, | ||||
|                       &p->theme_, | ||||
|                       &p->trackLocation_, | ||||
|                       &p->updateNotificationsEnabled_}); | ||||
|  | @ -240,6 +246,16 @@ SettingsVariable<std::string>& GeneralSettings::maptiler_api_key() const | |||
|    return p->maptilerApiKey_; | ||||
| } | ||||
| 
 | ||||
| SettingsVariable<bool>& GeneralSettings::show_map_attribution() const | ||||
| { | ||||
|    return p->showMapAttribution_; | ||||
| } | ||||
| 
 | ||||
| SettingsVariable<bool>& GeneralSettings::show_map_logo() const | ||||
| { | ||||
|    return p->showMapLogo_; | ||||
| } | ||||
| 
 | ||||
| SettingsVariable<std::string>& GeneralSettings::theme() const | ||||
| { | ||||
|    return p->theme_; | ||||
|  | @ -289,6 +305,8 @@ bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs) | |||
|            lhs.p->mapProvider_ == rhs.p->mapProvider_ && | ||||
|            lhs.p->mapboxApiKey_ == rhs.p->mapboxApiKey_ && | ||||
|            lhs.p->maptilerApiKey_ == rhs.p->maptilerApiKey_ && | ||||
|            lhs.p->showMapAttribution_ == rhs.p->showMapAttribution_ && | ||||
|            lhs.p->showMapLogo_ == rhs.p->showMapLogo_ && | ||||
|            lhs.p->theme_ == rhs.p->theme_ && | ||||
|            lhs.p->trackLocation_ == rhs.p->trackLocation_ && | ||||
|            lhs.p->updateNotificationsEnabled_ == | ||||
|  |  | |||
|  | @ -38,6 +38,8 @@ public: | |||
|    SettingsVariable<std::string>&                map_provider() const; | ||||
|    SettingsVariable<std::string>&                mapbox_api_key() const; | ||||
|    SettingsVariable<std::string>&                maptiler_api_key() const; | ||||
|    SettingsVariable<bool>&                       show_map_attribution() const; | ||||
|    SettingsVariable<bool>&                       show_map_logo() const; | ||||
|    SettingsVariable<std::string>&                theme() const; | ||||
|    SettingsVariable<bool>&                       track_location() const; | ||||
|    SettingsVariable<bool>& update_notifications_enabled() const; | ||||
|  |  | |||
|  | @ -15,19 +15,23 @@ static const std::string logPrefix_ = "scwx::qt::settings::text_settings"; | |||
| static const std::string kAlteDIN1451Mittelscrhift_ { | ||||
|    "Alte DIN 1451 Mittelschrift"}; | ||||
| static const std::string kInconsolata_ {"Inconsolata"}; | ||||
| static const std::string kRobotoFlex_ {"Roboto Flex"}; | ||||
| 
 | ||||
| static const std::string kRegular_ {"Regular"}; | ||||
| 
 | ||||
| static const std::unordered_map<types::FontCategory, std::string> | ||||
|    kDefaultFontFamily_ { | ||||
|       {types::FontCategory::Default, kAlteDIN1451Mittelscrhift_}, | ||||
|       {types::FontCategory::Tooltip, kInconsolata_}}; | ||||
|       {types::FontCategory::Tooltip, kInconsolata_}, | ||||
|       {types::FontCategory::Attribution, kRobotoFlex_}}; | ||||
| static const std::unordered_map<types::FontCategory, std::string> | ||||
|    kDefaultFontStyle_ {{types::FontCategory::Default, kRegular_}, | ||||
|                        {types::FontCategory::Tooltip, kRegular_}}; | ||||
|                        {types::FontCategory::Tooltip, kRegular_}, | ||||
|                        {types::FontCategory::Attribution, kRegular_}}; | ||||
| static const std::unordered_map<types::FontCategory, double> | ||||
|    kDefaultFontPointSize_ {{types::FontCategory::Default, 12.0}, | ||||
|                            {types::FontCategory::Tooltip, 10.5}}; | ||||
|                            {types::FontCategory::Tooltip, 10.5}, | ||||
|                            {types::FontCategory::Attribution, 9.0}}; | ||||
| 
 | ||||
| class TextSettings::Impl | ||||
| { | ||||
|  |  | |||
|  | @ -37,7 +37,8 @@ enum class Font | |||
| { | ||||
|    din1451alt, | ||||
|    din1451alt_g, | ||||
|    Inconsolata_Regular | ||||
|    Inconsolata_Regular, | ||||
|    RobotoFlex_Regular | ||||
| }; | ||||
| 
 | ||||
| } // namespace types
 | ||||
|  |  | |||
|  | @ -7,6 +7,11 @@ namespace qt | |||
| namespace types | ||||
| { | ||||
| 
 | ||||
| void IconInfo::SetAnchor(float anchorX, float anchorY) | ||||
| { | ||||
|    anchor_ = {anchorX, anchorY}; | ||||
| } | ||||
| 
 | ||||
| void IconInfo::UpdateTextureInfo() | ||||
| { | ||||
|    texture_ = util::TextureAtlas::Instance().GetTextureAttributes(iconSheet_); | ||||
|  | @ -26,10 +31,26 @@ void IconInfo::UpdateTextureInfo() | |||
|    } | ||||
| 
 | ||||
|    if (hotX_ == -1 || hotY_ == -1) | ||||
|    { | ||||
|       if (anchor_.has_value()) | ||||
|       { | ||||
|          hotX_ = | ||||
|             std::clamp<std::int32_t>(static_cast<std::int32_t>(std::lround( | ||||
|                                         iconWidth_ * anchor_.value().first)), | ||||
|                                      0, | ||||
|                                      static_cast<std::int32_t>(iconWidth_)); | ||||
|          hotY_ = | ||||
|             std::clamp<std::int32_t>(static_cast<std::int32_t>(std::lround( | ||||
|                                         iconHeight_ * anchor_.value().second)), | ||||
|                                      0, | ||||
|                                      static_cast<std::int32_t>(iconHeight_)); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          hotX_ = static_cast<std::int32_t>(iconWidth_ / 2); | ||||
|          hotY_ = static_cast<std::int32_t>(iconHeight_ / 2); | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    numIcons_ = columns_ * rows_; | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,7 +2,9 @@ | |||
| 
 | ||||
| #include <scwx/qt/util/texture_atlas.hpp> | ||||
| 
 | ||||
| #include <optional> | ||||
| #include <string> | ||||
| #include <utility> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
|  | @ -26,6 +28,7 @@ struct IconInfo | |||
|    { | ||||
|    } | ||||
| 
 | ||||
|    void SetAnchor(float anchorX, float anchorY); | ||||
|    void UpdateTextureInfo(); | ||||
| 
 | ||||
|    std::string             iconSheet_; | ||||
|  | @ -39,6 +42,8 @@ struct IconInfo | |||
|    std::size_t             numIcons_ {}; | ||||
|    float                   scaledWidth_ {}; | ||||
|    float                   scaledHeight_ {}; | ||||
| 
 | ||||
|    std::optional<std::pair<float, float>> anchor_ {}; | ||||
| }; | ||||
| 
 | ||||
| } // namespace types
 | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ namespace types | |||
| static const std::unordered_map<FontCategory, std::string> fontCategoryName_ { | ||||
|    {FontCategory::Default, "Default"}, | ||||
|    {FontCategory::Tooltip, "Tooltip"}, | ||||
|    {FontCategory::Attribution, "Attribution"}, | ||||
|    {FontCategory::Unknown, "?"}}; | ||||
| 
 | ||||
| static const std::unordered_map<TooltipMethod, std::string> tooltipMethodName_ { | ||||
|  |  | |||
|  | @ -15,10 +15,11 @@ enum class FontCategory | |||
| { | ||||
|    Default, | ||||
|    Tooltip, | ||||
|    Attribution, | ||||
|    Unknown | ||||
| }; | ||||
| typedef scwx::util:: | ||||
|    Iterator<FontCategory, FontCategory::Default, FontCategory::Tooltip> | ||||
|    Iterator<FontCategory, FontCategory::Default, FontCategory::Attribution> | ||||
|       FontCategoryIterator; | ||||
| 
 | ||||
| enum class TooltipMethod | ||||
|  |  | |||
|  | @ -21,7 +21,11 @@ static const std::unordered_map<ImageTexture, TextureInfo> imageTextureInfo_ { | |||
|    {ImageTexture::Compass24, | ||||
|     {"images/compass-24", ":/res/icons/flaticon/compass-24.png"}}, | ||||
|    {ImageTexture::Crosshairs24, | ||||
|     {"images/crosshairs-24", ":/res/textures/images/crosshairs-24.png"}}}; | ||||
|     {"images/crosshairs-24", ":/res/textures/images/crosshairs-24.png"}}, | ||||
|    {ImageTexture::MapboxLogo, | ||||
|     {"images/mapbox-logo", ":/res/textures/images/mapbox-logo.svg"}}, | ||||
|    {ImageTexture::MapTilerLogo, | ||||
|     {"images/maptiler-logo", ":/res/textures/images/maptiler-logo.svg"}}}; | ||||
| 
 | ||||
| static const std::unordered_map<LineTexture, TextureInfo> lineTextureInfo_ { | ||||
|    {LineTexture::Default1x7, | ||||
|  |  | |||
|  | @ -15,11 +15,13 @@ enum class ImageTexture | |||
| { | ||||
|    CardinalPoint24, | ||||
|    Compass24, | ||||
|    Crosshairs24 | ||||
|    Crosshairs24, | ||||
|    MapboxLogo, | ||||
|    MapTilerLogo | ||||
| }; | ||||
| typedef scwx::util::Iterator<ImageTexture, | ||||
|                              ImageTexture::CardinalPoint24, | ||||
|                              ImageTexture::Crosshairs24> | ||||
|                              ImageTexture::MapTilerLogo> | ||||
|    ImageTextureIterator; | ||||
| 
 | ||||
| enum class LineTexture | ||||
|  |  | |||
|  | @ -130,6 +130,8 @@ public: | |||
|           &theme_, | ||||
|           &defaultAlertAction_, | ||||
|           &antiAliasingEnabled_, | ||||
|           &showMapAttribution_, | ||||
|           &showMapLogo_, | ||||
|           &updateNotificationsEnabled_, | ||||
|           &debugEnabled_, | ||||
|           &alertAudioSoundFile_, | ||||
|  | @ -220,6 +222,8 @@ public: | |||
|    settings::SettingsInterface<std::string>  defaultAlertAction_ {}; | ||||
|    settings::SettingsInterface<std::string>  theme_ {}; | ||||
|    settings::SettingsInterface<bool>         antiAliasingEnabled_ {}; | ||||
|    settings::SettingsInterface<bool>         showMapAttribution_ {}; | ||||
|    settings::SettingsInterface<bool>         showMapLogo_ {}; | ||||
|    settings::SettingsInterface<bool>         updateNotificationsEnabled_ {}; | ||||
|    settings::SettingsInterface<bool>         debugEnabled_ {}; | ||||
| 
 | ||||
|  | @ -617,6 +621,13 @@ void SettingsDialogImpl::SetupGeneralTab() | |||
|       generalSettings.anti_aliasing_enabled()); | ||||
|    antiAliasingEnabled_.SetEditWidget(self_->ui->antiAliasingEnabledCheckBox); | ||||
| 
 | ||||
|    showMapAttribution_.SetSettingsVariable( | ||||
|       generalSettings.show_map_attribution()); | ||||
|    showMapAttribution_.SetEditWidget(self_->ui->showMapAttributionCheckBox); | ||||
| 
 | ||||
|    showMapLogo_.SetSettingsVariable(generalSettings.show_map_logo()); | ||||
|    showMapLogo_.SetEditWidget(self_->ui->showMapLogoCheckBox); | ||||
| 
 | ||||
|    updateNotificationsEnabled_.SetSettingsVariable( | ||||
|       generalSettings.update_notifications_enabled()); | ||||
|    updateNotificationsEnabled_.SetEditWidget( | ||||
|  |  | |||
|  | @ -322,6 +322,20 @@ | |||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QCheckBox" name="showMapAttributionCheckBox"> | ||||
|              <property name="text"> | ||||
|               <string>Show Map Attribution</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QCheckBox" name="showMapLogoCheckBox"> | ||||
|              <property name="text"> | ||||
|               <string>Show Map Logo</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QCheckBox" name="enableUpdateNotificationsCheckBox"> | ||||
|              <property name="text"> | ||||
|  | @ -373,8 +387,8 @@ | |||
|                    <rect> | ||||
|                     <x>0</x> | ||||
|                     <y>0</y> | ||||
|                     <width>514</width> | ||||
|                     <height>382</height> | ||||
|                     <width>66</width> | ||||
|                     <height>18</height> | ||||
|                    </rect> | ||||
|                   </property> | ||||
|                   <layout class="QGridLayout" name="gridLayout_3"> | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| #include <scwx/qt/util/maplibre.hpp> | ||||
| 
 | ||||
| #include <QMapLibreGL/utils.hpp> | ||||
| #include <QMapLibre/Utils> | ||||
| #include <mbgl/util/constants.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
|  | @ -13,14 +13,14 @@ namespace maplibre | |||
| { | ||||
| 
 | ||||
| units::length::meters<double> | ||||
| GetMapDistance(const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
| GetMapDistance(const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    return units::length::meters<double>( | ||||
|       QMapLibreGL::metersPerPixelAtLatitude(params.latitude, params.zoom) * | ||||
|       QMapLibre::metersPerPixelAtLatitude(params.latitude, params.zoom) * | ||||
|       (params.width + params.height) / 2.0); | ||||
| } | ||||
| 
 | ||||
| glm::mat4 GetMapMatrix(const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
| glm::mat4 GetMapMatrix(const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    glm::vec2 scale = GetMapScale(params); | ||||
| 
 | ||||
|  | @ -33,7 +33,7 @@ glm::mat4 GetMapMatrix(const QMapLibreGL::CustomLayerRenderParameters& params) | |||
|    return mapMatrix; | ||||
| } | ||||
| 
 | ||||
| glm::vec2 GetMapScale(const QMapLibreGL::CustomLayerRenderParameters& params) | ||||
| glm::vec2 GetMapScale(const QMapLibre::CustomLayerRenderParameters& params) | ||||
| { | ||||
|    const float scale = std::pow(2.0, params.zoom) * 2.0f * | ||||
|                        mbgl::util::tileSize_D / mbgl::util::DEGREES_MAX; | ||||
|  | @ -73,7 +73,7 @@ bool IsPointInPolygon(const std::vector<glm::vec2>& vertices, | |||
|    return inPolygon; | ||||
| } | ||||
| 
 | ||||
| glm::vec2 LatLongToScreenCoordinate(const QMapLibreGL::Coordinate& coordinate) | ||||
| glm::vec2 LatLongToScreenCoordinate(const QMapLibre::Coordinate& coordinate) | ||||
| { | ||||
|    static constexpr double RAD2DEG_D = 180.0 / M_PI; | ||||
| 
 | ||||
|  | @ -88,6 +88,26 @@ glm::vec2 LatLongToScreenCoordinate(const QMapLibreGL::Coordinate& coordinate) | |||
|    return screen; | ||||
| } | ||||
| 
 | ||||
| void SetMapStyleUrl(const std::shared_ptr<map::MapContext>& mapContext, | ||||
|                     const std::string&                      url) | ||||
| { | ||||
|    const auto mapProvider = mapContext->map_provider(); | ||||
| 
 | ||||
|    QString qUrl = QString::fromStdString(url); | ||||
| 
 | ||||
|    if (mapProvider == map::MapProvider::MapTiler) | ||||
|    { | ||||
|       qUrl.append("?key="); | ||||
|       qUrl.append(map::GetMapProviderApiKey(mapProvider)); | ||||
|    } | ||||
| 
 | ||||
|    auto map = mapContext->map().lock(); | ||||
|    if (map != nullptr) | ||||
|    { | ||||
|       map->setStyleUrl(qUrl); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| } // namespace maplibre
 | ||||
| } // namespace util
 | ||||
| } // namespace qt
 | ||||
|  |  | |||
|  | @ -1,6 +1,9 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <QMapLibreGL/types.hpp> | ||||
| #include <scwx/qt/map/map_context.hpp> | ||||
| 
 | ||||
| #include <QMapLibre/Map> | ||||
| #include <QMapLibre/Types> | ||||
| #include <glm/gtc/type_ptr.hpp> | ||||
| #include <units/length.h> | ||||
| 
 | ||||
|  | @ -14,9 +17,9 @@ namespace maplibre | |||
| { | ||||
| 
 | ||||
| units::length::meters<double> | ||||
| GetMapDistance(const QMapLibreGL::CustomLayerRenderParameters& params); | ||||
| glm::mat4 GetMapMatrix(const QMapLibreGL::CustomLayerRenderParameters& params); | ||||
| glm::vec2 GetMapScale(const QMapLibreGL::CustomLayerRenderParameters& params); | ||||
|           GetMapDistance(const QMapLibre::CustomLayerRenderParameters& params); | ||||
| glm::mat4 GetMapMatrix(const QMapLibre::CustomLayerRenderParameters& params); | ||||
| glm::vec2 GetMapScale(const QMapLibre::CustomLayerRenderParameters& params); | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Determine whether a point lies within a polygon | ||||
|  | @ -29,7 +32,10 @@ glm::vec2 GetMapScale(const QMapLibreGL::CustomLayerRenderParameters& params); | |||
| bool IsPointInPolygon(const std::vector<glm::vec2>& vertices, | ||||
|                       const glm::vec2&              point); | ||||
| 
 | ||||
| glm::vec2 LatLongToScreenCoordinate(const QMapLibreGL::Coordinate& coordinate); | ||||
| glm::vec2 LatLongToScreenCoordinate(const QMapLibre::Coordinate& coordinate); | ||||
| 
 | ||||
| void SetMapStyleUrl(const std::shared_ptr<map::MapContext>& mapContext, | ||||
|                     const std::string&                      url); | ||||
| 
 | ||||
| } // namespace maplibre
 | ||||
| } // namespace util
 | ||||
|  |  | |||
|  | @ -20,6 +20,9 @@ | |||
| #include <stb_image.h> | ||||
| #include <stb_rect_pack.h> | ||||
| #include <QFile> | ||||
| #include <QFileInfo> | ||||
| #include <QPainter> | ||||
| #include <QSvgRenderer> | ||||
| #include <QUrl> | ||||
| 
 | ||||
| #if defined(_MSC_VER) | ||||
|  | @ -49,6 +52,11 @@ public: | |||
|    static std::shared_ptr<boost::gil::rgba8_image_t> | ||||
|    LoadImage(const std::string& imagePath); | ||||
| 
 | ||||
|    static std::shared_ptr<boost::gil::rgba8_image_t> | ||||
|    ReadPngFile(const QString& imagePath); | ||||
|    static std::shared_ptr<boost::gil::rgba8_image_t> | ||||
|    ReadSvgFile(const QString& imagePath); | ||||
| 
 | ||||
|    std::vector<std::shared_ptr<boost::gil::rgba8_image_t>> | ||||
|                      registeredTextures_ {}; | ||||
|    std::shared_mutex registeredTextureMutex_ {}; | ||||
|  | @ -376,34 +384,23 @@ TextureAtlas::Impl::LoadImage(const std::string& imagePath) | |||
| { | ||||
|    logger_->debug("Loading image: {}", imagePath); | ||||
| 
 | ||||
|    std::shared_ptr<boost::gil::rgba8_image_t> image = | ||||
|       std::make_shared<boost::gil::rgba8_image_t>(); | ||||
|    std::shared_ptr<boost::gil::rgba8_image_t> image = nullptr; | ||||
| 
 | ||||
|    QUrl url = QUrl::fromUserInput(QString::fromStdString(imagePath)); | ||||
|    QString qImagePath = QString::fromStdString(imagePath); | ||||
| 
 | ||||
|    QUrl url = QUrl::fromUserInput(qImagePath); | ||||
| 
 | ||||
|    if (url.isLocalFile()) | ||||
|    { | ||||
|       QFile imageFile(imagePath.c_str()); | ||||
|       QString suffix = QFileInfo(qImagePath).suffix().toLower(); | ||||
| 
 | ||||
|       imageFile.open(QIODevice::ReadOnly); | ||||
| 
 | ||||
|       if (!imageFile.isOpen()) | ||||
|       if (suffix == "svg") | ||||
|       { | ||||
|          logger_->error("Could not open image: {}", imagePath); | ||||
|          return nullptr; | ||||
|          image = ReadSvgFile(qImagePath); | ||||
|       } | ||||
| 
 | ||||
|       boost::iostreams::stream<util::IoDeviceSource> dataStream(imageFile); | ||||
| 
 | ||||
|       try | ||||
|       else | ||||
|       { | ||||
|          boost::gil::read_and_convert_image( | ||||
|             dataStream, *image, boost::gil::png_tag()); | ||||
|       } | ||||
|       catch (const std::exception& ex) | ||||
|       { | ||||
|          logger_->error("Error reading image: {}", ex.what()); | ||||
|          return nullptr; | ||||
|          image = ReadPngFile(qImagePath); | ||||
|       } | ||||
|    } | ||||
|    else | ||||
|  | @ -442,6 +439,7 @@ TextureAtlas::Impl::LoadImage(const std::string& imagePath) | |||
|             width * desiredChannels); | ||||
| 
 | ||||
|          // Copy the view to the destination image
 | ||||
|          image      = std::make_shared<boost::gil::rgba8_image_t>(); | ||||
|          *image     = boost::gil::rgba8_image_t(stbView); | ||||
|          auto& view = boost::gil::view(*image); | ||||
| 
 | ||||
|  | @ -477,6 +475,69 @@ TextureAtlas::Impl::LoadImage(const std::string& imagePath) | |||
|    return image; | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<boost::gil::rgba8_image_t> | ||||
| TextureAtlas::Impl::ReadPngFile(const QString& imagePath) | ||||
| { | ||||
|    QFile imageFile(imagePath); | ||||
| 
 | ||||
|    imageFile.open(QIODevice::ReadOnly); | ||||
| 
 | ||||
|    if (!imageFile.isOpen()) | ||||
|    { | ||||
|       logger_->error("Could not open image: {}", imagePath.toStdString()); | ||||
|       return nullptr; | ||||
|    } | ||||
| 
 | ||||
|    boost::iostreams::stream<util::IoDeviceSource> dataStream(imageFile); | ||||
|    std::shared_ptr<boost::gil::rgba8_image_t>     image = | ||||
|       std::make_shared<boost::gil::rgba8_image_t>(); | ||||
| 
 | ||||
|    try | ||||
|    { | ||||
|       boost::gil::read_and_convert_image( | ||||
|          dataStream, *image, boost::gil::png_tag()); | ||||
|    } | ||||
|    catch (const std::exception& ex) | ||||
|    { | ||||
|       logger_->error("Error reading image: {}", ex.what()); | ||||
|       return nullptr; | ||||
|    } | ||||
| 
 | ||||
|    return image; | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<boost::gil::rgba8_image_t> | ||||
| TextureAtlas::Impl::ReadSvgFile(const QString& imagePath) | ||||
| { | ||||
|    QSvgRenderer renderer {imagePath}; | ||||
|    QPixmap      pixmap {renderer.defaultSize()}; | ||||
|    pixmap.fill(Qt::GlobalColor::transparent); | ||||
| 
 | ||||
|    QPainter painter {&pixmap}; | ||||
|    renderer.render(&painter, pixmap.rect()); | ||||
| 
 | ||||
|    QImage qImage = pixmap.toImage(); | ||||
| 
 | ||||
|    std::shared_ptr<boost::gil::rgba8_image_t> image = nullptr; | ||||
| 
 | ||||
|    if (qImage.width() > 0 && qImage.height() > 0) | ||||
|    { | ||||
|       // Convert to ARGB32 format if not already (equivalent to bgra8_pixel_t)
 | ||||
|       qImage.convertTo(QImage::Format_ARGB32); | ||||
| 
 | ||||
|       // Create a view pointing to the underlying QImage pixel data
 | ||||
|       auto view = boost::gil::interleaved_view( | ||||
|          qImage.width(), | ||||
|          qImage.height(), | ||||
|          reinterpret_cast<const boost::gil::bgra8_pixel_t*>(qImage.constBits()), | ||||
|          qImage.width() * 4); | ||||
| 
 | ||||
|       image = std::make_shared<boost::gil::rgba8_image_t>(view); | ||||
|    } | ||||
| 
 | ||||
|    return image; | ||||
| } | ||||
| 
 | ||||
| TextureAtlas& TextureAtlas::Instance() | ||||
| { | ||||
|    static TextureAtlas instance_ {}; | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ call tools\setup-common.bat | |||
| 
 | ||||
| set build_dir=build-debug | ||||
| set build_type=Debug | ||||
| set qt_version=6.6.1 | ||||
| set qt_version=6.6.2 | ||||
| 
 | ||||
| mkdir %build_dir% | ||||
| cmake -B %build_dir% -S . ^ | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| 
 | ||||
| build_dir=${1:-build-debug} | ||||
| build_type=Debug | ||||
| qt_version=6.6.1 | ||||
| qt_version=6.6.2 | ||||
| script_dir="$(dirname "$(readlink -f "$0")")" | ||||
| 
 | ||||
| mkdir -p ${build_dir} | ||||
|  |  | |||
|  | @ -2,7 +2,7 @@ call tools\setup-common.bat | |||
| 
 | ||||
| set build_dir=build-release | ||||
| set build_type=Release | ||||
| set qt_version=6.6.1 | ||||
| set qt_version=6.6.2 | ||||
| 
 | ||||
| mkdir %build_dir% | ||||
| cmake -B %build_dir% -S . ^ | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| 
 | ||||
| build_dir=${1:-build-release} | ||||
| build_type=Release | ||||
| qt_version=6.6.1 | ||||
| qt_version=6.6.2 | ||||
| script_dir="$(dirname "$(readlink -f "$0")")" | ||||
| 
 | ||||
| mkdir -p ${build_dir} | ||||
|  |  | |||
|  | @ -1 +1 @@ | |||
| Subproject commit 0446ff708b387728faf8d2dbb3862a757067c2ee | ||||
| Subproject commit 9cef3730c84d22803ea433fba8111826327dd82f | ||||
|  | @ -25,7 +25,7 @@ TEST(AwsLevel2DataProvider, FindKeyFixed) | |||
| 
 | ||||
| TEST(AwsLevel2DataProvider, FindKeyNow) | ||||
| { | ||||
|    AwsLevel2DataProvider provider("KLSX"); | ||||
|    AwsLevel2DataProvider provider("KILX"); | ||||
| 
 | ||||
|    provider.Refresh(); | ||||
|    std::string key = provider.FindKey(std::chrono::system_clock::now()); | ||||
|  | @ -78,7 +78,7 @@ TEST(AwsLevel2DataProvider, Prune) | |||
| 
 | ||||
| TEST(AwsLevel2DataProvider, Refresh) | ||||
| { | ||||
|    AwsLevel2DataProvider provider("KLSX"); | ||||
|    AwsLevel2DataProvider provider("KILX"); | ||||
| 
 | ||||
|    auto [newObjects, totalObjects] = provider.Refresh(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -25,7 +25,7 @@ TEST(AwsLevel3DataProvider, FindKeyFixed) | |||
| 
 | ||||
| TEST(AwsLevel3DataProvider, FindKeyNow) | ||||
| { | ||||
|    AwsLevel3DataProvider provider("KLSX", "N0B"); | ||||
|    AwsLevel3DataProvider provider("KILX", "N0B"); | ||||
| 
 | ||||
|    provider.Refresh(); | ||||
|    std::string key = provider.FindKey(std::chrono::system_clock::now()); | ||||
|  | @ -46,7 +46,7 @@ TEST(AwsLevel3DataProvider, LoadObjectByKey) | |||
| 
 | ||||
| TEST(AwsLevel3DataProvider, Refresh) | ||||
| { | ||||
|    AwsLevel3DataProvider provider("KLSX", "N0B"); | ||||
|    AwsLevel3DataProvider provider("KILX", "N0B"); | ||||
| 
 | ||||
|    auto [newObjects, totalObjects] = provider.Refresh(); | ||||
| 
 | ||||
|  | @ -58,7 +58,7 @@ TEST(AwsLevel3DataProvider, Refresh) | |||
| 
 | ||||
| TEST(AwsLevel3DataProvider, GetAvailableProducts) | ||||
| { | ||||
|    AwsLevel3DataProvider provider("KLSX", "N0B"); | ||||
|    AwsLevel3DataProvider provider("KILX", "N0B"); | ||||
| 
 | ||||
|    provider.RequestAvailableProducts(); | ||||
|    auto products = provider.GetAvailableProducts(); | ||||
|  |  | |||
|  | @ -1,12 +1,14 @@ | |||
| #include <scwx/qt/map/map_provider.hpp> | ||||
| #include <scwx/qt/settings/general_settings.hpp> | ||||
| #include <scwx/qt/util/maplibre.hpp> | ||||
| #include <scwx/util/environment.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
| 
 | ||||
| #include <QCoreApplication> | ||||
| #include <QMapLibreGL/QMapLibreGL> | ||||
| #include <QTimer> | ||||
| 
 | ||||
| #include <gtest/gtest.h> | ||||
| #include <qmaplibre.hpp> | ||||
| #include <re2/re2.h> | ||||
| 
 | ||||
| namespace scwx | ||||
|  | @ -45,22 +47,34 @@ TEST_P(ByMapProviderTest, MapProviderLayers) | |||
|    // Configure map provider
 | ||||
|    const MapProviderInfo& mapProviderInfo = GetMapProviderInfo(mapProvider); | ||||
| 
 | ||||
|    // Configure QMapLibreGL
 | ||||
|    QMapLibreGL::Settings mapSettings {}; | ||||
|    mapSettings.resetToTemplate(mapProviderInfo.settingsTemplate_); | ||||
|    // Configure QMapLibre
 | ||||
|    QMapLibre::Settings mapSettings {}; | ||||
|    if (mapProvider == map::MapProvider::Mapbox) | ||||
|    { | ||||
|       mapSettings.setProviderTemplate(mapProviderInfo.providerTemplate_); | ||||
|       mapSettings.setApiKey(QString::fromStdString(apiKey)); | ||||
|    } | ||||
|    else if (mapProvider == map::MapProvider::MapTiler) | ||||
|    { | ||||
|       settings::GeneralSettings::Instance().maptiler_api_key().SetValue(apiKey); | ||||
|    } | ||||
| 
 | ||||
|    QMapLibreGL::Map map(nullptr, mapSettings, QSize(1, 1)); | ||||
|    std::shared_ptr<map::MapContext> mapContext = | ||||
|       std::make_shared<map::MapContext>(); | ||||
|    std::shared_ptr<QMapLibre::Map> map = | ||||
|       std::make_shared<QMapLibre::Map>(nullptr, mapSettings, QSize(1, 1)); | ||||
|    mapContext->set_map(map); | ||||
|    mapContext->set_map_provider(mapProvider); | ||||
|    application.processEvents(); | ||||
| 
 | ||||
|    // Connect style load completion signal
 | ||||
|    QObject::connect( | ||||
|       &map, | ||||
|       &QMapLibreGL::Map::mapChanged, | ||||
|       [&](QMapLibreGL::Map::MapChange mapChange) | ||||
|       map.get(), | ||||
|       &QMapLibre::Map::mapChanged, | ||||
|       [&](QMapLibre::Map::MapChange mapChange) | ||||
|       { | ||||
|          if (mapChange == | ||||
|              QMapLibreGL::Map::MapChange::MapChangeDidFinishLoadingStyle) | ||||
|              QMapLibre::Map::MapChange::MapChangeDidFinishLoadingStyle) | ||||
|          { | ||||
|             application.exit(); | ||||
|          } | ||||
|  | @ -88,7 +102,7 @@ TEST_P(ByMapProviderTest, MapProviderLayers) | |||
| 
 | ||||
|       // Load style
 | ||||
|       timeout = false; | ||||
|       map.setStyleUrl(QString::fromStdString(mapStyle.url_)); | ||||
|       util::maplibre::SetMapStyleUrl(mapContext, mapStyle.url_); | ||||
|       timeoutTimer.start(5000ms); | ||||
|       application.exec(); | ||||
|       timeoutTimer.stop(); | ||||
|  | @ -97,12 +111,12 @@ TEST_P(ByMapProviderTest, MapProviderLayers) | |||
|       if (!timeout) | ||||
|       { | ||||
|          // Print layer names for debug
 | ||||
|          std::string layerIdsString = map.layerIds().join(", ").toStdString(); | ||||
|          std::string layerIdsString = map->layerIds().join(", ").toStdString(); | ||||
|          logger_->debug("{} Layers: [{}]", mapStyle.name_, layerIdsString); | ||||
| 
 | ||||
|          // Search layer list
 | ||||
|          bool foundMatch = false; | ||||
|          for (const QString& qlayer : map.layerIds()) | ||||
|          for (const QString& qlayer : map->layerIds()) | ||||
|          { | ||||
|             const std::string layer = qlayer.toStdString(); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat