def organize_legend(context, available_layers) -> None:
        """ Create groups and organize the legend. """
        root = context.project().layerTreeRoot()

        groups = OrderedDict()
        groups[root] = [
            "v_itineraire", "v_portion", "segment", "liaison", "repere", "poi_service", "poi_tourisme"]

        groups[QgsLayerTreeGroup('Composants')] = [
            "element", "portion", "etape", "itineraire"]

        groups[QgsLayerTreeGroup('Nomenclatures')] = [
            "statut_segment_val", "amenagement_segment_val", "amenagement_type_segment_val"]

        for node_composants, content in groups.items():
            if root != node_composants:
                root.addChildNode(node_composants)

            for com in content:
                layer_id = available_layers.get(com)

                if not layer_id:
                    continue

                layer = root.findLayer(layer_id)
                node_composants.addChildNode(layer.clone())
                layer.parent().removeChildNode(layer)
Esempio n. 2
0
def layerWarp(rasterNode: QgsLayerTreeGroup,
              domainLayer: QgsVectorLayer) -> None:
    """Description: Reprojects a raster if not already in the desired CRS.
		Make sure to save the shapefile, as it will be deleted otherwise! 
		Input:  QgsLayerTreeGroup rasterNode - node that contains the raster image to process
				QgsVectorLayer domainLayer - layer that contains a polygon specifying the bounds of the raster image to process
	"""

    rasterLayer = rasterNode.layer()
    fileSource = rasterLayer.source()
    geotiff = gdal.Open(fileSource)
    prj = geotiff.GetProjection()
    srs = osr.SpatialReference(wkt=prj)
    domainCRS = domainLayer.crs().authid()
    if srs.GetAttrValue("PROJCS|AUTHORITY", 1) is not None:
        epsgCode = srs.GetAttrValue("PROJCS|AUTHORITY", 1)
    elif srs.GetAttrValue("AUTHORITY", 1) is not None:
        epsgCode = srs.GetAttrValue("AUTHORITY", 1)
    else:
        epsgCode = str(32621)
    rasterCRS = "EPSG:" + epsgCode
    if (rasterCRS != domainCRS):
        print('warping...', rasterCRS, domainCRS)
        if not DRY_RUN:
            parent = rasterNode.parent()
            rasterName = rasterLayer.name()

            outSource = fileSource[0:-4] + "_" + domainCRS[5:] + ".tif"
            #processing.algorithmHelp("gdal:warpreproject")
            print(fileSource, outSource)
            processing.run(
                "gdal:warpreproject",
                {
                    'DATA_TYPE': 5,  #Float32
                    'INPUT': rasterName,
                    'MULTITHREADING': True,
                    'NODATA': 0.0,
                    'OPTIONS': '',
                    'OUTPUT': outSource,
                    'RESAMPLING': 1,  #Bilinear
                    'SOURCE_CRS': rasterCRS,
                    'TARGET_CRS': domainCRS,
                    'TARGET_EXTENT': None,
                    'TARGET_EXTENT_CRS': None,
                    'TARGET_RESOLUTION': None
                })
            print('hello')
            QgsProject.instance().removeMapLayer(rasterLayer.id())
            geotiff = None
            shutil.copy2(outSource, fileSource)
            os.remove(outSource)
            rasterLayer = QgsRasterLayer(fileSource, rasterName)
            QgsProject.instance().addMapLayer(rasterLayer, False)
            rasterNode = parent.insertLayer(0, rasterLayer)
            return rasterNode
    return rasterNode
Esempio n. 3
0
def nest_groups(parent: QgsLayerTreeGroup,
                groupnames: List[str],
                prepend: bool = True) -> QgsLayerTreeGroup:
    '''recursively nests groups in order of groupnames'''
    if len(groupnames) == 0:
        return parent
    next_parent = parent.findGroup(groupnames[0])
    if not next_parent:
        next_parent = (parent.insertGroup(0, groupnames[0])
                       if prepend else parent.addGroup(groupnames[0]))
    return nest_groups(next_parent, groupnames[1:], prepend=prepend)
Esempio n. 4
0
def findGroup(root: QgsLayerTreeGroup, name: str) -> QgsLayerTreeGroup:
    """Recursively finds first group that matches name."""
    #Search immediate children
    for child in root.children():
        if isinstance(child, QgsLayerTreeGroup):
            if name == child.name():
                return child
    #Search subchildren
    for child in root.children():
        if isinstance(child, QgsLayerTreeGroup):
            result = findGroup(child, name)
            if result != None:
                return result
    #Found nothing
    return None
