Exemple #1
0
    def define_layer(self, layer_path):
        """Create QGIS layer (either vector or raster) from file path input.

        :param layer_path: Full path to layer file.
        :type layer_path: str

        :return: QGIS layer.
        :rtype: QgsMapLayer
        """
        scenario_dir = self.source_directory.text()
        joined_path = os.path.join(scenario_dir, layer_path)
        full_path = os.path.normpath(joined_path)
        file_name = os.path.split(layer_path)[-1]

        # get extension and basename to create layer
        base_name, extension = os.path.splitext(file_name)

        # load layer in scenario
        layer = QgsRasterLayer(full_path, base_name)
        if layer.isValid():
            return layer
        else:
            layer = QgsVectorLayer(full_path, base_name, 'ogr')
            if layer.isValid():
                return layer
            # if layer is not vector nor raster
            else:
                LOGGER.warning('Input in scenario is not recognized/supported')
                return
    def test_clip_raster(self):
        """Raster layers can be clipped."""

        # Create a raster layer
        layer_name = 'shake'
        raster_layer = QgsRasterLayer(RASTERPATH, layer_name)

        message = (
            'Did not find layer "%s" in path "%s"' % (layer_name, RASTERPATH))
        assert raster_layer is not None, message

        # Create a bounding box
        bounding_box = [97, -3, 104, 1]

        # Clip the vector to the bbox
        result = clip_layer(raster_layer, bounding_box)

        # Check the output is valid
        assert os.path.exists(result.source())

        # Clip and give a desired resolution for the output
        # big pixel size
        size = 0.05
        result = clip_layer(raster_layer, bounding_box, size)
        new_raster_layer = QgsRasterLayer(result.source(), layer_name)
        assert new_raster_layer.isValid(), 'Resampled raster is not valid'
        message = (
            'Resampled raster has incorrect pixel size. Expected: %5f, '
            'Actual: %5f' % (size, new_raster_layer.rasterUnitsPerPixelX()))
        assert new_raster_layer.rasterUnitsPerPixelX() == size, message
Exemple #3
0
    def test_clipRaster(self):
        """Raster layers can be clipped
        """

        # Create a raster layer
        myName = 'shake'
        myRasterLayer = QgsRasterLayer(RASTERPATH, myName)

        myMessage = 'Did not find layer "%s" in path "%s"' % \
                    (myName, RASTERPATH)
        assert myRasterLayer is not None, myMessage

        # Create a bounding box
        myRect = [97, -3, 104, 1]

        # Clip the vector to the bbox
        myResult = clip_layer(myRasterLayer, myRect)

        # Check the output is valid
        assert os.path.exists(myResult.source())

        # Clip and give a desired resolution for the output
        mySize = 0.05
        myResult = clip_layer(myRasterLayer, myRect, mySize)
        myNewRasterLayer = QgsRasterLayer(myResult.source(), myName)
        assert myNewRasterLayer.isValid(), 'Resampled raster is not valid'

        myMessage = ('Resampled raster has incorrect pixel size.'
                     'Expected: %f, Actual: %f' %
                     (mySize, myNewRasterLayer.rasterUnitsPerPixelX()))
        assert myNewRasterLayer.rasterUnitsPerPixelX() == mySize, myMessage
Exemple #4
0
def loadLayer(theLayerFile):
    """Helper to load and return a single QGIS layer"""
    # Extract basename and absolute path
    myBaseName, myExt = os.path.splitext(theLayerFile)
    myPath = os.path.join(TESTDATA, theLayerFile)
    myKeywordPath = myPath[:-4] + '.keywords'
    # Determine if layer is hazard or exposure
    myKeywords = read_keywords(myKeywordPath)
    myType = 'undefined'
    if 'category' in myKeywords:
        myType = myKeywords['category']
    msg = 'Could not read %s' % myKeywordPath
    assert myKeywords is not None, msg

    # Create QGis Layer Instance
    if myExt in ['.asc', '.tif']:
        myLayer = QgsRasterLayer(myPath, myBaseName)
    elif myExt in ['.shp']:
        myLayer = QgsVectorLayer(myPath, myBaseName, 'ogr')
    else:
        myMessage = 'File %s had illegal extension' % myPath
        raise Exception(myMessage)

    myMessage = 'Layer "%s" is not valid' % str(myLayer.source())
    assert myLayer.isValid(), myMessage
    return myLayer, myType
    def generateLayer(self, nameCoverage, coverageTime, boundingBox=None):
        """Generates a raster layer for QGIS.

        :param nameCoverage: the name identifier of the coverage we want to retrieve.
        :type nameCoverage:  str

        :param coverageTime: the time dimension of the coverage we want.
        :type coverageTime:  str

        :returns: a QGIS-compatible raster layer object for the coverage and times provided.
        :rtype:   QgsRasterLayer
        """
        url = self.generateURLForGeoTIFF(nameCoverage, coverageTime, boundingBox)
        layerName = "{ct}_{nc}-{id}".format(ct=coverageTime, nc=nameCoverage, id=uuid.uuid4())

        if Utilities.is_linux():
            import requests
            with tempfile.NamedTemporaryFile(suffix=".tiff", delete=False) as f:
                r = requests.get(url, stream=True)
                with open(f.name, "wb") as g:
                    for chunk in r.iter_content():
                        g.write(chunk)

                layer = QgsRasterLayer(f.name, layerName)
        else:
            layer = QgsRasterLayer(url, layerName)

        if layer.isValid():
            return layer
        else:
            msg = "Couldn't create a valid layer."
            self.standardMessage.emit(msg)
Exemple #6
0
    def test_invalidFilenamesCaught(self):
        """Invalid filenames raise appropriate exceptions

        Wrote this test because test_clipBoth raised the wrong error
        when file was missing. Instead of reporting that, it gave
        Western boundary must be less than eastern. I got [0.0, 0.0, 0.0, 0.0]

        See issue #170
        """

        # Try to create a vector layer from non-existing filename
        myName = 'stnhaoeu_78oeukqjkrcgA'
        myPath = 'OEk_tnshoeu_439_kstnhoe'

        with RedirectStreams(stdout=DEVNULL, stderr=DEVNULL):
            myVectorLayer = QgsVectorLayer(myPath, myName, 'ogr')

        myMessage = ('QgsVectorLayer reported "valid" for non '
                     'existent path "%s" and name "%s".'
                     % (myPath, myName))
        assert not myVectorLayer.isValid(), myMessage

        # Create a raster layer
        with RedirectStreams(stdout=DEVNULL, stderr=DEVNULL):
            myRasterLayer = QgsRasterLayer(myPath, myName)
        myMessage = ('QgsRasterLayer reported "valid" for non '
                     'existent path "%s" and name "%s".'
                     % (myPath, myName))
        assert not myRasterLayer.isValid(), myMessage
    def __init__(self, methodName):
        """Run once on class initialisation."""
        unittest.TestCase.__init__(self, methodName)

        # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL
        self.mMapRegistry = QgsMapLayerRegistry.instance()

        # create point layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        self.mMapRegistry.addMapLayer(self.mPointLayer)

        # create polygon layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp')
        self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr')
        self.mMapRegistry.addMapLayer(self.mPolygonLayer)

        # create two raster layers
        myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif')
        self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1")
        self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2")
        myMultiBandRenderer1 = QgsMultiBandColorRenderer(self.mRasterLayer1.dataProvider(), 2, 3, 4)
        self.mRasterLayer1.setRenderer(myMultiBandRenderer1)
        self.mMapRegistry.addMapLayer(self.mRasterLayer1)
        myMultiBandRenderer2 = QgsMultiBandColorRenderer(self.mRasterLayer2.dataProvider(), 2, 3, 4)
        self.mRasterLayer2.setRenderer(myMultiBandRenderer2)
        self.mMapRegistry.addMapLayer(self.mRasterLayer2)

        # to match blend modes test comparisons background
        self.mCanvas = CANVAS
        self.mCanvas.setCanvasColor(QColor(152, 219, 249))
        self.mMap = self.mCanvas.map()
        self.mMap.resize(QSize(400, 400))
        self.mMapRenderer = self.mCanvas.mapRenderer()
        self.mMapRenderer.setOutputSize(QSize(400, 400), 72)
def createVrt(inventario, vrt):
    #Camada de inventario
    layer = processing.getObject(Inventario)
    
    count = 0
    size = layer.featureCount()
    p = 0
    progress.setPercentage(p)    
    rasterList = []
    for feature in layer.getFeatures():
        filename = feature['fileName']
        
        raster = QgsRasterLayer(filename, filename)
        if Override_CRS:
            raster.setCrs( QgsCoordinateReferenceSystem(int(CRS.split(':')[-1]), QgsCoordinateReferenceSystem.EpsgCrsId) )
           
        rasterList.append(raster)
        ovr = filename+'.ovr'
        if not os.path.isfile(ovr):
            progress.setText('Fazendo Pirâmides...')
            #('gdalogr:overviews', input, levels=8, clean=False, resampling_method=0(nearest), format=1(Gtiff .ovr))
            processing.runalg('gdalogr:overviews', raster, '4 8 32 128', True, 0, 1)

        if int(float(count)/size*100) != p:
            p = int(float(count)/size*100)
            progress.setPercentage(p)    
        count += 1
    progress.setText('Fazendo raster virtual...')
    processing.runalg('gdalogr:buildvirtualraster', rasterList, 0, False, False, VRT)
    def testLayerRemovalBeforeRun(self):
        """test behavior when layer is removed before task begins"""
        path = os.path.join(unitTestDataPath(), 'raster', 'with_color_table.tif')
        raster_layer = QgsRasterLayer(path, "test")
        self.assertTrue(raster_layer.isValid())

        pipe = QgsRasterPipe()
        self.assertTrue(pipe.set(raster_layer.dataProvider().clone()))

        tmp = create_temp_filename('remove_layer.tif')
        writer = QgsRasterFileWriter(tmp)

        task = QgsRasterFileWriterTask(writer, pipe, 100, 100, raster_layer.extent(), raster_layer.crs())

        task.writeComplete.connect(self.onSuccess)
        task.errorOccurred.connect(self.onFail)

        # remove layer
        raster_layer = None

        QgsApplication.taskManager().addTask(task)
        while not self.success and not self.fail:
            QCoreApplication.processEvents()

        # in this case will still get a positive result - since the pipe is cloned before the task
        # begins the task is no longer dependent on the original layer
        self.assertTrue(self.success)
        self.assertFalse(self.fail)
        self.assertTrue(os.path.exists(tmp))
Exemple #10
0
    def testPalettedColorTableToClassData(self):
        entries = [QgsColorRampShader.ColorRampItem(5, QColor(255, 0, 0), 'item1'),
                   QgsColorRampShader.ColorRampItem(3, QColor(0, 255, 0), 'item2'),
                   QgsColorRampShader.ColorRampItem(6, QColor(0, 0, 255), 'item3'),
                   ]
        classes = QgsPalettedRasterRenderer.colorTableToClassData(entries)
        self.assertEqual(classes[0].value, 5)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[2].value, 6)
        self.assertEqual(classes[0].label, 'item1')
        self.assertEqual(classes[1].label, 'item2')
        self.assertEqual(classes[2].label, 'item3')
        self.assertEqual(classes[0].color.name(), '#ff0000')
        self.assertEqual(classes[1].color.name(), '#00ff00')
        self.assertEqual(classes[2].color.name(), '#0000ff')

        # test #13263
        path = os.path.join(unitTestDataPath('raster'),
                            'hub13263.vrt')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path))
        classes = QgsPalettedRasterRenderer.colorTableToClassData(layer.dataProvider().colorTable(1))
        self.assertEqual(len(classes), 4)
        classes = QgsPalettedRasterRenderer.colorTableToClassData(layer.dataProvider().colorTable(15))
        self.assertEqual(len(classes), 256)
    def testIdentify(self):
        myPath = os.path.join(unitTestDataPath(), 'landsat.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage
        myPoint = QgsPoint(786690, 3345803)
        #print 'Extents: %s' % myRasterLayer.extent().toString()
        #myResult, myRasterValues = myRasterLayer.identify(myPoint)
        #assert myResult
        myRasterValues =  myRasterLayer.dataProvider().identify(myPoint, QgsRasterDataProvider.IdentifyFormatValue )

        assert len( myRasterValues ) > 0

        # Get the name of the first band
        myBand = myRasterValues.keys()[0]
        #myExpectedName = QString('Band 1')
        myExpectedBand = 1
        myMessage = 'Expected "%s" got "%s" for first raster band name' % (
                    myExpectedBand, myBand)
        assert myExpectedBand == myBand, myMessage

        # Convert each band value to a list of ints then to a string

        myValues = myRasterValues.values()
        myIntValues = []
        for myValue in myValues:
          #myIntValues.append(int(str(myValue)))
          myIntValues.append( myValue.toInt()[0] )
        myValues = str(myIntValues)
        myExpectedValues = '[127, 141, 112, 72, 86, 126, 156, 211, 170]'
        myMessage = 'Expected: %s\nGot: %s' % (myValues, myExpectedValues)
        self.assertEquals(myValues, myExpectedValues, myMessage)
Exemple #12
0
    def toMapLayer(self):
        from qgis.core import QgsRasterLayer, QgsContrastEnhancement

        rl = QgsRasterLayer(self.gdalUri(), self.name)
        if rl.isValid():
            rl.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum)
        return rl
Exemple #13
0
 def accept(self):
     input_path = str(self.leInputPath.text())
     output_path = str(self.leOutputPath.text())
     if not output_path.endswith('.tif'):
         QMessageBox.warning(
             self.parent, self.tr('InaSAFE'),
             (self.tr('Output file name must be tif file')))
     if not os.path.exists(input_path):
         QMessageBox.warning(
             self.parent, self.tr('InaSAFE'),
             (self.tr('Input file is not exist')))
         return
     my_algorithm = str(self.cboAlgorithm.currentText()).lower()
     fileName = convert_mmi_data(input_path, output_path,
                                 the_algorithm=my_algorithm,
                                 algorithm_name=False)
     if self.cBLoadLayer.isChecked():
         fileInfo = QFileInfo(fileName)
         baseName = fileInfo.baseName()
         my_raster_layer = QgsRasterLayer(fileName, baseName)
         if not my_raster_layer.isValid():
             LOGGER.debug("Failed to load")
         else:
             QgsMapLayerRegistry.instance().addMapLayer(my_raster_layer)
     self.done(self.Accepted)
     if not self.test_mode:
         QMessageBox.warning(
             self.parent, self.tr('InaSAFE'),
             (self.tr('Success to convert %1 to %2').
              arg(input_path).arg(output_path)))
  def accept(self):
    """Creates and loads the WMS layer."""
    self.close()
    currentIndex = self.comboBoxLayer.currentIndex()
    currentLayerId, unused_dataType = self.comboBoxLayer.itemData(currentIndex)
    currentLayerName = unicode(self.comboBoxLayer.currentText())
    mapId = self.labelMapId.text()
    # Create the WMS layer
    token = oauth2_utils.getToken()
    url = 'https://mapsengine.google.com/%s-4/wms/%s/'
    wmsUrl = url % (mapId, token.access_token)
    currentFormatIndex = self.comboBoxFormat.currentIndex()
    imageFormat = unicode(self.comboBoxFormat.itemData(currentFormatIndex))
    crs = self.comboBoxCrs.currentText()

    uri = QgsDataSourceURI()
    uri.setParam('url', wmsUrl)
    uri.setParam('layers', currentLayerId)
    uri.setParam('format', imageFormat)
    uri.setParam('crs', crs)
    uri.setParam('styles', '')

    rlayer = QgsRasterLayer(str(uri.encodedUri()), currentLayerName, 'wms')
    if rlayer.isValid():
      QgsMapLayerRegistry.instance().addMapLayer(rlayer)
    else:
      logText = 'Failed to add WMS layer %s with URI %s' % (
          currentLayerName, str(uri.encodedUri()))
      warnText = 'Failed to add WMS layer %s' % currentLayerName
      QgsMessageLog.logMessage(logText, 'GMEConnector', QgsMessageLog.CRITICAL)
      self.iface.messageBar().pushMessage(
          'Google Maps Engine Connector', warnText,
          level=QgsMessageBar.CRITICAL, duration=3)
Exemple #15
0
    def test_run_without_population_field(self):
        impact_function = AshRasterPlacesFunction.instance()

        hazard_path = standard_data_path("hazard", "ash_raster_wgs84.tif")
        exposure_path = standard_data_path("exposure", "places.shp")
        hazard_layer = QgsRasterLayer(hazard_path, "Ash")
        exposure_layer = QgsVectorLayer(exposure_path, "Places", "ogr")
        impact_function.hazard = hazard_layer
        impact_function.exposure = exposure_layer

        # Let's set the extent to the hazard extent
        extent = hazard_layer.extent()
        rect_extent = [extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()]
        impact_function.requested_extent = rect_extent
        impact_function.run()
        impact_layer = impact_function.impact

        # Extract calculated result
        impact_data = impact_layer.get_data()

        # 1 = inundated, 2 = wet, 3 = dry
        expected_result = {0: 0, 1: 135, 2: 62, 3: 1, 4: 0}

        result = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
        for feature in impact_data:
            inundated_status = feature[impact_function.target_field]
            result[inundated_status] += 1
        self.assertDictEqual(expected_result, result)
Exemple #16
0
    def testIdentify(self):
        myPath = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'testdata', 'landsat.tif'))
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage
        myPoint = QgsPoint(786690, 3345803)
        #print 'Extents: %s' % myRasterLayer.extent().toString()
        myResult, myRasterValues = myRasterLayer.identify(myPoint)
        assert myResult
        # Get the name of the first band
        myBandName = myRasterValues.keys()[0] 
        myExpectedName = QString('Band 1')
        myMessage = 'Expected "%s" got "%s" for first raster band name' % (
                    myExpectedName, myBandName)
        assert myExpectedName == myBandName, myMessage

        # Convert each band value to a list of ints then to a string

        myValues = myRasterValues.values()
        myIntValues = []
        for myValue in myValues:
          myIntValues.append(int(str(myValue)))
        myValues = str(myIntValues)
        myExpectedValues = '[127, 141, 112, 72, 86, 126, 156, 211, 170]'
        myMessage = 'Expected: %s\nGot: %s' % (myValues, myExpectedValues)
        self.assertEquals(myValues, myExpectedValues, myMessage)
    def test_run(self):
        function = FloodRasterRoadsFunction.instance()

        hazard_path = test_data_path('hazard', 'continuous_flood_20_20.asc')
        exposure_path = test_data_path('exposure', 'roads.shp')
        # noinspection PyCallingNonCallable
        hazard_layer = QgsRasterLayer(hazard_path, 'Flood')
        # noinspection PyCallingNonCallable
        exposure_layer = QgsVectorLayer(exposure_path, 'Roads', 'ogr')

        # Let's set the extent to the hazard extent
        extent = hazard_layer.extent()
        rect_extent = [
            extent.xMinimum(), extent.yMaximum(),
            extent.xMaximum(), extent.yMinimum()]
        function.hazard = SafeLayer(hazard_layer)
        function.exposure = SafeLayer(exposure_layer)
        function.requested_extent = rect_extent
        function.run()
        impact = function.impact

        keywords = impact.get_keywords()
        self.assertEquals(function.target_field, keywords['target_field'])
        expected_inundated_feature = 182
        count = sum(impact.get_data(attribute=function.target_field))
        self.assertEquals(count, expected_inundated_feature)
    def generateLayerFromGeoTIFFURL(self, geoTiffUrl, layerName):
        """Generates a new layer based on the GeoTIFF URL provided for the WCS service.
        This method also appends to the name an UUID so the uniqueness of it's name
        and ID is guaranteed to avoid problems when managing asynchronous generation
        of layers between different processes.

        :param geoTiffUrl: the download URL for this image.
        :type  geoTiffUrl: str

        :param layerName: the name to give to this layer. The resultant layer will have an UUID appended.
        :type  layerName: str
        """
        tiff_string = "{ln}{id}".format(ln=layerName, id=uuid.uuid4())
        layer = QgsRasterLayer(geoTiffUrl, tiff_string)

        if Utilities.is_linux():
            import requests
            with tempfile.NamedTemporaryFile(suffix=".tiff", delete=False) as f:
                r = requests.get(geoTiffUrl, stream=True)
                with open(f.name, "wb") as g:
                    for chunk in r.iter_content():
                        g.write(chunk)

                layer = QgsRasterLayer(f.name, layerName)
        else:
            layer = QgsRasterLayer(geoTiffUrl, layerName)

        if layer.isValid():
            return layer
        else:
            msg = "Couldn't create a valid layer."
            self.standardMessage.emit(msg)
