Пример #1
0
    def testSaveFields(self):
        # Create a new memory layer with no fields
        myMemoryLayer = QgsVectorLayer(('Point?crs=epsg:4326&index=yes'),
                                       'test', 'memory')

        # Add some fields to the layer
        myFields = [
            QgsField('TestInt', QVariant.Int, 'integer', 2, 0),
            QgsField('TestDbl', QVariant.Double, 'double', 8, 6),
            QgsField('TestString', QVariant.String, 'string', 50, 0),
            QgsField('TestDate', QVariant.Date, 'date'),
            QgsField('TestTime', QVariant.Time, 'time'),
            QgsField('TestDateTime', QVariant.DateTime, 'datetime')
        ]
        assert myMemoryLayer.startEditing()
        for f in myFields:
            assert myMemoryLayer.addAttribute(f)
        assert myMemoryLayer.commitChanges()
        myMemoryLayer.updateFields()

        # Export the layer to a layer-definition-XML
        qlr = QgsMapLayer.asLayerDefinition([myMemoryLayer])
        assert qlr is not None

        # Import the layer from the layer-definition-XML
        layers = QgsMapLayer.fromLayerDefinition(qlr)
        assert layers is not None
        myImportedLayer = layers[0]
        assert myImportedLayer is not None

        # Check for the presence of the fields
        importedFields = myImportedLayer.fields()
        assert importedFields is not None
        for f in myFields:
            assert f == importedFields.field(f.name())
Пример #2
0
def add_layer(layer: QgsMapLayer,
              name: str = None,
              index: int = -1,
              color: typing.Tuple[int, int, int] = None,
              size: float = None,
              file: str = None,
              parent: QgsLayerTreeNode = None,
              show_feature_count: bool = True) -> None:
    if name:
        layer.setName(name)

    if isinstance(layer, QgsVectorLayer):
        if color or size or file:
            update_symbology(layer, color=color, size=size, file=file)
    elif isinstance(layer, QgsRasterLayer):
        # TODO update symbology
        pass

    instance = QgsProject.instance()
    instance.addMapLayer(layer, False)

    layerTreeNode = QgsLayerTreeLayer(layer)
    layerTreeNode.setCustomProperty('showFeatureCount', show_feature_count)

    parent = parent if parent else instance.layerTreeRoot()
    parent.insertChildNode(index, layerTreeNode)
Пример #3
0
    def testSaveFields(self):
        # Create a new memory layer with no fields
        myMemoryLayer = QgsVectorLayer(
            ('Point?crs=epsg:4326&index=yes'),
            'test',
            'memory')

        # Add some fields to the layer
        myFields = [QgsField('TestInt', QVariant.Int, 'integer', 2, 0),
                    QgsField('TestDbl', QVariant.Double, 'double', 8, 6),
                    QgsField('TestString', QVariant.String, 'string', 50, 0),
                    QgsField('TestDate', QVariant.Date, 'date'),
                    QgsField('TestTime', QVariant.Time, 'time'),
                    QgsField('TestDateTime', QVariant.DateTime, 'datetime')]
        assert myMemoryLayer.startEditing()
        for f in myFields:
            assert myMemoryLayer.addAttribute(f)
        assert myMemoryLayer.commitChanges()
        myMemoryLayer.updateFields()

        # Export the layer to a layer-definition-XML
        qlr = QgsMapLayer.asLayerDefinition([myMemoryLayer])
        assert qlr is not None

        # Import the layer from the layer-definition-XML
        layers = QgsMapLayer.fromLayerDefinition(qlr)
        assert layers is not None
        myImportedLayer = layers[0]
        assert myImportedLayer is not None

        # Check for the presence of the fields
        importedFields = myImportedLayer.fields()
        assert importedFields is not None
        for f in myFields:
            assert f == importedFields.field(f.name())
Пример #4
0
    def startConvert(self, layer: QgsMapLayer):

        layerName = layer.name()
        nodeCoorDict = OrderedDict()
        graph = nx.Graph()
        if layerName:
            features = layer.getFeatures()
            count = 0
            for feature in features:
                if count > 10:
                    break
                geom = feature.geometry()
                geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
                if geom.type() == QgsWkbTypes.PolygonGeometry:
                    if geomSingleType:
                        polygon = geom.asPolygon()
                    else:
                        multiPolygon = geom.asMultiPolygon()
                        for polygon in multiPolygon:
                            nodeCoorDict = self.parsePolygon2Network(
                                polygon, nodeCoorDict, graph)
                count = count + 1
        '''
        plt.subplot(121)
        nx.draw(graph, with_labels=True, font_weight='bold')
        plt.show()
        '''
        return nodeCoorDict
