def getExtentForLocate(self, sourceRow):
     surfaceLayers = QgisHelper.getSurfaceLayers(self.surfaceType)
     rect = QgsRectangle()
     rect.setMinimal()
     for sfLayer in surfaceLayers:
         rect.combineExtentWith(sfLayer.extent())
     return rect
Exemplo n.º 2
0
    def groupify(self):
        with self.groupAssignmentLock:
            self.layersToBeGrouped = len(self.layerList)
            self.getGeneratedGroup()
            registryAddedLayers = QgsProject.instance().addMapLayers(
                self.layerList, False)
            for item in registryAddedLayers:
                if item not in self.layerList:
                    #print("****WARNING: A LAYER WAS NOT ADDED TO THE REGISTRY: "+str(item)+" --- ID : "+item.id())
                    self.errorCount = self.errorCount + 1
                    pass
            self.correctlyRegisteredLayers = sorted(
                self.layerList, key=lambda layer: layer.name())
            for layer in self.correctlyRegisteredLayers:
                self.generatedGroup.addLayer(layer)
                #iface.legendInterface().setLayerVisible(layer, False)
                QgsProject.instance().layerTreeRoot().findLayer(
                    layer.id()).setItemVisibilityChecked(True)
            #equally on play.
            extent = QgsRectangle()
            extent.setMinimal()
            for child in self.generatedGroup.children():
                if isinstance(child, QgsLayerTreeLayer):
                    extent.combineExtentWith(child.layer().extent())

            iface.mapCanvas().setExtent(extent)
            iface.mapCanvas().refresh()

            if self.errorCount > 0:
                self.errorsFound.emit(self.errorCount)
    def zoom_to_group(self, group_name, buffer=10):
        """ Make zoom to extent of the received group
        :param group_name: Group name where to zoom
        :param buffer: Space left between the group zoom and the canvas (integer)
        :return: False if don't find the group
        """

        extent = QgsRectangle()
        extent.setMinimal()

        # Iterate through layers from certain group and combine their extent
        root = QgsProject.instance().layerTreeRoot()
        group = root.findGroup(
            group_name)  # Adjust this to fit your group's name
        if not group:
            return False
        for child in group.children():
            if isinstance(child, QgsLayerTreeLayer):
                extent.combineExtentWith(child.layer().extent())

        xmax = extent.xMaximum() + buffer
        xmin = extent.xMinimum() - buffer
        ymax = extent.yMaximum() + buffer
        ymin = extent.yMinimum() - buffer
        extent.set(xmin, ymin, xmax, ymax)
        self.iface.mapCanvas().setExtent(extent)
        self.iface.mapCanvas().refresh()
Exemplo n.º 4
0
    def addResultToLayer(self, layer, result, lyrDefault, mode):
        if len(result) > 0:
            layer.startEditing()
            feats = []

            if lyrDefault is True:
                bbox = QgsRectangle()
                bbox.setMinimal()

            for res in result:
                feat = QgsFeature()
                if mode == 'web':
                    feat.setGeometry(
                        QgsGeometry.fromMultiPolygonXY(res["geom"]))
                else:
                    feat.setGeometry(QgsGeometry.fromWkt(res["wkt"]))

                feat.setAttributes([
                    res["id"], res["partido"], res["partida"],
                    res["nomenclatura"], res["codigo"], res["layer"]
                ])
                feats.append(feat)
                if lyrDefault is True:
                    bbox.combineExtentWith(feat.geometry().boundingBox())

            layer.dataProvider().addFeatures(feats)
            layer.commitChanges()
            layer.updateExtents()

            if lyrDefault is True:
                self.canvas.setExtent(self.setBboxMap(bbox, layer))
            else:
                self.canvas.setExtent(self.setBboxMap(layer.extent(), layer))
Exemplo n.º 5
0
    def getFeatureByAttributtes(self, layer, pdo_or_omencla, pda=None):
        try:
            if pda != None:
                result = layer.getFeatures(
                    QgsFeatureRequest(
                        QgsExpression(
                            '"partido" = {} and "partida" = {}'.format(
                                pdo_or_omencla, pda))))
                result = list(result)
                if len(result) == 0:
                    return False
            else:
                result = layer.getFeatures(
                    QgsFeatureRequest(
                        QgsExpression(
                            '"codigo" = \'{}\''.format(pdo_or_omencla))))
                result = list(result)
                if len(result) == 0:
                    return False

            bbox = QgsRectangle()
            bbox.setMinimal()

            for feat in result:
                bbox.combineExtentWith(feat.geometry().boundingBox())

            layer.updateExtents()
            self.canvas.setExtent(self.setBboxMap(bbox, layer))
            layer.triggerRepaint()
            #canvas.refresh()
            return True
        except Exception as e:  #en caso que la capa haya sido eliminada
            # fix_print_with_import
            print(str(e))
            return False
Exemplo n.º 6
0
def zoom_to_group(group):
    extent = QgsRectangle()
    extent.setMinimal()
    # Iterate through layers from group and combine their extent
    for child in group.children():
        if isinstance(child, QgsLayerTreeLayer):
            extent.combineExtentWith(child.layer().extent())
    iface.mapCanvas().setExtent(extent)
    iface.mapCanvas().refresh()
Exemplo n.º 7
0
def set_margin(layer, margin):

    extent = QgsRectangle()
    extent.setMinimal()
    extent.combineExtentWith(layer.extent())
    xmax = extent.xMaximum() + margin
    xmin = extent.xMinimum() - margin
    ymax = extent.yMaximum() + margin
    ymin = extent.yMinimum() - margin
    extent.set(xmin, ymin, xmax, ymax)
    global_vars.iface.mapCanvas().setExtent(extent)
    global_vars.iface.mapCanvas().refresh()
 def getExtentForLocate(self, sourceRow):
     surfaceType = self.source.item(sourceRow, self.IndexSurface).text()
     surfaceLayers = QgisHelper.getSurfaceLayers(self.surfaceType)
     rect = QgsRectangle()
     rect.setMinimal()
     for sfLayer in surfaceLayers:
         features = sfLayer.getFeatures()
         for feature in features:
             surfaceString = feature.attribute("surface").toString()
             if surfaceString == surfaceType:
                 geom = feature.geometry()
                 rect.combineExtentWith(geom.boundingBox())
     return rect
def add_resource_as_wfs_layers(wfs_resource, return_extent=False):
    if not isinstance(wfs_resource, NGWWfsService):
        raise NGWError('Resource type is not WfsService!')
    #Extent stuff
    if return_extent:
        summary_extent = QgsRectangle()
        summary_extent.setMinimal()
    #Add group
    toc_root = QgsProject.instance().layerTreeRoot()
    layers_group = toc_root.insertGroup(0, wfs_resource.common.display_name)
    #Add layers
    for wfs_layer in wfs_resource.wfs.layers:
        url = wfs_resource.get_wfs_url(
            wfs_layer.keyname
        ) + '&srsname=EPSG:3857&VERSION=1.0.0&REQUEST=GetFeature'
        qgs_wfs_layer = QgsVectorLayer(url, wfs_layer.display_name, 'WFS')

        ngw_vector_layer = wfs_resource.get_source_layer(wfs_layer.resource_id)

        # Add vector style. Select the first QGIS style if several.
        ngw_style_res = None
        vec_layer_children = ngw_vector_layer.get_children()
        for child in vec_layer_children:
            if isinstance(child, NGWQGISStyle):
                ngw_style_res = child
                break
        if not ngw_style_res is None:
            loop = QEventLoop()
            nam = QNetworkAccessManager()
            nam.finished.connect(loop.quit)
            reply = nam.get(
                QNetworkRequest(QUrl(ngw_style_res.download_qml_url())))
            loop.exec_()
            tmpfile = QTemporaryFile()
            if tmpfile.open(QIODevice.WriteOnly):
                tmpfile.write(reply.readAll())
                tmpfile.close()
                qgs_wfs_layer.loadNamedStyle(tmpfile.fileName())

        _add_aliases(qgs_wfs_layer, ngw_vector_layer)

        #summarize extent
        if return_extent:
            _summ_extent(summary_extent, qgs_wfs_layer)
        CompatQgis.layers_registry().addMapLayer(qgs_wfs_layer, False)
        layers_group.insertLayer(0, qgs_wfs_layer)

    if return_extent:
        return summary_extent
Exemplo n.º 10
0
def set_margin(layer, margin):
    """ Generates a margin around the layer so that it is fully visible on the canvas """

    if layer.extent().isNull():
        return

    extent = QgsRectangle()
    extent.setMinimal()
    extent.combineExtentWith(layer.extent())
    xmin = extent.xMinimum() - margin
    ymin = extent.yMinimum() - margin
    xmax = extent.xMaximum() + margin
    ymax = extent.yMaximum() + margin
    extent.set(xmin, ymin, xmax, ymax)
    iface.mapCanvas().setExtent(extent)
    iface.mapCanvas().refresh()
    def add_resource(self):
        sel_index = self.trvResources.selectionModel().currentIndex()
        if sel_index.isValid():
            #extent for_zoom
            summary_extent = QgsRectangle()
            summary_extent.setMinimal()

            self.hide() #hack
            ngw_resource = sel_index.data(Qt.UserRole)
            if ngw_resource.common.cls == NGWFoclProject.type_id:
                for child in ngw_resource.get_children():
                    self._append_resource_to_map(child, ngw_resource, summary_extent)
            else:
                parent_resource = sel_index.parent().data(Qt.UserRole)
                self._append_resource_to_map(ngw_resource, parent_resource, summary_extent)

            self.zoom_to_extent(summary_extent)
            self.close()
