Beispiel #1
0
def make_pdf():
    canvas = QgsMapCanvas()
    # Load our project
    QgsProject.instance().read(QFileInfo(project_path))
    bridge = QgsLayerTreeMapCanvasBridge(QgsProject.instance().layerTreeRoot(),
                                         canvas)
    bridge.setCanvasLayers()

    template_file = file(template_path)
    template_content = template_file.read()
    template_file.close()
    document = QDomDocument()
    document.setContent(template_content)
    composition = QgsComposition(canvas.mapSettings())
    # You can use this to replace any string like this [key]
    # in the template with a new value. e.g. to replace
    # [date] pass a map like this {'date': '1 Jan 2012'}
    substitution_map = {'DATE_TIME_START': 'foo', 'DATE_TIME_END': 'bar'}
    composition.loadFromTemplate(document, substitution_map)
    # You must set the id in the template
    map_item = composition.getComposerItemById('map')
    map_item.setMapCanvas(canvas)
    map_item.zoomToExtent(canvas.extent())
    # You must set the id in the template
    legend_item = composition.getComposerItemById('legend')
    legend_item.updateLegend()
    composition.refreshItems()
    composition.exportAsPDF('report.pdf')
    QgsProject.instance().clear()
def make_pdf():
    canvas = QgsMapCanvas()
    # Load our project
    QgsProject.instance().read(QFileInfo(project_path))
    bridge = QgsLayerTreeMapCanvasBridge(
        QgsProject.instance().layerTreeRoot(), canvas)
    bridge.setCanvasLayers()
    if canvas.layerCount() < 1:
        print 'No layers loaded from this project, exiting.'
        return
    print canvas.mapSettings().extent().toString()
    template_file = file(template_path)
    template_content = template_file.read()
    template_file.close()
    document = QDomDocument()
    document.setContent(template_content)
    composition = QgsComposition(canvas.mapSettings())
    # You can use this to replace any string like this [key]
    # in the template with a new value. e.g. to replace
    # [date] pass a map like this {'date': '1 Jan 2012'}
    substitution_map = {
        'DATE_TIME_START': TIME_START,
        'DATE_TIME_END': TIME_STOP}
    composition.loadFromTemplate(document, substitution_map)
    # You must set the id in the template
    map_item = composition.getComposerItemById('map')
    map_item.setMapCanvas(canvas)
    map_item.zoomToExtent(canvas.extent())
    # You must set the id in the template
    legend_item = composition.getComposerItemById('legend')
    legend_item.updateLegend()
    composition.refreshItems()
    composition.exportAsPDF(
        '/home/web/reports/pdf/%s/%s.pdf' % (TIME_SLICE, LABEL))
    QgsProject.instance().clear()
Beispiel #3
0
def make_pdf(xmin, ymin, xmax, ymax, filter_expression):
    canvas = QgsMapCanvas()
    # Load our project
    QgsProject.instance().read(QFileInfo(project_path))

    # Set canvas extent
    canvas.setExtent(QgsRectangle(xmin, ymin, xmax, ymax))

    # Load layers here if they are not already in the project
    for layer in QgsMapLayerRegistry.instance().mapLayers().values():
        if layer.name() == 'data':
            lyr = layer
            break
    lyr.setSubsetString(filter_expression)

    # bridge used in standalone script: http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/loadproject.html
    bridge = QgsLayerTreeMapCanvasBridge(QgsProject.instance().layerTreeRoot(),
                                         canvas)
    bridge.setCanvasLayers()

    # Check data providers load ok
    print('Provider List')
    print(QgsProviderRegistry.instance().providerList())

    # Print layer validity - I've had some trouble with some wms layers
    for layer in QgsMapLayerRegistry.instance().mapLayers().values():
        print(layer.name())
        print(layer.isValid())

    template_file = file(template_path)
    template_content = template_file.read()
    template_file.close()
    document = QDomDocument()
    document.setContent(template_content)
    composition = QgsComposition(canvas.mapSettings())
    # You can use this to replace any string like this [key]
    # in the template with a new value. e.g. to replace
    # [date] pass a map like this {'date': '1 Jan 2012'}
    substitution_map = {'title': 'the title of my map'}
    composition.loadFromTemplate(document, substitution_map)
    # You must set the id in the template
    map_item = composition.getComposerItemById('Main Map')
    map_item.setMapCanvas(canvas)
    map_item.zoomToExtent(canvas.extent())
    # You must set the id in the template
    legend_item = composition.getComposerItemById('Legend')
    legend_item.updateLegend()
    composition.refreshItems()
    composition.exportAsPDF('export.pdf')
    QgsProject.instance().clear()
 def export_pdf(self, title=''):
     '''
     Export Composition (map view and checked layers) to PDF
     '''
     title = self.active_scenario.name if self.active_scenario else ''
     dialog = ExportPDFDialog(title=title, parent=self)
     result = dialog.exec_()
     ok = result == QtGui.QDialog.Accepted
     if not ok:
         return
     title = dialog.title
     date = dialog.date
     filepath = browse_file(None, 'Export', PDF_FILTER, save=True, 
                            parent=self)
     if not filepath:
         return
     bridge = QgsLayerTreeMapCanvasBridge(
         QgsProject.instance().layerTreeRoot(), self.canvas)
     bridge.setCanvasLayers()
 
     template_file = file(REPORT_TEMPLATE_PATH)
     template_content = template_file.read()
     template_file.close()
     document = QDomDocument()
     document.setContent(template_content)
     composition = QgsComposition(self.canvas.mapSettings())
     # You can use this to replace any string like this [key]
     # in the template with a new value. e.g. to replace
     # [date] pass a map like this {'date': '1 Jan 2012'}
     substitution_map = {
         'TITLE': title,
         'DATE_TIME': date}
     composition.loadFromTemplate(document, substitution_map)
     # You must set the id in the template
     map_item = composition.getComposerItemById('map')
     map_item.setMapCanvas(self.canvas)
     map_item.zoomToExtent(self.canvas.extent())
     # You must set the id in the template
     legend_item = composition.getComposerItemById('legend')
     legend_item.updateLegend()
     composition.refreshItems()
     composition.exportAsPDF(filepath)
     if sys.platform.startswith('darwin'):
         subprocess.call(('open', filepath))
     elif os.name == 'nt':
         os.startfile(filepath)
     elif os.name == 'posix':
         subprocess.call(('xdg-open', filepath))
Beispiel #5
0
 def from_file(cls, filename, canvas, relative_base=None):
     """
     Load a project file from a path.
     :param filename: The path to the project file.
     :param canvas: (optional) Passing a canvas will auto add layers to the canvas when the load is
     loaded.
     :param relative_base_path: (optional) Relative base path for the project file to load layers from
     :return: A Project object which wraps QgsProject.instance()
     """
     QgsProject.instance().clear()
     bridge = None
     if canvas:
         bridge = QgsLayerTreeMapCanvasBridge(QgsProject.instance().layerTreeRoot(), canvas)
     if relative_base is None:
         relative_base = os.path.dirname(filename)
     QDir.setCurrent(relative_base)
     QgsProject.instance().read(QFileInfo(filename))
     if bridge:
         bridge.setCanvasLayers()
     return cls(bridge)