Пример #5
0
    def testSaveFields(self):
        # Create a new memory layer with no fields
        myMemoryLayer = QgsVectorLayer(("Point?crs=epsg:4326&index=yes"), "test", "memory")

        # Add some fields to the layer
        myFields = [
            QgsField("TestInt", QVariant.Int, "integer", 2, 0),
            QgsField("TestLong", QVariant.LongLong, "long", -1, 0),
            QgsField("TestDbl", QVariant.Double, "double", 8, 6),
            QgsField("TestString", QVariant.String, "string", 50, 0),
            QgsField("TestDate", QVariant.Date, "date"),
            QgsField("TestTime", QVariant.Time, "time"),
            QgsField("TestDateTime", QVariant.DateTime, "datetime"),
        ]
        assert myMemoryLayer.startEditing()
        for f in myFields:
            assert myMemoryLayer.addAttribute(f)
        assert myMemoryLayer.commitChanges()
        myMemoryLayer.updateFields()

        # Export the layer to a layer-definition-XML
        qlr = QgsMapLayer.asLayerDefinition([myMemoryLayer])
        assert qlr is not None

        # Import the layer from the layer-definition-XML
        layers = QgsMapLayer.fromLayerDefinition(qlr)
        assert layers is not None
        myImportedLayer = layers[0]
        assert myImportedLayer is not None

        # Check for the presence of the fields
        importedFields = myImportedLayer.fields()
        assert importedFields is not None
        for f in myFields:
            assert f == importedFields.field(f.name())
Пример #6
0
    def get_centroid_from_polygon(layerName):
        """Getting centroid from the polygon."""
        layerName = "INTERIOR"
        layer = QgsMapLayer.instance().mapLayersByName(layerName)[0]
        print("layer.name---->", layer.name())

        epsg = layer.crs().postgisSrid()

        uri = "Point?crs=epsg:" + str(epsg) + "&field=id:integer" "&index=yes"

        mem_layer = QgsVectorLayer(uri, 'point', 'memory')

        prov = mem_layer.dataProvider()

        i = 0

        for f in layer.getFeatures():
            feat = QgsFeature()
            pt = f.geometry().centroid().asPoint()
            print("pt---->", pt)
            feat.setAttributes([i])
            feat.setGeometry(QgsGeometry.fromPoint(pt))
            prov.addFeatures([feat])
            i += 1

        QgsMapLayer.instance().addMapLayer(mem_layer)
Пример #7
0
    def fetch_and_apply_style(layer: QgsMapLayer,
                              url: str,
                              style_attr: str = '') -> Optional[str]:
        """
        Fetches a QML style from the specified URL, and applies it to a layer.
        @param layer: target layer to apply style to
        @param url: URL for QML content
        @param style_attr: optional str specifying name of existing field in layer to automatically
        update classified references to
        @return: Returns a str if an error occurred, or None if the fetch and apply was successful
        """
        request = QgsBlockingNetworkRequest()
        if request.get(QNetworkRequest(
                QUrl(url))) != QgsBlockingNetworkRequest.NoError:
            return 'Error while fetching QML style: {}'.format(
                request.errorMessage())

        reply = request.reply().content()
        tmp_file = QTemporaryFile('{}/XXXXXX.qml'.format(QDir.tempPath()))
        tmp_file.open()
        tmp_file_name = tmp_file.fileName()
        tmp_file.close()
        with open(tmp_file_name, 'wt', encoding='utf8') as f:
            f.write(reply.data().decode())

        layer.loadNamedStyle(tmp_file_name)

        if style_attr:
            StyleUtils.update_class_attribute(layer, style_attr)

        layer.triggerRepaint()
        return None
Пример #8
0
 def __init__(self,
              level: Level,
              feedback_result: FeedbackResult,
              layer: QgsMapLayer = None) -> None:
     self.level = level
     self.message = feedback_result.message
     self.layer_id = layer.id() if layer else None
     self.layer_name = layer.name() if layer else None
Пример #9
0
 def layer_summary(layer_id: str, layer: QgsMapLayer):
     return dict(
         id=layer_id,
         name=layer.name(),
         source=layer.publicSource(),
         crs=layer.crs().userFriendlyIdentifier(),
         valid=layer.isValid(),
         spatial=layer.isSpatial(),
     )