Esempio n. 5
0
    def load_qlr_file(self, path):
        # Load qlr into a group owned by us
        try:
            group = QgsLayerTreeGroup()

            # On Windows this locks the parent dirs indefinitely
            # See http://hub.qgis.org/issues/14811
            # QgsLayerDefinition.loadLayerDefinition(path, group)

            # Instead handle file ourselves
            f = QFile(path)
            if not f.open(QIODevice.ReadOnly):
                return False
            try:
                doc = QDomDocument()
                if not doc.setContent(f.readAll()):
                    return False
                QgsLayerDefinition.loadLayerDefinition(doc, group)
            finally:
                f.close()

            # Get subtree of nodes
            nodes = group.children()
            # plain list of nodes
            nodeslist = []
            for addedNode in nodes:
                internalid = self._random_string()
                nodeinfo = {'internalid': internalid}
                addedNode.setCustomProperty(QlrManager.customPropertyName,
                                            internalid)
                if isinstance(addedNode, QgsLayerTreeGroup):
                    nodeinfo['type'] = 'group'
                    nodeinfo['name'] = addedNode.name()
                elif isinstance(addedNode, QgsLayerTreeLayer):
                    nodeinfo['type'] = 'layer'
                    nodeinfo['name'] = addedNode.layerName()
                    nodeinfo['layerid'] = addedNode.layerId()
                nodeslist.append(nodeinfo)
                # Remove from parent node. Otherwise we cant add it to a new parent
                group.takeChild(addedNode)
            self.fileSystemItemToLegendNode[path] = nodeslist

            # Insert them into the main project
            QgsProject.instance().layerTreeRoot().insertChildNodes(0, nodes)
            return True
        except:
            # For now just return silently
            return False
Esempio n. 6
0
    def draw(self):
        # print("draw")
        rb = self.tool.rb
        g = rb.asGeometry()

        layer = QgsVectorLayer(
            "Polygon?crs=" + self.iface.mapCanvas().mapSettings().destinationCrs().authid() + "&field=" + self.tr(
                'Drawings') + ":string(255)", self.searchAreaLayerName, "memory")
        layer.startEditing()
        symbols = layer.renderer().symbols(QgsRenderContext())  # todo which context ?
        symbols[0].setColor(self.color)
        feature = QgsFeature()
        feature.setGeometry(g)
        feature.setAttributes([self.searchAreaLayerName])
        layer.dataProvider().addFeatures([feature])
        layer.commitChanges()

        pjt = QgsProject.instance()
        layersList = pjt.mapLayersByName(self.searchAreaLayerName)
        if layersList is not None and len(layersList) > 0:
            pjt.removeMapLayer(layersList[0])

        pjt.addMapLayer(layer, False)
        if pjt.layerTreeRoot().findGroup(self.tr(self.groupName)) is None:
            pjt.layerTreeRoot().insertChildNode(0, QgsLayerTreeGroup(self.tr(self.groupName)))
        group = pjt.layerTreeRoot().findGroup(self.tr(self.groupName))
        group.insertLayer(0, layer)
        self.iface.layerTreeView().refreshLayerSymbology(layer.id())
        self.iface.mapCanvas().refresh()

        self.tool.reset()
Esempio n. 7
0
    def load_qlr_file(self, path):
        # Load qlr into a group owned by us
        try:
            group = QgsLayerTreeGroup()

            # On Windows this locks the parent dirs indefinitely
            # See http://hub.qgis.org/issues/14811
            # QgsLayerDefinition.loadLayerDefinition(path, group)

            # Instead handle file ourselves
            f = QFile(path)
            if not f.open(QIODevice.ReadOnly):
                return False
            try:
                doc = QDomDocument()
                if not doc.setContent( f.readAll() ):
                    return False
                QgsLayerDefinition.loadLayerDefinition(doc, group)
            finally:
                f.close()

            # Get subtree of nodes
            nodes = group.children()
            # plain list of nodes
            nodeslist = []
            for addedNode in nodes:
                internalid = self._random_string()
                nodeinfo = {'internalid': internalid}
                addedNode.setCustomProperty(QlrManager.customPropertyName, internalid)
                if isinstance(addedNode, QgsLayerTreeGroup):
                    nodeinfo['type'] = 'group'
                    nodeinfo['name'] = addedNode.name()
                elif isinstance(addedNode, QgsLayerTreeLayer):
                    nodeinfo['type'] = 'layer'
                    nodeinfo['name'] = addedNode.layerName()
                    nodeinfo['layerid'] = addedNode.layerId()
                nodeslist.append(nodeinfo)
                # Remove from parent node. Otherwise we cant add it to a new parent
                group.takeChild(addedNode)
            self.fileSystemItemToLegendNode[path] = nodeslist

            # Insert them into the main project
            QgsProject.instance().layerTreeRoot().insertChildNodes(0, nodes)
            return True
        except:
            # For now just return silently
            return False
