def define_layer(self, layer_path): """Create QGIS layer (either vector or raster) from file path input. :param layer_path: Full path to layer file. :type layer_path: str :return: QGIS layer. :rtype: QgsMapLayer """ scenario_dir = self.source_directory.text() joined_path = os.path.join(scenario_dir, layer_path) full_path = os.path.normpath(joined_path) file_name = os.path.split(layer_path)[-1] # get extension and basename to create layer base_name, extension = os.path.splitext(file_name) # load layer in scenario layer = QgsRasterLayer(full_path, base_name) if layer.isValid(): return layer else: layer = QgsVectorLayer(full_path, base_name, 'ogr') if layer.isValid(): return layer # if layer is not vector nor raster else: LOGGER.warning('Input in scenario is not recognized/supported') return
def test_clip_raster(self): """Raster layers can be clipped.""" # Create a raster layer layer_name = 'shake' raster_layer = QgsRasterLayer(RASTERPATH, layer_name) message = ( 'Did not find layer "%s" in path "%s"' % (layer_name, RASTERPATH)) assert raster_layer is not None, message # Create a bounding box bounding_box = [97, -3, 104, 1] # Clip the vector to the bbox result = clip_layer(raster_layer, bounding_box) # Check the output is valid assert os.path.exists(result.source()) # Clip and give a desired resolution for the output # big pixel size size = 0.05 result = clip_layer(raster_layer, bounding_box, size) new_raster_layer = QgsRasterLayer(result.source(), layer_name) assert new_raster_layer.isValid(), 'Resampled raster is not valid' message = ( 'Resampled raster has incorrect pixel size. Expected: %5f, ' 'Actual: %5f' % (size, new_raster_layer.rasterUnitsPerPixelX())) assert new_raster_layer.rasterUnitsPerPixelX() == size, message
def test_clipRaster(self): """Raster layers can be clipped """ # Create a raster layer myName = 'shake' myRasterLayer = QgsRasterLayer(RASTERPATH, myName) myMessage = 'Did not find layer "%s" in path "%s"' % \ (myName, RASTERPATH) assert myRasterLayer is not None, myMessage # Create a bounding box myRect = [97, -3, 104, 1] # Clip the vector to the bbox myResult = clip_layer(myRasterLayer, myRect) # Check the output is valid assert os.path.exists(myResult.source()) # Clip and give a desired resolution for the output mySize = 0.05 myResult = clip_layer(myRasterLayer, myRect, mySize) myNewRasterLayer = QgsRasterLayer(myResult.source(), myName) assert myNewRasterLayer.isValid(), 'Resampled raster is not valid' myMessage = ('Resampled raster has incorrect pixel size.' 'Expected: %f, Actual: %f' % (mySize, myNewRasterLayer.rasterUnitsPerPixelX())) assert myNewRasterLayer.rasterUnitsPerPixelX() == mySize, myMessage
def loadLayer(theLayerFile): """Helper to load and return a single QGIS layer""" # Extract basename and absolute path myBaseName, myExt = os.path.splitext(theLayerFile) myPath = os.path.join(TESTDATA, theLayerFile) myKeywordPath = myPath[:-4] + '.keywords' # Determine if layer is hazard or exposure myKeywords = read_keywords(myKeywordPath) myType = 'undefined' if 'category' in myKeywords: myType = myKeywords['category'] msg = 'Could not read %s' % myKeywordPath assert myKeywords is not None, msg # Create QGis Layer Instance if myExt in ['.asc', '.tif']: myLayer = QgsRasterLayer(myPath, myBaseName) elif myExt in ['.shp']: myLayer = QgsVectorLayer(myPath, myBaseName, 'ogr') else: myMessage = 'File %s had illegal extension' % myPath raise Exception(myMessage) myMessage = 'Layer "%s" is not valid' % str(myLayer.source()) assert myLayer.isValid(), myMessage return myLayer, myType
def generateLayer(self, nameCoverage, coverageTime, boundingBox=None): """Generates a raster layer for QGIS. :param nameCoverage: the name identifier of the coverage we want to retrieve. :type nameCoverage: str :param coverageTime: the time dimension of the coverage we want. :type coverageTime: str :returns: a QGIS-compatible raster layer object for the coverage and times provided. :rtype: QgsRasterLayer """ url = self.generateURLForGeoTIFF(nameCoverage, coverageTime, boundingBox) layerName = "{ct}_{nc}-{id}".format(ct=coverageTime, nc=nameCoverage, id=uuid.uuid4()) if Utilities.is_linux(): import requests with tempfile.NamedTemporaryFile(suffix=".tiff", delete=False) as f: r = requests.get(url, stream=True) with open(f.name, "wb") as g: for chunk in r.iter_content(): g.write(chunk) layer = QgsRasterLayer(f.name, layerName) else: layer = QgsRasterLayer(url, layerName) if layer.isValid(): return layer else: msg = "Couldn't create a valid layer." self.standardMessage.emit(msg)
def test_invalidFilenamesCaught(self): """Invalid filenames raise appropriate exceptions Wrote this test because test_clipBoth raised the wrong error when file was missing. Instead of reporting that, it gave Western boundary must be less than eastern. I got [0.0, 0.0, 0.0, 0.0] See issue #170 """ # Try to create a vector layer from non-existing filename myName = 'stnhaoeu_78oeukqjkrcgA' myPath = 'OEk_tnshoeu_439_kstnhoe' with RedirectStreams(stdout=DEVNULL, stderr=DEVNULL): myVectorLayer = QgsVectorLayer(myPath, myName, 'ogr') myMessage = ('QgsVectorLayer reported "valid" for non ' 'existent path "%s" and name "%s".' % (myPath, myName)) assert not myVectorLayer.isValid(), myMessage # Create a raster layer with RedirectStreams(stdout=DEVNULL, stderr=DEVNULL): myRasterLayer = QgsRasterLayer(myPath, myName) myMessage = ('QgsRasterLayer reported "valid" for non ' 'existent path "%s" and name "%s".' % (myPath, myName)) assert not myRasterLayer.isValid(), myMessage
def __init__(self, methodName): """Run once on class initialisation.""" unittest.TestCase.__init__(self, methodName) # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL self.mMapRegistry = QgsMapLayerRegistry.instance() # create point layer myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr') self.mMapRegistry.addMapLayer(self.mPointLayer) # create polygon layer myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr') self.mMapRegistry.addMapLayer(self.mPolygonLayer) # create two raster layers myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif') self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1") self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2") myMultiBandRenderer1 = QgsMultiBandColorRenderer(self.mRasterLayer1.dataProvider(), 2, 3, 4) self.mRasterLayer1.setRenderer(myMultiBandRenderer1) self.mMapRegistry.addMapLayer(self.mRasterLayer1) myMultiBandRenderer2 = QgsMultiBandColorRenderer(self.mRasterLayer2.dataProvider(), 2, 3, 4) self.mRasterLayer2.setRenderer(myMultiBandRenderer2) self.mMapRegistry.addMapLayer(self.mRasterLayer2) # to match blend modes test comparisons background self.mCanvas = CANVAS self.mCanvas.setCanvasColor(QColor(152, 219, 249)) self.mMap = self.mCanvas.map() self.mMap.resize(QSize(400, 400)) self.mMapRenderer = self.mCanvas.mapRenderer() self.mMapRenderer.setOutputSize(QSize(400, 400), 72)
def createVrt(inventario, vrt): #Camada de inventario layer = processing.getObject(Inventario) count = 0 size = layer.featureCount() p = 0 progress.setPercentage(p) rasterList = [] for feature in layer.getFeatures(): filename = feature['fileName'] raster = QgsRasterLayer(filename, filename) if Override_CRS: raster.setCrs( QgsCoordinateReferenceSystem(int(CRS.split(':')[-1]), QgsCoordinateReferenceSystem.EpsgCrsId) ) rasterList.append(raster) ovr = filename+'.ovr' if not os.path.isfile(ovr): progress.setText('Fazendo Pirâmides...') #('gdalogr:overviews', input, levels=8, clean=False, resampling_method=0(nearest), format=1(Gtiff .ovr)) processing.runalg('gdalogr:overviews', raster, '4 8 32 128', True, 0, 1) if int(float(count)/size*100) != p: p = int(float(count)/size*100) progress.setPercentage(p) count += 1 progress.setText('Fazendo raster virtual...') processing.runalg('gdalogr:buildvirtualraster', rasterList, 0, False, False, VRT)
def testLayerRemovalBeforeRun(self): """test behavior when layer is removed before task begins""" path = os.path.join(unitTestDataPath(), 'raster', 'with_color_table.tif') raster_layer = QgsRasterLayer(path, "test") self.assertTrue(raster_layer.isValid()) pipe = QgsRasterPipe() self.assertTrue(pipe.set(raster_layer.dataProvider().clone())) tmp = create_temp_filename('remove_layer.tif') writer = QgsRasterFileWriter(tmp) task = QgsRasterFileWriterTask(writer, pipe, 100, 100, raster_layer.extent(), raster_layer.crs()) task.writeComplete.connect(self.onSuccess) task.errorOccurred.connect(self.onFail) # remove layer raster_layer = None QgsApplication.taskManager().addTask(task) while not self.success and not self.fail: QCoreApplication.processEvents() # in this case will still get a positive result - since the pipe is cloned before the task # begins the task is no longer dependent on the original layer self.assertTrue(self.success) self.assertFalse(self.fail) self.assertTrue(os.path.exists(tmp))
def testPalettedColorTableToClassData(self): entries = [QgsColorRampShader.ColorRampItem(5, QColor(255, 0, 0), 'item1'), QgsColorRampShader.ColorRampItem(3, QColor(0, 255, 0), 'item2'), QgsColorRampShader.ColorRampItem(6, QColor(0, 0, 255), 'item3'), ] classes = QgsPalettedRasterRenderer.colorTableToClassData(entries) self.assertEqual(classes[0].value, 5) self.assertEqual(classes[1].value, 3) self.assertEqual(classes[2].value, 6) self.assertEqual(classes[0].label, 'item1') self.assertEqual(classes[1].label, 'item2') self.assertEqual(classes[2].label, 'item3') self.assertEqual(classes[0].color.name(), '#ff0000') self.assertEqual(classes[1].color.name(), '#00ff00') self.assertEqual(classes[2].color.name(), '#0000ff') # test #13263 path = os.path.join(unitTestDataPath('raster'), 'hub13263.vrt') info = QFileInfo(path) base_name = info.baseName() layer = QgsRasterLayer(path, base_name) self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path)) classes = QgsPalettedRasterRenderer.colorTableToClassData(layer.dataProvider().colorTable(1)) self.assertEqual(len(classes), 4) classes = QgsPalettedRasterRenderer.colorTableToClassData(layer.dataProvider().colorTable(15)) self.assertEqual(len(classes), 256)
def testIdentify(self): myPath = os.path.join(unitTestDataPath(), 'landsat.tif') myFileInfo = QFileInfo(myPath) myBaseName = myFileInfo.baseName() myRasterLayer = QgsRasterLayer(myPath, myBaseName) myMessage = 'Raster not loaded: %s' % myPath assert myRasterLayer.isValid(), myMessage myPoint = QgsPoint(786690, 3345803) #print 'Extents: %s' % myRasterLayer.extent().toString() #myResult, myRasterValues = myRasterLayer.identify(myPoint) #assert myResult myRasterValues = myRasterLayer.dataProvider().identify(myPoint, QgsRasterDataProvider.IdentifyFormatValue ) assert len( myRasterValues ) > 0 # Get the name of the first band myBand = myRasterValues.keys()[0] #myExpectedName = QString('Band 1') myExpectedBand = 1 myMessage = 'Expected "%s" got "%s" for first raster band name' % ( myExpectedBand, myBand) assert myExpectedBand == myBand, myMessage # Convert each band value to a list of ints then to a string myValues = myRasterValues.values() myIntValues = [] for myValue in myValues: #myIntValues.append(int(str(myValue))) myIntValues.append( myValue.toInt()[0] ) myValues = str(myIntValues) myExpectedValues = '[127, 141, 112, 72, 86, 126, 156, 211, 170]' myMessage = 'Expected: %s\nGot: %s' % (myValues, myExpectedValues) self.assertEquals(myValues, myExpectedValues, myMessage)
def toMapLayer(self): from qgis.core import QgsRasterLayer, QgsContrastEnhancement rl = QgsRasterLayer(self.gdalUri(), self.name) if rl.isValid(): rl.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum) return rl
def accept(self): input_path = str(self.leInputPath.text()) output_path = str(self.leOutputPath.text()) if not output_path.endswith('.tif'): QMessageBox.warning( self.parent, self.tr('InaSAFE'), (self.tr('Output file name must be tif file'))) if not os.path.exists(input_path): QMessageBox.warning( self.parent, self.tr('InaSAFE'), (self.tr('Input file is not exist'))) return my_algorithm = str(self.cboAlgorithm.currentText()).lower() fileName = convert_mmi_data(input_path, output_path, the_algorithm=my_algorithm, algorithm_name=False) if self.cBLoadLayer.isChecked(): fileInfo = QFileInfo(fileName) baseName = fileInfo.baseName() my_raster_layer = QgsRasterLayer(fileName, baseName) if not my_raster_layer.isValid(): LOGGER.debug("Failed to load") else: QgsMapLayerRegistry.instance().addMapLayer(my_raster_layer) self.done(self.Accepted) if not self.test_mode: QMessageBox.warning( self.parent, self.tr('InaSAFE'), (self.tr('Success to convert %1 to %2'). arg(input_path).arg(output_path)))
def accept(self): """Creates and loads the WMS layer.""" self.close() currentIndex = self.comboBoxLayer.currentIndex() currentLayerId, unused_dataType = self.comboBoxLayer.itemData(currentIndex) currentLayerName = unicode(self.comboBoxLayer.currentText()) mapId = self.labelMapId.text() # Create the WMS layer token = oauth2_utils.getToken() url = 'https://mapsengine.google.com/%s-4/wms/%s/' wmsUrl = url % (mapId, token.access_token) currentFormatIndex = self.comboBoxFormat.currentIndex() imageFormat = unicode(self.comboBoxFormat.itemData(currentFormatIndex)) crs = self.comboBoxCrs.currentText() uri = QgsDataSourceURI() uri.setParam('url', wmsUrl) uri.setParam('layers', currentLayerId) uri.setParam('format', imageFormat) uri.setParam('crs', crs) uri.setParam('styles', '') rlayer = QgsRasterLayer(str(uri.encodedUri()), currentLayerName, 'wms') if rlayer.isValid(): QgsMapLayerRegistry.instance().addMapLayer(rlayer) else: logText = 'Failed to add WMS layer %s with URI %s' % ( currentLayerName, str(uri.encodedUri())) warnText = 'Failed to add WMS layer %s' % currentLayerName QgsMessageLog.logMessage(logText, 'GMEConnector', QgsMessageLog.CRITICAL) self.iface.messageBar().pushMessage( 'Google Maps Engine Connector', warnText, level=QgsMessageBar.CRITICAL, duration=3)
def test_run_without_population_field(self): impact_function = AshRasterPlacesFunction.instance() hazard_path = standard_data_path("hazard", "ash_raster_wgs84.tif") exposure_path = standard_data_path("exposure", "places.shp") hazard_layer = QgsRasterLayer(hazard_path, "Ash") exposure_layer = QgsVectorLayer(exposure_path, "Places", "ogr") impact_function.hazard = hazard_layer impact_function.exposure = exposure_layer # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()] impact_function.requested_extent = rect_extent impact_function.run() impact_layer = impact_function.impact # Extract calculated result impact_data = impact_layer.get_data() # 1 = inundated, 2 = wet, 3 = dry expected_result = {0: 0, 1: 135, 2: 62, 3: 1, 4: 0} result = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0} for feature in impact_data: inundated_status = feature[impact_function.target_field] result[inundated_status] += 1 self.assertDictEqual(expected_result, result)
def testIdentify(self): myPath = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'testdata', 'landsat.tif')) myFileInfo = QFileInfo(myPath) myBaseName = myFileInfo.baseName() myRasterLayer = QgsRasterLayer(myPath, myBaseName) myMessage = 'Raster not loaded: %s' % myPath assert myRasterLayer.isValid(), myMessage myPoint = QgsPoint(786690, 3345803) #print 'Extents: %s' % myRasterLayer.extent().toString() myResult, myRasterValues = myRasterLayer.identify(myPoint) assert myResult # Get the name of the first band myBandName = myRasterValues.keys()[0] myExpectedName = QString('Band 1') myMessage = 'Expected "%s" got "%s" for first raster band name' % ( myExpectedName, myBandName) assert myExpectedName == myBandName, myMessage # Convert each band value to a list of ints then to a string myValues = myRasterValues.values() myIntValues = [] for myValue in myValues: myIntValues.append(int(str(myValue))) myValues = str(myIntValues) myExpectedValues = '[127, 141, 112, 72, 86, 126, 156, 211, 170]' myMessage = 'Expected: %s\nGot: %s' % (myValues, myExpectedValues) self.assertEquals(myValues, myExpectedValues, myMessage)
def test_run(self): function = FloodRasterRoadsFunction.instance() hazard_path = test_data_path('hazard', 'continuous_flood_20_20.asc') exposure_path = test_data_path('exposure', 'roads.shp') # noinspection PyCallingNonCallable hazard_layer = QgsRasterLayer(hazard_path, 'Flood') # noinspection PyCallingNonCallable exposure_layer = QgsVectorLayer(exposure_path, 'Roads', 'ogr') # Let's set the extent to the hazard extent extent = hazard_layer.extent() rect_extent = [ extent.xMinimum(), extent.yMaximum(), extent.xMaximum(), extent.yMinimum()] function.hazard = SafeLayer(hazard_layer) function.exposure = SafeLayer(exposure_layer) function.requested_extent = rect_extent function.run() impact = function.impact keywords = impact.get_keywords() self.assertEquals(function.target_field, keywords['target_field']) expected_inundated_feature = 182 count = sum(impact.get_data(attribute=function.target_field)) self.assertEquals(count, expected_inundated_feature)
def generateLayerFromGeoTIFFURL(self, geoTiffUrl, layerName): """Generates a new layer based on the GeoTIFF URL provided for the WCS service. This method also appends to the name an UUID so the uniqueness of it's name and ID is guaranteed to avoid problems when managing asynchronous generation of layers between different processes. :param geoTiffUrl: the download URL for this image. :type geoTiffUrl: str :param layerName: the name to give to this layer. The resultant layer will have an UUID appended. :type layerName: str """ tiff_string = "{ln}{id}".format(ln=layerName, id=uuid.uuid4()) layer = QgsRasterLayer(geoTiffUrl, tiff_string) if Utilities.is_linux(): import requests with tempfile.NamedTemporaryFile(suffix=".tiff", delete=False) as f: r = requests.get(geoTiffUrl, stream=True) with open(f.name, "wb") as g: for chunk in r.iter_content(): g.write(chunk) layer = QgsRasterLayer(f.name, layerName) else: layer = QgsRasterLayer(geoTiffUrl, layerName) if layer.isValid(): return layer else: msg = "Couldn't create a valid layer." self.standardMessage.emit(msg)
def load_layer(layer_path): """Helper to load and return a single QGIS layer. :param layer_path: Path name to raster or vector file. :type layer_path: str :returns: Layer instance. :rtype: QgsMapLayer """ # Extract basename and absolute path file_name = os.path.split(layer_path)[-1] # In case path was absolute base_name, extension = os.path.splitext(file_name) # Create QGis Layer Instance if extension in ['.asc', '.tif']: layer = QgsRasterLayer(layer_path, base_name) elif extension in ['.shp']: layer = QgsVectorLayer(layer_path, base_name, 'ogr') else: message = 'File %s had illegal extension' % layer_path raise Exception(message) # noinspection PyUnresolvedReferences message = 'Layer "%s" is not valid' % layer.source() # noinspection PyUnresolvedReferences if not layer.isValid(): print message # noinspection PyUnresolvedReferences if not layer.isValid(): raise Exception(message) return layer
def addToCanvas(self, roles): if self.canOpen(roles): if not oauth2_supported: iface.messageBar().pushMessage( "Cannot load basemap", "OAuth support is not available", QgsMessageBar.WARNING) else: authcfg = get_oauth_authcfg() if authcfg is None: iface.messageBar().pushMessage( "Cannot load basemap", "Cannot find a valid authentication configuration", QgsMessageBar.WARNING) else: authId = authcfg.id() layer = QgsRasterLayer('authcfg={authcfg}&type=xyz&url={url}'.format(url=urllib2.quote("{}?version={}".format(self.url, pluginSetting("apiVersion"))), authcfg=authId), self.name, "wms") if layer.isValid(): QgsMapLayerRegistry.instance().addMapLayer(layer) else: iface.messageBar().pushMessage( "Cannot load basemap", "Cannot create basemap layer", QgsMessageBar.WARNING) else: webbrowser.open_new(SUBSCRIBE_URL)
def __init__(self, methodName): """Run once on class initialisation.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'landsat.tif') rasterFileInfo = QFileInfo(myPath) mRasterLayer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( mRasterLayer.dataProvider(), 2, 3, 4) mRasterLayer.setRenderer(rasterRenderer) #pipe = mRasterLayer.pipe() #assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsMapLayerRegistry.instance().addMapLayers([mRasterLayer]) # create composition with composer map self.mMapRenderer = QgsMapRenderer() layerStringList = QStringList() layerStringList.append(mRasterLayer.id()) self.mMapRenderer.setLayerSet(layerStringList) self.mMapRenderer.setProjectionsEnabled(False) self.mComposition = QgsComposition(self.mMapRenderer) self.mComposition.setPaperSize(297, 210) self.mComposerMap = QgsComposerMap(self.mComposition, 20, 20, 200, 100) self.mComposerMap.setFrameEnabled(True) self.mComposition.addComposerMap(self.mComposerMap)
def test_clip_raster_small(self): """Raster layers can be clipped in small and precise size. For #710.""" # Create a raster layer layer_name = 'shake' raster_layer = QgsRasterLayer(RASTERPATH, layer_name) message = ( 'Did not find layer "%s" in path "%s"' % (layer_name, RASTERPATH)) assert raster_layer is not None, message # Create a bounding box bounding_box = [97, -3, 104, 1] # Clip the vector to the bbox result = clip_layer(raster_layer, bounding_box) # Check the output is valid assert os.path.exists(result.source()) # Clip and give a desired resolution for the output # small pixel size and high precision # based on pixel size of Flood_Current_Depth_Jakarta_geographic.asc size = 0.00045228819716 result = clip_layer(raster_layer, bounding_box, size) new_raster_layer = QgsRasterLayer(result.source(), layer_name) assert new_raster_layer.isValid(), 'Resampled raster is not valid' message = ( 'Resampled raster has incorrect pixel size. Expected: %.14f, ' 'Actual: %.14f' % ( size, new_raster_layer.rasterUnitsPerPixelX())) result_size = new_raster_layer.rasterUnitsPerPixelX() self.assertAlmostEqual(result_size, size, places=13, msg=message)
def test_read_existing_geopackage(self): """Test we can read an existing geopackage.""" path = standard_data_path('other', 'jakarta.gpkg') import os path = os.path.normpath(os.path.normcase(os.path.abspath(path))) geopackage = QFileInfo(path) data_store = GeoPackage(geopackage) # We should have 3 layers in this geopackage. self.assertEqual(len(data_store.layers()), 3) # Test we can load a vector layer. roads = QgsVectorLayer( data_store.layer_uri('roads'), 'Test', 'ogr' ) self.assertTrue(roads.isValid()) # Test we can load a raster layers. # This currently fails on windows... # So we have decorated it with expected fail on windows # Should pass on other platforms. path = data_store.layer_uri('flood') flood = QgsRasterLayer(path, 'flood') self.assertTrue(flood.isValid())
def toMapLayer(self): from qgis.core import QgsRasterLayer uri=self.uri() schema = "schema="+self.schemaName() if self.schemaName() else '' pgrasterUri= ('PG: dbname=%s host=%s user=%s password=%s port=%s mode=2 %s table=%s') % (uri.database(), uri.host(), uri.username(), uri.password(), uri.port(),schema,self.name) rasterLayer=QgsRasterLayer(pgrasterUri, self.name) rasterLayer.setContrastEnhancementAlgorithm("StretchToMinimumMaximum") return rasterLayer
def createXYZLayer(self, layerType, name): # create XYZ layer with tms url as uri provider = 'wms' url = "type=xyz&url=" + layerType.xyzUrlConfig() layer = QgsRasterLayer(url, name, provider, QgsRasterLayer.LayerOptions()) layer.setCustomProperty('ol_layer_type', layerType.layerTypeName) return layer, layerType.xyzUrlConfig()
def add_layer( self, layer_source, layer_name): layer = QgsRasterLayer(layer_source,self.tr(layer_name),"wms") if not layer.isValid(): # Test if string is valid QMessageBox.information(self.iface.mainWindow(),self.tr(u"Error!"), self.tr(u"Layer has no valid token... Try again!")) QSettings().setValue('lmopendata/token', '') # if layer is incorrect clear token key QgsMapLayerRegistry.instance().addMapLayer(layer)
def special_search(self, easter_code="isogeo"): """Make some special actions in certains cases. :param str easter_code: easter egg label. Available values: * isogeo: display Isogeo logo and zoom in our office location * picasa: change QGS project title """ canvas = iface.mapCanvas() if easter_code == "isogeo": # WMS wms_params = {"service": "WMS", "version": "1.3.0", "request": "GetMap", "layers": "Isogeo:isogeo_logo", "crs": "EPSG:3857", "format": "image/png", "styles": "isogeo_logo", "url": "http://noisy.hq.isogeo.fr:6090/geoserver/Isogeo/ows?" } wms_uri = unquote(urlencode(wms_params)) wms_lyr = QgsRasterLayer(wms_uri, u"Ici c'est Isogeo !", "wms") if wms_lyr.isValid: QgsMapLayerRegistry.instance().addMapLayer(wms_lyr) logger.info("Isogeo easter egg used and WMS displayed!") else: logger.error("WMS layer failed: {}" .format(wms_lyr.error().message())) # WFS uri = QgsDataSourceURI() uri.setParam("url", "http://noisy.hq.isogeo.fr:6090/geoserver/Isogeo/ows?") uri.setParam("service", "WFS") uri.setParam("version", "1.1.0") uri.setParam("typename", "Isogeo:isogeo_logo") uri.setParam("srsname", "EPSG:3857") uri.setParam("restrictToRequestBBOX", "0") wfs_uri = uri.uri() wfs_lyr = QgsVectorLayer(wfs_uri, u"Ici c'est Isogeo !", "WFS") if wfs_lyr.isValid: wfs_style = path.join(path.dirname(path.realpath(__file__)), "isogeo.qml") wfs_lyr.loadNamedStyle(wfs_style) QgsMapLayerRegistry.instance().addMapLayer(wfs_lyr) canvas.setExtent(wfs_lyr.extent()) logger.debug("Isogeo easter egg used") else: logger.error("Esater egg - WFS layer failed: {}" .format(wfs_lyr.error().message())) elif easter_code == "picasa": project = QgsProject.instance() project.setTitle(u"Isogeo, le Picasa de l'information géographique") logger.debug("Picasa easter egg used") else: pass # ending method return
def testTransformContextIsSetInCtor(self): """Test transform context can be set from ctor""" rl = QgsRasterLayer(self.rpath, 'raster') self.assertFalse(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857))) options = QgsRasterLayer.LayerOptions(transformContext=self.ctx) rl = QgsRasterLayer(self.rpath, 'raster', 'gdal', options) self.assertTrue(rl.transformContext().hasTransform(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(3857)))
def toMapLayer(self): from qgis.core import QgsRasterLayer, QgsContrastEnhancement # QGIS has no provider to load rasters, let's use GDAL uri = self.gpkgGdalUri() rl = QgsRasterLayer(uri, self.name) if rl.isValid(): rl.setContrastEnhancement(QgsContrastEnhancement.StretchToMinimumMaximum) return rl
def test_get_raster_layer_list(self): wms_url_with_parameters = self.valid_wms_url # use this list for proper testing... visibility = [True, False, True, True, True, False] # when debugging, use the list below instead # visibility = [True] for i, visible in enumerate(visibility): layer_name = layer_interaction.biuniquify_layer_name('r{}_visible:{}'.format(i, visible)) rlayer = QgsRasterLayer(wms_url_with_parameters, layer_name, 'wms') self.assertTrue(rlayer.isValid(), layer_name.join(' is not a valid raster layer')) QgsMapLayerRegistry.instance().addMapLayer(rlayer) self.iface.legendInterface().setLayerVisible(rlayer, visible) self.layer_list.append(layer_name) # get a list of all visible wms layers expected_layers = {} actual_layers = {} visible_raster_layers = layer_interaction.get_raster_layer_list(self.iface, 'visible') for i, visible in enumerate(visibility): if visible: expected_layers[self.layer_list[i]] = True for layer in visible_raster_layers: if '_visible:' in layer.name(): actual_layers[str(layer.name())] = True self.assertDictEqual(expected_layers, actual_layers, 'The returned layers do not match the expected layers.\n\t Expected: {0}\n\t received: {1}.'.format(expected_layers, actual_layers)) # get a list of all invisible wms layers expected_layers = {} actual_layers = {} invisible_raster_layers = layer_interaction.get_raster_layer_list(self.iface, 'invisible') for i, visible in enumerate(visibility): if not visible: expected_layers[self.layer_list[i]] = False for layer in invisible_raster_layers: if '_visible:' in layer.name(): actual_layers[str(layer.name())] = True if layer.name().endswith('True') else False self.assertDictEqual(expected_layers, actual_layers, 'The returned layers do not match the expected layers.\n\t Expected: {0}\n\t received: {1}.'.format(expected_layers, actual_layers)) # get a list of wms layers expected_layers = {} actual_layers = {} invisible_raster_layers = layer_interaction.get_raster_layer_list(self.iface, 'all') for i, visible in enumerate(visibility): expected_layers[self.layer_list[i]] = visible for layer in invisible_raster_layers: if '_visible:' in layer.name(): actual_layers[str(layer.name())] = True if layer.name().endswith('True') else False self.assertDictEqual(expected_layers, actual_layers, 'The returned layers do not match the expected layers.\n\t Expected: {0}\n\t received: {1}.'.format(expected_layers, actual_layers))
def testPaletted(self): """ test paletted raster renderer with raster with color table""" path = os.path.join(unitTestDataPath('raster'), 'with_color_table.tif') info = QFileInfo(path) base_name = info.baseName() layer = QgsRasterLayer(path, base_name) self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path)) renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 1, [ QgsPalettedRasterRenderer.Class(1, QColor(0, 255, 0), 'class 2'), QgsPalettedRasterRenderer.Class(3, QColor(255, 0, 0), 'class 1') ]) self.assertEqual(renderer.nColors(), 2) self.assertEqual(renderer.usesBands(), [1]) # test labels self.assertEqual(renderer.label(1), 'class 2') self.assertEqual(renderer.label(3), 'class 1') self.assertFalse(renderer.label(101)) # test legend symbology - should be sorted by value legend = renderer.legendSymbologyItems() self.assertEqual(legend[0][0], 'class 2') self.assertEqual(legend[1][0], 'class 1') self.assertEqual(legend[0][1].name(), '#00ff00') self.assertEqual(legend[1][1].name(), '#ff0000') # test retrieving classes classes = renderer.classes() self.assertEqual(classes[0].value, 1) self.assertEqual(classes[1].value, 3) self.assertEqual(classes[0].label, 'class 2') self.assertEqual(classes[1].label, 'class 1') self.assertEqual(classes[0].color.name(), '#00ff00') self.assertEqual(classes[1].color.name(), '#ff0000') # test set label # bad index renderer.setLabel(1212, 'bad') renderer.setLabel(3, 'new class') self.assertEqual(renderer.label(3), 'new class') # color ramp r = QgsLimitedRandomColorRamp(5) renderer.setSourceColorRamp(r) self.assertEqual(renderer.sourceColorRamp().type(), 'random') self.assertEqual(renderer.sourceColorRamp().count(), 5) # clone new_renderer = renderer.clone() classes = new_renderer.classes() self.assertEqual(classes[0].value, 1) self.assertEqual(classes[1].value, 3) self.assertEqual(classes[0].label, 'class 2') self.assertEqual(classes[1].label, 'new class') self.assertEqual(classes[0].color.name(), '#00ff00') self.assertEqual(classes[1].color.name(), '#ff0000') self.assertEqual(new_renderer.sourceColorRamp().type(), 'random') self.assertEqual(new_renderer.sourceColorRamp().count(), 5) # write to xml and read doc = QDomDocument('testdoc') elem = doc.createElement('qgis') renderer.writeXml(doc, elem) restored = QgsPalettedRasterRenderer.create( elem.firstChild().toElement(), layer.dataProvider()) self.assertTrue(restored) self.assertEqual(restored.usesBands(), [1]) classes = restored.classes() self.assertTrue(classes) self.assertEqual(classes[0].value, 1) self.assertEqual(classes[1].value, 3) self.assertEqual(classes[0].label, 'class 2') self.assertEqual(classes[1].label, 'new class') self.assertEqual(classes[0].color.name(), '#00ff00') self.assertEqual(classes[1].color.name(), '#ff0000') self.assertEqual(restored.sourceColorRamp().type(), 'random') self.assertEqual(restored.sourceColorRamp().count(), 5) # render test layer.setRenderer(renderer) ms = QgsMapSettings() ms.setLayers([layer]) ms.setExtent(layer.extent()) checker = QgsRenderChecker() checker.setControlName("expected_paletted_renderer") checker.setMapSettings(ms) self.assertTrue(checker.runTest("expected_paletted_renderer"), "Paletted rendering test failed")
def test_run(self): function = TsunamiRasterLandcoverFunction.instance() hazard_path = standard_data_path('hazard', 'tsunami_wgs84.tif') exposure_path = standard_data_path('exposure', 'landcover.shp') # noinspection PyCallingNonCallable hazard_layer = QgsRasterLayer(hazard_path, 'Tsunami') # noinspection PyCallingNonCallable exposure_layer = QgsVectorLayer(exposure_path, 'Land Cover', 'ogr') self.assertTrue(hazard_layer.isValid()) self.assertTrue(exposure_layer.isValid()) rect_extent = [106.5, -6.5, 107, -6] function.hazard = hazard_layer function.exposure = exposure_layer function.requested_extent = rect_extent function.run() impact = function.impact impact = safe_to_qgis_layer(impact) expected = { 'data': [[u'Population', u'Dry Zone', None, 793.6916054134609], [u'Water', u'Low Hazard Zone', None, 16.298813953855912], [ u'Population', u'Very High Hazard Zone', None, 12.45623642166847 ], [u'Water', u'Very High Hazard Zone', None, 0.08036139883589728], [u'Water', u'Medium Hazard Zone', None, 12.1033540507973], [u'Population', u'Low Hazard Zone', None, 28.866862427357326], [u'Water', u'Dry Zone', None, 164.67113858186028], [u'Meadow', u'Dry Zone', None, 249.95443689559693], [u'Population', u'Medium Hazard Zone', None, 30.69211822286981], [u'Water', u'High Hazard Zone', None, 5.835228232982915], [u'Population', u'High Hazard Zone', None, 29.72789895440279], [u'Forest', u'Dry Zone', None, 99.489344261353]], 'groups': ('landcover', 'hazard', 'zone') } ordered_columns = function.impact.impact_data.get('ordered columns') affected_columns = function.impact.impact_data.get('affected columns') expected = FlatTable().from_dict( groups=expected['groups'], data=expected['data'], ) expected = PivotTable(expected, row_field='landcover', column_field='hazard', columns=ordered_columns, affected_columns=affected_columns) self.assertEqual(impact.dataProvider().featureCount(), 72) table = function.impact.impact_data['impact table'] table = FlatTable().from_dict( groups=table['groups'], data=table['data'], ) table = PivotTable(table, row_field='landcover', column_field='hazard', columns=ordered_columns, affected_columns=affected_columns) for index, value in enumerate(expected.total_rows): self.assertAlmostEqual(value, table.total_rows[index]) for index, value in enumerate(expected.total_columns): self.assertAlmostEqual(value, table.total_columns[index]) for index, value in enumerate(expected.total_rows_affected): self.assertAlmostEqual(value, table.total_rows_affected[index]) for index, value in enumerate(expected.rows): self.assertAlmostEqual(value, table.rows[index]) for index, value in enumerate(expected.columns): self.assertAlmostEqual(value, table.columns[index]) for index, value in enumerate(expected.affected_columns): self.assertAlmostEqual(value, table.affected_columns[index]) # This is a list of list so we unpack both for index, value in enumerate(expected.data): for value_index, value_value in enumerate(value): self.assertAlmostEqual(value_value, table.data[index][value_index]) self.assertAlmostEqual(expected.total_affected, table.total_affected)
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 load(fileName, name=None, crs=None, style=None, isRaster=False): """Loads a layer/table into the current project, given its file. """ if fileName is None: return prjSetting = None settings = QgsSettings() if crs is not None: prjSetting = settings.value('/Projections/defaultBehavior') settings.setValue('/Projections/defaultBehavior', '') if name is None: name = os.path.split(fileName)[1] if isRaster: qgslayer = QgsRasterLayer(fileName, name) if qgslayer.isValid(): if crs is not None and qgslayer.crs() is None: qgslayer.setCrs(crs, False) if style is None: style = ProcessingConfig.getSetting( ProcessingConfig.RASTER_STYLE) qgslayer.loadNamedStyle(style) QgsProject.instance().addMapLayers([qgslayer]) else: if prjSetting: settings.setValue('/Projections/defaultBehavior', prjSetting) raise RuntimeError( QCoreApplication.translate( 'dataobject', 'Could not load layer: {0}\nCheck the processing framework log to look for errors.' ).format(fileName)) else: qgslayer = QgsVectorLayer(fileName, name, 'ogr') if qgslayer.isValid(): if crs is not None and qgslayer.crs() is None: qgslayer.setCrs(crs, False) if style is None: if qgslayer.geometryType() == QgsWkbTypes.PointGeometry: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_POINT_STYLE) elif qgslayer.geometryType() == QgsWkbTypes.LineGeometry: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_POLYGON_STYLE) qgslayer.loadNamedStyle(style) QgsProject.instance().addMapLayers([qgslayer]) if prjSetting: settings.setValue('/Projections/defaultBehavior', prjSetting) return qgslayer
class TestQgsBlendModes(TestCase): def __init__(self, methodName): """Run once on class initialisation.""" unittest.TestCase.__init__(self, methodName) # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL self.mMapRegistry = QgsMapLayerRegistry.instance() # create point layer myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr') self.mMapRegistry.addMapLayer(self.mPointLayer) # create polygon layer myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr') self.mMapRegistry.addMapLayer(self.mPolygonLayer) # create line layer myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp') self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr') self.mMapRegistry.addMapLayer(self.mLineLayer) # create two raster layers myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif') self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1") self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2") myMultiBandRenderer1 = QgsMultiBandColorRenderer(self.mRasterLayer1.dataProvider(), 2, 3, 4) self.mRasterLayer1.setRenderer(myMultiBandRenderer1) self.mMapRegistry.addMapLayer(self.mRasterLayer1) myMultiBandRenderer2 = QgsMultiBandColorRenderer(self.mRasterLayer2.dataProvider(), 2, 3, 4) self.mRasterLayer2.setRenderer(myMultiBandRenderer2) self.mMapRegistry.addMapLayer(self.mRasterLayer2) # to match blend modes test comparisons background self.mCanvas = CANVAS self.mCanvas.setCanvasColor(QColor(152, 219, 249)) self.mMap = self.mCanvas.map() self.mMap.resize(QSize(400, 400)) self.mMapRenderer = self.mCanvas.mapRenderer() self.mMapRenderer.setOutputSize(QSize(400, 400), 72) def testVectorBlending(self): """Test that blend modes work for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mPointLayer.extent()) #Set blending modes for both layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsRenderChecker() checker.setControlName("expected_vector_blendmodes") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("vector_blendmodes"); myMessage = ('vector blending failed') assert myResult, myMessage #Reset layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver) def testVectorFeatureBlending(self): """Test that feature blend modes work for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mPointLayer.extent()) #Set feature blending for line layer self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus) checker = QgsRenderChecker() checker.setControlName("expected_vector_featureblendmodes") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("vector_featureblendmodes"); myMessage = ('vector feature blending failed') assert myResult, myMessage #Reset layers self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_SourceOver) def testVectorLayerTransparency(self): """Test that layer transparency works for vector layers.""" #Add vector layers to map myLayers = [] myLayers.append(self.mLineLayer.id()) myLayers.append(self.mPolygonLayer.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mPointLayer.extent()) #Set feature blending for line layer self.mLineLayer.setLayerTransparency( 50 ) checker = QgsRenderChecker() checker.setControlName("expected_vector_layertransparency") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("vector_layertransparency"); myMessage = ('vector layer transparency failed') assert myResult, myMessage def testRasterBlending(self): """Test that blend modes work for raster layers.""" #Add raster layers to map myLayers = [] myLayers.append(self.mRasterLayer1.id()) myLayers.append(self.mRasterLayer2.id()) self.mMapRenderer.setLayerSet(myLayers) self.mMapRenderer.setExtent(self.mRasterLayer1.extent()) #Set blending mode for top layer self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Plus) checker = QgsRenderChecker() checker.setControlName("expected_raster_blendmodes") checker.setMapRenderer(self.mMapRenderer) myResult = checker.runTest("raster_blendmodes"); myMessage = ('raster blending failed') assert myResult, myMessage
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemMap def setUp(self): self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n" def tearDown(self): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(self.report) def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() QgsProject.instance().addMapLayers([self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map) def testOverviewMap(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) checker = QgsLayoutChecker('composermap_overview', self.layout) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testOverviewMapBlend(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsLayoutChecker('composermap_overview_blending', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testOverviewMapInvert(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(True) checker = QgsLayoutChecker('composermap_overview_invert', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testOverviewMapCenter(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(192, -288, 320, -224) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(False) overviewMap.overview().setCentered(True) checker = QgsLayoutChecker('composermap_overview_center', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) self.assertTrue(myTestResult, myMessage) def testAsMapLayer(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() map = QgsLayoutItemMap(l) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) l.addLayoutItem(map) overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(map) layer = overviewMap.overview().asMapLayer() self.assertIsNotNone(layer) self.assertTrue(layer.isValid()) self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))']) # check that layer has correct renderer fill_symbol = QgsFillSymbol.createSimple({'color': '#00ff00', 'outline_color': '#ff0000', 'outline_width': '10'}) overviewMap.overview().setFrameSymbol(fill_symbol) layer = overviewMap.overview().asMapLayer() self.assertIsInstance(layer.renderer(), QgsSingleSymbolRenderer) self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['color'], '0,255,0,255') self.assertEqual(layer.renderer().symbol().symbolLayer(0).properties()['outline_color'], '255,0,0,255') # test layer blend mode self.assertEqual(layer.blendMode(), QPainter.CompositionMode_SourceOver) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Clear) layer = overviewMap.overview().asMapLayer() self.assertEqual(layer.blendMode(), QPainter.CompositionMode_Clear) # should have no effect overviewMap.setMapRotation(45) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt() for f in layer.getFeatures()], ['Polygon ((96 -120, 160 -120, 160 -152, 96 -152, 96 -120))']) map.setMapRotation(15) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 155 -112, 163 -143, 101 -160, 93 -129))']) # with reprojection map.setCrs(QgsCoordinateReferenceSystem('EPSG:3875')) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((93 -129, 96 -128, 99 -127, 102 -126, 105 -126, 108 -125, 111 -124, 114 -123, 116 -123, 119 -122, 122 -121, 125 -120, 128 -119, 131 -119, 134 -118, 137 -117, 140 -116, 143 -115, 146 -115, 149 -114, 152 -113, 155 -112, 155 -114, 156 -115, 156 -117, 156 -118, 157 -120, 157 -121, 158 -123, 158 -124, 158 -126, 159 -127, 159 -128, 160 -130, 160 -131, 160 -133, 161 -134, 161 -136, 161 -137, 162 -139, 162 -140, 163 -142, 163 -143, 160 -144, 157 -145, 154 -146, 151 -146, 148 -147, 145 -148, 142 -149, 140 -149, 137 -150, 134 -151, 131 -152, 128 -153, 125 -153, 122 -154, 119 -155, 116 -156, 113 -157, 110 -157, 107 -158, 104 -159, 101 -160, 101 -158, 100 -157, 100 -155, 100 -154, 99 -152, 99 -151, 98 -149, 98 -148, 98 -146, 97 -145, 97 -144, 96 -142, 96 -141, 96 -139, 95 -138, 95 -136, 95 -135, 94 -133, 94 -132, 93 -130, 93 -129))']) map.setCrs(overviewMap.crs()) # with invert overviewMap.overview().setInverted(True) layer = overviewMap.overview().asMapLayer() self.assertEqual([f.geometry().asWkt(0) for f in layer.getFeatures()], ['Polygon ((-53 -128, 128 53, 309 -128, 128 -309, -53 -128),(93 -129, 101 -160, 163 -143, 155 -112, 93 -129))']) def test_StackingPosition(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap) self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMap) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer) self.assertEqual(overviewMap.overview().stackingPosition(), QgsLayoutItemMapItem.StackBelowMapLayer) overviewMap.overview().setStackingLayer(self.raster_layer) self.assertEqual(overviewMap.overview().stackingLayer(), self.raster_layer) overviewMap.overview().setStackingLayer(self.vector_layer) self.assertEqual(overviewMap.overview().stackingLayer(), self.vector_layer) overviewMap.overview().setStackingLayer(None) self.assertIsNone(overviewMap.overview().stackingLayer()) def test_ModifyMapLayerList(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) map = QgsLayoutItemMap(l) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) l.addLayoutItem(map) self.assertFalse(overviewMap.overviews().modifyMapLayerList([])) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) overviewMap.overview().setLinkedMap(map) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingLayer(self.raster_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer]) overviewMap.overview().setStackingLayer(self.vector_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer) overviewMap.overview().setStackingLayer(None) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingLayer(self.raster_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingLayer(self.vector_layer) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, overviewMap.overview().asMapLayer(), self.vector_layer]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [overviewMap.overview().asMapLayer(), self.raster_layer, self.vector_layer]) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLabels) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [self.raster_layer, self.vector_layer]) # two overviews overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMap) overviewMap.overviews().addOverview(QgsLayoutItemMapOverview('x', overviewMap)) overviewMap.overviews().overview(1).setLinkedMap(map) overviewMap.overviews().overview(1).setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLabels) self.assertEqual(overviewMap.overviews().modifyMapLayerList([self.raster_layer, self.vector_layer]), [overviewMap.overviews().overview(1).asMapLayer(), self.raster_layer, self.vector_layer, overviewMap.overview().asMapLayer()]) def testOverviewStacking(self): l = QgsLayout(QgsProject.instance()) l.initializeDefaults() map = QgsLayoutItemMap(l) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) map.setLayers([self.raster_layer]) l.addLayoutItem(map) overviewMap = QgsLayoutItemMap(l) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) l.addLayoutItem(overviewMap) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) map.setExtent(myRectangle) myRectangle2 = QgsRectangle(-20, -276, 276, 20) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(map) overviewMap.overview().setInverted(True) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackBelowMapLayer) overviewMap.overview().setStackingLayer(self.raster_layer) checker = QgsLayoutChecker('composermap_overview_belowmap', l) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.assertTrue(myTestResult, myMessage) overviewMap.overview().setStackingPosition(QgsLayoutItemMapItem.StackAboveMapLayer) overviewMap.overview().setStackingLayer(self.raster_layer) checker = QgsLayoutChecker('composermap_overview_abovemap', l) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.assertTrue(myTestResult, myMessage)
def testSetDataSource(self): """Test change data source""" temp_dir = QTemporaryDir() options = QgsDataProvider.ProviderOptions() myPath = os.path.join(unitTestDataPath('raster'), 'band1_float32_noct_epsg4326.tif') myFileInfo = QFileInfo(myPath) myBaseName = myFileInfo.baseName() layer = QgsRasterLayer(myPath, myBaseName) renderer = QgsSingleBandGrayRenderer(layer.dataProvider(), 2) image = layer.previewAsImage(QSize(400, 400)) self.assertFalse(image.isNull()) self.assertTrue(image.save(os.path.join(temp_dir.path(), 'expected.png'), "PNG")) layer.setDataSource(myPath.replace('4326.tif', '4326-BAD_SOURCE.tif'), 'bad_layer', 'gdal', options) self.assertFalse(layer.isValid()) image = layer.previewAsImage(QSize(400, 400)) self.assertTrue(image.isNull()) layer.setDataSource(myPath.replace('4326-BAD_SOURCE.tif', '4326.tif'), 'bad_layer', 'gdal', options) self.assertTrue(layer.isValid()) image = layer.previewAsImage(QSize(400, 400)) self.assertFalse(image.isNull()) self.assertTrue(image.save(os.path.join(temp_dir.path(), 'actual.png'), "PNG")) self.assertTrue(filecmp.cmp(os.path.join(temp_dir.path(), 'actual.png'), os.path.join(temp_dir.path(), 'expected.png')), False)
def showFileDialog(self, seldir): settings = QgsSettings() text = str(self.text.text()) if os.path.isdir(text): path = text elif not seldir and os.path.isdir(os.path.dirname(text)): path = os.path.dirname(text) elif settings.contains('/Processing/LastInputPath'): path = str(settings.value('/Processing/LastInputPath')) else: path = '' if not seldir: ret, selected_filter = QFileDialog.getOpenFileNames( self, self.tr('Select Files'), path, getFileFilter(self.param)) else: ret = QFileDialog.getExistingDirectory(self, self.tr('Select Directory'), path) if ret: if seldir: settings.setValue('/Processing/LastInputPath', ret) files = [] for pp in Path(ret).rglob("*"): if not pp.is_file(): continue p = pp.as_posix() if ((isinstance(self.param, QgsProcessingParameterRasterLayer) or (isinstance(self.param, QgsProcessingParameterMultipleLayers) and self.param.layerType() == QgsProcessing.TypeRaster)) and not QgsRasterLayer.isValidRasterFileName(p)): continue files.append(p) if not files: return else: files = list(ret) settings.setValue('/Processing/LastInputPath', os.path.dirname(str(files[0]))) for i, filename in enumerate(files): files[i] = dataobjects.getRasterSublayer(filename, self.param) if len(files) == 1: self.text.setText(files[0]) self.textEditingFinished() else: if isinstance(self.param, QgsProcessingParameterMultipleLayers): self.text.setText(';'.join(str(f) for f in files)) else: rowdif = len(files) - (self._table().rowCount() - self.row) for i in range(rowdif): self._panel().addRow() for i, f in enumerate(files): self._table().cellWidget(i + self.row, self.col).setValue(f)
True) # supply path to qgis install location # Now import the processing toolbox import processing # QGIS algorithm runner # Import all native QGIS algorithms QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms()) # --- QGIS analysis # Convert Path() to string for QGIS catchment_file = str(catchment_path / catchment_name) land_file = str(land_path / land_name) # Load the shape and raster layer_polygon = QgsVectorLayer(catchment_file, 'merit_hydro_basin', 'ogr') layer_raster = QgsRasterLayer(land_file, 'modis_land_classes') # Check we loaded the layers correctly if not layer_raster.isValid(): print('Raster layer failed to load') if not layer_polygon.isValid(): print('Polygon layer failed to load') # Specify the parameters for the zonalHistogram function band = 1 # raster band with the data we are after params = { 'COLUMN_PREFIX': 'IGBP_', 'INPUT_RASTER': layer_raster, 'INPUT_VECTOR': layer_polygon, 'OUTPUT': str(intersect_path / intersect_name),
def testPalettedClassDataFromLayer(self): # no layer classes = QgsPalettedRasterRenderer.classDataFromRaster(None, 1) self.assertFalse(classes) # 10 class layer path = os.path.join(unitTestDataPath('raster'), 'with_color_table.tif') info = QFileInfo(path) base_name = info.baseName() layer10 = QgsRasterLayer(path, base_name) classes = QgsPalettedRasterRenderer.classDataFromRaster( layer10.dataProvider(), 1) self.assertEqual(len(classes), 10) self.assertEqual(classes[0].value, 1) self.assertEqual(classes[0].label, '1') self.assertEqual(classes[1].value, 2) self.assertEqual(classes[1].label, '2') self.assertEqual(classes[2].value, 3) self.assertEqual(classes[2].label, '3') self.assertEqual(classes[3].value, 4) self.assertEqual(classes[3].label, '4') self.assertEqual(classes[4].value, 5) self.assertEqual(classes[4].label, '5') self.assertEqual(classes[5].value, 6) self.assertEqual(classes[5].label, '6') self.assertEqual(classes[6].value, 7) self.assertEqual(classes[6].label, '7') self.assertEqual(classes[7].value, 8) self.assertEqual(classes[7].label, '8') self.assertEqual(classes[8].value, 9) self.assertEqual(classes[8].label, '9') self.assertEqual(classes[9].value, 10) self.assertEqual(classes[9].label, '10') # bad band self.assertFalse( QgsPalettedRasterRenderer.classDataFromRaster( layer10.dataProvider(), 10101010)) # with ramp r = QgsGradientColorRamp(QColor(200, 0, 0, 100), QColor(0, 200, 0, 200)) classes = QgsPalettedRasterRenderer.classDataFromRaster( layer10.dataProvider(), 1, r) self.assertEqual(len(classes), 10) self.assertEqual(classes[0].color.name(), '#c80000') self.assertEqual(classes[1].color.name(), '#b21600') self.assertEqual(classes[2].color.name(), '#9c2c00') self.assertEqual(classes[3].color.name(), '#854200') self.assertEqual(classes[4].color.name(), '#6f5900') self.assertEqual(classes[5].color.name(), '#596f00') self.assertEqual(classes[6].color.name(), '#428500') self.assertEqual(classes[7].color.name(), '#2c9c00') self.assertEqual(classes[8].color.name(), '#16b200') self.assertEqual(classes[9].color.name(), '#00c800') # 30 class layer path = os.path.join(unitTestDataPath('raster'), 'unique_1.tif') info = QFileInfo(path) base_name = info.baseName() layer10 = QgsRasterLayer(path, base_name) classes = QgsPalettedRasterRenderer.classDataFromRaster( layer10.dataProvider(), 1) self.assertEqual(len(classes), 30) expected = [ 11, 21, 22, 24, 31, 82, 2002, 2004, 2014, 2019, 2027, 2029, 2030, 2080, 2081, 2082, 2088, 2092, 2097, 2098, 2099, 2105, 2108, 2110, 2114, 2118, 2126, 2152, 2184, 2220 ] self.assertEqual([c.value for c in classes], expected) # bad layer path = os.path.join(unitTestDataPath('raster'), 'hub13263.vrt') info = QFileInfo(path) base_name = info.baseName() layer = QgsRasterLayer(path, base_name) classes = QgsPalettedRasterRenderer.classDataFromRaster( layer.dataProvider(), 1) self.assertFalse(classes)
def testImportIntoGpkg(self): # init target file test_gpkg = tempfile.mktemp(suffix='.gpkg', dir=self.testDataDir) gdal.GetDriverByName('GPKG').Create(test_gpkg, 1, 1, 1) source = QgsRasterLayer( os.path.join(self.testDataDir, 'raster', 'band3_byte_noct_epsg4326.tif'), 'my', 'gdal') self.assertTrue(source.isValid()) provider = source.dataProvider() fw = QgsRasterFileWriter(test_gpkg) fw.setOutputFormat('gpkg') fw.setCreateOptions( ['RASTER_TABLE=imported_table', 'APPEND_SUBDATASET=YES']) pipe = QgsRasterPipe() self.assertTrue(pipe.set(provider.clone())) projector = QgsRasterProjector() projector.setCrs(provider.crs(), provider.crs()) self.assertTrue(pipe.set(projector)) self.assertEqual( fw.writeRaster(pipe, provider.xSize(), provider.ySize(), provider.extent(), provider.crs()), 0) # Check that the test geopackage contains the raster layer and compare rlayer = QgsRasterLayer('GPKG:%s:imported_table' % test_gpkg) self.assertTrue(rlayer.isValid()) out_provider = rlayer.dataProvider() for i in range(3): src_data = provider.block(i + 1, provider.extent(), source.width(), source.height()) out_data = out_provider.block(i + 1, out_provider.extent(), rlayer.width(), rlayer.height()) self.assertEqual(src_data.data(), out_data.data()) # remove result file os.unlink(test_gpkg)
def testExportToGpkgWithExtraExtentNoNoData(self): tmpName = tempfile.mktemp(suffix='.gpkg') # Remove nodata gdal.Translate('/vsimem/src.tif', os.path.join(self.testDataDir, 'raster', 'band3_byte_noct_epsg4326.tif'), options='-a_nodata none') source = QgsRasterLayer('/vsimem/src.tif', 'my', 'gdal') self.assertTrue(source.isValid()) provider = source.dataProvider() fw = QgsRasterFileWriter(tmpName) fw.setOutputFormat('gpkg') pipe = QgsRasterPipe() self.assertTrue(pipe.set(provider.clone())) self.assertEqual( fw.writeRaster(pipe, provider.xSize() + 4, provider.ySize() + 4, QgsRectangle(-3 - 2, -4 - 2, 7 + 2, 6 + 2), provider.crs()), 0) del fw # Check that the test geopackage contains the raster layer and compare rlayer = QgsRasterLayer(tmpName) self.assertTrue(rlayer.isValid()) out_provider = rlayer.dataProvider() for i in range(3): src_data = provider.block(i + 1, provider.extent(), source.width(), source.height()) out_data = out_provider.block(i + 1, provider.extent(), source.width(), source.height()) self.assertEqual(src_data.data(), out_data.data()) out_data = out_provider.block(1, QgsRectangle(7, -4, 7 + 2, 6), 2, 8) # No nodata: defaults to zero self.assertEqual(out_data.data().data(), b'\x00' * 2 * 8) del out_provider del rlayer # remove result file gdal.Unlink('/vsimem/src.tif') os.unlink(tmpName)
class TestQgsMapLayerAction(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) self.vector_layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddate:datetime", "test_layer", "memory") assert self.vector_layer.isValid() self.vector_layer2 = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddate:datetime", "test_layer", "memory") assert self.vector_layer2.isValid() raster_path = os.path.join(unitTestDataPath(), 'landsat.tif') self.raster_layer = QgsRasterLayer(raster_path, 'raster') assert self.raster_layer.isValid() def testCanRunUsingLayer(self): """ Test that actions correctly indicate when they can run for a layer """ action_all_layers = QgsMapLayerAction('action1', None) self.assertTrue(action_all_layers.canRunUsingLayer(None)) self.assertTrue(action_all_layers.canRunUsingLayer(self.vector_layer)) self.assertTrue(action_all_layers.canRunUsingLayer(self.raster_layer)) action_vector_layers_only = QgsMapLayerAction('action2', None, QgsMapLayer.VectorLayer) self.assertFalse(action_vector_layers_only.canRunUsingLayer(None)) self.assertTrue(action_vector_layers_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_vector_layers_only.canRunUsingLayer(self.raster_layer)) action_raster_layers_only = QgsMapLayerAction('action3', None, QgsMapLayer.RasterLayer) self.assertFalse(action_raster_layers_only.canRunUsingLayer(None)) self.assertFalse(action_raster_layers_only.canRunUsingLayer(self.vector_layer)) self.assertTrue(action_raster_layers_only.canRunUsingLayer(self.raster_layer)) action_specific_layer_only = QgsMapLayerAction('action4', None, self.vector_layer) self.assertFalse(action_specific_layer_only.canRunUsingLayer(None)) self.assertTrue(action_specific_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_specific_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse(action_specific_layer_only.canRunUsingLayer(self.raster_layer)) action_specific_raster_layer_only = QgsMapLayerAction('action4', None, self.raster_layer) self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(None)) self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_specific_raster_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertTrue(action_specific_raster_layer_only.canRunUsingLayer(self.raster_layer)) action_editable_layer_only = QgsMapLayerAction('action1', None, flags=QgsMapLayerAction.EnabledOnlyWhenEditable) self.assertFalse(action_editable_layer_only.canRunUsingLayer(None)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer)) self.vector_layer.startEditing() self.assertFalse(action_editable_layer_only.canRunUsingLayer(None)) self.assertTrue(action_editable_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer)) self.vector_layer.commitChanges() self.assertFalse(action_editable_layer_only.canRunUsingLayer(None)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse(action_editable_layer_only.canRunUsingLayer(self.raster_layer))
def testStatistics(self): """Test zonal stats""" TEST_DATA_DIR = unitTestDataPath() + "/zonalstatistics/" myTempPath = QDir.tempPath() + "/" testDir = QDir(TEST_DATA_DIR) for f in testDir.entryList(QDir.Files): QFile.remove(myTempPath + f) QFile.copy(TEST_DATA_DIR + f, myTempPath + f) myVector = QgsVectorLayer(myTempPath + "polys.shp", "poly", "ogr") myRaster = QgsRasterLayer(myTempPath + "edge_problem.asc", "raster", "gdal") zs = QgsZonalStatistics(myVector, myRaster, "", 1, QgsZonalStatistics.All) zs.calculateStatistics(None) feat = QgsFeature() # validate statistics for each feature request = QgsFeatureRequest().setFilterFid(0) feat = next(myVector.getFeatures(request)) myMessage = ('Expected: %f\nGot: %f\n' % (12.0, feat[1])) assert feat[1] == 12.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (8.0, feat[2])) assert feat[2] == 8.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.666666666666667, feat[3])) assert abs(feat[3] - 0.666666666666667) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4])) assert feat[4] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.47140452079103201, feat[5])) assert abs(feat[5] - 0.47140452079103201) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6])) assert feat[6] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7])) assert feat[7] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8])) assert feat[8] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9])) assert feat[9] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10])) assert feat[10] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11])) assert feat[11] == 2.0, myMessage request.setFilterFid(1) feat = next(myVector.getFeatures(request)) myMessage = ('Expected: %f\nGot: %f\n' % (9.0, feat[1])) assert feat[1] == 9.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (5.0, feat[2])) assert feat[2] == 5.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.555555555555556, feat[3])) assert abs(feat[3] - 0.555555555555556) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4])) assert feat[4] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.49690399499995302, feat[5])) assert abs(feat[5] - 0.49690399499995302) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6])) assert feat[6] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7])) assert feat[7] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8])) assert feat[8] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9])) assert feat[9] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10])) assert feat[10] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11])) assert feat[11] == 2.0, myMessage request.setFilterFid(2) feat = next(myVector.getFeatures(request)) myMessage = ('Expected: %f\nGot: %f\n' % (6.0, feat[1])) assert feat[1] == 6.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (5.0, feat[2])) assert feat[2] == 5.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.833333333333333, feat[3])) assert abs(feat[3] - 0.833333333333333) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[4])) assert feat[4] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.372677996249965, feat[5])) assert abs(feat[5] - 0.372677996249965) < 0.00001, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[6])) assert feat[6] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[7])) assert feat[7] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[8])) assert feat[8] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (0.0, feat[9])) assert feat[9] == 0.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (1.0, feat[10])) assert feat[10] == 1.0, myMessage myMessage = ('Expected: %f\nGot: %f\n' % (2.0, feat[11])) assert feat[11] == 2.0, myMessage
def adding(self, layer_info): """Add a layer to QGIS map canvas. Take layer index, search the required information to add it in the temporary dictionnary constructed in the show_results function. It then adds it. """ # one of many add-on option if layer_info[0] == "index": combobox = self.tbl_result.cellWidget(layer_info[1], 3) layer_label = self.tbl_result.cellWidget(layer_info[1], 0).text() layer_info = combobox.itemData(combobox.currentIndex()) # the only add_on option available elif layer_info[0] == "info": layer_label = self.tbl_result.cellWidget(layer_info[2], 0).text() layer_info = layer_info[1] else: pass self.md_sync.tr = self.tr logger.info( "Adding a layer from those parameters :{}".format(layer_info)) if type(layer_info) == list: # If the layer to be added is a vector file if layer_info[0] == "vector": path = layer_info[1] name = os.path.basename(path).split(".")[0] layer = QgsVectorLayer(path, layer_label, "ogr") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) try: QgsMessageLog.logMessage( message="Data layer added: {}".format(name), tag="Isogeo", level=0, ) logger.debug("Vector layer added: {}".format(path)) except UnicodeEncodeError: QgsMessageLog.logMessage( message="Vector layer added:: {}".format( name.decode("latin1")), tag="Isogeo", level=0, ) logger.debug("Vector layer added: {}".format( name.decode("latin1"))) else: error_msg = layer.error().message() logger.warning( "Invalid vector layer: {}. QGIS says: {}".format( path, error_msg)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "Vector not valid {}. QGIS says: {}", context=__class__.__name__, ).format(path, error_msg), ) # If raster file elif layer_info[0] == "raster": path = layer_info[1] name = os.path.basename(path).split(".")[0] layer = QgsRasterLayer(path, layer_label) if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) try: QgsMessageLog.logMessage( message="Data layer added: {}".format(name), tag="Isogeo", level=0, ) logger.debug("Raster layer added: {}".format(path)) except UnicodeEncodeError: QgsMessageLog.logMessage( message="Raster layer added:: {}".format( name.decode("latin1")), tag="Isogeo", level=0, ) logger.debug("Raster layer added: {}".format( name.decode("latin1"))) else: error_msg = layer.error().message() logger.warning( "Invalid raster layer: {}. QGIS says: {}".format( path, error_msg)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "Raster not valid {}. QGIS says: {}", context=__class__.__name__, ).format(path, error_msg), ) # If EFS link elif layer_info[0] == "EFS": name = layer_info[1] uri = layer_info[2] layer = QgsVectorLayer(uri, layer_label, "arcgisfeatureserver") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("EFS layer added: {}".format(uri)) else: error_msg = layer.error().message() logger.warning("Invalid service: {}. QGIS says: {}".format( uri, error_msg)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr("EFS not valid. QGIS says: {}", context=__class__.__name__).format(error_msg), ) # If EMS link elif layer_info[0] == "EMS": name = layer_info[1] uri = layer_info[2] layer = QgsRasterLayer(uri, layer_label, "arcgismapserver") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("EMS layer added: {}".format(uri)) else: error_msg = layer.error().message() logger.warning("Invalid service: {}. QGIS says: {}".format( uri, error_msg)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr("EMS not valid. QGIS says: {}", context=__class__.__name__).format(error_msg), ) # If WFS link elif layer_info[0] == "WFS": url = layer_info[2] name = layer_info[1] layer = QgsVectorLayer(url, layer_label, "WFS") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("WFS layer added: {}".format(url)) else: error_msg = layer.error().message() name_url = self.build_wfs_url(layer_info[3], layer_info[4], mode="complete") if name_url[0] != 0: layer = QgsVectorLayer(name_url[2], layer_label, "WFS") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("WFS layer added: {}".format(url)) else: error_msg = layer.error().message() logger.warning( "Invalid service: {}. QGIS says: {}".format( url, error_msg)) else: QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "WFS is not valid. QGIS says: {}", context=__class__.__name__, ).format(error_msg), ) pass # If WMS link elif layer_info[0] == "WMS": url = layer_info[2] name = layer_info[1] layer = QgsRasterLayer(url, layer_label, "wms") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("WMS layer added: {}".format(url)) else: error_msg = layer.error().message() name_url = self.build_wms_url(layer_info[3], layer_info[4], mode="complete") if name_url[0] != 0: layer = QgsRasterLayer(name_url[2], layer_label, "wms") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("WMS layer added: {}".format(url)) else: error_msg = layer.error().message() logger.warning( "Invalid service: {}. QGIS says: {}".format( url, error_msg)) else: QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "WMS is not valid. QGIS says: {}", context=__class__.__name__, ).format(error_msg), ) # If WMTS link elif layer_info[0] == "WMTS": url = layer_info[2] name = layer_info[1] layer = QgsRasterLayer(url, layer_label, "wms") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("WMTS service layer added: {}".format(url)) else: error_msg = layer.error().message() logger.warning("Invalid service: {}. QGIS says: {}".format( url, error_msg)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "WMTS is not valid. QGIS says: {}", context=__class__.__name__, ).format(error_msg), ) else: pass # If the data is a PostGIS table elif isinstance(layer_info, dict): logger.debug("Data type: PostGIS") # Give aliases to the data passed as arguement base_name = layer_info.get("base_name", "") schema = layer_info.get("schema", "") table = layer_info.get("table", "") # Retrieve the database information stored in the PostGISdict uri = QgsDataSourceUri() host = self.PostGISdict[base_name]["host"] port = self.PostGISdict[base_name]["port"] user = self.PostGISdict[base_name]["username"] password = self.PostGISdict[base_name]["password"] # set host name, port, database name, username and password uri.setConnection(host, port, base_name, user, password) # Get the geometry column name from the database connexion & table # name. c = pgis_con.PostGisDBConnector(uri) dico = c.getTables() for i in dico: if i[0 == 1] and i[1] == table: geometry_column = i[8] # set database schema, table name, geometry column uri.setDataSource(schema, table, geometry_column) # Adding the layer to the map canvas layer = QgsVectorLayer(uri.uri(), table, "postgres") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug("Data added: {}".format(table)) elif (not layer.isValid() and plg_tools.last_error[0] == "postgis" and "prim" in plg_tools.last_error[1]): logger.debug("PostGIS layer may be a view, " "so key column is missing. " "Trying to automatically set one...") # get layer fields to set as key column fields = layer.dataProvider().fields() fields_names = [i.name() for i in fields] # sort them by name containing id to better perf fields_names.sort(key=lambda x: ("id" not in x, x)) for field in fields_names: uri.setKeyColumn(field) layer = QgsVectorLayer(uri.uri(True), table, "postgres") if layer.isValid(): lyr = QgsProject.instance().addMapLayer(layer) logger.debug( "PostGIS view layer added with [{}] as key column". format(field)) # filling 'QGIS Server' tab of layer Properties self.md_sync.basic_sync(layer=lyr, info=layer_info) return 1 else: continue else: logger.debug("Layer not valid. table = {}".format(table)) QMessageBox.information( iface.mainWindow(), self.tr("Error", context=__class__.__name__), self.tr( "The PostGIS layer is not valid." " Reason: {}", context=__class__.__name__, ).format(plg_tools.last_error), ) return 0 # filling 'QGIS Server' tab of layer Properties if layer.isValid(): try: self.md_sync.basic_sync(layer=lyr, info=layer_info) except IndexError as e: logger.debug( "Not supported 'layer_info' format causes this error : {}". format(e)) else: pass return 1
class TestQgsLayoutMap(unittest.TestCase, LayoutItemTestCase): @classmethod def setUpClass(cls): cls.item_class = QgsLayoutItemMap def setUp(self): self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n" def tearDown(self): report_file_path = "%s/qgistest.html" % QDir.tempPath() with open(report_file_path, 'a') as report_file: report_file.write(self.report) def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() # pipe = mRasterLayer.pipe() # assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers( [self.raster_layer, self.vector_layer]) # create layout with layout map self.layout = QgsLayout(QgsProject.instance()) self.layout.initializeDefaults() self.map = QgsLayoutItemMap(self.layout) self.map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) self.map.setFrameEnabled(True) self.map.setLayers([self.raster_layer]) self.layout.addLayoutItem(self.map) def testOverviewMap(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) checker = QgsLayoutChecker('composermap_overview', self.layout) checker.setColorTolerance(6) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapBlend(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsLayoutChecker('composermap_overview_blending', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapInvert(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(True) checker = QgsLayoutChecker('composermap_overview_invert', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testOverviewMapCenter(self): overviewMap = QgsLayoutItemMap(self.layout) overviewMap.attemptSetSceneRect(QRectF(20, 130, 70, 70)) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.layout.addLayoutItem(overviewMap) # zoom in myRectangle = QgsRectangle(192, -288, 320, -224) self.map.setExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setExtent(myRectangle2) overviewMap.overview().setLinkedMap(self.map) overviewMap.overview().setInverted(False) overviewMap.overview().setCentered(True) checker = QgsLayoutChecker('composermap_overview_center', self.layout) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testLayout() self.report += checker.report() self.layout.removeLayoutItem(overviewMap) assert myTestResult, myMessage def testMapCrs(self): # create layout with layout map map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() # check that new maps inherit project CRS QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 200, 100)) map.setFrameEnabled(True) rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909) map.setExtent(rectangle) map.setLayers([self.vector_layer]) layout.addLayoutItem(map) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(map.crs().authid(), 'EPSG:3857') self.assertEqual(map.presetCrs().authid(), 'EPSG:3857') checker = QgsLayoutChecker('composermap_crs3857', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(map.presetCrs().authid(), 'EPSG:4326') self.assertEqual(map.crs().authid(), 'EPSG:4326') rectangle = QgsRectangle(-124, 17, -78, 52) map.zoomToExtent(rectangle) checker = QgsLayoutChecker('composermap_crs4326', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # change back to project CRS map.setCrs(QgsCoordinateReferenceSystem()) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) def testContainsAdvancedEffects(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.containsAdvancedEffects()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) result = map.containsAdvancedEffects() self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver) self.assertTrue(result) def testRasterization(self): map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) layout = QgsLayout(QgsProject.instance()) map = QgsLayoutItemMap(layout) self.assertFalse(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken) self.assertFalse(map.requiresRasterization()) self.assertTrue(map.containsAdvancedEffects()) map.setBackgroundEnabled(False) self.assertTrue(map.requiresRasterization()) map.setBackgroundEnabled(True) map.setBackgroundColor(QColor(1, 1, 1, 1)) self.assertTrue(map.requiresRasterization()) self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver)
class TestQgsBlendModes(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) self.iface = get_iface() # initialize class MapRegistry, Canvas, MapRenderer, Map and PAL self.mMapRegistry = QgsProject.instance() # create point layer myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp') self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr') self.mMapRegistry.addMapLayer(self.mPointLayer) self.mSimplifyMethod = QgsVectorSimplifyMethod() self.mSimplifyMethod.setSimplifyHints( QgsVectorSimplifyMethod.NoSimplification) # create polygon layer myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp') self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr') self.mPolygonLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mPolygonLayer) # create line layer myShpFile = os.path.join(TEST_DATA_DIR, 'lines.shp') self.mLineLayer = QgsVectorLayer(myShpFile, 'Lines', 'ogr') self.mLineLayer.setSimplifyMethod(self.mSimplifyMethod) self.mMapRegistry.addMapLayer(self.mLineLayer) # create two raster layers myRasterFile = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1") self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2") myMultiBandRenderer1 = QgsMultiBandColorRenderer( self.mRasterLayer1.dataProvider(), 1, 2, 3) self.mRasterLayer1.setRenderer(myMultiBandRenderer1) self.mMapRegistry.addMapLayer(self.mRasterLayer1) myMultiBandRenderer2 = QgsMultiBandColorRenderer( self.mRasterLayer2.dataProvider(), 1, 2, 3) self.mRasterLayer2.setRenderer(myMultiBandRenderer2) self.mMapRegistry.addMapLayer(self.mRasterLayer2) # to match blend modes test comparisons background self.mapSettings = QgsMapSettings() self.mapSettings.setLayers([self.mRasterLayer1, self.mRasterLayer2]) self.mapSettings.setBackgroundColor(QColor(152, 219, 249)) self.mapSettings.setOutputSize(QSize(400, 400)) self.mapSettings.setOutputDpi(96) self.extent = QgsRectangle(-118.8888888888887720, 22.8002070393376783, -83.3333333333331581, 46.8719806763287536) def testVectorBlending(self): """Test that blend modes work for vector layers.""" # Add vector layers to map myLayers = [self.mLineLayer, self.mPolygonLayer] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set blending modes for both layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_Difference) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_blendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_blendmodes", 20) myMessage = ('vector blending failed') assert myResult, myMessage # Reset layers self.mLineLayer.setBlendMode(QPainter.CompositionMode_SourceOver) self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_SourceOver) def testVectorFeatureBlending(self): """Test that feature blend modes work for vector layers.""" # Add vector layers to map myLayers = [self.mLineLayer, self.mPolygonLayer] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set feature blending for line layer self.mLineLayer.setFeatureBlendMode(QPainter.CompositionMode_Plus) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_featureblendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_featureblendmodes", 20) myMessage = ('vector feature blending failed') assert myResult, myMessage # Reset layers self.mLineLayer.setFeatureBlendMode( QPainter.CompositionMode_SourceOver) def testVectorLayerTransparency(self): """Test that layer transparency works for vector layers.""" # Add vector layers to map myLayers = [self.mLineLayer, self.mPolygonLayer] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.extent) # Set feature blending for line layer self.mLineLayer.setLayerTransparency(50) checker = QgsMultiRenderChecker() checker.setControlName("expected_vector_layertransparency") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) myResult = checker.runTest("vector_layertransparency", 20) myMessage = ('vector layer transparency failed') assert myResult, myMessage def testRasterBlending(self): """Test that blend modes work for raster layers.""" # Add raster layers to map myLayers = [self.mRasterLayer1, self.mRasterLayer2] self.mapSettings.setLayers(myLayers) self.mapSettings.setExtent(self.mRasterLayer1.extent()) # Set blending mode for top layer self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Difference) checker = QgsMultiRenderChecker() checker.setControlName("expected_raster_blendmodes") checker.setMapSettings(self.mapSettings) checker.setColorTolerance(1) checker.setColorTolerance(1) myResult = checker.runTest("raster_blendmodes", 20) myMessage = ('raster blending failed') assert myResult, myMessage
class TestQgsComposerMap(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'rgb256x256.png') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 1, 2, 3) self.raster_layer.setRenderer(rasterRenderer) myPath = os.path.join(TEST_DATA_DIR, 'points.shp') vector_file_info = QFileInfo(myPath) self.vector_layer = QgsVectorLayer(vector_file_info.filePath(), vector_file_info.completeBaseName(), 'ogr') assert self.vector_layer.isValid() #pipe = mRasterLayer.pipe() #assert pipe.set(rasterRenderer), 'Cannot set pipe renderer' QgsProject.instance().addMapLayers( [self.raster_layer, self.vector_layer]) # create composition with composer map self.mComposition = QgsComposition(QgsProject.instance()) self.mComposition.setPaperSize(297, 210) self.mComposerMap = QgsComposerMap(self.mComposition, 20, 20, 200, 100) self.mComposerMap.setFrameEnabled(True) self.mComposerMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(self.mComposerMap) def testOverviewMap(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) checker = QgsCompositionChecker('composermap_overview', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapBlend(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setBlendMode(QPainter.CompositionMode_Multiply) checker = QgsCompositionChecker('composermap_overview_blending', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapInvert(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(96, -152, 160, -120) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setInverted(True) checker = QgsCompositionChecker('composermap_overview_invert', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testOverviewMapCenter(self): overviewMap = QgsComposerMap(self.mComposition, 20, 130, 70, 70) overviewMap.setFrameEnabled(True) overviewMap.setLayers([self.raster_layer]) self.mComposition.addComposerMap(overviewMap) # zoom in myRectangle = QgsRectangle(192, -288, 320, -224) self.mComposerMap.setNewExtent(myRectangle) myRectangle2 = QgsRectangle(0, -256, 256, 0) overviewMap.setNewExtent(myRectangle2) overviewMap.overview().setFrameMap(self.mComposerMap.id()) overviewMap.overview().setInverted(False) overviewMap.overview().setCentered(True) checker = QgsCompositionChecker('composermap_overview_center', self.mComposition) checker.setControlPathPrefix("composer_mapoverview") myTestResult, myMessage = checker.testComposition() self.mComposition.removeComposerItem(overviewMap) assert myTestResult, myMessage def testMapCrs(self): # create composition with composer map map_settings = QgsMapSettings() map_settings.setLayers([self.vector_layer]) composition = QgsComposition(QgsProject.instance()) composition.setPaperSize(297, 210) # check that new maps inherit project CRS QgsProject.instance().setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsComposerMap(composition, 20, 20, 200, 100) map.setFrameEnabled(True) rectangle = QgsRectangle(-13838977, 2369660, -8672298, 6250909) map.setNewExtent(rectangle) map.setLayers([self.vector_layer]) composition.addComposerMap(map) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertEqual(map.crs().authid(), 'EPSG:3857') self.assertEqual(map.presetCrs().authid(), 'EPSG:3857') checker = QgsCompositionChecker('composermap_crs3857', composition) checker.setControlPathPrefix("composer_map") result, message = checker.testComposition() self.assertTrue(result, message) # overwrite CRS map.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(map.presetCrs().authid(), 'EPSG:4326') self.assertEqual(map.crs().authid(), 'EPSG:4326') rectangle = QgsRectangle(-124, 17, -78, 52) map.zoomToExtent(rectangle) checker = QgsCompositionChecker('composermap_crs4326', composition) checker.setControlPathPrefix("composer_map") result, message = checker.testComposition() self.assertTrue(result, message) # change back to project CRS map.setCrs(QgsCoordinateReferenceSystem()) self.assertEqual(map.crs().authid(), 'EPSG:4326') self.assertFalse(map.presetCrs().isValid()) # Fails because addItemsFromXml has been commented out in sip @unittest.expectedFailure def testuniqueId(self): doc = QDomDocument() documentElement = doc.createElement('ComposerItemClipboard') self.mComposition.writeXml(documentElement, doc) self.mComposition.addItemsFromXml(documentElement, doc, 0, False) # test if both composer maps have different ids newMap = QgsComposerMap() mapList = self.mComposition.composerMapItems() for mapIt in mapList: if mapIt != self.mComposerMap: newMap = mapIt break oldId = self.mComposerMap.id() newId = newMap.id() self.mComposition.removeComposerItem(newMap) myMessage = 'old: %s new: %s' % (oldId, newId) assert oldId != newId, myMessage def testWorldFileGeneration(self): myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125) self.mComposerMap.setNewExtent(myRectangle) self.mComposerMap.setMapRotation(30.0) self.mComposition.setGenerateWorldFile(True) self.mComposition.setReferenceMap(self.mComposerMap) p = self.mComposition.computeWorldFileParameters() pexpected = (4.180480199790922, 2.4133064516129026, 779443.7612381146, 2.4136013686911886, -4.179969388427311, 3342408.5663611) ptolerance = (0.001, 0.001, 1, 0.001, 0.001, 1e+03) for i in range(0, 6): assert abs(p[i] - pexpected[i]) < ptolerance[i]
def reclassify(layer, exposure_key=None, overwrite_input=False, callback=None): """Reclassify a continuous raster layer. Issue https://github.com/inasafe/inasafe/issues/3182 This function is a wrapper for the code from https://github.com/chiatt/gdal_reclassify For instance if you want to reclassify like this table : Original Value | Class - ∞ < val <= 0 | 1 0 < val <= 0.5 | 2 0.5 < val <= 5 | 3 5 < val < + ∞ | 6 You need a dictionary : ranges = OrderedDict() ranges[1] = [None, 0] ranges[2] = [0.0, 0.5] ranges[3] = [0.5, 5] ranges[6] = [5, None] :param layer: The raster layer. :type layer: QgsRasterLayer :param overwrite_input: Option for the output layer. True will overwrite the input layer. False will create a temporary layer. :type overwrite_input: bool :param exposure_key: The exposure key. :type exposure_key: str :param callback: A function to all to indicate progress. The function should accept params 'current' (int), 'maximum' (int) and 'step' (str). Defaults to None. :type callback: function :return: The classified raster layer. :rtype: QgsRasterLayer .. versionadded:: 4.0 """ output_layer_name = reclassify_raster_steps['output_layer_name'] processing_step = reclassify_raster_steps['step_name'] output_layer_name = output_layer_name % layer.keywords['layer_purpose'] if exposure_key: classification_key = active_classification(layer.keywords, exposure_key) thresholds = active_thresholds_value_maps(layer.keywords, exposure_key) layer.keywords['thresholds'] = thresholds layer.keywords['classification'] = classification_key else: classification_key = layer.keywords.get('classification') thresholds = layer.keywords.get('thresholds') if not thresholds: raise InvalidKeywordsForProcessingAlgorithm( 'thresholds are missing from the layer %s' % layer.keywords['layer_purpose']) if not classification_key: raise InvalidKeywordsForProcessingAlgorithm( 'classification is missing from the layer %s' % layer.keywords['layer_purpose']) ranges = {} value_map = {} hazard_classes = definition(classification_key)['classes'] for hazard_class in hazard_classes: ranges[hazard_class['value']] = thresholds[hazard_class['key']] value_map[hazard_class['key']] = [hazard_class['value']] if overwrite_input: output_raster = layer.source() else: output_raster = unique_filename(suffix='.tiff', dir=temp_dir()) driver = gdal.GetDriverByName('GTiff') raster_file = gdal.Open(layer.source()) band = raster_file.GetRasterBand(1) no_data = band.GetNoDataValue() source = band.ReadAsArray() destination = source.copy() for value, interval in ranges.iteritems(): v_min = interval[0] v_max = interval[1] if v_min is None: destination[np.where(source <= v_max)] = value if v_max is None: destination[np.where(source > v_min)] = value if v_min < v_max: destination[np.where((v_min < source) & (source <= v_max))] = value # Tag no data cells destination[np.where(source == no_data)] = no_data_value # Create the new file. output_file = driver.Create(output_raster, raster_file.RasterXSize, raster_file.RasterYSize, 1) output_file.GetRasterBand(1).WriteArray(destination) output_file.GetRasterBand(1).SetNoDataValue(no_data_value) # CRS output_file.SetProjection(raster_file.GetProjection()) output_file.SetGeoTransform(raster_file.GetGeoTransform()) output_file.FlushCache() del output_file if not isfile(output_raster): raise FileNotFoundError reclassified = QgsRasterLayer(output_raster, output_layer_name) # We transfer keywords to the output. reclassified.keywords = layer.keywords.copy() reclassified.keywords['layer_mode'] = 'classified' value_map = {} hazard_classes = definition(classification_key)['classes'] for hazard_class in reversed(hazard_classes): value_map[hazard_class['key']] = [hazard_class['value']] reclassified.keywords['value_map'] = value_map reclassified.keywords['title'] = output_layer_name check_layer(reclassified) return reclassified
def ProcessNBR(self, inFileA, inFileB): msg = u"NBR Processing for " + self.sceneID + "..." iface.mainWindow().statusBar().showMessage(msg) QgsMessageLog.logMessage(msg, level=QgsMessageLog.INFO) try: calculatorEntryList = [] tempOutFile = self.outFileNBR.replace("NBR", "NBR_temp") fileInfo1 = QFileInfo(inFileA) baseName1 = fileInfo1.baseName() newLayer1 = QgsRasterLayer(inFileA, baseName1) boh1 = QgsRasterCalculatorEntry() boh1.ref = "boh@1" boh1.bandNumber = 1 calculatorEntryList.append(boh1) boh1.raster = newLayer1 if newLayer1.isValid(): extents = newLayer1.extent() colCt = newLayer1.width() rowCt = newLayer1.height() else: raise IOError(u"Error, Invalid layer read!") fileInfo2 = QFileInfo(inFileB) baseName2 = fileInfo2.baseName() newLayer2 = QgsRasterLayer(inFileB, baseName2) boh2 = QgsRasterCalculatorEntry() boh2.ref = "boh@2" boh2.bandNumber = 1 calculatorEntryList.append(boh2) boh2.raster = newLayer2 if not newLayer2.isValid(): raise IOError(u"Error, Invalid layer read!") formula = ("(((boh@1 != 0 AND boh@2 != 0) * " "(boh@1 - boh@2) / (boh@1 + boh@2) * 1000) + " "((boh@1 = 0 OR boh@2 = 0) * " + str(self.minShort) + "))") # Process calculation with input extent and resolution calc = QgsRasterCalculator(formula, tempOutFile, 'GTiff', extents, colCt, rowCt, calculatorEntryList) result = calc.processCalculation() if result != 0: raise RuntimeError(u"Raster calculator failed.") # convert Raster Calculator result to int 16 self.Float2IntTif(tempOutFile, self.outFileNBR) except: raise RuntimeError(u"Unspecified error when calculating NBR") finally: # cleanup calculatorEntryList = None fileInfo1 = None baseName1 = None fileInfo2 = None baseName2 = None formula = None boh1 = None boh2 = None calc = None newLayer1 = None newLayer2 = None del calculatorEntryList del fileInfo1 del baseName1 del fileInfo2 del baseName2 del formula del boh1 del boh2 del calc del newLayer1 del newLayer2 gc.collect() msg = u"NBR Processing for " + self.sceneID + " Completed" iface.mainWindow().statusBar().showMessage(msg) QgsMessageLog.logMessage(msg, level=QgsMessageLog.INFO) iface.mainWindow().statusBar().showMessage("") return result
def testPalettedBand(self): """ test paletted raster render band""" path = os.path.join(unitTestDataPath(), 'landsat_4326.tif') info = QFileInfo(path) base_name = info.baseName() layer = QgsRasterLayer(path, base_name) self.assertTrue(layer.isValid(), 'Raster not loaded: {}'.format(path)) renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 2, [QgsPalettedRasterRenderer.Class(137, QColor(0, 255, 0), 'class 2'), QgsPalettedRasterRenderer.Class(138, QColor(255, 0, 0), 'class 1'), QgsPalettedRasterRenderer.Class(139, QColor(0, 0, 255), 'class 1')]) layer.setRenderer(renderer) ms = QgsMapSettings() ms.setLayers([layer]) ms.setExtent(layer.extent()) checker = QgsRenderChecker() checker.setControlName("expected_paletted_renderer_band2") checker.setMapSettings(ms) self.assertTrue(checker.runTest("expected_paletted_renderer_band2"), "Paletted rendering test failed") renderer = QgsPalettedRasterRenderer(layer.dataProvider(), 3, [QgsPalettedRasterRenderer.Class(120, QColor(0, 255, 0), 'class 2'), QgsPalettedRasterRenderer.Class(123, QColor(255, 0, 0), 'class 1'), QgsPalettedRasterRenderer.Class(124, QColor(0, 0, 255), 'class 1')]) layer.setRenderer(renderer) ms = QgsMapSettings() ms.setLayers([layer]) ms.setExtent(layer.extent()) checker = QgsRenderChecker() checker.setControlName("expected_paletted_renderer_band3") checker.setMapSettings(ms) self.assertTrue(checker.runTest("expected_paletted_renderer_band3"), "Paletted rendering test failed")
def layers_create(self, missing=None): """Utworzenie warstw w projekcie. Podanie atrybutu 'missing' spowoduje, że tylko wybrane warstwy będą dodane.""" # Ustalenie ilości dodawanych warstw: i_max = len(missing) if missing else self.lyr_cnt # Utworzenie listy ze słownikami warstw do dodania: lyrs = [] if missing: for l_dict in self.lyrs: if l_dict["name"] in missing: lyrs.append(l_dict) else: lyrs = self.lyrs i = 0 # Dodanie warstw: for l_dict in lyrs: QgsApplication.processEvents() i += 1 dlg.splash_screen.p_bar.setValue(i * 100 / self.lyr_cnt) QgsApplication.processEvents() raw_uri = l_dict["uri"] uri = eval("f'{}'".format(raw_uri)) if l_dict["source"] == "wms" or l_dict["source"] == "gdal": lyr = QgsRasterLayer(uri, l_dict["name"], l_dict["source"]) lyr_required = False else: lyr = QgsVectorLayer(uri, l_dict["name"], l_dict["source"]) lyr_required = True if not lyr.isValid() and not lyr_required: m_text = f'Nie udało się poprawnie wczytać podkładu mapowego: {l_dict["name"]}. Naciśnięcie Tak spowoduje kontynuowanie uruchamiania wtyczki (podkład mapowy nie będzie wyświetlany), naciśnięcie Nie przerwie proces uruchamiania wtyczki. Jeśli problem będzie się powtarzał, zaleca się powiadomienie administratora systemu.' reply = QMessageBox.question(dlg.app, "Moek_Editor", m_text, QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.No: return False elif not lyr.isValid() and lyr_required: m_text = f'Nie udało się poprawnie wczytać warstwy: {l_dict["name"]}. Jeśli problem będzie się powtarzał, proszę o powiadomienie administratora systemu.' QMessageBox.critical(dlg.app, "Moek_Editor", m_text) return False if l_dict["source"] == "memory": lyr.setCustomProperty("skipMemoryLayersCheck", 1) pr = lyr.dataProvider() pr.addAttributes(l_dict["attrib"]) lyr.updateFields() if "crs" in l_dict: lyr.setCrs(CRS_1992) dlg.proj.addMapLayer(lyr, False) if l_dict["root"]: parent_grp = self.root parent_grp.insertChildNode(l_dict["pos"], QgsLayerTreeLayer(lyr)) parent_grp.findLayer(lyr).setItemVisibilityChecked(l_dict["visible"]) else: if "pos" in l_dict: parent_grp = self.root.findGroup(l_dict["parent"]) parent_grp.insertChildNode(l_dict["pos"], QgsLayerTreeLayer(lyr)) parent_grp.findLayer(lyr).setItemVisibilityChecked(False) else: parent_grp = self.root.findGroup(l_dict["parent"]) node = parent_grp.addLayer(lyr) node.setItemVisibilityChecked(l_dict["visible"]) lyr.loadNamedStyle(f'{STYLE_PATH}{l_dict["name"].lower()}.qml') return True
def testRasterBlock(self): """Test raster block with extent""" path = os.path.join(unitTestDataPath(), 'landsat_4326.tif') raster_layer = QgsRasterLayer(path, 'test') self.assertTrue(raster_layer.isValid()) extent = QgsRectangle(17.94284482577178252, 30.23021770271909503, 17.94407867909909626, 30.23154272264058307) block = raster_layer.dataProvider().block(1, extent, 2, 3) self.checkBlockContents(block, [ 125.0, 125.0, 125.0, 125.0, 125.0, 124.0, ]) full_content = [ 125.0, 125.0, 125.0, 125.0, 125.0, 125.0, 125.0, 124.0, 125.0, 126.0, 127.0, 127.0, ] extent = raster_layer.extent() block = raster_layer.dataProvider().block(1, extent, 3, 4) self.checkBlockContents(block, full_content) extent = raster_layer.extent() extent.grow(-0.0001) block = raster_layer.dataProvider().block(1, extent, 3, 4) self.checkBlockContents(block, full_content) row_height = raster_layer.extent().height() / raster_layer.height() for row in range(raster_layer.height()): extent = raster_layer.extent() extent.setYMaximum(extent.yMaximum() - row_height * row) extent.setYMinimum(extent.yMaximum() - row_height) block = raster_layer.dataProvider().block(1, extent, 3, 1) self.checkBlockContents(block, full_content[row * 3:row * 3 + 3])
def WriteMultiBandFiles(self, fileList, outFile): msg = u"WriteMultiBandFiles for " + self.sceneID + "..." iface.mainWindow().statusBar().showMessage(msg) # give ownership of layers to map registry so unlock happens for entry in fileList: fileInfo1 = QFileInfo(entry) baseName1 = fileInfo1.baseName() layer1 = QgsRasterLayer(entry, baseName1) QgsMapLayerRegistry.instance().addMapLayer(layer1) # Build VRT for TOA processing vrtPath = os.path.join(self.workPath, self.sceneID + ".vrt") processing.runalg( "gdalogr:buildvirtualraster", { "INPUT": fileList, "RESOLUTION": 0, "SEPARATE": True, "OUTPUT": vrtPath }) # write out virtual raster ds = gdal.Open(vrtPath) rows = ds.RasterYSize cols = ds.RasterXSize geo = ds.GetGeoTransform() projection = ds.GetProjection() if self.sensor == "8": toa_ds =\ self.driver.Create(outFile, cols, rows, 8, gdal.GDT_Byte, ["TILED=YES", "BLOCKXSIZE=64", "BLOCKYSIZE=64"]) else: toa_ds =\ self.driver.Create(outFile, cols, rows, 6, gdal.GDT_Byte, ["TILED=YES", "BLOCKXSIZE=64", "BLOCKYSIZE=64"]) toa_ds.SetGeoTransform(geo) toa_ds.SetProjection(projection) # Process each band, one at a time for num in range(8): num += 1 if self.sensor != "8" and num > 6: continue band = ds.GetRasterBand(num) toa_band = toa_ds.GetRasterBand(num) b_arr = np.array(band.ReadAsArray(0, 0, cols, rows), dtype=np.int16) b_arr[b_arr < 0] = 0 b_arr = b_arr / 25 toa_band.WriteArray(b_arr.astype(np.uint8)) del toa_band del b_arr ds = None toa_ds = None vrtPath = None del ds del toa_ds del vrtPath QgsMapLayerRegistry.instance().removeAllMapLayers() msg = u"WriteMultiBandFiles for " + self.sceneID + " Completed" iface.mainWindow().statusBar().showMessage(msg) return
def test_project_roundtrip(self): """Tests that a project with bad layers can be saved and restored""" p = QgsProject.instance() temp_dir = QTemporaryDir() for ext in ('shp', 'dbf', 'shx', 'prj'): copyfile(os.path.join(TEST_DATA_DIR, 'lines.%s' % ext), os.path.join(temp_dir.path(), 'lines.%s' % ext)) copyfile( os.path.join(TEST_DATA_DIR, 'raster', 'band1_byte_ct_epsg4326.tif'), os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif')) copyfile( os.path.join(TEST_DATA_DIR, 'raster', 'band1_byte_ct_epsg4326.tif'), os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif')) l = QgsVectorLayer(os.path.join(temp_dir.path(), 'lines.shp'), 'lines', 'ogr') self.assertTrue(l.isValid()) rl = QgsRasterLayer( os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326.tif'), 'raster', 'gdal') self.assertTrue(rl.isValid()) rl_copy = QgsRasterLayer( os.path.join(temp_dir.path(), 'band1_byte_ct_epsg4326_copy.tif'), 'raster_copy', 'gdal') self.assertTrue(rl_copy.isValid()) self.assertTrue(p.addMapLayers([l, rl, rl_copy])) # Save project project_path = os.path.join(temp_dir.path(), 'project.qgs') self.assertTrue(p.write(project_path)) # Re-load the project, checking for the XML properties p.removeAllMapLayers() self.assertTrue(p.read(project_path)) vector = list(p.mapLayersByName('lines'))[0] raster = list(p.mapLayersByName('raster'))[0] raster_copy = list(p.mapLayersByName('raster_copy'))[0] self.assertTrue(vector.originalXmlProperties() != '') self.assertTrue(raster.originalXmlProperties() != '') self.assertTrue(raster_copy.originalXmlProperties() != '') # Test setter raster.setOriginalXmlProperties('pippo') self.assertEqual(raster.originalXmlProperties(), 'pippo') # Now create and invalid project: bad_project_path = os.path.join(temp_dir.path(), 'project_bad.qgs') with open(project_path, 'r') as infile: with open(bad_project_path, 'w+') as outfile: outfile.write(infile.read().replace( './lines.shp', './lines-BAD_SOURCE.shp').replace( 'band1_byte_ct_epsg4326_copy.tif', 'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif')) # Load the bad project p.removeAllMapLayers() self.assertTrue(p.read(bad_project_path)) # Check layer is invalid vector = list(p.mapLayersByName('lines'))[0] raster = list(p.mapLayersByName('raster'))[0] raster_copy = list(p.mapLayersByName('raster_copy'))[0] self.assertIsNotNone(vector.dataProvider()) self.assertIsNotNone(raster.dataProvider()) self.assertIsNotNone(raster_copy.dataProvider()) self.assertFalse(vector.isValid()) self.assertFalse(raster_copy.isValid()) # Try a getFeatures self.assertEqual([f for f in vector.getFeatures()], []) self.assertTrue(raster.isValid()) self.assertEqual(vector.providerType(), 'ogr') # Save the project bad_project_path2 = os.path.join(temp_dir.path(), 'project_bad2.qgs') p.write(bad_project_path2) # Re-save the project, with fixed paths good_project_path = os.path.join(temp_dir.path(), 'project_good.qgs') with open(bad_project_path2, 'r') as infile: with open(good_project_path, 'w+') as outfile: outfile.write(infile.read().replace( './lines-BAD_SOURCE.shp', './lines.shp').replace( 'band1_byte_ct_epsg4326_copy-BAD_SOURCE.tif', 'band1_byte_ct_epsg4326_copy.tif')) # Load the good project p.removeAllMapLayers() self.assertTrue(p.read(good_project_path)) # Check layer is valid vector = list(p.mapLayersByName('lines'))[0] raster = list(p.mapLayersByName('raster'))[0] raster_copy = list(p.mapLayersByName('raster_copy'))[0] self.assertTrue(vector.isValid()) self.assertTrue(raster.isValid()) self.assertTrue(raster_copy.isValid())
def add_layer(layer_name, style=None, preset_style=None): cql = self.get_cql_query() if self.service_type == SERVICE_MANAGER.WFS: end_point = self.service_config['endpointurl'] if cql: if not end_point.endswith('?'): end_point += '?' end_point += 'CQL_FILTER=' + urllib.parse.quote(cql) uri = "pagingEnabled='true'" if not cql: uri += " restrictToRequestBBOX='1'" uri += " srsname='{}' typename='{}' url='{}' version='auto'".format( self.service_config['srs'], layer_name, end_point) vl = QgsVectorLayer(uri, layer_name, 'WFS') if preset_style.get('style') and preset_style[ 'style'] in SERVICE_MANAGER.PRESET_STYLES: style_url = SERVICE_MANAGER.PRESET_STYLES[ preset_style['style']]['url'] StyleUtils.fetch_and_apply_style(vl, style_url) layers_to_add.append(vl) elif self.service_type == SERVICE_MANAGER.WMS: base_uri = 'contextualWMSLegend=0&crs={}&dpiMode=7&format=image/png&layers={}'.format( self.service_config['srs'], layer_name) if style: uri = base_uri + "&styles={}".format(style) layer_name += ' ({})'.format(style) else: uri = base_uri + "&styles" uri += "&url={}".format(self.service_config['endpointurl']) if cql: uri += 'CQL_FILTER=' + urllib.parse.quote(cql) uri = 'IgnoreGetMapUrl=1&' + uri rl = QgsRasterLayer(uri, layer_name, 'wms') layers_to_add.append(rl) elif self.service_type == SERVICE_MANAGER.WCS: end_point = self.service_config['endpointurl'] if cql: if not end_point.endswith('?'): end_point += '?' end_point += 'CQL_FILTER=' + urllib.parse.quote(cql) uri = "pagingEnabled='true'" if not cql: uri += " restrictToRequestBBOX='1'" uri += " srsname='{}' typename='{}' url='{}' version='auto'".format( self.service_config['srs'], layer_name, end_point) rl = QgsRasterLayer(uri, layer_name, 'wcs') if preset_style.get('style') and preset_style[ 'style'] in SERVICE_MANAGER.PRESET_STYLES: style_url = SERVICE_MANAGER.PRESET_STYLES[ preset_style['style']]['url'] StyleUtils.fetch_and_apply_style(rl, style_url) layers_to_add.append(rl)
class TestQgsRasterRendererCreateSld(unittest.TestCase): """ This class tests the creation of SLD from QGis raster layers """ @classmethod def setUpClass(self): pass def setUp(self): pass def tearDown(self): pass def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) myPath = os.path.join(TEST_DATA_DIR, 'landsat.tif') rasterFileInfo = QFileInfo(myPath) self.raster_layer = QgsRasterLayer(rasterFileInfo.filePath(), rasterFileInfo.completeBaseName()) def testSingleBandPseudoColorRenderer_Interpolated(self): # get min and max of the band to renderer bandNo = 3 stats = self.raster_layer.dataProvider().bandStatistics( bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max) minValue = stats.minimumValue maxValue = stats.maximumValue # create shader for the renderer shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Interpolated) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(10): items.append( QgsColorRampShader.ColorRampItem( index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer( self.raster_layer.dataProvider(), bandNo, shader) self.raster_layer.setRenderer(rasterRenderer) # do test dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo)) # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'ramp') colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) def testSingleBandPseudoColorRenderer_Discrete(self): # get min and max of the band to renderer bandNo = 3 stats = self.raster_layer.dataProvider().bandStatistics( bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max) minValue = stats.minimumValue maxValue = stats.maximumValue # create shader for the renderer shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Discrete) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(10): items.append( QgsColorRampShader.ColorRampItem( index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer( self.raster_layer.dataProvider(), bandNo, shader) self.raster_layer.setRenderer(rasterRenderer) # do test dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo)) # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'intervals') colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) def testSingleBandPseudoColorRenderer_Exact(self): # get min and max of the band to renderer bandNo = 3 stats = self.raster_layer.dataProvider().bandStatistics( bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max) minValue = stats.minimumValue maxValue = stats.maximumValue # create shader for the renderer shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Exact) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(10): items.append( QgsColorRampShader.ColorRampItem( index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer( self.raster_layer.dataProvider(), bandNo, shader) self.raster_layer.setRenderer(rasterRenderer) # do test dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo)) # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'values') self.assertFalse(colorMap.hasAttribute('extendend')) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) # add check that is set ColoMap extended="true" if colormap is bigger that 255 entries # !NOTE! can't reuse previous shader => segmentation fault shader = QgsRasterShader(minValue, maxValue) colorRampShaderFcn = QgsColorRampShader(minValue, maxValue) colorRampShaderFcn.setColorRampType(QgsColorRampShader.Exact) colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous) colorRampShaderFcn.setClip(True) items = [] for index in range(255): items.append( QgsColorRampShader.ColorRampItem( index, QColor.fromHsv(index, 255, 255, 255), "{}".format(index))) colorRampShaderFcn.setColorRampItemList(items) shader.setRasterShaderFunction(colorRampShaderFcn) # create instance to test rasterRenderer = QgsSingleBandPseudoColorRenderer( self.raster_layer.dataProvider(), bandNo, shader) # self.raster_layer.setRenderer(rasterRenderer) # dom, root = self.rendererToSld(self.raster_layer.renderer()) # self.assertTrue( colorMap.hasAttribute( 'extendend' ) ) # self.assertEqual( colorMap.attribute( 'extendend' ), 'true' ) def testPalettedRasterRenderer(self): # create 10 color classes #classesString = '122 0 0 0 255 122\n123 1 1 1 255 123\n124 2 2 2 255 124\n125 3 3 3 255 125\n126 4 4 4 255 126\n127 5 5 5 255 127\n128 6 6 6 255 128\n129 7 7 7 255 129\n130 8 8 8 255 130' classesString = '' for index in range(10): classesString += '{0} {0} {0} {0} 255 {0}\n'.format(index) classes = QgsPalettedRasterRenderer.classDataFromString(classesString) rasterRenderer = QgsPalettedRasterRenderer( self.raster_layer.dataProvider(), 3, classes) self.raster_layer.setRenderer(rasterRenderer) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') # check ColorMapEntry classes colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertFalse(colorMap.isNull()) self.assertEqual(colorMap.attribute('type'), 'values') self.assertFalse(colorMap.hasAttribute('extendend')) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(colorMapEntries.count(), 10) for index in range(colorMapEntries.count()): colorMapEntry = colorMapEntries.at(index).toElement() self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index)) self.assertEqual(colorMapEntry.attribute('opacity'), '') self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index)) # add check that is set ColoMap extended="true" if colormap is bigger that 255 entries classesString = '' values = range(255) for index in range(255): classesString += '{0} {1} {1} {1} 255 {0}\n'.format( index, random.choice(values)) classes = QgsPalettedRasterRenderer.classDataFromString(classesString) rasterRenderer = QgsPalettedRasterRenderer( self.raster_layer.dataProvider(), 3, classes) self.raster_layer.setRenderer(rasterRenderer) dom, root = self.rendererToSld(self.raster_layer.renderer()) colorMap = root.elementsByTagName('sld:ColorMap') colorMap = colorMap.item(0).toElement() self.assertTrue(colorMap.hasAttribute('extended')) self.assertEqual(colorMap.attribute('extended'), 'true') def testMultiBandColorRenderer(self): rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 3, 1, 2) self.raster_layer.setRenderer(rasterRenderer) self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.StretchToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:RedChannel', '3') self.assertChannelBand(root, 'sld:GreenChannel', '1') self.assertChannelBand(root, 'sld:BlueChannel', '2') def testSingleBandGrayRenderer(self): # check with StretchToMinimumMaximum rasterRenderer = QgsSingleBandGrayRenderer( self.raster_layer.dataProvider(), 3) self.raster_layer.setRenderer(rasterRenderer) self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.StretchToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) maximum = self.raster_layer.renderer().contrastEnhancement( ).maximumValue() minmum = self.raster_layer.renderer().contrastEnhancement( ).minimumValue() self.assertEqual(minmum, 51) self.assertEqual(maximum, 172) # check default values dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') elements = root.elementsByTagName('sld:ContrastEnhancement') self.assertEqual(len(elements), 1) enhancement = elements.at(0).toElement() self.assertFalse(enhancement.isNull()) normalize = enhancement.firstChildElement('sld:Normalize') self.assertFalse(normalize.isNull()) self.assertVendorOption(normalize, 'algorithm', 'StretchToMinimumMaximum') self.assertVendorOption(normalize, 'minValue', '51') self.assertVendorOption(normalize, 'maxValue', '172') elements = root.elementsByTagName('sld:ColorMap') self.assertEqual(len(elements), 1) colorMap = elements.at(0).toElement() self.assertFalse(colorMap.isNull()) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(len(colorMapEntries), 2) clorMap1 = colorMapEntries.at(0) self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual( clorMap1.attributes().namedItem('quantity').nodeValue(), '0') clorMap2 = colorMapEntries.at(1) self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual( clorMap2.attributes().namedItem('quantity').nodeValue(), '255') # check when StretchAndClipToMinimumMaximum # then min/max have always to be the real one and not that set in the contrastEnhancement self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.StretchAndClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) minmum = self.raster_layer.renderer().contrastEnhancement( ).setMinimumValue(100) maximum = self.raster_layer.renderer().contrastEnhancement( ).maximumValue() minmum = self.raster_layer.renderer().contrastEnhancement( ).minimumValue() self.assertEqual(minmum, 100) self.assertEqual(maximum, 172) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') elements = root.elementsByTagName('sld:ContrastEnhancement') self.assertEqual(len(elements), 1) enhancement = elements.at(0).toElement() self.assertFalse(enhancement.isNull()) normalize = enhancement.firstChildElement('sld:Normalize') self.assertFalse(normalize.isNull()) self.assertVendorOption(normalize, 'minValue', '51') self.assertVendorOption(normalize, 'maxValue', '172') elements = root.elementsByTagName('sld:ColorMap') self.assertEqual(len(elements), 1) colorMap = elements.at(0).toElement() self.assertFalse(colorMap.isNull()) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(len(colorMapEntries), 4) clorMap1 = colorMapEntries.at(0) self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual( clorMap1.attributes().namedItem('quantity').nodeValue(), '100') self.assertEqual( clorMap1.attributes().namedItem('opacity').nodeValue(), '0') clorMap2 = colorMapEntries.at(1) self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual( clorMap2.attributes().namedItem('quantity').nodeValue(), '100') clorMap3 = colorMapEntries.at(2) self.assertEqual(clorMap3.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual( clorMap3.attributes().namedItem('quantity').nodeValue(), '172') clorMap4 = colorMapEntries.at(3) self.assertEqual(clorMap4.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual( clorMap4.attributes().namedItem('quantity').nodeValue(), '172') self.assertEqual( clorMap4.attributes().namedItem('opacity').nodeValue(), '0') # check when ClipToMinimumMaximum # then min/max have always to be the real one and not that set in the contrastEnhancement self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.ClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) minmum = self.raster_layer.renderer().contrastEnhancement( ).setMinimumValue(100) maximum = self.raster_layer.renderer().contrastEnhancement( ).maximumValue() minmum = self.raster_layer.renderer().contrastEnhancement( ).minimumValue() self.assertEqual(minmum, 100) self.assertEqual(maximum, 172) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) self.assertChannelBand(root, 'sld:GrayChannel', '3') elements = root.elementsByTagName('sld:ContrastEnhancement') self.assertEqual(len(elements), 1) enhancement = elements.at(0).toElement() self.assertFalse(enhancement.isNull()) normalize = enhancement.firstChildElement('sld:Normalize') self.assertFalse(normalize.isNull()) self.assertVendorOption(normalize, 'minValue', '51') self.assertVendorOption(normalize, 'maxValue', '172') elements = root.elementsByTagName('sld:ColorMap') self.assertEqual(len(elements), 1) colorMap = elements.at(0).toElement() self.assertFalse(colorMap.isNull()) colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry') self.assertEqual(len(colorMapEntries), 4) clorMap1 = colorMapEntries.at(0) self.assertEqual(clorMap1.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual( clorMap1.attributes().namedItem('quantity').nodeValue(), '100') self.assertEqual( clorMap1.attributes().namedItem('opacity').nodeValue(), '0') clorMap2 = colorMapEntries.at(1) self.assertEqual(clorMap2.attributes().namedItem('color').nodeValue(), '#000000') self.assertEqual( clorMap2.attributes().namedItem('quantity').nodeValue(), '100') clorMap3 = colorMapEntries.at(2) self.assertEqual(clorMap3.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual( clorMap3.attributes().namedItem('quantity').nodeValue(), '172') clorMap4 = colorMapEntries.at(3) self.assertEqual(clorMap4.attributes().namedItem('color').nodeValue(), '#ffffff') self.assertEqual( clorMap4.attributes().namedItem('quantity').nodeValue(), '172') self.assertEqual( clorMap4.attributes().namedItem('opacity').nodeValue(), '0') def testRasterRenderer(self): class fakerenderer(QgsRasterRenderer): def __init__(self, interface): QgsRasterRenderer.__init__(self, interface, '') rasterRenderer = fakerenderer(self.raster_layer.dataProvider()) self.raster_layer.setRenderer(rasterRenderer) # check opacity default value is not exported dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertNoOpacity(root) # check if opacity is not the default value rasterRenderer.setOpacity(1.1) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertOpacity(root, '1.1') # check gamma properties from [-100:0] streched to [0:1] # and (0:100] stretche dto (1:100] # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-100'}) # self.assertGamma(root, '0') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-50'}) # self.assertGamma(root, '0.5') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '0'}) # self.assertGamma(root, '1') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1'}) # self.assertGamma(root, '1') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '100'}) # self.assertGamma(root, '100') # # input contrast are always integer, btw the value is managed also if it's double # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1.1'}) # self.assertGamma(root, '1.1') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '1.6'}) # self.assertGamma(root, '1.6') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-50.5'}) # self.assertGamma(root, '0.495') # dom, root = self.rendererToSld(rasterRenderer, {'contrast': '-0.1'}) # self.assertGamma(root, '0.999') def testStretchingAlgorithm(self): rasterRenderer = QgsMultiBandColorRenderer( self.raster_layer.dataProvider(), 3, 1, 2) self.raster_layer.setRenderer(rasterRenderer) # check StretchToMinimumMaximum stretching alg self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.StretchToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel', 'StretchToMinimumMaximum', '51', '172') self.assertContrastEnhancement(root, 'sld:GreenChannel', 'StretchToMinimumMaximum', '122', '130') self.assertContrastEnhancement(root, 'sld:BlueChannel', 'StretchToMinimumMaximum', '133', '148') # check StretchAndClipToMinimumMaximum stretching alg self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.StretchAndClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel', 'ClipToZero', '51', '172') self.assertContrastEnhancement(root, 'sld:GreenChannel', 'ClipToZero', '122', '130') self.assertContrastEnhancement(root, 'sld:BlueChannel', 'ClipToZero', '133', '148') # check ClipToMinimumMaximum stretching alg self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.ClipToMinimumMaximum, limits=QgsRasterMinMaxOrigin.MinMax) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel', 'ClipToMinimumMaximum', '51', '172') self.assertContrastEnhancement(root, 'sld:GreenChannel', 'ClipToMinimumMaximum', '122', '130') self.assertContrastEnhancement(root, 'sld:BlueChannel', 'ClipToMinimumMaximum', '133', '148') # check NoEnhancement stretching alg self.raster_layer.setContrastEnhancement( algorithm=QgsContrastEnhancement.NoEnhancement) dom, root = self.rendererToSld(self.raster_layer.renderer()) self.assertContrastEnhancement(root, 'sld:RedChannel') self.assertContrastEnhancement(root, 'sld:GreenChannel') self.assertContrastEnhancement(root, 'sld:BlueChannel') def assertVendorOption(self, root, name, expectedValue): """Set expectedValue=None to check that the vendor option is not present.""" vendorOptions = root.elementsByTagName('sld:VendorOption') found = False for vendorOptionIndex in range(vendorOptions.count()): vendorOption = vendorOptions.at(vendorOptionIndex) self.assertEqual('sld:VendorOption', vendorOption.nodeName()) if (vendorOption.attributes().namedItem('name').nodeValue() == name ): found = True self.assertEqual(vendorOption.firstChild().nodeValue(), expectedValue) if (expectedValue is None) and found: self.fail( "found VendorOption: {} where supposed not present".format( name)) if expectedValue and not found: self.fail("Not found VendorOption: {}".format(name)) def assertGamma(self, root, expectedValue, index=0): enhancement = root.elementsByTagName('sld:ContrastEnhancement').item( index) gamma = enhancement.firstChildElement('sld:GammaValue') self.assertEqual(expectedValue, gamma.firstChild().nodeValue()) def assertOpacity(self, root, expectedValue, index=0): opacity = root.elementsByTagName('sld:Opacity').item(index) self.assertEqual(expectedValue, opacity.firstChild().nodeValue()) def assertNoOpacity(self, root): opacities = root.elementsByTagName('sld:Opacity') self.assertEqual(opacities.size(), 0) def assertContrastEnhancement(self, root, bandTag, expectedAlg=None, expectedMin=None, expectedMax=None, index=0): channelSelection = root.elementsByTagName('sld:ChannelSelection').item( index) self.assertIsNotNone(channelSelection) band = channelSelection.firstChildElement(bandTag) # check if no enhancement alg is iset if (not expectedAlg): contrastEnhancementName = band.firstChildElement( 'sld:ContrastEnhancement') self.assertEqual('', contrastEnhancementName.firstChild().nodeName()) return # check if enhancement alg is set contrastEnhancementName = band.firstChildElement( 'sld:ContrastEnhancement') self.assertEqual('sld:Normalize', contrastEnhancementName.firstChild().nodeName()) normalize = contrastEnhancementName.firstChildElement('sld:Normalize') vendorOptions = normalize.elementsByTagName('VendorOption') for vendorOptionIndex in range(vendorOptions.count()): vendorOption = vendorOptions.at(vendorOptionIndex) self.assertEqual('VendorOption', vendorOption.nodeName()) if (vendorOption.attributes().namedItem('name').nodeValue() == 'algorithm'): self.assertEqual(expectedAlg, vendorOption.firstChild().nodeValue()) elif (vendorOption.attributes().namedItem('name').nodeValue() == 'minValue'): self.assertEqual(expectedMin, vendorOption.firstChild().nodeValue()) elif (vendorOption.attributes().namedItem('name').nodeValue() == 'maxValue'): self.assertEqual(expectedMax, vendorOption.firstChild().nodeValue()) else: self.fail('Unrecognised vendorOption name {}'.format( vendorOption.attributes().namedItem('name').nodeValue())) def assertChannelBand(self, root, bandTag, expectedValue, index=0): channelSelection = root.elementsByTagName('sld:ChannelSelection').item( index) self.assertIsNotNone(channelSelection) band = channelSelection.firstChildElement(bandTag) sourceChannelName = band.firstChildElement('sld:SourceChannelName') self.assertEqual(expectedValue, sourceChannelName.firstChild().nodeValue()) def rendererToSld(self, renderer, properties={}): dom = QDomDocument() root = dom.createElement("FakeRoot") dom.appendChild(root) renderer.toSld(dom, root, properties) return dom, root
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 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