Пример #10
0
    def is_compatible_with_layer(self, layer: QgsMapLayer, is_editable: bool):
        if layer is None:
            return False

        if layer.type() != QgsMapLayerType.VectorLayer:
            return False

        return layer.geometryType(
        ) == QgsWkbTypes.PointGeometry and is_editable
def add_report_to_layer(report: typing.Dict, layer: QgsMapLayer):
    history_msg = (f'{report["generated"]} - Validation report: '
                   f'{"Valid" if report["dataset_is_valid"] else "Invalid"}')
    abstract_msg = utils.serialize_report_to_plain_text(report)
    metadata: QgsLayerMetadata = layer.metadata()
    history: typing.List = metadata.history()
    history.append(history_msg)
    abstract: str = metadata.abstract()
    abstract = "\n\n---\n\n".join((abstract, abstract_msg))
    metadata.setAbstract(abstract)
    metadata.setHistory(history)
    layer.setMetadata(metadata)
Пример #12
0
def layer_name_source(layer: QgsMapLayer) -> Tuple[str, str]:
    """
    Returns the name and the source path of the layer.

    :param layer: the layer from which to extract name and source.
    :type layer: QgsMapLayer.
    :return: the layer name and source.
    :rtype: tuple of two strings.

    Examples:
    """

    return layer.name(), layer.source()
Пример #13
0
    def startConvert(self,layer:QgsMapLayer):

        layerName = layer.name()
        nodeCoorDict = OrderedDict()
        graph = nx.Graph()

        if layerName:
            features_forCounts = layer.getFeatures()  # type:QgsFeatureIterator
            # 记录当前处理的polygon id编号
            plyId = 0
            count = 0
            feaNums = sum(1 for _ in features_forCounts)  #此时已经迭代过了

            features = layer.getFeatures()  # type:QgsFeatureIterator
            pbar = self.dlg.progressBar  # type:QProgressBar
            pbar.setRange(0, feaNums)
            print(feaNums)
            for feature in features:
                #if count >= 10:
                #    break
                geom = feature.geometry()
                geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
                if geom.type() == QgsWkbTypes.PolygonGeometry:
                    if geomSingleType:
                        polygon = geom.asPolygon()
                        nodeCoorDict, graph = self.parsePolygon2Network(polygon, nodeCoorDict, graph, plyId=plyId)
                        plyId = plyId + 1
                    else:
                        multiPolygon = geom.asMultiPolygon()
                        for polygon in multiPolygon:
                            nodeCoorDict,graph = self.parsePolygon2Network(polygon,nodeCoorDict,graph,plyId=plyId)
                            plyId = plyId + 1
                pbar.setValue(count)
                count = count + 1
                #print("complete!")
        #plt.subplot(121)
        #print(nodeCoorDict)
        '''
        # 每个节点坐标,绘制带坐标的图
        pos = list(nodeCoorDict.values())
        #nx.draw(graph,pos, with_labels=True)
        nx.draw(graph, pos,node_size=20)
        nx.fruchterman_reingold_layout(graph)
        plt.show()
        '''
        print('all complete')
        pbar.setValue(feaNums)
        return nodeCoorDict,graph,True
    def on_current_layer_changed(self, map_layer: QgsMapLayer) -> None:
        """
        slot for checking selection changes
        :param map_layer:
        :return: Nothing
        """
        if self.__active_layer is not None:
            try:
                self.__active_layer.geometryChanged.disconnect(
                    self.on_geometry_changed)
                self.__active_layer.selectionChanged.disconnect(
                    self.on_active_layer_selection_changed)
            except AttributeError:
                pass
            except TypeError:
                pass

        if (map_layer is None) or (map_layer.type() !=
                                   QgsMapLayer.VectorLayer):
            self.__active_layer = None
        else:
            self.__active_layer = map_layer
            self.__active_layer.geometryChanged.connect(
                self.on_geometry_changed)
            self.__active_layer.selectionChanged.connect(
                self.on_active_layer_selection_changed)

        self._parse_selection()
Пример #15
0
    def enable_actions_for_layer(self,
                                 layer: QgsMapLayer,
                                 forced_edit_state=None):
        """
        Toggles whether actions should be enabled for the specified layer
        """

        is_editable = forced_edit_state
        if is_editable is None:
            if isinstance(layer, QgsVectorLayer):
                is_editable = layer.isEditable()
            else:
                is_editable = False

        for action in self.actions:
            if sip.isdeleted(action):
                continue

            if self.tools.get(action.data()):
                tool = self.tools[action.data()]
                action.setEnabled(
                    tool.is_compatible_with_layer(layer, is_editable))
                if tool == self.active_tool and not action.isEnabled():
                    self.iface.mapCanvas().unsetMapTool(tool)
                    self.iface.actionPan().trigger()