Exemplo n.º 12
0
	def zoomToExtent(self):
		self.addLayers(self.proj.readEntry("QGYF", "dataPath")[0], [
			"research_area",
			"ground_areas",
			"point_object",
			"line_object",
			"polygon_object",
		])
		extent = QgsRectangle()
		extent.setMinimal()
		root = self.proj.layerTreeRoot()
		ground_layer = self.proj.mapLayersByName('Grundytor')
		extent.combineExtentWith(ground_layer[0].extent())
		group = root.findGroup("Klassificering")
		for child in group.children():
			extent.combineExtentWith(child.layer().extent())
		self.iface.mapCanvas().setExtent(extent)
		self.iface.mapCanvas().refresh()
Exemplo n.º 13
0
def add_resource_as_wfs_layers(wfs_resource, return_extent=False):
    if not isinstance(wfs_resource, NGWWfsService):
        raise NGWError('Resource type is not WfsService!')
    #Extent stuff
    if return_extent:
        summary_extent = QgsRectangle()
        summary_extent.setMinimal()
    #Add group
    toc_root = QgsProject.instance().layerTreeRoot()
    layers_group = toc_root.insertGroup(0, wfs_resource.common.display_name)
    #Add layers
    for wfs_layer in wfs_resource.wfs.layers:
        url = wfs_resource.get_wfs_url(wfs_layer.keyname) + '&srsname=EPSG:3857&VERSION=1.0.0&REQUEST=GetFeature'
        qgs_wfs_layer = QgsVectorLayer(url, wfs_layer.display_name, 'WFS')
        #summarize extent
        if return_extent:
            _summ_extent(summary_extent, qgs_wfs_layer)
        QgsMapLayerRegistry.instance().addMapLayer(qgs_wfs_layer, False)
        layers_group.insertLayer(0, qgs_wfs_layer)

    if return_extent:
        return summary_extent
Exemplo n.º 14
0
 def groupify(self):
     print "Inside groupify"
     with self.groupAssignmentLock:
         self.layersToBeGrouped = len(self.layerList)
         self.getGeneratedGroup()
         registryAddedLayers = QgsMapLayerRegistry.instance().addMapLayers(self.layerList, False)
         for item in registryAddedLayers:
             if item not in self.layerList:
                 print("****WARNING: A LAYER WAS NOT ADDED TO THE REGISTRY: "+str(item)+" --- ID : "+item.id())
                 self.errorCount = self.errorCount + 1
                 pass
         self.correctlyRegisteredLayers = sorted(self.layerList, key=lambda layer: layer.name())
         for layer in self.correctlyRegisteredLayers:
             self.generatedGroup.addLayer(layer)
             print "set visible layer identifier"
             print type(self.canvas)
             print type(self.parent)
             print (layer)
             #QgsProject.instance().layerTreeRoot().findLayer(layer.id()).setVisible(Qt.Unchecked)
            # self.canvas.legendInterface().setLayerVisible(layer, False)
             print "set visible layer ok"
         #We combine the group extents so all the layers are zoomed
         #equally on play.
         extent = QgsRectangle()
         extent.setMinimal()
         for child in self.generatedGroup.children():
             if isinstance(child, QgsLayerTreeLayer):
                 extent.combineExtentWith( child.layer().extent() )
     
         self.canvas.setExtent( extent )
         self.canvas.refresh()
         print "extend ok"
         #iface.mapCanvas().setExtent( extent )
         #iface.mapCanvas().refresh()
         
         if self.errorCount > 0:
             self.errorsFound.emit(self.errorCount)
def add_resource_as_wfs_layers(wfs_resource, return_extent=False):
    if not isinstance(wfs_resource, NGWWfsService):
        raise NGWError('Resource type is not WfsService!')
    #Extent stuff
    if return_extent:
        summary_extent = QgsRectangle()
        summary_extent.setMinimal()
    #Add group
    toc_root = QgsProject.instance().layerTreeRoot()
    layers_group = toc_root.insertGroup(0, wfs_resource.common.display_name)
    #Add layers
    for wfs_layer in wfs_resource.wfs.layers:
        url = wfs_resource.get_wfs_url(
            wfs_layer.keyname
        ) + '&srsname=EPSG:3857&VERSION=1.0.0&REQUEST=GetFeature'
        qgs_wfs_layer = QgsVectorLayer(url, wfs_layer.display_name, 'WFS')
        #summarize extent
        if return_extent:
            _summ_extent(summary_extent, qgs_wfs_layer)
        QgsMapLayerRegistry.instance().addMapLayer(qgs_wfs_layer, False)
        layers_group.insertLayer(0, qgs_wfs_layer)

    if return_extent:
        return summary_extent
Exemplo n.º 16
0
def qgis_composer_renderer(impact_report, component):
    """Default Map Report Renderer using QGIS Composer.

    Render using qgis composer for a given impact_report data and component
    context.

    :param impact_report: ImpactReport contains data about the report that is
        going to be generated.
    :type impact_report: safe.report.impact_report.ImpactReport

    :param component: Contains the component metadata and context for
        rendering the output.
    :type component:
        safe.report.report_metadata.QgisComposerComponentsMetadata

    :return: Whatever type of output the component should be.

    .. versionadded:: 4.0
    """
    context = component.context
    """:type: safe.report.extractors.composer.QGISComposerContext"""
    qgis_composition_context = impact_report.qgis_composition_context

    # load composition object
    composition = QgsComposition(qgis_composition_context.map_settings)

    # load template
    main_template_folder = impact_report.metadata.template_folder

    # we do this condition in case custom template was found
    if component.template.startswith('../qgis-composer-templates/'):
        template_path = os.path.join(main_template_folder, component.template)
    else:
        template_path = component.template

    with open(template_path) as template_file:
        template_content = template_file.read()

    document = QtXml.QDomDocument()
    document.setContent(template_content)

    load_status = composition.loadFromTemplate(
        document, context.substitution_map)

    if not load_status:
        raise TemplateLoadingError(
            tr('Error loading template: %s') % template_path)

    # replace image path
    for img in context.image_elements:
        item_id = img.get('id')
        path = img.get('path')
        image = composition_item(composition, item_id, QgsComposerPicture)
        """:type: qgis.core.QgsComposerPicture"""
        if image and path:
            image.setPicturePath(path)

    # replace html frame
    for html_el in context.html_frame_elements:
        item_id = html_el.get('id')
        mode = html_el.get('mode')
        composer_item = composition.getComposerItemById(item_id)
        try:
            html_element = composition.getComposerHtmlByItem(composer_item)
        except:
            pass
        """:type: qgis.core.QgsComposerHtml"""
        if html_element:
            if mode == 'text':
                text = html_el.get('text')
                text = text if text else ''
                html_element.setContentMode(QgsComposerHtml.ManualHtml)
                html_element.setHtml(text)
                html_element.loadHtml()
            elif mode == 'url':
                url = html_el.get('url')
                html_element.setContentMode(QgsComposerHtml.Url)
                qurl = QUrl.fromLocalFile(url)
                html_element.setUrl(qurl)

    original_crs = impact_report.impact_function.crs
    destination_crs = qgis_composition_context.map_settings.destinationCrs()
    coord_transform = QgsCoordinateTransform(original_crs, destination_crs)

    # resize map extent
    for map_el in context.map_elements:
        item_id = map_el.get('id')
        split_count = map_el.get('grid_split_count')
        layers = [
            layer for layer in map_el.get('layers') if isinstance(
                layer, QgsMapLayer)
        ]
        map_extent_option = map_el.get('extent')
        composer_map = composition_item(composition, item_id, QgsComposerMap)

        for index, layer in enumerate(layers):
            # we need to check whether the layer is registered or not
            registered_layer = (
                QgsMapLayerRegistry.instance().mapLayer(layer.id()))
            if registered_layer:
                if not registered_layer == layer:
                    layers[index] = registered_layer
            else:
                QgsMapLayerRegistry.instance().addMapLayer(layer)

        """:type: qgis.core.QgsComposerMap"""
        if composer_map:

            # Search for specified map extent in the template.
            min_x = composer_map.extent().xMinimum() if (
                impact_report.use_template_extent) else None
            min_y = composer_map.extent().yMinimum() if (
                impact_report.use_template_extent) else None
            max_x = composer_map.extent().xMaximum() if (
                impact_report.use_template_extent) else None
            max_y = composer_map.extent().yMaximum() if (
                impact_report.use_template_extent) else None

            composer_map.setKeepLayerSet(True)
            layer_set = [l.id() for l in layers if isinstance(l, QgsMapLayer)]
            composer_map.setLayerSet(layer_set)
            map_overview_extent = None
            if map_extent_option and isinstance(
                    map_extent_option, QgsRectangle):
                # use provided map extent
                extent = coord_transform.transform(map_extent_option)
                for l in [layer for layer in layers if
                          isinstance(layer, QgsMapLayer)]:
                    layer_extent = coord_transform.transform(l.extent())
                    if l.name() == map_overview['id']:
                        map_overview_extent = layer_extent
            else:
                # if map extent not provided, try to calculate extent
                # from list of given layers. Combine it so all layers were
                # shown properly
                extent = QgsRectangle()
                extent.setMinimal()
                for l in [layer for layer in layers if
                          isinstance(layer, QgsMapLayer)]:
                    # combine extent if different layer is provided.
                    layer_extent = coord_transform.transform(l.extent())
                    extent.combineExtentWith(layer_extent)
                    if l.name() == map_overview['id']:
                        map_overview_extent = layer_extent

            width = extent.width()
            height = extent.height()
            longest_width = width if width > height else height
            half_length = longest_width / 2
            margin = half_length / 5
            center = extent.center()
            min_x = min_x or (center.x() - half_length - margin)
            max_x = max_x or (center.x() + half_length + margin)
            min_y = min_y or (center.y() - half_length - margin)
            max_y = max_y or (center.y() + half_length + margin)

            # noinspection PyCallingNonCallable
            square_extent = QgsRectangle(min_x, min_y, max_x, max_y)

            if component.key == 'population-infographic' and (
                    map_overview_extent):
                square_extent = map_overview_extent

            composer_map.zoomToExtent(square_extent)
            composer_map.renderModeUpdateCachedImage()

            actual_extent = composer_map.extent()

            # calculate intervals for grid
            x_interval = actual_extent.width() / split_count
            composer_map.grid().setIntervalX(x_interval)
            y_interval = actual_extent.height() / split_count
            composer_map.grid().setIntervalY(y_interval)

    # calculate legend element
    for leg_el in context.map_legends:
        item_id = leg_el.get('id')
        title = leg_el.get('title')
        layers = [
            layer for layer in leg_el.get('layers') if isinstance(
                layer, QgsMapLayer)
        ]
        symbol_count = leg_el.get('symbol_count')
        column_count = leg_el.get('column_count')

        legend = composition_item(composition, item_id, QgsComposerLegend)
        """:type: qgis.core.QgsComposerLegend"""
        if legend:
            # set column count
            if column_count:
                legend.setColumnCount(column_count)
            elif symbol_count <= 7:
                legend.setColumnCount(1)
            else:
                legend.setColumnCount(symbol_count / 7 + 1)

            # set legend title
            if title is not None and not impact_report.legend_layers:
                legend.setTitle(title)

            # set legend
            root_group = legend.modelV2().rootGroup()
            for layer in layers:
                # we need to check whether the layer is registered or not
                registered_layer = (
                    QgsMapLayerRegistry.instance().mapLayer(layer.id()))
                if registered_layer:
                    if not registered_layer == layer:
                        layer = registered_layer
                else:
                    QgsMapLayerRegistry.instance().addMapLayer(layer)
                # used for customizations
                tree_layer = root_group.addLayer(layer)
                if impact_report.legend_layers or (
                        not impact_report.multi_exposure_impact_function):
                    QgsLegendRenderer.setNodeLegendStyle(
                        tree_layer, QgsComposerLegendStyle.Hidden)
            legend.synchronizeWithModel()

    # process to output

    # in case output folder not specified
    if impact_report.output_folder is None:
        impact_report.output_folder = mkdtemp(dir=temp_dir())

    output_format = component.output_format
    component_output_path = impact_report.component_absolute_output_path(
        component.key)
    component_output = None

    doc_format = QgisComposerComponentsMetadata.OutputFormat.DOC_OUTPUT
    template_format = QgisComposerComponentsMetadata.OutputFormat.QPT
    if isinstance(output_format, list):
        component_output = []
        for i in range(len(output_format)):
            each_format = output_format[i]
            each_path = component_output_path[i]

            if each_format in doc_format:
                result_path = create_qgis_pdf_output(
                    impact_report,
                    each_path,
                    composition,
                    each_format,
                    component)
                component_output.append(result_path)
            elif each_format == template_format:
                result_path = create_qgis_template_output(
                    each_path, composition)
                component_output.append(result_path)
    elif isinstance(output_format, dict):
        component_output = {}
        for key, each_format in output_format.iteritems():
            each_path = component_output_path[key]

            if each_format in doc_format:
                result_path = create_qgis_pdf_output(
                    impact_report,
                    each_path,
                    composition,
                    each_format,
                    component)
                component_output[key] = result_path
            elif each_format == template_format:
                result_path = create_qgis_template_output(
                    each_path, composition)
                component_output[key] = result_path
    elif (output_format in
            QgisComposerComponentsMetadata.OutputFormat.SUPPORTED_OUTPUT):
        component_output = None

        if output_format in doc_format:
            result_path = create_qgis_pdf_output(
                impact_report,
                component_output_path,
                composition,
                output_format,
                component)
            component_output = result_path
        elif output_format == template_format:
            result_path = create_qgis_template_output(
                component_output_path, composition)
            component_output = result_path

    component.output = component_output

    return component.output
