Beispiel #1
0
    def test_convert_group_to_group_layer(self):
        """
        Test converting a QgsLayerTreeGroup to a QgsGroupLayer
        """
        group_node = QgsLayerTreeGroup()

        options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext())
        group_layer = group_node.convertToGroupLayer(options)
        self.assertFalse(group_layer.childLayers())
        self.assertEqual(group_node.groupLayer(), group_layer)

        # if a group layer is already assigned, convertToGroupLayer should do nothing
        self.assertIsNone(group_node.convertToGroupLayer(options))

        group_node.setGroupLayer(None)
        # add some child layers to node
        layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory")
        group_node.addLayer(layer)
        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        group_node.addLayer(layer2)

        group_layer = group_node.convertToGroupLayer(options)
        self.assertEqual(group_layer.childLayers(), [layer2, layer])
        self.assertEqual(group_node.groupLayer(), group_layer)
Beispiel #2
0
    def make(self, composition, inomen, mapAreaLayer, showLayers):
        # Cleanup
        self.deleteGroups(['articulation'])
        mapIDsToBeDisplayed = []
        instance = QgsProject.instance()

        # Creating the articulation frame
        gridLayer = self.createGridLayer(inomen)
        self.loadStyleToGridLayer(gridLayer)
        instance.addMapLayer(gridLayer, False)
        mapIDsToBeDisplayed.append(gridLayer.id())

        # Creating a copy of mapAreaLayer
        mapAreaLayer = self.createVectorLayerFromIter('articulationMapArea', mapAreaLayer.getFeatures())
        self.loadStyleToLayer(mapAreaLayer, self.stylesFolder / 'mapExtentStyle.qml')
        instance.addMapLayer(mapAreaLayer, False)
        mapIDsToBeDisplayed.append(mapAreaLayer.id())

        # Updates composition
        self.updateMapItem(composition, gridLayer, mapAreaLayer)

        if showLayers:
            articulationNodeGroup = QgsLayerTreeGroup('articulation')
            articulationNodeGroup.setItemVisibilityChecked(False)
            for layer in (gridLayer, mapAreaLayer):
                articulationNodeGroup.addLayer(layer)
            root = instance.layerTreeRoot()
            root.addChildNode(articulationNodeGroup)
        
        return mapIDsToBeDisplayed
Beispiel #3
0
    def make(self,
             composition,
             mapExtentsLayer,
             mapExtents,
             layers,
             showLayers=False):

        mapLayers = []
        self.deleteGroups(['map'])

        instance = QgsProject.instance()
        # Setting up grid layer
        mapExtent = self.getExtent(mapExtents)
        gridLayer, mapExtentsTransformed = self.createLayerForGrid(
            mapExtentsLayer, mapExtents)
        self.applyStyleGridLayer(gridLayer)
        gridLayer.triggerRepaint()
        instance.addMapLayer(gridLayer, False)

        # Setting up aux_label, which is reprojected to mapLayers
        crs = next(iter(layers['map'])).crs()
        copyLabel = self.cloneVectorLayerReproject(gridLayer, 'aux_label', crs)
        copyLabelStyle = Path(
            __file__).parent.parent / 'styles' / 'grid' / 'aux_label.qml'
        copyLabel.loadNamedStyle(str(copyLabelStyle))
        instance.addMapLayer(copyLabel, False)

        # Setting up aux_moldura
        copy = self.cloneVectorLayer(gridLayer, 'aux_moldura')
        copyStyle = Path(
            __file__).parent.parent / 'styles' / 'grid' / 'style.qml'
        copy.loadNamedStyle(str(copyStyle))
        instance.addMapLayer(copy, False)

        # Setting up mask layer
        maskLayer = self.createMaskLayer(mapExtents)
        instance.addMapLayer(maskLayer, False)

        mapLayers.extend((copy.id(), copyLabel.id(), gridLayer.id(),
                          maskLayer.id(), *layers['id_map']))
        layersToComposition = [
            gridLayer, maskLayer, copy, copyLabel, *layers['map'],
            *layers['images']
        ]
        self.updateMapItem(composition, mapExtent, mapExtentsTransformed,
                           gridLayer, layersToComposition)

        if showLayers:
            mapGroupNode = QgsLayerTreeGroup('map')
            mapGroupNode.setItemVisibilityChecked(False)
            for lyr in layersToComposition:
                mapGroupNode.addLayer(lyr)
            root = QgsProject.instance().layerTreeRoot()
            root.addChildNode(mapGroupNode)

        return mapLayers
Beispiel #4
0
    def make(self, composition, mapArea, showLayers=False, isInternational=False):
        # Cleanup
        self.deleteGroups(['divisao'])

        mapLayers = []

        # Inserting necessary layers
        divisionGroupNode = QgsLayerTreeGroup('divisao')
        divisionGroupNode.setItemVisibilityChecked(False)

        layerCountyArea, layerCountyLine, layerStateLine, layerCountryArea, layerCountryLine, layerOcean = self.createLayersGroup()
        mapLayers.extend([
            layerCountyArea.id(),layerCountyLine.id(), layerStateLine.id(), layerOcean.id(), layerCountryArea.id(), layerCountryLine.id()])

        # Getting map extents
        gridBound = mapArea.geometry().boundingBox()
        gridRectangleLayer = self.createGridRectangle(gridBound, 'divisionMapArea')
        mapLayers.append(gridRectangleLayer.id())

        # Get map extent for intersections
        # TODO: Check possible refactor on getExtent
        outerExtents = self.getExtent(gridBound, mapArea)
        orderedCountiesByCentroidDistance, orderedCountiesNamesByArea = self.getIntersections(
            layerCountyArea, outerExtents, mapArea, isInternational)

        # Labeling counties
        self.setStyles(layerCountyArea, orderedCountiesByCentroidDistance, orderedCountiesNamesByArea)

        # Inserting counties table
        html_tabledata = self.customcreateHtmlTableData(orderedCountiesNamesByArea)
        self.setMunicipiosTable(composition,  html_tabledata)

        if not isInternational:
            self.hideInternationalCouties(layerCountryArea)
            # self.unsetLabel(layerCountry)

        # Update map in correct sequence
        layersToShow = (
            gridRectangleLayer, layerOcean, layerCountryLine, layerCountryArea, layerStateLine, layerCountyLine, layerCountyArea)
        for layer in layersToShow:
            QgsProject.instance().addMapLayer(layer, False)
            divisionGroupNode.addLayer(layer)
        if showLayers:
            root = QgsProject.instance().layerTreeRoot()
            root.addChildNode(divisionGroupNode)
        self.updateMapItem(composition, outerExtents, layersToShow)
        return mapLayers
Beispiel #5
0
    def test_group_layer_updates_from_node(self):
        """
        Test that group layer child layers are synced correctly from the group node
        """
        group_node = QgsLayerTreeGroup('my group')
        options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext())
        group_layer = group_node.convertToGroupLayer(options)
        self.assertFalse(group_layer.childLayers())

        layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory")
        group_node.addLayer(layer)
        self.assertEqual(group_layer.childLayers(), [layer])

        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        group_node.insertLayer(0, layer2)
        self.assertEqual(group_layer.childLayers(), [layer, layer2])

        layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3",
                                "memory")
        layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4",
                                "memory")
        layer3_node = QgsLayerTreeLayer(layer3)
        layer4_node = QgsLayerTreeLayer(layer4)
        group_node.insertChildNodes(1, [layer3_node, layer4_node])
        self.assertEqual(group_layer.childLayers(),
                         [layer, layer4, layer3, layer2])

        layer5 = QgsVectorLayer("Point?field=fldtxt:string", "layer5",
                                "memory")
        layer5_node = QgsLayerTreeLayer(layer5)
        group_node.addChildNode(layer5_node)
        self.assertEqual(group_layer.childLayers(),
                         [layer5, layer, layer4, layer3, layer2])

        group_node.removeChildNode(layer3_node)
        self.assertEqual(group_layer.childLayers(),
                         [layer5, layer, layer4, layer2])

        group_node.removeLayer(layer)
        self.assertEqual(group_layer.childLayers(), [layer5, layer4, layer2])

        group_node.removeChildren(0, 2)
        self.assertEqual(group_layer.childLayers(), [layer5])

        group_node.removeAllChildren()
        self.assertEqual(group_layer.childLayers(), [])
Beispiel #6
0
    def make(self,
             composition,
             mapAreaFeature,
             showLayers=False,
             isInternational=False):
        # Cleanup
        self.deleteGroups(['localizacao'])
        mapLayers = []
        instance = QgsProject.instance()

        # Creating layer for mapArea
        mapAreaBoundingBox = mapAreaFeature.geometry().boundingBox()
        mapAreaLayer = self.createGridRectangle(mapAreaBoundingBox,
                                                'localizationMapArea')
        mapLayers.append(mapAreaLayer.id())

        # Getting state layer
        stateShpPath = Path(
            __file__).parent.parent / 'limites' / '2020' / 'Estados_2020.shp'
        stateLayerBackground = self.loadShapeLayer(stateShpPath, '',
                                                   'backgroundStates')
        mapExtents = self.getExtent(mapAreaFeature, stateLayerBackground,
                                    isInternational)
        self.setupBackgroundLayer(stateLayerBackground)
        self.setLabel(stateLayerBackground, isInternational)
        mapLayers.append(stateLayerBackground.id())

        # Adding layers
        instance.addMapLayer(stateLayerBackground, False)
        instance.addMapLayer(mapAreaLayer, False)

        # Updating composition
        self.updateMapItem(composition, stateLayerBackground, mapAreaLayer,
                           mapExtents)

        if showLayers:
            localizationGroupNode = QgsLayerTreeGroup('localizacao')
            localizationGroupNode.setItemVisibilityChecked(False)
            for layer in (mapAreaLayer, stateLayerBackground):
                localizationGroupNode.addLayer(layer)
            root = QgsProject.instance().layerTreeRoot()
            root.addChildNode(localizationGroupNode)

        return mapLayers
Beispiel #7
0
	def make(self, composition, mapArea, layers, showLayers=False):	
		self.deleteGroups(['minimap'])	

		mapExtents = mapArea.geometry().convexHull().boundingBox()
		# Creating layers to lock map
		layersToLock = []
		layersToLock.extend(layers['minimap'])
		layersToLock.extend(layers['images'])
		self.updateMapItem(composition, mapExtents, layersToLock)	

		if showLayers:
			miniMapGroupNode = QgsLayerTreeGroup('minimap')	
			miniMapGroupNode.setItemVisibilityChecked(False)								
			for layer in layersToLock:
				miniMapGroupNode.addLayer(layer)
			root = QgsProject.instance().layerTreeRoot()		
			root.addChildNode(miniMapGroupNode)

		return layers['id_minimap']
