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))