Exemplo n.º 17
0
class ROSVectorProvider(QgsVectorDataProvider):

    fieldsUpdated = pyqtSignal()

    @classmethod
    def providerKey(cls):
        return 'rosvectorprovider'

    @classmethod
    def description(cls):
        return 'ROS Vector Provider'

    @classmethod
    def createProvider(cls, uri, providerOptions):
        return ROSVectorProvider(uri, providerOptions)

    def __init__(self,
                 uri='',
                 providerOptions=QgsDataProvider.ProviderOptions()):
        '''Set up the Data Provider.

        uri contains the topic name, topic type.
        Example uri: 'foo/my_pose?type=geometry_msgs/PoseStamped'
        '''
        try:
            self._topic, argString = uri.split('?')
        except IndexError:
            raise ValueError(
                'uri Cannot be parsed. Is it valid? uri: {}'.format(uri))

        # Parse string of arguments into dict of python types.
        args = parseUrlArgs(argString)
        super().__init__(uri)

        self._translator = TranslatorRegistry.instance().get(args['type'])

        # There's no source for a reasonable collection of native types so we just steal from another provider.
        mlayer = QgsVectorLayer('Polygon?crs=epsg:4326', 'ml',
                                'memory')  # Wrong url but doesn't matter.
        nativeTypes = mlayer.dataProvider().nativeTypes()
        self.setNativeTypes(nativeTypes)

        self._uri = uri
        self._fields = QgsFields()
        self._wkbType = self._translator.geomType  # TODO: if unknown, infer it.
        self._features = {}
        self._extent = QgsRectangle()
        self._extent.setMinimal()
        self._subset_string = ''
        self._spatialindex = None
        self._provider_options = providerOptions
        self.next_feature_id = 0  # TODO: Consider a generator for a better numbering approach.
        self._lock = RLock()
        self._subscriber = None

        self.keepOlderMessages = args.get('keepOlderMessages', False)
        self._handledMessageCount = 0
        self.sampleInterval = int(args.get('sampleInterval', 1))

        if args.get('index'):
            self.createSpatialIndex()

        if args.get('subscribe'):
            self._subscriber = rospy.Subscriber(self._topic,
                                                self._translator.messageType,
                                                self._handleMessage)
        else:
            msg = rospy.wait_for_message(self._topic,
                                         self._translator.messageType,
                                         timeout=5)
            self._handleMessage(msg)

    def _handleMessage(self, msg):
        self._handledMessageCount += 1
        # Skip message if not on interval.
        if (self._handledMessageCount - 1
            ) % self.sampleInterval:  # -1 so that first message is handled.
            return

        features = self._translator.translate(msg)
        qgsFeatures, fields = featuresToQgs(features)

        # TODO: check if fields changed and emit a signal only then.
        self._fields = fields
        self.fieldsUpdated.emit()

        # If we're not accumulating history, clear features first.
        if not self.keepOlderMessages:
            self.next_feature_id = 0
            self._features = {}  # Clear features.

        try:
            self._setFeatures(qgsFeatures)
        except RuntimeError:
            self._cleanup()

        # Throttle data update to avoid over-stressing QGIS runtime. Consider alleviating this.
        global last_global_refresh
        now = rospy.get_time()
        if now - last_global_refresh > DATA_UPDATE_THROTTLE:
            last_global_refresh = now
            self.dataChanged.emit(
            )  # TODO: remove occasional flicker when this happens.

    def _cleanup(self):
        ''' Clean up ROS subscriber connection.
        The provider is owned by the QgsVectorLayer, which is owned by QGIS internals (layer registry)
        When a layer is removed, it gets deleted and cleaned up. However, there's no clean way to perform
        cleanup activities on the Python side before the underlying C++ object is deleted, thus making this
        object unstable.  A RuntimeError is raised when this is detected. We'll perform cleanup at that point.
        '''
        if self._subscriber:
            self._subscriber.unregister()
            self._subscriber = None

    def featureSource(self):
        with self._lock:
            return ROSVectorFeatureSource(self)

    def dataSourceUri(self, expandAuthConfig=True):
        return self._uri

    def storageType(self):
        return "ROS Topic"

    def getFeatures(self, request=QgsFeatureRequest()):
        with self._lock:
            return QgsFeatureIterator(
                ROSVectorFeatureIterator(ROSVectorFeatureSource(self),
                                         request))

    def uniqueValues(self, fieldIndex, limit=1):
        with self._lock:
            results = set()
            if fieldIndex >= 0 and fieldIndex < self._fields.count():
                req = QgsFeatureRequest()
                req.setFlags(QgsFeatureRequest.NoGeometry)
                req.setSubsetOfAttributes([fieldIndex])
                for f in self.getFeatures(req):
                    results.add(f.attributes()[fieldIndex])
            return results

    def wkbType(self):
        return self._wkbType

    def featureCount(self):
        with self._lock:
            if not self.subsetString():
                return len(self._features)
            else:
                req = QgsFeatureRequest()
                req.setFlags(QgsFeatureRequest.NoGeometry)
                req.setSubsetOfAttributes([])
                return len([f for f in self.getFeatures(req)])

    def fields(self):
        with self._lock:
            return self._fields

    def _setFeatures(self, flist, flags=None):
        with self._lock:
            added = False
            f_added = []

            if self._spatialindex is not None:
                for f in self._features.values():
                    self._spatialindex.deleteFeature(f)

            for _f in flist:
                self._features[self.next_feature_id] = _f
                _f.setId(self.next_feature_id)
                self.next_feature_id += 1
                added = True
                f_added.append(_f)

            if self._spatialindex is not None:
                self._spatialindex.insertFeature(_f)

            if f_added:
                self.clearMinMaxCache()
                self.updateExtents()

            return added, f_added

    def allFeatureIds(self):
        with self._lock:
            return list(self._features.keys())

    def subsetString(self):
        return self._subset_string

    def setSubsetString(self, subsetString):
        if subsetString == self._subset_string:
            return True
        self._subset_string = subsetString
        self.updateExtents()
        self.clearMinMaxCache()
        self.dataChanged.emit()
        return True

    def supportsSubsetString(self):
        return True

    def createSpatialIndex(self):
        if self._spatialindex is None:
            self._spatialindex = QgsSpatialIndex()
            for f in self._features.values():
                self._spatialindex.insertFeature(f)
        return True

    def capabilities(self):
        return QgsVectorDataProvider.SelectAtId | QgsVectorDataProvider.CreateSpatialIndex

    def name(self):
        return self.providerKey()

    def extent(self):
        if self._extent.isEmpty() and self._features:
            self._extent.setMinimal()
            if not self._subset_string:
                # fast way - iterate through all features
                for feat in self._features.values():
                    if feat.hasGeometry():
                        self._extent.combineExtentWith(
                            feat.geometry().boundingBox())
            else:
                for f in self.getFeatures(
                        QgsFeatureRequest().setSubsetOfAttributes([])):
                    if f.hasGeometry():
                        self._extent.combineExtentWith(
                            f.geometry().boundingBox())

        elif not self._features:
            self._extent.setMinimal()
        return QgsRectangle(self._extent)

    def updateExtents(self):
        self._extent.setMinimal()

    def isValid(self):
        return True

    def crs(self):
        return simpleCrs
