コード例 #1
0
 def sel_oldlim(self):
     # Selection in the canvas
     self.hide()
     self.l_edge.removeSelection()
     self.identify_oldlim = QgsMapToolIdentifyFeature(
         self.canvas, self.l_edge)
     self.identify_oldlim.setCursor(QCursor(Qt.PointingHandCursor))
     self.identify_oldlim.featureIdentified.connect(self.oldlim_identified)
     self.canvas.setMapTool(self.identify_oldlim)
コード例 #2
0
ファイル: polypainter.py プロジェクト: chrisashwalker/Work
    def __init__(self, canvas):
        QgsMapToolIdentifyFeature.__init__(self, canvas)
        self.linkedcanvas = canvas
        self.activefeature = None
        self.active = False

        #TODO: Enable users to set the following:
        self.brushsize = 0.01
        self.brushroundness = 4
        self.activelayer = self.linkedcanvas.layer(0)
コード例 #3
0
 def __init__(self, iface, layer, obj):
     self.iface = iface
     self.canvas = self.iface.mapCanvas()
     self.layer = layer
     self.nodes = []
     self.obj = obj
     self.field = ""
     self.deselectedSegmentIndex = False
     self.buttonValue = False
     QgsMapToolIdentifyFeature.__init__(self, self.canvas, self.layer)
コード例 #4
0
    def __init__(self,
                 parent,
                 utils,
                 parcel_number=None,
                 collected_parcel_t_id=None):
        QgsPanelWidget.__init__(self, None)
        self.setupUi(self)
        self.parent = parent
        self.utils = utils

        self.setDockMode(True)
        self.setPanelTitle(
            QCoreApplication.translate("ChangesPerParcelPanelWidget",
                                       "Change detection per parcel"))

        self._current_official_substring = ""
        self._current_substring = ""

        self.utils.add_layers()
        self.fill_combos()

        # Remove selection in plot layers
        self.utils._layers[PLOT_TABLE][LAYER].removeSelection()
        self.utils._official_layers[PLOT_TABLE][LAYER].removeSelection()

        # Map tool before activate map swipe tool
        self.init_map_tool = self.utils.canvas.mapTool()

        self.active_map_tool_before_custom = None
        self.btn_identify_plot.setIcon(
            QIcon(":/Asistente-LADM_COL/resources/images/spatial_unit.png"))
        self.btn_identify_plot.clicked.connect(self.btn_plot_toggled)

        # Create maptool
        self.maptool_identify = QgsMapToolIdentifyFeature(self.utils.canvas)

        # Set connections
        self.btn_alphanumeric_query.clicked.connect(self.alphanumeric_query)
        self.chk_show_all_plots.toggled.connect(self.show_all_plots)
        self.cbo_parcel_fields.currentIndexChanged.connect(
            self.search_field_updated)
        self.panelAccepted.connect(self.initialize_tools_and_layers)
        self.tbl_changes_per_parcel.itemDoubleClicked.connect(
            self.call_party_panel)

        self.initialize_field_values_line_edit()
        self.initialize_tools_and_layers()

        if parcel_number is not None:  # Do a search!
            self.txt_alphanumeric_query.setValue(parcel_number)
            if collected_parcel_t_id is not None:  # Search data for a duplicated parcel_number, so, take the t_id into account!
                self.search_data(parcel_number=parcel_number,
                                 collected_parcel_t_id=collected_parcel_t_id)
            else:
                self.search_data(parcel_number=parcel_number)
コード例 #5
0
 def sel_nwvtxnear_rfu(self):
     # Selection in the canvas
     if self.sel_nw_vtx:
         self.hide()
         self.identify_rfu_vtx = QgsMapToolIdentifyFeature(self.canvas, self.l_vertex)
         self.identify_rfu_vtx.setCursor(QCursor(Qt.PointingHandCursor))
         self.identify_rfu_vtx.featureIdentified.connect(partial(self.rfu_vtx_identified, "near"))
         self.canvas.setMapTool(self.identify_rfu_vtx)
     # Message if no line selected in the tablview
     else:
         QMessageBox.warning(self, tr_vtxplt_sel_nolinesel_msg[0], tr_vtxplt_sel_nolinesel_msg[1])
コード例 #6
0
ファイル: mainWindow.py プロジェクト: luolingchun/PyQGIS
    def actionIdentifyTriggered(self):
        # 设置识别工具
        self.identifyTool = QgsMapToolIdentifyFeature(self.mapCanvas)
        self.identifyTool.featureIdentified.connect(self.showFeatures)
        self.mapCanvas.setMapTool(self.identifyTool)

        # 设置需要识别的图层
        layers = self.mapCanvas.layers()
        if layers:
            # 识别画布中第一个图层
            self.identifyTool.setLayer(layers[0])
コード例 #7
0
    def __init__(self, iface, controller, parent=None):
        super(DockWidgetQueries, self).__init__(None)
        self.setupUi(self)
        self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.iface = iface
        self._controller = controller

        self.logger = Logger()
        self.app = AppInterface()

        self.canvas = iface.mapCanvas()
        self.active_map_tool_before_custom = None

        self._identify_tool = None

        self._fill_combos()

        self.btn_identify_plot.setIcon(
            QIcon(":/Asistente-LADM-COL/resources/images/spatial_unit.png"))

        self.tab_results.setTabEnabled(
            TAB_BASIC_INFO_INDEX,
            False)  # TODO: Remove when queries support LevCat 1.2
        self.tab_results.setTabEnabled(
            TAB_PHYSICAL_INFO_INDEX,
            False)  # TODO: Remove when queries support LevCat 1.2
        self.tab_results.setTabEnabled(
            TAB_ECONOMIC_INFO_INDEX,
            False)  # TODO: Remove when queries support LevCat 1.2
        self.tab_results.setCurrentIndex(
            TAB_LEGAL_INFO_INDEX
        )  # TODO: Remove when queries support LevCat 1.2

        # Set connections
        self._controller.close_view_requested.connect(self._close_dock_widget)

        self.btn_alphanumeric_query.clicked.connect(self._alphanumeric_query)
        self.cbo_parcel_fields.currentIndexChanged.connect(
            self._search_field_updated)
        self.btn_identify_plot.clicked.connect(self._btn_plot_toggled)
        self.btn_query_informality.clicked.connect(self._query_informality)
        self.btn_next_informal_parcel.clicked.connect(
            self._query_next_informal_parcel)
        self.btn_previous_informal_parcel.clicked.connect(
            self._query_previous_informal_parcel)

        # Context menu
        self._set_context_menus()

        # Create maptool
        self.maptool_identify = QgsMapToolIdentifyFeature(self.canvas)

        self._initialize_field_values_line_edit()
        self._update_informal_controls()
    def select_feature(self):
        self.setVisible(False)  # Make wizard disappear

        # Create maptool
        self.maptool_identify = QgsMapToolIdentifyFeature(self.canvas)
        self.maptool_identify.setLayer(self._current_layer)
        cursor = QCursor()
        cursor.setShape(Qt.CrossCursor)
        self.maptool_identify.setCursor(cursor)
        self.canvas.setMapTool(self.maptool_identify)
        self.maptool_identify.featureIdentified.connect(self.get_feature_id)
コード例 #9
0
ファイル: linkerdock.py プロジェクト: 3nids/linkit
    def __init__(self, iface):
        # QGIS
        self.iface = iface
        self.settings = MySettings()
        self.linkRubber = QgsRubberBand(self.iface.mapCanvas())
        self.featureHighlight = None
        # Relation management
        self.relationManager = QgsProject.instance().relationManager()
        self.relationManager.changed.connect(self.loadRelations)
        self.relation = QgsRelation()
        self.referencingFeature = QgsFeature()
        self.relationWidgetWrapper = None
        self.editorContext = QgsAttributeEditorContext()
        self.editorContext.setVectorLayerTools(self.iface.vectorLayerTools())

        # GUI
        QDockWidget.__init__(self)
        self.setupUi(self)
        SettingDialog.__init__(self, MySettings(), False, True)
        self.drawButton.setChecked(self.settings.value("drawEnabled"))

        self.relationReferenceWidget.setAllowMapIdentification(True)
        self.relationReferenceWidget.setEmbedForm(False)

        self.mapTool = QgsMapToolIdentifyFeature(self.iface.mapCanvas())
        self.mapTool.setButton(self.identifyReferencingFeatureButton)

        # Connect signal/slot
        self.relationComboBox.currentIndexChanged.connect(self.currentRelationChanged)
        self.mapTool.featureIdentified.connect(self.setReferencingFeature)

        # load relations at start
        self.loadRelations()
コード例 #10
0
    def tool_select_pt_to_plot(self, type_fnc):

        self.plot_fnc_mode = type_fnc
        if self.conn and self.rfu and self.rfu.zone:
            # Prompt message
            self.iface.messageBar().pushMessage(plot_dif_txt[type_fnc][0],
                                                plot_dif_txt[type_fnc][1],
                                                Qgis.Info,
                                                duration=10)
            # Pointer to choose the vertex
            # Set the layer l_vertex current
            self.iface.setActiveLayer(self.rfu.l_vertex)
            self.project.layerTreeRoot().findLayer(
                self.rfu.l_vertex.id()).setItemVisibilityChecked(True)
            self.canvas.refresh()
            self.identify_pttoplot = QgsMapToolIdentifyFeature(
                self.canvas, self.rfu.l_vertex)
            self.identify_pttoplot.setCursor(QCursor(Qt.WhatsThisCursor))
            self.identify_pttoplot.featureIdentified.connect(
                self.pt_to_plot_identified)
            self.canvas.setMapTool(self.identify_pttoplot)
コード例 #11
0
    def __init__(self, iface, db, qgis_utils, ladm_data, parent=None):
        super(DockWidgetQueries, self).__init__(None)
        self.setupUi(self)
        self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.iface = iface
        self._db = db
        self.qgis_utils = qgis_utils
        self.ladm_data = ladm_data
        self.logger = Logger()
        self.canvas = iface.mapCanvas()
        self.active_map_tool_before_custom = None
        self.names = self._db.names

        self.clipboard = QApplication.clipboard()

        # Required layers
        self.restart_dict_of_layers()

        self._identify_tool = None

        self.add_layers()
        self.fill_combos()

        self.btn_identify_plot.setIcon(
            QIcon(":/Asistente-LADM_COL/resources/images/spatial_unit.png"))

        # Set connections
        self.btn_alphanumeric_query.clicked.connect(self.alphanumeric_query)
        self.cbo_parcel_fields.currentIndexChanged.connect(
            self.search_field_updated)
        self.btn_identify_plot.clicked.connect(self.btn_plot_toggled)

        # Context menu
        self._set_context_menus()

        # Create maptool
        self.maptool_identify = QgsMapToolIdentifyFeature(self.canvas)

        self.initialize_field_values_line_edit()
コード例 #12
0
    def __init__(self, iface, db, qgis_utils, ladm_data, parent=None):
        super(DockWidgetQueries, self).__init__(None)
        self.setupUi(self)
        self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.iface = iface
        self.canvas = iface.mapCanvas()
        self._db = db
        self.qgis_utils = qgis_utils
        self.ladm_data = ladm_data
        self.selection_color = None
        self.active_map_tool_before_custom = None

        self.clipboard = QApplication.clipboard()

        # Required layers
        self._plot_layer = None
        self._parcel_layer = None
        self._uebaunit_table = None

        self._identify_tool = None

        self.add_layers()
        self.fill_combos()

        self.btn_identify_plot.setIcon(
            QIcon(":/Asistente-LADM_COL/resources/images/spatial_unit.png"))

        # Set connections
        self.btn_alphanumeric_query.clicked.connect(self.alphanumeric_query)
        self.btn_clear_alphanumeric_query.clicked.connect(
            self.clear_alphanumeric_query)
        self.btn_identify_plot.clicked.connect(self.btn_plot_toggled)

        # Context menu
        self._set_context_menus()

        # Create maptool
        self.maptool_identify = QgsMapToolIdentifyFeature(self.canvas)
コード例 #13
0
    def __init__(self, id, gtotool, config, debug):
        super(run, self).__init__()
        self.debug = debug
        self.gtotool = gtotool
        self.gtomain = gtotool.gtomain
        self.info = gtotool.info
        self.iface = self.gtotool.iface
        self.act = self.sender()
        self.act.setCheckable(True)
        self.sourcefeat = None
        self.rubbers = []
        try:
            # create rubberband
            self.rubber = QgsRubberBand(self.iface.mapCanvas(), QgsWkbTypes.LineGeometry)
            self.rubber.setColor(QColor(Qt.blue))
            self.rubber.setLineStyle(Qt.PenStyle(Qt.DashDotLine))
            self.rubber.setWidth(2)

            # get metadata
            self.sourcelayer = QgsProject.instance().mapLayersByName(config["sourcelayer"])[0]
            self.targetlayer = QgsProject.instance().mapLayersByName(config['targetlayer'])[0]
            self.iface.setActiveLayer(self.targetlayer)
            # start edit
            if not self.targetlayer.isEditable(): self.targetlayer.startEditing()
            if not self.sourcelayer.isEditable(): self.sourcelayer.startEditing()
            # mouse move
            self.canvas = self.iface.mapCanvas()
            self.canvas.xyCoordinates.connect(self.mouse_move)
            # set maptool
            self.mapTool = QgsMapToolIdentifyFeature(self.canvas)
            self.mapTool.setLayer(self.sourcelayer)
            self.canvas.setMapTool(self.mapTool)
            self.mapTool.featureIdentified.connect(self.feature_Identified)
            self.mapTool.deactivated.connect(self.reset_tool)
            self.act.setChecked(True)
        except Exception as e:
            self.info.err(e)
コード例 #14
0
class EditGenericAttributes(QgsMapToolEmitPoint):
    """
    Tool to edit generic attributes by clicking on
    the map.
    """
    def __init__(self, canvas, layer):

        QgsMapToolEmitPoint.__init__(self, canvas)
        self.canvas = canvas
        self.layer = layer

        self.identifier = QgsMapToolIdentifyFeature(canvas, layer)

        self.setCursor(Qt.CrossCursor)

    def canvasReleaseEvent(self, event):
        feature = self.identifier.identify(
            event.x(), event.y(), self.identifier.TopDownStopAtFirst)[0]
        self.identifier.featureIdentified.emit(feature.mFeature)

    def deactivate(self):
        QgsMapTool.deactivate(self)
        self.deactivated.emit()
コード例 #15
0
class EdgeCreator(QDockWidget, gui_dckwdgt_edge_creator):
    def __init__(self,
                 canvas,
                 l_vertex,
                 l_edge,
                 user=None,
                 auth_creator=[],
                 parent=None):

        super(EdgeCreator, self).__init__(parent)
        self.setupUi(self)

        # Delete Widget on close event..
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.save = False

        self.canvas = canvas
        self.l_edge = l_edge
        self.l_vertex = l_vertex
        self.user = user
        self.auth_creator = auth_creator

        self.vertices = self.l_vertex.getFeatures()
        self.vtx_start = None
        self.vtx_end = None
        self.selected_vertices = [None, None]

        self.edge = None

        for i, vertex in enumerate(self.vertices):

            self.startVertexComboBox.insertItem(i, str(vertex.id()))
            self.startVertexComboBox.setItemData(i, vertex, 32)
            self.startVertexComboBox.setCurrentIndex(-1)

            self.endVertexComboBox.insertItem(i, str(vertex.id()))
            self.endVertexComboBox.setItemData(i, vertex, 32)
            self.endVertexComboBox.setCurrentIndex(-1)

        # Attribute: `som_createur`
        for i, e in enumerate(self.auth_creator):
            self.creatorComboBox.addItem(u"%s (%s)" % (e[1], e[0]))
            if self.user == e[0]:
                self.creatorComboBox.setCurrentIndex(i)

        self.startVertextoolButton.clicked.connect(
            self.select_start_vertex_on_canvas)
        self.endVertextoolButton.clicked.connect(
            self.select_end_vertex_on_canvas)

        self.startVertexComboBox.highlighted.connect(self.on_vtx_start_pressed)
        self.endVertexComboBox.highlighted.connect(self.on_vtx_end_pressed)
        self.startVertexComboBox.currentIndexChanged.connect(
            self.on_vtx_start_pressed)
        self.endVertexComboBox.currentIndexChanged.connect(
            self.on_vtx_end_pressed)

        self.startVertexComboBox.highlighted.connect(self.create_edge)
        self.endVertexComboBox.highlighted.connect(self.create_edge)
        self.startVertexComboBox.currentIndexChanged.connect(self.create_edge)
        self.endVertexComboBox.currentIndexChanged.connect(self.create_edge)

        self.buttonBox.accepted.connect(self.on_accepted)
        self.buttonBox.rejected.connect(self.on_rejected)
        self.buttonBox.button(QDialogButtonBox.Reset).clicked.connect(
            self.on_reset)

    def closeEvent(self, event):
        if not self.save:
            self.on_rejected()

    def select_start_vertex_on_canvas(self):

        self.identify_start_vertex = QgsMapToolIdentifyFeature(
            self.canvas, self.l_vertex)
        self.identify_start_vertex.setCursor(QCursor(Qt.PointingHandCursor))
        self.identify_start_vertex.featureIdentified.connect(
            self.on_start_vertex_identified)
        self.canvas.setMapTool(self.identify_start_vertex)

    def select_end_vertex_on_canvas(self):

        self.identify_end_vertex = QgsMapToolIdentifyFeature(
            self.canvas, self.l_vertex)
        self.identify_end_vertex.setCursor(QCursor(Qt.PointingHandCursor))
        self.identify_end_vertex.featureIdentified.connect(
            self.on_end_vertex_identified)
        self.canvas.setMapTool(self.identify_end_vertex)

    def on_start_vertex_identified(self, feature):

        cb = self.startVertexComboBox
        items = [cb.itemText(i) for i in range(cb.count())]
        for i, e in enumerate(items):
            if int(feature.id()) == int(e):
                cb.setCurrentIndex(i)

    def on_end_vertex_identified(self, feature):

        cb = self.endVertexComboBox
        items = [cb.itemText(i) for i in range(cb.count())]
        for i, e in enumerate(items):
            if int(feature.id()) == int(e):
                cb.setCurrentIndex(i)

    def on_vtx_start_pressed(self, idx):

        self.vtx_start = self.startVertexComboBox.itemData(idx, 32)
        self.select_vertices(self.vtx_start, 0)

        self.endVertexComboBox.setEnabled(True)
        self.endVertextoolButton.setEnabled(True)

    def on_vtx_end_pressed(self, idx):

        self.vtx_end = self.endVertexComboBox.itemData(idx, 32)
        self.select_vertices(self.vtx_end, 1)

        self.creatorComboBox.setEnabled(True)

    def select_vertices(self, feature, i):
        if feature:
            self.selected_vertices[i] = feature.id()
        else:
            self.selected_vertices[i] = None
        self.l_vertex.setSelectedFeatures(self.selected_vertices)

    def unselect_vertices(self):
        self.l_vertex.setSelectedFeatures([])

    def create_edge(self):

        # If edge already exists, delete it..
        if self.edge:
            self.l_edge.deleteFeature(self.edge.id())

        # Two vertices are needed..
        if not self.vtx_start or not self.vtx_end:
            return self.canvas.refresh()

        # Two DIFFERENT vertices..
        if self.vtx_start == self.vtx_end:
            return self.canvas.refresh()

        # Create line geometry..
        line = QgsGeometry.fromPolyline([
            self.vtx_start.geometry().asPoint(),
            self.vtx_end.geometry().asPoint()
        ])

        # Create the feature..
        self.edge = QgsFeature()
        self.edge.setGeometry(line)
        self.edge.setFields(self.l_edge.pendingFields())
        self.edge.setAttributes(
            [QPyNullVariant(int),
             QPyNullVariant(int),
             QPyNullVariant(int)])

        # Add feature to layer..
        self.l_edge.addFeature(self.edge)
        self.canvas.refresh()

    def on_accepted(self):

        if not self.edge:
            return False

        self.lim_ge_createur = self.auth_creator[
            self.creatorComboBox.currentIndex()][0]
        self.edge.setAttributes(
            [QPyNullVariant(int),
             QPyNullVariant(int), self.lim_ge_createur])
        self.l_edge.updateFeature(self.edge)
        self.canvas.refresh()
        self.save = True
        self.close()

    def on_rejected(self):

        # Do not save the feature..
        if self.edge:
            self.l_edge.deleteFeature(self.edge.id())

        self.unselect_vertices()
        self.canvas.refresh()
        self.close()

    def on_reset(self):

        self.startVertexComboBox.setCurrentIndex(0)
        # self.startVertexComboBox.setEnabled(True)
        # self.startVertexLabel.setEnabled(True)

        self.endVertexComboBox.setCurrentIndex(0)
        self.endVertexComboBox.setEnabled(False)
        self.endVertexLabel.setEnabled(False)
        self.endVertextoolButton.setEnabled(False)

        for i, e in enumerate(self.auth_creator):
            if self.user == e[0]:
                self.creatorComboBox.setCurrentIndex(i)
        self.creatorComboBox.setEnabled(False)
        self.creatorLabel.setEnabled(False)

        self.unselect_vertices()
        self.canvas.refresh()
