class DistanceInputPanel(NumberInputPanel): """ Distance input panel for use outside the modeler - this input panel contains a label showing the distance unit. """ def __init__(self, param): super().__init__(param) self.label = QLabel('') label_margin = self.fontMetrics().width('X') self.layout().insertSpacing(1, label_margin / 2) self.layout().insertWidget(2, self.label) self.layout().insertSpacing(3, label_margin / 2) self.warning_label = QLabel() icon = QgsApplication.getThemeIcon('mIconWarning.svg') size = max(24, self.spnValue.height() * 0.5) self.warning_label.setPixmap(icon.pixmap(icon.actualSize(QSize(size, size)))) self.warning_label.setToolTip(self.tr('Distance is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results.')) self.layout().insertWidget(4, self.warning_label) self.layout().insertSpacing(5, label_margin) self.setUnits(QgsUnitTypes.DistanceUnknownUnit) def setUnits(self, units): self.label.setText(QgsUnitTypes.toString(units)) self.warning_label.setVisible(units == QgsUnitTypes.DistanceDegrees) def setUnitParameterValue(self, value): units = QgsUnitTypes.DistanceUnknownUnit layer = self.getLayerFromValue(value) if isinstance(layer, QgsMapLayer): units = layer.crs().mapUnits() elif isinstance(value, QgsCoordinateReferenceSystem): units = value.mapUnits() elif isinstance(value, str): crs = QgsCoordinateReferenceSystem(value) if crs.isValid(): units = crs.mapUnits() self.setUnits(units)
class DxfDialog(QDialog): def __init__(self, parent = None): super(DxfDialog, self).__init__(parent) self.setWindowTitle("Type geometrie") max_bouwlaag = 30 min_bouwlaag = -10 qlayout = QVBoxLayout(self) self.label1 = QLabel(self) self.label1.setText("Welke type geometrie wilt u importeren?") qlayout.addWidget(self.label1) self.inputGeometry = QComboBox(self) self.inputGeometry.addItems(['lijn', 'vlak']) qlayout.addWidget(self.inputGeometry) self.label2 = QLabel(self) self.label2.setText("Wilt u de polygoon importeren als Bouwlaag?") qlayout.addWidget(self.label2) self.checkBouwlaag = QCheckBox(self) qlayout.addWidget(self.checkBouwlaag) self.checkBouwlaag.stateChanged.connect(self.addBouwlaagQuestion) self.qComboA = QComboBox(self) for i in range(max_bouwlaag - min_bouwlaag + 1): if max_bouwlaag - i != 0: self.qComboA.addItem(str(max_bouwlaag - i)) if max_bouwlaag - i == 1: init_index = i self.qComboA.setCurrentIndex(init_index) self.qComboA.setFixedWidth(100) self.qComboA.setMaxVisibleItems(30) self.label3 = QLabel(self) self.label3.setText("Geef de bouwlaag op waarvoor u de polygoon wilt inlezen.") self.qComboA.setVisible(False) self.label3.setVisible(False) qlayout.addWidget(self.label3) qlayout.addWidget(self.qComboA) buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) qlayout.addWidget(buttons) def addBouwlaagQuestion(self): if self.qComboA.isVisible(): self.qComboA.setVisible(False) self.label3.setVisible(False) else: self.qComboA.setVisible(True) self.label3.setVisible(True) @staticmethod def getGeometryType(parent = None): dialog = DxfDialog(parent) result = dialog.exec_() return (dialog.checkBouwlaag.isChecked(), dialog.inputGeometry.currentText(), dialog.qComboA.currentText(), result == QDialog.Accepted)
class DistanceInputPanel(NumberInputPanel): """ Distance input panel for use outside the modeler - this input panel contains a label showing the distance unit. """ def __init__(self, param): super().__init__(param) self.label = QLabel('') self.units_combo = QComboBox() self.base_units = QgsUnitTypes.DistanceUnknownUnit for u in (QgsUnitTypes.DistanceMeters, QgsUnitTypes.DistanceKilometers, QgsUnitTypes.DistanceFeet, QgsUnitTypes.DistanceMiles, QgsUnitTypes.DistanceYards): self.units_combo.addItem(QgsUnitTypes.toString(u), u) label_margin = self.fontMetrics().width('X') self.layout().insertSpacing(1, label_margin / 2) self.layout().insertWidget(2, self.label) self.layout().insertWidget(3, self.units_combo) self.layout().insertSpacing(4, label_margin / 2) self.warning_label = QLabel() icon = QgsApplication.getThemeIcon('mIconWarning.svg') size = max(24, self.spnValue.height() * 0.5) self.warning_label.setPixmap(icon.pixmap(icon.actualSize(QSize(size, size)))) self.warning_label.setToolTip(self.tr('Distance is in geographic degrees. Consider reprojecting to a projected local coordinate system for accurate results.')) self.layout().insertWidget(4, self.warning_label) self.layout().insertSpacing(5, label_margin) self.setUnits(QgsUnitTypes.DistanceUnknownUnit) def setUnits(self, units): self.label.setText(QgsUnitTypes.toString(units)) if QgsUnitTypes.unitType(units) != QgsUnitTypes.Standard: self.units_combo.hide() self.label.show() else: self.units_combo.setCurrentIndex(self.units_combo.findData(units)) self.units_combo.show() self.label.hide() self.warning_label.setVisible(units == QgsUnitTypes.DistanceDegrees) self.base_units = units def setUnitParameterValue(self, value): units = QgsUnitTypes.DistanceUnknownUnit layer = self.getLayerFromValue(value) if isinstance(layer, QgsMapLayer): units = layer.crs().mapUnits() elif isinstance(value, QgsCoordinateReferenceSystem): units = value.mapUnits() elif isinstance(value, str): crs = QgsCoordinateReferenceSystem(value) if crs.isValid(): units = crs.mapUnits() self.setUnits(units) def getValue(self): val = super().getValue() if isinstance(val, float) and self.units_combo.isVisible(): display_unit = self.units_combo.currentData() return val * QgsUnitTypes.fromUnitToUnitFactor(display_unit, self.base_units) return val def setValue(self, value): try: self.spnValue.setValue(float(value)) except: return
def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Help) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.displayName()) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText( self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameterDefinitions(): if param.isDestination( ) or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue desc = param.description() if isinstance(param, QgsProcessingParameterExtent): desc += self.tr('(xmin, xmax, ymin, ymax)') if isinstance(param, QgsProcessingParameterPoint): desc += self.tr('(x, y)') if param.flags() & QgsProcessingParameterDefinition.FlagOptional: desc += self.tr(' [optional]') label = QLabel(desc) self.labels[param.name()] = label wrapper = WidgetWrapperFactory.create_wrapper(param, self) self.wrappers[param.name()] = wrapper widget = wrapper.widget if widget is not None: self.valueItems[param.name()] = widget tooltip = param.description() label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.flags( ) & QgsProcessingParameterDefinition.FlagAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name()] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for dest in self._alg.destinationParameterDefinitions(): if dest.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if isinstance(dest, (QgsProcessingParameterRasterDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterFileDestination, QgsProcessingParameterFolderDestination)): label = QLabel(dest.description()) item = QgsFilterLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[dest.name()] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.displayName()) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QgsScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.verticalLayout2.addWidget(self.scrollArea) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) self.buttonBox.helpRequested.connect(self.openHelp) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values()))
class CommanderWindow(QDialog): def __init__(self, parent, canvas): self.canvas = canvas QDialog.__init__(self, parent, Qt.FramelessWindowHint) self.commands = imp.load_source('commands', self.commandsFile()) self.initGui() def commandsFolder(self): folder = unicode(os.path.join(userFolder(), 'commander')) mkdir(folder) return os.path.abspath(folder) def commandsFile(self): f = os.path.join(self.commandsFolder(), 'commands.py') if not os.path.exists(f): out = open(f, 'w') out.write('from qgis.core import *\n') out.write('import processing\n\n') out.write('def removeall():\n') out.write('\tmapreg = QgsMapLayerRegistry.instance()\n') out.write('\tmapreg.removeAllMapLayers()\n\n') out.write('def load(*args):\n') out.write('\tprocessing.load(args[0])\n') out.close() return f def algsListHasChanged(self): self.fillCombo() def initGui(self): self.combo = ExtendedComboBox() self.fillCombo() self.combo.setEditable(True) self.label = QLabel('Enter command:') self.errorLabel = QLabel('Enter command:') self.vlayout = QVBoxLayout() self.vlayout.setSpacing(2) self.vlayout.setMargin(0) self.vlayout.addSpacerItem( QSpacerItem(0, OFFSET, QSizePolicy.Maximum, QSizePolicy.Expanding)) self.hlayout = QHBoxLayout() self.hlayout.addWidget(self.label) self.vlayout.addLayout(self.hlayout) self.hlayout2 = QHBoxLayout() self.hlayout2.addWidget(self.combo) self.vlayout.addLayout(self.hlayout2) self.vlayout.addSpacerItem( QSpacerItem(0, OFFSET, QSizePolicy.Maximum, QSizePolicy.Expanding)) self.setLayout(self.vlayout) self.combo.lineEdit().returnPressed.connect(self.run) self.prepareGui() def fillCombo(self): self.combo.clear() # Add algorithms for algs in algList.algs.values(): for alg in algs: self.combo.addItem('Processing algorithm: ' + alg) # Add functions for command in dir(self.commands): if isinstance(self.commands.__dict__.get(command), types.FunctionType): self.combo.addItem('Command: ' + command) # Add menu entries menuActions = [] actions = iface.mainWindow().menuBar().actions() for action in actions: menuActions.extend(self.getActions(action)) for action in menuActions: self.combo.addItem('Menu action: ' + unicode(action.text())) def prepareGui(self): self.combo.setEditText('') self.combo.setMaximumSize( QSize(self.canvas.rect().width() - 2 * OFFSET, ITEMHEIGHT)) self.combo.view().setStyleSheet('min-height: 150px') self.combo.setFocus(Qt.OtherFocusReason) self.label.setMaximumSize(self.combo.maximumSize()) self.label.setVisible(False) self.adjustSize() pt = self.canvas.rect().topLeft() absolutePt = self.canvas.mapToGlobal(pt) self.move(absolutePt) self.resize(self.canvas.rect().width(), HEIGHT) self.setStyleSheet('CommanderWindow {background-color: #e7f5fe; \ border: 1px solid #b9cfe4;}') def getActions(self, action): menuActions = [] menu = action.menu() if menu is None: menuActions.append(action) return menuActions else: actions = menu.actions() for subaction in actions: if subaction.menu() is not None: menuActions.extend(self.getActions(subaction)) elif not subaction.isSeparator(): menuActions.append(subaction) return menuActions def run(self): s = unicode(self.combo.currentText()) if s.startswith('Processing algorithm: '): algName = s[len('Processing algorithm: '):] alg = Processing.getAlgorithmFromFullName(algName) if alg is not None: self.close() self.runAlgorithm(alg) elif s.startswith("Command: "): command = s[len("Command: "):] try: self.runCommand(command) self.close() except Exception as e: self.label.setVisible(True) self.label.setText('Error:' + unicode(e)) elif s.startswith('Menu action: '): actionName = s[len('Menu action: '):] menuActions = [] actions = iface.mainWindow().menuBar().actions() for action in actions: menuActions.extend(self.getActions(action)) for action in menuActions: if action.text() == actionName: self.close() action.trigger() return else: try: self.runCommand(s) self.close() except Exception as e: self.label.setVisible(True) self.label.setText('Error:' + unicode(e)) def runCommand(self, command): tokens = command.split(' ') if len(tokens) == 1: method = self.commands.__dict__.get(command) if method is not None: method() else: raise Exception('Wrong command') else: method = self.commands.__dict__.get(tokens[0]) if method is not None: method(*tokens[1:]) else: raise Exception('Wrong command') def runAlgorithm(self, alg): alg = alg.getCopy() message = alg.checkBeforeOpeningParametersDialog() if message: dlg = MessageDialog() dlg.setTitle(self.tr('Missing dependency')) dlg.setMessage(message) dlg.exec_() return dlg = alg.getCustomParametersDialog() if not dlg: dlg = AlgorithmDialog(alg) canvas = iface.mapCanvas() prevMapTool = canvas.mapTool() dlg.show() dlg.exec_() if canvas.mapTool() != prevMapTool: try: canvas.mapTool().reset() except: pass canvas.setMapTool(prevMapTool)
def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok | QDialogButtonBox.Help) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.displayName()) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameterDefinitions(): if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText(self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameterDefinitions(): if param.isDestination() or param.flags() & QgsProcessingParameterDefinition.FlagHidden: continue desc = param.description() if isinstance(param, QgsProcessingParameterExtent): desc += self.tr('(xmin, xmax, ymin, ymax)') if isinstance(param, QgsProcessingParameterPoint): desc += self.tr('(x, y)') if param.flags() & QgsProcessingParameterDefinition.FlagOptional: desc += self.tr(' [optional]') label = QLabel(desc) self.labels[param.name()] = label wrapper = WidgetWrapperFactory.create_wrapper(param, self) self.wrappers[param.name()] = wrapper widget = wrapper.widget if widget is not None: self.valueItems[param.name()] = widget tooltip = param.description() label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.flags() & QgsProcessingParameterDefinition.FlagAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name()] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for dest in self._alg.destinationParameterDefinitions(): if dest.flags() & QgsProcessingParameterDefinition.FlagHidden: continue if isinstance(dest, (QgsProcessingParameterRasterDestination, QgsProcessingParameterVectorDestination, QgsProcessingParameterFeatureSink, QgsProcessingParameterFileDestination, QgsProcessingParameterFolderDestination)): label = QLabel(dest.description()) item = QgsFilterLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[dest.name()] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.displayName()) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QgsScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.verticalLayout2.addWidget(self.scrollArea) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) self.buttonBox.helpRequested.connect(self.openHelp) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values()))
def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) tooltips = self._alg.getParameterDescriptions() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.displayName()) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameters: if param.isAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText( self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameters: if param.hidden: continue desc = param.description if isinstance(param, ParameterExtent): desc += self.tr('(xmin, xmax, ymin, ymax)') if isinstance(param, ParameterPoint): desc += self.tr('(x, y)') if param.optional: desc += self.tr(' [optional]') label = QLabel(desc) self.labels[param.name] = label wrapper = param.wrapper(self) self.wrappers[param.name] = wrapper widget = wrapper.widget if widget is not None: self.valueItems[param.name] = widget if param.name in list(tooltips.keys()): tooltip = tooltips[param.name] else: tooltip = param.description label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.isAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for output in self._alg.outputs: if output.hidden: continue if isinstance(output, (OutputRaster, OutputVector, OutputTable, OutputHTML, OutputFile, OutputDirectory)): label = QLabel(output.description + '<' + output.__class__.__name__ + '>') item = QLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[output.name] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.displayName()) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.tabWidget = QTabWidget() self.tabWidget.setMinimumWidth(300) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QgsScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.tabWidget.addTab(self.scrollArea, self.tr('Parameters')) self.txtHelp = QTextBrowser() html = None isText, algHelp = self._alg.help() if algHelp is not None: algHelp = algHelp if isText else QUrl(algHelp) try: if isText: self.txtHelp.setHtml(algHelp) else: html = self.tr( '<p>Downloading algorithm help... Please wait.</p>') self.txtHelp.setHtml(html) self.tabWidget.addTab(self.txtHelp, 'Help') self.reply = QgsNetworkAccessManager.instance().get( QNetworkRequest(algHelp)) self.reply.finished.connect(self.requestFinished) except: pass self.verticalLayout2.addWidget(self.tabWidget) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values()))
class PlanetOrderItemTypeWidget(QWidget): selectionChanged = pyqtSignal() def __init__(self, item_type, images): super().__init__() self.thumbnails = [] self.item_type = item_type self.images = images layout = QGridLayout() layout.setMargin(0) self.labelThumbnail = QLabel() pixmap = QPixmap(PLACEHOLDER_THUMB, "SVG") thumb = pixmap.scaled(96, 96, Qt.KeepAspectRatio, Qt.SmoothTransformation) self.labelThumbnail.setPixmap(thumb) self.labelThumbnail.setFixedSize(96, 96) layout.addWidget(self.labelThumbnail, 0, 0, 3, 1) for image in images: url = f"{image['_links']['thumbnail']}?api_key={PlanetClient.getInstance().api_key()}" download_thumbnail(url, self) labelName = IconLabel( f"<b>{PlanetClient.getInstance().item_types_names()[self.item_type]}</b>", SATELLITE_ICON, ) labelNumItems = IconLabel(f"{len(images)} items", NITEMS_ICON) layout.addWidget(labelNumItems, 0, 1) layout.addWidget(labelName, 1, 1) self.btnDetails = QPushButton() self.btnDetails.setFlat(True) self.btnDetails.setIcon(EXPAND_MORE_ICON) self.btnDetails.clicked.connect(self._btnDetailsClicked) layout.addWidget(self.btnDetails, 0, 2) self.widgetDetails = QWidget() layout.addWidget(self.widgetDetails, 3, 0, 1, 3) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout.addWidget(line, 4, 0, 1, 3) self.setLayout(layout) self.widgetDetails.hide() self.updateGeometry() self.populate_details() def populate_details(self): self.bundleWidgets = [] client = PlanetClient.getInstance() permissions = [img[PERMISSIONS] for img in self.images] item_bundles = client.bundles_for_item_type(self.item_type, permissions=permissions) default = default_bundles.get(self.item_type, "") def _center(obj): hlayout = QHBoxLayout() hlayout.addStretch() hlayout.addWidget(obj) hlayout.addStretch() return hlayout layout = QVBoxLayout() layout.setMargin(0) layout.setSpacing(20) layout.addLayout(_center(QLabel("<b>RECTIFIED ASSETS</b>"))) gridlayout = QGridLayout() gridlayout.setMargin(0) widgets = {} i = 0 for bundleid, bundle in item_bundles.items(): if bundle["rectification"] == "orthorectified": name = bundle["name"] description = bundle["description"] udm = bundle.get("auxiliaryFiles", "").lower().startswith("udm2") assets = bundle["assets"][self.item_type] can_harmonize = ("ortho_analytic_4b_sr" in assets or "ortho_analytic_8b_sr" in assets) w = PlanetOrderBundleWidget(bundleid, name, description, udm, can_harmonize, True) gridlayout.addWidget(w, i // 2, i % 2) w.setSelected(False) widgets[bundleid] = w w.selectionChanged.connect( partial(self._bundle_selection_changed, w)) self.bundleWidgets.append(w) i += 1 selected = False for defaultid in default: for bundleid, w in widgets.items(): if defaultid == bundleid: w.setSelected(True) selected = True break if selected: break layout.addLayout(gridlayout) self.labelUnrectified = QLabel("<b>UNRECTIFIED ASSETS</b>") layout.addLayout(_center(self.labelUnrectified)) self.widgetUnrectified = QWidget() gridlayoutUnrect = QGridLayout() gridlayoutUnrect.setMargin(0) i = 0 for bundleid, bundle in item_bundles.items(): if bundle["rectification"] != "orthorectified": name = bundle["name"] description = bundle["description"] udm = bundle.get("auxiliaryFiles", "").lower().startswith("udm2") assets = bundle["assets"][self.item_type] can_harmonize = ("ortho_analytic_4b_sr" in assets or "ortho_analytic_8b_sr" in assets) w = PlanetOrderBundleWidget(bundleid, name, description, udm, can_harmonize, False) gridlayoutUnrect.addWidget(w, i // 2, i % 2) w.selectionChanged.connect( partial(self._bundle_selection_changed, w)) self.bundleWidgets.append(w) i += 1 self.widgetUnrectified.setLayout(gridlayoutUnrect) layout.addWidget(self.widgetUnrectified) self.labelMore = QLabel('<a href="#">+ Show More</a>') self.labelMore.setOpenExternalLinks(False) self.labelMore.setTextInteractionFlags(Qt.LinksAccessibleByMouse) self.labelMore.linkActivated.connect(self._showMoreClicked) layout.addLayout(_center(self.labelMore)) self.widgetUnrectified.hide() self.labelUnrectified.hide() self.widgetDetails.setLayout(layout) def _bundle_selection_changed(self, widget): for w in self.bundleWidgets: if widget != w: w.setSelected(False, False) self.selectionChanged.emit() def _showMoreClicked(self): visible = self.widgetUnrectified.isVisible() self.widgetUnrectified.setVisible(not visible) self.labelUnrectified.setVisible(not visible) if visible: self.labelMore.setText('<a href="#">+ Show More</a>') else: self.labelMore.setText('<a href="#">- Show Less</a>') def expand(self): self.widgetDetails.show() self.btnDetails.setIcon(EXPAND_LESS_ICON) self.updateGeometry() def _btnDetailsClicked(self): if self.widgetDetails.isVisible(): self.widgetDetails.hide() self.btnDetails.setIcon(EXPAND_MORE_ICON) else: self.widgetDetails.show() self.btnDetails.setIcon(EXPAND_LESS_ICON) self.updateGeometry() def bundles(self): bundles = [] for w in self.bundleWidgets: if w.selected(): bundle = {} bundle["id"] = w.bundleid bundle["name"] = w.name bundle["filetype"] = w.filetype() bundle["udm"] = w.udm bundle["rectified"] = w.rectified bundle["canharmonize"] = w.can_harmonize bundles.append(bundle) return bundles def set_thumbnail(self, img): thumbnail = QPixmap(img) self.thumbnails.append( thumbnail.scaled(96, 96, Qt.KeepAspectRatio, Qt.SmoothTransformation)) if len(self.images) == len(self.thumbnails): bboxes = [img[GEOMETRY] for img in self.images] pixmap = createCompoundThumbnail(bboxes, self.thumbnails) thumb = pixmap.scaled(128, 128, Qt.KeepAspectRatio, Qt.SmoothTransformation) self.labelThumbnail.setPixmap(thumb)
class CommanderWindow(QDialog): def __init__(self, parent, canvas): self.canvas = canvas QDialog.__init__(self, parent, Qt.FramelessWindowHint) self.commands = imp.load_source('commands', self.commandsFile()) self.initGui() def commandsFolder(self): folder = str(os.path.join(userFolder(), 'commander')) mkdir(folder) return os.path.abspath(folder) def commandsFile(self): f = os.path.join(self.commandsFolder(), 'commands.py') if not os.path.exists(f): with open(f, 'w') as out: out.write('from qgis.core import *\n') out.write('import processing\n\n') out.write('def removeall():\n') out.write('\tmapreg = QgsProject.instance()\n') out.write('\tmapreg.removeAllMapLayers()\n\n') out.write('def load(*args):\n') out.write('\tprocessing.load(args[0])\n') return f def algsListHasChanged(self): self.fillCombo() def initGui(self): self.combo = ExtendedComboBox() self.fillCombo() self.combo.setEditable(True) self.label = QLabel('Enter command:') self.errorLabel = QLabel('Enter command:') self.vlayout = QVBoxLayout() self.vlayout.setSpacing(2) self.vlayout.setMargin(0) self.vlayout.addSpacerItem(QSpacerItem(0, OFFSET, QSizePolicy.Maximum, QSizePolicy.Expanding)) self.hlayout = QHBoxLayout() self.hlayout.addWidget(self.label) self.vlayout.addLayout(self.hlayout) self.hlayout2 = QHBoxLayout() self.hlayout2.addWidget(self.combo) self.vlayout.addLayout(self.hlayout2) self.vlayout.addSpacerItem(QSpacerItem(0, OFFSET, QSizePolicy.Maximum, QSizePolicy.Expanding)) self.setLayout(self.vlayout) self.combo.lineEdit().returnPressed.connect(self.run) self.prepareGui() def fillCombo(self): self.combo.clear() # Add algorithms for provider in list(algList.algs.values()): for alg in provider: self.combo.addItem('Processing algorithm: ' + alg) # Add functions for command in dir(self.commands): if isinstance(self.commands.__dict__.get(command), types.FunctionType): self.combo.addItem('Command: ' + command) # Add menu entries menuActions = [] actions = iface.mainWindow().menuBar().actions() for action in actions: menuActions.extend(self.getActions(action)) for action in menuActions: self.combo.addItem('Menu action: ' + str(action.text())) def prepareGui(self): self.combo.setEditText('') self.combo.setMaximumSize(QSize(self.canvas.rect().width() - 2 * OFFSET, ITEMHEIGHT)) self.combo.view().setStyleSheet('min-height: 150px') self.combo.setFocus(Qt.OtherFocusReason) self.label.setMaximumSize(self.combo.maximumSize()) self.label.setVisible(False) self.adjustSize() pt = self.canvas.rect().topLeft() absolutePt = self.canvas.mapToGlobal(pt) self.move(absolutePt) self.resize(self.canvas.rect().width(), HEIGHT) self.setStyleSheet('CommanderWindow {background-color: #e7f5fe; \ border: 1px solid #b9cfe4;}') def getActions(self, action): menuActions = [] menu = action.menu() if menu is None: menuActions.append(action) return menuActions else: actions = menu.actions() for subaction in actions: if subaction.menu() is not None: menuActions.extend(self.getActions(subaction)) elif not subaction.isSeparator(): menuActions.append(subaction) return menuActions def run(self): s = str(self.combo.currentText()) if s.startswith('Processing algorithm: '): algName = s[len('Processing algorithm: '):] alg = algList.getAlgorithm(algName) if alg is not None: self.close() self.runAlgorithm(alg) elif s.startswith("Command: "): command = s[len("Command: "):] try: self.runCommand(command) self.close() except Exception as e: self.label.setVisible(True) self.label.setText('Error:' + str(e)) elif s.startswith('Menu action: '): actionName = s[len('Menu action: '):] menuActions = [] actions = iface.mainWindow().menuBar().actions() for action in actions: menuActions.extend(self.getActions(action)) for action in menuActions: if action.text() == actionName: self.close() action.trigger() return else: try: self.runCommand(s) self.close() except Exception as e: self.label.setVisible(True) self.label.setText('Error:' + str(e)) def runCommand(self, command): tokens = command.split(' ') if len(tokens) == 1: method = self.commands.__dict__.get(command) if method is not None: method() else: raise Exception('Wrong command') else: method = self.commands.__dict__.get(tokens[0]) if method is not None: method(*tokens[1:]) else: raise Exception('Wrong command') def runAlgorithm(self, alg): alg = alg.getCopy() message = alg.checkBeforeOpeningParametersDialog() if message: dlg = MessageDialog() dlg.setTitle(self.tr('Missing dependency')) dlg.setMessage(message) dlg.exec_() return dlg = alg.getCustomParametersDialog() if not dlg: dlg = AlgorithmDialog(alg) canvas = iface.mapCanvas() prevMapTool = canvas.mapTool() dlg.show() dlg.exec_() if canvas.mapTool() != prevMapTool: try: canvas.mapTool().reset() except: pass canvas.setMapTool(prevMapTool)
def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.wrappers = {} self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) tooltips = self._alg.getParameterDescriptions() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.verticalLayout.addWidget(self.bar) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.name) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameters: if param.isAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText(self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameters: if param.hidden: continue desc = param.description if isinstance(param, ParameterExtent): desc += self.tr('(xmin, xmax, ymin, ymax)') if isinstance(param, ParameterPoint): desc += self.tr('(x, y)') if param.optional: desc += self.tr(' [optional]') label = QLabel(desc) self.labels[param.name] = label wrapper = param.wrapper(self) self.wrappers[param.name] = wrapper widget = wrapper.widget if widget: self.valueItems[param.name] = widget if param.name in list(tooltips.keys()): tooltip = tooltips[param.name] else: tooltip = param.description label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.isAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for output in self._alg.outputs: if output.hidden: continue if isinstance(output, (OutputRaster, OutputVector, OutputTable, OutputHTML, OutputFile, OutputDirectory)): label = QLabel(output.description + '<' + output.__class__.__name__ + '>') item = QLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[output.name] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setPreviousValues() self.setWindowTitle(self._alg.name) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.tabWidget = QTabWidget() self.tabWidget.setMinimumWidth(300) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.tabWidget.addTab(self.scrollArea, self.tr('Parameters')) self.txtHelp = QTextBrowser() html = None isText, algHelp = self._alg.help() if algHelp is not None: algHelp = algHelp if isText else QUrl(algHelp) try: if isText: self.txtHelp.setHtml(algHelp) else: html = self.tr('<p>Downloading algorithm help... Please wait.</p>') self.txtHelp.setHtml(html) self.tabWidget.addTab(self.txtHelp, 'Help') self.reply = QgsNetworkAccessManager.instance().get(QNetworkRequest(algHelp)) self.reply.finished.connect(self.requestFinished) except: pass self.verticalLayout2.addWidget(self.tabWidget) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) QMetaObject.connectSlotsByName(self) for wrapper in list(self.wrappers.values()): wrapper.postInitialize(list(self.wrappers.values()))
class HistoryDiffViewerWidget(QWidget): def __init__(self, dialog, server, user, repo, graph, layer=None, initialSimplify=False): self.graph = graph self.dialog = dialog self.server = server self.user = user self.repo = repo self.layer = layer self.afterLayer = None self.beforeLayer = None self.extraLayers = [] # layers for the "Map" tab QWidget.__init__(self, iface.mainWindow()) self.setWindowFlags(Qt.Window) self.simplifyLog = initialSimplify self.initGui() self.tabWidget.setVisible(False) self.setLabelText("Select a commit to show its content") self.label.setVisible(False) if self.graph.commits: self.history.setCurrentItem(self.history.topLevelItem(0)) self.itemChanged(self.history.topLevelItem(0), None) self.history.currentItemChanged.connect(self.itemChanged) def setShowPopup(self, show): self.history.showPopup = show def initGui(self): layout = QVBoxLayout() splitter = QSplitter() splitter.setOrientation(Qt.Vertical) self.history = HistoryTree(self.dialog) self.history.updateContent(self.server, self.user, self.repo, self.graph, self.layer) self.historyWithFilter = HistoryTreeWrapper(self.history) if self.simplifyLog: self.historyWithFilter.simplify(True) splitter.addWidget(self.historyWithFilter) self.tabWidget = QTabWidget() self.tabCanvas = QWidget() tabLayout = QVBoxLayout() tabLayout.setMargin(0) self.canvas = QgsMapCanvas(self.tabCanvas) self.canvas.setCanvasColor(Qt.white) self.panTool = QgsMapToolPan(self.canvas) self.canvas.setMapTool(self.panTool) tabLayout.addWidget(self.canvas) self.labelNoChanges = QLabel("This commit doesn't change any geometry") self.labelNoChanges.setAlignment(Qt.AlignCenter) self.labelNoChanges.setVisible(False) tabLayout.addWidget(self.labelNoChanges) self.tabCanvas.setLayout(tabLayout) self.summaryTextBrowser = QTextBrowser() self.summaryTextBrowser.setOpenLinks(False) self.summaryTextBrowser.anchorClicked.connect(self.summaryTextBrowserAnchorClicked) self.tabWidget.addTab(self.summaryTextBrowser, "Commit Summary") self.tabWidget.addTab(self.tabCanvas, "Map") tabLayout = QVBoxLayout() tabLayout.setMargin(0) self.tabDiffViewer = QWidget() self.diffViewer = DiffViewerWidget({}) tabLayout.addWidget(self.diffViewer) self.tabDiffViewer.setLayout(tabLayout) self.tabWidget.addTab(self.tabDiffViewer, "Attributes") splitter.addWidget(self.tabWidget) self.label = QTextBrowser() self.label.setVisible(False) splitter.addWidget(self.label) self.tabWidget.setCurrentWidget(self.tabDiffViewer) layout.addWidget(splitter) self.setLayout(layout) exportDiffButton = QPushButton("Export this commit's DIFF for all layers") exportDiffButton.clicked.connect(self.exportDiffAllLayers) layout.addWidget(exportDiffButton) self.label.setMinimumHeight(self.tabWidget.height()) self.setWindowTitle("Repository history") def summaryTextBrowserAnchorClicked(self,url): url = url.url() #convert to string item = self.history.currentItem() if item is None: return commitid = item.commit.commitid cmd,layerName = url.split(".",1) if cmd == "addLive": execute(lambda: self.history.exportVersion(layerName,commitid,True)) elif cmd == "addGeoPKG": self.history.exportVersion(layerName,commitid,False) elif cmd == "exportDiff": execute(lambda: self.history.exportDiff(item, None,layer=layerName)) def exportDiffAllLayers(self): item = self.history.currentItem() if item is not None: self.history.exportDiff(item, None) def setLabelText(self,text): self.label.setHtml("<br><br><br><center><b>{}</b></center>".format(text)) def setContent(self, server, user, repo, graph, layer = None): self.server = server self.user = user self.repo = repo self.layer = layer self.graph = graph self.historyWithFilter.updateContent(server, user, repo, graph, layer) if self.history.graph.commits: self.history.setCurrentItem(self.history.topLevelItem(0)) def itemChanged(self, current, previous, THRESHOLD = 1500): item = self.history.currentItem() if item is not None: commit = self.graph.getById(item.ref) if commit is None: self.tabWidget.setVisible(False) self.setLabelText("Select a commit to show its content") self.label.setVisible(True) return commit2 = commit.commitid + "~1" if not item.commit.hasParents(): commit2 = "0000000000000000" total,details = self.server.diffSummary(self.user, self.repo, commit2,commit.commitid) tooLargeDiff = total > THRESHOLD if tooLargeDiff: html = "<br><br><center><b><font size=+3>Commit <font size=-0.1><tt>{}</tt></font> DIFF is too large to be shown</b></font><br>".format(commit.commitid[:8]) else: html = "<br><br><center><b><font size=+3>Commit <font size=-0.1><tt>{}</tt></font> Summary</b></font><br>".format(commit.commitid[:8]) html += "<table>" html += "<tr><Td style='padding:5px'><b>Layer Name</b></td><td style='padding:5px'><b>Additions</b></td><td style='padding:5px'><b>Deletions</b></td><td style='padding:5px'><b>Modifications</b></td><td></td><td></td><td></td></tr>" for detail in details.values(): html += "<tr><td style='padding:5px'>{}</td><td style='padding:5px'><center>{:,}</center></td><td style='padding:5px'><center>{:,}</center></td><td style='padding:5px'><center>{:,}</center></td><td style='padding:5px'>{}</td><td style='padding:5px'>{}</td><td style='padding:5px'>{}</td></tr>".format( detail["path"], int(detail["featuresAdded"]), int(detail["featuresRemoved"]),int(detail["featuresChanged"]), "<a href='addLive.{}'>Add Live</a>".format(detail["path"]), "<a href='addGeoPKG.{}'>Add GeoPKG</a>".format(detail["path"]), "<a href='exportDiff.{}'>Export Diff</a>".format(detail["path"]) ) html += "<tr></tr>" html += "<tr><td colspan=4>There is a total of {:,} features changed</td></tr>".format(total) html += "</table>" # html += "<br><br>There is a total of {:,} features changed".format(total) self.summaryTextBrowser.setHtml(html) self.label.setVisible(False) self.tabWidget.setVisible(True) self.tabWidget.setTabEnabled(1,not tooLargeDiff) self.tabWidget.setTabEnabled(2,not tooLargeDiff) if not tooLargeDiff: self.setDiffContent(commit, commit2) else: self.tabWidget.setVisible(False) self.setLabelText("Select a commit to show its content") self.label.setVisible(True) def setDiffContent(self, commit, commit2): if self.layer is None: layers = set(self.server.layers(self.user, self.repo, commit.commitid)) layers2 = set(self.server.layers(self.user, self.repo, commit2)) layers = layers.union(layers2) else: layers = [self.layer] diffs = {layer: execute(lambda: self.server.diff(self.user, self.repo, layer, commit.commitid, commit2)) for layer in layers} diffs = {key:value for (key,value) in diffs.items() if len(value) !=0} layers = [l for l in diffs.keys()] self.diffViewer.setChanges(diffs) self.canvas.setLayers([]) self.removeMapLayers() extent = QgsRectangle() for layer in layers: if not diffs[layer]: continue beforeLayer, afterLayer = execute(lambda: self._getLayers(diffs[layer])) if afterLayer is not None: resourcesPath = os.path.join(os.path.dirname(__file__), os.pardir, "resources") oldStylePath = os.path.join(resourcesPath, "{}_before.qml".format( QgsWkbTypes.geometryDisplayString(beforeLayer.geometryType()))) newStylePath = os.path.join(resourcesPath, "{}_after.qml".format( QgsWkbTypes.geometryDisplayString(afterLayer.geometryType()))) beforeLayer.loadNamedStyle(oldStylePath) afterLayer.loadNamedStyle(newStylePath) QgsProject.instance().addMapLayer(beforeLayer, False) QgsProject.instance().addMapLayer(afterLayer, False) extent.combineExtentWith(beforeLayer.extent()) extent.combineExtentWith(afterLayer.extent()) self.extraLayers.append(beforeLayer) self.extraLayers.append(afterLayer) # make extent a bit bit (10%) bigger # this gives some margin around the dataset (not cut-off at edges) if not extent.isEmpty(): widthDelta = extent.width() * 0.05 heightDelta = extent.height() * 0.05 extent = QgsRectangle(extent.xMinimum() - widthDelta, extent.yMinimum() - heightDelta, extent.xMaximum() + widthDelta, extent.yMaximum() + heightDelta) layers = self.extraLayers hasChanges = False for layer in layers: if layer is not None and layer.featureCount() > 0: hasChanges = True break self.canvas.setLayers(layers) self.canvas.setExtent(extent) self.canvas.refresh() self.canvas.setVisible(hasChanges) self.labelNoChanges.setVisible(not hasChanges) def _getLayers(self, changes): ADDED, MODIFIED, REMOVED, = 0, 1, 2 def _feature(g, changeType): feat = QgsFeature() if g is not None: feat.setGeometry(g) feat.setAttributes([changeType]) return feat if changes: f = changes[0] new = f["new"] old = f["old"] reference = new or old geomtype = QgsWkbTypes.displayString(reference.geometry().wkbType()) oldLayer = loadLayerNoCrsDialog(geomtype + "?crs=epsg:4326&field=geogig.changeType:integer", "old", "memory") newLayer = loadLayerNoCrsDialog(geomtype + "?crs=epsg:4326&field=geogig.changeType:integer", "new", "memory") oldFeatures = [] newFeatures = [] for f in changes: new = f["new"] old = f["old"] newGeom = new.geometry() if new is not None else None oldGeom = old.geometry() if old is not None else None if oldGeom is None: feature = _feature(newGeom, ADDED) newFeatures.append(feature) elif newGeom is None: feature = _feature(oldGeom, REMOVED) oldFeatures.append(feature) elif oldGeom.asWkt() != newGeom.asWkt(): feature = _feature(oldGeom, MODIFIED) oldFeatures.append(feature) feature = _feature(newGeom, MODIFIED) newFeatures.append(feature) else: feature = _feature(newGeom, MODIFIED) newFeatures.append(feature) oldLayer.dataProvider().addFeatures(oldFeatures) newLayer.dataProvider().addFeatures(newFeatures) else: oldLayer = None newLayer = None return oldLayer, newLayer def removeMapLayers(self): for layer in self.extraLayers: if layer is not None: QgsProject.instance().removeMapLayer(layer.id()) self.extraLayers = []
def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) tooltips = self._alg.getParameterDescriptions() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.name) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameters: if param.isAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText( self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameters: if param.hidden: continue desc = param.description if isinstance(param, ParameterExtent): desc += self.tr('(xmin, xmax, ymin, ymax)') if isinstance(param, ParameterPoint): desc += self.tr('(x, y)') label = QLabel(desc) self.labels[param.name] = label widget = self.getWidgetFromParameter(param) self.valueItems[param.name] = widget if param.name in tooltips.keys(): tooltip = tooltips[param.name] else: tooltip = param.description label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.isAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for output in self._alg.outputs: if output.hidden: continue if isinstance(output, (OutputRaster, OutputVector, OutputTable, OutputHTML, OutputFile, OutputDirectory)): label = QLabel(output.description + '<' + output.__class__.__name__ + '>') item = QLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[output.name] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setLayout(self.verticalLayout) self.setPreviousValues() self.setWindowTitle(self._alg.name) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.tabWidget = QTabWidget() self.tabWidget.setMinimumWidth(300) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.tabWidget.addTab(self.scrollArea, self.tr('Parameters')) self.webView = QWebView() html = None url = None isText, help = self._alg.help() if help is not None: if isText: html = help else: url = QUrl(help) else: html = self.tr('<h2>Sorry, no help is available for this ' 'algorithm.</h2>') try: if html: self.webView.setHtml(html) elif url: self.webView.load(url) except: self.webView.setHtml( self.tr('<h2>Could not open help file :-( </h2>')) self.tabWidget.addTab(self.webView, 'Help') self.verticalLayout2.addWidget(self.tabWidget) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) QMetaObject.connectSlotsByName(self)
def setupUi(self): self.labels = {} self.widgets = {} self.checkBoxes = {} self.showAdvanced = False self.valueItems = {} self.dependentItems = {} self.resize(650, 450) self.buttonBox = QDialogButtonBox() self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) tooltips = self._alg.getParameterDescriptions() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.verticalLayout = QVBoxLayout() self.verticalLayout.setSpacing(5) self.verticalLayout.setMargin(20) hLayout = QHBoxLayout() hLayout.setSpacing(5) hLayout.setMargin(0) descriptionLabel = QLabel(self.tr("Description")) self.descriptionBox = QLineEdit() self.descriptionBox.setText(self._alg.name) hLayout.addWidget(descriptionLabel) hLayout.addWidget(self.descriptionBox) self.verticalLayout.addLayout(hLayout) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) self.verticalLayout.addWidget(line) for param in self._alg.parameters: if param.isAdvanced: self.advancedButton = QPushButton() self.advancedButton.setText(self.tr('Show advanced parameters')) self.advancedButton.clicked.connect( self.showAdvancedParametersClicked) advancedButtonHLayout = QHBoxLayout() advancedButtonHLayout.addWidget(self.advancedButton) advancedButtonHLayout.addStretch() self.verticalLayout.addLayout(advancedButtonHLayout) break for param in self._alg.parameters: if param.hidden: continue desc = param.description if isinstance(param, ParameterExtent): desc += self.tr('(xmin, xmax, ymin, ymax)') if isinstance(param, ParameterPoint): desc += self.tr('(x, y)') label = QLabel(desc) self.labels[param.name] = label widget = self.getWidgetFromParameter(param) self.valueItems[param.name] = widget if param.name in tooltips.keys(): tooltip = tooltips[param.name] else: tooltip = param.description label.setToolTip(tooltip) widget.setToolTip(tooltip) if param.isAdvanced: label.setVisible(self.showAdvanced) widget.setVisible(self.showAdvanced) self.widgets[param.name] = widget self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(widget) for output in self._alg.outputs: if output.hidden: continue if isinstance(output, (OutputRaster, OutputVector, OutputTable, OutputHTML, OutputFile, OutputDirectory)): label = QLabel(output.description + '<' + output.__class__.__name__ + '>') item = QLineEdit() if hasattr(item, 'setPlaceholderText'): item.setPlaceholderText(ModelerParametersDialog.ENTER_NAME) self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(item) self.valueItems[output.name] = item label = QLabel(' ') self.verticalLayout.addWidget(label) label = QLabel(self.tr('Parent algorithms')) self.dependenciesPanel = self.getDependenciesPanel() self.verticalLayout.addWidget(label) self.verticalLayout.addWidget(self.dependenciesPanel) self.verticalLayout.addStretch(1000) self.setLayout(self.verticalLayout) self.setPreviousValues() self.setWindowTitle(self._alg.name) self.verticalLayout2 = QVBoxLayout() self.verticalLayout2.setSpacing(2) self.verticalLayout2.setMargin(0) self.tabWidget = QTabWidget() self.tabWidget.setMinimumWidth(300) self.paramPanel = QWidget() self.paramPanel.setLayout(self.verticalLayout) self.scrollArea = QScrollArea() self.scrollArea.setWidget(self.paramPanel) self.scrollArea.setWidgetResizable(True) self.tabWidget.addTab(self.scrollArea, self.tr('Parameters')) self.webView = QWebView() html = None url = None isText, help = self._alg.help() if help is not None: if isText: html = help else: url = QUrl(help) else: html = self.tr('<h2>Sorry, no help is available for this ' 'algorithm.</h2>') try: if html: self.webView.setHtml(html) elif url: self.webView.load(url) except: self.webView.setHtml(self.tr('<h2>Could not open help file :-( </h2>')) self.tabWidget.addTab(self.webView, 'Help') self.verticalLayout2.addWidget(self.tabWidget) self.verticalLayout2.addWidget(self.buttonBox) self.setLayout(self.verticalLayout2) self.buttonBox.accepted.connect(self.okPressed) self.buttonBox.rejected.connect(self.cancelPressed) QMetaObject.connectSlotsByName(self)
class QvFormSimbMapificacio(QvFormBaseMapificacio): def __init__(self, llegenda, capa=None, amplada=500): super().__init__(llegenda, amplada) if capa is None: self.capa = llegenda.currentLayer() else: self.capa = capa self.info = None if not self.iniParams(): return self.setWindowTitle('Modificar mapa simbòlic ' + self.renderParams.tipusMapa.lower()) self.layout = QVBoxLayout() self.layout.setSpacing(14) self.setLayout(self.layout) self.color = QComboBox(self) self.color.setEditable(False) self.comboColors(self.color) self.contorn = QComboBox(self) self.contorn.setEditable(False) self.comboColors(self.contorn, mv.MAP_CONTORNS) self.color.currentIndexChanged.connect(self.canviaContorns) self.metode = QComboBox(self) self.metode.setEditable(False) if self.renderParams.numCategories > 1: self.metode.addItems(mv.MAP_METODES_MODIF.keys()) else: self.metode.addItems(mv.MAP_METODES.keys()) self.metode.setCurrentIndex(-1) self.metode.currentIndexChanged.connect(self.canviaMetode) self.nomIntervals = QLabel("Nombre d'intervals:", self) self.intervals = QSpinBox(self) self.intervals.setMinimum(min(2, self.renderParams.numCategories)) self.intervals.setMaximum(max(mv.MAP_MAX_CATEGORIES, self.renderParams.numCategories)) self.intervals.setSingleStep(1) self.intervals.setValue(4) if self.renderParams.tipusMapa == 'Àrees': self.intervals.setSuffix(" (depèn del mètode)") # self.intervals.valueChanged.connect(self.deselectValue) self.nomTamany = QLabel("Tamany cercle:", self) self.tamany = QSpinBox(self) self.tamany.setMinimum(1) self.tamany.setMaximum(12) self.tamany.setSingleStep(1) self.tamany.setValue(4) self.bInfo = QPushButton('Info') self.bInfo.clicked.connect(self.veureInfo) self.buttons = QDialogButtonBox() self.buttons.addButton(QDialogButtonBox.Ok) self.buttons.accepted.connect(self.accept) self.buttons.addButton(QDialogButtonBox.Cancel) self.buttons.rejected.connect(self.cancel) self.buttons.addButton(self.bInfo, QDialogButtonBox.ResetRole) self.gSimb = QGroupBox('Simbologia del mapa') self.lSimb = QFormLayout() self.lSimb.setSpacing(14) self.gSimb.setLayout(self.lSimb) self.lSimb.addRow('Color base:', self.color) self.lSimb.addRow('Color contorn:', self.contorn) if self.renderParams.tipusMapa == 'Àrees': self.lSimb.addRow('Mètode classificació:', self.metode) self.lSimb.addRow(self.nomIntervals, self.intervals) self.nomTamany.setVisible(False) self.tamany.setVisible(False) else: self.metode.setVisible(False) self.nomIntervals.setVisible(False) self.intervals.setVisible(False) self.lSimb.addRow(self.nomTamany, self.tamany) self.wInterval = [] for w in self.iniIntervals(): self.wInterval.append(w) self.gInter = self.grupIntervals() self.layout.addWidget(self.gSimb) if self.renderParams.tipusMapa == 'Àrees': self.layout.addWidget(self.gInter) self.layout.addWidget(self.buttons) self.valorsInicials() def iniParams(self): self.info = QgsExpressionContextUtils.layerScope(self.capa).variable(mv.MAP_ID) if self.info is None: return False self.renderParams = QvMapRendererParams.fromLayer(self.capa) if self.renderParams.msgError == '': self.custom = (self.renderParams.modeCategories == 'Personalitzat') return True else: self.msgInfo("No s'han pogut recuperar els paràmetres del mapa simbòlic\n\n" + "Error: " + self.renderParams.msgError) return False @pyqtSlot() def veureInfo(self): if self.info is not None: box = QMessageBox(self) box.setWindowTitle('Info del mapa simbòlic') txt = '<table width="600">' params = self.info.split('\n') for param in params: linea = param.strip() if linea.endswith(':'): linea += ' ---' txt += '<tr><td><nobr>· {}</nobr></td></tr>'.format(linea) txt += '</table>' box.setTextFormat(Qt.RichText) box.setText("Paràmetres d'agregació de dades:") box.setInformativeText(txt) box.setIcon(QMessageBox.Information) box.setStandardButtons(QMessageBox.Ok) box.setDefaultButton(QMessageBox.Ok) box.exec() def valorsInicials(self): self.color.setCurrentIndex(self.color.findText(self.renderParams.colorBase)) self.contorn.setCurrentIndex(self.contorn.findText(self.renderParams.colorContorn)) self.intervals.setValue(self.renderParams.numCategories) self.tamany.setValue(self.renderParams.increase) self.metode.setCurrentIndex(self.metode.findText(self.renderParams.modeCategories)) def valorsFinals(self): self.renderParams.colorBase = self.color.currentText() self.renderParams.colorContorn = self.contorn.currentText() self.renderParams.modeCategories = self.metode.currentText() self.renderParams.numCategories = self.intervals.value() self.renderParams.increase = self.tamany.value() if self.custom: self.renderParams.rangsCategories = [] for fila in self.wInterval: self.renderParams.rangsCategories.append((fila[0].text(), fila[2].text())) self.renderParams.numCategories = len(self.renderParams.rangsCategories) def txtRang(self, num): if type(num) == str: return num return QvApp().locale.toString(num, 'f', self.renderParams.numDecimals) def iniFilaInterval(self, iniValor, finValor): maxSizeB = 27 # validator = QDoubleValidator(self) # validator.setLocale(QvApp().locale) # validator.setNotation(QDoubleValidator.StandardNotation) # validator.setDecimals(5) validator = QvVerifNumero(self) ini = QLineEdit(self) ini.setText(self.txtRang(iniValor)) ini.setValidator(validator) sep = QLabel('-', self) fin = QLineEdit(self) fin.setText(self.txtRang(finValor)) fin.setValidator(validator) fin.editingFinished.connect(self.nouTall) add = QPushButton('+', self) add.setMaximumSize(maxSizeB, maxSizeB) add.setToolTip('Afegeix nou interval') add.clicked.connect(self.afegirFila) add.setFocusPolicy(Qt.NoFocus) rem = QPushButton('-', self) rem.setMaximumSize(maxSizeB, maxSizeB) rem.setToolTip('Esborra interval') rem.clicked.connect(self.eliminarFila) rem.setFocusPolicy(Qt.NoFocus) return [ini, sep, fin, add, rem] def iniIntervals(self): for cat in self.renderParams.rangsCategories: yield self.iniFilaInterval(cat.lowerValue(), cat.upperValue()) def grupIntervals(self): group = QGroupBox('Definició dels intervals') # group.setMinimumWidth(400) layout = QGridLayout() layout.setSpacing(10) # layout.setColumnMinimumWidth(4, 40) numFilas = len(self.wInterval) for fila, widgets in enumerate(self.wInterval): for col, w in enumerate(widgets): # Primera fila: solo + if fila == 0 and col > 3: w.setVisible(False) # # Ultima fila: no hay + ni - elif fila > 0 and fila == (numFilas - 1) and col > 2: w.setVisible(False) else: w.setVisible(True) # Valor inicial deshabilitado (menos 1a fila) if col == 0 and fila != 0: w.setDisabled(True) w.setProperty('Fila', fila) layout.addWidget(w, fila, col) group.setLayout(layout) return group def actGrupIntervals(self): self.intervals.setValue(len(self.wInterval)) self.setUpdatesEnabled(False) self.buttons.setVisible(False) self.gInter.setVisible(False) self.layout.removeWidget(self.buttons) self.layout.removeWidget(self.gInter) self.gInter.deleteLater() self.gInter = self.grupIntervals() self.layout.addWidget(self.gInter) self.layout.addWidget(self.buttons) self.gInter.setVisible(True) self.buttons.setVisible(True) self.adjustSize() self.setUpdatesEnabled(True) @pyqtSlot() def afegirFila(self): masFilas = (len(self.wInterval) < mv.MAP_MAX_CATEGORIES) if masFilas: f = self.sender().property('Fila') + 1 ini = self.wInterval[f][0] val = ini.text() ini.setText('') w = self.iniFilaInterval(val, '') self.wInterval.insert(f, w) self.actGrupIntervals() self.wInterval[f][2].setFocus() else: self.msgInfo("S'ha arribat al màxim d'intervals possibles") @pyqtSlot() def eliminarFila(self): f = self.sender().property('Fila') ini = self.wInterval[f][0] val = ini.text() del self.wInterval[f] ini = self.wInterval[f][0] ini.setText(val) self.actGrupIntervals() @pyqtSlot() def nouTall(self): w = self.sender() if w.isModified(): f = w.property('Fila') + 1 if f < len(self.wInterval): ini = self.wInterval[f][0] ini.setText(w.text()) w.setModified(False) @pyqtSlot() def canviaMetode(self): self.custom = (self.metode.currentText() == 'Personalitzat') if self.custom: self.intervals.setValue(len(self.wInterval)) self.intervals.setEnabled(not self.custom) self.gInter.setVisible(self.custom) self.adjustSize() # print('GSIMB -> Ancho:', self.gSimb.size().width(), '- Alto:', self.gSimb.size().height()) # print('FORM -> Ancho:', self.size().width(), '- Alto:', self.size().height()) @pyqtSlot() def canviaContorns(self): self.comboColors(self.contorn, mv.MAP_CONTORNS, mv.MAP_COLORS[self.color.currentText()], True) def leSelectFocus(self, wLineEdit): lon = len(wLineEdit.text()) if lon > 0: wLineEdit.setSelection(0, lon) wLineEdit.setFocus() def validaNum(self, wLineEdit): val = wLineEdit.validator() if val is None: return True res = val.validate(wLineEdit.text(), 0) if res[0] == QValidator.Acceptable: return True else: self.msgInfo("Cal introduir un nombre enter o amb decimals.\n" "Es farà servir la coma (,) per separar els decimals.\n" "I pels milers, opcionalment, el punt (.)") self.leSelectFocus(wLineEdit) return False def validaInterval(self, wLineEdit1, wLineEdit2): num1, _ = QvApp().locale.toFloat(wLineEdit1.text()) num2, _ = QvApp().locale.toFloat(wLineEdit2.text()) if num2 >= num1: return True else: self.msgInfo("El segon nombre de l'interval ha de ser major que el primer") self.leSelectFocus(wLineEdit2) return False def validaFila(self, fila): wLineEdit1 = fila[0] wLineEdit2 = fila[2] if not self.validaNum(wLineEdit1): return False if not self.validaNum(wLineEdit2): return False if not self.validaInterval(wLineEdit1, wLineEdit2): return False return True def valida(self): if self.custom: for fila in self.wInterval: if not self.validaFila(fila): return False return True def procesa(self): self.valorsFinals() try: mapRenderer = self.renderParams.mapRenderer(self.llegenda) if self.custom: self.renderParams.colorBase = mv.MAP_COLORS[self.renderParams.colorBase] self.renderParams.colorContorn = mv.MAP_CONTORNS[self.renderParams.colorContorn] self.renderer = mapRenderer.customRender(self.capa) else: self.renderParams.colorBase = mv.MAP_COLORS[self.renderParams.colorBase] if self.renderParams.colorContorn == 'Base': self.renderParams.colorContorn = self.renderParams.colorBase else: self.renderParams.colorContorn = mv.MAP_CONTORNS[self.renderParams.colorContorn] self.renderParams.modeCategories = \ mv.MAP_METODES_MODIF[self.renderParams.modeCategories] self.renderer = mapRenderer.calcRender(self.capa) if self.renderer is None: return "No s'ha pogut elaborar el mapa simbòlic" err = self.llegenda.saveStyleToGeoPackage(self.capa, mv.MAP_ID) if err != '': return "Hi ha hagut problemes al desar la simbologia\n({})".format(err) # self.llegenda.modificacioProjecte('mapModified') return '' except Exception as e: return "No s'ha pogut modificar el mapa simbòlic\n({})".format(str(e))