def testNonSpatialLayer(self): """ test that non spatial layers are not passed to canvas """ 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") non_spatial = QgsVectorLayer("None?field=fldtxt:string", "non_spatial", "memory") prj.addMapLayers([layer, layer2, layer3, non_spatial]) canvas = QgsMapCanvas() bridge = QgsLayerTreeMapCanvasBridge(prj.layerTreeRoot(), canvas) #custom layer order prj.layerTreeRoot().setHasCustomLayerOrder(True) prj.layerTreeRoot().setCustomLayerOrder([layer3, layer, layer2]) app.processEvents() self.assertEqual(canvas.mapSettings().layers(), [layer3, layer, layer2]) # with non-spatial (should not be possible through ui, but is through api) prj.layerTreeRoot().setCustomLayerOrder([layer3, layer, layer2, non_spatial]) app.processEvents() #self.assertEqual(canvas.mapSettings().layers(),[layer3,layer,layer2]) # no custom layer order prj.layerTreeRoot().setHasCustomLayerOrder(False) app.processEvents() self.assertEqual(canvas.mapSettings().layers(), [layer, layer2, layer3])
def get_iface(): """ Will return a mock QgisInterface object with some methods implemented in a generic way. You can further control its behavior by using the mock infrastructure. Refer to https://docs.python.org/3/library/unittest.mock.html for more details. Returns ------- QgisInterface A mock QgisInterface """ start_app() my_iface = mock.Mock(spec=QgisInterface) my_iface.mainWindow.return_value = QMainWindow() canvas = QgsMapCanvas(my_iface.mainWindow()) canvas.resize(QSize(400, 400)) my_iface.mapCanvas.return_value = canvas return my_iface
def testGettersSetters(self): canvas = QgsMapCanvas() # should be disabled by default self.assertFalse(canvas.previewJobsEnabled()) canvas.setPreviewJobsEnabled(True) self.assertTrue(canvas.previewJobsEnabled())
def qgis_app(): """ Start QGIS application to test against. Based on code from Inasafe plugin. :return: Reference to QGIS application, canvas and parent widget. :rtype:(QgsApplication, QWidget, QgsMapCanvas) """ global QGIS_APP if QGIS_APP is None: gui_flag = True QCoreApplication.setOrganizationName('QGIS') QCoreApplication.setOrganizationDomain('qgis.org') QCoreApplication.setApplicationName('STDM_Testing') QGIS_APP = QgsApplication(sys.argv, gui_flag) QGIS_APP.initQgis() global PARENT if PARENT is None: PARENT = QWidget() global CANVAS if CANVAS is None: CANVAS = QgsMapCanvas(PARENT) CANVAS.resize(QSize(400, 400)) return QGIS_APP, CANVAS, PARENT
def getTestApp(): """ Start one QGis application to test agaist. If QGis is already running the handle to that app will be returned """ global QGISAPP # pylint: disable=W0603 if QGISAPP is None: myGuiFlag = True # All test will run qgis in safe_qgis mode QGISAPP = QgsApplication(sys.argv, myGuiFlag) QGISAPP.initQgis() # print QGISAPP.showSettings() global PARENT # pylint: disable=W0603 if PARENT is None: PARENT = QtGui.QWidget() global CANVAS # pylint: disable=W0603 if CANVAS is None: CANVAS = QgsMapCanvas(PARENT) CANVAS.resize(QtCore.QSize(400, 400)) global IFACE # pylint: disable=W0603 if IFACE is None: # QgisInterface is a stub implementation of the QGIS plugin interface IFACE = QgisInterface(CANVAS) return QGISAPP, CANVAS, IFACE, PARENT
def get_qgis_app(): """ Start one QGIS application to test against. :returns: Handle to QGIS app, canvas, iface and parent. If there are any errors the tuple members will be returned as None. :rtype: (QgsApplication, CANVAS, IFACE, PARENT) If QGIS is already running the handle to that app will be returned. """ global QGIS_APP, PARENT, IFACE, CANVAS # pylint: disable=W0603 if iface: from qgis.core import QgsApplication QGIS_APP = QgsApplication CANVAS = iface.mapCanvas() PARENT = iface.mainWindow() IFACE = iface return QGIS_APP, CANVAS, IFACE, PARENT try: from PyQt4 import QtGui, QtCore from qgis.core import QgsApplication from qgis.gui import QgsMapCanvas except ImportError: return None, None, None, None global QGIS_APP # pylint: disable=W0603 if QGIS_APP is None: gui_flag = True # All test will run qgis in gui mode # noinspection PyPep8Naming QGIS_APP = QgsApplication(sys.argv, gui_flag) # Make sure QGIS_PREFIX_PATH is set in your env if needed! QGIS_APP.initQgis() s = QGIS_APP.showSettings() LOGGER.debug(s) global PARENT # pylint: disable=W0603 if PARENT is None: # noinspection PyPep8Naming PARENT = QtGui.QWidget() global CANVAS # pylint: disable=W0603 if CANVAS is None: # noinspection PyPep8Naming CANVAS = QgsMapCanvas(PARENT) CANVAS.resize(QtCore.QSize(400, 400)) global IFACE # pylint: disable=W0603 if IFACE is None: # QgisInterface is a stub implementation of the QGIS plugin interface # noinspection PyPep8Naming # IFACE = QgisInterface(CANVAS) IFACE = None return QGIS_APP, CANVAS, IFACE, PARENT
def __init__(self, parent=None): QgsMapCanvas.__init__(self, parent) self.setCanvasColor(QColor(255,255,255)) # reuse settings from QGIS settings = QSettings() self.enableAntiAliasing( settings.value( "/qgis/enable_anti_aliasing", QVariant(False) ).toBool() ) self.useImageToRender( settings.value( "/qgis/use_qimage_to_render", QVariant(False) ).toBool() ) action = settings.value( "/qgis/wheel_action", QVariant(0) ).toInt()[0] zoomFactor = settings.value( "/qgis/zoom_factor", QVariant(2) ).toDouble()[0] self.setWheelAction( QgsMapCanvas.WheelAction(action), zoomFactor ) self._clear()
def get_qgis_app(): """ Start one QGis application to test against Input NIL Output handle to qgis app If QGis is already running the handle to that app will be returned """ global QGIS_APP # pylint: disable=W0603 if QGIS_APP is None: gui_flag = True # All test will run qgis in safe_qgis mode # noinspection PyPep8Naming QGIS_APP = QgsApplication(sys.argv, gui_flag) # Note: This block is not needed for QGIS > 1.8 which will # automatically check the QGIS_PREFIX_PATH var so it is here # for backwards compatibility only if "QGIS_PREFIX_PATH" in os.environ: path = os.environ["QGIS_PREFIX_PATH"] use_default_path_flag = True QGIS_APP.setPrefixPath(path, use_default_path_flag) QGIS_APP.initQgis() s = QGIS_APP.showSettings() LOGGER.debug(s) global PARENT # pylint: disable=W0603 if PARENT is None: # noinspection PyPep8Naming PARENT = QtGui.QWidget() global CANVAS # pylint: disable=W0603 if CANVAS is None: # noinspection PyPep8Naming CANVAS = QgsMapCanvas(PARENT) CANVAS.resize(QtCore.QSize(400, 400)) global IFACE # pylint: disable=W0603 if IFACE is None: # QgisInterface is a stub implementation of the QGIS plugin interface # noinspection PyPep8Naming IFACE = QgisInterface(CANVAS) return QGIS_APP, CANVAS, IFACE, PARENT
def __init__(self, parent=None): QgsMapCanvas.__init__(self, parent) self.parent = parent self.setCanvasColor(QColor(255, 255, 255)) self.item = None self.dirty = False self.currentLayer = None # reuse settings from QGIS settings = QgsSettings() self.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type=bool)) zoomFactor = settings.value("/qgis/zoom_factor", 2, type=float) self.setWheelFactor(zoomFactor)
def testVisibility(self): """ test that map canvas annotation item visibility follows layer""" a = QgsTextAnnotation() canvas = QgsMapCanvas() i = QgsMapCanvasAnnotationItem(a, canvas) self.assertTrue(i.isVisible()) layer = QgsVectorLayer("Point?crs=EPSG:3111&field=fldtxt:string", 'test', "memory") a.setMapLayer(layer) self.assertFalse(i.isVisible()) canvas.setLayers([layer]) self.assertTrue(i.isVisible())
def get_qgis_app(): """Start one QGIS application to test against. This method has been copied from PluginBuilder generated code by Gary Sherman: https://github.com/g-sherman/Qgis-Plugin-Builder :returns: Handle to QGIS app, canvas, iface and parent. If there are any errors the tuple members will be returned as None. :rtype: (QgsApplication, CANVAS, IFACE, PARENT) If QGIS is already running the handle to that app will be returned. """ try: from PyQt4 import QtGui, QtCore from qgis.core import QgsApplication from qgis.gui import QgsMapCanvas from qgis_interface import QgisInterface except ImportError: return None, None, None, None global QGIS_APP # pylint: disable=W0603 if QGIS_APP is None: gui_flag = True # All test will run qgis in gui mode #noinspection PyPep8Naming QGIS_APP = QgsApplication(sys.argv, gui_flag) # Make sure QGIS_PREFIX_PATH is set in your env if needed! QGIS_APP.initQgis() s = QGIS_APP.showSettings() LOGGER.debug(s) global PARENT # pylint: disable=W0603 if PARENT is None: #noinspection PyPep8Naming PARENT = QtGui.QWidget() global CANVAS # pylint: disable=W0603 if CANVAS is None: #noinspection PyPep8Naming CANVAS = QgsMapCanvas(PARENT) CANVAS.resize(QtCore.QSize(400, 400)) global IFACE # pylint: disable=W0603 if IFACE is None: # QgisInterface is a stub implementation of the QGIS plugin interface #noinspection PyPep8Naming IFACE = QgisInterface(CANVAS) return QGIS_APP, CANVAS, IFACE, PARENT
def __init__(self, parent=None): QgsMapCanvas.__init__(self, parent) self.setCanvasColor(QColor(255,255,255)) self.item = None self.dirty = False # reuse settings from QGIS settings = QSettings() self.enableAntiAliasing( settings.value( "/qgis/enable_anti_aliasing", False, type=bool ) ) action = settings.value( "/qgis/wheel_action", 0, type=float ) zoomFactor = settings.value( "/qgis/zoom_factor", 2, type=float ) self.setWheelAction( QgsMapCanvas.WheelAction(action), zoomFactor ) self._clear()
def getQgisTestApp(): """ Start one QGis application to test agaist Input NIL Output handle to qgis app If QGis is already running the handle to that app will be returned """ global QGISAPP # pylint: disable=W0603 if QGISAPP is None: myGuiFlag = True # All test will run qgis in gui mode # In python3 we need to conver to a bytes object (or should # QgsApplication accept a QString instead of const char* ?) try: argvb = list(map(os.fsencode, sys.argv)) except AttributeError: argvb = sys.argv # Note: QGIS_PREFIX_PATH is evaluated in QgsApplication - # no need to mess with it here. QGISAPP = QgsApplication(argvb, myGuiFlag) QGISAPP.initQgis() s = QGISAPP.showSettings() print(s) global PARENT # pylint: disable=W0603 if PARENT is None: PARENT = QWidget() global CANVAS # pylint: disable=W0603 if CANVAS is None: CANVAS = QgsMapCanvas(PARENT) CANVAS.resize(QSize(400, 400)) global IFACE # pylint: disable=W0603 if IFACE is None: # QgisInterface is a stub implementation of the QGIS plugin interface IFACE = QgisInterface(CANVAS) return QGISAPP, CANVAS, IFACE, PARENT
def setupUi(self, frmPropertyPreview): frmPropertyPreview.setObjectName(_fromUtf8("frmPropertyPreview")) frmPropertyPreview.resize(627, 480) frmPropertyPreview.setTabPosition(QtGui.QTabWidget.South) self.local = QtGui.QWidget() self.local.setObjectName(_fromUtf8("local")) self.gridLayout = QtGui.QGridLayout(self.local) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.localMap = QgsMapCanvas(self.local) self.localMap.setObjectName(_fromUtf8("localMap")) self.gridLayout.addWidget(self.localMap, 0, 0, 1, 2) self.label = QtGui.QLabel(self.local) self.label.setMaximumSize(QtCore.QSize(120, 16777215)) self.label.setObjectName(_fromUtf8("label")) self.gridLayout.addWidget(self.label, 1, 0, 1, 1) self.cboMapReference = QtGui.QComboBox(self.local) self.cboMapReference.setMinimumSize(QtCore.QSize(0, 30)) self.cboMapReference.setObjectName(_fromUtf8("cboMapReference")) self.gridLayout.addWidget(self.cboMapReference, 1, 1, 1, 1) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/plugins/stdm/images/icons/local.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) frmPropertyPreview.addTab(self.local, icon, _fromUtf8("")) self.web = QtGui.QWidget() self.web.setObjectName(_fromUtf8("web")) self.webView = QtWebKit.QWebView(self.web) self.webView.setGeometry(QtCore.QRect(19, 19, 561, 401)) self.webView.setUrl(QtCore.QUrl(_fromUtf8("about:blank"))) self.webView.setObjectName(_fromUtf8("webView")) icon1 = QtGui.QIcon() icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/plugins/stdm/images/icons/web.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) frmPropertyPreview.addTab(self.web, icon1, _fromUtf8("")) self.retranslateUi(frmPropertyPreview) frmPropertyPreview.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(frmPropertyPreview)
def initGui(self): #Models self.tblChanges.setModel( ChangeModel() ) proxyChanges = HistoryProxyModel() proxyChanges.setSourceModel( HistoryModel() ) self.tblHistory.setModel( proxyChanges ) #Signals self.plugin.tvIdentificationResult.model().sourceModel().on_history.connect( self.historyChanged ) self.tblHistory.selectionModel().currentChanged.connect( self.currentHistoryChanged ) #Widgets settings = QSettings() self.mapCanvas = QgsMapCanvas(self.vSplitter) self.mapCanvas.setDestinationCrs( QgsCoordinateReferenceSystem('EPSG:4326') ) zoomFactor = settings.value( "/qgis/zoom_factor", 2.0, type=float ) action = settings.value( "/qgis/wheel_action", 0, type=int) self.mapCanvas.setWheelFactor( zoomFactor ) self.mapCanvas.enableAntiAliasing( settings.value( "/qgis/enable_anti_aliasing", False, type=bool )) #self.mapCanvas.useImageToRender( settings.value( "/qgis/use_qimage_to_render", False, type=bool )) self.toolPan = QgsMapToolPan( self.mapCanvas ) self.mapCanvas.setMapTool( self.toolPan ) #Canvas items self.new_geometry = QgsRubberBand(self.mapCanvas) self.new_geometry.setWidth(2) self.new_geometry.setIcon( QgsRubberBand.ICON_CIRCLE ) g = QColor(0, 128, 0, 100) self.new_geometry.setColor( g ) self.old_geometry = QgsRubberBand(self.mapCanvas) self.old_geometry.setWidth(2) self.old_geometry.setIcon( QgsRubberBand.ICON_CIRCLE ) r = QColor(255, 0, 0, 100) self.old_geometry.setColor( r )
def initGui(self): layout = QVBoxLayout() self.tab = QTabWidget() self.table = QTableView() self.setLayout(layout) self.canvas = QgsMapCanvas() self.canvas.setCanvasColor(Qt.white) settings = QSettings() self.canvas.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type = bool)) self.canvas.useImageToRender(settings.value("/qgis/use_qimage_to_render", False, type = bool)) self.canvas.mapSettings().setDestinationCrs(self.crs) action = settings.value("/qgis/wheel_action", 0, type = float) zoomFactor = settings.value("/qgis/zoom_factor", 2, type = float) self.canvas.setWheelAction(QgsMapCanvas.WheelAction(action), zoomFactor) self.panTool = QgsMapToolPan(self.canvas) self.canvas.setMapTool(self.panTool) execute(self.createLayers) model = GeomDiffTableModel(self.data) self.table.setModel(model) self.table.resizeColumnsToContents() self.table.resizeRowsToContents() self.tab.addTab(self.canvas, "Map view") self.tab.addTab(self.table, "Table view") layout.addWidget(self.tab) self.resize(600, 500) self.setWindowTitle("Geometry comparison")
def __init__(self, repo, path): super(VersionViewerDialog, self).__init__(config.iface.mainWindow(), Qt.WindowSystemMenuHint | Qt.WindowTitleHint) self.repo = repo self.path = path self.setupUi(self) self.listWidget.itemClicked.connect(self.commitClicked) settings = QSettings() horizontalLayout = QHBoxLayout() horizontalLayout.setSpacing(0) horizontalLayout.setMargin(0) self.mapCanvas = QgsMapCanvas() self.mapCanvas.setCanvasColor(Qt.white) self.mapCanvas.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type = bool)) self.mapCanvas.useImageToRender(settings.value("/qgis/use_qimage_to_render", False, type = bool)) action = settings.value("/qgis/wheel_action", 0, type = float) zoomFactor = settings.value("/qgis/zoom_factor", 2, type = float) self.mapCanvas.setWheelAction(QgsMapCanvas.WheelAction(action), zoomFactor) horizontalLayout.addWidget(self.mapCanvas) self.mapWidget.setLayout(horizontalLayout) self.panTool = QgsMapToolPan(self.mapCanvas) self.mapCanvas.setMapTool(self.panTool) versions = repo.log(path = path) if versions: for commit in versions: item = CommitListItem(commit, repo, path) self.listWidget.addItem(item) ''''w = CommitListItemWidget(commit) self.ui.listWidget.setItemWidget(item, w)''' else: raise GeoGigException("The selected feature is not versioned yet")
def setupUi(self, LayerSelectDialog): LayerSelectDialog.setObjectName(_fromUtf8("LayerSelectDialog")) LayerSelectDialog.resize(439, 425) self.verticalLayout = QtGui.QVBoxLayout(LayerSelectDialog) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.tabWidget = QtGui.QTabWidget(LayerSelectDialog) self.tabWidget.setObjectName(_fromUtf8("tabWidget")) self.tab_Tree = QtGui.QWidget() self.tab_Tree.setObjectName(_fromUtf8("tab_Tree")) self.gridLayout_2 = QtGui.QGridLayout(self.tab_Tree) self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) self.treeView = QgsLayerTreeView(self.tab_Tree) self.treeView.setObjectName(_fromUtf8("treeView")) self.gridLayout_2.addWidget(self.treeView, 0, 0, 1, 1) self.tabWidget.addTab(self.tab_Tree, _fromUtf8("")) self.tab_Preview = QtGui.QWidget() self.tab_Preview.setObjectName(_fromUtf8("tab_Preview")) self.gridLayout = QtGui.QGridLayout(self.tab_Preview) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.canvas = QgsMapCanvas(self.tab_Preview) self.canvas.setObjectName(_fromUtf8("canvas")) self.gridLayout.addWidget(self.canvas, 0, 0, 1, 1) self.tabWidget.addTab(self.tab_Preview, _fromUtf8("")) self.verticalLayout.addWidget(self.tabWidget) self.buttonBox = QtGui.QDialogButtonBox(LayerSelectDialog) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.verticalLayout.addWidget(self.buttonBox) self.retranslateUi(LayerSelectDialog) self.tabWidget.setCurrentIndex(0) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), LayerSelectDialog.accept) QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), LayerSelectDialog.reject) QtCore.QMetaObject.connectSlotsByName(LayerSelectDialog)
def getQgisTestApp(): """ Start one QGis application to test agaist Input NIL Output handle to qgis app If QGis is already running the handle to that app will be returned """ global QGISAPP if QGISAPP is None: myGuiFlag = True # All test will run qgis in gui mode QGISAPP = QgsApplication(sys.argv, myGuiFlag) if 'QGISPATH' in os.environ: myPath = os.environ['QGISPATH'] myUseDefaultPathFlag = True QGISAPP.setPrefixPath(myPath, myUseDefaultPathFlag) else: print 'Warning: QGISPATH is not set' QGISAPP.initQgis() s = QGISAPP.showSettings() print s global PARENT if PARENT is None: PARENT = QtGui.QWidget() global CANVAS if CANVAS is None: CANVAS = QgsMapCanvas(PARENT) CANVAS.resize(QtCore.QSize(400, 400)) global IFACE if IFACE is None: # QgisInterface is a stub implementation of the QGIS plugin # interface IFACE = QgisInterface(CANVAS) return (QGISAPP, CANVAS, IFACE, PARENT)
def getQgisTestApp(): """ Start one QGis application to test agaist Input NIL Output handle to qgis app If QGis is already running the handle to that app will be returned """ global QGISAPP # pylint: disable=W0603 if QGISAPP is None: myGuiFlag = True # All test will run qgis in gui mode # Note: QGIS_PREFIX_PATH is evaluated in QgsApplication - # no need to mess with it here. QGISAPP = QgsApplication(sys.argv, myGuiFlag) QGISAPP.initQgis() s = QGISAPP.showSettings() print s global PARENT # pylint: disable=W0603 if PARENT is None: PARENT = QWidget() global CANVAS # pylint: disable=W0603 if CANVAS is None: CANVAS = QgsMapCanvas(PARENT) CANVAS.resize(QSize(400, 400)) global IFACE # pylint: disable=W0603 if IFACE is None: # QgisInterface is a stub implementation of the QGIS plugin interface IFACE = QgisInterface(CANVAS) return QGISAPP, CANVAS, IFACE, PARENT
class MainWindow(QtGui.QMainWindow): def __init__(self): QtGui.QMainWindow.__init__(self) self.canvas = QgsMapCanvas() self.canvas.setCanvasColor(QtGui.QColor(255, 255, 255)) self.canvas.enableAntiAliasing(True) def create_layer(self, data): display_name = 'some-layer' uri = 'Point?crs=epsg:4326&index=yes&uuid=%s' % uuid.uuid4() vlayer = QgsVectorLayer(uri, display_name, 'memory') QgsMapLayerRegistry.instance().addMapLayer(vlayer) provider = vlayer.dataProvider() vlayer.startEditing() provider.addAttributes([ QgsField('population_density', QtCore.QVariant.Double), ]) features = [] for x, y, density in data: feat = QgsFeature() geom = QgsGeometry.fromPoint(QgsPoint(x, y)) feat.setGeometry(geom) feat.setAttributes([density]) features.append(feat) provider.addFeatures(features) vlayer.commitChanges() vlayer.updateExtents() self.canvas.setExtent(vlayer.extent()) vlayer.triggerRepaint()
class Dialog(QtGui.QWidget, Ui_DialogBase): def __init__(self): QtGui.QWidget.__init__(self) self.setupUi(self) self.widget = QgsMapCanvas() self.show() def on_pushButton_clicked(self): """Wow - an autoconnected slot!""" print 'Click!' myPath = os.path.join( os.path.dirname(__file__), 'landsat.tif') print myPath layer = QgsRasterLayer(myPath, 'A Layer') QgsMapLayerRegistry.instance().addMapLayers([layer]) layer.setGrayBandName(layer.bandName(1)) layer.setDrawingStyle(QgsRasterLayer.SingleBandPseudoColor) layer.setColorShadingAlgorithm(QgsRasterLayer.PseudoColorShader) layer.saveDefaultStyle() self.widget.zoomToFullExtent() print self.widget.extent().toString() print layer.extent().toString() self.widget.refresh()
def make_pdf(): canvas = QgsMapCanvas() # Load our project QgsProject.instance().read(QFileInfo(project_path)) bridge = QgsLayerTreeMapCanvasBridge( QgsProject.instance().layerTreeRoot(), canvas) bridge.setCanvasLayers() if canvas.layerCount() < 1: print 'No layers loaded from this project, exiting.' return print canvas.mapSettings().extent().toString() template_file = file(template_path) template_content = template_file.read() template_file.close() document = QDomDocument() document.setContent(template_content) composition = QgsComposition(canvas.mapSettings()) # You can use this to replace any string like this [key] # in the template with a new value. e.g. to replace # [date] pass a map like this {'date': '1 Jan 2012'} substitution_map = { 'DATE_TIME_START': TIME_START, 'DATE_TIME_END': TIME_STOP} composition.loadFromTemplate(document, substitution_map) # You must set the id in the template map_item = composition.getComposerItemById('map') map_item.setMapCanvas(canvas) map_item.zoomToExtent(canvas.extent()) # You must set the id in the template legend_item = composition.getComposerItemById('legend') legend_item.updateLegend() composition.refreshItems() composition.exportAsPDF( '/home/web/reports/pdf/%s/%s.pdf' % (TIME_SLICE, LABEL)) QgsProject.instance().clear()
def qgis_app(): """Start a QGIS application and get the iface. Mostly inspired by https://github.com/qgis/QGIS/blob/release-2_18/python/testing/mocked.py The application is returned as first argument. The QgisInterface is returned as second argument. The parent can be accessed by iface.mainWindow() The canvas can be access by iface.mapCanvas() You can further control its behavior by using the mock infrastructure. Refer to https://docs.python.org/3/library/unittest.mock.html for more details. :return: The QGIS interface. :rtype: QgisInterface """ from qgis.utils import iface if iface: # We are already in QGIS. # I don't know if I can get the current QApplication. # But I guess we shouldn't use it too much. return None, iface # We are not in QGIS, we need to start an app. application = start_app() my_iface = mock.Mock(spec=QgisInterface) my_iface.mainWindow.return_value = QMainWindow() canvas = QgsMapCanvas(my_iface.mainWindow()) canvas.resize(QSize(400, 400)) my_iface.mapCanvas.return_value = canvas return application, my_iface
def __init__(self, conflicts): super(ConflictDialog, self).__init__(None, Qt.WindowSystemMenuHint | Qt.WindowTitleHint) self.solved = False self.resolvedConflicts = {} self.conflicts = conflicts self.setupUi(self) self.setWindowFlags(self.windowFlags() | Qt.WindowSystemMenuHint | Qt.WindowMinMaxButtonsHint) self.zoomButton.clicked.connect(self.zoomToFullExtent) self.solveButton.clicked.connect(self.solve) self.conflictsTree.itemClicked.connect(self.treeItemClicked) self.attributesTable.cellClicked.connect(self.cellClicked) self.solveAllLocalButton.clicked.connect(self.solveAllLocal) self.solveAllRemoteButton.clicked.connect(self.solveAllRemote) self.solveLocalButton.clicked.connect(self.solveLocal) self.solveRemoteButton.clicked.connect(self.solveRemote) self.showRemoteCheck.stateChanged.connect(self.showGeoms) self.showLocalCheck.stateChanged.connect(self.showGeoms) self.lastSelectedItem = None self.currentPath = None self.currentConflict = None self.theirsLayer = None self.oursLayer = None settings = QSettings() horizontalLayout = QHBoxLayout() horizontalLayout.setSpacing(0) horizontalLayout.setMargin(0) self.mapCanvas = QgsMapCanvas() self.mapCanvas.setCanvasColor(Qt.white) self.mapCanvas.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type = bool)) self.mapCanvas.useImageToRender(settings.value("/qgis/use_qimage_to_render", False, type = bool)) self.mapCanvas.mapRenderer().setProjectionsEnabled(True) action = settings.value("/qgis/wheel_action", 0, type = float) zoomFactor = settings.value("/qgis/zoom_factor", 2, type = float) self.mapCanvas.setWheelAction(QgsMapCanvas.WheelAction(action), zoomFactor) horizontalLayout.addWidget(self.mapCanvas) self.canvasWidget.setLayout(horizontalLayout) self.panTool = QgsMapToolPan(self.mapCanvas) self.mapCanvas.setMapTool(self.panTool) self.solveButton.setEnabled(False) self.solveLocalButton.setEnabled(False) self.solveRemoteButton.setEnabled(False) self.fillConflictsTree()
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName(_fromUtf8("MainWindow")) MainWindow.resize(800, 600) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.canvas = QgsMapCanvas(self.centralwidget) self.canvas.setGeometry(QtCore.QRect(99, 19, 681, 521)) self.canvas.setObjectName(_fromUtf8("canvas")) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 25)) self.menubar.setObjectName(_fromUtf8("menubar")) MainWindow.setMenuBar(self.menubar) self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
def __init__(self, template_path, debug=False): """Constructor. :param template_path: Absolute path to a QGIS composer template file. :type template_path: str """ gui_flag = True self.app = QgsApplication(sys.argv, gui_flag) # Make sure QGIS_PREFIX_PATH is set in your env if needed! self.app.initQgis() if debug: print QgsProviderRegistry.instance().pluginList() self.canvas = QgsMapCanvas() self.canvas.enableAntiAliasing(True) self.template_path = template_path
def setupUi(self, MainWindow): MainWindow.setObjectName(_fromUtf8("MainWindow")) MainWindow.resize(800, 600) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.canvas = QgsMapCanvas(self.centralwidget) self.canvas.setGeometry(QtCore.QRect(99, 19, 681, 521)) self.canvas.setObjectName(_fromUtf8("canvas")) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 25)) self.menubar.setObjectName(_fromUtf8("menubar")) MainWindow.setMenuBar(self.menubar) self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow)
def show_canvas(app): canvas = QgsMapCanvas() layer = QgsVectorLayer("D:\\Software\\QGis\\StatPlanet_France\\map\\map.shp", "teste" , "ogr") if not layer.isValid(): raise IOError, "Failed to open the layer" else: # add layer to the registry QgsMapLayerRegistry.instance().addMapLayer(layer) # set extent to the extent of our layer canvas.setExtent(layer.extent()) # set the map canvas layer set canvas.setLayerSet([QgsMapCanvasLayer(layer)]) canvas.show() app.exec_()
class SaveSearchDialog(BASE, WIDGET): def __init__(self, request, parent=None): super(SaveSearchDialog, self).__init__(parent) self.request = request self.request_to_save = None self.setupUi(self) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.layout().addWidget(self.bar) self.buttonBox.button(QDialogButtonBox.Save).clicked.connect(self.save) self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect( self.reject) self.btnCreateFolder.clicked.connect(self.createFolder) self.set_from_request() self.populate_folders() def createFolder(self): name, _ = QInputDialog.getText(self, "Save Search", "Enter folder name") if name and name not in self._folder_names: self._folder_names.append(name) self.populate_folders() def populate_folders(self): self.comboFolder.clear() self.comboFolder.addItems(self._folders()) _folder_names = None def _folders(self): if self._folder_names is None: self._folder_names = [""] client = PlanetClient.getInstance() res = client.get_searches().get() for search in res["searches"]: tokens = search["name"].split("/") if len(tokens) > 1 and tokens[0] not in self._folder_names: self._folder_names.append(tokens[0]) return self._folder_names def set_from_request(self): filters = filters_from_request(self.request, "geometry") if filters: geom = filters[0].get("config") aoi_txt = json.dumps(geom) extent = qgsgeometry_from_geojson(aoi_txt).boundingBox() else: extent = iface.mapCanvas().fullExtent() layout = QVBoxLayout() layout.setMargin(0) self.canvas = QgsMapCanvas() layers = iface.mapCanvas().mapSettings().layers() crs = QgsCoordinateReferenceSystem("EPSG:4326") self.canvas.setLayers(layers) self.canvas.setDestinationCrs(crs) self.canvas.setExtent(extent) layout.addWidget(self.canvas) self.widgetAOI.setLayout(layout) filters = filters_from_request(self.request, 'acquired') if filters: gte = filters[0]['config'].get('gte') if gte is not None: self.lblStartDate.setText( QDateTime.fromString(gte, Qt.ISODate).date().toString()) else: self.lblStartDate.setText("---") self.chkExcludeStart.setEnabled(False) lte = filters[0]['config'].get('lte') if lte is not None: self.lblEndDate.setText( QDateTime.fromString(lte, Qt.ISODate).date().toString()) else: self.lblEndDate.setText("---") self.chkExcludeEnd.setEnabled(False) self.txtFilters.setPlainText(filters_as_text_from_request( self.request)) def save(self): name = self.txtName.text() if len(name) == 0: self.bar.pushMessage("", "Invalid name", Qgis.Warning) return folder = self.comboFolder.currentText() if folder: name = f"{folder}/{name}" self.request_to_save = copy.deepcopy(self.request) self.request_to_save["name"] = name filters = filters_from_request(self.request, 'acquired') if filters: config = filters[0]['config'] if self.chkExcludeStart.isChecked(): del config['gte'] if self.chkExcludeEnd.isChecked(): del config['lte'] self.replace_date_filter(self.request_to_save, config) self.accept() def replace_date_filter(self, request, newfilter): def process_filter(filterdict): if filterdict["type"] in ["AndFilter", "OrFilter"]: for subfilter in filterdict["config"]: process_filter(subfilter) elif (filterdict["field_name"] == "acquired"): filterdict["config"] == newfilter process_filter(request["filter"])
def testDeferredUpdate(self): """ test that map canvas doesn't auto refresh on deferred layer update """ 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") 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('empty_canvas', 'empty_canvas', canvas)) # add polygon to layer f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer.dataProvider().addFeatures([f])) # deferred update - so expect that canvas will not been refreshed layer.triggerRepaint(True) timeout = time.time() + 0.1 while time.time() < timeout: # messy, but only way to check that canvas redraw doesn't occur self.assertFalse(canvas.isDrawing()) # canvas should still be empty self.assertTrue( self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas)) # refresh canvas canvas.refresh() canvas.waitWhileRendering() # now we expect the canvas check to fail (since they'll be a new polygon rendered over it) self.assertFalse( self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas))
def testSaveMultipleCanvasesToProject(self): # test saving/restoring canvas state to project with multiple canvases c1 = QgsMapCanvas() c1.setObjectName('c1') c1.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3111')) c1.setRotation(45) c1.expressionContextScope().setVariable('vara', 1111) c1.expressionContextScope().setVariable('varb', 'bb') c2 = QgsMapCanvas() c2.setObjectName('c2') c2.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4326')) c2.setRotation(65) c2.expressionContextScope().setVariable('vara', 2222) c2.expressionContextScope().setVariable('varc', 'cc') doc = QDomDocument("testdoc") elem = doc.createElement("qgis") doc.appendChild(elem) c1.writeProject(doc) c2.writeProject(doc) c3 = QgsMapCanvas() c3.setObjectName('c1') c4 = QgsMapCanvas() c4.setObjectName('c2') c3.readProject(doc) c4.readProject(doc) self.assertEqual(c3.mapSettings().destinationCrs().authid(), 'EPSG:3111') self.assertEqual(c3.rotation(), 45) self.assertEqual(set(c3.expressionContextScope().variableNames()), {'vara', 'varb'}) self.assertEqual(c3.expressionContextScope().variable('vara'), 1111) self.assertEqual(c3.expressionContextScope().variable('varb'), 'bb') self.assertEqual(c4.mapSettings().destinationCrs().authid(), 'EPSG:4326') self.assertEqual(c4.rotation(), 65) self.assertEqual(set(c4.expressionContextScope().variableNames()), {'vara', 'varc'}) self.assertEqual(c4.expressionContextScope().variable('vara'), 2222) self.assertEqual(c4.expressionContextScope().variable('varc'), 'cc')
def get_qgis_app(): """ Start one QGIS application to test against. :returns: Handle to QGIS app, canvas, iface and parent. If there are any errors the tuple members will be returned as None. :rtype: (QgsApplication, CANVAS, IFACE, PARENT) If QGIS is already running the handle to that app will be returned. """ try: from qgis.core import QgsApplication from qgis.gui import QgsMapCanvas # pylint: disable=no-name-in-module # noinspection PyPackageRequirements from PyQt4 import QtGui, QtCore # pylint: disable=W0621 # noinspection PyPackageRequirements from PyQt4.QtCore import QCoreApplication, QSettings from safe.gis.qgis_interface import QgisInterface except ImportError: return None, None, None, None global QGIS_APP # pylint: disable=W0603 if QGIS_APP is None: gui_flag = True # All test will run qgis in gui mode # AG: For testing purposes, we use our own configuration file instead # of using the QGIS apps conf of the host # noinspection PyCallByClass,PyArgumentList QCoreApplication.setOrganizationName('QGIS') # noinspection PyCallByClass,PyArgumentList QCoreApplication.setOrganizationDomain('qgis.org') # noinspection PyCallByClass,PyArgumentList QCoreApplication.setApplicationName('QGIS2InaSAFETesting') # noinspection PyPep8Naming QGIS_APP = QgsApplication(sys.argv, gui_flag) # Make sure QGIS_PREFIX_PATH is set in your env if needed! QGIS_APP.initQgis() s = QGIS_APP.showSettings() LOGGER.debug(s) # Save some settings settings = QSettings() settings.setValue('locale/overrideFlag', True) settings.setValue('locale/userLocale', 'en_US') # We disabled message bars for now for extent selector as # we don't have a main window to show them in TS - version 3.2 settings.setValue('inasafe/show_extent_confirmations', False) settings.setValue('inasafe/show_extent_warnings', False) settings.setValue('inasafe/showRubberBands', True) settings.setValue('inasafe/analysis_extents_mode', 'HazardExposure') global PARENT # pylint: disable=W0603 if PARENT is None: # noinspection PyPep8Naming PARENT = QtGui.QWidget() global CANVAS # pylint: disable=W0603 if CANVAS is None: # noinspection PyPep8Naming CANVAS = QgsMapCanvas(PARENT) CANVAS.resize(QtCore.QSize(400, 400)) global IFACE # pylint: disable=W0603 if IFACE is None: # QgisInterface is a stub implementation of the QGIS plugin interface # noinspection PyPep8Naming IFACE = QgisInterface(CANVAS) register_impact_functions() return QGIS_APP, CANVAS, IFACE, PARENT
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 get_snapper(self): """ Return snapper """ snapper = QgsMapCanvas.snappingUtils(self.canvas) return snapper
class EventDialog(QtGui.QDialog, FORM_CLASS): # Editable layer to alter edition mode (transaction group). editableLayerObject = None # Replay is not enabled. replayEnabled = False # # Internal. # catchLayerModifications = True def __init__(self, parent, connection_wrapper_read, connection_wrapper_write, map_canvas, audit_table, replay_function=None, table_map={}, selected_layer_id=None, selected_feature_id=None): """Constructor. @param parent parent widget @param connection_wrapper_read connection wrapper (dbapi2) @param connection_wrapper_write connection wrapper (dbapi2 or transaction group) @param map_canvas the main QgsMapCanvas @param audit_table the name of the audit table in the database @param replay_function name of the replay function in the database @param table_map a dict that associates database table name to a QGIS layer id layer_id : table_name @param selected_layer_id selected layer @param selected_feature_id selected feature_id """ super(EventDialog, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) # reload button icons self.searchButton.setIcon( QIcon( os.path.join(os.path.dirname(__file__), 'icons', 'mActionFilter2.svg'))) self.replayButton.setIcon( QIcon( os.path.join(os.path.dirname(__file__), 'icons', 'mIconWarn.png'))) # Store connections. self.connection_wrapper_read = connection_wrapper_read self.connection_wrapper_write = connection_wrapper_write self.map_canvas = map_canvas self.audit_table = audit_table self.replay_function = replay_function # Watch for layer added or removed for replay button state update. QgsMapLayerRegistry.instance().layersRemoved.connect( self.updateReplayButtonState) QgsMapLayerRegistry.instance().layersAdded.connect( self.updateReplayButtonState) # Register all current layers. self.updateReplayButtonState() # geometry columns : table_name => list of geometry columns, the first one is the "main" geometry column self.geometry_columns = {} self.table_map = table_map # populate layer combo layer_idx = None for i, layer_id in enumerate(self.table_map.keys()): l = QgsMapLayerRegistry.instance().mapLayer(layer_id) if l is None: continue print layer_id, selected_layer_id if layer_id == selected_layer_id: layer_idx = i + 1 self.layerCombo.addItem(l.name(), layer_id) if layer_idx is not None: self.layerCombo.setCurrentIndex(layer_idx) if selected_feature_id is not None: self.idEdit.setEnabled(True) self.idEdit.setText(str(selected_feature_id)) self.dataTable.hide() # # inner canvas self.vbox = QVBoxLayout() margins = self.vbox.contentsMargins() margins.setBottom(0) margins.setTop(11) margins.setLeft(0) margins.setRight(0) self.vbox.setContentsMargins(margins) self.inner_canvas = QgsMapCanvas() # copy layer set self.inner_canvas.setLayerSet( [QgsMapCanvasLayer(l) for l in self.map_canvas.layers()]) self.inner_canvas.setExtent(self.map_canvas.extent()) self.geometryGroup.setLayout(self.vbox) self.geometryGroup.hide() self.hsplitter.setSizes([100, 100]) self.displayer = GeometryDisplayer(self.map_canvas) self.inner_displayer = GeometryDisplayer(self.inner_canvas) self.afterDt.setDateTime(QDateTime.currentDateTime()) self.beforeDt.setDateTime(QDateTime.currentDateTime()) self.advancedGroup.setCollapsed(True) # Old/new geometry legend. self.hbox = QHBoxLayout() self.oldGeometryLabel = QLabel() self.oldGeometryLabel.setText("------- old geometry") self.oldGeometryLabel.setStyleSheet( "color: " + self.displayer.oldGeometryColor().name()) self.newGeometryLabel = QLabel() self.newGeometryLabel.setText( "------- new geometry (will be restored when replaying event)") self.newGeometryLabel.setStyleSheet( "color: " + self.displayer.newGeometryColor().name()) self.hbox.addWidget(self.oldGeometryLabel) self.hbox.addWidget(self.newGeometryLabel) self.hbox.addItem( QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Fixed)) self.vbox.addLayout(self.hbox) self.vbox.addWidget(self.inner_canvas) # refresh results when the search button is clicked self.searchButton.clicked.connect(self.populate) # update the feature id line edit visiblity based on the current layer selection self.layerCombo.currentIndexChanged.connect(self.onCurrentLayerChanged) # replay button if self.replay_function: self.replayButton.clicked.connect(self.onReplayEvent) def onCurrentLayerChanged(self, index): self.idEdit.setEnabled(index > 0) def done(self, status): self.undisplayGeometry() return QDialog.done(self, status) def populate(self): wheres = [] # filter by selected layer/table index = self.layerCombo.currentIndex() if index > 0: lid = self.layerCombo.itemData(index) schema, table = self.table_map[lid].split(".") wheres.append("schema_name = '{}'".format(schema)) wheres.append("table_name = '{}'".format(table)) # filter by feature id, if any if len(self.idEdit.text()) > 0: try: id = int(self.idEdit.text()) wheres.append("row_data->'id'='{}'".format(id)) except ValueError: pass # filter by data if self.dataChck.isChecked(): v = self.dataEdit.text() v = v.replace('\\', '\\\\').replace("'", "''").replace( '%', '\\%').replace('_', '\\_') wheres.append( "(SELECT string_agg(v,' ') FROM svals(row_data) as v) ILIKE '%{}%'" .format(v)) # filter by event type types = [] if self.insertsChck.isChecked(): types.append('I') if self.updatesChck.isChecked(): types.append('U') if self.deletesChck.isChecked(): types.append('D') wheres.append("action IN ('{}')".format("','".join(types))) # filter by dates if self.afterChck.isChecked(): dt = self.afterDt.dateTime() wheres.append("action_tstamp_clk > '{}'".format( dt.toString(Qt.ISODate))) if self.beforeChck.isChecked(): dt = self.beforeDt.dateTime() wheres.append("action_tstamp_clk < '{}'".format( dt.toString(Qt.ISODate))) # base query q = "SELECT event_id, action_tstamp_clk, schema_name || '.' || table_name, action, application_name, row_data, changed_fields FROM {} l".format( self.audit_table) # where clause if len(wheres) > 0: q += " WHERE " + " AND ".join(wheres) # Descending order. q += " ORDER BY action_tstamp_clk DESC" # Create cursor. cur = self.connection_wrapper_read.cursor() if cur == None: print "Cannot get cursor for database." return cur.execute(q) self.eventModel = EventModel(cur) self.eventTable.setModel(self.eventModel) self.eventTable.selectionModel().currentRowChanged.connect( self.onEventSelection) self.eventTable.horizontalHeader().setResizeMode( QHeaderView.Interactive) def updateReplayButton(self): self.replayButton.setEnabled(False) self.replayButton.setToolTip( "No replay function or layer is in edition mode: replay action is not available." ) if self.replay_function and self.replayEnabled == True: self.replayButton.setEnabled(True) self.replayButton.setToolTip("Replay the current selected item.") def onEventSelection(self, current_idx, previous_idx): reset_table_widget(self.dataTable) self.undisplayGeometry() # get current selection if current_idx.row() == -1: self.dataTable.hide() return i = current_idx.row() # action from current selection action = self.eventModel.data(self.eventModel.index(i, 2), Qt.UserRole) self.updateReplayButton() # get geometry columns data = self.eventModel.row_data(i) table_name = self.eventModel.data(self.eventModel.index(i, 1)) gcolumns = self.geometry_columns.get(table_name) if gcolumns is None: schema, table = table_name.split('.') # Create cursor. cur = self.connection_wrapper_read.cursor() if cur == None: print "Cursor creation has failed" return q = "SELECT f_geometry_column FROM geometry_columns WHERE f_table_schema='{}' AND f_table_name='{}'".format( schema, table) cur.execute(q) self.geometry_columns[table_name] = [r[0] for r in cur.fetchall()] gcolumns = self.geometry_columns[table_name] # insertion or deletion if action == 'I' or action == 'D': self.dataTable.setColumnCount(2) self.dataTable.setHorizontalHeaderLabels(["Column", "Value"]) j = 0 for k, v in data.iteritems(): if len(gcolumns) > 0 and k == gcolumns[0]: self.displayGeometry(ewkb_to_geom(v)) continue if k in gcolumns: continue if v is None: continue self.dataTable.insertRow(j) self.dataTable.setItem(j, 0, QTableWidgetItem(k)) self.dataTable.setItem(j, 1, QTableWidgetItem(v)) j += 1 # update elif action == 'U': self.dataTable.setColumnCount(3) self.dataTable.setHorizontalHeaderLabels( ["Column", "Old value", "New value"]) changed_fields = self.eventModel.changed_fields(i) j = 0 for k, v in data.iteritems(): if len(gcolumns) > 0 and k == gcolumns[0]: w = changed_fields.get(k) if w is not None: self.displayGeometry(ewkb_to_geom(v), ewkb_to_geom(w)) continue if k in gcolumns: continue w = changed_fields.get(k) if v is None and w is None: continue self.dataTable.insertRow(j) self.dataTable.setItem(j, 0, QTableWidgetItem(k)) self.dataTable.setItem(j, 1, QTableWidgetItem(v)) if w is None: self.dataTable.setItem(j, 2, QTableWidgetItem(v)) else: self.dataTable.setItem(j, 2, QTableWidgetItem(w)) if v != w: b = QBrush(QColor("#ff8888")) self.dataTable.item(j, 0).setBackground(b) self.dataTable.item(j, 1).setBackground(b) self.dataTable.item(j, 2).setBackground(b) j += 1 self.dataTable.resizeColumnsToContents() #self.dataTable.sortByColumn(0, Qt.DescendingOrder) self.dataTable.show() def undisplayGeometry(self): self.geometryGroup.hide() self.displayer.reset() self.inner_displayer.reset() def displayGeometry(self, geom, geom2=None): self.inner_displayer.display(geom, geom2) self.geometryGroup.show() if self.onMainCanvas.isChecked(): self.displayer.display(geom, geom2) def onReplayEvent(self): i = self.eventTable.selectionModel().currentIndex().row() if i == -1: return # event_id from current selection event_id = self.eventModel.data(self.eventModel.index(i, 0), Qt.UserRole) error = "" q = "SELECT {}({})".format(self.replay_function, event_id) # Make a layer using transaction group editable to allow Sql execution. self.catchLayerModifications = False if self.editableLayerObject != None: self.editableLayerObject.startEditing() error = self.connection_wrapper_write.executeSql(q) if self.editableLayerObject != None: self.editableLayerObject.commitChanges() self.catchLayerModifications = True if error != "": self.error_dlg = error_dialog.ErrorDialog(self) self.error_dlg.setErrorText( "An error has occurred during database access.") self.error_dlg.setContextText(error) self.error_dlg.setDetailsText("") self.error_dlg.exec_() self.connection_wrapper_write.commit() # refresh table self.populate() # Refresh replay button state. self.updateReplayButtonState() # Check if provided layer database connection is identical as current connection. def isLayerDatabaseCurrentConnection(self, layer): source = layer.source() layerUri = QgsDataSourceURI(source) pluginuri = QgsDataSourceURI(self.connection_wrapper_read.db_source) return self.areConnectionsEquals(layerUri, pluginuri) # Compare connections. def areConnectionsEquals(self, connection1, connection2): # Service id defined: compare service & Ssl mode. service = connection1.service() + connection2.service() if service != "": if connection1.service() != connection2.service(): return False if connection1.sslMode() != connection2.sslMode(): return False # Connections are equals. return True # No service: compare host, port & database. if connection1.host() != connection2.host(): return False if connection1.port() != connection2.port(): return False if connection1.database() != connection2.database(): return False # Connections are equals. return True # Reload replay button state by checking layer edition mode. def updateReplayButtonState(self, unused): self.updateReplayButtonState() def layerEditionModeChanged(self): self.updateReplayButtonState() def updateReplayButtonState(self): if self.catchLayerModifications == False: return self.editableLayerObject = None # Get all layers. layers = QgsMapLayerRegistry.instance().mapLayers() self.replayEnabled = True for lid, layer in layers.items(): # Check for layer using same database connection. usingSameDb = self.isLayerDatabaseCurrentConnection(layer) # Layer is in edition mode: if layer.isEditable() == True: # Check for database connection. if usingSameDb == True: # Disable replay button. self.replayEnabled = False # Layer is not editable: candidate for layer storage. # Store a layer that uses this connection. else: if usingSameDb == True: self.editableLayerObject = layer # Watch layer edition mode changes. if getattr(layer, "beforeEditingStarted", None) != None and getattr( layer, "editingStopped", None) != None: try: layer.editingStarted.connect(self.layerEditionModeChanged, Qt.UniqueConnection) layer.editingStopped.connect(self.layerEditionModeChanged, Qt.UniqueConnection) except: pass self.updateReplayButton()
def _create_control(self, parent): self._canvas_ctrl=QgsMapCanvas() return self._canvas_ctrl
def testCancelAndDestroy(self): """ test that nothing goes wrong if we destroy a canvas while a job is canceling """ canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) canvas.setFrameStyle(0) canvas.resize(600, 400) layer = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string", "layer", "memory") # add a ton of features for i in range(5000): f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer.dataProvider().addFeatures([f])) 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() self.assertTrue(canvas.isDrawing()) canvas.stopRendering() del canvas
def __init__(self, parent, connection_wrapper_read, connection_wrapper_write, map_canvas, audit_table, replay_function=None, table_map={}, selected_layer_id=None, selected_feature_id=None): """Constructor. @param parent parent widget @param connection_wrapper_read connection wrapper (dbapi2) @param connection_wrapper_write connection wrapper (dbapi2 or transaction group) @param map_canvas the main QgsMapCanvas @param audit_table the name of the audit table in the database @param replay_function name of the replay function in the database @param table_map a dict that associates database table name to a QGIS layer id layer_id : table_name @param selected_layer_id selected layer @param selected_feature_id selected feature_id """ super(EventDialog, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect self.setupUi(self) # reload button icons self.searchButton.setIcon( QIcon( os.path.join(os.path.dirname(__file__), 'icons', 'mActionFilter2.svg'))) self.replayButton.setIcon( QIcon( os.path.join(os.path.dirname(__file__), 'icons', 'mIconWarn.png'))) # Store connections. self.connection_wrapper_read = connection_wrapper_read self.connection_wrapper_write = connection_wrapper_write self.map_canvas = map_canvas self.audit_table = audit_table self.replay_function = replay_function # Watch for layer added or removed for replay button state update. QgsMapLayerRegistry.instance().layersRemoved.connect( self.updateReplayButtonState) QgsMapLayerRegistry.instance().layersAdded.connect( self.updateReplayButtonState) # Register all current layers. self.updateReplayButtonState() # geometry columns : table_name => list of geometry columns, the first one is the "main" geometry column self.geometry_columns = {} self.table_map = table_map # populate layer combo layer_idx = None for i, layer_id in enumerate(self.table_map.keys()): l = QgsMapLayerRegistry.instance().mapLayer(layer_id) if l is None: continue print layer_id, selected_layer_id if layer_id == selected_layer_id: layer_idx = i + 1 self.layerCombo.addItem(l.name(), layer_id) if layer_idx is not None: self.layerCombo.setCurrentIndex(layer_idx) if selected_feature_id is not None: self.idEdit.setEnabled(True) self.idEdit.setText(str(selected_feature_id)) self.dataTable.hide() # # inner canvas self.vbox = QVBoxLayout() margins = self.vbox.contentsMargins() margins.setBottom(0) margins.setTop(11) margins.setLeft(0) margins.setRight(0) self.vbox.setContentsMargins(margins) self.inner_canvas = QgsMapCanvas() # copy layer set self.inner_canvas.setLayerSet( [QgsMapCanvasLayer(l) for l in self.map_canvas.layers()]) self.inner_canvas.setExtent(self.map_canvas.extent()) self.geometryGroup.setLayout(self.vbox) self.geometryGroup.hide() self.hsplitter.setSizes([100, 100]) self.displayer = GeometryDisplayer(self.map_canvas) self.inner_displayer = GeometryDisplayer(self.inner_canvas) self.afterDt.setDateTime(QDateTime.currentDateTime()) self.beforeDt.setDateTime(QDateTime.currentDateTime()) self.advancedGroup.setCollapsed(True) # Old/new geometry legend. self.hbox = QHBoxLayout() self.oldGeometryLabel = QLabel() self.oldGeometryLabel.setText("------- old geometry") self.oldGeometryLabel.setStyleSheet( "color: " + self.displayer.oldGeometryColor().name()) self.newGeometryLabel = QLabel() self.newGeometryLabel.setText( "------- new geometry (will be restored when replaying event)") self.newGeometryLabel.setStyleSheet( "color: " + self.displayer.newGeometryColor().name()) self.hbox.addWidget(self.oldGeometryLabel) self.hbox.addWidget(self.newGeometryLabel) self.hbox.addItem( QSpacerItem(20, 20, QSizePolicy.Expanding, QSizePolicy.Fixed)) self.vbox.addLayout(self.hbox) self.vbox.addWidget(self.inner_canvas) # refresh results when the search button is clicked self.searchButton.clicked.connect(self.populate) # update the feature id line edit visiblity based on the current layer selection self.layerCombo.currentIndexChanged.connect(self.onCurrentLayerChanged) # replay button if self.replay_function: self.replayButton.clicked.connect(self.onReplayEvent)
def testPosition(self): """ test that map canvas annotation item syncs position correctly """ a = QgsTextAnnotation() a.setFrameSize(QSizeF(300, 200)) a.setFrameOffsetFromReferencePoint(QPointF(40, 50)) a.setMapPosition(QgsPointXY(12, 34)) a.setMapPositionCrs(QgsCoordinateReferenceSystem(4326)) canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) canvas.setFrameStyle(0) canvas.resize(600, 400) canvas.show() canvas.setExtent(QgsRectangle(10, 30, 20, 35)) i = QgsMapCanvasAnnotationItem(a, canvas) self.assertEqual(canvas.width(), 600) self.assertEqual(canvas.height(), 400) # test that correct initial position is set self.assertAlmostEqual(i.pos().x(), 120, 1) self.assertAlmostEqual(i.pos().y(), 110, 1) # shift annotation map position, check that item is moved a.setMapPosition(QgsPointXY(14, 32)) self.assertAlmostEqual(i.pos().x(), 240, 1) self.assertAlmostEqual(i.pos().y(), 230, 1) # check relative position a.setHasFixedMapPosition(False) a.setRelativePosition(QPointF(0.8, 0.4)) self.assertAlmostEqual(i.pos().x(), 480, 1) self.assertAlmostEqual(i.pos().y(), 160, 1) # flicking between relative and fixed position a.setHasFixedMapPosition(True) self.assertAlmostEqual(i.pos().x(), 240, 1) self.assertAlmostEqual(i.pos().y(), 230, 1) a.setHasFixedMapPosition(False) self.assertAlmostEqual(i.pos().x(), 480, 1) self.assertAlmostEqual(i.pos().y(), 160, 1)
def testSettingFeature(self): """ test that feature is set when item moves """ a = QgsTextAnnotation() a.setFrameSize(QSizeF(300, 200)) a.setFrameOffsetFromReferencePoint(QPointF(40, 50)) a.setHasFixedMapPosition(True) a.setMapPosition(QgsPointXY(12, 34)) a.setMapPositionCrs(QgsCoordinateReferenceSystem(4326)) canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) canvas.setFrameStyle(0) canvas.resize(600, 400) canvas.setExtent(QgsRectangle(10, 30, 20, 35)) i = QgsMapCanvasAnnotationItem(a, canvas) # NOQA layer = QgsVectorLayer( "Point?crs=EPSG:4326&field=station:string&field=suburb:string", 'test', "memory") canvas.setLayers([layer]) f = QgsFeature(layer.fields()) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(14, 31))) f.setValid(True) f.setAttributes(['hurstbridge', 'somewhere']) self.assertTrue(layer.dataProvider().addFeatures([f])) a.setMapLayer(layer) self.assertFalse(a.associatedFeature().isValid()) a.setMapPosition(QgsPointXY(14, 31)) self.assertTrue(a.associatedFeature().isValid()) self.assertEqual(a.associatedFeature().attributes()[0], 'hurstbridge') a.setMapPosition(QgsPointXY(17, 31)) self.assertFalse(a.associatedFeature().isValid())
def testSize(self): """ test that map canvas annotation item size is correct """ a = QgsTextAnnotation() a.setFrameSize(QSizeF(300, 200)) a.setHasFixedMapPosition(False) a.setFillSymbol( QgsFillSymbol.createSimple({ 'color': 'blue', 'width_border': '0' })) canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) canvas.setFrameStyle(0) canvas.resize(600, 400) canvas.show() canvas.setExtent(QgsRectangle(10, 30, 20, 35)) i = QgsMapCanvasAnnotationItem(a, canvas) self.assertAlmostEqual(i.boundingRect().width(), 300, 1) self.assertAlmostEqual(i.boundingRect().height(), 200, 1) a.setHasFixedMapPosition(True) a.setFrameOffsetFromReferencePoint(QPointF(0, 0)) self.assertAlmostEqual(i.boundingRect().width(), 300, -1) self.assertAlmostEqual(i.boundingRect().height(), 200, -1) a.setFrameOffsetFromReferencePoint(QPointF(10, 20)) self.assertAlmostEqual(i.boundingRect().width(), 310, -1) self.assertAlmostEqual(i.boundingRect().height(), 220, -1)
def __init__(self, parent, geometryWin, numWin): def populateStatusBar(): statusBar = self.statusBar() w = QCheckBox("Render", self) w.setObjectName('renderCheck') w.setToolTip("Toggle map rendering") w.setChecked(True) statusBar.addPermanentWidget(w) w = QCheckBox("Marker", self) w.setObjectName('markerCheck') w.setToolTip("Toggle marker with cursor position from main map") w.setChecked(False) statusBar.addPermanentWidget(w, 1) w = QCheckBox("Extent", self) w.setObjectName('extentCheck') w.setToolTip("Show extent of main map") w.setChecked(False) statusBar.addPermanentWidget(w, 1) w = QToolButton(self) w.setObjectName('highlightBtn') w.setToolTip("Highlight extent in main map") w.setText("Highlight") statusBar.addPermanentWidget(w, 1) w = QLabel("Scale factor:", self) w.setObjectName('scaleFactorLabel') w.setAlignment(Qt.AlignRight | Qt.AlignVCenter) statusBar.addPermanentWidget(w, 1) w = QDoubleSpinBox(self) w.setObjectName('scaleFactorSpin') w.setToolTip("Current scale factor of main map") w.setMinimum(0.0) w.setMaximum(1000.0) w.setDecimals(3) w.setValue(1) w.setSingleStep(.05) statusBar.addPermanentWidget(w, 1) w = QToolButton(self) w.setObjectName('scaleBtn') w.setToolTip("Set scale for main map") w.setText("Scale: ") statusBar.addPermanentWidget(w, 1) def setupUi(): self.setObjectName("AuxiliaryWindow") self.setGeometry(geometryWin) self.addDockWidget(Qt.LeftDockWidgetArea, self.dockLegend) self.actLegend = self.menuBar().addAction("") self.actLegend.triggered.connect(self.onActionLegend) self.canvas.setMapTool(self.toolPan) self.canvas.setCanvasColor(QColor(255, 255, 255)) self.canvas.enableAntiAliasing(False) self.canvas.useImageToRender(False) self.canvas.setWheelAction(QgsMapCanvas.WheelZoom) self.setCentralWidget(centralWidget) self.messageBar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) layout = QGridLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.canvas, 0, 0, 2, 1) layout.addWidget(self.messageBar, 0, 0, 1, 1) centralWidget.setLayout(layout) super(AuxiliaryWindow, self).__init__(parent) centralWidget = QWidget(self) self.canvas = QgsMapCanvas(centralWidget) self.messageBar = QgsMessageBar(centralWidget) self.toolPan = QgsMapToolPan(self.canvas) self.qgisCanvas = qgis.utils.iface.mapCanvas() self.qgisTView = qgis.utils.iface.layerTreeView() self.qgisSyncGroup = None self.numWin = numWin self.ltg = QgsLayerTreeGroup('', Qt.Unchecked) self.dockLegend = AuxiliaryLegend(self, numWin) self.root = QgsProject.instance().layerTreeRoot() self.extent = self.actLegend = None self.marker = MarkerWindow(self.canvas) setupUi() populateStatusBar() self.onCurrentLayerChanged(None) self.onDestinationCrsChanged_MapUnitsChanged() self.onHasCrsTransformEnabledChanged( self.qgisCanvas.hasCrsTransformEnabled())
class BBOXDialog(QDialog, FORM_CLASS): def __init__(self, inp_sparql, triplestoreconf, endpointIndex): super(QDialog, self).__init__() self.setupUi(self) self.inp_sparql = inp_sparql self.triplestoreconf = triplestoreconf self.endpointIndex = endpointIndex self.vl = QgsVectorLayer("Point", "temporary_points", "memory") self.map_canvas = QgsMapCanvas(self) self.layerExtentOrBBOX = False self.map_canvas.setMinimumSize(500, 475) uri = "url=http://a.tile.openstreetmap.org/{z}/{x}/{y}.png&zmin=0&type=xyz" self.mts_layer = QgsRasterLayer(uri, 'OSM', 'wms') if not self.mts_layer.isValid(): print("Layer failed to load!") self.rect_tool = RectangleMapTool(self.map_canvas) self.map_canvas.setMapTool(self.rect_tool) self.map_canvas.setExtent(self.mts_layer.extent()) self.map_canvas.setLayers([self.vl, self.mts_layer]) self.map_canvas.setCurrentLayer(self.mts_layer) #chooseLayerLabel=QLabel("Choose Layer Extent:",self) #chooseLayerLabel.move(0,480) #self.chooseBBOXLayer=QComboBox(self) #self.chooseBBOXLayer.move(150,475) #b2 = QPushButton("Apply Layer Extent",self) #b2.move(10,500) self.b2.clicked.connect(self.setBBOXExtentQuery) layers = QgsProject.instance().layerTreeRoot().children() for layer in layers: self.chooseBBOXLayer.addItem(layer.name()) #b1 = QPushButton("Apply BBOX",self) #b1.move(400,500) self.b1.clicked.connect(self.setBBOXInQuery) def setBBOXExtentQuery(self): self.mts_layer = QgsProject.instance().layerTreeRoot().children()[ self.chooseBBOXLayer.currentIndex()].layer() self.layerExtentOrBBOX = True self.setBBOXInQuery() def setBBOXInQuery(self): if self.layerExtentOrBBOX: xMax = self.mts_layer.extent().xMaximum() xMin = self.mts_layer.extent().xMinimum() yMin = self.mts_layer.extent().yMinimum() yMax = self.mts_layer.extent().yMaximum() pointt1 = QgsGeometry.fromPointXY(QgsPointXY(xMax, yMin)) pointt2 = QgsGeometry.fromPointXY(QgsPointXY(xMin, yMin)) pointt3 = QgsGeometry.fromPointXY(QgsPointXY(xMin, yMax)) pointt4 = QgsGeometry.fromPointXY(QgsPointXY(xMax, yMax)) sourceCrs = QgsCoordinateReferenceSystem( self.mts_layer.sourceCrs()) else: pointt1 = QgsGeometry.fromWkt(self.rect_tool.point1.asWkt()) pointt2 = QgsGeometry.fromWkt(self.rect_tool.point2.asWkt()) pointt3 = QgsGeometry.fromWkt(self.rect_tool.point3.asWkt()) pointt4 = QgsGeometry.fromWkt(self.rect_tool.point4.asWkt()) sourceCrs = QgsCoordinateReferenceSystem(self.mts_layer.crs()) destCrs = QgsCoordinateReferenceSystem(4326) tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance()) pointt1.transform(tr) pointt2.transform(tr) pointt3.transform(tr) pointt4.transform(tr) polygon = QgsGeometry.fromPolylineXY([ pointt1.asPoint(), pointt2.asPoint(), pointt3.asPoint(), pointt4.asPoint() ]) center = polygon.centroid() #distance = QgsDistanceArea() #distance.setSourceCrs(destCrs) #distance.setEllipsoidalMode(True) #distance.setEllipsoid('WGS84') widthm = 100 #distance.measureLine(pointt1, pointt2) self.curbbox = [] self.curbbox.append(pointt1) self.curbbox.append(pointt2) self.curbbox.append(pointt3) self.curbbox.append(pointt4) self.close() curquery = self.inp_sparql.toPlainText() if "bboxquery" in self.triplestoreconf[ self.endpointIndex] and self.triplestoreconf[ self.endpointIndex]["bboxquery"]["type"] == "minmax": curquery = curquery[0:curquery.rfind('}')] + self.triplestoreconf[ self.endpointIndex]["bboxquery"]["query"].replace( "%%minPoint%%", pointt2.asWkt()).replace( "%%maxPoint%%", pointt4.asWkt()) + curquery[curquery.rfind('}') + 1:] elif "bboxquery" in self.triplestoreconf[ self.endpointIndex] and self.triplestoreconf[ self. endpointIndex]["bboxquery"]["type"] == "pointdistance": curquery = curquery[0:curquery.rfind('}')] + self.triplestoreconf[ self.endpointIndex]["bboxquery"]["query"].replace( "%%lat%%", str(center.asPoint().y())).replace( "%%lon%%", str(center.asPoint().x())).replace( "%%distance%%", str(widthm / 1000)) + curquery[curquery.rfind('}') + 1:] self.inp_sparql.setPlainText(curquery)
class AuxiliaryWindow(QMainWindow): closed = pyqtSignal(int) def __init__(self, parent, geometryWin, numWin): def populateStatusBar(): statusBar = self.statusBar() w = QCheckBox("Render", self) w.setObjectName('renderCheck') w.setToolTip("Toggle map rendering") w.setChecked(True) statusBar.addPermanentWidget(w) w = QCheckBox("Marker", self) w.setObjectName('markerCheck') w.setToolTip("Toggle marker with cursor position from main map") w.setChecked(False) statusBar.addPermanentWidget(w, 1) w = QCheckBox("Extent", self) w.setObjectName('extentCheck') w.setToolTip("Show extent of main map") w.setChecked(False) statusBar.addPermanentWidget(w, 1) w = QToolButton(self) w.setObjectName('highlightBtn') w.setToolTip("Highlight extent in main map") w.setText("Highlight") statusBar.addPermanentWidget(w, 1) w = QLabel("Scale factor:", self) w.setObjectName('scaleFactorLabel') w.setAlignment(Qt.AlignRight | Qt.AlignVCenter) statusBar.addPermanentWidget(w, 1) w = QDoubleSpinBox(self) w.setObjectName('scaleFactorSpin') w.setToolTip("Current scale factor of main map") w.setMinimum(0.0) w.setMaximum(1000.0) w.setDecimals(3) w.setValue(1) w.setSingleStep(.05) statusBar.addPermanentWidget(w, 1) w = QToolButton(self) w.setObjectName('scaleBtn') w.setToolTip("Set scale for main map") w.setText("Scale: ") statusBar.addPermanentWidget(w, 1) def setupUi(): self.setObjectName("AuxiliaryWindow") self.setGeometry(geometryWin) self.addDockWidget(Qt.LeftDockWidgetArea, self.dockLegend) self.actLegend = self.menuBar().addAction("") self.actLegend.triggered.connect(self.onActionLegend) self.canvas.setMapTool(self.toolPan) self.canvas.setCanvasColor(QColor(255, 255, 255)) self.canvas.enableAntiAliasing(False) self.canvas.useImageToRender(False) self.canvas.setWheelAction(QgsMapCanvas.WheelZoom) self.setCentralWidget(centralWidget) self.messageBar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) layout = QGridLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.canvas, 0, 0, 2, 1) layout.addWidget(self.messageBar, 0, 0, 1, 1) centralWidget.setLayout(layout) super(AuxiliaryWindow, self).__init__(parent) centralWidget = QWidget(self) self.canvas = QgsMapCanvas(centralWidget) self.messageBar = QgsMessageBar(centralWidget) self.toolPan = QgsMapToolPan(self.canvas) self.qgisCanvas = qgis.utils.iface.mapCanvas() self.qgisTView = qgis.utils.iface.layerTreeView() self.qgisSyncGroup = None self.numWin = numWin self.ltg = QgsLayerTreeGroup('', Qt.Unchecked) self.dockLegend = AuxiliaryLegend(self, numWin) self.root = QgsProject.instance().layerTreeRoot() self.extent = self.actLegend = None self.marker = MarkerWindow(self.canvas) setupUi() populateStatusBar() self.onCurrentLayerChanged(None) self.onDestinationCrsChanged_MapUnitsChanged() self.onHasCrsTransformEnabledChanged( self.qgisCanvas.hasCrsTransformEnabled()) def _connect(self, isConnect=True): widgets = { 'scaleBtn': self.findChild(QToolButton, 'scaleBtn'), 'renderCheck': self.findChild(QCheckBox, 'renderCheck'), 'markerCheck': self.findChild(QCheckBox, 'markerCheck'), 'extentCheck': self.findChild(QCheckBox, 'extentCheck'), 'highlightBtn': self.findChild(QToolButton, 'highlightBtn'), 'scaleFactorSpin': self.findChild(QDoubleSpinBox, 'scaleFactorSpin') } signal_slot = ({ 'signal': widgets['scaleBtn'].clicked, 'slot': self.onClickedScale }, { 'signal': widgets['renderCheck'].toggled, 'slot': self.onToggledRender }, { 'signal': widgets['markerCheck'].toggled, 'slot': self.onToggledMarker }, { 'signal': widgets['extentCheck'].toggled, 'slot': self.onToggledExtent }, { 'signal': widgets['highlightBtn'].clicked, 'slot': self.onClickedHighlight }, { 'signal': widgets['scaleFactorSpin'].valueChanged, 'slot': self.onValueChangedScale }, { 'signal': self.dockLegend.currentLayerChanged, 'slot': self.onCurrentLayerChanged }, { 'signal': self.dockLegend.currentLayerQgis, 'slot': self.onCurrentLayerQgis }, { 'signal': self.dockLegend.syncGroupLayer, 'slot': self.onSyncGroupAddLayersQgis }, { 'signal': self.dockLegend.addSelectedLayersQgis, 'slot': self.onAddSelectedLayersQgis }, { 'signal': self.dockLegend.removeLayer, 'slot': self.onRemoveLayers }, { 'signal': self.dockLegend.needSelectLayer, 'slot': self.onNeedSelectLayer }, { 'signal': self.dockLegend.closed, 'slot': self.onClosedLegend }, { 'signal': self.canvas.extentsChanged, 'slot': self.onExtentsChangedMirror }, { 'signal': self.qgisCanvas.extentsChanged, 'slot': self.onExtentsChangedQgisCanvas }, { 'signal': self.qgisCanvas.xyCoordinates, 'slot': self.marker.onXYCoordinates }, { 'signal': self.qgisCanvas.destinationCrsChanged, 'slot': self.onDestinationCrsChanged_MapUnitsChanged }, { 'signal': self.qgisCanvas.mapUnitsChanged, 'slot': self.onDestinationCrsChanged_MapUnitsChanged }, { 'signal': self.qgisCanvas.hasCrsTransformEnabledChanged, 'slot': self.onHasCrsTransformEnabledChanged }, { 'signal': self.root.removedChildren, 'slot': self.onRemovedChildrenQgisRoot }, { 'signal': QgsMapLayerRegistry.instance().layersWillBeRemoved, 'slot': self.onLayersWillBeRemoved }) if isConnect: for item in signal_slot: item['signal'].connect(item['slot']) else: for item in signal_slot: item['signal'].disconnect(item['slot']) def _extentsChanged(self, canvasOrigin, originSlot, canvasDest, scaleFactor=None): canvasOrigin.extentsChanged.disconnect(originSlot) if scaleFactor is None: scale = canvasOrigin.scale() canvasOrigin.setExtent(canvasDest.extent()) canvasOrigin.zoomScale(scale) else: canvasOrigin.setExtent(canvasDest.extent()) canvasOrigin.zoomScale(scaleFactor * canvasDest.scale()) canvasOrigin.extentsChanged.connect(originSlot) def _textScaleBtnChanched(self): scale = locale.format("%.0f", self.canvas.scale(), True) w = self.findChild(QToolButton, 'scaleBtn') w.setText("Scale 1:%s" % scale) def _extent(self): rect = self.qgisCanvas.extent() p1 = QgsPoint(rect.xMinimum(), rect.yMinimum()) p2 = QgsPoint(rect.xMinimum(), rect.yMaximum()) p3 = QgsPoint(rect.xMaximum(), rect.yMaximum()) p4 = QgsPoint(rect.xMaximum(), rect.yMinimum()) p5 = QgsPoint(rect.xMinimum(), rect.yMinimum()) points = [p1, p2, p3, p4, p5] self.extent.setToGeometry(QgsGeometry.fromPolyline(points), None) def _execFunction(self, func, arg, signal, slot): signal.disconnect(slot) func(arg) signal.connect(slot) def _connectVectorRefresh(self, layer, isConnect=True): if isinstance(layer, QgsVectorLayer): f = layer.editCommandEnded.connect if isConnect else layer.editCommandEnded.disconnect f(self.canvas.refresh) def _addLayersQgis(self, layersQgis, needMsg=True): self.dockLegend.clearBridge() l1 = set(layersQgis) l2 = set(map(lambda item: item.layer(), self.ltg.findLayers())) layers = list(l1 - l2) if len(layers) == 0: if needMsg: self.messageBar.pushMessage( "Need select new layer(s) in main map", QgsMessageBar.WARNING, 2) else: # Get order by layersQgis for item in layersQgis: if item in layers: self.ltg.addLayer(item) self._connectVectorRefresh(item) self.dockLegend.setBridge(self.canvas) def _syncGroupAddLayersQgis(self, ltg): layersQgis = map(lambda item: item.layer(), ltg.findLayers()) if len(layersQgis) == 0: return False name = ltg.name() if self.qgisSyncGroup == ltg: msg = "Already synchronized group (main map) -> '%s'" % name self.messageBar.pushMessage(msg, QgsMessageBar.INFO, 4) return True if not self.qgisSyncGroup is None: self.qgisSyncGroup.addedChildren.disconnect( self.addedChildrenLayer) self.qgisSyncGroup = ltg self.qgisSyncGroup.addedChildren.connect(self.addedChildrenLayer) self.dockLegend.addNameSyncGroup(name) msg = "Changed synchronized group (main map) -> '%s'" % name self.messageBar.pushMessage(msg, QgsMessageBar.INFO, 4) self._addLayersQgis(layersQgis) return True def run(self): if len(self.qgisTView.selectedLayerNodes()) > 0: self.onAddSelectedLayersQgis() else: ltn = self.qgisTView.currentNode() if not isinstance(ltn, QgsLayerTreeGroup): return False else: if ltn == self.root: return False else: if not self._syncGroupAddLayersQgis(ltn): return False self.dockLegend.setBridge(self.canvas) self.canvas.setRenderFlag(False) self.show() # Need show before self._connect() self._connect() self.canvas.setExtent(self.qgisCanvas.extent()) w = self.findChild(QDoubleSpinBox, 'scaleFactorSpin') w.setValue(1) self.canvas.setRenderFlag(True) return True def getLayersCanvas(self): layerIds = map(lambda x: x.layerId(), self.ltg.findLayers()) layerChecks = map(lambda x: str(x.isVisible()), self.ltg.findLayers()) return (layerIds, layerChecks) def setLayersCanvas(self, layerIds, layerChecks): prevFlag = self.canvas.renderFlag() self.canvas.setRenderFlag(False) lyrRegs = QgsMapLayerRegistry.instance() for id in range(len(layerIds)): layer = lyrRegs.mapLayer(layerIds[id]) isVisible = int(layerChecks[id]) if not layer is None: self.ltg.addLayer(layer).setVisible(isVisible) self.canvas.setRenderFlag(prevFlag) def getWindowSetting(self): g = self.geometry() r = self.canvas.extent() nodes = self.ltg.findLayers() currentLayer = self.dockLegend.tview.currentLayer() currentLayerId = currentLayer.id( ) if not currentLayer is None else "None" windowSetting = { 'numWin': self.numWin, 'geometryWin': { 'x': g.x(), 'y': g.y(), 'width': g.width(), 'height': g.height() }, 'extentCanvas': { 'xmin': r.xMinimum(), 'ymin': r.yMinimum(), 'xmax': r.xMaximum(), 'ymax': r.yMaximum() }, 'currentLayerId': currentLayerId, 'layerIds': ' '.join(map(lambda item: item.layerId(), nodes)), 'visibles': ' '.join(map(lambda item: str(int(item.isVisible())), nodes)) } for item in ('render', 'marker', 'extent'): nameGui = "%sCheck" % item windowSetting[item] = int( self.findChild(QCheckBox, nameGui).isChecked()) return windowSetting def setWindowSetting(self, windowSetting): self.numWin = windowSetting['numWin'] # Populate with layers and set Bridge for legend layerIds = windowSetting['layerIds'].split(' ') visibles = map(lambda item: bool(int(item)), windowSetting['visibles'].split(' ')) ltg = self.qgisTView.layerTreeModel().rootGroup() for id in range(len(layerIds)): node = ltg.findLayer(layerIds[id]) if node is None: continue layer = node.layer() visible = Qt.Checked if visibles[id] else Qt.Unchecked self._connectVectorRefresh(layer) self.ltg.addLayer(layer).setVisible(visible) self.dockLegend.setBridge(self.canvas) self.show() # Need show before self._connect() self._connect() node = ltg.findLayer(windowSetting['currentLayerId']) if not node is None: layer = node.layer() self.dockLegend.tview.setCurrentLayer(layer) w = windowSetting['extentCanvas'] self.canvas.setExtent( QgsRectangle(w['xmin'], w['ymin'], w['xmax'], w['ymax'])) for item in ('render', 'marker', 'extent'): value = bool(windowSetting[item]) nameGui = "%sCheck" % item self.findChild(QCheckBox, nameGui).setChecked(value) def closeEvent(self, event): self._connect(False) event.accept() self.closed.emit(self.numWin) @pyqtSlot(int) def onValueChangedScale(self, scaleFactor): w = self.findChild(QCheckBox, 'renderCheck') if not w.isChecked(): return self._execFunction(self.canvas.zoomScale, scaleFactor * self.qgisCanvas.scale(), self.canvas.extentsChanged, self.onExtentsChangedMirror) self._textScaleBtnChanched() @pyqtSlot() def onClickedScale(self): self._execFunction(self.qgisCanvas.zoomScale, self.canvas.scale(), self.qgisCanvas.extentsChanged, self.onExtentsChangedQgisCanvas) w = self.findChild(QDoubleSpinBox, 'scaleFactorSpin') self._execFunction(w.setValue, 1.0, w.valueChanged, self.onValueChangedScale) @pyqtSlot() def onClickedHighlight(self): def removeRB(): rb.reset(True) self.qgisCanvas.scene().removeItem(rb) rb = QgsRubberBand(self.qgisCanvas, QGis.Polygon) rb.setBorderColor(QColor(255, 0, 0)) rb.setWidth(2) rb.setToGeometry(QgsGeometry.fromRect(self.canvas.extent()), None) QTimer.singleShot(2000, removeRB) @pyqtSlot(bool) def onToggledRender(self, enabled): if enabled: self.canvas.setMapTool(self.toolPan) w = self.findChild(QDoubleSpinBox, 'scaleFactorSpin') self._extentsChanged(self.canvas, self.onExtentsChangedMirror, self.qgisCanvas, w.value()) self._textScaleBtnChanched() self.canvas.setWheelAction(QgsMapCanvas.WheelZoom) else: self.canvas.unsetMapTool(self.toolPan) self.canvas.setWheelAction(QgsMapCanvas.WheelNothing) self.canvas.setRenderFlag(enabled) @pyqtSlot(bool) def onToggledMarker(self, enabled): self.marker.add() if enabled else self.marker.remove() @pyqtSlot(bool) def onToggledExtent(self, enabled): def setExtent(): if not self.extent is None: self.canvas.scene().removeItem(self.extent) self.extent = QgsRubberBand(self.canvas, QGis.Polygon) self.extent.setBorderColor(QColor(255, 0, 0)) self.extent.setWidth(2) self._extent() if enabled: setExtent() else: if not self.extent is None: self.canvas.scene().removeItem(self.extent) self.extent = None @pyqtSlot() def onExtentsChangedMirror(self): w = self.findChild(QCheckBox, 'renderCheck') if not w.isChecked(): return self._extentsChanged(self.qgisCanvas, self.onExtentsChangedQgisCanvas, self.canvas) self._textScaleBtnChanched() w = self.findChild(QDoubleSpinBox, 'scaleFactorSpin') self._execFunction(w.setValue, self.canvas.scale() / self.qgisCanvas.scale(), w.valueChanged, self.onValueChangedScale) if not self.extent is None: self._extent() @pyqtSlot() def onExtentsChangedQgisCanvas(self): w = self.findChild(QCheckBox, 'renderCheck') if not w.isChecked(): return w = self.findChild(QDoubleSpinBox, 'scaleFactorSpin') self._extentsChanged(self.canvas, self.onExtentsChangedMirror, self.qgisCanvas, w.value()) self._textScaleBtnChanched() if not self.extent is None: self._extent() @pyqtSlot() def onDestinationCrsChanged_MapUnitsChanged(self): prevFlag = self.canvas.renderFlag() self.canvas.setRenderFlag(False) self.canvas.setDestinationCrs( self.qgisCanvas.mapRenderer().destinationCrs()) self.canvas.setMapUnits(self.qgisCanvas.mapUnits()) self.canvas.setRenderFlag(prevFlag) @pyqtSlot(bool) def onHasCrsTransformEnabledChanged(self, enabled): prevFlag = self.canvas.renderFlag() self.canvas.setRenderFlag(False) self.canvas.mapRenderer().setProjectionsEnabled(enabled) self.canvas.setRenderFlag(prevFlag) @pyqtSlot(list) def onLayersWillBeRemoved(self, theLayerIds): ids = list(set(self.ltg.findLayerIds()) & set(theLayerIds)) # intersection nodes = map(lambda item: self.ltg.findLayer(item), ids) for item in nodes: self._connectVectorRefresh(item.layer(), False) self.ltg.removeChildNode(item) @pyqtSlot() def onAddSelectedLayersQgis(self): layersQgis = map(lambda item: item.layer(), self.qgisTView.selectedLayerNodes()) self._addLayersQgis(layersQgis) @pyqtSlot('QgsLayerTreeNode', int, int) def addedChildrenLayer(self, ltg, indexFrom, indexTo): layersQgis = map(lambda item: item.layer(), ltg.findLayers()) self._addLayersQgis(layersQgis, False) @pyqtSlot('QgsLayerTreeNode', int, int) def onRemovedChildrenQgisRoot(self, ltg, indexFrom, indexTo): if not self.qgisSyncGroup is None and not self.qgisSyncGroup in self.root.children( ): self.qgisSyncGroup = None self.dockLegend.addNameSyncGroup("None") msg = "Removed synchronized group (main map)" self.messageBar.pushMessage(msg, QgsMessageBar.INFO, 4) @pyqtSlot() def onSyncGroupAddLayersQgis(self): msg = "Need active a group in main map with new layers" ltn = self.qgisTView.currentNode() if not isinstance(ltn, QgsLayerTreeGroup) or ltn == self.root: self.messageBar.pushMessage(msg, QgsMessageBar.WARNING, 3) return if not self._syncGroupAddLayersQgis(ltn): self.messageBar.pushMessage(msg, QgsMessageBar.WARNING, 3) @pyqtSlot('QgsMapLayer') def onRemoveLayers(self, layer): self._connectVectorRefresh(layer, False) @pyqtSlot() def onNeedSelectLayer(self): self.messageBar.pushMessage("Need select layer(s)", QgsMessageBar.WARNING, 2) @pyqtSlot('QgsMapLayer') def onCurrentLayerQgis(self, layer): if layer is None: self.messageBar.pushMessage("Need active layer", QgsMessageBar.WARNING, 2) else: self.qgisTView.setCurrentLayer(layer) @pyqtSlot('QgsMapLayer') def onCurrentLayerChanged(self, layer): hasLayer = True if not layer is None else False selectName = "Select layer '%s'" % layer.name( ) if hasLayer else "None select layer" title = "#%d - %s" % (self.numWin, selectName) self.setWindowTitle(title) @pyqtSlot() def onClosedLegend(self): self.actLegend.setText("Show layers") @pyqtSlot() def onActionLegend(self): self.actLegend.setText("") self.dockLegend.show()
def test_rendered_item_results_remove_outdated(self): """ Test that outdated results are removed from rendered item result caches """ canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4326')) canvas.setFrameStyle(0) canvas.resize(600, 400) canvas.setCachingEnabled(True) self.assertEqual(canvas.width(), 600) self.assertEqual(canvas.height(), 400) layer = QgsAnnotationLayer( 'test', QgsAnnotationLayer.LayerOptions( QgsProject.instance().transformContext())) self.assertTrue(layer.isValid()) layer2 = QgsAnnotationLayer( 'test', QgsAnnotationLayer.LayerOptions( QgsProject.instance().transformContext())) self.assertTrue(layer2.isValid()) item = QgsAnnotationPolygonItem( QgsPolygon( QgsLineString([ QgsPoint(11.5, 13), QgsPoint(12, 13), QgsPoint(12, 13.5), QgsPoint(11.5, 13) ]))) item.setSymbol( QgsFillSymbol.createSimple({ 'color': '200,100,100', 'outline_color': 'black', 'outline_width': '2' })) item.setZIndex(1) i1_id = layer.addItem(item) item = QgsAnnotationLineItem( QgsLineString( [QgsPoint(11, 13), QgsPoint(12, 13), QgsPoint(12, 15)])) item.setZIndex(2) i2_id = layer.addItem(item) item = QgsAnnotationMarkerItem(QgsPoint(12, 13)) item.setZIndex(3) i3_id = layer2.addItem(item) layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) layer2.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) canvas.setLayers([layer, layer2]) canvas.setExtent(QgsRectangle(10, 10, 18, 18)) 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() results = canvas.renderedItemResults() self.assertCountEqual([i.itemId() for i in results.renderedItems()], [i1_id, i2_id, i3_id]) # now try modifying an annotation in the layer -- it will redraw, and we don't want to reuse any previously # cached rendered item results for this layer! item = QgsAnnotationPolygonItem( QgsPolygon( QgsLineString([ QgsPoint(11.5, 13), QgsPoint(12.5, 13), QgsPoint(12.5, 13.5), QgsPoint(11.5, 13) ]))) item.setZIndex(1) layer.replaceItem(i1_id, item) while not canvas.isDrawing(): app.processEvents() canvas.waitWhileRendering() item = QgsAnnotationMarkerItem(QgsPoint(17, 18)) item.setZIndex(3) layer2.replaceItem(i3_id, item) while not canvas.isDrawing(): app.processEvents() canvas.waitWhileRendering() results = canvas.renderedItemResults() items_in_bounds = results.renderedAnnotationItemsInBounds( QgsRectangle(10, 10, 15, 15)) self.assertCountEqual([i.itemId() for i in items_in_bounds], [i1_id, i2_id]) items_in_bounds = results.renderedAnnotationItemsInBounds( QgsRectangle(15, 15, 20, 20)) self.assertCountEqual([i.itemId() for i in items_in_bounds], [i3_id])
def add_layer_canvas(self,layer): # canvas = QgsMapCanvas() QgsMapLayerRegistry.instance().addMapLayer(layer) QgsMapCanvas().setExtent(layer.extent())
def testRefreshOnTimer(self): """ test that map canvas refreshes with auto refreshing layers """ 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") 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('empty_canvas', 'empty_canvas', canvas)) # add polygon to layer f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer.dataProvider().addFeatures([f])) # set auto refresh on layer layer.setAutoRefreshInterval(100) layer.setAutoRefreshEnabled(True) timeout = time.time() + 1 # expect canvas to auto refresh... while not canvas.isDrawing(): app.processEvents() self.assertTrue(time.time() < timeout) while canvas.isDrawing(): app.processEvents() self.assertTrue(time.time() < timeout) # add a polygon to layer f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer.dataProvider().addFeatures([f])) # wait for canvas auto refresh while not canvas.isDrawing(): app.processEvents() self.assertTrue(time.time() < timeout) while canvas.isDrawing(): app.processEvents() self.assertTrue(time.time() < timeout) # now canvas should look different... self.assertFalse( self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas)) # switch off auto refresh layer.setAutoRefreshEnabled(False) timeout = time.time() + 0.5 while time.time() < timeout: # messy, but only way to check that canvas redraw doesn't occur self.assertFalse(canvas.isDrawing())
def test_temporal_animation(self): """ Test temporal animation logic """ canvas = QgsMapCanvas() self.assertEqual(canvas.mapSettings().frameRate(), -1) self.assertEqual(canvas.mapSettings().currentFrame(), -1) controller = QgsTemporalController() canvas.setTemporalController(controller) controller.updateTemporalRange.emit( QgsDateTimeRange(QDateTime(QDate(2020, 1, 2), QTime(1, 2, 3)), QDateTime(QDate(2020, 1, 4), QTime(1, 2, 3)))) # should be no change self.assertEqual(canvas.mapSettings().frameRate(), -1) self.assertEqual(canvas.mapSettings().currentFrame(), -1) temporal_no = QgsTemporalNavigationObject() temporal_no.setTemporalExtents( QgsDateTimeRange(QDateTime(QDate(2020, 1, 2), QTime(1, 2, 3)), QDateTime(QDate(2020, 1, 4), QTime(1, 2, 3)))) temporal_no.setFrameDuration(QgsInterval(0, 0, 0, 0, 1, 0, 0)) canvas.setTemporalController(temporal_no) controller.updateTemporalRange.emit( QgsDateTimeRange(QDateTime(QDate(2020, 1, 2), QTime(1, 2, 3)), QDateTime(QDate(2020, 1, 4), QTime(1, 2, 3)))) # should be no change self.assertEqual(canvas.mapSettings().frameRate(), -1) self.assertEqual(canvas.mapSettings().currentFrame(), -1) temporal_no.setFramesPerSecond(30) temporal_no.pause() temporal_no.setCurrentFrameNumber(6) canvas.refresh() # should be no change - temporal controller is not in animation mode self.assertEqual(canvas.mapSettings().frameRate(), -1) self.assertEqual(canvas.mapSettings().currentFrame(), -1) temporal_no.setNavigationMode(QgsTemporalNavigationObject.Animated) self.assertEqual(canvas.mapSettings().frameRate(), 30) self.assertEqual(canvas.mapSettings().currentFrame(), 6) temporal_no.setCurrentFrameNumber(7) self.assertEqual(canvas.mapSettings().frameRate(), 30) self.assertEqual(canvas.mapSettings().currentFrame(), 6) # switch off animation mode temporal_no.setNavigationMode(QgsTemporalNavigationObject.FixedRange) self.assertEqual(canvas.mapSettings().frameRate(), -1) self.assertEqual(canvas.mapSettings().currentFrame(), -1) temporal_no.setNavigationMode(QgsTemporalNavigationObject.Animated) self.assertEqual(canvas.mapSettings().frameRate(), 30) self.assertEqual(canvas.mapSettings().currentFrame(), 7) temporal_no.setNavigationMode( QgsTemporalNavigationObject.NavigationOff) self.assertEqual(canvas.mapSettings().frameRate(), -1) self.assertEqual(canvas.mapSettings().currentFrame(), -1)
def setUpClass(cls): cls.mCanvas = QgsMapCanvas() QgsGui.editorWidgetRegistry().initEditors(cls.mCanvas)
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 __init__(self, app): """ constructor - initialize UI elements - connect UI elements to callback """ super(WidgetResult, self).__init__() self.ui = Ui_widgetResult() self.ui.setupUi(self) # create canvas self.canvas = QgsMapCanvas(self.ui.widget_map) self.canvas.setGeometry( 0, # x self.ui.widget_map_menu_l.x() + self.ui.widget_map_menu_l.height(), # y self.ui.widget_map.width() - 2 * UI_PADDING, # width self.ui.widget_map.width() - 2 * UI_PADDING # height ) self.canvas.setCanvasColor(Qt.white) self.canvas.enableAntiAliasing(True) self.canvas.mapRenderer().setProjectionsEnabled(True) self.canvas.mapRenderer().setDestinationCrs( QgsCoordinateReferenceSystem( 4326, QgsCoordinateReferenceSystem.PostgisCrsId)) self.canvas.zoomNextStatusChanged.connect(self.checkRendering) self.canvas.xyCoordinates.connect(self.currentLocation) self.registry = QgsMapLayerRegistry.instance() self.map_layers = [None] * len(self.LAYER_NAMES) self.map_layer_renderer = [None] * len(self.LAYER_NAMES) for idx, str_style in enumerate(self.LAYER_STYLES): rdoc = QDomDocument("renderer") rdoc.setContent(str_style) self.map_layer_renderer[idx] = QgsFeatureRendererV2.load( rdoc.firstChild().toElement()) # populate export list self.ui.cb_export_format.clear() for export_format in self.EXPORT_FORMATS.keys(): self.ui.cb_export_format.addItem(export_format) # style object required for QgsRendererV2PropertiesDialog self.style = QgsStyleV2() # create the map tools self.toolPan = QgsMapToolPan(self.canvas) self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out self.toolInfo = QgsMapToolEmitPoint(self.canvas) self.toolInfo.canvasClicked.connect(self.showInfo) self.canvas.setMapTool(self.toolPan) # additional self.dlgResultDetail = DialogResult() self.dlgResultDetail.setModal(True) # set link to application main controller self.app = app # reset project self._project = None # default export setting self.export_format = ExportTypes.Shapefile # connect slots (ui event) self.ui.btn_zoom_full.clicked.connect(self.mapZoomFull) self.ui.btn_zoom_in.clicked.connect(self.mapZoomIn) self.ui.btn_zoom_out.clicked.connect(self.mapZoomOut) self.ui.btn_stop.clicked.connect(self.stopRendering) self.ui.btn_zoom_layer.clicked.connect(self.mapZoomLayer) self.ui.btn_pan.clicked.connect(self.mapPan) self.ui.btn_theme.clicked.connect(self.mapEditTheme) self.ui.btn_info.clicked.connect(self.mapIdentify) self.ui.btn_zoom_to_feature.clicked.connect(self.searchFeature) self.ui.cb_export_format.currentIndexChanged[str].connect( self.exportFormatChanged) self.ui.btn_export.clicked.connect(self.exportData) self.ui.btn_export_select_path.clicked.connect(self.selectExportFile)
def testSaveMultipleCanvasesToProject(self): # test saving/restoring canvas state to project with multiple canvases c1 = QgsMapCanvas() c1.setObjectName('c1') c1.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:3111')) c1.setRotation(45) c2 = QgsMapCanvas() c2.setObjectName('c2') c2.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4326')) c2.setRotation(65) doc = QDomDocument("testdoc") elem = doc.createElement("qgis") doc.appendChild(elem) c1.writeProject(doc) c2.writeProject(doc) c3 = QgsMapCanvas() c3.setObjectName('c1') c4 = QgsMapCanvas() c4.setObjectName('c2') c3.readProject(doc) c4.readProject(doc) self.assertEqual(c3.mapSettings().destinationCrs().authid(), 'EPSG:3111') self.assertEqual(c3.rotation(), 45) self.assertEqual(c4.mapSettings().destinationCrs().authid(), 'EPSG:4326') self.assertEqual(c4.rotation(), 65)
def test_geocode(self): geocoder = TestGeocoder() canvas = QgsMapCanvas() filter = QgsGeocoderLocatorFilter('testgeocoder', 'my geocoder', 'pref', geocoder, canvas) self.assertEqual(filter.name(), 'testgeocoder') self.assertEqual(filter.displayName(), 'my geocoder') self.assertEqual(filter.prefix(), 'pref') self.assertEqual(filter.geocoder(), geocoder) spy = QSignalSpy(filter.resultFetched) context = QgsLocatorContext() feedback = QgsFeedback() # no results filter.fetchResults('cvxbcvb', context, feedback) self.assertEqual(len(spy), 0) # one result filter.fetchResults('a', context, feedback) self.assertEqual(len(spy), 1) res = spy[-1][0] self.assertEqual(res.displayString, 'res 1') # some sip weirdness here -- if we directly access the QgsLocatorResult object here then we get segfaults! # so instead convert back to QgsGeocoderResult. This makes the test more robust anyway... geocode_result = filter.locatorResultToGeocoderResult(res) self.assertEqual(geocode_result.identifier(), 'res 1') self.assertEqual(geocode_result.geometry().asWkt(), 'Point (1 2)') self.assertEqual(geocode_result.crs().authid(), 'EPSG:4326') self.assertEqual(geocode_result.additionalAttributes(), { 'b': 123, 'c': 'xyz' }) self.assertTrue(geocode_result.viewport().isNull()) self.assertFalse(geocode_result.description()) self.assertFalse(geocode_result.group()) # two possible results filter.fetchResults('b', context, feedback) self.assertEqual(len(spy), 3) res1 = spy[-2][0] res2 = spy[-1][0] self.assertEqual(res1.displayString, 'res 1') geocode_result = filter.locatorResultToGeocoderResult(res1) self.assertEqual(geocode_result.identifier(), 'res 1') self.assertEqual(geocode_result.geometry().asWkt(), 'Point (11 12)') self.assertEqual(geocode_result.crs().authid(), 'EPSG:4326') self.assertEqual(geocode_result.additionalAttributes(), { 'b': 123, 'c': 'xyz' }) self.assertTrue(geocode_result.viewport().isNull()) self.assertEqual(geocode_result.description(), 'desc') self.assertEqual(geocode_result.group(), 'group') self.assertEqual(res2.displayString, 'res 2') geocode_result = filter.locatorResultToGeocoderResult(res2) self.assertEqual(geocode_result.identifier(), 'res 2') self.assertEqual(geocode_result.geometry().asWkt(), 'Point (13 14)') self.assertEqual(geocode_result.crs().authid(), 'EPSG:3857') self.assertEqual(geocode_result.additionalAttributes(), {'d': 456}) self.assertEqual(geocode_result.viewport(), QgsRectangle(1, 2, 3, 4)) self.assertFalse(geocode_result.description()) self.assertFalse(geocode_result.group())
class RenderWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setupUi() self.layer = None self.marker = Marker(self.canvas) def setupUi(self): gridLayout = QGridLayout(self) gridLayout.setContentsMargins(0, 0, 0, 0) self.canvas = QgsMapCanvas() self.canvas.setCanvasColor(QColor(255, 255, 255)) self.canvas.setStyleSheet("border: 0px;") settings = QSettings() self.canvas.enableAntiAliasing(settings.value("/qgis/enable_anti_aliasing", False, type=bool)) self.setMinimumSize(15, 15) # mouse action pan and zoom self.pan_zoom_tool = PanAndZoomPointTool(self) self.canvas.setMapTool(self.pan_zoom_tool) gridLayout.addWidget(self.canvas) def render_layer(self, layer): with block_signals_to(self): # set the CRS of the canvas view based on sampling layer sampling_crs = self.parent_view.sampling_layer.crs() self.canvas.setDestinationCrs(sampling_crs) # set the sampling over the layer to view self.canvas.setLayers([self.parent_view.sampling_layer, layer]) # set init extent from other view if any is activated else set layer extent from AcATaMa.gui.classification_dialog import ClassificationDialog others_view = [(view_widget.render_widget.canvas.extent(), view_widget.current_scale_factor) for view_widget in ClassificationDialog.view_widgets if not view_widget.render_widget.canvas.extent().isEmpty()] if others_view: extent, scale = others_view[0] extent.scale(1 / scale) self.set_extents_and_scalefactor(extent) elif ClassificationDialog.current_sample: ClassificationDialog.current_sample.fit_to( self.parent_view, ClassificationDialog.instance.radiusFitToSample.value()) self.canvas.refresh() self.layer = layer # show marker if ClassificationDialog.current_sample: self.marker.show(ClassificationDialog.current_sample) def set_extents_and_scalefactor(self, extent): with block_signals_to(self.canvas): self.canvas.setExtent(extent) self.canvas.zoomByFactor(self.parent_view.scaleFactor.value()) if self.marker.marker: self.marker.marker.updatePosition() def layer_style_editor(self): style_editor_dlg = StyleEditorDialog(self.layer, self.canvas, self.parent_view) if style_editor_dlg.exec_(): style_editor_dlg.apply()
def testMainAnnotationLayerRendered(self): """ test that main annotation layer is rendered above all other layers """ canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG: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") sym3 = QgsFillSymbol.createSimple({'color': '#b200b2'}) layer.renderer().setSymbol(sym3) 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('empty_canvas', 'empty_canvas', canvas)) # add polygon to layer f = QgsFeature() f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45))) self.assertTrue(layer.dataProvider().addFeatures([f])) # refresh canvas canvas.refresh() canvas.waitWhileRendering() # no annotation yet... self.assertFalse( self.canvasImageCheck('main_annotation_layer', 'main_annotation_layer', canvas, expect_fail=True)) annotation_layer = QgsProject.instance().mainAnnotationLayer() annotation_layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) annotation_geom = QgsGeometry.fromRect(QgsRectangle(12, 30, 18, 33)) annotation = QgsAnnotationPolygonItem( annotation_geom.constGet().clone()) sym3 = QgsFillSymbol.createSimple({ 'color': '#ff0000', 'outline_style': 'no' }) annotation.setSymbol(sym3) annotation_layer.addItem(annotation) # refresh canvas canvas.refresh() canvas.waitWhileRendering() # annotation must be rendered over other layers self.assertTrue( self.canvasImageCheck('main_annotation_layer', 'main_annotation_layer', canvas)) annotation_layer.clear()
def testSaveCanvasVariablesToProject(self): """ Ensure that temporary canvas atlas variables are not written to project """ c1 = QgsMapCanvas() c1.setObjectName('c1') c1.expressionContextScope().setVariable('atlas_featurenumber', 1111) c1.expressionContextScope().setVariable('atlas_pagename', 'bb') c1.expressionContextScope().setVariable('atlas_feature', QgsFeature(1)) c1.expressionContextScope().setVariable('atlas_featureid', 22) c1.expressionContextScope().setVariable( 'atlas_geometry', QgsGeometry.fromWkt('Point( 1 2 )')) c1.expressionContextScope().setVariable('vara', 1111) c1.expressionContextScope().setVariable('varb', 'bb') doc = QDomDocument("testdoc") elem = doc.createElement("qgis") doc.appendChild(elem) c1.writeProject(doc) c2 = QgsMapCanvas() c2.setObjectName('c1') c2.readProject(doc) self.assertCountEqual(c2.expressionContextScope().variableNames(), ['vara', 'varb']) self.assertEqual(c2.expressionContextScope().variable('vara'), 1111) self.assertEqual(c2.expressionContextScope().variable('varb'), 'bb')
def testLockedScale(self): """Test zoom/pan/center operations when scale lock is on""" c = QgsMapCanvas() dpr = c.mapSettings().devicePixelRatio() self.assertEqual(c.size().width(), 640) self.assertEqual(c.size().height(), 480) c.setExtent(QgsRectangle(5, 45, 9, 47)) self.assertEqual(round(c.scale() / 100000), 13 * dpr) c.zoomScale(2500000) c.setScaleLocked(True) self.assertEqual(round(c.magnificationFactor(), 1), 1) # Test setExtent c.setExtent(QgsRectangle(6, 45.5, 8, 46), True) self.assertEqual(round(c.scale()), 2500000) self.assertEqual(c.center().x(), 7.0) self.assertEqual(c.center().y(), 45.75) self.assertEqual(round(c.magnificationFactor()), 4 / dpr) # Test setCenter c.setCenter(QgsPointXY(6, 46)) self.assertEqual(c.center().x(), 6) self.assertEqual(c.center().y(), 46) self.assertEqual(round(c.scale()), 2500000) # Test zoom c.zoomByFactor(0.5, QgsPointXY(6.5, 46.5), False) self.assertEqual(c.center().x(), 6.5) self.assertEqual(c.center().y(), 46.5) self.assertTrue(c.magnificationFactor() > 7 / dpr) self.assertEqual(round(c.scale()), 2500000) # Test zoom with center # default zoom factor is 2, x and y are pixel coordinates, default size is 640x480 c.zoomWithCenter(300, 200, True) self.assertEqual(round(c.center().x(), 1), 6.5) self.assertEqual(round(c.center().y(), 1), 46.6) self.assertEqual(round(c.scale()), 2500000) self.assertTrue(c.magnificationFactor() > (14 / dpr) and c.magnificationFactor() < (16 / dpr)) # out ... c.zoomWithCenter(300, 200, False) self.assertEqual(round(c.center().x(), 1), 6.5) self.assertEqual(round(c.center().y(), 1), 46.6) self.assertEqual(round(c.scale()), 2500000) self.assertTrue(c.magnificationFactor() > 7 / dpr) # Test setExtent with different ratio c2 = QgsMapCanvas() c2.setExtent(QgsRectangle(5, 45, 9, 47)) c2.zoomScale(2500000) c2.setScaleLocked(True) c2.setExtent(QgsRectangle(3, 45, 11, 45.5), True) self.assertEqual(round(c2.scale()), 2500000) self.assertEqual(c2.center().x(), 7.0) self.assertEqual(c2.center().y(), 45.25) self.assertAlmostEqual(c2.magnificationFactor(), 1 / dpr, 0) # Restore original c2.setExtent(QgsRectangle(5, 45, 9, 47), True) self.assertEqual(round(c2.scale()), 2500000) self.assertEqual(c2.center().x(), 7.0) self.assertEqual(c2.center().y(), 46.0) self.assertAlmostEqual(c2.magnificationFactor(), 2 / dpr, 0) c2.setExtent(QgsRectangle(7, 46, 11, 46.5), True) self.assertEqual(round(c2.scale()), 2500000) self.assertEqual(c2.center().x(), 9.0) self.assertEqual(c2.center().y(), 46.25) self.assertAlmostEqual(c2.magnificationFactor(), 2 / dpr, 0) c2.setExtent(QgsRectangle(7, 46, 9, 46.5), True) self.assertEqual(round(c2.scale()), 2500000) self.assertEqual(c2.center().x(), 8.0) self.assertEqual(c2.center().y(), 46.25) self.assertAlmostEqual(c2.magnificationFactor(), 4 / dpr, 0)
def test_rendered_items(self): canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4326')) canvas.setFrameStyle(0) canvas.resize(600, 400) canvas.setCachingEnabled(True) self.assertEqual(canvas.width(), 600) self.assertEqual(canvas.height(), 400) layer = QgsAnnotationLayer( 'test', QgsAnnotationLayer.LayerOptions( QgsProject.instance().transformContext())) self.assertTrue(layer.isValid()) layer2 = QgsAnnotationLayer( 'test', QgsAnnotationLayer.LayerOptions( QgsProject.instance().transformContext())) self.assertTrue(layer2.isValid()) item = QgsAnnotationPolygonItem( QgsPolygon( QgsLineString([ QgsPoint(11.5, 13), QgsPoint(12, 13), QgsPoint(12, 13.5), QgsPoint(11.5, 13) ]))) item.setSymbol( QgsFillSymbol.createSimple({ 'color': '200,100,100', 'outline_color': 'black', 'outline_width': '2' })) item.setZIndex(1) i1_id = layer.addItem(item) item = QgsAnnotationLineItem( QgsLineString( [QgsPoint(11, 13), QgsPoint(12, 13), QgsPoint(12, 15)])) item.setZIndex(2) i2_id = layer.addItem(item) item = QgsAnnotationMarkerItem(QgsPoint(12, 13)) item.setZIndex(3) i3_id = layer2.addItem(item) layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) layer2.setCrs(QgsCoordinateReferenceSystem('EPSG:4326')) canvas.setLayers([layer, layer2]) canvas.setExtent(QgsRectangle(10, 10, 18, 18)) 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() results = canvas.renderedItemResults() self.assertCountEqual([i.itemId() for i in results.renderedItems()], [i1_id, i2_id, i3_id]) # turn off a layer -- the other layer will be rendered direct from the cached version canvas.setLayers([layer2]) while not canvas.isDrawing(): app.processEvents() canvas.waitWhileRendering() results = canvas.renderedItemResults() # only layer2 items should be present in results -- but these MUST be present while layer2 is visible in the canvas, # even though the most recent canvas redraw used a cached version of layer2 and didn't actually have to redraw the layer self.assertEqual([i.itemId() for i in results.renderedItems()], [i3_id]) # turn layer 1 back on canvas.setLayers([layer, layer2]) while not canvas.isDrawing(): app.processEvents() canvas.waitWhileRendering() results = canvas.renderedItemResults() # both layer1 and layer2 items should be present in results -- even though NEITHER of these layers were re-rendered, # and instead we used precached renders of both layers self.assertCountEqual([i.itemId() for i in results.renderedItems()], [i1_id, i2_id, i3_id])
def getQgisTestApp(): """ Start one QGis application to test agaist Input NIL Output handle to qgis app If QGis is already running the handle to that app will be returned """ global QGISAPP # pylint: disable=W0603 if QGISAPP is None: myGuiFlag = True # All test will run qgis in gui mode QGISAPP = QgsApplication(sys.argv, myGuiFlag) if 'QGIS_PREFIX_PATH' in os.environ: myPath = os.environ['QGIS_PREFIX_PATH'] myUseDefaultPathFlag = True QGISAPP.setPrefixPath(myPath, myUseDefaultPathFlag) if sys.platform.startswith('darwin'): # override resource paths, otherwise looks for Resources in app if 'QGIS_MAC_PKGDATA_DIR' in os.environ: myPkgPath = os.environ['QGIS_MAC_PKGDATA_DIR'] QGISAPP.setPkgDataPath(myPkgPath) if 'QGIS_MAC_SVG_DIR' in os.environ: mySVGPath = os.environ['QGIS_MAC_SVG_DIR'] mySVGPaths = QGISAPP.svgPaths() # doesn't get rid of incorrect path, just adds correct one mySVGPaths.prepend(mySVGPath) QGISAPP.setDefaultSvgPaths(mySVGPaths) QGISAPP.initQgis() s = QGISAPP.showSettings() print s global PARENT # pylint: disable=W0603 if PARENT is None: PARENT = QtGui.QWidget() global CANVAS # pylint: disable=W0603 if CANVAS is None: CANVAS = QgsMapCanvas(PARENT) CANVAS.resize(QtCore.QSize(400, 400)) global IFACE # pylint: disable=W0603 if IFACE is None: # QgisInterface is a stub implementation of the QGIS plugin interface IFACE = QgisInterface(CANVAS) return QGISAPP, CANVAS, IFACE, PARENT