示例#1
0
    def view(self):
        """create view and import layers"""
        layer = QgsMapLayerRegistry.instance().mapLayer(
                self.current_layers[0] )
        uri = QgsDataSourceURI(layer.source())
        mtch = re.match(r'(.+)_([^_]+)_rev_(head|\d+)', uri.schema())
        schema = mtch.group(1)
        assert(schema)

        # Disconnect signals previously connected upon calling this function
        # The first time this function is called will throw an error because no
        # previous connections to the slots were made
        try:
            #print "Disconnecting ..."
            self.q_view_dlg.tblw.itemChanged.disconnect()
            self.q_view_dlg.diffmode_chk.stateChanged.disconnect()
        except:
            #print "Failed disconnection"
            pass

        # Make sure combobox is initalized correctly
        self.q_view_dlg.diffmode_chk.setCheckState(Qt.Unchecked)
        self.q_view_dlg.diffmode_chk.setEnabled(False)

        pcur = versioning_base.Db( psycopg2.connect(self.pg_conn_info()) )
        pcur.execute("SELECT rev, author, date::timestamp(0), branch, commit_msg "
            "FROM "+schema+".revisions ORDER BY rev ASC")
        revs = pcur.fetchall()
        pcur.close()

        self.q_view_dlg.tblw.setRowCount(len(revs))
        self.q_view_dlg.tblw.setColumnCount(5)
        self.q_view_dlg.tblw.setHorizontalHeaderLabels(['Rev#', 'Author', 'Date',
                                        'Branch', 'Commit Message'])

        for i, rev in enumerate(revs):
            for j, item in enumerate(rev):
                self.q_view_dlg.tblw.setItem(i,j,QTableWidgetItem( str(item) ))
                # set rev# checkable
                if j == 0:
                    self.q_view_dlg.tblw.item(i,j).setCheckState(Qt.Unchecked)

        self.q_view_dlg.tblw.itemChanged.connect(self.enable_diffmode)
        self.q_view_dlg.tblw.resizeRowsToContents()
        self.q_view_dlg.tblw.resizeColumnsToContents()
        self.q_view_dlg.diffmode_chk.stateChanged.connect(self.check_branches)

        if not self.q_view_dlg.exec_():
            return

        rows = set()
        revision_number_list = []
        branches = []

        for i in range(len(revs)):
            if  self.q_view_dlg.tblw.item(i,0).checkState():
                print "Revision "+ self.q_view_dlg.tblw.item(i,0).text() +" will be fetched"
                revision_number_list.append(int(self.q_view_dlg.tblw.item(i,0).text()))
                branches.append(self.q_view_dlg.tblw.item(i,3).text())
                rows.add(self.q_view_dlg.tblw.item(i,0).row())

        progressMessageBar = self.iface.messageBar().createMessage("Querying "
        "the database for revision(s) "+str(revision_number_list))
        progress = QProgressBar()
        progress.setMaximum(len(rows))
        progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
        progressMessageBar.layout().addWidget(progress)
        self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO)
        progress.setValue(0)

        # if diffmode, create one layer with feature differences between the
        # two revisions; else checkout the full data sets for the specified
        # revisions and put them in separate layers (original behaviour)
        rev_begin = 0
        rev_end = 0
        empty_layers = []
        grp_name=''

        if self.q_view_dlg.diffmode_chk.isChecked():
            print "Diffmode checked"
            # revision_number_list necessarily has only two items in diffmode
            rev_begin = revision_number_list[0]
            rev_end = revision_number_list[1]
            if rev_begin > rev_end:
                rev_begin, rev_end = rev_end, rev_begin
            # if the two revisions are not on the same branch, exit
            if revs[rev_begin - 1][3] != revs[rev_end - 1][3]:
                print "Revisions are not on the same branch, exiting"
                #print "Rev_begin " +  str(rev_begin) + " is on " + revs[rev_begin - 1][3]
                #print "Rev_end " + str(rev_end) + " is on " + revs[rev_end - 1][3]
                return
            else :
                print "Revisions are on the same branch"
                #print "Rev_begin " + str(rev_begin) + " is on " + revs[rev_begin - 1][3]
                #print "Rev_end " +str(rev_end) + " is on " + revs[rev_end - 1][3]

            grp_name = "Compare revisions "+str(rev_begin)+" vs "+ str(rev_end)
            grp_idx = self.iface.legendInterface().addGroup( grp_name )

            for i, layer_id in enumerate(reversed(self.current_layers)):
                progress.setValue(i+1)
                layer = QgsMapLayerRegistry.instance().mapLayer(layer_id)
                new_uri = QgsDataSourceURI(layer.source())
                select_str = versioning_base.diff_rev_view_str( uri.connectionInfo(),
                    schema, new_uri.table(), branches[0], rev_begin, rev_end )
                # change data source uri to point to select sql
                # schema needs to be set to empty
                new_uri.setDataSource("",
                    "("+select_str+")",
                    new_uri.geometryColumn(),
                    new_uri.sql(),
                    new_uri.keyColumn())
                display_name =  QgsMapLayerRegistry.instance().mapLayer(layer_id).name()
                #print "new_uri.uri() = " + new_uri.uri()
                tmp_pg_layer = self.iface.addVectorLayer( new_uri.uri(),
                       display_name, 'postgres')
                #print "Number of features in layer " + display_name + " = " + str(tmp_pg_layer.featureCount())
                # if layer has no feature, delete tmp layer and resume for loop
                if not(tmp_pg_layer.featureCount()):
                    QgsMapLayerRegistry.instance().removeMapLayer( tmp_pg_layer.id() )
                    empty_layers.append(str(display_name))
                    continue
                mem_uri = self.mem_layer_uri(tmp_pg_layer)

                #print "mem_uri = " + mem_uri
                if  mem_uri == "Unknown":
                    return
                new_mem_layer = self.iface.addVectorLayer( mem_uri,
                    display_name + '_diff', 'memory')
                pr = new_mem_layer.dataProvider()
                source_layer_features = [f for f in tmp_pg_layer.getFeatures()]
                #print "Got features from source vector layer"
                QgsMapLayerRegistry.instance().removeMapLayer( tmp_pg_layer.id() )
                #print "Removed tmp layer"
                pr.addFeatures(source_layer_features)
                #print "Copied source features to mem layer"
                # Style layer to show features as a function of whether they were
                # - added/created ('a')
                # - updated ('u')
                # - deleted ('d')
                # For all feature types, so do once
                # Code from http://snorf.net/blog/2014/03/04/symbology-of-vector-layers-in-qgis-python-plugins
                # For colors, use the names at http://www.w3schools.com/HTML/html_colornames.asp, but lowercase only; tested with "aliceblue"
                # define some rules: label, expression, color name, size, (min scale, max scale)
                modification_type_rules = (
                    ('Intermediate', '"diff_status" LIKE \'i\'', 'aliceblue', 2.0, None),
                    ('Created', '"diff_status" LIKE \'a\'', 'chartreuse', 3.0, None),
                    ('Updated', '"diff_status" LIKE \'u\'', 'sandybrown', 3.0, None),
                    ('Deleted', '"diff_status" LIKE \'d\'', 'red', 3.0, None),)

                symbol = QgsSymbolV2.defaultSymbol(new_mem_layer.geometryType())
                renderer = QgsRuleBasedRendererV2(symbol)
                root_rule = renderer.rootRule()
                for label, expression, color_name, size, scale in modification_type_rules:
                    # create a clone (i.e. a copy) of the default rule
                    rule = root_rule.children()[0].clone()
                    # set the label, expression and color
                    rule.setLabel(label)
                    rule.setFilterExpression(expression)
                    rule.symbol().setColor(QColor(color_name))
                    ##rule.symbol().setSize(size) # works only for POINT layers
                    # set the scale limits if they have been specified
                    ##if scale is not None:
                    ##    rule.setScaleMinDenom(scale[0])
                    ##    rule.setScaleMaxDenom(scale[1])
                    # append the rule to the list of rules
                    root_rule.appendChild(rule)

                # delete the default rule
                root_rule.removeChildAt(0)
                new_mem_layer.setRendererV2(renderer)
                # refresh map and legend
                self.iface.mapCanvas().refresh()
                self.iface.legendInterface().refreshLayerSymbology(new_mem_layer)
                self.iface.legendInterface().moveLayer( new_mem_layer, grp_idx)
        else:
            print "Diffmode unchecked"
            for i, row in enumerate(rows):
                progress.setValue(i+1)
                branch = revs[row][3]
                rev = revs[row][0]
                grp_name = branch+' revision '+str(rev)
                grp_idx = self.iface.legendInterface().addGroup( grp_name )
                for layer_id in reversed(self.current_layers):
                    layer = QgsMapLayerRegistry.instance().mapLayer(layer_id)
                    new_uri = QgsDataSourceURI(layer.source())
                    select_str, where_str =  versioning_base.rev_view_str(
                        self.pg_conn_info(),
                        schema,
                        new_uri.table(),
                        branches[0],
                        rev)
                    new_uri.setSql(where_str)
                    new_uri.setDataSource("",
                        "("+select_str+")",
                        new_uri.geometryColumn(),
                        new_uri.sql(),
                        new_uri.keyColumn())

                    display_name =  QgsMapLayerRegistry.instance().mapLayer(layer_id).name()
                    src = new_uri.uri().replace('()','')
                    new_layer = self.iface.addVectorLayer( src,
                        display_name, 'postgres')
                    self.iface.legendInterface().moveLayer( new_layer, grp_idx)
        self.iface.messageBar().clearWidgets()
        #print "len (self.current_layers) = " + str(len (self.current_layers))
        #print "len(empty_layers) = " + str(len(empty_layers))
        if empty_layers and len(empty_layers) == len (self.current_layers):
            print "No layers in layer group"
            self.iface.messageBar().pushMessage("Notice",
                "No layers will be shown; deleted the \"" +grp_name +"\" layer group",
                level=QgsMessageBar.WARNING, duration = 15)
            self.iface.legendInterface().removeGroup(grp_idx)
        elif empty_layers :
            print "Empty layers"
            self.iface.messageBar().pushMessage("Notice",
                "No modified features between revisions "+str(rev_begin)+" "
                "and "+str(rev_end)+" for layer(s) "+str(empty_layers)+". ",
                level=QgsMessageBar.WARNING, duration = 15)