Exemple #19
0
def load_layer(layer_path):
    """Helper to load and return a single QGIS layer.

    :param layer_path: Path name to raster or vector file.
    :type layer_path: str

    :returns: Layer instance.
    :rtype: QgsMapLayer
    """
    # Extract basename and absolute path
    file_name = os.path.split(layer_path)[-1]  # In case path was absolute
    base_name, extension = os.path.splitext(file_name)

    # Create QGis Layer Instance
    if extension in ['.asc', '.tif']:
        layer = QgsRasterLayer(layer_path, base_name)
    elif extension in ['.shp']:
        layer = QgsVectorLayer(layer_path, base_name, 'ogr')
    else:
        message = 'File %s had illegal extension' % layer_path
        raise Exception(message)

    # noinspection PyUnresolvedReferences
    message = 'Layer "%s" is not valid' % layer.source()
    # noinspection PyUnresolvedReferences
    if not layer.isValid():
        print message
    # noinspection PyUnresolvedReferences
    if not layer.isValid():
        raise Exception(message)
    return layer
 def addToCanvas(self, roles):
     if self.canOpen(roles):
         if not oauth2_supported:
             iface.messageBar().pushMessage(
                 "Cannot load basemap",
                 "OAuth support is not available",
                 QgsMessageBar.WARNING)
         else:
             authcfg = get_oauth_authcfg()
             if authcfg is None:
                 iface.messageBar().pushMessage(
                     "Cannot load basemap",
                     "Cannot find a valid authentication configuration",
                     QgsMessageBar.WARNING)
             else:
                 authId = authcfg.id()
                 layer = QgsRasterLayer('authcfg={authcfg}&type=xyz&url={url}'.format(url=urllib2.quote("{}?version={}".format(self.url, pluginSetting("apiVersion"))),
                                                                                      authcfg=authId), self.name, "wms")
                 if layer.isValid():
                     QgsMapLayerRegistry.instance().addMapLayer(layer)
                 else:
                     iface.messageBar().pushMessage(
                         "Cannot load basemap",
                         "Cannot create basemap layer",
                         QgsMessageBar.WARNING)
     else:
         webbrowser.open_new(SUBSCRIBE_URL)
    def __init__(self, methodName):
        """Run once on class initialisation."""
        unittest.TestCase.__init__(self, methodName)
        myPath = os.path.join(TEST_DATA_DIR, 'landsat.tif')
        rasterFileInfo = QFileInfo(myPath)
        mRasterLayer = QgsRasterLayer(rasterFileInfo.filePath(),
                                      rasterFileInfo.completeBaseName())
        rasterRenderer = QgsMultiBandColorRenderer(
            mRasterLayer.dataProvider(), 2, 3, 4)
        mRasterLayer.setRenderer(rasterRenderer)
        #pipe = mRasterLayer.pipe()
        #assert pipe.set(rasterRenderer), 'Cannot set pipe renderer'
        QgsMapLayerRegistry.instance().addMapLayers([mRasterLayer])

        # create composition with composer map
        self.mMapRenderer = QgsMapRenderer()
        layerStringList = QStringList()
        layerStringList.append(mRasterLayer.id())
        self.mMapRenderer.setLayerSet(layerStringList)
        self.mMapRenderer.setProjectionsEnabled(False)
        self.mComposition = QgsComposition(self.mMapRenderer)
        self.mComposition.setPaperSize(297, 210)
        self.mComposerMap = QgsComposerMap(self.mComposition, 20, 20, 200, 100)
        self.mComposerMap.setFrameEnabled(True)
        self.mComposition.addComposerMap(self.mComposerMap)
Exemple #22
0
    def test_clip_raster_small(self):
        """Raster layers can be clipped in small and precise size. For #710."""

        # Create a raster layer
        layer_name = 'shake'
        raster_layer = QgsRasterLayer(RASTERPATH, layer_name)

        message = (
            'Did not find layer "%s" in path "%s"' % (layer_name, RASTERPATH))
        assert raster_layer is not None, message

        # Create a bounding box
        bounding_box = [97, -3, 104, 1]

        # Clip the vector to the bbox
        result = clip_layer(raster_layer, bounding_box)

        # Check the output is valid
        assert os.path.exists(result.source())

        # Clip and give a desired resolution for the output

        # small pixel size and high precision

        # based on pixel size of Flood_Current_Depth_Jakarta_geographic.asc
        size = 0.00045228819716
        result = clip_layer(raster_layer, bounding_box, size)
        new_raster_layer = QgsRasterLayer(result.source(), layer_name)
        assert new_raster_layer.isValid(), 'Resampled raster is not valid'
        message = (
            'Resampled raster has incorrect pixel size. Expected: %.14f, '
            'Actual: %.14f' % (
                size, new_raster_layer.rasterUnitsPerPixelX()))
        result_size = new_raster_layer.rasterUnitsPerPixelX()
        self.assertAlmostEqual(result_size, size, places=13, msg=message)
    def test_read_existing_geopackage(self):
        """Test we can read an existing geopackage."""
        path = standard_data_path('other', 'jakarta.gpkg')
        import os
        path = os.path.normpath(os.path.normcase(os.path.abspath(path)))
        geopackage = QFileInfo(path)
        data_store = GeoPackage(geopackage)

        # We should have 3 layers in this geopackage.
        self.assertEqual(len(data_store.layers()), 3)

        # Test we can load a vector layer.
        roads = QgsVectorLayer(
            data_store.layer_uri('roads'),
            'Test',
            'ogr'
        )
        self.assertTrue(roads.isValid())

        # Test we can load a raster layers.
        # This currently fails on windows...
        # So we have decorated it with expected fail on windows
        # Should pass on other platforms.
        path = data_store.layer_uri('flood')
        flood = QgsRasterLayer(path, 'flood')
        self.assertTrue(flood.isValid())
Exemple #24
0
	def toMapLayer(self):
		from qgis.core import QgsRasterLayer 
		uri=self.uri()
		schema = "schema="+self.schemaName() if self.schemaName() else ''
		pgrasterUri= ('PG: dbname=%s host=%s user=%s password=%s port=%s mode=2 %s table=%s') % (uri.database(), uri.host(), uri.username(), uri.password(), uri.port(),schema,self.name)
		rasterLayer=QgsRasterLayer(pgrasterUri, self.name)
		rasterLayer.setContrastEnhancementAlgorithm("StretchToMinimumMaximum")
		return rasterLayer
 def createXYZLayer(self, layerType, name):
     # create XYZ layer with tms url as uri
     provider = 'wms'
     url = "type=xyz&url=" + layerType.xyzUrlConfig()
     layer = QgsRasterLayer(url, name, provider,
                            QgsRasterLayer.LayerOptions())
     layer.setCustomProperty('ol_layer_type', layerType.layerTypeName)
     return layer, layerType.xyzUrlConfig()
Exemple #26
0
 def add_layer(
     self,
     layer_source,
     layer_name):
     layer = QgsRasterLayer(layer_source,self.tr(layer_name),"wms")
     if not layer.isValid(): # Test if string is valid
     	 QMessageBox.information(self.iface.mainWindow(),self.tr(u"Error!"), self.tr(u"Layer has no valid token... Try again!"))
     	 QSettings().setValue('lmopendata/token', '') # if layer is incorrect clear token key
     QgsMapLayerRegistry.instance().addMapLayer(layer)
Exemple #27
0
    def special_search(self, easter_code="isogeo"):
        """Make some special actions in certains cases.
        
        :param str easter_code: easter egg label. Available values:
          
          * isogeo: display Isogeo logo and zoom in our office location
          * picasa: change QGS project title
        """
        canvas = iface.mapCanvas()
        if easter_code == "isogeo":
            # WMS
            wms_params = {"service": "WMS",
                          "version": "1.3.0",
                          "request": "GetMap",
                          "layers": "Isogeo:isogeo_logo",
                          "crs": "EPSG:3857",
                          "format": "image/png",
                          "styles": "isogeo_logo",
                          "url": "http://noisy.hq.isogeo.fr:6090/geoserver/Isogeo/ows?"
                          }
            wms_uri = unquote(urlencode(wms_params))
            wms_lyr = QgsRasterLayer(wms_uri, u"Ici c'est Isogeo !", "wms")
            if wms_lyr.isValid:
                QgsMapLayerRegistry.instance().addMapLayer(wms_lyr)
                logger.info("Isogeo easter egg used and WMS displayed!")
            else:
                logger.error("WMS layer failed: {}"
                             .format(wms_lyr.error().message()))

            # WFS
            uri = QgsDataSourceURI()
            uri.setParam("url", "http://noisy.hq.isogeo.fr:6090/geoserver/Isogeo/ows?")
            uri.setParam("service", "WFS")
            uri.setParam("version", "1.1.0")
            uri.setParam("typename", "Isogeo:isogeo_logo")
            uri.setParam("srsname", "EPSG:3857")
            uri.setParam("restrictToRequestBBOX", "0")
            wfs_uri = uri.uri()
            wfs_lyr = QgsVectorLayer(wfs_uri, u"Ici c'est Isogeo !", "WFS")
            if wfs_lyr.isValid:
                wfs_style = path.join(path.dirname(path.realpath(__file__)),
                                      "isogeo.qml")
                wfs_lyr.loadNamedStyle(wfs_style)
                QgsMapLayerRegistry.instance().addMapLayer(wfs_lyr)
                canvas.setExtent(wfs_lyr.extent())
                logger.debug("Isogeo easter egg used")
            else:
                logger.error("Esater egg - WFS layer failed: {}"
                             .format(wfs_lyr.error().message()))
        elif easter_code == "picasa":
            project = QgsProject.instance()
            project.setTitle(u"Isogeo, le Picasa de l'information géographique")
            logger.debug("Picasa easter egg used")
        else:
            pass
        # ending method
        return
Exemple #28
0
    def testTransformContextIsSetInCtor(self):
        """Test transform context can be set from ctor"""

        rl = QgsRasterLayer(self.rpath, 'raster')
        self.assertFalse(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857)))

        options = QgsRasterLayer.LayerOptions(transformContext=self.ctx)
        rl = QgsRasterLayer(self.rpath, 'raster', 'gdal', options)
        self.assertTrue(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857)))
Exemple #29
0
    def toMapLayer(self):
        from qgis.core import QgsRasterLayer, QgsContrastEnhancement

        # QGIS has no provider to load rasters, let's use GDAL
        uri = self.gpkgGdalUri()
        rl = QgsRasterLayer(uri, self.name)
        if rl.isValid():
            rl.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum)
        return rl
    def test_get_raster_layer_list(self):
        wms_url_with_parameters = self.valid_wms_url
        # use this list for proper testing...
        visibility = [True, False, True, True, True, False]
        # when debugging, use the list below instead
        # visibility = [True]


        for i, visible in enumerate(visibility):
            layer_name = layer_interaction.biuniquify_layer_name('r{}_visible:{}'.format(i, visible))
            rlayer = QgsRasterLayer(wms_url_with_parameters, layer_name, 'wms')
            self.assertTrue(rlayer.isValid(), layer_name.join(' is not a valid raster layer'))
            QgsMapLayerRegistry.instance().addMapLayer(rlayer)
            self.iface.legendInterface().setLayerVisible(rlayer, visible)
            self.layer_list.append(layer_name)

        # get a list of all visible wms layers
        expected_layers = {}
        actual_layers = {}
        visible_raster_layers = layer_interaction.get_raster_layer_list(self.iface, 'visible')
        for i, visible in enumerate(visibility):
            if visible:
                expected_layers[self.layer_list[i]] = True

        for layer in visible_raster_layers:
            if '_visible:' in layer.name():
                actual_layers[str(layer.name())] = True

        self.assertDictEqual(expected_layers, actual_layers, 'The returned layers do not match the expected layers.\n\t Expected: {0}\n\t received: {1}.'.format(expected_layers, actual_layers))

        # get a list of all invisible wms layers
        expected_layers = {}
        actual_layers = {}
        invisible_raster_layers = layer_interaction.get_raster_layer_list(self.iface, 'invisible')
        for i, visible in enumerate(visibility):
            if not visible:
                expected_layers[self.layer_list[i]] = False

        for layer in invisible_raster_layers:
            if '_visible:' in layer.name():
                actual_layers[str(layer.name())] = True if layer.name().endswith('True') else False

        self.assertDictEqual(expected_layers, actual_layers, 'The returned layers do not match the expected layers.\n\t Expected: {0}\n\t received: {1}.'.format(expected_layers, actual_layers))

        # get a list of wms layers
        expected_layers = {}
        actual_layers = {}
        invisible_raster_layers = layer_interaction.get_raster_layer_list(self.iface, 'all')
        for i, visible in enumerate(visibility):
            expected_layers[self.layer_list[i]] = visible

        for layer in invisible_raster_layers:
            if '_visible:' in layer.name():
                actual_layers[str(layer.name())] = True if layer.name().endswith('True') else False

        self.assertDictEqual(expected_layers, actual_layers, 'The returned layers do not match the expected layers.\n\t Expected: {0}\n\t received: {1}.'.format(expected_layers, actual_layers))
    def testPaletted(self):
        """ test paletted raster renderer with raster with color table"""
        path = os.path.join(unitTestDataPath('raster'), 'with_color_table.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path))

        renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 1, [
            QgsPalettedRasterRenderer.Class(1, QColor(0, 255, 0), 'class 2'),
            QgsPalettedRasterRenderer.Class(3, QColor(255, 0, 0), 'class 1')
        ])

        self.assertEqual(renderer.nColors(), 2)
        self.assertEqual(renderer.usesBands(), [1])

        # test labels
        self.assertEqual(renderer.label(1), 'class 2')
        self.assertEqual(renderer.label(3), 'class 1')
        self.assertFalse(renderer.label(101))

        # test legend symbology - should be sorted by value
        legend = renderer.legendSymbologyItems()
        self.assertEqual(legend[0][0], 'class 2')
        self.assertEqual(legend[1][0], 'class 1')
        self.assertEqual(legend[0][1].name(), '#00ff00')
        self.assertEqual(legend[1][1].name(), '#ff0000')

        # test retrieving classes
        classes = renderer.classes()
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'class 1')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')

        # test set label
        # bad index
        renderer.setLabel(1212, 'bad')
        renderer.setLabel(3, 'new class')
        self.assertEqual(renderer.label(3), 'new class')

        # color ramp
        r = QgsLimitedRandomColorRamp(5)
        renderer.setSourceColorRamp(r)
        self.assertEqual(renderer.sourceColorRamp().type(), 'random')
        self.assertEqual(renderer.sourceColorRamp().count(), 5)

        # clone
        new_renderer = renderer.clone()
        classes = new_renderer.classes()
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'new class')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')
        self.assertEqual(new_renderer.sourceColorRamp().type(), 'random')
        self.assertEqual(new_renderer.sourceColorRamp().count(), 5)

        # write to xml and read
        doc = QDomDocument('testdoc')
        elem = doc.createElement('qgis')
        renderer.writeXml(doc, elem)
        restored = QgsPalettedRasterRenderer.create(
            elem.firstChild().toElement(), layer.dataProvider())
        self.assertTrue(restored)
        self.assertEqual(restored.usesBands(), [1])
        classes = restored.classes()
        self.assertTrue(classes)
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[1].value, 3)
        self.assertEqual(classes[0].label, 'class 2')
        self.assertEqual(classes[1].label, 'new class')
        self.assertEqual(classes[0].color.name(), '#00ff00')
        self.assertEqual(classes[1].color.name(), '#ff0000')
        self.assertEqual(restored.sourceColorRamp().type(), 'random')
        self.assertEqual(restored.sourceColorRamp().count(), 5)

        # render test
        layer.setRenderer(renderer)
        ms = QgsMapSettings()
        ms.setLayers([layer])
        ms.setExtent(layer.extent())

        checker = QgsRenderChecker()
        checker.setControlName("expected_paletted_renderer")
        checker.setMapSettings(ms)

        self.assertTrue(checker.runTest("expected_paletted_renderer"),
                        "Paletted rendering test failed")
    def test_run(self):
        function = TsunamiRasterLandcoverFunction.instance()

        hazard_path = standard_data_path('hazard', 'tsunami_wgs84.tif')
        exposure_path = standard_data_path('exposure', 'landcover.shp')
        # noinspection PyCallingNonCallable
        hazard_layer = QgsRasterLayer(hazard_path, 'Tsunami')
        # noinspection PyCallingNonCallable
        exposure_layer = QgsVectorLayer(exposure_path, 'Land Cover', 'ogr')
        self.assertTrue(hazard_layer.isValid())
        self.assertTrue(exposure_layer.isValid())

        rect_extent = [106.5, -6.5, 107, -6]
        function.hazard = hazard_layer
        function.exposure = exposure_layer
        function.requested_extent = rect_extent
        function.run()
        impact = function.impact
        impact = safe_to_qgis_layer(impact)

        expected = {
            'data':
            [[u'Population', u'Dry Zone', None, 793.6916054134609],
             [u'Water', u'Low Hazard Zone', None, 16.298813953855912],
             [
                 u'Population', u'Very High Hazard Zone', None,
                 12.45623642166847
             ],
             [u'Water', u'Very High Hazard Zone', None, 0.08036139883589728],
             [u'Water', u'Medium Hazard Zone', None, 12.1033540507973],
             [u'Population', u'Low Hazard Zone', None, 28.866862427357326],
             [u'Water', u'Dry Zone', None, 164.67113858186028],
             [u'Meadow', u'Dry Zone', None, 249.95443689559693],
             [u'Population', u'Medium Hazard Zone', None, 30.69211822286981],
             [u'Water', u'High Hazard Zone', None, 5.835228232982915],
             [u'Population', u'High Hazard Zone', None, 29.72789895440279],
             [u'Forest', u'Dry Zone', None, 99.489344261353]],
            'groups': ('landcover', 'hazard', 'zone')
        }
        ordered_columns = function.impact.impact_data.get('ordered columns')
        affected_columns = function.impact.impact_data.get('affected columns')
        expected = FlatTable().from_dict(
            groups=expected['groups'],
            data=expected['data'],
        )
        expected = PivotTable(expected,
                              row_field='landcover',
                              column_field='hazard',
                              columns=ordered_columns,
                              affected_columns=affected_columns)

        self.assertEqual(impact.dataProvider().featureCount(), 72)
        table = function.impact.impact_data['impact table']
        table = FlatTable().from_dict(
            groups=table['groups'],
            data=table['data'],
        )
        table = PivotTable(table,
                           row_field='landcover',
                           column_field='hazard',
                           columns=ordered_columns,
                           affected_columns=affected_columns)
        for index, value in enumerate(expected.total_rows):
            self.assertAlmostEqual(value, table.total_rows[index])
        for index, value in enumerate(expected.total_columns):
            self.assertAlmostEqual(value, table.total_columns[index])
        for index, value in enumerate(expected.total_rows_affected):
            self.assertAlmostEqual(value, table.total_rows_affected[index])
        for index, value in enumerate(expected.rows):
            self.assertAlmostEqual(value, table.rows[index])
        for index, value in enumerate(expected.columns):
            self.assertAlmostEqual(value, table.columns[index])
        for index, value in enumerate(expected.affected_columns):
            self.assertAlmostEqual(value, table.affected_columns[index])
        # This is a list of list so we unpack both
        for index, value in enumerate(expected.data):
            for value_index, value_value in enumerate(value):
                self.assertAlmostEqual(value_value,
                                       table.data[index][value_index])
        self.assertAlmostEqual(expected.total_affected, table.total_affected)