Beispiel #6
0
def export_map(layer, new_extent):
    """This function changes the map extents and creates a exported map image"""
    legend = iface.legendInterface()
    legend.setLayerVisible(layer, False)
    canvas = iface.mapCanvas()
    canvas.setExtent(new_extent)
    canvas.refresh()
    project_path = os.path.join(gis_files, 'air_tasking_order.qgs')
    QgsProject.instance().write(QFileInfo(project_path))    #Save with the flight lines
    QgsProject.instance().read(QFileInfo(project_path))
    bridge = QgsLayerTreeMapCanvasBridge(
        QgsProject.instance().layerTreeRoot(), canvas)
    bridge.setCanvasLayers()
    template_file = file(os.path.join(gis_files, 'airborne_survey.qpt'))
    template_content = template_file.read()
    template_file.close()
    document = QDomDocument()
    document.setContent(template_content)
    ms = canvas.mapSettings()
    composition = QgsComposition(ms)
    composition.loadFromTemplate(document, {})
    map_item = composition.getComposerItemById('the_map')
    map_item.setMapCanvas(canvas)
    map_item.zoomToExtent(canvas.extent())
    map_text_box = '<font face="Arial">%s Tasking <br />%s - %s<br />%s' % (
        Requesting_RFC, Survey_Start_Date, Survey_End_Date, Survey_Name)
    map_text = composition.getComposerItemById('Map_ID_Text')
    map_text.setText(map_text_box)
    composition.refreshItems()
    dpi = 300
    dpmm = dpi / 24.4
    width = int(dpmm * composition.paperWidth())
    height = int(dpmm * composition.paperHeight())
    image = QImage(QSize(width, height), QImage.Format_ARGB32)
    image.setDotsPerMeterX(dpmm * 1000)
    image.setDotsPerMeterY(dpmm * 1000)
    imagePainter = QPainter(image)
    composition.renderPage(imagePainter, 0)
    imagePainter.end()
    image.save(Survey_Name + '.png', 'png')
Beispiel #7
0
class QgisInterface(QObject):
    """Class to expose qgis objects and functions to plugins.

    This class is here for enabling us to run unit tests only,
    so most methods are simply stubs.
    """
    currentLayerChanged = pyqtSignal(QgsMapCanvasLayer)
    layerSavedAs = pyqtSignal(QgsMapLayer, str)

    def __init__(self, canvas):
        """Constructor
        :param canvas:
        """
        QObject.__init__(self)
        self.canvas = canvas
        self.legend = QgisLegend(canvas)
        self.message_bar = QgsMessageBar(None)
        # Set up slots so we can mimic the behaviour of QGIS when layers
        # are added.
        LOGGER.debug('Initialising canvas...')
        # noinspection PyArgumentList
        QgsMapLayerRegistry.instance().layersAdded.connect(self.addLayers)
        # noinspection PyArgumentList
        QgsMapLayerRegistry.instance().layerWasAdded.connect(self.addLayer)
        # noinspection PyArgumentList
        QgsMapLayerRegistry.instance().removeAll.connect(self.removeAllLayers)

        # For processing module
        self.destCrs = None
        # For keeping track of which layer is active in the legend.
        self.active_layer = None

        # In the next section of code, we are going to do some monkey patching
        # to make the QGIS processing framework think that this mock QGIS IFACE
        # instance is the actual one. It will also ensure that the processing
        # algorithms are nicely loaded and available for use.

        # Since QGIS > 2.0, the module is moved from QGisLayers to dataobjects
        # pylint: disable=F0401, E0611
        if QGis.QGIS_VERSION_INT > 20001:
            # noinspection PyUnresolvedReferences
            from processing.tools import dataobjects
        else:
            # noinspection PyUnresolvedReferences
            from processing.core import QGisLayers as dataobjects

        # noinspection PyUnresolvedReferences
        import processing
        # noinspection PyUnresolvedReferences
        from processing.core.Processing import Processing
        # pylint: enable=F0401, E0611
        processing.classFactory(self)

        # We create our own getAlgorithm function below which will will monkey
        # patch in to the Processing class in QGIS in order to ensure that the
        # Processing.initialize() call is made before asking for an alg.

        @staticmethod
        def mock_getAlgorithm(name):
            """
            Modified version of the original getAlgorithm function.

            :param name: Name of the algorithm to load.
            :type name: str

            :return: An algorithm concrete class.
            :rtype: QgsAlgorithm  ?
            """
            Processing.initialize()
            for provider in Processing.algs.values():
                if name in provider:
                    return provider[name]
            return None

        # Now we let the monkey loose!
        Processing.getAlgorithm = mock_getAlgorithm
        # We also need to make dataobjects think that this iface is 'the one'
        # Note. the placement here (after the getAlgorithm monkey patch above)
        # is significant, so don't move it!
        dataobjects.iface = self

        # set up a layer tree bridge so that new added layers appear in legend
        self.layer_tree_root = QgsProject.instance().layerTreeRoot()
        self.bridge = QgsLayerTreeMapCanvasBridge(self.layer_tree_root,
                                                  self.canvas)
        self.bridge.setCanvasLayers()

    def __getattr__(self, *args, **kwargs):
        # It's for processing module
        def dummy(*a, **kwa):
            _ = a, kwa
            return QgisInterface(self.canvas)

        return dummy

    def __iter__(self):
        # It's for processing module
        return self

    def next(self):
        # It's for processing module
        raise StopIteration

    def layers(self):
        # It's for processing module
        # simulate iface.legendInterface().layers()
        return QgsMapLayerRegistry.instance().mapLayers().values()

    @pyqtSlot('QStringList')
    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 = []
        # We need to keep the record of the registered layers on our canvas!
        registered_layers = []
        for layer in current_layers:
            final_layers.append(QgsMapCanvasLayer(layer))
            registered_layers.append(layer.id())
        for layer in layers:
            if layer.id() not in registered_layers:
                final_layers.append(QgsMapCanvasLayer(layer))

        self.canvas.setLayerSet(final_layers)
        # LOGGER.debug('Layer Count After: %s' % len(self.canvas.layers()))

    @pyqtSlot('QgsMapLayer')
    def addLayer(self, layer):
        """Handle a layer being added to the registry so it shows up in canvas.

        :param layer: 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.

        .. note: The addLayer method was deprecated in QGIS 1.8 so you should
                 not need this method much.
        """
        pass

    @pyqtSlot()
    def removeAllLayers(self, ):
        """Remove layers from the canvas before they get deleted.

        .. note:: This is NOT part of the QGisInterface API but is needed
            to support QgsMapLayerRegistry.removeAllLayers().

        """
        self.canvas.setLayerSet([])
        self.active_layer = None

    def newProject(self):
        """Create new project."""
        # noinspection PyArgumentList
        QgsMapLayerRegistry.instance().removeAllMapLayers()

    # ---------------- API Mock for QgsInterface follows -------------------

    def zoomFull(self):
        """Zoom to the map full extent."""
        pass

    def zoomToPrevious(self):
        """Zoom to previous view extent."""
        pass

    def zoomToNext(self):
        """Zoom to next view extent."""
        pass

    def zoomToActiveLayer(self):
        """Zoom to extent of active layer."""
        pass

    def addVectorLayer(self, path, base_name, provider_key):
        """Add a vector layer.

        :param path: Path to layer.
        :type path: str

        :param base_name: Base name for layer.
        :type base_name: str

        :param provider_key: Provider key e.g. 'ogr'
        :type provider_key: str
        """
        pass

    def addRasterLayer(self, path, base_name):
        """Add a raster layer given a raster layer file name

        :param path: Path to layer.
        :type path: str

        :param base_name: Base name for layer.
        :type base_name: str
        """
        pass

    def setActiveLayer(self, layer):
        """Set the currently active layer in the legend.
        :param layer: Layer to make active.
        :type layer: QgsMapLayer, QgsVectorLayer, QgsRasterLayer
        """
        self.active_layer = layer

    def activeLayer(self):
        """Get pointer to the active layer (layer selected in the legend)."""
        if self.active_layer is not None:
            return self.active_layer
        else:
            return None

    def addToolBarIcon(self, action):
        """Add an icon to the plugins toolbar.

        :param action: Action to add to the toolbar.
        :type action: QAction
        """
        pass

    def removeToolBarIcon(self, action):
        """Remove an action (icon) from the plugin toolbar.

        :param action: Action to add to the toolbar.
        :type action: QAction
        """
        pass

    def addToolBar(self, name):
        """Add toolbar with specified name.

        :param name: Name for the toolbar.
        :type name: str
        """
        pass

    def mapCanvas(self):
        """Return a pointer to the map canvas."""
        return self.canvas

    def mainWindow(self):
        """Return a pointer to the main window.

        In case of QGIS it returns an instance of QgisApp.
        """
        pass

    def addDockWidget(self, area, dock_widget):
        """Add a dock widget to the main window.

        :param area: Where in the ui the dock should be placed.
        :type area:

        :param dock_widget: A dock widget to add to the UI.
        :type dock_widget: QDockWidget
        """
        pass

    def legendInterface(self):
        """Get the legend.

        See also discussion at:

        https://github.com/AIFDR/inasafe/pull/924/

        Implementation added for version 3.2.
        """
        return self.legend

    def messageBar(self):
        """Get the message bar.

        .. versionadded:: 3.2

        :returns: A QGIS message bar instance
        :rtype: QgsMessageBar
        """
        return self.message_bar