Beispiel #8
0
    def test_group_layer_nested(self):
        """
        Test group node with child nodes converted to group layer
        """
        group_node = QgsLayerTreeGroup('my group')
        options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext())
        group_layer = group_node.convertToGroupLayer(options)
        self.assertFalse(group_layer.childLayers())

        layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory")
        group_node.addLayer(layer)
        group2 = group_node.addGroup('child group 1')
        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        group_node.addLayer(layer2)

        layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3",
                                "memory")
        layer3_node = group2.addLayer(layer3)

        group3 = group2.addGroup('grand child group 1')
        group4 = group2.addGroup('grand child group 2')

        layer4 = QgsVectorLayer("Point?field=fldtxt:string", "layer4",
                                "memory")
        layer4_node = group3.addLayer(layer4)
        layer5 = QgsVectorLayer("Point?field=fldtxt:string", "layer5",
                                "memory")
        layer5_node = group4.addLayer(layer5)

        self.assertEqual(group_layer.childLayers(),
                         [layer2, layer5, layer4, layer3, layer])

        layer5_node.setItemVisibilityChecked(False)
        self.assertEqual(group_layer.childLayers(),
                         [layer2, layer4, layer3, layer])

        group2.setItemVisibilityChecked(False)
        self.assertEqual(group_layer.childLayers(), [layer2, layer])
        group2.setItemVisibilityCheckedRecursive(True)
        self.assertEqual(group_layer.childLayers(),
                         [layer2, layer5, layer4, layer3, layer])
Beispiel #9
0
    def test_group_layer_updates_from_node_visibility(self):
        """
        Test that group layer child layers are synced correctly from the group node when layer visibility is changed
        """
        group_node = QgsLayerTreeGroup('my group')
        options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext())
        group_layer = group_node.convertToGroupLayer(options)
        self.assertFalse(group_layer.childLayers())

        layer = QgsVectorLayer("Point?field=fldtxt:string", "layer1", "memory")
        group_node.addLayer(layer)
        layer2 = QgsVectorLayer("Point?field=fldtxt:string", "layer2",
                                "memory")
        layer2_node = group_node.addLayer(layer2)
        layer3 = QgsVectorLayer("Point?field=fldtxt:string", "layer3",
                                "memory")
        group_node.addLayer(layer3)
        self.assertEqual(group_layer.childLayers(), [layer3, layer2, layer])

        layer2_node.setItemVisibilityChecked(False)
        self.assertEqual(group_layer.childLayers(), [layer3, layer])

        layer2_node.setItemVisibilityChecked(True)
        self.assertEqual(group_layer.childLayers(), [layer3, layer2, layer])
Beispiel #10
0
def _create_and_add_layer(
    *,
    node: LayerNode,
    project: qgc.QgsProject,
    group: qgc.QgsLayerTreeGroup,
) -> None:
    layer_id = node.name
    logger.debug(f'Adding {layer_id}...')
    layer_cfg = node.layer_cfg

    map_layer = make_map_layer(node)

    # Assign to a different name because this changes the type. We need to add
    # `map_layer` to the project as the last step.
    grouped_layer = group.addLayer(map_layer)
    grouped_layer.setItemVisibilityChecked(layer_cfg.show, )

    # All layers start collapsed. When expanded (the default), they show the
    # entire colormap. This takes up a large amount of space in the QGIS table
    # of contents.
    grouped_layer.setExpanded(False)

    project.addMapLayer(map_layer, addToLegend=False)