Exemple #33
0
    def testWriteSld(self):
        """Test SLD generation for the XMLS fields geneerated at RasterLayer level and not to the deeper renderer level."""

        myPath = os.path.join(unitTestDataPath(), 'landsat.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage

        # do generic export with default layer values
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = root.elementsByTagName('sld:LayerFeatureConstraints')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = element.elementsByTagName('sld:FeatureTypeConstraint')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = root.elementsByTagName('sld:UserStyle')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        name = element.firstChildElement('sld:Name')
        self.assertFalse(name.isNull())
        self.assertEqual(name.text(), 'landsat')

        abstract = element.firstChildElement('sld:Abstract')
        self.assertTrue(abstract.isNull())

        title = element.firstChildElement('sld:Title')
        self.assertTrue(title.isNull())

        featureTypeStyle = element.firstChildElement('sld:FeatureTypeStyle')
        self.assertFalse(featureTypeStyle.isNull())

        rule = featureTypeStyle.firstChildElement('sld:Rule')
        self.assertFalse(rule.isNull())

        temp = rule.firstChildElement('sld:MinScaleDenominator')
        self.assertTrue(temp.isNull())

        temp = rule.firstChildElement('sld:MaxScaleDenominator')
        self.assertTrue(temp.isNull())

        rasterSymbolizer = rule.firstChildElement('sld:RasterSymbolizer')
        self.assertFalse(rule.isNull())

        vendorOptions = rasterSymbolizer.elementsByTagName('sld:VendorOption')
        self.assertTrue(vendorOptions.size() == 0)

        # set no default values and check exported sld
        myRasterLayer.setName('')
        myRasterLayer.setAbstract('fake')
        myRasterLayer.setTitle('fake')
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = root.elementsByTagName('sld:LayerFeatureConstraints')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = element.elementsByTagName('sld:FeatureTypeConstraint')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        elements = root.elementsByTagName('sld:UserStyle')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()

        # no generated if empty
        name = element.firstChildElement('sld:Name')
        self.assertTrue(name.isNull())

        # generated if not empty
        abstract = element.firstChildElement('sld:Abstract')
        self.assertFalse(abstract.isNull())
        self.assertEqual(abstract.text(), 'fake')

        title = element.firstChildElement('sld:Title')
        self.assertFalse(title.isNull())
        self.assertEqual(title.text(), 'fake')

        # if setScaleBasedVisibility is true print scales
        myRasterLayer.setScaleBasedVisibility(True)
        myRasterLayer.setMaximumScale(0.0001)
        myRasterLayer.setMinimumScale(0.01)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:Rule')
        self.assertEqual(len(elements), 1)
        rule = elements.at(0).toElement()
        self.assertFalse(rule.isNull())

        temp = rule.firstChildElement('sld:MinScaleDenominator')
        self.assertFalse(temp.isNull())
        self.assertEqual(temp.text(), '0.0001')

        temp = rule.firstChildElement('sld:MaxScaleDenominator')
        self.assertFalse(temp.isNull())
        self.assertEqual(temp.text(), '0.01')

        # check non default hueSaturationFilter values
        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleLightness)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', 'lightness')

        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleLuminosity)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', 'luminosity')

        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleAverage)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', 'average')

        hue = myRasterLayer.hueSaturationFilter()
        hue.setGrayscaleMode(QgsHueSaturationFilter.GrayscaleOff)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'grayScale', None)

        # manage colorize vendorOption tags
        hue = myRasterLayer.hueSaturationFilter()
        hue.setColorizeOn(True)
        hue.setColorizeStrength(50)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'colorizeOn', '1')
        self.assertVendorOption(element, 'colorizeRed', '255')
        self.assertVendorOption(element, 'colorizeGreen', '128')
        self.assertVendorOption(element, 'colorizeBlue', '128')
        self.assertVendorOption(element, 'colorizeStrength', '0.5')
        self.assertVendorOption(element, 'saturation', '0.498039')

        # other hue non default values, no colorize and saturation = 0
        hue = myRasterLayer.hueSaturationFilter()
        hue.setColorizeOn(False)
        hue.setSaturation(0)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'colorizeOn', None)
        self.assertVendorOption(element, 'colorizeRed', None)
        self.assertVendorOption(element, 'colorizeGreen', None)
        self.assertVendorOption(element, 'colorizeBlue', None)
        self.assertVendorOption(element, 'colorizeStrength', None)
        self.assertVendorOption(element, 'saturation', None)
        self.assertVendorOption(element, 'brightness', None)
        self.assertVendorOption(element, 'contrast', None)

        # other hue non default values, no colorize and saturation = 100
        hue = myRasterLayer.hueSaturationFilter()
        hue.setColorizeOn(False)
        hue.setSaturation(100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'colorizeOn', None)
        self.assertVendorOption(element, 'colorizeRed', None)
        self.assertVendorOption(element, 'colorizeGreen', None)
        self.assertVendorOption(element, 'colorizeBlue', None)
        self.assertVendorOption(element, 'colorizeStrength', None)
        self.assertVendorOption(element, 'saturation', '1')
        hue.setSaturation(-100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        self.assertVendorOption(root, 'saturation', '0')

        # brightness filter default values
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertTrue(myRasterLayer.brightnessFilter().brightness() == 0)
        self.assertTrue(myRasterLayer.brightnessFilter().contrast() == 0)
        self.assertVendorOption(element, 'brightness', None)
        self.assertVendorOption(element, 'contrast', None)

        # brightness filter no default values
        bf = myRasterLayer.brightnessFilter()
        bf.setBrightness(-255)
        bf.setContrast(-100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'brightness', '0')
        self.assertVendorOption(element, 'contrast', '0')

        bf.setBrightness(255)
        bf.setContrast(100)
        dom, root, errorMessage = self.layerToSld(myRasterLayer)
        elements = dom.elementsByTagName('sld:RasterSymbolizer')
        self.assertEqual(len(elements), 1)
        element = elements.at(0).toElement()
        self.assertFalse(element.isNull())
        self.assertVendorOption(element, 'brightness', '1')
        self.assertVendorOption(element, 'contrast', '1')
Exemple #34
0
def load(fileName, name=None, crs=None, style=None, isRaster=False):
    """Loads a layer/table into the current project, given its file.
    """

    if fileName is None:
        return
    prjSetting = None
    settings = QgsSettings()
    if crs is not None:
        prjSetting = settings.value('/Projections/defaultBehavior')
        settings.setValue('/Projections/defaultBehavior', '')
    if name is None:
        name = os.path.split(fileName)[1]

    if isRaster:
        qgslayer = QgsRasterLayer(fileName, name)
        if qgslayer.isValid():
            if crs is not None and qgslayer.crs() is None:
                qgslayer.setCrs(crs, False)
            if style is None:
                style = ProcessingConfig.getSetting(
                    ProcessingConfig.RASTER_STYLE)
            qgslayer.loadNamedStyle(style)
            QgsProject.instance().addMapLayers([qgslayer])
        else:
            if prjSetting:
                settings.setValue('/Projections/defaultBehavior', prjSetting)
            raise RuntimeError(
                QCoreApplication.translate(
                    'dataobject',
                    'Could not load layer: {0}\nCheck the processing framework log to look for errors.'
                ).format(fileName))
    else:
        qgslayer = QgsVectorLayer(fileName, name, 'ogr')
        if qgslayer.isValid():
            if crs is not None and qgslayer.crs() is None:
                qgslayer.setCrs(crs, False)
            if style is None:
                if qgslayer.geometryType() == QgsWkbTypes.PointGeometry:
                    style = ProcessingConfig.getSetting(
                        ProcessingConfig.VECTOR_POINT_STYLE)
                elif qgslayer.geometryType() == QgsWkbTypes.LineGeometry:
                    style = ProcessingConfig.getSetting(
                        ProcessingConfig.VECTOR_LINE_STYLE)
                else:
                    style = ProcessingConfig.getSetting(
                        ProcessingConfig.VECTOR_POLYGON_STYLE)
            qgslayer.loadNamedStyle(style)
            QgsProject.instance().addMapLayers([qgslayer])

    if prjSetting:
        settings.setValue('/Projections/defaultBehavior', prjSetting)

    return qgslayer
class TestQgsBlendModes(TestCase):

    def __init__(self, methodName):
        """Run once on class initialisation."""
        unittest.TestCase.__init__(self, methodName)

        # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL
        self.mMapRegistry = QgsMapLayerRegistry.instance()

        # create point layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        self.mMapRegistry.addMapLayer(self.mPointLayer)

        # create polygon layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp')
        self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr')
        self.mMapRegistry.addMapLayer(self.mPolygonLayer)

        # create line layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp')
        self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr')
        self.mMapRegistry.addMapLayer(self.mLineLayer)

        # create two raster layers
        myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif')
        self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1")
        self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2")
        myMultiBandRenderer1 = QgsMultiBandColorRenderer(self.mRasterLayer1.dataProvider(), 2, 3, 4)
        self.mRasterLayer1.setRenderer(myMultiBandRenderer1)
        self.mMapRegistry.addMapLayer(self.mRasterLayer1)
        myMultiBandRenderer2 = QgsMultiBandColorRenderer(self.mRasterLayer2.dataProvider(), 2, 3, 4)
        self.mRasterLayer2.setRenderer(myMultiBandRenderer2)
        self.mMapRegistry.addMapLayer(self.mRasterLayer2)

        # to match blend modes test comparisons background
        self.mCanvas = CANVAS
        self.mCanvas.setCanvasColor(QColor(152, 219, 249))
        self.mMap = self.mCanvas.map()
        self.mMap.resize(QSize(400, 400))
        self.mMapRenderer = self.mCanvas.mapRenderer()
        self.mMapRenderer.setOutputSize(QSize(400, 400), 72)

    def testVectorBlending(self):
        """Test that blend modes work for vector layers."""

        #Add vector layers to map
        myLayers = []
        myLayers.append(self.mLineLayer.id())
        myLayers.append(self.mPolygonLayer.id())
        self.mMapRenderer.setLayerSet(myLayers)
        self.mMapRenderer.setExtent(self.mPointLayer.extent())

        #Set blending modes for both layers
        self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference)
        self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference)

        checker = QgsRenderChecker()
        checker.setControlName("expected_vector_blendmodes")
        checker.setMapRenderer(self.mMapRenderer)

        myResult = checker.runTest("vector_blendmodes");
        myMessage = ('vector blending failed')
        assert myResult, myMessage

        #Reset layers
        self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver)
        self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver)

    def testVectorFeatureBlending(self):
        """Test that feature blend modes work for vector layers."""

        #Add vector layers to map
        myLayers = []
        myLayers.append(self.mLineLayer.id())
        myLayers.append(self.mPolygonLayer.id())
        self.mMapRenderer.setLayerSet(myLayers)
        self.mMapRenderer.setExtent(self.mPointLayer.extent())

        #Set feature blending for line layer
        self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus)

        checker = QgsRenderChecker()
        checker.setControlName("expected_vector_featureblendmodes")
        checker.setMapRenderer(self.mMapRenderer)

        myResult = checker.runTest("vector_featureblendmodes");
        myMessage = ('vector feature blending failed')
        assert myResult, myMessage

        #Reset layers
        self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_SourceOver)

    def testVectorLayerTransparency(self):
        """Test that layer transparency works for vector layers."""

        #Add vector layers to map
        myLayers = []
        myLayers.append(self.mLineLayer.id())
        myLayers.append(self.mPolygonLayer.id())
        self.mMapRenderer.setLayerSet(myLayers)
        self.mMapRenderer.setExtent(self.mPointLayer.extent())

        #Set feature blending for line layer
        self.mLineLayer.setLayerTransparency( 50 )

        checker = QgsRenderChecker()
        checker.setControlName("expected_vector_layertransparency")
        checker.setMapRenderer(self.mMapRenderer)

        myResult = checker.runTest("vector_layertransparency");
        myMessage = ('vector layer transparency failed')
        assert myResult, myMessage

    def testRasterBlending(self):
        """Test that blend modes work for raster layers."""
        #Add raster layers to map
        myLayers = []
        myLayers.append(self.mRasterLayer1.id())
        myLayers.append(self.mRasterLayer2.id())
        self.mMapRenderer.setLayerSet(myLayers)
        self.mMapRenderer.setExtent(self.mRasterLayer1.extent())

        #Set blending mode for top layer
        self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Plus)
        checker = QgsRenderChecker()
        checker.setControlName("expected_raster_blendmodes")
        checker.setMapRenderer(self.mMapRenderer)

        myResult = checker.runTest("raster_blendmodes");
        myMessage = ('raster blending failed')
        assert myResult, myMessage
Exemple #36
0
	def toMapLayer(self):
		from qgis.core import QgsRasterLayer, QgsContrastEnhancement
		rl = QgsRasterLayer(self.gdalUri(), self.name)
		if rl.isValid():
			rl.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum)
		return rl
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase):

    @classmethod
    def setUpClass(cls):
        cls.item_class = QgsLayoutItemMap

    def setUp(self):
        self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n"

    def tearDown(self):
        report_file_path = "%s/qgistest.html" % QDir.tempPath()
        with open(report_file_path, 'a') as report_file:
            report_file.write(self.report)

    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)
        myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png')
        rasterFileInfo = QFileInfo(myPath)
        self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(),
                                           rasterFileInfo.completeBaseName())
        rasterRenderer = QgsMultiBandColorRenderer(
            self.raster_layer.dataProvider(), 1, 2, 3)
        self.raster_layer.setRenderer(rasterRenderer)

        myPath = os.path.join(TEST_DATA_DIR, 'points.shp')
        vector_file_info = QFileInfo(myPath)
        self.vector_layer = QgsVectorLayer(vector_file_info.filePath(),
                                           vector_file_info.completeBaseName(), 'ogr')
        assert self.vector_layer.isValid()
        QgsProject.instance().addMapLayers([self.raster_layer, self.vector_layer])

        # create layout with layout map
        self.layout = QgsLayout(QgsProject.instance())
        self.layout.initializeDefaults()
        self.map = QgsLayoutItemMap(self.layout)
        self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        self.map.setFrameEnabled(True)
        self.map.setLayers([self.raster_layer])
        self.layout.addLayoutItem(self.map)

    def testOverviewMap(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        checker = QgsLayoutChecker('composermap_overview', self.layout)
        checker.setColorTolerance(6)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        self.assertTrue(myTestResult, myMessage)

    def testOverviewMapBlend(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply)
        checker = QgsLayoutChecker('composermap_overview_blending', self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        self.assertTrue(myTestResult, myMessage)

    def testOverviewMapInvert(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setInverted(True)
        checker = QgsLayoutChecker('composermap_overview_invert', self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        self.assertTrue(myTestResult, myMessage)

    def testOverviewMapCenter(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(192, -288, 320, -224)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setInverted(False)
        overviewMap.overview().setCentered(True)
        checker = QgsLayoutChecker('composermap_overview_center', self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        self.assertTrue(myTestResult, myMessage)

    def testAsMapLayer(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()
        map = QgsLayoutItemMap(l)
        map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        l.addLayoutItem(map)

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(map)

        layer = overviewMap.overview().asMapLayer()
        self.assertIsNotNone(layer)
        self.assertTrue(layer.isValid())
        self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))'])

        # check that layer has correct renderer
        fill_symbol = QgsFillSymbol.createSimple({'color': '#00ff00', 'outline_color': '#ff0000', 'outline_width': '10'})
        overviewMap.overview().setFrameSymbol(fill_symbol)
        layer = overviewMap.overview().asMapLayer()
        self.assertIsInstance(layer.renderer(), QgsSingleSymbolRenderer)
        self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['color'], '0,255,0,255')
        self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['outline_color'], '255,0,0,255')

        # test layer blend mode
        self.assertEqual(layer.blendMode(), QPainter.CompositionMode_SourceOver)
        overviewMap.overview().setBlendMode(QPainter.CompositionMode_Clear)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual(layer.blendMode(), QPainter.CompositionMode_Clear)

        # should have no effect
        overviewMap.setMapRotation(45)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))'])

        map.setMapRotation(15)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 155 -112, 163 -143, 101 -160, 93 -129))'])

        # with reprojection
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:3875'))
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 96 -128, 99 -127, 102 -126, 105 -126, 108 -125, 111 -124, 114 -123, 116 -123, 119 -122, 122 -121, 125 -120, 128 -119, 131 -119, 134 -118, 137 -117, 140 -116, 143 -115, 146 -115, 149 -114, 152 -113, 155 -112, 155 -114, 156 -115, 156 -117, 156 -118, 157 -120, 157 -121, 158 -123, 158 -124, 158 -126, 159 -127, 159 -128, 160 -130, 160 -131, 160 -133, 161 -134, 161 -136, 161 -137, 162 -139, 162 -140, 163 -142, 163 -143, 160 -144, 157 -145, 154 -146, 151 -146, 148 -147, 145 -148, 142 -149, 140 -149, 137 -150, 134 -151, 131 -152, 128 -153, 125 -153, 122 -154, 119 -155, 116 -156, 113 -157, 110 -157, 107 -158, 104 -159, 101 -160, 101 -158, 100 -157, 100 -155, 100 -154, 99 -152, 99 -151, 98 -149, 98 -148, 98 -146, 97 -145, 97 -144, 96 -142, 96 -141, 96 -139, 95 -138, 95 -136, 95 -135, 94 -133, 94 -132, 93 -130, 93 -129))'])

        map.setCrs(overviewMap.crs())
        # with invert
        overviewMap.overview().setInverted(True)
        layer = overviewMap.overview().asMapLayer()
        self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((-53 -128, 128 53, 309 -128, 128 -309, -53 -128),(93 -129, 101 -160, 163 -143, 155 -112, 93 -129))'])

    def test_StackingPosition(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap)
        self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMap)
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer)
        self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMapLayer)

        overviewMap.overview().setStackingLayer(self.raster_layer)
        self.assertEqual(overviewMap.overview().stackingLayer(), self.raster_layer)
        overviewMap.overview().setStackingLayer(self.vector_layer)
        self.assertEqual(overviewMap.overview().stackingLayer(), self.vector_layer)
        overviewMap.overview().setStackingLayer(None)
        self.assertIsNone(overviewMap.overview().stackingLayer())

    def test_ModifyMapLayerList(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        map = QgsLayoutItemMap(l)
        map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        l.addLayoutItem(map)

        self.assertFalse(overviewMap.overviews().modifyMapLayerList([]))
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer])
        overviewMap.overview().setLinkedMap(map)
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()])
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, self.vector_layer])
        overviewMap.overview().setStackingLayer(self.raster_layer)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer])
        overviewMap.overview().setStackingLayer(self.vector_layer)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()])
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer)
        overviewMap.overview().setStackingLayer(None)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, self.vector_layer])
        overviewMap.overview().setStackingLayer(self.raster_layer)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer])
        overviewMap.overview().setStackingLayer(self.vector_layer)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer])
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer])
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLabels)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [self.raster_layer, self.vector_layer])

        # two overviews
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap)
        overviewMap.overviews().addOverview(QgsLayoutItemMapOverview('x', overviewMap))
        overviewMap.overviews().overview(1).setLinkedMap(map)
        overviewMap.overviews().overview(1).setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels)
        self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]),
                         [overviewMap.overviews().overview(1).asMapLayer(), self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()])

    def testOverviewStacking(self):
        l = QgsLayout(QgsProject.instance())
        l.initializeDefaults()
        map = QgsLayoutItemMap(l)
        map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        map.setFrameEnabled(True)
        map.setLayers([self.raster_layer])
        l.addLayoutItem(map)

        overviewMap = QgsLayoutItemMap(l)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        l.addLayoutItem(overviewMap)
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(-20, -276, 276, 20)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(map)
        overviewMap.overview().setInverted(True)
        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer)
        overviewMap.overview().setStackingLayer(self.raster_layer)

        checker = QgsLayoutChecker('composermap_overview_belowmap', l)
        checker.setColorTolerance(6)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(myTestResult, myMessage)

        overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer)
        overviewMap.overview().setStackingLayer(self.raster_layer)

        checker = QgsLayoutChecker('composermap_overview_abovemap', l)
        checker.setColorTolerance(6)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(myTestResult, myMessage)