Esempio n. 8
0
def firstGroupWithoutCustomProperty(group: QgsLayerTreeGroup,
                                    _property: str) -> QgsLayerTreeGroup:
    """
    Taken from QgsLayerTreeUtils::firstGroupWithoutCustomProperty
    :param group:
    :param _property:
    :return:
    """
    # if the group is embedded go to the first non-embedded group, at worst the top level item
    while group.customProperty(_property):
        if not group.parent():
            break
        if QgsLayerTree.isGroup(group.parent()):
            group = group.parent()
        else:
            dbg_info(group)
            assert False

    return group
Esempio n. 9
0
def findChildren(root: QgsLayerTreeGroup, matchString: str):
    """Return a list of groups in the root that match a regex string argument."""
    result = []
    matchStringParts = matchString.split('/', 1)
    for child in root.children():
        if fnmatch.fnmatch(child.name(), matchStringParts[0]):
            if isinstance(child, QgsLayerTreeGroup):
                result.extend(findChildren(child, matchStringParts[1]))
            else:
                result.append(child)
    return result
Esempio n. 10
0
    def groupSelected(self):
        nodes = self.mView.selectedNodes(True)
        if len(nodes) < 2 or not QgsLayerTree.isGroup(nodes[0].parent()):
            return

        parentGroup = nodes[0].parent()
        insertIdx = parentGroup.children().index(nodes[0])

        newGroup = QgsLayerTreeGroup(self.uniqueGroupName(parentGroup))
        for node in nodes:
            newGroup.addChildNode(node.clone())

        parentGroup.insertChildNode(insertIdx, newGroup)

        for node in nodes:
            group = node.parent()
            if group != None:
                group.removeChildNode(node)
        self.mView.setCurrentIndex(
            self.mView.layerTreeModel().node2index(newGroup))
Esempio n. 11
0
def layerFromPath(lineFilePath: str, rootGroup: QgsLayerTreeGroup,
                  project: QgsLayerTreeGroup) -> None:
    lineFileBasename = os.path.splitext(os.path.basename(lineFilePath))[0]
    lineLayer = QgsVectorLayer(lineFilePath, lineFileBasename, 'ogr')

    # Get number of features (range of Sequence#, number of renderer color classes)
    driver = ogr.GetDriverByName('ESRI Shapefile')
    dataSource = driver.Open(lineFilePath,
                             0)  # 0 means read-only. 1 means writeable.
    layer = dataSource.GetLayer()
    dataSource = None

    #Setup graduated color renderer based on year
    targetField = 'Year'
    renderer = QgsGraduatedSymbolRenderer('', [QgsRendererRange()])
    renderer.setClassAttribute(targetField)
    lineLayer.setRenderer(renderer)

    #Get viridis color ramp
    style = QgsStyle().defaultStyle()
    defaultColorRampNames = style.colorRampNames()
    viridisIndex = defaultColorRampNames.index('Viridis')
    viridisColorRamp = style.colorRamp(
        defaultColorRampNames[viridisIndex])  #Spectral color ramp

    #Dynamically recalculate number of classes and colors
    renderer.updateColorRamp(viridisColorRamp)
    yearsRange = list(range(1972, 2020))
    classCount = len(yearsRange)
    renderer.updateClasses(lineLayer, QgsGraduatedSymbolRenderer.EqualInterval,
                           classCount)

    #Set graduated color renderer based on Sequence#
    for i in range(classCount):  #[1972-2019], 2020 not included
        targetField = 'DateUnix'
        year = yearsRange[i]
        renderer.updateRangeLowerValue(i, year)
        renderer.updateRangeUpperValue(i, year)

    project.addMapLayer(lineLayer, False)
    rootGroup.insertLayer(0, lineLayer)