Пример #16
0
def update_symbology(layer: QgsMapLayer,
                     color: typing.Tuple[int, int, int] = None,
                     size: float = None,
                     file: str = None) -> None:
    assert layer, 'Layer is not defined'

    if file:
        assert isinstance(file, str)

        (msg, noError) = layer.loadNamedStyle(file)

        if not noError:
            raise Exception(msg)

    renderer = layer.renderer()

    symbol = None

    if isinstance(renderer, QgsSingleSymbolRenderer):
        symbol = renderer.symbol()
    elif isinstance(renderer, QgsGraduatedSymbolRenderer):
        symbol = renderer.sourceSymbol()
    else:
        raise Exception('Unknown renderer!')

    if color:
        assert isinstance(
            color, collections.abc.Sequence
        ), 'Color should be a iteratable of three numbers for Red, Green, Blue; Each of them between 0 and 255'
        assert len(color) in (
            3, 4
        ), 'There should be three numbers passed for Red, Green, Blue; Each of them between 0 and 255'

        symbol.setColor(QColor.fromRgb(*color))

    if size:
        # For lines
        if type(symbol) == QgsLineSymbol:
            symbol.setWidth(size)

        # For points
        if type(symbol) == QgsMarkerSymbol:
            symbol.setSize(size)

        layer.triggerRepaint()
        iface.layerTreeView().refreshLayerSymbology(layer.id())
Пример #17
0
    def print_layer_name(self, layer: QgsMapLayer):

        try:
            LOGGER.info(tr("Printing layer name"),
                        extra=bar_msg(tr("Layer name is {}", layer.name())))
        except:
            raise QgsPluginException("Error occured",
                                     bar_msg("Select layer first!"))
Пример #18
0
    def check_layer_is_geopackage(layer: QgsMapLayer) -> Tuple[bool, str]:

        if not layer:
            return False, 'La couche est invalide'

        testing = os.environ.get('TESTING_MERCICOR', '')
        if testing == 'True':
            return True, ''

        uri = QgsProviderRegistry.instance().decodeUri('ogr', layer.source())
        if not uri['path'].lower().endswith('.gpkg') or not uri['layerName']:
            message = (
                'La couche doit être le geopackage de la zone d\'étude et non pas {}'
                .format(layer.source()))
            return False, message

        return True, ''
Пример #19
0
    def addLayers(self, layers):
        """Handle layers being added to the registry so they show up in canvas.

        :param layers: list<QgsMapLayer> list of map layers that were added

        .. note:: The QgsInterface api does not include this method,
            it is added here as a helper to facilitate testing.
        """
        #LOGGER.debug('addLayers called on qgis_interface')
        #LOGGER.debug('Number of layers being added: %s' % len(layers))
        #LOGGER.debug('Layer Count Before: %s' % len(self.canvas.layers()))
        current_layers = self.canvas.layers()
        final_layers = []
        for layer in current_layers:
            final_layers.append(QgsMapLayer(layer))
        for layer in layers:
            final_layers.append(QgsMapLayer(layer))

        self.canvas.setLayerSet(final_layers)
Пример #20
0
def getConnectionParameterFromDbLayer(layer: QgsMapLayer) -> Dict[str,str]:
    '''
    Get connection parameters
    from the layer datasource
    '''
    connectionParams = None

    if layer.providerType() == 'postgres':
        dbType = 'postgis'
    else:
        dbType = 'spatialite'

    src = layer.source()
    try:
        uri = QgsDataSourceUri(src)
    except:
        uri = QgsDataSourceURI(src)

    # TODO Use immutable namedtuple
    connectionParams = {
        'service' : uri.service(),
        'dbname' : uri.database(),
        'host' : uri.host(),
        'port': uri.port(),
        'user' : uri.username(),
        'password': uri.password(),
        'sslmode' : uri.sslMode(),
        'key': uri.keyColumn(),
        'estimatedmetadata' : str(uri.useEstimatedMetadata()),
        'checkPrimaryKeyUnicity' : '',
        'srid' : uri.srid(),
        'type': uri.wkbType(),
        'schema': uri.schema(),
        'table' : uri.table(),
        'geocol' : uri.geometryColumn(),
        'sql' : uri.sql(),
        'dbType': dbType
    }

    return connectionParams
