def create_rule_tab(self, rule_id, rule): """ Create a tab in the Rule tab. The tab is added to the left. Args: (int) rule_id: The id of the rule. (list) rule: A list of tuples containing the attributes of the rule. """ tab = QWidget() layout = QVBoxLayout(tab) tab.setLayout(layout) label_field = QLabel(tab) label_field.setGeometry(10, 10, 300, 21) label_field.setText("Measure variable: {}".format(rule[4])) label_field = QLabel(tab) label_field.setGeometry(10, 40, 300, 21) operator = "" if rule[1] == ">": operator = "Bottom up" elif rule[1] == "<": operator = "Top down" label_field.setText("Operator: {}".format(operator)) label_field = QLabel(tab) label_field.setGeometry(310, 10, 300, 21) structure_type = "" if rule[3] == "v2_culvert": structure_type = "culvert" elif rule[3] == "v2_pumpstation": structure_type = "pumpstation" elif rule[3] == "v2_orifice": structure_type = "orifice" elif rule[3] == "v2_weir": structure_type = "weir" label_field.setText("Structure type: {}".format(structure_type)) label_field = QLabel(tab) label_field.setGeometry(310, 40, 300, 21) label_field.setText("Structure id: {}".format(rule[2])) label_field = QLabel(tab) label_field.setGeometry(310, 70, 741, 21) label_field.setText("Action type: {}".format(rule[5])) table_control_table = QTableWidget(tab) table_control_table.setGeometry(10, 100, 741, 181) table_control_table.insertColumn(0) table_control_table.setHorizontalHeaderItem( 0, QTableWidgetItem("measuring_value")) table_control_table.insertColumn(1) table_control_table.setHorizontalHeaderItem( 1, QTableWidgetItem("action_value")) table_control_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.dockwidget_controlled_structures.table_control_view = table_control_table self.dockwidget_controlled_structures.tab_table_control_view.insertTab( 0, tab, "Table control: {}".format(str(rule_id)))
class AddRasterDialog(QDialog): def __init__(self): super(QDialog, self).__init__() self.resize(410, 200) self.setWindowTitle('Add Raster Layer Dialog') self.label = QLabel(self) self.label.setGeometry(QtCore.QRect(20, 20, 300, 100)) self.label.setAlignment(QtCore.Qt.AlignCenter) self.label.setText( 'The requested ressource is a raster layer. \n' 'Depending on it\'s size\', downloading \nand importing it to QGIS' 'may \ntake while. You can also consider to only import the\n' 'layer as a WMS if you only need to view it') self.cancelbutton = QPushButton(self) self.cancelbutton.setText('Cancel') self.cancelbutton.setGeometry(QtCore.QRect(20, 150, 125, 30)) self.wmsbutton = QPushButton(self) self.wmsbutton.setText('Add as WMS Layer') self.wmsbutton.setGeometry(QtCore.QRect(150, 150, 125, 30)) self.rasterbutton = QPushButton(self) self.rasterbutton.setText('Add as Raster Layer') self.rasterbutton.setGeometry(QtCore.QRect(280, 150, 125, 30)) # we reconfigure the already existing slot self.done() (inherited # from QDialog to emit different ints - self.done() is called by # exec_()) self.cancelbutton.clicked.connect(lambda: self.done(0)) self.wmsbutton.clicked.connect(lambda: self.done(1)) self.rasterbutton.clicked.connect(lambda: self.done(2))
class Ui_GHydraulicsResultDialog(object): def setupUi(self, GHydraulicsResultDialog): GHydraulicsResultDialog.setObjectName(_fromUtf8("GHydraulicsResultDialog")) GHydraulicsResultDialog.resize(640, 480) self.buttonBox = QDialogButtonBox(GHydraulicsResultDialog) self.buttonBox.setGeometry(QtCore.QRect(10, 440, 620, 32)) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok) self.buttonBox.setObjectName(_fromUtf8("buttonBox")) self.tabWidget = QTabWidget(GHydraulicsResultDialog) self.tabWidget.setGeometry(QtCore.QRect(10, 10, 620, 390)) self.tabWidget.setObjectName(_fromUtf8("tabWidget")) self.tabOutput = QWidget() self.tabOutput.setObjectName(_fromUtf8("tabOutput")) self.textOutput = QTextBrowser(self.tabOutput) self.textOutput.setGeometry(QtCore.QRect(10, 10, 600, 340)) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.textOutput.sizePolicy().hasHeightForWidth()) self.textOutput.setSizePolicy(sizePolicy) self.textOutput.setObjectName(_fromUtf8("textOutput")) self.tabWidget.addTab(self.tabOutput, _fromUtf8("")) self.tabReport = QWidget() self.tabReport.setObjectName(_fromUtf8("tabReport")) self.textReport = QTextBrowser(self.tabReport) self.textReport.setGeometry(QtCore.QRect(10, 10, 600, 340)) sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.textReport.sizePolicy().hasHeightForWidth()) self.textReport.setSizePolicy(sizePolicy) self.textReport.setObjectName(_fromUtf8("textReport")) self.tabWidget.addTab(self.tabReport, _fromUtf8("")) self.comboStep = QComboBox(GHydraulicsResultDialog) self.comboStep.setGeometry(QtCore.QRect(150, 410, 80, 27)) self.comboStep.setObjectName(_fromUtf8("comboStep")) self.labelStep = QLabel(GHydraulicsResultDialog) self.labelStep.setGeometry(QtCore.QRect(10, 415, 120, 17)) self.labelStep.setObjectName(_fromUtf8("labelStep")) self.retranslateUi(GHydraulicsResultDialog) self.tabWidget.setCurrentIndex(0) #QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), GHydraulicsResultDialog.accept) self.buttonBox.accepted.connect(GHydraulicsResultDialog.accept) #QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), GHydraulicsResultDialog.reject) self.buttonBox.rejected.connect(GHydraulicsResultDialog.reject) QtCore.QMetaObject.connectSlotsByName(GHydraulicsResultDialog) def retranslateUi(self, GHydraulicsResultDialog): GHydraulicsResultDialog.setWindowTitle(_translate("GHydraulicsResultDialog", "EPANET Results", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tabOutput), _translate("GHydraulicsResultDialog", "EPANET Output", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tabReport), _translate("GHydraulicsResultDialog", "Report", None)) self.labelStep.setText(_translate("GHydraulicsResultDialog", "Load time step", None))
def add_table_control_tab_dockwidget(self): """ Create a tab for the measure group within the Rule group tab in the dockwidget. """ tab = QWidget() layout = QVBoxLayout(tab) tab.setLayout(layout) label_field = QLabel(tab) label_field.setGeometry(10, 10, 300, 21) label_field.setText("Measure variable: {}".format( self.combobox_input_rule_measure_variable.currentText())) label_field = QLabel(tab) label_field.setGeometry(10, 40, 300, 21) label_field.setText("Operator: {}".format( self.combobox_input_rule_operator.currentText())) label_field = QLabel(tab) label_field.setGeometry(310, 10, 300, 21) label_field.setText("Structure type: {}".format( self.combobox_input_structure_table.currentText())) label_field = QLabel(tab) label_field.setGeometry(310, 40, 300, 21) label_field.setText("Structure id: {}".format( self.combobox_input_structure_id.currentText())) label_field = QLabel(tab) label_field.setGeometry(310, 70, 741, 21) label_field.setText("Action type: {}".format( self.combobox_input_action_type.currentText())) table_control_table = QTableWidget(tab) table_control_table.setGeometry(10, 100, 741, 181) table_control_table.insertColumn(0) table_control_table.setHorizontalHeaderItem( 0, QTableWidgetItem("measuring_value")) table_control_table.insertColumn(1) table_control_table.setHorizontalHeaderItem( 1, QTableWidgetItem("action_value")) table_control_table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.dockwidget_controlled_structures.table_control_view = table_control_table self.dockwidget_controlled_structures.tab_table_control_view.insertTab( 0, tab, "Table control: {}".format(str(self.table_control_id)))
def create_control_group_tab(self, control_group_id, control_group): """ Create a tab in the Control group tab. The tab is added to the left. Args: (int) control_group_id: The id of the control group. (list) control_group: A list of tuples containing the attributes of the control group. """ tab = QWidget() layout = QVBoxLayout(tab) tab.setLayout(layout) label_field = QLabel(tab) label_field.setGeometry(10, 10, 741, 21) label_field.setText("Name: {}".format(control_group[2])) label_field = QLabel(tab) label_field.setGeometry(10, 40, 741, 51) label_field.setText("Description: {}".format(control_group[0])) control_group_table = QTableWidget(tab) control_group_table.setGeometry(10, 100, 741, 181) control_group_table.insertColumn(0) control_group_table.setHorizontalHeaderItem( 0, QTableWidgetItem("measuring_group_id")) control_group_table.insertColumn(1) control_group_table.setHorizontalHeaderItem( 1, QTableWidgetItem("rule_type")) control_group_table.insertColumn(2) control_group_table.setHorizontalHeaderItem( 2, QTableWidgetItem("rule_id")) control_group_table.insertColumn(3) control_group_table.setHorizontalHeaderItem( 3, QTableWidgetItem("structure")) control_group_table.insertColumn(4) control_group_table.setHorizontalHeaderItem( 4, QTableWidgetItem("structure_id")) control_group_table.setEditTriggers(QAbstractItemView.NoEditTriggers) # Add the tab to the tabwidget in the dockwidget self.dockwidget_controlled_structures.control_group_table = control_group_table self.dockwidget_controlled_structures.tab_control_view.insertTab( 0, tab, "Control group: {}".format(str(control_group_id)))
def add_control_group_tab_dockwidget(self): """ Create a tab for the measure group within the Measure group tab in the dockwidget. """ tab = QWidget() layout = QVBoxLayout(tab) tab.setLayout(layout) label_field = QLabel(tab) label_field.setGeometry(10, 10, 741, 21) label_field.setText("Name: {}".format( self.lineedit_input_control_name.text())) label_field = QLabel(tab) label_field.setGeometry(10, 40, 741, 51) label_field.setText("Description: {}".format( self.textedit_input_control_description.toPlainText())) control_group_table = QTableWidget(tab) control_group_table.setGeometry(10, 100, 741, 181) control_group_table.insertColumn(0) control_group_table.setHorizontalHeaderItem( 0, QTableWidgetItem("measuring_group_id")) control_group_table.insertColumn(1) control_group_table.setHorizontalHeaderItem( 1, QTableWidgetItem("rule_type")) control_group_table.insertColumn(2) control_group_table.setHorizontalHeaderItem( 2, QTableWidgetItem("rule_id")) control_group_table.insertColumn(3) control_group_table.setHorizontalHeaderItem( 3, QTableWidgetItem("structure")) control_group_table.insertColumn(4) control_group_table.setHorizontalHeaderItem( 4, QTableWidgetItem("structure_id")) control_group_table.setEditTriggers(QAbstractItemView.NoEditTriggers) # Add the tab to the tabwidget in the dockwidget self.dockwidget_controlled_structures.control_group_table = control_group_table self.dockwidget_controlled_structures.tab_control_view.insertTab( 0, tab, "Control group: {}".format(str(self.control_group_id)))
class ConnectDialog(QDialog): def __init__(self): QDialog.__init__(self) self.resize(400, 300) self.setWindowTitle('Connection Dialog') self.label = QLabel(self) self.label.setGeometry(QRect(140, 150, 81, 20)) self.label.setText('username') self.label2 = QLabel(self) self.label2.setGeometry(QRect(140, 190, 81, 20)) self.label2.setText('password') self.label3 = QLabel(self) self.label3.setGeometry(QRect(40, 32, 151, 20)) self.label3.setText('Name of the Shogun Client') self.label4 = QLabel(self) self.label4.setGeometry(QRect(40, 82, 151, 20)) self.label4.setText('URL:') self.nameIn = QLineEdit(self) self.nameIn.setGeometry(QRect(200, 30, 180, 27)) self.nameIn.setText('Default Shogun Client') self.urlIn = QLineEdit(self) self.urlIn.setGeometry(QRect(122, 80, 258, 27)) self.urlIn.setPlaceholderText('i. e.: http(s)://.../shogun2-webapp') self.userIn = QLineEdit(self) self.userIn.setGeometry(QRect(230, 150, 150, 27)) self.passwordIn = QLineEdit(self) self.passwordIn.setGeometry(QRect(230, 190, 150, 27)) self.passwordIn.setEchoMode(QLineEdit.Password) self.okButton = QPushButton(self) self.okButton.setGeometry(QRect(270, 240, 85, 27)) self.okButton.setText('OK') self.cancelButton = QPushButton(self) self.cancelButton.setGeometry(QRect(180, 240, 85, 27)) self.cancelButton.setText('Cancel')
class CoordinateCaptureDockWidget(QDockWidget): closingPlugin = pyqtSignal() def __init__(self, parent=None): """Constructor.""" super(CoordinateCaptureDockWidget, self).__init__(parent) self.setWindowTitle(self.tr("Coordinate Capture")) self.setGeometry(0, 0, 300, 228) self.dockWidgetContents = QWidget(self) self.setWidget(self.dockWidgetContents) self.gridLayout = QGridLayout() self.dockWidgetContents.setLayout(self.gridLayout) self.dockWidgetContents.layout().setColumnMinimumWidth(0, 36) self.userCrsToolButton = QToolButton(self.dockWidgetContents) self.userCrsToolButton.setIcon( QIcon(":/plugins/coordinate_capture/mIconProjectionEnabled.svg")) self.userCrsToolButton.setToolTip( self.tr("Click to select the CRS to use for coordinate display")) self.userCrsLabel = QLabel(self.dockWidgetContents) self.userCrsLabel.setPixmap( QPixmap(":/plugins/coordinate_capture/transformed.svg")) self.userCrsLabel.setGeometry(self.userCrsToolButton.geometry()) self.userCrsEdit = QLineEdit(self.dockWidgetContents) self.userCrsEdit.setReadOnly(True) self.userCrsEdit.setToolTip( self.tr("Coordinate in your selected CRS (lat,lon or east,north)")) self.copyUserCrsCoordinatesAction = self.userCrsEdit.addAction( QIcon(":/plugins/coordinate_capture/mActionEditCopy.svg"), QLineEdit.TrailingPosition) self.copyUserCrsCoordinatesAction.triggered.connect( self.copyUserCrsCoordinates) self.canvasCrsEdit = QLineEdit(self.dockWidgetContents) self.canvasCrsEdit.setReadOnly(True) self.canvasCrsEdit.setToolTip( self. tr("Coordinate in map canvas coordinate reference system (lat,lon or east,north)" )) self.copyCanvasCrsCoordinatesAction = self.canvasCrsEdit.addAction( QIcon(":/plugins/coordinate_capture/mActionEditCopy.svg"), QLineEdit.TrailingPosition) self.copyCanvasCrsCoordinatesAction.triggered.connect( self.copyCanvasCrsCoordinates) self.trackMouseButton = QToolButton(self.dockWidgetContents) self.trackMouseButton.setIcon( QIcon(":/plugins/coordinate_capture/tracking.svg")) self.trackMouseButton.setCheckable(True) self.trackMouseButton.setToolTip( self.tr( "Click to enable mouse tracking. Click the canvas to stop")) self.trackMouseButton.setChecked(False) # Create the action for tool self.captureButton = QPushButton(self.dockWidgetContents) self.captureButton.setText(self.tr("Start Capture")) self.captureButton.setToolTip( self.tr("Click to enable coordinate capture")) self.captureButton.setIcon( QIcon(":/plugins/coordinate_capture/coordinate_capture.png")) self.captureButton.setWhatsThis( self. tr("Click on the map to view coordinates and capture to clipboard." )) # // Set the icons # setCurrentTheme(QString()); self.dockWidgetContents.layout().addWidget(self.userCrsToolButton, 0, 0) self.dockWidgetContents.layout().addWidget(self.userCrsEdit, 0, 1) self.dockWidgetContents.layout().addWidget(self.userCrsLabel, 1, 0) self.dockWidgetContents.layout().addWidget(self.canvasCrsEdit, 1, 1) self.dockWidgetContents.layout().addWidget(self.trackMouseButton, 2, 0) self.dockWidgetContents.layout().addWidget(self.captureButton, 2, 1) def copyUserCrsCoordinates(self): self.userCrsEdit.selectAll() self.userCrsEdit.copy() def copyCanvasCrsCoordinates(self): self.canvasCrsEdit.selectAll() self.canvasCrsEdit.copy() def closeEvent(self, event): self.closingPlugin.emit() event.accept()
class Ui_form1(object): def setupUi(self, form1): form1.setObjectName(_fromUtf8("form1")) form1.resize(400, 253) form1.setFocusPolicy(QtCore.Qt.TabFocus) form1.setWindowTitle(_fromUtf8("Kuwahara filter")) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/qgis.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) form1.setWindowIcon(icon) self.label = QLabel(form1) self.label.setGeometry(QtCore.QRect(21, 10, 111, 20)) font = QtGui.QFont() font.setPointSize(10) self.label.setFont(font) self.label.setToolTip(_fromUtf8("")) self.label.setObjectName(_fromUtf8("label")) self.outputb = QPushButton(form1) self.outputb.setGeometry(QtCore.QRect(320, 47, 31, 23)) self.outputb.setObjectName(_fromUtf8("outputb")) self.label_2 = QLabel(form1) self.label_2.setGeometry(QtCore.QRect(22, 49, 101, 20)) font = QtGui.QFont() font.setPointSize(10) self.label_2.setFont(font) self.label_2.setToolTip(_fromUtf8("")) self.label_2.setObjectName(_fromUtf8("label_2")) self.progressBar = QProgressBar(form1) self.progressBar.setGeometry(QtCore.QRect(19, 220, 361, 23)) self.progressBar.setProperty(_fromUtf8("value"), 24) self.progressBar.setObjectName(_fromUtf8("progressBar")) self.label_3 = QLabel(form1) self.label_3.setGeometry(QtCore.QRect(22, 88, 131, 20)) font = QtGui.QFont() font.setPointSize(10) self.label_3.setFont(font) self.label_3.setObjectName(_fromUtf8("label_3")) self.label_4 = QLabel(form1) self.label_4.setGeometry(QtCore.QRect(21, 125, 181, 20)) font = QtGui.QFont() font.setPointSize(10) self.label_4.setFont(font) self.label_4.setObjectName(_fromUtf8("label_4")) self.run = QPushButton(form1) self.run.setGeometry(QtCore.QRect(139, 185, 101, 23)) self.run.setObjectName(_fromUtf8("run")) self.inputbox = QgsMapLayerComboBox(form1) self.inputbox.setGeometry(QtCore.QRect(141, 10, 170, 22)) self.inputbox.setObjectName(_fromUtf8("input")) self.output = QLineEdit(form1) self.output.setGeometry(QtCore.QRect(149, 45, 160, 28)) self.output.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) self.output.setObjectName(_fromUtf8("output")) self.refb = QLineEdit(form1) self.refb.setGeometry(QtCore.QRect(149, 82, 160, 28)) self.refb.setObjectName(_fromUtf8("refb")) self.mem = QLineEdit(form1) self.mem.setGeometry(QtCore.QRect(208, 120, 101, 28)) self.mem.setObjectName(_fromUtf8("mem")) self.addout = QCheckBox(form1) self.addout.setGeometry(QtCore.QRect(100, 158, 171, 17)) self.addout.setChecked(True) self.addout.setObjectName(_fromUtf8("checkBox")) self.inputb = QPushButton(form1) self.inputb.setGeometry(QtCore.QRect(320, 10, 31, 23)) self.inputb.setObjectName(_fromUtf8("inputb")) self.retranslateUi(form1) self.setWindowFlags(QtCore.Qt.WindowFlags(QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowMaximizeButtonHint | QtCore.Qt.WindowCloseButtonHint)) QtCore.QMetaObject.connectSlotsByName(form1) def retranslateUi(self, form1): self.label.setText(QtCore.QCoreApplication.translate("form1", "Input raster")) self.outputb.setText("...") self.label_2.setText(QApplication.translate("form1", "Output raster")) self.label_3.setToolTip(QApplication.translate("form1", "Reference band from which variances will be calculated to choose subwindow mean.")) self.label_3.setText(QApplication.translate("form1", "Reference band")) self.label_4.setToolTip(QApplication.translate("form1", "Maximum memory usage in megabytes (it is an approximated value, since algorithm will only choose how many lines will be read at once).")) self.label_4.setText(QApplication.translate("form1", "Max memory usage (MB)")) self.run.setText(QApplication.translate("form1", "Run")) self.output.setPlaceholderText(QApplication.translate("form1", "<temporary file>")) self.refb.setToolTip(QApplication.translate("form1", "Reference band from which variances will be calculated to choose subwindow mean.")) self.refb.setText("1") self.mem.setToolTip(QApplication.translate("form1", "Maximum memory usage in MeB (it is an approximated value, since algorithm will only choose how many lines will be read at once).")) self.mem.setText("100") self.addout.setText(QApplication.translate("form1", "Add results to project")) self.inputb.setText("...")
class gpx_to_3d(QDialog): # Open Qgis Aplication, for using his function # I think there is a better way to start, but by the moment I don't know how #QgsApplication.setPrefixPath('/usr', True) #qgs = QgsApplication([], False) #qgs.initQgis() # Initialize window and create Graphic User Interface def __init__(self): super().__init__() self.setWindowTitle("GPX TO 3D") #QgsApplication.setPrefixPath('/usr', True) #self.qgs = QgsApplication([], False) #self.qgs.initQgis() # File to show in map self.Output_KML_File = 'C:/Roberto/Visual_Studio_Code/Sharing_Little_Things/Python/Qgis/GPX 3D/2019_E6_V8.gpx' self.Output_KML_File = 'C:/Roberto/Visual_Studio_Code/Sharing_Little_Things/Python/Qgis/GPX 3D/2019_E6_V8_3D.kml' #self.Output_KML_File=None self.initGui() def select_file(self): # User select the file to converter and start convertion filename, _ = QFileDialog.getOpenFileName( self, 'Select GPX File / Selecciona Fichero GPX', os.path.dirname(__file__), 'TRACK (*.gpx *.kml)') if filename: # Start convertion self.convert_track(filename) # Create a Profile self.profile() # Open Map map = see_map(self.Output_KML_File) map.exec_() self.info('Finished / Finalizado') def convert_track(self, filename): self.file_name = filename if self.file_name[-3:] == 'gpx': # Set parameters to load file like a layer. Get track like a points, not a line uri = self.file_name + "|layername=track_points" # Load Layer with points of track gpx o line KML self.points = QgsVectorLayer(uri, "Original Points", "ogr") # Check if load is correct if not self.points.isValid(): self.info("Track failed to load! /n" + filename) else: self.info("Track Load Correct! " + filename) elif self.file_name[-3:] == 'kml': uri = self.file_name # Set parameters to load file like a layer. Get track like a line # Load Layer with points of track gpx o line KML lines = QgsVectorLayer(uri, "Original Line", "ogr") # Check if load is correct if not lines.isValid(): self.info("Track failed to load! /n" + filename) else: self.info("Track Load Correct! " + filename) # KML is a line convert line in points for line in lines.getFeatures(): # Create a layer for points in memory self.points = QgsVectorLayer("Point?crs=epsg:4326&index=yes", "Original Points", "memory") features = [] for vertex in line.geometry().vertices(): feature = QgsFeature() feature.setGeometry(vertex) features.append(feature) self.points.dataProvider().addFeatures(features) # Set parameters to load the Digital Elevation Model of IGN if self.comboBox.currentIndex() == 3: uri = "dpiMode=7&identifier=mdt:Elevacion4258_1000&url=http://www.ign.es/wcs/mdt" uri2 = "dpiMode=7&identifier=Elevacion4258_1000&url=http://servicios.idee.es/wcs-inspire/mdt?version%3D1.1.2" elif self.comboBox.currentIndex() == 2: uri = "dpiMode=7&identifier=mdt:Elevacion4258_500&url=http://www.ign.es/wcs/mdt" uri2 = "dpiMode=7&identifier=Elevacion4258_500&url=http://servicios.idee.es/wcs-inspire/mdt?version%3D1.1.2" elif self.comboBox.currentIndex() == 1: uri = "dpiMode=7&identifier=mdt:Elevacion4258_200&url=http://www.ign.es/wcs/mdt" uri2 = "dpiMode=7&identifier=Elevacion4258_200&url=http://servicios.idee.es/wcs-inspire/mdt?version%3D1.1.2" else: uri = "dpiMode=7&identifier=mdt:Elevacion4258_25&url=http://www.ign.es/wcs/mdt" uri2 = "dpiMode=7&identifier=Elevacion4258_25&url=http://servicios.idee.es/wcs-inspire/mdt?version%3D1.1.2" DEM = QgsRasterLayer(uri, 'my wcs layer', 'wcs') if not DEM.isValid(): self.info("DEM failed to load!") else: self.info("DEM Load Correct!") # For calculate distance between points d = QgsDistanceArea() d.setEllipsoid('WGS84') point_origin = 0 # For make profile self.all_coord_m = [] self.all_coord_z = [] self.ymax = 0 # Start to create KML file (firts lines of file) self.start_creation_kml() # Start to create GPX file (firts lines of file) self.start_creation_gpx() # For put time in points of track self.track_day = QDateTime.currentDateTime() # For each point in the track, analize information for point in self.points.getFeatures(): # Get Geometry of feature like a point geompt = point.geometry().asPoint() if not DEM.isValid(): if self.file_name[-3:] == 'kml': elevation = [0, 0] else: elevation = [point['ele'], point['ele']] else: # Find this point in DEM and return his elevation elevation = DEM.dataProvider().identify( geompt, QgsRaster.IdentifyFormatValue).results() #print (elevation[1],point['ele']) # Get Value of original point (y - Latitude, x - Longitude) self.coor_x = geompt.x() self.coor_y = geompt.y() if len(elevation) > 0: # Set value of elevation like coordinate Z self.coor_z = elevation[1] else: self.info('Point ' + str(self.coor_y) + " / " + str(self.coor_x) + " Not Found / No encontrado") self.coor_z = 0 # Calculate lenght of track if not point_origin == 0: self.distance = d.measureLine(point_origin, geompt) self.coor_m += (self.distance / 1000) # Distance in km point_origin = geompt else: self.coor_m = 0 self.distance = 0 point_origin = geompt # Maxium Hight for profile if self.ymax < self.coor_z: self.ymax = self.coor_z # Acumulate points (distance / Elevation) for make profile self.all_coord_m.append(self.coor_m) self.all_coord_z.append(self.coor_z) # Put a time in points if self.file_name[-3:] == 'kml': self.track_day = self.track_day.addSecs(1) else: if point['time'] == None: # If track hase no time add 1 second to previous time self.track_day = self.track_day.addSecs(1) else: # Get point time from track self.track_day = point['time'] # Add point in the new kml file self.add_points_kml() # Add point in the new GPX file self.add_points_gpx() # Close and write finish of kml file self.finish_kml() # Close and write finish of gpx file self.finish_gpx() def start_creation_kml(self): # Write head lines of kml file self.Output_KML_File = self.file_name[:-4] + '_3D.kml' self.file_kml = open(self.Output_KML_File, 'w') color_dic = { 'Rojo': 'ff0000ff', 'Verde': 'ff00ff00', 'Azul': 'ffff0000', 'Morado': 'ff800080', 'Amarillo': 'ff00ffff', 'Rosado': 'ffff00ff', 'Naranja': 'ff0080ff', 'Marrón': 'ff336699' } color = [ 'ff0000ff', 'ff00ff00', 'ffff0000', 'ff800080', 'ff00ffff', 'ffff00ff', 'ff0080ff', 'ff336699' ] self.file_kml.write("<?xml version='1.0' encoding='UTF-8'?>\n") self.file_kml.write( "<kml xmlns='http://www.opengis.net/kml/2.2' xmlns:gx='http://www.google.com/kml/ext/2.2' xmlns:kml='http://www.opengis.net/kml/2.2' xmlns:atom='http://www.w3.org/2005/Atom'>\n" ) self.file_kml.write("<Document>\n") self.file_kml.write(" <name>" + self.Output_KML_File + "</name>\n") self.file_kml.write(" <Placemark>\n") self.file_kml.write(" <name>" + os.path.basename(self.Output_KML_File) + "</name>\n") self.file_kml.write(" <description>" + os.path.basename(self.Output_KML_File) + "</description>\n") self.file_kml.write(" <Style>\n") self.file_kml.write(" <LineStyle>\n") self.file_kml.write(" <color>" + color[0] + "</color>\n") self.file_kml.write(" <width>4</width>\n") self.file_kml.write(" </LineStyle>\n") self.file_kml.write(" </Style>\n") self.file_kml.write(" <LineString>\n") self.file_kml.write(" <coordinates>") def add_points_kml(self): self.file_kml.write( str(self.coor_x) + "," + str(self.coor_y) + "," + str(self.coor_z) + " ") def finish_kml(self): # Write foot lines, write and close kml file self.file_kml.write(" </coordinates>\n") self.file_kml.write(" </LineString>\n") self.file_kml.write(" </Placemark>\n") self.file_kml.write("</Document>\n") self.file_kml.write("</kml>\n") self.file_kml.close() self.info(self.Output_KML_File) def start_creation_gpx(self): # Write head lines of gpx file self.Output_GPX_File = self.file_name[:-4] + '_3D.gpx' self.file_gpx = open(self.Output_GPX_File, 'w') self.file_gpx.write('''<?xml version="1.0"?>\n''') self.file_gpx.write( '''<gpx version="1.1" creator="GDAL 3.0.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">\n''' ) self.file_gpx.write(" <trk>\n") self.file_gpx.write(" <name>" + os.path.basename(self.Output_GPX_File) + "</name>\n") self.file_gpx.write(" <trkseg>\n") def add_points_gpx(self): # Add points in the GPX file self.file_gpx.write(' <trkpt lat="' + str(self.coor_y) + '" lon="' + str(self.coor_x) + '">\n') self.file_gpx.write(" <ele>" + str(self.coor_z) + "</ele>\n") self.file_gpx.write(" <time>" + self.track_day.toString('yyyy-MM-ddTHH:mm:ssZ') + "</time>\n") self.file_gpx.write(" </trkpt>\n") def finish_gpx(self): # Write foot lines, write and close kml file self.file_gpx.write(" </trkseg>\n") self.file_gpx.write(" </trk>\n") self.file_gpx.write("</gpx>\n") self.file_gpx.close() self.info(self.Output_GPX_File) def profile(self): import matplotlib.pyplot as plt # Create Profile plt.xlim(right=self.coor_m) #xmax is your value plt.xlim(left=0) #xmin is your value plt.ylim(top=self.ymax * 1.2) #ymax is your value plt.ylim(bottom=0) #ymin is your value plt.plot(self.all_coord_m, self.all_coord_z) plt.fill_between(self.all_coord_m, self.all_coord_z, facecolor='red', color='#539ecd') #pylab.fill_between(x, y, color='#539ecd') file_profile = self.file_name[:-3] + "jpg" plt.savefig(file_profile) plt.clf() pixmap = QPixmap(file_profile) self.profile_jpg.setPixmap(pixmap) self.profile_jpg.setScaledContents(True) self.info(file_profile) def info(self, message): # Show Information message in the screen and print in console print(message) self.message_box.append(message) def initGui(self): # Create Graphical User Interface icon = QIcon() icon.addPixmap(QPixmap(os.path.dirname(__file__) + "/icon.png"), QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) self.setWindowModality(Qt.WindowModal) self.setWindowFlags(Qt.Window | Qt.WindowSystemMenuHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint) self.resize(520, 520) self.label = QLabel(self) self.label.setGeometry(QRect(10, 20, 500, 20)) font = QFont() font.setPointSize(14) font.setUnderline(True) self.label.setFont(font) self.label.setAlignment(Qt.AlignCenter) self.label_2 = QLabel(self) self.label_2.setGeometry(QRect(10, 70, 500, 16)) self.label_3 = QLabel(self) self.label_3.setGeometry(QRect(10, 90, 500, 16)) self.label_4 = QLabel(self) self.label_4.setGeometry(QRect(10, 110, 500, 16)) self.pushButton = QPushButton(self) self.pushButton.setGeometry(QRect(50, 150, 121, 24)) self.comboBox = QComboBox(self) self.comboBox.setGeometry(QRect(240, 150, 121, 24)) self.comboBox.addItem("Paso Malla 25m") self.comboBox.addItem("Paso Malla 200m") self.comboBox.addItem("Paso Malla 500m") self.comboBox.addItem("Paso Malla 1.000m") self.bt_view_map = QPushButton(self) self.bt_view_map.setGeometry(QRect(370, 150, 121, 24)) self.profile_jpg = QLabel(self) self.profile_jpg.setGeometry(QRect(20, 200, 480, 180)) self.message_box = QTextEdit(self) self.message_box.setGeometry(QRect(10, 400, 500, 111)) self.label.setText("KML / GPX TO 3D") self.label_2.setText( "Convert a GPX file without elevation, in a GPX and KML with elevation. It's only for Spain." ) self.label_3.setText( "Convierte un GPX sin elevación, en un GPX y KML con elevación.") self.label_4.setText( "Es solo para España ya que utiliza el servicio WCS del Instituto Geografico Nacional" ) self.pushButton.setText("File / Fichero") self.bt_view_map.setText("Map / Mapa") self.pushButton.clicked.connect(self.select_file) self.bt_view_map.clicked.connect( lambda: see_map(self.Output_KML_File).exec_())
class Ui_Dialog(object): """ def __init__(self, iface): self.iface = iface """ def setupUi(self, Dialog): self.iface = iface Dialog.setObjectName("Dialog") Dialog.resize( QtCore.QSize(QtCore.QRect(0, 0, 350, 250).size()).expandedTo( Dialog.minimumSizeHint())) Dialog.setWindowTitle("GroupPointsWithinDistance") # QLabel lancer recherche self.label10 = QLabel(Dialog) self.label10.setGeometry(QtCore.QRect(15, 15, 320, 18)) self.label10.setObjectName("label10") self.label10.setText("Select a layer with points to regroup: ") ListeCouchesPoint = [""] NbCouches = self.iface.mapCanvas().layerCount() if NbCouches == 0: QMessageBox.information(None, "information:", "No layers ! ") else: for i in range(0, NbCouches): couche = self.iface.mapCanvas().layer(i) # 0 pour point if couche.geometryType() == 0 or couche.geometryType() == 3: if couche.isValid(): ListeCouchesPoint.append(couche.name()) else: QMessageBox.information(None, "information:", "No layers with points ! ") return None self.ComboBoxPoints = QComboBox(Dialog) self.ComboBoxPoints.setMinimumSize(QtCore.QSize(320, 25)) self.ComboBoxPoints.setMaximumSize(QtCore.QSize(320, 25)) self.ComboBoxPoints.setGeometry(QtCore.QRect(10, 35, 320, 25)) self.ComboBoxPoints.setObjectName("ComboBoxPoints") for i in range(len(ListeCouchesPoint)): self.ComboBoxPoints.addItem(ListeCouchesPoint[i]) # QLabel entrer Enter distance of recherch self.labelResearchDistance = QLabel(Dialog) self.labelResearchDistance.setGeometry(QtCore.QRect(15, 80, 240, 23)) self.labelResearchDistance.setObjectName(" ResearchDistance") self.labelResearchDistance.setText("Enter distance of research :") #Exemple de QDoubleSpinBox self.dsbResearchDistance = QDoubleSpinBox(Dialog) self.dsbResearchDistance.setMinimumSize(QtCore.QSize(70, 23)) self.dsbResearchDistance.setMaximumSize(QtCore.QSize(70, 23)) self.dsbResearchDistance.setGeometry(QtCore.QRect(180, 80, 70, 23)) self.dsbResearchDistance.setObjectName("dsb") #self.dsbResearchDistance.setValue(10.0) self.dsbResearchDistance.setDecimals(1) self.dsbResearchDistance.setSingleStep(10.0) self.dsbResearchDistance.setRange(0, 1000000) self.dsbResearchDistance.setProperty("value", 100.0) #self.dsbResearchDistance.valueChanged.connect(self.onValueChanged) #Exemple de QPushButton self.DoButton = QPushButton(Dialog) self.DoButton.setMinimumSize(QtCore.QSize(280, 20)) self.DoButton.setMaximumSize(QtCore.QSize(280, 20)) self.DoButton.setGeometry(QtCore.QRect(15, 120, 280, 20)) self.DoButton.setObjectName("DoButton") self.DoButton.setText(" Let's make aggregates - being patient !") #Exemple de QLCDNumber self.progressBar = QProgressBar(Dialog) self.progressBar.setProperty("value", 0) self.progressBar.setMinimumSize(QtCore.QSize(260, 15)) self.progressBar.setMaximumSize(QtCore.QSize(260, 15)) self.progressBar.setGeometry(QtCore.QRect(30, 155, 260, 15)) self.progressBar.setAlignment(QtCore.Qt.AlignCenter) self.progressBar.setTextVisible(True) self.progressBar.setObjectName("progressBar") self.progressBar.setStyleSheet( """QProgressBar {border: 2px solid grey; border-radius: 5px; text-align: center;}""" """QProgressBar::chunk {background-color: #6C96C6; width: 20px;}""" ) #Pose a minima une valeur de la barre de progression / slide contrôle self.progressBar.setValue(0) #Exemple de QPushButton self.aboutButton = QPushButton(Dialog) self.aboutButton.setMinimumSize(QtCore.QSize(70, 20)) self.aboutButton.setMaximumSize(QtCore.QSize(70, 20)) self.aboutButton.setGeometry(QtCore.QRect(30, 195, 70, 23)) self.aboutButton.setObjectName("aboutButton") self.aboutButton.setText(" Read me ") self.PushButton = QPushButton(Dialog) self.PushButton.setMinimumSize(QtCore.QSize(100, 20)) self.PushButton.setMaximumSize(QtCore.QSize(100, 20)) self.PushButton.setGeometry(QtCore.QRect(185, 195, 100, 20)) self.PushButton.setObjectName("PushButton") self.PushButton.setText("Close") self.PushButton.clicked.connect(Dialog.reject) self.ComboBoxPoints.activated[str].connect(self.onComboP) self.aboutButton.clicked.connect(self.doAbout) self.DoButton.clicked.connect(self.Run) QtCore.QMetaObject.connectSlotsByName(Dialog) def onComboP(self): global SelectionP SelectionP = self.ComboBoxPoints.currentText() def doAbout(self): d = doAboutGroupPointsWithinDistance.Dialog() d.exec_() def Run(self): D = 0.0 D = self.dsbResearchDistance.value() #QMessageBox.information(None,"information:"," D : "+str(D)) DicoP1 = {} DicoA = {} counterProgess = 0 compteur_pt = 0 layerP = fonctionsGPWD.getVectorLayerByName(SelectionP) # on parcourt la couche de points et on stocke dans les dictionnaire DicoP1 les points # the points of the point laye are put into a dictionnary for featP in layerP.getFeatures(): Point_id = featP.id() geomP1 = featP.geometry() Point1 = geomP1.asPoint() DicoP1[Point_id] = [Point1] compteur_pt += 1 if D == 0: QMessageBox.information(None, "information:", "Zero is not a value for D !") #zdim est le compteur de la progress bar zDim = compteur_pt counterProgess = 0 cpt_agg = 1 nb = 0 liste_id = [] liste_pt = [] liste_aggreg_pt = [] DicoSegments = {} firstDicoSegments = True T = True while len(DicoP1) != 0: first = True zPercent = int(100 * counterProgess / zDim) self.progressBar.setValue(zPercent) nb = 0 for keyD1 in list(DicoP1.keys()): P1 = DicoP1[keyD1][0] if first: # we pick a first point and delete it from the dictionnary we point are stored T = True first = False nb += 1 liste_id = [keyD1] liste_pt = [P1] counterProgess += 1 del DicoP1[keyD1] while T: # We are generating an aggregates and making it grows # by adding points at distance from the point it contains # and repeating the research all over again as soon a poitn is added # untill none are added for pt in liste_pt: compteur_corresP = 0 for keyD1 in list(DicoP1.keys()): P1 = DicoP1[keyD1][0] if fonctionsGPWD.mag(fonctionsGPWD.vect( pt, P1)) < D: # one point at distance found compteur_corresId = 0 for idp in liste_id: if keyD1 == idp: # is this point already added in the aggregate compteur_corresId += 1 if compteur_corresId == 0: # if not let s add it nb += 1 liste_id.append(keyD1) liste_pt.append(P1) compteur_corresP += 1 counterProgess += 1 # boucle des segments # interpoint line loop idseg = '' # a segment as an id made of the points id order ordered id: smallerid-biggerid idseg = str(keyD1) + '-' + str(idp) idseg_reverse = str(idp) + '-' + str(keyD1) if firstDicoSegments: firstDicoSegments = False if int(keyD1) > int(idp): idseg = idseg_reverse DicoSegments[idseg] = [[pt, P1], idp, keyD1, cpt_agg] else: DicoSegments[idseg] = [[P1, pt], keyD1, idp, cpt_agg] else: for idseg_cheack in list( DicoSegments.keys()): if idseg == idseg_cheack or idseg_reverse == idseg_cheack: pass else: if int(keyD1) > int(idp): idseg = idseg_reverse DicoSegments[idseg] = [[ pt, P1 ], idp, keyD1, cpt_agg] else: DicoSegments[idseg] = [[ P1, pt ], keyD1, idp, cpt_agg] if compteur_corresP == 0: # if no more points are find then we are over with the previous aggregate T = False DicoA[cpt_agg] = [nb, liste_id, liste_pt, DicoSegments] cpt_agg += 1 for id in liste_id: for keyD1 in list(DicoP1.keys()): if id == keyD1: del DicoP1[keyD1] # on fabrique un polygone buffer de D/100 # du convexHull de tous les points de l'agregat # pour les operateur Pyqgis # voir http://www.qgis.org/api/classQgsGeometry.html#a1699b205d01c365a50ead2d0bf2bbcfb DicoP4 = {} for key2 in list(DicoA.keys()): list_pt = [] list_pt = DicoA[key2][2] nb_pt = 0 nb_pt = DicoA[key2][0] Liste_id = [] Liste_id = DicoA[key2][1] buff = 0.0 first = True for pt in list_pt: if first: first = False #https://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/geometry.html g0 = QgsGeometry().fromPointXY(pt) else: g0 = QgsGeometry().fromPointXY(pt).combine( g0) # combine pour union car union reserve C++ buff = D / 100 P = g0.convexHull() B = P.buffer(buff, 5) DicoP4[key2] = [B, Liste_id, nb_pt] zPercent = int(100 * counterProgess / zDim) self.progressBar.setValue(zPercent) self.iface.mapCanvas().refresh() STATIONS = QgsVectorLayer( "MultiPolygon", "Polygons_under_AGGREGATES_D" + str(D) + "_OF_" + str(layerP.name()), "memory") QgsProject.instance().addMapLayer(STATIONS) prSTATIONS = STATIONS.dataProvider() listFieldsS = [] listFieldsS.append(QgsField("NumAggreg", QVariant.String)) listFieldsS.append(QgsField("List_Pts", QVariant.String)) listFieldsS.append(QgsField("Nb_Pts", QVariant.Int)) prSTATIONS.addAttributes(listFieldsS) STATIONS.startEditing() newfeatSTATIONS = QgsFeature() for keyP4 in DicoP4.keys(): GeomPoly = DicoP4[keyP4][0] newfeatSTATIONS = QgsFeature() newfeatSTATIONS.setGeometry(GeomPoly) toto = '' first = True for t in DicoP4[keyP4][1]: if first: first = False toto = str(t) else: toto = toto + ' - ' + str(t) NbObs = DicoP4[keyP4][2] ValuesSTATIONS = [keyP4] ValuesSTATIONS.append(toto) ValuesSTATIONS.append(NbObs) newfeatSTATIONS.setAttributes(ValuesSTATIONS) prSTATIONS.addFeatures([newfeatSTATIONS]) STATIONS.commitChanges() iface.mapCanvas().refresh() SEGMENTS = QgsVectorLayer( "MultiLineString", "Lines_from_" + str(layerP.name()) + "_Aggregates_with_D" + str(D), "memory") QgsProject.instance().addMapLayer(SEGMENTS) prSEGMENTS = SEGMENTS.dataProvider() listFields = [] listFields.append(QgsField("NumAgregat", QVariant.String)) listFields.append(QgsField("Nb_Pts", QVariant.Int)) prSEGMENTS.addAttributes(listFields) SEGMENTS.startEditing() newfeatSEGMENTS = QgsFeature() attributs = [] for keyA in DicoA.keys(): DicoSeg = DicoA[keyA][3] NbObs = DicoA[keyA][0] firstSEG = True MultiLine = [] GeomLine = QgsGeometry for keyPair in DicoSeg.keys(): if DicoSeg[keyPair][3] == keyA: if firstSEG: firstSEG = False MultiLine = [] MultiLine = [DicoSeg[keyPair][0]] else: MultiLine.append(DicoSeg[keyPair][0]) GeomLine = QgsGeometry.fromMultiPolylineXY(MultiLine) NumAg = keyA newfeatSEGMENTS = QgsFeature() newfeatSEGMENTS.setGeometry(GeomLine) ValuesSEGMENTS = [NumAg] ValuesSEGMENTS.append(NbObs) newfeatSEGMENTS.setAttributes(ValuesSEGMENTS) prSEGMENTS.addFeatures([newfeatSEGMENTS]) SEGMENTS.commitChanges() iface.mapCanvas().refresh() # modification de la table de point initiale pour ajout d un numero d agregat # making of the modified point layer with aggregates code AGGREGATS = QgsVectorLayer( "Point", str(layerP.name()) + "_aggregated_with_D" + str(D), "memory") QgsProject.instance().addMapLayer(AGGREGATS) prAGGREGATS = AGGREGATS.dataProvider() fieldsP = layerP.fields() listFields = [] for f in fieldsP: znameField = f.name() Type = str(f.typeName()) if Type == 'Integer': listFields.append(QgsField(znameField, QVariant.Int)) if Type == 'Real': listFields.append(QgsField(znameField, QVariant.Double)) if Type == 'String': listFields.append(QgsField(znameField, QVariant.String)) else: listFields.append(QgsField(znameField, QVariant.String)) listFields.append(QgsField("Point_id", QVariant.String)) listFields.append(QgsField("NumAggreg", QVariant.String)) listFields.append(QgsField("Nb_Pts", QVariant.Int)) listFields.append(QgsField("List_Pts", QVariant.String)) prAGGREGATS.addAttributes(listFields) AGGREGATS.startEditing() newfeatAGGREGATS = QgsFeature() attributs = [] for featP in layerP.getFeatures(): attributs = featP.attributes() Point_id = featP.id() geomP1 = featP.geometry() NbObs = 1 NumAgregat = 0 for keyP4 in DicoP4.keys(): #GeomPoly=DicoP4[keyP4][0] #if geomP1.intersects(GeomPoly): for ptid in DicoP4[keyP4][1]: if Point_id == ptid: NbObs = DicoP4[keyP4][2] toto = '' first = True for t in DicoP4[keyP4][1]: if first: first = False toto = str(t) else: toto = toto + ' - ' + str(t) list_id = toto NumAgregat = keyP4 newfeatAGGREGATS = QgsFeature() newfeatAGGREGATS.setGeometry(geomP1) ValuesAGGREGATS = attributs ValuesAGGREGATS.append(Point_id) ValuesAGGREGATS.append(NumAgregat) ValuesAGGREGATS.append(NbObs) ValuesAGGREGATS.append(list_id) newfeatAGGREGATS.setAttributes(ValuesAGGREGATS) prAGGREGATS.addFeatures([newfeatAGGREGATS]) AGGREGATS.commitChanges() iface.mapCanvas().refresh()