Exemple #38
0
    def testSetDataSource(self):
        """Test change data source"""

        temp_dir = QTemporaryDir()
        options = QgsDataProvider.ProviderOptions()
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        layer = QgsRasterLayer(myPath, myBaseName)
        renderer = QgsSingleBandGrayRenderer(layer.dataProvider(), 2)

        image = layer.previewAsImage(QSize(400, 400))
        self.assertFalse(image.isNull())
        self.assertTrue(image.save(os.path.join(temp_dir.path(), 'expected.png'), "PNG"))

        layer.setDataSource(myPath.replace('4326.tif', '4326-BAD_SOURCE.tif'), 'bad_layer', 'gdal', options)
        self.assertFalse(layer.isValid())
        image = layer.previewAsImage(QSize(400, 400))
        self.assertTrue(image.isNull())

        layer.setDataSource(myPath.replace('4326-BAD_SOURCE.tif', '4326.tif'), 'bad_layer', 'gdal', options)
        self.assertTrue(layer.isValid())
        image = layer.previewAsImage(QSize(400, 400))
        self.assertFalse(image.isNull())
        self.assertTrue(image.save(os.path.join(temp_dir.path(), 'actual.png'), "PNG"))

        self.assertTrue(filecmp.cmp(os.path.join(temp_dir.path(), 'actual.png'), os.path.join(temp_dir.path(), 'expected.png')), False)
Exemple #39
0
    def showFileDialog(self, seldir):
        settings = QgsSettings()
        text = str(self.text.text())
        if os.path.isdir(text):
            path = text
        elif not seldir and os.path.isdir(os.path.dirname(text)):
            path = os.path.dirname(text)
        elif settings.contains('/Processing/LastInputPath'):
            path = str(settings.value('/Processing/LastInputPath'))
        else:
            path = ''

        if not seldir:
            ret, selected_filter = QFileDialog.getOpenFileNames(
                self, self.tr('Select Files'), path, getFileFilter(self.param))
        else:
            ret = QFileDialog.getExistingDirectory(self,
                                                   self.tr('Select Directory'),
                                                   path)

        if ret:
            if seldir:
                settings.setValue('/Processing/LastInputPath', ret)

                files = []
                for pp in Path(ret).rglob("*"):
                    if not pp.is_file():
                        continue

                    p = pp.as_posix()

                    if ((isinstance(self.param,
                                    QgsProcessingParameterRasterLayer) or
                         (isinstance(self.param,
                                     QgsProcessingParameterMultipleLayers) and
                          self.param.layerType() == QgsProcessing.TypeRaster))
                            and not QgsRasterLayer.isValidRasterFileName(p)):
                        continue

                    files.append(p)

                if not files:
                    return

            else:
                files = list(ret)
                settings.setValue('/Processing/LastInputPath',
                                  os.path.dirname(str(files[0])))

            for i, filename in enumerate(files):
                files[i] = dataobjects.getRasterSublayer(filename, self.param)
            if len(files) == 1:
                self.text.setText(files[0])
                self.textEditingFinished()
            else:
                if isinstance(self.param,
                              QgsProcessingParameterMultipleLayers):
                    self.text.setText(';'.join(str(f) for f in files))
                else:
                    rowdif = len(files) - (self._table().rowCount() - self.row)
                    for i in range(rowdif):
                        self._panel().addRow()
                    for i, f in enumerate(files):
                        self._table().cellWidget(i + self.row,
                                                 self.col).setValue(f)
                             True)  # supply path to qgis install location

# Now import the processing toolbox
import processing  # QGIS algorithm runner

# Import all native QGIS algorithms
QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())

# --- QGIS analysis
# Convert Path() to string for QGIS
catchment_file = str(catchment_path / catchment_name)
land_file = str(land_path / land_name)

# Load the shape and raster
layer_polygon = QgsVectorLayer(catchment_file, 'merit_hydro_basin', 'ogr')
layer_raster = QgsRasterLayer(land_file, 'modis_land_classes')

# Check we loaded the layers correctly
if not layer_raster.isValid():
    print('Raster layer failed to load')

if not layer_polygon.isValid():
    print('Polygon layer failed to load')

# Specify the parameters for the zonalHistogram function
band = 1  # raster band with the data we are after
params = {
    'COLUMN_PREFIX': 'IGBP_',
    'INPUT_RASTER': layer_raster,
    'INPUT_VECTOR': layer_polygon,
    'OUTPUT': str(intersect_path / intersect_name),
    def testPalettedClassDataFromLayer(self):
        # no layer
        classes = QgsPalettedRasterRenderer.classDataFromRaster(None, 1)
        self.assertFalse(classes)

        # 10 class layer
        path = os.path.join(unitTestDataPath('raster'), 'with_color_table.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer10 = QgsRasterLayer(path, base_name)
        classes = QgsPalettedRasterRenderer.classDataFromRaster(
            layer10.dataProvider(), 1)
        self.assertEqual(len(classes), 10)
        self.assertEqual(classes[0].value, 1)
        self.assertEqual(classes[0].label, '1')
        self.assertEqual(classes[1].value, 2)
        self.assertEqual(classes[1].label, '2')
        self.assertEqual(classes[2].value, 3)
        self.assertEqual(classes[2].label, '3')
        self.assertEqual(classes[3].value, 4)
        self.assertEqual(classes[3].label, '4')
        self.assertEqual(classes[4].value, 5)
        self.assertEqual(classes[4].label, '5')
        self.assertEqual(classes[5].value, 6)
        self.assertEqual(classes[5].label, '6')
        self.assertEqual(classes[6].value, 7)
        self.assertEqual(classes[6].label, '7')
        self.assertEqual(classes[7].value, 8)
        self.assertEqual(classes[7].label, '8')
        self.assertEqual(classes[8].value, 9)
        self.assertEqual(classes[8].label, '9')
        self.assertEqual(classes[9].value, 10)
        self.assertEqual(classes[9].label, '10')

        # bad band
        self.assertFalse(
            QgsPalettedRasterRenderer.classDataFromRaster(
                layer10.dataProvider(), 10101010))

        # with ramp
        r = QgsGradientColorRamp(QColor(200, 0, 0, 100),
                                 QColor(0, 200, 0, 200))
        classes = QgsPalettedRasterRenderer.classDataFromRaster(
            layer10.dataProvider(), 1, r)
        self.assertEqual(len(classes), 10)
        self.assertEqual(classes[0].color.name(), '#c80000')
        self.assertEqual(classes[1].color.name(), '#b21600')
        self.assertEqual(classes[2].color.name(), '#9c2c00')
        self.assertEqual(classes[3].color.name(), '#854200')
        self.assertEqual(classes[4].color.name(), '#6f5900')
        self.assertEqual(classes[5].color.name(), '#596f00')
        self.assertEqual(classes[6].color.name(), '#428500')
        self.assertEqual(classes[7].color.name(), '#2c9c00')
        self.assertEqual(classes[8].color.name(), '#16b200')
        self.assertEqual(classes[9].color.name(), '#00c800')

        # 30 class layer
        path = os.path.join(unitTestDataPath('raster'), 'unique_1.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer10 = QgsRasterLayer(path, base_name)
        classes = QgsPalettedRasterRenderer.classDataFromRaster(
            layer10.dataProvider(), 1)
        self.assertEqual(len(classes), 30)
        expected = [
            11, 21, 22, 24, 31, 82, 2002, 2004, 2014, 2019, 2027, 2029, 2030,
            2080, 2081, 2082, 2088, 2092, 2097, 2098, 2099, 2105, 2108, 2110,
            2114, 2118, 2126, 2152, 2184, 2220
        ]
        self.assertEqual([c.value for c in classes], expected)

        # bad layer
        path = os.path.join(unitTestDataPath('raster'), 'hub13263.vrt')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        classes = QgsPalettedRasterRenderer.classDataFromRaster(
            layer.dataProvider(), 1)
        self.assertFalse(classes)
    def testImportIntoGpkg(self):
        # init target file
        test_gpkg = tempfile.mktemp(suffix='.gpkg', dir=self.testDataDir)
        gdal.GetDriverByName('GPKG').Create(test_gpkg, 1, 1, 1)
        source = QgsRasterLayer(
            os.path.join(self.testDataDir, 'raster',
                         'band3_byte_noct_epsg4326.tif'), 'my', 'gdal')
        self.assertTrue(source.isValid())
        provider = source.dataProvider()
        fw = QgsRasterFileWriter(test_gpkg)
        fw.setOutputFormat('gpkg')
        fw.setCreateOptions(
            ['RASTER_TABLE=imported_table', 'APPEND_SUBDATASET=YES'])

        pipe = QgsRasterPipe()
        self.assertTrue(pipe.set(provider.clone()))

        projector = QgsRasterProjector()
        projector.setCrs(provider.crs(), provider.crs())
        self.assertTrue(pipe.set(projector))

        self.assertEqual(
            fw.writeRaster(pipe, provider.xSize(), provider.ySize(),
                           provider.extent(), provider.crs()), 0)

        # Check that the test geopackage contains the raster layer and compare
        rlayer = QgsRasterLayer('GPKG:%s:imported_table' % test_gpkg)
        self.assertTrue(rlayer.isValid())
        out_provider = rlayer.dataProvider()
        for i in range(3):
            src_data = provider.block(i + 1, provider.extent(), source.width(),
                                      source.height())
            out_data = out_provider.block(i + 1, out_provider.extent(),
                                          rlayer.width(), rlayer.height())
            self.assertEqual(src_data.data(), out_data.data())

        # remove result file
        os.unlink(test_gpkg)
    def testExportToGpkgWithExtraExtentNoNoData(self):
        tmpName = tempfile.mktemp(suffix='.gpkg')
        # Remove nodata
        gdal.Translate('/vsimem/src.tif',
                       os.path.join(self.testDataDir, 'raster',
                                    'band3_byte_noct_epsg4326.tif'),
                       options='-a_nodata none')
        source = QgsRasterLayer('/vsimem/src.tif', 'my', 'gdal')
        self.assertTrue(source.isValid())
        provider = source.dataProvider()
        fw = QgsRasterFileWriter(tmpName)
        fw.setOutputFormat('gpkg')

        pipe = QgsRasterPipe()
        self.assertTrue(pipe.set(provider.clone()))

        self.assertEqual(
            fw.writeRaster(pipe,
                           provider.xSize() + 4,
                           provider.ySize() + 4,
                           QgsRectangle(-3 - 2, -4 - 2, 7 + 2, 6 + 2),
                           provider.crs()), 0)
        del fw

        # Check that the test geopackage contains the raster layer and compare
        rlayer = QgsRasterLayer(tmpName)
        self.assertTrue(rlayer.isValid())
        out_provider = rlayer.dataProvider()
        for i in range(3):
            src_data = provider.block(i + 1, provider.extent(), source.width(),
                                      source.height())
            out_data = out_provider.block(i + 1, provider.extent(),
                                          source.width(), source.height())
            self.assertEqual(src_data.data(), out_data.data())
        out_data = out_provider.block(1, QgsRectangle(7, -4, 7 + 2, 6), 2, 8)
        # No nodata: defaults to zero
        self.assertEqual(out_data.data().data(), b'\x00' * 2 * 8)
        del out_provider
        del rlayer

        # remove result file
        gdal.Unlink('/vsimem/src.tif')
        os.unlink(tmpName)
Exemple #44
0
class TestQgsMapLayerAction(unittest.TestCase):

    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)

        self.vector_layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddate:datetime",
                                           "test_layer", "memory")
        assert self.vector_layer.isValid()
        self.vector_layer2 = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddate:datetime",
                                            "test_layer", "memory")
        assert self.vector_layer2.isValid()
        raster_path = os.path.join(unitTestDataPath(), 'landsat.tif')
        self.raster_layer = QgsRasterLayer(raster_path, 'raster')
        assert self.raster_layer.isValid()

    def testCanRunUsingLayer(self):
        """
        Test that actions correctly indicate when they can run for a layer
        """
        action_all_layers = QgsMapLayerAction('action1', None)
        self.assertTrue(action_all_layers.canRunUsingLayer(None))
        self.assertTrue(action_all_layers.canRunUsingLayer(self.vector_layer))
        self.assertTrue(action_all_layers.canRunUsingLayer(self.raster_layer))

        action_vector_layers_only = QgsMapLayerAction('action2', None, QgsMapLayer.VectorLayer)
        self.assertFalse(action_vector_layers_only.canRunUsingLayer(None))
        self.assertTrue(action_vector_layers_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_vector_layers_only.canRunUsingLayer(self.raster_layer))

        action_raster_layers_only = QgsMapLayerAction('action3', None, QgsMapLayer.RasterLayer)
        self.assertFalse(action_raster_layers_only.canRunUsingLayer(None))
        self.assertFalse(action_raster_layers_only.canRunUsingLayer(self.vector_layer))
        self.assertTrue(action_raster_layers_only.canRunUsingLayer(self.raster_layer))

        action_specific_layer_only = QgsMapLayerAction('action4', None, self.vector_layer)
        self.assertFalse(action_specific_layer_only.canRunUsingLayer(None))
        self.assertTrue(action_specific_layer_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_specific_layer_only.canRunUsingLayer(self.vector_layer2))
        self.assertFalse(action_specific_layer_only.canRunUsingLayer(self.raster_layer))

        action_specific_raster_layer_only = QgsMapLayerAction('action4', None, self.raster_layer)
        self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(None))
        self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(self.vector_layer2))
        self.assertTrue(action_specific_raster_layer_only.canRunUsingLayer(self.raster_layer))

        action_editable_layer_only = QgsMapLayerAction('action1', None, flags=QgsMapLayerAction.EnabledOnlyWhenEditable)
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(None))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer))
        self.vector_layer.startEditing()
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(None))
        self.assertTrue(action_editable_layer_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer))
        self.vector_layer.commitChanges()
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(None))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2))
        self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer))
    def testStatistics(self):
        """Test zonal stats"""
        TEST_DATA_DIR = unitTestDataPath() + "/zonalstatistics/"
        myTempPath = QDir.tempPath() + "/"
        testDir = QDir(TEST_DATA_DIR)
        for f in testDir.entryList(QDir.Files):
            QFile.remove(myTempPath + f)
            QFile.copy(TEST_DATA_DIR + f, myTempPath + f)

        myVector = QgsVectorLayer(myTempPath + "polys.shp", "poly", "ogr")
        myRaster = QgsRasterLayer(myTempPath + "edge_problem.asc", "raster", "gdal")
        zs = QgsZonalStatistics(myVector, myRaster, "", 1, QgsZonalStatistics.All)
        zs.calculateStatistics(None)

        feat = QgsFeature()
        # validate statistics for each feature
        request = QgsFeatureRequest().setFilterFid(0)
        feat = next(myVector.getFeatures(request))
        myMessage = ('Expected: %f\nGot: %f\n' % (12.0, feat[1]))
        assert feat[1] == 12.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (8.0, feat[2]))
        assert feat[2] == 8.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.666666666666667, feat[3]))
        assert abs(feat[3] - 0.666666666666667) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4]))
        assert feat[4] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.47140452079103201, feat[5]))
        assert abs(feat[5] - 0.47140452079103201) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6]))
        assert feat[6] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7]))
        assert feat[7] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8]))
        assert feat[8] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9]))
        assert feat[9] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10]))
        assert feat[10] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11]))
        assert feat[11] == 2.0, myMessage

        request.setFilterFid(1)
        feat = next(myVector.getFeatures(request))
        myMessage = ('Expected: %f\nGot: %f\n' % (9.0, feat[1]))
        assert feat[1] == 9.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (5.0, feat[2]))
        assert feat[2] == 5.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.555555555555556, feat[3]))
        assert abs(feat[3] - 0.555555555555556) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4]))
        assert feat[4] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.49690399499995302, feat[5]))
        assert abs(feat[5] - 0.49690399499995302) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6]))
        assert feat[6] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7]))
        assert feat[7] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8]))
        assert feat[8] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9]))
        assert feat[9] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10]))
        assert feat[10] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11]))
        assert feat[11] == 2.0, myMessage

        request.setFilterFid(2)
        feat = next(myVector.getFeatures(request))
        myMessage = ('Expected: %f\nGot: %f\n' % (6.0, feat[1]))
        assert feat[1] == 6.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (5.0, feat[2]))
        assert feat[2] == 5.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.833333333333333, feat[3]))
        assert abs(feat[3] - 0.833333333333333) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4]))
        assert feat[4] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.372677996249965, feat[5]))
        assert abs(feat[5] - 0.372677996249965) < 0.00001, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6]))
        assert feat[6] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7]))
        assert feat[7] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8]))
        assert feat[8] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9]))
        assert feat[9] == 0.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10]))
        assert feat[10] == 1.0, myMessage
        myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11]))
        assert feat[11] == 2.0, myMessage