Пример #21
0
def layer_from_source(source_uri, name):
    """Return QgsMapLayer from a given source uri.

    :param source_uri: A source URI
    :type source_uri: basestring

    :param name: Designated layer name
    :type name: basestring

    :return: QgsMapLayer
    :rtype: qgis.core.QgsMapLayer
    """
    vector_extensions = ('shp', 'geojson')
    raster_extensions = ('asc', 'tiff', 'tif', 'geotiff', 'geotif')
    qlr_extensions = ('qlr', )

    qgis_layer = None

    if is_file_path(source_uri):

        # sanitize source_uri
        sanitized_uri = urllib.unquote(source_uri).decode('utf-8')
        sanitized_uri.replace('file://', '')

        if source_uri.endswith(vector_extensions):
            qgis_layer = QgsVectorLayer(sanitized_uri, name, 'ogr')

        elif source_uri.endswith(raster_extensions):
            qgis_layer = QgsRasterLayer(sanitized_uri, name)

        elif source_uri.endswith(qlr_extensions):

            qgis_layer = QgsMapLayer.fromLayerDefinitionFile(sanitized_uri)
            if qgis_layer:
                qgis_layer = qgis_layer[0]
                qgis_layer.setName(name)

    elif is_tile_path(source_uri):

        # sanitize source_uri
        sanitized_uri = urllib.unquote(source_uri).decode('utf-8')
        # Check if it is only a url
        if sanitized_uri.startswith(('http://', 'https://')):
            # Then it is probably a tile xyz url
            sanitized_uri = 'type=xyz&url={0}'.format(sanitized_uri)
        # It might be in the form of query string
        query_params = urlparse.parse_qs(sanitized_uri)
        driver = query_params.get('driver', 'wms')

        qgis_layer = QgsRasterLayer(sanitized_uri, name, driver)

    return qgis_layer
Пример #22
0
def _set_output_layer_style(layerName: str, layer: QgsMapLayer,
                            alg: QgsProcessingAlgorithm,
                            details: 'QgsProcessingContext::LayerDetails',
                            context: QgsProcessingContext, parameters) -> None:
    """ Set layer style 

        Original code is from python/plugins/processing/gui/Postprocessing.py
    """
    '''If running a model, the execution will arrive here when an algorithm that is part of
    that model is executed. We check if its output is a final otuput of the model, and
    adapt the output name accordingly'''
    outputName = details.outputName
    if parameters:
        expcontext = QgsExpressionContext()
        scope = QgsExpressionContextScope()
        expcontext.appendScope(scope)
        for out in alg.outputDefinitions():
            if out.name() not in parameters:
                continue
            outValue = parameters[out.name()]
            if hasattr(outValue, "sink"):
                outValue = outValue.sink.valueAsString(expcontext)[0]
            else:
                outValue = str(outValue)
            if outValue == layerName:
                outputName = out.name()
                break

    style = None
    if outputName:
        # If a style with the same name as the outputName exists
        # in workdir then use it
        style = os.path.join(context.workdir, outputName + '.qml')
        if not os.path.exists(style):
            style = RenderingStyles.getStyle(alg.id(), outputName)
        LOGGER.debug("Getting style for %s: %s <%s>", alg.id(), outputName,
                     style)

    # Get defaults styles
    if style is None:
        if layer.type() == QgsMapLayer.RasterLayer:
            style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE)
        else:
            if layer.geometryType() == QgsWkbTypes.PointGeometry:
                style = ProcessingConfig.getSetting(
                    ProcessingConfig.VECTOR_POINT_STYLE)
            elif layer.geometryType() == QgsWkbTypes.LineGeometry:
                style = ProcessingConfig.getSetting(
                    ProcessingConfig.VECTOR_LINE_STYLE)
            else:
                style = ProcessingConfig.getSetting(
                    ProcessingConfig.VECTOR_POLYGON_STYLE)
    if style:
        LOGGER.debug("Adding style '%s' to layer %s (outputName %s)", style,
                     details.name, outputName)
        layer.loadNamedStyle(style)

    LOGGER.debug("Layer name set to %s <details name: %s>", layer.name(),
                 details.name)
