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 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))
def testCollection(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add a page guides = l.guides() # no guides initially self.assertEqual(guides.rowCount(QModelIndex()), 0) self.assertFalse( guides.data(QModelIndex(), QgsLayoutGuideCollection.OrientationRole)) self.assertFalse(guides.guides(QgsLayoutGuide.Horizontal)) self.assertFalse(guides.guides(QgsLayoutGuide.Vertical)) # add a guide g1 = QgsLayoutGuide( QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) guides.addGuide(g1) self.assertEqual(guides.rowCount(QModelIndex()), 1) self.assertEqual( guides.data(guides.index(0, 0), QgsLayoutGuideCollection.OrientationRole), QgsLayoutGuide.Horizontal) self.assertEqual( guides.data(guides.index(0, 0), QgsLayoutGuideCollection.PositionRole), 5) self.assertEqual( guides.data(guides.index(0, 0), QgsLayoutGuideCollection.UnitsRole), QgsUnitTypes.LayoutCentimeters) self.assertEqual( guides.data(guides.index(0, 0), QgsLayoutGuideCollection.PageRole), 0) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [g1]) self.assertFalse(guides.guides(QgsLayoutGuide.Vertical)) self.assertEqual(guides.guidesOnPage(0), [g1]) self.assertEqual(guides.guidesOnPage(1), []) g2 = QgsLayoutGuide(QgsLayoutGuide.Horizontal, QgsLayoutMeasurement(15), l.pageCollection().page(0)) guides.addGuide(g2) self.assertEqual(guides.rowCount(QModelIndex()), 2) self.assertEqual( guides.data(guides.index(1, 0), QgsLayoutGuideCollection.OrientationRole), QgsLayoutGuide.Horizontal) self.assertEqual( guides.data(guides.index(1, 0), QgsLayoutGuideCollection.PositionRole), 15) self.assertEqual( guides.data(guides.index(1, 0), QgsLayoutGuideCollection.UnitsRole), QgsUnitTypes.LayoutMillimeters) self.assertEqual( guides.data(guides.index(1, 0), QgsLayoutGuideCollection.PageRole), 0) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [g1, g2]) self.assertFalse(guides.guides(QgsLayoutGuide.Vertical)) self.assertEqual(guides.guidesOnPage(0), [g1, g2]) page2 = QgsLayoutItemPage(l) page2.setPageSize('A3') l.pageCollection().addPage(page2) g3 = QgsLayoutGuide(QgsLayoutGuide.Vertical, QgsLayoutMeasurement(35), l.pageCollection().page(1)) guides.addGuide(g3) self.assertEqual(guides.rowCount(QModelIndex()), 3) self.assertEqual( guides.data(guides.index(2, 0), QgsLayoutGuideCollection.OrientationRole), QgsLayoutGuide.Vertical) self.assertEqual( guides.data(guides.index(2, 0), QgsLayoutGuideCollection.PositionRole), 35) self.assertEqual( guides.data(guides.index(2, 0), QgsLayoutGuideCollection.UnitsRole), QgsUnitTypes.LayoutMillimeters) self.assertEqual( guides.data(guides.index(2, 0), QgsLayoutGuideCollection.PageRole), 1) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal), [g1, g2]) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal, 0), [g1, g2]) self.assertEqual(guides.guides(QgsLayoutGuide.Horizontal, 1), []) self.assertEqual(guides.guides(QgsLayoutGuide.Vertical), [g3]) self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 0), []) self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 1), [g3]) self.assertEqual(guides.guides(QgsLayoutGuide.Vertical, 2), []) self.assertEqual(guides.guidesOnPage(0), [g1, g2]) self.assertEqual(guides.guidesOnPage(1), [g3])
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 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 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 testLegendRenderWithMapTheme(self): """Test rendering legends linked to map themes""" QgsProject.instance().removeAllMapLayers() point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') line_path = os.path.join(TEST_DATA_DIR, 'lines.shp') line_layer = QgsVectorLayer(line_path, 'lines', 'ogr') QgsProject.instance().clear() QgsProject.instance().addMapLayers([point_layer, line_layer]) marker_symbol = QgsMarkerSymbol.createSimple({ 'color': '#ff0000', 'outline_style': 'no', 'size': '5' }) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) point_layer.styleManager().addStyleFromLayer("red") line_symbol = QgsLineSymbol.createSimple({ 'color': '#ff0000', 'line_width': '2' }) line_layer.setRenderer(QgsSingleSymbolRenderer(line_symbol)) line_layer.styleManager().addStyleFromLayer("red") red_record = QgsMapThemeCollection.MapThemeRecord() point_red_record = QgsMapThemeCollection.MapThemeLayerRecord( point_layer) point_red_record.usingCurrentStyle = True point_red_record.currentStyle = 'red' red_record.addLayerRecord(point_red_record) line_red_record = QgsMapThemeCollection.MapThemeLayerRecord(line_layer) line_red_record.usingCurrentStyle = True line_red_record.currentStyle = 'red' red_record.addLayerRecord(line_red_record) QgsProject.instance().mapThemeCollection().insert('red', red_record) marker_symbol1 = QgsMarkerSymbol.createSimple({ 'color': '#0000ff', 'outline_style': 'no', 'size': '5' }) marker_symbol2 = QgsMarkerSymbol.createSimple({ 'color': '#0000ff', 'name': 'diamond', 'outline_style': 'no', 'size': '5' }) marker_symbol3 = QgsMarkerSymbol.createSimple({ 'color': '#0000ff', 'name': 'rectangle', 'outline_style': 'no', 'size': '5' }) point_layer.setRenderer( QgsCategorizedSymbolRenderer('Class', [ QgsRendererCategory('B52', marker_symbol1, ''), QgsRendererCategory('Biplane', marker_symbol2, ''), QgsRendererCategory('Jet', marker_symbol3, ''), ])) point_layer.styleManager().addStyleFromLayer("blue") line_symbol = QgsLineSymbol.createSimple({ 'color': '#0000ff', 'line_width': '2' }) line_layer.setRenderer(QgsSingleSymbolRenderer(line_symbol)) line_layer.styleManager().addStyleFromLayer("blue") blue_record = QgsMapThemeCollection.MapThemeRecord() point_blue_record = QgsMapThemeCollection.MapThemeLayerRecord( point_layer) point_blue_record.usingCurrentStyle = True point_blue_record.currentStyle = 'blue' blue_record.addLayerRecord(point_blue_record) line_blue_record = QgsMapThemeCollection.MapThemeLayerRecord( line_layer) line_blue_record.usingCurrentStyle = True line_blue_record.currentStyle = 'blue' blue_record.addLayerRecord(line_blue_record) QgsProject.instance().mapThemeCollection().insert('blue', blue_record) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map1 = QgsLayoutItemMap(layout) map1.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map1.setFrameEnabled(True) map1.setLayers([point_layer, line_layer]) layout.addLayoutItem(map1) map1.setExtent(point_layer.extent()) map1.setFollowVisibilityPreset(True) map1.setFollowVisibilityPresetName('red') map2 = QgsLayoutItemMap(layout) map2.attemptSetSceneRect(QRectF(20, 120, 80, 80)) map2.setFrameEnabled(True) map2.setLayers([point_layer, line_layer]) layout.addLayoutItem(map2) map2.setExtent(point_layer.extent()) map2.setFollowVisibilityPreset(True) map2.setFollowVisibilityPresetName('blue') legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setLinkedMap(map1) legend2 = QgsLayoutItemLegend(layout) legend2.setTitle("Legend") legend2.attemptSetSceneRect(QRectF(120, 120, 80, 80)) legend2.setFrameEnabled(True) legend2.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend2.setBackgroundColor(QColor(200, 200, 200)) legend2.setTitle('') layout.addLayoutItem(legend2) legend2.setLinkedMap(map2) checker = QgsLayoutChecker('composer_legend_theme', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() TestQgsLayoutItemLegend.report += checker.report() self.assertTrue(result, message) QgsProject.instance().clear()
def testLegendRenderLinkedMapScale(self): """Test rendering legends linked to maps follow scale correctly""" QgsProject.instance().removeAllMapLayers() line_path = os.path.join(TEST_DATA_DIR, 'lines.shp') line_layer = QgsVectorLayer(line_path, 'lines', 'ogr') QgsProject.instance().clear() QgsProject.instance().addMapLayers([line_layer]) line_symbol = QgsLineSymbol.createSimple({ 'color': '#ff0000', 'width_unit': 'mapunits', 'width': '0.0001' }) line_layer.setRenderer(QgsSingleSymbolRenderer(line_symbol)) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map1 = QgsLayoutItemMap(layout) map1.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map1.setFrameEnabled(True) map1.setLayers([line_layer]) layout.addLayoutItem(map1) map1.setExtent(line_layer.extent()) map1.setScale(2000) map2 = QgsLayoutItemMap(layout) map2.attemptSetSceneRect(QRectF(20, 120, 80, 80)) map2.setFrameEnabled(True) map2.setLayers([line_layer]) layout.addLayoutItem(map2) map2.setExtent(line_layer.extent()) map2.setScale(5000) legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setLinkedMap(map1) legend2 = QgsLayoutItemLegend(layout) legend2.setTitle("Legend") legend2.attemptSetSceneRect(QRectF(120, 120, 80, 80)) legend2.setFrameEnabled(True) legend2.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend2.setBackgroundColor(QColor(200, 200, 200)) legend2.setTitle('') layout.addLayoutItem(legend2) legend2.setLinkedMap(map2) checker = QgsLayoutChecker('composer_legend_scale_map', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() TestQgsLayoutItemLegend.report += checker.report() self.assertTrue(result, message) QgsProject.instance().clear()
def testInitialSizeSymbolMapUnits(self): """Test initial size of legend with a symbol size in map units""" QgsProject.instance().removeAllMapLayers() point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') QgsProject.instance().clear() QgsProject.instance().addMapLayers([point_layer]) marker_symbol = QgsMarkerSymbol.createSimple({ 'color': '#ff0000', 'outline_style': 'no', 'size': '5', 'size_unit': 'MapUnit' }) point_layer.setRenderer(QgsSingleSymbolRenderer(marker_symbol)) s = QgsMapSettings() s.setLayers([point_layer]) layout = QgsLayout(QgsProject.instance()) layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 80, 80)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') layout.addLayoutItem(legend) legend.setLinkedMap(map) checker = QgsLayoutChecker('composer_legend_mapunits', layout) checker.setControlPathPrefix("composer_legend") result, message = checker.testLayout() TestQgsLayoutItemLegend.report += checker.report() self.assertTrue(result, message) # resize with non-top-left reference point legend.setResizeToContents(False) legend.setReferencePoint(QgsLayoutItem.LowerRight) legend.attemptMove(QgsLayoutPoint(120, 90)) legend.attemptResize(QgsLayoutSize(50, 60)) self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 70, -1) self.assertAlmostEqual(legend.pos().y(), 30, -1) legend.setResizeToContents(True) legend.updateLegend() self.assertEqual(legend.positionWithUnits().x(), 120.0) self.assertEqual(legend.positionWithUnits().y(), 90.0) self.assertAlmostEqual(legend.pos().x(), 91, -1) self.assertAlmostEqual(legend.pos().y(), 71, -1) QgsProject.instance().removeMapLayers([point_layer.id()])
def testSymbolExpressionRender(self): """Test expressions embedded in legend node text""" point_path = os.path.join(TEST_DATA_DIR, 'points.shp') point_layer = QgsVectorLayer(point_path, 'points', 'ogr') layout = QgsPrintLayout(QgsProject.instance()) layout.setName('LAYOUT') layout.initializeDefaults() map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(20, 20, 80, 80)) map.setFrameEnabled(True) map.setLayers([point_layer]) layout.addLayoutItem(map) map.setExtent(point_layer.extent()) legend = QgsLayoutItemLegend(layout) legend.setTitle("Legend") legend.attemptSetSceneRect(QRectF(120, 20, 100, 100)) legend.setFrameEnabled(True) legend.setFrameStrokeWidth(QgsLayoutMeasurement(2)) legend.setBackgroundColor(QColor(200, 200, 200)) legend.setTitle('') legend.setLegendFilterByMapEnabled(False) legend.setStyleFont(QgsLegendStyle.Title, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Group, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Subgroup, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.Symbol, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setStyleFont(QgsLegendStyle.SymbolLabel, QgsFontUtils.getStandardTestFont('Bold', 16)) legend.setAutoUpdateModel(False) QgsProject.instance().addMapLayers([point_layer]) s = QgsMapSettings() s.setLayers([point_layer]) group = legend.model().rootGroup().addGroup( "Group [% 1 + 5 %] [% @layout_name %]") layer_tree_layer = group.addLayer(point_layer) counterTask = point_layer.countSymbolFeatures() counterTask.waitForFinished() layer_tree_layer.setCustomProperty( "legend/title-label", 'bbbb [% 1+2 %] xx [% @layout_name %] [% @layer_name %]') QgsMapLayerLegendUtils.setLegendNodeUserLabel(layer_tree_layer, 0, 'xxxx') legend.model().refreshLayerLegend(layer_tree_layer) layer_tree_layer.setLabelExpression( 'Concat(@symbol_id, @symbol_label, count("Class"))') legend.model().layerLegendNodes(layer_tree_layer)[0].setUserLabel( ' sym 1') legend.model().layerLegendNodes(layer_tree_layer)[1].setUserLabel( '[%@symbol_count %]') legend.model().layerLegendNodes(layer_tree_layer)[2].setUserLabel( '[% count("Class") %]') layout.addLayoutItem(legend) legend.setLinkedMap(map) legend.updateLegend() print(layer_tree_layer.labelExpression()) map.setExtent(QgsRectangle(-102.51, 41.16, -102.36, 41.30)) checker = QgsLayoutChecker('composer_legend_symbol_expression', layout) checker.setControlPathPrefix("composer_legend") sleep(4) result, message = checker.testLayout() self.assertTrue(result, message) QgsProject.instance().removeMapLayers([point_layer.id()])
def testUpdateGuide(self): p = QgsProject() l = QgsLayout(p) l.initializeDefaults() # add a page # add a second page page2 = QgsLayoutItemPage(l) page2.setPageSize('A5') l.pageCollection().addPage(page2) g = QgsLayoutGuide( Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) g.setLayout(l) g.update() self.assertTrue(g.item().isVisible()) self.assertEqual(g.item().line().x1(), 0) self.assertEqual(g.item().line().y1(), 50) self.assertEqual(g.item().line().x2(), 297) self.assertEqual(g.item().line().y2(), 50) self.assertEqual(g.layoutPosition(), 50) g.setPosition(QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters)) g.update() self.assertTrue(g.item().isVisible()) self.assertEqual(g.item().line().x1(), 0) self.assertEqual(g.item().line().y1(), 15) self.assertEqual(g.item().line().x2(), 297) self.assertEqual(g.item().line().y2(), 15) self.assertEqual(g.layoutPosition(), 15) # guide on page2 g1 = QgsLayoutGuide( Qt.Horizontal, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(1)) g1.setLayout(l) g1.update() g1.setPosition(QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters)) g1.update() self.assertTrue(g1.item().isVisible()) self.assertEqual(g1.item().line().x1(), 0) self.assertEqual(g1.item().line().y1(), 235) self.assertEqual(g1.item().line().x2(), 148) self.assertEqual(g1.item().line().y2(), 235) self.assertEqual(g1.layoutPosition(), 235) # vertical guide g2 = QgsLayoutGuide( Qt.Vertical, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(0)) g2.setLayout(l) g2.update() self.assertTrue(g2.item().isVisible()) self.assertEqual(g2.item().line().x1(), 50) self.assertEqual(g2.item().line().y1(), 0) self.assertEqual(g2.item().line().x2(), 50) self.assertEqual(g2.item().line().y2(), 210) self.assertEqual(g2.layoutPosition(), 50) g.setPage(None) g.update() self.assertFalse(g.item().isVisible()) g.setPage(l.pageCollection().page(0)) g.update() self.assertTrue(g.item().isVisible()) #throw it off the bottom of the page g.setPosition( QgsLayoutMeasurement(1115, QgsUnitTypes.LayoutMillimeters)) g.update() self.assertFalse(g.item().isVisible()) # guide on page2 g3 = QgsLayoutGuide( Qt.Vertical, QgsLayoutMeasurement(5, QgsUnitTypes.LayoutCentimeters), l.pageCollection().page(1)) g3.setLayout(l) g3.update() self.assertTrue(g3.item().isVisible()) self.assertEqual(g3.item().line().x1(), 50) self.assertEqual(g3.item().line().y1(), 220) self.assertEqual(g3.item().line().x2(), 50) self.assertEqual(g3.item().line().y2(), 430) self.assertEqual(g3.layoutPosition(), 50)
def testLabelMargin(self): """ Test rendering map item with a label margin set """ format = QgsTextFormat() format.setFont(QgsFontUtils.getStandardTestFont("Bold")) format.setSize(20) format.setNamedStyle("Bold") format.setColor(QColor(0, 0, 0)) settings = QgsPalLayerSettings() settings.setFormat(format) settings.fieldName = "'X'" settings.isExpression = True settings.placement = QgsPalLayerSettings.OverPoint vl = QgsVectorLayer("Point?crs=epsg:4326&field=id:integer", "vl", "memory") vl.setRenderer(QgsNullSymbolRenderer()) f = QgsFeature(vl.fields(), 1) for x in range(15): for y in range(15): f.setGeometry(QgsPoint(x, y)) vl.dataProvider().addFeature(f) vl.setLabeling(QgsVectorLayerSimpleLabeling(settings)) vl.setLabelsEnabled(True) p = QgsProject() engine_settings = QgsLabelingEngineSettings() engine_settings.setFlag(QgsLabelingEngineSettings.UsePartialCandidates, False) engine_settings.setFlag(QgsLabelingEngineSettings.DrawLabelRectOnly, True) p.setLabelingEngineSettings(engine_settings) p.addMapLayer(vl) layout = QgsLayout(p) layout.initializeDefaults() p.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) map = QgsLayoutItemMap(layout) map.attemptSetSceneRect(QRectF(10, 10, 180, 180)) map.setFrameEnabled(True) map.zoomToExtent(vl.extent()) map.setLayers([vl]) layout.addLayoutItem(map) checker = QgsLayoutChecker('composermap_label_nomargin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setLabelMargin( QgsLayoutMeasurement(15, QgsUnitTypes.LayoutMillimeters)) checker = QgsLayoutChecker('composermap_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setLabelMargin( QgsLayoutMeasurement(3, QgsUnitTypes.LayoutCentimeters)) checker = QgsLayoutChecker('composermap_label_cm_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) map.setMapRotation(45) map.zoomToExtent(vl.extent()) map.setScale(map.scale() * 1.2) checker = QgsLayoutChecker('composermap_rotated_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message) # data defined map.setMapRotation(0) map.zoomToExtent(vl.extent()) map.dataDefinedProperties().setProperty( QgsLayoutObject.MapLabelMargin, QgsProperty.fromExpression('1+3')) map.refresh() checker = QgsLayoutChecker('composermap_dd_label_margin', layout) checker.setControlPathPrefix("composer_map") result, message = checker.testLayout() self.report += checker.report() self.assertTrue(result, message)
def testQgsLayoutMeasurement(self): b = QgsLayoutMeasurement(3, QgsUnitTypes.LayoutPoints) self.assertEqual(b.__repr__(), "<QgsLayoutMeasurement: 3 pt >")