Esempio n. 12
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
Esempio n. 13
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
Esempio n. 14
0
    def test_copy_layer_tree_group(self):
        # copying layer tree group should also copy group layer setting
        options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext())
        group_layer = QgsGroupLayer('group', options)

        group_node = QgsLayerTreeGroup()
        group_node.setGroupLayer(group_layer)
        self.assertEqual(group_node.groupLayer(), group_layer)

        group_node2 = group_node.clone()
        self.assertEqual(group_node2.groupLayer(), group_layer)
Esempio n. 15
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])
Esempio n. 16
0
    def test_layer_tree_group_layer(self):
        """
        Test setting a group layer on a QgsLayerTreeGroup
        """
        options = QgsGroupLayer.LayerOptions(QgsCoordinateTransformContext())
        group_layer = QgsGroupLayer('group', options)

        group_node = QgsLayerTreeGroup()
        self.assertFalse(group_node.groupLayer())
        group_node.setGroupLayer(group_layer)
        self.assertEqual(group_node.groupLayer(), group_layer)

        group_layer.deleteLater()
        group_layer = None
        QCoreApplication.sendPostedEvents(None, QEvent.DeferredDelete)
        # should be automatically cleaned
        self.assertFalse(group_node.groupLayer())
Esempio n. 17
0
 def __add_layer_definition_file(self, file_name, root_group):
     """
     shamelessly copied from
     https://github.com/qgis/QGIS/blob/master/src/core/qgslayerdefinition.cpp
     """
     qfile = QFile(file_name)
     if not qfile.open(QIODevice.ReadOnly):
         return None
     doc = QDomDocument()
     if not doc.setContent(qfile):
         return None
     file_info = QFileInfo(qfile)
     QDir.setCurrent(file_info.absoluteDir().path())
     root = QgsLayerTreeGroup()
     ids = doc.elementsByTagName('id')
     for i in range(0, ids.size()):
         id_node = ids.at(i)
         id_elem = id_node.toElement()
         old_id = id_elem.text()
         layer_name = old_id[:-17]
         date_time = QDateTime.currentDateTime()
         new_id = layer_name + date_time.toString('yyyyMMddhhmmsszzz')
         id_elem.firstChild().setNodeValue(new_id)
         tree_layer_nodes = doc.elementsByTagName('layer-tree-layer')
         for j in range(0, tree_layer_nodes.count()):
             layer_node = tree_layer_nodes.at(j)
             layer_elem = layer_node.toElement()
             if old_id == layer_elem.attribute('id'):
                 layer_node.toElement().setAttribute('id', new_id)
     layer_tree_elem = doc.documentElement().firstChildElement(
         'layer-tree-group')
     load_in_legend = True
     if not layer_tree_elem.isNull():
         root.readChildrenFromXML(layer_tree_elem)
         load_in_legend = False
     layers = QgsMapLayer.fromLayerDefinition(doc)
     QgsProject.instance().addMapLayers(layers, load_in_legend)
     nodes = root.children()
     for node in nodes:
         root.takeChild(node)
     del root
     root_group.insertChildNodes(-1, nodes)
     return None
Esempio n. 18
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
Esempio n. 19
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])
Esempio n. 20
0
def addLayer(layer, loadInLegend=True, group=None, isSubGroup=False):
    """
    Add one or several layers to the QGIS session and layer registry.
    @param layer: The layer object or list with layers  to add the QGIS layer registry and session.
    @param loadInLegend: True if this layer should be added to the legend.
    :return: The added layer
    """

    global groupName

    if not hasattr(layer, "__iter__"):
        layer = [layer]
    if group is not None:
        _layerreg.addMapLayers(layer, False)
        root = _layerreg.layerTreeRoot()

        if isSubGroup:
            vg = root.findGroup(groupName)
            g = vg.findGroup(group)
        else:
            g = root.findGroup(group)

        if g is None:
            # Create Group
            node_group = QgsLayerTreeGroup(group)
            root.insertChildNode(0, node_group)

        if isSubGroup:
            vg = root.findGroup(groupName)
            g = vg.findGroup(group)
        else:
            g = root.findGroup(group)

        g.insertChildNode(0, QgsLayerTreeLayer(layer[0]))

    else:
        _layerreg.addMapLayers(layer, loadInLegend)
    return layer
