Beispiel #1
0
    def createBaseMapLayer(self, map_theme, layer, tile_size,
                           map_units_per_pixel):
        """
        Create a basemap from map layer(s)

        :param dataPath:             The path where the basemap should be writtent to
        :param extent:               The extent rectangle in which data shall be fetched
        :param map_theme:            The name of the map theme to be rendered
        :param layer:                A layer id to be rendered. Will only be used if map_theme is None.
        :param tile_size:            The extent rectangle in which data shall be fetched
        :param map_units_per_pixel:  Number of map units per pixel (1: 1 m per pixel, 10: 10 m per pixel...)
        """
        extent_string = '{},{},{},{}'.format(self.extent.xMinimum(),
                                             self.extent.xMaximum(),
                                             self.extent.yMinimum(),
                                             self.extent.yMaximum())

        alg = QgsApplication.instance().processingRegistry(
        ).createAlgorithmById('qgis:rasterize')

        params = {
            'EXTENT': extent_string,
            'MAP_THEME': map_theme,
            'LAYER': layer,
            'MAP_UNITS_PER_PIXEL': map_units_per_pixel,
            'TILE_SIZE': tile_size,
            'MAKE_BACKGROUND_TRANSPARENT': False,
            'OUTPUT': os.path.join(self.export_folder, 'basemap.gpkg')
        }

        feedback = QgsProcessingFeedback()
        context = QgsProcessingContext()
        context.setProject(QgsProject.instance())

        results, ok = alg.run(params, context, feedback)

        new_layer = QgsRasterLayer(results['OUTPUT'], self.tr('Basemap'))

        resample_filter = new_layer.resampleFilter()
        resample_filter.setZoomedInResampler(QgsCubicRasterResampler())
        resample_filter.setZoomedOutResampler(QgsBilinearRasterResampler())
        self.project_configuration.project.addMapLayer(new_layer, False)
        layer_tree = QgsProject.instance().layerTreeRoot()
        layer_tree.insertLayer(len(layer_tree.children()), new_layer)
Beispiel #2
0
    def createBaseMapLayer(self, map_theme, layer, tile_size,
                           map_units_per_pixel):
        """
        Create a basemap from map layer(s)

        :param dataPath:             The path where the basemap should be writtent to
        :param extent:               The extent rectangle in which data shall be fetched
        :param map_theme:            The name of the map theme to be rendered
        :param layer:                A layer id to be rendered. Will only be used if map_theme is None.
        :param tile_size:            The extent rectangle in which data shall be fetched
        :param map_units_per_pixel:  Number of map units per pixel (1: 1 m per pixel, 10: 10 m per pixel...)
        """
        extent_string = '{},{},{},{}'.format(self.extent.xMinimum(),
                                             self.extent.xMaximum(),
                                             self.extent.yMinimum(),
                                             self.extent.yMaximum())

        alg = processing.Processing.getAlgorithm(
            'qfieldsync:basemap').getCopy()

        alg.setParameterValue('EXTENT', extent_string)
        alg.setParameterValue('MAP_THEME', map_theme)
        alg.setParameterValue('LAYER', layer)
        alg.setParameterValue('MAP_UNITS_PER_PIXEL', map_units_per_pixel)
        alg.setParameterValue('TILE_SIZE', tile_size)
        alg.setOutputValue('OUTPUT_LAYER',
                           os.path.join(self.export_folder, 'basemap.gpkg'))
        alg.execute(progress=self.convertorProcessingProgress())

        out = alg.outputs[0]
        new_layer = QgsRasterLayer(out.value, self.tr('Basemap'))

        resample_filter = new_layer.resampleFilter()
        resample_filter.setZoomedInResampler(QgsCubicRasterResampler())
        resample_filter.setZoomedOutResampler(QgsBilinearRasterResampler())
        self.project_configuration.project.addMapLayer(new_layer, False)
        layer_tree = QgsProject.instance().layerTreeRoot()
        layer_tree.insertLayer(len(layer_tree.children()), new_layer)