class AuxiliaryWindow(QMainWindow):
    """Creates a New Canvas."""

    closed = pyqtSignal(int)

    def __init__(self, parent, geometryWin, numWin):
        def populateStatusBar():
            statusBar = self.statusBar()

            w = QCheckBox("Render", self)
            w.setObjectName('renderCheck')
            w.setToolTip("Toggle map rendering")
            w.setChecked(True)
            statusBar.addPermanentWidget(w)

            w = QCheckBox("Marker", self)
            w.setObjectName('markerCheck')
            w.setToolTip("Toggle marker with cursor position from main map")
            w.setChecked(False)
            statusBar.addPermanentWidget(w, 1)

            w = QCheckBox("Extent", self)
            w.setObjectName('extentCheck')
            w.setToolTip("Show extent of main map")
            w.setChecked(False)
            statusBar.addPermanentWidget(w, 1)

            w = QToolButton(self)
            w.setObjectName('highlightBtn')
            w.setToolTip("Highlight extent in main map")
            w.setText("Highlight")
            statusBar.addPermanentWidget(w, 1)

            w = QLabel("Scale factor:", self)
            w.setObjectName('scaleFactorLabel')
            w.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
            statusBar.addPermanentWidget(w, 1)

            w = QDoubleSpinBox(self)
            w.setObjectName('scaleFactorSpin')
            w.setToolTip("Current scale factor of main map")
            w.setMinimum(0.0)
            w.setMaximum(1000.0)
            w.setDecimals(3)
            w.setValue(1)
            w.setSingleStep(.05)
            statusBar.addPermanentWidget(w, 1)

            w = QToolButton(self)
            w.setObjectName('scaleBtn')
            w.setToolTip("Set scale for main map")
            w.setText("Scale: ")
            statusBar.addPermanentWidget(w, 1)

        def setupUi():
            self.setObjectName("AuxiliaryWindow")
            self.setGeometry(geometryWin)
            self.addDockWidget(Qt.LeftDockWidgetArea, self.dockLegend)
            self.actLegend = self.menuBar().addAction("")
            self.actLegend.triggered.connect(self.onActionLegend)
            self.canvas.setMapTool(self.toolPan)
            self.canvas.setCanvasColor(QColor(255, 255, 255))
            self.canvas.enableAntiAliasing(False)
            self.canvas.useImageToRender(False)
            self.canvas.setWheelAction(QgsMapCanvas.WheelZoom)
            self.setCentralWidget(centralWidget)
            self.messageBar.setSizePolicy(QSizePolicy.Minimum,
                                          QSizePolicy.Fixed)
            layout = QGridLayout()
            layout.setContentsMargins(0, 0, 0, 0)
            layout.addWidget(self.canvas, 0, 0, 2, 1)
            layout.addWidget(self.messageBar, 0, 0, 1, 1)
            centralWidget.setLayout(layout)

        super(AuxiliaryWindow, self).__init__(parent)

        centralWidget = QWidget(self)
        self.canvas = QgsMapCanvas(centralWidget)
        self.messageBar = QgsMessageBar(centralWidget)
        self.toolPan = QgsMapToolPan(self.canvas)
        self.qgisCanvas = qgis.utils.iface.mapCanvas()
        self.qgisTView = qgis.utils.iface.layerTreeView()
        self.qgisSyncGroup = None
        self.numWin = numWin

        self.ltg = QgsLayerTreeGroup('', Qt.Unchecked)
        self.dockLegend = AuxiliaryLegend(self, numWin)
        self.root = QgsProject.instance().layerTreeRoot()

        self.extent = self.actLegend = None
        self.marker = MarkerWindow(self.canvas)

        setupUi()
        populateStatusBar()

        self.onCurrentLayerChanged(None)
        self.onDestinationCrsChanged_MapUnitsChanged()
        self.onHasCrsTransformEnabledChanged(
            self.qgisCanvas.hasCrsTransformEnabled())

    def _connect(self, isConnect=True):
        widgets = {
            'scaleBtn': self.findChild(QToolButton, 'scaleBtn'),
            'renderCheck': self.findChild(QCheckBox, 'renderCheck'),
            'markerCheck': self.findChild(QCheckBox, 'markerCheck'),
            'extentCheck': self.findChild(QCheckBox, 'extentCheck'),
            'highlightBtn': self.findChild(QToolButton, 'highlightBtn'),
            'scaleFactorSpin': self.findChild(QDoubleSpinBox,
                                              'scaleFactorSpin')
        }
        signal_slot = ({
            'signal': widgets['scaleBtn'].clicked,
            'slot': self.onClickedScale
        }, {
            'signal': widgets['renderCheck'].toggled,
            'slot': self.onToggledRender
        }, {
            'signal': widgets['markerCheck'].toggled,
            'slot': self.onToggledMarker
        }, {
            'signal': widgets['extentCheck'].toggled,
            'slot': self.onToggledExtent
        }, {
            'signal': widgets['highlightBtn'].clicked,
            'slot': self.onClickedHighlight
        }, {
            'signal': widgets['scaleFactorSpin'].valueChanged,
            'slot': self.onValueChangedScale
        }, {
            'signal': self.dockLegend.currentLayerChanged,
            'slot': self.onCurrentLayerChanged
        }, {
            'signal': self.dockLegend.currentLayerQgis,
            'slot': self.onCurrentLayerQgis
        }, {
            'signal': self.dockLegend.syncGroupLayer,
            'slot': self.onSyncGroupAddLayersQgis
        }, {
            'signal': self.dockLegend.addSelectedLayersQgis,
            'slot': self.onAddSelectedLayersQgis
        }, {
            'signal': self.dockLegend.removeLayer,
            'slot': self.onRemoveLayers
        }, {
            'signal': self.dockLegend.needSelectLayer,
            'slot': self.onNeedSelectLayer
        }, {
            'signal': self.dockLegend.closed,
            'slot': self.onClosedLegend
        }, {
            'signal': self.canvas.extentsChanged,
            'slot': self.onExtentsChangedMirror
        }, {
            'signal': self.qgisCanvas.extentsChanged,
            'slot': self.onExtentsChangedQgisCanvas
        }, {
            'signal': self.qgisCanvas.xyCoordinates,
            'slot': self.marker.onXYCoordinates
        }, {
            'signal': self.qgisCanvas.destinationCrsChanged,
            'slot': self.onDestinationCrsChanged_MapUnitsChanged
        }, {
            'signal': self.qgisCanvas.mapUnitsChanged,
            'slot': self.onDestinationCrsChanged_MapUnitsChanged
        }, {
            'signal': self.qgisCanvas.hasCrsTransformEnabledChanged,
            'slot': self.onHasCrsTransformEnabledChanged
        }, {
            'signal': self.root.removedChildren,
            'slot': self.onRemovedChildrenQgisRoot
        }, {
            'signal': QgsMapLayerRegistry.instance().layersWillBeRemoved,
            'slot': self.onLayersWillBeRemoved
        })
        if isConnect:
            for item in signal_slot:
                item['signal'].connect(item['slot'])
        else:
            for item in signal_slot:
                item['signal'].disconnect(item['slot'])

    def _extentsChanged(self,
                        canvasOrigin,
                        originSlot,
                        canvasDest,
                        scaleFactor=None):
        canvasOrigin.extentsChanged.disconnect(originSlot)

        if scaleFactor is None:
            scale = canvasOrigin.scale()
            canvasOrigin.setExtent(canvasDest.extent())
            canvasOrigin.zoomScale(scale)
        else:
            canvasOrigin.setExtent(canvasDest.extent())
            canvasOrigin.zoomScale(scaleFactor * canvasDest.scale())

        canvasOrigin.extentsChanged.connect(originSlot)

    def _textScaleBtnChanched(self):
        scale = locale.format("%.0f", self.canvas.scale(), True)
        w = self.findChild(QToolButton, 'scaleBtn')
        w.setText("Scale 1:%s" % scale)

    def _extent(self):
        rect = self.qgisCanvas.extent()
        p1 = QgsPoint(rect.xMinimum(), rect.yMinimum())
        p2 = QgsPoint(rect.xMinimum(), rect.yMaximum())
        p3 = QgsPoint(rect.xMaximum(), rect.yMaximum())
        p4 = QgsPoint(rect.xMaximum(), rect.yMinimum())
        p5 = QgsPoint(rect.xMinimum(), rect.yMinimum())
        points = [p1, p2, p3, p4, p5]
        self.extent.setToGeometry(QgsGeometry.fromPolyline(points), None)

    def _execFunction(self, func, arg, signal, slot):
        signal.disconnect(slot)
        func(arg)
        signal.connect(slot)

    def _connectVectorRefresh(self, layer, isConnect=True):
        if isinstance(layer, QgsVectorLayer):
            f = layer.editCommandEnded.connect if isConnect else layer.editCommandEnded.disconnect
            f(self.canvas.refresh)

    def _addLayersQgis(self, layersQgis, needMsg=True):

        self.dockLegend.clearBridge()

        l1 = set(layersQgis)
        l2 = set(map(lambda item: item.layer(), self.ltg.findLayers()))
        layers = list(l1 - l2)
        if len(layers) == 0:
            if needMsg:
                self.messageBar.pushMessage(
                    "Need select new layer(s) in main map",
                    QgsMessageBar.WARNING, 2)
        else:
            # Get order by layersQgis
            for item in layersQgis:
                if item in layers:
                    self.ltg.addLayer(item)
                    self._connectVectorRefresh(item)

        self.dockLegend.setBridge(self.canvas)

    def _syncGroupAddLayersQgis(self, ltg):
        layersQgis = map(lambda item: item.layer(), ltg.findLayers())
        if len(layersQgis) == 0:
            return False

        name = ltg.name()
        if self.qgisSyncGroup == ltg:
            msg = "Already synchronized group (main map) -> '%s'" % name
            self.messageBar.pushMessage(msg, QgsMessageBar.INFO, 4)
            return True

        if not self.qgisSyncGroup is None:
            self.qgisSyncGroup.addedChildren.disconnect(
                self.addedChildrenLayer)

        self.qgisSyncGroup = ltg
        self.qgisSyncGroup.addedChildren.connect(self.addedChildrenLayer)

        self.dockLegend.addNameSyncGroup(name)
        msg = "Changed synchronized group (main map) -> '%s'" % name
        self.messageBar.pushMessage(msg, QgsMessageBar.INFO, 4)

        self._addLayersQgis(layersQgis)
        return True

    def run(self):

        if len(self.qgisTView.selectedLayerNodes()) > 0:
            self.onAddSelectedLayersQgis()
        else:
            ltn = self.qgisTView.currentNode()
            if not isinstance(ltn, QgsLayerTreeGroup):
                return False
            else:
                if ltn == self.root:
                    return False
                else:
                    if not self._syncGroupAddLayersQgis(ltn):
                        return False

        self.dockLegend.setBridge(self.canvas)

        self.canvas.setRenderFlag(False)
        self.show()  # Need show before self._connect()
        self._connect()
        self.canvas.setExtent(self.qgisCanvas.extent())
        w = self.findChild(QDoubleSpinBox, 'scaleFactorSpin')
        w.setValue(1)
        self.canvas.setRenderFlag(True)

        return True

    def getLayersCanvas(self):
        layerIds = map(lambda x: x.layerId(), self.ltg.findLayers())
        layerChecks = map(lambda x: str(x.isVisible()), self.ltg.findLayers())

        return (layerIds, layerChecks)

    def setLayersCanvas(self, layerIds, layerChecks):
        prevFlag = self.canvas.renderFlag()
        self.canvas.setRenderFlag(False)

        lyrRegs = QgsMapLayerRegistry.instance()
        for id in range(len(layerIds)):
            layer = lyrRegs.mapLayer(layerIds[id])
            isVisible = int(layerChecks[id])
            if not layer is None:
                self.ltg.addLayer(layer).setVisible(isVisible)

        self.canvas.setRenderFlag(prevFlag)

    def getWindowSetting(self):
        g = self.geometry()
        r = self.canvas.extent()
        nodes = self.ltg.findLayers()
        currentLayer = self.dockLegend.tview.currentLayer()
        currentLayerId = currentLayer.id(
        ) if not currentLayer is None else "None"

        windowSetting = {
            'numWin':
            self.numWin,
            'geometryWin': {
                'x': g.x(),
                'y': g.y(),
                'width': g.width(),
                'height': g.height()
            },
            'extentCanvas': {
                'xmin': r.xMinimum(),
                'ymin': r.yMinimum(),
                'xmax': r.xMaximum(),
                'ymax': r.yMaximum()
            },
            'currentLayerId':
            currentLayerId,
            'layerIds':
            ' '.join(map(lambda item: item.layerId(), nodes)),
            'visibles':
            ' '.join(map(lambda item: str(int(item.isVisible())), nodes))
        }
        for item in ('render', 'marker', 'extent'):
            nameGui = "%sCheck" % item
            windowSetting[item] = int(
                self.findChild(QCheckBox, nameGui).isChecked())

        return windowSetting

    def setWindowSetting(self, windowSetting):
        self.numWin = windowSetting['numWin']

        # Populate with layers and set Bridge for legend
        layerIds = windowSetting['layerIds'].split(' ')
        visibles = map(lambda item: bool(int(item)),
                       windowSetting['visibles'].split(' '))
        ltg = self.qgisTView.layerTreeModel().rootGroup()
        for id in range(len(layerIds)):
            node = ltg.findLayer(layerIds[id])
            if node is None:
                continue
            layer = node.layer()
            visible = Qt.Checked if visibles[id] else Qt.Unchecked
            self._connectVectorRefresh(layer)
            self.ltg.addLayer(layer).setVisible(visible)
        self.dockLegend.setBridge(self.canvas)

        self.show()  # Need show before self._connect()
        self._connect()
        node = ltg.findLayer(windowSetting['currentLayerId'])
        if not node is None:
            layer = node.layer()
            self.dockLegend.tview.setCurrentLayer(layer)
        w = windowSetting['extentCanvas']
        self.canvas.setExtent(
            QgsRectangle(w['xmin'], w['ymin'], w['xmax'], w['ymax']))
        for item in ('render', 'marker', 'extent'):
            value = bool(windowSetting[item])
            nameGui = "%sCheck" % item
            self.findChild(QCheckBox, nameGui).setChecked(value)

    def closeEvent(self, event):
        self._connect(False)
        event.accept()
        self.closed.emit(self.numWin)

    @pyqtSlot(int)
    def onValueChangedScale(self, scaleFactor):
        w = self.findChild(QCheckBox, 'renderCheck')
        if not w.isChecked():
            return
        self._execFunction(self.canvas.zoomScale,
                           scaleFactor * self.qgisCanvas.scale(),
                           self.canvas.extentsChanged,
                           self.onExtentsChangedMirror)
        self._textScaleBtnChanched()

    @pyqtSlot()
    def onClickedScale(self):
        self._execFunction(self.qgisCanvas.zoomScale, self.canvas.scale(),
                           self.qgisCanvas.extentsChanged,
                           self.onExtentsChangedQgisCanvas)
        w = self.findChild(QDoubleSpinBox, 'scaleFactorSpin')
        self._execFunction(w.setValue, 1.0, w.valueChanged,
                           self.onValueChangedScale)

    @pyqtSlot()
    def onClickedHighlight(self):
        def removeRB():
            rb.reset(True)
            self.qgisCanvas.scene().removeItem(rb)

        rb = QgsRubberBand(self.qgisCanvas, QGis.Polygon)
        rb.setBorderColor(QColor(255, 0, 0))
        rb.setWidth(2)
        rb.setToGeometry(QgsGeometry.fromRect(self.canvas.extent()), None)
        QTimer.singleShot(2000, removeRB)

    @pyqtSlot(bool)
    def onToggledRender(self, enabled):
        if enabled:
            self.canvas.setMapTool(self.toolPan)
            w = self.findChild(QDoubleSpinBox, 'scaleFactorSpin')
            self._extentsChanged(self.canvas, self.onExtentsChangedMirror,
                                 self.qgisCanvas, w.value())
            self._textScaleBtnChanched()
            self.canvas.setWheelAction(QgsMapCanvas.WheelZoom)
        else:
            self.canvas.unsetMapTool(self.toolPan)
            self.canvas.setWheelAction(QgsMapCanvas.WheelNothing)
        self.canvas.setRenderFlag(enabled)

    @pyqtSlot(bool)
    def onToggledMarker(self, enabled):
        self.marker.add() if enabled else self.marker.remove()

    @pyqtSlot(bool)
    def onToggledExtent(self, enabled):
        def setExtent():
            if not self.extent is None:
                self.canvas.scene().removeItem(self.extent)
            self.extent = QgsRubberBand(self.canvas, QGis.Polygon)
            self.extent.setBorderColor(QColor(255, 0, 0))
            self.extent.setWidth(2)
            self._extent()

        if enabled:
            setExtent()
        else:
            if not self.extent is None:
                self.canvas.scene().removeItem(self.extent)
                self.extent = None

    @pyqtSlot()
    def onExtentsChangedMirror(self):
        w = self.findChild(QCheckBox, 'renderCheck')
        if not w.isChecked():
            return
        self._extentsChanged(self.qgisCanvas, self.onExtentsChangedQgisCanvas,
                             self.canvas)
        self._textScaleBtnChanched()
        w = self.findChild(QDoubleSpinBox, 'scaleFactorSpin')
        self._execFunction(w.setValue,
                           self.canvas.scale() / self.qgisCanvas.scale(),
                           w.valueChanged, self.onValueChangedScale)
        if not self.extent is None:
            self._extent()

    @pyqtSlot()
    def onExtentsChangedQgisCanvas(self):
        w = self.findChild(QCheckBox, 'renderCheck')
        if not w.isChecked():
            return
        w = self.findChild(QDoubleSpinBox, 'scaleFactorSpin')
        self._extentsChanged(self.canvas, self.onExtentsChangedMirror,
                             self.qgisCanvas, w.value())
        self._textScaleBtnChanched()
        if not self.extent is None:
            self._extent()

    @pyqtSlot()
    def onDestinationCrsChanged_MapUnitsChanged(self):
        prevFlag = self.canvas.renderFlag()
        self.canvas.setRenderFlag(False)

        self.canvas.setDestinationCrs(
            self.qgisCanvas.mapRenderer().destinationCrs())
        self.canvas.setMapUnits(self.qgisCanvas.mapUnits())

        self.canvas.setRenderFlag(prevFlag)

    @pyqtSlot(bool)
    def onHasCrsTransformEnabledChanged(self, enabled):
        prevFlag = self.canvas.renderFlag()
        self.canvas.setRenderFlag(False)
        self.canvas.mapRenderer().setProjectionsEnabled(enabled)
        self.canvas.setRenderFlag(prevFlag)

    @pyqtSlot(list)
    def onLayersWillBeRemoved(self, theLayerIds):
        ids = list(set(self.ltg.findLayerIds())
                   & set(theLayerIds))  # intersection
        nodes = map(lambda item: self.ltg.findLayer(item), ids)
        for item in nodes:
            self._connectVectorRefresh(item.layer(), False)
            self.ltg.removeChildNode(item)

    @pyqtSlot()
    def onAddSelectedLayersQgis(self):
        layersQgis = map(lambda item: item.layer(),
                         self.qgisTView.selectedLayerNodes())
        self._addLayersQgis(layersQgis)

    @pyqtSlot('QgsLayerTreeNode', int, int)
    def addedChildrenLayer(self, ltg, indexFrom, indexTo):
        layersQgis = map(lambda item: item.layer(), ltg.findLayers())
        self._addLayersQgis(layersQgis, False)

    @pyqtSlot('QgsLayerTreeNode', int, int)
    def onRemovedChildrenQgisRoot(self, ltg, indexFrom, indexTo):
        if not self.qgisSyncGroup is None and not self.qgisSyncGroup in self.root.children(
        ):
            self.qgisSyncGroup = None
            self.dockLegend.addNameSyncGroup("None")
            msg = "Removed synchronized group (main map)"
            self.messageBar.pushMessage(msg, QgsMessageBar.INFO, 4)

    @pyqtSlot()
    def onSyncGroupAddLayersQgis(self):

        msg = "Need active a group in main map with new layers"
        ltn = self.qgisTView.currentNode()
        if not isinstance(ltn, QgsLayerTreeGroup) or ltn == self.root:
            self.messageBar.pushMessage(msg, QgsMessageBar.WARNING, 3)
            return

        if not self._syncGroupAddLayersQgis(ltn):
            self.messageBar.pushMessage(msg, QgsMessageBar.WARNING, 3)

    @pyqtSlot('QgsMapLayer')
    def onRemoveLayers(self, layer):
        self._connectVectorRefresh(layer, False)

    @pyqtSlot()
    def onNeedSelectLayer(self):
        self.messageBar.pushMessage("Need select layer(s)",
                                    QgsMessageBar.WARNING, 2)

    @pyqtSlot('QgsMapLayer')
    def onCurrentLayerQgis(self, layer):
        if layer is None:
            self.messageBar.pushMessage("Need active layer",
                                        QgsMessageBar.WARNING, 2)
        else:
            self.qgisTView.setCurrentLayer(layer)

    @pyqtSlot('QgsMapLayer')
    def onCurrentLayerChanged(self, layer):
        hasLayer = True if not layer is None else False
        selectName = "Select layer '%s'" % layer.name(
        ) if hasLayer else "None select layer"
        title = "#%d - %s" % (self.numWin, selectName)
        self.setWindowTitle(title)

    @pyqtSlot()
    def onClosedLegend(self):
        self.actLegend.setText("Show layers")

    @pyqtSlot()
    def onActionLegend(self):
        self.actLegend.setText("")
        self.dockLegend.show()