Esempio n. 21
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)
Esempio n. 22
0
    def object_to_layers_and_tree(obj, input_file, context: Context):
        """
        Converts an ESRI object to layers and equivalent layer tree
        """
        layers = []

        def add_layer(layer, group_node):
            nonlocal layers
            results = LayerConverter.layer_to_QgsLayer(
                layer,
                input_file,
                context=context,
                fallback_crs=QgsCoordinateReferenceSystem('EPSG:4326'))
            for res in results:
                node = group_node.addLayer(res)
                if not layer.visible:
                    node.setItemVisibilityChecked(False)
                if len(node.children()) > 10:
                    node.setExpanded(False)
                layers.append(res)

        def add_group(group, parent):
            group_node = parent.addGroup(group.name)
            for c in group.children:
                if isinstance(c, (GroupLayer, BaseMapLayer)):
                    add_group(c, group_node)
                else:
                    add_layer(c, group_node)

        root_node = QgsLayerTreeGroup()

        if LayerConverter.is_layer(obj):
            add_layer(obj, root_node)
        else:
            add_group(obj, root_node)

        return root_node, layers
Esempio n. 23
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
Esempio n. 24
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']
Esempio n. 25
0
 def __add_layer_definition_file(self, file_name, root_group):
     """
     shamelessly copied from
     https://github.com/qgis/QGIS/blob/master/src/core/qgslayerdefinition.cpp
     """
     qfile = QFile(file_name)
     if not qfile.open(QIODevice.ReadOnly):
         return None
     doc = QDomDocument()
     if not doc.setContent(qfile):
         return None
     file_info = QFileInfo(qfile)
     QDir.setCurrent(file_info.absoluteDir().path())
     root = QgsLayerTreeGroup()
     ids = doc.elementsByTagName('id')
     for i in xrange(0, ids.size()):
         id_node = ids.at(i)
         id_elem = id_node.toElement()
         old_id = id_elem.text()
         layer_name = old_id[:-17]
         date_time = QDateTime.currentDateTime()
         new_id = layer_name + date_time.toString('yyyyMMddhhmmsszzz')
         id_elem.firstChild().setNodeValue(new_id)
         tree_layer_nodes = doc.elementsByTagName('layer-tree-layer')
         for j in xrange(0, tree_layer_nodes.count()):
             layer_node = tree_layer_nodes.at(j)
             layer_elem = layer_node.toElement()
             if old_id == layer_elem.attribute('id'):
                 layer_node.toElement().setAttribute('id', new_id)
     layer_tree_elem = doc.documentElement().firstChildElement('layer-tree-group')
     load_in_legend = True
     if not layer_tree_elem.isNull():
         root.readChildrenFromXML(layer_tree_elem)
         load_in_legend = False
     layers = QgsMapLayer.fromLayerDefinition(doc)
     QgsMapLayerRegistry.instance().addMapLayers(layers, load_in_legend)
     nodes = root.children()
     for node in nodes:
         root.takeChild(node)
     del root
     root_group.insertChildNodes(-1, nodes)
     return None
    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())
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()
Esempio n. 28
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
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()
  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 fusionnerJointure(self, cheminCompletParcelle, jointureChoisie):
        """ Selon les tables déja ouverte dans le projet : ouverture si necessaire des différents cas de délimiteurs
            Jointure par QGIS """
        # Vérification du projet ouverte
        monProjet = QgsProject.instance()
        if monProjet.fileName() == None or monProjet.fileName() == "":
            monPrint("Projet en cours de création", T_WAR)
        else:
            monPrint("Projet ouvert {}".format(monProjet.fileName()))

        root = monProjet.layerTreeRoot()
        # Création du groupe jointure_date
        dateMaintenant = datetime.now()
        nomGroupe = MonParcellaire_JOI + " du " + dateMaintenant.strftime(
            "%d %b à %Hh%M:%S")
        temporaireGroupe = QgsLayerTreeGroup(nomGroupe)
        # Positionner en haut de root
        root.addChildNode(temporaireGroupe)
        nouveauGroupe = temporaireGroupe.clone()
        root.insertChildNode(0, nouveauGroupe)
        root.removeChildNode(temporaireGroupe)

        # Ouverture du vecteur parcelle
        parcelle = QgsVectorLayer(
            cheminCompletParcelle,
            MonParcellaire_PAR + SEP_U + MonParcellaire_JOI, 'ogr')
        monProjet.addMapLayer(parcelle, False)
        nouveauGroupe.addLayer(parcelle)

        # Recherche delimiteur
        delimiteur, csv, nomCsv = self.rechercherDelimiteurJointure(
            jointureChoisie, "No Pandas")
        nomCourtJointure = os.path.basename(jointureChoisie)

        monPrint(
            "Délimiteur identifié {0} pour {1}".format(delimiteur,
                                                       nomCourtJointure), T_OK)
        monProjet.addMapLayer(csv, False)
        nouveauGroupe.addLayer(csv)

        # Jointure
        attributsSelectionnes = self.AttributsAJoindre_listWidget.selectedItems(
        )
        attributsAJoindre = []
        for positionAttribut in range(len(attributsSelectionnes)):
            attributsAJoindre.append(
                str(self.AttributsAJoindre_listWidget.selectedItems()
                    [positionAttribut].text()))
        #monPrint( "Attributs à joindre {}".format( attributsAJoindre))
        # Liste des champs dans csv
        nomColonnes, _ = self.lireAttributsJointure(jointureChoisie)
        attributsAJoindreOrdonne = []
        for col in nomColonnes:
            if col in attributsAJoindre:
                if col != MonParcellaireNomAttribut:
                    attributsAJoindreOrdonne.append(col)
        #monPrint( "Attributs à joindre ordonné {}".format( attributsAJoindreOrdonne))

        champVecteur = MonParcellaireNomAttribut
        maJointure = QgsVectorLayerJoinInfo()
        champCsv = self.AttributJointure_comboBox.currentText()
        maJointure.setJoinFieldName(champCsv)
        maJointure.setTargetFieldName(champVecteur)
        maJointure.setUsingMemoryCache(True)
        maJointure.setPrefix("")
        maJointure.setJoinLayer(csv)
        # Récupérer les champs de jointure
        maJointure.setJoinFieldNamesSubset(attributsAJoindreOrdonne)
        parcelle.addJoin(maJointure)
        return jointureChoisie, attributsAJoindreOrdonne