コード例 #16
0
class DockWidgetQueries(QgsDockWidget, DOCKWIDGET_UI):

    zoom_to_features_requested = pyqtSignal(QgsVectorLayer, list, dict,
                                            int)  # layer, ids, t_ids, duration

    def __init__(self, iface, db, qgis_utils, ladm_data, parent=None):
        super(DockWidgetQueries, self).__init__(None)
        self.setupUi(self)
        self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.iface = iface
        self._db = db
        self.qgis_utils = qgis_utils
        self.ladm_data = ladm_data
        self.logger = Logger()
        self.canvas = iface.mapCanvas()
        self.active_map_tool_before_custom = None
        self.names = self._db.names

        self.clipboard = QApplication.clipboard()

        # Required layers
        self.restart_dict_of_layers()

        self._identify_tool = None

        self.add_layers()
        self.fill_combos()

        self.btn_identify_plot.setIcon(
            QIcon(":/Asistente-LADM_COL/resources/images/spatial_unit.png"))

        # Set connections
        self.btn_alphanumeric_query.clicked.connect(self.alphanumeric_query)
        self.cbo_parcel_fields.currentIndexChanged.connect(
            self.search_field_updated)
        self.btn_identify_plot.clicked.connect(self.btn_plot_toggled)

        # Context menu
        self._set_context_menus()

        # Create maptool
        self.maptool_identify = QgsMapToolIdentifyFeature(self.canvas)

        self.initialize_field_values_line_edit()

    def search_field_updated(self, index=None):
        self.initialize_field_values_line_edit()

    def initialize_field_values_line_edit(self):
        self.txt_alphanumeric_query.setLayer(
            self._layers[self.names.OP_PARCEL_T][LAYER])
        idx = self._layers[self.names.OP_PARCEL_T][LAYER].fields().indexOf(
            self.cbo_parcel_fields.currentData())
        self.txt_alphanumeric_query.setAttributeIndex(idx)

    def _set_context_menus(self):
        self.tree_view_basic.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view_basic.customContextMenuRequested.connect(
            self.show_context_menu)

        self.tree_view_legal.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view_legal.customContextMenuRequested.connect(
            self.show_context_menu)

        self.tree_view_property_record_card.setContextMenuPolicy(
            Qt.CustomContextMenu)
        self.tree_view_property_record_card.customContextMenuRequested.connect(
            self.show_context_menu)

        self.tree_view_physical.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view_physical.customContextMenuRequested.connect(
            self.show_context_menu)

        self.tree_view_economic.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view_economic.customContextMenuRequested.connect(
            self.show_context_menu)

    def restart_dict_of_layers(self):
        self._layers = {
            self.names.OP_PLOT_T: {
                'name': self.names.OP_PLOT_T,
                'geometry': QgsWkbTypes.PolygonGeometry,
                LAYER: None
            },
            self.names.OP_PARCEL_T: {
                'name': self.names.OP_PARCEL_T,
                'geometry': None,
                LAYER: None
            },
            self.names.COL_UE_BAUNIT_T: {
                'name': self.names.COL_UE_BAUNIT_T,
                'geometry': None,
                LAYER: None
            }
        }

    def add_layers(self):
        self.qgis_utils.get_layers(self._db, self._layers, load=True)
        if not self._layers:
            self.restart_dict_of_layers()  # Let it ready for the next call
            return None

        # Layer was found, listen to its removal so that we can deactivate the custom tool when that occurs
        try:
            self._layers[self.names.OP_PLOT_T][LAYER].willBeDeleted.disconnect(
                self.layer_removed)
        except TypeError as e:
            pass
        self._layers[self.names.OP_PLOT_T][LAYER].willBeDeleted.connect(
            self.layer_removed)

        # Layer was found, listen to its removal so that we can update the variable properly
        try:
            self._layers[
                self.names.OP_PARCEL_T][LAYER].willBeDeleted.disconnect(
                    self.parcel_layer_removed)
        except TypeError as e:
            pass
        self._layers[self.names.OP_PARCEL_T][LAYER].willBeDeleted.connect(
            self.parcel_layer_removed)

        # Layer was found, listen to its removal so that we can update the variable properly
        try:
            self._layers[
                self.names.COL_UE_BAUNIT_T][LAYER].willBeDeleted.disconnect(
                    self.uebaunit_table_removed)
        except TypeError as e:
            pass
        self._layers[self.names.COL_UE_BAUNIT_T][LAYER].willBeDeleted.connect(
            self.uebaunit_table_removed)

    def initialize_tool(self):
        self._layers[self.names.OP_PLOT_T][LAYER] = None
        self.initialize_tools(new_tool=None, old_tool=self.maptool_identify)
        self.btn_plot_toggled()

    def update_db_connection(self, db, ladm_col_db, db_source):
        self._db = db
        self.initialize_tool()

        if not ladm_col_db:
            self.setVisible(False)

    def layer_removed(self):
        # The required layer was removed, deactivate custom tool
        self.initialize_tool()

    def parcel_layer_removed(self):
        self._layers[self.names.OP_PARCEL_T][LAYER] = None

    def uebaunit_table_removed(self):
        self._layers[self.names.COL_UE_BAUNIT_T][LAYER] = None

    def fill_combos(self):
        self.cbo_parcel_fields.clear()

        self.cbo_parcel_fields.addItem(
            QCoreApplication.translate("DockWidgetQueries", "Parcel Number"),
            self.names.OP_PARCEL_T_PARCEL_NUMBER_F)
        self.cbo_parcel_fields.addItem(
            QCoreApplication.translate("DockWidgetQueries",
                                       "Previous Parcel Number"),
            self.names.OP_PARCEL_T_PREVIOUS_PARCEL_NUMBER_F)
        self.cbo_parcel_fields.addItem(
            QCoreApplication.translate("DockWidgetQueries",
                                       "Folio de Matrícula Inmobiliaria"),
            self.names.OP_PARCEL_T_FMI_F)

    def initialize_tools(self, new_tool, old_tool):
        if self.maptool_identify == old_tool:
            # custom identify was deactivated
            try:
                self.canvas.mapToolSet.disconnect(self.initialize_tools)
            except TypeError as e:
                pass
            self.btn_identify_plot.setChecked(False)
        else:
            # custom identify was activated
            pass

    def btn_plot_toggled(self):
        if self.btn_identify_plot.isChecked():
            self.prepare_identify_plot()
        else:
            # The button was toggled and deactivated, go back to the previous tool
            self.canvas.setMapTool(self.active_map_tool_before_custom)

    def prepare_identify_plot(self):
        """
            Custom Identify tool was activated, prepare everything for identifying plots
        """
        self.active_map_tool_before_custom = self.canvas.mapTool()

        self.btn_identify_plot.setChecked(True)

        self.canvas.mapToolSet.connect(self.initialize_tools)

        if self._layers[self.names.OP_PLOT_T][LAYER] is None:
            self.add_layers()

        self.maptool_identify.setLayer(
            self._layers[self.names.OP_PLOT_T][LAYER])
        cursor = QCursor()
        cursor.setShape(Qt.PointingHandCursor)
        self.maptool_identify.setCursor(cursor)
        self.canvas.setMapTool(self.maptool_identify)

        try:
            self.maptool_identify.featureIdentified.disconnect()
        except TypeError as e:
            pass
        self.maptool_identify.featureIdentified.connect(self.get_info_by_plot)

    def get_info_by_plot(self, plot_feature):
        plot_t_id = plot_feature[self.names.T_ID_F]
        self.canvas.flashFeatureIds(self._layers[self.names.OP_PLOT_T][LAYER],
                                    [plot_feature.id()],
                                    QColor(255, 0, 0, 255),
                                    QColor(255, 0, 0, 0),
                                    flashes=1,
                                    duration=500)

        with OverrideCursor(Qt.WaitCursor):
            if not self.isVisible():
                self.show()

            self.search_data_by_component(plot_t_id=plot_t_id,
                                          zoom_and_select=False)
            self._layers[self.names.OP_PLOT_T][LAYER].selectByIds(
                [plot_feature.id()])

    def search_data_by_component(self, **kwargs):
        self._layers[self.names.OP_PLOT_T][LAYER].removeSelection()

        # Read zoom_and_select parameter and remove it from kwargs
        bZoom = False
        if 'zoom_and_select' in kwargs:
            bZoom = kwargs['zoom_and_select']
            del kwargs['zoom_and_select']

        records = self._db.get_igac_basic_info(**kwargs)
        self.setup_tree_view(self.tree_view_basic, records)

        if bZoom:
            # Zoom to resulting plots
            plot_t_ids = self.get_plot_t_ids_from_basic_info(records)
            if plot_t_ids:
                features = self.ladm_data.get_features_from_t_ids(
                    self._layers[self.names.OP_PLOT_T][LAYER],
                    self.names.T_ID_F, plot_t_ids, True, True)
                plot_ids = [feature.id() for feature in features]
                self.zoom_to_features_requested.emit(
                    self._layers[self.names.OP_PLOT_T][LAYER], plot_ids,
                    dict(), 500)
                self._layers[self.names.OP_PLOT_T][LAYER].selectByIds(plot_ids)

        records = self._db.get_igac_legal_info(**kwargs)
        self.setup_tree_view(self.tree_view_legal, records)

        records = self._db.get_igac_property_record_card_info(**kwargs)
        self.setup_tree_view(self.tree_view_property_record_card, records)

        records = self._db.get_igac_physical_info(**kwargs)
        self.setup_tree_view(self.tree_view_physical, records)

        records = self._db.get_igac_economic_info(**kwargs)
        self.setup_tree_view(self.tree_view_economic, records)

    def setup_tree_view(self, tree_view, records):
        """
        Configure result tree views

        :param tree_view:
        :return:
        """
        tree_view.setModel(TreeModel(self.names, data=records))
        tree_view.expandAll()
        self.add_thumbnails_to_tree_view(tree_view)

    def add_thumbnails_to_tree_view(self, tree_view):
        """
        Gets a list of model indexes corresponding to extFiles objects to show a preview

        :param model:
        :return:
        """
        model = tree_view.model()
        indexes = model.getPixmapIndexList()
        for idx in indexes:
            url = model.data(idx, Qt.UserRole)['url']
            res, image = self.download_image("{}{}".format(
                url, SUFFIX_GET_THUMBNAIL))
            if res:
                pixmap = QPixmap()
                pixmap.loadFromData(image)
                label = QLabel()
                label.setPixmap(pixmap)
                tree_view.setIndexWidget(idx, label)

    def get_plot_t_ids_from_basic_info(self, records):
        res = []
        if records:
            for record in records:
                if self.names.OP_PLOT_T in record:
                    for element in record[self.names.OP_PLOT_T]:
                        res.append(element['id'])

        return res

    def alphanumeric_query(self):
        """
        Alphanumeric query
        """
        option = self.cbo_parcel_fields.currentData()
        query = self.txt_alphanumeric_query.value()
        if query:
            if option == self.names.OP_PARCEL_T_FMI_F:
                self.search_data_by_component(parcel_fmi=query,
                                              zoom_and_select=True)
            elif option == self.names.OP_PARCEL_T_PARCEL_NUMBER_F:
                self.search_data_by_component(parcel_number=query,
                                              zoom_and_select=True)
            else:  # previous_parcel_number
                self.search_data_by_component(previous_parcel_number=query,
                                              zoom_and_select=True)
        else:
            self.iface.messageBar().pushMessage(
                "Asistente LADM_COL",
                QCoreApplication.translate("DockWidgetQueries",
                                           "First enter a query"))

    def show_context_menu(self, point):
        tree_view = self.sender()
        index = tree_view.indexAt(point)

        context_menu = QMenu("Context menu")

        index_data = index.data(Qt.UserRole)

        if index_data is None:
            return

        if "value" in index_data:
            action_copy = QAction(
                QCoreApplication.translate("DockWidgetQueries", "Copy value"))
            action_copy.triggered.connect(
                partial(self.copy_value, index_data["value"]))
            context_menu.addAction(action_copy)
            context_menu.addSeparator()

        if "url" in index_data:
            action_open_url = QAction(
                QCoreApplication.translate("DockWidgetQueries", "Open URL"))
            action_open_url.triggered.connect(
                partial(self.open_url, index_data["url"]))
            context_menu.addAction(action_open_url)
            context_menu.addSeparator()

        # Configure actions for tables/layers
        if "type" in index_data and "id" in index_data:
            table_name = index_data["type"]
            table_package = LayerConfig.get_dict_table_package(self.names)
            t_id = index_data["id"]
            geometry_type = None
            if table_name in table_package and table_package[
                    table_name] == LADMNames.SPATIAL_UNIT_PACKAGE:
                # Layers in Spatial Unit package have double geometry, we need the polygon one
                geometry_type = QgsWkbTypes.PolygonGeometry

            if table_name == self.names.OP_PARCEL_T:
                if self._layers[
                        self.names.OP_PARCEL_T][LAYER] is None or self._layers[
                            self.names.
                            OP_PLOT_T][LAYER] is None or self._layers[
                                self.names.COL_UE_BAUNIT_T][LAYER] is None:
                    self.add_layers()
                layer = self._layers[self.names.OP_PARCEL_T][LAYER]
                self.iface.layerTreeView().setCurrentLayer(layer)
            else:
                layer = self.qgis_utils.get_layer(self._db, table_name,
                                                  geometry_type, True)

            if layer is not None:
                if layer.isSpatial():
                    action_zoom_to_feature = QAction(
                        QCoreApplication.translate(
                            "DockWidgetQueries",
                            "Zoom to {} with {}={}").format(
                                table_name, self.names.T_ID_F, t_id))
                    action_zoom_to_feature.triggered.connect(
                        partial(self.zoom_to_feature, layer, t_id))
                    context_menu.addAction(action_zoom_to_feature)

                if table_name == self.names.OP_PARCEL_T:
                    # We show a handy option to zoom to related plots
                    plot_ids = self.ladm_data.get_plots_related_to_parcels(
                        self._db, [t_id], None,
                        self._layers[self.names.OP_PLOT_T][LAYER],
                        self._layers[self.names.COL_UE_BAUNIT_T][LAYER])
                    if plot_ids:
                        action_zoom_to_plots = QAction(
                            QCoreApplication.translate(
                                "DockWidgetQueries",
                                "Zoom to related plot(s)"))
                        action_zoom_to_plots.triggered.connect(
                            partial(self.zoom_to_plots, plot_ids))
                        context_menu.addAction(action_zoom_to_plots)

                action_open_feature_form = QAction(
                    QCoreApplication.translate(
                        "DockWidgetQueries",
                        "Open form for {} with {}={}").format(
                            table_name, self.names.T_ID_F, t_id))
                action_open_feature_form.triggered.connect(
                    partial(self.open_feature_form, layer, t_id))
                context_menu.addAction(action_open_feature_form)

        if context_menu.actions():
            context_menu.exec_(tree_view.mapToGlobal(point))

    def copy_value(self, value):
        self.clipboard.setText(str(value))

    def open_url(self, url):
        webbrowser.open(url)

    def zoom_to_feature(self, layer, t_id):
        feature = self.get_feature_from_t_id(layer, t_id)
        self.iface.mapCanvas().zoomToFeatureIds(layer, [feature.id()])
        self.canvas.flashFeatureIds(layer, [feature.id()],
                                    QColor(255, 0, 0, 255),
                                    QColor(255, 0, 0, 0),
                                    flashes=1,
                                    duration=500)

    def open_feature_form(self, layer, t_id):
        feature = self.get_feature_from_t_id(layer, t_id)
        self.iface.openFeatureForm(layer, feature)

    def get_feature_from_t_id(self, layer, t_id):
        field_idx = layer.fields().indexFromName(self.names.T_ID_F)
        request = QgsFeatureRequest(
            QgsExpression("{}={}".format(self.names.T_ID_F, t_id)))
        request.setFlags(QgsFeatureRequest.NoGeometry)

        iterator = layer.getFeatures(request)
        feature = QgsFeature()
        res = iterator.nextFeature(feature)
        if res:
            return feature

        return None

    def zoom_to_plots(self, plot_ids):
        self.iface.mapCanvas().zoomToFeatureIds(
            self._layers[self.names.OP_PLOT_T][LAYER], plot_ids)
        self.canvas.flashFeatureIds(self._layers[self.names.OP_PLOT_T][LAYER],
                                    plot_ids,
                                    QColor(255, 0, 0, 255),
                                    QColor(255, 0, 0, 0),
                                    flashes=1,
                                    duration=500)

    def closeEvent(self, event):
        try:
            self.canvas.mapToolSet.disconnect(self.initialize_tools)
        except TypeError as e:
            pass
        self.canvas.setMapTool(self.active_map_tool_before_custom)

    def download_image(self, url):
        res = False
        img = None
        msg = {'text': '', 'level': Qgis.Warning}
        if url:
            self.logger.info(__name__, "Downloading file from {}".format(url))
            msg = "Downloading image from document repository (this might take a while)..."
            with ProcessWithStatus(msg):
                if self.qgis_utils.is_connected(TEST_SERVER):

                    nam = QNetworkAccessManager()
                    request = QNetworkRequest(QUrl(url))
                    reply = nam.get(request)

                    loop = QEventLoop()
                    reply.finished.connect(loop.quit)
                    loop.exec_()

                    status = reply.attribute(
                        QNetworkRequest.HttpStatusCodeAttribute)
                    if status == 200:
                        res = True
                        img = reply.readAll()
                    else:
                        res = False
                        msg['text'] = QCoreApplication.translate(
                            "SettingsDialog",
                            "There was a problem connecting to the server. The server might be down or the service cannot be reached at the given URL."
                        )
                else:
                    res = False
                    msg['text'] = QCoreApplication.translate(
                        "SettingsDialog",
                        "There was a problem connecting to Internet.")

        else:
            res = False
            msg['text'] = QCoreApplication.translate("SettingsDialog",
                                                     "Not valid URL")

        if not res:
            self.logger.log_message(__name__, msg['text'], msg['level'])
        return (res, img)