Exemplo n.º 18
0
 def init_layers(self, scenario):
     '''
     initialize the layers in layer-window for given scenario
     including adding groups and background-layers and setting the
     editability of the institutional layers
     '''
     if not scenario:
         return
     scen_group = get_group(scenario.name, add_at_index=0)
     # just for the right initial order
     get_group('Filter', scen_group)
     cat_group = get_group('Einrichtungen', scen_group)
     get_group('Erreichbarkeiten PKW', scen_group)
     get_group(u'Erreichbarkeiten ÖPNV')
     border_group = get_group('Verwaltungsgrenzen')
     self.add_wms_background_map(group=get_group('Hintergrundkarte',
                                                 add_at_index=-1))
     self.add_xml_background_map(GOOGLE_XML,
                                 group=get_group('Hintergrundkarte'),
                                 visible=False)
     
     for name, tablename in [('Gemeinden', 'gemeinden_20161231'),
                             ('Verwaltungsgemeinschaften', 'vwg_20161231'),
                             ('Kreise', 'kreis_20161231')]:
         border_style = self.borders[name]
         symbology = SimpleFillSymbology(border_style=border_style)
         self.add_db_layer(name, 'verwaltungsgrenzen', tablename,
                           'geom', group=border_group, visible=False,
                           symbology=symbology)
     
     self.canvas.refresh()
     
     ### SET THE EDITABILITY OF INSTITUTIONAL LAYER-FIELDS###
 
     columns = ['spalte', 'editierbar', 'nur_auswahl_zulassen',
                'auswahlmoeglichkeiten', 'alias', 'auto_vervollst',
                'typ', 'min', 'max']
     for category, filter_tree in self.categories.iteritems():
         table = filter_tree.tablename
         symbology = SimpleSymbology(self.colors[category])
         layer = self.add_db_layer(category, SCHEMA, table, 'geom_gk',
                                   symbology, group=cat_group, zoom=False,
                                   where='szenario_id={}'.format(scenario.id))
         rows = get_values('editierbare_spalten', columns,
                           self.db_conn, schema='einrichtungen',
                           where="tabelle='{}'".format(table),
                           order_by='reihenfolge')
         editable_columns = [r.spalte for r in rows]
         #if not rows:
             #continue
         for i, f in enumerate(layer.fields()):
             if f.name() == 'szenario_id':
                 layer.setEditorWidgetV2(i, 'Hidden')
                 layer.setDefaultValueExpression(i, str(scenario.id))
                 continue
             try:
                 idx = editable_columns.index(f.name())
             except:
                 layer.setEditorWidgetV2(i, 'Hidden')
                 continue
             col, is_ed, is_sel, selections, alias, auto_complete, typ, min_value, max_value = rows[idx]
             if alias:
                 layer.addAttributeAlias(i, alias) 
             if not is_ed:
                 layer.setEditorWidgetV2(i, 'Hidden')
                 continue
             # type range (integers)
             if typ == 'range':
                 layer.setEditorWidgetV2(i, 'Range')
                 layer.setEditorWidgetV2Config(
                     i, {'AllowNull': False,
                         'Min': min_value, 'Max': max_value})
             # auto complete: take all existing unique values of field,
             # text will can be auto completed to one of those in UI
             if auto_complete:
                 layer.setEditorWidgetV2(i, 'UniqueValues')
                 layer.setEditorWidgetV2Config(i, {u'Editable': True})
             # selectable values are predefined in database
             elif is_sel and selections:
                 layer.setEditorWidgetV2(i, 'ValueMap')
                 sel = []
                 for s in selections:
                     try:
                         s = s.decode('utf-8')
                     except:
                         pass
                     sel.append(s)
                 d = dict([(s, s) for s in sel])
                 layer.setEditorWidgetV2Config(i, d)
             elif is_sel:
                 layer.setEditorWidgetV2(i, 'UniqueValues')
     # zoom to extent
     extent = QgsRectangle()
     extent.setMinimal()
     for child in cat_group.children():
         if isinstance(child, QgsLayerTreeLayer):
             #print child.layer().extent()
             extent.combineExtentWith(child.layer().extent())
     self.canvas.setExtent(extent)
     self.canvas.refresh()
Exemplo n.º 19
0
##MM=group
##r.series_directory=name
##Select_directory=Folder
##output=output raster

import glob, os
from PyQt4.QtCore import QFileInfo
from qgis.core import QgsRasterLayer, QgsRectangle

os.chdir(Select_directory)
rlist = []
extent = QgsRectangle()
extent.setMinimal()
for raster in glob.glob("*.tif"):
    fileInfo = QFileInfo(raster)
    baseName = fileInfo.baseName()
    rlayer = QgsRasterLayer(raster, baseName)
    # Combine raster layers to list
    rlist.append(rlayer)
    # Combine raster extents
    extent.combineExtentWith(rlayer.extent())

