def testRenderLineLayerDataDefined(self): """ test that rendering a line symbol with data defined enabled layer works""" lines_shp = os.path.join(TEST_DATA_DIR, 'lines.shp') lines_layer = QgsVectorLayer(lines_shp, 'Lines', 'ogr') QgsProject.instance().addMapLayer(lines_layer) layer = QgsSimpleLineSymbolLayer() layer.setDataDefinedProperty(QgsSymbolLayer.PropertyLayerEnabled, QgsProperty.fromExpression("Name='Highway'")) layer.setColor(QColor(100, 150, 150)) layer.setWidth(5) symbol = QgsLineSymbol() symbol.changeSymbolLayer(0, layer) lines_layer.setRenderer(QgsSingleSymbolRenderer(symbol)) ms = QgsMapSettings() ms.setOutputSize(QSize(400, 400)) ms.setOutputDpi(96) ms.setExtent(QgsRectangle(-133, 22, -70, 52)) ms.setLayers([lines_layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(ms) renderchecker.setControlPathPrefix('symbol_layer') renderchecker.setControlName('expected_linelayer_ddenabled') self.assertTrue(renderchecker.runTest('linelayer_ddenabled')) QgsProject.instance().removeMapLayer(lines_layer)
def load_layer(self, id, param): """ Loads a layer which was specified as parameter. """ filepath = self.filepath_from_param(param) if 'in_place' in param and param['in_place']: # check if alg modifies layer in place tmpdir = tempfile.mkdtemp() self.cleanup_paths.append(tmpdir) path, file_name = os.path.split(filepath) base, ext = os.path.splitext(file_name) for file in glob.glob(os.path.join(path, '{}.*'.format(base))): shutil.copy(os.path.join(path, file), tmpdir) filepath = os.path.join(tmpdir, file_name) self.in_place_layers[id] = filepath if param['type'] in ('vector', 'table'): if filepath in self.vector_layer_params: return self.vector_layer_params[filepath] options = QgsVectorLayer.LayerOptions() options.loadDefaultStyle = False lyr = QgsVectorLayer(filepath, param['name'], 'ogr', options) self.vector_layer_params[filepath] = lyr elif param['type'] == 'raster': options = QgsRasterLayer.LayerOptions() options.loadDefaultStyle = False lyr = QgsRasterLayer(filepath, param['name'], 'gdal', options) self.assertTrue(lyr.isValid(), 'Could not load layer "{}" from param {}'.format(filepath, param)) QgsProject.instance().addMapLayer(lyr) return lyr
def testValidRelationAfterChangingStyle(self): # load project myPath = os.path.join(unitTestDataPath(), 'relations.qgs') QgsProject.instance().read(myPath) # get referenced layer relations = QgsProject.instance().relationManager().relations() relation = relations[list(relations.keys())[0]] referencedLayer = relation.referencedLayer() # check that the relation is valid valid = False for tab in referencedLayer.editFormConfig().tabs(): for t in tab.children(): if (t.type() == QgsAttributeEditorElement.AeTypeRelation): valid = t.relation().isValid() self.assertTrue(valid) # update style referencedLayer.styleManager().setCurrentStyle("custom") # check that the relation is still valid referencedLayer = relation.referencedLayer() valid = False for tab in referencedLayer.editFormConfig().tabs(): for t in tab.children(): if (t.type() == QgsAttributeEditorElement.AeTypeRelation): valid = t.relation().isValid() self.assertTrue(valid)
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 testUpdatedFields(self): """Test when referenced layer update its fields https://issues.qgis.org/issues/20893 """ ml = QgsVectorLayer("Point?srid=EPSG:4326&field=a:int", "mem", "memory") self.assertEqual(ml.isValid(), True) QgsProject.instance().addMapLayer(ml) ml.startEditing() f1 = QgsFeature(ml.fields()) f1.setGeometry(QgsGeometry.fromWkt('POINT(2 3)')) ml.addFeatures([f1]) ml.commitChanges() vl = QgsVectorLayer("?query=select a, geometry from mem", "vl", "virtual") self.assertEqual(vl.isValid(), True) # add one more field ml.dataProvider().addAttributes([QgsField('newfield', QVariant.Int)]) ml.updateFields() self.assertEqual(ml.featureCount(), vl.featureCount()) self.assertEqual(vl.fields().count(), 1) geometry = next(vl.getFeatures()).geometry() self.assertTrue(geometry) point = geometry.asPoint() self.assertEqual(point.x(), 2) self.assertEqual(point.y(), 3) QgsProject.instance().removeMapLayer(ml)
def testNoSliverPolygons(self): # create a layer with some polygons that will be used as a source for "avoid intersections" l = QgsVectorLayer('MultiPolygon', 'test_layer', 'memory') assert l.isValid() QgsProject.instance().addMapLayer(l) QgsProject.instance().writeEntry("Digitizing", "/AvoidIntersectionsList", [l.id()]) features = [] for i, wkt in enumerate(feat_wkt): f = QgsFeature(i + 1) f.setGeometry(QgsGeometry.fromWkt(wkt)) features.append(f) l.dataProvider().addFeatures(features) assert l.pendingFeatureCount() == 7 # create a geometry and remove its intersections with other geometries g = QgsGeometry.fromWkt(newg_wkt) assert g.avoidIntersections() == 0 # the resulting multi-polygon must have exactly three parts # (in QGIS 2.0 it has one more tiny part that appears at the border between two of the original polygons) mpg = g.asMultiPolygon() assert len(mpg) == 3
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 execute(self): model = self.itemData if model is None: return # shouldn't happen, but let's be safe project_provider = model.provider().id() == PROJECT_PROVIDER_ID if project_provider: msg = self.tr('Are you sure you want to delete this model from the current project?', 'DeleteModelAction') else: msg = self.tr('Are you sure you want to delete this model?', 'DeleteModelAction') reply = QMessageBox.question( None, self.tr('Delete Model', 'DeleteModelAction'), msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: if project_provider: provider = QgsApplication.processingRegistry().providerById(PROJECT_PROVIDER_ID) provider.remove_model(model) QgsProject.instance().setDirty(True) else: os.remove(model.sourceFilePath()) QgsApplication.processingRegistry().providerById('model').refreshAlgorithms()
def setUp(self): myShpFile = os.path.join(TEST_DATA_DIR, 'rectangles.shp') layer = QgsVectorLayer(myShpFile, 'Points', 'ogr') QgsProject.instance().addMapLayer(layer) # Create rulebased style sym1 = QgsFillSymbol.createSimple({'color': '#fdbf6f', 'outline_color': 'black'}) sym2 = QgsFillSymbol.createSimple({'color': '#71bd6c', 'outline_color': 'black'}) sym3 = QgsFillSymbol.createSimple({'color': '#1f78b4', 'outline_color': 'black'}) self.r1 = QgsRuleBasedRenderer.Rule(sym1, 0, 0, '"id" = 1') self.r2 = QgsRuleBasedRenderer.Rule(sym2, 0, 0, '"id" = 2') self.r3 = QgsRuleBasedRenderer.Rule(sym3, 0, 0, 'ELSE') rootrule = QgsRuleBasedRenderer.Rule(None) rootrule.appendChild(self.r1) rootrule.appendChild(self.r2) rootrule.appendChild(self.r3) layer.setRenderer(QgsRuleBasedRenderer(rootrule)) self.mapsettings = QgsMapSettings() self.mapsettings.setOutputSize(QSize(400, 400)) self.mapsettings.setOutputDpi(96) self.mapsettings.setExtent(QgsRectangle(-163, 22, -70, 52)) rendered_layers = [layer] self.mapsettings.setLayers(rendered_layers)
def runTestForLayer(self, layer, testname): tempdir = tempfile.mkdtemp() layer = QgsVectorLayer(layer, 'Layer', 'ogr') QgsProject.instance().addMapLayer(layer) self.iface.mapCanvas().setExtent(layer.extent()) geom = next(layer.getFeatures()).geometry() highlight = QgsHighlight(self.iface.mapCanvas(), geom, layer) color = QColor(Qt.red) highlight.setColor(color) highlight.setWidth(2) color.setAlpha(50) highlight.setFillColor(color) highlight.show() image = QImage(QSize(400, 400), QImage.Format_ARGB32) image.fill(Qt.white) painter = QPainter() painter.begin(image) self.iface.mapCanvas().render(painter) painter.end() control_image = os.path.join(tempdir, 'highlight_{}.png'.format(testname)) image.save(control_image) checker = QgsRenderChecker() checker.setControlPathPrefix("highlight") checker.setControlName("expected_highlight_{}".format(testname)) checker.setRenderedImage(control_image) self.assertTrue(checker.compareImages("highlight_{}".format(testname))) shutil.rmtree(tempdir)
def test_expressionRequiresFormScope(self): res = list(QgsValueRelationFieldFormatter.expressionFormAttributes("current_value('ONE') AND current_value('TWO')")) res = sorted(res) self.assertEqual(res, ['ONE', 'TWO']) res = list(QgsValueRelationFieldFormatter.expressionFormVariables("@current_geometry")) self.assertEqual(res, ['current_geometry']) self.assertFalse(QgsValueRelationFieldFormatter.expressionRequiresFormScope("")) self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("current_value('TWO')")) self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("current_value ( 'TWO' )")) self.assertTrue(QgsValueRelationFieldFormatter.expressionRequiresFormScope("@current_geometry")) self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("", QgsFeature())) self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("@current_geometry", QgsFeature())) self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'TWO' )", QgsFeature())) layer = QgsVectorLayer("none?field=pkid:integer&field=decoded:string", "layer", "memory") self.assertTrue(layer.isValid()) QgsProject.instance().addMapLayer(layer) f = QgsFeature(layer.fields()) f.setAttributes([1, 'value']) point = QgsGeometry.fromPointXY(QgsPointXY(123, 456)) f.setGeometry(point) self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("current_geometry", f)) self.assertFalse(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'TWO' )", f)) self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("current_value ( 'pkid' )", f)) self.assertTrue(QgsValueRelationFieldFormatter.expressionIsUsable("@current_geometry current_value ( 'pkid' )", f)) QgsProject.instance().removeMapLayer(layer.id())
def getAsString(self, value): if self.datatype == dataobjects.TYPE_RASTER: if isinstance(value, QgsRasterLayer): return str(value.dataProvider().dataSourceUri()) else: s = str(value) layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance()) for layer in layers: if layer.name() == s: return str(layer.dataProvider().dataSourceUri()) return s if self.datatype == dataobjects.TYPE_FILE: return str(value) else: if isinstance(value, QgsVectorLayer): return str(value.source()) else: s = str(value) if self.datatype != dataobjects.TYPE_VECTOR_ANY: layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.datatype], False) else: layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False) for layer in layers: if layer.name() == s: return str(layer.source()) return s
def testLayers(self): """ check that layers are shown in widget model""" p = QgsProject.instance() layer = QgsVectorLayer("Point", "layer1", "memory") layer2 = QgsVectorLayer("Point", "layer2", "memory") p.addMapLayers([layer, layer2]) w = QgsExpressionBuilderWidget() m = w.model() # check that layers are shown items = m.findItems('layer1', Qt.MatchRecursive) self.assertEqual(len(items), 1) items = m.findItems('layer2', Qt.MatchRecursive) self.assertEqual(len(items), 1) # change project p2 = QgsProject() layer3 = QgsVectorLayer("Point", "layer3", "memory") p2.addMapLayers([layer3]) w.setProject(p2) m = w.model() items = m.findItems('layer1', Qt.MatchRecursive) self.assertEqual(len(items), 0) items = m.findItems('layer2', Qt.MatchRecursive) self.assertEqual(len(items), 0) items = m.findItems('layer3', Qt.MatchRecursive) self.assertEqual(len(items), 1)
def test_representValue(self): QgsSettings().setValue("qgis/nullValue", "NULL") layer = QgsVectorLayer("none?field=number1:integer&field=number2:double&field=text1:string&field=number3:integer&field=number4:double&field=text2:string", "layer", "memory") self.assertTrue(layer.isValid()) QgsProject.instance().addMapLayer(layer) f = QgsFeature() f.setAttributes([2, 2.5, 'NULL', None, None, None]) layer.dataProvider().addFeatures([f]) fieldFormatter = QgsValueMapFieldFormatter() # Tests with different value types occurring in the value map config = {'map': {'two': '2', 'twoandhalf': '2.5', 'NULL text': 'NULL', 'nothing': self.VALUEMAP_NULL_TEXT}} self.assertEqual(fieldFormatter.representValue(layer, 0, config, None, 2), 'two') self.assertEqual(fieldFormatter.representValue(layer, 1, config, None, 2.5), 'twoandhalf') self.assertEqual(fieldFormatter.representValue(layer, 2, config, None, 'NULL'), 'NULL text') # Tests with null values of different types, if value map contains null self.assertEqual(fieldFormatter.representValue(layer, 3, config, None, None), 'nothing') self.assertEqual(fieldFormatter.representValue(layer, 4, config, None, None), 'nothing') self.assertEqual(fieldFormatter.representValue(layer, 5, config, None, None), 'nothing') # Tests with fallback display for different value types config = {} self.assertEqual(fieldFormatter.representValue(layer, 0, config, None, 2), '(2)') self.assertEqual(fieldFormatter.representValue(layer, 1, config, None, 2.5), '(2.50000)') self.assertEqual(fieldFormatter.representValue(layer, 2, config, None, 'NULL'), '(NULL)') # Tests with fallback display for null in different types of fields self.assertEqual(fieldFormatter.representValue(layer, 3, config, None, None), '(NULL)') self.assertEqual(fieldFormatter.representValue(layer, 4, config, None, None), '(NULL)') self.assertEqual(fieldFormatter.representValue(layer, 5, config, None, None), '(NULL)') QgsProject.instance().removeAllMapLayers()
def setUp(self): self.iface = get_iface() QgsProject.instance().removeAllMapLayers() self.iface.mapCanvas().viewport().resize(400, 400) # For some reason the resizeEvent is not delivered, fake it self.iface.mapCanvas().resizeEvent(QResizeEvent(QSize(400, 400), self.iface.mapCanvas().size()))
def _set_up_composition(self, width, height, dpi, engine_settings): # set up composition and add map self._c = QgsComposition(QgsProject.instance()) """:type: QgsComposition""" # self._c.setUseAdvancedEffects(False) self._c.setPrintResolution(dpi) # 600 x 400 px = 211.67 x 141.11 mm @ 72 dpi paperw = width * 25.4 / dpi paperh = height * 25.4 / dpi self._c.setPaperSize(paperw, paperh) # NOTE: do not use QgsComposerMap(self._c, 0, 0, paperw, paperh) since # it only takes integers as parameters and the composition will grow # larger based upon union of item scene rectangles and a slight buffer # see end of QgsComposition::compositionBounds() # add map as small graphics item first, then set its scene QRectF later self._cmap = QgsComposerMap(self._c, 10, 10, 10, 10) """:type: QgsComposerMap""" self._cmap.setFrameEnabled(False) self._cmap.setLayers(self._TestMapSettings.layers()) self._c.addComposerMap(self._cmap) # now expand map to fill page and set its extent self._cmap.setSceneRect(QRectF(0, 0, paperw, paperw)) self._cmap.setNewExtent(self.aoiExtent()) # self._cmap.updateCachedImage() self._c.setPlotStyle(QgsComposition.Print) # composition takes labeling engine settings from project QgsProject.instance().setLabelingEngineSettings(engine_settings)
def __init__(self, snapLayer, parent=None): super(LayerSnappingEnabledAction, self).__init__(parent) self._layerId = '' self._iface = None # QgisInteface if isinstance(snapLayer, QgisInterface): self._iface = snapLayer elif isinstance(snapLayer, QgsVectorLayer): self._layerId = snapLayer.id() elif isinstance(snapLayer, str) or isinstance(snapLayer, unicode): self._layerId = snapLayer self.setCheckable(True) self.setText('Toggle Layer Snapping') self.setStatusTip('Toggle snapping on this layer') self.setIcon(QIcon(':/plugins/ark/snapEnable.png')) self._refresh() self.triggered.connect(self._triggered) # Make sure we catch changes in the main snapping dialog QgsProject.instance().snapSettingsChanged.connect(self._refresh) # If using current layer, make sure we update when it changes if self._iface: self._iface.legendInterface().currentLayerChanged.connect(self._refresh) # If the layer is removed then disable the button QgsMapLayerRegistry.instance().layerRemoved.connect(self._layerRemoved) # If we change the settings, make such others are told self.snappingEnabledChanged.connect(QgsProject.instance().snapSettingsChanged)
def _layerRemoved(self, layerId): if self._layerId and layerId == self._layerId: self._layerId = '' self.setEnabled(False) QgsProject.instance().snapSettingsChanged.disconnect(self._refresh) QgsMapLayerRegistry.instance().layerRemoved.disconnect(self._layerRemoved) self.snappingEnabledChanged.disconnect(QgsProject.instance().snapSettingsChanged)
def testReplaceLayerWhileOpen(self): ''' Replace an existing geopackage layer whilst it's open in the project''' tmpfile = os.path.join(self.basetestpath, 'testGeopackageReplaceOpenLayer.gpkg') ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile) lyr = ds.CreateLayer('layer1', geom_type=ogr.wkbPoint) lyr.CreateField(ogr.FieldDefn('attr', ogr.OFTInteger)) lyr.CreateField(ogr.FieldDefn('attr2', ogr.OFTInteger)) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 0)')) lyr.CreateFeature(f) f = None vl1 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer1", u'layer1', u'ogr') p = QgsProject() p.addMapLayer(vl1) request = QgsFeatureRequest().setSubsetOfAttributes([0]) features = [f for f in vl1.getFeatures(request)] self.assertEqual(len(features), 1) # now, overwrite the layer with a different geometry type and fields ds.DeleteLayer('layer1') lyr = ds.CreateLayer('layer1', geom_type=ogr.wkbLineString) lyr.CreateField(ogr.FieldDefn('attr', ogr.OFTString)) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('LineString(0 0, 1 1)')) lyr.CreateFeature(f) f = None vl2 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer1", u'layer2', u'ogr') p.addMapLayer(vl2) features = [f for f in vl1.getFeatures(request)] self.assertEqual(len(features), 1)
def test_check_validity(self): """Test that the output invalid contains the error reason""" polygon_layer = self._make_layer('Polygon') self.assertTrue(polygon_layer.startEditing()) f = QgsFeature(polygon_layer.fields()) f.setAttributes([1]) # Flake! f.setGeometry(QgsGeometry.fromWkt( 'POLYGON ((0 0, 2 2, 0 2, 2 0, 0 0))')) self.assertTrue(f.isValid()) f2 = QgsFeature(polygon_layer.fields()) f2.setAttributes([1]) f2.setGeometry(QgsGeometry.fromWkt( 'POLYGON((1.1 1.1, 1.1 2.1, 2.1 2.1, 2.1 1.1, 1.1 1.1))')) self.assertTrue(f2.isValid()) self.assertTrue(polygon_layer.addFeatures([f, f2])) polygon_layer.commitChanges() polygon_layer.rollBack() self.assertEqual(polygon_layer.featureCount(), 2) QgsProject.instance().addMapLayers([polygon_layer]) alg = self.registry.createAlgorithmById('qgis:checkvalidity') context = QgsProcessingContext() context.setProject(QgsProject.instance()) feedback = ConsoleFeedBack() self.assertIsNotNone(alg) parameters = {} parameters['INPUT_LAYER'] = polygon_layer.id() parameters['VALID_OUTPUT'] = 'memory:' parameters['INVALID_OUTPUT'] = 'memory:' parameters['ERROR_OUTPUT'] = 'memory:' # QGIS method parameters['METHOD'] = 1 ok, results = execute( alg, parameters, context=context, feedback=feedback) self.assertTrue(ok) invalid_layer = QgsProcessingUtils.mapLayerFromString( results['INVALID_OUTPUT'], context) self.assertEqual(invalid_layer.fields().names()[-1], '_errors') self.assertEqual(invalid_layer.featureCount(), 1) f = next(invalid_layer.getFeatures()) self.assertEqual(f.attributes(), [ 1, 'segments 0 and 2 of line 0 intersect at 1, 1']) # GEOS method parameters['METHOD'] = 2 ok, results = execute( alg, parameters, context=context, feedback=feedback) self.assertTrue(ok) invalid_layer = QgsProcessingUtils.mapLayerFromString( results['INVALID_OUTPUT'], context) self.assertEqual(invalid_layer.fields().names()[-1], '_errors') self.assertEqual(invalid_layer.featureCount(), 1) f = next(invalid_layer.getFeatures()) self.assertEqual(f.attributes(), [1, 'Self-intersection'])
def testCheckStateRole(self): l1 = create_layer('l1') l2 = create_layer('l2') QgsProject.instance().addMapLayers([l1, l2]) m = QgsMapLayerModel() # not checkable self.assertFalse(m.data(m.index(0, 0), Qt.CheckStateRole)) self.assertFalse(m.data(m.index(1, 0), Qt.CheckStateRole)) m.setAllowEmptyLayer(True) self.assertFalse(m.data(m.index(0, 0), Qt.CheckStateRole)) self.assertFalse(m.data(m.index(1, 0), Qt.CheckStateRole)) self.assertFalse(m.data(m.index(2, 0), Qt.CheckStateRole)) m.setAllowEmptyLayer(False) # checkable m.setItemsCheckable(True) m.checkAll(Qt.Checked) self.assertTrue(m.data(m.index(0, 0), Qt.CheckStateRole)) self.assertTrue(m.data(m.index(1, 0), Qt.CheckStateRole)) m.setAllowEmptyLayer(True) self.assertFalse(m.data(m.index(0, 0), Qt.CheckStateRole)) self.assertTrue(m.data(m.index(1, 0), Qt.CheckStateRole)) self.assertTrue(m.data(m.index(2, 0), Qt.CheckStateRole)) m.setAdditionalItems(['a']) self.assertFalse(m.data(m.index(3, 0), Qt.CheckStateRole)) QgsProject.instance().removeMapLayers([l1.id(), l2.id()])
def testFlags(self): l1 = create_layer('l1') l2 = create_layer('l2') QgsProject.instance().addMapLayers([l1, l2]) m = QgsMapLayerModel() # not checkable self.assertFalse(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable) self.assertFalse(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable) m.setAllowEmptyLayer(True) self.assertFalse(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable) self.assertFalse(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable) self.assertFalse(m.flags(m.index(2, 0)) & Qt.ItemIsUserCheckable) m.setAllowEmptyLayer(False) # checkable m.setItemsCheckable(True) self.assertTrue(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable) self.assertTrue(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable) m.setAllowEmptyLayer(True) self.assertFalse(m.flags(m.index(0, 0)) & Qt.ItemIsUserCheckable) self.assertTrue(m.flags(m.index(1, 0)) & Qt.ItemIsUserCheckable) self.assertTrue(m.flags(m.index(2, 0)) & Qt.ItemIsUserCheckable) m.setAdditionalItems(['a']) self.assertFalse(m.flags(m.index(3, 0)) & Qt.ItemIsUserCheckable) QgsProject.instance().removeMapLayers([l1.id(), l2.id()])
def testFilterString(self): """ test filtering by string""" QgsProject.instance().clear() m = QgsMapLayerProxyModel() l1 = QgsVectorLayer("Point?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer", 'layer 1', "memory") QgsProject.instance().addMapLayer(l1) l2 = QgsVectorLayer("Polygon?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer", 'lAyEr 2', "memory") QgsProject.instance().addMapLayer(l2) l3 = QgsVectorLayer("None?field=fldtxt:string&field=fldint:integer", 'another', "memory") QgsProject.instance().addMapLayer(l3) l4 = QgsVectorLayer("LineString?crs=EPSG:3111&field=fldtxt:string&field=fldint:integer", 'final layer', "memory") QgsProject.instance().addMapLayer(l4) m.setFilterString('layer') self.assertEqual(m.rowCount(), 3) self.assertEqual(m.data(m.index(0, 0)), 'final layer') self.assertEqual(m.data(m.index(1, 0)), 'layer 1') self.assertEqual(m.data(m.index(2, 0)), 'lAyEr 2') m.setFilterString('') self.assertEqual(m.rowCount(), 4)
def test_geometryTypes(self): geo = [(1, "POINT", "(0 0)"), (2, "LINESTRING", "(0 0,1 0)"), (3, "POLYGON", "((0 0,1 0,1 1,0 0))"), (4, "MULTIPOINT", "((1 1))"), (5, "MULTILINESTRING", "((0 0,1 0),(0 1,1 1))"), (6, "MULTIPOLYGON", "(((0 0,1 0,1 1,0 0)),((2 2,3 0,3 3,2 2)))")] for wkb_type, wkt_type, wkt in geo: l = QgsVectorLayer("%s?crs=epsg:4326" % wkt_type, "m1", "memory", False) self.assertEqual(l.isValid(), True) QgsProject.instance().addMapLayer(l) f1 = QgsFeature(1) g = QgsGeometry.fromWkt(wkt_type + wkt) self.assertEqual(g is None, False) f1.setGeometry(g) l.dataProvider().addFeatures([f1]) l2 = QgsVectorLayer("?layer_ref=%s" % l.id(), "vtab", "virtual", False) self.assertEqual(l2.isValid(), True) self.assertEqual(l2.dataProvider().featureCount(), 1) self.assertEqual(l2.dataProvider().wkbType(), wkb_type) QgsProject.instance().removeMapLayer(l.id())
def _set_up_composition(self, width, height, dpi, engine_settings): # set up layout and add map self._c = QgsLayout(QgsProject.instance()) """:type: QgsLayout""" # self._c.setUseAdvancedEffects(False) self._c.renderContext().setDpi(dpi) # 600 x 400 px = 211.67 x 141.11 mm @ 72 dpi paperw = width * 25.4 / dpi paperh = height * 25.4 / dpi page = QgsLayoutItemPage(self._c) page.attemptResize(QgsLayoutSize(paperw, paperh)) self._c.pageCollection().addPage(page) # NOTE: do not use QgsLayoutItemMap(self._c, 0, 0, paperw, paperh) since # it only takes integers as parameters and the composition will grow # larger based upon union of item scene rectangles and a slight buffer # see end of QgsComposition::compositionBounds() # add map as small graphics item first, then set its scene QRectF later self._cmap = QgsLayoutItemMap(self._c) self._cmap.attemptSetSceneRect(QRectF(10, 10, 10, 10)) """:type: QgsLayoutItemMap""" self._cmap.setFrameEnabled(False) self._cmap.setLayers(self._TestMapSettings.layers()) if self._TestMapSettings.labelingEngineSettings().flags() & QgsLabelingEngineSettings.UsePartialCandidates: self._cmap.setMapFlags(QgsLayoutItemMap.ShowPartialLabels) self._c.addLayoutItem(self._cmap) # now expand map to fill page and set its extent self._cmap.attemptSetSceneRect(QRectF(0, 0, paperw, paperw)) self._cmap.setExtent(self.aoiExtent()) # self._cmap.updateCachedImage() # composition takes labeling engine settings from project QgsProject.instance().setLabelingEngineSettings(engine_settings)
def loadSqlLayer(self): with OverrideCursor(Qt.WaitCursor): layer = self._getSqlLayer(self.filter) if layer is None: return QgsProject.instance().addMapLayers([layer], True)
def testGettersSetters(self): """ test model getters/setters """ m = QgsMapLayerProxyModel() l1 = create_layer('l1') QgsProject.instance().addMapLayer(l1) l2 = create_layer('l2') QgsProject.instance().addMapLayer(l2) m.setFilters(QgsMapLayerProxyModel.LineLayer | QgsMapLayerProxyModel.WritableLayer) self.assertEqual(m.filters(), QgsMapLayerProxyModel.LineLayer | QgsMapLayerProxyModel.WritableLayer) m.setExceptedLayerIds([l2.id()]) self.assertEqual(m.exceptedLayerIds(), [l2.id()]) m.setExceptedLayerList([l2]) self.assertEqual(m.exceptedLayerList(), [l2]) m.setLayerWhitelist([l2]) self.assertEqual(m.layerWhitelist(), [l2]) m.setExcludedProviders(['a', 'b']) self.assertEqual(m.excludedProviders(), ['a', 'b']) m.setFilterString('c') self.assertEqual(m.filterString(), 'c')
def test_snappointstogrid(self): """Check that this runs correctly""" polygon_layer = self._make_layer('Polygon') f1 = QgsFeature(polygon_layer.fields()) f1.setAttributes([1]) f1.setGeometry(QgsGeometry.fromWkt('POLYGON((1.2 1.2, 1.2 2.2, 2.2 2.2, 2.2 1.2, 1.2 1.2))')) f2 = QgsFeature(polygon_layer.fields()) f2.setAttributes([2]) f2.setGeometry(QgsGeometry.fromWkt('POLYGON((1.1 1.1, 1.1 2.1, 2.1 2.1, 2.1 1.1, 1.1 1.1))')) self.assertTrue(f2.isValid()) self.assertTrue(polygon_layer.startEditing()) self.assertTrue(polygon_layer.addFeatures([f1, f2])) self.assertEqual(polygon_layer.featureCount(), 2) polygon_layer.commitChanges() self.assertEqual(polygon_layer.featureCount(), 2) QgsProject.instance().addMapLayers([polygon_layer]) polygon_layer.selectByIds([next(polygon_layer.getFeatures()).id()]) self.assertEqual(polygon_layer.selectedFeatureCount(), 1) old_features, new_features = self._alg_tester( 'native:snappointstogrid', polygon_layer, { 'HSPACING': 0.5, 'VSPACING': 0.5, } ) g = [f.geometry() for f in new_features][0] self.assertEqual(g.asWkt(), 'Polygon ((1 1, 1 2, 2 2, 2 1, 1 1))') # Check selected self.assertEqual(polygon_layer.selectedFeatureIds(), [1])
def testAdditionalItems(self): l1 = create_layer('l1') l2 = create_layer('l2') QgsProject.instance().addMapLayers([l1, l2]) m = QgsMapLayerModel() self.assertEqual(m.rowCount(QModelIndex()), 2) m.setAdditionalItems(['a', 'b']) self.assertEqual(m.rowCount(QModelIndex()), 4) self.assertEqual(m.data(m.index(0, 0), Qt.DisplayRole), 'l1') self.assertEqual(m.data(m.index(1, 0), Qt.DisplayRole), 'l2') self.assertEqual(m.data(m.index(2, 0), Qt.DisplayRole), 'a') self.assertEqual(m.data(m.index(3, 0), Qt.DisplayRole), 'b') m.setAllowEmptyLayer(True) self.assertEqual(m.rowCount(QModelIndex()), 5) self.assertFalse(m.data(m.index(0, 0), Qt.DisplayRole)) self.assertEqual(m.data(m.index(1, 0), Qt.DisplayRole), 'l1') self.assertEqual(m.data(m.index(2, 0), Qt.DisplayRole), 'l2') self.assertEqual(m.data(m.index(3, 0), Qt.DisplayRole), 'a') self.assertEqual(m.data(m.index(4, 0), Qt.DisplayRole), 'b') QgsProject.instance().removeMapLayers([l1.id(), l2.id()]) self.assertEqual(m.rowCount(QModelIndex()), 3) self.assertFalse(m.data(m.index(0, 0), Qt.DisplayRole)) self.assertEqual(m.data(m.index(1, 0), Qt.DisplayRole), 'a') self.assertEqual(m.data(m.index(2, 0), Qt.DisplayRole), 'b')
def testRenderMarkerLayerDataDefined(self): """ test that rendering a marker symbol with data defined enabled layer works""" points_shp = os.path.join(TEST_DATA_DIR, 'points.shp') points_layer = QgsVectorLayer(points_shp, 'Points', 'ogr') QgsProject.instance().addMapLayer(points_layer) layer = QgsSimpleMarkerSymbolLayer() layer.setDataDefinedProperty(QgsSymbolLayer.PropertyLayerEnabled, QgsProperty.fromExpression("Class='Biplane'")) layer.setColor(QColor(100, 150, 150)) layer.setSize(5) layer.setStrokeStyle(Qt.NoPen) symbol = QgsMarkerSymbol() symbol.changeSymbolLayer(0, layer) points_layer.setRenderer(QgsSingleSymbolRenderer(symbol)) ms = QgsMapSettings() ms.setOutputSize(QSize(400, 400)) ms.setOutputDpi(96) ms.setExtent(QgsRectangle(-133, 22, -70, 52)) ms.setLayers([points_layer]) renderchecker = QgsMultiRenderChecker() renderchecker.setMapSettings(ms) renderchecker.setControlPathPrefix('symbol_layer') renderchecker.setControlName('expected_markerlayer_ddenabled') self.assertTrue(renderchecker.runTest('markerlayer_ddenabled')) QgsProject.instance().removeMapLayer(points_layer)
def testSnapPointToGrid(self): p = QgsProject() l = QgsLayout(p) # need a page to snap to grid page = QgsLayoutItemPage(l) page.setPageSize('A4') l.pageCollection().addPage(page) s = QgsLayoutSnapper(l) l.gridSettings().setResolution( QgsLayoutMeasurement(5, QgsUnitTypes.LayoutMillimeters)) s.setSnapToGrid(True) s.setSnapTolerance(1) point, snappedX, snappedY = s.snapPointToGrid(QPointF(1, 1), 1) self.assertTrue(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(0, 0)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(9, 1), 1) self.assertTrue(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(10, 0)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(1, 11), 1) self.assertTrue(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(0, 10)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(13, 11), 1) self.assertFalse(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(13, 10)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(11, 13), 1) self.assertTrue(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(10, 13)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(13, 23), 1) self.assertFalse(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(13, 23)) # grid disabled s.setSnapToGrid(False) point, nappedX, snappedY = s.snapPointToGrid(QPointF(1, 1), 1) self.assertFalse(nappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(1, 1)) s.setSnapToGrid(True) # with different pixel scale point, snappedX, snappedY = s.snapPointToGrid(QPointF(0.5, 0.5), 1) self.assertTrue(snappedX) self.assertTrue(snappedY) self.assertEqual(point, QPointF(0, 0)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(0.5, 0.5), 3) self.assertFalse(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(0.5, 0.5)) # with offset grid l.gridSettings().setOffset(QgsLayoutPoint(2, 0)) point, snappedX, snappedY = s.snapPointToGrid(QPointF(13, 23), 1) self.assertTrue(snappedX) self.assertFalse(snappedY) self.assertEqual(point, QPointF(12, 23))
def testPages(self): """ Test adding/retrieving/deleting pages from the collection """ p = QgsProject() l = QgsLayout(p) collection = l.pageCollection() self.assertEqual(collection.pageCount(), 0) self.assertFalse(collection.pages()) self.assertFalse(collection.page(-1)) self.assertFalse(collection.page(0)) self.assertFalse(collection.page(1)) # add a page page = QgsLayoutItemPage(l) page.setPageSize('A4') self.assertEqual(collection.pageNumber(page), -1) collection.addPage(page) self.assertTrue(page in l.items()) self.assertEqual(collection.pageCount(), 1) self.assertEqual(collection.pages(), [page]) self.assertFalse(collection.page(-1)) self.assertEqual(collection.page(0), page) self.assertFalse(collection.page(1)) self.assertEqual(collection.pageNumber(page), 0) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') collection.addPage(page2) self.assertEqual(collection.pageCount(), 2) self.assertEqual(collection.pages(), [page, page2]) self.assertFalse(collection.page(-1)) self.assertEqual(collection.page(0), page) self.assertEqual(collection.page(1), page2) self.assertEqual(collection.pageNumber(page2), 1) # insert a page page3 = QgsLayoutItemPage(l) page3.setPageSize('A3') collection.insertPage(page3, 1) self.assertTrue(page3 in l.items()) self.assertEqual(collection.pageCount(), 3) self.assertEqual(collection.pages(), [page, page3, page2]) self.assertEqual(collection.page(0), page) self.assertEqual(collection.page(1), page3) self.assertEqual(collection.page(2), page2) self.assertEqual(collection.pageNumber(page3), 1) # delete page collection.deletePage(-1) self.assertEqual(collection.pageCount(), 3) self.assertEqual(collection.pages(), [page, page3, page2]) collection.deletePage(100) self.assertEqual(collection.pageCount(), 3) self.assertEqual(collection.pages(), [page, page3, page2]) collection.deletePage(1) self.assertEqual(collection.pageCount(), 2) self.assertEqual(collection.pages(), [page, page2]) # make sure page was deleted QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) self.assertTrue(sip.isdeleted(page3)) del l QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete) self.assertTrue(sip.isdeleted(page)) self.assertTrue(sip.isdeleted(page2))
def tearDown(self): QgsProject.instance().removeAllMapLayers()
def test_signalConnection(self): # remove all layers QgsProject.instance().removeAllMapLayers() # set dependencies and add back layers self.pointsLayer = QgsVectorLayer( "dbname='%s' table=\"node\" (geom) sql=" % self.fn, "points", "spatialite") assert (self.pointsLayer.isValid()) self.linesLayer = QgsVectorLayer( "dbname='%s' table=\"section\" (geom) sql=" % self.fn, "lines", "spatialite") assert (self.linesLayer.isValid()) self.pointsLayer2 = QgsVectorLayer( "dbname='%s' table=\"node2\" (geom) sql=" % self.fn, "_points2", "spatialite") assert (self.pointsLayer2.isValid()) self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())]) self.pointsLayer2.setDependencies( [QgsMapLayerDependency(self.pointsLayer.id())]) # this should update connections between layers QgsProject.instance().addMapLayers([self.pointsLayer]) QgsProject.instance().addMapLayers([self.linesLayer]) QgsProject.instance().addMapLayers([self.pointsLayer2]) ms = QgsMapSettings() ms.setOutputSize(QSize(100, 100)) ms.setExtent(QgsRectangle(0, 0, 1, 1)) self.assertTrue(ms.hasValidSettings()) u = QgsSnappingUtils() u.setMapSettings(ms) cfg = u.config() cfg.setEnabled(True) cfg.setMode(QgsSnappingConfig.AdvancedConfiguration) cfg.setIndividualLayerSettings( self.pointsLayer, QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels)) cfg.setIndividualLayerSettings( self.pointsLayer2, QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels)) u.setConfig(cfg) # add another line f = QgsFeature(self.linesLayer.fields()) f.setId(4) geom = QgsGeometry.fromWkt("LINESTRING(0.5 0.2,0.6 0)") f.setGeometry(geom) self.linesLayer.startEditing() self.linesLayer.addFeatures([f]) self.linesLayer.commitChanges() # check the second snapped point is ok m = u.snapToMap(QPoint(75, 100 - 0)) self.assertTrue(m.isValid()) self.assertTrue(m.hasVertex()) self.assertEqual(m.point(), QgsPoint(0.8, 0.0)) self.pointsLayer.setDependencies([]) self.pointsLayer2.setDependencies([])
def testDistance(self): self.checkConstructWrapper(QgsProcessingParameterDistance('test'), DistanceWidgetWrapper) alg = QgsApplication.processingRegistry().algorithmById( 'native:centroids') dlg = AlgorithmDialog(alg) param = QgsProcessingParameterDistance('test') wrapper = DistanceWidgetWrapper(param, dlg) widget = wrapper.createWidget() # test units widget.show() # crs values widget.setUnitParameterValue('EPSG:3111') self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) widget.setUnitParameterValue('EPSG:4326') self.assertEqual(widget.label.text(), 'degrees') self.assertTrue(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) widget.setUnitParameterValue(QgsCoordinateReferenceSystem('EPSG:3111')) self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) widget.setUnitParameterValue(QgsCoordinateReferenceSystem('EPSG:4326')) self.assertEqual(widget.label.text(), 'degrees') self.assertTrue(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) # layer values vl = QgsVectorLayer("Polygon?crs=epsg:3111&field=pk:int", "vl", "memory") widget.setUnitParameterValue(vl) self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) vl2 = QgsVectorLayer("Polygon?crs=epsg:4326&field=pk:int", "vl", "memory") widget.setUnitParameterValue(vl2) self.assertEqual(widget.label.text(), 'degrees') self.assertTrue(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) # unresolvable values widget.setUnitParameterValue(vl.id()) self.assertEqual(widget.label.text(), '<unknown>') self.assertFalse(widget.warning_label.isVisible()) self.assertFalse(widget.units_combo.isVisible()) self.assertTrue(widget.label.isVisible()) # resolvable text value QgsProject.instance().addMapLayer(vl) widget.setUnitParameterValue(vl.id()) self.assertEqual(widget.label.text(), 'meters') self.assertFalse(widget.warning_label.isVisible()) self.assertTrue(widget.units_combo.isVisible()) self.assertFalse(widget.label.isVisible()) self.assertEqual(widget.units_combo.currentData(), QgsUnitTypes.DistanceMeters) widget.setValue(5) self.assertEqual(widget.getValue(), 5) widget.units_combo.setCurrentIndex( widget.units_combo.findData(QgsUnitTypes.DistanceKilometers)) self.assertEqual(widget.getValue(), 5000) widget.setValue(2) self.assertEqual(widget.getValue(), 2000) widget.setUnitParameterValue(vl.id()) self.assertEqual(widget.getValue(), 2) widget.setValue(5) self.assertEqual(widget.getValue(), 5) widget.deleteLater()
def testSaveLoadProject(self): schema_uri = encode_uri(self.ds_uri, 'qgis_test') project_uri = encode_uri(self.ds_uri, 'qgis_test', 'abc') self.dropProjectsTable() # make sure we have a clean start prj = QgsProject() uri = self.vl.source() vl1 = QgsVectorLayer(uri, 'test', 'postgres') self.assertEqual(vl1.isValid(), True) prj.addMapLayer(vl1) prj_storage = QgsApplication.projectStorageRegistry( ).projectStorageFromType("postgresql") self.assertTrue(prj_storage) lst0 = prj_storage.listProjects(schema_uri) self.assertEqual(lst0, []) # try to save project in the database prj.setFileName(project_uri) res = prj.write() self.assertTrue(res) lst1 = prj_storage.listProjects(schema_uri) self.assertEqual(lst1, ["abc"]) # now try to load the project back prj2 = QgsProject() prj2.setFileName(project_uri) res = prj2.read() self.assertTrue(res) self.assertEqual(len(prj2.mapLayers()), 1) self.assertEqual(prj2.baseName(), "abc") self.assertEqual(prj2.absoluteFilePath(), "") # path not supported for project storages self.assertTrue( abs(prj2.lastModified().secsTo(QDateTime.currentDateTime())) < 10) # try to see project's metadata res, metadata = prj_storage.readProjectStorageMetadata(project_uri) self.assertTrue(res) self.assertEqual(metadata.name, "abc") time_project = metadata.lastModified time_now = QDateTime.currentDateTime() time_diff = time_now.secsTo(time_project) self.assertTrue(abs(time_diff) < 10) # try to remove the project res = prj_storage.removeProject(project_uri) self.assertTrue(res) lst2 = prj_storage.listProjects(schema_uri) self.assertEqual(lst2, []) self.dropProjectsTable( ) # make sure we have a clean finish... "leave no trace"
def testResizeToContents(self): p = QgsProject() l = QgsLayout(p) shape1 = QgsLayoutItemShape(l) shape1.attemptResize(QgsLayoutSize(90, 50)) shape1.attemptMove(QgsLayoutPoint(90, 50)) shape1.setItemRotation(45, False) l.addLayoutItem(shape1) shape2 = QgsLayoutItemShape(l) shape2.attemptResize(QgsLayoutSize(110, 50)) shape2.attemptMove(QgsLayoutPoint(100, 150), True, False, 0) l.addLayoutItem(shape2) shape3 = QgsLayoutItemShape(l) l.addLayoutItem(shape3) shape3.attemptResize(QgsLayoutSize(50, 100)) shape3.attemptMove(QgsLayoutPoint(210, 250), True, False, 0) shape4 = QgsLayoutItemShape(l) l.addLayoutItem(shape4) shape4.attemptResize(QgsLayoutSize(50, 30)) shape4.attemptMove(QgsLayoutPoint(10, 340), True, False, 0) shape4.setVisibility(False) # resize with no existing pages l.pageCollection().resizeToContents(QgsMargins(1, 2, 3, 4), QgsUnitTypes.LayoutCentimeters) self.assertEqual(l.pageCollection().pageCount(), 1) self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().width(), 290.3, 2) self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().height(), 380.36, 2) self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertAlmostEqual(shape1.positionWithUnits().x(), 90.15, 2) self.assertAlmostEqual(shape1.positionWithUnits().y(), 20.21, 2) self.assertAlmostEqual(shape2.positionWithUnits().x(), 100.15, 2) self.assertAlmostEqual(shape2.positionWithUnits().y(), 120.21, 2) self.assertAlmostEqual(shape3.positionWithUnits().x(), 210.15, 2) self.assertAlmostEqual(shape3.positionWithUnits().y(), 220.21, 2) self.assertAlmostEqual(shape4.positionWithUnits().x(), 10.15, 2) self.assertAlmostEqual(shape4.positionWithUnits().y(), 310.21, 2) # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize("A4", QgsLayoutItemPage.Landscape) l.pageCollection().addPage(page2) # add some guides g1 = QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(2.5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) l.guides().addGuide(g1) g2 = QgsLayoutGuide(Qt.Vertical, QgsLayoutMeasurement(4.5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) l.guides().addGuide(g2) # second page should be removed l.pageCollection().resizeToContents(QgsMargins(0, 0, 0, 0), QgsUnitTypes.LayoutCentimeters) self.assertEqual(l.pageCollection().pageCount(), 1) self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().width(), 250.3, 2) self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().height(), 320.36, 2) self.assertAlmostEqual(l.pageCollection().page(0).sizeWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertAlmostEqual(g1.position().length(), 0.5, 2) self.assertAlmostEqual(g2.position().length(), 3.5, 2)
def testThemeChanged(self): """ Test that the mapTheme(s)Changed signals are correctly emitted in all relevant situations """ project = QgsProject() collection = QgsMapThemeCollection(project) record = QgsMapThemeCollection.MapThemeRecord() theme_changed_spy = QSignalSpy(collection.mapThemeChanged) themes_changed_spy = QSignalSpy(collection.mapThemesChanged) collection.insert('theme1', record) self.assertEqual(len(theme_changed_spy), 1) self.assertEqual(theme_changed_spy[-1][0], 'theme1') self.assertEqual(len(themes_changed_spy), 1) # reinsert collection.insert('theme1', record) self.assertEqual(len(theme_changed_spy), 2) self.assertEqual(theme_changed_spy[-1][0], 'theme1') self.assertEqual(len(themes_changed_spy), 2) # update collection.update('theme1', record) self.assertEqual(len(theme_changed_spy), 3) self.assertEqual(theme_changed_spy[-1][0], 'theme1') self.assertEqual(len(themes_changed_spy), 3) # remove invalid collection.removeMapTheme( 'i wish i was a slave to an age old trade... like riding around on rail cars and working long days' ) self.assertEqual(len(theme_changed_spy), 3) self.assertEqual(len(themes_changed_spy), 3) # remove valid collection.removeMapTheme('theme1') self.assertEqual(len(theme_changed_spy), 3) # not changed - removed! self.assertEqual(len(themes_changed_spy), 4) # reinsert collection.insert('theme1', record) self.assertEqual(len(theme_changed_spy), 4) self.assertEqual(len(themes_changed_spy), 5) # clear collection.clear() self.assertEqual(len(theme_changed_spy), 4) # not changed - removed! self.assertEqual(len(themes_changed_spy), 6) # check that mapThemeChanged is emitted if layer is removed layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") project.addMapLayers([layer, layer2]) # record for layer1 record.addLayerRecord(QgsMapThemeCollection.MapThemeLayerRecord(layer)) collection.insert('theme1', record) self.assertEqual(len(theme_changed_spy), 5) self.assertEqual(len(themes_changed_spy), 7) # now kill layer 2 project.removeMapLayer(layer2) self.assertEqual( len(theme_changed_spy), 5) # signal should not be emitted - layer is not in record # now kill layer 1 project.removeMapLayer(layer) app.processEvents() self.assertEqual(len(theme_changed_spy), 6) # signal should be emitted - layer is in record
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 testLayout(self): # test that layouts have a collection p = QgsProject() l = QgsLayout(p) self.assertTrue(l.pageCollection()) self.assertEqual(l.pageCollection().layout(), l)
def formatCoord(self, pt, delimiter): '''Format the coordinate string according to the settings from the settings dialog.''' if self.settings.captureProjIsWgs84(): # ProjectionTypeWgs84 # Make sure the coordinate is transformed to EPSG:4326 canvasCRS = self.canvas.mapSettings().destinationCrs() if canvasCRS == epsg4326: pt4326 = pt else: transform = QgsCoordinateTransform(canvasCRS, epsg4326, QgsProject.instance()) pt4326 = transform.transform(pt.x(), pt.y()) lat = pt4326.y() lon = pt4326.x() if self.settings.wgs84NumberFormat == self.settings.Wgs84TypeDMS: # DMS msg = formatDmsString(lat, lon, 0, self.settings.dmsPrecision, self.settings.coordOrder, delimiter, settings.captureAddDmsSpace, settings.capturePadZeroes) elif self.settings.wgs84NumberFormat == self.settings.Wgs84TypeDDMMSS: # DDMMSS msg = formatDmsString(lat, lon, 1, self.settings.dmsPrecision, self.settings.coordOrder, delimiter, settings.capturePadZeroes) elif self.settings.wgs84NumberFormat == self.settings.Wgs84TypeDMM: # DM.MM msg = formatDmsString(lat, lon, 2, settings.captureDmmPrecision, self.settings.coordOrder, delimiter, settings.captureAddDmsSpace, settings.capturePadZeroes) elif self.settings.wgs84NumberFormat == self.settings.Wgs84TypeWKT: # WKT msg = 'POINT({:.{prec}f} {:.{prec}f})'.format( pt4326.x(), pt4326.y(), prec=self.settings.decimalDigits) elif self.settings.wgs84NumberFormat == self.settings.Wgs84TypeGeoJSON: # GeoJSON msg = '{{"type": "Point","coordinates": [{:.{prec}f},{:.{prec}f}]}}'.format( pt4326.x(), pt4326.y(), prec=self.settings.decimalDigits) else: # decimal degrees if self.settings.coordOrder == self.settings.OrderYX: msg = '{:.{prec}f}{}{:.{prec}f}'.format( pt4326.y(), delimiter, pt4326.x(), prec=self.settings.decimalDigits) else: msg = '{:.{prec}f}{}{:.{prec}f}'.format( pt4326.x(), delimiter, pt4326.y(), prec=self.settings.decimalDigits) elif self.settings.captureProjIsProjectCRS(): # Projection in the project CRS if self.settings.otherNumberFormat == 0: # Numerical if self.settings.coordOrder == self.settings.OrderYX: msg = '{:.{prec}f}{}{:.{prec}f}'.format( pt.y(), delimiter, pt.x(), prec=self.settings.decimalDigits) else: msg = '{:.{prec}f}{}{:.{prec}f}'.format( pt.x(), delimiter, pt.y(), prec=self.settings.decimalDigits) else: msg = 'POINT({:.{prec}f} {:.{prec}f})'.format( pt.x(), pt.y(), prec=self.settings.decimalDigits) elif self.settings.captureProjIsCustomCRS(): # Projection is a custom CRS canvasCRS = self.canvas.mapSettings().destinationCrs() customCRS = self.settings.captureCustomCRS() transform = QgsCoordinateTransform(canvasCRS, customCRS, QgsProject.instance()) pt = transform.transform(pt.x(), pt.y()) if self.settings.otherNumberFormat == 0: # Numerical if self.settings.coordOrder == self.settings.OrderYX: msg = '{:.{prec}f}{}{:.{prec}f}'.format( pt.y(), delimiter, pt.x(), prec=self.settings.decimalDigits) else: msg = '{:.{prec}f}{}{:.{prec}f}'.format( pt.x(), delimiter, pt.y(), prec=self.settings.decimalDigits) else: msg = 'POINT({:.{prec}f} {:.{prec}f})'.format( pt.x(), pt.y(), prec=self.settings.decimalDigits) elif self.settings.captureProjIsMGRS(): # Make sure the coordinate is transformed to EPSG:4326 canvasCRS = self.canvas.mapSettings().destinationCrs() if canvasCRS == epsg4326: pt4326 = pt else: transform = QgsCoordinateTransform(canvasCRS, epsg4326, QgsProject.instance()) pt4326 = transform.transform(pt.x(), pt.y()) try: msg = mgrs.toMgrs(pt4326.y(), pt4326.x()) except Exception: # traceback.print_exc() msg = None elif self.settings.captureProjIsPlusCodes(): # Make sure the coordinate is transformed to EPSG:4326 canvasCRS = self.canvas.mapSettings().destinationCrs() if canvasCRS == epsg4326: pt4326 = pt else: transform = QgsCoordinateTransform(canvasCRS, epsg4326, QgsProject.instance()) pt4326 = transform.transform(pt.x(), pt.y()) try: msg = olc.encode(pt4326.y(), pt4326.x(), self.settings.plusCodesLength) except Exception: msg = None elif self.settings.captureProjIsUTM(): # Make sure the coordinate is transformed to EPSG:4326 canvasCRS = self.canvas.mapSettings().destinationCrs() if canvasCRS == epsg4326: pt4326 = pt else: transform = QgsCoordinateTransform(canvasCRS, epsg4326, QgsProject.instance()) pt4326 = transform.transform(pt.x(), pt.y()) msg = latLon2UtmString(pt4326.y(), pt4326.x(), settings.captureUtmPrecision) if msg == '': msg = None elif self.settings.captureProjIsGeohash(): # Make sure the coordinate is transformed to EPSG:4326 canvasCRS = self.canvas.mapSettings().destinationCrs() if canvasCRS == epsg4326: pt4326 = pt else: transform = QgsCoordinateTransform(canvasCRS, epsg4326, QgsProject.instance()) pt4326 = transform.transform(pt.x(), pt.y()) msg = geohash.encode(pt4326.y(), pt4326.x(), settings.captureGeohashPrecision) if msg == '': msg = None elif self.settings.captureProjIsMaidenhead(): # Make sure the coordinate is transformed to EPSG:4326 canvasCRS = self.canvas.mapSettings().destinationCrs() if canvasCRS == epsg4326: pt4326 = pt else: transform = QgsCoordinateTransform(canvasCRS, epsg4326, QgsProject.instance()) pt4326 = transform.transform(pt.x(), pt.y()) try: msg = maidenhead.toMaiden( pt4326.y(), pt4326.x(), precision=settings.captureMaidenheadPrecision) except Exception: msg = None msg = '{}{}{}'.format(self.settings.capturePrefix, msg, self.settings.captureSuffix) return msg
def testMasterLayerOrder(self): """ test master layer order""" prj = QgsProject.instance() prj.clear() layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") prj.addMapLayers([layer, layer2, layer3]) prj.layerTreeRoot().setHasCustomLayerOrder(True) prj.layerTreeRoot().setCustomLayerOrder([layer2, layer]) self.assertEqual(prj.mapThemeCollection().masterLayerOrder(), [layer2, layer]) prj.layerTreeRoot().setCustomLayerOrder([layer, layer2, layer3]) # make some themes... theme1 = QgsMapThemeCollection.MapThemeRecord() theme1.setLayerRecords([ QgsMapThemeCollection.MapThemeLayerRecord(layer3), QgsMapThemeCollection.MapThemeLayerRecord(layer) ]) theme2 = QgsMapThemeCollection.MapThemeRecord() theme2.setLayerRecords([ QgsMapThemeCollection.MapThemeLayerRecord(layer3), QgsMapThemeCollection.MapThemeLayerRecord(layer2), QgsMapThemeCollection.MapThemeLayerRecord(layer) ]) theme3 = QgsMapThemeCollection.MapThemeRecord() theme3.setLayerRecords([ QgsMapThemeCollection.MapThemeLayerRecord(layer2), QgsMapThemeCollection.MapThemeLayerRecord(layer) ]) prj.mapThemeCollection().insert('theme1', theme1) prj.mapThemeCollection().insert('theme2', theme2) prj.mapThemeCollection().insert('theme3', theme3) #order of layers in theme should respect master order self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer, layer3]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer, layer2, layer3]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer, layer2]) # also check ids! self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'), [layer.id(), layer3.id()]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'), [layer.id(), layer2.id(), layer3.id()]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer.id(), layer2.id()]) # reset master order prj.layerTreeRoot().setCustomLayerOrder([layer2, layer3, layer]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer3, layer]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer2, layer3, layer]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer2, layer]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'), [layer3.id(), layer.id()]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'), [layer2.id(), layer3.id(), layer.id()]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer2.id(), layer.id()]) # check that layers include those hidden in the layer tree canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(prj.layerTreeRoot(), canvas) root = prj.layerTreeRoot() layer_node = root.findLayer(layer2.id()) layer_node.setItemVisibilityChecked(False) app.processEvents() prj.layerTreeRoot().setHasCustomLayerOrder(False) self.assertEqual(prj.mapThemeCollection().masterLayerOrder(), [layer, layer2, layer3]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayers('theme1'), [layer, layer3]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayers('theme2'), [layer, layer2, layer3]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayers('theme3'), [layer, layer2]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayerIds('theme1'), [layer.id(), layer3.id()]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayerIds('theme2'), [layer.id(), layer2.id(), layer3.id()]) self.assertEqual( prj.mapThemeCollection().mapThemeVisibleLayerIds('theme3'), [layer.id(), layer2.id()])
def setUp(self): self.project = QgsProject.instance()
def testMapTheme(self): canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) canvas.setFrameStyle(0) canvas.resize(600, 400) self.assertEqual(canvas.width(), 600) self.assertEqual(canvas.height(), 400) layer = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string", "layer", "memory") # add a polygon to layer f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer.dataProvider().addFeatures([f])) # create a style sym1 = QgsFillSymbol.createSimple({'color': '#ffb200'}) renderer = QgsSingleSymbolRenderer(sym1) layer.setRenderer(renderer) canvas.setLayers([layer]) canvas.setExtent(QgsRectangle(10, 30, 20, 35)) canvas.show() # need to wait until first redraw can occur (note that we first need to wait till drawing starts!) while not canvas.isDrawing(): app.processEvents() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # add some styles layer.styleManager().addStyleFromLayer('style1') sym2 = QgsFillSymbol.createSimple({'color': '#00b2ff'}) renderer2 = QgsSingleSymbolRenderer(sym2) layer.setRenderer(renderer2) layer.styleManager().addStyleFromLayer('style2') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas)) layer.styleManager().setCurrentStyle('style1') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # OK, so all good with setting/rendering map styles # try setting canvas to a particular theme # make some themes... theme1 = QgsMapThemeCollection.MapThemeRecord() record1 = QgsMapThemeCollection.MapThemeLayerRecord(layer) record1.currentStyle = 'style1' record1.usingCurrentStyle = True theme1.setLayerRecords([record1]) theme2 = QgsMapThemeCollection.MapThemeRecord() record2 = QgsMapThemeCollection.MapThemeLayerRecord(layer) record2.currentStyle = 'style2' record2.usingCurrentStyle = True theme2.setLayerRecords([record2]) QgsProject.instance().mapThemeCollection().insert('theme1', theme1) QgsProject.instance().mapThemeCollection().insert('theme2', theme2) canvas.setTheme('theme2') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas)) canvas.setTheme('theme1') canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # add another layer layer2 = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string", "layer2", "memory") f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer2.dataProvider().addFeatures([f])) # create a style sym1 = QgsFillSymbol.createSimple({'color': '#b2ff00'}) renderer = QgsSingleSymbolRenderer(sym1) layer2.setRenderer(renderer) # rerender canvas - should NOT show new layer canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # test again - this time refresh all layers canvas.refreshAllLayers() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas)) # add layer 2 to theme1 record3 = QgsMapThemeCollection.MapThemeLayerRecord(layer2) theme1.setLayerRecords([record3]) QgsProject.instance().mapThemeCollection().update('theme1', theme1) canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas)) # change the appearance of an active style layer2.styleManager().addStyleFromLayer('original') layer2.styleManager().addStyleFromLayer('style4') record3.currentStyle = 'style4' record3.usingCurrentStyle = True theme1.setLayerRecords([record3]) QgsProject.instance().mapThemeCollection().update('theme1', theme1) canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas)) layer2.styleManager().setCurrentStyle('style4') sym3 = QgsFillSymbol.createSimple({'color': '#b200b2'}) layer2.renderer().setSymbol(sym3) canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas)) # try setting layers while a theme is in place canvas.setLayers([layer]) canvas.refresh() # should be no change... setLayers should be ignored if canvas is following a theme! canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas)) # setLayerStyleOverrides while theme is in place canvas.setLayerStyleOverrides({layer2.id(): 'original'}) # should be no change... setLayerStyleOverrides should be ignored if canvas is following a theme! canvas.refresh() canvas.waitWhileRendering() self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas)) # clear theme canvas.setTheme('') canvas.refresh() canvas.waitWhileRendering() # should be different - we should now render project layers self.assertFalse(self.canvasImageCheck('theme4', 'theme4', canvas))
def testAlign(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemPicture(l) item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize(QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemPicture(l) item2.attemptMove(QgsLayoutPoint(6, 10, QgsUnitTypes.LayoutMillimeters)) item2.attemptResize(QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) l.addItem(item2) item3 = QgsLayoutItemPicture(l) item3.attemptMove(QgsLayoutPoint(0.8, 1.2, QgsUnitTypes.LayoutCentimeters)) item3.attemptResize(QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) l.addItem(item3) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignLeft) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(4, 10, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 1.2, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignHCenter) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(8, 10, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 1.2, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignRight) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(12, 10, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 1.2, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignTop) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(12, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 0.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignVCenter) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 10, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(12, 11.5, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 0.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.alignItems(l, [item1, item2, item3], QgsLayoutAligner.AlignBottom) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.positionWithUnits(), QgsLayoutPoint(12, 15, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item3.positionWithUnits(), QgsLayoutPoint(0.4, 0.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))
def accept(self): alg_parameters = [] feedback = self.createFeedback() load_layers = self.mainWidget().checkLoadLayersOnCompletion.isChecked() project = QgsProject.instance() if load_layers else None for row in range(self.mainWidget().tblParameters.rowCount()): col = 0 parameters = {} for param in self.algorithm().parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagHidden or param.isDestination(): continue wrapper = self.mainWidget().wrappers[row][col] parameters[param.name()] = wrapper.value() if not param.checkValueIsAcceptable(wrapper.value()): self.messageBar().pushMessage("", self.tr('Wrong or missing parameter value: {0} (row {1})').format( param.description(), row + 1), level=Qgis.Warning, duration=5) return col += 1 count_visible_outputs = 0 for out in self.algorithm().destinationParameterDefinitions(): if out.flags() & QgsProcessingParameterDefinition.FlagHidden: continue count_visible_outputs += 1 widget = self.mainWidget().tblParameters.cellWidget(row, col) text = widget.getValue() if out.checkValueIsAcceptable(text): if isinstance(out, (QgsProcessingParameterRasterDestination, QgsProcessingParameterFeatureSink)): # load rasters and sinks on completion parameters[out.name()] = QgsProcessingOutputLayerDefinition(text, project) else: parameters[out.name()] = text col += 1 else: self.messageBar().pushMessage("", self.tr('Wrong or missing output value: {0} (row {1})').format( out.description(), row + 1), level=Qgis.Warning, duration=5) return alg_parameters.append(parameters) with OverrideCursor(Qt.WaitCursor): self.mainWidget().setEnabled(False) self.cancelButton().setEnabled(True) # Make sure the Log tab is visible before executing the algorithm try: self.showLog() self.repaint() except: pass start_time = time.time() algorithm_results = [] for count, parameters in enumerate(alg_parameters): if feedback.isCanceled(): break self.setProgressText(QCoreApplication.translate('BatchAlgorithmDialog', '\nProcessing algorithm {0}/{1}…').format(count + 1, len(alg_parameters))) self.setInfo(self.tr('<b>Algorithm {0} starting…</b>').format(self.algorithm().displayName()), escapeHtml=False) parameters = self.algorithm().preprocessParameters(parameters) feedback.pushInfo(self.tr('Input parameters:')) feedback.pushCommandInfo(pformat(parameters)) feedback.pushInfo('') # important - we create a new context for each iteration # this avoids holding onto resources and layers from earlier iterations, # and allows batch processing of many more items then is possible # if we hold on to these layers context = dataobjects.createContext(feedback) alg_start_time = time.time() ret, results = execute(self.algorithm(), parameters, context, feedback) if ret: self.setInfo(QCoreApplication.translate('BatchAlgorithmDialog', 'Algorithm {0} correctly executed…').format(self.algorithm().displayName()), escapeHtml=False) feedback.setProgress(100) feedback.pushInfo( self.tr('Execution completed in {0:0.2f} seconds'.format(time.time() - alg_start_time))) feedback.pushInfo(self.tr('Results:')) feedback.pushCommandInfo(pformat(results)) feedback.pushInfo('') algorithm_results.append(results) else: break handleAlgorithmResults(self.algorithm(), context, feedback, False) feedback.pushInfo(self.tr('Batch execution completed in {0:0.2f} seconds'.format(time.time() - start_time))) self.finish(algorithm_results) self.cancelButton().setEnabled(False)
def test_getcapabilities(self): project = self._project_path assert os.path.exists(project), "Project file not found: " + project # without cache query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.3.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) doc = QDomDocument("wms_getcapabilities_130.xml") doc.setContent(body) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.1.1&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WFS&VERSION=1.1.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WFS&VERSION=1.0.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WCS&VERSION=1.0.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) # without cache query_string = '?MAP=%s&SERVICE=WMTS&VERSION=1.0.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') header, body = self._execute_request(query_string) # with cache header, body = self._execute_request(query_string) filelist = [f for f in os.listdir(self._servercache._cache_dir) if f.endswith(".xml")] self.assertEqual(len(filelist), 6, 'Not enough file in cache') cacheManager = self._server_iface.cacheManager() self.assertTrue(cacheManager.deleteCachedDocuments(None), 'deleteCachedDocuments does not return True') filelist = [f for f in os.listdir(self._servercache._cache_dir) if f.endswith(".xml")] self.assertEqual(len(filelist), 0, 'All files in cache are not deleted ') prj = QgsProject() prj.read(project) query_string = '?MAP=%s&SERVICE=WMS&VERSION=1.3.0&REQUEST=%s' % (urllib.parse.quote(project), 'GetCapabilities') request = QgsBufferServerRequest(query_string, QgsServerRequest.GetMethod, {}, None) accessControls = self._server_iface.accessControls() cDoc = QDomDocument("wms_getcapabilities_130.xml") self.assertFalse(cacheManager.getCachedDocument(cDoc, prj, request, accessControls), 'getCachedDocument is not None') self.assertTrue(cacheManager.setCachedDocument(doc, prj, request, accessControls), 'setCachedDocument false') self.assertTrue(cacheManager.getCachedDocument(cDoc, prj, request, accessControls), 'getCachedDocument is None') self.assertEqual(doc.documentElement().tagName(), cDoc.documentElement().tagName(), 'cachedDocument not equal to provide document') self.assertTrue(cacheManager.deleteCachedDocuments(None), 'deleteCachedDocuments does not return True')
def testCreateExpression(self): """ Test creating an expression using the widget""" layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", "test", "memory") # setup value relation parent_layer = QgsVectorLayer("Point?field=stringkey:string&field=intkey:integer&field=display:string", "parent", "memory") f1 = QgsFeature(parent_layer.fields(), 1) f1.setAttributes(['a', 1, 'value a']) f2 = QgsFeature(parent_layer.fields(), 2) f2.setAttributes(['b', 2, 'value b']) f3 = QgsFeature(parent_layer.fields(), 3) f3.setAttributes(['c', 3, 'value c']) parent_layer.dataProvider().addFeatures([f1, f2, f3]) QgsProject.instance().addMapLayers([layer, parent_layer]) config = {"Layer": parent_layer.id(), "Key": 'stringkey', "Value": 'display'} w = QgsValueRelationSearchWidgetWrapper(layer, 0) w.setConfig(config) c = w.widget() # first, set it to the "select value" item c.setCurrentIndex(0) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '') c.setCurrentIndex(1) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldtxt"=\'a\'') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldtxt"<>\'a\'') c.setCurrentIndex(2) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldtxt" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldtxt" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldtxt"=\'b\'') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldtxt"<>\'b\'') # try with numeric field w = QgsValueRelationSearchWidgetWrapper(layer, 1) config['Key'] = 'intkey' w.setConfig(config) c = w.widget() c.setCurrentIndex(c.findText('value c')) self.assertEqual(c.currentIndex(), 3) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldint" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldint" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldint"=3') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldint"<>3') # try with allow null set w = QgsValueRelationSearchWidgetWrapper(layer, 1) config['AllowNull'] = True w.setConfig(config) c = w.widget() c.setCurrentIndex(c.findText('value c')) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldint" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldint" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldint"=3') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldint"<>3') # try with line edit w = QgsValueRelationSearchWidgetWrapper(layer, 1) config['UseCompleter'] = True w.setConfig(config) l = w.widget() l.setText('value b') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNull), '"fldint" IS NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.IsNotNull), '"fldint" IS NOT NULL') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EqualTo), '"fldint"=2') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.NotEqualTo), '"fldint"<>2')
def testCombo(self): project = QgsProject() layout = QgsPrintLayout(project) combo = QgsLayoutItemComboBox(None) spy = QSignalSpy(combo.itemChanged) self.assertEqual(combo.count(), 0) self.assertIsNone(combo.currentLayout()) self.assertIsNone(combo.currentItem()) self.assertIsNone(combo.item(0)) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(1)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(combo.currentIndex(), -1) self.assertEqual(len(spy), 0) combo.setCurrentLayout(layout) self.assertEqual(combo.currentIndex(), -1) self.assertEqual(len(spy), 0) self.assertEqual(combo.currentLayout(), layout) self.assertEqual(combo.count(), 0) self.assertIsNone(combo.currentItem()) self.assertIsNone(combo.item(0)) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(1)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 0) combo.setAllowEmptyItem(True) self.assertEqual(combo.currentIndex(), 0) self.assertEqual(combo.count(), 1) self.assertEqual(len(spy), 2) self.assertEqual(combo.currentLayout(), layout) self.assertIsNone(combo.currentItem()) self.assertIsNone(combo.item(0)) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(1)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 2) self.assertEqual(combo.currentIndex(), 0) self.assertEqual(combo.itemText(0), '') combo.setAllowEmptyItem(False) self.assertEqual(combo.currentIndex(), -1) self.assertEqual(combo.count(), 0) self.assertEqual(len(spy), 4) self.assertEqual(combo.currentLayout(), layout) self.assertIsNone(combo.currentItem()) self.assertIsNone(combo.item(0)) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(1)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 4) self.assertEqual(combo.currentIndex(), -1) label1 = QgsLayoutItemLabel(layout) label1.setId('llll') # don't add to layout yet! combo.setItem(label1) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 4) self.assertEqual(combo.currentIndex(), -1) combo.setAllowEmptyItem(True) combo.setItem(label1) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 6) self.assertEqual(combo.currentIndex(), 0) combo.setAllowEmptyItem(False) layout.addLayoutItem(label1) self.assertEqual(combo.currentIndex(), 0) self.assertEqual(combo.count(), 1) self.assertEqual(combo.itemText(0), 'llll') self.assertEqual(len(spy), 10) self.assertEqual(combo.currentLayout(), layout) self.assertEqual(combo.currentItem(), label1) self.assertEqual(combo.item(0), label1) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(1)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 11) self.assertEqual(combo.currentIndex(), -1) combo.setItem(label1) self.assertEqual(combo.currentItem(), label1) self.assertEqual(len(spy), 12) self.assertEqual(combo.currentIndex(), 0) combo.setAllowEmptyItem(True) self.assertEqual(combo.currentIndex(), 1) self.assertEqual(combo.count(), 2) self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'llll') self.assertEqual(len(spy), 13) self.assertEqual(combo.currentLayout(), layout) self.assertEqual(combo.currentItem(), label1) self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label1) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(2)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 14) self.assertEqual(combo.currentIndex(), 0) combo.setItem(label1) self.assertEqual(combo.currentItem(), label1) self.assertEqual(len(spy), 15) self.assertEqual(combo.currentIndex(), 1) label2 = QgsLayoutItemLabel(layout) label2.setId('mmmm') layout.addLayoutItem(label2) self.assertEqual(combo.currentIndex(), 1) self.assertEqual(combo.count(), 3) self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'llll') self.assertEqual(combo.itemText(2), 'mmmm') self.assertEqual(len(spy), 15) self.assertEqual(combo.currentLayout(), layout) self.assertEqual(combo.currentItem(), label1) self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label1) self.assertEqual(combo.item(2), label2) self.assertIsNone(combo.item(-1)) self.assertIsNone(combo.item(3)) combo.setItem(None) self.assertIsNone(combo.currentItem()) self.assertEqual(len(spy), 16) self.assertEqual(combo.currentIndex(), 0) combo.setItem(label1) self.assertEqual(combo.currentItem(), label1) self.assertEqual(len(spy), 17) self.assertEqual(combo.currentIndex(), 1) label1.setId('nnnn') self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'mmmm') self.assertEqual(combo.itemText(2), 'nnnn') self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label2) self.assertEqual(combo.item(2), label1) self.assertEqual(combo.currentItem(), label1) combo.setAllowEmptyItem(False) self.assertEqual(combo.itemText(0), 'mmmm') self.assertEqual(combo.itemText(1), 'nnnn') self.assertEqual(combo.item(0), label2) self.assertEqual(combo.item(1), label1) self.assertEqual(combo.currentItem(), label1) combo.setItem(label2) label2.setId('oooo') self.assertEqual(combo.itemText(0), 'nnnn') self.assertEqual(combo.itemText(1), 'oooo') self.assertEqual(combo.item(0), label1) self.assertEqual(combo.item(1), label2) self.assertEqual(combo.currentItem(), label2) combo.setAllowEmptyItem(True) layout.removeLayoutItem(label1) self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'oooo') self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label2) self.assertEqual(combo.currentItem(), label2) map = QgsLayoutItemMap(layout) layout.addLayoutItem(map) map.setId('pppp') self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'oooo') self.assertEqual(combo.itemText(2), 'pppp') self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label2) self.assertEqual(combo.item(2), map) self.assertEqual(combo.currentItem(), label2) combo.setItemType(QgsLayoutItemRegistry.LayoutMap) self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'pppp') self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), map) self.assertIsNone(combo.currentItem()) combo.setItemType(QgsLayoutItemRegistry.LayoutLabel) self.assertEqual(combo.itemText(0), '') self.assertEqual(combo.itemText(1), 'oooo') self.assertIsNone(combo.item(0)) self.assertEqual(combo.item(1), label2) self.assertIsNone(combo.currentItem()) combo.setItemType(QgsLayoutItemRegistry.LayoutAttributeTable) self.assertEqual(combo.itemText(0), '') self.assertIsNone(combo.item(0)) self.assertIsNone(combo.currentItem()) combo.setAllowEmptyItem(False) self.assertEqual(combo.count(), 0) self.assertIsNone(combo.currentItem()) self.assertEqual(combo.currentIndex(), -1)
def testDistribute(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemPicture(l) item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize(QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemPicture(l) item2.attemptMove(QgsLayoutPoint(7, 10, QgsUnitTypes.LayoutMillimeters)) item2.attemptResize(QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) l.addItem(item2) item3 = QgsLayoutItemPicture(l) item3.attemptMove(QgsLayoutPoint(0.8, 1.2, QgsUnitTypes.LayoutCentimeters)) item3.attemptResize(QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) l.addItem(item3) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeLeft) self.assertEqual(item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().x(), 6.0, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().x(), 0.8, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeHCenter) self.assertAlmostEqual(item1.positionWithUnits().x(), 5.0, 3) self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().x(), 6.0, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().x(), 0.8, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeRight) self.assertAlmostEqual(item1.positionWithUnits().x(), 3.0, 3) self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().x(), 6.0, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().x(), 0.8, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeTop) self.assertAlmostEqual(item1.positionWithUnits().y(), 8.0, 3) self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().y(), 10.0, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().y(), 1.2, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeVCenter) self.assertAlmostEqual(item1.positionWithUnits().y(), 8.0, 3) self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().y(), 12.5, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().y(), 1.2, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters)) QgsLayoutAligner.distributeItems(l, [item1, item2, item3], QgsLayoutAligner.DistributeBottom) self.assertAlmostEqual(item1.positionWithUnits().y(), 8.0, 3) self.assertEqual(item1.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item2.positionWithUnits().y(), 15.0, 3) self.assertEqual(item2.positionWithUnits().units(), QgsUnitTypes.LayoutMillimeters) self.assertEqual(item2.sizeWithUnits(), QgsLayoutSize(10, 9, QgsUnitTypes.LayoutMillimeters)) self.assertAlmostEqual(item3.positionWithUnits().y(), 1.2, 3) self.assertEqual(item3.positionWithUnits().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(item3.sizeWithUnits(), QgsLayoutSize(1.8, 1.6, QgsUnitTypes.LayoutCentimeters))
def activeLayer(self): """Get pointer to the active layer (layer selected in the legend)""" myLayers = QgsProject.instance().mapLayers() for myItem in myLayers: return myLayers[myItem]
class TestQgsLayerTreeView(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) # setup a dummy project self.project = QgsProject() self.layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory") self.layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2", "memory") self.layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3", "memory") self.layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4", "memory") self.layer5 = QgsVectorLayer("Point?field=fldtxt:string", "layer5", "memory") self.project.addMapLayers([self.layer, self.layer2, self.layer3]) self.model = QgsLayerTreeModel(self.project.layerTreeRoot()) def nodeOrder(self, group): nodeorder = [] layerTree = QgsLayerTree() for node in group: if QgsLayerTree.isGroup(node): groupname = node.name() nodeorder.append(groupname) for child in self.nodeOrder(node.children()): nodeorder.append(groupname + '-' + child) elif QgsLayerTree.isLayer(node): nodeorder.append(node.layer().name()) return nodeorder def testSetModel(self): view = QgsLayerTreeView() # should not work string_list_model = QStringListModel() view.setModel(string_list_model) self.assertFalse(view.model()) # should work view.setModel(self.model) self.assertEqual(view.model(), self.model) def testSetCurrentLayer(self): view = QgsLayerTreeView() view.setModel(self.model) current_layer_changed_spy = QSignalSpy(view.currentLayerChanged) self.assertFalse(view.currentLayer()) view.setCurrentLayer(self.layer3) self.assertEqual(view.currentLayer(), self.layer3) self.assertEqual(len(current_layer_changed_spy), 1) view.setCurrentLayer(self.layer) self.assertEqual(view.currentLayer(), self.layer) self.assertEqual(len(current_layer_changed_spy), 2) view.setCurrentLayer(None) self.assertFalse(view.currentLayer()) self.assertEqual(len(current_layer_changed_spy), 3) def testDefaultActions(self): view = QgsLayerTreeView() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) # show in overview action view.setCurrentLayer(self.layer) self.assertEqual(view.currentNode().customProperty('overview', 0), False) show_in_overview = actions.actionShowInOverview() show_in_overview.trigger() self.assertEqual(view.currentNode().customProperty('overview', 0), True) show_in_overview.trigger() self.assertEqual(view.currentNode().customProperty('overview', 0), False) def testMoveOutOfGroupActionLayer(self): """Test move out of group action on layer""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) view.setCurrentLayer(self.layer5) moveOutOfGroup = actions.actionMoveOutOfGroup() moveOutOfGroup.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), self.layer5.name(), groupname, groupname + '-' + self.layer4.name(), ]) def testMoveToTopActionLayer(self): """Test move to top action on layer""" view = QgsLayerTreeView() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer, self.layer2, self.layer3]) view.setCurrentLayer(self.layer3) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual(self.project.layerTreeRoot().layerOrder(), [self.layer3, self.layer, self.layer2]) def testMoveToTopActionGroup(self): """Test move to top action on group""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) nodeLayerIndex = self.model.node2index(group) view.setCurrentIndex(nodeLayerIndex) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), self.layer.name(), self.layer2.name(), self.layer3.name(), ]) def testMoveToTopActionEmbeddedGroup(self): """Test move to top action on embeddedgroup layer""" view = QgsLayerTreeView() group = self.project.layerTreeRoot().addGroup("embeddedgroup") group.addLayer(self.layer4) group.addLayer(self.layer5) groupname = group.name() view.setModel(self.model) actions = QgsLayerTreeViewDefaultActions(view) self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer4.name(), groupname + '-' + self.layer5.name(), ]) view.setCurrentLayer(self.layer5) movetotop = actions.actionMoveToTop() movetotop.trigger() self.assertEqual( self.nodeOrder(self.project.layerTreeRoot().children()), [ self.layer.name(), self.layer2.name(), self.layer3.name(), groupname, groupname + '-' + self.layer5.name(), groupname + '-' + self.layer4.name(), ])
def testReadWriteXml(self): p = QgsProject() l = QgsPrintLayout(p) l.setName('my layout') l.setUnits(QgsUnitTypes.LayoutInches) collection = l.pageCollection() # add a page page = QgsLayoutItemPage(l) page.setPageSize('A6') collection.addPage(page) grid = l.gridSettings() grid.setResolution(QgsLayoutMeasurement(5, QgsUnitTypes.LayoutPoints)) g1 = QgsLayoutGuide( Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) l.guides().addGuide(g1) snapper = l.snapper() snapper.setSnapTolerance(7) # add some items item1 = QgsLayoutItemMap(l) item1.setId('xxyyxx') l.addItem(item1) item2 = QgsLayoutItemMap(l) item2.setId('zzyyzz') l.addItem(item2) l.setReferenceMap(item2) doc = QDomDocument("testdoc") elem = l.writeXml(doc, QgsReadWriteContext()) l2 = QgsPrintLayout(p) self.assertTrue(l2.readXml(elem, doc, QgsReadWriteContext())) self.assertEqual(l2.name(), 'my layout') self.assertEqual(l2.units(), QgsUnitTypes.LayoutInches) collection2 = l2.pageCollection() self.assertEqual(collection2.pageCount(), 1) self.assertAlmostEqual(collection2.page(0).pageSize().width(), 105, 4) self.assertEqual(collection2.page(0).pageSize().height(), 148) self.assertEqual(l2.gridSettings().resolution().length(), 5.0) self.assertEqual(l2.gridSettings().resolution().units(), QgsUnitTypes.LayoutPoints) self.assertEqual(l2.guides().guidesOnPage(0)[0].orientation(), Qt.Horizontal) self.assertEqual(l2.guides().guidesOnPage(0)[0].position().length(), 5.0) self.assertEqual(l2.guides().guidesOnPage(0)[0].position().units(), QgsUnitTypes.LayoutCentimeters) self.assertEqual(l2.snapper().snapTolerance(), 7) # check restored items new_item1 = l2.itemByUuid(item1.uuid()) self.assertTrue(new_item1) self.assertEqual(new_item1.id(), 'xxyyxx') new_item2 = l2.itemByUuid(item2.uuid()) self.assertTrue(new_item2) self.assertEqual(new_item2.id(), 'zzyyzz') self.assertEqual(l2.referenceMap().id(), 'zzyyzz')
def addFeature(self): text = self.lineEdit.text().strip() if text == "": return layer = self.iface.activeLayer() if layer is None: return try: if (self.inputProjection == 0) or (text[0] == '{'): # If this is GeoJson it does not matter what inputProjection is if text[0] == '{': # This may be a GeoJSON point codec = QTextCodec.codecForName("UTF-8") fields = QgsJsonUtils.stringToFields(text, codec) fet = QgsJsonUtils.stringToFeatureList(text, fields, codec) if (len(fet) == 0) or not fet[0].isValid(): raise ValueError('Invalid Coordinates') geom = fet[0].geometry() if geom.isEmpty() or (geom.wkbType() != QgsWkbTypes.Point): raise ValueError('Invalid GeoJSON Geometry') pt = geom.asPoint() lat = pt.y() lon = pt.x() elif re.search(r'POINT\(', text) is not None: m = re.findall(r'POINT\(\s*([+-]?\d*\.?\d*)\s+([+-]?\d*\.?\d*)', text) if len(m) != 1: raise ValueError('Invalid Coordinates') lon = float(m[0][0]) lat = float(m[0][1]) else: lat, lon = parseDMSString(text, self.inputXYOrder) srcCrs = epsg4326 elif self.inputProjection == 1: # This is an MGRS coordinate text = re.sub(r'\s+', '', text) # Remove all white space lat, lon = mgrs.toWgs(text) srcCrs = epsg4326 elif self.inputProjection == 4: text = text.strip() coord = olc.decode(text) lat = coord.latitudeCenter lon = coord.longitudeCenter srcCrs = epsg4326 elif self.inputProjection == 5: text = text.strip() pt = utm2Point(text, epsg4326) lat = pt.y() lon = pt.x() srcCrs = epsg4326 else: # Is either the project or custom CRS if re.search(r'POINT\(', text) is None: coords = re.split(r'[\s,;:]+', text, 1) if len(coords) < 2: raise ValueError('Invalid Coordinates') if self.inputXYOrder == 0: # Y, X Order lat = float(coords[0]) lon = float(coords[1]) else: lon = float(coords[0]) lat = float(coords[1]) else: m = re.findall(r'POINT\(\s*([+-]?\d*\.?\d*)\s+([+-]?\d*\.?\d*)', text) if len(m) != 1: raise ValueError('Invalid Coordinates') lon = float(m[0][0]) lat = float(m[0][1]) if self.inputProjection == 2: # Project CRS srcCrs = self.canvas.mapSettings().destinationCrs() else: srcCrs = QgsCoordinateReferenceSystem(self.inputCustomCRS) except Exception: # traceback.print_exc() self.iface.messageBar().pushMessage("", "Invalid Coordinate", level=Qgis.Warning, duration=2) return self.lineEdit.clear() caps = layer.dataProvider().capabilities() if caps & QgsVectorDataProvider.AddFeatures: destCRS = layer.crs() # Get the CRS of the layer we are adding a point toWgs transform = QgsCoordinateTransform(srcCrs, destCRS, QgsProject.instance()) # Transform the input coordinate projection to the layer CRS x, y = transform.transform(float(lon), float(lat)) geom = QgsGeometry.fromPointXY(QgsPointXY(x, y)) feat = QgsVectorLayerUtils.createFeature(layer, geom, {}, layer.createExpressionContext() ) if layer.fields().count() == 0: layer.addFeature(feat) self.lltools.zoomTo(srcCrs, lat, lon) else: if self.iface.openFeatureForm(layer, feat): layer.addFeature(feat) self.lltools.zoomTo(srcCrs, lat, lon)
def testAddItemsFromXml(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemLabel(l) item1.setId('xxyyxx') item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemLabel(l) item2.setId('zzyyzz') item2.attemptMove( QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) item2.attemptResize( QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) l.addItem(item2) doc = QDomDocument("testdoc") # store in xml elem = l.writeXml(doc, QgsReadWriteContext()) l2 = QgsLayout(p) new_items = l2.addItemsFromXml(elem, doc, QgsReadWriteContext()) self.assertEqual(len(new_items), 2) items = l2.items() self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) new_item1 = [i for i in items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.positionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( new_item2.positionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) # test with a group group = QgsLayoutItemGroup(l) group.addItem(item1) group.addItem(item2) l.addLayoutItem(group) elem = l.writeXml(doc, QgsReadWriteContext()) l3 = QgsLayout(p) new_items = l3.addItemsFromXml(elem, doc, QgsReadWriteContext()) self.assertEqual(len(new_items), 3) items = l3.items() self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue(new_items[0] in l3.items()) self.assertTrue(new_items[1] in l3.items()) self.assertTrue(new_items[2] in l3.items()) # f*** you sip, I'll just manually cast new_group = sip.cast(l3.itemByUuid(group.uuid()), QgsLayoutItemGroup) self.assertIsNotNone(new_group) other_items = [i for i in new_items if i.type() != new_group.type()] self.assertCountEqual(new_group.items(), other_items) # test restoring at set position l3 = QgsLayout(p) new_items = l3.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 30)) self.assertEqual(len(new_items), 3) items = l3.items() new_item1 = [i for i in items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in items if i.id() == 'zzyyzz'][0] self.assertEqual( new_item1.positionWithUnits(), QgsLayoutPoint(10, 30, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( new_item2.positionWithUnits(), QgsLayoutPoint(2.0, 4.0, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) # paste in place l4 = QgsLayout(p) page = QgsLayoutItemPage(l) page.setPageSize('A3') l4.pageCollection().addPage(page) page = QgsLayoutItemPage(l) page.setPageSize('A6') l4.pageCollection().addPage(page) new_items = l4.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 30), True) self.assertEqual(len(new_items), 3) new_item1 = [i for i in new_items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in new_items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.pagePositionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.page(), 0) self.assertEqual( new_item2.pagePositionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(new_item2.page(), 0) # paste in place, page 2 new_items = l4.addItemsFromXml(elem, doc, QgsReadWriteContext(), QPointF(10, 550), True) self.assertEqual(len(new_items), 3) new_item1 = [i for i in new_items if i.id() == 'xxyyxx'][0] new_item2 = [i for i in new_items if i.id() == 'zzyyzz'][0] self.assertEqual(new_item1.pagePositionWithUnits(), QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) self.assertEqual(new_item1.page(), 1) self.assertEqual(new_item1.sizeWithUnits(), QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) self.assertEqual( new_item2.pagePositionWithUnits(), QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) self.assertEqual(new_item2.page(), 1) self.assertEqual( new_item2.sizeWithUnits(), QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters))
def testStacking(self): p = QgsProject() l = QgsLayout(p) # add some items item1 = QgsLayoutItemMap(l) l.addLayoutItem(item1) item2 = QgsLayoutItemMap(l) l.addLayoutItem(item2) item3 = QgsLayoutItemMap(l) l.addLayoutItem(item3) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 3) # no effect interactions self.assertFalse(l.raiseItem(None)) self.assertFalse(l.lowerItem(None)) self.assertFalse(l.moveItemToTop(None)) self.assertFalse(l.moveItemToBottom(None)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 3) # raising self.assertFalse(l.raiseItem(item3)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 3) self.assertTrue(l.raiseItem(item2)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) self.assertFalse(l.raiseItem(item2)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) self.assertTrue(l.raiseItem(item1)) self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 1) # lower self.assertFalse(l.lowerItem(item3)) self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 1) self.assertTrue(l.lowerItem(item2)) self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 2) self.assertEqual(item3.zValue(), 1) self.assertTrue(l.lowerItem(item2)) self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 2) # raise to top self.assertFalse(l.moveItemToTop(item1)) self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 2) self.assertTrue(l.moveItemToTop(item3)) self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 3) self.assertTrue(l.moveItemToTop(item2)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) # move to bottom self.assertFalse(l.moveItemToBottom(item1)) self.assertEqual(item1.zValue(), 1) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 2) self.assertTrue(l.moveItemToBottom(item3)) self.assertEqual(item1.zValue(), 2) self.assertEqual(item2.zValue(), 3) self.assertEqual(item3.zValue(), 1) self.assertTrue(l.moveItemToBottom(item2)) self.assertEqual(item1.zValue(), 3) self.assertEqual(item2.zValue(), 1) self.assertEqual(item3.zValue(), 2)
def testSnapPointsToItems(self): p = QgsProject() l = QgsLayout(p) page = QgsLayoutItemPage(l) page.setPageSize('A4') #l.pageCollection().addPage(page) s = QgsLayoutSnapper(l) guides = l.guides() s.setSnapToItems(True) s.setSnapTolerance(1) # no items point, snapped = s.snapPointsToItems([0.5], Qt.Horizontal, 1, []) self.assertFalse(snapped) line = QGraphicsLineItem() line.setVisible(True) point, snapped = s.snapPointsToItems([0.5], Qt.Horizontal, 1, [], line) self.assertFalse(line.isVisible()) guides.addGuide( QgsLayoutGuide(Qt.Vertical, QgsLayoutMeasurement(1), page)) # add an item item1 = QgsLayoutItemMap(l) item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) point, snapped = s.snapPointsToItems([3.5], Qt.Horizontal, 1, [], line) self.assertTrue(snapped) self.assertEqual(point, 0.5) self.assertTrue(line.isVisible()) point, snapped = s.snapPointsToItems([4.5], Qt.Horizontal, 1, []) self.assertTrue(snapped) self.assertEqual(point, -0.5) point, snapped = s.snapPointsToItems([4.6, 4.5], Qt.Horizontal, 1, []) self.assertTrue(snapped) self.assertEqual(point, -0.5) point, snapped = s.snapPointsToItems([4.6, 4.5, 3.7], Qt.Horizontal, 1, []) self.assertTrue(snapped) self.assertAlmostEqual(point, 0.3, 5) # ignoring item point, snapped = s.snapPointsToItems([4.5], Qt.Horizontal, 1, [item1]) self.assertFalse(snapped) # outside tolerance point, snapped = s.snapPointsToItems([5.5], Qt.Horizontal, 1, [], line) self.assertFalse(snapped) self.assertFalse(line.isVisible()) # snap to center point, snapped = s.snapPointsToItems([12.5], Qt.Horizontal, 1, []) self.assertTrue(snapped) self.assertEqual(point, 0.5) # snap to right point, snapped = s.snapPointsToItems([22.5], Qt.Horizontal, 1, []) self.assertTrue(snapped) self.assertEqual(point, -0.5) #snap to top point, snapped = s.snapPointsToItems([7.5], Qt.Vertical, 1, [], line) self.assertTrue(snapped) self.assertEqual(point, 0.5) self.assertTrue(line.isVisible()) point, snapped = s.snapPointsToItems([8.5], Qt.Vertical, 1, []) self.assertTrue(snapped) self.assertEqual(point, -0.5) # outside tolerance point, snapped = s.snapPointsToItems([5.5], Qt.Vertical, 1, [], line) self.assertFalse(snapped) self.assertFalse(line.isVisible()) # snap to center point, snapped = s.snapPointsToItems([13.5], Qt.Vertical, 1, []) self.assertTrue(snapped) self.assertEqual(point, 0.5) # snap to bottom point, snapped = s.snapPointsToItems([20.5], Qt.Vertical, 1, []) self.assertTrue(snapped) self.assertEqual(point, -0.5) # snapping off s.setSnapToItems(False) line.setVisible(True) point, snapped = s.snapPointsToItems([20.5], Qt.Vertical, 1, [], line) self.assertFalse(snapped) self.assertFalse(line.isVisible()) # with different pixel scale s.setSnapToItems(True) point, snapped = s.snapPointsToItems([20.5], Qt.Vertical, 3, []) self.assertFalse(snapped)
def testSaveLoadTemplate(self): tmpfile = os.path.join(self.basetestpath, 'testTemplate.qpt') p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add some items item1 = QgsLayoutItemLabel(l) item1.setId('xxyyxx') item1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) item1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) item2 = QgsLayoutItemLabel(l) item2.setId('zzyyzz') item2.attemptMove( QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) item2.attemptResize( QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) l.addItem(item2) # multiframe multiframe1 = QgsLayoutItemHtml(l) multiframe1.setHtml('mf1') l.addMultiFrame(multiframe1) frame1 = QgsLayoutFrame(l, multiframe1) frame1.setId('frame1') frame1.attemptMove(QgsLayoutPoint(4, 8, QgsUnitTypes.LayoutMillimeters)) frame1.attemptResize( QgsLayoutSize(18, 12, QgsUnitTypes.LayoutMillimeters)) multiframe1.addFrame(frame1) multiframe2 = QgsLayoutItemHtml(l) multiframe2.setHtml('mf2') l.addMultiFrame(multiframe2) frame2 = QgsLayoutFrame(l, multiframe2) frame2.setId('frame2') frame2.attemptMove( QgsLayoutPoint(1.4, 1.8, QgsUnitTypes.LayoutCentimeters)) frame2.attemptResize( QgsLayoutSize(2.8, 2.2, QgsUnitTypes.LayoutCentimeters)) multiframe2.addFrame(frame2) uuids = { item1.uuid(), item2.uuid(), frame1.uuid(), frame2.uuid(), multiframe1.uuid(), multiframe2.uuid() } original_uuids = { item1.uuid(), item2.uuid(), frame1.uuid(), frame2.uuid() } self.assertTrue(l.saveAsTemplate(tmpfile, QgsReadWriteContext())) l2 = QgsLayout(p) with open(tmpfile) as f: template_content = f.read() doc = QDomDocument() doc.setContent(template_content) # adding to existing items new_items, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items), 4) items = l2.items() multiframes = l2.multiFrames() self.assertEqual(len(multiframes), 2) self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue([i for i in items if i.id() == 'frame1']) self.assertTrue([i for i in items if i.id() == 'frame2']) self.assertTrue([i for i in multiframes if i.html() == 'mf1']) self.assertTrue([i for i in multiframes if i.html() == 'mf2']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) self.assertTrue(new_items[2] in l2.items()) self.assertTrue(new_items[3] in l2.items()) # double check that new items have a unique uid self.assertNotIn(new_items[0].uuid(), uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items[1].uuid(), uuids) uuids.add(new_items[1].uuid()) self.assertNotIn(new_items[2].uuid(), uuids) uuids.add(new_items[2].uuid()) self.assertNotIn(new_items[3].uuid(), uuids) uuids.add(new_items[3].uuid()) self.assertNotIn( multiframes[0].uuid(), [multiframe1.uuid(), multiframe2.uuid()]) self.assertNotIn( multiframes[1].uuid(), [multiframe1.uuid(), multiframe2.uuid()]) new_multiframe1 = [i for i in multiframes if i.html() == 'mf1'][0] self.assertEqual(new_multiframe1.layout(), l2) new_multiframe2 = [i for i in multiframes if i.html() == 'mf2'][0] self.assertEqual(new_multiframe2.layout(), l2) new_frame1 = sip.cast([i for i in items if i.id() == 'frame1'][0], QgsLayoutFrame) new_frame2 = sip.cast([i for i in items if i.id() == 'frame2'][0], QgsLayoutFrame) self.assertEqual(new_frame1.multiFrame(), new_multiframe1) self.assertEqual(new_multiframe1.frames()[0].uuid(), new_frame1.uuid()) self.assertEqual(new_frame2.multiFrame(), new_multiframe2) self.assertEqual(new_multiframe2.frames()[0].uuid(), new_frame2.uuid()) # adding to existing items new_items2, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), False) self.assertTrue(ok) self.assertEqual(len(new_items2), 4) items = l2.items() self.assertEqual(len(items), 8) multiframes2 = l2.multiFrames() self.assertEqual(len(multiframes2), 4) multiframes2 = [ m for m in l2.multiFrames() if not m.uuid() in [new_multiframe1.uuid(), new_multiframe2.uuid()] ] self.assertEqual(len(multiframes2), 2) self.assertTrue([i for i in items if i.id() == 'xxyyxx']) self.assertTrue([i for i in items if i.id() == 'zzyyzz']) self.assertTrue([i for i in items if i.id() == 'frame1']) self.assertTrue([i for i in items if i.id() == 'frame2']) self.assertTrue([i for i in multiframes2 if i.html() == 'mf1']) self.assertTrue([i for i in multiframes2 if i.html() == 'mf2']) self.assertTrue(new_items[0] in l2.items()) self.assertTrue(new_items[1] in l2.items()) self.assertTrue(new_items[2] in l2.items()) self.assertTrue(new_items[3] in l2.items()) self.assertTrue(new_items2[0] in l2.items()) self.assertTrue(new_items2[1] in l2.items()) self.assertTrue(new_items2[2] in l2.items()) self.assertTrue(new_items2[3] in l2.items()) self.assertNotIn(new_items2[0].uuid(), uuids) uuids.add(new_items[0].uuid()) self.assertNotIn(new_items2[1].uuid(), uuids) uuids.add(new_items[1].uuid()) self.assertNotIn(new_items2[2].uuid(), uuids) uuids.add(new_items[2].uuid()) self.assertNotIn(new_items2[3].uuid(), uuids) uuids.add(new_items[3].uuid()) self.assertNotIn(multiframes2[0].uuid(), [ multiframe1.uuid(), multiframe2.uuid(), new_multiframe1.uuid(), new_multiframe2.uuid() ]) self.assertNotIn(multiframes2[1].uuid(), [ multiframe1.uuid(), multiframe2.uuid(), new_multiframe1.uuid(), new_multiframe2.uuid() ]) new_multiframe1b = [i for i in multiframes2 if i.html() == 'mf1'][0] self.assertEqual(new_multiframe1b.layout(), l2) new_multiframe2b = [i for i in multiframes2 if i.html() == 'mf2'][0] self.assertEqual(new_multiframe2b.layout(), l2) new_frame1b = sip.cast([ i for i in items if i.id() == 'frame1' and i.uuid() != new_frame1.uuid() ][0], QgsLayoutFrame) new_frame2b = sip.cast([ i for i in items if i.id() == 'frame2' and i.uuid() != new_frame2.uuid() ][0], QgsLayoutFrame) self.assertEqual(new_frame1b.multiFrame(), new_multiframe1b) self.assertEqual(new_multiframe1b.frames()[0].uuid(), new_frame1b.uuid()) self.assertEqual(new_frame2b.multiFrame(), new_multiframe2b) self.assertEqual(new_multiframe2b.frames()[0].uuid(), new_frame2b.uuid()) # clearing existing items new_items3, ok = l2.loadFromTemplate(doc, QgsReadWriteContext(), True) new_multiframes = l2.multiFrames() self.assertTrue(ok) self.assertEqual(len(new_items3), 5) # includes page self.assertEqual(len(new_multiframes), 2) items = l2.items() self.assertTrue([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'xxyyxx' ]) self.assertTrue([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'zzyyzz' ]) self.assertTrue([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame1' ]) self.assertTrue([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame2' ]) self.assertTrue(new_items3[0] in l2.items()) self.assertTrue(new_items3[1] in l2.items()) self.assertTrue(new_items3[2] in l2.items()) self.assertTrue(new_items3[3] in l2.items()) new_multiframe1 = [i for i in new_multiframes if i.html() == 'mf1'][0] new_multiframe2 = [i for i in new_multiframes if i.html() == 'mf2'][0] new_frame1 = sip.cast([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame1' ][0], QgsLayoutFrame) new_frame2 = sip.cast([ i for i in items if isinstance(i, QgsLayoutItem) and i.id() == 'frame2' ][0], QgsLayoutFrame) self.assertEqual(new_frame1.multiFrame(), new_multiframe1) self.assertEqual(new_multiframe1.frames()[0].uuid(), new_frame1.uuid()) self.assertEqual(new_frame2.multiFrame(), new_multiframe2) self.assertEqual(new_multiframe2.frames()[0].uuid(), new_frame2.uuid())
def __init__(self, map_theme, layer, extent, tile_size, mupp, output, make_trans, map_settings): """ :param map_theme: :param extent: :param layer: :param tile_size: :param mupp: :param output: :param map_settings: Map canvas map settings used for some fallback values and CRS """ self.extent = extent self.mupp = mupp self.tile_size = tile_size driver = self.getDriverForFile(output) if not driver: raise QgsProcessingException( u'Could not load GDAL driver for file {}'.format(output)) crs = map_settings.destinationCrs() self.x_tile_count = math.ceil(extent.width() / mupp / tile_size) self.y_tile_count = math.ceil(extent.height() / mupp / tile_size) xsize = self.x_tile_count * tile_size ysize = self.y_tile_count * tile_size if make_trans: no_bands = 4 else: no_bands = 3 self.dataset = driver.Create(output, xsize, ysize, no_bands) self.dataset.SetProjection(str(crs.toWkt())) self.dataset.SetGeoTransform( [extent.xMinimum(), mupp, 0, extent.yMaximum(), 0, -mupp]) self.image = QImage(QSize(tile_size, tile_size), QImage.Format_ARGB32) self.settings = QgsMapSettings() self.settings.setOutputDpi(self.image.logicalDpiX()) self.settings.setOutputImageFormat(QImage.Format_ARGB32) self.settings.setDestinationCrs(crs) self.settings.setOutputSize(self.image.size()) self.settings.setFlag(QgsMapSettings.Antialiasing, True) self.settings.setFlag(QgsMapSettings.RenderMapTile, True) self.settings.setFlag(QgsMapSettings.UseAdvancedEffects, True) if make_trans: self.settings.setBackgroundColor(QColor(255, 255, 255, 0)) else: self.settings.setBackgroundColor(QColor(255, 255, 255)) if QgsProject.instance().mapThemeCollection().hasMapTheme(map_theme): self.settings.setLayers( QgsProject.instance().mapThemeCollection( ).mapThemeVisibleLayers( map_theme)) self.settings.setLayerStyleOverrides( QgsProject.instance().mapThemeCollection( ).mapThemeStyleOverrides( map_theme)) elif layer: self.settings.setLayers([layer]) else: self.settings.setLayers(map_settings.layers())
def testSnapRect(self): p = QgsProject() l = QgsLayout(p) page = QgsLayoutItemPage(l) page.setPageSize('A4') l.pageCollection().addPage(page) s = QgsLayoutSnapper(l) guides = l.guides() # first test snapping to grid l.gridSettings().setResolution( QgsLayoutMeasurement(5, QgsUnitTypes.LayoutMillimeters)) s.setSnapToItems(False) s.setSnapToGrid(True) s.setSnapTolerance(1) rect, snapped = s.snapRect(QRectF(1, 1, 2, 1), 1) self.assertTrue(snapped) self.assertEqual(rect, QRectF(0, 0, 2, 1)) rect, snapped = s.snapRect(QRectF(1, 1, 3.5, 3.5), 1) self.assertTrue(snapped) self.assertEqual(rect, QRectF(1.5, 1.5, 3.5, 3.5)) s.setSnapToItems(False) s.setSnapToGrid(False) rect, snapped = s.snapRect(QRectF(1, 1, 3.5, 3.5), 1) self.assertFalse(snapped) self.assertEqual(rect, QRectF(1, 1, 3.5, 3.5)) # test that guide takes precedence s.setSnapToGrid(True) s.setSnapToGuides(True) guides.addGuide( QgsLayoutGuide(Qt.Horizontal, QgsLayoutMeasurement(0.5), page)) rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1) self.assertTrue(snapped) self.assertEqual(rect, QRectF(0.0, 0.5, 2.0, 3.0)) # add an item item1 = QgsLayoutItemMap(l) item1.attemptMove( QgsLayoutPoint(121, 1.1, QgsUnitTypes.LayoutMillimeters)) l.addItem(item1) # test that guide takes precedence over item s.setSnapToGrid(True) s.setSnapToGuides(True) s.setSnapToItems(True) rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1) self.assertTrue(snapped) self.assertEqual(rect, QRectF(0.0, 0.5, 2.0, 3.0)) # but items take precedence over grid s.setSnapToGuides(False) rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1) self.assertTrue(snapped) self.assertEqual(rect, QRectF(0.0, 1.1, 2.0, 3.0)) # ... unless item is ignored! rect, snapped = s.snapRect(QRectF(1, 1, 2, 3), 1, None, None, [item1]) self.assertTrue(snapped) self.assertEqual(rect, QRectF(0.0, 0.0, 2.0, 3.0))