コード例 #17
0
class DockWidgetQueries(QgsDockWidget, DOCKWIDGET_UI):
    def __init__(self, iface, controller, parent=None):
        super(DockWidgetQueries, self).__init__(None)
        self.setupUi(self)
        self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        self.iface = iface
        self._controller = controller

        self.logger = Logger()
        self.app = AppInterface()

        self.canvas = iface.mapCanvas()
        self.active_map_tool_before_custom = None

        self._identify_tool = None

        self._fill_combos()

        self.btn_identify_plot.setIcon(
            QIcon(":/Asistente-LADM-COL/resources/images/spatial_unit.png"))

        self.tab_results.setTabEnabled(
            TAB_BASIC_INFO_INDEX,
            False)  # TODO: Remove when queries support LevCat 1.2
        self.tab_results.setTabEnabled(
            TAB_PHYSICAL_INFO_INDEX,
            False)  # TODO: Remove when queries support LevCat 1.2
        self.tab_results.setTabEnabled(
            TAB_ECONOMIC_INFO_INDEX,
            False)  # TODO: Remove when queries support LevCat 1.2
        self.tab_results.setCurrentIndex(
            TAB_LEGAL_INFO_INDEX
        )  # TODO: Remove when queries support LevCat 1.2

        # Set connections
        self._controller.close_view_requested.connect(self._close_dock_widget)

        self.btn_alphanumeric_query.clicked.connect(self._alphanumeric_query)
        self.cbo_parcel_fields.currentIndexChanged.connect(
            self._search_field_updated)
        self.btn_identify_plot.clicked.connect(self._btn_plot_toggled)
        self.btn_query_informality.clicked.connect(self._query_informality)
        self.btn_next_informal_parcel.clicked.connect(
            self._query_next_informal_parcel)
        self.btn_previous_informal_parcel.clicked.connect(
            self._query_previous_informal_parcel)

        # Context menu
        self._set_context_menus()

        # Create maptool
        self.maptool_identify = QgsMapToolIdentifyFeature(self.canvas)

        self._initialize_field_values_line_edit()
        self._update_informal_controls()

    def _search_field_updated(self, index=None):
        self._initialize_field_values_line_edit()

    def _initialize_field_values_line_edit(self):
        self.txt_alphanumeric_query.setLayer(self._controller.parcel_layer())
        idx = self._controller.parcel_layer().fields().indexOf(
            self.cbo_parcel_fields.currentData())
        self.txt_alphanumeric_query.setAttributeIndex(idx)

    def _set_context_menus(self):
        self.tree_view_basic.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view_basic.customContextMenuRequested.connect(
            self._show_context_menu)

        self.tree_view_legal.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view_legal.customContextMenuRequested.connect(
            self._show_context_menu)

        self.tree_view_physical.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view_physical.customContextMenuRequested.connect(
            self._show_context_menu)

        self.tree_view_economic.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view_economic.customContextMenuRequested.connect(
            self._show_context_menu)

    def _close_dock_widget(self):
        # Deactivate custom tool and close dockwidget
        self._controller.disconnect_plot_layer()
        self._controller.disconnect_parcel_layer()

        self._initialize_tools(new_tool=None, old_tool=self.maptool_identify)
        self._btn_plot_toggled()
        self.close(
        )  # The user needs to use the menus again, which will start everything from scratch

    def _fill_combos(self):
        self.cbo_parcel_fields.clear()
        self.cbo_parcel_fields.addItem(
            QCoreApplication.translate("DockWidgetQueries", "Parcel Number"),
            self._controller.parcel_number_name())
        self.cbo_parcel_fields.addItem(
            QCoreApplication.translate("DockWidgetQueries",
                                       "Previous Parcel Number"),
            self._controller.previous_parcel_number_name())
        self.cbo_parcel_fields.addItem(
            QCoreApplication.translate("DockWidgetQueries",
                                       "Folio de Matrícula Inmobiliaria"),
            self._controller.fmi_name())

    def _initialize_tools(self, new_tool, old_tool):
        if self.maptool_identify == old_tool:
            # custom identify was deactivated
            try:
                self.canvas.mapToolSet.disconnect(self._initialize_tools)
            except TypeError as e:
                pass
            self.btn_identify_plot.setChecked(False)
        else:
            # custom identify was activated
            pass

    def _btn_plot_toggled(self):
        if self.btn_identify_plot.isChecked():
            self._prepare_identify_plot()
        else:
            # The button was toggled and deactivated, go back to the previous tool
            self.canvas.setMapTool(self.active_map_tool_before_custom)

    def _prepare_identify_plot(self):
        """
        Custom Identify tool was activated, prepare everything for identifying plots
        """
        self.active_map_tool_before_custom = self.canvas.mapTool()
        self.btn_identify_plot.setChecked(True)

        self.canvas.mapToolSet.connect(self._initialize_tools)

        self.maptool_identify.setLayer(self._controller.plot_layer())
        cursor = QCursor()
        cursor.setShape(Qt.PointingHandCursor)
        self.maptool_identify.setCursor(cursor)
        self.canvas.setMapTool(self.maptool_identify)

        try:
            self.maptool_identify.featureIdentified.disconnect()
        except TypeError as e:
            pass
        self.maptool_identify.featureIdentified.connect(
            self._search_data_by_plot)

    def _search_data_by_plot(self, plot_feature):
        plot_t_id = plot_feature[self._controller.t_id_name()]
        self.app.gui.flash_features(self._controller.plot_layer(),
                                    [plot_feature.id()])

        with OverrideCursor(Qt.WaitCursor):
            if not self.isVisible():
                self.show()

            self._search_data_by_component(plot_t_ids=[plot_t_id],
                                           zoom_and_select=False)
            self._controller.plot_layer().selectByIds([plot_feature.id()])

    def _search_data_by_component(self, **kwargs):
        """
        Perform the searches by component and fill tree views

        :param kwargs: A dict with search criteria.
        """
        self._controller.plot_layer().removeSelection()

        # Read zoom_and_select parameter and remove it from kwargs
        bZoom = False
        if 'zoom_and_select' in kwargs:
            bZoom = kwargs['zoom_and_select']
            del kwargs['zoom_and_select']

        if 'parcel_number' in kwargs and kwargs['parcel_number'] == NULL:
            self.logger.warning(
                __name__,
                QCoreApplication.translate(
                    "DockWidgetQueries",
                    "The parcel number is NULL! We cannot retrieve data for parcels with NULL parcel numbers."
                ))

        # records = self._controller.search_data_basic_info(**kwargs)
        # if bZoom:
        #     self._controller.zoom_to_resulting_plots(records)

        # self._setup_tree_view(self.tree_view_basic, records)

        records = self._controller.search_data_legal_info(**kwargs)
        self._setup_tree_view(self.tree_view_legal, records)

        # records = self._controller.search_data_physical_info(**kwargs)
        # self._setup_tree_view(self.tree_view_physical, records)

        # records = self._controller.search_data_economic_info(**kwargs)
        # self._setup_tree_view(self.tree_view_economic, records)

    def _setup_tree_view(self, tree_view, records):
        """
        Configure result tree views

        :param tree_view: Tree view to be updated
        :param records: List of dicts. A dict per plot: {id: 21, attributes: {...}}
        """
        tree_view.setModel(self._controller.create_model(records))
        self._collapse_tree_view_items(tree_view)
        self._add_thumbnails_to_tree_view(tree_view)

    def _collapse_tree_view_items(self, tree_view):
        """
        Collapse tree view items based on a property
        """
        tree_view.expandAll()
        for idx in tree_view.model().getCollapseIndexList():
            tree_view.collapse(idx)

    def _add_thumbnails_to_tree_view(self, tree_view):
        """
        Gets a list of model indexes corresponding to extFiles objects to show a preview
        """
        model = tree_view.model()
        for idx in model.getPixmapIndexList():
            url = model.data(idx, Qt.UserRole)['url']
            res, image = self._controller.download_image("{}{}".format(
                url, SUFFIX_GET_THUMBNAIL))
            if res:
                pixmap = QPixmap()
                pixmap.loadFromData(image)
                label = QLabel()
                label.setPixmap(pixmap)
                tree_view.setIndexWidget(idx, label)

    def _alphanumeric_query(self):
        option = self.cbo_parcel_fields.currentData()
        query = self.txt_alphanumeric_query.value()
        if query:
            if option == self._controller.fmi_name():
                self._search_data_by_component(parcel_fmi=query,
                                               zoom_and_select=True)
            elif option == self._controller.parcel_number_name():
                self._search_data_by_component(parcel_number=query,
                                               zoom_and_select=True)
            else:  # previous_parcel_number
                self._search_data_by_component(previous_parcel_number=query,
                                               zoom_and_select=True)
        else:
            self.logger.info_msg(
                __name__,
                QCoreApplication.translate("DockWidgetQueries",
                                           "First enter a query"))

    def _show_context_menu(self, point):
        tree_view = self.sender()
        index = tree_view.indexAt(point)

        context_menu = QMenu("Context menu")

        index_data = index.data(Qt.UserRole)

        if index_data is None:
            return

        if "value" in index_data:
            action_copy = QAction(
                QCoreApplication.translate("DockWidgetQueries", "Copy value"))
            action_copy.triggered.connect(
                partial(self._controller.copy_value, index_data["value"]))
            context_menu.addAction(action_copy)
            context_menu.addSeparator()

        if "url" in index_data:
            action_open_url = QAction(
                QCoreApplication.translate("DockWidgetQueries", "Open URL"))
            action_open_url.triggered.connect(
                partial(self._controller.open_url, index_data["url"]))
            context_menu.addAction(action_open_url)
            context_menu.addSeparator()

        # Configure actions for tables/layers
        if "type" in index_data and "id" in index_data:
            table_name = index_data["type"]
            t_id = index_data["id"]

            if table_name == self._controller.parcel_layer_name():
                layer = self._controller.parcel_layer()
                self.app.core.activate_layer_requested.emit(layer)
            else:
                layer = self._controller.get_layer(table_name)

            if layer is not None:
                if layer.isSpatial():
                    action_zoom_to_feature = QAction(
                        QCoreApplication.translate(
                            "DockWidgetQueries",
                            "Zoom to {} with {}={}").format(
                                table_name, self._controller.t_id_name(),
                                t_id))
                    action_zoom_to_feature.triggered.connect(
                        partial(self._controller.zoom_to_feature, layer, t_id))
                    context_menu.addAction(action_zoom_to_feature)

                if table_name == self._controller.parcel_layer_name():
                    # We show a handy option to zoom to related plots
                    plot_ids = self._controller.get_plots_related_to_parcel(
                        t_id)
                    if plot_ids:
                        action_zoom_to_plots = QAction(
                            QCoreApplication.translate(
                                "DockWidgetQueries",
                                "Zoom to related plot(s)"))
                        action_zoom_to_plots.triggered.connect(
                            partial(self._controller.zoom_to_plots, plot_ids))
                        context_menu.addAction(action_zoom_to_plots)

                action_open_feature_form = QAction(
                    QCoreApplication.translate(
                        "DockWidgetQueries",
                        "Open form for {} with {}={}").format(
                            table_name, self._controller.t_id_name(), t_id))
                action_open_feature_form.triggered.connect(
                    partial(self._controller.open_feature_form, layer, t_id))
                context_menu.addAction(action_open_feature_form)

        if context_menu.actions():
            context_menu.exec_(tree_view.mapToGlobal(point))

    def _query_informality(self):
        first_parcel_number, current, total = self._controller.query_informal_parcels(
        )
        self._search_data_by_component(parcel_number=first_parcel_number,
                                       zoom_and_select=True)
        self._update_informal_controls(first_parcel_number, current, total)

        if not total:
            self.logger.info_msg(
                __name__,
                QCoreApplication.translate(
                    "DockWidgetQueries",
                    "There are no informal parcels in this database!"))

    def _update_informal_controls(self, parcel_number='', current=0, total=0):
        """
        Update controls (reset labels, enable buttons if we have informality)
        """
        self._update_informal_labels(parcel_number, current, total)
        self.btn_query_informality.setText(
            QCoreApplication.translate("DockWidgetQueries", "Restart"
                                       ) if current else QCoreApplication.
            translate("DockWidgetQueries", "Start"))

        enable = total > 1  # At least 2 to enable buttons that traverse the parcels
        self.btn_next_informal_parcel.setEnabled(enable)
        self.btn_previous_informal_parcel.setEnabled(enable)

    def _update_informal_labels(self, parcel_number='', current=0, total=0):
        self.lbl_informal_parcel_number.setText(
            parcel_number if parcel_number != NULL else 'NULL')
        out_of = ''
        if current and total:
            out_of = QCoreApplication.translate("DockWidgetQueries",
                                                "{} out of {}").format(
                                                    current, total)
        self.lbl_informal_out_of_total.setText(out_of)

    def _query_next_informal_parcel(self):
        parcel_number, current, total = self._controller.get_next_informal_parcel(
        )
        self._search_data_by_component(parcel_number=parcel_number,
                                       zoom_and_select=True)
        self._update_informal_controls(parcel_number, current, total)

    def _query_previous_informal_parcel(self):
        parcel_number, current, total = self._controller.get_previous_informal_parcel(
        )
        self._search_data_by_component(parcel_number=parcel_number,
                                       zoom_and_select=True)
        self._update_informal_controls(parcel_number, current, total)

    def closeEvent(self, event):
        try:
            self.canvas.mapToolSet.disconnect(self._initialize_tools)
        except TypeError as e:
            pass
        self.canvas.setMapTool(self.active_map_tool_before_custom)
コード例 #18
0
class FeatureSelectorWidget(QWidget):
    featureIdentified = pyqtSignal(QgsFeature)

    def __init__(self, parent):
        QWidget.__init__(self, parent)

        editLayout = QHBoxLayout()
        editLayout.setContentsMargins(0, 0, 0, 0)
        editLayout.setSpacing(2)
        self.setLayout(editLayout)

        self.lineEdit = QLineEdit(self)
        self.lineEdit.setReadOnly(True)
        editLayout.addWidget(self.lineEdit)
        
        self.highlightFeatureButton = QToolButton(self)
        self.highlightFeatureButton.setPopupMode(QToolButton.MenuButtonPopup)
        self.highlightFeatureAction = QAction(QgsApplication.getThemeIcon("/mActionHighlightFeature.svg"), "Highlight feature", self)
        self.scaleHighlightFeatureAction = QAction(QgsApplication.getThemeIcon("/mActionScaleHighlightFeature.svg"), "Scale and highlight feature", self)
        self.panHighlightFeatureAction = QAction(QgsApplication.getThemeIcon("/mActionPanHighlightFeature.svg"), "Pan and highlight feature", self)
        self.highlightFeatureButton.addAction(self.highlightFeatureAction)
        self.highlightFeatureButton.addAction(self.scaleHighlightFeatureAction)
        self.highlightFeatureButton.addAction(self.panHighlightFeatureAction)
        self.highlightFeatureButton.setDefaultAction(self.highlightFeatureAction)
        editLayout.addWidget(self.highlightFeatureButton)

        self.mapIdentificationButton = QToolButton(self)
        self.mapIdentificationButton.setIcon(QgsApplication.getThemeIcon("/mActionMapIdentification.svg"))
        self.mapIdentificationButton.setText("Select on map")
        self.mapIdentificationButton.setCheckable(True)
        editLayout.addWidget(self.mapIdentificationButton)

        self.mapIdentificationButton.clicked.connect(self.mapIdentification)
        self.highlightFeatureButton.triggered.connect(self.highlightActionTriggered)

        self.layer = None
        self.mapTool = None
        self.canvas = None
        self.windowWidget = None
        self.highlight = None
        self.feature = QgsFeature()

    def setCanvas(self, mapCanvas):
        self.mapTool = QgsMapToolIdentifyFeature(mapCanvas)
        self.mapTool.setButton(self.mapIdentificationButton)
        self.canvas = mapCanvas

    def setLayer(self, layer):
        self.layer = layer

    def setFeature(self, feature, canvasExtent = CanvasExtent.Fixed):
        self.lineEdit.clear()
        self.feature = feature

        if not self.feature.isValid() or self.layer is None:
            return

        featureTitle = feature.attribute(self.layer.displayField())
        if featureTitle == '':
            featureTitle = feature.id()
        self.lineEdit.setText(str(featureTitle))
        self.highlightFeature(canvasExtent)


    def clear(self):
        self.feature = QgsFeature()
        self.lineEdit.clear()

    def mapIdentification(self):
        if self.layer is None or self.mapTool is None or self.canvas is None:
            return

        self.mapTool.setLayer(self.layer)
        self.canvas.setMapTool(self.mapTool)

        self.windowWidget = QWidget.window(self)
        self.canvas.window().raise_()
        self.canvas.activateWindow()
        self.canvas.setFocus()

        self.mapTool.featureIdentified.connect(self.mapToolFeatureIdentified)
        self.mapTool.deactivated.connect(self.mapToolDeactivated)

    def mapToolFeatureIdentified(self, feature):
        feature = QgsFeature(feature)
        self.featureIdentified.emit(feature)
        self.unsetMapTool()
        self.setFeature(feature)

    def mapToolDeactivated(self):
        if self.windowWidget is not None:
            self.windowWidget.raise_()
            self.windowWidget.activateWindow()

    def highlightFeature(self, canvasExtent = CanvasExtent.Fixed):
        if self.canvas is None or not self.feature.isValid():
            return

        geom = self.feature.geometry()

        if geom is None:
            return
  
        if canvasExtent == CanvasExtent.Scale:
            featBBox = geom.boundingBox()
            featBBox = self.canvas.mapSettings().layerToMapCoordinates(self.layer, featBBox)
            extent = self.canvas.extent()
            if not extent.contains(featBBox):
                extent.combineExtentWith(featBBox)
                extent.scale(1.1)
                self.canvas.setExtent(extent)
                self.canvas.refresh()
            
        elif canvasExtent == CanvasExtent.Pan:
            centroid = geom.centroid()
            center = centroid.asPoint()

            center = self.canvas.mapSettings().layerToMapCoordinates(self.layer, center)
            self.canvas.zoomByFactor(1.0, center)  # refresh is done in this method

        # highlight
        self.delete_highlight()
        self.highlight = QgsHighlight(self.canvas, geom, self.layer)

        settings = QSettings()
        color = QColor(settings.value("/Map/highlight/color", QGis.DEFAULT_HIGHLIGHT_COLOR.name()))
        alpha = int(settings.value("/Map/highlight/colorAlpha", QGis.DEFAULT_HIGHLIGHT_COLOR.alpha()))
        buffer = 2*float(settings.value("/Map/highlight/buffer", QGis.DEFAULT_HIGHLIGHT_BUFFER_MM))
        min_width = 2*float(settings.value("/Map/highlight/min_width", QGis.DEFAULT_HIGHLIGHT_MIN_WIDTH_MM))

        self.highlight.setColor(color)  # sets also fill with default alpha
        color.setAlpha(alpha)
        self.highlight.setFillColor(color)  # sets fill with alpha
        self.highlight.setBuffer(buffer)
        self.highlight.setMinWidth(min_width)
        self.highlight.setWidth(4.0)
        self.highlight.show()
        
        self.timer = QTimer(self)
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.delete_highlight)
        self.timer.start(3000)

    def delete_highlight(self):
        if self.highlight is not None:
            self.highlight.hide()
            del self.highlight
            self.highlight = None

    def unsetMapTool(self):
        if self.canvas is not None and self.mapTool is not None:
            # this will call mapToolDeactivated
            self.canvas.unsetMapTool(self.mapTool)

    def highlightActionTriggered(self, action):
        self.highlightFeatureButton.setDefaultAction(action)

        if action == self.highlightFeatureAction:
            self.highlightFeature()

        elif action == self.scaleHighlightFeatureAction:
            self.highlightFeature(CanvasExtent.Scale)

        elif action == self.panHighlightFeatureAction:
            self.highlightFeature(CanvasExtent.Pan)
コード例 #19
0
ファイル: selector_tools.py プロジェクト: thinkWhere/Roadnet
 def __init__(self, canvas, vlayer, toolbar):
     QgsMapToolIdentifyFeature.__init__(self, canvas, vlayer)
     self.canvas = canvas
     self.vlayer = vlayer
     self.toolbar = toolbar
     self.featureIdentified.connect(self.select_rdpoly)
コード例 #20
0
class CandRRedistrict(object):
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgisInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface

        #        QgsMapTool.__init(self, self.iface.mapCanvas())
        self.canvas = self.iface.mapCanvas()
        self.canvas.setMouseTracking(True)

        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'CandRRedistrict_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Arrowsmith Redistricter')
        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'CandRRedistrict')
        self.toolbar.setObjectName(u'CandRRedistrict')

        #print "** INITIALIZING CandRRedistrict"

        # variables to initialise
        self.pluginIsActive = False
        self.dockwidget = None  #variable for the main dock
        self.attrdockwidget = None  #variable for the attribute table dock
        self.dlgparameters = None  #variable for the parameters dialog
        self.dlgtoolbox = None  #variable for the toolbox dialog
        self.dlgelectorates = None  #variable for the electorates dialog
        self.featIdentTool = None  #make sure we can use the identify tool in the code

        self.districts = None  #number of districts in the tool
        self.activedistrict = '1'  #which district is active. We use string literals
        self.activeLayer = None  #which layer is active - which layer we're reapportioning
        self.popfield = None  #the population field in the database
        self.distfield = None  #the district field in the database
        self.totalpop = 0  #the total population
        self.targetpop = 0  #the target population
        self.targetpoppct = 0  #target population percentage tolerance
        self.targetpoplower = 0  #target pop lower bound
        self.targetpophigher = 0  #target pop upper bound

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('CandRRedistrict', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/CandRRedistricter/icon.png'
        self.add_action(icon_path,
                        text=self.tr(u'Arrowsmith Redistricter'),
                        callback=self.run,
                        parent=self.iface.mainWindow())

    #--------------------------------------------------------------------------

    def onClosePlugin(self):
        """Cleanup necessary items here when plugin dockwidget is closed"""

        #print "** CLOSING CandRRedistrict"

        # disconnects
        self.attrdockwidget.closingPlugin.disconnect(self.onClosePlugin)
        self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)

        # remove this statement if dockwidget is to remain
        # for reuse if plugin is reopened
        # Commented next statement since it causes QGIS crashe
        # when closing the docked window:
        # self.dockwidget = None

        self.pluginIsActive = False

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""

        #print "** UNLOAD CandRRedistrict"

        for action in self.actions:
            self.iface.removePluginMenu(self.tr(u'&Arrowsmith Redistricter'),
                                        action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

    #--------------------------------------------------------------------------

    def run(self):
        """Run method that loads and starts the plugin"""

        if not self.pluginIsActive:
            self.pluginIsActive = True

            #print "** STARTING CandRRedistrict"

            # dockwidget may not exist if:
            #    first run of plugin
            #    removed on close (see self.onClosePlugin method)
            if self.dockwidget == None:
                # Create the dockwidget (after translation) and keep reference
                self.dockwidget = CandRRedistrictDockWidget()

            if self.attrdockwidget == None:
                self.attrdockwidget = CandRRedistrictAttrDockWidget()

            if self.dlgparameters == None:
                self.dlgparameters = CandRRedistrictDlgParameter()

            if self.dlgtoolbox == None:
                self.dlgtoolbox = CandRRedistrictDlgToolbox()

            if self.dlgelectorates == None:
                self.dlgelectorates = CandRRedistrictDlgElectorates()

            # connect to provide cleanup on closing of dockwidget
            self.dockwidget.closingPlugin.connect(self.onClosePlugin)

            #provide other gui options
            self.dockwidget.btnParameters.clicked.connect(
                self.openParametersDialog)
            self.dockwidget.btnUpdate.clicked.connect(self.updateAttributes)
            self.dockwidget.btnEraser.clicked.connect(self.setEraser)
            self.dockwidget.btnSelect.clicked.connect(
                self.updateSelectedElectorate)
            #            self.dockwidget.btnCompactness.clicked.connect(self.showCompactness)
            self.dockwidget.btnToolbox.clicked.connect(self.openToolbox)
            #            self.dockwidget.btnToolbox.clicked.connect(self.enclaveRemover)
            self.dockwidget.sliderDistricts.valueChanged.connect(
                self.updateDistrict)

            self.attrdockwidget.tblPop.itemClicked.connect(
                self.updateLockedFields)

            self.dlgparameters.cmbActiveLayer.currentIndexChanged.connect(
                self.updateFields)

            self.dlgparameters.boxButton.button(
                QDialogButtonBox.Ok).clicked.connect(self.saveParameters)
            self.dlgparameters.btnAddDataField.clicked.connect(
                self.addDataField)
            self.dlgparameters.btnRemoveDataField.clicked.connect(
                self.removeDataField)
            self.dlgparameters.btnLoadParameters.clicked.connect(
                self.loadParameters)

            self.dlgtoolbox.btnExportToCsv.clicked.connect(self.exportToCsv)
            self.dlgtoolbox.btnRename.clicked.connect(self.renameElectorates)

            self.dlgelectorates.boxButton.button(
                QDialogButtonBox.Ok).clicked.connect(self.updateElectorates)

            # show the dockwidget
            # TODO: fix to allow choice of dock location
            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget)
            self.dockwidget.show()

            self.iface.addDockWidget(Qt.RightDockWidgetArea,
                                     self.attrdockwidget)
            self.attrdockwidget.show()

    def canvasReleaseEvent(self, event):
        QgsMessageLog.logMessage("released!")
        with edit(self.activeLayer):
            selection = self.activeLayer.selectedFeatures()
            for feature in selection:
                feature[self.distfield] = self.activedistrict

    def updateAttributes(self):
        global locked
        QgsMessageLog.logMessage("released!")
        selection = self.activeLayer.selectedFeatures()
        field_id = self.activeLayer.fieldNameIndex(self.distfield)
        self.activeLayer.startEditing()
        for feature in selection:
            try:
                if locked[districtId[str(feature[self.distfield])]] == 0:
                    self.updateFeatureValue(feature)
            except:
                self.updateFeatureValue(feature)
#               QgsMessageLog.logMessage(str(feature.id) + " changed to: " + str(self.activedistrict) + " on " + str(field_id))
        self.activeLayer.commitChanges()
        self.activeLayer.removeSelection()
        self.updateTable()

    def updateFeatureValue(self, feature):
        QgsMessageLog.logMessage("updating feature value")
        global distPop
        field_id = self.activeLayer.fieldNameIndex(self.distfield)
        try:
            distPop[int(districtId[str(
                feature[self.distfield])])] = distPop[int(districtId[str(
                    feature[self.distfield])])] - feature[
                        self.popfield]  # feature[self.popfield]
            QgsMessageLog.logMessage(
                "from: " + str(districtId[str(feature[self.distfield])]))
        except:
            try:
                distPop[0] = distPop[0] - feature[self.popfield]
                QgsMessageLog.logMessage("from: zer0")
            except:
                errors = 1
                QgsMessageLog.logMessage(self.distfield + " failed on load")
        for d in dataFieldList:
            try:
                d.field_sum[int(districtId[str(
                    feature[self.distfield])])] = d.field_sum[int(
                        districtId[str(
                            feature[self.distfield])])] - feature[d.name]
                d.total_sum = d.total_sum - feature[d.name]
            except:
                d.field_sum[0] = d.field_sum[0] - feature[d.name]
                d.total_sum = d.total_sum - feature[d.name]

        QgsMessageLog.logMessage(districtId[str(feature[self.distfield])])
        self.activeLayer.changeAttributeValue(
            feature.id(), field_id, districtName[self.activedistrict])
        newId = int(districtId[str(districtName[self.activedistrict])])

        try:
            distPop[newId] = distPop[newId] + feature[self.popfield]
            QgsMessageLog.logMessage("to: " + str(newId))
        except:
            try:
                distPop[0] = distPop[0] + feature[self.popfield]
                QgsMessageLog.logMessage("to: zer0")
            except:
                errors = 1
                QgsMessageLog.logMessage(self.distfield + " failed on load")
        for d in dataFieldList:
            try:
                d.field_sum[newId] = d.field_sum[newId] + feature[d.name]
                d.total_sum = d.total_sum + feature[d.name]
            except:
                d.field_sum[0] = d.field_sum[0] + feature[d.name]
                d.total_sum = d.total_sum + feature[d.name]

    def openParametersDialog(self):
        self.dlgparameters.show()
        layers = self.iface.legendInterface().layers()
        layer_list = []
        for layer in layers:
            layer_list.append(layer.name())
        self.dlgparameters.cmbActiveLayer.clear()
        self.dlgparameters.cmbActiveLayer.addItems(layer_list)
        if self.activeLayer != None:
            self.dlgparameters.cmbActiveLayer.setCurrentIndex(
                self.dlgparameters.cmbActiveLayer.findText(
                    self.activeLayer.name()))
            self.setParameters()

    def openToolbox(self):
        self.dlgtoolbox.show()

    def saveParametersToFile(self):
        #	try:
        f = open(self.activeLayer.source() + '.qgis.red', 'w')
        f.write(str(self.districts) + '\n')
        f.write(str(self.totalpop) + '\n')
        f.write(str(self.targetpop) + '\n')
        f.write(str(self.targetpoplower) + '\n')
        f.write(str(self.targetpophigher) + '\n')
        f.write(str(self.popfield) + '\n')
        f.write(str(self.distfield) + '\n')
        counter = 0
        for d in dataFieldList:
            counter = counter + 1
        f.write(str(counter) + '\n')
        for d in dataFieldList:
            f.write(d.name + '\n')
            f.write(str(d.type) + '\n')

        f.write(str(len(districtName)) + '\n')
        for r in districtName:
            f.write(str(districtName[r]) + '\n')

    def updateLockedFields(self):
        QgsMessageLog.logMessage("Locking...")
        global locked
        locked = {}
        for r in range(0, self.districts + 1):
            locked[districtId[str(r)]] = 0
            if self.attrdockwidget.tblPop.item(r,
                                               1).checkState() == Qt.Checked:
                #flock		        QgsMessageLog.logMessage((districtId[str(r)]) + " Locked")
                locked[districtId[str(r)]] = 1

    def loadParameters(self):
        #	try:
        layers = self.iface.legendInterface().layers()
        selectedLayerIndex = self.dlgparameters.cmbActiveLayer.currentIndex()
        selectedLayer = layers[selectedLayerIndex]
        f = open(selectedLayer.source() + '.qgis.red', 'r')
        self.districts = f.readline()
        self.districts = int(self.districts)
        self.totalpop = f.readline()
        self.totalpop = int(self.totalpop)
        self.targetpop = f.readline()
        self.targetpop = int(self.targetpop)
        self.targetpoplower = f.readline()
        self.targetpoplower = int(self.targetpoplower)
        self.targetpophigher = f.readline()
        self.targetpophigher = int(self.targetpophigher)
        self.popfield = f.readline().rstrip()
        self.distfield = f.readline().rstrip()
        fieldparams = int(f.readline())
        self.setParameters()
        del dataFieldList[:]
        for fp in range(0, fieldparams):
            newfield = f.readline().rstrip()
            newfieldtype = int(f.readline())
            df = DataField([newfield, newfieldtype])
        loader = f.readline()
        loader_int = int(loader)
        for fn in range(0, loader_int):
            tmpDistrictName = f.readline().rstrip()
            districtName[fn] = tmpDistrictName
            if str(tmpDistrictName) not in districtId:
                districtId[str(tmpDistrictName)] = str(fn)