Пример #23
0
def create_default_project(available_maps, visible_maps, project_template, authcfg=None):
    """Create a default project from a template and return it as a string"""
    layers = []
    for m in available_maps:
        connstring = u'type=xyz&url=%(url)s'
        if authcfg is not None:
            connstring = u'authcfg=%(authcfg)s&' + connstring
        layer = QgsRasterLayer(connstring % {
            'url': quote(m['endpoint']),
            'authcfg': authcfg,
        }, m['name'], 'wms')
        # I've no idea why the following is required even if the crs is specified 
        # in the layer definition
        layer.setCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        layers.append(layer)
    if len(layers):
        xml = QgsMapLayer.asLayerDefinition(layers)
        maplayers = "\n".join(xml.toString().split("\n")[3:-3])
        layer_tree_layer = ""
        custom_order = ""
        legend_layer = ""
        layer_coordinate_transform = ""
        for layer in layers:
            is_visible = layer.name() in visible_maps
            values = {'name': layer.name(), 'id': layer.id(), 'visible': ('1' if is_visible else '0'), 'checked': ('Qt::Checked' if is_visible else 'Qt::Unchecked')}
            custom_order += "<item>%s</item>" % layer.id()
            layer_tree_layer += """
            <layer-tree-layer expanded="1" checked="%(checked)s" id="%(id)s" name="%(name)s">
                <customproperties/>
            </layer-tree-layer>""" % values
            legend_layer += """
            <legendlayer drawingOrder="-1" open="true" checked="%(checked)s" name="%(name)s" showFeatureCount="0">
              <filegroup open="true" hidden="false">
                <legendlayerfile isInOverview="0" layerid="%(id)s" visible="%(visible)s"/>
              </filegroup>
            </legendlayer>""" % values
            layer_coordinate_transform += '<layer_coordinate_transform destAuthId="EPSG:3857" srcAuthId="EPSG:3857" srcDatumTransform="-1" destDatumTransform="-1" layerid="%s"/>' % layer.id()
        tpl = ""
        with open(project_template, 'rb') as f:
            tpl = f.read()
        for tag in ['custom_order', 'layer_tree_layer', 'legend_layer', 'layer_coordinate_transform', 'maplayers']:
            tpl = tpl.replace("#%s#" % tag.upper(), locals()[tag])
        return tpl
    else:
        return None
def createDefaultProject(available_maps, visible_maps, project_template, authcfg=None):
    """Create a default project from a template and return it as a string"""
    layers = []
    for m in available_maps:
        connstring = u'type=xyz&url={url}'
        if authcfg is not None:
            connstring = u'authcfg={authcfg}&' + connstring
        layer = QgsRasterLayer(connstring.format(url=urllib2.quote("{}?version={}".format(m['endpoint'], pluginSetting("apiVersion"))),
                                                 authcfg=authcfg), m['name'], "wms")
        # I've no idea why the following is required even if the crs is specified
        # in the layer definition
        layer.setCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        layers.append(layer)
    if len(layers):
        xml = QgsMapLayer.asLayerDefinition(layers)
        maplayers = "\n".join(xml.toString().split("\n")[3:-3])
        layer_tree_layer = ""
        custom_order = ""
        legend_layer = ""
        layer_coordinate_transform = ""
        for layer in layers:
            is_visible = layer.name() in visible_maps
            values = {'name': layer.name(), 'id': layer.id(), 'visible': ('1' if is_visible else '0'), 'checked': ('Qt::Checked' if is_visible else 'Qt::Unchecked')}
            custom_order += "<item>%s</item>" % layer.id()
            layer_tree_layer += """
            <layer-tree-layer expanded="1" checked="%(checked)s" id="%(id)s" name="%(name)s">
                <customproperties/>
            </layer-tree-layer>""" % values
            legend_layer += """
            <legendlayer drawingOrder="-1" open="true" checked="%(checked)s" name="%(name)s" showFeatureCount="0">
              <filegroup open="true" hidden="false">
                <legendlayerfile isInOverview="0" layerid="%(id)s" visible="%(visible)s"/>
              </filegroup>
            </legendlayer>""" % values
            layer_coordinate_transform += '<layer_coordinate_transform destAuthId="EPSG:3857" srcAuthId="EPSG:3857" srcDatumTransform="-1" destDatumTransform="-1" layerid="%s"/>' % layer.id()
        tpl = ""
        with open(project_template, 'rb') as f:
            tpl = f.read()
        for tag in ['custom_order', 'layer_tree_layer', 'legend_layer', 'layer_coordinate_transform', 'maplayers']:
            tpl = tpl.replace("#%s#" % tag.upper(), locals()[tag])
        return tpl
    else:
        return None
Пример #25
0
 def __add_layer_definition_file(self, file_name, root_group):
     """
     shamelessly copied from
     https://github.com/qgis/QGIS/blob/master/src/core/qgslayerdefinition.cpp
     """
     qfile = QFile(file_name)
     if not qfile.open(QIODevice.ReadOnly):
         return None
     doc = QDomDocument()
     if not doc.setContent(qfile):
         return None
     file_info = QFileInfo(qfile)
     QDir.setCurrent(file_info.absoluteDir().path())
     root = QgsLayerTreeGroup()
     ids = doc.elementsByTagName('id')
     for i in 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