Exemple #46
0
    def adding(self, layer_info):
        """Add a layer to QGIS map canvas.

        Take layer index, search the required information to add it in
        the temporary dictionnary constructed in the show_results function.
        It then adds it.
        """
        # one of many add-on option
        if layer_info[0] == "index":
            combobox = self.tbl_result.cellWidget(layer_info[1], 3)
            layer_label = self.tbl_result.cellWidget(layer_info[1], 0).text()
            layer_info = combobox.itemData(combobox.currentIndex())
        # the only add_on option available
        elif layer_info[0] == "info":
            layer_label = self.tbl_result.cellWidget(layer_info[2], 0).text()
            layer_info = layer_info[1]
        else:
            pass
        self.md_sync.tr = self.tr
        logger.info(
            "Adding a layer from those parameters :{}".format(layer_info))

        if type(layer_info) == list:
            # If the layer to be added is a vector file
            if layer_info[0] == "vector":
                path = layer_info[1]
                name = os.path.basename(path).split(".")[0]
                layer = QgsVectorLayer(path, layer_label, "ogr")
                if layer.isValid():
                    lyr = QgsProject.instance().addMapLayer(layer)
                    try:
                        QgsMessageLog.logMessage(
                            message="Data layer added: {}".format(name),
                            tag="Isogeo",
                            level=0,
                        )
                        logger.debug("Vector layer added: {}".format(path))
                    except UnicodeEncodeError:
                        QgsMessageLog.logMessage(
                            message="Vector layer added:: {}".format(
                                name.decode("latin1")),
                            tag="Isogeo",
                            level=0,
                        )
                        logger.debug("Vector layer added: {}".format(
                            name.decode("latin1")))
                else:
                    error_msg = layer.error().message()
                    logger.warning(
                        "Invalid vector layer: {}. QGIS says: {}".format(
                            path, error_msg))
                    QMessageBox.information(
                        iface.mainWindow(),
                        self.tr("Error", context=__class__.__name__),
                        self.tr(
                            "Vector not valid {}. QGIS says: {}",
                            context=__class__.__name__,
                        ).format(path, error_msg),
                    )
            # If raster file
            elif layer_info[0] == "raster":
                path = layer_info[1]
                name = os.path.basename(path).split(".")[0]
                layer = QgsRasterLayer(path, layer_label)
                if layer.isValid():
                    lyr = QgsProject.instance().addMapLayer(layer)
                    try:
                        QgsMessageLog.logMessage(
                            message="Data layer added: {}".format(name),
                            tag="Isogeo",
                            level=0,
                        )
                        logger.debug("Raster layer added: {}".format(path))
                    except UnicodeEncodeError:
                        QgsMessageLog.logMessage(
                            message="Raster layer added:: {}".format(
                                name.decode("latin1")),
                            tag="Isogeo",
                            level=0,
                        )
                        logger.debug("Raster layer added: {}".format(
                            name.decode("latin1")))
                else:
                    error_msg = layer.error().message()
                    logger.warning(
                        "Invalid raster layer: {}. QGIS says: {}".format(
                            path, error_msg))
                    QMessageBox.information(
                        iface.mainWindow(),
                        self.tr("Error", context=__class__.__name__),
                        self.tr(
                            "Raster not valid {}. QGIS says: {}",
                            context=__class__.__name__,
                        ).format(path, error_msg),
                    )
            # If EFS link
            elif layer_info[0] == "EFS":
                name = layer_info[1]
                uri = layer_info[2]
                layer = QgsVectorLayer(uri, layer_label, "arcgisfeatureserver")
                if layer.isValid():
                    lyr = QgsProject.instance().addMapLayer(layer)
                    logger.debug("EFS layer added: {}".format(uri))
                else:
                    error_msg = layer.error().message()
                    logger.warning("Invalid service: {}. QGIS says: {}".format(
                        uri, error_msg))
                    QMessageBox.information(
                        iface.mainWindow(),
                        self.tr("Error", context=__class__.__name__),
                        self.tr("EFS not valid. QGIS says: {}",
                                context=__class__.__name__).format(error_msg),
                    )
            # If EMS link
            elif layer_info[0] == "EMS":
                name = layer_info[1]
                uri = layer_info[2]
                layer = QgsRasterLayer(uri, layer_label, "arcgismapserver")
                if layer.isValid():
                    lyr = QgsProject.instance().addMapLayer(layer)
                    logger.debug("EMS layer added: {}".format(uri))
                else:
                    error_msg = layer.error().message()
                    logger.warning("Invalid service: {}. QGIS says: {}".format(
                        uri, error_msg))
                    QMessageBox.information(
                        iface.mainWindow(),
                        self.tr("Error", context=__class__.__name__),
                        self.tr("EMS not valid. QGIS says: {}",
                                context=__class__.__name__).format(error_msg),
                    )
            # If WFS link
            elif layer_info[0] == "WFS":
                url = layer_info[2]
                name = layer_info[1]
                layer = QgsVectorLayer(url, layer_label, "WFS")
                if layer.isValid():
                    lyr = QgsProject.instance().addMapLayer(layer)
                    logger.debug("WFS layer added: {}".format(url))
                else:
                    error_msg = layer.error().message()
                    name_url = self.build_wfs_url(layer_info[3],
                                                  layer_info[4],
                                                  mode="complete")
                    if name_url[0] != 0:
                        layer = QgsVectorLayer(name_url[2], layer_label, "WFS")
                        if layer.isValid():
                            lyr = QgsProject.instance().addMapLayer(layer)
                            logger.debug("WFS layer added: {}".format(url))
                        else:
                            error_msg = layer.error().message()
                            logger.warning(
                                "Invalid service: {}. QGIS says: {}".format(
                                    url, error_msg))
                    else:
                        QMessageBox.information(
                            iface.mainWindow(),
                            self.tr("Error", context=__class__.__name__),
                            self.tr(
                                "WFS is not valid. QGIS says: {}",
                                context=__class__.__name__,
                            ).format(error_msg),
                        )
                        pass
            # If WMS link
            elif layer_info[0] == "WMS":
                url = layer_info[2]
                name = layer_info[1]
                layer = QgsRasterLayer(url, layer_label, "wms")
                if layer.isValid():
                    lyr = QgsProject.instance().addMapLayer(layer)
                    logger.debug("WMS layer added: {}".format(url))
                else:
                    error_msg = layer.error().message()
                    name_url = self.build_wms_url(layer_info[3],
                                                  layer_info[4],
                                                  mode="complete")
                    if name_url[0] != 0:
                        layer = QgsRasterLayer(name_url[2], layer_label, "wms")
                        if layer.isValid():
                            lyr = QgsProject.instance().addMapLayer(layer)
                            logger.debug("WMS layer added: {}".format(url))
                        else:
                            error_msg = layer.error().message()
                            logger.warning(
                                "Invalid service: {}. QGIS says: {}".format(
                                    url, error_msg))
                    else:
                        QMessageBox.information(
                            iface.mainWindow(),
                            self.tr("Error", context=__class__.__name__),
                            self.tr(
                                "WMS is not valid. QGIS says: {}",
                                context=__class__.__name__,
                            ).format(error_msg),
                        )
            # If WMTS link
            elif layer_info[0] == "WMTS":
                url = layer_info[2]
                name = layer_info[1]
                layer = QgsRasterLayer(url, layer_label, "wms")
                if layer.isValid():
                    lyr = QgsProject.instance().addMapLayer(layer)
                    logger.debug("WMTS service layer added: {}".format(url))
                else:
                    error_msg = layer.error().message()
                    logger.warning("Invalid service: {}. QGIS says: {}".format(
                        url, error_msg))
                    QMessageBox.information(
                        iface.mainWindow(),
                        self.tr("Error", context=__class__.__name__),
                        self.tr(
                            "WMTS is not valid. QGIS says: {}",
                            context=__class__.__name__,
                        ).format(error_msg),
                    )
            else:
                pass

        # If the data is a PostGIS table
        elif isinstance(layer_info, dict):
            logger.debug("Data type: PostGIS")
            # Give aliases to the data passed as arguement
            base_name = layer_info.get("base_name", "")
            schema = layer_info.get("schema", "")
            table = layer_info.get("table", "")
            # Retrieve the database information stored in the PostGISdict
            uri = QgsDataSourceUri()
            host = self.PostGISdict[base_name]["host"]
            port = self.PostGISdict[base_name]["port"]
            user = self.PostGISdict[base_name]["username"]
            password = self.PostGISdict[base_name]["password"]
            # set host name, port, database name, username and password
            uri.setConnection(host, port, base_name, user, password)
            # Get the geometry column name from the database connexion & table
            # name.
            c = pgis_con.PostGisDBConnector(uri)
            dico = c.getTables()
            for i in dico:
                if i[0 == 1] and i[1] == table:
                    geometry_column = i[8]
            # set database schema, table name, geometry column
            uri.setDataSource(schema, table, geometry_column)
            # Adding the layer to the map canvas
            layer = QgsVectorLayer(uri.uri(), table, "postgres")
            if layer.isValid():
                lyr = QgsProject.instance().addMapLayer(layer)
                logger.debug("Data added: {}".format(table))
            elif (not layer.isValid() and plg_tools.last_error[0] == "postgis"
                  and "prim" in plg_tools.last_error[1]):
                logger.debug("PostGIS layer may be a view, "
                             "so key column is missing. "
                             "Trying to automatically set one...")
                # get layer fields to set as key column
                fields = layer.dataProvider().fields()
                fields_names = [i.name() for i in fields]
                # sort them by name containing id to better perf
                fields_names.sort(key=lambda x: ("id" not in x, x))
                for field in fields_names:
                    uri.setKeyColumn(field)
                    layer = QgsVectorLayer(uri.uri(True), table, "postgres")
                    if layer.isValid():
                        lyr = QgsProject.instance().addMapLayer(layer)
                        logger.debug(
                            "PostGIS view layer added with [{}] as key column".
                            format(field))
                        # filling 'QGIS Server' tab of layer Properties
                        self.md_sync.basic_sync(layer=lyr, info=layer_info)
                        return 1
                    else:
                        continue
            else:
                logger.debug("Layer not valid. table = {}".format(table))
                QMessageBox.information(
                    iface.mainWindow(),
                    self.tr("Error", context=__class__.__name__),
                    self.tr(
                        "The PostGIS layer is not valid."
                        " Reason: {}",
                        context=__class__.__name__,
                    ).format(plg_tools.last_error),
                )
                return 0
        # filling 'QGIS Server' tab of layer Properties
        if layer.isValid():
            try:
                self.md_sync.basic_sync(layer=lyr, info=layer_info)
            except IndexError as e:
                logger.debug(
                    "Not supported 'layer_info' format causes this error : {}".
                    format(e))
        else:
            pass
        return 1
Exemple #47
0
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase):
    @classmethod
    def setUpClass(cls):
        cls.item_class = QgsLayoutItemMap

    def setUp(self):
        self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n"

    def tearDown(self):
        report_file_path = "%s/qgistest.html" % QDir.tempPath()
        with open(report_file_path, 'a') as report_file:
            report_file.write(self.report)

    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)
        myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png')
        rasterFileInfo = QFileInfo(myPath)
        self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(),
                                           rasterFileInfo.completeBaseName())
        rasterRenderer = QgsMultiBandColorRenderer(
            self.raster_layer.dataProvider(), 1, 2, 3)
        self.raster_layer.setRenderer(rasterRenderer)

        myPath = os.path.join(TEST_DATA_DIR, 'points.shp')
        vector_file_info = QFileInfo(myPath)
        self.vector_layer = QgsVectorLayer(vector_file_info.filePath(),
                                           vector_file_info.completeBaseName(),
                                           'ogr')
        assert self.vector_layer.isValid()

        # pipe = mRasterLayer.pipe()
        # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer'
        QgsProject.instance().addMapLayers(
            [self.raster_layer, self.vector_layer])

        # create layout with layout map
        self.layout = QgsLayout(QgsProject.instance())
        self.layout.initializeDefaults()
        self.map = QgsLayoutItemMap(self.layout)
        self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        self.map.setFrameEnabled(True)
        self.map.setLayers([self.raster_layer])
        self.layout.addLayoutItem(self.map)

    def testOverviewMap(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        checker = QgsLayoutChecker('composermap_overview', self.layout)
        checker.setColorTolerance(6)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapBlend(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply)
        checker = QgsLayoutChecker('composermap_overview_blending',
                                   self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapInvert(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setInverted(True)
        checker = QgsLayoutChecker('composermap_overview_invert', self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapCenter(self):
        overviewMap = QgsLayoutItemMap(self.layout)
        overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70))
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.layout.addLayoutItem(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(192, -288, 320, -224)
        self.map.setExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setExtent(myRectangle2)
        overviewMap.overview().setLinkedMap(self.map)
        overviewMap.overview().setInverted(False)
        overviewMap.overview().setCentered(True)
        checker = QgsLayoutChecker('composermap_overview_center', self.layout)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testLayout()
        self.report += checker.report()
        self.layout.removeLayoutItem(overviewMap)
        assert myTestResult, myMessage

    def testMapCrs(self):
        # create layout with layout map
        map_settings = QgsMapSettings()
        map_settings.setLayers([self.vector_layer])
        layout = QgsLayout(QgsProject.instance())
        layout.initializeDefaults()

        # check that new maps inherit project CRS
        QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsLayoutItemMap(layout)
        map.attemptSetSceneRect(QRectF(20, 20, 200, 100))
        map.setFrameEnabled(True)
        rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909)
        map.setExtent(rectangle)
        map.setLayers([self.vector_layer])
        layout.addLayoutItem(map)

        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        self.assertFalse(map.presetCrs().isValid())

        # overwrite CRS
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        self.assertEqual(map.crs().authid(), 'EPSG:3857')
        self.assertEqual(map.presetCrs().authid(), 'EPSG:3857')

        checker = QgsLayoutChecker('composermap_crs3857', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        # overwrite CRS
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        self.assertEqual(map.presetCrs().authid(), 'EPSG:4326')
        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        rectangle = QgsRectangle(-124, 17, -78, 52)
        map.zoomToExtent(rectangle)
        checker = QgsLayoutChecker('composermap_crs4326', layout)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testLayout()
        self.report += checker.report()
        self.assertTrue(result, message)

        # change back to project CRS
        map.setCrs(QgsCoordinateReferenceSystem())
        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        self.assertFalse(map.presetCrs().isValid())

    def testContainsAdvancedEffects(self):
        map_settings = QgsMapSettings()
        map_settings.setLayers([self.vector_layer])
        layout = QgsLayout(QgsProject.instance())
        map = QgsLayoutItemMap(layout)

        self.assertFalse(map.containsAdvancedEffects())
        self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken)
        result = map.containsAdvancedEffects()
        self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver)
        self.assertTrue(result)

    def testRasterization(self):
        map_settings = QgsMapSettings()
        map_settings.setLayers([self.vector_layer])
        layout = QgsLayout(QgsProject.instance())
        map = QgsLayoutItemMap(layout)

        self.assertFalse(map.requiresRasterization())
        self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken)
        self.assertFalse(map.requiresRasterization())
        self.assertTrue(map.containsAdvancedEffects())

        map.setBackgroundEnabled(False)
        self.assertTrue(map.requiresRasterization())
        map.setBackgroundEnabled(True)
        map.setBackgroundColor(QColor(1, 1, 1, 1))
        self.assertTrue(map.requiresRasterization())

        self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver)
Exemple #48
0
class TestQgsBlendModes(unittest.TestCase):
    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)

        self.iface = get_iface()

        # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL
        self.mMapRegistry = QgsProject.instance()

        # create point layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
        self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
        self.mMapRegistry.addMapLayer(self.mPointLayer)

        self.mSimplifyMethod = QgsVectorSimplifyMethod()
        self.mSimplifyMethod.setSimplifyHints(
            QgsVectorSimplifyMethod.NoSimplification)

        # create polygon layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp')
        self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr')
        self.mPolygonLayer.setSimplifyMethod(self.mSimplifyMethod)
        self.mMapRegistry.addMapLayer(self.mPolygonLayer)

        # create line layer
        myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp')
        self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr')
        self.mLineLayer.setSimplifyMethod(self.mSimplifyMethod)
        self.mMapRegistry.addMapLayer(self.mLineLayer)

        # create two raster layers
        myRasterFile = os.path.join(TEST_DATA_DIR, 'rgb256x256.png')
        self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1")
        self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2")
        myMultiBandRenderer1 = QgsMultiBandColorRenderer(
            self.mRasterLayer1.dataProvider(), 1, 2, 3)
        self.mRasterLayer1.setRenderer(myMultiBandRenderer1)
        self.mMapRegistry.addMapLayer(self.mRasterLayer1)
        myMultiBandRenderer2 = QgsMultiBandColorRenderer(
            self.mRasterLayer2.dataProvider(), 1, 2, 3)
        self.mRasterLayer2.setRenderer(myMultiBandRenderer2)
        self.mMapRegistry.addMapLayer(self.mRasterLayer2)

        # to match blend modes test comparisons background
        self.mapSettings = QgsMapSettings()
        self.mapSettings.setLayers([self.mRasterLayer1, self.mRasterLayer2])
        self.mapSettings.setBackgroundColor(QColor(152, 219, 249))
        self.mapSettings.setOutputSize(QSize(400, 400))
        self.mapSettings.setOutputDpi(96)

        self.extent = QgsRectangle(-118.8888888888887720, 22.8002070393376783,
                                   -83.3333333333331581, 46.8719806763287536)

    def testVectorBlending(self):
        """Test that blend modes work for vector layers."""

        # Add vector layers to map
        myLayers = [self.mLineLayer, self.mPolygonLayer]
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.extent)

        # Set blending modes for both layers
        self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference)
        self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference)

        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_vector_blendmodes")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)

        myResult = checker.runTest("vector_blendmodes", 20)
        myMessage = ('vector blending failed')
        assert myResult, myMessage

        # Reset layers
        self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver)
        self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver)

    def testVectorFeatureBlending(self):
        """Test that feature blend modes work for vector layers."""

        # Add vector layers to map
        myLayers = [self.mLineLayer, self.mPolygonLayer]
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.extent)

        # Set feature blending for line layer
        self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus)

        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_vector_featureblendmodes")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)

        myResult = checker.runTest("vector_featureblendmodes", 20)
        myMessage = ('vector feature blending failed')
        assert myResult, myMessage

        # Reset layers
        self.mLineLayer.setFeatureBlendMode(
            QPainter.CompositionMode_SourceOver)

    def testVectorLayerTransparency(self):
        """Test that layer transparency works for vector layers."""

        # Add vector layers to map
        myLayers = [self.mLineLayer, self.mPolygonLayer]
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.extent)

        # Set feature blending for line layer
        self.mLineLayer.setLayerTransparency(50)

        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_vector_layertransparency")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)

        myResult = checker.runTest("vector_layertransparency", 20)
        myMessage = ('vector layer transparency failed')
        assert myResult, myMessage

    def testRasterBlending(self):
        """Test that blend modes work for raster layers."""
        # Add raster layers to map
        myLayers = [self.mRasterLayer1, self.mRasterLayer2]
        self.mapSettings.setLayers(myLayers)
        self.mapSettings.setExtent(self.mRasterLayer1.extent())

        # Set blending mode for top layer
        self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Difference)
        checker = QgsMultiRenderChecker()
        checker.setControlName("expected_raster_blendmodes")
        checker.setMapSettings(self.mapSettings)
        checker.setColorTolerance(1)
        checker.setColorTolerance(1)

        myResult = checker.runTest("raster_blendmodes", 20)
        myMessage = ('raster blending failed')
        assert myResult, myMessage