#		self.updateDistricts()
        self.updateFieldTable()
#	except:
#QgsMessageLog.logMessage("Save file failed to load")

    def setParameters(self):
        self.dlgparameters.inpDistricts.setValue(self.districts)
        self.dlgparameters.cmbPopField.setCurrentIndex(
            (self.dlgparameters.cmbPopField.findText(self.popfield)))
        self.dlgparameters.cmbDistField.setCurrentIndex(
            (self.dlgparameters.cmbDistField.findText(self.distfield)))
        self.updateFieldTable()

    def updateDistricts(self):
        try:
            if len(districtName) < self.districts:
                counter = 1
                for p in range(len(districtName), self.districts + 1):
                    if str(p) not in districtName:
                        districtName[p] = str(p)
                    else:
                        while (str(self.districts + counter)
                               in districtName) or (counter < 10000):
                            counter = counter + 1
                        districtName[p] = str(self.districts + counter)
                    if districtName[p] not in districtId:
                        districtId[str(p)] = str(p)
                QgsMessageLog.logMessage("Updating districts:")
                QgsMessageLog.logMessage(format(districtName))
                QgsMessageLog.logMessage(format(districtId))
        except:
            QgsMessageLog.logMessage("No map loaded")

    def saveParameters(self):
        self.updateDistricts()
        layers = self.iface.legendInterface().layers()
        selectedLayerIndex = self.dlgparameters.cmbActiveLayer.currentIndex()
        selectedLayer = layers[selectedLayerIndex]
        self.activeLayer = selectedLayer
        self.districts = self.dlgparameters.inpDistricts.value()
        self.activedistrict = 1
        self.dockwidget.lblActiveDistrict.setText("Active District: " +
                                                  str(self.activedistrict))
        self.dockwidget.sliderDistricts.setMinimum(1)
        self.dockwidget.sliderDistricts.setMaximum(self.districts)
        self.dockwidget.sliderDistricts.setValue(1)
        self.popfield = self.dlgparameters.cmbPopField.currentText()
        self.distfield = self.dlgparameters.cmbDistField.currentText()
        #        self.dispfield1 = self.dlgparameters.cmbDispField1.currentText()
        #       self.dispfield2 = self.dlgparameters.cmbDispField1.currentText()
        QgsMessageLog.logMessage("Popfield:" + str(self.popfield))
        self.totalpop = 0
        self.targetpop = 0
        for feature in self.activeLayer.getFeatures():
            self.totalpop = self.totalpop + feature[self.popfield]
        self.targetpop = int(self.totalpop / self.districts)
        self.targetpoppct = self.dlgparameters.inpTolerance.value()
        targetpoprem = int((self.targetpop / 100) * self.targetpoppct)
        self.targetpoplower = int(self.targetpop - targetpoprem)
        self.targetpophigher = int(self.targetpop + targetpoprem + 1)
        QgsMessageLog.logMessage("TargetPop:" + str(self.targetpop) + "(" +
                                 str(self.targetpoplower) + ", " +
                                 str(self.targetpophigher) + ")")
        QgsMessageLog.logMessage("Districts:" + str(self.districts))
        self.dockwidget.lblMainInfo.setText("Active Layer: " +
                                            self.activeLayer.name() +
                                            "\nActive District Field: " +
                                            self.distfield +
                                            "\nTarget Population: " +
                                            str(self.targetpop) + " (" +
                                            str(self.targetpoplower) + ", " +
                                            str(self.targetpophigher) + ")")
        self.attrdockwidget.tblPop.setRowCount(self.districts + 1)
        numDataFields = 0
        for d in dataFieldList:
            numDataFields = numDataFields + 1
            self.attrdockwidget.tblPop.setHorizontalHeaderItem(
                2 + numDataFields, QTableWidgetItem(d.name))
        self.attrdockwidget.tblPop.setColumnCount(4 + numDataFields)
        for r in range(0, self.districts + 1):
            chkBoxItem = QTableWidgetItem()
            chkBoxItem.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            chkBoxItem.setCheckState(Qt.Unchecked)
            self.attrdockwidget.tblPop.setItem(r, 1, chkBoxItem)
        self.attrdockwidget.tblPop.setHorizontalHeaderLabels(
            ['#', 'Lock', 'Population', 'To Target'])
        numDataFields = 0
        for d in dataFieldList:
            numDataFields = numDataFields + 1
            if d.type == 1:
                self.attrdockwidget.tblPop.setHorizontalHeaderItem(
                    3 + numDataFields, QTableWidgetItem(d.name))
            else:
                self.attrdockwidget.tblPop.setHorizontalHeaderItem(
                    3 + numDataFields, QTableWidgetItem(d.name + '%'))

        if len(districtName) == 0:
            self.initializeElectorates()

        try:
            self.saveParametersToFile()
            QgsMessageLog.logMessage("Parameters file saved!")
        except:
            QgsMessageLog.logMessage("Parameters file could not be saved")

        if self.dlgparameters.chkStyleMap.isChecked():
            categories = []
            for cat in range(0, self.districts + 1):
                symbol = QgsSymbolV2.defaultSymbol(
                    self.activeLayer.geometryType())
                layer_style = {}
                layer_style['color'] = '%d, %d, %d' % (randrange(
                    0, 256), randrange(0, 256), randrange(0, 256))
                layer_style['outline'] = '#000000'
                symbol_layer = QgsSimpleFillSymbolLayerV2.create(layer_style)

                # replace default symbol layer with the configured one
                if symbol_layer is not None:
                    symbol.changeSymbolLayer(0, symbol_layer)

                # create renderer object
                category = QgsRendererCategoryV2(cat, symbol, str(cat))
                # entry for the list of category items
                categories.append(category)
            renderer = QgsCategorizedSymbolRendererV2(self.distfield,
                                                      categories)
            # assign the created renderer to the layer
            if renderer is not None:
                self.activeLayer.setRendererV2(renderer)

            self.activeLayer.triggerRepaint()
        self.updateFieldValues()
        self.updateTable()
        self.updateLockedFields()
        self.updateDistricts()

    def updateDistrict(self):
        self.activedistrict = self.dockwidget.sliderDistricts.value()
        QgsMessageLog.logMessage("Active District:" +
                                 str(districtName[self.activedistrict]))
        self.dockwidget.lblActiveDistrict.setText(
            "Active district: " + str(districtName[self.activedistrict]))

    def updateFieldValues(self):
        global distPop
        QgsMessageLog.logMessage("Updating Field Values")
        QgsMessageLog.logMessage(format(districtName))
        QgsMessageLog.logMessage(format(districtId))
        numDataFields = 0
        for d in dataFieldList:
            del d.field_sum[:]
            for p in range(0, self.districts + 1):
                d.field_sum.append(p)
                d.field_sum[p] = 0
                d.total_sum = 0
                numDataFields = numDataFields + 1
        for p in range(0, self.districts + 1):
            distPop[p] = 0
        for feature in self.activeLayer.getFeatures():
            try:
                distPop[int(districtId[str(
                    feature[self.distfield])])] = distPop[int(districtId[str(
                        feature[self.distfield])])] + feature[self.popfield]
            except:
                try:
                    distPop[0] = distPop[0] + feature[self.popfield]
                except:
                    errors = 1
#		        QgsMessageLog.logMessage(self.distfield + " failed on load")
            for d in dataFieldList:
                try:
                    d.field_sum[int(districtId[str(
                        feature[self.distfield])])] = d.field_sum[int(
                            districtId[str(
                                feature[self.distfield])])] + feature[d.name]
                    d.total_sum = d.total_sum + feature[d.name]
                except:
                    d.field_sum[0] = d.field_sum[0] + feature[d.name]
                    d.total_sum = d.total_sum + feature[d.name]

    def updateTable(self):
        QgsMessageLog.logMessage("Updating Table")
        global distPop
        print(distPop)
        for p in range(0, self.districts + 1):
            self.attrdockwidget.tblPop.setItem(
                p, 0, QTableWidgetItem(str(districtName[p])))
            self.attrdockwidget.tblPop.setItem(
                p, 2, QTableWidgetItem(str(distPop[p])))
            self.attrdockwidget.tblPop.setItem(
                p, 3, QTableWidgetItem(str(self.targetpop - distPop[p])))
            self.attrdockwidget.tblPop.item(p, 0).setBackground(
                QColor(255, 255, 255))
            self.attrdockwidget.tblPop.item(p, 2).setBackground(
                QColor(255, 255, 255))
            self.attrdockwidget.tblPop.item(p, 3).setBackground(
                QColor(255, 255, 255))
            if distPop[p] >= self.targetpoplower and distPop[
                    p] <= self.targetpophigher:
                self.attrdockwidget.tblPop.item(p, 0).setBackground(
                    QColor(0, 200, 0))
                self.attrdockwidget.tblPop.item(p, 2).setBackground(
                    QColor(0, 200, 0))
                self.attrdockwidget.tblPop.item(p, 3).setBackground(
                    QColor(0, 200, 0))
            rowNum = 0
            for d in dataFieldList:
                rowNum = rowNum + 1
                if d.type == 1:
                    self.attrdockwidget.tblPop.setItem(
                        p, 3 + rowNum, QTableWidgetItem(str(d.field_sum[p])))
                elif d.type == 2:
                    if distPop[p] > 0:
                        QgsMessageLog.logMessage(
                            str(d.field_sum[p]) + " " + str(distPop[p]))
                        self.attrdockwidget.tblPop.setItem(
                            p, 3 + rowNum,
                            QTableWidgetItem(
                                str(
                                    round(
                                        float(
                                            float(d.field_sum[p]) /
                                            float(distPop[p])) * 100, 2)) +
                                '%'))
                    else:
                        self.attrdockwidget.tblPop.setItem(
                            p, 3 + rowNum, QTableWidgetItem('0.00%'))
                elif d.type == 3:
                    if self.totalpop > 0:
                        QgsMessageLog.logMessage(
                            str(d.field_sum[p]) + " " + str(self.totalpop))
                        self.attrdockwidget.tblPop.setItem(
                            p, 3 + rowNum,
                            QTableWidgetItem(
                                str(
                                    round(
                                        float(
                                            float(d.field_sum[p]) /
                                            float(self.totalpop)) * 100, 2)) +
                                '%'))
                    else:
                        self.attrdockwidget.tblPop.setItem(
                            p, 3 + rowNum, QTableWidgetItem('0.00%'))
                elif d.type == 4:
                    if d.total_sum > 0:
                        QgsMessageLog.logMessage(
                            str(d.field_sum[p]) + " " + str(d.total_sum))
                        self.attrdockwidget.tblPop.setItem(
                            p, 3 + rowNum,
                            QTableWidgetItem(
                                str(
                                    round(
                                        float(
                                            float(d.field_sum[p]) /
                                            float(d.total_sum)) * 100, 2)) +
                                '%'))
                    else:
                        self.attrdockwidget.tblPop.setItem(
                            p, 3 + rowNum, QTableWidgetItem('0.00%'))

        self.attrdockwidget.tblPop.resizeColumnToContents(0)
        self.attrdockwidget.tblPop.resizeColumnToContents(1)
        self.attrdockwidget.tblPop.resizeColumnToContents(2)
        self.attrdockwidget.tblPop.resizeColumnToContents(3)

    def addDataField(self):
        f = DataField([
            self.dlgparameters.cmbDataField.currentText(),
            self.dlgparameters.cmbDataType.currentText()
        ])
        self.updateFieldTable()

    def removeDataField(self):
        indexes = self.dlgparameters.tblDataFields.selectionModel(
        ).selectedRows()
        counter = 0
        for f in dataFieldList:
            for g in indexes:
                if counter == g.row():
                    dataFieldList.remove(f)
            counter = counter + 1
        self.updateFieldTable()

    def updateFieldTable(self):
        tblRows = 0
        for d in dataFieldList:
            tblRows = tblRows + 1
        self.dlgparameters.tblDataFields.setRowCount(tblRows)
        self.dlgparameters.tblDataFields.setColumnCount(2)
        tblRows = 0
        for d in dataFieldList:
            self.dlgparameters.tblDataFields.setItem(tblRows, 0,
                                                     QTableWidgetItem(d.name))
            #	        QgsMessageLog.logMessage("Districts:" + str(d.type))
            if d.type == 1:
                self.dlgparameters.tblDataFields.setItem(
                    tblRows, 1, QTableWidgetItem('Sum'))
            elif d.type == 2:
                self.dlgparameters.tblDataFields.setItem(
                    tblRows, 1, QTableWidgetItem('% of district pop'))
            elif d.type == 3:
                self.dlgparameters.tblDataFields.setItem(
                    tblRows, 1, QTableWidgetItem('% of total pop'))
            elif d.type == 4:
                self.dlgparameters.tblDataFields.setItem(
                    tblRows, 1, QTableWidgetItem('% of field'))
            elif d.type == 99:
                self.dlgparameters.tblDataFields.setItem(
                    tblRows, 1, QTableWidgetItem('population'))

            tblRows = tblRows + 1

    def updateFields(self):
        print("updateFields")
        self.dlgparameters.cmbPopField.clear()
        self.dlgparameters.cmbDistField.clear()
        self.dlgparameters.cmbDataField.clear()
        self.dlgparameters.cmbDataType.clear()
        #        self.dlgparameters.cmbDispField1.clear()
        #        self.dlgparameters.cmbDispField2.clear()
        layers = self.iface.legendInterface().layers()
        selectedLayerIndex = self.dlgparameters.cmbActiveLayer.currentIndex()
        selectedLayer = layers[selectedLayerIndex]
        fields = selectedLayer.pendingFields()
        field_names = [field.name() for field in fields]
        self.dlgparameters.cmbPopField.addItems(field_names)
        self.dlgparameters.cmbDistField.addItems(field_names)
        #	self.dlgparameters.cmbDispField1.addItems(["None"])
        #	self.dlgparameters.cmbDispField2.addItems(["None"])
        self.dlgparameters.cmbDataField.addItems(field_names)
        self.dlgparameters.cmbDataType.addItems(
            ['Sum', '% of Dist. Pop', '% of Total Pop', '% of Field'])
        #       self.dlgparameters.cmbDispField2.addItems(field_names)
        selectedLayerIndex = self.dlgparameters.cmbActiveLayer.currentIndex()
        selectedLayer = layers[selectedLayerIndex]

        loadFile = selectedLayer.source() + '.qgis.red'
        QgsMessageLog.logMessage('loadfile: ' + loadFile)
        if os.path.isfile(loadFile) == True:
            self.dlgparameters.btnLoadParameters.setEnabled(True)
        else:
            self.dlgparameters.btnLoadParameters.setEnabled(False)

    def showCompactness(self):
        field_id = self.activeLayer.fieldNameIndex(self.distfield)
        QgsMessageLog.logMessage("Starting...")
        QgsMessageLog.logMessage(self.activeLayer.source())
        QgsMessageLog.logMessage(self.activeLayer.name())
        ogr2ogr.main([
            '',
            self.activeLayer.name() + '_compactness.shp',
            self.activeLayer.source(), '-dialect', 'sqlite', '-sql',
            'SELECT ST_Union(geometry), ' + self.distfield + ' from ' +
            self.activeLayer.name() + ' GROUP BY ' + self.distfield
        ])
        QgsMessageLog.logMessage("...done.")
        #        QgsGeometryAnalyzer().dissolve(self.activeLayer, self.activeLayer.name() + "_compactness.shp", onlySelectedFeatures=False,uniqueIdField=field_id, p=True)
        comp_layer = QgsVectorLayer(
            self.activeLayer.name() + "_compactness.shp", "Compactness Report",
            "ogr")
        if comp_layer.isValid():
            QgsMessageLog.logMessage("valid layer!.")
            comp_layer.startEditing()
            comp_layer.dataProvider().addAttributes([
                QgsField("Area", QVariant.Double),
                QgsField("Perimeter", QVariant.Double),
                QgsField("Contiguous", QVariant.Int)
            ])
            comp_layer.updateFields()
            area = 0
            for feature in comp_layer.getFeatures():
                calculator = QgsDistanceArea()
                calculator.setEllipsoid('WGS84')
                calculator.setEllipsoidalMode(True)
                calculator.computeAreaInit()
                geom = gFeat.geometry()
                landArea = feature['Area']
                if geom.isMultipart():
                    polyg = geom.asPolygon()
                    if len(polyg) > 0:
                        area = calculator.measurePolygon(polyg[0])
                        landArea = area
                else:
                    multi = geom.asMultiPolygon()
                    for polyg in multi:
                        area = area + calculator.measurePolygon(polyg[0])
                    landArea = area
            comp_layer.commitChanges()

    def setEraser(self):
        if self.activedistrict == 0:
            self.activedistrict = self.dockwidget.sliderDistricts.value()
            self.dockwidget.lblActiveDistrict.setText("Active District: " +
                                                      str(self.activedistrict))
        else:
            self.activedistrict = 0
            self.dockwidget.lblActiveDistrict.setText("Eraser Active")

    def exportToCsv(self):
        saveFileName, __ = QFileDialog.getSaveFileName(None)
        if saveFileName:
            with open(saveFileName, 'w') as csvFile:
                csvWriter = csv.writer(csvFile,
                                       delimiter=',',
                                       quoting=csv.QUOTE_MINIMAL)
                headerWriter = ['District', 'Population', 'To Target']
                for d in dataFieldList:
                    headerWriter.append(d.name)
                csvWriter.writerow(headerWriter)
                for p in range(0, self.districts + 1):
                    rowWriter = [str(p)]
                    rowWriter.append(str(distPop[p]))
                    rowWriter.append(str(self.targetpop - distPop[p]))
                    for d in dataFieldList:
                        if d.type == 1:
                            self.attrdockwidget.tblPop.setItem(
                                p, 3 + rowNum,
                                QTableWidgetItem(str(d.field_sum[p])))
                        elif d.type == 2:
                            if distPop[p] > 0:
                                QgsMessageLog.logMessage(
                                    str(d.field_sum[p]) + " " +
                                    str(distPop[p]))
                                rowWriter.append(
                                    str(
                                        round(
                                            float(
                                                float(d.field_sum[p]) /
                                                float(distPop[p])) * 100, 2)) +
                                    '%')
                            else:
                                rowWriter.append('0.00%')
                        elif d.type == 3:
                            if self.totalpop > 0:
                                QgsMessageLog.logMessage(
                                    str(d.field_sum[p]) + " " +
                                    str(self.totalpop))
                                rowWriter.append(
                                    str(
                                        round(
                                            float(
                                                float(d.field_sum[p]) /
                                                float(self.totalpop)) *
                                            100, 2)) + '%')
                            else:
                                rowWriter.append('0.00%')
                        elif d.type == 4:
                            if d.total_sum > 0:
                                QgsMessageLog.logMessage(
                                    str(d.field_sum[p]) + " " +
                                    str(d.total_sum))
                                rowWriter.append(
                                    str(
                                        round(
                                            float(
                                                float(d.field_sum[p]) /
                                                float(d.total_sum)) *
                                            100, 2)) + '%')
                            else:
                                rowWriter.append('0.00%')
                        csvWriter.writerow(rowWriter)

    def enclaveRemover(self):
        field_id = self.activeLayer.fieldNameIndex(self.distfield)
        self.activeLayer.startEditing()
        # Create a dictionary of all features
        feature_dict = {f.id(): f for f in self.activeLayer.getFeatures()}

        QgsMessageLog.logMessage("Building spatial index...")
        # Build a spatial index
        index = QgsSpatialIndex()
        for f in list(feature_dict.values()):
            index.insertFeature(f)

        QgsMessageLog.logMessage("Finding neighbors...")
        # Loop through all features and find features that touch each feature
        for f in list(feature_dict.values()):
            geom = f.geometry()
            # Find all features that intersect the bounding box of the current feature.
            # We use spatial index to find the features intersecting the bounding box
            # of the current feature. This will narrow down the features that we need
            # to check neighboring features.
            intersecting_ids = index.intersects(geom.boundingBox())
            # Initalize neighbors list and sum
            neighbors = []
            neighbors_district = -1
            finished = 0
            if f[self.distfield] == 0:
                QgsMessageLog.logMessage("feature " + str(f.id()) +
                                         " with null distfield found!")
                while neighbors_district != -2 and finished == 0:
                    finished = 0
                    for intersecting_id in intersecting_ids:
                        # Look up the feature from the dictionary
                        intersecting_f = feature_dict[intersecting_id]
                        QgsMessageLog.logMessage("Neighbor found!")
                        # For our purpose we consider a feature as 'neighbor' if it touches or
                        # intersects a feature. We use the 'disjoint' predicate to satisfy
                        # these conditions. So if a feature is not disjoint, it is a neighbor.
                        if (f != intersecting_f and
                                not intersecting_f.geometry().disjoint(geom)):
                            if intersecting_f[self.distfield] > 0:
                                QgsMessageLog.logMessage(
                                    "Neighbor found with > 0!")
                                if neighbors_district == -1:
                                    neighbors_district = intersecting_f[
                                        self.distfield]
                                    QgsMessageLog.logMessage(
                                        "neighbors_district set to " +
                                        str(neighbors_district))
                                elif neighbors_district != intersecting_f[
                                        self.distfield]:
                                    neighbors_district = -2
                                    QgsMessageLog.logMessage(
                                        "neighbors_district set to " +
                                        str(neighbors_district) + ", " +
                                        str(intersecting_f[self.distfield]) +
                                        " not matching")
                    if neighbors_district > 0:
                        QgsMessageLog.logMessage(
                            str(f.id()) + " updating district to " +
                            str(neighbors_district))
                        self.activeLayer.changeAttributeValue(
                            f.id(), field_id, neighbors_district)
                        # Update the layer with new attribute values.
                    finished = 1

        self.activeLayer.commitChanges()

    def renameElectorates(self):
        self.dlgelectorates.show()
        self.dlgtoolbox.hide()
        txtBox = ''
        #	try:
        for d, val in list(districtId.items()):
            if d != '0':
                #			QgsMessageLog.logMessage("looping through " + str(val))
                txtBox = txtBox + str(val) + '\n'
        self.dlgelectorates.txtElectorates.setPlainText(txtBox)