Пример #26
0
def add_layer_metadata(map_layer: qgc.QgsMapLayer, layer_cfg: Layer) -> None:
    """Add layer metadata.

    Renders a jinja template to a temporary file location as a valid QGIS qmd
    metadata file. This metadata then gets associated with the `map_layer` using
    its `loadNamedMetadata` method. This metadata gets written to the project
    file when the layer is added to the `project`.
    """
    qmd_template = load_template('metadata.jinja')

    # Set the layer's tooltip
    tooltip = _build_layer_tooltip(layer_cfg)
    map_layer.setAbstract(tooltip)

    # Render the qmd template.
    abstract = escape(build_layer_metadata(layer_cfg))
    layer_extent = map_layer.extent()
    layer_crs = map_layer.crs()

    if layer_cfg.steps:
        provenance_list = [escape(step.provenance) for step in layer_cfg.steps]
    else:
        provenance_list = []

    rendered_qmd = qmd_template.render(
        provenance_list=provenance_list,
        abstract=abstract,
        title=layer_cfg.title,
        crs_proj4_str=layer_crs.toProj4(),
        crs_srsid=layer_crs.srsid(),
        crs_postgres_srid=layer_crs.postgisSrid(),
        crs_authid=layer_crs.authid(),
        crs_description=layer_crs.description(),
        crs_projection_acronym=layer_crs.projectionAcronym(),
        crs_ellipsoid_acronym=layer_crs.ellipsoidAcronym(),
        minx=layer_extent.xMinimum(),
        miny=layer_extent.yMinimum(),
        maxx=layer_extent.xMaximum(),
        maxy=layer_extent.yMaximum(),
    )

    # Write the rendered tempalte to a temporary file
    # location. `map_layer.loadNamedMetadata` expects a string URI corresponding
    # to a file on disk.
    with tempfile.NamedTemporaryFile('w') as temp_file:
        temp_file.write(rendered_qmd)
        temp_file.flush()
        map_layer.loadNamedMetadata(temp_file.name)
Пример #27
0
def load_layers(iface):
    # Load a dictionary of layerId:layer pairs
    layer_dic = QgsProject.instance().layerStore().mapLayers()

    # Filter the vector layers (LayerType(0))
    vec_dic = dict()
    for l in layer_dic:
        if layer_dic[l].type() == QgsMapLayer.LayerType(0):
            vec_dic[l] = layer_dic[l]

    # Further filter those polygon layers (geometryType(2)) which have
    #          at least 1 feature and add them to the drop down menu.
    poly_geom = QgsWkbTypes.GeometryType(2)
    poly_dic = dict()
    poly_ind = []  # Indices are saved here
    for l in vec_dic:
        if vec_dic[l].geometryType() == poly_geom and vec_dic[l].featureCount(
        ) and vec_dic[l].crs().authid() == 'EPSG:31287':
            poly_dic[l] = vec_dic[l]
            poly_ind.append(l)

    return poly_dic, poly_ind
Пример #28
0
    def __getCrs(self,
                 layer: QgsMapLayer = None) -> QgsCoordinateReferenceSystem:
        if layer:
            return layer.sourceCrs()

        return self.project.crs()
Пример #29
0
 def loadQlrs(qlrList):
     for qlr in qlrList:
         lyrs = QgsMapLayer.fromLayerDefinitionFile(qlr)
         QgsMapLayerRegistry.instance().addMapLayers(lyrs)