Esempio n. 32
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()
Esempio n. 33
0
    def getDataButtonClicked(self):
        clId = self.leClientID.text()
        clSecret = self.leClientSecret.text()

        if len(clId) == 0 or len(clSecret) == 0:
            self._show_message("Некорректные данные", "Данные пользователя не могут быть пустыми")
            return

        dateTimeFrom = self.dateTimeEditFrom.dateTime()
        dateTimeTo = self.dateTimeEditTo.dateTime()
        if dateTimeFrom >= dateTimeTo:
            self._show_message("Некорректные данные", "Дата 'По' должна быть больше, чем дата 'С'")
            return

        pjt = QgsProject.instance()
        # clear results
        layersList = pjt.mapLayersByName(self.resultsLayerName)
        if layersList is not None and len(layersList) > 0:
            pjt.removeMapLayer(layersList[0])
            self.iface.mapCanvas().refresh()

        layersList = pjt.mapLayersByName(self.searchAreaLayerName)

        polygonGeometry = None
        if layersList is not None and len(layersList) > 0:
            feat = list(layersList[0].getFeatures())[0]
            if feat.hasGeometry():
                polygonGeometry = self.geomTransform(
                    feat.geometry(),
                    self.iface.mapCanvas().mapSettings().destinationCrs(),
                    QgsCoordinateReferenceSystem(4326))

        if polygonGeometry is None:
            self._show_message("Некорректные данные", "Необходимо задать полигон поиска")
            return

        availableAreaName = "available_area"
        shpLayer = QgsVectorLayer(os.path.dirname(__file__) + "/roi/ZRV.shp", availableAreaName, "ogr")
        if not shpLayer.isValid():
            self._show_message("Некорректные данные", "Некорректный файл с зоной охвата")
            return
        intersectionGeom = None
        for feature in shpLayer.getFeatures():
            if feature.geometry().intersects(polygonGeometry):
                intersectionGeom = feature.geometry().intersection(polygonGeometry)

        if intersectionGeom == None:
            layersList = pjt.mapLayersByName(availableAreaName)
            if layersList is not None and len(layersList) > 0:
                pjt.removeMapLayer(layersList[0])

            symbols = shpLayer.renderer().symbols(QgsRenderContext())
            symbols[0].setColor(QColor(76, 205, 53, 84))
            pjt.addMapLayer(shpLayer, False)
            if pjt.layerTreeRoot().findGroup(self.tr(self.groupName)) is None:
                pjt.layerTreeRoot().insertChildNode(0, QgsLayerTreeGroup(self.tr(self.groupName)))
            group = pjt.layerTreeRoot().findGroup(self.tr(self.groupName))
            group.addLayer(shpLayer)
            self.iface.layerTreeView().refreshLayerSymbology(shpLayer.id())
            geom = self.geomTransform(
                list(shpLayer.getFeatures())[0].geometry(),
                QgsCoordinateReferenceSystem(4326),
                self.iface.mapCanvas().mapSettings().destinationCrs())
            self.iface.mapCanvas().setExtent(geom.boundingBox())
            self.iface.mapCanvas().refresh()

            self._show_message("Некорректные данные", "Полигон поиска лежит за пределами зоны охвата")
            return

        self.polygon = intersectionGeom.asWkt()
        # print("polygon=", self.polygon)

        self.__toggle(False, True)
        self.getDataButton.setEnabled(False)
        QApplication.setOverrideCursor(Qt.WaitCursor)
        self.__show_status_label(StatusMessageType.LOAD_STARTED)
        self.dataRequest.dataRequest(clId, clSecret, dateTimeFrom, dateTimeTo, self.polygon)