Exemple #49
0
class TestQgsComposerMap(unittest.TestCase):
    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)
        myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png')
        rasterFileInfo = QFileInfo(myPath)
        self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(),
                                           rasterFileInfo.completeBaseName())
        rasterRenderer = QgsMultiBandColorRenderer(
            self.raster_layer.dataProvider(), 1, 2, 3)
        self.raster_layer.setRenderer(rasterRenderer)

        myPath = os.path.join(TEST_DATA_DIR, 'points.shp')
        vector_file_info = QFileInfo(myPath)
        self.vector_layer = QgsVectorLayer(vector_file_info.filePath(),
                                           vector_file_info.completeBaseName(),
                                           'ogr')
        assert self.vector_layer.isValid()

        #pipe = mRasterLayer.pipe()
        #assert pipe.set(rasterRenderer), 'Cannot set pipe renderer'
        QgsProject.instance().addMapLayers(
            [self.raster_layer, self.vector_layer])

        # create composition with composer map
        self.mComposition = QgsComposition(QgsProject.instance())
        self.mComposition.setPaperSize(297, 210)
        self.mComposerMap = QgsComposerMap(self.mComposition, 20, 20, 200, 100)
        self.mComposerMap.setFrameEnabled(True)
        self.mComposerMap.setLayers([self.raster_layer])
        self.mComposition.addComposerMap(self.mComposerMap)

    def testOverviewMap(self):
        overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70)
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.mComposition.addComposerMap(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.mComposerMap.setNewExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setNewExtent(myRectangle2)
        overviewMap.overview().setFrameMap(self.mComposerMap.id())
        checker = QgsCompositionChecker('composermap_overview',
                                        self.mComposition)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testComposition()
        self.mComposition.removeComposerItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapBlend(self):
        overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70)
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.mComposition.addComposerMap(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.mComposerMap.setNewExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setNewExtent(myRectangle2)
        overviewMap.overview().setFrameMap(self.mComposerMap.id())
        overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply)
        checker = QgsCompositionChecker('composermap_overview_blending',
                                        self.mComposition)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testComposition()
        self.mComposition.removeComposerItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapInvert(self):
        overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70)
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.mComposition.addComposerMap(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(96, -152, 160, -120)
        self.mComposerMap.setNewExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setNewExtent(myRectangle2)
        overviewMap.overview().setFrameMap(self.mComposerMap.id())
        overviewMap.overview().setInverted(True)
        checker = QgsCompositionChecker('composermap_overview_invert',
                                        self.mComposition)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testComposition()
        self.mComposition.removeComposerItem(overviewMap)
        assert myTestResult, myMessage

    def testOverviewMapCenter(self):
        overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70)
        overviewMap.setFrameEnabled(True)
        overviewMap.setLayers([self.raster_layer])
        self.mComposition.addComposerMap(overviewMap)
        # zoom in
        myRectangle = QgsRectangle(192, -288, 320, -224)
        self.mComposerMap.setNewExtent(myRectangle)
        myRectangle2 = QgsRectangle(0, -256, 256, 0)
        overviewMap.setNewExtent(myRectangle2)
        overviewMap.overview().setFrameMap(self.mComposerMap.id())
        overviewMap.overview().setInverted(False)
        overviewMap.overview().setCentered(True)
        checker = QgsCompositionChecker('composermap_overview_center',
                                        self.mComposition)
        checker.setControlPathPrefix("composer_mapoverview")
        myTestResult, myMessage = checker.testComposition()
        self.mComposition.removeComposerItem(overviewMap)
        assert myTestResult, myMessage

    def testMapCrs(self):
        # create composition with composer map
        map_settings = QgsMapSettings()
        map_settings.setLayers([self.vector_layer])
        composition = QgsComposition(QgsProject.instance())
        composition.setPaperSize(297, 210)

        # check that new maps inherit project CRS
        QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        map = QgsComposerMap(composition, 20, 20, 200, 100)
        map.setFrameEnabled(True)
        rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909)
        map.setNewExtent(rectangle)
        map.setLayers([self.vector_layer])
        composition.addComposerMap(map)

        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        self.assertFalse(map.presetCrs().isValid())

        # overwrite CRS
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        self.assertEqual(map.crs().authid(), 'EPSG:3857')
        self.assertEqual(map.presetCrs().authid(), 'EPSG:3857')
        checker = QgsCompositionChecker('composermap_crs3857', composition)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testComposition()
        self.assertTrue(result, message)

        # overwrite CRS
        map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
        self.assertEqual(map.presetCrs().authid(), 'EPSG:4326')
        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        rectangle = QgsRectangle(-124, 17, -78, 52)
        map.zoomToExtent(rectangle)
        checker = QgsCompositionChecker('composermap_crs4326', composition)
        checker.setControlPathPrefix("composer_map")
        result, message = checker.testComposition()
        self.assertTrue(result, message)

        # change back to project CRS
        map.setCrs(QgsCoordinateReferenceSystem())
        self.assertEqual(map.crs().authid(), 'EPSG:4326')
        self.assertFalse(map.presetCrs().isValid())

    # Fails because addItemsFromXml has been commented out in sip
    @unittest.expectedFailure
    def testuniqueId(self):
        doc = QDomDocument()
        documentElement = doc.createElement('ComposerItemClipboard')
        self.mComposition.writeXml(documentElement, doc)
        self.mComposition.addItemsFromXml(documentElement, doc, 0, False)

        # test if both composer maps have different ids
        newMap = QgsComposerMap()
        mapList = self.mComposition.composerMapItems()

        for mapIt in mapList:
            if mapIt != self.mComposerMap:
                newMap = mapIt
                break

        oldId = self.mComposerMap.id()
        newId = newMap.id()

        self.mComposition.removeComposerItem(newMap)
        myMessage = 'old: %s new: %s' % (oldId, newId)
        assert oldId != newId, myMessage

    def testWorldFileGeneration(self):
        myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375,
                                   3345223.125)
        self.mComposerMap.setNewExtent(myRectangle)
        self.mComposerMap.setMapRotation(30.0)

        self.mComposition.setGenerateWorldFile(True)
        self.mComposition.setReferenceMap(self.mComposerMap)

        p = self.mComposition.computeWorldFileParameters()
        pexpected = (4.180480199790922, 2.4133064516129026, 779443.7612381146,
                     2.4136013686911886, -4.179969388427311, 3342408.5663611)
        ptolerance = (0.001, 0.001, 1, 0.001, 0.001, 1e+03)
        for i in range(0, 6):
            assert abs(p[i] - pexpected[i]) < ptolerance[i]
Exemple #50
0
def reclassify(layer, exposure_key=None, overwrite_input=False, callback=None):
    """Reclassify a continuous raster layer.

    Issue https://github.com/inasafe/inasafe/issues/3182


    This function is a wrapper for the code from
    https://github.com/chiatt/gdal_reclassify

    For instance if you want to reclassify like this table :
            Original Value     |   Class
            - ∞ < val <= 0     |     1
            0   < val <= 0.5   |     2
            0.5 < val <= 5     |     3
            5   < val <  + ∞   |     6

    You need a dictionary :
        ranges = OrderedDict()
        ranges[1] = [None, 0]
        ranges[2] = [0.0, 0.5]
        ranges[3] = [0.5, 5]
        ranges[6] = [5, None]

    :param layer: The raster layer.
    :type layer: QgsRasterLayer

    :param overwrite_input: Option for the output layer. True will overwrite
        the input layer. False will create a temporary layer.
    :type overwrite_input: bool

    :param exposure_key: The exposure key.
    :type exposure_key: str

    :param callback: A function to all to indicate progress. The function
        should accept params 'current' (int), 'maximum' (int) and 'step' (str).
        Defaults to None.
    :type callback: function

    :return: The classified raster layer.
    :rtype: QgsRasterLayer

    .. versionadded:: 4.0
    """
    output_layer_name = reclassify_raster_steps['output_layer_name']
    processing_step = reclassify_raster_steps['step_name']
    output_layer_name = output_layer_name % layer.keywords['layer_purpose']

    if exposure_key:
        classification_key = active_classification(layer.keywords,
                                                   exposure_key)
        thresholds = active_thresholds_value_maps(layer.keywords, exposure_key)
        layer.keywords['thresholds'] = thresholds
        layer.keywords['classification'] = classification_key
    else:
        classification_key = layer.keywords.get('classification')
        thresholds = layer.keywords.get('thresholds')
    if not thresholds:
        raise InvalidKeywordsForProcessingAlgorithm(
            'thresholds are missing from the layer %s' %
            layer.keywords['layer_purpose'])

    if not classification_key:
        raise InvalidKeywordsForProcessingAlgorithm(
            'classification is missing from the layer %s' %
            layer.keywords['layer_purpose'])

    ranges = {}
    value_map = {}
    hazard_classes = definition(classification_key)['classes']
    for hazard_class in hazard_classes:
        ranges[hazard_class['value']] = thresholds[hazard_class['key']]
        value_map[hazard_class['key']] = [hazard_class['value']]

    if overwrite_input:
        output_raster = layer.source()
    else:
        output_raster = unique_filename(suffix='.tiff', dir=temp_dir())

    driver = gdal.GetDriverByName('GTiff')

    raster_file = gdal.Open(layer.source())
    band = raster_file.GetRasterBand(1)
    no_data = band.GetNoDataValue()
    source = band.ReadAsArray()
    destination = source.copy()

    for value, interval in ranges.iteritems():
        v_min = interval[0]
        v_max = interval[1]

        if v_min is None:
            destination[np.where(source <= v_max)] = value

        if v_max is None:
            destination[np.where(source > v_min)] = value

        if v_min < v_max:
            destination[np.where((v_min < source) & (source <= v_max))] = value

    # Tag no data cells
    destination[np.where(source == no_data)] = no_data_value

    # Create the new file.
    output_file = driver.Create(output_raster, raster_file.RasterXSize,
                                raster_file.RasterYSize, 1)
    output_file.GetRasterBand(1).WriteArray(destination)
    output_file.GetRasterBand(1).SetNoDataValue(no_data_value)

    # CRS
    output_file.SetProjection(raster_file.GetProjection())
    output_file.SetGeoTransform(raster_file.GetGeoTransform())
    output_file.FlushCache()

    del output_file

    if not isfile(output_raster):
        raise FileNotFoundError

    reclassified = QgsRasterLayer(output_raster, output_layer_name)

    # We transfer keywords to the output.
    reclassified.keywords = layer.keywords.copy()
    reclassified.keywords['layer_mode'] = 'classified'

    value_map = {}

    hazard_classes = definition(classification_key)['classes']
    for hazard_class in reversed(hazard_classes):
        value_map[hazard_class['key']] = [hazard_class['value']]

    reclassified.keywords['value_map'] = value_map
    reclassified.keywords['title'] = output_layer_name

    check_layer(reclassified)
    return reclassified
Exemple #51
0
    def ProcessNBR(self, inFileA, inFileB):
        msg = u"NBR Processing for " + self.sceneID + "..."
        iface.mainWindow().statusBar().showMessage(msg)
        QgsMessageLog.logMessage(msg, level=QgsMessageLog.INFO)
        try:
            calculatorEntryList = []
            tempOutFile = self.outFileNBR.replace("NBR", "NBR_temp")

            fileInfo1 = QFileInfo(inFileA)
            baseName1 = fileInfo1.baseName()
            newLayer1 = QgsRasterLayer(inFileA, baseName1)
            boh1 = QgsRasterCalculatorEntry()
            boh1.ref = "boh@1"
            boh1.bandNumber = 1
            calculatorEntryList.append(boh1)
            boh1.raster = newLayer1

            if newLayer1.isValid():
                extents = newLayer1.extent()
                colCt = newLayer1.width()
                rowCt = newLayer1.height()
            else:
                raise IOError(u"Error, Invalid layer read!")

            fileInfo2 = QFileInfo(inFileB)
            baseName2 = fileInfo2.baseName()
            newLayer2 = QgsRasterLayer(inFileB, baseName2)
            boh2 = QgsRasterCalculatorEntry()
            boh2.ref = "boh@2"
            boh2.bandNumber = 1
            calculatorEntryList.append(boh2)
            boh2.raster = newLayer2
            if not newLayer2.isValid():
                raise IOError(u"Error, Invalid layer read!")

            formula = ("(((boh@1 != 0 AND boh@2 != 0) * "
                       "(boh@1 - boh@2) / (boh@1 + boh@2) * 1000) + "
                       "((boh@1 = 0 OR boh@2 = 0) * " + str(self.minShort) +
                       "))")

            # Process calculation with input extent and resolution
            calc = QgsRasterCalculator(formula, tempOutFile, 'GTiff', extents,
                                       colCt, rowCt, calculatorEntryList)

            result = calc.processCalculation()

            if result != 0:
                raise RuntimeError(u"Raster calculator failed.")

            # convert Raster Calculator result to int 16
            self.Float2IntTif(tempOutFile, self.outFileNBR)
        except:
            raise RuntimeError(u"Unspecified error when calculating NBR")
        finally:
            # cleanup
            calculatorEntryList = None
            fileInfo1 = None
            baseName1 = None
            fileInfo2 = None
            baseName2 = None
            formula = None
            boh1 = None
            boh2 = None
            calc = None
            newLayer1 = None
            newLayer2 = None

            del calculatorEntryList
            del fileInfo1
            del baseName1
            del fileInfo2
            del baseName2
            del formula
            del boh1
            del boh2
            del calc
            del newLayer1
            del newLayer2
        gc.collect()

        msg = u"NBR Processing for " + self.sceneID + " Completed"
        iface.mainWindow().statusBar().showMessage(msg)
        QgsMessageLog.logMessage(msg, level=QgsMessageLog.INFO)
        iface.mainWindow().statusBar().showMessage("")
        return result
    def testPalettedBand(self):
        """ test paletted raster render band"""
        path = os.path.join(unitTestDataPath(),
                            'landsat_4326.tif')
        info = QFileInfo(path)
        base_name = info.baseName()
        layer = QgsRasterLayer(path, base_name)
        self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path))

        renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 2,
                                             [QgsPalettedRasterRenderer.Class(137, QColor(0, 255, 0), 'class 2'),
                                              QgsPalettedRasterRenderer.Class(138, QColor(255, 0, 0), 'class 1'),
                                              QgsPalettedRasterRenderer.Class(139, QColor(0, 0, 255), 'class 1')])

        layer.setRenderer(renderer)
        ms = QgsMapSettings()
        ms.setLayers([layer])
        ms.setExtent(layer.extent())

        checker = QgsRenderChecker()
        checker.setControlName("expected_paletted_renderer_band2")
        checker.setMapSettings(ms)

        self.assertTrue(checker.runTest("expected_paletted_renderer_band2"), "Paletted rendering test failed")

        renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 3,
                                             [QgsPalettedRasterRenderer.Class(120, QColor(0, 255, 0), 'class 2'),
                                              QgsPalettedRasterRenderer.Class(123, QColor(255, 0, 0), 'class 1'),
                                              QgsPalettedRasterRenderer.Class(124, QColor(0, 0, 255), 'class 1')])

        layer.setRenderer(renderer)
        ms = QgsMapSettings()
        ms.setLayers([layer])
        ms.setExtent(layer.extent())

        checker = QgsRenderChecker()
        checker.setControlName("expected_paletted_renderer_band3")
        checker.setMapSettings(ms)

        self.assertTrue(checker.runTest("expected_paletted_renderer_band3"), "Paletted rendering test failed")
Exemple #53
0
 def layers_create(self, missing=None):
     """Utworzenie warstw w projekcie. Podanie atrybutu 'missing' spowoduje, że tylko wybrane warstwy będą dodane."""
     # Ustalenie ilości dodawanych warstw:
     i_max = len(missing) if missing else self.lyr_cnt
     # Utworzenie listy ze słownikami warstw do dodania:
     lyrs = []
     if missing:
         for l_dict in self.lyrs:
             if l_dict["name"] in missing:
                 lyrs.append(l_dict)
     else:
         lyrs = self.lyrs
     i = 0
     # Dodanie warstw:
     for l_dict in lyrs:
         QgsApplication.processEvents()
         i += 1
         dlg.splash_screen.p_bar.setValue(i * 100 / self.lyr_cnt)
         QgsApplication.processEvents()
         raw_uri = l_dict["uri"]
         uri = eval("f'{}'".format(raw_uri))
         if l_dict["source"] == "wms" or l_dict["source"] == "gdal":
             lyr = QgsRasterLayer(uri, l_dict["name"], l_dict["source"])
             lyr_required = False
         else:
             lyr = QgsVectorLayer(uri, l_dict["name"], l_dict["source"])
             lyr_required = True
         if not lyr.isValid() and not lyr_required:
             m_text = f'Nie udało się poprawnie wczytać podkładu mapowego: {l_dict["name"]}. Naciśnięcie Tak spowoduje kontynuowanie uruchamiania wtyczki (podkład mapowy nie będzie wyświetlany), naciśnięcie Nie przerwie proces uruchamiania wtyczki. Jeśli problem będzie się powtarzał, zaleca się powiadomienie administratora systemu.'
             reply = QMessageBox.question(dlg.app, "Moek_Editor", m_text, QMessageBox.Yes, QMessageBox.No)
             if reply == QMessageBox.No:
                 return False
         elif not lyr.isValid() and lyr_required:
             m_text = f'Nie udało się poprawnie wczytać warstwy: {l_dict["name"]}. Jeśli problem będzie się powtarzał, proszę o powiadomienie administratora systemu.'
             QMessageBox.critical(dlg.app, "Moek_Editor", m_text)
             return False
         if l_dict["source"] == "memory":
             lyr.setCustomProperty("skipMemoryLayersCheck", 1)
             pr = lyr.dataProvider()
             pr.addAttributes(l_dict["attrib"])
             lyr.updateFields()
         if "crs" in l_dict:
             lyr.setCrs(CRS_1992)
         dlg.proj.addMapLayer(lyr, False)
         if l_dict["root"]:
             parent_grp = self.root
             parent_grp.insertChildNode(l_dict["pos"], QgsLayerTreeLayer(lyr))
             parent_grp.findLayer(lyr).setItemVisibilityChecked(l_dict["visible"])
         else:
             if "pos" in l_dict:
                 parent_grp = self.root.findGroup(l_dict["parent"])
                 parent_grp.insertChildNode(l_dict["pos"], QgsLayerTreeLayer(lyr))
                 parent_grp.findLayer(lyr).setItemVisibilityChecked(False)
             else:
                 parent_grp = self.root.findGroup(l_dict["parent"])
                 node = parent_grp.addLayer(lyr)
                 node.setItemVisibilityChecked(l_dict["visible"])
         lyr.loadNamedStyle(f'{STYLE_PATH}{l_dict["name"].lower()}.qml')
     return True
Exemple #54
0
    def testRasterBlock(self):
        """Test raster block with extent"""

        path = os.path.join(unitTestDataPath(), 'landsat_4326.tif')
        raster_layer = QgsRasterLayer(path, 'test')
        self.assertTrue(raster_layer.isValid())

        extent = QgsRectangle(17.94284482577178252, 30.23021770271909503,
                              17.94407867909909626, 30.23154272264058307)
        block = raster_layer.dataProvider().block(1, extent, 2, 3)
        self.checkBlockContents(block, [
            125.0,
            125.0,
            125.0,
            125.0,
            125.0,
            124.0,
        ])

        full_content = [
            125.0,
            125.0,
            125.0,
            125.0,
            125.0,
            125.0,
            125.0,
            124.0,
            125.0,
            126.0,
            127.0,
            127.0,
        ]

        extent = raster_layer.extent()
        block = raster_layer.dataProvider().block(1, extent, 3, 4)
        self.checkBlockContents(block, full_content)

        extent = raster_layer.extent()
        extent.grow(-0.0001)
        block = raster_layer.dataProvider().block(1, extent, 3, 4)
        self.checkBlockContents(block, full_content)

        row_height = raster_layer.extent().height() / raster_layer.height()

        for row in range(raster_layer.height()):
            extent = raster_layer.extent()
            extent.setYMaximum(extent.yMaximum() - row_height * row)
            extent.setYMinimum(extent.yMaximum() - row_height)
            block = raster_layer.dataProvider().block(1, extent, 3, 1)
            self.checkBlockContents(block, full_content[row * 3:row * 3 + 3])