# Get extent
xmin = extent.xMinimum()
xmax = extent.xMaximum()
ymin = extent.yMinimum()
ymax = extent.yMaximum()
# Run algorithm and set relevant parameters
processing.runalg(
    "grass:r.series", {
        "input": rlist,
Exemplo n.º 20
0
class DjangoProvider(QgsVectorDataProvider):

    @classmethod
    def providerKey(cls):
        return 'django'

    @classmethod
    def description(cls):
        return 'Django vector provider'

    @classmethod
    def createProvider(cls, uri, providerOptions):
        return DjangoProvider(uri, providerOptions)

    def __init__(self, uri='', providerOptions=QgsDataProvider.ProviderOptions()):
        """
        :param uri: <app>.<model>[?geofield=<name>]
        :param providerOptions:
        """
        super().__init__(uri)
        self._is_valid = False
        self.setNativeTypes((
            # TODO
            QgsVectorDataProvider.NativeType('Integer', 'integer', QVariant.Int, -1, -1, 0, 0),
            QgsVectorDataProvider.NativeType('Text', 'text', QVariant.String, -1, -1, -1, -1),
        ))
        self._uri = uri
        url = QUrl(uri)
        url_query = QUrlQuery(url)
        self._full_model_name = url.path()
        self._app_label, self._model_name = self._full_model_name.split('.')
        self._model = apps.get_model(self._app_label, self._model_name)  # Django model
        self._meta = self._model._meta

        self._qgis_fields = QgsFields()
        self._django_fields = []  # Django fields represented by provider in the same order as QgsFields
        for django_field in self._meta.get_fields():
            # TODO: more field types
            qgis_field = self._get_qgis_field_from_django_field(django_field)

            if qgis_field:
                self._qgis_fields.append(qgis_field)
                self._django_fields.append(django_field)

        self._geo_field_name = url_query.queryItemValue('geofield')
        self._geo_field = None  # Django geometry field
        if self._geo_field_name:
            self._meta.get_field(self._geo_field_name)
        else:
            # If geometry field was not specified in uri, use the first one if any.
            for field in self._meta.get_fields():
                if isinstance(field, models.GeometryField):
                    self._geo_field = field
                    self._geo_field_name = field.name
                    break

        self._wkbType = QgsWkbTypes.NoGeometry
        if self._geo_field:
            for geo_field_class in wkb_types.keys():
                if isinstance(self._geo_field, geo_field_class):
                    self._wkbType = wkb_types[geo_field_class]
                    break

        self._extent = QgsRectangle()
        self._crs = None
        if self._geo_field:
            self._crs = QgsCoordinateReferenceSystem.fromEpsgId(self._geo_field.srid)
        self._provider_options = providerOptions
        self._is_valid = True

    def featureSource(self):
        return DjangoFeatureSource(self._model, self._qgis_fields, self._django_fields, self._geo_field, self._crs)

    def dataSourceUri(self, expandAuthConfig=True):
        return self._uri

    def storageType(self):
        return "Django"

    def getFeatures(self, request=QgsFeatureRequest()):
        return QgsFeatureIterator(self.featureSource().getFeatures(request))

    def uniqueValues(self, fieldIndex, limit=-1):
        if fieldIndex < 0 or fieldIndex >= self.fields().count():
            return set()

        dj_field = self._django_fields[fieldIndex]
        values = self._model.objects.get_queryset().order_by(dj_field.name).values_list(dj_field.name, flat=True).distinct()
        if limit >= 0:
            values = values[:limit]
        return set(values)

    def wkbType(self):
        return self._wkbType

    def featureCount(self):
        return self._model.objects.get_queryset().count()

    def fields(self):
        return self._qgis_fields

    def addFeatures(self, features, flags=None):
        # TODO
        return False

    def deleteFeatures(self, ids):
        # TODO
        return False

    def addAttributes(self, attrs):
        return False

    def renameAttributes(self, renamedAttributes):
        return False

    def deleteAttributes(self, attributes):
        return False

    def changeAttributeValues(self, attr_map):
        # TODO
        for feature_id, attrs in attr_map.items():
            pass
        self.clearMinMaxCache()
        return True

    def changeGeometryValues(self, geometry_map):
        # TODO
        for feature_id, geometry in geometry_map.items():
            pass
        self.updateExtents()
        return True

    def allFeatureIds(self):
        return list(self._model.objects.get_queryset().values_list(self._meta.pk.name, flat=True))

    def subsetString(self):
        return None

    def setSubsetString(self, subsetString):
        return False

    def supportsSubsetString(self):
        return False

    def createSpatialIndex(self):
        return False

    def capabilities(self):
        # TODO: QgsVectorDataProvider.AddFeatures | QgsVectorDataProvider.DeleteFeatures | QgsVectorDataProvider.ChangeGeometries | QgsVectorDataProvider.ChangeAttributeValues
        # TODO: TransactionSupport
        return QgsVectorDataProvider.SelectAtId

    # ---------------------------- functions from QgsDataProvider ----------------------------

    def name(self):
        return self.providerKey()

    def extent(self):
        # TODO
        return QgsRectangle(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
        if self._extent.isEmpty() and self._geo_field:
            box = list(self._model.objects.get_queryset().aggregate(models.Extent(self._geo_field_name)).values())[0]
            self._extent = QgsRectangle(box[0], box[0], box[0], box[0])

        return QgsRectangle(self._extent)

    def updateExtents(self):
        self._extent.setMinimal()

    def isValid(self):
        return self._is_valid

    def crs(self):
        return self._crs

    # -------------------------------- Private methods --------------------------------

    def _get_django_field(self, field_index):
        return self._django_fields[field_index]

    @staticmethod
    def _get_qgis_field_from_django_field(django_field):
        # IS it OK to take class name?
        name = django_field.name
        type_name = type(django_field).__name__.replace('Field', '').lower()
        comment = django_field.verbose_name
        # boolean
        if isinstance(django_field, models.BooleanField):
            return QgsField(name, QVariant.Bool, type_name, -1, -1, comment)
        elif isinstance(django_field, models.NullBooleanField):
            return QgsField(name, QVariant.Bool, type_name, -1, -1, comment)
        # integer
        elif isinstance(django_field, models.SmallIntegerField):
            return QgsField(name, QVariant.Int, type_name, -1, 0, comment)
        elif isinstance(django_field, models.IntegerField):
            return QgsField(name, QVariant.Int, type_name, -1, 0, comment)
        elif isinstance(django_field, models.BigIntegerField):
            return QgsField(name, QVariant.LongLong, type_name, -1, 0, comment)
        # float
        elif isinstance(django_field, models.FloatField):
            return QgsField(name, QVariant.Double, type_name, -1, -1, comment)
        elif isinstance(django_field, models.DecimalField):
            return QgsField(name, QVariant.Double, type_name, django_field.max_digits, django_field.decimal_places, comment)
        # char
        elif isinstance(django_field, models.CharField):
            return QgsField(name, QVariant.String, type_name, django_field.max_length, -1, comment)
        elif isinstance(django_field, models.TextField):
            return QgsField(name, QVariant.String, type_name, -1, -1, comment)
        # datetime
        elif isinstance(django_field, models.DateField):
            return QgsField(name, QVariant.Date, type_name, -1, -1, comment)
        elif isinstance(django_field, models.TimeField):
            return QgsField(name, QVariant.Time, type_name, -1, -1, comment)
        elif isinstance(django_field, models.DateTimeField):
            return QgsField(name, QVariant.DateTime, type_name, -1, -1, comment)

        return None
Exemplo n.º 21
0
def qgis_composer_renderer(impact_report, component):
    """Default Map Report Renderer using QGIS Composer.

    Render using qgis composer for a given impact_report data and component
    context

    :param impact_report: ImpactReport contains data about the report that is
        going to be generated
    :type impact_report: safe.report.impact_report.ImpactReport

    :param component: Contains the component metadata and context for
        rendering the output
    :type component:
        safe.report.report_metadata.QgisComposerComponentsMetadata

    :return: whatever type of output the component should be

    .. versionadded:: 4.0
    """
    context = component.context
    """:type: safe.report.extractors.composer.QGISComposerContext"""
    qgis_composition_context = impact_report.qgis_composition_context
    inasafe_context = impact_report.inasafe_context

    # load composition object
    composition = QgsComposition(qgis_composition_context.map_settings)

    # load template
    main_template_folder = impact_report.metadata.template_folder
    template_path = os.path.join(main_template_folder, component.template)

    with open(template_path) as template_file:
        template_content = template_file.read()

    document = QtXml.QDomDocument()
    document.setContent(template_content)

    load_status = composition.loadFromTemplate(
        document, context.substitution_map)

    if not load_status:
        raise TemplateLoadingError(
            tr('Error loading template: %s') % template_path)

    # replace image path
    for img in context.image_elements:
        item_id = img.get('id')
        path = img.get('path')
        image = composition.getComposerItemById(item_id)
        """:type: qgis.core.QgsComposerPicture"""
        if image is not None and path is not None:
            try:
                image.setPicturePath(path)
            except:
                pass

    # replace html frame
    for html_el in context.html_frame_elements:
        item_id = html_el.get('id')
        mode = html_el.get('mode')
        html_element = composition.getComposerItemById(item_id)
        """:type: qgis.core.QgsComposerHtml"""
        if html_element:
            if mode == 'text':
                text = html_el.get('text')
                text = text if text else ''
                html_element.setContentMode(QgsComposerHtml.ManualHtml)
                html_element.setHtml(text)
                html_element.loadHtml()
            elif mode == 'url':
                url = html_el.get('url')
                html_element.setContentMode(QgsComposerHtml.Url)
                qurl = QUrl.fromLocalFile(url)
                html_element.setUrl(qurl)

    # resize map extent
    for map_el in context.map_elements:
        item_id = map_el.get('id')
        split_count = map_el.get('grid_split_count')
        layers = map_el.get('layers')
        map_extent_option = map_el.get('extent')
        composer_map = composition.getComposerItemById(item_id)
        """:type: qgis.core.QgsComposerMap"""
        if isinstance(composer_map, QgsComposerMap):
            composer_map.setKeepLayerSet(True)
            layer_set = [l.id() for l in layers if isinstance(l, QgsMapLayer)]
            composer_map.setLayerSet(layer_set)
            if map_extent_option and isinstance(
                    map_extent_option, QgsRectangle):
                # use provided map extent
                extent = map_extent_option
            else:
                # if map extent not provided, try to calculate extent
                # from list of given layers. Combine it so all layers were
                # shown properly
                extent = QgsRectangle()
                extent.setMinimal()
                for l in layers:
                    # combine extent if different layer is provided.
                    extent.combineExtentWith(l.extent())

            width = extent.width()
            height = extent.height()
            longest_width = width if width > height else height
            half_length = longest_width / 2
            margin = half_length / 5
            center = extent.center()
            min_x = center.x() - half_length - margin
            max_x = center.x() + half_length + margin
            min_y = center.y() - half_length - margin
            max_y = center.y() + half_length + margin

            # noinspection PyCallingNonCallable
            square_extent = QgsRectangle(min_x, min_y, max_x, max_y)

            composer_map.zoomToExtent(square_extent)
            composer_map.renderModeUpdateCachedImage()

            actual_extent = composer_map.extent()

            # calculate intervals for grid
            x_interval = actual_extent.width() / split_count
            composer_map.grid().setIntervalX(x_interval)
            y_interval = actual_extent.height() / split_count
            composer_map.grid().setIntervalY(y_interval)

    # calculate legend element
    for leg_el in context.map_legends:
        item_id = leg_el.get('id')
        title = leg_el.get('title')
        layers = leg_el.get('layers')
        symbol_count = leg_el.get('symbol_count')
        column_count = leg_el.get('column_count')

        legend = composition.getComposerItemById(item_id)
        """:type: qgis.core.QgsComposerLegend"""
        if isinstance(legend, QgsComposerLegend):
            # set column count
            if column_count:
                legend.setColumnCount(column_count)
            elif symbol_count <= 5:
                legend.setColumnCount(1)
            else:
                legend.setColumnCount(symbol_count / 5 + 1)

            # set legend title
            if title is not None:
                legend.setTitle(title)

            # set legend
            root_group = legend.modelV2().rootGroup()
            for l in layers:
                # used for customizations
                tree_layer = root_group.addLayer(l)
                QgsLegendRenderer.setNodeLegendStyle(
                    tree_layer, QgsComposerLegendStyle.Hidden)
            legend.synchronizeWithModel()

    # process to output

    # in case output folder not specified
    if impact_report.output_folder is None:
        impact_report.output_folder = mkdtemp(dir=temp_dir())

    output_format = component.output_format
    component_output_path = impact_report.component_absolute_output_path(
        component.key)
    component_output = None

    doc_format = QgisComposerComponentsMetadata.OutputFormat.DOC_OUTPUT
    template_format = QgisComposerComponentsMetadata.OutputFormat.QPT
    if isinstance(output_format, list):
        component_output = []
        for i in range(len(output_format)):
            each_format = output_format[i]
            each_path = component_output_path[i]

            if each_format in doc_format:
                result_path = create_qgis_pdf_output(
                    each_path,
                    composition,
                    impact_report.qgis_composition_context,
                    each_format,
                    component)
                component_output.append(result_path)
            elif each_format == template_format:
                result_path = create_qgis_template_output(
                    each_path, composition)
                component_output.append(result_path)
    elif isinstance(output_format, dict):
        component_output = {}
        for key, each_format in output_format.iteritems():
            each_path = component_output_path[key]

            if each_format in doc_format:
                result_path = create_qgis_pdf_output(
                    each_path,
                    composition,
                    impact_report.qgis_composition_context,
                    each_format,
                    component)
                component_output[key] = result_path
            elif each_format == template_format:
                result_path = create_qgis_template_output(
                    each_path, composition)
                component_output[key] = result_path
    elif (output_format in
            QgisComposerComponentsMetadata.OutputFormat.SUPPORTED_OUTPUT):
        component_output = None

        if output_format in doc_format:
            result_path = create_qgis_pdf_output(
                component_output_path,
                composition,
                impact_report.qgis_composition_context,
                output_format,
                component)
            component_output = result_path
        elif output_format == template_format:
            result_path = create_qgis_template_output(
                component_output_path, composition)
            component_output = result_path

    component.output = component_output

    return component.output
Exemplo n.º 22
0
class PyProvider(QgsVectorDataProvider):

    next_feature_id = 1

    @classmethod
    def providerKey(cls):
        """Returns the memory provider key"""
        return 'pythonprovider'

    @classmethod
    def description(cls):
        """Returns the memory provider description"""
        return 'Python Test Provider'

    @classmethod
    def createProvider(cls, uri, providerOptions):
        return PyProvider(uri, providerOptions)

    # Implementation of functions from QgsVectorDataProvider

    def __init__(self, uri='', providerOptions=QgsDataProvider.ProviderOptions()):
        super().__init__(uri)
        # Use the memory layer to parse the uri
        mlayer = QgsVectorLayer(uri, 'ml', 'memory')
        self.setNativeTypes(mlayer.dataProvider().nativeTypes())
        self._uri = uri
        self._fields = mlayer.fields()
        self._wkbType = mlayer.wkbType()
        self._features = {}
        self._extent = QgsRectangle()
        self._extent.setMinimal()
        self._subset_string = ''
        self._crs = mlayer.crs()
        self._spatialindex = None
        self._provider_options = providerOptions
        if 'index=yes'in self._uri:
            self.createSpatialIndex()

    def featureSource(self):
        return PyFeatureSource(self)

    def dataSourceUri(self, expandAuthConfig=True):
        return self._uri

    def storageType(self):
        return "Python test memory storage"

    def getFeatures(self, request=QgsFeatureRequest()):
        return QgsFeatureIterator(PyFeatureIterator(PyFeatureSource(self), request))

    def uniqueValues(self, fieldIndex, limit=1):
        results = set()
        if fieldIndex >= 0 and fieldIndex < self.fields().count():
            req = QgsFeatureRequest()
            req.setFlags(QgsFeatureRequest.NoGeometry)
            req.setSubsetOfAttributes([fieldIndex])
            for f in self.getFeatures(req):
                results.add(f.attributes()[fieldIndex])
        return results

    def wkbType(self):
        return self._wkbType

    def featureCount(self):
        if not self.subsetString():
            return len(self._features)
        else:
            req = QgsFeatureRequest()
            req.setFlags(QgsFeatureRequest.NoGeometry)
            req.setSubsetOfAttributes([])
            return len([f for f in self.getFeatures(req)])

    def fields(self):
        return self._fields

    def addFeatures(self, flist, flags=None):
        added = False
        f_added = []
        for f in flist:
            if f.hasGeometry() and (f.geometry().wkbType() != self.wkbType()):
                return added, f_added

        for f in flist:
            _f = QgsFeature(self.fields())
            _f.setGeometry(f.geometry())
            attrs = [None for i in range(_f.fields().count())]
            for i in range(min(len(attrs), len(f.attributes()))):
                attrs[i] = f.attributes()[i]
            _f.setAttributes(attrs)
            _f.setId(self.next_feature_id)
            self._features[self.next_feature_id] = _f
            self.next_feature_id += 1
            added = True
            f_added.append(_f)

            if self._spatialindex is not None:
                self._spatialindex.insertFeature(_f)

        if len(f_added):
            self.clearMinMaxCache()
            self.updateExtents()

        return added, f_added

    def deleteFeatures(self, ids):
        if not ids:
            return True
        removed = False
        for id in ids:
            if id in self._features:
                if self._spatialindex is not None:
                    self._spatialindex.deleteFeature(self._features[id])
                del self._features[id]
                removed = True
        if removed:
            self.clearMinMaxCache()
            self.updateExtents()
        return removed

    def addAttributes(self, attrs):
        try:
            for new_f in attrs:
                if new_f.type() not in (QVariant.Int, QVariant.Double, QVariant.String, QVariant.Date, QVariant.Time, QVariant.DateTime, QVariant.LongLong, QVariant.StringList, QVariant.List):
                    continue
                self._fields.append(new_f)
                for f in self._features.values():
                    old_attrs = f.attributes()
                    old_attrs.append(None)
                    f.setAttributes(old_attrs)
            self.clearMinMaxCache()
            return True
        except Exception:
            return False

    def renameAttributes(self, renamedAttributes):
        result = True
        # We need to replace all fields because python bindings return a copy from [] and at()
        new_fields = [self._fields.at(i) for i in range(self._fields.count())]
        for fieldIndex, new_name in renamedAttributes.items():
            if fieldIndex < 0 or fieldIndex >= self._fields.count():
                result = False
                continue
            if self._fields.indexFromName(new_name) >= 0:
                #field name already in use
                result = False
                continue
            new_fields[fieldIndex].setName(new_name)
        if result:
            self._fields = QgsFields()
            for i in range(len(new_fields)):
                self._fields.append(new_fields[i])
        return result

    def deleteAttributes(self, attributes):
        attrIdx = sorted(attributes, reverse=True)

        # delete attributes one-by-one with decreasing index
        for idx in attrIdx:
            self._fields.remove(idx)
            for f in self._features.values():
                attr = f.attributes()
                del(attr[idx])
                f.setAttributes(attr)
        self.clearMinMaxCache()
        return True

    def changeAttributeValues(self, attr_map):
        for feature_id, attrs in attr_map.items():
            try:
                f = self._features[feature_id]
            except KeyError:
                continue
            for k, v in attrs.items():
                f.setAttribute(k, v)
        self.clearMinMaxCache()
        return True

    def changeGeometryValues(self, geometry_map):
        for feature_id, geometry in geometry_map.items():
            try:
                f = self._features[feature_id]
                f.setGeometry(geometry)
            except KeyError:
                continue
        self.updateExtents()
        return True

    def allFeatureIds(self):
        return list(self._features.keys())

    def subsetString(self):
        return self._subset_string

    def setSubsetString(self, subsetString):
        if subsetString == self._subset_string:
            return True
        self._subset_string = subsetString
        self.updateExtents()
        self.clearMinMaxCache()
        self.dataChanged.emit()
        return True

    def supportsSubsetString(self):
        return True

    def createSpatialIndex(self):
        if self._spatialindex is None:
            self._spatialindex = QgsSpatialIndex()
            for f in self._features.values():
                self._spatialindex.insertFeature(f)
        return True

    def capabilities(self):
        return QgsVectorDataProvider.AddFeatures | QgsVectorDataProvider.DeleteFeatures | QgsVectorDataProvider.CreateSpatialIndex | QgsVectorDataProvider.ChangeGeometries | QgsVectorDataProvider.ChangeAttributeValues | QgsVectorDataProvider.AddAttributes | QgsVectorDataProvider.DeleteAttributes | QgsVectorDataProvider.RenameAttributes | QgsVectorDataProvider.SelectAtId | QgsVectorDataProvider. CircularGeometries

    #/* Implementation of functions from QgsDataProvider */

    def name(self):
        return self.providerKey()

    def extent(self):
        if self._extent.isEmpty() and self._features:
            self._extent.setMinimal()
            if not self._subset_string:
                # fast way - iterate through all features
                for feat in self._features.values():
                    if feat.hasGeometry():
                        self._extent.combineExtentWith(feat.geometry().boundingBox())
            else:
                for f in self.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([])):
                    if f.hasGeometry():
                        self._extent.combineExtentWith(f.geometry().boundingBox())

        elif not self._features:
            self._extent.setMinimal()
        return QgsRectangle(self._extent)

    def updateExtents(self):
        self._extent.setMinimal()

    def isValid(self):
        return True

    def crs(self):
        return self._crs
Exemplo n.º 23
0
def qgis_composer_renderer(impact_report, component):
    """Default Map Report Renderer using QGIS Composer.

    Render using qgis composer for a given impact_report data and component
    context.

    :param impact_report: ImpactReport contains data about the report that is
        going to be generated.
    :type impact_report: safe.report.impact_report.ImpactReport

    :param component: Contains the component metadata and context for
        rendering the output.
    :type component:
        safe.report.report_metadata.QgisComposerComponentsMetadata

    :return: Whatever type of output the component should be.

    .. versionadded:: 4.0
    """
    context = component.context
    qgis_composition_context = impact_report.qgis_composition_context

    # load composition object
    layout = QgsPrintLayout(QgsProject.instance())

    # load template
    main_template_folder = impact_report.metadata.template_folder

    # we do this condition in case custom template was found
    if component.template.startswith('../qgis-composer-templates/'):
        template_path = os.path.join(main_template_folder, component.template)
    else:
        template_path = component.template

    with open(template_path) as template_file:
        template_content = template_file.read()

    document = QtXml.QDomDocument()

    # Replace
    for k, v in context.substitution_map.items():
        template_content = template_content.replace('[{}]'.format(k), v)

    document.setContent(template_content)

    rwcontext = QgsReadWriteContext()
    load_status = layout.loadFromTemplate(
        document, rwcontext)

    if not load_status:
        raise TemplateLoadingError(
            tr('Error loading template: %s') % template_path)

    # replace image path
    for img in context.image_elements:
        item_id = img.get('id')
        path = img.get('path')
        image = layout_item(layout, item_id, QgsLayoutItemPicture)
        if image and path:
            image.setPicturePath(path)

    # replace html frame
    for html_el in context.html_frame_elements:
        item_id = html_el.get('id')
        mode = html_el.get('mode')
        html_element = layout_item(layout, item_id, QgsLayoutItemHtml)
        if html_element:
            if mode == 'text':
                text = html_el.get('text')
                text = text if text else ''
                html_element.setContentMode(QgsLayoutItemHtml.ManualHtml)
                html_element.setHtml(text)
                html_element.loadHtml()
            elif mode == 'url':
                url = html_el.get('url')
                html_element.setContentMode(QgsLayoutItemHtml.Url)
                qurl = QUrl.fromLocalFile(url)
                html_element.setUrl(qurl)

    original_crs = impact_report.impact_function.crs
    destination_crs = qgis_composition_context.map_settings.destinationCrs()
    coord_transform = QgsCoordinateTransform(original_crs,
                                             destination_crs,
                                             QgsProject.instance())

    # resize map extent
    for map_el in context.map_elements:
        item_id = map_el.get('id')
        split_count = map_el.get('grid_split_count')
        layers = [
            layer for layer in map_el.get('layers') if isinstance(
                layer, QgsMapLayer)
        ]
        map_extent_option = map_el.get('extent')
        composer_map = layout_item(layout, item_id, QgsLayoutItemMap)

        for index, layer in enumerate(layers):
            # we need to check whether the layer is registered or not
            registered_layer = (
                QgsProject.instance().mapLayer(layer.id()))
            if registered_layer:
                if not registered_layer == layer:
                    layers[index] = registered_layer
            else:
                QgsProject.instance().addMapLayer(layer)

        """:type: qgis.core.QgsLayoutItemMap"""
        if composer_map:

            # Search for specified map extent in the template.
            min_x = composer_map.extent().xMinimum() if (
                impact_report.use_template_extent) else None
            min_y = composer_map.extent().yMinimum() if (
                impact_report.use_template_extent) else None
            max_x = composer_map.extent().xMaximum() if (
                impact_report.use_template_extent) else None
            max_y = composer_map.extent().yMaximum() if (
                impact_report.use_template_extent) else None

            composer_map.setKeepLayerSet(True)
            layer_set = [l for l in layers if isinstance(l, QgsMapLayer)]
            composer_map.setLayers(layer_set)
            map_overview_extent = None
            if map_extent_option and isinstance(
                    map_extent_option, QgsRectangle):
                # use provided map extent
                extent = coord_transform.transform(map_extent_option)
                for l in [layer for layer in layers if
                          isinstance(layer, QgsMapLayer)]:
                    layer_extent = coord_transform.transform(l.extent())
                    if l.name() == map_overview['id']:
                        map_overview_extent = layer_extent
            else:
                # if map extent not provided, try to calculate extent
                # from list of given layers. Combine it so all layers were
                # shown properly
                extent = QgsRectangle()
                extent.setMinimal()
                for l in [layer for layer in layers if
                          isinstance(layer, QgsMapLayer)]:
                    # combine extent if different layer is provided.
                    layer_extent = coord_transform.transform(l.extent())
                    extent.combineExtentWith(layer_extent)
                    if l.name() == map_overview['id']:
                        map_overview_extent = layer_extent

            width = extent.width()
            height = extent.height()
            longest_width = width if width > height else height
            half_length = longest_width / 2
            margin = half_length / 5
            center = extent.center()
            min_x = min_x or (center.x() - half_length - margin)
            max_x = max_x or (center.x() + half_length + margin)
            min_y = min_y or (center.y() - half_length - margin)
            max_y = max_y or (center.y() + half_length + margin)

            # noinspection PyCallingNonCallable
            square_extent = QgsRectangle(min_x, min_y, max_x, max_y)

            if component.key == 'population-infographic' and (
                    map_overview_extent):
                square_extent = map_overview_extent

            composer_map.zoomToExtent(square_extent)
            composer_map.invalidateCache()

            actual_extent = composer_map.extent()

            # calculate intervals for grid
            x_interval = actual_extent.width() / split_count
            composer_map.grid().setIntervalX(x_interval)
            y_interval = actual_extent.height() / split_count
            composer_map.grid().setIntervalY(y_interval)

    # calculate legend element
    for leg_el in context.map_legends:
        item_id = leg_el.get('id')
        title = leg_el.get('title')
        layers = [
            layer for layer in leg_el.get('layers') if isinstance(
                layer, QgsMapLayer)
        ]
        symbol_count = leg_el.get('symbol_count')
        column_count = leg_el.get('column_count')

        legend = layout_item(layout, item_id, QgsLayoutItemLegend)
        """:type: qgis.core.QgsLayoutItemLegend"""
        if legend:
            # set column count
            if column_count:
                legend.setColumnCount(column_count)
            elif symbol_count <= 7:
                legend.setColumnCount(1)
            else:
                legend.setColumnCount(symbol_count / 7 + 1)

            # set legend title
            if title is not None and not impact_report.legend_layers:
                legend.setTitle(title)

            # set legend
            root_group = legend.model().rootGroup()
            for layer in layers:
                # we need to check whether the layer is registered or not
                registered_layer = (
                    QgsProject.instance().mapLayer(layer.id()))
                if registered_layer:
                    if not registered_layer == layer:
                        layer = registered_layer
                else:
                    QgsProject.instance().addMapLayer(layer)
                # used for customizations
                tree_layer = root_group.addLayer(layer)
                if impact_report.legend_layers or (
                        not impact_report.multi_exposure_impact_function):
                    QgsLegendRenderer.setNodeLegendStyle(
                        tree_layer, QgsLegendStyle.Hidden)
            legend.adjustBoxSize()
            legend.updateFilterByMap(False)

    # process to output

    # in case output folder not specified
    if impact_report.output_folder is None:
        impact_report.output_folder = mkdtemp(dir=temp_dir())

    output_format = component.output_format
    component_output_path = impact_report.component_absolute_output_path(
        component.key)
    component_output = None

    doc_format = QgisComposerComponentsMetadata.OutputFormat.DOC_OUTPUT
    template_format = QgisComposerComponentsMetadata.OutputFormat.QPT
    if isinstance(output_format, list):
        component_output = []
        for i in range(len(output_format)):
            each_format = output_format[i]
            each_path = component_output_path[i]

            if each_format in doc_format:
                result_path = create_qgis_pdf_output(
                    impact_report,
                    each_path,
                    layout,
                    each_format,
                    component)
                component_output.append(result_path)
            elif each_format == template_format:
                result_path = create_qgis_template_output(
                    each_path, layout)
                component_output.append(result_path)
    elif isinstance(output_format, dict):
        component_output = {}
        for key, each_format in list(output_format.items()):
            each_path = component_output_path[key]

            if each_format in doc_format:
                result_path = create_qgis_pdf_output(
                    impact_report,
                    each_path,
                    layout,
                    each_format,
                    component)
                component_output[key] = result_path
            elif each_format == template_format:
                result_path = create_qgis_template_output(
                    each_path, layout)
                component_output[key] = result_path
    elif (output_format in
            QgisComposerComponentsMetadata.OutputFormat.SUPPORTED_OUTPUT):
        component_output = None

        if output_format in doc_format:
            result_path = create_qgis_pdf_output(
                impact_report,
                component_output_path,
                layout,
                output_format,
                component)
            component_output = result_path
        elif output_format == template_format:
            result_path = create_qgis_template_output(
                component_output_path, layout)
            component_output = result_path

    component.output = component_output

    return component.output
Exemplo n.º 24
0
class PyProvider(QgsVectorDataProvider):

    next_feature_id = 1

    @classmethod
    def providerKey(cls):
        """Returns the memory provider key"""
        return 'pythonprovider'

    @classmethod
    def description(cls):
        """Returns the memory provider description"""
        return 'Python Test Provider'

    @classmethod
    def createProvider(cls, uri, providerOptions):
        return PyProvider(uri, providerOptions)

    # Implementation of functions from QgsVectorDataProvider

    def __init__(self, uri='', providerOptions=QgsDataProvider.ProviderOptions()):
        super().__init__(uri)
        # Use the memory layer to parse the uri
        mlayer = QgsVectorLayer(uri, 'ml', 'memory')
        self.setNativeTypes(mlayer.dataProvider().nativeTypes())
        self._uri = uri
        self._fields = mlayer.fields()
        self._wkbType = mlayer.wkbType()
        self._features = {}
        self._extent = QgsRectangle()
        self._extent.setMinimal()
        self._subset_string = ''
        self._crs = mlayer.crs()
        self._spatialindex = None
        self._provider_options = providerOptions
        if 'index=yes'in self._uri:
            self.createSpatialIndex()

    def featureSource(self):
        return PyFeatureSource(self)

    def dataSourceUri(self, expandAuthConfig=True):
        return self._uri

    def storageType(self):
        return "Python test memory storage"

    def getFeatures(self, request=QgsFeatureRequest()):
        return QgsFeatureIterator(PyFeatureIterator(PyFeatureSource(self), request))

    def uniqueValues(self, fieldIndex, limit=1):
        results = set()
        if fieldIndex >= 0 and fieldIndex < self.fields().count():
            req = QgsFeatureRequest()
            req.setFlags(QgsFeatureRequest.NoGeometry)
            req.setSubsetOfAttributes([fieldIndex])
            for f in self.getFeatures(req):
                results.add(f.attributes()[fieldIndex])
        return results

    def wkbType(self):
        return self._wkbType

    def featureCount(self):
        if not self.subsetString():
            return len(self._features)
        else:
            req = QgsFeatureRequest()
            req.setFlags(QgsFeatureRequest.NoGeometry)
            req.setSubsetOfAttributes([])
            return len([f for f in self.getFeatures(req)])

    def fields(self):
        return self._fields

    def addFeatures(self, flist, flags=None):
        added = False
        f_added = []
        for f in flist:
            if f.hasGeometry() and (f.geometry().wkbType() != self.wkbType()):
                return added, f_added

        for f in flist:
            _f = QgsFeature(self.fields())
            _f.setGeometry(f.geometry())
            attrs = [None for i in range(_f.fields().count())]
            for i in range(min(len(attrs), len(f.attributes()))):
                attrs[i] = f.attributes()[i]
            _f.setAttributes(attrs)
            _f.setId(self.next_feature_id)
            self._features[self.next_feature_id] = _f
            self.next_feature_id += 1
            added = True
            f_added.append(_f)

            if self._spatialindex is not None:
                self._spatialindex.insertFeature(_f)

        if len(f_added):
            self.clearMinMaxCache()
            self.updateExtents()

        return added, f_added

    def deleteFeatures(self, ids):
        if not ids:
            return True
        removed = False
        for id in ids:
            if id in self._features:
                if self._spatialindex is not None:
                    self._spatialindex.deleteFeature(self._features[id])
                del self._features[id]
                removed = True
        if removed:
            self.clearMinMaxCache()
            self.updateExtents()
        return removed

    def addAttributes(self, attrs):
        try:
            for new_f in attrs:
                if new_f.type() not in (QVariant.Int, QVariant.Double, QVariant.String, QVariant.Date, QVariant.Time, QVariant.DateTime, QVariant.LongLong, QVariant.StringList, QVariant.List):
                    continue
                self._fields.append(new_f)
                for f in self._features.values():
                    old_attrs = f.attributes()
                    old_attrs.append(None)
                    f.setAttributes(old_attrs)
            self.clearMinMaxCache()
            return True
        except Exception:
            return False

    def renameAttributes(self, renamedAttributes):
        result = True
        # We need to replace all fields because python bindings return a copy from [] and at()
        new_fields = [self._fields.at(i) for i in range(self._fields.count())]
        for fieldIndex, new_name in renamedAttributes.items():
            if fieldIndex < 0 or fieldIndex >= self._fields.count():
                result = False
                continue
            if self._fields.indexFromName(new_name) >= 0:
                #field name already in use
                result = False
                continue
            new_fields[fieldIndex].setName(new_name)
        if result:
            self._fields = QgsFields()
            for i in range(len(new_fields)):
                self._fields.append(new_fields[i])
        return result

    def deleteAttributes(self, attributes):
        attrIdx = sorted(attributes, reverse=True)

        # delete attributes one-by-one with decreasing index
        for idx in attrIdx:
            self._fields.remove(idx)
            for f in self._features.values():
                attr = f.attributes()
                del(attr[idx])
                f.setAttributes(attr)
        self.clearMinMaxCache()
        return True

    def changeAttributeValues(self, attr_map):
        for feature_id, attrs in attr_map.items():
            try:
                f = self._features[feature_id]
            except KeyError:
                continue
            for k, v in attrs.items():
                f.setAttribute(k, v)
        self.clearMinMaxCache()
        return True

    def changeGeometryValues(self, geometry_map):
        for feature_id, geometry in geometry_map.items():
            try:
                f = self._features[feature_id]
                f.setGeometry(geometry)
            except KeyError:
                continue
        self.updateExtents()
        return True

    def allFeatureIds(self):
        return list(self._features.keys())

    def subsetString(self):
        return self._subset_string

    def setSubsetString(self, subsetString):
        if subsetString == self._subset_string:
            return True
        self._subset_string = subsetString
        self.updateExtents()
        self.clearMinMaxCache()
        self.dataChanged.emit()
        return True

    def supportsSubsetString(self):
        return True

    def createSpatialIndex(self):
        if self._spatialindex is None:
            self._spatialindex = QgsSpatialIndex()
            for f in self._features.values():
                self._spatialindex.insertFeature(f)
        return True

    def capabilities(self):
        return QgsVectorDataProvider.AddFeatures | QgsVectorDataProvider.DeleteFeatures | QgsVectorDataProvider.CreateSpatialIndex | QgsVectorDataProvider.ChangeGeometries | QgsVectorDataProvider.ChangeAttributeValues | QgsVectorDataProvider.AddAttributes | QgsVectorDataProvider.DeleteAttributes | QgsVectorDataProvider.RenameAttributes | QgsVectorDataProvider.SelectAtId | QgsVectorDataProvider. CircularGeometries

    #/* Implementation of functions from QgsDataProvider */

    def name(self):
        return self.providerKey()

    def extent(self):
        if self._extent.isEmpty() and self._features:
            self._extent.setMinimal()
            if not self._subset_string:
                # fast way - iterate through all features
                for feat in self._features.values():
                    if feat.hasGeometry():
                        self._extent.combineExtentWith(feat.geometry().boundingBox())
            else:
                for f in self.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([])):
                    if f.hasGeometry():
                        self._extent.combineExtentWith(f.geometry().boundingBox())

        elif not self._features:
            self._extent.setMinimal()
        return QgsRectangle(self._extent)

    def updateExtents(self):
        self._extent.setMinimal()

    def isValid(self):
        return True

    def crs(self):
        return self._crs
    def _on_set_schematisation(self, something, filename=""):
        """Method is called when schematisation setting is changed in
        datasource model.

        Args:
            something:
            filename:

        Returns: None
        """

        self.init_references_from_layer_tree()

        tracer = dict([(ref, ident) for ident, ref in self.tracer_mapping])

        if filename == "":
            if self.model_layergroup is not None:
                self.model_layergroup.removeAllChildren()
            return

        split = os.path.split(filename)
        split_dir = os.path.split(split[0])

        name = self.model_layergroup_basename + "/".join(
            (split_dir[-1], split[-1]))

        # adjust spatialite for correct visualization of layers
        threedi_db = ThreediDatabase({"db_path": filename})
        threedi_db.create_views()
        threedi_db.fix_spatial_indices()

        if self.model_layergroup is None:
            # todo: see if we can set 'tracer' as custom property to identify
            # group later on
            root = QgsProject.instance().layerTreeRoot()
            self.model_layergroup = root.insertGroup(2, name)
            self._mark(self.model_layergroup, tracer["model_layergroup"])
        else:
            self.model_layergroup.setName(name)

        if self.schematisation_layergroup is None:
            self.schematisation_layergroup = self.model_layergroup.insertGroup(
                1, self.schematisation_group_name)
            self._mark(self.schematisation_layergroup,
                       tracer["schematisation_layergroup"])
        else:
            self.schematisation_layergroup.removeAllChildren()

        self.schematisation_layergroup.insertGroup(
            0, self.schematisation_advanced_settings_group_name)

        # schematisation_inflow_group_name = 'inflow'
        # inflow_imp_surface_subgroup_name = 'impervious_surface'
        # inflow_surface_subgroup_name = 'surface'

        self.inflow_root = self.schematisation_layergroup.insertGroup(
            1, self.schematisation_inflow_group_name)
        self.inflow_root.addGroup(self.inflow_imp_surface_subgroup_name)
        self.inflow_root.addGroup(self.inflow_surface_subgroup_name)

        self.schematisation_layergroup.insertGroup(
            0, self.schematisation_grid_refinement_group_name)
        self.schematisation_layergroup.insertGroup(
            0, self.schematisation_obstacle_group_name)
        self.schematisation_layergroup.insertGroup(
            0, self.schematisation_additional_oned_group_name)
        self.schematisation_layergroup.insertGroup(
            0, self.schematisation_oned_group_name)
        self.schematisation_layergroup.insertGroup(
            0, self.schematisation_lateral_group_name)
        self.schematisation_layergroup.insertGroup(
            0, self.schematisation_boundary_group_name)
        self.schematisation_layergroup.insertGroup(
            0, self.schematisation_settings_group_name)

        # add_schematisation layers
        self._add_model_schematisation_layers(filename)

        # zoom to model extent:
        extent = QgsRectangle()
        extent.setMinimal()

        tree_layer = None
        for tree_layer in self.schematisation_layergroup.findLayers():
            extent.combineExtentWith(tree_layer.layer().extent())

        extent.scale(1.1)

        if not tree_layer:
            return

        transform = QgsCoordinateTransform(tree_layer.layer().crs(),
                                           QgsProject.instance().crs(),
                                           QgsProject.instance())

        self.iface.mapCanvas().setExtent(transform.transform(extent))

        return