Beispiel #3
0
    def _export_basemap(self) -> bool:
        self.total_progress_updated.emit(0, 1,
                                         self.trUtf8("Creating base map…"))

        if not self._export_basemap_requirements_check():
            return False

        project = QgsProject.instance()
        basemap_extent = self.area_of_interest.boundingBox()

        if basemap_extent.isNull() or not basemap_extent.isFinite():
            self.warning.emit(
                self.tr("Failed to create basemap"),
                self.tr(
                    "Cannot create basemap for the given area of interest."),
            )
            return False

        if not self.project_configuration.base_map_layer.strip():
            self.warning.emit(
                self.tr("Failed to create basemap"),
                self.
                tr("No basemap layer selected. Please check the project configuration."
                   ).format(self.project_configuration.base_map_layer),
            )
            return False

        extent = basemap_extent
        base_map_type = self.project_configuration.base_map_type
        if base_map_type == ProjectProperties.BaseMapType.SINGLE_LAYER:
            basemap_layer = project.mapLayer(
                self.project_configuration.base_map_layer)

            if not basemap_layer:
                self.warning.emit(
                    self.tr("Failed to create basemap"),
                    self.
                    tr('Cannot find the configured base layer with id "{}". Please check the project configuration.'
                       ).format(self.project_configuration.base_map_layer),
                )
                return False

            # we need to transform the extent to match the one of the selected layer
            extent = QgsCoordinateTransform(
                QgsCoordinateReferenceSystem(self.area_of_interest_crs),
                project.crs(),
                project,
            ).transformBoundingBox(basemap_extent)
        elif base_map_type == ProjectProperties.BaseMapType.MAP_THEME:
            if not project.mapThemeCollection().hasMapTheme(
                    self.project_configuration.base_map_theme):
                self.warning.emit(
                    self.tr("Failed to create basemap"),
                    self.
                    tr('Cannot find the configured base theme with name "{}". Please check the project configuration.'
                       ).format(self.project_configuration.base_map_theme),
                )
                return False

        extent_string = "{},{},{},{}".format(
            extent.xMinimum(),
            extent.xMaximum(),
            extent.yMinimum(),
            extent.yMaximum(),
        )

        alg = (QgsApplication.instance().processingRegistry().
               createAlgorithmById("native:rasterize"))

        params = {
            "EXTENT": extent_string,
            "EXTENT_BUFFER": 0,
            "TILE_SIZE": self.project_configuration.base_map_tile_size,
            "MAP_UNITS_PER_PIXEL": self.project_configuration.base_map_mupp,
            "MAKE_BACKGROUND_TRANSPARENT": False,
            "OUTPUT": os.path.join(self.export_folder, "basemap.gpkg"),
        }

        if base_map_type == ProjectProperties.BaseMapType.SINGLE_LAYER:
            params["LAYERS"] = [self.project_configuration.base_map_layer]
        elif base_map_type == ProjectProperties.BaseMapType.MAP_THEME:
            params["MAP_THEME"] = self.project_configuration.base_map_theme

        feedback = QgsProcessingFeedback()
        context = QgsProcessingContext()
        context.setProject(QgsProject.instance())

        results, ok = alg.run(params, context, feedback)

        if not ok:
            self.warning.emit(self.tr("Failed to create basemap"),
                              feedback.textLog())
            return False

        new_layer = QgsRasterLayer(results["OUTPUT"], self.tr("Basemap"))

        resample_filter = new_layer.resampleFilter()
        resample_filter.setZoomedInResampler(QgsCubicRasterResampler())
        resample_filter.setZoomedOutResampler(QgsBilinearRasterResampler())
        self.project_configuration.project.addMapLayer(new_layer, False)
        layer_tree = QgsProject.instance().layerTreeRoot()
        layer_tree.insertLayer(len(layer_tree.children()), new_layer)

        return True