Beispiel #12
0
def run(item, action, mainwindow):
    db = item.database()
    uri = db.uri()
    iface = mainwindow.iface

    quoteId = db.connector.quoteId
    quoteStr = db.connector.quoteString

    # check if the selected item is a topology schema
    isTopoSchema = False

    if not hasattr(item, 'schema'):
        mainwindow.infoBar.pushMessage(
            "Invalid topology", u'Select a topology schema to continue.',
            Qgis.Info, mainwindow.iface.messageTimeout())
        return False

    if item.schema() is not None:
        sql = u"SELECT srid FROM topology.topology WHERE name = %s" % quoteStr(
            item.schema().name)
        res = db.executeSql(sql)
        isTopoSchema = len(res) > 0

    if not isTopoSchema:
        mainwindow.infoBar.pushMessage(
            "Invalid topology",
            u'Schema "{0}" is not registered in topology.topology.'.format(
                item.schema().name), Qgis.Warning,
            mainwindow.iface.messageTimeout())
        return False

    if (res[0][0] < 0):
        mainwindow.infoBar.pushMessage(
            "WARNING",
            u'Topology "{0}" is registered as having a srid of {1} in topology.topology, we will assume 0 (for unknown)'
            .format(item.schema().name, res[0]), Qgis.Warning,
            mainwindow.iface.messageTimeout())
        toposrid = '0'
    else:
        toposrid = str(res[0][0])

    # load layers into the current project
    toponame = item.schema().name
    template_dir = os.path.join(current_path, 'templates')

    # do not refresh the canvas until all the layers are added
    wasFrozen = iface.mapCanvas().isFrozen()
    iface.mapCanvas().freeze()
    try:
        provider = db.dbplugin().providerName()
        uri = db.uri()

        # Force use of estimated metadata (topologies can be big)
        uri.setUseEstimatedMetadata(True)

        # FACES

        # face mbr
        uri.setDataSource(toponame, 'face', 'mbr', '', 'face_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.Polygon)
        layerFaceMbr = QgsVectorLayer(uri.uri(False),
                                      u'%s.face_mbr' % toponame, provider)
        layerFaceMbr.loadNamedStyle(os.path.join(template_dir, 'face_mbr.qml'))

        face_extent = layerFaceMbr.extent()

        # face geometry
        sql = u'SELECT face_id, mbr, topology.ST_GetFaceGeometry(%s,' \
              'face_id)::geometry(polygon, %s) as geom ' \
              'FROM %s.face WHERE face_id > 0' % \
              (quoteStr(toponame), toposrid, quoteId(toponame))
        uri.setDataSource('', u'(%s\n)' % sql, 'geom', '', 'face_id')
        uri.setParam('bbox', 'mbr')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.Polygon)
        layerFaceGeom = QgsVectorLayer(uri.uri(False), u'%s.face' % toponame,
                                       provider)
        layerFaceGeom.setExtent(face_extent)
        layerFaceGeom.loadNamedStyle(os.path.join(template_dir, 'face.qml'))

        # face_seed
        sql = u'SELECT face_id, mbr, ST_PointOnSurface(' \
              'topology.ST_GetFaceGeometry(%s,' \
              'face_id))::geometry(point, %s) as geom ' \
              'FROM %s.face WHERE face_id > 0' % \
              (quoteStr(toponame), toposrid, quoteId(toponame))
        uri.setDataSource('', u'(%s)' % sql, 'geom', '', 'face_id')
        uri.setParam('bbox', 'mbr')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.Point)
        layerFaceSeed = QgsVectorLayer(uri.uri(False),
                                       u'%s.face_seed' % toponame, provider)
        layerFaceSeed.setExtent(face_extent)
        layerFaceSeed.loadNamedStyle(
            os.path.join(template_dir, 'face_seed.qml'))

        # TODO: add polygon0, polygon1 and polygon2 ?

        # NODES

        # node
        uri.setDataSource(toponame, 'node', 'geom', '', 'node_id')
        uri.removeParam('bbox')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.Point)
        layerNode = QgsVectorLayer(uri.uri(False), u'%s.node' % toponame,
                                   provider)
        layerNode.loadNamedStyle(os.path.join(template_dir, 'node.qml'))
        node_extent = layerNode.extent()

        # node labels
        uri.setDataSource(toponame, 'node', 'geom', '', 'node_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.Point)
        uri.removeParam('bbox')
        layerNodeLabel = QgsVectorLayer(uri.uri(False),
                                        u'%s.node_id' % toponame, provider)
        layerNodeLabel.setExtent(node_extent)
        layerNodeLabel.loadNamedStyle(
            os.path.join(template_dir, 'node_label.qml'))

        # EDGES

        # edge
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        uri.removeParam('bbox')
        layerEdge = QgsVectorLayer(uri.uri(False), u'%s.edge' % toponame,
                                   provider)
        edge_extent = layerEdge.extent()

        # directed edge
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        uri.removeParam('bbox')
        layerDirectedEdge = QgsVectorLayer(uri.uri(False),
                                           u'%s.directed_edge' % toponame,
                                           provider)
        layerDirectedEdge.setExtent(edge_extent)
        layerDirectedEdge.loadNamedStyle(os.path.join(template_dir,
                                                      'edge.qml'))

        # edge labels
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        uri.removeParam('bbox')
        layerEdgeLabel = QgsVectorLayer(uri.uri(False),
                                        u'%s.edge_id' % toponame, provider)
        layerEdgeLabel.setExtent(edge_extent)
        layerEdgeLabel.loadNamedStyle(
            os.path.join(template_dir, 'edge_label.qml'))

        # face_left
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        uri.removeParam('bbox')
        layerFaceLeft = QgsVectorLayer(uri.uri(False),
                                       u'%s.face_left' % toponame, provider)
        layerFaceLeft.setExtent(edge_extent)
        layerFaceLeft.loadNamedStyle(
            os.path.join(template_dir, 'face_left.qml'))

        # face_right
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        uri.removeParam('bbox')
        layerFaceRight = QgsVectorLayer(uri.uri(False),
                                        u'%s.face_right' % toponame, provider)
        layerFaceRight.setExtent(edge_extent)
        layerFaceRight.loadNamedStyle(
            os.path.join(template_dir, 'face_right.qml'))

        # next_left
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        uri.removeParam('bbox')
        layerNextLeft = QgsVectorLayer(uri.uri(False),
                                       u'%s.next_left' % toponame, provider)
        layerNextLeft.setExtent(edge_extent)
        layerNextLeft.loadNamedStyle(
            os.path.join(template_dir, 'next_left.qml'))

        # next_right
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        uri.removeParam('bbox')
        layerNextRight = QgsVectorLayer(uri.uri(False),
                                        u'%s.next_right' % toponame, provider)
        layerNextRight.setExtent(edge_extent)
        layerNextRight.loadNamedStyle(
            os.path.join(template_dir, 'next_right.qml'))

        # Add layers to the layer tree

        faceLayers = [layerFaceMbr, layerFaceGeom, layerFaceSeed]
        nodeLayers = [layerNode, layerNodeLabel]
        edgeLayers = [
            layerEdge, layerDirectedEdge, layerEdgeLabel, layerFaceLeft,
            layerFaceRight, layerNextLeft, layerNextRight
        ]

        QgsProject.instance().addMapLayers(faceLayers, False)
        QgsProject.instance().addMapLayers(nodeLayers, False)
        QgsProject.instance().addMapLayers(edgeLayers, False)

        # Organize layers in groups

        groupFaces = QgsLayerTreeGroup(u'Faces')
        for layer in faceLayers:
            nodeLayer = groupFaces.addLayer(layer)
            nodeLayer.setItemVisibilityChecked(False)
            nodeLayer.setExpanded(False)

        groupNodes = QgsLayerTreeGroup(u'Nodes')
        for layer in nodeLayers:
            nodeLayer = groupNodes.addLayer(layer)
            nodeLayer.setItemVisibilityChecked(False)
            nodeLayer.setExpanded(False)

        groupEdges = QgsLayerTreeGroup(u'Edges')
        for layer in edgeLayers:
            nodeLayer = groupEdges.addLayer(layer)
            nodeLayer.setItemVisibilityChecked(False)
            nodeLayer.setExpanded(False)

        supergroup = QgsLayerTreeGroup(u'Topology "%s"' % toponame)
        supergroup.insertChildNodes(-1, [groupFaces, groupNodes, groupEdges])

        layerTree = QgsProject.instance().layerTreeRoot()

        layerTree.addChildNode(supergroup)

        # Set layers rendering order

        order = layerTree.layerOrder()

        order.insert(0, order.pop(order.index(layerFaceMbr)))
        order.insert(0, order.pop(order.index(layerFaceGeom)))
        order.insert(0, order.pop(order.index(layerEdge)))
        order.insert(0, order.pop(order.index(layerDirectedEdge)))

        order.insert(0, order.pop(order.index(layerNode)))
        order.insert(0, order.pop(order.index(layerFaceSeed)))

        order.insert(0, order.pop(order.index(layerNodeLabel)))
        order.insert(0, order.pop(order.index(layerEdgeLabel)))

        order.insert(0, order.pop(order.index(layerNextLeft)))
        order.insert(0, order.pop(order.index(layerNextRight)))
        order.insert(0, order.pop(order.index(layerFaceLeft)))
        order.insert(0, order.pop(order.index(layerFaceRight)))

        layerTree.setHasCustomLayerOrder(True)
        layerTree.setCustomLayerOrder(order)

    finally:

        # Set canvas extent to topology extent, if not yet initialized
        canvas = iface.mapCanvas()
        if (canvas.fullExtent().isNull()):
            ext = node_extent
            ext.combineExtentWith(edge_extent)
            # Grow by 1/20 of largest side
            ext = ext.buffered(max(ext.width(), ext.height()) / 20)
            canvas.setExtent(ext)

        # restore canvas render flag
        if not wasFrozen:
            iface.mapCanvas().freeze(False)

    return True
Beispiel #13
0
    def getLegendGraphic(self, params):
        qgsLayer = self.layerRegistry.mapLayer(params.get('layer'))

        boxSpace = 1
        layerSpace = 2
        # layerTitleSpace = 3
        symbolSpace = 2
        iconLabelSpace = 2
        symbolWidth = 5
        symbolHeight = 3

        drawLegendLabel = True

        rootGroup = QgsLayerTreeGroup()
        rootGroup.addLayer(qgsLayer)
        # layer = QgsLayerTreeLayer(qgsLayer)

        # if qgsLayer.title():
        #     layer.setLayerName(qgsLayer.title())

        legendModel = QgsLayerTreeModel(rootGroup)

        rootChildren = rootGroup.children()

        img_tmp = QImage(QSize(1, 1), QImage.Format_ARGB32_Premultiplied)
        dpm = 1 / 0.00028
        img_tmp.setDotsPerMeterX(dpm)
        img_tmp.setDotsPerMeterY(dpm)

        dpmm = img_tmp.dotsPerMeterX() / 1000.0

        del img_tmp

        legendSettings = QgsLegendSettings()
        legendSettings.setTitle('')
        legendSettings.setBoxSpace(boxSpace)
        legendSettings.rstyle(QgsComposerLegendStyle.Subgroup).setMargin(QgsComposerLegendStyle.Top, layerSpace)

        legendSettings.rstyle(QgsComposerLegendStyle.Symbol).setMargin(QgsComposerLegendStyle.Top, symbolSpace)
        legendSettings.rstyle(QgsComposerLegendStyle.SymbolLabel).setMargin(QgsComposerLegendStyle.Left, iconLabelSpace)
        legendSettings.setSymbolSize(QSizeF(symbolWidth, symbolHeight))
        # legendSettings.rstyle(QgsComposerLegendStyle.Subgroup).setFont(layerFont)
        # legendSettings.rstyle(QgsComposerLegendStyle.SymbolLabel).setFont(itemFont)
        # // TODO: not available: layer font color
        # legendSettings.setFontColor( itemFontColor );

        # for node in rootChildren:
        #     if (QgsLayerTree.isLayer(node)):
        #         QgsLegendRenderer.setNodeLegendStyle(node, QgsComposerLegendStyle.Subgroup)
        #     # rule item titles
        #     # if ( !mDrawLegendItemLabel )
        #     #     for legendNode in legendModel.layerLegendNodes(nodeLayer):
        #     #         legendNode.setUserLabel(' ')
        #     # }

        legendRenderer = QgsLegendRenderer(legendModel, legendSettings)
        minSize = legendRenderer.minimumSize()
        s = QSize(minSize.width() * dpmm, minSize.height() * dpmm)

        img = QImage(s, QImage.Format_ARGB32_Premultiplied)
        # fill in the background
        color = QColor(0, 0, 0, 0)
        img.fill(color)

        p = QPainter()
        p.begin(img)

        p.setRenderHint(QPainter.Antialiasing, True)
        p.scale(dpmm, dpmm)
        legendRenderer.drawLegend(p)

        map_buffer = QBuffer()
        map_buffer.open(QIODevice.ReadWrite)

        img.save(map_buffer, 'PNG')
        # clean up

        map_buffer.close()
        p.end()

        # self.layerRegistry.removeAllMapLayers()
        return map_buffer.data()
Beispiel #14
0
def run(item, action, mainwindow):
    db = item.database()
    uri = db.uri()
    iface = mainwindow.iface

    quoteId = db.connector.quoteId
    quoteStr = db.connector.quoteString

    # check if the selected item is a topology schema
    isTopoSchema = False

    if not hasattr(item, 'schema'):
        mainwindow.infoBar.pushMessage("Invalid topology", u'Select a topology schema to continue.', QgsMessageBar.INFO,
                                       mainwindow.iface.messageTimeout())
        return False

    if item.schema() is not None:
        sql = u"SELECT srid FROM topology.topology WHERE name = %s" % quoteStr(item.schema().name)
        c = db.connector._get_cursor()
        db.connector._execute(c, sql)
        res = db.connector._fetchone(c)
        isTopoSchema = res is not None

    if not isTopoSchema:
        mainwindow.infoBar.pushMessage("Invalid topology",
                                       u'Schema "{0}" is not registered in topology.topology.'.format(
                                           item.schema().name), QgsMessageBar.WARNING,
                                       mainwindow.iface.messageTimeout())
        return False

    if (res[0] < 0):
        mainwindow.infoBar.pushMessage("WARNING", u'Topology "{0}" is registered as having a srid of {1} in topology.topology, we will assume 0 (for unknown)'.format(item.schema().name, res[0]), QgsMessageBar.WARNING, mainwindow.iface.messageTimeout())
        toposrid = '0'
    else:
        toposrid = str(res[0])

    # load layers into the current project
    toponame = item.schema().name
    template_dir = os.path.join(current_path, 'templates')

    # do not refresh the canvas until all the layers are added
    wasFrozen = iface.mapCanvas().isFrozen()
    iface.mapCanvas().freeze()
    try:
        provider = db.dbplugin().providerName()
        uri = db.uri()

        # Force use of estimated metadata (topologies can be big)
        uri.setUseEstimatedMetadata(True)

        # FACES

        # face mbr
        uri.setDataSource(toponame, 'face', 'mbr', '', 'face_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.Polygon)
        layerFaceMbr = QgsVectorLayer(uri.uri(False), u'%s.face_mbr' % toponame, provider)
        layerFaceMbr.loadNamedStyle(os.path.join(template_dir, 'face_mbr.qml'))

        face_extent = layerFaceMbr.extent()

        # face geometry
        sql = u'SELECT face_id, topology.ST_GetFaceGeometry(%s,' \
              'face_id)::geometry(polygon, %s) as geom ' \
              'FROM %s.face WHERE face_id > 0' % \
              (quoteStr(toponame), toposrid, quoteId(toponame))
        uri.setDataSource('', u'(%s\n)' % sql, 'geom', '', 'face_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.Polygon)
        layerFaceGeom = QgsVectorLayer(uri.uri(False), u'%s.face' % toponame, provider)
        layerFaceGeom.setExtent(face_extent)
        layerFaceGeom.loadNamedStyle(os.path.join(template_dir, 'face.qml'))

        # face_seed
        sql = u'SELECT face_id, ST_PointOnSurface(' \
              'topology.ST_GetFaceGeometry(%s,' \
              'face_id))::geometry(point, %s) as geom ' \
              'FROM %s.face WHERE face_id > 0' % \
              (quoteStr(toponame), toposrid, quoteId(toponame))
        uri.setDataSource('', u'(%s)' % sql, 'geom', '', 'face_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.Point)
        layerFaceSeed = QgsVectorLayer(uri.uri(False), u'%s.face_seed' % toponame, provider)
        layerFaceSeed.setExtent(face_extent)
        layerFaceSeed.loadNamedStyle(os.path.join(template_dir, 'face_seed.qml'))

        # TODO: add polygon0, polygon1 and polygon2 ?

        # NODES

        # node
        uri.setDataSource(toponame, 'node', 'geom', '', 'node_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.Point)
        layerNode = QgsVectorLayer(uri.uri(False), u'%s.node' % toponame, provider)
        layerNode.loadNamedStyle(os.path.join(template_dir, 'node.qml'))
        node_extent = layerNode.extent()

        # node labels
        uri.setDataSource(toponame, 'node', 'geom', '', 'node_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.Point)
        layerNodeLabel = QgsVectorLayer(uri.uri(False), u'%s.node_id' % toponame, provider)
        layerNodeLabel.setExtent(node_extent)
        layerNodeLabel.loadNamedStyle(os.path.join(template_dir, 'node_label.qml'))

        # EDGES

        # edge
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        layerEdge = QgsVectorLayer(uri.uri(False), u'%s.edge' % toponame, provider)
        edge_extent = layerEdge.extent()

        # directed edge
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        layerDirectedEdge = QgsVectorLayer(uri.uri(False), u'%s.directed_edge' % toponame, provider)
        layerDirectedEdge.setExtent(edge_extent)
        layerDirectedEdge.loadNamedStyle(os.path.join(template_dir, 'edge.qml'))

        # edge labels
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        layerEdgeLabel = QgsVectorLayer(uri.uri(False), u'%s.edge_id' % toponame, provider)
        layerEdgeLabel.setExtent(edge_extent)
        layerEdgeLabel.loadNamedStyle(os.path.join(template_dir, 'edge_label.qml'))

        # face_left
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        layerFaceLeft = QgsVectorLayer(uri.uri(False), u'%s.face_left' % toponame, provider)
        layerFaceLeft.setExtent(edge_extent)
        layerFaceLeft.loadNamedStyle(os.path.join(template_dir, 'face_left.qml'))

        # face_right
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        layerFaceRight = QgsVectorLayer(uri.uri(False), u'%s.face_right' % toponame, provider)
        layerFaceRight.setExtent(edge_extent)
        layerFaceRight.loadNamedStyle(os.path.join(template_dir, 'face_right.qml'))

        # next_left
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        layerNextLeft = QgsVectorLayer(uri.uri(False), u'%s.next_left' % toponame, provider)
        layerNextLeft.setExtent(edge_extent)
        layerNextLeft.loadNamedStyle(os.path.join(template_dir, 'next_left.qml'))

        # next_right
        uri.setDataSource(toponame, 'edge_data', 'geom', '', 'edge_id')
        uri.setSrid(toposrid)
        uri.setWkbType(QgsWkbTypes.LineString)
        layerNextRight = QgsVectorLayer(uri.uri(False), u'%s.next_right' % toponame, provider)
        layerNextRight.setExtent(edge_extent)
        layerNextRight.loadNamedStyle(os.path.join(template_dir, 'next_right.qml'))

        # Add layers to the layer tree

        faceLayers = [layerFaceMbr, layerFaceGeom, layerFaceSeed]
        nodeLayers = [layerNode, layerNodeLabel]
        edgeLayers = [layerEdge, layerDirectedEdge, layerEdgeLabel
                      # , layerEdgeFaceLeft, layerEdgeFaceRight, layerEdgeNextLeft, layerEdgeNextRight
                      ]

        QgsProject.instance().addMapLayers(faceLayers, False)

        groupFaces = QgsLayerTreeGroup(u'Faces')
        for layer in faceLayers:
            nodeLayer = groupFaces.addLayer(layer)
            nodeLayer.setVisible(Qt.Unchecked)
            nodeLayer.setExpanded(False)

        groupNodes = QgsLayerTreeGroup(u'Nodes')
        for layer in nodeLayers:
            nodeLayer = groupNodes.addLayer(layer)
            nodeLayer.setVisible(Qt.Unchecked)
            nodeLayer.setExpanded(False)

        groupEdges = QgsLayerTreeGroup(u'Edges')
        for layer in edgeLayers:
            nodeLayer = groupEdges.addLayer(layer)
            nodeLayer.setVisible(Qt.Unchecked)
            nodeLayer.setExpanded(False)

        supergroup = QgsLayerTreeGroup(u'Topology "%s"' % toponame)
        supergroup.insertChildNodes(-1, [groupFaces, groupNodes, groupEdges])

        QgsProject.instance().layerTreeRoot().addChildNode(supergroup)

    finally:

        # Set canvas extent to topology extent, if not yet initialized
        canvas = iface.mapCanvas()
        if (canvas.fullExtent().isNull()):
            ext = node_extent
            ext.combineExtentWith(edge_extent)
            # Grow by 1/20 of largest side
            ext = ext.buffer(max(ext.width(), ext.height()) / 20)
            canvas.setExtent(ext)

        # restore canvas render flag
        if not wasFrozen:
            iface.mapCanvas().freeze(False)

    return True
Beispiel #15
0
    def renderer(self):
        if 'QGIS_AUTH_DB_DIR_PATH' not in os.environ:
            os.environ['QGIS_AUTH_DB_DIR_PATH'] = '/tmp'

        qgis = None
        while True:
            options, result = self.queue.get()

            # Don't start QGIS until first request
            if qgis is None:
                qgis = QgsApplication([], False)
                qgis.setPrefixPath(self.settings.get('path'), True)
                qgis.setDefaultSvgPaths(qgis.svgPaths() +
                                        self.settings.get('svgpaths'))
                qgis.setMaxThreads(1)
                qgis.initQgis()

            try:
                if isinstance(options, LegendOptions):
                    style, = options

                    layer = self._qgs_memory_layer(style)
                    layer.setName(style.parent.display_name)

                    QgsMapLayerRegistry.instance().addMapLayer(layer)

                    root = QgsLayerTreeGroup()
                    root.addLayer(layer)

                    # 'Cannot create a QPixmap when no GUI is being used'
                    #  warning occurs here
                    model = QgsLayerTreeModel(root)

                    settings = QgsLegendSettings()
                    settings.setTitle('')
                    settings.setBoxSpace(1)
                    settings.setSymbolSize(QSizeF(5, 3))
                    settings.setDpi(96)

                    renderer = QgsLegendRenderer(model, settings)

                    # Dots per mm
                    dpmm = settings.dpi() / 25.4

                    min_size = renderer.minimumSize()
                    size = QSize(dpmm * min_size.width(),
                                 dpmm * min_size.height())
                    img = QImage(size, QImage.Format_ARGB32)
                    img.fill(QColor(0, 0, 0, 0))

                    painter = QPainter()
                    painter.begin(img)
                    painter.scale(dpmm, dpmm)
                    renderer.drawLegend(painter)
                    painter.end()

                    QgsMapLayerRegistry.instance().removeAllMapLayers()

                    ba = QByteArray()
                    bf = QBuffer(ba)
                    bf.open(QIODevice.WriteOnly)
                    img.save(bf, 'PNG')
                    bf.close()

                    buf = StringIO()
                    buf.write(bf.data())
                    buf.seek(0)
                    result.put(buf)

                else:
                    path = features = None
                    if isinstance(options, VectorRenderOptions):
                        style, features, render_size, \
                            extended, target_box = options
                        layer = self._qgs_memory_layer(style,
                                                       features=features)
                    elif isinstance(options, RasterRenderOptions):
                        style, path, render_size, \
                            extended, target_box = options
                        layer = QgsRasterLayer(path)
                        layer.loadNamedStyle(
                            self.env.file_storage.filename(style.qml_fileobj))

                    settings = QgsMapSettings()
                    settings.setLayers([layer.id()])
                    settings.setFlag(QgsMapSettings.DrawLabeling)
                    settings.setFlag(QgsMapSettings.Antialiasing)

                    settings.setCrsTransformEnabled(True)
                    settings.setDestinationCrs(layer.crs())
                    settings.setMapUnits(layer.crs().mapUnits())
                    settings.setOutputSize(QSize(*render_size))
                    settings.setExtent(QgsRectangle(*extended))

                    settings.setOutputImageFormat(QImage.Format_ARGB32)
                    bgcolor = QColor.fromRgba(qRgba(255, 255, 255, 0))
                    settings.setBackgroundColor(bgcolor)
                    settings.setOutputDpi(96)

                    QgsMapLayerRegistry.instance().addMapLayer(layer)
                    settings.setLayers([layer.id()])

                    # Create QImage by hand to be able to use
                    # QgsMapRendererCustomPainterJob. Others will not
                    # allow to workaround a bug with overlay rendering.
                    img = QImage(settings.outputSize(), QImage.Format_ARGB32)

                    # These cludges are needed for rendering
                    # on transparent background, otherwise it's a mess.
                    img.fill(QColor.fromRgba(qRgba(255, 255, 255, 255)))
                    img.fill(QColor.fromRgba(qRgba(255, 255, 255, 0)))

                    # DPI should be equal to settings, otherwise an error.
                    # In QImage the resolution is set in dots per meter
                    # for each axis.
                    dpm = settings.outputDpi() / 25.4 * 1000
                    img.setDotsPerMeterX(dpm)
                    img.setDotsPerMeterY(dpm)

                    painter = QPainter(img)
                    job = QgsMapRendererCustomPainterJob(settings, painter)
                    job.renderSynchronously()
                    painter.end()

                    QgsMapLayerRegistry.instance().removeAllMapLayers()

                    img = self._qimage_to_pil(img)

                    # Clip needed part
                    result.put(img.crop(target_box))

                    # Cleanup
                    if path is not None:
                        gdal.Unlink(path)

            except Exception as exc:
                self.logger.error(exc.message)
                result.put(exc)

        qgis.exitQgis()
class AuxiliaryWindow(QMainWindow):
  
  closed = pyqtSignal( int )
  
  def __init__(self, parent, geometryWin, numWin):
    
    def populateStatusBar():
      statusBar = self.statusBar()

      w = QCheckBox( "Render", self )
      w.setObjectName( 'renderCheck')
      w.setToolTip( "Toggle map rendering" )
      w.setChecked( True )
      statusBar.addPermanentWidget( w )

      w = QCheckBox( "Marker", self )
      w.setObjectName( 'markerCheck')
      w.setToolTip( "Toggle marker with cursor position from main map" )
      w.setChecked( False )
      statusBar.addPermanentWidget( w, 1 )

      w = QCheckBox( "Extent", self )
      w.setObjectName( 'extentCheck')
      w.setToolTip( "Show extent of main map" )
      w.setChecked( False )
      statusBar.addPermanentWidget( w, 1 )

      w = QToolButton(self)
      w.setObjectName( 'highlightBtn')
      w.setToolTip( "Highlight extent in main map" )
      w.setText("Highlight")
      statusBar.addPermanentWidget( w, 1 )

      w = QLabel( "Scale factor:", self )
      w.setObjectName( 'scaleFactorLabel')
      w.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
      statusBar.addPermanentWidget( w, 1 )

      w = QDoubleSpinBox(self)
      w.setObjectName( 'scaleFactorSpin')
      w.setToolTip( "Current scale factor of main map" )
      w.setMinimum(0.0)
      w.setMaximum(1000.0)
      w.setDecimals(3)
      w.setValue(1)
      w.setSingleStep(.05)
      statusBar.addPermanentWidget( w, 1 )

      w = QToolButton(self)
      w.setObjectName( 'scaleBtn')
      w.setToolTip( "Set scale for main map" )
      w.setText("Scale: ")
      statusBar.addPermanentWidget( w, 1 )

    def setupUi():
      self.setObjectName( "AuxiliaryWindow" )
      self.setGeometry( geometryWin )
      self.addDockWidget ( Qt.LeftDockWidgetArea, self.dockLegend )
      self.actLegend = self.menuBar().addAction("")
      self.actLegend.triggered.connect( self.onActionLegend )
      self.canvas.setMapTool( self.toolPan )
      self.canvas.setCanvasColor( QColor(255,255,255) )
      self.canvas.enableAntiAliasing( False )
      self.canvas.useImageToRender( False )
      self.canvas.setWheelAction( QgsMapCanvas.WheelZoom )
      self.setCentralWidget( centralWidget )
      self.messageBar.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed )
      layout = QGridLayout()
      layout.setContentsMargins( 0, 0, 0, 0 )
      layout.addWidget( self.canvas, 0, 0, 2, 1 )
      layout.addWidget( self.messageBar, 0, 0, 1, 1 )
      centralWidget.setLayout( layout )

    super( AuxiliaryWindow, self ).__init__( parent )

    centralWidget = QWidget( self )
    self.canvas = QgsMapCanvas( centralWidget )
    self.messageBar = QgsMessageBar( centralWidget )
    self.toolPan = QgsMapToolPan( self.canvas )
    self.qgisCanvas = qgis.utils.iface.mapCanvas()
    self.qgisTView = qgis.utils.iface.layerTreeView()
    self.qgisSyncGroup = None
    self.numWin = numWin

    self.ltg = QgsLayerTreeGroup('', Qt.Unchecked)
    self.dockLegend = AuxiliaryLegend( self, numWin )
    self.root = QgsProject.instance().layerTreeRoot()
    

    self.extent = self.actLegend = None
    self.marker = MarkerWindow( self.canvas )

    setupUi()
    populateStatusBar()

    self.onCurrentLayerChanged( None )
    self.onDestinationCrsChanged_MapUnitsChanged()
    self.onHasCrsTransformEnabledChanged( self.qgisCanvas.hasCrsTransformEnabled() )
    
  def _connect(self, isConnect = True):
    widgets = {
     'scaleBtn': self.findChild( QToolButton, 'scaleBtn'),
     'renderCheck': self.findChild( QCheckBox, 'renderCheck'),
     'markerCheck': self.findChild( QCheckBox, 'markerCheck'),
     'extentCheck': self.findChild( QCheckBox, 'extentCheck'),
     'highlightBtn': self.findChild( QToolButton, 'highlightBtn'),
     'scaleFactorSpin': self.findChild( QDoubleSpinBox, 'scaleFactorSpin')
    }
    signal_slot = (
      { 'signal': widgets['scaleBtn'].clicked, 'slot': self.onClickedScale },
      { 'signal': widgets['renderCheck'].toggled, 'slot': self.onToggledRender },
      { 'signal': widgets['markerCheck'].toggled, 'slot': self.onToggledMarker },
      { 'signal': widgets['extentCheck'].toggled, 'slot': self.onToggledExtent },
      { 'signal': widgets['highlightBtn'].clicked, 'slot': self.onClickedHighlight },
      { 'signal': widgets['scaleFactorSpin'].valueChanged, 'slot': self.onValueChangedScale },
      { 'signal': self.dockLegend.currentLayerChanged, 'slot': self.onCurrentLayerChanged },
      { 'signal': self.dockLegend.currentLayerQgis, 'slot': self.onCurrentLayerQgis },
      { 'signal': self.dockLegend.syncGroupLayer, 'slot': self.onSyncGroupAddLayersQgis },
      { 'signal': self.dockLegend.addSelectedLayersQgis, 'slot': self.onAddSelectedLayersQgis },
      { 'signal': self.dockLegend.removeLayer, 'slot': self.onRemoveLayers },
      { 'signal': self.dockLegend.needSelectLayer, 'slot': self.onNeedSelectLayer },
      { 'signal': self.dockLegend.closed, 'slot': self.onClosedLegend },
      { 'signal': self.canvas.extentsChanged, 'slot': self.onExtentsChangedMirror },
      { 'signal': self.qgisCanvas.extentsChanged, 'slot': self.onExtentsChangedQgisCanvas },
      { 'signal': self.qgisCanvas.xyCoordinates, 'slot': self.marker.onXYCoordinates },
      { 'signal': self.qgisCanvas.destinationCrsChanged, 'slot': self.onDestinationCrsChanged_MapUnitsChanged },
      { 'signal': self.qgisCanvas.mapUnitsChanged, 'slot': self.onDestinationCrsChanged_MapUnitsChanged },
      { 'signal': self.qgisCanvas.hasCrsTransformEnabledChanged, 'slot': self.onHasCrsTransformEnabledChanged },
      { 'signal': self.root.removedChildren, 'slot': self.onRemovedChildrenQgisRoot },
      { 'signal': QgsMapLayerRegistry.instance().layersWillBeRemoved, 'slot': self.onLayersWillBeRemoved }
    )
    if isConnect:
      for item in signal_slot:
        item['signal'].connect( item['slot'] )
    else:
      for item in signal_slot:
        item['signal'].disconnect( item['slot'] )

  def _extentsChanged(self, canvasOrigin, originSlot, canvasDest, scaleFactor=None):
    canvasOrigin.extentsChanged.disconnect( originSlot )

    if scaleFactor is None:
      scale = canvasOrigin.scale()
      canvasOrigin.setExtent( canvasDest.extent() )
      canvasOrigin.zoomScale( scale )
    else:
      canvasOrigin.setExtent( canvasDest.extent() )
      canvasOrigin.zoomScale( scaleFactor * canvasDest.scale() )

    canvasOrigin.extentsChanged.connect( originSlot )

  def _textScaleBtnChanched(self):
    scale = locale.format( "%.0f", self.canvas.scale(), True ) 
    w = self.findChild( QToolButton, 'scaleBtn' )
    w.setText("Scale 1:%s" % scale )

  def _extent(self):
   rect = self.qgisCanvas.extent()
   p1 = QgsPoint( rect.xMinimum() , rect.yMinimum() )
   p2 = QgsPoint( rect.xMinimum() , rect.yMaximum() )
   p3 = QgsPoint( rect.xMaximum() , rect.yMaximum() )
   p4 = QgsPoint( rect.xMaximum() , rect.yMinimum() )
   p5 = QgsPoint( rect.xMinimum() , rect.yMinimum() )
   points = [ p1, p2, p3, p4, p5 ]
   self.extent.setToGeometry(QgsGeometry.fromPolyline (points), None)

  def _execFunction( self, func, arg, signal, slot):
   signal.disconnect( slot )
   func( arg )
   signal.connect( slot )

  def _connectVectorRefresh(self, layer, isConnect=True):
    if isinstance( layer, QgsVectorLayer ):
      f = layer.editCommandEnded.connect if isConnect else layer.editCommandEnded.disconnect
      f( self.canvas.refresh )

  def _addLayersQgis( self, layersQgis, needMsg=True ):
    
    self.dockLegend.clearBridge()

    l1 = set( layersQgis )
    l2 = set( map( lambda item: item.layer(), self.ltg.findLayers() ) )
    layers = list( l1 - l2 )
    if len( layers ) == 0:
      if needMsg:
        self.messageBar.pushMessage("Need select new layer(s) in main map", QgsMessageBar.WARNING, 2 )
    else:
      # Get order by layersQgis
      for item in layersQgis:
        if item in layers:
          self.ltg.addLayer( item )
          self._connectVectorRefresh( item )

    self.dockLegend.setBridge( self.canvas )

  def _syncGroupAddLayersQgis( self, ltg ):
    layersQgis = map( lambda item: item.layer(), ltg.findLayers() )
    if len( layersQgis ) == 0:
      return False

    name = ltg.name()
    if self.qgisSyncGroup == ltg:
      msg = "Already synchronized group (main map) -> '%s'" % name
      self.messageBar.pushMessage( msg, QgsMessageBar.INFO, 4 )
      return True
    
    if not self.qgisSyncGroup is None:
      self.qgisSyncGroup.addedChildren.disconnect( self.addedChildrenLayer )
      
    self.qgisSyncGroup = ltg
    self.qgisSyncGroup.addedChildren.connect( self.addedChildrenLayer )
    
    self.dockLegend.addNameSyncGroup( name )
    msg = "Changed synchronized group (main map) -> '%s'" % name
    self.messageBar.pushMessage( msg, QgsMessageBar.INFO, 4 )
    
    self._addLayersQgis( layersQgis )
    return True

  def run(self):
    
    if len( self.qgisTView.selectedLayerNodes() ) > 0:
      self.onAddSelectedLayersQgis()
    else:
      ltn = self.qgisTView.currentNode()
      if not isinstance( ltn, QgsLayerTreeGroup ):
        return False
      else:
        if ltn == self.root:
          return False
        else:
          if not self._syncGroupAddLayersQgis( ltn ):
            return False

    self.dockLegend.setBridge( self.canvas)

    self.canvas.setRenderFlag( False )
    self.show() # Need show before self._connect()
    self._connect()
    self.canvas.setExtent( self.qgisCanvas.extent() )
    w = self.findChild( QDoubleSpinBox, 'scaleFactorSpin')
    w.setValue( 1 )
    self.canvas.setRenderFlag( True )

    return True

  def getLayersCanvas(self):
    layerIds = map(lambda x: x.layerId(), self.ltg.findLayers() )
    layerChecks = map(lambda x: str( x.isVisible() ), self.ltg.findLayers() )

    return ( layerIds, layerChecks )

  def setLayersCanvas(self, layerIds, layerChecks ):
    prevFlag = self.canvas.renderFlag()
    self.canvas.setRenderFlag( False )

    lyrRegs = QgsMapLayerRegistry.instance()
    for id in range( len( layerIds ) ):
      layer = lyrRegs.mapLayer(  layerIds[id] )
      isVisible = int( layerChecks[id] )
      if not layer is None:
        self.ltg.addLayer( layer ).setVisible( isVisible )

    self.canvas.setRenderFlag( prevFlag )

  def getWindowSetting(self):
    g = self.geometry()
    r = self.canvas.extent()
    nodes = self.ltg.findLayers()
    currentLayer = self.dockLegend.tview.currentLayer()
    currentLayerId = currentLayer.id() if not currentLayer is None else "None"
    
    windowSetting =  {
      'numWin': self.numWin,
      'geometryWin': { 'x': g.x(), 'y': g.y(), 'width': g.width(), 'height': g.height() },
      'extentCanvas': { 'xmin': r.xMinimum(), 'ymin': r.yMinimum(), 'xmax': r.xMaximum(), 'ymax': r.yMaximum() },
      'currentLayerId': currentLayerId,
      'layerIds' : ' '.join( map(lambda item: item.layerId(), nodes ) ),
      'visibles': ' '.join( map(lambda item: str( int( item.isVisible() ) ), nodes ) )
    }
    for item in ( 'render', 'marker', 'extent' ):
      nameGui = "%sCheck" % item
      windowSetting[ item ] = int( self.findChild( QCheckBox, nameGui).isChecked() )

    return windowSetting

  def setWindowSetting(self, windowSetting):
    self.numWin = windowSetting['numWin']

    # Populate with layers and set Bridge for legend
    layerIds = windowSetting['layerIds'].split(' ')
    visibles = map( lambda item: bool( int( item ) ), windowSetting['visibles'].split(' ') )
    ltg = self.qgisTView.layerTreeModel().rootGroup()
    for id in range( len( layerIds ) ):
      node = ltg.findLayer( layerIds[ id ] )
      if node is None:
        continue
      layer = node.layer()
      visible = Qt.Checked if visibles[ id ] else Qt.Unchecked
      self._connectVectorRefresh( layer )
      self.ltg.addLayer( layer ).setVisible( visible )
    self.dockLegend.setBridge( self.canvas)
    
    self.show() # Need show before self._connect()
    self._connect()
    node = ltg.findLayer( windowSetting['currentLayerId'] )
    if not node is None:
      layer = node.layer()
      self.dockLegend.tview.setCurrentLayer( layer )
    w = windowSetting['extentCanvas']
    self.canvas.setExtent( QgsRectangle( w['xmin'], w['ymin'], w['xmax'], w['ymax'] ) )
    for item in ( 'render', 'marker', 'extent' ):
      value = bool( windowSetting[ item ] )
      nameGui = "%sCheck" % item
      self.findChild( QCheckBox, nameGui ).setChecked( value )

  def closeEvent(self, event):
    self._connect( False )
    event.accept()
    self.closed.emit( self.numWin )

  @pyqtSlot(int)
  def onValueChangedScale(self, scaleFactor):
    w = self.findChild( QCheckBox, 'renderCheck')
    if not w.isChecked():
      return
    self._execFunction(
      self.canvas.zoomScale, scaleFactor * self.qgisCanvas.scale(),
      self.canvas.extentsChanged, self.onExtentsChangedMirror
    )
    self._textScaleBtnChanched()

  @pyqtSlot()
  def onClickedScale(self):
    self._execFunction( 
        self.qgisCanvas.zoomScale, self.canvas.scale(),
        self.qgisCanvas.extentsChanged, self.onExtentsChangedQgisCanvas
    )
    w = self.findChild( QDoubleSpinBox, 'scaleFactorSpin' )
    self._execFunction( w.setValue, 1.0, w.valueChanged, self.onValueChangedScale )

  @pyqtSlot()
  def onClickedHighlight(self):
    def removeRB():
      rb.reset( True )
      self.qgisCanvas.scene().removeItem( rb )
    
    rb = QgsRubberBand( self.qgisCanvas, QGis.Polygon)
    rb.setBorderColor( QColor( 255,  0, 0 ) )
    rb.setWidth( 2 )
    rb.setToGeometry( QgsGeometry.fromRect( self.canvas.extent() ), None )
    QTimer.singleShot( 2000, removeRB )

  @pyqtSlot(bool)
  def onToggledRender(self, enabled):
    if enabled:
      self.canvas.setMapTool(self.toolPan)
      w = self.findChild( QDoubleSpinBox, 'scaleFactorSpin' )
      self._extentsChanged( self.canvas, self.onExtentsChangedMirror, self.qgisCanvas, w.value() )
      self._textScaleBtnChanched()
      self.canvas.setWheelAction( QgsMapCanvas.WheelZoom )
    else:
      self.canvas.unsetMapTool(self.toolPan)
      self.canvas.setWheelAction( QgsMapCanvas.WheelNothing )
    self.canvas.setRenderFlag( enabled )

  @pyqtSlot(bool)
  def onToggledMarker(self, enabled):
    self.marker.add() if enabled else self.marker.remove() 

  @pyqtSlot(bool)
  def onToggledExtent(self, enabled):
    def setExtent():
      if not self.extent is None:
        self.canvas.scene().removeItem( self.extent )
      self.extent = QgsRubberBand( self.canvas, QGis.Polygon )
      self.extent.setBorderColor( QColor( 255, 0 , 0 ) )
      self.extent.setWidth( 2 )
      self._extent()

    if enabled:
      setExtent()
    else:
      if not self.extent is None:
        self.canvas.scene().removeItem( self.extent )
        self.extent = None

  @pyqtSlot()
  def onExtentsChangedMirror(self):
    w = self.findChild( QCheckBox, 'renderCheck')
    if not w.isChecked():
      return
    self._extentsChanged( self.qgisCanvas, self.onExtentsChangedQgisCanvas, self.canvas )
    self._textScaleBtnChanched()
    w = self.findChild( QDoubleSpinBox, 'scaleFactorSpin' )
    self._execFunction(
        w.setValue, self.canvas.scale() / self.qgisCanvas.scale(),
        w.valueChanged, self.onValueChangedScale
    )
    if not self.extent is None:
      self._extent()

  @pyqtSlot()
  def onExtentsChangedQgisCanvas(self):
    w = self.findChild( QCheckBox, 'renderCheck')
    if not w.isChecked():
      return
    w = self.findChild( QDoubleSpinBox, 'scaleFactorSpin' )
    self._extentsChanged( self.canvas, self.onExtentsChangedMirror, self.qgisCanvas, w.value() )
    self._textScaleBtnChanched()
    if not self.extent is None:
      self._extent()

  @pyqtSlot()
  def onDestinationCrsChanged_MapUnitsChanged(self):
    prevFlag = self.canvas.renderFlag()
    self.canvas.setRenderFlag( False )

    self.canvas.setDestinationCrs( self.qgisCanvas.mapRenderer().destinationCrs()  )
    self.canvas.setMapUnits( self.qgisCanvas.mapUnits() )

    self.canvas.setRenderFlag( prevFlag )

  @pyqtSlot(bool)
  def onHasCrsTransformEnabledChanged(self, enabled):
    prevFlag = self.canvas.renderFlag()
    self.canvas.setRenderFlag( False )
    self.canvas.mapRenderer().setProjectionsEnabled( enabled )
    self.canvas.setRenderFlag( prevFlag )

  @pyqtSlot(list)
  def onLayersWillBeRemoved( self, theLayerIds ):
    ids = list( set( self.ltg.findLayerIds() ) & set( theLayerIds ) ) # intersection
    nodes = map( lambda item: self.ltg.findLayer( item ), ids )
    for item in nodes:
      self._connectVectorRefresh( item.layer(), False )
      self.ltg.removeChildNode( item )

  @pyqtSlot()
  def onAddSelectedLayersQgis( self ):
    layersQgis = map( lambda item: item.layer(), self.qgisTView.selectedLayerNodes() )
    self._addLayersQgis( layersQgis )

  @pyqtSlot('QgsLayerTreeNode', int, int)
  def addedChildrenLayer(self, ltg, indexFrom, indexTo):
    layersQgis = map( lambda item: item.layer(), ltg.findLayers() )
    self._addLayersQgis( layersQgis, False )

  @pyqtSlot('QgsLayerTreeNode', int, int)
  def onRemovedChildrenQgisRoot(self, ltg, indexFrom, indexTo):
    if not self.qgisSyncGroup is None and not self.qgisSyncGroup in self.root.children():
      self.qgisSyncGroup = None
      self.dockLegend.addNameSyncGroup( "None" )
      msg = "Removed synchronized group (main map)"
      self.messageBar.pushMessage( msg, QgsMessageBar.INFO, 4 )
      
      
  @pyqtSlot()
  def onSyncGroupAddLayersQgis( self):
    
    msg = "Need active a group in main map with new layers"
    ltn = self.qgisTView.currentNode()
    if not isinstance( ltn, QgsLayerTreeGroup ) or ltn == self.root:
      self.messageBar.pushMessage( msg, QgsMessageBar.WARNING, 3 )
      return

    if not self._syncGroupAddLayersQgis( ltn ):
      self.messageBar.pushMessage( msg, QgsMessageBar.WARNING, 3 )

  @pyqtSlot( 'QgsMapLayer' )
  def onRemoveLayers( self, layer ):
    self._connectVectorRefresh(layer, False)

  @pyqtSlot()
  def onNeedSelectLayer(self):
    self.messageBar.pushMessage("Need select layer(s)", QgsMessageBar.WARNING, 2 )    

  @pyqtSlot('QgsMapLayer')
  def onCurrentLayerQgis(self, layer ):
    if layer is None:
      self.messageBar.pushMessage("Need active layer", QgsMessageBar.WARNING, 2 )
    else:
      self.qgisTView.setCurrentLayer( layer )

  @pyqtSlot('QgsMapLayer')
  def onCurrentLayerChanged(self, layer ):
    hasLayer = True if not layer is None else False
    selectName = "Select layer '%s'" % layer.name() if hasLayer else "None select layer"
    title = "#%d - %s" % ( self.numWin, selectName )
    self.setWindowTitle( title )

  @pyqtSlot()
  def onClosedLegend(self):
    self.actLegend.setText( "Show layers" )

  @pyqtSlot()
  def onActionLegend(self):
    self.actLegend.setText( "" )
    self.dockLegend.show()