Beispiel #8
0
gui_flag = True
app = QgsApplication(sys.argv, True)
QgsApplication.setPrefixPath("/usr", True)
QgsApplication.initQgis()

project_path = 'report_maps.qgs'
template_path = 'owner_occupancy.qpt'

canvas = QgsMapCanvas()
canvas.resize(QSize(1450, 850))
#start = time.time()
QgsProject.instance().read(QFileInfo(project_path))
#end = time.time()
root = QgsProject.instance().layerTreeRoot()
bridge = QgsLayerTreeMapCanvasBridge(root, canvas)
bridge.setCanvasLayers()
registry = QgsMapLayerRegistry.instance()

template_file = file(template_path)
template_content = template_file.read()
template_file.close()
document = QDomDocument()
document.setContent(template_content)
map_settings = canvas.mapSettings()
composition = QgsComposition(map_settings)
#start = time.time()
composition.loadFromTemplate(document)
#end = time.time()

#create list of all layers currently in the map
map_layers = [lyr for lyr in registry.mapLayers() if root.findLayer(lyr)]
    def print_atlas(self,
                    project_path,
                    composer_name,
                    predefined_scales,
                    feature_filter=None,
                    page_name_expression=None):

        # Get composer from project
        # in QGIS 2, canno get composers without iface
        # so we reading project xml and extract composer
        # in QGIS 3.0, we will use  project layoutManager()
        from xml.etree import ElementTree as ET
        composer_xml = None
        with open(project_path, 'r') as f:
            tree = ET.parse(f)
            for elem in tree.findall('.//Composer[@title="%s"]' %
                                     composer_name):
                composer_xml = ET.tostring(elem, encoding='utf8', method='xml')

        if not composer_xml:
            return

        document = QDomDocument()
        document.setContent(composer_xml)

        # Get canvas, map setting & instantiate composition
        canvas = QgsMapCanvas()
        QgsProject.instance().read(QFileInfo(project_path))
        bridge = QgsLayerTreeMapCanvasBridge(
            QgsProject.instance().layerTreeRoot(), canvas)
        bridge.setCanvasLayers()
        ms = canvas.mapSettings()
        composition = QgsComposition(ms)

        # Load content from XML
        substitution_map = {}
        composition.loadFromTemplate(document, substitution_map)

        # Get atlas for this composition
        atlas = composition.atlasComposition()
        atlas.setEnabled(True)
        atlas_map = composition.getComposerMapById(0)
        atlas_map.setAtlasScalingMode(QgsComposerMap.Predefined)

        # get project scales
        atlas.setPredefinedScales(predefined_scales)
        atlas.setComposerMap(atlas_map)

        #on definit le filtre
        if feature_filter:
            atlas.setFilterFeatures(True)
            atlas.setFeatureFilter(feature_filter)
        if page_name_expression:
            atlas.setPageNameExpression(page_name_expression)

        # Set atlas mode
        composition.setAtlasMode(QgsComposition.ExportAtlas)

        # Generate atlas
        atlas.beginRender()
        uid = uuid4()
        for i in range(0, atlas.numFeatures()):
            atlas.prepareForFeature(i)
            export_path = os.path.join(
                tempfile.gettempdir(),
                '%s_%s.pdf' % (atlas.nameForPage(i), uid))
            exported = composition.exportAsPDF(export_path)
            if not exported or not os.path.isfile(export_path):
                return None
            break

        atlas.endRender()

        return export_path
Beispiel #10
0
class QgisInterface(QObject):
    """Class to expose qgis objects and functions to plugins.

    This class is here for enabling us to run unit tests only,
    so most methods are simply stubs.
    """

    currentLayerChanged = pyqtSignal(QgsMapCanvasLayer)
    layerSavedAs = pyqtSignal(QgsMapLayer, str)

    def __init__(self, canvas):
        """Constructor
        :param canvas:
        """
        QObject.__init__(self)
        self.canvas = canvas
        self.legend = QgisLegend(canvas)
        self.message_bar = QgsMessageBar(None)
        # Set up slots so we can mimic the behaviour of QGIS when layers
        # are added.
        LOGGER.debug("Initialising canvas...")
        # noinspection PyArgumentList
        QgsMapLayerRegistry.instance().layersAdded.connect(self.addLayers)
        # noinspection PyArgumentList
        QgsMapLayerRegistry.instance().layerWasAdded.connect(self.addLayer)
        # noinspection PyArgumentList
        QgsMapLayerRegistry.instance().removeAll.connect(self.removeAllLayers)

        # For processing module
        self.destCrs = None
        # For keeping track of which layer is active in the legend.
        self.active_layer = None

        # In the next section of code, we are going to do some monkey patching
        # to make the QGIS processing framework think that this mock QGIS IFACE
        # instance is the actual one. It will also ensure that the processing
        # algorithms are nicely loaded and available for use.

        # Since QGIS > 2.0, the module is moved from QGisLayers to dataobjects
        # pylint: disable=F0401, E0611
        if QGis.QGIS_VERSION_INT > 20001:
            # noinspection PyUnresolvedReferences
            from processing.tools import dataobjects
        else:
            # noinspection PyUnresolvedReferences
            from processing.core import QGisLayers as dataobjects

        # noinspection PyUnresolvedReferences
        import processing

        # noinspection PyUnresolvedReferences
        from processing.core.Processing import Processing

        # pylint: enable=F0401, E0611
        processing.classFactory(self)

        # We create our own getAlgorithm function below which will will monkey
        # patch in to the Processing class in QGIS in order to ensure that the
        # Processing.initialize() call is made before asking for an alg.

        @staticmethod
        def mock_getAlgorithm(name):
            """
            Modified version of the original getAlgorithm function.

            :param name: Name of the algorithm to load.
            :type name: str

            :return: An algorithm concrete class.
            :rtype: QgsAlgorithm  ?
            """
            Processing.initialize()
            for provider in Processing.algs.values():
                if name in provider:
                    return provider[name]
            return None

        # Now we let the monkey loose!
        Processing.getAlgorithm = mock_getAlgorithm
        # We also need to make dataobjects think that this iface is 'the one'
        # Note. the placement here (after the getAlgorithm monkey patch above)
        # is significant, so don't move it!
        dataobjects.iface = self

        # set up a layer tree bridge so that new added layers appear in legend
        self.layer_tree_root = QgsProject.instance().layerTreeRoot()
        self.bridge = QgsLayerTreeMapCanvasBridge(self.layer_tree_root, self.canvas)
        self.bridge.setCanvasLayers()

    def __getattr__(self, *args, **kwargs):
        # It's for processing module
        def dummy(*a, **kwa):
            _ = a, kwa
            return QgisInterface(self.canvas)

        return dummy

    def __iter__(self):
        # It's for processing module
        return self

    def next(self):
        # It's for processing module
        raise StopIteration

    def layers(self):
        # It's for processing module
        # simulate iface.legendInterface().layers()
        return QgsMapLayerRegistry.instance().mapLayers().values()

    @pyqtSlot("QStringList")
    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 = []
        # We need to keep the record of the registered layers on our canvas!
        registered_layers = []
        for layer in current_layers:
            final_layers.append(QgsMapCanvasLayer(layer))
            registered_layers.append(layer.id())
        for layer in layers:
            if layer.id() not in registered_layers:
                final_layers.append(QgsMapCanvasLayer(layer))

        self.canvas.setLayerSet(final_layers)
        # LOGGER.debug('Layer Count After: %s' % len(self.canvas.layers()))

    @pyqtSlot("QgsMapLayer")
    def addLayer(self, layer):
        """Handle a layer being added to the registry so it shows up in canvas.

        :param layer: 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.

        .. note: The addLayer method was deprecated in QGIS 1.8 so you should
                 not need this method much.
        """
        pass

    @pyqtSlot()
    def removeAllLayers(self,):
        """Remove layers from the canvas before they get deleted.

        .. note:: This is NOT part of the QGisInterface API but is needed
            to support QgsMapLayerRegistry.removeAllLayers().

        """
        self.canvas.setLayerSet([])
        self.active_layer = None

    def newProject(self):
        """Create new project."""
        # noinspection PyArgumentList
        QgsMapLayerRegistry.instance().removeAllMapLayers()

    # ---------------- API Mock for QgsInterface follows -------------------

    def zoomFull(self):
        """Zoom to the map full extent."""
        pass

    def zoomToPrevious(self):
        """Zoom to previous view extent."""
        pass

    def zoomToNext(self):
        """Zoom to next view extent."""
        pass

    def zoomToActiveLayer(self):
        """Zoom to extent of active layer."""
        pass

    def addVectorLayer(self, path, base_name, provider_key):
        """Add a vector layer.

        :param path: Path to layer.
        :type path: str

        :param base_name: Base name for layer.
        :type base_name: str

        :param provider_key: Provider key e.g. 'ogr'
        :type provider_key: str
        """
        pass

    def addRasterLayer(self, path, base_name):
        """Add a raster layer given a raster layer file name

        :param path: Path to layer.
        :type path: str

        :param base_name: Base name for layer.
        :type base_name: str
        """
        pass

    def setActiveLayer(self, layer):
        """Set the currently active layer in the legend.
        :param layer: Layer to make active.
        :type layer: QgsMapLayer, QgsVectorLayer, QgsRasterLayer
        """
        self.active_layer = layer

    def activeLayer(self):
        """Get pointer to the active layer (layer selected in the legend)."""
        if self.active_layer is not None:
            return self.active_layer
        else:
            return None

    def addToolBarIcon(self, action):
        """Add an icon to the plugins toolbar.

        :param action: Action to add to the toolbar.
        :type action: QAction
        """
        pass

    def removeToolBarIcon(self, action):
        """Remove an action (icon) from the plugin toolbar.

        :param action: Action to add to the toolbar.
        :type action: QAction
        """
        pass

    def addToolBar(self, name):
        """Add toolbar with specified name.

        :param name: Name for the toolbar.
        :type name: str
        """
        pass

    def mapCanvas(self):
        """Return a pointer to the map canvas."""
        return self.canvas

    def mainWindow(self):
        """Return a pointer to the main window.

        In case of QGIS it returns an instance of QgisApp.
        """
        pass

    def addDockWidget(self, area, dock_widget):
        """Add a dock widget to the main window.

        :param area: Where in the ui the dock should be placed.
        :type area:

        :param dock_widget: A dock widget to add to the UI.
        :type dock_widget: QDockWidget
        """
        pass

    def legendInterface(self):
        """Get the legend.

        See also discussion at:

        https://github.com/AIFDR/inasafe/pull/924/

        Implementation added for version 3.2.
        """
        return self.legend

    def messageBar(self):
        """Get the message bar.

        .. versionadded:: 3.2

        :returns: A QGIS message bar instance
        :rtype: QgsMessageBar
        """
        return self.message_bar