#	except:
# just to give the error checker something to do
#	txtBox = ''

    def initializeElectorates(self):
        global districtId
        global districtName
        QgsMessageLog.logMessage("initializeElectorates called")
        counter = 1
        districtId = {}
        districtName = {}
        districtName[0] = str("0", "utf-8")
        districtId[str("0", "utf-8")] = 0
        for j in range(counter, self.districts + 1):
            districtName[counter] = str(str(counter), "utf-8")
            districtId[str(str(counter), "utf-8")] = counter
            counter = counter + 1
        QgsMessageLog.logMessage(format(districtName))
        QgsMessageLog.logMessage(format(districtId))
        self.saveParametersToFile()
        self.updateFieldValues()
        self.updateTable()

    def updateElectorates(self):
        global districtId
        global districtName
        QgsMessageLog.logMessage("updateElectorates called")
        electorates = self.dlgelectorates.txtElectorates.toPlainText()
        electorateNames = electorates.split('\n')
        counter = 1
        districtId = {}
        districtName = {}
        districtName[0] = str(str(0), "utf-8")
        districtId[str(str(0), "utf-8")] = 0
        for i in electorateNames:
            if counter <= self.districts:
                districtName[counter] = i
                districtId[str(str(i), "utf-8")] = counter
                counter = counter + 1
                QgsMessageLog.logMessage(i)
        if counter > self.districts:
            for j in range(counter, self.districts):
                districtName[counter] = str(str(counter), "utf-8")
                districtId[str(str(counter), "utf-8")] = counter
                counter = counter + 1
        QgsMessageLog.logMessage(format(districtName))
        QgsMessageLog.logMessage(format(districtId))
        self.saveParametersToFile()
        self.updateFieldValues()
        self.updateTable()
        self.updateLockedFields()

    def updateSelectedElectorate(self):
        self.dockwidget.lblActiveDistrict.setText("Click on the map...")
        self.featIdentTool = QgsMapToolIdentifyFeature(self.canvas)
        self.featIdentTool.featureIdentified.connect(self.toolbtnSelectAction)
        self.featIdentTool.setLayer(self.activeLayer)
        self.canvas.setMapTool(self.featIdentTool)

    def toolbtnSelectAction(self, feature):
        #QgsMessageLog.logMessage(str(feature.id()) + " updating district to " + str(feature[self.distfield]))
        self.activedistrict = feature[self.distfield]
        self.dockwidget.lblActiveDistrict.setText("Active District: " +
                                                  str(self.activedistrict))
        self.dockwidget.sliderDistricts.setValue(
            int(districtId[str(self.activedistrict)]))
        self.canvas.unsetMapTool(self.featIdentTool)
        self.featIdentTool = None

    def toolbtnSelectDeselect(self):
        self.dockwidget.lblActiveDistrict.setText("Active District: " +
                                                  str(self.activedistrict))
コード例 #21
0
class run(QObject):
    def __init__(self, id, gtotool, config, debug):
        super(run, self).__init__()
        self.debug = debug
        self.gtotool = gtotool
        self.gtomain = gtotool.gtomain
        self.info = gtotool.info
        self.iface = self.gtotool.iface
        self.act = self.sender()
        self.act.setCheckable(True)
        self.sourcefeat = None
        self.rubbers = []
        try:
            # create rubberband
            self.rubber = QgsRubberBand(self.iface.mapCanvas(), QgsWkbTypes.LineGeometry)
            self.rubber.setColor(QColor(Qt.blue))
            self.rubber.setLineStyle(Qt.PenStyle(Qt.DashDotLine))
            self.rubber.setWidth(2)

            # get metadata
            self.sourcelayer = QgsProject.instance().mapLayersByName(config["sourcelayer"])[0]
            self.targetlayer = QgsProject.instance().mapLayersByName(config['targetlayer'])[0]
            self.iface.setActiveLayer(self.targetlayer)
            # start edit
            if not self.targetlayer.isEditable(): self.targetlayer.startEditing()
            if not self.sourcelayer.isEditable(): self.sourcelayer.startEditing()
            # mouse move
            self.canvas = self.iface.mapCanvas()
            self.canvas.xyCoordinates.connect(self.mouse_move)
            # set maptool
            self.mapTool = QgsMapToolIdentifyFeature(self.canvas)
            self.mapTool.setLayer(self.sourcelayer)
            self.canvas.setMapTool(self.mapTool)
            self.mapTool.featureIdentified.connect(self.feature_Identified)
            self.mapTool.deactivated.connect(self.reset_tool)
            self.act.setChecked(True)
        except Exception as e:
            self.info.err(e)

    def mouse_move(self, pointXY):
        try:
            if self.sourcefeat is not None:
                if self.rubber.numberOfVertices() > 1:
                    self.rubber.removeLastPoint()
                self.rubber.addPoint(pointXY)
        except Exception as e:
            self.info.err(e)

    def feature_Identified(self, feature):
        try:
            if self.sourcefeat is None:
                self.sourcefeat = feature
                self.mapTool.setLayer(self.targetlayer)
            else:
                # transform
                geo = self.sourcefeat.geometry()
                sourceCrs = self.sourcelayer.crs()
                destCrs = self.targetlayer.crs()
                tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
                geo.transform(tr)
                # change geometry
                self.targetlayer.beginEditCommand("New feature")
                self.targetlayer.changeGeometry(feature.id(), geo)
                self.targetlayer.endEditCommand()
                # cleanup
                self.rubber.reset()
                self.iface.mapCanvas().refresh()
                self.mapTool.setLayer(self.sourcelayer)
                self.sourcefeat = None
            print("feature selected : " + str(feature.id()))
        except Exception as e:
            self.info.err(e)

    def reset_tool(self):
        try:
            self.act.setChecked(False)
            self.iface.mapCanvas().scene().removeItem(self.rubber)
        except Exception as e:
            self.info.err(e)
コード例 #22
0
class ChangesPerParcelPanelWidget(QgsPanelWidget, WIDGET_UI):
    def __init__(self,
                 parent,
                 utils,
                 parcel_number=None,
                 collected_parcel_t_id=None):
        QgsPanelWidget.__init__(self, None)
        self.setupUi(self)
        self.parent = parent
        self.utils = utils
        self.logger = Logger()

        self.setDockMode(True)
        self.setPanelTitle(
            QCoreApplication.translate("ChangesPerParcelPanelWidget",
                                       "Change detection per parcel"))

        self._current_supplies_substring = ""
        self._current_substring = ""

        self.utils.add_layers()
        self.fill_combos()

        # Remove selection in plot layers
        self.utils._layers[self.utils._db.names.LC_PLOT_T].removeSelection()
        self.utils._supplies_layers[
            self.utils._supplies_db.names.GC_PLOT_T].removeSelection()

        # Map tool before activate map swipe tool
        self.init_map_tool = self.utils.canvas.mapTool()

        self.active_map_tool_before_custom = None
        self.btn_identify_plot.setIcon(
            QIcon(":/Asistente-LADM-COL/resources/images/spatial_unit.png"))
        self.btn_identify_plot.clicked.connect(self.btn_plot_toggled)

        # Create maptool
        self.maptool_identify = QgsMapToolIdentifyFeature(self.utils.canvas)

        # Set connections
        self.btn_alphanumeric_query.clicked.connect(self.alphanumeric_query)
        self.chk_show_all_plots.toggled.connect(self.show_all_plots)
        self.cbo_parcel_fields.currentIndexChanged.connect(
            self.search_field_updated)
        self.panelAccepted.connect(self.initialize_tools_and_layers)
        self.tbl_changes_per_parcel.itemDoubleClicked.connect(
            self.call_party_panel)

        self.initialize_field_values_line_edit()
        self.initialize_tools_and_layers()

        if parcel_number is not None:  # Do a search!
            self.txt_alphanumeric_query.setValue(parcel_number)
            if collected_parcel_t_id is not None:  # Search data for a duplicated parcel_number, so, take the t_id into account!
                self.search_data(parcel_number=parcel_number,
                                 collected_parcel_t_id=collected_parcel_t_id)
            else:
                self.search_data(parcel_number=parcel_number)

    def btn_plot_toggled(self):
        self.clear_result_table()

        if self.btn_identify_plot.isChecked():
            self.prepare_identify_plot()
        else:
            # The button was toggled and deactivated, go back to the previous tool
            self.utils.canvas.setMapTool(self.active_map_tool_before_custom)

    def clear_result_table(self):
        self.tbl_changes_per_parcel.clearContents()
        self.tbl_changes_per_parcel.setRowCount(0)

    def prepare_identify_plot(self):
        """
            Custom Identify tool was activated, prepare everything for identifying plots
        """
        self.active_map_tool_before_custom = self.utils.canvas.mapTool()

        self.btn_identify_plot.setChecked(True)

        self.utils.canvas.mapToolSet.connect(self.initialize_maptool)

        if self.utils._supplies_layers[
                self.utils._supplies_db.names.GC_PLOT_T] is None:
            self.utils.add_layers()

        self.maptool_identify.setLayer(self.utils._supplies_layers[
            self.utils._supplies_db.names.GC_PLOT_T])
        cursor = QCursor()
        cursor.setShape(Qt.PointingHandCursor)
        self.maptool_identify.setCursor(cursor)
        self.utils.canvas.setMapTool(self.maptool_identify)

        try:
            self.maptool_identify.featureIdentified.disconnect()
        except TypeError as e:
            pass
        self.maptool_identify.featureIdentified.connect(self.get_info_by_plot)

    def get_info_by_plot(self, plot_feature):
        """
        :param plot_feature: from supplies db
        """
        plot_t_id = plot_feature[self.utils._supplies_db.names.T_ID_F]

        self.utils.canvas.flashFeatureIds(self.utils._supplies_layers[
            self.utils._supplies_db.names.GC_PLOT_T], [plot_feature.id()],
                                          QColor(255, 0, 0, 255),
                                          QColor(255, 0, 0, 0),
                                          flashes=1,
                                          duration=500)

        if not self.isVisible():
            self.show()

        self.spatial_query(plot_t_id)
        self.utils._supplies_layers[
            self.utils._supplies_db.names.GC_PLOT_T].selectByIds(
                [plot_feature.id()])

    def spatial_query(self, plot_id):
        if plot_id:
            parcel_number = self.utils.ladm_data.get_parcels_related_to_plots_supplies(
                self.utils._supplies_db, [plot_id],
                self.utils._supplies_db.names.GC_PARCEL_T_PARCEL_NUMBER_F)
            if parcel_number:  # Delegate handling of duplicates to search_data() method
                self.search_data(parcel_number=parcel_number[0])

    def call_party_panel(self, item):
        row = item.row()
        if self.tbl_changes_per_parcel.item(row, 0).text(
        ) == DICT_ALIAS_KEYS_CHANGE_DETECTION[DICT_KEY_PARTIES]:
            data = {
                SUPPLIES_DB_SOURCE:
                self.tbl_changes_per_parcel.item(row, 1).data(Qt.UserRole),
                COLLECTED_DB_SOURCE:
                self.tbl_changes_per_parcel.item(row, 2).data(Qt.UserRole)
            }
            self.parent.show_party_panel(data)

    def search_field_updated(self, index=None):
        self.initialize_field_values_line_edit()

    def initialize_field_values_line_edit(self):
        # We search for alphanumeric data in supplies data source
        self.txt_alphanumeric_query.setLayer(self.utils._supplies_layers[
            self.utils._supplies_db.names.GC_PARCEL_T])
        search_option = self.cbo_parcel_fields.currentData()
        search_field_supplies = get_supplies_search_options(
            self.utils._supplies_db.names)[search_option]
        idx = self.utils._supplies_layers[
            self.utils._supplies_db.names.GC_PARCEL_T].fields().indexOf(
                search_field_supplies)
        self.txt_alphanumeric_query.setAttributeIndex(idx)

    def fill_combos(self):
        self.cbo_parcel_fields.clear()
        self.cbo_parcel_fields.addItem(
            QCoreApplication.translate("DockWidgetChanges", "Parcel Number"),
            PARCEL_NUMBER_SEARCH_KEY)
        self.cbo_parcel_fields.addItem(
            QCoreApplication.translate("DockWidgetChanges",
                                       "Previous Parcel Number"),
            PREVIOUS_PARCEL_NUMBER_SEARCH_KEY)
        self.cbo_parcel_fields.addItem(
            QCoreApplication.translate("DockWidgetChanges",
                                       "Folio de Matrícula Inmobiliaria"),
            FMI_PARCEL_SEARCH_KEY)

    @_with_override_cursor
    def search_data(self, **kwargs):
        """
        Get plot geometries associated with parcels, both collected and supplies, zoom to them, fill comparison table
        and activate map swipe tool.

        To fill the comparison table we build two search dicts, one for supplies (already given because the alphanumeric
        search is on supplies db source), and another one for collected. For the latter, we have 3 cases. We specify
        them below (inline).

        :param kwargs: key-value (field name-field value) to search in parcel tables, both collected and supplies
                       Normally, keys are parcel_number, old_parcel_number or FMI, but if duplicates are found, an
                       additional t_id disambiguates only for the collected source. In the supplies source we assume
                       we will not find duplicates, if there are, we will choose the first record found an will not deal
                       with letting the user choose one of the duplicates by hand (as we do for the collected source).
        """
        self.chk_show_all_plots.setEnabled(False)
        self.chk_show_all_plots.setChecked(True)
        self.initialize_tools_and_layers()  # Reset any filter on layers

        plots_supplies = list()
        plots_collected = list()
        self.clear_result_table()

        search_option = self.cbo_parcel_fields.currentData()
        search_field_supplies = get_supplies_search_options(
            self.utils._supplies_db.names)[search_option]
        search_field_collected = get_collected_search_options(
            self.utils._db.names)[search_option]
        search_value = list(kwargs.values())[0]

        # Build search criterion for both supplies and collected
        search_criterion_supplies = {search_field_supplies: search_value}

        # Get supplies parcel's t_id and get related plot(s)
        expression_supplies = QgsExpression("{}='{}'".format(
            search_field_supplies, search_value))
        request = QgsFeatureRequest(expression_supplies)
        field_idx = self.utils._supplies_layers[
            self.utils._supplies_db.names.GC_PARCEL_T].fields().indexFromName(
                self.utils._supplies_db.names.T_ID_F)
        request.setFlags(QgsFeatureRequest.NoGeometry)
        request.setSubsetOfAttributes([field_idx
                                       ])  # Note: this adds a new flag
        supplies_parcels = [
            feature for feature in self.utils._supplies_layers[
                self.utils._supplies_db.names.GC_PARCEL_T].getFeatures(request)
        ]

        if len(supplies_parcels) > 1:
            # We do not expect duplicates in the supplies source!
            pass  # We'll choose the first one anyways
        elif len(supplies_parcels) == 0:
            self.logger.info(
                __name__, "No supplies parcel found! Search: {}={}".format(
                    search_field_supplies, search_value))

        supplies_plot_t_ids = []
        if supplies_parcels:
            supplies_plot_t_ids = self.utils.ladm_data.get_plots_related_to_parcels_supplies(
                self.utils._supplies_db,
                [supplies_parcels[0][self.utils._supplies_db.names.T_ID_F]],
                self.utils._supplies_db.names.T_ID_F,
                self.utils._supplies_layers[
                    self.utils._supplies_db.names.GC_PLOT_T])

            if supplies_plot_t_ids:
                self._current_supplies_substring = "\"{}\" IN ('{}')".format(
                    self.utils._supplies_db.names.T_ID_F,
                    "','".join([str(t_id) for t_id in supplies_plot_t_ids]))
                plots_supplies = self.utils.ladm_data.get_features_from_t_ids(
                    self.utils._supplies_layers[
                        self.utils._supplies_db.names.GC_PLOT_T],
                    self.utils._supplies_db.names.T_ID_F, supplies_plot_t_ids,
                    True)

        # Now get COLLECTED parcel's t_id to build the search dict for collected
        collected_parcel_t_id = None
        if 'collected_parcel_t_id' in kwargs:
            # This is the case when this panel is called and we already know the parcel number is duplicated
            collected_parcel_t_id = kwargs['collected_parcel_t_id']
            search_criterion_collected = {
                self.utils._db.names.T_ID_F: collected_parcel_t_id
            }  # As there are duplicates, we need to use t_ids
        else:
            # This is the case when:
            #   + Either this panel was called and we know the parcel number is not duplicated, or
            #   + This panel was shown without knowing about duplicates (e.g., individual parcel search) and we still
            #     need to discover whether we have duplicates for this search criterion
            search_criterion_collected = {search_field_collected: search_value}

            expression_collected = QgsExpression("{}='{}'".format(
                search_field_collected, search_value))
            request = QgsFeatureRequest(expression_collected)
            request.setFlags(QgsFeatureRequest.NoGeometry)
            request.setSubsetOfAttributes(
                [self.utils._db.names.T_ID_F],
                self.utils._layers[self.utils._db.names.LC_PARCEL_T].fields(
                ))  # Note this adds a new flag
            collected_parcels = self.utils._layers[
                self.utils._db.names.LC_PARCEL_T].getFeatures(request)
            collected_parcels_t_ids = [
                feature[self.utils._db.names.T_ID_F]
                for feature in collected_parcels
            ]

            if collected_parcels_t_ids:
                collected_parcel_t_id = collected_parcels_t_ids[0]
                if len(collected_parcels_t_ids
                       ) > 1:  # Duplicates in collected source after a search
                    QApplication.restoreOverrideCursor(
                    )  # Make sure cursor is not waiting (it is if on an identify)
                    QCoreApplication.processEvents()
                    dlg_select_parcel = SelectDuplicateParcelDialog(
                        self.utils, collected_parcels_t_ids, self.parent)
                    dlg_select_parcel.exec_()

                    if dlg_select_parcel.parcel_t_id:  # User selected one of the duplicated parcels
                        collected_parcel_t_id = dlg_select_parcel.parcel_t_id
                        search_criterion_collected = {
                            self.utils._db.names.T_ID_F: collected_parcel_t_id
                        }
                    else:
                        return  # User just cancelled the dialog, there is nothing more to do

        self.fill_table(search_criterion_supplies, search_criterion_collected)

        # Now get related plot(s) for both collected and supplies,
        if collected_parcel_t_id is not None:
            plot_t_ids = self.utils.ladm_data.get_plots_related_to_parcels(
                self.utils._db, [collected_parcel_t_id],
                self.utils._db.names.T_ID_F,
                plot_layer=self.utils._layers[self.utils._db.names.LC_PLOT_T],
                uebaunit_table=self.utils._layers[
                    self.utils._db.names.COL_UE_BAUNIT_T])

            if plot_t_ids:
                self._current_substring = "{} IN ('{}')".format(
                    self.utils._db.names.T_ID_F,
                    "','".join([str(t_id) for t_id in plot_t_ids]))
                plots_collected = self.utils.ladm_data.get_features_from_t_ids(
                    self.utils._layers[self.utils._db.names.LC_PLOT_T],
                    self.utils._db.names.T_ID_F, plot_t_ids, True)

        # Zoom to combined extent
        plot_features = plots_supplies + plots_collected  # Feature list
        plots_extent = QgsRectangle()
        for plot in plot_features:
            plots_extent.combineExtentWith(plot.geometry().boundingBox())

        if not plots_extent.isEmpty():
            self.utils.iface.mapCanvas().zoomToFeatureExtent(plots_extent)

            if plots_supplies and plots_collected:  # Otherwise the map swipe tool doesn't add any value :)
                # Activate Swipe Tool
                self.utils.app.gui.activate_layer(self.utils._supplies_layers[
                    self.utils._supplies_db.names.GC_PLOT_T])
                self.parent.activate_map_swipe_tool()

                # Send a custom mouse move on the map to make the map swipe tool's limit appear on the canvas
                coord_x = plots_extent.xMaximum() - (plots_extent.xMaximum(
                ) - plots_extent.xMinimum()) / 9  # 90%
                coord_y = plots_extent.yMaximum() - (plots_extent.yMaximum(
                ) - plots_extent.yMinimum()) / 2  # 50%

                coord_transform = self.utils.iface.mapCanvas(
                ).getCoordinateTransform()
                map_point = coord_transform.transform(coord_x, coord_y)
                widget_point = map_point.toQPointF().toPoint()
                global_point = self.utils.canvas.mapToGlobal(widget_point)

                self.utils.canvas.mousePressEvent(
                    QMouseEvent(QEvent.MouseButtonPress, global_point,
                                Qt.LeftButton, Qt.LeftButton, Qt.NoModifier))
                self.utils.canvas.mouseMoveEvent(
                    QMouseEvent(QEvent.MouseMove, widget_point + QPoint(1, 0),
                                Qt.NoButton, Qt.LeftButton, Qt.NoModifier))
                self.utils.canvas.mouseReleaseEvent(
                    QMouseEvent(QEvent.MouseButtonRelease,
                                widget_point + QPoint(1, 0), Qt.LeftButton,
                                Qt.LeftButton, Qt.NoModifier))

        # Once the query is done, activate the checkbox to alternate all plots/only selected plot
        self.chk_show_all_plots.setEnabled(True)

    def fill_table(self, search_criterion_supplies,
                   search_criterion_collected):
        """
        Shouldn't handle 'inverse' mode as we won't switch table columns at runtime.

        :param search_criterion_supplies: key-value pair to build an expression to search data in the supplies source
        :param search_criterion_collected: key-value pair to build an expression to search data in the collected source
        :return:
        """
        plural = LayerConfig.get_dict_plural(self.utils._db.names)
        dict_collected_parcels = self.utils.ladm_data.get_parcel_data_to_compare_changes(
            self.utils._db, search_criterion_collected)

        # Custom layer modifiers
        layer_modifiers = {
            LayerConfig.PREFIX_LAYER_MODIFIERS:
            LayerConfig.SUPPLIES_DB_PREFIX,
            LayerConfig.SUFFIX_LAYER_MODIFIERS:
            LayerConfig.SUPPLIES_DB_SUFFIX,
            LayerConfig.STYLE_GROUP_LAYER_MODIFIERS:
            Symbology().get_style_group_layer_modifiers(
                self.utils._supplies_db.names)
        }
        dict_supplies_parcels = self.utils.ladm_data.get_parcel_data_to_compare_changes_supplies(
            self.utils._supplies_db,
            search_criterion_supplies,
            layer_modifiers=layer_modifiers)

        # Before filling the table we make sure we get one and only one parcel attrs dict
        collected_attrs = dict()
        if dict_collected_parcels:
            collected_parcel_number = list(dict_collected_parcels.keys())[0]
            collected_attrs = dict_collected_parcels[collected_parcel_number][
                0]
            del collected_attrs[
                self.utils._db.names.
                T_ID_F]  # Remove this line if self.utils._db.names.T_ID_F is somehow needed

        supplies_attrs = dict()
        if dict_supplies_parcels:
            supplies_parcel_number = list(dict_supplies_parcels.keys())[0]
            supplies_attrs = dict_supplies_parcels[supplies_parcel_number][0]
            del supplies_attrs[
                self.utils._supplies_db.names.
                T_ID_F]  # Remove this line if self.utils._supplies_db.names,T_ID_F is somehow needed

        number_of_rows = len(collected_attrs) or len(supplies_attrs)
        self.tbl_changes_per_parcel.setRowCount(
            number_of_rows)  # t_id shouldn't be counted
        self.tbl_changes_per_parcel.setSortingEnabled(False)

        field_names = list(
            collected_attrs.keys()) if collected_attrs else list(
                supplies_attrs.keys())
        if PLOT_GEOMETRY_KEY in field_names:
            field_names.remove(
                PLOT_GEOMETRY_KEY)  # We'll handle plot geometry separately

        for row, field_name in enumerate(field_names):
            supplies_value = supplies_attrs[
                field_name] if field_name in supplies_attrs else NULL
            collected_value = collected_attrs[
                field_name] if field_name in collected_attrs else NULL
            field_alias = DICT_ALIAS_KEYS_CHANGE_DETECTION[
                field_name] if field_name in DICT_ALIAS_KEYS_CHANGE_DETECTION else field_name
            self.fill_row(field_alias, supplies_value, collected_value, row,
                          plural)

        if number_of_rows:  # At least one row in the table?
            self.fill_geometry_row(
                PLOT_GEOMETRY_KEY, supplies_attrs[PLOT_GEOMETRY_KEY]
                if PLOT_GEOMETRY_KEY in supplies_attrs else QgsGeometry(),
                collected_attrs[PLOT_GEOMETRY_KEY] if PLOT_GEOMETRY_KEY
                in collected_attrs else QgsGeometry(), number_of_rows - 1)

        self.tbl_changes_per_parcel.setSortingEnabled(True)

    def fill_row(self, field_name, supplies_value, collected_value, row,
                 plural):
        item = QTableWidgetItem(field_name)
        # item.setData(Qt.UserRole, parcel_attrs[self.names.T_ID_F])
        self.tbl_changes_per_parcel.setItem(row, 0, item)

        if field_name == DICT_ALIAS_KEYS_CHANGE_DETECTION[DICT_KEY_PARTIES]:
            item = self.fill_party_item(supplies_value)
            self.tbl_changes_per_parcel.setItem(row, 1, item)

            item = self.fill_party_item(collected_value)
            self.tbl_changes_per_parcel.setItem(row, 2, item)

            self.tbl_changes_per_parcel.setItem(row, 3, QTableWidgetItem())
            self.tbl_changes_per_parcel.item(row, 3).setBackground(
                Qt.green if supplies_value == collected_value else Qt.red)
        else:
            item = QTableWidgetItem(
                str(supplies_value) if supplies_value != NULL else '')
            #item.setData(Qt.UserRole, parcel_attrs[self.names.T_ID_F])
            self.tbl_changes_per_parcel.setItem(row, 1, item)

            item = QTableWidgetItem(
                str(collected_value) if collected_value != NULL else '')
            # item.setData(Qt.UserRole, parcel_attrs[self.names.T_ID_F])
            self.tbl_changes_per_parcel.setItem(row, 2, item)

            self.tbl_changes_per_parcel.setItem(row, 3, QTableWidgetItem())
            self.tbl_changes_per_parcel.item(row, 3).setBackground(
                Qt.green if supplies_value == collected_value else Qt.red)

    def fill_party_item(self, value):
        # Party's info comes in a list or a list of lists if it's a group party
        display_value = ''

        if value != NULL:
            if type(value) is list and value:
                display_value = "{} {}".format(
                    len(value),
                    QCoreApplication.translate("DockWidgetChanges", "parties")
                    if len(value) > 1 else QCoreApplication.translate(
                        "DockWidgetChanges", "party"))
        #else:
        #    display_value = QCoreApplication.translate("DockWidgetChanges", "0 parties")

        item = QTableWidgetItem(display_value)
        item.setData(Qt.UserRole, value)
        return item

    def fill_geometry_row(self, field_name, supplies_geom, collected_geom,
                          row):
        self.tbl_changes_per_parcel.setItem(
            row, 0,
            QTableWidgetItem(
                QCoreApplication.translate("DockWidgetChanges", "Geometry")))
        self.tbl_changes_per_parcel.setItem(
            row, 1,
            QTableWidgetItem(self.get_geometry_type_name(supplies_geom)))
        self.tbl_changes_per_parcel.setItem(
            row, 2,
            QTableWidgetItem(self.get_geometry_type_name(collected_geom)))

        self.tbl_changes_per_parcel.setItem(row, 3, QTableWidgetItem())
        self.tbl_changes_per_parcel.item(row, 3).setBackground(
            Qt.green if self.utils.compare_features_geometries(
                collected_geom, supplies_geom) else Qt.red)

    @staticmethod
    def get_geometry_type_name(geometry):
        if geometry is None:
            return QCoreApplication.translate("DockWidgetChanges",
                                              "No associated plot")
        elif geometry.type() == QgsWkbTypes.UnknownGeometry:
            return ''
        elif geometry.type() == QgsWkbTypes.PolygonGeometry:
            return QCoreApplication.translate("DockWidgetChanges", "Polygon")
        else:
            return "Type: {}".format(geometry.type())

    def alphanumeric_query(self):
        """
        Alphanumeric query (On supplies db)
        """
        option = self.cbo_parcel_fields.currentData()
        query = self.txt_alphanumeric_query.value()
        if query:
            if option == FMI_PARCEL_SEARCH_KEY:
                self.search_data(parcel_fmi=query)
            elif option == PARCEL_NUMBER_SEARCH_KEY:
                self.search_data(parcel_number=query)
            else:  # previous_parcel_number
                self.search_data(previous_parcel_number=query)

        else:
            self.utils.iface.messageBar().pushMessage(
                "Asistente LADM-COL",
                QCoreApplication.translate("DockWidgetChanges",
                                           "First enter a query"))

    def show_all_plots(self, state):
        try:
            self.utils._supplies_layers[
                self.utils._supplies_db.names.GC_PLOT_T].setSubsetString(
                    self._current_supplies_substring if not state else "")
        except RuntimeError:  # If the layer was previously removed
            pass

        try:
            self.utils._layers[self.utils._db.names.LC_PLOT_T].setSubsetString(
                self._current_substring if not state else "")
        except RuntimeError:  # If the layer was previously removed
            pass

    def initialize_tools_and_layers(self, panel=None):
        self.parent.deactivate_map_swipe_tool()
        self.show_all_plots(True)

    def initialize_maptool(self, new_tool, old_tool):
        if self.maptool_identify == old_tool:
            # custom identify was deactivated
            try:
                self.utils.canvas.mapToolSet.disconnect(
                    self.initialize_maptool)
            except TypeError as e:
                pass

            self.btn_identify_plot.setChecked(False)
        else:
            # custom identify was activated
            pass

    def close_panel(self):
        self.show_all_plots(
            True
        )  # Remove filter in plots layers if it was activate and panel is closed
        # custom identify was deactivated
        try:
            self.utils.canvas.mapToolSet.disconnect(self.initialize_maptool)
        except TypeError as e:
            pass

        self.utils.canvas.setMapTool(self.init_map_tool)