Esempio n. 34
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
Esempio n. 35
0
    def showRequestResult(self, items, append, last, message):
        # print("showRequestResult")
        if items is None or len(items) == 0:
            QApplication.restoreOverrideCursor()
            self.__show_status_label(StatusMessageType.LOAD_FINISHED)
            self.getDataButton.setEnabled(True)

            if message is None or len(message) == 0:
                message = "По указанным параметрам ничего не найдено"

            self._show_message(self, "Загузка завершена", message)
            return

        color = QColor(237, 28, 36, 200)
        pjt = QgsProject.instance()
        layersList = pjt.mapLayersByName(self.resultsLayerName)

        if not append:
            if layersList is not None and len(layersList) > 0:
                pjt.removeMapLayer(layersList[0])
                # print("remove results")
            layersList.clear()
        if not append or layersList is None or len(layersList) == 0:
            # print("create layer")
            layer = QgsVectorLayer("Point?crs=EPSG:4326"
                                   "&field=coordinatesWKT:string(255)&field=shootingDateTime:string(255)"
                                   "&field=temperature:double(7)&field=pixelSizeInDirection:double(5)"
                                   "&field=pixelSizeAcross:double(5)&field=thermalPower:double(5)"
                                   "&field=baseResourceId:string(255)&field=id:string(255)&field=updated:string(255)"
                                   "&field=satellite:string(10)",
                                   self.resultsLayerName, "memory")
        else:
            layer = layersList[0]

        symbol = QgsSymbol.defaultSymbol(layer.geometryType())
        svg_marker = QgsSvgMarkerSymbolLayer(":/plugins/thermal_anomaly/fire.svg")
        svg_marker.setSize(6.0)
        symbol.changeSymbolLayer(0, svg_marker)
        layer.renderer().setSymbol(symbol)

        layer.startEditing()
        print("all items=", len(items))
        poly = QgsGeometry.fromWkt(self.polygon)

        for point in items:
            symbols = layer.renderer().symbols(QgsRenderContext())  # todo which context ?
            symbols[0].setColor(color)
            feature = QgsFeature()
            coord = QgsGeometry.fromWkt(point["coordinatesWKT"])
            feature.setGeometry(coord)
            feature.setAttributes([point["coordinatesWKT"], point["shootingDateTime"], point["temperature"],
                                   point["pixelSizeInDirection"], point["pixelSizeAcross"], point["thermalPower"],
                                   point["baseResourceId"], point["id"], point["updated"], point["satellite"]])
            layer.dataProvider().addFeatures([feature])

            # if not poly.contains(coord):
            #     print("point out of poly: id =", point["id"], "coord =", point["coordinatesWKT"])
        layer.commitChanges()

        if not append:
            pjt.addMapLayer(layer, False)
            if pjt.layerTreeRoot().findGroup(self.tr(self.groupName)) is None:
                pjt.layerTreeRoot().insertChildNode(0, QgsLayerTreeGroup(self.tr(self.groupName)))
            group = pjt.layerTreeRoot().findGroup(self.tr(self.groupName))
            group.insertLayer(0, layer)
        self.iface.layerTreeView().refreshLayerSymbology(layer.id())
        self.iface.mapCanvas().refresh()
        if last:
            QApplication.restoreOverrideCursor()
            self.__show_status_label(StatusMessageType.LOAD_FINISHED)
            self.getDataButton.setEnabled(True)
        else:
            self.__show_status_label(StatusMessageType.LOAD_STARTED, message)
