class NewCaptureSourceArea(QFrame, FORM_CLASS): def __init__(self, dockwidget, parent=None): """Constructor.""" super(NewCaptureSourceArea, self).__init__(parent) self.setupUi(self) self.db = db self.db.connect() self.dockwidget = dockwidget self.layer_registry = LayerRegistry() self.error_dialog = None self.current_layer = None self.added_building_ids = [] self.geom = None self.add_capture_source_area_layer() self.init_table() self.setup_toolbar() self.le_area_title.setDisabled(True) self.le_external_id.setDisabled(True) self.mcb_selection_layer.setDisabled(True) self.mcb_selection_layer.setExceptedLayerList( [self.capture_source_area]) self.rb_select_from_layer.setChecked(False) self.capture_source_area.featureAdded.connect( self.creator_feature_added) self.capture_source_area.featureDeleted.connect( self.creator_feature_deleted) self.capture_source_area.geometryChanged.connect( self.creator_geometry_changed) self.rb_select_from_layer.toggled.connect( self.rb_select_from_layer_clicked) self.btn_save.clicked.connect( partial(self.save_clicked, commit_status=True)) self.btn_reset.clicked.connect(self.reset_clicked) self.btn_exit.clicked.connect(self.exit_clicked) QgsProject.instance().layerWillBeRemoved.connect(self.layers_removed) iface.actionToggleEditing().trigger() iface.actionAddFeature().trigger() def rb_select_from_layer_clicked(self, checked): """PyqtSlot: When the select from layer radio button is clicked""" self.l_wrong_projection.setText("") if checked: self.mcb_selection_layer.showPopup() self.mcb_selection_layer.setEnabled(True) iface.actionSelect().trigger() self.mcb_selection_layer.layerChanged.connect( self.mcb_selection_layer_changed) else: self.mcb_selection_layer.layerChanged.disconnect( self.mcb_selection_layer_changed) if self.current_layer is not None: self.current_layer.removeSelection() self.current_layer.selectionChanged.disconnect( self.current_layer_selection_changed) self.mcb_selection_layer.setDisabled(True) iface.actionAddFeature().trigger() self.current_layer = None iface.setActiveLayer(self.current_layer) def mcb_selection_layer_changed(self, current_layer): """PyQtSlot: When the multi-combobox layer to select from is changed""" if current_layer is None: return if not self.check_projection(current_layer): self.l_wrong_projection.setText("ERROR: Incorrect Projection") self.is_wrong_projection = True else: self.l_wrong_projection.setText("") self.is_wrong_projection = False if self.current_layer is not None: self.current_layer.removeSelection() try: self.current_layer.selectionChanged.disconnect( self.current_layer_selection_changed) except TypeError: pass self.current_layer = current_layer iface.setActiveLayer(current_layer) self.current_layer.selectionChanged.connect( self.current_layer_selection_changed) def current_layer_selection_changed(self): """PyqtSlot: When the selection of the current layer is changed""" if self.is_wrong_projection: self.projection_error() return selection = self.current_layer.selectedFeatures() if len(selection) == 0: self.le_external_id.setDisabled(True) self.le_area_title.setDisabled(True) elif len(selection) > 1: self.le_external_id.setDisabled(True) self.le_area_title.setDisabled(True) iface.messageBar().pushMessage( "INFO", "More than one feature selected, please re-select.", level=Qgis.Info, duration=3) elif len(selection) == 1: new_geometry = selection[0].geometry() # error pops up if geometry type is not polygon or multipolygon if new_geometry.wkbType() not in [ QgsWkbTypes.Polygon, QgsWkbTypes.MultiPolygon ]: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n -------------------- WRONG GEOMETRY TYPE ------" "-------------- \n\nInserted capture source area " "should be either polygon or multipolygon.") self.error_dialog.show() return self.le_external_id.setEnabled(True) self.le_area_title.setEnabled(True) # convert to correct format if new_geometry.wkbType() == QgsWkbTypes.Polygon: new_geometry = QgsGeometry.fromMultiPolygonXY( [new_geometry.asPolygon()]) wkt = new_geometry.asWkt() sql = general_select.convert_geometry result = self.db.execute_return(sql, (wkt, )) self.geom = result.fetchall()[0][0] def check_projection(self, layer): """Ensure layer has correct projection""" if layer.crs().authid() != "EPSG:2193": self.projection_error() return False return True def projection_error(self): """Error dialog on incorrect projection of layer""" self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n -------------------- INCORRECT CRS-------------" "------- \n\nThe Coordinate Reference System is not NTZM 2000. " "Please resolve and reattempt.") self.error_dialog.show() def add_capture_source_area_layer(self): """Called on opening of frame to add capture source area layer""" path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "styles/") # add layer self.capture_source_area = self.layer_registry.add_postgres_layer( "capture_source_area", "capture_source_area", "shape", "buildings_reference", "", "") # set style self.capture_source_area.loadNamedStyle(path + "capture_source.qml") # make capture source area the active layer iface.setActiveLayer(self.capture_source_area) def init_table(self): """Set up capture source area table""" tbl = self.tbl_capture_source_area tbl.setRowCount(0) tbl.setColumnCount(2) tbl.setHorizontalHeaderItem(0, QTableWidgetItem("Id")) tbl.setHorizontalHeaderItem(1, QTableWidgetItem("Area Title")) tbl.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) tbl.verticalHeader().setVisible(False) tbl.setSelectionBehavior(QAbstractItemView.SelectRows) tbl.setSelectionMode(QAbstractItemView.SingleSelection) tbl.setShowGrid(True) sql_csa = reference_select.capture_source_area_id_and_name result = self.db.execute_return(sql_csa) for (polygon_id, area_title) in result.fetchall(): row_tbl = tbl.rowCount() tbl.setRowCount(row_tbl + 1) tbl.setItem(row_tbl, 0, QTableWidgetItem("%s" % polygon_id)) tbl.setItem(row_tbl, 1, QTableWidgetItem("%s" % area_title)) tbl.sortItems(0) def setup_toolbar(self): """Called on opening of from to set up the buildings toolbar for selection only""" selecttools = iface.attributesToolBar().findChildren(QToolButton) # selection actions iface.building_toolbar.addSeparator() for sel in selecttools: if sel.text() == "Select Feature(s)": for a in sel.actions()[0:3]: iface.building_toolbar.addAction(a) # editing actions iface.building_toolbar.addSeparator() for dig in iface.digitizeToolBar().actions(): if dig.objectName() in [ "mActionAddFeature", "mActionNodeTool", "mActionMoveFeature" ]: iface.building_toolbar.addAction(dig) # advanced Actions iface.building_toolbar.addSeparator() for adv in iface.advancedDigitizeToolBar().actions(): if adv.objectName() in [ "mActionUndo", "mActionRedo", "mActionReshapeFeatures", "mActionOffsetCurve" ]: iface.building_toolbar.addAction(adv) iface.building_toolbar.show() def creator_feature_added(self, qgsfId): """ Called when feature is added @param qgsfId: Id of added feature @type qgsfId: qgis.core.QgsFeature.QgsFeatureId """ if qgsfId not in self.added_building_ids: self.added_building_ids.append(qgsfId) # get new feature geom request = QgsFeatureRequest().setFilterFid(qgsfId) new_feature = next(self.capture_source_area.getFeatures(request)) new_geometry = new_feature.geometry() # convert to correct format if new_geometry.wkbType() == QgsWkbTypes.Polygon: new_geometry = QgsGeometry.fromMultiPolygonXY( [new_geometry.asPolygon()]) wkt = new_geometry.asWkt() sql = general_select.convert_geometry result = self.db.execute_return(sql, (wkt, )) self.geom = result.fetchall()[0][0] self.le_area_title.setEnabled(True) self.le_external_id.setEnabled(True) def creator_feature_deleted(self, qgsfId): """ Called when a Feature is Deleted @param qgsfId: Id of deleted feature @type qgsfId: qgis.core.QgsFeature.QgsFeatureId """ if qgsfId in self.added_building_ids: self.added_building_ids.remove(qgsfId) if self.added_building_ids == []: self.le_area_title.setDisabled(True) self.le_external_id.setDisabled(True) self.geom = None def creator_geometry_changed(self, qgsfId, geom): """ Called when feature is changed @param qgsfId: Id of added feature @type qgsfId: qgis.core.QgsFeature.QgsFeatureId @param geom: geometry of added feature @type geom: qgis.core.QgsGeometry """ if qgsfId in self.added_building_ids: if geom.wkbType() == QgsWkbTypes.Polygon: geom = QgsGeometry.fromMultiPolygonXY([geom.asPolygon()]) wkt = geom.asWkt() if not wkt: self.disable_UI_functions() self.geom = None return sql = general_select.convert_geometry result = self.db.execute_return(sql, (wkt, )) self.geom = result.fetchall()[0][0] else: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n -------------------- WRONG GEOMETRY EDITED ------" "-------------- \n\nOnly current added outline can " "be edited. Please go to [Edit Geometry] to edit " "existing outlines.") self.error_dialog.show() def save_clicked(self, commit_status): """PyqtSlot: Called when save is clicked""" if self.le_area_title.text() == "" or self.le_external_id.text() == "": self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n -------------------- Empty Area Title ------" "-------------- \n\nPlease add the title and " "external id for the newly created capture " "source area.") self.error_dialog.show() return self.db.open_cursor() area_title = self.le_area_title.text() external_id = self.le_external_id.text() geom = self.geom sql = "SELECT buildings_reference.capture_source_area_insert(%s, %s, %s)" self.db.execute_no_commit(sql, (external_id, area_title, geom)) self.init_table() self.le_area_title.clear() self.le_external_id.clear() self.le_area_title.setDisabled(True) self.le_external_id.setDisabled(True) if commit_status: self.db.commit_open_cursor() self.geom = None self.added_building_ids = [] def reset_clicked(self): """Called When reset is clicked""" self.geom = None self.added_building_ids = [] self.le_area_title.clear() self.le_area_title.setDisabled(True) self.le_external_id.setDisabled(True) self.rb_select_from_layer.setChecked(False) self.mcb_selection_layer.setDisabled(True) self.l_wrong_projection.setText("") iface.setActiveLayer(self.capture_source_area) self.capture_source_area.geometryChanged.disconnect( self.creator_geometry_changed) iface.actionCancelEdits().trigger() self.capture_source_area.geometryChanged.connect( self.creator_geometry_changed) # restart editing iface.actionToggleEditing().trigger() iface.actionAddFeature().trigger() def exit_clicked(self): """Called when exit is clicked""" self.close_frame() def close_frame(self): """Close the frame""" self.rb_select_from_layer.setChecked(False) self.mcb_selection_layer.setDisabled(True) self.geom = None self.added_building_ids = [] self.current_layer = None QgsProject.instance().layerWillBeRemoved.disconnect( self.layers_removed) self.layer_registry.remove_layer(self.capture_source_area) from buildings.gui.new_capture_source import NewCaptureSource dw = self.dockwidget dw.stk_options.removeWidget(dw.stk_options.currentWidget()) dw.new_widget(NewCaptureSource(dw)) def layers_removed(self, layerids): """Check no necessary layers are removed from the map canvas""" self.layer_registry.update_layers() if "capture_source_area" in layerids: self.le_area_title.setDisabled(1) self.le_external_id.setDisabled(1) self.btn_save.setDisabled(1) self.btn_reset.setDisabled(1) self.tbl_capture_source_area.setDisabled(1) iface.messageBar().pushMessage( "ERROR", "Required layer Removed! Please reload the buildings plugin or the current frame before continuing", level=Qgis.Critical, duration=5, ) return
class EditAttribute(ProductionChanges): """ Class to edit attributes in buildings.building_outlines Inherits ProductionChanges """ def __init__(self, edit_dialog): """Constructor""" ProductionChanges.__init__(self, edit_dialog) # set editing to edit polygon iface.actionSelect().trigger() selecttools = iface.attributesToolBar().findChildren(QToolButton) # selection actions iface.building_toolbar.addSeparator() for sel in selecttools: if sel.text() == "Select Feature(s)": for a in sel.actions()[0:3]: iface.building_toolbar.addAction(a) iface.building_toolbar.show() self.msgbox_remove = self.confirmation_dialog_box("remove") self.disable_UI_functions() if len(self.editing_layer.selectedFeatures()) > 0: if self.is_correct_selections(): self.get_selections() self.enable_UI_functions() self.populate_edit_comboboxes() self.select_comboboxes_value() else: self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None self.disable_UI_functions() def edit_save_clicked(self, commit_status): """ When production frame btn_edit_save clicked """ self.edit_dialog.db.open_cursor() capture_method_id, capture_source_id, lifecycle_stage_id, suburb, town, t_a = self.get_comboboxes_values( ) if len(self.edit_dialog.ids) > 0: for i in self.edit_dialog.ids: sql = "SELECT buildings.building_outlines_update_attributes(%s, %s, %s, %s, %s, %s, %s);" self.edit_dialog.db.execute_no_commit( sql, (i, capture_method_id, capture_source_id, lifecycle_stage_id, suburb, town, t_a)) sql = "SELECT buildings.building_outlines_update_modified_date(%s);" self.edit_dialog.db.execute_no_commit(sql, (i, )) self.disable_UI_functions() if commit_status: self.edit_dialog.db.commit_open_cursor() self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None def edit_reset_clicked(self): """ When production frame btn_edit_reset clicked """ self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None # restart editing iface.actionSelect().trigger() iface.activeLayer().removeSelection() # reset and disable comboboxes self.disable_UI_functions() def selection_changed(self, added, removed, cleared): """ Called when feature is selected """ # If no outlines are selected the function will return if len(self.editing_layer.selectedFeatures()) == 0: self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None self.disable_UI_functions() return if self.is_correct_selections(): self.get_selections() self.enable_UI_functions() self.populate_edit_comboboxes() self.select_comboboxes_value() else: self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None self.disable_UI_functions() def end_lifespan(self, commit_status): """ end the lifespan of building""" # get the dataset id and dates of the most recent supplied dataset if not self.confirm(self.msgbox_remove): return dates = self.edit_dialog.db.execute_return( bulk_load_select.supplied_dataset_latest_id_and_dates) dates = dates.fetchone() # get list of building_ids from building_outline_ids building_ids = [] for outline in self.edit_dialog.ids: result = self.edit_dialog.db.execute_return( buildings_select.building_id_by_building_outline_id, (outline, )) building_ids.append(result.fetchone()[0]) # if the current supplied dataset is not in compare is_bulk_loaded = dates[1] is None and dates[2] is None is_compared = dates[1] is not None and dates[2] is None is_published = dates[1] is not None and dates[2] is not None if is_bulk_loaded or is_published: if self.edit_dialog.db._open_cursor is None: self.edit_dialog.db.open_cursor() # end lifespan in use table sql = "SELECT buildings.building_use_update_end_lifespan(%s);" self.edit_dialog.db.execute_no_commit(sql, (building_ids, )) # end lifespan in name table sql = "SELECT buildings.building_name_update_end_lifespan(%s);" self.edit_dialog.db.execute_no_commit(sql, (building_ids, )) # end lifespan in building outlines table sql = "SELECT buildings.building_outlines_update_end_lifespan(%s);" result = self.edit_dialog.db.execute_no_commit( sql, (self.edit_dialog.ids, )) # end lifespan in buildings table sql = "SELECT buildings.buildings_update_end_lifespan(%s);" self.edit_dialog.db.execute_no_commit(sql, (building_ids, )) if commit_status: self.edit_dialog.db.commit_open_cursor() self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None self.editing_layer.removeSelection() iface.mapCanvas().refreshAllLayers() # if current is in compare elif is_compared: bool_delete = True for outline in self.edit_dialog.ids: # see if outline in existing_subset_extracts dataset = self.edit_dialog.db.execute_return( bulk_load_select. existing_subset_extracts_dataset_by_building_outline_id, (outline, )) dataset = dataset.fetchone() # if the outline is in existing_subset_extracts if dataset: # if the dataset the outline relates to is the current dataset if dataset[0] == dates[0]: # check if the bulk_loaded_outline is in removed table removed_count = self.edit_dialog.db.execute_return( bulk_load_select. removed_count_by_building_outline_id, (outline, )) removed_count = removed_count.fetchone() if removed_count[0] == 0: # if it isn't error self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n -------------------- BUILDING HAS RELATIONSHIP ------" "-------------- \n\nYou cannot delete this outline as it has" " a relationship with a current bulk loaded outline, first remove " "this relationship and then try again.") self.error_dialog.show() bool_delete = False break # if able to delete outlines if bool_delete: if self.edit_dialog.db._open_cursor is None: self.edit_dialog.db.open_cursor() # end lifespan in use table sql = "SELECT buildings.building_use_update_end_lifespan(%s);" self.edit_dialog.db.execute_no_commit(sql, (building_ids, )) # end lifespan in name table sql = "SELECT buildings.building_name_update_end_lifespan(%s);" self.edit_dialog.db.execute_no_commit(sql, (building_ids, )) # remove outline from removed table sql = "SELECT buildings_bulk_load.removed_delete_existing_outlines(%s);" self.edit_dialog.db.execute_no_commit(sql, (self.edit_dialog.ids, )) # remove outline from existing subset extracts table sql = "SELECT buildings_bulk_load.existing_subset_extracts_remove_by_building_outline_id(%s);" self.edit_dialog.db.execute_no_commit(sql, (self.edit_dialog.ids, )) # end lifespan in building outlines table sql = "SELECT buildings.building_outlines_update_end_lifespan(%s);" result = self.edit_dialog.db.execute_no_commit( sql, (self.edit_dialog.ids, )) # end lifespan in buildings table sql = "SELECT buildings.buildings_update_end_lifespan(%s);" self.edit_dialog.db.execute_no_commit(sql, (building_ids, )) if commit_status: self.edit_dialog.db.commit_open_cursor() self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None self.editing_layer.removeSelection() iface.mapCanvas().refreshAllLayers() def is_correct_selections(self): """ Check if the selections meet the requirement """ feats = [] for feature in self.editing_layer.selectedFeatures(): ls = [] ls.append(feature.attributes()[2]) ls.append(feature.attributes()[3]) ls.append(feature.attributes()[4]) ls.append(feature.attributes()[5]) ls.append(feature.attributes()[6]) ls.append(feature.attributes()[7]) if ls not in feats: feats.append(ls) # if selected features have different attributes (not allowed) if len(feats) > 1: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n ---- MULTIPLE NON IDENTICAL FEATURES SELECTED" " ---- \n\n Can only edit attributes of multiple" " features when all existing attributes a" "re identical.") self.error_dialog.show() return False # if all selected features have the same attributes (allowed) elif len(feats) == 1: return True return False def get_selections(self): """ Return the selection values """ self.edit_dialog.ids = [ feat.id() for feat in self.editing_layer.selectedFeatures() ] self.edit_dialog.building_outline_id = [ feat.id() for feat in self.editing_layer.selectedFeatures() ][0] building_feat = [ feat for feat in self.editing_layer.selectedFeatures() ][0] building_geom = building_feat.geometry() # convert to correct format wkt = building_geom.asWkt() sql = general_select.convert_geometry result = self.edit_dialog.db.execute_return(sql, (wkt, )) self.edit_dialog.geom = result.fetchall()[0][0] def select_comboboxes_value(self): """ Select the correct combobox value for the geometry """ # lifecycle stage result = self.edit_dialog.db.execute_return( buildings_select.lifecycle_stage_value_by_building_outline_id, (self.edit_dialog.building_outline_id, )) result = result.fetchall()[0][0] self.edit_dialog.cmb_lifecycle_stage.setCurrentIndex( self.edit_dialog.cmb_lifecycle_stage.findText(result)) # capture method result = self.edit_dialog.db.execute_return( common_select.capture_method_value_by_building_outline_id, (self.edit_dialog.building_outline_id, )) result = result.fetchall()[0][0] self.edit_dialog.cmb_capture_method.setCurrentIndex( self.edit_dialog.cmb_capture_method.findText(result)) # capture source result = self.edit_dialog.db.execute_return( common_select. capture_source_group_value_external_by_building_outline_id, (self.edit_dialog.building_outline_id, )) result = result.fetchall()[0] text = "- ".join(result) self.edit_dialog.cmb_capture_source.setCurrentIndex( self.edit_dialog.cmb_capture_source.findText(text)) # suburb result = self.edit_dialog.db.execute_return( reference_select.suburb_locality_suburb_4th_by_building_outline_id, (self.edit_dialog.building_outline_id, )) result = result.fetchall()[0][0] self.edit_dialog.cmb_suburb.setCurrentIndex( self.edit_dialog.cmb_suburb.findText(result)) # town city result = self.edit_dialog.db.execute_return( reference_select.town_city_name_by_building_outline_id, (self.edit_dialog.building_outline_id, )) result = result.fetchall() if result: self.edit_dialog.cmb_town.setCurrentIndex( self.edit_dialog.cmb_town.findText(result[0][0])) else: self.edit_dialog.cmb_town.setCurrentIndex(0) # territorial Authority result = self.edit_dialog.db.execute_return( reference_select.territorial_authority_name_by_building_outline_id, (self.edit_dialog.building_outline_id, )) result = result.fetchall()[0][0] self.edit_dialog.cmb_ta.setCurrentIndex( self.edit_dialog.cmb_ta.findText(result))
class EditGeometry(BulkLoadChanges): """Class to edit outline's geometry in buildings_bulk_load.bulk_load_outlines Inherits BulkLoadChanges""" def __init__(self, edit_dialog): """Constructor""" BulkLoadChanges.__init__(self, edit_dialog) iface.actionToggleEditing().trigger() # set editing to edit polygon iface.actionVertexTool().trigger() selecttools = iface.attributesToolBar().findChildren(QToolButton) # selection actions iface.building_toolbar.addSeparator() for sel in selecttools: if sel.text() == "Select Feature(s)": for a in sel.actions()[0:3]: iface.building_toolbar.addAction(a) # editing actions iface.building_toolbar.addSeparator() for dig in iface.digitizeToolBar().actions(): if dig.objectName() in ["mActionVertexTool", "mActionMoveFeature"]: iface.building_toolbar.addAction(dig) # advanced Actions iface.building_toolbar.addSeparator() for adv in iface.advancedDigitizeToolBar().actions(): if adv.objectName() in [ "mActionUndo", "mActionRedo", "mActionReshapeFeatures", "mActionOffsetCurve", "mActionSplitFeatures", ]: iface.building_toolbar.addAction(adv) iface.building_toolbar.show() self.disable_UI_functions() self.new_attrs = {} # @pyqtSlot(bool) def edit_save_clicked(self, commit_status): """When bulk load frame btn_edit_save clicked""" self.edit_dialog.db.open_cursor() _, capture_method_id, _, _, _, _ = self.get_comboboxes_values() self.edit_dialog.edit_geometry_saved.emit( list(self.edit_dialog.geoms.keys())) if len(self.edit_dialog.split_geoms) > 0: # insert into bulk_load_outlines table for qgsfId, geom in list(self.edit_dialog.split_geoms.items()): attributes = self.new_attrs[qgsfId] if not attributes[7]: attributes[7] = None sql = "SELECT buildings_bulk_load.bulk_load_outlines_insert(%s, NULL, 2, %s, %s, %s, %s, %s, %s);" result = self.edit_dialog.db.execute_no_commit( sql, ( self.edit_dialog.current_dataset, capture_method_id, attributes[5], attributes[6], attributes[7], attributes[8], geom, ), ) self.edit_dialog.outline_id = result.fetchall()[0][0] # insert into added table result = self.edit_dialog.db.execute_return( bulk_load_select. supplied_dataset_processed_date_by_dataset_id, (self.edit_dialog.current_dataset, ), ) processed_date = result.fetchall()[0][0] if processed_date: sql = "SELECT buildings_bulk_load.added_insert_bulk_load_outlines(%s, %s);" self.edit_dialog.db.execute_no_commit( sql, (self.edit_dialog.outline_id, 1)) for key in self.edit_dialog.geoms: sql = "SELECT buildings_bulk_load.bulk_load_outlines_update_shape(%s, %s);" self.edit_dialog.db.execute_no_commit( sql, (self.edit_dialog.geoms[key], key)) self.edit_dialog.db.execute_no_commit( "SELECT buildings_bulk_load.bulk_load_outlines_update_capture_method(%s, %s)", (key, capture_method_id), ) if self.parent_frame.__class__.__name__ == "AlterRelationships": self.parent_frame.repaint_view() self.disable_UI_functions() if commit_status: self.edit_dialog.db.commit_open_cursor() self.edit_dialog.geoms = {} self.new_attrs = {} self.edit_dialog.editing_layer.triggerRepaint() if len(self.edit_dialog.split_geoms) > 0: self.edit_reset_clicked() self.parent_frame.reload_bulk_load_layer() self.edit_dialog.split_geoms = {} # @pyqtSlot() def edit_reset_clicked(self): """When bulk load frame btn_reset_save clicked""" self.editing_layer.geometryChanged.disconnect(self.geometry_changed) iface.actionCancelEdits().trigger() self.editing_layer.geometryChanged.connect(self.geometry_changed) self.edit_dialog.geoms = {} self.edit_dialog.split_geoms = {} self.new_attrs = {} # restart editing iface.actionToggleEditing().trigger() iface.actionVertexTool().trigger() iface.activeLayer().removeSelection() # reset and disable comboboxes self.disable_UI_functions() # @pyqtSlot(int, QgsGeometry) def geometry_changed(self, qgsfId, geom): """ Called when feature is changed @param qgsfId: Id of added feature @type qgsfId: qgis.core.QgsFeature.QgsFeatureId @param geom: geometry of added feature @type geom: qgis.core.QgsGeometry """ # get new feature geom and convert to correct format result = self.edit_dialog.db.execute_return( bulk_load_select.bulk_load_status_id_by_outline_id, (qgsfId, )) result = result.fetchone() if result is not None: if result[0] == 3: iface.messageBar().pushMessage( "INFO", "You cannot edit the geometry of a removed outline.", level=Qgis.Info, duration=3, ) self.disable_UI_functions() self.edit_dialog.btn_edit_reset.setEnabled(1) return wkt = geom.asWkt() sql = general_select.convert_geometry result = self.edit_dialog.db.execute_return(sql, (wkt, )) self.edit_dialog.geom = result.fetchall()[0][0] result = self.edit_dialog.db.execute_return( bulk_load_select.bulk_load_outline_shape_by_id, (qgsfId, )) area = geom.area() if area < 10: iface.messageBar().pushMessage( "INFO", "You've edited the outline to less than 10sqm, are you sure this is correct?", level=Qgis.Info, duration=3, ) result = result.fetchall() if len(result) == 0: iface.messageBar().pushMessage( "CANNOT SPLIT/EDIT A NEWLY ADDED FEATURE", "You've tried to split/edit an outline that has just been created. You must first save this new outline to the db before splitting/editing it again.", level=Qgis.Warning, duration=5, ) self.edit_dialog.btn_edit_save.setDisabled(1) self.disable_UI_functions() self.edit_dialog.btn_edit_reset.setEnabled(1) return else: result = result[0][0] if self.edit_dialog.geom == result: if qgsfId in list(self.edit_dialog.geoms.keys()): del self.edit_dialog.geoms[qgsfId] self.disable_UI_functions() else: self.edit_dialog.geoms[qgsfId] = self.edit_dialog.geom self.enable_UI_functions() self.populate_edit_comboboxes() self.select_comboboxes_value() self.edit_dialog.activateWindow() self.edit_dialog.btn_edit_save.setDefault(True) # @pyqtSlot(int) def creator_feature_added(self, qgsfId): # get new feature geom request = QgsFeatureRequest().setFilterFid(qgsfId) new_feature = next(self.editing_layer.getFeatures(request)) self.new_attrs[qgsfId] = new_feature.attributes() if not self.new_attrs[qgsfId][5]: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n -------------------- CANNOT ADD NEW FEATURE ------" "-------------- \n\nYou've added a new feature, " "this can't be done in edit geometry, " "please switch to add outline.") self.error_dialog.show() self.disable_UI_functions() self.edit_dialog.btn_edit_reset.setEnabled(1) return new_geometry = new_feature.geometry() # calculate area area = new_geometry.area() if area < 10: iface.messageBar().pushMessage( "INFO", "You've created an outline that is less than 10sqm, are you sure this is correct?", level=Qgis.Info, duration=3, ) # convert to correct format wkt = new_geometry.asWkt() sql = general_select.convert_geometry result = self.edit_dialog.db.execute_return(sql, (wkt, )) self.edit_dialog.split_geoms[qgsfId] = result.fetchall()[0][0] def select_comboboxes_value(self): """Select the correct combobox value for the geometry""" self.edit_dialog.cmb_capture_method.setCurrentIndex( self.edit_dialog.cmb_capture_method.findText( "Trace Orthophotography"))
class EditAttribute(BulkLoadChanges): """Class to edit Attribute in buildings_bulk_load.bulk_load_outlines Inherits BulkLoadChanges""" def __init__(self, edit_dialog): """Constructor""" BulkLoadChanges.__init__(self, edit_dialog) # set editing to edit polygon iface.actionSelect().trigger() selecttools = iface.attributesToolBar().findChildren(QToolButton) # selection actions iface.building_toolbar.addSeparator() for sel in selecttools: if sel.text() == "Select Feature(s)": for a in sel.actions()[0:3]: iface.building_toolbar.addAction(a) iface.building_toolbar.show() self.disable_UI_functions() if len(iface.activeLayer().selectedFeatures()) > 0: if self.is_correct_selections(): self.get_selections() self.enable_UI_functions() self.populate_edit_comboboxes() self.select_comboboxes_value() else: self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None self.disable_UI_functions() # @pyqtSlot(bool) def edit_save_clicked(self, commit_status): """When bulk load frame btn_edit_save clicked""" self.edit_dialog.db.open_cursor() bulk_load_status_id, capture_method_id, capture_source_id, suburb, town, t_a = ( self.get_comboboxes_values()) # bulk load status ls_relationships = {"added": [], "matched": [], "related": []} if self.edit_dialog.cmb_status.currentText() == "Deleted During QA": # can only delete outlines if no relationship self.edit_dialog.description_del = ( self.edit_dialog.le_deletion_reason.text()) if len(self.edit_dialog.description_del) == 0: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n -------------------- EMPTY VALUE FIELD ------" '-------------- \n\n There are no "reason for deletion" entries ' ) self.error_dialog.show() self.disable_UI_functions() return ls_relationships = self.remove_compared_outlines() if (len(ls_relationships["matched"]) == 0 and len(ls_relationships["related"]) == 0): if len(self.edit_dialog.ids) > 0: # Send signal to LIQA through edit dialog self.edit_dialog.delete_outline_saved.emit( self.edit_dialog.ids, self.edit_dialog.description_del) for i in self.edit_dialog.ids: # check current status of building sql = bulk_load_select.bulk_load_status_id_by_outline_id current_status = self.edit_dialog.db.execute_no_commit( sql, (i, )) current_status = current_status.fetchall() if current_status[0][0] == 3: sql = "SELECT buildings_bulk_load.delete_deleted_description(%s);" self.edit_dialog.db.execute_no_commit(sql, (i, )) sql = "SELECT buildings_bulk_load.deletion_description_insert(%s, %s);" self.edit_dialog.db.execute_no_commit( sql, (i, self.edit_dialog.description_del)) # remove outline from added table sql = "SELECT buildings_bulk_load.added_delete_bulk_load_outlines(%s);" self.edit_dialog.db.execute_no_commit(sql, (i, )) sql = "SELECT buildings_bulk_load.bulk_load_outlines_update_attributes(%s, %s, %s, %s, %s, %s, %s);" self.edit_dialog.db.execute_no_commit( sql, ( i, bulk_load_status_id, capture_method_id, capture_source_id, suburb, town, t_a, ), ) self.editing_layer.removeSelection() else: for i in self.edit_dialog.ids: # check current status of building sql = bulk_load_select.bulk_load_status_id_by_outline_id current_status = self.edit_dialog.db.execute_no_commit( sql, (i, )) current_status = current_status.fetchall() if current_status[0][0] == 3: sql = "SELECT buildings_bulk_load.delete_deleted_description(%s);" self.edit_dialog.db.execute_no_commit(sql, (i, )) # change attributes sql = "SELECT buildings_bulk_load.bulk_load_outlines_update_attributes(%s, %s, %s, %s, %s, %s, %s);" self.edit_dialog.db.execute_no_commit( sql, ( i, bulk_load_status_id, capture_method_id, capture_source_id, suburb, town, t_a, ), ) self.editing_layer.removeSelection() self.disable_UI_functions() self.edit_dialog.completer_box() if commit_status: self.edit_dialog.db.commit_open_cursor() self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None # @pyqtSlot() def edit_reset_clicked(self): """When bulk load frame btn_reset_save clicked""" self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None iface.actionSelect().trigger() iface.activeLayer().removeSelection() # reset and disable comboboxes self.edit_dialog.circle_tool = None self.disable_UI_functions() # @pyqtSlot(list, list, bool) def selection_changed(self, added, removed, cleared): """Called when feature is selected""" # If no outlines are selected the function will return if len(self.editing_layer.selectedFeatures()) == 0: self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None self.disable_UI_functions() return if self.is_correct_selections(): self.get_selections() self.enable_UI_functions() self.populate_edit_comboboxes() self.select_comboboxes_value() else: self.edit_dialog.ids = [] self.edit_dialog.building_outline_id = None self.disable_UI_functions() def is_correct_selections(self): """Check if the selections meet the requirement""" feats = [] for feature in self.editing_layer.selectedFeatures(): ls = [] ls.append(feature.attributes()[3]) ls.append(feature.attributes()[4]) ls.append(feature.attributes()[5]) ls.append(feature.attributes()[6]) ls.append(feature.attributes()[7]) ls.append(feature.attributes()[8]) if ls not in feats: feats.append(ls) # if selected features have different attributes (not allowed) if len(feats) > 1: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n ---- MULTIPLE NON IDENTICAL FEATURES SELECTED" " ---- \n\n Can only edit attributes of multiple" "features when all existing attributes a" "re identical.") self.error_dialog.show() return False # if all selected features have the same attributes (allowed) elif len(feats) == 1: deleted = 0 reasons = [] for feature in self.editing_layer.selectedFeatures(): sql = bulk_load_select.bulk_load_status_id_by_outline_id result = self.edit_dialog.db.execute_return( sql, (feature["bulk_load_outline_id"], )) bl_status = result.fetchall()[0][0] if bl_status == 3: deleted = deleted + 1 sql = bulk_load_select.deletion_description_by_bulk_load_id result = self.edit_dialog.db.execute_return( sql, (feature["bulk_load_outline_id"], )) reason = result.fetchall()[0][0] if reason not in reasons: reasons.append(reason) if deleted > 0: if deleted == len(self.editing_layer.selectedFeatures()): if self.parent_frame.btn_compare_outlines.isEnabled(): if len(reasons) <= 1: return True else: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n ---- DIFFERING DELETION REASONS ---- \n\n" "Cannot edit deleted features as have differing" " reasons for deletion. Please edit individually.\n" ) self.error_dialog.show() return False else: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n ---- CANNOT EDIT DELETED FEATURE ---- \n\n" "Cannot edit deleted feature after comparison has been" " run, instead please add this feature manually.\n" "Note: Don't forget to update the relationship too!" ) self.error_dialog.show() return False else: return True return False def get_selections(self): """Return the selection values""" self.edit_dialog.ids = [ feat.id() for feat in self.editing_layer.selectedFeatures() ] self.edit_dialog.bulk_load_outline_id = self.edit_dialog.ids[0] bulk_load_feat = [ feat for feat in self.editing_layer.selectedFeatures() ][0] bulk_load_geom = bulk_load_feat.geometry() # convert to correct format wkt = bulk_load_geom.asWkt() sql = general_select.convert_geometry result = self.edit_dialog.db.execute_return(sql, (wkt, )) self.edit_dialog.geom = result.fetchall()[0][0] def select_comboboxes_value(self): """Select the correct combobox value for the geometry""" # bulk load status result = self.edit_dialog.db.execute_return( bulk_load_select.bulk_load_status_value_by_outline_id, (self.edit_dialog.bulk_load_outline_id, ), ) result = result.fetchall()[0][0] self.edit_dialog.cmb_status.setCurrentIndex( self.edit_dialog.cmb_status.findText(result)) # reason for deletion if self.edit_dialog.cmb_status.currentText() == "Deleted During QA": reason = bulk_load_select.deletion_description_by_bulk_load_id reason = self.edit_dialog.db.execute_return( reason, (self.edit_dialog.bulk_load_outline_id, )) reason = reason.fetchall()[0][0] self.edit_dialog.le_deletion_reason.setText(reason) # capture method result = self.edit_dialog.db.execute_return( common_select.capture_method_value_by_bulk_outline_id, (self.edit_dialog.bulk_load_outline_id, ), ) result = result.fetchall()[0][0] self.edit_dialog.cmb_capture_method.setCurrentIndex( self.edit_dialog.cmb_capture_method.findText(result)) # capture source result = self.edit_dialog.db.execute_return( common_select. capture_source_group_value_external_by_bulk_outline_id, (self.edit_dialog.bulk_load_outline_id, ), ) result = result.fetchall()[0] text = "- ".join(result) self.edit_dialog.cmb_capture_source.setCurrentIndex( self.edit_dialog.cmb_capture_source.findText(text)) # suburb result = self.edit_dialog.db.execute_return( reference_select.suburb_locality_suburb_4th_by_bulk_outline_id, (self.edit_dialog.bulk_load_outline_id, ), ) result = result.fetchall()[0][0] self.edit_dialog.cmb_suburb.setCurrentIndex( self.edit_dialog.cmb_suburb.findText(result)) # town city result = self.edit_dialog.db.execute_return( reference_select.town_city_name_by_bulk_outline_id, (self.edit_dialog.bulk_load_outline_id, ), ) result = result.fetchall() if result: self.edit_dialog.cmb_town.setCurrentIndex( self.edit_dialog.cmb_town.findText(result[0][0])) else: self.edit_dialog.cmb_town.setCurrentIndex(0) # territorial Authority result = self.edit_dialog.db.execute_return( reference_select.territorial_authority_name_by_bulk_outline_id, (self.edit_dialog.bulk_load_outline_id, ), ) result = result.fetchall()[0][0] self.edit_dialog.cmb_ta.setCurrentIndex( self.edit_dialog.cmb_ta.findText(result)) def remove_compared_outlines(self): """called to check can mark outline for deletion""" added_outlines = self.edit_dialog.db.execute_no_commit( bulk_load_select.added_outlines_by_dataset_id, (self.edit_dialog.current_dataset, ), ) added_outlines = added_outlines.fetchall() matched_outlines = self.edit_dialog.db.execute_no_commit( bulk_load_select.matched_outlines_by_dataset_id, (self.edit_dialog.current_dataset, ), ) matched_outlines = matched_outlines.fetchall() related_outlines = self.edit_dialog.db.execute_no_commit( bulk_load_select.related_outlines_by_dataset_id, (self.edit_dialog.current_dataset, ), ) related_outlines = related_outlines.fetchall() if len(self.edit_dialog.ids) > 0: # if there is more than one feature to update ls_relationships = {"added": [], "matched": [], "related": []} for item in self.edit_dialog.ids: # added if (item, ) in added_outlines: ls_relationships["added"].append(item) # matched if (item, ) in matched_outlines: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n --------------- RELATIONSHIP EXISTS ---------" "-------\n\nCan only mark for deletion outline if" " no relationship exists") self.error_dialog.show() ls_relationships["matched"].append(item) break # related if (item, ) in related_outlines: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n ------------------- RELATIONSHIP EXISTS ---------" "---------- \n\nCan only mark for deletion outline if" " no relationship exists") self.error_dialog.show() ls_relationships["related"].append(item) break return ls_relationships
class BulkLoadFrame(QFrame, FORM_CLASS): """Bulk Load outlines frame class""" closed = pyqtSignal() def __init__(self, dockwidget, parent=None): """Constructor.""" super(BulkLoadFrame, self).__init__(parent) self.setupUi(self) # Frame fields self.dockwidget = dockwidget self.layer_registry = LayerRegistry() # Set up pop-up dialog self.check_dialog = CheckDialog() self.error_dialog = None self.edit_dialog = None # bulk load changes instance self.change_instance = None # layer set up self.historic_layer = None self.bulk_load_layer = None # database setup self.db = db db.connect() # selection colour iface.mapCanvas().setSelectionColor(QColor("Yellow")) # set up confirmation message box self.msgbox_bulk_load = self.confirmation_dialog_box("bulk load") self.msgbox_compare = self.confirmation_dialog_box("compare") self.msgbox_publish = self.confirmation_dialog_box("publish") self.grpb_layers.hide() # Find current supplied dataset result = self.db._execute( bulk_load_select.supplied_dataset_count_processed_date_is_null) result = result.fetchall()[0][0] # if there is an unprocessed dataset if result > 1: # error self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n ---------------------- DATASET ERROR ---------" "----------------- \n\nThere are multiple not processed" " datasets. Please fix database tables before continuing") self.error_dialog.show() self.display_dataset_error() elif result == 1: p_result = self.db._execute( bulk_load_select.supplied_dataset_processed_date_is_null) self.current_dataset = p_result.fetchall()[0][0] self.lb_dataset_id.setText(str(self.current_dataset)) self.add_outlines() self.display_current_bl_not_compared() self.grpb_layers.show() # Setup edit dialog self.edit_dialog = EditDialog(self) # if all datasets are processed else: result2 = self.db._execute( bulk_load_select.supplied_dataset_count_transfer_date_is_null) result2 = result2.fetchall()[0][0] # if there is a processed but not transferred dataset if result > 1: # error self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n ---------------------- DATASET ERROR ---------" "----------------- \n\nThere are multiple not transferred" " datasets. Please fix database tables before continuing") self.error_dialog.show() self.display_dataset_error() elif result2 == 1: t_result = self.db._execute( bulk_load_select.supplied_dataset_transfer_date_is_null) self.current_dataset = t_result.fetchall()[0][0] self.lb_dataset_id.setText(str(self.current_dataset)) self.add_outlines() self.display_not_published() self.grpb_layers.show() # Setup edit dialog self.edit_dialog = EditDialog(self) # No current dataset is being worked on else: self.current_dataset = None self.lb_dataset_id.setText("None") self.display_no_bulk_load() self.cmb_capture_src_grp.currentIndexChanged.connect( self.cmb_capture_src_grp_changed) # initiate le_data_description self.le_data_description.setMaxLength(250) self.le_data_description.setPlaceholderText("Data Description") # set up signals and slots self.rad_external_id.toggled.connect( partial(bulk_load.enable_external_bulk, self)) self.ml_outlines_layer.currentIndexChanged.connect( partial(bulk_load.populate_external_fcb, self)) self.btn_bl_save.clicked.connect( partial(self.bulk_load_save_clicked, True)) self.btn_bl_reset.clicked.connect(self.bulk_load_reset_clicked) self.btn_compare_outlines.clicked.connect( partial(self.compare_outlines_clicked, True)) self.btn_alter_rel.clicked.connect(self.alter_relationships_clicked) self.btn_publish.clicked.connect(partial(self.publish_clicked, True)) self.btn_exit.clicked.connect(self.exit_clicked) self.cb_bulk_load.clicked.connect(self.cb_bulk_load_clicked) self.cb_removed.clicked.connect(self.cb_removed_clicked) self.cb_added.clicked.connect(self.cb_added_clicked) QgsProject.instance().layerWillBeRemoved.connect(self.layers_removed) def confirmation_dialog_box(self, button_text): return QMessageBox( QMessageBox.Question, button_text.upper(), "Are you sure you want to %s outlines?" % button_text, buttons=QMessageBox.No | QMessageBox.Yes, ) def confirm(self, msgbox): reply = msgbox.exec_() if reply == QMessageBox.Yes: return True return False def setup_toolbar(self): if "Add Outline" not in ( action.text() for action in iface.building_toolbar.actions()): image_dir = os.path.join(__location__, "..", "icons") icon_path = os.path.join(image_dir, "plus.png") icon = QIcon() icon.addFile(icon_path, QSize(8, 8)) self.add_action = QAction(icon, "Add Outline", iface.building_toolbar) iface.registerMainWindowAction(self.add_action, "Ctrl+1") self.add_action.triggered.connect(self.canvas_add_outline) iface.building_toolbar.addAction(self.add_action) if "Edit Geometry" not in ( action.text() for action in iface.building_toolbar.actions()): image_dir = os.path.join(__location__, "..", "icons") icon_path = os.path.join(image_dir, "edit_geometry.png") icon = QIcon() icon.addFile(icon_path, QSize(8, 8)) self.edit_geom_action = QAction(icon, "Edit Geometry", iface.building_toolbar) iface.registerMainWindowAction(self.edit_geom_action, "Ctrl+2") self.edit_geom_action.triggered.connect(self.canvas_edit_geometry) iface.building_toolbar.addAction(self.edit_geom_action) if "Edit Attributes" not in ( action.text() for action in iface.building_toolbar.actions()): image_dir = os.path.join(__location__, "..", "icons") icon_path = os.path.join(image_dir, "edit_attributes.png") icon = QIcon() icon.addFile(icon_path, QSize(8, 8)) self.edit_attrs_action = QAction(icon, "Edit Attributes", iface.building_toolbar) iface.registerMainWindowAction(self.edit_attrs_action, "Ctrl+3") self.edit_attrs_action.triggered.connect( self.canvas_edit_attribute) iface.building_toolbar.addAction(self.edit_attrs_action) iface.building_toolbar.show() def display_dataset_error(self): """UI Display when there are multiple supplied datasets.""" self.current_dataset = None self.lb_dataset_id.setText("None") self.grpb_bulk_load.hide() iface.building_toolbar.hide() self.btn_compare_outlines.setDisabled(1) self.btn_alter_rel.setDisabled(1) self.btn_publish.setDisabled(1) def display_no_bulk_load(self): """UI Display When there is no Current dataset.""" self.grpb_bulk_load.show() bulk_load.populate_bulk_comboboxes(self) self.ml_outlines_layer.setEnabled(1) self.rad_external_id.setEnabled(1) self.rad_external_id.setChecked(False) self.fcb_external_id.setDisabled(1) self.cmb_capture_src_grp.setEnabled(1) self.cmb_capture_src_grp.setCurrentIndex(0) self.cmb_cap_src_area.setEnabled(1) self.le_data_description.setEnabled(1) self.le_data_description.clear() self.cmb_capture_method.setEnabled(1) self.cmb_capture_method.setCurrentIndex(0) self.cmb_organisation.setEnabled(1) self.cmb_organisation.setCurrentIndex(0) self.btn_bl_save.show() self.btn_bl_reset.show() self.current_dataset = None self.lb_dataset_id.setText("None") self.btn_compare_outlines.setDisabled(1) self.btn_alter_rel.setDisabled(1) self.btn_publish.setDisabled(1) self.add_historic_outlines() self.l_cs_area_title.setText("") iface.building_toolbar.hide() def display_data_exists(self): """ Display setup when data has been bulk loaded - subfunction of: display_not_published & display_current_bl_not_compared """ bulk_load.populate_bulk_comboboxes(self) bulk_load.load_current_fields(self) self.grpb_bulk_load.show() self.ml_outlines_layer.setDisabled(1) self.rad_external_id.setDisabled(1) self.fcb_external_id.setDisabled(1) self.cmb_capture_src_grp.setDisabled(1) self.cmb_cap_src_area.setDisabled(1) self.le_data_description.setDisabled(1) self.cmb_capture_method.setDisabled(1) self.cmb_organisation.setDisabled(1) self.btn_bl_save.hide() self.btn_bl_reset.hide() sql = reference_select.capture_source_area_name_by_supplied_dataset area_id = self.db._execute(sql, (self.current_dataset, )) area_id = area_id.fetchall() if area_id is not None: self.l_cs_area_title.setText(area_id[0][0]) else: self.l_cs_area_title.setText("") def display_not_published(self): """ UI display when there is a dataset that hasn't been published. """ self.display_data_exists() self.btn_compare_outlines.setDisabled(1) self.btn_publish.setEnabled(1) self.setup_toolbar() def display_current_bl_not_compared(self): """ UI Display when there is a dataset that hasn't been compared. """ self.display_data_exists() self.btn_compare_outlines.setEnabled(1) sql = reference_select.capture_source_area_name_by_supplied_dataset area_id = self.db._execute(sql, (self.current_dataset, )) if area_id is not None: self.area_id = area_id.fetchall() if len(self.area_id) > 0: self.area_id = self.area_id[0][0] self.l_cs_area_title.setText(self.area_id) else: self.area_id = None self.l_cs_area_title.setText("") self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n ---------------------- NO CAPTURE SOURCE AREA ---------" "----------------- \n\nThere is no area id, please fix in database" ) self.error_dialog.show() self.display_dataset_error() self.btn_compare_outlines.setDisabled(1) return self.btn_alter_rel.setDisabled(1) self.btn_publish.setDisabled(1) self.setup_toolbar() def add_outlines(self): """ Add bulk load outlines of current dataset to canvas. """ path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "styles/") # add the bulk_load_outlines to the layer registry self.bulk_load_layer = self.layer_registry.add_postgres_layer( "bulk_load_outlines", "bulk_load_outlines", "shape", "buildings_bulk_load", "", "supplied_dataset_id = {0}".format(self.current_dataset), ) self.bulk_load_layer.loadNamedStyle(path + "building_editing.qml") iface.setActiveLayer(self.bulk_load_layer) def add_historic_outlines(self): path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "styles/") self.historic_layer = self.layer_registry.add_postgres_layer( "loaded_datasets", "bulk_load_outlines", "shape", "buildings_bulk_load", "", "") self.historic_layer.loadNamedStyle(path + "building_historic.qml") @pyqtSlot(int) def cmb_capture_src_grp_changed(self, index): self.cmb_cap_src_area.clear() id_capture_src_grp = self.ids_capture_src_grp[index] result = self.db._execute( common_select. capture_source_external_id_and_area_title_by_group_id, (id_capture_src_grp, )) ls = result.fetchall() for (external_id, area_title) in reversed(ls): text = external_id + "- " + area_title self.cmb_cap_src_area.addItem(text) @pyqtSlot(bool) def cb_bulk_load_clicked(self, checked): layer_tree_layer = QgsProject.instance().layerTreeRoot().findLayer( self.bulk_load_layer.id()) layer_tree_model = iface.layerTreeView().model() categories = layer_tree_model.layerLegendNodes(layer_tree_layer) bulk_category = [ ln for ln in categories if ln.data(Qt.DisplayRole) == "Bulk Loaded" ] if checked: bulk_category[0].setData(Qt.Checked, Qt.CheckStateRole) else: bulk_category[0].setData(Qt.Unchecked, Qt.CheckStateRole) @pyqtSlot(bool) def cb_added_clicked(self, checked): layer_tree_layer = QgsProject.instance().layerTreeRoot().findLayer( self.bulk_load_layer.id()) layer_tree_model = iface.layerTreeView().model() categories = layer_tree_model.layerLegendNodes(layer_tree_layer) added_category = [ ln for ln in categories if ln.data(Qt.DisplayRole) == "Added During QA" ] added_edit_category = [ ln for ln in categories if ln.data(Qt.DisplayRole) == "Added- to be saved" ] if checked: added_category[0].setData(Qt.Checked, Qt.CheckStateRole) added_edit_category[0].setData(Qt.Checked, Qt.CheckStateRole) else: added_category[0].setData(Qt.Unchecked, Qt.CheckStateRole) added_edit_category[0].setData(Qt.Unchecked, Qt.CheckStateRole) @pyqtSlot(bool) def cb_removed_clicked(self, checked): layer_tree_layer = QgsProject.instance().layerTreeRoot().findLayer( self.bulk_load_layer.id()) layer_tree_model = iface.layerTreeView().model() categories = layer_tree_model.layerLegendNodes(layer_tree_layer) removed_category = [ ln for ln in categories if ln.data(Qt.DisplayRole) == "Removed During QA" ] if checked: removed_category[0].setData(Qt.Checked, Qt.CheckStateRole) else: removed_category[0].setData(Qt.Unchecked, Qt.CheckStateRole) @pyqtSlot(bool) def bulk_load_save_clicked(self, commit_status): """ When bulk load outlines save clicked """ if self.confirm(self.msgbox_bulk_load): QApplication.setOverrideCursor(Qt.WaitCursor) bulk_load.bulk_load(self, commit_status) # find if adding was successful result = self.db._execute( bulk_load_select.supplied_dataset_count_both_dates_are_null) result = result.fetchall()[0][0] # if bulk loading completed without errors if result == 1: QgsProject.instance().layerWillBeRemoved.disconnect( self.layers_removed) self.layer_registry.remove_layer(self.historic_layer) QgsProject.instance().layerWillBeRemoved.connect( self.layers_removed) self.cmb_capture_src_grp.currentIndexChanged.disconnect( self.cmb_capture_src_grp_changed) self.add_outlines() self.display_current_bl_not_compared() QApplication.restoreOverrideCursor() self.edit_dialog = EditDialog(self) @pyqtSlot() def bulk_load_reset_clicked(self): """ When bulk Load reset clicked """ self.cmb_capture_method.setCurrentIndex(0) self.ml_outlines_layer.setCurrentIndex(0) self.cmb_organisation.setCurrentIndex(0) self.le_data_description.clear() self.rad_external_id.setChecked(False) @pyqtSlot(bool) def compare_outlines_clicked(self, commit_status): """ When compare outlines clicked """ if self.confirm(self.msgbox_compare): QApplication.setOverrideCursor(Qt.WaitCursor) self.edit_cancel_clicked() comparisons.compare_outlines(self, commit_status) self.btn_publish.setEnabled(1) self.btn_compare_outlines.setDisabled(1) self.btn_alter_rel.setEnabled(1) QApplication.restoreOverrideCursor() def canvas_add_outline(self): """ When add outline radio button toggled """ self.edit_dialog.add_outline() self.edit_dialog.show() self.change_instance = self.edit_dialog.get_change_instance() self.circle_tool = None self.polyline = None # setup circle button image_dir = os.path.join(__location__, "..", "icons") icon_path = os.path.join(image_dir, "circle.png") icon = QIcon() icon.addFile(icon_path, QSize(8, 8)) self.circle_action = QAction(icon, "Draw Circle", iface.building_toolbar) iface.registerMainWindowAction(self.circle_action, "Ctrl+0") self.circle_action.triggered.connect(self.circle_tool_clicked) self.circle_action.setCheckable(True) iface.building_toolbar.addAction(self.circle_action) def circle_tool_clicked(self): if self.circle_action.isChecked(): circle_tool.setup_circle(self) else: iface.actionAddFeature().trigger() def canvas_edit_attribute(self): """ When edit outline radio button toggled """ self.edit_dialog.show() self.edit_dialog.edit_attribute() self.change_instance = self.edit_dialog.get_change_instance() self.change_instance.populate_edit_comboboxes() def canvas_edit_geometry(self): """ When edit geometry radio button toggled """ self.edit_dialog.edit_geometry() self.edit_dialog.show() self.change_instance = self.edit_dialog.get_change_instance() def edit_cancel_clicked(self): """ When cancel clicked """ if len(QgsProject.instance().mapLayersByName( "bulk_load_outlines")) > 0: if isinstance(self.change_instance, bulk_load_changes.EditAttribute): try: self.bulk_load_layer.selectionChanged.disconnect( self.change_instance.selection_changed) except TypeError: pass elif isinstance(self.change_instance, bulk_load_changes.EditGeometry): try: self.bulk_load_layer.geometryChanged.disconnect( self.change_instance.geometry_changed) except TypeError: pass try: self.bulk_load_layer.featureAdded.disconnect() except TypeError: pass elif isinstance(self.change_instance, bulk_load_changes.AddBulkLoad): try: self.bulk_load_layer.featureAdded.disconnect() except TypeError: pass try: self.bulk_load_layer.featureDeleted.disconnect() except TypeError: pass try: self.bulk_load_layer.geometryChanged.disconnect() except TypeError: pass if self.polyline: self.polyline.reset() if isinstance(self.circle_tool, PointTool): self.circle_tool.canvas_clicked.disconnect() self.circle_tool.mouse_moved.disconnect() self.circle_tool.deactivate() iface.actionPan().trigger() iface.actionCancelEdits().trigger() self.setup_toolbar() self.change_instance = None @pyqtSlot() def alter_relationships_clicked(self): """ When alter relationships button clicked open alter relationships frame """ if self.change_instance is not None: self.edit_dialog.close() self.db.close_connection() QgsProject.instance().layerWillBeRemoved.disconnect( self.layers_removed) self.layer_registry.remove_layer(self.bulk_load_layer) for action in iface.building_toolbar.actions(): if action.objectName() not in ["mActionPan"]: iface.building_toolbar.removeAction(action) iface.building_toolbar.hide() dw = self.dockwidget dw.stk_options.removeWidget(dw.stk_options.currentWidget()) dw.new_widget(AlterRelationships(dw, self.current_dataset)) @pyqtSlot(bool) def publish_clicked(self, commit_status): """ When publish button clicked """ if not self.check_duplicate_ids(): return if self.confirm(self.msgbox_publish): QApplication.setOverrideCursor(Qt.WaitCursor) if self.change_instance is not None: self.edit_dialog.close() self.db.open_cursor() sql = "SELECT buildings_bulk_load.load_building_outlines(%s);" self.db.execute_no_commit(sql, (self.current_dataset, )) if commit_status: self.db.commit_open_cursor() self.display_no_bulk_load() self.cmb_capture_src_grp.currentIndexChanged.connect( self.cmb_capture_src_grp_changed) self.current_dataset = None self.lb_dataset_id.setText("None") QgsProject.instance().layerWillBeRemoved.disconnect( self.layers_removed) self.layer_registry.remove_layer(self.bulk_load_layer) self.add_historic_outlines() QApplication.restoreOverrideCursor() self.grpb_layers.hide() QgsProject.instance().layerWillBeRemoved.connect( self.layers_removed) def check_duplicate_ids(self): """ Check same ids in different tables (added/matched/related) """ result = self.run_check() if not result: return True else: self.check_dialog.show() self.check_dialog.set_message("FAILED: duplicate id(s) found.") self.check_dialog.set_data(result) return False def run_check(self): """ Run check and return the output data """ result = self.db._execute( bulk_load_select.added_outlines_by_dataset_id, (self.current_dataset, )) added_outlines = result.fetchall() result = self.db._execute( bulk_load_select.matched_outlines_by_dataset_id, (self.current_dataset, )) matched_outlines = result.fetchall() result = self.db._execute( bulk_load_select.related_outlines_by_dataset_id, (self.current_dataset, )) related_outlines = result.fetchall() ids_added_matched = self.find_match_ids(added_outlines, matched_outlines) ids_added_related = self.find_match_ids(added_outlines, related_outlines) ids_matched_related = self.find_match_ids(matched_outlines, related_outlines) data = self.get_error_data(ids_added_matched, ids_added_related, ids_matched_related) return data def find_match_ids(self, ids_1, ids_2): return list(set(ids_1) & set(ids_2)) def get_error_data(self, ids_added_matched, ids_added_related, ids_matched_related): """ Return the output data """ data = [] for (feat_id, ) in ids_added_matched: data.append((feat_id, "Added", "Matched")) for (feat_id, ) in ids_added_related: data.append((feat_id, "Added", "Related")) for (feat_id, ) in ids_matched_related: data.append((feat_id, "Matched", "Related")) return data @pyqtSlot() def exit_clicked(self): """ Called when bulk load frame exit button clicked. """ self.close_frame() self.dockwidget.lst_sub_menu.clearSelection() def close_frame(self): """ Clean up and remove the bulk load frame. """ if self.change_instance is not None: self.edit_dialog.close() QgsProject.instance().layerWillBeRemoved.disconnect( self.layers_removed) iface.actionCancelEdits().trigger() if self.historic_layer is not None: self.layer_registry.remove_layer(self.historic_layer) if self.bulk_load_layer is not None: self.layer_registry.remove_layer(self.bulk_load_layer) from buildings.gui.menu_frame import MenuFrame dw = self.dockwidget dw.stk_options.removeWidget(dw.stk_options.currentWidget()) dw.new_widget(MenuFrame(dw)) for action in iface.building_toolbar.actions(): if action.text() not in ["Pan Map"]: iface.building_toolbar.removeAction(action) iface.building_toolbar.hide() @pyqtSlot(str) def layers_removed(self, layerids): self.layer_registry.update_layers() if "bulk_load_outlines" in layerids: self.btn_compare_outlines.setDisabled(1) self.btn_alter_rel.setDisabled(1) self.btn_publish.setDisabled(1) self.cb_bulk_load.setDisabled(1) self.cb_added.setDisabled(1) self.cb_removed.setDisabled(1) for action in iface.building_toolbar.actions(): if action.text() not in [ "Pan Map", "Add Outline", "Edit Geometry", "Edit Attributes" ]: iface.building_toolbar.removeAction(action) if action.text() in [ "Add Outline", "Edit Geometry", "Edit Attributes" ]: action.setDisabled(True) else: action.setEnabled(True) iface.messageBar().pushMessage( "ERROR", "Required layer Removed! Please reload the buildings plugin or the current frame before continuing", level=Qgis.Critical, duration=5, ) return if "loaded_datasets" in layerids: iface.messageBar().pushMessage( "ERROR", "Required layer Removed! Please reload the buildings plugin or the current frame before continuing", level=Qgis.Critical, duration=5, ) # disable bulk loading buttons self.btn_bl_save.setDisabled(1) self.btn_bl_reset.setDisabled(1) return def reload_bulk_load_layer(self): """To ensure QGIS has most up to date ID for the newly split feature see #349""" self.cb_added_clicked(False) self.cb_added_clicked(True)
class UpdateReferenceData(QFrame, FORM_CLASS): def __init__(self, dockwidget, parent=None): """Constructor.""" super(UpdateReferenceData, self).__init__(parent) self.setupUi(self) self.dockwidget = dockwidget self.db = db self.db.connect() self.error_dialog = None self.message = "" self.msgbox = self.message_box() self.btn_view_key.setIcon( QIcon( os.path.join(__location__, "..", "icons", "view_password.png"))) # disable all check boxes if a curret dataset exists sql = bulk_load_select.supplied_dataset_latest_id_and_dates result = self.db.execute_return(sql) if result is None: self.enable_checkboxes() self.le_key.setDisabled(1) self.btn_view_key.setDisabled(1) else: result = result.fetchone() process = result[1] transfer = result[2] if process is not None and transfer is not None: self.enable_checkboxes() self.le_key.setDisabled(1) self.btn_view_key.setDisabled(1) else: self.disable_checkboxes() # set up signals and slots self.btn_view_key.pressed.connect(self.view_key) self.btn_view_key.released.connect(self.hide_key) self.le_key.editingFinished.connect(self.hide_key) self.grbx_topo.toggled.connect(self.check_all_topo) self.grbx_admin.toggled.connect(self.check_all_admin) self.btn_exit.clicked.connect(self.exit_clicked) self.btn_update.clicked.connect( partial(self.update_clicked, commit_status=True)) for box in self.grbx_topo.findChildren(QCheckBox): box.clicked.connect(self.chbx_clicked) def close_cursor(self): self.db.close_cursor() def connect(self): self.db.connect() def enable_checkboxes(self): """Enable frame""" self.grbx_topo.setEnabled(1) self.grbx_admin.setEnabled(1) self.chbx_canals.setEnabled(1) self.chbx_coastline_and_islands.setEnabled(1) self.chbx_lagoons.setEnabled(1) self.chbx_lakes.setEnabled(1) self.chbx_ponds.setEnabled(1) self.chbx_rivers.setEnabled(1) self.chbx_swamps.setEnabled(1) self.chbx_huts.setEnabled(1) self.chbx_shelters.setEnabled(1) self.chbx_bivouacs.setEnabled(1) self.chbx_protected_areas.setEnabled(1) self.chbx_suburbs.setEnabled(1) self.chbx_town.setEnabled(1) self.chbx_ta.setEnabled(1) self.btn_update.setEnabled(1) # clear message self.lb_message.setText("") def disable_checkboxes(self): """Disable frame (when outlines dataset in progress)""" self.le_key.setDisabled(1) self.grbx_topo.setDisabled(1) self.grbx_admin.setDisabled(1) self.chbx_canals.setDisabled(1) self.chbx_coastline_and_islands.setDisabled(1) self.chbx_lagoons.setDisabled(1) self.chbx_lakes.setDisabled(1) self.chbx_ponds.setDisabled(1) self.chbx_rivers.setDisabled(1) self.chbx_swamps.setDisabled(1) self.chbx_huts.setDisabled(1) self.chbx_shelters.setDisabled(1) self.chbx_bivouacs.setDisabled(1) self.chbx_protected_areas.setDisabled(1) self.chbx_suburbs.setDisabled(1) self.chbx_town.setDisabled(1) self.chbx_ta.setDisabled(1) self.btn_view_key.setDisabled(1) self.btn_update.setDisabled(1) # add message self.lb_message.setText( "\nNOTE: You can't update reference data with\n a dataset in progress \n" ) @pyqtSlot() def view_key(self): """Called when view key button pressed""" self.le_key.setEchoMode(QLineEdit.Normal) @pyqtSlot() def hide_key(self): """Called when view key button released/editing of text finished""" self.le_key.setEchoMode(QLineEdit.Password) @pyqtSlot() def update_clicked(self, commit_status=True): """Called when update btn clicked""" # set cursor to busy QApplication.setOverrideCursor(Qt.WaitCursor) # setup self.message = "" self.api_key = self.le_key.text() self.updates = [] # canals if self.chbx_canals.isChecked(): self.topo_layer_processing("canal_polygons") # lagoon if self.chbx_lagoons.isChecked(): self.topo_layer_processing("lagoon_polygons") # lake if self.chbx_lakes.isChecked(): self.topo_layer_processing("lake_polygons") # pond if self.chbx_ponds.isChecked(): self.topo_layer_processing("pond_polygons") # rivers if self.chbx_rivers.isChecked(): self.topo_layer_processing("river_polygons") # swamp if self.chbx_swamps.isChecked(): self.topo_layer_processing("swamp_polygons") # huts if self.chbx_huts.isChecked(): self.topo_layer_processing("hut_points") # shelters if self.chbx_shelters.isChecked(): self.topo_layer_processing("shelter_points") # bivouacs if self.chbx_bivouacs.isChecked(): self.topo_layer_processing("bivouac_points") # protected areas if self.chbx_protected_areas.isChecked(): self.topo_layer_processing("protected_areas_polygons") # coastlines and islands (placeholder) if self.chbx_coastline_and_islands.isChecked(): self.message += "The coastlines and islands table must be updated manually" if self.db._open_cursor is None: self.db.open_cursor() # suburb localities if self.chbx_suburbs.isChecked(): # update building_outlines suburb values (changed, deleted & added) # delete remove suburbs and update modified suburbs db.execute_no_commit( "SELECT buildings_reference.building_outlines_update_changed_and_deleted_suburb();" ) # add new suburbs and update building outlines db.execute_no_commit( "SELECT buildings_reference.building_outlines_update_added_suburb();" ) # update messages and log self.update_message("updated", "suburb_locality") self.updates.append("suburb_locality") # town_city if self.chbx_town.isChecked(): town_list = [] # delete existing areas where the external id is no longer in the town_city table result = db.execute_no_commit( "SELECT buildings_reference.town_city_delete_removed_areas();") if result is not None: town_list.extend(result.fetchone()[0]) # modify all existing areas to check they are up to date result = db.execute_no_commit( "SELECT buildings_reference.town_city_insert_new_areas();") if result is not None: town_list.extend(result.fetchone()[0]) # insert into table ids in nz_localities that are not in town_city result = db.execute_no_commit( "SELECT buildings_reference.town_city_update_areas();") if result is not None: town_list.extend(result.fetchone()[0]) # update bulk_load_outlines town/city values db.execute_no_commit( "SELECT buildings_bulk_load.bulk_load_outlines_update_all_town_cities(%s);", (town_list, ), ) # update building outlines town/city values db.execute_no_commit( "SELECT buildings.building_outlines_update_town_city(%s);", (town_list, )) # update messages and log self.update_message("updated", "town_city") self.updates.append("town_city") # territorial authority and grid if self.chbx_ta.isChecked(): ta_list = [] # delete removed TA areas result = db.execute_no_commit( "SELECT buildings_reference.territorial_auth_delete_areas();") if result is not None: ta_list.extend(result.fetchone()[0]) # Insert TA areas result = db.execute_no_commit( "SELECT buildings_reference.territorial_auth_insert_areas();") if result is not None: ta_list.extend(result.fetchone()[0]) # Update new TA areas result = db.execute_no_commit( "SELECT buildings_reference.territorial_auth_update_areas();") if result is not None: ta_list.extend(result.fetchone()[0]) # update bulk_load_outlines territorial authority values db.execute_no_commit( "SELECT buildings_bulk_load.bulk_load_outlines_update_all_territorial_authorities(%s);", (ta_list, ), ) # update building outlines territorial authority values db.execute_no_commit( "SELECT buildings.building_outlines_update_territorial_authority(%s);", (ta_list, ), ) # update message and log self.update_message("updated", "territorial_authority") self.updates.append("territorial_authority") # refresh grid db.execute_no_commit(reference_select.refresh_ta_grid_view) self.update_message("updated", "territorial_authority_grid") self.updates.append("territorial_authority_grid") # create log for this update if len(self.updates) > 0: sql = "SELECT buildings_reference.reference_update_log_insert_log(%s);" self.db.execute_no_commit(sql, (self.updates, )) # restore cursor QApplication.restoreOverrideCursor() # final message box if self.message == "": self.message = "No layers were updated." self.msgbox.setText(self.message) self.msgbox.exec_() if commit_status: self.db.commit_open_cursor() @pyqtSlot() def exit_clicked(self): """ Called when new entry exit button clicked. """ self.close_frame() self.dockwidget.lst_sub_menu.clearSelection() def close_frame(self): """ Clean up and remove the new entry frame. """ self.db.close_connection() from buildings.gui.menu_frame import MenuFrame dw = self.dockwidget dw.stk_options.removeWidget(dw.stk_options.currentWidget()) dw.new_widget(MenuFrame(dw)) @pyqtSlot() def check_all_topo(self): """ Called when combobox to check all topo layers is toggled""" if self.grbx_topo.isChecked(): for box in self.grbx_topo.findChildren(QCheckBox): box.setChecked(True) box.setEnabled(1) self.chbx_clicked() else: for box in self.grbx_topo.findChildren(QCheckBox): box.setChecked(False) box.setEnabled(1) self.chbx_clicked() @pyqtSlot() def chbx_clicked(self): """Called when topo checkboxes are checked""" if not self.loop_topo_boxes(): self.le_key.setDisabled(1) self.btn_view_key.setDisabled(1) def loop_topo_boxes(self): """loops through topo check boxes returns true if one is checked and enables api key features""" for box in self.grbx_topo.findChildren(QCheckBox): if box.isChecked(): self.le_key.setEnabled(1) self.btn_view_key.setEnabled(1) return True return False @pyqtSlot() def check_all_admin(self): """ Called when combobox to check all admin layers is toggled""" if self.grbx_admin.isChecked(): for box in self.grbx_admin.findChildren(QCheckBox): box.setChecked(True) box.setEnabled(1) else: for box in self.grbx_admin.findChildren(QCheckBox): box.setChecked(False) box.setEnabled(1) def message_box(self): return QMessageBox(QMessageBox.Information, "Note", self.message, buttons=QMessageBox.Ok) def request_error(self): """Called when failure to request a changeset""" self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n ---------------------- REQUEST ERROR ---------" "----------------- \n\nSomething appears to have gone" " wrong with requesting the changeset, first please" " check you entered the correct api key if this is correct" " then please inform a developer.") self.error_dialog.show() QApplication.restoreOverrideCursor() def topo_layer_processing(self, layer): """Processes to run for all topo layers""" if not self.check_api_key(): return status = topo50.update_topo50(self.api_key, layer) self.update_message(status, "{}_polygons".format(layer)) if status != "error": self.updates.append(layer) def check_api_key(self): # check for API key if self.api_key == "": self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n------------- NO API KEY -------------" "\n\nPlease enter a koordinates api key to" " update the reference data.") self.error_dialog.show() QApplication.restoreOverrideCursor() return False return True def update_message(self, status, name): """add to message for display at end of processing""" if status == "current": self.message += "The {} table was up to date\n".format(name) if status == "updated": self.message += "The {} table has been updated\n".format(name) if status == "error": self.message += "The request errored on the {} table\n".format( name) self.request_error()
class NewEntry(QFrame, FORM_CLASS): value = "" new_type = "" def __init__(self, dockwidget, parent=None): """Constructor.""" super(NewEntry, self).__init__(parent) self.setupUi(self) self.dockwidget = dockwidget self.db = db self.db.connect() # set up signals and slots self.organisation_id = None self.lifecycle_stage_id = None self.capture_method_id = None self.capture_source_group_id = None self.btn_ok.clicked.connect( partial(self.save_clicked, commit_status=True)) self.btn_exit.clicked.connect(self.exit_clicked) self.le_description.setDisabled(1) self.cmb_new_type_selection.currentIndexChanged.connect( self.set_new_type) def close_cursor(self): """close db cursor""" db.close_cursor() def connect(self): """Connect to db""" db.connect() def get_comments(self): """ Get comments from comment box, return default if empty """ if self.le_new_entry.text() == "": self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n -------------------- EMPTY VALUE FIELD ------" "-------------- \n\n Null values not allowed") self.error_dialog.show() return if len(self.le_new_entry.text()) >= 40: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n -------------------- VALUE TOO LONG ---------" "----------- \n\n Enter less than 40 characters") self.error_dialog.show() return return self.le_new_entry.text() def get_description(self): """ Returns description input This is only required if the type to add is capture source group """ if self.new_type != "Capture Source Group": return else: if self.le_description.text() == "": self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n -------------------- EMPTY DESCRIPTION FIELD " "-------------------- \n\n Null values not allowed") self.error_dialog.show() return if len(self.le_description.text()) >= 40: self.error_dialog = ErrorDialog() self.error_dialog.fill_report( "\n -------------------- DESCRIPTION TOO LONG ---" "----------------- \n\n Enter less than 40 characters") self.error_dialog.show() return return self.le_description.text() def get_combobox_value(self): """ Get the type to add from the combo box """ return self.cmb_new_type_selection.currentText() @pyqtSlot() def set_new_type(self): """ Called when type to add combobox index is chaged """ self.new_type = self.cmb_new_type_selection.currentText() if self.new_type == "Capture Source Group": self.le_description.setEnabled(1) else: self.le_description.setDisabled(1) @pyqtSlot(bool) def save_clicked(self, commit_status): """When save button is clicked""" self.value = self.get_comments() # get type self.new_type = self.get_combobox_value() self.status = False # call insert depending on type if self.value is not None: if self.new_type == "Organisation": self.status = self.new_organisation(self.value, commit_status) elif self.new_type == "Lifecycle Stage": self.status = self.new_lifecycle_stage(self.value, commit_status) elif self.new_type == "Capture Method": self.status = self.new_capture_method(self.value, commit_status) elif self.new_type == "Capture Source Group": self.description = self.get_description() if self.description is not None: self.status = self.new_capture_source_group( self.value, self.description, commit_status) if self.status: iface.messageBar().pushMessage("SUCCESS", "You've added a new {}!".format( self.new_type), level=Qgis.Success, duration=3) @pyqtSlot() def exit_clicked(self): """ Called when new entry exit button clicked. """ self.close_frame() self.dockwidget.lst_sub_menu.clearSelection() def close_frame(self): """ Clean up and remove the new entry frame. """ self.db.close_connection() from buildings.gui.menu_frame import MenuFrame dw = self.dockwidget dw.stk_options.removeWidget(dw.stk_options.currentWidget()) dw.new_widget(MenuFrame(dw)) def new_organisation(self, organisation, commit_status): """ update the organisation table. value output = organisation auto generate id """ # check if organisation in buildings_bulk_load.organisation table result = self.db.execute_return(bulk_load_select.organisation_by_value, (organisation, )) ls = result.fetchall() # if it is in the table return dialog box and exit if len(ls) > 0: self.error_dialog = ErrorDialog() self.error_dialog.fill_report(" ") self.error_dialog.fill_report( "\n -------------------- ORGANISATION EXISTS ----" "---------------- \n\n Value entered exists in table") self.error_dialog.show() return False # if it isn't in the table add to table elif len(ls) == 0: # enter but don't commit self.db.open_cursor() sql = "SELECT buildings_bulk_load.organisation_insert(%s);" result = self.db.execute_no_commit(sql, (organisation, )) self.organisation_id = result.fetchall()[0][0] if commit_status: self.db.commit_open_cursor() self.le_new_entry.clear() return True def new_lifecycle_stage(self, lifecycle_stage, commit_status): """ update the lifecycle stage table value = lifecycle stage auto generate id """ # check if lifecycle stage in buildings.lifecycle_stage table result = self.db.execute_return( buildings_select.lifecycle_stage_by_value, (lifecycle_stage, )) ls = result.fetchall() # if it is in the table return dialog box and exit if len(ls) > 0: self.error_dialog = ErrorDialog() self.error_dialog.fill_report(" ") self.error_dialog.fill_report( "\n -------------------- LIFECYCLE STAGE EXISTS -" "------------------- \n\n Value entered exists in table") self.error_dialog.show() return False # if it isn't in the table add to table elif len(ls) == 0: # enter but don't commit self.db.open_cursor() sql = "SELECT buildings.lifecycle_stage_insert(%s);" result = self.db.execute_no_commit(sql, (lifecycle_stage, )) self.lifecycle_stage_id = result.fetchall()[0][0] if commit_status: self.db.commit_open_cursor() self.le_new_entry.clear() return True def new_capture_method(self, capture_method, commit_status): """ update the capture method table value = capture method autogenerate id """ # check if capture method in buildings_common.capture_method table result = self.db.execute_return(common_select.capture_method_by_value, (capture_method, )) ls = result.fetchall() # if it is in the table return dialog box and exit if len(ls) > 0: self.error_dialog = ErrorDialog() self.error_dialog.fill_report(" ") self.error_dialog.fill_report( "\n -------------------- CAPTURE METHOD EXISTS --" "------------------ \n\n Value entered exists in table") self.error_dialog.show() return False # if it isn't in the table add to table elif len(ls) == 0: # enter but don't commit self.db.open_cursor() sql = "SELECT buildings_common.capture_method_insert(%s);" result = self.db.execute_no_commit(sql, (capture_method, )) self.capture_method_id = result.fetchall()[0][0] if commit_status: self.db.commit_open_cursor() self.le_new_entry.clear() return True def new_capture_source_group(self, capture_source_group, description, commit_status): """ update the capture source group table value = capture source group autogenerate id """ # Check if capture source group in buildings # _common.capture_source_group table result = self.db.execute_return( common_select.capture_source_group_by_value_and_description, (capture_source_group, description)) ls = result.fetchall() # if it is in the table return dialog box and exit if len(ls) > 0: self.error_dialog = ErrorDialog() self.error_dialog.fill_report(" ") self.error_dialog.fill_report( "\n ---------------- CAPTURE SOURCE GROUP " "---------------- \n\n Value entered exists in table") self.error_dialog.show() return False elif len(ls) == 0: # enter but don't commit self.db.open_cursor() sql = "SELECT buildings_common.capture_source_group_insert(%s, %s);" result = self.db.execute_no_commit( sql, (capture_source_group, description)) self.capture_source_group_id = result.fetchall()[0][0] if commit_status: self.db.commit_open_cursor() self.le_new_entry.clear() self.le_description.clear() return True