Beispiel #11
0
def print_atlas(project, layout_name, feature_filter, scales=None, scale=None):
    """Generate an atlas.

    :param project: The project to render as atlas.
    :type project: QgsProject

    :param layout_name: Name of the layout.
    :type layout_name: basestring

    :param feature_filter: QGIS Expression to use to select the feature.
    It can return many features, a multiple pages PDF will be returned.
    :type feature_filter: basestring

    :param scale: A scale to force in the atlas context. Default to None.
    :type scale: int

    :param scales: A list of predefined list of scales to force in the atlas context.
    Default to None.
    :type scales: list

    :return: Path to the PDF.
    :rtype: basestring
    """
    canvas = QgsMapCanvas()
    bridge = QgsLayerTreeMapCanvasBridge(project.layerTreeRoot(), canvas)
    bridge.setCanvasLayers()
    manager = project.layoutManager()
    master_layout = manager.layoutByName(layout_name)

    if not master_layout:
        raise AtlasPrintException('Layout not found')

    if master_layout.layoutType() != QgsMasterLayoutInterface.PrintLayout:
        raise AtlasPrintException('The layout is not a print layout')

    for l in manager.printLayouts():
        if l.name() == layout_name:
            layout = l
            break
    else:
        raise AtlasPrintException('The layout is not found')

    atlas = layout.atlas()

    if not atlas.enabled():
        raise AtlasPrintException('The layout is not enabled for an atlas')

    settings = QgsLayoutExporter.PdfExportSettings()

    if scale:
        layout.referenceMap().setAtlasScalingMode(QgsLayoutItemMap.Fixed)
        layout.referenceMap().setScale(scale)

    if scales:
        layout.referenceMap().setAtlasScalingMode(QgsLayoutItemMap.Predefined)
        if Qgis.QGIS_VERSION_INT >= 30900:
            settings.predefinedMapScales = scales
        else:
            layout.reportContext().setPredefinedScales(scales)

    layer = atlas.coverageLayer()
    feature_filter = optimize_expression(layer, feature_filter)

    expression = QgsExpression(feature_filter)
    if expression.hasParserError():
        raise AtlasPrintException(
            'Expression is invalid, parser error: {}'.format(
                expression.parserErrorString()))

    context = QgsExpressionContext()
    context.appendScope(QgsExpressionContextUtils.globalScope())
    context.appendScope(QgsExpressionContextUtils.projectScope(project))
    context.appendScope(QgsExpressionContextUtils.layoutScope(layout))
    context.appendScope(QgsExpressionContextUtils.atlasScope(atlas))
    context.appendScope(QgsExpressionContextUtils.layerScope(layer))

    expression.prepare(context)
    if expression.hasEvalError():
        raise AtlasPrintException(
            'Expression is invalid, eval error: {}'.format(
                expression.evalErrorString()))

    atlas.setFilterFeatures(True)
    atlas.setFilterExpression(feature_filter)

    if not scales and layout.referenceMap().atlasScalingMode(
    ) == QgsLayoutItemMap.Predefined:
        if Qgis.QGIS_VERSION_INT >= 30900:
            use_project = project.useProjectScales()
            map_scales = project.mapScales()
        else:
            map_scales = project_scales(project)
            use_project = len(map_scales) == 0

        if not use_project or len(map_scales) == 0:
            QgsMessageLog.logMessage(
                'Map scales not found in project, fetching predefined map scales in global config',
                'atlasprint', Qgis.Info)
            map_scales = global_scales()

        if Qgis.QGIS_VERSION_INT >= 30900:
            settings.predefinedMapScales = map_scales
        else:
            layout.reportContext().setPredefinedScales(map_scales)

    export_path = os.path.join(tempfile.gettempdir(),
                               '{}_{}.pdf'.format(layout_name, uuid4()))
    exporter = QgsLayoutExporter(layout)
    result = exporter.exportToPdf(atlas, export_path, settings)

    if result[0] != QgsLayoutExporter.Success and not os.path.isfile(
            export_path):
        raise Exception('export not generated {}'.format(export_path))

    return export_path
