Beispiel #1
0
    def testRasterScaling(self):
        """Raster layers can be scaled when resampled

        This is a test for ticket #52

        Native test .asc data has

        Population_Jakarta_geographic.asc
        ncols         638
        nrows         649
        cellsize      0.00045228819716044

        Population_2010.asc
        ncols         5525
        nrows         2050
        cellsize      0.0083333333333333

        Scaling is necessary for raster data that represents density
        such as population per km^2
        """

        for myFilename in [
                'Population_Jakarta_geographic.asc', 'Population_2010.asc'
        ]:

            myRasterPath = ('%s/%s' % (TESTDATA, myFilename))

            # Get reference values
            mySafeLayer = readSafeLayer(myRasterPath)
            myMinimum, myMaximum = mySafeLayer.get_extrema()
            del myMaximum
            del myMinimum
            myNativeResolution = mySafeLayer.get_resolution()

            # Get the Hazard extents as an array in EPSG:4326
            myBoundingBox = mySafeLayer.get_bounding_box()

            # Test for a range of resolutions
            for myResolution in [
                    0.02,
                    0.01,
                    0.005,
                    0.002,
                    0.001,
                    0.0005,  # Coarser
                    0.0002
            ]:  # Finer

                # To save time only do two resolutions for the
                # large population set
                if myFilename.startswith('Population_2010'):
                    if myResolution > 0.01 or myResolution < 0.005:
                        break

                # Clip the raster to the bbox
                myExtraKeywords = {'resolution': myNativeResolution}
                myRasterLayer = QgsRasterLayer(myRasterPath, 'xxx')
                myResult = clipLayer(myRasterLayer,
                                     myBoundingBox,
                                     myResolution,
                                     theExtraKeywords=myExtraKeywords)

                mySafeLayer = readSafeLayer(myResult)
                myNativeData = mySafeLayer.get_data(scaling=False)
                myScaledData = mySafeLayer.get_data(scaling=True)

                mySigma = (mySafeLayer.get_resolution()[0] /
                           myNativeResolution[0])**2

                # Compare extrema
                myExpectedScaledMax = mySigma * numpy.nanmax(myNativeData)
                myMessage = ('Resampled raster was not rescaled correctly: '
                             'max(myScaledData) was %f but expected %f' %
                             (numpy.nanmax(myScaledData), myExpectedScaledMax))

                # FIXME (Ole): The rtol used to be 1.0e-8 -
                #              now it has to be 1.0e-6, otherwise we get
                #              max(myScaledData) was 12083021.000000 but
                #              expected 12083020.414316
                #              Is something being rounded to the nearest
                #              integer?
                assert numpy.allclose(myExpectedScaledMax,
                                      numpy.nanmax(myScaledData),
                                      rtol=1.0e-6,
                                      atol=1.0e-8), myMessage

                myExpectedScaledMin = mySigma * numpy.nanmin(myNativeData)
                myMessage = ('Resampled raster was not rescaled correctly: '
                             'min(myScaledData) was %f but expected %f' %
                             (numpy.nanmin(myScaledData), myExpectedScaledMin))
                assert numpy.allclose(myExpectedScaledMin,
                                      numpy.nanmin(myScaledData),
                                      rtol=1.0e-8,
                                      atol=1.0e-12), myMessage

                # Compare elementwise
                myMessage = 'Resampled raster was not rescaled correctly'
                assert nanallclose(myNativeData * mySigma,
                                   myScaledData,
                                   rtol=1.0e-8,
                                   atol=1.0e-8), myMessage

                # Check that it also works with manual scaling
                myManualData = mySafeLayer.get_data(scaling=mySigma)
                myMessage = 'Resampled raster was not rescaled correctly'
                assert nanallclose(myManualData,
                                   myScaledData,
                                   rtol=1.0e-8,
                                   atol=1.0e-8), myMessage

                # Check that an exception is raised for bad arguments
                try:
                    mySafeLayer.get_data(scaling='bad')
                except GetDataError:
                    pass
                else:
                    myMessage = 'String argument should have raised exception'
                    raise Exception(myMessage)

                try:
                    mySafeLayer.get_data(scaling='(1, 3)')
                except GetDataError:
                    pass
                else:
                    myMessage = 'Tuple argument should have raised exception'
                    raise Exception(myMessage)

                # Check None option without keyword datatype == 'density'
                mySafeLayer.keywords['datatype'] = 'undefined'
                myUnscaledData = mySafeLayer.get_data(scaling=None)
                myMessage = 'Data should not have changed'
                assert nanallclose(myNativeData,
                                   myUnscaledData,
                                   rtol=1.0e-12,
                                   atol=1.0e-12), myMessage

                # Try with None and density keyword
                mySafeLayer.keywords['datatype'] = 'density'
                myUnscaledData = mySafeLayer.get_data(scaling=None)
                myMessage = 'Resampled raster was not rescaled correctly'
                assert nanallclose(myScaledData,
                                   myUnscaledData,
                                   rtol=1.0e-12,
                                   atol=1.0e-12), myMessage

                mySafeLayer.keywords['datatype'] = 'counts'
                myUnscaledData = mySafeLayer.get_data(scaling=None)
                myMessage = 'Data should not have changed'
                assert nanallclose(myNativeData,
                                   myUnscaledData,
                                   rtol=1.0e-12,
                                   atol=1.0e-12), myMessage
    for f in layer.getFeatures():

        col_select =str(f[Champ_code_INSEE]),f[Champ_nom_de_commune]
        tab.append(col_select)

        #Permet la suppression des doublons
        Lt= list(set(tab))
        Lt.sort()

    for c_insee, n_couche in Lt  :

        #AMORCES_CAD,LIEUDIT,CP.CadastralParcel,SUBFISCAL,CLOTURE,DETAIL_TOPO,HYDRO,VOIE_COMMUNICATION,BU.Building,BORNE_REPERE
        urlWithParams = "url=http://inspire.cadastre.gouv.fr/scpc/"+c_insee+".wms?contextualWMSLegend=0&crs=EPSG:"+Code_EPSG+"&dpiMode=7&featureCount=10&format=image/png&layers=BU.Building&styles=&maxHeight=1024&maxWidth=1280"

        rlayer = QgsRasterLayer(urlWithParams, 'Batiments_'+n_couche+'_'+c_insee, 'wms')

        progress.setText(u'Nom de la commune : ' + n_couche+' - '+c_insee)
        progress.setText(u'Validite du flux : %s' % rlayer.isValid())

        QgsMapLayerRegistry.instance().addMapLayer(rlayer)

        if  rlayer.isValid() == True :
            iface.messageBar().pushMessage("Information :", "Ajout du flux WMS pour la commune : "+n_couche, QgsMessageBar.INFO, duration=5)
            iface.mapCanvas().refresh()

        else :
            iface.messageBar().pushMessage("Warning :", "WMS invalide pour la commune : "+n_couche, QgsMessageBar.WARNING, duration=15)

else :
    iface.messageBar().pushMessage("Warning :", "EPSG inconnu", QgsMessageBar.WARNING, duration=15)
Beispiel #3
0
    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)
Beispiel #4
0
    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())
