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)
def testPalettedClassDataFromLayer(self): # no layer classes = QgsPalettedRasterRenderer.classDataFromRaster(None, 1) self.assertFalse(classes) # 10 class layer path = os.path.join(unitTestDataPath('raster'), 'with_color_table.tif') info = QFileInfo(path) base_name = info.baseName() layer10 = QgsRasterLayer(path, base_name) classes = QgsPalettedRasterRenderer.classDataFromRaster( layer10.dataProvider(), 1) self.assertEqual(len(classes), 10) self.assertEqual(classes[0].value, 1) self.assertEqual(classes[0].label, '1') self.assertEqual(classes[1].value, 2) self.assertEqual(classes[1].label, '2') self.assertEqual(classes[2].value, 3) self.assertEqual(classes[2].label, '3') self.assertEqual(classes[3].value, 4) self.assertEqual(classes[3].label, '4') self.assertEqual(classes[4].value, 5) self.assertEqual(classes[4].label, '5') self.assertEqual(classes[5].value, 6) self.assertEqual(classes[5].label, '6') self.assertEqual(classes[6].value, 7) self.assertEqual(classes[6].label, '7') self.assertEqual(classes[7].value, 8) self.assertEqual(classes[7].label, '8') self.assertEqual(classes[8].value, 9) self.assertEqual(classes[8].label, '9') self.assertEqual(classes[9].value, 10) self.assertEqual(classes[9].label, '10') # bad band self.assertFalse( QgsPalettedRasterRenderer.classDataFromRaster( layer10.dataProvider(), 10101010)) # with ramp r = QgsGradientColorRamp(QColor(200, 0, 0, 100), QColor(0, 200, 0, 200)) classes = QgsPalettedRasterRenderer.classDataFromRaster( layer10.dataProvider(), 1, r) self.assertEqual(len(classes), 10) self.assertEqual(classes[0].color.name(), '#c80000') self.assertEqual(classes[1].color.name(), '#b21600') self.assertEqual(classes[2].color.name(), '#9c2c00') self.assertEqual(classes[3].color.name(), '#854200') self.assertEqual(classes[4].color.name(), '#6f5900') self.assertEqual(classes[5].color.name(), '#596f00') self.assertEqual(classes[6].color.name(), '#428500') self.assertEqual(classes[7].color.name(), '#2c9c00') self.assertEqual(classes[8].color.name(), '#16b200') self.assertEqual(classes[9].color.name(), '#00c800') # 30 class layer path = os.path.join(unitTestDataPath('raster'), 'unique_1.tif') info = QFileInfo(path) base_name = info.baseName() layer10 = QgsRasterLayer(path, base_name) classes = QgsPalettedRasterRenderer.classDataFromRaster( layer10.dataProvider(), 1) self.assertEqual(len(classes), 30) expected = [ 11, 21, 22, 24, 31, 82, 2002, 2004, 2014, 2019, 2027, 2029, 2030, 2080, 2081, 2082, 2088, 2092, 2097, 2098, 2099, 2105, 2108, 2110, 2114, 2118, 2126, 2152, 2184, 2220 ] self.assertEqual([c.value for c in classes], expected) # bad layer path = os.path.join(unitTestDataPath('raster'), 'hub13263.vrt') info = QFileInfo(path) base_name = info.baseName() layer = QgsRasterLayer(path, base_name) classes = QgsPalettedRasterRenderer.classDataFromRaster( layer.dataProvider(), 1) self.assertFalse(classes)
def test_project_roundtrip(self): """Tests that a project with bad layers can be saved and restored""" p = QgsProject.instance() temp_dir = QTemporaryDir() for ext in ('shp', 'dbf', 'shx', 'prj'): copyfile(os.path.join(TEST_DATA_DIR, 'lines.%s' % ext), os.path.join(temp_dir.path(), 'lines.%s' % ext)) copyfile( os.path.join(TEST_DATA_DIR, 'raster', 'band1_byte_ct_epsg4326.tif'), os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif')) copyfile( os.path.join(TEST_DATA_DIR, 'raster', 'band1_byte_ct_epsg4326.tif'), os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif')) l = QgsVectorLayer(os.path.join(temp_dir.path(), 'lines.shp'), 'lines', 'ogr') self.assertTrue(l.isValid()) rl = QgsRasterLayer( os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif'), 'raster', 'gdal') self.assertTrue(rl.isValid()) rl_copy = QgsRasterLayer( os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif'), 'raster_copy', 'gdal') self.assertTrue(rl_copy.isValid()) self.assertTrue(p.addMapLayers([l, rl, rl_copy])) # Save project project_path = os.path.join(temp_dir.path(), 'project.qgs') self.assertTrue(p.write(project_path)) # Re-load the project, checking for the XML properties p.removeAllMapLayers() self.assertTrue(p.read(project_path)) vector = list(p.mapLayersByName('lines'))[0] raster = list(p.mapLayersByName('raster'))[0] raster_copy = list(p.mapLayersByName('raster_copy'))[0] self.assertTrue(vector.originalXmlProperties() != '') self.assertTrue(raster.originalXmlProperties() != '') self.assertTrue(raster_copy.originalXmlProperties() != '') # Test setter raster.setOriginalXmlProperties('pippo') self.assertEqual(raster.originalXmlProperties(), 'pippo') # Now create and invalid project: bad_project_path = os.path.join(temp_dir.path(), 'project_bad.qgs') with open(project_path, 'r') as infile: with open(bad_project_path, 'w+') as outfile: outfile.write(infile.read().replace( './lines.shp', './lines-BAD_SOURCE.shp').replace( 'band1_byte_ct_epsg4326_copy.tif', 'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif')) # Load the bad project p.removeAllMapLayers() self.assertTrue(p.read(bad_project_path)) # Check layer is invalid vector = list(p.mapLayersByName('lines'))[0] raster = list(p.mapLayersByName('raster'))[0] raster_copy = list(p.mapLayersByName('raster_copy'))[0] self.assertIsNotNone(vector.dataProvider()) self.assertIsNotNone(raster.dataProvider()) self.assertIsNotNone(raster_copy.dataProvider()) self.assertFalse(vector.isValid()) self.assertFalse(raster_copy.isValid()) # Try a getFeatures self.assertEqual([f for f in vector.getFeatures()], []) self.assertTrue(raster.isValid()) self.assertEqual(vector.providerType(), 'ogr') # Save the project bad_project_path2 = os.path.join(temp_dir.path(), 'project_bad2.qgs') p.write(bad_project_path2) # Re-save the project, with fixed paths good_project_path = os.path.join(temp_dir.path(), 'project_good.qgs') with open(bad_project_path2, 'r') as infile: with open(good_project_path, 'w+') as outfile: outfile.write(infile.read().replace( './lines-BAD_SOURCE.shp', './lines.shp').replace( 'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif', 'band1_byte_ct_epsg4326_copy.tif')) # Load the good project p.removeAllMapLayers() self.assertTrue(p.read(good_project_path)) # Check layer is valid vector = list(p.mapLayersByName('lines'))[0] raster = list(p.mapLayersByName('raster'))[0] raster_copy = list(p.mapLayersByName('raster_copy'))[0] self.assertTrue(vector.isValid()) self.assertTrue(raster.isValid()) self.assertTrue(raster_copy.isValid())
def 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
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') }
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')
def __input_raster_layer(): options = QgsRasterLayer.LayerOptions() options.loadDefaultStyle = False return QgsRasterLayer( os.path.join(AlgorithmsTestBase.processingTestDataPath(), 'raster.tif'), "raster_input", 'gdal', options)
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}
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):
def createLayer(self, layerPath, layerBaseName): """ Create a raster layer """ return QgsRasterLayer(layerPath, layerBaseName)
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
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
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
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
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
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")
##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,
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"
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