コード例 #23
0
 def __init__(self, canvas, dlg):
     QgsMapToolIdentifyFeature.__init__(self, canvas)
     self.canvas = canvas
     self.dlg = dlg
コード例 #24
0
ファイル: mainWindow.py プロジェクト: luolingchun/PyQGIS
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.first_flag = True
        self.setWindowTitle('PyQGIS')
        # 调整窗口大小
        self.resize(800, 600)
        # 初始化图层树
        vl = QVBoxLayout(self.dockWidgetContents)
        self.layerTreeView = QgsLayerTreeView(self)
        vl.addWidget(self.layerTreeView)
        # 初始化地图画布
        self.mapCanvas = QgsMapCanvas(self)
        hl = QHBoxLayout(self.frame)
        hl.setContentsMargins(0, 0, 0, 0)
        hl.addWidget(self.mapCanvas)

        # 建立桥梁
        self.model = QgsLayerTreeModel(PROJECT.layerTreeRoot(), self)
        self.model.setFlag(QgsLayerTreeModel.AllowNodeRename)
        self.model.setFlag(QgsLayerTreeModel.AllowNodeReorder)
        self.model.setFlag(QgsLayerTreeModel.AllowNodeChangeVisibility)
        self.model.setFlag(QgsLayerTreeModel.ShowLegendAsTree)
        self.model.setAutoCollapseLegendNodes(10)
        self.layerTreeView.setModel(self.model)
        self.layerTreeBridge = QgsLayerTreeMapCanvasBridge(
            PROJECT.layerTreeRoot(), self.mapCanvas, self)
        # 显示经纬度
        self.mapCanvas.xyCoordinates.connect(self.showLngLat)

        # 打开工程
        self.actionOpen.triggered.connect(self.actionOpenTriggered)
        # 退出程序
        self.actionQuit.triggered.connect(self.close)

        # 地图工具
        # TODO:放大、缩小没有图标
        self.actionPanTriggered()
        self.actionPan.triggered.connect(self.actionPanTriggered)
        self.actionZoomin.triggered.connect(self.actionZoomInTriggered)
        self.actionZoomout.triggered.connect(self.actionZoomOutTriggered)
        self.actionIdentity.triggered.connect(self.actionIdentifyTriggered)

        # 图层
        self.actionShapefile.triggered.connect(self.actionShapefileTriggered)
        self.actionCsv.triggered.connect(self.actionCsvTriggered)
        self.actionPostGIS.triggered.connect(self.actionPostGISTriggered)
        self.actionWFS.triggered.connect(self.actionWFSTriggered)

        self.actionGeotiff.triggered.connect(self.actionGeotiffTriggered)
        self.actionXYZ.triggered.connect(self.actionXYZTriggered)

        # 绘图工具
        self.actionPoint.triggered.connect(self.actionPointTriggered)
        self.actionLine.triggered.connect(self.actionLineTriggered)
        self.actionRectangle.triggered.connect(self.actionRectangleTriggered)
        self.actionPolygon.triggered.connect(self.actionPolygonTriggered)

        # 关于Qt
        self.actionAboutQt.triggered.connect(
            lambda: QMessageBox.aboutQt(self, '关于Qt'))
        self.actionAbout.triggered.connect(
            lambda: QMessageBox.about(self, '关于', 'PyQGIS二次开发'))

        # self.actionPan.triggered.connect(self.actionPanTriggered)
        # self.actionIdentify.triggered.connect(self.actionIdentifyTriggered)

        # 图层右键菜单
        self.customMenuProvider = CustomMenuProvider(self.layerTreeView,
                                                     self.mapCanvas)
        self.layerTreeView.setMenuProvider(self.customMenuProvider)
        # self.layerTreeRegistryBridge = QgsLayerTreeRegistryBridge(PROJECT.layerTreeRoot(), PROJECT, self)

    def actionOpenTriggered(self):
        """打开工程"""
        data_file, ext = QFileDialog.getOpenFileName(self, '打开', '',
                                                     '工程文件(*.qgs , *.qgz)')
        if data_file:
            PROJECT.read(data_file)

    def actionPanTriggered(self):
        self.mapTool = QgsMapToolPan(self.mapCanvas)
        self.mapCanvas.setMapTool(self.mapTool)

    def actionZoomInTriggered(self):
        self.mapTool = QgsMapToolZoom(self.mapCanvas, False)
        self.mapCanvas.setMapTool(self.mapTool)

    def actionZoomOutTriggered(self):
        self.mapTool = QgsMapToolZoom(self.mapCanvas, True)
        self.mapCanvas.setMapTool(self.mapTool)

    def actionIdentifyTriggered(self):
        # 设置识别工具
        self.identifyTool = QgsMapToolIdentifyFeature(self.mapCanvas)
        self.identifyTool.featureIdentified.connect(self.showFeatures)
        self.mapCanvas.setMapTool(self.identifyTool)

        # 设置需要识别的图层
        layers = self.mapCanvas.layers()
        if layers:
            # 识别画布中第一个图层
            self.identifyTool.setLayer(layers[0])

    def showFeatures(self, feature):
        print(type(feature))

        QMessageBox.information(self, '信息', ''.join(feature.attributes()))

    def actionAddGroupTriggered(self):
        PROJECT.layerTreeRoot().addGroup('group1')

    def actionShapefileTriggered(self):
        """打开shp"""
        data_file, ext = QFileDialog.getOpenFileName(self, '打开', '', '*.shp')
        if data_file:
            layer = QgsVectorLayer(
                data_file,
                os.path.splitext(os.path.basename(data_file))[0], "ogr")
            self.addLayer(layer)

    def actionCsvTriggered(self):
        """加载csv数据"""
        data_file, ext = QFileDialog.getOpenFileName(self, '打开', '', '*.csv')
        if data_file:
            # 去掉盘符,否则图层无效
            data_file = os.path.splitdrive(data_file)[1]
            uri = f"file://{data_file}?delimiter=,&xField=x&yField=y"
            print(uri)
            layer = QgsVectorLayer(uri, "point", "delimitedtext")
            self.addLayer(layer)

    def actionPostGISTriggered(self):
        """加载postgis图层"""
        dialog = PostGISDialog(self)
        if dialog.exec_():
            uri = QgsDataSourceUri()
            uri.setConnection(dialog.lineEditHost.text(),
                              dialog.lineEditPort.text(),
                              dialog.lineEditDatabase.text(),
                              dialog.lineEditUsername.text(),
                              dialog.lineEditPassword.text())
            # lineEditGeometryColumn:根据实际情况,可能为:wkb_geometry、geometry、the_geom...
            uri.setDataSource("public", dialog.lineEditLayer.text(),
                              dialog.lineEditGeometryColumn.text())

            layer = QgsVectorLayer(uri.uri(False), dialog.lineEditLayer.text(),
                                   "postgres")
            self.addLayer(layer)

    def actionWFSTriggered(self):
        """加载天地图WFS图层"""
        uri = 'http://gisserver.tianditu.gov.cn/TDTService/wfs?' \
              'srsname=EPSG:4326&typename=TDTService:RESA&version=auto&request=GetFeature&service=WFS'
        layer = QgsVectorLayer(uri, "RESA", "WFS")
        self.addLayer(layer)

    def actionGeotiffTriggered(self):
        """加载geotiff"""
        data_file, ext = QFileDialog.getOpenFileName(self, '打开', '', '*.tif')
        if data_file:
            layer = QgsRasterLayer(data_file, os.path.basename(data_file))
            self.addLayer(layer)

    def actionXYZTriggered(self):
        uri = 'type=xyz&' \
              'url=https://www.google.cn/maps/vt?lyrs=s@804%26gl=cn%26x={x}%26y={y}%26z={z}&' \
              'zmax=19&' \
              'zmin=0&' \
              'crs=EPSG3857'
        layer = QgsRasterLayer(uri, 'google', 'wms')
        self.addLayer(layer)

    def addLayer(self, layer):
        if layer.isValid():
            if self.first_flag:
                self.mapCanvas.setDestinationCrs(layer.crs())
                self.mapCanvas.setExtent(layer.extent())
                self.first_flag = False
            PROJECT.addMapLayer(layer)
            layers = [layer
                      ] + [PROJECT.mapLayer(i) for i in PROJECT.mapLayers()]
            self.mapCanvas.setLayers(layers)
            self.mapCanvas.refresh()
        else:
            print('图层无效.')

    def actionPointTriggered(self):
        self.pointTool = PointMapTool(self.mapCanvas)
        self.mapCanvas.setMapTool(self.pointTool)

    def actionLineTriggered(self):
        self.lineTool = LineMapTool(self.mapCanvas)
        self.mapCanvas.setMapTool(self.lineTool)

    def actionRectangleTriggered(self):
        self.rectangleTool = RectangleMapTool(self.mapCanvas)
        self.mapCanvas.setMapTool(self.rectangleTool)

    def actionPolygonTriggered(self):
        self.polygonTool = PolygonMapTool(self.mapCanvas)
        self.mapCanvas.setMapTool(self.polygonTool)

    def showLngLat(self, point):
        x = point.x()
        y = point.y()
        self.statusbar.showMessage(f'经度:{x}, 纬度:{y}')
コード例 #25
0
class FeatureSelectorWidget(QWidget):
    feature_identified = pyqtSignal(QgsFeature)

    def __init__(self, parent):
        QWidget.__init__(self, parent)

        edit_layout = QHBoxLayout()
        edit_layout.setContentsMargins(0, 0, 0, 0)
        edit_layout.setSpacing(2)
        self.setLayout(edit_layout)

        self.line_edit = QLineEdit(self)
        self.line_edit.setReadOnly(True)
        edit_layout.addWidget(self.line_edit)

        self.highlight_feature_button = QToolButton(self)
        self.highlight_feature_button.setPopupMode(QToolButton.MenuButtonPopup)
        self.highlight_feature_action = QAction(
            QgsApplication.getThemeIcon("/mActionHighlightFeature.svg"),
            "Highlight feature", self)
        self.scale_highlight_feature_action = QAction(
            QgsApplication.getThemeIcon("/mActionScaleHighlightFeature.svg"),
            "Scale and highlight feature", self)
        self.pan_highlight_feature_action = QAction(
            QgsApplication.getThemeIcon("/mActionPanHighlightFeature.svg"),
            "Pan and highlight feature", self)
        self.highlight_feature_button.addAction(self.highlight_feature_action)
        self.highlight_feature_button.addAction(
            self.scale_highlight_feature_action)
        self.highlight_feature_button.addAction(
            self.pan_highlight_feature_action)
        self.highlight_feature_button.setDefaultAction(
            self.highlight_feature_action)
        edit_layout.addWidget(self.highlight_feature_button)

        self.map_identification_button = QToolButton(self)
        self.map_identification_button.setIcon(
            QgsApplication.getThemeIcon("/mActionMapIdentification.svg"))
        self.map_identification_button.setText("Select on map")
        self.map_identification_button.setCheckable(True)
        edit_layout.addWidget(self.map_identification_button)

        self.map_identification_button.clicked.connect(self.map_identification)
        self.highlight_feature_button.triggered.connect(
            self.highlight_action_triggered)

        self.layer = None
        self.map_tool = None
        self.canvas = None
        self.window_widget = None
        self.highlight = None
        self.feature = QgsFeature()

    def set_canvas(self, map_canvas):
        self.map_tool = QgsMapToolIdentifyFeature(map_canvas)
        self.map_tool.setButton(self.map_identification_button)
        self.canvas = map_canvas

    def set_layer(self, layer):
        self.layer = layer

    def set_feature(self, feature, canvas_extent=CanvasExtent.Fixed):
        self.line_edit.clear()
        self.feature = feature

        if self.feature is None or not self.feature.isValid(
        ) or self.layer is None:
            return

        expression = QgsExpression(self.layer.displayExpression())
        context = QgsExpressionContext()
        scope = QgsExpressionContextScope()
        context.appendScope(scope)
        scope.setFeature(feature)
        feature_title = expression.evaluate(context)
        if feature_title == "":
            feature_title = feature.id()
        self.line_edit.setText(str(feature_title))
        self.highlight_feature(canvas_extent)

    def clear(self):
        self.feature = QgsFeature()
        self.line_edit.clear()

    @pyqtSlot()
    def map_identification(self):
        if self.layer is None or self.map_tool is None or self.canvas is None:
            return

        self.map_tool.setLayer(self.layer)
        self.canvas.setMapTool(self.map_tool)

        self.window_widget = QWidget.window(self)
        self.canvas.window().raise_()
        self.canvas.activateWindow()
        self.canvas.setFocus()

        self.map_tool.featureIdentified.connect(
            self.map_tool_feature_identified)
        self.map_tool.deactivated.connect(self.map_tool_deactivated)

    def map_tool_feature_identified(self, feature):
        feature = QgsFeature(feature)
        self.feature_identified.emit(feature)
        self.unset_map_tool()
        self.set_feature(feature)

    def map_tool_deactivated(self):
        if self.window_widget is not None:
            self.window_widget.raise_()
            self.window_widget.activateWindow()

    def highlight_feature(self, canvas_extent=CanvasExtent.Fixed):
        if self.canvas is None or not self.feature.isValid():
            return

        geom = self.feature.geometry()

        if geom is None:
            return

        if canvas_extent == CanvasExtent.Scale:
            feature_bounding_box = geom.boundingBox()
            feature_bounding_box = self.canvas.mapSettings(
            ).layerToMapCoordinates(self.layer, feature_bounding_box)
            extent = self.canvas.extent()
            if not extent.contains(feature_bounding_box):
                extent.combineExtentWith(feature_bounding_box)
                extent.scale(1.1)
                self.canvas.setExtent(extent)
                self.canvas.refresh()

        elif canvas_extent == CanvasExtent.Pan:
            centroid = geom.centroid()
            center = centroid.asPoint()

            center = self.canvas.mapSettings().layerToMapCoordinates(
                self.layer, center)
            self.canvas.zoomByFactor(1.0,
                                     center)  # refresh is done in this method

        # highlight
        self.delete_highlight()
        self.highlight = QgsHighlight(self.canvas, geom, self.layer)

        settings = QSettings()
        color = QColor(
            settings.value("/Map/highlight/color",
                           Qgis.DEFAULT_HIGHLIGHT_COLOR.name()))
        alpha = int(
            settings.value("/Map/highlight/colorAlpha",
                           Qgis.DEFAULT_HIGHLIGHT_COLOR.alpha()))
        buffer = 2 * float(
            settings.value("/Map/highlight/buffer",
                           Qgis.DEFAULT_HIGHLIGHT_BUFFER_MM))
        min_width = 2 * float(
            settings.value("/Map/highlight/min_width",
                           Qgis.DEFAULT_HIGHLIGHT_MIN_WIDTH_MM))

        self.highlight.setColor(color)  # sets also fill with default alpha
        color.setAlpha(alpha)
        self.highlight.setFillColor(color)  # sets fill with alpha
        self.highlight.setBuffer(buffer)
        self.highlight.setMinWidth(min_width)
        self.highlight.setWidth(4.0)
        self.highlight.show()

        self.timer = QTimer(self)
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.delete_highlight)
        self.timer.start(3000)

    def delete_highlight(self):
        if self.highlight is not None:
            self.highlight.hide()
            del self.highlight
            self.highlight = None

    def unset_map_tool(self):
        if self.canvas is not None and self.map_tool is not None:
            # this will call mapTool.deactivated
            self.canvas.unsetMapTool(self.map_tool)

    def highlight_action_triggered(self, action):
        self.highlight_feature_button.setDefaultAction(action)

        if action == self.highlight_feature_action:
            self.highlight_feature()

        elif action == self.scale_highlight_feature_action:
            self.highlight_feature(CanvasExtent.Scale)

        elif action == self.pan_highlight_feature_action:
            self.highlight_feature(CanvasExtent.Pan)