Esempio n. 36
0
    def draw(self):
        rb = self.tool.rb
        g = rb.asGeometry()

        ok = True
        warning = False
        errBuffer_noAtt = False
        errBuffer_Vertices = False

        layer = self.iface.layerTreeView().currentLayer()
        if self.toolname == 'drawBuffer':
            if self.bGeom is None:
                warning = True
                errBuffer_noAtt = True
            else:
                perim, ok = QInputDialog.getDouble(
                    self.iface.mainWindow(),
                    self.tr('Perimeter'),
                    self.tr('Give a perimeter in m:') + '\n' +
                    self.tr('(works only with metric crs)'),
                    min=0)
                g = self.bGeom.buffer(perim, 40)
                rb.setToGeometry(
                    g,
                    QgsVectorLayer("Polygon?crs=" + layer.crs().authid(), "",
                                   "memory"))
                if g.length() == 0 and ok:
                    warning = True
                    errBuffer_Vertices = True

        if self.toolname == 'drawCopies':
            if g.length() < 0:
                warning = True
                errBuffer_noAtt = True

        if ok and not warning:
            name = ''
            ok = True
            add = False
            index = 0
            layers = []
            while not name.strip() and not add and ok:
                dlg = QDrawLayerDialog(self.iface, self.drawShape)
                name, add, index, layers, ok = dlg.getName(
                    self.iface, self.drawShape)
        if ok and not warning:
            layer = None
            if add:
                layer = layers[index]
                if self.drawShape in ['point', 'XYpoint']:
                    g = g.centroid()
            else:
                if self.drawShape == 'point':
                    layer = QgsVectorLayer(
                        "Point?crs=" + self.iface.mapCanvas().mapSettings(
                        ).destinationCrs().authid() + "&field=" +
                        self.tr('Drawings') + ":string(255)", name, "memory")
                    g = g.centroid()  # force geometry as point
                elif self.drawShape == 'XYpoint':
                    layer = QgsVectorLayer(
                        "Point?crs=" + self.XYcrs.authid() + "&field=" +
                        self.tr('Drawings') + ":string(255)", name, "memory")
                    g = g.centroid()
                elif self.drawShape == 'line':
                    layer = QgsVectorLayer(
                        "LineString?crs=" + self.iface.mapCanvas().mapSettings(
                        ).destinationCrs().authid() + "&field=" +
                        self.tr('Drawings') + ":string(255)", name, "memory")
                    # fix_print_with_import
                    print("LineString?crs=" + self.iface.mapCanvas(
                    ).mapSettings().destinationCrs().authid() + "&field=" +
                          self.tr('Drawings') + ":string(255)")
                else:
                    layer = QgsVectorLayer(
                        "Polygon?crs=" + self.iface.mapCanvas().mapSettings(
                        ).destinationCrs().authid() + "&field=" +
                        self.tr('Drawings') + ":string(255)", name, "memory")
            layer.startEditing()
            symbols = layer.renderer().symbols(
                QgsRenderContext())  # todo which context ?
            symbols[0].setColor(self.settings.getColor())
            feature = QgsFeature()
            feature.setGeometry(g)
            feature.setAttributes([name])
            layer.dataProvider().addFeatures([feature])
            layer.commitChanges()
            if not add:
                pjt = QgsProject.instance()
                pjt.addMapLayer(layer, False)
                if pjt.layerTreeRoot().findGroup(self.tr('Drawings')) is None:
                    pjt.layerTreeRoot().insertChildNode(
                        0, QgsLayerTreeGroup(self.tr('Drawings')))
                group = pjt.layerTreeRoot().findGroup(self.tr('Drawings'))
                group.insertLayer(0, layer)
            self.iface.layerTreeView().refreshLayerSymbology(layer.id())
            self.iface.mapCanvas().refresh()
        else:
            if warning:
                if errBuffer_noAtt:
                    self.iface.messageBar().pushWarning(
                        self.tr('Warning'),
                        self.tr('You didn\'t click on a layer\'s attribute !'))
                elif errBuffer_Vertices:
                    self.iface.messageBar().pushWarning(
                        self.tr('Warning'),
                        self.tr('You must give a non-null value for a \
                        point\'s or line\'s perimeter !'))
                else:
                    self.iface.messageBar().pushWarning(
                        self.tr('Warning'),
                        self.tr('There is no selected layer, or it is not \
                                vector nor visible !'))
        self.tool.reset()
        self.resetSB()
        self.bGeom = None