versioning_base.add_branch( pg_conn_info, 'epanet', 'mybranch', 'test msg' )


pcur = versioning_base.Db(psycopg2.connect(pg_conn_info))
pcur.execute("SELECT * FROM epanet_mybranch_rev_head.junctions")
assert( len(pcur.fetchall()) == 2 )
pcur.execute("SELECT * FROM epanet_mybranch_rev_head.pipes")
assert( len(pcur.fetchall()) == 1 )

##versioning_base.add_revision_view( pg_conn_info, 'epanet', 'mybranch', 2)
##pcur.execute("SELECT * FROM epanet_mybranch_rev_2.junctions")
##assert( len(pcur.fetchall()) == 2 )
##pcur.execute("SELECT * FROM epanet_mybranch_rev_2.pipes")
##assert( len(pcur.fetchall()) == 1 )

select_and_where_str =  versioning_base.rev_view_str( pg_conn_info, 'epanet', 'junctions','mybranch', 2)
print select_and_where_str[0] + " WHERE " + select_and_where_str[1]
pcur.execute(select_and_where_str[0] + " WHERE " + select_and_where_str[1])
assert( len(pcur.fetchall()) == 2 )
select_and_where_str =  versioning_base.rev_view_str( pg_conn_info, 'epanet', 'pipes','mybranch', 2)
print select_and_where_str[0] + " WHERE " + select_and_where_str[1]
pcur.execute(select_and_where_str[0] + " WHERE " + select_and_where_str[1])
assert( len(pcur.fetchall()) == 1 )