Beispiel #12
0
    def print_atlas(project_path, composer_name, predefined_scales, feature_filter, page_name_expression=None):
        if not feature_filter:
            QgsMessageLog.logMessage("atlasprint: NO feature_filter provided !", 'atlasprint', Qgis.Critical)
            return None

        # Get composer from project
        # in QGIS 2, we can't get composers without iface
        # so we reading project xml and extract composer
        # TODO Since QGIS 3.0, we should be able to use project layoutManager()
        # noinspection PyPep8Naming
        from xml.etree import ElementTree as ET
        composer_xml = None
        with open(project_path, 'r') as f:
            tree = ET.parse(f)
            for elem in tree.findall('.//Composer[@title="%s"]' % composer_name):
                composer_xml = ET.tostring(
                    elem,
                    encoding='utf8',
                    method='xml'
                )
            if not composer_xml:
                for elem in tree.findall('.//Layout[@name="%s"]' % composer_name):
                    composer_xml = ET.tostring(
                        elem,
                        encoding='utf8',
                        method='xml'
                    )

        if not composer_xml:
            QgsMessageLog.logMessage("atlasprint: Composer XML not parsed !", 'atlasprint', Qgis.Critical)
            return None

        document = QDomDocument()
        document.setContent(composer_xml)

        # Get canvas, map setting & instantiate composition
        canvas = QgsMapCanvas()
        project = QgsProject()
        project.read(project_path)
        bridge = QgsLayerTreeMapCanvasBridge(
            project.layerTreeRoot(),
            canvas
        )
        bridge.setCanvasLayers()

        layout = QgsPrintLayout(project)

        # Load content from XML
        layout.loadFromTemplate(
            document,
            QgsReadWriteContext(),
        )

        atlas = layout.atlas()
        atlas.setEnabled(True)

        atlas_map = layout.referenceMap()
        atlas_map.setAtlasDriven(True)
        atlas_map.setAtlasScalingMode(QgsLayoutItemMap.Predefined)

        layout.reportContext().setPredefinedScales(predefined_scales)

        if page_name_expression:
            atlas.setPageNameExpression(page_name_expression)

        # Filter feature here to avoid QGIS looping through every feature when doing : composition.setAtlasMode(QgsComposition.ExportAtlas)
        coverage_layer = atlas.coverageLayer()

        # Filter by FID as QGIS cannot compile expressions with $id or other $ vars
        # which leads to bad performance for big dataset
        use_fid = None
        if '$id' in feature_filter:
            import re
            ids = list(map(int, re.findall(r'\d+', feature_filter)))
            if len(ids) > 0:
                use_fid = ids[0]
        if use_fid:
            qReq = QgsFeatureRequest().setFilterFid(use_fid)
        else:
            qReq = QgsFeatureRequest().setFilterExpression(feature_filter)

        # Change feature_filter in order to improve performance
        pks = coverage_layer.dataProvider().pkAttributeIndexes()
        if use_fid and len(pks) == 1:
            pk = coverage_layer.dataProvider().fields()[pks[0]].name()
            feature_filter = '"%s" IN (%s)' % (pk, use_fid)
            QgsMessageLog.logMessage("atlasprint: feature_filter changed into: %s" % feature_filter, 'atlasprint', Qgis.Info)
            qReq = QgsFeatureRequest().setFilterExpression(feature_filter)
        atlas.setFilterFeatures(True)
        atlas.setFilterExpression(feature_filter)
        uid = uuid4()
        i = 0  # We use a single page for now.

        atlas.beginRender()
        atlas.seekTo(i)

        # setup settings
        settings = QgsLayoutExporter.PdfExportSettings()
        export_path = os.path.join(
                tempfile.gettempdir(),
                '%s_%s.pdf' % (atlas.nameForPage(i), uid)
        )
        exporter = QgsLayoutExporter(layout)
        result = exporter.exportToPdf(export_path, settings)

        atlas.endRender()
        if result != QgsLayoutExporter.Success:
            QgsMessageLog.logMessage("atlasprint: export not generated %s" % export_path, 'atlasprint', Qgis.Critical)
            return None

        if not os.path.isfile(export_path):
            QgsMessageLog.logMessage("atlasprint: export not generated %s" % export_path, 'atlasprint', Qgis.Critical)
            return None

        QgsMessageLog.logMessage("atlasprint: path generated %s" % export_path, 'atlasprint', Qgis.Success)
        return export_path
    def print_atlas(self,
                    project_path,
                    composer_name,
                    predefined_scales,
                    feature_filter=None,
                    page_name_expression=None):

        if not feature_filter:
            QgsMessageLog.logMessage(
                "atlasprint: NO feature_filter provided !")
            return None

        # Get composer from project
        # in QGIS 2, canno get composers without iface
        # so we reading project xml and extract composer
        # in QGIS 3.0, we will use  project layoutManager()
        from xml.etree import ElementTree as ET
        composer_xml = None
        with open(project_path, 'r') as f:
            tree = ET.parse(f)
            for elem in tree.findall('.//Composer[@title="%s"]' %
                                     composer_name):
                composer_xml = ET.tostring(elem, encoding='utf8', method='xml')

        if not composer_xml:
            QgsMessageLog.logMessage("atlasprint: Composer XML not parsed !")
            return None

        document = QDomDocument()
        document.setContent(composer_xml)

        # Get canvas, map setting & instantiate composition
        canvas = QgsMapCanvas()
        QgsProject.instance().read(QFileInfo(project_path))
        bridge = QgsLayerTreeMapCanvasBridge(
            QgsProject.instance().layerTreeRoot(), canvas)
        bridge.setCanvasLayers()
        ms = canvas.mapSettings()
        composition = QgsComposition(ms)

        # Load content from XML
        substitution_map = {}
        composition.loadFromTemplate(document, substitution_map)

        # Get atlas for this composition
        atlas = composition.atlasComposition()
        atlas.setEnabled(True)

        atlas_map = composition.getComposerMapById(0)
        atlas_map.setAtlasScalingMode(QgsComposerMap.Predefined)

        # get project scales
        atlas.setPredefinedScales(predefined_scales)
        atlas_map.setAtlasDriven(True)
        #atlas.setComposerMap(atlas_map)

        if page_name_expression:
            atlas.setPageNameExpression(page_name_expression)

        # Filter feature here to avoid QGIS looping through every feature when doing : composition.setAtlasMode(QgsComposition.ExportAtlas)
        coverageLayer = atlas.coverageLayer()

        # Filter by FID as QGIS cannot compile expressions with $id or other $ vars
        # which leads to bad perfs for big datasets
        useFid = None
        if '$id' in feature_filter:
            import re
            ids = map(int, re.findall(r'\d+', feature_filter))
            if len(ids) > 0:
                useFid = ids[0]
        if useFid:
            qReq = QgsFeatureRequest().setFilterFid(useFid)
        else:
            qReq = QgsFeatureRequest().setFilterExpression(feature_filter)

        # Change feature_filter in order to improve perfs
        pks = coverageLayer.dataProvider().pkAttributeIndexes()
        if useFid and len(pks) == 1:
            pk = coverageLayer.dataProvider().fields()[pks[0]].name()
            feature_filter = '"%s" IN (%s)' % (pk, useFid)
            QgsMessageLog.logMessage(
                "atlasprint: feature_filter changed into: %s" % feature_filter)
            qReq = QgsFeatureRequest().setFilterExpression(feature_filter)
        atlas.setFilterFeatures(True)
        atlas.setFeatureFilter(feature_filter)
        uid = uuid4()
        i = 0

        # Set Atlas mode
        composition.setAtlasMode(QgsComposition.ExportAtlas)
        atlas.beginRender()

        for feat in coverageLayer.getFeatures(qReq):
            atlas.prepareForFeature(feat)
            export_path = os.path.join(
                tempfile.gettempdir(),
                '%s_%s.pdf' % (atlas.nameForPage(i), uid))
            exported = composition.exportAsPDF(export_path)
            if not exported or not os.path.isfile(export_path):
                QgsMessageLog.logMessage(
                    "atlasprint: An error occured while exporting the atlas !")
                return None

            break

        atlas.endRender()

        if os.path.isfile(export_path):
            QgsMessageLog.logMessage("atlasprint: path generated %s" %
                                     export_path)
        return export_path