Exemple #55
0
    def WriteMultiBandFiles(self, fileList, outFile):
        msg = u"WriteMultiBandFiles for " + self.sceneID + "..."
        iface.mainWindow().statusBar().showMessage(msg)
        # give ownership of layers to map registry so unlock happens
        for entry in fileList:
            fileInfo1 = QFileInfo(entry)
            baseName1 = fileInfo1.baseName()
            layer1 = QgsRasterLayer(entry, baseName1)
            QgsMapLayerRegistry.instance().addMapLayer(layer1)

        # Build VRT for TOA processing
        vrtPath = os.path.join(self.workPath, self.sceneID + ".vrt")
        processing.runalg(
            "gdalogr:buildvirtualraster", {
                "INPUT": fileList,
                "RESOLUTION": 0,
                "SEPARATE": True,
                "OUTPUT": vrtPath
            })

        # write out virtual raster
        ds = gdal.Open(vrtPath)
        rows = ds.RasterYSize
        cols = ds.RasterXSize
        geo = ds.GetGeoTransform()
        projection = ds.GetProjection()

        if self.sensor == "8":
            toa_ds =\
                self.driver.Create(outFile,
                                   cols, rows, 8, gdal.GDT_Byte,
                                   ["TILED=YES",
                                    "BLOCKXSIZE=64",
                                    "BLOCKYSIZE=64"])
        else:
            toa_ds =\
                self.driver.Create(outFile,
                                   cols, rows, 6, gdal.GDT_Byte,
                                   ["TILED=YES",
                                    "BLOCKXSIZE=64",
                                    "BLOCKYSIZE=64"])

        toa_ds.SetGeoTransform(geo)
        toa_ds.SetProjection(projection)
        # Process each band, one at a time
        for num in range(8):
            num += 1

            if self.sensor != "8" and num > 6:
                continue

            band = ds.GetRasterBand(num)
            toa_band = toa_ds.GetRasterBand(num)

            b_arr = np.array(band.ReadAsArray(0, 0, cols, rows),
                             dtype=np.int16)
            b_arr[b_arr < 0] = 0
            b_arr = b_arr / 25
            toa_band.WriteArray(b_arr.astype(np.uint8))
            del toa_band

        del b_arr
        ds = None
        toa_ds = None
        vrtPath = None
        del ds
        del toa_ds
        del vrtPath
        QgsMapLayerRegistry.instance().removeAllMapLayers()

        msg = u"WriteMultiBandFiles for " + self.sceneID + " Completed"
        iface.mainWindow().statusBar().showMessage(msg)
        return
    def test_project_roundtrip(self):
        """Tests that a project with bad layers can be saved and restored"""

        p = QgsProject.instance()
        temp_dir = QTemporaryDir()
        for ext in ('shp', 'dbf', 'shx', 'prj'):
            copyfile(os.path.join(TEST_DATA_DIR, 'lines.%s' % ext),
                     os.path.join(temp_dir.path(), 'lines.%s' % ext))
        copyfile(
            os.path.join(TEST_DATA_DIR, 'raster',
                         'band1_byte_ct_epsg4326.tif'),
            os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif'))
        copyfile(
            os.path.join(TEST_DATA_DIR, 'raster',
                         'band1_byte_ct_epsg4326.tif'),
            os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif'))
        l = QgsVectorLayer(os.path.join(temp_dir.path(), 'lines.shp'), 'lines',
                           'ogr')
        self.assertTrue(l.isValid())

        rl = QgsRasterLayer(
            os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif'),
            'raster', 'gdal')
        self.assertTrue(rl.isValid())
        rl_copy = QgsRasterLayer(
            os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif'),
            'raster_copy', 'gdal')
        self.assertTrue(rl_copy.isValid())
        self.assertTrue(p.addMapLayers([l, rl, rl_copy]))

        # Save project
        project_path = os.path.join(temp_dir.path(), 'project.qgs')
        self.assertTrue(p.write(project_path))

        # Re-load the project, checking for the XML properties
        p.removeAllMapLayers()
        self.assertTrue(p.read(project_path))
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertTrue(vector.originalXmlProperties() != '')
        self.assertTrue(raster.originalXmlProperties() != '')
        self.assertTrue(raster_copy.originalXmlProperties() != '')
        # Test setter
        raster.setOriginalXmlProperties('pippo')
        self.assertEqual(raster.originalXmlProperties(), 'pippo')

        # Now create and invalid project:
        bad_project_path = os.path.join(temp_dir.path(), 'project_bad.qgs')
        with open(project_path, 'r') as infile:
            with open(bad_project_path, 'w+') as outfile:
                outfile.write(infile.read().replace(
                    './lines.shp', './lines-BAD_SOURCE.shp').replace(
                        'band1_byte_ct_epsg4326_copy.tif',
                        'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif'))

        # Load the bad project
        p.removeAllMapLayers()
        self.assertTrue(p.read(bad_project_path))
        # Check layer is invalid
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertIsNotNone(vector.dataProvider())
        self.assertIsNotNone(raster.dataProvider())
        self.assertIsNotNone(raster_copy.dataProvider())
        self.assertFalse(vector.isValid())
        self.assertFalse(raster_copy.isValid())
        # Try a getFeatures
        self.assertEqual([f for f in vector.getFeatures()], [])
        self.assertTrue(raster.isValid())
        self.assertEqual(vector.providerType(), 'ogr')

        # Save the project
        bad_project_path2 = os.path.join(temp_dir.path(), 'project_bad2.qgs')
        p.write(bad_project_path2)
        # Re-save the project, with fixed paths
        good_project_path = os.path.join(temp_dir.path(), 'project_good.qgs')
        with open(bad_project_path2, 'r') as infile:
            with open(good_project_path, 'w+') as outfile:
                outfile.write(infile.read().replace(
                    './lines-BAD_SOURCE.shp', './lines.shp').replace(
                        'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif',
                        'band1_byte_ct_epsg4326_copy.tif'))

        # Load the good project
        p.removeAllMapLayers()
        self.assertTrue(p.read(good_project_path))
        # Check layer is valid
        vector = list(p.mapLayersByName('lines'))[0]
        raster = list(p.mapLayersByName('raster'))[0]
        raster_copy = list(p.mapLayersByName('raster_copy'))[0]
        self.assertTrue(vector.isValid())
        self.assertTrue(raster.isValid())
        self.assertTrue(raster_copy.isValid())
        def add_layer(layer_name, style=None, preset_style=None):
            cql = self.get_cql_query()
            if self.service_type == SERVICE_MANAGER.WFS:
                end_point = self.service_config['endpointurl']
                if cql:
                    if not end_point.endswith('?'):
                        end_point += '?'

                    end_point += 'CQL_FILTER=' + urllib.parse.quote(cql)

                uri = "pagingEnabled='true'"
                if not cql:
                    uri += " restrictToRequestBBOX='1'"

                uri += " srsname='{}' typename='{}' url='{}' version='auto'".format(
                    self.service_config['srs'], layer_name, end_point)
                vl = QgsVectorLayer(uri, layer_name, 'WFS')

                if preset_style.get('style') and preset_style[
                        'style'] in SERVICE_MANAGER.PRESET_STYLES:
                    style_url = SERVICE_MANAGER.PRESET_STYLES[
                        preset_style['style']]['url']
                    StyleUtils.fetch_and_apply_style(vl, style_url)

                layers_to_add.append(vl)
            elif self.service_type == SERVICE_MANAGER.WMS:
                base_uri = 'contextualWMSLegend=0&crs={}&dpiMode=7&format=image/png&layers={}'.format(
                    self.service_config['srs'], layer_name)

                if style:
                    uri = base_uri + "&styles={}".format(style)
                    layer_name += ' ({})'.format(style)
                else:
                    uri = base_uri + "&styles"

                uri += "&url={}".format(self.service_config['endpointurl'])

                if cql:
                    uri += 'CQL_FILTER=' + urllib.parse.quote(cql)
                    uri = 'IgnoreGetMapUrl=1&' + uri

                rl = QgsRasterLayer(uri, layer_name, 'wms')
                layers_to_add.append(rl)
            elif self.service_type == SERVICE_MANAGER.WCS:
                end_point = self.service_config['endpointurl']
                if cql:
                    if not end_point.endswith('?'):
                        end_point += '?'

                    end_point += 'CQL_FILTER=' + urllib.parse.quote(cql)

                uri = "pagingEnabled='true'"
                if not cql:
                    uri += " restrictToRequestBBOX='1'"

                uri += " srsname='{}' typename='{}' url='{}' version='auto'".format(
                    self.service_config['srs'], layer_name, end_point)
                rl = QgsRasterLayer(uri, layer_name, 'wcs')

                if preset_style.get('style') and preset_style[
                        'style'] in SERVICE_MANAGER.PRESET_STYLES:
                    style_url = SERVICE_MANAGER.PRESET_STYLES[
                        preset_style['style']]['url']
                    StyleUtils.fetch_and_apply_style(rl, style_url)

                layers_to_add.append(rl)
class TestQgsRasterRendererCreateSld(unittest.TestCase):
    """
     This class tests the creation of SLD from QGis raster layers
    """
    @classmethod
    def setUpClass(self):
        pass

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def __init__(self, methodName):
        """Run once on class initialization."""
        unittest.TestCase.__init__(self, methodName)
        myPath = os.path.join(TEST_DATA_DIR, 'landsat.tif')
        rasterFileInfo = QFileInfo(myPath)
        self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(),
                                           rasterFileInfo.completeBaseName())

    def testSingleBandPseudoColorRenderer_Interpolated(self):
        # get min and max of the band to renderer
        bandNo = 3
        stats = self.raster_layer.dataProvider().bandStatistics(
            bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max)
        minValue = stats.minimumValue
        maxValue = stats.maximumValue
        # create shader for the renderer
        shader = QgsRasterShader(minValue, maxValue)
        colorRampShaderFcn = QgsColorRampShader(minValue, maxValue)
        colorRampShaderFcn.setColorRampType(QgsColorRampShader.Interpolated)
        colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous)
        colorRampShaderFcn.setClip(True)
        items = []
        for index in range(10):
            items.append(
                QgsColorRampShader.ColorRampItem(
                    index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)),
                    "{}".format(index)))
        colorRampShaderFcn.setColorRampItemList(items)
        shader.setRasterShaderFunction(colorRampShaderFcn)
        # create instance to test
        rasterRenderer = QgsSingleBandPseudoColorRenderer(
            self.raster_layer.dataProvider(), bandNo, shader)
        self.raster_layer.setRenderer(rasterRenderer)

        # do test
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertNoOpacity(root)
        self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo))
        # check ColorMapEntry classes
        colorMap = root.elementsByTagName('sld:ColorMap')
        colorMap = colorMap.item(0).toElement()
        self.assertFalse(colorMap.isNull())
        self.assertEqual(colorMap.attribute('type'), 'ramp')
        colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry')
        self.assertEqual(colorMapEntries.count(), 10)
        for index in range(colorMapEntries.count()):
            colorMapEntry = colorMapEntries.at(index).toElement()
            self.assertEqual(colorMapEntry.attribute('quantity'),
                             '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('label'),
                             '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('opacity'), '')
            self.assertEqual(colorMapEntry.attribute('color'),
                             '#{0:02d}{0:02d}{0:02d}'.format(index))

    def testSingleBandPseudoColorRenderer_Discrete(self):
        # get min and max of the band to renderer
        bandNo = 3
        stats = self.raster_layer.dataProvider().bandStatistics(
            bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max)
        minValue = stats.minimumValue
        maxValue = stats.maximumValue
        # create shader for the renderer
        shader = QgsRasterShader(minValue, maxValue)
        colorRampShaderFcn = QgsColorRampShader(minValue, maxValue)
        colorRampShaderFcn.setColorRampType(QgsColorRampShader.Discrete)
        colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous)
        colorRampShaderFcn.setClip(True)
        items = []
        for index in range(10):
            items.append(
                QgsColorRampShader.ColorRampItem(
                    index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)),
                    "{}".format(index)))
        colorRampShaderFcn.setColorRampItemList(items)
        shader.setRasterShaderFunction(colorRampShaderFcn)
        # create instance to test
        rasterRenderer = QgsSingleBandPseudoColorRenderer(
            self.raster_layer.dataProvider(), bandNo, shader)
        self.raster_layer.setRenderer(rasterRenderer)

        # do test
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertNoOpacity(root)
        self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo))
        # check ColorMapEntry classes
        colorMap = root.elementsByTagName('sld:ColorMap')
        colorMap = colorMap.item(0).toElement()
        self.assertFalse(colorMap.isNull())
        self.assertEqual(colorMap.attribute('type'), 'intervals')
        colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry')
        self.assertEqual(colorMapEntries.count(), 10)
        for index in range(colorMapEntries.count()):
            colorMapEntry = colorMapEntries.at(index).toElement()
            self.assertEqual(colorMapEntry.attribute('quantity'),
                             '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('label'),
                             '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('opacity'), '')
            self.assertEqual(colorMapEntry.attribute('color'),
                             '#{0:02d}{0:02d}{0:02d}'.format(index))

    def testSingleBandPseudoColorRenderer_Exact(self):
        # get min and max of the band to renderer
        bandNo = 3
        stats = self.raster_layer.dataProvider().bandStatistics(
            bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max)
        minValue = stats.minimumValue
        maxValue = stats.maximumValue
        # create shader for the renderer
        shader = QgsRasterShader(minValue, maxValue)
        colorRampShaderFcn = QgsColorRampShader(minValue, maxValue)
        colorRampShaderFcn.setColorRampType(QgsColorRampShader.Exact)
        colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous)
        colorRampShaderFcn.setClip(True)
        items = []
        for index in range(10):
            items.append(
                QgsColorRampShader.ColorRampItem(
                    index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)),
                    "{}".format(index)))
        colorRampShaderFcn.setColorRampItemList(items)
        shader.setRasterShaderFunction(colorRampShaderFcn)
        # create instance to test
        rasterRenderer = QgsSingleBandPseudoColorRenderer(
            self.raster_layer.dataProvider(), bandNo, shader)
        self.raster_layer.setRenderer(rasterRenderer)

        # do test
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertNoOpacity(root)
        self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo))
        # check ColorMapEntry classes
        colorMap = root.elementsByTagName('sld:ColorMap')
        colorMap = colorMap.item(0).toElement()
        self.assertFalse(colorMap.isNull())
        self.assertEqual(colorMap.attribute('type'), 'values')
        self.assertFalse(colorMap.hasAttribute('extendend'))
        colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry')
        self.assertEqual(colorMapEntries.count(), 10)
        for index in range(colorMapEntries.count()):
            colorMapEntry = colorMapEntries.at(index).toElement()
            self.assertEqual(colorMapEntry.attribute('quantity'),
                             '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('label'),
                             '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('opacity'), '')
            self.assertEqual(colorMapEntry.attribute('color'),
                             '#{0:02d}{0:02d}{0:02d}'.format(index))

        # add check that is set ColoMap extended="true" if colormap is bigger that 255 entries
        # !NOTE! can't reuse previous shader => segmentation fault
        shader = QgsRasterShader(minValue, maxValue)
        colorRampShaderFcn = QgsColorRampShader(minValue, maxValue)
        colorRampShaderFcn.setColorRampType(QgsColorRampShader.Exact)
        colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous)
        colorRampShaderFcn.setClip(True)
        items = []
        for index in range(255):
            items.append(
                QgsColorRampShader.ColorRampItem(
                    index, QColor.fromHsv(index, 255, 255, 255),
                    "{}".format(index)))
        colorRampShaderFcn.setColorRampItemList(items)
        shader.setRasterShaderFunction(colorRampShaderFcn)
        # create instance to test
        rasterRenderer = QgsSingleBandPseudoColorRenderer(
            self.raster_layer.dataProvider(), bandNo, shader)
        # self.raster_layer.setRenderer(rasterRenderer)
        # dom, root = self.rendererToSld(self.raster_layer.renderer())
        # self.assertTrue( colorMap.hasAttribute( 'extendend' ) )
        # self.assertEqual( colorMap.attribute( 'extendend' ), 'true' )

    def testPalettedRasterRenderer(self):
        # create 10 color classes
        #classesString = '122 0 0 0 255 122\n123 1 1 1 255 123\n124 2 2 2 255 124\n125 3 3 3 255 125\n126 4 4 4 255 126\n127 5 5 5 255 127\n128 6 6 6 255 128\n129 7 7 7 255 129\n130 8 8 8 255 130'
        classesString = ''
        for index in range(10):
            classesString += '{0} {0} {0} {0} 255 {0}\n'.format(index)
        classes = QgsPalettedRasterRenderer.classDataFromString(classesString)

        rasterRenderer = QgsPalettedRasterRenderer(
            self.raster_layer.dataProvider(), 3, classes)
        self.raster_layer.setRenderer(rasterRenderer)

        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertNoOpacity(root)
        self.assertChannelBand(root, 'sld:GrayChannel', '3')
        # check ColorMapEntry classes
        colorMap = root.elementsByTagName('sld:ColorMap')
        colorMap = colorMap.item(0).toElement()
        self.assertFalse(colorMap.isNull())
        self.assertEqual(colorMap.attribute('type'), 'values')
        self.assertFalse(colorMap.hasAttribute('extendend'))
        colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry')
        self.assertEqual(colorMapEntries.count(), 10)
        for index in range(colorMapEntries.count()):
            colorMapEntry = colorMapEntries.at(index).toElement()
            self.assertEqual(colorMapEntry.attribute('quantity'),
                             '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('label'),
                             '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('opacity'), '')
            self.assertEqual(colorMapEntry.attribute('color'),
                             '#{0:02d}{0:02d}{0:02d}'.format(index))

        # add check that is set ColoMap extended="true" if colormap is bigger that 255 entries
        classesString = ''
        values = range(255)
        for index in range(255):
            classesString += '{0} {1} {1} {1} 255 {0}\n'.format(
                index, random.choice(values))
        classes = QgsPalettedRasterRenderer.classDataFromString(classesString)
        rasterRenderer = QgsPalettedRasterRenderer(
            self.raster_layer.dataProvider(), 3, classes)
        self.raster_layer.setRenderer(rasterRenderer)
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        colorMap = root.elementsByTagName('sld:ColorMap')
        colorMap = colorMap.item(0).toElement()
        self.assertTrue(colorMap.hasAttribute('extended'))
        self.assertEqual(colorMap.attribute('extended'), 'true')

    def testMultiBandColorRenderer(self):
        rasterRenderer = QgsMultiBandColorRenderer(
            self.raster_layer.dataProvider(), 3, 1, 2)
        self.raster_layer.setRenderer(rasterRenderer)
        self.raster_layer.setContrastEnhancement(
            algorithm=QgsContrastEnhancement.StretchToMinimumMaximum,
            limits=QgsRasterMinMaxOrigin.MinMax)

        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertNoOpacity(root)
        self.assertChannelBand(root, 'sld:RedChannel', '3')
        self.assertChannelBand(root, 'sld:GreenChannel', '1')
        self.assertChannelBand(root, 'sld:BlueChannel', '2')

    def testSingleBandGrayRenderer(self):
        # check with StretchToMinimumMaximum
        rasterRenderer = QgsSingleBandGrayRenderer(
            self.raster_layer.dataProvider(), 3)
        self.raster_layer.setRenderer(rasterRenderer)
        self.raster_layer.setContrastEnhancement(
            algorithm=QgsContrastEnhancement.StretchToMinimumMaximum,
            limits=QgsRasterMinMaxOrigin.MinMax)
        maximum = self.raster_layer.renderer().contrastEnhancement(
        ).maximumValue()
        minmum = self.raster_layer.renderer().contrastEnhancement(
        ).minimumValue()
        self.assertEqual(minmum, 51)
        self.assertEqual(maximum, 172)

        # check default values
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertNoOpacity(root)
        self.assertChannelBand(root, 'sld:GrayChannel', '3')

        elements = root.elementsByTagName('sld:ContrastEnhancement')
        self.assertEqual(len(elements), 1)
        enhancement = elements.at(0).toElement()
        self.assertFalse(enhancement.isNull())

        normalize = enhancement.firstChildElement('sld:Normalize')
        self.assertFalse(normalize.isNull())
        self.assertVendorOption(normalize, 'algorithm',
                                'StretchToMinimumMaximum')
        self.assertVendorOption(normalize, 'minValue', '51')
        self.assertVendorOption(normalize, 'maxValue', '172')

        elements = root.elementsByTagName('sld:ColorMap')
        self.assertEqual(len(elements), 1)
        colorMap = elements.at(0).toElement()
        self.assertFalse(colorMap.isNull())

        colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry')
        self.assertEqual(len(colorMapEntries), 2)
        clorMap1 = colorMapEntries.at(0)
        self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(),
                         '#000000')
        self.assertEqual(
            clorMap1.attributes().namedItem('quantity').nodeValue(), '0')

        clorMap2 = colorMapEntries.at(1)
        self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(),
                         '#ffffff')
        self.assertEqual(
            clorMap2.attributes().namedItem('quantity').nodeValue(), '255')

        # check when StretchAndClipToMinimumMaximum
        # then min/max have always to be the real one and not that set in the contrastEnhancement
        self.raster_layer.setContrastEnhancement(
            algorithm=QgsContrastEnhancement.StretchAndClipToMinimumMaximum,
            limits=QgsRasterMinMaxOrigin.MinMax)
        minmum = self.raster_layer.renderer().contrastEnhancement(
        ).setMinimumValue(100)
        maximum = self.raster_layer.renderer().contrastEnhancement(
        ).maximumValue()
        minmum = self.raster_layer.renderer().contrastEnhancement(
        ).minimumValue()
        self.assertEqual(minmum, 100)
        self.assertEqual(maximum, 172)

        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertNoOpacity(root)
        self.assertChannelBand(root, 'sld:GrayChannel', '3')

        elements = root.elementsByTagName('sld:ContrastEnhancement')
        self.assertEqual(len(elements), 1)
        enhancement = elements.at(0).toElement()
        self.assertFalse(enhancement.isNull())

        normalize = enhancement.firstChildElement('sld:Normalize')
        self.assertFalse(normalize.isNull())
        self.assertVendorOption(normalize, 'minValue', '51')
        self.assertVendorOption(normalize, 'maxValue', '172')

        elements = root.elementsByTagName('sld:ColorMap')
        self.assertEqual(len(elements), 1)
        colorMap = elements.at(0).toElement()
        self.assertFalse(colorMap.isNull())

        colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry')
        self.assertEqual(len(colorMapEntries), 4)
        clorMap1 = colorMapEntries.at(0)
        self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(),
                         '#000000')
        self.assertEqual(
            clorMap1.attributes().namedItem('quantity').nodeValue(), '100')
        self.assertEqual(
            clorMap1.attributes().namedItem('opacity').nodeValue(), '0')

        clorMap2 = colorMapEntries.at(1)
        self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(),
                         '#000000')
        self.assertEqual(
            clorMap2.attributes().namedItem('quantity').nodeValue(), '100')

        clorMap3 = colorMapEntries.at(2)
        self.assertEqual(clorMap3.attributes().namedItem('color').nodeValue(),
                         '#ffffff')
        self.assertEqual(
            clorMap3.attributes().namedItem('quantity').nodeValue(), '172')

        clorMap4 = colorMapEntries.at(3)
        self.assertEqual(clorMap4.attributes().namedItem('color').nodeValue(),
                         '#ffffff')
        self.assertEqual(
            clorMap4.attributes().namedItem('quantity').nodeValue(), '172')
        self.assertEqual(
            clorMap4.attributes().namedItem('opacity').nodeValue(), '0')

        # check when ClipToMinimumMaximum
        # then min/max have always to be the real one and not that set in the contrastEnhancement
        self.raster_layer.setContrastEnhancement(
            algorithm=QgsContrastEnhancement.ClipToMinimumMaximum,
            limits=QgsRasterMinMaxOrigin.MinMax)
        minmum = self.raster_layer.renderer().contrastEnhancement(
        ).setMinimumValue(100)
        maximum = self.raster_layer.renderer().contrastEnhancement(
        ).maximumValue()
        minmum = self.raster_layer.renderer().contrastEnhancement(
        ).minimumValue()
        self.assertEqual(minmum, 100)
        self.assertEqual(maximum, 172)

        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertNoOpacity(root)
        self.assertChannelBand(root, 'sld:GrayChannel', '3')

        elements = root.elementsByTagName('sld:ContrastEnhancement')
        self.assertEqual(len(elements), 1)
        enhancement = elements.at(0).toElement()
        self.assertFalse(enhancement.isNull())

        normalize = enhancement.firstChildElement('sld:Normalize')
        self.assertFalse(normalize.isNull())
        self.assertVendorOption(normalize, 'minValue', '51')
        self.assertVendorOption(normalize, 'maxValue', '172')

        elements = root.elementsByTagName('sld:ColorMap')
        self.assertEqual(len(elements), 1)
        colorMap = elements.at(0).toElement()
        self.assertFalse(colorMap.isNull())

        colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry')
        self.assertEqual(len(colorMapEntries), 4)
        clorMap1 = colorMapEntries.at(0)
        self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(),
                         '#000000')
        self.assertEqual(
            clorMap1.attributes().namedItem('quantity').nodeValue(), '100')
        self.assertEqual(
            clorMap1.attributes().namedItem('opacity').nodeValue(), '0')

        clorMap2 = colorMapEntries.at(1)
        self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(),
                         '#000000')
        self.assertEqual(
            clorMap2.attributes().namedItem('quantity').nodeValue(), '100')

        clorMap3 = colorMapEntries.at(2)
        self.assertEqual(clorMap3.attributes().namedItem('color').nodeValue(),
                         '#ffffff')
        self.assertEqual(
            clorMap3.attributes().namedItem('quantity').nodeValue(), '172')

        clorMap4 = colorMapEntries.at(3)
        self.assertEqual(clorMap4.attributes().namedItem('color').nodeValue(),
                         '#ffffff')
        self.assertEqual(
            clorMap4.attributes().namedItem('quantity').nodeValue(), '172')
        self.assertEqual(
            clorMap4.attributes().namedItem('opacity').nodeValue(), '0')

    def testRasterRenderer(self):
        class fakerenderer(QgsRasterRenderer):
            def __init__(self, interface):
                QgsRasterRenderer.__init__(self, interface, '')

        rasterRenderer = fakerenderer(self.raster_layer.dataProvider())
        self.raster_layer.setRenderer(rasterRenderer)

        # check opacity default value is not exported
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertNoOpacity(root)
        # check if opacity is not the default value
        rasterRenderer.setOpacity(1.1)
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertOpacity(root, '1.1')

        # check gamma properties from [-100:0] streched to [0:1]
        #  and (0:100] stretche dto (1:100]
        # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-100'})
        # self.assertGamma(root, '0')
        # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-50'})
        # self.assertGamma(root, '0.5')
        # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '0'})
        # self.assertGamma(root, '1')
        # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1'})
        # self.assertGamma(root, '1')
        # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '100'})
        # self.assertGamma(root, '100')
        # # input contrast are always integer, btw the value is managed also if it's double
        # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1.1'})
        # self.assertGamma(root, '1.1')
        # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1.6'})
        # self.assertGamma(root, '1.6')
        # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-50.5'})
        # self.assertGamma(root, '0.495')
        # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-0.1'})
        # self.assertGamma(root, '0.999')

    def testStretchingAlgorithm(self):
        rasterRenderer = QgsMultiBandColorRenderer(
            self.raster_layer.dataProvider(), 3, 1, 2)
        self.raster_layer.setRenderer(rasterRenderer)

        # check StretchToMinimumMaximum stretching alg
        self.raster_layer.setContrastEnhancement(
            algorithm=QgsContrastEnhancement.StretchToMinimumMaximum,
            limits=QgsRasterMinMaxOrigin.MinMax)
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertContrastEnhancement(root, 'sld:RedChannel',
                                       'StretchToMinimumMaximum', '51', '172')
        self.assertContrastEnhancement(root, 'sld:GreenChannel',
                                       'StretchToMinimumMaximum', '122', '130')
        self.assertContrastEnhancement(root, 'sld:BlueChannel',
                                       'StretchToMinimumMaximum', '133', '148')

        # check StretchAndClipToMinimumMaximum stretching alg
        self.raster_layer.setContrastEnhancement(
            algorithm=QgsContrastEnhancement.StretchAndClipToMinimumMaximum,
            limits=QgsRasterMinMaxOrigin.MinMax)
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertContrastEnhancement(root, 'sld:RedChannel', 'ClipToZero',
                                       '51', '172')
        self.assertContrastEnhancement(root, 'sld:GreenChannel', 'ClipToZero',
                                       '122', '130')
        self.assertContrastEnhancement(root, 'sld:BlueChannel', 'ClipToZero',
                                       '133', '148')

        # check ClipToMinimumMaximum stretching alg
        self.raster_layer.setContrastEnhancement(
            algorithm=QgsContrastEnhancement.ClipToMinimumMaximum,
            limits=QgsRasterMinMaxOrigin.MinMax)
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertContrastEnhancement(root, 'sld:RedChannel',
                                       'ClipToMinimumMaximum', '51', '172')
        self.assertContrastEnhancement(root, 'sld:GreenChannel',
                                       'ClipToMinimumMaximum', '122', '130')
        self.assertContrastEnhancement(root, 'sld:BlueChannel',
                                       'ClipToMinimumMaximum', '133', '148')

        # check NoEnhancement stretching alg
        self.raster_layer.setContrastEnhancement(
            algorithm=QgsContrastEnhancement.NoEnhancement)
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertContrastEnhancement(root, 'sld:RedChannel')
        self.assertContrastEnhancement(root, 'sld:GreenChannel')
        self.assertContrastEnhancement(root, 'sld:BlueChannel')

    def assertVendorOption(self, root, name, expectedValue):
        """Set expectedValue=None to check that the vendor option is not present."""
        vendorOptions = root.elementsByTagName('sld:VendorOption')
        found = False
        for vendorOptionIndex in range(vendorOptions.count()):
            vendorOption = vendorOptions.at(vendorOptionIndex)
            self.assertEqual('sld:VendorOption', vendorOption.nodeName())
            if (vendorOption.attributes().namedItem('name').nodeValue() == name
                ):
                found = True
                self.assertEqual(vendorOption.firstChild().nodeValue(),
                                 expectedValue)
        if (expectedValue is None) and found:
            self.fail(
                "found VendorOption: {} where supposed not present".format(
                    name))
        if expectedValue and not found:
            self.fail("Not found VendorOption: {}".format(name))

    def assertGamma(self, root, expectedValue, index=0):
        enhancement = root.elementsByTagName('sld:ContrastEnhancement').item(
            index)
        gamma = enhancement.firstChildElement('sld:GammaValue')
        self.assertEqual(expectedValue, gamma.firstChild().nodeValue())

    def assertOpacity(self, root, expectedValue, index=0):
        opacity = root.elementsByTagName('sld:Opacity').item(index)
        self.assertEqual(expectedValue, opacity.firstChild().nodeValue())

    def assertNoOpacity(self, root):
        opacities = root.elementsByTagName('sld:Opacity')
        self.assertEqual(opacities.size(), 0)

    def assertContrastEnhancement(self,
                                  root,
                                  bandTag,
                                  expectedAlg=None,
                                  expectedMin=None,
                                  expectedMax=None,
                                  index=0):
        channelSelection = root.elementsByTagName('sld:ChannelSelection').item(
            index)
        self.assertIsNotNone(channelSelection)
        band = channelSelection.firstChildElement(bandTag)
        # check if no enhancement alg is iset
        if (not expectedAlg):
            contrastEnhancementName = band.firstChildElement(
                'sld:ContrastEnhancement')
            self.assertEqual('',
                             contrastEnhancementName.firstChild().nodeName())
            return
        # check if enhancement alg is set
        contrastEnhancementName = band.firstChildElement(
            'sld:ContrastEnhancement')
        self.assertEqual('sld:Normalize',
                         contrastEnhancementName.firstChild().nodeName())
        normalize = contrastEnhancementName.firstChildElement('sld:Normalize')
        vendorOptions = normalize.elementsByTagName('VendorOption')
        for vendorOptionIndex in range(vendorOptions.count()):
            vendorOption = vendorOptions.at(vendorOptionIndex)
            self.assertEqual('VendorOption', vendorOption.nodeName())
            if (vendorOption.attributes().namedItem('name').nodeValue() ==
                    'algorithm'):
                self.assertEqual(expectedAlg,
                                 vendorOption.firstChild().nodeValue())
            elif (vendorOption.attributes().namedItem('name').nodeValue() ==
                  'minValue'):
                self.assertEqual(expectedMin,
                                 vendorOption.firstChild().nodeValue())
            elif (vendorOption.attributes().namedItem('name').nodeValue() ==
                  'maxValue'):
                self.assertEqual(expectedMax,
                                 vendorOption.firstChild().nodeValue())
            else:
                self.fail('Unrecognised vendorOption name {}'.format(
                    vendorOption.attributes().namedItem('name').nodeValue()))

    def assertChannelBand(self, root, bandTag, expectedValue, index=0):
        channelSelection = root.elementsByTagName('sld:ChannelSelection').item(
            index)
        self.assertIsNotNone(channelSelection)
        band = channelSelection.firstChildElement(bandTag)
        sourceChannelName = band.firstChildElement('sld:SourceChannelName')
        self.assertEqual(expectedValue,
                         sourceChannelName.firstChild().nodeValue())

    def rendererToSld(self, renderer, properties={}):
        dom = QDomDocument()
        root = dom.createElement("FakeRoot")
        dom.appendChild(root)
        renderer.toSld(dom, root, properties)
        return dom, root