コード例 #26
0
class EdgeCreator(QDockWidget, gui_dckwdgt_edge_creator):

    def __init__(self, canvas, l_vertex, l_edge,
                 user=None, auth_creator=[], parent=None):

        super(EdgeCreator, self).__init__(parent)
        self.setupUi(self)

        # Delete Widget on close event..
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.save = False

        self.canvas = canvas
        self.l_edge = l_edge
        self.l_vertex = l_vertex
        self.user = user
        self.auth_creator = auth_creator

        self.vertices = self.l_vertex.getFeatures()
        self.vtx_start = None
        self.vtx_end = None
        self.selected_vertices = [None, None]

        self.edge = None

        for i, vertex in enumerate(self.vertices):

            self.startVertexComboBox.insertItem(i, str(vertex.id()))
            self.startVertexComboBox.setItemData(i, vertex, 32)
            self.startVertexComboBox.setCurrentIndex(-1)

            self.endVertexComboBox.insertItem(i, str(vertex.id()))
            self.endVertexComboBox.setItemData(i, vertex, 32)
            self.endVertexComboBox.setCurrentIndex(-1)

        # Attribute: `som_createur`
        for i, e in enumerate(self.auth_creator):
            self.creatorComboBox.addItem(u"%s (%s)" % (e[1], e[0]))
            if self.user == e[0]:
                self.creatorComboBox.setCurrentIndex(i)

        self.startVertextoolButton.clicked.connect(self.select_start_vertex_on_canvas)
        self.endVertextoolButton.clicked.connect(self.select_end_vertex_on_canvas)

        self.startVertexComboBox.highlighted.connect(self.on_vtx_start_pressed)
        self.endVertexComboBox.highlighted.connect(self.on_vtx_end_pressed)
        self.startVertexComboBox.currentIndexChanged.connect(self.on_vtx_start_pressed)
        self.endVertexComboBox.currentIndexChanged.connect(self.on_vtx_end_pressed)

        self.startVertexComboBox.highlighted.connect(self.create_edge)
        self.endVertexComboBox.highlighted.connect(self.create_edge)
        self.startVertexComboBox.currentIndexChanged.connect(self.create_edge)
        self.endVertexComboBox.currentIndexChanged.connect(self.create_edge)

        self.buttonBox.accepted.connect(self.on_accepted)
        self.buttonBox.rejected.connect(self.on_rejected)
        self.buttonBox.button(QDialogButtonBox.Reset).clicked.connect(self.on_reset)

    def closeEvent(self, event):
        if not self.save:
            self.on_rejected()

    def select_start_vertex_on_canvas(self):

        self.identify_start_vertex = QgsMapToolIdentifyFeature(self.canvas, self.l_vertex)
        self.identify_start_vertex.setCursor(QCursor(Qt.PointingHandCursor))
        self.identify_start_vertex.featureIdentified.connect(self.on_start_vertex_identified)
        self.canvas.setMapTool(self.identify_start_vertex)

    def select_end_vertex_on_canvas(self):

        self.identify_end_vertex = QgsMapToolIdentifyFeature(self.canvas, self.l_vertex)
        self.identify_end_vertex.setCursor(QCursor(Qt.PointingHandCursor))
        self.identify_end_vertex.featureIdentified.connect(self.on_end_vertex_identified)
        self.canvas.setMapTool(self.identify_end_vertex)

    def on_start_vertex_identified(self, feature):

        cb = self.startVertexComboBox
        items = [cb.itemText(i) for i in range(cb.count())]
        for i, e in enumerate(items):
            if int(feature.id()) == int(e):
                cb.setCurrentIndex(i)

    def on_end_vertex_identified(self, feature):

        cb = self.endVertexComboBox
        items = [cb.itemText(i) for i in range(cb.count())]
        for i, e in enumerate(items):
            if int(feature.id()) == int(e):
                cb.setCurrentIndex(i)

    def on_vtx_start_pressed(self, idx):

        self.vtx_start = self.startVertexComboBox.itemData(idx, 32)
        self.select_vertices(self.vtx_start, 0)

        self.endVertexComboBox.setEnabled(True)
        self.endVertextoolButton.setEnabled(True)

    def on_vtx_end_pressed(self, idx):

        self.vtx_end = self.endVertexComboBox.itemData(idx, 32)
        self.select_vertices(self.vtx_end, 1)

        self.creatorComboBox.setEnabled(True)

    def select_vertices(self, feature, i):
        if feature:
            self.selected_vertices[i] = feature.id()
        else:
            self.selected_vertices[i] = None
        self.l_vertex.setSelectedFeatures(self.selected_vertices)

    def unselect_vertices(self):
        self.l_vertex.setSelectedFeatures([])

    def create_edge(self):

        # If edge already exists, delete it..
        if self.edge:
            self.l_edge.deleteFeature(self.edge.id())

        # Two vertices are needed..
        if not self.vtx_start or not self.vtx_end:
            return self.canvas.refresh()

        # Two DIFFERENT vertices..
        if self.vtx_start == self.vtx_end:
            return self.canvas.refresh()

        # Create line geometry..
        line = QgsGeometry.fromPolyline([self.vtx_start.geometry().asPoint(),
                                         self.vtx_end.geometry().asPoint()])

        # Create the feature..
        self.edge = QgsFeature()
        self.edge.setGeometry(line)
        self.edge.setFields(self.l_edge.pendingFields())
        self.edge.setAttributes(
                [QPyNullVariant(int), QPyNullVariant(int), QPyNullVariant(int)])

        # Add feature to layer..
        self.l_edge.addFeature(self.edge)
        self.canvas.refresh()

    def on_accepted(self):

        if not self.edge:
            return False

        self.lim_ge_createur = self.auth_creator[self.creatorComboBox.currentIndex()][0]
        self.edge.setAttributes(
                [QPyNullVariant(int), QPyNullVariant(int), self.lim_ge_createur])
        self.l_edge.updateFeature(self.edge)
        self.canvas.refresh()
        self.save = True
        self.close()

    def on_rejected(self):

        # Do not save the feature..
        if self.edge:
            self.l_edge.deleteFeature(self.edge.id())

        self.unselect_vertices()
        self.canvas.refresh()
        self.close()

    def on_reset(self):

        self.startVertexComboBox.setCurrentIndex(0)
        # self.startVertexComboBox.setEnabled(True)
        # self.startVertexLabel.setEnabled(True)

        self.endVertexComboBox.setCurrentIndex(0)
        self.endVertexComboBox.setEnabled(False)
        self.endVertexLabel.setEnabled(False)
        self.endVertextoolButton.setEnabled(False)

        for i, e in enumerate(self.auth_creator):
            if self.user == e[0]:
                self.creatorComboBox.setCurrentIndex(i)
        self.creatorComboBox.setEnabled(False)
        self.creatorLabel.setEnabled(False)

        self.unselect_vertices()
        self.canvas.refresh()
コード例 #27
0
ファイル: linkerdock.py プロジェクト: 3nids/linkit
class LinkerDock(QDockWidget, Ui_linker, SettingDialog):
    def __init__(self, iface):
        # QGIS
        self.iface = iface
        self.settings = MySettings()
        self.linkRubber = QgsRubberBand(self.iface.mapCanvas())
        self.featureHighlight = None
        # Relation management
        self.relationManager = QgsProject.instance().relationManager()
        self.relationManager.changed.connect(self.loadRelations)
        self.relation = QgsRelation()
        self.referencingFeature = QgsFeature()
        self.relationWidgetWrapper = None
        self.editorContext = QgsAttributeEditorContext()
        self.editorContext.setVectorLayerTools(self.iface.vectorLayerTools())

        # GUI
        QDockWidget.__init__(self)
        self.setupUi(self)
        SettingDialog.__init__(self, MySettings(), False, True)
        self.drawButton.setChecked(self.settings.value("drawEnabled"))

        self.relationReferenceWidget.setAllowMapIdentification(True)
        self.relationReferenceWidget.setEmbedForm(False)

        self.mapTool = QgsMapToolIdentifyFeature(self.iface.mapCanvas())
        self.mapTool.setButton(self.identifyReferencingFeatureButton)

        # Connect signal/slot
        self.relationComboBox.currentIndexChanged.connect(self.currentRelationChanged)
        self.mapTool.featureIdentified.connect(self.setReferencingFeature)

        # load relations at start
        self.loadRelations()

    def showEvent(self, QShowEvent):
        self.drawLink()

    def closeEvent(self, e):
        self.iface.mapCanvas().unsetMapTool(self.mapTool)
        self.linkRubber.reset()
        self.deleteHighlight()
        self.deleteWrapper()
        self.disconnectLayer()

    def disconnectLayer(self):
        if self.relation.isValid():
            self.relation.referencingLayer().editingStarted.disconnect(self.relationEditableChanged)
            self.relation.referencingLayer().editingStopped.disconnect(self.relationEditableChanged)
            self.relation.referencingLayer().attributeValueChanged.disconnect(self.layerValueChangedOutside)

    def runForFeature(self, relationId, layer, feature):
        index = self.relationComboBox.findData(relationId)
        self.relationComboBox.setCurrentIndex(index)
        self.setReferencingFeature(feature)
        self.show()
        if not layer.isEditable():
            self.iface.messageBar().pushMessage("Link It", "Cannot set a new related feature since %s is not editable" % layer.name(), QgsMessageBar.WARNING, 4)
        else:
            self.relationReferenceWidget.mapIdentification()

    @pyqtSlot(name="on_identifyReferencingFeatureButton_clicked")
    def activateMapTool(self):
        self.iface.mapCanvas().setMapTool(self.mapTool)

    def deactivateMapTool(self):
        self.iface.mapCanvas().unsetMapTool(self.mapTool)

    def loadRelations(self):
        self.deleteWrapper()
        self.disconnectLayer()
        self.relation = QgsRelation()
        self.referencingFeature = QgsFeature()
        self.relationComboBox.currentIndexChanged.disconnect(self.currentRelationChanged)
        self.relationComboBox.clear()
        for relation in self.relationManager.referencedRelations():
            if relation.referencingLayer().hasGeometryType():
                self.relationComboBox.addItem(relation.name(), relation.id())
        self.relationComboBox.setCurrentIndex(-1)
        self.relationComboBox.currentIndexChanged.connect(self.currentRelationChanged)
        self.currentRelationChanged(-1)

    def currentRelationChanged(self, index):
        # disconnect previous relation
        if self.relation.isValid():
            try:
                self.relation.referencingLayer().editingStarted.disconnect(self.relationEditableChanged)
                self.relation.referencingLayer().editingStopped.disconnect(self.relationEditableChanged)
                self.relation.referencingLayer().attributeValueChanged.disconnect(self.layerValueChangedOutside)
            except TypeError:
                pass

        self.referencingFeatureLayout.setEnabled(index >= 0)
        relationId = self.relationComboBox.itemData(index)
        self.relation = self.relationManager.relation(relationId)
        self.mapTool.setLayer(self.relation.referencingLayer())
        self.setReferencingFeature()
        # connect
        if self.relation.isValid():
            self.relation.referencingLayer().editingStarted.connect(self.relationEditableChanged)
            self.relation.referencingLayer().editingStopped.connect(self.relationEditableChanged)
            self.relation.referencingLayer().attributeValueChanged.connect(self.layerValueChangedOutside)

    def setReferencingFeature(self, feature=QgsFeature()):
        self.deactivateMapTool()
        self.referencingFeature = QgsFeature(feature)
        self.deleteWrapper()

        # disable relation reference widget if no referencing feature
        self.referencedFeatureLayout.setEnabled(feature.isValid())

        # set line edit
        if not self.relation.isValid() or not feature.isValid():
            self.referencingFeatureLineEdit.clear()
            return
        self.referencingFeatureLineEdit.setText("%s" % feature.id())

        fieldIdx = self.referencingFieldIndex()
        widgetConfig = self.relation.referencingLayer().editorWidgetV2Config(fieldIdx)
        self.relationWidgetWrapper = QgsEditorWidgetRegistry.instance().create("RelationReference",
                                                                               self.relation.referencingLayer(),
                                                                               fieldIdx,
                                                                               widgetConfig,
                                                                               self.relationReferenceWidget,
                                                                               self,
                                                                               self.editorContext)

        self.relationWidgetWrapper.setEnabled(self.relation.referencingLayer().isEditable())
        self.relationWidgetWrapper.setValue(feature[fieldIdx])
        self.relationWidgetWrapper.valueChanged.connect(self.foreignKeyChanged)
        # override field definition to allow map identification
        self.relationReferenceWidget.setAllowMapIdentification(True)
        self.relationReferenceWidget.setEmbedForm(False)

        # update drawn link
        self.highlightReferencingFeature()
        self.drawLink()

    def deleteWrapper(self):
        if self.relationWidgetWrapper is not None:
            self.relationWidgetWrapper.valueChanged.disconnect(self.foreignKeyChanged)
            self.relationWidgetWrapper.setValue(None)
            del self.relationWidgetWrapper
            self.relationWidgetWrapper = None

    def foreignKeyChanged(self, newKey):
        if not self.relation.isValid() or not self.relation.referencingLayer().isEditable() or not self.referencingFeature.isValid():
            self.drawLink()
            return
        if not self.relation.referencingLayer().editBuffer().changeAttributeValue(self.referencingFeature.id(), self.referencingFieldIndex(), newKey):
            self.iface.messageBar().pushMessage("Link It", "Cannot change attribute value.", QgsMessageBar.CRITICAL)
        self.drawLink()

    def relationEditableChanged(self):
        if self.relationWidgetWrapper is not None:
            self.relationWidgetWrapper.setEnabled(self.relation.isValid() and self.relation.referencingLayer().isEditable())

    def layerValueChangedOutside(self, fid, fieldIdx, value):
        if not self.relation.isValid() or not self.referencingFeature.isValid() or self.relationWidgetWrapper is None:
            return
        # not the correct feature
        if fid != self.referencingFeature.id():
            return
        # not the correct field
        if fieldIdx != self.referencingFieldIndex():
            return
        # widget already has this value
        if value == self.relationWidgetWrapper.value():
            return
        self.relationWidgetWrapper.valueChanged.disconnect(self.foreignKeyChanged)
        self.relationWidgetWrapper.setValue(value)
        self.relationWidgetWrapper.valueChanged.connect(self.foreignKeyChanged)

    def referencingFieldIndex(self):
        if not self.relation.isValid():
            return -1
        fieldName = self.relation.fieldPairs().keys()[0]
        fieldIdx = self.relation.referencingLayer().fieldNameIndex(fieldName)
        return fieldIdx

    @pyqtSlot(bool, name="on_drawButton_toggled")
    def drawLink(self):
        self.settings.setValue("drawEnabled", self.drawButton.isChecked())
        self.linkRubber.reset()
        if not self.drawButton.isChecked() or not self.referencingFeature.isValid() or not self.relation.isValid():
            return

        referencedFeature = self.relationReferenceWidget.referencedFeature()
        if not referencedFeature.isValid():
            return

        p1 = self.centroid(self.relation.referencedLayer(), referencedFeature)
        p2 = self.centroid(self.relation.referencingLayer(), self.referencingFeature)
        geom = arc(p1, p2)

        self.linkRubber.setToGeometry(geom, None)
        self.linkRubber.setWidth(self.settings.value("rubberWidth"))
        self.linkRubber.setColor(self.settings.value("rubberColor"))
        self.linkRubber.setLineStyle(Qt.DashLine)

    def centroid(self, layer, feature):
        geom = feature.geometry()
        if geom.type() == QGis.Line:
            geom = geom.interpolate(geom.length()/2)
        else:
            geom = geom.centroid()
        return self.iface.mapCanvas().mapSettings().layerToMapCoordinates(layer, geom.asPoint())

    @pyqtSlot(name="on_highlightReferencingFeatureButton_clicked")
    def highlightReferencingFeature(self):
        self.deleteHighlight()
        if not self.relation.isValid() or not self.referencingFeature.isValid():
            return
        
        self.featureHighlight = QgsHighlight(self.iface.mapCanvas(), self.referencingFeature.geometry(), self.relation.referencingLayer())
        settings = QSettings()
        color = QColor( settings.value("/Map/highlight/color", QGis.DEFAULT_HIGHLIGHT_COLOR.name()))
        alpha = int(settings.value("/Map/highlight/colorAlpha", QGis.DEFAULT_HIGHLIGHT_COLOR.alpha()))
        bbuffer = float(settings.value("/Map/highlight/buffer", QGis.DEFAULT_HIGHLIGHT_BUFFER_MM))
        minWidth = float(settings.value("/Map/highlight/minWidth", QGis.DEFAULT_HIGHLIGHT_MIN_WIDTH_MM))
        
        self.featureHighlight.setColor(color)
        color.setAlpha(alpha)
        self.featureHighlight.setFillColor(color)
        self.featureHighlight.setBuffer(bbuffer)
        self.featureHighlight.setMinWidth(minWidth)
        self.featureHighlight.show()

        timer = QTimer(self)
        timer.setSingleShot(True)
        timer.timeout.connect(self.deleteHighlight)
        timer.start(3000)

    def deleteHighlight(self):
        if self.featureHighlight:
            del self.featureHighlight
        self.featureHighlight = None
コード例 #28
0
    def select_end_vertex_on_canvas(self):

        self.identify_end_vertex = QgsMapToolIdentifyFeature(self.canvas, self.l_vertex)
        self.identify_end_vertex.setCursor(QCursor(Qt.PointingHandCursor))
        self.identify_end_vertex.featureIdentified.connect(self.on_end_vertex_identified)
        self.canvas.setMapTool(self.identify_end_vertex)
コード例 #29
0
 def __init__(self, canvas):
     self.canvas = canvas
     QgsMapToolIdentifyFeature.__init__(self, self.canvas)
コード例 #30
0
 def updateSelectedElectorate(self):
     self.dockwidget.lblActiveDistrict.setText("Click on the map...")
     self.featIdentTool = QgsMapToolIdentifyFeature(self.canvas)
     self.featIdentTool.featureIdentified.connect(self.toolbtnSelectAction)
     self.featIdentTool.setLayer(self.activeLayer)
     self.canvas.setMapTool(self.featIdentTool)
コード例 #31
0
 def __init__(self, canvas, iface):
     self.canvas = canvas
     self.iface = iface
     QgsMapToolIdentifyFeature.__init__(self, self.canvas)
コード例 #32
0
 def setCanvas(self, mapCanvas):
     self.mapTool = QgsMapToolIdentifyFeature(mapCanvas)
     self.mapTool.setButton(self.mapIdentificationButton)
     self.canvas = mapCanvas