class see_map(QDialog):
    #app2 = QgsApplication([], True)
    #app2.initQgis()
    def __init__(self, file_name):
        super().__init__()

        # Creación del Lienzo / Canvas
        self.canvas = QgsMapCanvas(self)
        self.setWindowTitle("Map of Track  /  Mapa del Recorrido")
        self.canvas.setCanvasColor(Qt.white)

        self.initGui()

        if not file_name == None:
            vlayer = QgsVectorLayer(file_name, "Track Converted", "ogr")
            #vlayer.updateExtents()
            self.project.instance().addMapLayer(vlayer)
            vlayer.renderer().symbol().setWidth(2)
            vlayer.renderer().symbol().setColor(QColor.fromRgb(250, 0, 0))
            self.view.refreshLayerSymbology(vlayer.id())

            uri = 'crs=EPSG:4326&dpiMode=7&format=image/jpeg&layers=IGNBaseTodo&styles=default&tileMatrixSet=EPSG:4326&url=http://www.ign.es/wmts/ign-base'
            map_spain = QgsRasterLayer(uri, "Spain", "wms")
            self.root.insertLayer(1, map_spain)
            self.project.instance().addMapLayer(map_spain)
            if not map_spain.isValid():
                print("Track failed to load! /n" + file_name)
            else:
                print("Track Load Correct! " + file_name)

        else:
            uri = 'crs=EPSG:4326&dpiMode=7&format=image/jpeg&layers=IGNBaseTodo&styles=default&tileMatrixSet=EPSG:4326&url=http://www.ign.es/wmts/ign-base'
            map_spain = QgsRasterLayer(uri, "Spain", "wms")
            self.project.instance().addMapLayer(map_spain)

            if not map_spain.isValid():
                print("Track failed to load! /n" + file_name)
            else:
                print("Track Load Correct! " + file_name)

    def zoomIn(self):
        self.canvas.setMapTool(self.toolZoomIn)

    def zoomOut(self):
        self.canvas.setMapTool(self.toolZoomOut)

    def pan(self):
        self.canvas.setMapTool(self.toolPan)

    def file(self):
        filename, _ = QFileDialog.getOpenFileName(self,
                                                  'Selecciona Fichero GPX',
                                                  'c:/', 'QGis (*.qgz)')
        if filename:
            self.project.read(filename)

    def initGui(self):
        icon = QIcon()
        icon.addPixmap(
            QPixmap(
                "C:/Roberto/Visual_Studio_Code/GisBike/programa/IMG/Qgis.png"),
            QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        self.setWindowModality(Qt.WindowModal)
        self.setWindowFlags(Qt.Window
                            | Qt.WindowSystemMenuHint
                            | Qt.WindowMinimizeButtonHint
                            | Qt.WindowMaximizeButtonHint
                            | Qt.WindowCloseButtonHint)

        self.resize(1200, 600)

        self.verticalLayout_2 = QVBoxLayout(self)
        self.splitter = QSplitter(self)
        self.splitter.setOrientation(Qt.Horizontal)

        self.actionZoomIn = QPushButton("Zoom in", self.splitter)
        self.actionZoomOut = QPushButton("Zoom out", self.splitter)
        self.actionPan = QPushButton("Pan", self.splitter)
        self.actionFile = QPushButton("File", self.splitter)

        self.project = QgsProject.instance()
        self.project.read('C:/Users/Fcc/Desktop/QGis/pruebas2.qgz')
        self.root = QgsProject.instance().layerTreeRoot()
        self.bridge = QgsLayerTreeMapCanvasBridge(self.root, self.canvas)

        self.bridge.setCanvasLayers()
        self.bridge.setAutoSetupOnFirstLayer(True)

        #https://gis.stackexchange.com/questions/141516/adding-legend-to-canvas-in-standalone-pyqgis-application
        self.model = QgsLayerTreeModel(self.root)
        self.model.setFlag(QgsLayerTreeModel.AllowNodeReorder)
        self.model.setFlag(QgsLayerTreeModel.AllowNodeRename)
        self.model.setFlag(QgsLayerTreeModel.AllowNodeChangeVisibility)
        self.model.setFlag(QgsLayerTreeModel.ShowLegend)
        self.view = QgsLayerTreeView(self.splitter)
        self.view.setModel(self.model)
        self.view.setFixedWidth(150)
        #self.view.resize(150,600)

        self.widget = QWidget(self.splitter)
        self.verticalLayout = QVBoxLayout(self.widget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.addWidget(self.actionZoomIn)
        self.horizontalLayout.addWidget(self.actionZoomOut)
        self.horizontalLayout.addWidget(self.actionPan)
        self.horizontalLayout.addWidget(self.actionFile)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.verticalLayout.addWidget(self.canvas)
        self.verticalLayout_2.addWidget(self.splitter)

        self.actionZoomIn.clicked.connect(self.zoomIn)
        self.actionZoomOut.clicked.connect(self.zoomOut)
        self.actionPan.clicked.connect(self.pan)
        self.actionFile.clicked.connect(self.file)

        # create the map tools
        self.toolPan = QgsMapToolPan(self.canvas)
        self.toolZoomIn = QgsMapToolZoom(self.canvas, False)  # false = in
        self.toolZoomOut = QgsMapToolZoom(self.canvas, True)  # true = out
Beispiel #15
0
def print_layout(project,
                 layout_name,
                 feature_filter: str = None,
                 scales=None,
                 scale=None,
                 **kwargs):
    """Generate a PDF for an atlas or a report.

    :param project: The QGIS project.
    :type project: QgsProject

    :param layout_name: Name of the layout of the atlas or report.
    :type layout_name: basestring

    :param feature_filter: QGIS Expression to use to select the feature.
    It can return many features, a multiple pages PDF will be returned.
    This is required to print atlas, not report
    :type feature_filter: basestring

    :param scale: A scale to force in the atlas context. Default to None.
    :type scale: int

    :param scales: A list of predefined list of scales to force in the atlas context.
    Default to None.
    :type scales: list

    :return: Path to the PDF.
    :rtype: basestring
    """
    canvas = QgsMapCanvas()
    bridge = QgsLayerTreeMapCanvasBridge(project.layerTreeRoot(), canvas)
    bridge.setCanvasLayers()
    manager = project.layoutManager()
    master_layout = manager.layoutByName(layout_name)
    settings = QgsLayoutExporter.PdfExportSettings()

    atlas = None
    atlas_layout = None
    report_layout = None

    logger = Logger()

    if not master_layout:
        raise AtlasPrintException('Layout `{}` not found'.format(layout_name))

    if master_layout.layoutType() == QgsMasterLayoutInterface.PrintLayout:
        for _print_layout in manager.printLayouts():
            if _print_layout.name() == layout_name:
                atlas_layout = _print_layout
                break

        atlas = atlas_layout.atlas()
        if not atlas.enabled():
            raise AtlasPrintException('The layout is not enabled for an atlas')

        layer = atlas.coverageLayer()

        if feature_filter is None:
            raise AtlasPrintException(
                'EXP_FILTER is mandatory to print an atlas layout')

        feature_filter = optimize_expression(layer, feature_filter)

        expression = QgsExpression(feature_filter)
        if expression.hasParserError():
            raise AtlasPrintException(
                'Expression is invalid, parser error: {}'.format(
                    expression.parserErrorString()))

        context = QgsExpressionContext()
        context.appendScope(QgsExpressionContextUtils.globalScope())
        context.appendScope(QgsExpressionContextUtils.projectScope(project))
        context.appendScope(
            QgsExpressionContextUtils.layoutScope(atlas_layout))
        context.appendScope(QgsExpressionContextUtils.atlasScope(atlas))
        context.appendScope(QgsExpressionContextUtils.layerScope(layer))
        expression.prepare(context)
        if expression.hasEvalError():
            raise AtlasPrintException(
                'Expression is invalid, eval error: {}'.format(
                    expression.evalErrorString()))

        atlas.setFilterFeatures(True)
        atlas.setFilterExpression(feature_filter)

        if scale:
            atlas_layout.referenceMap().setAtlasScalingMode(
                QgsLayoutItemMap.Fixed)
            atlas_layout.referenceMap().setScale(scale)

        if scales:
            atlas_layout.referenceMap().setAtlasScalingMode(
                QgsLayoutItemMap.Predefined)
            if Qgis.QGIS_VERSION_INT >= 30900:
                settings.predefinedMapScales = scales
            else:
                atlas_layout.reportContext().setPredefinedScales(scales)

        if not scales and atlas_layout.referenceMap().atlasScalingMode(
        ) == QgsLayoutItemMap.Predefined:
            if Qgis.QGIS_VERSION_INT >= 30900:
                use_project = project.useProjectScales()
                map_scales = project.mapScales()
            else:
                map_scales = project_scales(project)
                use_project = len(map_scales) == 0

            if not use_project or len(map_scales) == 0:
                logger.info(
                    'Map scales not found in project, fetching predefined map scales in global config'
                )
                map_scales = global_scales()

            if Qgis.QGIS_VERSION_INT >= 30900:
                settings.predefinedMapScales = map_scales
            else:
                atlas_layout.reportContext().setPredefinedScales(map_scales)

    elif master_layout.layoutType() == QgsMasterLayoutInterface.Report:
        report_layout = master_layout

    else:
        raise AtlasPrintException('The layout is not supported by the plugin')

    for key, value in kwargs.items():
        found = False
        if atlas_layout:
            item = atlas_layout.itemById(key.lower())
            if isinstance(item, QgsLayoutItemLabel):
                item.setText(value)
                found = True
        logger.info(
            'Additional parameters: {} found in layout {}, value {}'.format(
                key, found, value))

    export_path = os.path.join(tempfile.gettempdir(),
                               '{}_{}.pdf'.format(layout_name, uuid4()))
    result, error = QgsLayoutExporter.exportToPdf(atlas or report_layout,
                                                  export_path, settings)

    if result != QgsLayoutExporter.Success and not os.path.isfile(export_path):
        raise Exception('export not generated {} ({})'.format(
            export_path, error))

    return export_path
Beispiel #16
0
    print layer.name()
	
#show and set map canvas
canvas = QgsMapCanvas()

canvas.setCanvasColor(Qt.white)
#canvas.setCanvasColor(Qt.red)
canvas.enableAntiAliasing(True)

# set extent to the extent of our layer
canvas.setExtent(baselayer.extent())

# Load our project
bridge = QgsLayerTreeMapCanvasBridge(QgsProject.instance().layerTreeRoot(), canvas)
#QgsProject.instance().read(QFileInfo(project_path))
bridge.setCanvasLayers()

canvas.show()

#----------------------------------------------------------------------------------------------------------------------------------------
#Part 2. Select local .shp file and load as vector layer 
#----------------------
from PyQt4.QtCore import *
#PyQt4.QtCore -->  QFileInfo
from PyQt4.QtGui import * 
# PyQt4.QtGui --> QApplication
import qgis.core
#qgis.core --> QgsProject, QgsComposition, QgsApplication, QgsProviderRegistry
import qgis.gui #adds additional gui components 
#qgis.gui --> QgsMapCanvas, QgsLayerTreeMapCanvasBridge
from glob import glob
Beispiel #17
0
def print_layout(
    project: QgsProject,
    layout_name: str,
    output_format: OutputFormat,
    feature_filter: str = None,
    scales: list = None,
    scale: int = None,
    **kwargs,
):
    """Generate a PDF for an atlas or a report.

    :param project: The QGIS project.
    :type project: QgsProject

    :param layout_name: Name of the layout of the atlas or report.
    :type layout_name: basestring

    :param feature_filter: QGIS Expression to use to select the feature.
    It can return many features, a multiple pages PDF will be returned.
    This is required to print atlas, not report
    :type feature_filter: basestring

    :param scale: A scale to force in the atlas context. Default to None.
    :type scale: int

    :param scales: A list of predefined list of scales to force in the atlas context.
    Default to None.
    :type scales: list

    :param output_format: The output format, default to PDF if not provided.

    :return: Path to the PDF.
    :rtype: basestring
    """
    canvas = QgsMapCanvas()
    bridge = QgsLayerTreeMapCanvasBridge(project.layerTreeRoot(), canvas)
    bridge.setCanvasLayers()
    manager = project.layoutManager()
    master_layout = manager.layoutByName(layout_name)

    if output_format == OutputFormat.Svg:
        settings = QgsLayoutExporter.SvgExportSettings()
    elif output_format in (OutputFormat.Png, OutputFormat.Jpeg):
        settings = QgsLayoutExporter.ImageExportSettings()
    else:
        # PDF by default
        settings = QgsLayoutExporter.PdfExportSettings()

    atlas = None
    atlas_layout = None
    report_layout = None

    logger = Logger()

    if not master_layout:
        raise AtlasPrintException("Layout `{}` not found".format(layout_name))

    if master_layout.layoutType() == QgsMasterLayoutInterface.PrintLayout:
        for _print_layout in manager.printLayouts():
            if _print_layout.name() == layout_name:
                atlas_layout = _print_layout
                break

        atlas = atlas_layout.atlas()
        if not atlas.enabled():
            raise AtlasPrintException("The layout is not enabled for an atlas")

        layer = atlas.coverageLayer()

        if feature_filter is None:
            raise AtlasPrintException(
                "EXP_FILTER is mandatory to print an atlas layout")

        feature_filter = optimize_expression(layer, feature_filter)

        expression = QgsExpression(feature_filter)
        if expression.hasParserError():
            raise AtlasPrintException(
                "Expression is invalid, parser error: {}".format(
                    expression.parserErrorString()))

        context = QgsExpressionContext()
        context.appendScope(QgsExpressionContextUtils.globalScope())
        context.appendScope(QgsExpressionContextUtils.projectScope(project))
        context.appendScope(
            QgsExpressionContextUtils.layoutScope(atlas_layout))
        context.appendScope(QgsExpressionContextUtils.atlasScope(atlas))
        context.appendScope(QgsExpressionContextUtils.layerScope(layer))
        expression.prepare(context)
        if expression.hasEvalError():
            raise AtlasPrintException(
                "Expression is invalid, eval error: {}".format(
                    expression.evalErrorString()))

        atlas.setFilterFeatures(True)
        atlas.setFilterExpression(feature_filter)
        atlas.updateFeatures()

        if scale:
            atlas_layout.referenceMap().setAtlasScalingMode(
                QgsLayoutItemMap.Fixed)
            atlas_layout.referenceMap().setScale(scale)

        if scales:
            atlas_layout.referenceMap().setAtlasScalingMode(
                QgsLayoutItemMap.Predefined)
            settings.predefinedMapScales = scales

        if (not scales and atlas_layout.referenceMap().atlasScalingMode()
                == QgsLayoutItemMap.Predefined):
            use_project = project.useProjectScales()
            map_scales = project.mapScales()
            if not use_project or len(map_scales) == 0:
                logger.info(
                    "Map scales not found in project, fetching predefined map scales in global config"
                )
                map_scales = global_scales()
            settings.predefinedMapScales = map_scales

    elif master_layout.layoutType() == QgsMasterLayoutInterface.Report:
        report_layout = master_layout

    else:
        raise AtlasPrintException("The layout is not supported by the plugin")

    for key, value in kwargs.items():
        found = False
        if atlas_layout:
            item = atlas_layout.itemById(key.lower())
            if isinstance(item, QgsLayoutItemLabel):
                item.setText(value)
                found = True
        logger.info(
            'Additional parameters "{key}" {found} in layout, value "{value}"'.
            format(key=key,
                   found="found" if found else "not found",
                   value=value))

    file_name = "{}_{}.{}".format(clean_string(layout_name), uuid4(),
                                  output_format.name.lower())
    export_path = Path(tempfile.gettempdir()).joinpath(file_name)

    Logger().info("Exporting the request in {} using {}".format(
        export_path, output_format.value))

    if output_format in (OutputFormat.Png, OutputFormat.Jpeg):
        exporter = QgsLayoutExporter(atlas_layout or report_layout)
        result = exporter.exportToImage(str(export_path), settings)
        error = result_message(result)
    elif output_format in (OutputFormat.Svg, ):
        exporter = QgsLayoutExporter(atlas_layout or report_layout)
        result = exporter.exportToSvg(str(export_path), settings)
        error = result_message(result)
    else:
        # Default to PDF
        result, error = QgsLayoutExporter.exportToPdf(atlas or report_layout,
                                                      str(export_path),
                                                      settings)
        # Let's override error message
        _ = error
        error = result_message(result)

    if result != QgsLayoutExporter.Success:
        raise Exception("Export not generated in QGIS exporter {} : {}".format(
            export_path, error))

    if not export_path.is_file():
        logger.warning(
            "No error from QGIS Exporter, but the file does not exist.\n"
            "Message from QGIS exporter : {}\n"
            "File path : {}\n".format(error, export_path))
        raise Exception(
            "Export OK from QGIS, but file not found on the file system : {}".
            format(export_path))

    return export_path
    def responseComplete(self):
        request = self.serverIface.requestHandler()
        params = request.parameterMap( )

        # Check if dynamic layers params are passed
        # If not, do not change QGIS Server response
        if params['SERVICE'].lower() != 'dynamiclayers':
            return

        # Check if needed params are set
        if 'DLSOURCELAYER' not in params or 'DLEXPRESSION' not in params:
            # Change response
            request.clearHeaders()
            request.setInfoFormat('text/json')
            request.setHeader('Status', '200')
            request.setHeader('Content-type', 'text/json')
            request.clearBody()
            body = {
                'status': 0,
                'message': 'Missing parameters DLSOURCELAYER or DLEXPRESSION',
                'childProject': None
            }
            request.appendBody( json.dumps( body ) )
            return

        # Get layer and expression
        player = params['DLSOURCELAYER']
        pexp = params['DLEXPRESSION']
        #~ QgsMessageLog.logMessage( "DynamicLayers - layer = %s  - expression = %s" % ( player, pexp ))

        # Open project
        pmap = params['MAP']
        self.projectPath = pmap
        pfile = QFileInfo( pmap )
        p = QgsProject.instance()

        # Define canvas and layer treet root
        # Needed to write canvas and layer-tree-root in project file
        canvas = QgsMapCanvas()
        treeRoot = p.layerTreeRoot()
        bridge = QgsLayerTreeMapCanvasBridge( treeRoot, canvas )
        bridge.setCanvasLayers()
        canvas.zoomToFullExtent()
        self.canvas = canvas
        self.bridge = bridge
        self.composers = []
        self.project = p
        self.project.readProject.connect( bridge.readProject )
        self.project.readProject.connect( self.loadComposersFromProject )
        self.project.writeProject.connect( bridge.writeProject )
        self.project.writeProject.connect( self.writeOldLegend )
        self.project.writeProject.connect( self.writeComposers )

        # read project
        p.read( pfile )

        # Get an instance of engine class
        dle = DynamicLayersEngine()

        # Set the dynamic layers list
        dle.setDynamicLayersList()
        if not dle.dynamicLayers:
            QgsMessageLog.logMessage( "DynamicLayers - no dynamic layers found")
            # Change response
            request.clearHeaders()
            request.setInfoFormat('text/json')
            request.setHeader('Status', '200')
            request.setHeader('Content-type', 'text/json')
            request.setHeader('Content-Disposition', 'attachment; filename="DynamicLayers.json"')
            request.clearBody()
            body = {
                'status': 0,
                'message': 'No dynamic layers found in parent project',
                'childProject': None
            }
            request.appendBody( json.dumps( body ) )
            return


        # Set search and replace dictionary
        lr = QgsMapLayerRegistry.instance()
        sourceLayerList = [ layer for lname,layer in lr.mapLayers().items() if layer.name() == player ]
        if len(sourceLayerList ) != 1:
            QgsMessageLog.logMessage( "DynamicLayers - source layer not in project")
            # Change response
            request.clearHeaders()
            request.setInfoFormat('text/json')
            request.setHeader('Status', '200')
            request.setHeader('Content-type', 'text/json')
            request.setHeader('Content-Disposition', 'attachment; filename="DynamicLayers.json"')
            request.clearBody()
            body = {
                'status': 0,
                'message': 'The source layer cannot be found in the project',
                'childProject': None
            }
            request.appendBody( json.dumps( body ) )
            return

        sourceLayer = sourceLayerList[0]
        dle.setSearchAndReplaceDictionaryFromLayer( sourceLayer, pexp )
        self.searchAndReplaceDictionary = dle.searchAndReplaceDictionary

        # Get child name computed path, and check if it is already there or not
        childPath = self.getChildProjectName( pmap, player, pexp )
        self.childPath = childPath
        if os.path.exists( childPath ):
            if os.path.getmtime( childPath ) > os.path.getmtime( pmap ):
                QgsMessageLog.logMessage( 'DynamicLayer - Parent older than child : do not recreate child project')

                # Change response
                request.clearHeaders()
                request.setInfoFormat('text/json')
                request.setHeader('Status', '200')
                request.setHeader('Content-type', 'text/json')
                request.setHeader('Content-Disposition', 'attachment; filename="DynamicLayers.json"')
                request.clearBody()
                body = {
                    'status': 1,
                    'message': 'Child project is already up-to-date',
                    'childProject': os.path.basename(childPath)
                }
                request.appendBody( json.dumps( body ) )
                return
            else:
                QgsMessageLog.logMessage( 'DynamicLayer - Must recreate the child project')

        # Change layers datasource
        dle.setDynamicLayersDatasourceFromDic( )

        # Set project properties
        dle.setDynamicProjectProperties()

        # Set extent layer
        extentLayerIdGet = p.readEntry('PluginDynamicLayers' , 'ExtentLayer')
        if extentLayerIdGet:
            extentLayerId = extentLayerIdGet[0]
            extentLayerList = [ layer for lid,layer in lr.mapLayers().items() if layer.id() == extentLayerId ]

            if len(extentLayerList) == 1:
                dle.setExtentLayer( extentLayerList[0] )

                # Set extent margin
                extentMarginGet = p.readEntry('PluginDynamicLayers' , 'ExtentMargin')
                if extentMarginGet:
                    extentMargin = int( extentMarginGet[0] )
                else:
                    extentMargin = 20
                dle.setExtentMargin( extentMargin )

                # Set new extent
                newExtent = dle.setProjectExtent()
                self.extent = newExtent

                # Zoom to extent Layer
                if newExtent:
                    self.canvas.setExtent( newExtent )

        # Create suffix to append after layers id
        # prevent cache issues
        self.layerIdSuffix = int( time.time() )

        # Save child project
        childProject = self.saveChildProject()

        # Save child project lizmap configuration
        if os.path.exists( self.projectPath + '.cfg' ):
            self.writeLizmapChildProjectConfig()

        if childProject:
            # Change response
            request.clearHeaders()
            request.setInfoFormat('text/json')
            request.setHeader('Status', '200')
            request.setHeader('Content-type', 'text/json')
            request.setHeader('Content-Disposition', 'attachment; filename="DynamicLayers.json"')
            request.clearBody()
            body = {
                'status': 1,
                'message': 'Child project has been updated',
                'childProject': os.path.basename(childPath)
            }
            request.appendBody( json.dumps( body ) )
        else:
            # Change response
            request.clearHeaders()
            request.setInfoFormat('text/json')
            request.setHeader('Status', '200')
            request.setHeader('Content-type', 'text/json')
            request.setHeader('Content-Disposition', 'attachment; filename="DynamicLayers.json"')
            request.clearBody()
            body = {
                'status': 0,
                'message': 'Error while creating child project',
                'childProject': None
            }
            request.appendBody( json.dumps( body ) )

        return