Exemple #59
0
    def testTransparency(self):
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage

        renderer = QgsSingleBandGrayRenderer(myRasterLayer.dataProvider(), 1)
        myRasterLayer.setRenderer(renderer)
        myRasterLayer.setContrastEnhancement(
            QgsContrastEnhancement.StretchToMinimumMaximum,
            QgsRasterMinMaxOrigin.MinMax)

        myContrastEnhancement = myRasterLayer.renderer().contrastEnhancement()
        # print ("myContrastEnhancement.minimumValue = %.17g" %
        #       myContrastEnhancement.minimumValue())
        # print ("myContrastEnhancement.maximumValue = %.17g" %
        #        myContrastEnhancement.maximumValue())

        # Unfortunately the minimum/maximum values calculated in C++ and Python
        # are slightly different (e.g. 3.3999999521443642e+38 x
        # 3.3999999521444001e+38)
        # It is not clear where the precision is lost.
        # We set the same values as C++.
        myContrastEnhancement.setMinimumValue(-3.3319999287625854e+38)
        myContrastEnhancement.setMaximumValue(3.3999999521443642e+38)
        #myType = myRasterLayer.dataProvider().dataType(1);
        #myEnhancement = QgsContrastEnhancement(myType);

        myTransparentSingleValuePixelList = []
        rasterTransparency = QgsRasterTransparency()

        myTransparentPixel1 = \
            QgsRasterTransparency.TransparentSingleValuePixel()
        myTransparentPixel1.min = -2.5840000772112106e+38
        myTransparentPixel1.max = -1.0879999684602689e+38
        myTransparentPixel1.percentTransparent = 50
        myTransparentSingleValuePixelList.append(myTransparentPixel1)

        myTransparentPixel2 = \
            QgsRasterTransparency.TransparentSingleValuePixel()
        myTransparentPixel2.min = 1.359999960575336e+37
        myTransparentPixel2.max = 9.520000231087593e+37
        myTransparentPixel2.percentTransparent = 70
        myTransparentSingleValuePixelList.append(myTransparentPixel2)

        rasterTransparency.setTransparentSingleValuePixelList(
            myTransparentSingleValuePixelList)

        rasterRenderer = myRasterLayer.renderer()
        assert rasterRenderer

        rasterRenderer.setRasterTransparency(rasterTransparency)

        QgsProject.instance().addMapLayers([
            myRasterLayer,
        ])

        myMapSettings = QgsMapSettings()
        myMapSettings.setLayers([myRasterLayer])
        myMapSettings.setExtent(myRasterLayer.extent())

        myChecker = QgsRenderChecker()
        myChecker.setControlName("expected_raster_transparency")
        myChecker.setMapSettings(myMapSettings)

        myResultFlag = myChecker.runTest("raster_transparency_python")
        assert myResultFlag, "Raster transparency rendering test failed"
Exemple #60
0
    def testRelativePaths(self):
        """
        Test whether paths to layer sources are stored as relative to the project path
        """
        tmpDir = QTemporaryDir()
        tmpFile = "{}/project.qgs".format(tmpDir.path())
        copyfile(os.path.join(TEST_DATA_DIR, "points.shp"),
                 os.path.join(tmpDir.path(), "points.shp"))
        copyfile(os.path.join(TEST_DATA_DIR, "points.dbf"),
                 os.path.join(tmpDir.path(), "points.dbf"))
        copyfile(os.path.join(TEST_DATA_DIR, "points.shx"),
                 os.path.join(tmpDir.path(), "points.shx"))
        copyfile(os.path.join(TEST_DATA_DIR, "lines.shp"),
                 os.path.join(tmpDir.path(), "lines.shp"))
        copyfile(os.path.join(TEST_DATA_DIR, "lines.dbf"),
                 os.path.join(tmpDir.path(), "lines.dbf"))
        copyfile(os.path.join(TEST_DATA_DIR, "lines.shx"),
                 os.path.join(tmpDir.path(), "lines.shx"))
        copyfile(os.path.join(TEST_DATA_DIR, "landsat_4326.tif"),
                 os.path.join(tmpDir.path(), "landsat_4326.tif"))

        project = QgsProject()

        l0 = QgsVectorLayer(os.path.join(tmpDir.path(), "points.shp"),
                            "points", "ogr")
        l1 = QgsVectorLayer(os.path.join(tmpDir.path(), "lines.shp"), "lines",
                            "ogr")
        l2 = QgsRasterLayer(os.path.join(tmpDir.path(), "landsat_4326.tif"),
                            "landsat", "gdal")
        self.assertTrue(l0.isValid())
        self.assertTrue(l1.isValid())
        self.assertTrue(l2.isValid())
        self.assertTrue(project.addMapLayers([l0, l1, l2]))
        self.assertTrue(project.write(tmpFile))
        del project

        with open(tmpFile, 'r') as f:
            content = ''.join(f.readlines())
            self.assertTrue('source="./lines.shp"' in content)
            self.assertTrue('source="./points.shp"' in content)
            self.assertTrue('source="./landsat_4326.tif"' in content)

        # Re-read the project and store absolute
        project = QgsProject()
        self.assertTrue(project.read(tmpFile))
        store = project.layerStore()
        self.assertEquals(set([l.name() for l in store.mapLayers().values()]),
                          set(['lines', 'landsat', 'points']))
        project.writeEntryBool('Paths', '/Absolute', True)
        tmpFile2 = "{}/project2.qgs".format(tmpDir.path())
        self.assertTrue(project.write(tmpFile2))

        with open(tmpFile2, 'r') as f:
            content = ''.join(f.readlines())
            self.assertTrue(
                'source="{}/lines.shp"'.format(tmpDir.path()) in content)
            self.assertTrue(
                'source="{}/points.shp"'.format(tmpDir.path()) in content)
            self.assertTrue('source="{}/landsat_4326.tif"'.format(
                tmpDir.path()) in content)

        del project