def addToDefaultProject(maps, visibleMaps, authcfg=None):
    """Add basemaps to the existing default project"""
    layers = []
    for m in maps:
        connstring = u'type=xyz&url={url}'
        if authcfg is not None:
            connstring = u'authcfg={authcfg}&' + connstring
        layer = QgsRasterLayer(connstring.format(url=urllib2.quote("{}?version={}".format(m['endpoint'], pluginSetting("apiVersion"))),
                                                 authcfg=authcfg), m['name'], 'wms')
        # I've no idea why the following is required even if the crs is specified
        # in the layer definition
        layer.setCrs(QgsCoordinateReferenceSystem('EPSG:3857'))
        layers.append(layer)

    if os.path.isfile(defaultProjectPath()):
        backup = defaultProjectPath().replace(
            '.qgs', '-%s.qgs' % datetime.now().strftime('%Y-%m-%d-%H_%M_%S'))
        shutil.copy2(defaultProjectPath(), backup)

   # open default project
    with open(defaultProjectPath()) as f:
        content = f.read()

    doc = QDomDocument()
    setOk, errorString, errorLine, errorColumn = doc.setContent(content)
    if not setOk:
        return False

    root = doc.documentElement()

    for layer in layers:
        is_visible = layer.name() in visibleMaps
        xml = QgsMapLayer.asLayerDefinition([layer])
        r = xml.documentElement()
        mapLayerElement = r.firstChildElement("maplayers").firstChildElement("maplayer")

        layerTreeLayerElement = doc.createElement("layer-tree-layer")
        layerTreeLayerElement.setAttribute("expanded", "1")
        layerTreeLayerElement.setAttribute("checked", "Qt::Checked" if is_visible else "Qt::Unchecked")
        layerTreeLayerElement.setAttribute("id", layer.id())
        layerTreeLayerElement.setAttribute("name", layer.name())

        customPropertiesElement = doc.createElement("customproperties")
        layerTreeLayerElement.appendChild(customPropertiesElement)

        legendLayerElement = doc.createElement("legendlayer")
        legendLayerElement.setAttribute("drawingOrder", "-1")
        legendLayerElement.setAttribute("open", "true")
        legendLayerElement.setAttribute("checked", "Qt::Checked" if is_visible else "Qt::Unchecked")
        legendLayerElement.setAttribute("name", layer.name())
        legendLayerElement.setAttribute("showFeatureCount", "0")

        filegroupElement = doc.createElement("filegroup")
        filegroupElement.setAttribute("open", "true")
        filegroupElement.setAttribute("hidden", "false")

        legendlayerfileElement = doc.createElement("legendlayerfile")
        legendlayerfileElement.setAttribute("isInOverview", "0")
        legendlayerfileElement.setAttribute("layerid", layer.id())
        legendlayerfileElement.setAttribute("visible", "1" if is_visible else "0")

        filegroupElement.appendChild(legendlayerfileElement)
        legendLayerElement.appendChild(filegroupElement)

        crsElement = doc.createElement("layer_coordinate_transform")
        crsElement.setAttribute("destAuthId", "EPSG:3857")
        crsElement.setAttribute("srcAuthId", "EPSG:3857")
        crsElement.setAttribute("srcDatumTransform", "-1")
        crsElement.setAttribute("destDatumTransform", "-1")
        crsElement.setAttribute("layerid", layer.id())

        itemElement = doc.createElement("item")
        text = doc.createTextNode(layer.id())
        itemElement.appendChild(text)

        e = root.firstChildElement("layer-tree-group")
        e.appendChild(layerTreeLayerElement)

        e = root.firstChildElement("mapcanvas").firstChildElement("layer_coordinate_transform_info")
        e.appendChild(crsElement)

        e = root.firstChildElement("layer-tree-canvas").firstChildElement("custom-order")
        e.appendChild(itemElement)

        e = root.firstChildElement("legend")
        e.appendChild(legendLayerElement)

        e = root.firstChildElement("projectlayers")
        e.appendChild(mapLayerElement)

    with open(defaultProjectPath(), "wb+") as f:
        f.write(doc.toString(2))

    settings = QSettings()
    settings.setValue('/qgis/newProjectDefault', True)
    return True
Пример #31
0
 def _allowed_layer(lyr: QgsMapLayer) -> bool:
     return AllowedValue(value=lyr.name(),
                         allowed_type=ALLOWEDVALUETYPE.LAYER)
Пример #32
0
def _load_qml_style(map_layer: qgc.QgsMapLayer, style_path: Path) -> None:
    msg, status = map_layer.loadNamedStyle(str(style_path))

    if not status:
        raise RuntimeError(f"Problem loading '{style_path}': '{msg}'")
Пример #33
0
 def tag_layer_as_stdm_layer(layer: QgsMapLayer):
     """
     Tags a map layer as a STDM sourced layer
     """
     layer.setCustomProperty(LayerUtils.IS_STDM_LAYER_KEY, True)
Пример #34
0
 def is_layer_stdm_layer(layer: QgsMapLayer) -> bool:
     """
     Returns True if the layer is a STDM sourced layer
     """
     return bool(layer.customProperty(LayerUtils.IS_STDM_LAYER_KEY))
Пример #35
0
def add_layer_to_project(layer: QgsMapLayer):
    project = QgsProject.instance()
    layer_candidates = project.mapLayersByName(layer.name())
    if len(layer_candidates) > 0:
        project.removeMapLayers(layer_candidates)
    project.addMapLayer(layer)