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)
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
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)
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
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
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()
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
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
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
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))
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)
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
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
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)
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])
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())
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
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
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])
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
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)
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
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
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']
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()
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
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()
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)
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
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)
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