Beispiel #4
0
    def testCubicResample(self):
        path = os.path.join(unitTestDataPath(), 'landsat.tif')
        raster_layer = QgsRasterLayer(path, 'test')
        self.assertTrue(raster_layer.isValid())

        extent = QgsRectangle(785994.37761193525511771,
                              3346249.2209800467826426,
                              786108.49096253968309611,
                              3346362.94137834152206779)

        renderer = QgsSingleBandGrayRenderer(raster_layer.dataProvider(), 1)
        filter = QgsRasterResampleFilter(renderer)

        # default (nearest neighbour) resampling
        block = filter.block(1, extent, 2, 2)
        self.checkBlockContents(block, [[124, 127], [125, 126]])

        block = filter.block(1, extent, 4, 4)
        self.checkBlockContents(block,
                                [[124, 124, 127, 127], [124, 124, 127, 127],
                                 [125, 125, 126, 126], [125, 125, 126, 126]])

        block = filter.block(1, extent, 8, 8)
        self.checkBlockContents(block,
                                [[124, 124, 124, 124, 127, 127, 127, 127],
                                 [124, 124, 124, 124, 127, 127, 127, 127],
                                 [124, 124, 124, 124, 127, 127, 127, 127],
                                 [124, 124, 124, 124, 127, 127, 127, 127],
                                 [125, 125, 125, 125, 126, 126, 126, 126],
                                 [125, 125, 125, 125, 126, 126, 126, 126],
                                 [125, 125, 125, 125, 126, 126, 126, 126],
                                 [125, 125, 125, 125, 126, 126, 126, 126]])

        # with resampling
        filter.setZoomedInResampler(QgsCubicRasterResampler())
        block = filter.block(1, extent, 2, 2)
        self.checkBlockContents(block, [[124, 127], [125, 126]])

        block = filter.block(1, extent, 4, 4)
        self.checkBlockContents(block,
                                [[124, 125, 127, 127], [124, 125, 126, 127],
                                 [125, 125, 126, 126], [125, 125, 126, 126]])

        block = filter.block(1, extent, 8, 8)
        self.checkBlockContents(block,
                                [[125, 124, 124, 125, 126, 127, 127, 127],
                                 [125, 124, 124, 125, 126, 127, 127, 127],
                                 [125, 124, 124, 125, 126, 127, 127, 127],
                                 [125, 124, 124, 125, 126, 126, 127, 127],
                                 [125, 125, 125, 125, 126, 126, 126, 126],
                                 [125, 125, 125, 125, 126, 126, 126, 126],
                                 [125, 125, 125, 125, 126, 126, 126, 126],
                                 [125, 125, 125, 125, 126, 126, 126, 126]])

        # with oversampling
        extent = QgsRectangle(785878.92593475803732872,
                              3346136.27493690419942141,
                              786223.56509550288319588,
                              3346477.7564090033993125)
        block = filter.block(1, extent, 2, 2)
        self.checkBlockContents(block, [[127, 126], [125, 126]])

        block = filter.block(1, extent, 4, 4)
        self.checkBlockContents(block,
                                [[125, 127, 127, 127], [126, 127, 127, 126],
                                 [125, 126, 126, 126], [127, 125, 125, 125]])

        block = filter.block(1, extent, 8, 8)
        self.checkBlockContents(block,
                                [[127, 126, 127, 126, 126, 125, 126, 126],
                                 [127, 127, 127, 126, 126, 126, 126, 126],
                                 [126, 127, 125, 125, 126, 127, 127, 127],
                                 [126, 126, 126, 124, 126, 127, 126, 127],
                                 [126, 126, 125, 124, 125, 126, 126, 127],
                                 [126, 126, 125, 125, 125, 126, 127, 127],
                                 [126, 125, 127, 125, 125, 127, 128, 126],
                                 [126, 125, 127, 127, 126, 125, 125, 126]])

        filter.setMaxOversampling(2)
        block = filter.block(1, extent, 2, 2)
        self.checkBlockContents(block, [[127, 126], [125, 126]])

        block = filter.block(1, extent, 4, 4)
        self.checkBlockContents(block,
                                [[125, 127, 127, 127], [126, 127, 127, 126],
                                 [125, 126, 126, 126], [127, 125, 125, 125]])

        block = filter.block(1, extent, 8, 8)
        self.checkBlockContents(block,
                                [[127, 126, 127, 126, 126, 125, 126, 126],
                                 [127, 127, 127, 126, 126, 126, 126, 126],
                                 [126, 127, 125, 125, 126, 127, 127, 127],
                                 [126, 126, 126, 124, 126, 127, 126, 127],
                                 [126, 126, 125, 124, 125, 126, 126, 127],
                                 [126, 126, 125, 125, 125, 126, 127, 127],
                                 [126, 125, 127, 125, 125, 127, 128, 126],
                                 [126, 125, 127, 127, 126, 125, 125, 126]])

        filter.setMaxOversampling(4)
        block = filter.block(1, extent, 2, 2)
        self.checkBlockContents(block, [[127, 126], [125, 126]])

        block = filter.block(1, extent, 4, 4)
        self.checkBlockContents(block,
                                [[125, 127, 127, 127], [126, 127, 127, 126],
                                 [125, 126, 126, 126], [127, 125, 125, 125]])

        block = filter.block(1, extent, 8, 8)
        self.checkBlockContents(block,
                                [[127, 126, 127, 126, 126, 125, 126, 126],
                                 [127, 127, 127, 126, 126, 126, 126, 126],
                                 [126, 127, 125, 125, 126, 127, 127, 127],
                                 [126, 126, 126, 124, 126, 127, 126, 127],
                                 [126, 126, 125, 124, 125, 126, 126, 127],
                                 [126, 126, 125, 125, 125, 126, 127, 127],
                                 [126, 125, 127, 125, 125, 127, 128, 126],
                                 [126, 125, 127, 127, 126, 125, 125, 126]])