Beispiel #5
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
Beispiel #6
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """
        # Retrieve parameters from the gui
        OUTPUTFOLDER = self.parameterAsFile(parameters,
                                            self.FLOOD_DEPTH_OUTPUT, context)

        if parameters["FLOOD_DEPTH_OUTPUT"] == "TEMPORARY_OUTPUT":
            OUTPUTFOLDER = os.path.dirname(OUTPUTFOLDER)

        DEM = self.parameterAsRasterLayer(parameters, self.DEM_INPUT,
                                          context).source()
        INUNDPOLYGON = self.parameterAsVectorLayer(parameters,
                                                   self.FLOOD_POLYGON_INPUT,
                                                   context).source()

        # feedback.pushInfo('The output directory is {}'.format(self.parameterAsFile(
        # parameters, self.FLOOD_DEPTH_OUTPUT, context)))
        feedback.pushInfo(DEM)

        # Raster specifications that are needed by JSON inputs
        # Load the DEM to extract the layer extent and pixel size
        demLayer = QgsRasterLayer(DEM, 'dem_extent')
        inundpolygonLayer = QgsVectorLayer(INUNDPOLYGON, 'indund_extent')

        # Extract the DEM extent in a float format.
        demExtent = self.floatDemExtent(demLayer)
        inundpolygonExtent = self.floatDemExtent(inundpolygonLayer)

        # It is assumed that the unit per pixel size for the X direction is the same for the Y direction
        demSize = demLayer.rasterUnitsPerPixelX()
        # End raster specifications that are needed by JSON inputs

        # JSON input setup
        clip_input = {
            "INPUT": DEM,
            "OUTPUT":
            os.path.join(OUTPUTFOLDER,
                         'clippingMask.sdat'),  # this will need to change
            "POLYGONS": INUNDPOLYGON
        }

        polygons_to_lines_input = {
            "LINES": os.path.join(OUTPUTFOLDER, 'polyline.shp'),
            "POLYGONS": INUNDPOLYGON
        }

        rasterize_input = {
            'INPUT': os.path.join(OUTPUTFOLDER, 'polyline.shp'),
            'FIELD': None,
            'BURN': 1,
            'UNITS': 1,
            # width and height should match that of the cell size of the DEM input
            'WIDTH': demSize,
            'HEIGHT': demSize,
            # the extent of the area must be given in a comma seperated list
            # ending with an uncommaed CRS within e.g. [EPSG:26712]
            'EXTENT': inundpolygonExtent,
            'NODATA': 0,
            'OPTIONS': '',
            'DATA_TYPE': 0,
            'INIT': 0,
            'INVERT': False,
            'OUTPUT': os.path.join(OUTPUTFOLDER, 'rasterLine.tif')
        }

        grow_distance_input = {
            'input': os.path.join(OUTPUTFOLDER, 'extractElevation.tif'),
            # euclidean distance
            'metric': 0,
            '-m': False,
            '-': False,
            'distance': os.path.join(OUTPUTFOLDER, 'scratch.tif'),
            'value': os.path.join(OUTPUTFOLDER, 'growDistance.tif'),
            'GRASS_REGION_PARAMETER': demExtent,
            'GRASS_REGION_CELLSIZE_PARAMETER': 0,
            'GRASS_RASTER_FORMAT_OPT': '',
            'GRASS_RASTER_FORMAT_META': ''
        }

        gaussian_filter_input = {
            'INPUT': os.path.join(OUTPUTFOLDER, 'waterDepth.tif'),
            'MODE': 0,
            'RADIUS': 3,
            'RESULT': os.path.join(OUTPUTFOLDER, 'waterDepthFiltered.sdat'),
            'SIGMA': 1
        }

        # End json input setup

        # create a clipping mask from the DEM to later be used to subtract from the calculated gross waterdepth
        processing.run("saga:cliprasterwithpolygon",
                       clip_input,
                       context=context,
                       feedback=feedback)

        feedback.setProgress(12)

        # convert floodextent to polyline outline
        POLYLINE = processing.run("saga:convertpolygonstolines",
                                  polygons_to_lines_input,
                                  context=context,
                                  feedback=feedback)['LINES']

        feedback.setProgress(24)

        polyLineExtent = self.floatDemExtent(
            QgsVectorLayer(POLYLINE, 'line_extent', 'ogr'))

        feedback.setProgress(36)

        # convert the above polyline to a raster line so that raster opperations may be preformed
        processing.run("gdal:rasterize",
                       rasterize_input,
                       context=context,
                       feedback=feedback)

        feedback.setProgress(48)

        # associate underlying DEM values to rasterized line
        extractElevation = self.rasterCalculator(
            [rasterize_input['OUTPUT'], DEM], '({0} * {1}) / {0}', 0,
            'extractElevation.tif')

        feedback.setProgress(60)

        processing.run("grass7:r.grow.distance",
                       grow_distance_input,
                       context=context,
                       feedback=feedback)

        feedback.setProgress(72)

        # clip grow distance output using clipDEM
        waterDepth = self.rasterCalculator(
            [clip_input['OUTPUT'], grow_distance_input['value']],
            '(({1} - {0}) > 0) * ({1} - {0})',
            0,
            fname='waterDepth.tif')
        feedback.setProgress(84)

        # filter inputs will need to change once gaussianfilter wrapper is updated to saga >= 4
        processing.run("saga:gaussianfilter",
                       gaussian_filter_input,
                       context=context,
                       feedback=feedback)

        feedback.setProgress(100)

        return {
            'OUTPUT': os.path.join(OUTPUTFOLDER, 'waterDepthFiltered.sdat')
        }
Beispiel #7
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')
Beispiel #8
0
 def __input_raster_layer():
     options = QgsRasterLayer.LayerOptions()
     options.loadDefaultStyle = False
     return QgsRasterLayer(
         os.path.join(AlgorithmsTestBase.processingTestDataPath(),
                      'raster.tif'), "raster_input", 'gdal', options)
Beispiel #9
0
    def test_clip_both(self):
        """Raster and Vector layers can be clipped."""

        # Create a vector layer
        layer_name = 'padang'
        vector_layer = QgsVectorLayer(VECTOR_PATH, layer_name, 'ogr')
        message = ('Did not find layer "%s" in path "%s"' %
                   (layer_name, VECTOR_PATH))
        assert vector_layer.isValid(), message

        # 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.isValid(), message

        # Create a bounding box
        view_port_geo_extent = [99.53, -1.22, 101.20, -0.36]

        # Get the Hazard extents as an array in EPSG:4326
        hazard_geo_extent = [
            raster_layer.extent().xMinimum(),
            raster_layer.extent().yMinimum(),
            raster_layer.extent().xMaximum(),
            raster_layer.extent().yMaximum()
        ]

        # Get the Exposure extents as an array in EPSG:4326
        exposure_geo_extent = [
            vector_layer.extent().xMinimum(),
            vector_layer.extent().yMinimum(),
            vector_layer.extent().xMaximum(),
            vector_layer.extent().yMaximum()
        ]

        # Now work out the optimal extent between the two layers and
        # the current view extent. The optimal extent is the intersection
        # between the two layers and the viewport.
        # Extent is returned as an array [xmin,ymin,xmax,ymax]
        geo_extent = get_optimal_extent(hazard_geo_extent, exposure_geo_extent,
                                        view_port_geo_extent)

        # Clip the vector to the bbox
        result = clip_layer(vector_layer, geo_extent)

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

        # Clip the raster to the bbox
        result = clip_layer(raster_layer, geo_extent)

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

        # -------------------------------
        # Check the extra keywords option
        # -------------------------------
        # Clip the vector to the bbox
        result = clip_layer(vector_layer,
                            geo_extent,
                            extra_keywords={'kermit': 'piggy'})

        # Check the output is valid
        assert os.path.exists(result.source())
        safe_layer = read_safe_layer(result.source())
        keywords = safe_layer.get_keywords()
        # message = 'Extra keyword was not found in %s: %s' % (myResult,
        # keywords)
        assert keywords['kermit'] == 'piggy'

        # Clip the raster to the bbox
        result = clip_layer(raster_layer,
                            geo_extent,
                            extra_keywords={'zoot': 'animal'})

        # Check the output is valid
        assert os.path.exists(result.source())
        safe_layer = read_safe_layer(result.source())
        keywords = safe_layer.get_keywords()

        message = ('Extra keyword was not found in %s: %s' %
                   (result.source(), keywords))
        assert keywords['zoot'] == 'animal', message
    for f in layer.getFeatures():

        col_select = str(f[Champ_code_INSEE]), f[Champ_nom_de_commune]
        tab.append(col_select)

        #Permet la suppression des doublons
        Lt = list(set(tab))
        Lt.sort()

    for c_insee, n_couche in Lt:

        #AMORCES_CAD,LIEUDIT,CP.CadastralParcel,SUBFISCAL,CLOTURE,DETAIL_TOPO,HYDRO,VOIE_COMMUNICATION,BU.Building,BORNE_REPERE
        urlWithParams = "url=http://inspire.cadastre.gouv.fr/scpc/" + c_insee + ".wms?contextualWMSLegend=0&crs=EPSG:" + Code_EPSG + "&dpiMode=7&featureCount=10&format=image/png&layers=DETAIL_TOPO&styles=&maxHeight=1024&maxWidth=1280"

        rlayer = QgsRasterLayer(
            urlWithParams,
            'Details_topographiques_' + n_couche + '_' + c_insee, 'wms')

        progress.setText(u'Nom de la commune : ' + n_couche + ' - ' + c_insee)
        progress.setText(u'Validite du flux : %s' % rlayer.isValid())

        QgsMapLayerRegistry.instance().addMapLayer(rlayer)

        if rlayer.isValid() == True:
            iface.messageBar().pushMessage(
                "Information :",
                "Ajout du flux WMS pour la commune : " + n_couche,
                QgsMessageBar.INFO,
                duration=5)
            iface.mapCanvas().refresh()
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """
        log = feedback.setProgressText

        input_raster = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)

        # Check that the input raster has been loaded correctly
        if not input_raster.isValid():
            error_message = "Layer failed to load."
            feedback.reportError(error_message)
            return {'error': error_message}

        # Check that the input raster is in the right CRS
        input_raster_crs = input_raster.crs().authid()
        if input_raster_crs == "EPSG:102003":
            log("The input raster is in the right CRS: EPSG:102003. Check")
        else:
            error_message = "The input raster isn't in the right CRS. It must be in EPSG:102003. The one you input was in " + str(input_raster_crs) + "."
            feedback.reportError(error_message)
            log("")
            return {'error': error_message}

        # Check that the input raster has the right pixel size
        units_per_pixel_x = input_raster.rasterUnitsPerPixelX()
        units_per_pixel_y = input_raster.rasterUnitsPerPixelY()
        if units_per_pixel_x != 30 or units_per_pixel_y != 30:
            if round(units_per_pixel_x) == 30 and round(units_per_pixel_y) == 30:
                feedback.pushDebugInfo("Your input raster pixels weren't exactly 30x30 meters, but were close enough that the program will continue to run. Your input raster pixels were " + str(units_per_pixel_x) + "x" + str(units_per_pixel_y) + ".")
            else:
                error_message = "The input raster should have 30x30 meter pixels. The one you input has " + str(units_per_pixel_x) + "x" + str(units_per_pixel_y) + "."
                feedback.reportError(error_message)
                log("")
                return {'error': error_message}
        else:
            log("The input raster's pixel size is correct: 30x30. Check")

        input_vector = self.parameterAsVectorLayer(parameters, self.MASK_LAYER, context)

        # Check that the input vector is in the right CRS
        input_vector_crs = input_vector.crs().authid()
        if input_vector_crs == "EPSG:102003":
            log("The input mask layer is in the right CRS: EPSG:102003. Check")
        else:
            error_message = "The input mask layer isn't in the right CRS. It must be in EPSG:102003. The one you input was in " + str(input_vector_crs) + "."
            feedback.reportError(error_message)
            log("")
            return {'error': error_message}

        # Get the input table of esv research data into a list of lists so we can work with it
        input_esv_index = self.parameterAsEnum(parameters, self.INPUT_ESV, context)
        input_esv_file = self.ESV_CSVS[input_esv_index]
        input_esv_table = []
        with open(os.path.join(__esv_data_location__, input_esv_file), newline='') as f:
            reader = csv.reader(f)
            for row in reader:
                input_esv_table.append(row)

        # Check to make sure the input table of esv research data has 6 columns
        if len(input_esv_table[0]) != 6:
            error_message = "The Input table of ESV research data should have 6 columns, the one you input has " + str(len(input_esv_table[0]))
            feedback.reportError(error_message)
            log("")
            return {'error': error_message}
        else:
            log("Input table of ESV research data has 6 columns. Check")

        # Check to make sure the input table of esv research data has NLCD codes in its first column
        input_esv_table_column_1_values = [row[0] for row in input_esv_table]
        nlcd_codes = ['11', '21', '22', '23', '24', '31', '41', '42', '43', '52', '71', '81', '82', '90', '95']
        if all(str(i) in nlcd_codes for i in input_esv_table_column_1_values[1:]):
            log("The input input table of esv research data has the correct NLCD codes in the first column. Check")
        else:
            error_message = "The first column of the input table of esv research data isn't all legitimate NLCD codes. They must all be one of these values: " + str(nlcd_codes) + ". The table you input had these values: " + str(input_esv_table_column_1_values[1:])
            feedback.reportError(error_message)
            log("")
            return {'error': error_message}

        # Append input raster and input vector filenames to end of output clipped raster filename
        if isinstance(parameters['CLIPPED_RASTER'], QgsProcessingOutputLayerDefinition):
            dest_name = input_raster.name() + "-CLIPPED_BY-" + input_vector.name()
            setattr(parameters['CLIPPED_RASTER'], 'destinationName', dest_name)
        elif isinstance(parameters['CLIPPED_RASTER'], str):  # for some reason when running this as part of a model parameters['OUTPUT_ESV_TABLE'] isn't a QgsProcessingOutputLayerDefinition object, but instead is just a string
            if parameters['CLIPPED_RASTER'][0:7] == "memory:":
                parameters['CLIPPED_RASTER'] = input_raster.name() + "-CLIPPED_BY-" + input_vector.name()

        clipped_raster_destination = self.parameterAsOutputLayer(parameters, self.CLIPPED_RASTER, context)

        # Clip the input raster by the input mask layer (vector)
        log("Clipping raster...")
        processing.run("gdal:cliprasterbymasklayer", {'INPUT': input_raster, 'MASK': input_vector.source(), 'ALPHA_BAND': False, 'CROP_TO_CUTLINE': True, 'KEEP_RESOLUTION': False, 'DATA_TYPE': 0, 'OUTPUT': clipped_raster_destination}, context=context, feedback=feedback)
        log("Done clipping raster.")

        # Summarize the raster, i.e. calculate the pixel counts and total area for each NLCD value
        log("Summarizing raster...")
        html_output_path = self.parameterAsFileOutput(parameters, self.HTML_OUTPUT_PATH, context)
        clipped_raster = QgsRasterLayer(clipped_raster_destination)
        processing.run("native:rasterlayeruniquevaluesreport", {'INPUT': clipped_raster, 'BAND': 1, 'OUTPUT_HTML_FILE': html_output_path}, context=context, feedback=feedback)
        log("Done summarizing raster.")

        log("Calculating ecosystem service values for clipped raster...")
        # Process html output of rasterlayeruniquevaluesreport algorithm into a table so we can do stuff with it
        input_html = open(html_output_path, 'r', encoding='latin1')
        input_html_string = input_html.read()
        # Instantiate the parser and then parse the table elements into a python list of lists
        p = HTMLTableParser()
        p.feed(input_html_string)
        raster_summary_table = p.tables[0]
        del raster_summary_table[0]  # Delete the header row

        # Check to make sure the input raster is an NLCD raster, i.e. has the right kinds of pixel values
        raster_summary_table_column_1_values = [row[0] for row in raster_summary_table]
        if all(str(i) in nlcd_codes for i in raster_summary_table_column_1_values):
            log("The input raster has the correct NLCD codes for pixel values. Check")
        else:
            error_message = "The input raster's pixels aren't all legitimate NLCD codes. They must all be one of these values: " + str(nlcd_codes) + ". The raster you input had these values: " + str(raster_summary_table_column_1_values)
            feedback.reportError(error_message)
            log("")
            return {'error': error_message}

        # Create list of fields (i.e. column names) for the output esv table
        output_esv_table_fields = QgsFields()
        output_esv_table_fields.append(QgsField("nlcd_code"))
        output_esv_table_fields.append(QgsField("nlcd_description"))
        output_esv_table_fields.append(QgsField("pixel_count"))
        output_esv_table_fields.append(QgsField("area_m2"))
        # Create fields for the min, max, and mean of each unique
        # ecosystem service (i.e. water, recreation, etc)
        unique_eco_services = set([row[2] for row in input_esv_table[1:]])
        for eco_service in unique_eco_services:
            min_field_str = eco_service.lower().replace(" ", "-").replace(",", "") + "_" + "min"
            mean_field_str = eco_service.lower().replace(" ", "-").replace(",", "") + "_" + "mean"
            max_field_str = eco_service.lower().replace(" ", "-").replace(",", "") + "_" + "max"
            output_esv_table_fields.append(QgsField(min_field_str))
            output_esv_table_fields.append(QgsField(mean_field_str))
            output_esv_table_fields.append(QgsField(max_field_str))
        # Then append three more columns for the totals
        output_esv_table_fields.append(QgsField("total_min"))
        output_esv_table_fields.append(QgsField("total_mean"))
        output_esv_table_fields.append(QgsField("total_max"))
        log("Failing after line 269")

        # Append input raster filename to end of output esv table filename
        if isinstance(parameters['OUTPUT_ESV_TABLE'], QgsProcessingOutputLayerDefinition):
            dest_name = self.OUTPUT_ESV_TABLE_FILENAME_DEFAULT.replace(" ", "_") + "-" + input_esv_file.split(".")[0] + "-" + parameters['CLIPPED_RASTER'].destinationName
            setattr(parameters['OUTPUT_ESV_TABLE'], 'destinationName', dest_name)
        elif isinstance(parameters['OUTPUT_ESV_TABLE'], str):  # for some reason when running this as part of a model parameters['OUTPUT_ESV_TABLE'] isn't a QgsProcessingOutputLayerDefinition object, but instead is just a string
            if parameters['OUTPUT_ESV_TABLE'][0:7] == "memory:":
                parameters['OUTPUT_ESV_TABLE'] = parameters['OUTPUT_ESV_TABLE'].replace(" ", "_") + "-" + input_esv_file.split(".")[0] + "-" + parameters['CLIPPED_RASTER'].destinationName

        # Create the feature sink for the output esv table, i.e. the place where we're going to start
        # putting our output data. The 'dest_id' variable is used
        # to uniquely identify the feature sink, and must be included in the
        # dictionary returned by the processAlgorithm function.
        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_ESV_TABLE, context, output_esv_table_fields)

        result = {self.CLIPPED_RASTER: clipped_raster_destination,
                  self.OUTPUT_ESV_TABLE: dest_id}

        # Compute the number of steps to display within the progress bar
        total = 100.0 / len(raster_summary_table) if len(raster_summary_table) else 0

        area_units_conversion_factor = 0.0001  # Going from meters squared to hectares

        # Populate the output table (feature sink) with values
        for raster_summary_current, raster_summary_row in enumerate(raster_summary_table):
            # Stop the algorithm if cancel button has been clicked
            if feedback.isCanceled():
                break

            nlcd_code = raster_summary_row[0]
            pixel_count = raster_summary_row[1]
            area = raster_summary_row[2]

            new_feature = QgsFeature(output_esv_table_fields)
            new_feature.setAttribute(0, nlcd_code)
            new_feature.setAttribute(2, pixel_count)
            new_feature.setAttribute(3, area)

            total_min = 0
            total_mean = 0
            total_max = 0

            for row in input_esv_table:
                if row[0] == nlcd_code:
                    new_feature.setAttribute(1, row[1])  # Set the value of the second column in the output table, the nlcd description
                    input_es_name = row[2].lower().replace(" ", "-")
                    for field_index in output_esv_table_fields.allAttributesList():
                        output_es = output_esv_table_fields.field(field_index).name().split("_")
                        output_es_name = output_es[0].lower()
                        if len(output_es) > 1:
                            output_es_stat = output_es[1].lower()
                            if input_es_name == output_es_name:
                                if output_es_stat == "min":
                                    nlcd_es_min = float(row[3].replace(',', '').replace('$', ''))*float(area)*float(area_units_conversion_factor)
                                    new_feature.setAttribute(field_index, '${:,.0f}'.format(nlcd_es_min))
                                    total_min = total_min + nlcd_es_min
                                elif output_es_stat == "mean":
                                    nlcd_es_mean = float(row[4].replace(',', '').replace('$', ''))*float(area)*float(area_units_conversion_factor)
                                    new_feature.setAttribute(field_index, '${:,.0f}'.format(nlcd_es_mean))
                                    total_mean = total_mean + nlcd_es_mean
                                elif output_es_stat == "max":
                                    nlcd_es_max = float(row[5].replace(',', '').replace('$', ''))*float(area)*float(area_units_conversion_factor)
                                    new_feature.setAttribute(field_index, '${:,.0f}'.format(nlcd_es_max))
                                    total_max = total_max + nlcd_es_max
                            elif output_es_name == "total":
                                if output_es_stat == "min":
                                    new_feature.setAttribute(field_index, '${:,.0f}'.format(total_min))
                                elif output_es_stat == "mean":
                                    new_feature.setAttribute(field_index, '${:,.0f}'.format(total_mean))
                                elif output_es_stat == "max":
                                    new_feature.setAttribute(field_index, '${:,.0f}'.format(total_max))

            # Add the feature to the sink
            sink.addFeature(new_feature, QgsFeatureSink.FastInsert)

            # Update the progress bar
            feedback.setProgress(int(raster_summary_current * total))
        log("Done calculating ecosystem service values for clipped raster.")

        # Return the results of the algorithm, which includes the clipped raster
        # and the output esv table
        return result
    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        #feedback = QgsProcessingMultiStepFeedback(2, model_feedback)
        results = {}
        outputs = {}

        download_service = self.services[parameters['Product collection']]
        
        #STEP1
        alg_params = {
            'URL': 'https://land.copernicus.vgt.vito.be/manifest/%s' % download_service,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        output = processing.run('native:filedownloader', alg_params)
        dfs = pandas.read_html(output['OUTPUT'])
        df = dfs[0]
        for index,row in df.iterrows():
            if not pandas.isna(row[1]) and row[1].startswith('manifest'):
                manifest_url = row[1]
        
        #STEP2
        url = 'https://land.copernicus.vgt.vito.be/manifest/%s/%s' % (download_service, manifest_url)
        alg_params = {
            'URL': url,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        output = processing.run('native:filedownloader', alg_params)
        log = []
        max_delta = timedelta.max.total_seconds()
        target = None
        td = datetime.strptime( parameters['Select the day'], '%Y-%m-%dT%H:%M:%S' )
        with open(output['OUTPUT'], 'r') as t:
            for line in t.readlines():
                r = re.findall(r"((\/)\d\d\d\d(\/)\d\d(\/)\d\d(\/))",line)
                match = r[0][0]
                ud = datetime.strptime(match, "/%Y/%m/%d/")
                log.append({
                    "url": line.replace("\n",''),
                    "date": ud
                })
                dd = td - ud
                if abs(dd.total_seconds()) < max_delta:
                    max_delta = abs(dd.total_seconds())
                    target = line.replace("\n",'')
                    
        #STEP3
        u = urlparse(target)
        filepath, filename = os.path.split(u.path)
        target_dir = self.parameterAsFile(parameters, 'Download directory', context).replace("/Download directory",'')
        
        #target_file = self.parameterAsFile(parameters, 'Download directory', context)
        #print ("target_file",target_file)
        
        #if not target_file:
        target_file = os.path.join(target_dir, filename)
        
        print ("target_dir",target_dir)
        alg_params = {
            'URL': target,
            'OUTPUT': target_file
        }
        print (alg_params)
        outputs['file'] = processing.run('native:filedownloader', alg_params, context=context, feedback=model_feedback, is_child_algorithm=True)
        input_nc_source = outputs['file']['OUTPUT']
        print ("NETCDF source",input_nc_source)
        nc_source = gdal.Open('NETCDF:"%s"' % input_nc_source)
        nc_info = gdal.Info(nc_source)
        nc_rex = re.compile('":.+SUBDATASET_1_DESC', re.MULTILINE|re.DOTALL)
        first_subds_match = nc_rex.search(nc_info)
        if first_subds_match:
            first_subds_name = first_subds_match.group(0).split("  ")[0][2:-1]
            print ("FIRST SUBDATASET NAME", first_subds_name)
            
            uri='NETCDF:"%s":%s' % (input_nc_source, first_subds_name)
        else:
            first_subds_name = ""
            uri=input_nc_source
        input_raster = QgsRasterLayer(uri,download_service)

        #print(input_raster.dataProvider().bandStatistics(1).minimumValue)
        
        output_tiff = target_file+".tif"
        
        '''
        translateoptions = gdal.TranslateOptions(gdal.ParseCommandLine("-if netCDF -of Gtiff"))
        try:
            res = gdal.Translate(output_raster, input_nc_source+":"+first_subds_name, options=translateoptions)
            return {'OUTPUT': output_raster, 'INPUT': input_nc_source+":"+first_subds_name, 'ERROR': ''}
        except Exception as e: 
            return {'OUTPUT': '', 'INPUT': input_nc_source+":"+first_subds_name, 'ERROR': e}
            
        '''
                
        # Xmin = -180 + ((1 / 112) / 2)
        # Xmax = 180 - ((1 / 112) / 2)
        # Ymax = 80 - ((1 / 112) / 2)
        # Ymin = -60 + ((1 / 112) / 2)

        # pixelX= 1./112.
        # pixelY= 1./112.

        # stats= input_raster.dataProvider().bandStatistics(1)

        # src_min= stats.minimumValue
        # src_max= stats.maximumValue
        # dst_min= stats.minimumValue
        # dst_max= stats.maximumValue

        # print (src_min, src_max, dst_min, dst_max)


        tra_extra = "-of Gtiff -co COMPRESS=DEFLATE -co PREDICTOR=2 -co ZLEVEL=9 "
        #tra_extra += " -projwin " + str(Xmin) + " " + str(Ymax) + " " + str(Xmax) + " " + str(Ymin)
        #tra_extra += " -r average -tr " + str(pixelX) + " " + str(pixelY)
        #tra_extra += " -scale " + str(src_min) + " " + str(src_max) + " " + str(dst_min) + " " + str(dst_max)


        alg_params = {
            'INPUT': input_raster,
            'EXTRA': tra_extra,
            'OUTPUT': output_tiff
        }
        print ("params",alg_params)
        outputs['translate'] = processing.run('gdal:translate', alg_params, context=context, feedback=model_feedback, is_child_algorithm=True)
        return {'Download file': outputs['translate']['OUTPUT'],  "RESOURCE": target}
Beispiel #13
0
osm_lbls = (
    "contextualWMSLegend=0&crs=EPSG:4326&dpiMode=7&featureCount=10&format=image/png&layers"
    "=Reference_Labels&styles=default&tileMatrixSet=250m&url=https://gibs.earthdata.nasa.gov/wmts"
    "/epsg4326/best/1.0.0/WMTSCapabilities.xml")
osm_refs = (
    "contextualWMSLegend=0&crs=EPSG:4326&dpiMode=7&featureCount=10&format=image/png&layers"
    "=Reference_Features&styles=default&tileMatrixSet=250m&url=https://gibs.earthdata.nasa.gov/wm"
    "ts/epsg4326/best/1.0.0/WMTSCapabilities.xml")
blue_marble = (
    "contextualWMSLegend=0&crs=EPSG:4326&dpiMode=7&featureCount=10&format=image/jpeg&la"
    "yers=BlueMarble_ShadedRelief_Bathymetry&styles=default&tileMatrixSet=500m&url=https://gibs.e"
    "arthdata.nasa.gov/wmts/epsg4326/best/1.0.0/WMTSCapabilities.xml")

li_lyrs_refs = [
    QgsRasterLayer(osm_lbls, "Labels", "wms"),
    QgsRasterLayer(osm_refs, "Refs", "wms"),
    QgsRasterLayer(blue_marble, "Base", "wms"),
]

# ############################################################################
# ########## Classes ###############
# ##################################


class MetadataDisplayer:
    """Manage metadata displaying in QGIS UI."""

    url_edition = "https://app.isogeo.com"

    def __init__(self):
Beispiel #14
0
 def createLayer(self, layerPath, layerBaseName):
     """ Create a raster layer """
     return QgsRasterLayer(layerPath, layerBaseName)
Beispiel #15
0
def _clip_raster_layer(
        theLayer, theExtent, theCellSize=None, theExtraKeywords=None):
    """Clip a Hazard or Exposure raster layer to the extents provided.

    The layer must be a raster layer or an exception will be thrown.

    .. note:: The extent *must* be in EPSG:4326.

    The output layer will always be in WGS84/Geographic.

    :param theLayer: A valid QGIS raster layer in EPSG:4326
    :type theLayer: QgsRasterLayer

    :param theExtent:  An array representing the exposure layer
           extents in the form [xmin, ymin, xmax, ymax]. It is assumed
           that the coordinates are in EPSG:4326 although currently
           no checks are made to enforce this.
           or:
           A QgsGeometry of type polygon.
           **Polygon clipping currently only supported for vector datasets.**
    :type theExtent: list(float), QgsGeometry

    :param theCellSize: Cell size (in GeoCRS) which the layer should
            be resampled to. If not provided for a raster layer (i.e.
            theCellSize=None), the native raster cell size will be used.
    :type theCellSize: float

    :returns: Output clipped layer (placed in the system temp dir).
    :rtype: QgsRasterLayer

    :raises: InvalidProjectionError - if input layer is a density
        layer in projected coordinates. See issue #123.

    """
    if not theLayer or not theExtent:
        myMessage = tr('Layer or Extent passed to clip is None.')
        raise InvalidParameterError(myMessage)

    if theLayer.type() != QgsMapLayer.RasterLayer:
        myMessage = tr(
            'Expected a raster layer but received a %s.' %
            str(theLayer.type()))
        raise InvalidParameterError(myMessage)

    myWorkingLayer = str(theLayer.source())

    # Check for existence of keywords file
    myKeywordsPath = myWorkingLayer[:-4] + '.keywords'
    myMessage = tr(
        'Input file to be clipped "%s" does not have the '
        'expected keywords file %s' % (
            myWorkingLayer, myKeywordsPath))
    verify(os.path.isfile(myKeywordsPath), myMessage)

    # Raise exception if layer is projected and refers to density (issue #123)
    # FIXME (Ole): Need to deal with it - e.g. by automatically reprojecting
    # the layer at this point and setting the native resolution accordingly
    # in its keywords.
    myKeywords = readKeywordsFromFile(myKeywordsPath)
    if 'datatype' in myKeywords and myKeywords['datatype'] == 'density':
        if str(theLayer.crs().authid()) != 'EPSG:4326':

            # This layer is not WGS84 geographic
            myMessage = ('Layer %s represents density but has spatial '
                         'reference "%s". Density layers must be given in '
                         'WGS84 geographic coordinates, so please reproject '
                         'and try again. For more information, see issue '
                         'https://github.com/AIFDR/inasafe/issues/123'
                         % (myWorkingLayer, theLayer.crs().toProj4()))
            raise InvalidProjectionError(myMessage)

    # We need to provide gdalwarp with a dataset for the clip
    # because unline gdal_translate, it does not take projwin.
    myClipKml = extent_to_kml(theExtent)

    # Create a filename for the clipped, resampled and reprojected layer
    myHandle, myFilename = tempfile.mkstemp('.tif', 'clip_',
                                            temp_dir())
    os.close(myHandle)
    os.remove(myFilename)

    # If no cell size is specified, we need to run gdalwarp without
    # specifying the output pixel size to ensure the raster dims
    # remain consistent.
    myBinaryList = which('gdalwarp')
    LOGGER.debug('Path for gdalwarp: %s' % myBinaryList)
    if len(myBinaryList) < 1:
        raise CallGDALError(
            tr('gdalwarp could not be found on your computer'))
    # Use the first matching gdalwarp found
    myBinary = myBinaryList[0]
    if theCellSize is None:
        myCommand = ('%s -q -t_srs EPSG:4326 -r near '
                     '-cutline %s -crop_to_cutline -of GTiff '
                     '"%s" "%s"' % (myBinary,
                                    myClipKml,
                                    myWorkingLayer,
                                    myFilename))
    else:
        myCommand = ('%s -q -t_srs EPSG:4326 -r near -tr %f %f '
                     '-cutline %s -crop_to_cutline -of GTiff '
                     '"%s" "%s"' % (myBinary,
                                    theCellSize,
                                    theCellSize,
                                    myClipKml,
                                    myWorkingLayer,
                                    myFilename))

    LOGGER.debug(myCommand)
    myResult = QProcess().execute(myCommand)

    # For QProcess exit codes see
    # http://qt-project.org/doc/qt-4.8/qprocess.html#execute
    if myResult == -2:  # cannot be started
        myMessageDetail = tr('Process could not be started.')
        myMessage = tr(
            '<p>Error while executing the following shell command:'
            '</p><pre>%s</pre><p>Error message: %s'
            % (myCommand, myMessageDetail))
        raise CallGDALError(myMessage)
    elif myResult == -1:  # process crashed
        myMessageDetail = tr('Process could not be started.')
        myMessage = tr('<p>Error while executing the following shell command:'
                       '</p><pre>%s</pre><p>Error message: %s'
                       % (myCommand, myMessageDetail))
        raise CallGDALError(myMessage)

    # .. todo:: Check the result of the shell call is ok
    myKeywordIO = KeywordIO()
    myKeywordIO.copy_keywords(
        theLayer, myFilename, extra_keywords=theExtraKeywords)
    myBaseName = '%s clipped' % theLayer.name()
    myLayer = QgsRasterLayer(myFilename, myBaseName)

    return myLayer
Beispiel #16
0
    def test_raster_scaling(self):
        """Raster layers can be scaled when resampled.

        This is a test for ticket #52

        Native test .asc data has

        Population_Jakarta_geographic.asc
        ncols         638
        nrows         649
        cellsize      0.00045228819716044

        Population_2010.asc
        ncols         5525
        nrows         2050
        cellsize      0.0083333333333333

        Scaling is necessary for raster data that represents density
        such as population per km^2
        """

        filenames = [
            'Population_Jakarta_geographic.asc', 'Population_2010.asc'
        ]
        for filename in filenames:
            raster_path = ('%s/%s' % (TESTDATA, filename))

            # Get reference values
            safe_layer = read_safe_layer(raster_path)
            min_value, max_value = safe_layer.get_extrema()
            del max_value
            del min_value
            native_resolution = safe_layer.get_resolution()

            # Get the Hazard extents as an array in EPSG:4326
            bounding_box = safe_layer.get_bounding_box()

            resolutions = [
                0.02,
                0.01,
                0.005,
                0.002,
                0.001,
                0.0005,  # Coarser
                0.0002  # Finer
            ]
            # Test for a range of resolutions
            for resolution in resolutions:  # Finer
                # To save time only do two resolutions for the
                # large population set
                if filename.startswith('Population_2010'):
                    if resolution > 0.01 or resolution < 0.005:
                        break

                # Clip the raster to the bbox
                extra_keywords = {'resolution': native_resolution}
                raster_layer = QgsRasterLayer(raster_path, 'xxx')
                result = clip_layer(raster_layer,
                                    bounding_box,
                                    resolution,
                                    extra_keywords=extra_keywords)

                safe_layer = read_safe_layer(result.source())
                native_data = safe_layer.get_data(scaling=False)
                scaled_data = safe_layer.get_data(scaling=True)

                sigma_value = (safe_layer.get_resolution()[0] /
                               native_resolution[0])**2

                # Compare extrema
                expected_scaled_max = sigma_value * numpy.nanmax(native_data)
                message = ('Resampled raster was not rescaled correctly: '
                           'max(scaled_data) was %f but expected %f' %
                           (numpy.nanmax(scaled_data), expected_scaled_max))

                # FIXME (Ole): The rtol used to be 1.0e-8 -
                #              now it has to be 1.0e-6, otherwise we get
                #              max(scaled_data) was 12083021.000000 but
                #              expected 12083020.414316
                #              Is something being rounded to the nearest
                #              integer?
                assert numpy.allclose(expected_scaled_max,
                                      numpy.nanmax(scaled_data),
                                      rtol=1.0e-6,
                                      atol=1.0e-8), message

                expected_scaled_min = sigma_value * numpy.nanmin(native_data)
                message = ('Resampled raster was not rescaled correctly: '
                           'min(scaled_data) was %f but expected %f' %
                           (numpy.nanmin(scaled_data), expected_scaled_min))
                assert numpy.allclose(expected_scaled_min,
                                      numpy.nanmin(scaled_data),
                                      rtol=1.0e-8,
                                      atol=1.0e-12), message

                # Compare element-wise
                message = 'Resampled raster was not rescaled correctly'
                assert nan_allclose(native_data * sigma_value,
                                    scaled_data,
                                    rtol=1.0e-8,
                                    atol=1.0e-8), message

                # Check that it also works with manual scaling
                manual_data = safe_layer.get_data(scaling=sigma_value)
                message = 'Resampled raster was not rescaled correctly'
                assert nan_allclose(manual_data,
                                    scaled_data,
                                    rtol=1.0e-8,
                                    atol=1.0e-8), message

                # Check that an exception is raised for bad arguments
                try:
                    safe_layer.get_data(scaling='bad')
                except GetDataError:
                    pass
                else:
                    message = 'String argument should have raised exception'
                    raise Exception(message)

                try:
                    safe_layer.get_data(scaling='(1, 3)')
                except GetDataError:
                    pass
                else:
                    message = 'Tuple argument should have raised exception'
                    raise Exception(message)

                # Check None option without keyword datatype == 'density'
                safe_layer.keywords['datatype'] = 'undefined'
                unscaled_data = safe_layer.get_data(scaling=None)
                message = 'Data should not have changed'
                assert nan_allclose(native_data,
                                    unscaled_data,
                                    rtol=1.0e-12,
                                    atol=1.0e-12), message

                # Try with None and density keyword
                safe_layer.keywords['datatype'] = 'density'
                unscaled_data = safe_layer.get_data(scaling=None)
                message = 'Resampled raster was not rescaled correctly'
                assert nan_allclose(scaled_data,
                                    unscaled_data,
                                    rtol=1.0e-12,
                                    atol=1.0e-12), message

                safe_layer.keywords['datatype'] = 'counts'
                unscaled_data = safe_layer.get_data(scaling=None)
                message = 'Data should not have changed'
                assert nan_allclose(native_data,
                                    unscaled_data,
                                    rtol=1.0e-12,
                                    atol=1.0e-12), message
Beispiel #17
0
    def processAlgorithm(self, parameters, context, feedback):
        self.parameters = parameters
        self.context = context
        self.feedback = feedback
        load_geotiffs = self.parameterAsInt(parameters, self.PrmLoadGeoTiffs,
                                            context)
        out_folder = self.parameterAsFile(parameters,
                                          self.PrmGroundOverlayFolder, context)
        input_file = self.parameterAsFile(parameters, self.PrmInput, context)
        f, extension = os.path.splitext(input_file)
        dirname = os.path.dirname(input_file)
        extension = extension.lower()
        try:
            if extension == '.kmz':
                kmz = ZipFile(input_file, 'r')
                kml = kmz.open('doc.kml', 'r')
            elif extension == '.kml':
                kml = open(input_file,
                           encoding="utf-8",
                           errors="backslashreplace")
            else:
                msg = "Invalid extension: Should be kml or kmz"
                raise QgsProcessingException(msg)
        except Exception:
            msg = "Failed to open file"
            raise QgsProcessingException(msg)

        parser = xml.sax.make_parser()

        self.overlays = []
        # Set up the handler for doing the main processing
        handler = GroundOverlayHandler(feedback)
        handler.groundoverlay.connect(self.groundoverlay)
        parser.setContentHandler(handler)
        try:
            input_source = xml.sax.xmlreader.InputSource()
            input_source.setByteStream(kml)
            input_source.setEncoding('utf-8')
            parser.parse(input_source)
        except Exception:
            '''s = traceback.format_exc()
            feedback.pushInfo(s)'''
            feedback.reportError(
                tr('Failure in kml extraction - May return partial results.'))
            handler.endDocument()

        # Iterate through each found overlay images
        for overlay in self.overlays:
            north = overlay[0]
            south = overlay[1]
            east = overlay[2]
            west = overlay[3]
            rotation = overlay[4]
            href = overlay[5]
            if href.startswith('http:') or href.startswith('https:'):
                feedback.reportError(
                    'Cannot process network images: {}'.format(href))
                continue
            if extension == '.kmz':
                try:
                    image = kmz.read(href)
                    output_file = os.path.basename(href)
                    file_name, ext = os.path.splitext(output_file)
                    # Write out a temporary image
                    temp_file_name = os.path.join(
                        out_folder, '{}_temp{}'.format(file_name, ext))
                    fp = open(temp_file_name, "wb")
                    fp.write(image)
                    fp.close()
                    raster = QgsRasterLayer(temp_file_name, "temp")
                except Exception:
                    feedback.reportError(
                        'Image does not exist: {}'.format(href))
                    continue
            else:
                # Check to see if it is a valid file name
                in_path = os.path.join(dirname, href)
                if not os.path.isfile(in_path):
                    # The path was not valid
                    feedback.reportError(
                        'Image file does not exist: {}'.format(in_path))
                    continue
                raster = QgsRasterLayer(in_path, "temp")
                output_file = os.path.basename(in_path)
                file_name, ext = os.path.splitext(output_file)
            if not raster.isValid():
                feedback.reportError('Invalid raster image: {}'.format(href))
                continue
            out_path = os.path.join(out_folder, file_name + ".tif")
            if rotation == 0:
                status = processing.run(
                    "gdal:translate", {
                        'INPUT':
                        raster,
                        'EXTRA':
                        '-a_srs EPSG:4326 -a_ullr {} {} {} {}'.format(
                            west, north, east, south),
                        'DATA_TYPE':
                        0,
                        'OUTPUT':
                        out_path
                    })
            else:
                rwidth = raster.width()
                rheight = raster.height()
                center_x = (east + west) / 2.0
                center_y = (north + south) / 2.0
                center_pt = QgsPointXY(center_x, center_y)
                ul_pt = QgsPointXY(west, north)
                ur_pt = QgsPointXY(east, north)
                lr_pt = QgsPointXY(east, south)
                ll_pt = QgsPointXY(west, south)
                distance = center_pt.distance(ul_pt)
                az = center_pt.azimuth(ul_pt) - rotation
                pt1 = center_pt.project(distance, az)
                az = center_pt.azimuth(ur_pt) - rotation
                pt2 = center_pt.project(distance, az)
                az = center_pt.azimuth(lr_pt) - rotation
                pt3 = center_pt.project(distance, az)
                az = center_pt.azimuth(ll_pt) - rotation
                pt4 = center_pt.project(distance, az)
                gcp1 = '-gcp {} {} {} {}'.format(0, 0, pt1.x(), pt1.y())
                gcp2 = '-gcp {} {} {} {}'.format(rwidth, 0, pt2.x(), pt2.y())
                gcp3 = '-gcp {} {} {} {}'.format(rwidth, rheight, pt3.x(),
                                                 pt3.y())
                gcp4 = '-gcp {} {} {} {}'.format(0, rheight, pt4.x(), pt4.y())

                status = processing.run(
                    "gdal:translate", {
                        'INPUT':
                        raster,
                        'EXTRA':
                        '-a_srs EPSG:4326 -a_nodata 0,0,0 {} {} {} {}'.format(
                            gcp1, gcp2, gcp3, gcp4),
                        'DATA_TYPE':
                        0,
                        'OUTPUT':
                        out_path
                    })
            if load_geotiffs:
                context.addLayerToLoadOnCompletion(
                    out_path,
                    context.LayerDetails(file_name, project=context.project()))

            del raster
            if extension == '.kmz':
                try:
                    os.remove(temp_file_name)
                    os.remove(temp_file_name + '.aux.xml')
                except Exception:
                    pass

        if extension == '.kmz':
            kmz.close()
        else:
            kml.close()

        # self.feedback.pushInfo('Number of overlays: {}'.format(len(self.overlays)))

        return ({})
    def get_layer_description_from_browser(self, category):
        """Obtain the description of the browser layer selected by user.

        :param category: The category of the layer to get the description.
        :type category: string

        :returns: Tuple of boolean and string. Boolean is true if layer is
            validated as compatible for current role (impact function and
            category) and false otherwise. String contains a description
            of the selected layer or an error message.
        :rtype: tuple
        """

        if category == 'hazard':
            browser = self.tvBrowserHazard
        elif category == 'exposure':
            browser = self.tvBrowserExposure
        elif category == 'aggregation':
            browser = self.tvBrowserAggregation
        else:
            raise InaSAFEError

        index = browser.selectionModel().currentIndex()
        if not index:
            return False, ''

        # Map the proxy model index to the source model index
        index = browser.model().mapToSource(index)
        item = browser.model().sourceModel().dataItem(index)
        if not item:
            return False, ''

        item_class_name = item.metaObject().className()
        # if not itemClassName.endswith('LayerItem'):
        if not item.type() == QgsDataItem.Layer:
            if item_class_name == 'QgsPGRootItem' and not item.children():
                return False, create_postGIS_connection_first
            else:
                return False, ''

        if item_class_name not in [
                'QgsOgrLayerItem',
                'QgsGdalLayerItem',
                'QgsPGLayerItem',
                'QgsLayerItem',
        ]:
            return False, ''

        path = item.path()

        if item_class_name in [
                'QgsOgrLayerItem', 'QgsGdalLayerItem', 'QgsLayerItem'
        ] and not os.path.exists(path):
            return False, ''

        # try to create the layer
        if item_class_name == 'QgsOgrLayerItem':
            layer = QgsVectorLayer(path, '', 'ogr')
        elif item_class_name == 'QgsPGLayerItem':
            uri = self.postgis_path_to_uri(path)
            if uri:
                layer = QgsVectorLayer(uri.uri(), uri.table(), 'postgres')
            else:
                layer = None
        else:
            layer = QgsRasterLayer(path, '', 'gdal')

        if not layer or not layer.isValid():
            return False, self.tr('Not a valid layer.')

        try:
            keywords = self.keyword_io.read_keywords(layer)
            if 'layer_purpose' not in keywords:
                keywords = None
        except (HashNotFoundError, OperationalError, NoKeywordsFoundError,
                KeywordNotFoundError, InvalidParameterError,
                UnsupportedProviderError, MissingMetadata):
            keywords = None

        # set the layer name for further use in the step_fc_summary
        if keywords:
            if qgis_version() >= 21800:
                layer.setName(keywords.get('title'))
            else:
                layer.setLayerName(keywords.get('title'))

        if not self.parent.is_layer_compatible(layer, category, keywords):
            label_text = '%s<br/>%s' % (
                self.tr('This layer\'s keywords or type are not suitable:'),
                self.unsuitable_layer_description_html(layer, category,
                                                       keywords))
            return False, label_text

        # set the current layer (e.g. for the keyword creation sub-thread
        #                          or for adding the layer to mapCanvas)
        self.parent.layer = layer
        if category == 'hazard':
            self.parent.hazard_layer = layer
        elif category == 'exposure':
            self.parent.exposure_layer = layer
        else:
            self.parent.aggregation_layer = layer

        # Check if the layer is keywordless
        if keywords and 'keyword_version' in keywords:
            kw_ver = str(keywords['keyword_version'])
            self.parent.is_selected_layer_keywordless = (
                not is_keyword_version_supported(kw_ver))
        else:
            self.parent.is_selected_layer_keywordless = True

        desc = layer_description_html(layer, keywords)
        return True, desc
    def createMapLayer(self,
                       mapLayerName,
                       layerStyleName,
                       layerTime="",
                       minMaxRange=None):
        """
        Will create a QGIS valid raster layer for the
        parsed map, using the passed parameters to get the
        layer we need, with the requested style, and optionally
        a time dimension.
        The possibility of using WMS-T (Time) is provided by
        a 'hack' (QGIS does not allow it through its WMS provider
        API), taken from Anita Graser's Time Manager (GPL2).
        
        :param mapLayerName:      The name identifier of the coverage we want
                                  to retrieve..
        :type mapLayerName:       str
        
        :param layerStyleName:      The name identifier of the layer style we want
                                    used to paint our layer.
        :type layerStyleName:       str
        
        :param layerTime:   The time dimension we want (optional).
        :type layerTime:    str
        
        :param minMaxRange:   A tuple or list containing the min and max values to 
                              be used in the request of this map. Used for rendering
                              the proper colors. If none or not provided, it will
                              ask the server for the max-min values of this time-defined
                              map and use them instead.
        :type minMaxRange:    list or tuple with floats (min, max)
        
        :returns:   A QGIS-compatible raster layer object with the given parameters.
        :rtype:     QgsRasterLayer
        """
        if self.mapInfo is None:
            self.getMapInfoFromCapabilities()

        if minMaxRange == None:
            minMaxRange = self.getMinMaxRasterValuesFromTimeRange(
                mapLayerName, layerStyleName, [layerTime])

        rasterMinMaxValues = str(minMaxRange[0]) + "," + str(minMaxRange[1])
        #print("Raster range for "+mapLayerName+"_"+layerStyleName+": "+rasterMinMaxValues)

        finalUrl = self.baseWMSUrl.format(layer=mapLayerName,
                                          style=layerStyleName,
                                          url=self.mapInfo.getURL())

        #We add an UUID to guarantee uniqueness in the layer name and id
        layerName = self.mapInfo.getName() + "-" + str(uuid.uuid4())
        resultLayer = QgsRasterLayer(finalUrl, layerName, 'wms')

        #HACK taken from Anita Graser's Time Manager:
        #https://github.com/anitagraser/TimeManager/blob/master/raster/wmstlayer.py
        #(Under GPL2 license) with an extra added for COLORSCALERANGE ncWMS attribute.
        resultLayer.dataProvider().setDataSourceUri(
            self.qgisWMSThack + resultLayer.dataProvider().dataSourceUri() +
            "?TIME={time}%26COLORSCALERANGE={scale}".format(
                time=layerTime, scale=rasterMinMaxValues))

        if resultLayer.isValid():
            self.mapLayer = resultLayer
        else:
            raise StandardError('No se pudo crear una capa válida.')
def despeckeleGamma(dlg, conf, dir_raster_src, dir_dest, rasterName, gammaName,
                    extension_input_raster):

    # Calcul despeckele option Gamma
    li = layerList()

    messInfo(dlg, "Calcul du despeckele Gamma.")
    messInfo(dlg, "")

    rasterPath = dir_raster_src + os.sep + rasterName + extension_input_raster
    gammaPath = dir_dest + os.sep + gammaName + EXT_RASTER
    radius = dlg.spinBoxRadius.value()
    nb_looks = dlg.doubleSpinBoxLooks.value()

    # Suppression du fichier de sortie si il existe
    if os.path.exists(gammaPath):
        try:
            os.remove(gammaPath)
        except:
            QMessageBox.information(
                None, "Attention !!!", gammaPath +
                " ne peut pas être effacé. Vérifiez que le fichier n'est pas verrouillé par un autre utilisateur ou que le fichier peut être effacé manuellement (droits d'écriture sur le répertoire).",
                QMessageBox.Ok, QMessageBox.NoButton)
            messErreur(dlg, gammaPath + " ne peut pas être effacé.")
            return None

    # Calcul
    if conf.rbOTB.isChecked():
        # Despeckele Gamma par OTB
        try:
            #processing.algorithmHelp("otb:Despeckle")
            #processing.runalg('otb:despecklegammamap', rasterPath, '128', 0, radius, nb_looks, gammaPath)
            parameters = {
                "in": rasterPath,
                "out": gammaPath,
                "filter": 'gammamap',
                "filter.gammamap.rad": radius,
                "filter.gammamap.nblooks": nb_looks,
                "outputpixeltype": 5
            }
            processing.run('otb:Despeckle', parameters)
        except:
            messErreur(dlg, "Erreur de traitement sur otb:Despeckle Gamma.")
            return None
        # Fin OTB

    else:
        # Despeckele Gamma par GRASS
        entries = []

        raster = li[rasterName]
        extent = raster.extent()
        height = raster.height()
        width = raster.width()

        try:
            # En attente de faire fonctionner le despeckle avec GRASS !!!
            print("DEBUG  lancement grass:despeckle Gamma")
            processing.algorithmHelp("grass:i.despeckle")
            #processing.runalg('grass:i.despeckle', rasterPath, 'gamma', radius, nb_looks, gammaPath)
            print("DEBUG  fin grass:despeckle Gamma")
        except:
            messErreur(dlg, "Erreur de traitement sur grass:despeckle.")
            return None
        # Fin GRASS

    if os.path.exists(gammaPath):
        gamma = QgsRasterLayer(gammaPath, gammaName)
    else:
        QMessageBox.information(
            None, "Attention !!!", gammaPath +
            " n'a pas été créé. Vérifiez que le fichier n'est pas verrouillé par un autre utilisateur ou que le fichier peut être effacé manuellement (droits d'écriture sur le répertoire).",
            QMessageBox.Ok, QMessageBox.NoButton)
        messErreur(dlg, gammaPath + " n'a pas été créé.")
        return None

    if not gamma.isValid():
        messErreur(dlg, gammaPath + " ne peut pas être chargé.")
        return None

    return gamma
Beispiel #21
0
from qgis.core import QgsMapLayerRegistry, QgsRasterLayer
from qgis.analysis import QgsRasterCalculatorEntry, QgsRasterCalculator
from PyQt4.QtCore import QFileInfo

# Split rasters
layers = Raster.split(';')
output_path = OUT + "/"
suffix = "_suffix.tif"

for ras in layers:
    # Get layer object
    lyr = processing.getObjectFromUri(ras)
    entries = []
    ras = QgsRasterCalculatorEntry()
    ras.ref = 'lyr@1'
    ras.raster = lyr
    ras.bandNumber = 1
    entries.append(ras)
    calc = QgsRasterCalculator('(lyr@1 / lyr@1) * lyr@1',
                               output_path + lyr.name() + suffix, 'GTiff',
                               lyr.extent(), lyr.width(), lyr.height(),
                               entries)
    calc.processCalculation()

for results in glob.glob(output_path + "*" + suffix):
    fileInfo = QFileInfo(results)
    path = fileInfo.filePath()
    baseName = fileInfo.baseName()
    layer = QgsRasterLayer(path, baseName)
    QgsMapLayerRegistry.instance().addMapLayer(layer)
def computeNdvi(dlg, conf, dir_raster_src, dir_dest, rasterName, ndviName,
                extension_input_raster):

    # Calcul despeckele indice Ndvi
    li = layerList()

    messInfo(dlg, "Calcul du NDVI.")
    messInfo(dlg, "")

    rasterPath = dir_raster_src + os.sep + rasterName + extension_input_raster
    ndviPath = dir_dest + os.sep + ndviName + EXT_RASTER

    # Test si c'est une image multibande
    cols, rows, bands = getGeometryImage(rasterPath)
    if bands < 4:
        QMessageBox.information(
            None, "Attention !!!", ndviPath +
            " ne peut pas être créé. L'image raster d'entrée n'a pas un nombre de bande suffisant.",
            QMessageBox.Ok, QMessageBox.NoButton)
        messErreur(dlg, ndviPath + " ne peut pas être créé.")
        return None

    # Selection des bandes pour le calcul du NDVI
    num_channel_red = 0
    num_channel_nir = 0
    d = conf.channelOrderDic
    key = "Red"
    if key in conf.channelOrderDic.keys():
        num_channel_red = int(conf.channelOrderDic[key])
    key = "NIR"
    if key in conf.channelOrderDic.keys():
        num_channel_nir = int(conf.channelOrderDic[key])

    if (num_channel_red == 0 or num_channel_nir == 0):
        QMessageBox.information(
            None, "Attention !!!", ndviPath +
            " ne peut pas être créé. NDVI needs Red and NIR channels to be computed).",
            QMessageBox.Ok, QMessageBox.NoButton)
        messErreur(dlg, ndviPath + " ne peut pas être créé.")
        return None

    # Suppression du fichier de sortie si il existe
    if os.path.exists(ndviPath):
        try:
            os.remove(ndviPath)
        except:
            QMessageBox.information(
                None, "Attention !!!", ndviPath +
                " ne peut pas être effacé. Vérifiez que le fichier n'est pas verrouillé par un autre utilisateur ou que le fichier peut être effacé manuellement (droits d'écriture sur le répertoire).",
                QMessageBox.Ok, QMessageBox.NoButton)
            messErreur(dlg, ndviPath + " ne peut pas être effacé.")
            return None

    # Calcul
    if conf.rbOTB.isChecked():
        # Calculatrice raster OTB
        try:
            expression = '(im1b%s - im1b%s)/(im1b%s + im1b%s)' % (
                str(num_channel_nir), str(num_channel_red),
                str(num_channel_nir), str(num_channel_red))
            #processing.algorithmHelp("otb:BandMath")
            #processing.runalg('otb:bandmath', rasterPath, '128',expression, ndviPath)
            parameters = {
                "il": [rasterPath],
                "out": ndviPath,
                "exp": expression,
                "outputpixeltype": 5
            }
            processing.run('otb:BandMath', parameters)
        except:
            messErreur(dlg, "Erreur de traitement sur otb:BandMath ndvi.")
            return None
        # Fin OTB

    else:
        # Calculatrice raster QGIS
        entries = []

        raster = li[rasterName]
        extent = raster.extent()
        height = raster.height()
        width = raster.width()

        b_red = QgsRasterCalculatorEntry()
        b_red.ref = 'b@%s' % (str(num_channel_red))
        b_red.raster = raster
        b_red.bandNumber = num_channel_red
        entries.append(b_red)

        b_nir = QgsRasterCalculatorEntry()
        b_nir.ref = 'b@%s' % (str(num_channel_nir))
        b_nir.raster = raster
        b_nir.bandNumber = num_channel_nir
        entries.append(b_nir)

        expression = '(b@%s - b@%s)/(b@%s + b@%s)' % (
            str(num_channel_nir), str(num_channel_red), str(num_channel_nir),
            str(num_channel_red))
        calc = QgsRasterCalculator(expression, ndviPath, FORMAT_IMA, extent,
                                   width, height, entries)

        ret = calc.processCalculation()

        if ret != 0:
            QMessageBox.information(
                None, "Attention !!!",
                " Erreur d'exécution, cela peut être du à une insuffisance mémoire, image trop volumineuse.",
                QMessageBox.Ok, QMessageBox.NoButton)
            messErreur(dlg, "Erreur lors du lancement de QgsRasterCalculator.")
            return None
        # Fin QGIS

    if os.path.exists(ndviPath):
        ndvi = QgsRasterLayer(ndviPath, ndviName)
    else:
        QMessageBox.information(
            None, "Attention !!!", ndviPath +
            " n'a pas été créé. Vérifiez que le fichier n'est pas verrouillé par un autre utilisateur ou que le fichier peut être effacé manuellement (droits d'écriture sur le répertoire).",
            QMessageBox.Ok, QMessageBox.NoButton)
        messErreur(dlg, ndviPath + " n'a pas été créé.")
        return None

    if not ndvi.isValid():
        messErreur(dlg, ndviPath + " ne peut pas être chargé.")
        return None

    return ndvi
Beispiel #23
0
    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
def computeMaskThreshold(dlg, conf, dir_raster_treat, dir_dest,
                         rasterTreatName, rasterSeuilName, seuilStr, deltaStr,
                         extension_input_raster):

    # Calcul du masque d'eau fonction du seuil choisi
    seuil = float(seuilStr)
    if not dlg.rbSeuil.isChecked():
        delta = 0
        values_seuil_list = [0]
    else:
        delta = float(deltaStr)
        values_seuil_list = [-1, 0, +1]

    messInfo(dlg, "Seuil: " + seuilStr)
    messInfo(dlg, "")

    if dlg.rbComputeNdvi.isChecked():
        direction = True
    elif dlg.rbComputeNdwi2.isChecked():
        direction = False
    else:
        direction = True

    if direction:
        direction_operator_str = "<"  # Operateur inferieur
    else:
        direction_operator_str = ">"  # Operateur superieur

    if conf.rbOTB.isChecked():
        # Calculatrice OTB
        init = 41253
    else:
        # Calculatrice QGIS
        init = 32526

    masks_list = []
    for i in values_seuil_list:
        newSeuil = seuil + i * delta

        if float(newSeuil) == 0:
            newSeuilStr = '0'
            newSeuil10Str = '0'
        else:
            newSeuilStr = str(newSeuil)
            newSeuil10Str = str(newSeuil * 10)
            while newSeuilStr[0] == '0' and len(
                    newSeuilStr) >= 2 and newSeuilStr[1] != '.':
                newSeuilStr = newSeuilStr[1:]
            if '.' in newSeuilStr:
                while newSeuilStr[-1] == '0':
                    newSeuilStr = newSeuilStr[:len(newSeuilStr) - 1]
                if newSeuilStr[-1] == '.':
                    newSeuilStr = newSeuilStr[:len(newSeuilStr) - 1]

        if newSeuil != init:
            init = newSeuil

            if delta == 0:
                layerSeuilName = rasterSeuilName + seuilStr
            else:
                layerSeuilName = rasterSeuilName + newSeuilStr

            layerSeuilPath = dir_dest + os.sep + layerSeuilName + EXT_RASTER

            if os.path.exists(layerSeuilPath):
                try:
                    os.remove(layerSeuilPath)
                except:
                    QMessageBox.information(
                        None, "Attention !!!", layerSeuilPath +
                        " ne peut pas être effacé. Vérifiez que le fichier n'est pas verrouillé par un autre utilisateur ou que le fichier peut être effacé manuellement (droits d'écriture sur le répertoire).",
                        QMessageBox.Ok, QMessageBox.NoButton)
                    messErreur(dlg,
                               layerSeuilPath + " ne peut pas être effacé.")
                    return None

            messInfo(dlg,
                     "Calcul du masque 'Eau' avec le seuil: " + newSeuilStr)
            messInfo(dlg, "")

            # Calculatrice OTB
            if conf.rbOTB.isChecked():
                rasterTreatPath = dir_raster_treat + os.sep + rasterTreatName + extension_input_raster
                try:
                    expression = 'im1b1' + direction_operator_str + newSeuilStr + '?1:2'
                    #processing.algorithmHelp("otb:BandMath")
                    #processing.runalg('otb:bandmath', rasterTreatPath, '128',expression ,layerSeuilPath)
                    parameters = {
                        "il": [rasterTreatPath],
                        "out": layerSeuilPath,
                        "exp": expression,
                        "outputpixeltype": 0
                    }
                    processing.run('otb:BandMath', parameters)
                except:
                    messErreur(
                        dlg,
                        "Erreur lors du lancement de otb:BandMath seuillage.")
                    return None
            # Fin OTB

            # Calculatrice QGIS
            else:
                entries = []
                li = layerList()
                raster = li[rasterTreatName]
                extent = raster.extent()
                height = raster.height()
                width = raster.width()

                s1 = QgsRasterCalculatorEntry()
                s1.ref = 's@1'
                s1.raster = raster
                s1.bandNumber = 1
                entries.append(s1)

                if platform.system() == "Linux":
                    # Bug calculatrice raster sous linux
                    calc = QgsRasterCalculator(
                        '(10*s@1' + direction_operator_str + newSeuil10Str +
                        ')', layerSeuilPath, FORMAT_IMA, extent, width, height,
                        entries)

                else:
                    calc = QgsRasterCalculator(
                        '(s@1' + direction_operator_str + newSeuilStr + ')',
                        layerSeuilPath, FORMAT_IMA, extent, width, height,
                        entries)

                ret = calc.processCalculation()
                if ret != 0:
                    QMessageBox.information(
                        None, "Attention !!!",
                        " Erreur d'exécution, cela peut être du à une insuffisance mémoire, image trop volumineuse.",
                        QMessageBox.Ok, QMessageBox.NoButton)
                    messErreur(
                        dlg, "Erreur de traitement sur QgsRasterCalculator.")
                    return None
            # Fin QGIS

            if os.path.exists(layerSeuilPath):
                mask = QgsRasterLayer(layerSeuilPath, layerSeuilName)
            else:
                QMessageBox.information(
                    None, "Attention !!!", layerSeuilPath +
                    " n'a pas été créé. Vérifiez que le fichier n'est pas verrouillé par un autre utilisateur ou que le fichier peut être effacé manuellement (droits d'écriture sur le répertoire).",
                    QMessageBox.Ok, QMessageBox.NoButton)
                messErreur(dlg, layerSeuilPath + " n'a pas été créé.")
                return None

            if not mask.isValid():
                messErreur(dlg, layerSeuilPath + " ne peut pas être chargé.")
                return None

            # Add list pour return
            masks_list.append(mask)

    return masks_list
def run_scenario(scenario, use_debug=False):
    """Run scenario.

    :param scenario: Dictionary of hazard, exposure, and aggregation.
    :type scenario: dict

    :param use_debug: If we should use debug_mode when we run the scenario.
    :type use_debug: bool

    :returns: Tuple(status, Flow dictionary, outputs).
    :rtype: list
    """
    if os.path.exists(scenario['exposure']):
        exposure_path = scenario['exposure']
    elif os.path.exists(standard_data_path('exposure', scenario['exposure'])):
        exposure_path = standard_data_path('exposure', scenario['exposure'])
    elif os.path.exists(
            standard_data_path(*(scenario['exposure'].split('/')))):
        exposure_path = standard_data_path(*(scenario['exposure'].split('/')))
    else:
        raise IOError('No exposure file')

    if os.path.exists(scenario['hazard']):
        hazard_path = scenario['hazard']
    elif os.path.exists(standard_data_path('hazard', scenario['hazard'])):
        hazard_path = standard_data_path('hazard', scenario['hazard'])
    elif os.path.exists(standard_data_path(*(scenario['hazard'].split('/')))):
        hazard_path = standard_data_path(*(scenario['hazard'].split('/')))
    else:
        raise IOError('No hazard file')

    if not scenario['aggregation']:
        aggregation_path = None
    else:
        if os.path.exists(scenario['aggregation']):
            aggregation_path = scenario['aggregation']
        elif os.path.exists(standard_data_path(
                'aggregation', scenario['aggregation'])):
            aggregation_path = standard_data_path(
                'aggregation', scenario['aggregation'])
        elif os.path.exists(
                standard_data_path(*(scenario['aggregation'].split('/')))):
            aggregation_path = standard_data_path(
                *(scenario['aggregation'].split('/')))
        else:
            raise IOError('No aggregation file')

    impact_function = ImpactFunction()
    impact_function.debug_mode = use_debug

    layer = QgsVectorLayer(hazard_path, 'Hazard', 'ogr')
    if not layer.isValid():
        layer = QgsRasterLayer(hazard_path, 'Hazard')
    impact_function.hazard = layer

    layer = QgsVectorLayer(exposure_path, 'Exposure', 'ogr')
    if not layer.isValid():
        layer = QgsRasterLayer(exposure_path, 'Exposure')
    impact_function.exposure = layer

    if aggregation_path:
        impact_function.aggregation = QgsVectorLayer(
            aggregation_path, 'Aggregation', 'ogr')

    status, message = impact_function.prepare()
    if status != 0:
        return status, message, None

    status, message = impact_function.run()
    if status != 0:
        return status, message, None

    for layer in impact_function.outputs:
        if layer.type() == QgsMapLayer.VectorLayer:
            check_inasafe_fields(layer)

    return status, impact_function.state, impact_function.outputs
def filterRaster(dlg, conf, dir_dest, rasterSeuilName, rasterFilterName):

    # Filtre que l'on propose pour éliminer les zones d'eau mineures
    li = layerList()
    layerSeuil = li[rasterSeuilName]
    layerSeuilPath = dir_dest + os.sep + rasterSeuilName + EXT_RASTER
    layerFiltreIlotsPath = dir_dest + os.sep + rasterFilterName + EXT_RASTER

    for elem in li:
        if elem == rasterFilterName:
            QgsProject.instance().removeMapLayer(li[elem].id())

    if os.path.exists(layerFiltreIlotsPath):
        try:
            os.remove(layerFiltreIlotsPath)
        except:
            QMessageBox.information(
                None, "Attention !!!", layerFiltreIlotsPath +
                " ne peut pas être effacé. Vérifiez que le fichier n'est pas verrouillé par un autre utilisateur ou que le fichier peut être effacé manuellement (droits d'écriture sur le répertoire).",
                QMessageBox.Ok, QMessageBox.NoButton)
            messErreur(dlg, layerFiltreIlotsPath + " ne peut pas être effacé.")
            return None

    # Filtrage OTB
    if conf.rbOTB.isChecked():

        seuilCMR = dlg.seuilCMR.text()
        if seuilCMR == '':
            QMessageBox.information(None, "Attention !!!",
                                    "Valeur de radius incorrecte !",
                                    QMessageBox.Ok, QMessageBox.NoButton)
            return None
        try:
            seuilCMR = int(seuilCMR)
        except:
            QMessageBox.information(None, "Attention !!!",
                                    "Valeur de radius incorrecte !",
                                    QMessageBox.Ok, QMessageBox.NoButton)
            return None
        if not 0 <= int(seuilCMR) <= 30:
            QMessageBox.information(None, "Attention !!!",
                                    "Valeur de radius incorrecte !",
                                    QMessageBox.Ok, QMessageBox.NoButton)
            return None

        messInfo(
            dlg,
            "Lancement du filtre 'Classification Map Regularization' sur le raster: "
            + rasterSeuilName)
        messInfo(dlg, "Radius: " + str(seuilCMR))
        messInfo(dlg, "")

        try:
            #processing.algorithmHelp("otb:ClassificationMapRegularization")
            #processing.runalg('otb:classificationmapregularization', layerSeuilPath, seuilCMR, True, 0, 0, False, 0, 128, layerFiltreIlotsPath)
            parameters = {
                "io.in": layerSeuilPath,
                "io.out": layerFiltreIlotsPath,
                "ip.radius": seuilCMR,
                "ip.suvbool": True,
                "ip.nodatalabel": 0,
                "ip.undecidedlabel": 0,
                "ip.onlyisolatedpixels": False,
                "ip.isolatedthreshold": 0,
                "outputpixeltype": 0
            }
            processing.run('otb:ClassificationMapRegularization', parameters)
        except:
            messErreur(
                dlg,
                "Erreur de traitement par (filtre Classification Map Regularization) de %s !!!"
                % (layerFiltreIlotsPath))
            return None
    # Fin OTB

    # Filtrage QGIS (Gdal)
    else:

        seuilTamiser = dlg.seuilTamiser.text()
        if seuilTamiser == '':
            QMessageBox.information(None, "Attention !!!",
                                    "Valeur de seuil incorrecte !",
                                    QMessageBox.Ok, QMessageBox.NoButton)
            return None
        try:
            seuilTamiser = int(seuilTamiser)
        except:
            QMessageBox.information(None, "Attention !!!",
                                    "Valeur de seuil incorrecte !",
                                    QMessageBox.Ok, QMessageBox.NoButton)
            return None
        if not 0 <= int(seuilTamiser) < 10000:
            QMessageBox.information(None, "Attention !!!",
                                    "Valeur de seuil incorrecte !",
                                    QMessageBox.Ok, QMessageBox.NoButton)
            return None

        if dlg.rbTamiser4.isChecked():
            conn = False
        else:
            conn = True

        messInfo(dlg,
                 "Lancement du filtrage sur le raster: " + rasterSeuilName)
        messInfo(dlg, "Seuil: " + str(seuilTamiser))
        messInfo(dlg, "")

        try:
            #processing.algorithmHelp("gdal:sieve")
            #processing.runalg('gdalogr:sieve', layerSeuil,seuilTamiser,conn,layerFiltreIlotsPath)
            parameters = {
                "INPUT": layerSeuil,
                "THRESHOLD": seuilTamiser,
                "EIGHT_CONNECTEDNESS": conn,
                "NO_MASK": True,
                "MASK_LAYER": "",
                "OUTPUT": layerFiltreIlotsPath
            }
            processing.run('gdal:sieve', parameters)
        except:
            messErreur(
                dlg, "Erreur de traitement par gdal:sieve (filtre) de %s !!!" %
                (layerFiltreIlotsPath))
            return None
    # Fin QGIS

    # Test si le filtrage à reussi
    if os.path.exists(layerFiltreIlotsPath):
        layer = QgsRasterLayer(layerFiltreIlotsPath, rasterFilterName)
    else:
        QMessageBox.information(
            None, "Attention !!!", layerFiltreIlotsPath +
            " n'a pas été créé. Vérifiez que le fichier n'est pas verrouillé par un autre utilisateur ou que le fichier peut être effacé manuellement (droits d'écriture sur le répertoire).",
            QMessageBox.Ok, QMessageBox.NoButton)
        messErreur(dlg, layerFiltreIlotsPath + " n'a pas été créé.")
        return None

    if not layer.isValid():
        messErreur(dlg, layerFiltreIlotsPath + " ne peut pas être chargé.")
        return None

    return layer
Beispiel #27
0
    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")
Beispiel #28
0
##r.series_directory=name
##Select_directory=Folder
##output=output raster

import glob, os
from PyQt4.QtCore import QFileInfo
from qgis.core import QgsRasterLayer, QgsRectangle

os.chdir(Select_directory)
rlist = []
extent = QgsRectangle()
extent.setMinimal()
for raster in glob.glob("*.tif"):
    fileInfo = QFileInfo(raster)
    baseName = fileInfo.baseName()
    rlayer = QgsRasterLayer(raster, baseName)
    # Combine raster layers to list
    rlist.append(rlayer)
    # Combine raster extents
    extent.combineExtentWith(rlayer.extent())

# Get extent
xmin = extent.xMinimum()
xmax = extent.xMaximum()
ymin = extent.yMinimum()
ymax = extent.yMaximum()
# Run algorithm and set relevant parameters
processing.runalg(
    "grass7:r.series", {
        "input": rlist,
        "-n": False,
Beispiel #29
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"
Beispiel #30
0
    def test_clipBoth(self):
        """Raster and Vector layers can be clipped
        """

        # Create a vector layer
        myName = 'padang'
        myVectorLayer = QgsVectorLayer(VECTOR_PATH, myName, 'ogr')
        myMessage = 'Did not find layer "%s" in path "%s"' % (myName,
                                                              VECTOR_PATH)
        assert myVectorLayer.isValid(), myMessage

        # Create a raster layer
        myName = 'shake'
        myRasterLayer = QgsRasterLayer(RASTERPATH, myName)
        myMessage = 'Did not find layer "%s" in path "%s"' % (myName,
                                                              RASTERPATH)
        assert myRasterLayer.isValid(), myMessage

        # Create a bounding box
        myViewportGeoExtent = [99.53, -1.22, 101.20, -0.36]

        # Get the Hazard extents as an array in EPSG:4326
        myHazardGeoExtent = [
            myRasterLayer.extent().xMinimum(),
            myRasterLayer.extent().yMinimum(),
            myRasterLayer.extent().xMaximum(),
            myRasterLayer.extent().yMaximum()
        ]

        # Get the Exposure extents as an array in EPSG:4326
        myExposureGeoExtent = [
            myVectorLayer.extent().xMinimum(),
            myVectorLayer.extent().yMinimum(),
            myVectorLayer.extent().xMaximum(),
            myVectorLayer.extent().yMaximum()
        ]

        # Now work out the optimal extent between the two layers and
        # the current view extent. The optimal extent is the intersection
        # between the two layers and the viewport.
        # Extent is returned as an array [xmin,ymin,xmax,ymax]
        myGeoExtent = getOptimalExtent(myHazardGeoExtent, myExposureGeoExtent,
                                       myViewportGeoExtent)

        # Clip the vector to the bbox
        myResult = clipLayer(myVectorLayer, myGeoExtent)

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

        # Clip the raster to the bbox
        myResult = clipLayer(myRasterLayer, myGeoExtent)

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

        # -------------------------------
        # Check the extra keywords option
        # -------------------------------
        # Clip the vector to the bbox
        myResult = clipLayer(myVectorLayer,
                             myGeoExtent,
                             theExtraKeywords={'kermit': 'piggy'})

        # Check the output is valid
        assert os.path.exists(myResult)
        L = readSafeLayer(myResult)
        kwds = L.get_keywords()
        myMessage = 'Extra keyword was not found in %s: %s' % (myResult, kwds)
        assert kwds['kermit'] == 'piggy'

        # Clip the raster to the bbox
        myResult = clipLayer(myRasterLayer,
                             myGeoExtent,
                             theExtraKeywords={'zoot': 'animal'})

        # Check the output is valid
        assert os.path.exists(myResult)
        L = readSafeLayer(myResult)
        kwds = L.get_keywords()

        myMessage = 'Extra keyword was not found in %s: %s' % (myResult, kwds)
        assert kwds['zoot'] == 'animal', myMessage