コード例 #33
0
class TransfoPtToPlot(QDialog, gui_dlg_transfo_pttoplot):
    
    def __init__(self, canvas, project, l_vertex, l_edge, parent=None):

        super(TransfoPtToPlot, self).__init__(parent)
        self.setupUi(self)

        self.canvas = canvas
        self.project = project
        self.l_edge = l_edge
        self.l_vertex = l_vertex
        
        self.sel_nw_vtx = None
                
        self.resize_dlg = ResizeDlg(self, "dlg_transfo_pt_to_plots")
        self.resize_params = self.resize_dlg.load_dlgresize()
        self.resize_on = self.resize_params["dlg_transfo_pt_to_plots"]
        
        self.buttValid.clicked.connect(self.close)
        self.buttResize.clicked.connect(self.resize_dlg.dlg_ch_resize)
        self.selrfuvtxnearButt.clicked.connect(self.sel_nwvtxnear_rfu)
        self.nearvtxvalButt.clicked.connect(self.nwvtx_valid)
        self.selnwvxtButt.clicked.connect(self.sel_nwvtxfar)
        self.selrfuvtxfarButt.clicked.connect(self.sel_rfuvtxfar)
        self.nearvtxTbv.clicked.connect(self.tbv_sel)
        
        # Delete Widget on close event
        self.setAttribute(Qt.WA_DeleteOnClose)
 
    # Zoom to 2 new + RFU vertices if a line is selected in the tableview
    def tbv_sel(self):
        # Find the selected cell (considering only the first selected cell)
        idx = self.nearvtxTbv.selectedIndexes()[0].row()
        # Find the new vertex feature and the near RFU vertex feature
        self.sel_nw_vtx = self.nr_feats[idx]
        id_rfu_vtx = self.nr_feats[idx]["point_rfu_proche"]
        rfu_vtx = feats_by_cond(self.l_vertex, r"@id_noeud", id_rfu_vtx)[0]
        # Zoom to the 2 features
        self.canvas.zoomToFeatureIds(self.l_vertex, [self.sel_nw_vtx.id(), rfu_vtx.id()])

    # Let the user select the new vertex to transform into a plot
    def sel_nwvtxfar(self):
        # Selection in the canvas
        self.hide()
        self.identify_nwvtxfar_vtx = QgsMapToolIdentifyFeature(self.canvas, self.l_vertex)
        self.identify_nwvtxfar_vtx.setCursor(QCursor(Qt.PointingHandCursor))
        self.identify_nwvtxfar_vtx.featureIdentified.connect(self.far_nwvtx_identified)
        self.canvas.setMapTool(self.identify_nwvtxfar_vtx)

    def far_nwvtx_identified(self, feat):
        self.l_vertex.selectByIds([feat.id()])
        # Check if the point selected is a new vertex
        if not feat[r"@id_noeud"]:
            self.sel_nw_vtx = feat
            self.canvas.unsetMapTool(self.identify_nwvtxfar_vtx)
            self.dlg_show()
        else:
            QMessageBox.warning(self, tr_vtxplt_notnwvtx_msg[0], tr_vtxplt_notnwvtx_msg[1])
       
    
    # Let the user select the RFU vertex to use with the far new vertex
    def sel_rfuvtxfar(self):
        # Selection in the canvas
        if self.sel_nw_vtx:
            self.hide()
            self.identify_rfuvtxfar_vtx = QgsMapToolIdentifyFeature(self.canvas, self.l_vertex)
            self.identify_rfuvtxfar_vtx.setCursor(QCursor(Qt.PointingHandCursor))
            self.identify_rfuvtxfar_vtx.featureIdentified.connect(partial(self.rfu_vtx_identified, "far"))
            self.canvas.setMapTool(self.identify_rfuvtxfar_vtx)
        # Message if no line selected in the tableview
        else:
            QMessageBox.warning(self, tr_vtxplt_sel_nonwvtxsel_msg[0], tr_vtxplt_sel_nonwvtxsel_msg[1])  

    # Let the user select the RFU vertex near the new vertex
    def sel_nwvtxnear_rfu(self):
        # Selection in the canvas
        if self.sel_nw_vtx:
            self.hide()
            self.identify_rfu_vtx = QgsMapToolIdentifyFeature(self.canvas, self.l_vertex)
            self.identify_rfu_vtx.setCursor(QCursor(Qt.PointingHandCursor))
            self.identify_rfu_vtx.featureIdentified.connect(partial(self.rfu_vtx_identified, "near"))
            self.canvas.setMapTool(self.identify_rfu_vtx)
        # Message if no line selected in the tablview
        else:
            QMessageBox.warning(self, tr_vtxplt_sel_nolinesel_msg[0], tr_vtxplt_sel_nolinesel_msg[1])
        
    def rfu_vtx_identified(self, vtx_type, feat):
        self.vtx_type = vtx_type
        self.l_vertex.selectByIds([feat.id()])
        if self.vtx_type == "near":
            self.canvas.unsetMapTool(self.identify_rfu_vtx)
        else:
            self.canvas.unsetMapTool(self.identify_rfuvtxfar_vtx)
        # Check if the point selected is a RFU vertex
        if feat[r"@id_noeud"]:
            id_node = feat[r"@id_noeud"]
            # Tolerance in cm
            tol = feat[r"som_tolerance"]*100
            nw_coord_e = self.sel_nw_vtx["som_coord_est"]
            nw_coord_n = self.sel_nw_vtx["som_coord_nord"]
            nw_rep_plane = self.sel_nw_vtx["som_representation_plane"]
            nw_pt_cc = QgsPointXY(self.sel_nw_vtx["som_coord_est"], self.sel_nw_vtx["som_coord_nord"])
            rfu_pt_cc = QgsPointXY(feat["som_coord_est"], feat["som_coord_nord"])
            # Distance between the 2 points in cm
            dist_vtx = dist_2_pts(nw_pt_cc, rfu_pt_cc)*100
            if dist_vtx < tol:
                self.vtx_type = "near"
            # Check if the 2 points have the same som_representation_plane
            # Otherwise, cancel the process
            if nw_rep_plane == feat["som_representation_plane"]:
                if self.vtx_type == "near":
                    tl_msg = tr_vtxplt_confirm_msg[0]
                    txt_msg = tr_vtxplt_confirm_msg[1].format(nw_coord_e, nw_coord_n, id_node)
                else:
                    tl_msg = tr_vtxplt_attest_msg[0]
                    txt_msg = tr_vtxplt_attest_msg[1].format(nw_coord_e, nw_coord_n, id_node, dist_vtx, tol)
                confirm = QMessageBox.question( self, tl_msg, txt_msg, 
                                                QMessageBox.Yes | QMessageBox.No)
                if confirm == QMessageBox.Yes:
                    nw_vals = {}
                    for att in tr_toplot_atts:
                        id_att = self.l_vertex.fields().indexFromName(att)
                        nw_vals[id_att] = self.sel_nw_vtx[att]
                    # Change the atteste_qualite value
                    if self.vtx_type == "far":
                        id_att = self.l_vertex.fields().indexFromName("attestation_qualite")
                        nw_vals[id_att] = "true"
                    self.l_vertex.changeAttributeValues(feat.id(), nw_vals)
                    self.l_vertex.deleteFeature(self.sel_nw_vtx.id())
                    self.tr_edges(self.sel_nw_vtx.geometry(), feat.geometry())
                    self.canvas.refresh()
                    QMessageBox.information(
                                self, 
                                tr_vtxplot_transfok_msg[0], 
                                tr_vtxplot_transfok_msg[1].format(nw_coord_e, nw_coord_n, id_node))
                # Process canceled by the user    
                else:
                    QMessageBox.information(self, tr_vtxplt_canceld_msg[0], tr_vtxplt_canceld_msg[1])
            # Case of no same som_representation_plane
            else:
                QMessageBox.warning(self, tr_vtxplot_nosamerp_msg[0], tr_vtxplot_nosamerp_msg[1])
            self.nearvtxTbv.clearSelection()
            self.sel_nw_vtx = None
            # Deselect point
            self.l_vertex.selectByIds([])
            self.dlg_show()
        else:
            QMessageBox.warning(self, tr_vtxplt_notrfuvtx_msg[0], tr_vtxplt_notrfuvtx_msg[1])
            if self.vtx_type == "near":
                self.sel_nwvtxnear_rfu()
            else:
                self.sel_rfuvtxfar()
        
    # Move edges if they are linked to a new vertex transformed into plot
    def tr_edges(self, old_geom, nw_geom):
        # Transformations to obtain the WGS84 or the CC coordinates
        coords_tr_wgs, coords_tr_cc = crs_trans_params(self.canvas, self.project)
        old_geom_pt = old_geom.asPoint()
        nw_geom_pt = nw_geom.asPoint()
        old_geom_cc = coords_tr_cc.transform(old_geom_pt)
        # Process only new edges
        nw_edges = feats_by_cond(self.l_edge, "@id_arc", NULL)
        if len(nw_edges) > 0:
            for edge_ft in nw_edges:
                ch_geom = False
                edge_ft_line = edge_ft.geometry().asPolyline()
                start_pt = edge_ft_line[0]
                end_pt = edge_ft_line[-1]
                # Comparison done on cc coordinates
                start_pt_cc = coords_tr_cc.transform(start_pt)
                end_pt_cc = coords_tr_cc.transform(end_pt)  
                # Case of start point to move
                if check_identical_pts(old_geom_cc, start_pt_cc, 2):
                    self.l_edge.moveVertex(nw_geom_pt.x(), nw_geom_pt.y(), edge_ft.id(), 0)
                    nw_line_g = QgsGeometry.fromPolylineXY([nw_geom_pt, end_pt])
                    ch_geom = True
                # Case of end point to move
                if check_identical_pts(old_geom_cc, end_pt_cc, 2):
                    self.l_edge.moveVertex(nw_geom_pt.x(), nw_geom_pt.y(), edge_ft.id(), 1)
                    nw_line_g = QgsGeometry.fromPolylineXY([start_pt, nw_geom_pt])
                    ch_geom = True
                # Check if new line is the same as an existing edge_ft
                # In this case, delete the new line
                if ch_geom:
                    for old_edge_ft in self.l_edge.getFeatures():
                        if old_edge_ft.id() != edge_ft.id() and \
                            check_identical_lines(old_edge_ft.geometry().asPolyline(), nw_line_g.asPolyline(), 12):
                            self.l_edge.deleteFeature(edge_ft.id())
    
    
    # Let the user valid the new vertex
    def nwvtx_valid(self):       
        # Reset the point_rfu_proche field
        if self.sel_nw_vtx:
            self.l_vertex.changeAttributeValue(self.sel_nw_vtx.id(), 10, NULL)
            # self.l_vertex.commitChanges()
            self.canvas.refresh()
            QMessageBox.information(self, tr_vtxplt_valid_msg[0], tr_vtxplt_valid_msg[1].format(self.sel_nw_vtx["som_coord_est"], self.sel_nw_vtx["som_coord_nord"]))
            self.nearvtxTbv.clearSelection()
            self.sel_nw_vtx = None
            self.hide()
            self.dlg_show()
        # Message if no line selected in the tablview
        else:
            QMessageBox.warning(self, tr_vtxplt_nolinesel_msg[0], tr_vtxplt_nolinesel_msg[1])

    
    # Launch the dlg appearence
    def dlg_show(self):
                                 
        self.nr_feats = []
        # Create the tableview
        self.tr_vtxtbl_data = []
        tr_vtxtbl_hd = []
        # Build the header
        for fld_name in tr_vtx_atts:
            tr_vtxtbl_hd.append(fld_name)
        # Build the contents
        nb_rows = 0
        for obj in self.l_vertex.getFeatures():
            if obj['point_rfu_proche']:
                tr_vtxtbl_row = []
                for fld_name in tr_vtx_atts:
                    tr_vtxtbl_row.append(str(obj[fld_name]))
                self.tr_vtxtbl_data.append(tr_vtxtbl_row)
                self.nr_feats.append(obj)
                nb_rows += 1
        if nb_rows != 0:
            tr_vtxtbl_model=MyTableModel(self, self.tr_vtxtbl_data, tr_vtxtbl_hd)
            # Populate data in the tableview
            self.nearvtxTbv.setModel(tr_vtxtbl_model)
            self.height_tbv = 0
            self.width_tbv = 0
            # Set column width to fit contents
            self.nearvtxTbv.resizeColumnsToContents()
            # Increase a little bit the width of the columns
            for id_col, val_col in enumerate(tr_vtxtbl_hd):
                nw_size = self.nearvtxTbv.columnWidth(id_col) + 5
                self.nearvtxTbv.setColumnWidth(id_col, nw_size)
                self.width_tbv += nw_size
            # Set row height
            self.nearvtxTbv.resizeRowsToContents()
            self.height_tbv = (self.nearvtxTbv.rowHeight(0)) * (nb_rows+1)
            self.width_tbv += 45
            self.height_tbv += 330
            self.resize_dlg.wtbv = self.width_tbv
            self.resize_dlg.htbv = self.height_tbv
            # Hide vertical header
            vh = self.nearvtxTbv.verticalHeader()
            vh.setVisible(False)
        else:
            self.nearvtxGp.hide()
            self.width_tbv = dlg_transfo_pt_to_plots_sw
            self.height_tbv = 176
            self.resize_dlg.wtbv = self.width_tbv
            self.resize_dlg.htbv = self.height_tbv
        if self.resize_on:
            self.resize_dlg.dlg_auto_resize()
        self.show()
        
   
    def to_close(self):
        self.close()
コード例 #34
0
class MapWindow(QMainWindow):
    """This class offers a canvas and tools to select polygons from a vector
        layer provided by the main app."""
        
    # signal emitted when polygons succesfully selected
    finished = pyqtSignal()
    
    def __init__(self):
        QMainWindow.__init__(self)
        #self.setWindowFlags(Qt.CustomizeWindowHint)
        #self.setWindowFlags(Qt.WindowMinMaxButtonsHint)
        
        # creating map canvas, which draws the maplayers
        # setting up features like canvas color
        self.canvas = QgsMapCanvas()
        self.canvas.setMinimumSize(550, 700)
        self.canvas.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self.canvas.setCanvasColor(Qt.white)
        self.canvas.setSelectionColor(QColor(255,255,26,200))
        self.canvas.enableAntiAliasing(True)
        self.canvas.setParallelRenderingEnabled(True)

        # empty list for selected polygons
        self.selected_features = []
        
        # setting up label settings: object below houses all of them
        self.label_settings = QgsPalLayerSettings()
        
        # object for text settings
        text_format = QgsTextFormat()
        
        text_format.setFont(QFont("Helvetica", 12))
        text_format.setSize(7)
        
        # setting up a white buffer around the labels
        buffer_settings = QgsTextBufferSettings()
        buffer_settings.setEnabled(True)
        buffer_settings.setSize(0.65)
        buffer_settings.setColor(Qt.white)
        text_format.setBuffer(buffer_settings)
        
        # label settings:
        # fieldName = which field is shown as the label (currently Finnish name)
        # placement = labels can be placed differently in relation to one another
        #              - see documentation for details
        self.label_settings.setFormat(text_format)
        self.label_settings.fieldName = "namefin"
        self.label_settings.placement = 0
        self.label_settings.enabled = True
        
        # Qmainwindow requires a central widget. Canvas is placed
        self.setCentralWidget(self.canvas)
        
        # creating each desired action
        self.actionGet = QAction("Return selected and close", self)
        self.actionPan = QAction("Pan tool", self)
        self.actionSelect = QAction("Select tool", self)
        self.actionClear = QAction("Clear selection", self)
        self.actionCancel = QAction("Cancel and close", self)
        
        # these two function as on/off. the rest are clickable
        self.actionPan.setCheckable(True)
        self.actionSelect.setCheckable(True)
        
        # when actions are clicked, do corresponding function
        self.actionPan.triggered.connect(self.pan)
        self.actionSelect.triggered.connect(self.select)
        self.actionClear.triggered.connect(self.clearSelection)
        self.actionGet.triggered.connect(self.finishedSelection)
        self.actionCancel.triggered.connect(self.cancel)
        
        # toolbar at the top of the screen: houses actions as buttons
        # change order here to change their placement on window
        self.toolbar = self.addToolBar("Canvas actions")
        self.toolbar.setContextMenuPolicy(Qt.PreventContextMenu)
        self.toolbar.setMovable(False)
        self.toolbar.addAction(self.actionGet)
        self.toolbar.addAction(self.actionPan)
        self.toolbar.addAction(self.actionSelect)
        self.toolbar.addAction(self.actionClear)
        self.toolbar.addAction(self.actionCancel)

        # link actions to premade map tools
        self.toolPan = QgsMapToolPan(self.canvas)
        self.toolPan.setAction(self.actionPan)
        self.toolSelect = QgsMapToolIdentifyFeature(self.canvas)
        self.toolSelect.setAction(self.actionSelect)
        self.toolSelect.featureIdentified.connect(self.selectFeature)
        
        self.blocks_flag = False
        
        self.selection_rectangle = False
        
        # set select tool as default
        self.select()

    def pan(self):
        """Simply activates the tool"""
        self.canvas.setMapTool(self.toolPan)
        
    def select(self):
        self.canvas.setMapTool(self.toolSelect)
        
    def addLayer(self, layer):
        """Called when user click button on the main plugin: receives a vector
            layer, sets up labels & rendering parameters and shows the layer."""
        # empty output list in case function is called multiple times
        self.selected_features.clear()
        self.selection_rectangle = False
        
        # layer into a self variable
        self.layer = layer
        
        # add layer to project: required to show it on screen
        # False = do not show the layer on the legend listing nor draw on main canvas
        QgsProject.instance().addMapLayer(self.layer, False)
        
        # set up visual stuff
        self.layer.setLabelsEnabled(True)
        layer_labeling = QgsVectorLayerSimpleLabeling(self.label_settings)
        self.layer.setLabeling(layer_labeling)
        self.layer.renderer().symbol().setColor(QColor(220,220,220))
        
        # select tool needs a vector layer assigned to it
        self.toolSelect.setLayer(self.layer)
        self.canvas.setExtent(self.layer.extent())
        
        # set layer to canvas
        self.canvas.setLayers([self.layer])
        
        # show to user
        self.show()
        
    def addBlocksLayer(self, layer):
        self.selected_features.clear()
        self.blocks_flag = True
        
        self.layer = layer
        
        QgsProject.instance().addMapLayer(self.layer, False)
        
        self.layer.renderer().symbol().setColor(Qt.cyan)
        self.layer.renderer().symbol().setOpacity(0.30)
        
        # select tool needs a vector layer assigned to it
        self.toolSelect.setLayer(self.layer)
        self.canvas.setExtent(self.layer.extent())
        
        # set layer to canvas
        """
        url = ("https://vm0160.kaj.pouta.csc.fi/geoserver/ows?service=wfs&version=2.0.0"+ 
        "&request=GetFeature&typename=ogiir:maakuntajako_2018_4500k&pagingEnabled=true")
        self.bg_layer = QgsVectorLayer(url, "BACKGROUND-REMOVE", "WFS")
        """
        self.bg_layer = QgsRasterLayer("url=https://vm0160.kaj.pouta.csc.fi/ogiir_cache/wmts/1.0.0/" +
                       "WMTSCapabilities.xml&crs=EPSG:3067&dpiMode=7&format=image/"+
                       "png&layers=taustakartta&styles=default&tileMatrixSet=GRIDI-FIN", 
                       'GEOCUBES BG-LAYER - TEMPORARY', 'wms')

        if self.bg_layer.isValid():
            QgsProject.instance().addMapLayer(self.bg_layer, False)
            self.canvas.setLayers([self.layer, self.bg_layer])
        else:
            self.canvas.setLayers([self.layer])
        
        self.show()
        
        
    def selectFeature(self, feat):
        """Activated when user clicks something on screen. This returns the
            clicked feature. The function does 2 things:
            1. selects the feature on the map / deselects if already selected
            2. adds features to a list in the same format (name, id_code) as 
                they're stored in the 'Admin areas box' in the main file """
        idx  = feat.id()
        if self.blocks_flag:
            xmin = feat[0]
            ymax = feat[1]
            label = str(xmin) + "|" + str(ymax) 
        else:
            code = feat[1]
            name = feat[2]
            label = name + "|" + code
        
        if label in self.selected_features:
            self.layer.deselect(idx)
            self.selected_features.remove(label)
        else:
            self.layer.select(idx)
            self.selected_features.append(label)
            
    def clearSelection(self):
        """Clear map selection and list on button click"""
        self.layer.removeSelection()
        self.selected_features.clear()
        
    def finishedSelection(self):
        """Activated when user clicks 'return selection'. Closes window
            and emits signal to indicate the job is finished"""
        self.close()
        self.finished.emit()
        
    def cancel(self):
        """In case user changes their mind. Does the same as above, but doesn't
            emit signal."""
        self.close()
        
    def getSelection(self):
        """Returns list of selected features (polygons)"""
        return self.selected_features
    
    def getSelectionBbox(self):
        return self.selection_rectangle
        
    def closeEvent(self, event):
        """Activated anytime Mapwindow is closed either by buttons given or
            if the user finds some other way to close the window. Removes
            selection and deletes scrap maplayer."""
        self.selection_rectangle = self.layer.boundingBoxOfSelected()
        self.layer.removeSelection()
        QgsProject.instance().removeMapLayer(self.layer)
        try:
            QgsProject.instance().removeMapLayer(self.bg_layer)
        except Exception:
            pass
        self.blocks_flag = False
        QMainWindow.closeEvent(self, event)
コード例 #35
0
 def set_canvas(self, map_canvas):
     self.map_tool = QgsMapToolIdentifyFeature(map_canvas)
     self.map_tool.setButton(self.map_identification_button)
     self.canvas = map_canvas
コード例 #36
0
    def __init__(self):
        QMainWindow.__init__(self)
        #self.setWindowFlags(Qt.CustomizeWindowHint)
        #self.setWindowFlags(Qt.WindowMinMaxButtonsHint)
        
        # creating map canvas, which draws the maplayers
        # setting up features like canvas color
        self.canvas = QgsMapCanvas()
        self.canvas.setMinimumSize(550, 700)
        self.canvas.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self.canvas.setCanvasColor(Qt.white)
        self.canvas.setSelectionColor(QColor(255,255,26,200))
        self.canvas.enableAntiAliasing(True)
        self.canvas.setParallelRenderingEnabled(True)

        # empty list for selected polygons
        self.selected_features = []
        
        # setting up label settings: object below houses all of them
        self.label_settings = QgsPalLayerSettings()
        
        # object for text settings
        text_format = QgsTextFormat()
        
        text_format.setFont(QFont("Helvetica", 12))
        text_format.setSize(7)
        
        # setting up a white buffer around the labels
        buffer_settings = QgsTextBufferSettings()
        buffer_settings.setEnabled(True)
        buffer_settings.setSize(0.65)
        buffer_settings.setColor(Qt.white)
        text_format.setBuffer(buffer_settings)
        
        # label settings:
        # fieldName = which field is shown as the label (currently Finnish name)
        # placement = labels can be placed differently in relation to one another
        #              - see documentation for details
        self.label_settings.setFormat(text_format)
        self.label_settings.fieldName = "namefin"
        self.label_settings.placement = 0
        self.label_settings.enabled = True
        
        # Qmainwindow requires a central widget. Canvas is placed
        self.setCentralWidget(self.canvas)
        
        # creating each desired action
        self.actionGet = QAction("Return selected and close", self)
        self.actionPan = QAction("Pan tool", self)
        self.actionSelect = QAction("Select tool", self)
        self.actionClear = QAction("Clear selection", self)
        self.actionCancel = QAction("Cancel and close", self)
        
        # these two function as on/off. the rest are clickable
        self.actionPan.setCheckable(True)
        self.actionSelect.setCheckable(True)
        
        # when actions are clicked, do corresponding function
        self.actionPan.triggered.connect(self.pan)
        self.actionSelect.triggered.connect(self.select)
        self.actionClear.triggered.connect(self.clearSelection)
        self.actionGet.triggered.connect(self.finishedSelection)
        self.actionCancel.triggered.connect(self.cancel)
        
        # toolbar at the top of the screen: houses actions as buttons
        # change order here to change their placement on window
        self.toolbar = self.addToolBar("Canvas actions")
        self.toolbar.setContextMenuPolicy(Qt.PreventContextMenu)
        self.toolbar.setMovable(False)
        self.toolbar.addAction(self.actionGet)
        self.toolbar.addAction(self.actionPan)
        self.toolbar.addAction(self.actionSelect)
        self.toolbar.addAction(self.actionClear)
        self.toolbar.addAction(self.actionCancel)

        # link actions to premade map tools
        self.toolPan = QgsMapToolPan(self.canvas)
        self.toolPan.setAction(self.actionPan)
        self.toolSelect = QgsMapToolIdentifyFeature(self.canvas)
        self.toolSelect.setAction(self.actionSelect)
        self.toolSelect.featureIdentified.connect(self.selectFeature)
        
        self.blocks_flag = False
        
        self.selection_rectangle = False
        
        # set select tool as default
        self.select()