##pcur.execute("SELECT ST_AsText(geometry), ST_AsText(geometry_schematic) FROM epanet_mybranch_rev_2.junctions")
pcur.execute("SELECT ST_AsText(geometry), ST_AsText(geometry_schematic) FROM epanet.junctions")
res = pcur.fetchall()
assert( res[0][0] == 'POINT(0 0)' )
assert( res[1][1] == 'POLYGON((0 0,2 0,2 2,0 2,0 0))' )

示例#3
0
versioning_base.add_branch(pg_conn_info, 'epanet', 'mybranch', 'test msg')

pcur = versioning_base.Db(psycopg2.connect(pg_conn_info))
pcur.execute("SELECT * FROM epanet_mybranch_rev_head.junctions")
assert (len(pcur.fetchall()) == 2)
pcur.execute("SELECT * FROM epanet_mybranch_rev_head.pipes")
assert (len(pcur.fetchall()) == 1)

##versioning_base.add_revision_view( pg_conn_info, 'epanet', 'mybranch', 2)
##pcur.execute("SELECT * FROM epanet_mybranch_rev_2.junctions")
##assert( len(pcur.fetchall()) == 2 )
##pcur.execute("SELECT * FROM epanet_mybranch_rev_2.pipes")
##assert( len(pcur.fetchall()) == 1 )

select_and_where_str = versioning_base.rev_view_str(pg_conn_info, 'epanet',
                                                    'junctions', 'mybranch', 2)
print select_and_where_str[0] + " WHERE " + select_and_where_str[1]
pcur.execute(select_and_where_str[0] + " WHERE " + select_and_where_str[1])
assert (len(pcur.fetchall()) == 2)
select_and_where_str = versioning_base.rev_view_str(pg_conn_info, 'epanet',
                                                    'pipes', 'mybranch', 2)
print select_and_where_str[0] + " WHERE " + select_and_where_str[1]
pcur.execute(select_and_where_str[0] + " WHERE " + select_and_where_str[1])
assert (len(pcur.fetchall()) == 1)

##pcur.execute("SELECT ST_AsText(geometry), ST_AsText(geometry_schematic) FROM epanet_mybranch_rev_2.junctions")
pcur.execute(
    "SELECT ST_AsText(geometry), ST_AsText(geometry_schematic) FROM epanet.junctions"
)
res = pcur.fetchall()
assert (res[0][0] == 'POINT(0 0)')