diff --git a/felt/core/layer_exporter.py b/felt/core/layer_exporter.py index 272243f..3207013 100644 --- a/felt/core/layer_exporter.py +++ b/felt/core/layer_exporter.py @@ -267,7 +267,8 @@ def generate_file_name(self, suffix: str) -> str: def export_layer_for_felt( self, layer: QgsMapLayer, - feedback: Optional[QgsFeedback] = None + feedback: Optional[QgsFeedback] = None, + upload_raster_as_styled: bool = True ) -> ZippedExportResult: """ Exports a layer into a format acceptable for Felt @@ -276,7 +277,9 @@ def export_layer_for_felt( if isinstance(layer, QgsVectorLayer): res = self.export_vector_layer(layer, feedback) elif isinstance(layer, QgsRasterLayer): - res = self.export_raster_layer(layer, feedback) + res = self.export_raster_layer( + layer, feedback, + upload_raster_as_styled) else: assert False @@ -504,17 +507,17 @@ def run_raster_writer(self, def export_raster_layer( self, layer: QgsRasterLayer, - feedback: Optional[QgsFeedback] = None) -> LayerExportDetails: + feedback: Optional[QgsFeedback] = None, + upload_raster_as_styled: bool = True) -> LayerExportDetails: """ Exports a raster layer into a format acceptable for Felt """ - raw_dest_file = self.generate_file_name('.tif') - styled_dest_file = raw_dest_file.replace('.tif', '_styled.tif') + dest_file = self.generate_file_name('.tif') layer_export_result, error_message = self.run_raster_writer( layer, - file_name=styled_dest_file, - use_style=True, + file_name=dest_file, + use_style=upload_raster_as_styled, feedback=feedback) if error_message: @@ -526,31 +529,9 @@ def export_raster_layer( ) raise LayerPackagingException(error_message) - filenames = [styled_dest_file] - if layer_export_result != LayerExportResult.Canceled: - # also write raw raster - - layer_export_result, error_message = self.run_raster_writer( - layer, - file_name=raw_dest_file, - use_style=False, - feedback=feedback) - - if error_message: - Logger.instance().log_error_json( - { - 'type': Logger.PACKAGING_RASTER, - 'error': 'Error packaging layer: {}'.format( - error_message) - } - ) - raise LayerPackagingException(error_message) - - filenames.append(raw_dest_file) - return LayerExportDetails( - representative_filename=raw_dest_file, - filenames=filenames, + representative_filename=dest_file, + filenames=[dest_file], result=layer_export_result, error_message=error_message, qgis_style_xml=self._get_original_style_xml(layer) diff --git a/felt/core/map_uploader.py b/felt/core/map_uploader.py index da9ea05..c990e48 100644 --- a/felt/core/map_uploader.py +++ b/felt/core/map_uploader.py @@ -42,7 +42,8 @@ QgsTask, QgsFeedback, QgsBlockingNetworkRequest, - QgsReferencedRectangle + QgsReferencedRectangle, + QgsSettings ) from qgis.utils import iface @@ -250,6 +251,10 @@ def run(self): self.feedback = QgsFeedback() + upload_raster_as_styled = QgsSettings().value( + "felt/upload_raster_as_styled", True, bool, QgsSettings.Plugins + ) + multi_step_feedback = MultiStepFeedback( total_steps, self.feedback ) @@ -342,7 +347,8 @@ def run(self): try: result = exporter.export_layer_for_felt( layer, - multi_step_feedback + multi_step_feedback, + upload_raster_as_styled=upload_raster_as_styled ) except LayerPackagingException as e: layer.moveToThread(None) diff --git a/felt/gui/create_map_dialog.py b/felt/gui/create_map_dialog.py index 28b9165..f0b741a 100644 --- a/felt/gui/create_map_dialog.py +++ b/felt/gui/create_map_dialog.py @@ -42,7 +42,8 @@ from qgis.core import ( QgsMapLayer, QgsApplication, - QgsProject + QgsProject, + QgsSettings ) from qgis.gui import QgsGui @@ -161,6 +162,30 @@ def __init__(self, # pylint: disable=too-many-statements QColor(255, 255, 255)) self.setting_menu.setPalette(palette) + self.upload_raster_as_styled_action = QAction(self.tr('Upload Raster Layers as Styled Images'), + self.setting_menu) + self.upload_raster_as_styled_action.setCheckable(True) + self.upload_raster_as_styled_action.setChecked( + QgsSettings().value( + "felt/upload_raster_as_styled", True, bool, QgsSettings.Plugins + ) + ) + + def upload_raster_as_styled_toggled(): + """ + Called when upload raster as style action is toggled + """ + QgsSettings().setValue( + "felt/upload_raster_as_styled", + self.upload_raster_as_styled_action.isChecked(), + QgsSettings.Plugins + ) + + self.upload_raster_as_styled_action.toggled.connect( + upload_raster_as_styled_toggled) + self.setting_menu.addAction(self.upload_raster_as_styled_action) + + self.setting_menu.addSeparator() self.logout_action = QAction(self.tr('Log Out'), self.setting_menu) self.setting_menu.addAction(self.logout_action) self.logout_action.triggered.connect(self._logout) diff --git a/felt/test/test_layer_exporter.py b/felt/test/test_layer_exporter.py index 02d581e..6e56675 100644 --- a/felt/test/test_layer_exporter.py +++ b/felt/test/test_layer_exporter.py @@ -217,9 +217,9 @@ def test_gml_conversion(self): self.assertEqual(out_layer.featureCount(), layer.featureCount()) self.assertEqual(out_layer.wkbType(), QgsWkbTypes.MultiPolygon) - def test_raster_conversion(self): + def test_raster_conversion_raw(self): """ - Test raster layer conversion + Test raw raster layer conversion """ file = str(TEST_DATA_PATH / 'dem.tif') layer = QgsRasterLayer(file, 'test') @@ -228,15 +228,14 @@ def test_raster_conversion(self): exporter = LayerExporter( QgsCoordinateTransformContext() ) - result = exporter.export_layer_for_felt(layer) + result = exporter.export_layer_for_felt(layer, + upload_raster_as_styled=False) self.assertEqual(result.result, LayerExportResult.Success) self.assertTrue(result.filename) self.assertEqual(result.filename[-4:], '.zip') with zipfile.ZipFile(result.filename) as z: tif_files = [f for f in z.namelist() if f.endswith('tif')] - self.assertEqual(len(tif_files), 2) - - styled_tif = [f for f in tif_files if '_styled' in f][0] + self.assertEqual(len(tif_files), 1) self.assertEqual( result.qgis_style_xml[:58], @@ -244,20 +243,14 @@ def test_raster_conversion(self): ) out_layer = QgsRasterLayer( - '/vsizip/{}/{}'.format(result.filename, styled_tif), + '/vsizip/{}/{}'.format(result.filename, tif_files[0]), 'test') self.assertTrue(out_layer.isValid()) self.assertEqual(out_layer.width(), 373) self.assertEqual(out_layer.height(), 350) - self.assertEqual(out_layer.bandCount(), 4) + self.assertEqual(out_layer.bandCount(), 1) self.assertEqual(out_layer.dataProvider().dataType(1), - Qgis.DataType.Byte) - self.assertEqual(out_layer.dataProvider().dataType(2), - Qgis.DataType.Byte) - self.assertEqual(out_layer.dataProvider().dataType(3), - Qgis.DataType.Byte) - self.assertEqual(out_layer.dataProvider().dataType(4), - Qgis.DataType.Byte) + Qgis.DataType.Float32) self.assertEqual(out_layer.crs(), QgsCoordinateReferenceSystem('EPSG:4326')) self.assertAlmostEqual(out_layer.extent().xMinimum(), @@ -269,16 +262,46 @@ def test_raster_conversion(self): self.assertAlmostEqual(out_layer.extent().yMaximum(), 45.8117014376, 3) - raw_tif = [f for f in tif_files if '_styled' not in f][0] + def test_raster_conversion_styled(self): + """ + Test raster layer conversion + """ + file = str(TEST_DATA_PATH / 'dem.tif') + layer = QgsRasterLayer(file, 'test') + self.assertTrue(layer.isValid()) + + exporter = LayerExporter( + QgsCoordinateTransformContext() + ) + result = exporter.export_layer_for_felt(layer, + upload_raster_as_styled=True) + self.assertEqual(result.result, LayerExportResult.Success) + self.assertTrue(result.filename) + self.assertEqual(result.filename[-4:], '.zip') + with zipfile.ZipFile(result.filename) as z: + tif_files = [f for f in z.namelist() if f.endswith('tif')] + self.assertEqual(len(tif_files), 1) + + self.assertEqual( + result.qgis_style_xml[:58], + "" + ) + out_layer = QgsRasterLayer( - '/vsizip/{}/{}'.format(result.filename, raw_tif), + '/vsizip/{}/{}'.format(result.filename, tif_files[0]), 'test') self.assertTrue(out_layer.isValid()) self.assertEqual(out_layer.width(), 373) self.assertEqual(out_layer.height(), 350) - self.assertEqual(out_layer.bandCount(), 1) + self.assertEqual(out_layer.bandCount(), 4) self.assertEqual(out_layer.dataProvider().dataType(1), - Qgis.DataType.Float32) + Qgis.DataType.Byte) + self.assertEqual(out_layer.dataProvider().dataType(2), + Qgis.DataType.Byte) + self.assertEqual(out_layer.dataProvider().dataType(3), + Qgis.DataType.Byte) + self.assertEqual(out_layer.dataProvider().dataType(4), + Qgis.DataType.Byte) self.assertEqual(out_layer.crs(), QgsCoordinateReferenceSystem('EPSG:4326')) self.assertAlmostEqual(out_layer.extent().xMinimum(),