QGIS Planet

QGIS 3.10 Loves GeoPDF!

Recently, we’ve been working on an exciting development which is coming soon in QGIS 3.10… support for Geospatial PDF exports! This has been a long-desired feature for many QGIS users, and it was only made possible thanks to a group of financial backers (listed below). In this post, we’re going to explore these new features and how they improve your QGIS PDF outputs.

Geospatial PDFs can now be created either by exporting the main QGIS map canvas, or by creating and exporting a custom print layout. For instance, when you select the “Save Map as PDF” option from the main QGIS window, you’ll see a new group of Geospatial PDF related options:

At its most basic, Geospatial PDF is a standard extension to the PDF format which allows for vector spatial datasets to be embedded in PDF files. If the “Include vector feature information” checkbox is ticked when creating a Geospatial PDF output, then QGIS will automatically include all the geometry and attribute information from features visible within the page. So if we export a simple map to PDF, we’ll get an output file which looks just like any old regular PDF map output…

…but, we can also pull this PDF back into QGIS and treat it just like any other vector data source! In the screenshot below we’re using the Identify tool to query on of the polygons and see all the attribute information from the original source layer.

This ability adds a lot of value to PDF exports. Anyone who has ever been supplied a non-spatial PDF as a “spatial dataset” will attest to the frustrations these cause… but if you create proper Geospatial PDFs instead, then there’s no loss of the valuable underlying spatial information or feature attributes! Furthermore, if these PDFs are opened within Acrobat Reader, tools are enabled which allow users to query features interactively.

Another nice benefit which comes with Geospatial PDF output is that layers can be interactively toggled on or off in the PDF viewer. The screenshot below shows a Geospatial PDF file created from a simple QGIS map. On the left we have a list of the layers in the PDF, each of which can be turned on or off inside the PDF viewer!

The really nice thing here is that, thanks to the underlying smarts in the GDAL library which is responsible for the actual Geospatial PDF creation, the PDF renders identically to our original QGIS map. While labels turn on and off alongside their corresponding map layer, they are still correctly stacked in the exact same way as you see in the QGIS window. Furthermore, the created PDFs keep labels and vector features as vector artwork… so there’s absolutely no loss in quality when zooming in to the map! These files look GREAT!

On that same note… the sponsorship allowed us to tackle another related issue, which is that in previous QGIS versions PDF (or SVG) exports would always export every single vertex from any visible feature! Ouch! This meant that if you had a complex polygon boundary layer, you would potentially be creating a PDF with millions of vertices per feature, even though most of these would be overlapping and completely redundant at the exported map’s scale. Now, QGIS automatically simplifies vector features while exporting them (using an appropriate, effectively invisible, level of simplification). The dramatically reduces the created file sizes and speeds up opening them and navigating them in other applications (especially Inkscape). (There’s an option at export time to disable this simplification, if you have a specific reason to!).

Creating Geospatial PDFs from print layouts gives even more options. For a start, whenever a print layout is exported to Geospatial PDFs, we ensure that the created PDF correctly handles stacking of layers alongside any other print layout items you have. In the image below we see a custom print layout which includes interactive layer visibility controls. If a layer is toggled, it’s hidden only from the map item — all the other surrounding elements like the title, north arrow and scalebar remain visible:

That’s not all though! When exporting a print layout to Geospatial PDF, QGIS also hooks into any map themes you’ve setup in your project. If you select to include these themes in your output, then the result is magical! The screenshot below shows the export options for a project with a number of themes, and we’ve chosen to export these themes in the PDF:

Opening the resultant PDF shows that our layer control on the left now lists the map themes instead of individual layers. Viewers can switch between these themes, changing the visibility of layers and their styling to match the QGIS map theme from the project! Additionally, you can even expand out a theme and expose layer-by-layer visibility control. Wow! This means you could create a single PDF output file which includes an environmental, social, cadastral, transport, …. view of your map, all in the one file.

Lastly, there’s even control for fine-tuning the combination of layers which are exposed in the output PDF file and which ones should be toggled on and off together. In the screenshot below we’ve opted to group the “Aircraft” and “Roads” map layers into a single logical PDF group called “Transport”. 

The resultant PDF respects this, showing an entry in the interactive layer tree for “Transport” which toggles both the aircraft and roads layers together:

So there you go — the power of Geospatial PDF, coming your way in QGIS 3.10!

One semi-related benefit of this work is that it gave us an opportunity to rework how “layered” exports from print layouts are created. This has had a significant flow-on impact on the existing ability to create layered SVG outputs from QGIS. Previously, this was a rather fragile feature, which created SVGs with lots of issues – overlapping labels, incorrectly stacked layers, and last-but-not-least, non-descriptive layer names! Now, just like Geospatial PDF exports, the layered SVG exports correctly respect the exact look of your map, and have much more friendly, descriptive layer names:

This should significantly reduce the amount of housekeeping required when working on these layered SVG exports. 

This work was funded by:

  • Land Vorarlberg
  • Municipality of Vienna
  • Municipality of Dornbirn
  • Biodiversity Information Service for Powys and BBNP Local
  • Kanton Zug
  • Canton de Neuchâtel
  • Canton de Thurgovia

North Road are leading experts in extending the QGIS application to meet your needs. If you’d like to discuss how you can sponsor development of features or fixes which you want in QGIS, just contact us for further details!

 

 

QGIS Print Layouts Graphs and Charts — target reached!

We’ve just passed the extended deadline for our recent QGIS Print Layouts Graphs and Charts campaign, and the great news is that thanks to a large number of generous backers we’ve successfully hit the target for this campaign! This has only been possible thanks to the tireless work of the QGIS community and user groups in promoting this campaign and spreading the word.

The Print Layouts Graphs and Charts campaign is a joint effort with our friends at Faunalia, so we’ll soon be starting work together on all the wonderful new functionality heading to the QGIS DataPlotly plugin as a result. The work will be commencing late June, just after the QGIS 3.8.0 final release. Keep an eye out for further updates on the development from this time! You can read more about what’s coming in detail at the campaign page.

We’d like to take this opportunity to extend our heartfelt thanks to all the backers who have pledged to support this project:

  • Federico Gianoli
  • Papercraft Mountains
  • Liam McCrae
  • Henry Walshaw
  • Raúl Sangonzalo
  • Ferdinando Urbano
  • pitsch-ing.ch
  • Carbon-X
  • Gabriel Diosan
  • Rene Giovanni Borella
  • Enrico Bertonati
  • Guido Ingwer
  • David Addy
  • Gerd Jünger
  • Andreas Neumann
  • Stefano Campus
  • Michael Jabot
  • Korto
  • Enrico Ferreguti
  • Carlo A. Nicolini
  • Salvatore Fiandaca
  • Alberto Grava
  • Hans van der Kwast
  • Ben Hur Pintor
  • Silvio Grosso
  • Nobusuke Iwasaki
  • Alasdair Rae
  • Manori Senanayake
  • Canton de Neuchâtel
  • Matthias Daues
  • Alteri Seculo
  • SunGIS Ltd.
  • Stu Smith
  • Keolis Rennes
  • Gabriel Diosan
  • Aiden Price
  • Giacomo Ponticelli
  • Diane Fritz
  • Gemio Bissolati
  • Claire Birnie
  • Nicolas Roelandt
  • Rocco Pispico
  • Gabriel Bengtsson
  • Birds Eye View
  • Barend Köbben
  • Roberto Marzocchi (GTER)
  • Yoichi Kayama
  • Alessandro Sarretta
  • Luca Angeli
  • Luca Bellani
  • giswelt
  • Stefan Giese
  • Ben Harding
  • Joao Gaspar
  • Romain Lacroix
  • Ryan Cooper
  • Daniele Bonaposta
  • QGIS Swedish User Group
  • Nino Formica
  • Michael Gieding
  • Amedeo Fadini
  • Andrew Hannell
  • Stefano
  • Phil Wyatt
  • Brett Edmond Carlock
  • Transitec

 

QGIS Print Layouts Graphs and Charts – campaign deadline extended!

If you’re a regular reader of this blog, it won’t surprise you to hear that we’re very excited about adding rich charting and graph functionality to QGIS’ Print Layout designer! Alongside our friends at Faunalia, we’re currently running a crowd funding campaign to make this a reality.

So, while the required funds weren’t raised within our original April 30 deadline, we’ve decided to extend this campaign by an additional 30 days in the hopes that the users and organisations from the wider QGIS community will jump onboard and pledge the remaining required funds.

This missing feature is a large gap in QGIS printing capabilities, so we’re counting on you to show your support and spread the word to your local user groups, QGIS users, and any organisations you know of who rely on QGIS and would love to see its inbuilt reporting capabilities levelled up!

QGIS (and SLYR!), now with Hash Lines support

Thanks to an anonymous corporate sponsor, we’ve recently had the opportunity to add a new Hashed Line symbol type for QGIS 3.8. This allows for a repeating line segment to be drawn over the length of a feature, with a line-sub symbol used to render each individual segment.

There’s tons of options available for customising the appearance and placement of line hashes. We based the feature heavily off QGIS’ existing “Marker Line” support, so you can create hashed lines placed at set intervals, on line vertices, or at the start/end/middle of lines. There’s options to offset the lines, and tweak the rotation angle of individual hashes too. Added to QGIS’ rich support for “data defined” symbol properties, this allows for a huge range of new symbol effects.

E.g. using a data defined hash length which increases over the length of a feature gives us this effect:

Or, when using a complex line sub-symbol for rendering each hash, we can get something like this:

Or even go completely “meta” and use a hashed line sub symbol for the hash line itself!

With the right combination of symbol settings and QGIS draw effects you can even emulate a calligraphic pen effect:

Or a chunky green highlighter!

This same corporate sponsor also funded a change which results in a huge improvement to the appearance of both rotated hashed lines and marker lines. Previously, when marker or hash lines were rendered, the symbol angles were determined by taking the exact line orientation at the position of the symbol. This often leads to undesirable rendering effects, where little “bumps” or corners in lines which occur at the position of the symbol cause the marker or hash line to be oriented at a very different angle to what the eye expects to see.

With this improvement, the angle is instead calculated by averaging the line over a specified distance either side of the symbol. E.g. averaging the line angle over 4mm means we take the points along the line 2mm from either side of the symbol placement, and use these instead to calculate the line angle for that symbol. This has the effect of smoothing (or removing) any tiny local deviations from the overall line direction, resulting in much nicer visual orientation of marker or hash lines.

It’s easiest to show the difference visually. Here’s a before image, showing arrow markers following a line feature. Pay specific attention to the 3rd and last arrow, which seem completely random oriented due to the little shifts in line direction:

With new smoothing logic this is much improved:

The difference is even more noticeable for hashed lines. Here’s the before:

…and the after:

Suffice to say, cartographers will definitely appreciate the result!

Lastly, we’ve taken this new hash line feature as an opportunity to implement automatic conversion of ESRI hash line symbols within our SLYR ESRI to QGIS conversion tool. Read more about SLYR here, and how you can purchase this tool for .style, .lyr and .mxd document conversion.

QGIS Print Layouts Graphs and Charts – an Illustrated Showcase

If you’ve been following our latest updates, you’ll be well aware that North Road and Faunalia are running a crowd funding campaign to add rich charting and graph functionality to QGIS’ Print Layout designer. This missing feature is a large gap in QGIS printing capabilities, so we’re planning on filling that gap by exposing the powerful QGIS “Data Plotly” plugin to allow these charts to be embedded inside your layouts, and allow them to be created and modified in a simple, interactive style. And thanks to a large group of generous backers, the campaign is off to a fantastic start!

Accordingly, we’d like to take the opportunity to showcase some of the current plot styles available from the QGIS DataPlotly plugin, all of which will be possible to insert into your print layouts if the campaign is successful. Let’s start with the default chart option – a simple scatter plot:

In this screenshot we see a scatter plot of Educational Usage vs Distance from City for a network of railway stations. We’ve left most settings at their default in order to illustrate that even out-of-the-box, the charts look great! They’ll fit right alongside your map masterpieces in your print layouts and won’t look out of place. It’s also important to note that the above screenshot demonstrates the current interactive canvas mode for the DataPlotly plugin. If this campaign is successful, the chart designer shown above will be available directly inside the QGIS Print Layout designer window. Users will be able to drop new charts into their layouts, and then edit the properties of those charts in a interactive manner. Exciting stuff indeed!

So what other plot styles are currently available in DataPlotly? Here’s a quick showcase of what’s hopefully in the future for QGIS’ print layouts…

Box plots

Bar plot

Histograms

Pie Charts

2D Histogram

Polar Plots

Ternary Plots

Contour Plots

Violin Plots

These plots can already be created from your map canvas using the version of DataPlotly available from the standard QGIS plugin repository, so we encourage you to download the plugin and have a play, and start to get a feel for the flexibility and power having access to these charting options will bring to your print layouts!

You can help make this feature a reality by supporting the campaign or by sharing the page and increasing exposure to the campaign. Full details about the planned functionality and how to contribute are available at the campaign page.

QGIS Print Layouts Graphs and Charts crowdfund launched!

Ever wished QGIS had a way to insert dynamic, feature rich charts and graphs directly inside print layouts? If so, our latest crowdfunding campaign has you covered! This missing feature is a large gap in QGIS printing capabilities, so we’re planning on filling that gap by exposing the powerful QGIS “Data Plotly” plugin to allow these charts to be embedded inside your layouts, and allow them to be created and modified in a simple, interactive style.

If you’re not aware of the existing capabilities of the DataPlotly plugin, here’s a quick screencast which should get you excited about the possibilities here…

QGIS is already a reporting powerhouse, and we believe that linking DataPlotly with QGIS print layouts will boost the current functionality up an order of magnitude! To make it possible we need 8600€ pledged before 30 April 2019. North Road is collaborating on this campaign with our friends at Faunalia, and development work will be shared between the two consultancy firms.

You can help make this a reality by supporting the campaign or by sharing the page and increasing exposure to the campaign. Full details about the planned functionality and how to contribute are available at the campaign page.

Announcing our SLYR (MXD to QGIS) funding drive!

One product which North Road had the chance to develop last year, and which we are super-proud of, is our SLYR ESRI style to QGIS conversion tool. If you haven’t heard of it before, this tool allows automatic conversion of ESRI .style database files to their equivalent QGIS symbology equivalent. It works well for the most part, and now we’re keen to take this to the next stage.

The good news is that North Road have been conducting extensive research and development over the past 12 months, and we’re pleased to announce our plans for extending SLYR to support ESRI LYR and MXD documents. The LYR and MXD formats are proprietary ESRI-only formats, with no public specifications allowing their use. This is a huge issue for organisations who want to move from an ESRI environment to the open geospatial world, yet are held back by hundreds (or thousands!) of existing ESRI MXD map documents and layer styles which they currently cannot utilise outside of the ESRI software ecosystem. Furthermore, many providers of spatial data only include ESRI specific layer formatting files with their data supplies. This leaves users with no means of utilising these official, pre-defined styles in non-ESRI tools.

In order for us to continue development of the SLYR tool and unlock use of LYR and MXD formats outside of ESRI tools, we are conducting a funding campaign. Sponsors of the campaign will receive access to the tools as they are developed and gain access to official support channels covering their use. At the conclusion of this drive we’ll be releasing all the tools and specifications under a free, open-source license.

You can read the full details of the campaign here, including pricing to become a project sponsor and gain access to the tools as they develop. As a campaign launch promo, we’re offering the first 10 sponsors a super-special discounted rate (as a reward for jumping on the development early).

The mockup below shows what the end goal is: seamless, fully integrated, automatic conversion of MXD and LYR files directly within the QGIS desktop application!

On custom layout checks in QGIS 3.6, and how they can do your work for you!

Recently, we had the opportunity to implement an exciting new feature within QGIS. An enterprise with a large number of QGIS installs was looking for a way to control the outputs which staff were creating from the software, and enforce a set of predefined policies. The policies were designed to ensure that maps created in QGIS’ print layout designer would meet a set of minimum standards, e.g.:

  • Layouts must include a “Copyright 2019 by XXX” label somewhere on the page
  • All maps must have a linked scale bar
  • No layers from certain blacklisted sources (e.g. Google Maps tiles) are permitted
  • Required attribution text for other layers must be included somewhere on the layout

Instead of just making a set of written policies and hoping that staff correctly follow them, it was instead decided that the checks should be performed automatically by QGIS itself. If any of the checks failed (indicating that the map wasn’t complying to the policies), the layout export would be blocked and the user would be advised what they needed to change in their map to make it compliant.

The result of this work is a brand new API for implementing custom “validity checks” within QGIS. Out of the box, QGIS 3.6 ships with two in-built validity checks. These are:

  • A check to warn users when a layout includes a scale bar which isn’t linked to a map
  • A check to warn users if a map overview in a layout isn’t linked to a map (e.g. if the linked map has been deleted)

All QGIS 3.6 users will see a friendly warning if either of these conditions are met, advising them of the potential issue.

 

The exciting stuff comes in custom, in-house checks. These are written in PyQGIS, so they can be deployed through in-house plugins or startup scripts. Let’s explore some examples to see how these work.

A basic check looks something like this:

from qgis.core import check

@check.register(type=QgsAbstractValidityCheck.TypeLayoutCheck)
def my_layout_check(context, feedback):
  results = ...
  return results

Checks are created using the @check.register decorator. This takes a single argument, the check type. For now, only layout checks are implemented, so this should be set to QgsAbstractValidityCheck.TypeLayoutCheck. The check function is given two arguments, a QgsValidityCheckContext argument, and a feedback argument. We can safely ignore the feedback option for now, but the context argument is important. This context contains information useful for the check to run — in the case of layout checks, the context contains a reference to the layout being checked. The check function should return a list of QgsValidityCheckResult objects, or an empty list if the check was passed successfully with no warnings or errors.

Here’s a more complete example. This one throws a warning whenever a layout map item is set to the web mercator (EPSG:3875) projection:

@check.register(type=QgsAbstractValidityCheck.TypeLayoutCheck)
def layout_map_crs_choice_check(context, feedback):
  layout = context.layout
  results = []
  for i in layout.items():
    if isinstance(i, QgsLayoutItemMap) and i.crs().authid() == 'EPSG:3857':
      res = QgsValidityCheckResult()
      res.type = QgsValidityCheckResult.Warning
      res.title='Map projection is misleading'
      res.detailedDescription='The projection for the map item {} is set to Web Mercator (EPSG:3857) which misrepresents areas and shapes. Consider using an appropriate local projection instead.'.format(i.displayName())
      results.append(res)

  return results

Here, our check loops through all the items in the layout being tested, looking for QgsLayoutItemMap instances. It then checks the CRS for each map, and if that CRS is ‘EPSG:3857’, a warning result is returned. The warning includes a friendly message for users advising them why the check failed.

In this example our check is returning results with a QgsValidityCheckResult.Warning type. Warning results are shown to users, but they don’t prevent users from proceeding and continuing to export their layout.

Checks can also return “critical” results. If any critical results are obtained, then the actual export itself is blocked. The user is still shown the messages generated by the check so that they know how to resolve the issue, but they can’t proceed with the export until they’ve fixed their layout. Here’s an example of a check which returns critical results, preventing layout export if there’s no “Copyright 2019 North Road” labels included on their layout:

@check.register(type=QgsAbstractValidityCheck.TypeLayoutCheck)
def layout_map_crs_choice_check(context, feedback):
  layout = context.layout
  for i in layout.items():
    if isinstance(i, QgsLayoutItemLabel) and 'Copyright 2019 North Road' in i.currentText():
      return

  # did not find copyright text, block layout export
  res = QgsValidityCheckResult()
  res.type = QgsValidityCheckResult.Critical
  res.title = 'Missing copyright label'
  res.detailedDescription = 'Layout has no "Copyright" label. Please add a label containing the text "Copyright 2019 North Road".'
  return [res]

If we try to export a layout with the copyright notice, we now get this error:

Notice how the OK button is disabled, and users are forced to fix the error before they can export their layouts.

Here’s a final example. This one runs through all the layers included within maps in the layout, and if any of them come from a “blacklisted” source, the user is not permitted to proceed with the export:

@check.register(type=QgsAbstractValidityCheck.TypeLayoutCheck)
def layout_map_crs_choice_check(context, feedback):
  layout = context.layout
  for i in layout.items():
    if isinstance(i, QgsLayoutItemMap):
      for l in i.layersToRender():
        # check if layer source is blacklisted
        if 'mt1.google.com' in l.source():
          res = QgsValidityCheckResult()
          res.type = QgsValidityCheckResult.Critical
          res.title = 'Blacklisted layer source'
          res.detailedDescription = 'This layout includes a Google maps layer ("{}"), which is in violation of their Terms of Service.'.format(l.name())
          return [res]

Of course, all checks are run each time — so if a layout fails multiple checks, the user will see a summary of ALL failed checks, and can click on each in turn to see the detailed description of the failure.

So there we go — when QGIS 3.6 is released in late February 2019, you’ll  have access to this API and can start making QGIS automatically enforce your organisation policies for you! The really neat thing is that this doesn’t only apply to large organisations. Even if you’re a one-person shop using QGIS, you could write your own checks to  make QGIS “remind” you when you’ve forgotten to include something in your products. It’d even be possible to hook into one of the available Python spell checking libraries to write a spelling check! With any luck, this should lead to better quality outputs and less back and forth with your clients.

North Road are leading experts in customising the QGIS application for enterprise installs. If you’d like to discuss how you can deploy in-house customisation like this within your organisation, contact us for further details!

Edit Features “In Place” crowdfund — made it to QGIS 3.4!

Well, thanks to the resounding success of our QGIS edit-in-place crowdfunding campaign, we’ve been frantically smashing away at our keyboards in an attempt to reward the QGIS community by sneaking this feature in a whole 4 months earlier than originally promised! And, we’re very proud to announce, that this exciting new feature has been implemented and will be included in the upcoming QGIS 3.4 release (due late October 2018). So go ahead — grab one of the nightly pre-release of QGIS 3.4 and checkout the results.

This wouldn’t have been possible without the rapid response to the campaign and the generosity of our wonderful backers:

(In addition to these backers, we’ve also received numerous anonymous donations to this feature from many other individuals — while we can’t list you all publicly, you’re also in our thanks!)

 

Keep an eye on this blog for other upcoming QGIS crowdfunding campaigns targeted at QGIS 3.6 and beyond… we’ve got lots more exciting work planned for these releases!

 

Edit Features “In Place” crowdfund — target reached!

Well, the final pledges have been tallied and we’re very proud to announce that our latest crowd funding campaign has been a roaring success!

We’ve been completely blown away by the response to this campaign. Thanks to some incredibly generous backers and donors, we’ve been able to hit the campaign target with plenty of time to spare. As a result, we’ll be pushing hard to reward the generosity of the community by trying to sneak this feature in for the upcoming QGIS 3.4 release (instead of the originally promised 3.6 release)! You can read more about what we’re adding at the campaign page.

We’d like to take this opportunity to extend our heartfelt thanks to all the backers who have pledged to support this project:

In addition to these backers, we’ve also received numerous anonymous donations to this feature from many other individuals — while we can’t list you all publicly, you’re also in our thanks!

Stay tuned for more updates to come as work proceeds on this feature…

Edit Features “In Place” Using QGIS Spatial Operations crowdfund launched!

We’ve just launched a new QGIS crowd funding campaign which we’re super-excited about! This time, we’re addressing what we see as the major shortcoming within QGIS vector layer editing tools, and bridging the gap between the vast power of QGIS’ Processing algorithms and easy-to-use operations which modify layer features “in place”. Here’s a quick sneak preview of what we have planned:

 

QGIS is already a vector editing powerhouse, and we believe that this improvement will boost the current functionality up an order of magnitude! To make it possible we need 6500€ pledged before 30 September 2018.

This is also our first crowdfunding campaign in which we’re running a “dual funding” approach, which we think should make things friendly and easy for both corporate backers and end user contributions alike. Read more about this at the full campaign page.

You can help make this a reality by supporting the campaign or by sharing the page and increasing exposure to the campaign. Updates to follow!

 

Drill down (cascading) forms in QGIS crowdfund – final stretch!

Update: donations are now closed, with the outcome of the campaign pending!

We’re nearing the final hours of our crowd funding campaign to implement a drill-down (cascading) field support within QGIS forms, and thanks to numerous generous backers we’re very close to hitting the funding goal! This is a really exciting new feature which would help add greater flexibility and power to QGIS feature forms, but in order to implement it for QGIS 3.2 we need to hit the funding target by 11 May 2018.

As a result, we’re dropping the minimum contribution amount and throwing open the campaign for payments of any amount. These smaller payment will be treated as direct donations to the campaign, so unlike the standard campaign backing these are payable up front. In the case that the campaign IS NOT successful, the donations will not be refunded and will instead be reinvested back into the QGIS (via bug fixing and maintenance efforts). Of course, if you’d prefer to pledge using the standard crowdfunding “no payment if campaign unsuccessful” model you’re more than welcome to! (Full details are available on the campaign page).

Donations closed – outcome pending!

Full details are available on the campaign page.

Drill-down (cascading) forms in QGIS crowdfund launched!

We’ve just launched a new crowd funding campaign to implement a drill-down (cascading) field support within QGIS forms. Full details are available on the campaign page.

This is a really exciting new feature which would help add greater flexibility and power to QGIS feature forms! To make it possible we need 3500€ pledged before 11 May 2018. You can help make this a reality by supporting the campaign or by sharing the page and increasing exposure to the campaign. Updates to follow!

Implementing an in-house “New Project Wizard” for QGIS

Recently, we were required to implement a custom “New Project Wizard” for use in a client’s internal QGIS installation. The goal here was that users would be required to fill out certain metadata fields whenever they created a new QGIS project.

Fortunately, the PyQGIS (and underlying Qt) libraries makes this possibly, and relatively straightforward to do. Qt has a powerful API for creating multi-page “wizard” type dialogs, via the QWizard and QWizardPage classes. Let’s have a quick look at writing a custom wizard using these classes, and finally we’ll hook it into the QGIS interface using some PyQGIS magic.

We’ll start super simple, creating a single page wizard with no settings. To do this we first create a Page1 subclass of QWizardPage, a ProjectWizard subclass of QWizard, and a simple runNewProjectWizard function which launches the wizard. (The code below is designed for QGIS 3.0, but will run with only small modifications on QGIS 2.x):

class Page1(QWizardPage):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setTitle('General Properties')
        self.setSubTitle('Enter general properties for this project.')


class ProjectWizard(QWizard):
    
    def __init__(self, parent=None):
        super().__init__(parent)
        
        self.addPage(Page1(self))
        self.setWindowTitle("New Project")


def runNewProjectWizard():
    d=ProjectWizard()
    d.exec()

If this code is executed in the QGIS Python console, you’ll see something like this:

Not too fancy (or functional) yet, but still not bad for 20 lines of code! We can instantly make this a bit nicer by inserting a custom logo into the widget. This is done by calling setPixmap inside the ProjectWizard constructor.

class ProjectWizard(QWizard):
    
    def __init__(self, parent=None):
        super().__init__(parent)
        
        self.addPage(Page1(self))
        self.setWindowTitle("New Project")

        logo_image = QImage('path_to_logo.png')
        self.setPixmap(QWizard.LogoPixmap, QPixmap.fromImage(logo_image))

That’s a bit nicer. QWizard has HEAPS of options for tweaking the wizards — best to read about those over at the Qt documentation. Our next step is to start adding some settings to this wizard. We’ll keep things easy for now and just insert a number of text input boxes (QLineEdits) into Page1:

class Page1(QWizardPage):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setTitle('General Properties')
        self.setSubTitle('Enter general properties for this project.')

        # create some widgets
        self.project_number_line_edit = QLineEdit()
        self.project_title_line_edit = QLineEdit()
        self.author_line_edit = QLineEdit()        
        
        # set the page layout
        layout = QGridLayout()
        layout.addWidget(QLabel('Project Number'),0,0)
        layout.addWidget(self.project_number_line_edit,0,1)
        layout.addWidget(QLabel('Title'),1,0)
        layout.addWidget(self.project_title_line_edit,1,1)
        layout.addWidget(QLabel('Author'),2,0)
        layout.addWidget(self.author_line_edit,2,1)
        self.setLayout(layout)

There’s nothing particularly new here, especially if you’ve used Qt widgets before. We make a number of QLineEdit widgets, and then create a grid layout containing these widgets and accompanying labels (QLabels). Here’s the result if we run our wizard now:

So now there’s the option to enter a project number, title and author. The next step is to force users to populate these fields before they can complete the wizard. Fortunately, QWizardPage has us covered here and we can use the registerField() function to do this. By calling registerField, we make the wizard aware of the settings we’ve added on this page, allowing us to retrieve their values when the wizard completes. We can also use registerField to automatically force their population by appending a * to the end of the field names. Just like this…

class Page1(QWizardPage):
    def __init__(self, parent=None):
        super().__init__(parent)
        ...
        self.registerField('number*',self.project_number_line_edit)
        self.registerField('title*',self.project_title_line_edit)
        self.registerField('author*',self.author_line_edit)

If we ran the wizard now, we’d be forced to enter something for project number, title and author before the Finish button becomes enabled. Neat! By registering the fields, we’ve also allowed their values to be retrieved after the wizard completes. Let’s alter runNewProjectWizard to retrieve these values and do something with them:

def runNewProjectWizard():
   d=ProjectWizard()
   d.exec()

   # Set the project title
   title=d.field('title')
   QgsProject.instance().setTitle(d.field('title'))

   # Create expression variables for the author and project number
   number=d.field('number')
   QgsExpressionContextUtils.setProjectVariable(QgsProject.instance(),'project_number', number)
   author=d.field('author')
   QgsExpressionContextUtils.setProjectVariable(QgsProject.instance(),'project_author', author)
 

Here, we set the project title directly and create expression variables for the project number and author. This allows their use within QGIS expressions via the @project_number and @project_author variables. Accordingly, they can be embedded into print layout templates so that layout elements are automatically populated with the corresponding author and project number. Nifty!

Ok, let’s beef up our wizard by adding a second page, asking the user to select a sensible projection (coordinate reference system) for their project. Thanks to improvements in QGIS 3.0, it’s super-easy to embed a powerful pre-made projection selector widget into your scripts, which even includes a handy preview of the area of the world that the projection is valid for.

class Page2(QWizardPage):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setTitle('Project Coordinate System')
        self.setSubTitle('Choosing an appropriate projection is important to ensure accurate distance and area measurements.')
        
        self.proj_selector = QgsProjectionSelectionTreeWidget()
        layout = QVBoxLayout()
        layout.addWidget(self.proj_selector)
        self.setLayout(layout)
        
        self.registerField('crs',self.proj_selector)
        self.proj_selector.crsSelected.connect(self.crs_selected)
        
    def crs_selected(self):
        self.setField('crs',self.proj_selector.crs())
        self.completeChanged.emit()
        
    def isComplete(self):
        return self.proj_selector.crs().isValid()

There’s a lot happening here. First, we subclass QWizardPage to create a second page in our widget. Then, just like before, we add some widgets to this page and set the page’s layout. In this case we are using the standard QgsProjectionSelectionTreeWidget to give users a projection choice. Again, we let the wizard know about our new setting by a call to registerField. However, since QWizard has no knowledge about how to handle a QgsProjectionSelectionTreeWidget, there’s a bit more to do here. So we make a connection to the projection selector’s crsSelected signal, hooking it up to a function which sets the wizard’s “crs” field value to the widget’s selected CRS. Here, we also emit the completeChanged signal, which indicates that the wizard page should re-validate the current settings. Lastly, we override QWizardPage’s isComplete method, checking that there’s a valid CRS selection in the selector widget. If we run the wizard now we’ll be forced to choose a valid CRS from the widget before the wizard allows us to proceed:

Lastly, we need to adapt runNewProjectWizard to also handle the projection setting:

def runNewProjectWizard():
    d=ProjectWizard()
    d.exec()

    # Set the project crs
    crs=d.field('crs')
    QgsProject.instance().setCrs(crs)

    # Set the project title
    title=d.field('title')
    ...

Great! A fully functional New Project wizard. The final piece of the puzzle is triggering this wizard when a user creates a new project within QGIS. To do this, we hook into the iface.newProjectCreated signal. By connecting to this signal, our code will be called whenever the user creates a new project (after all the logic for saving and closing the current project has been performed). It’s as simple as this:

iface.newProjectCreated.connect(runNewProjectWizard)

Now, whenever a new project is made, our wizard is triggered – forcing users to populate the required fields and setting up the project accordingly!

There’s one last little bit to do – we also need to prevent users cancelling or closing the wizard before completing it. That’s done by changing a couple of settings in the ProjectWizard constructor, and by overriding the default reject method (which prevents closing the dialog by pressing escape).

class ProjectWizard(QWizard):
    
    def __init__(self, parent=None):
        super().__init__(parent)
        ...
        self.setOption(QWizard.NoCancelButton, True)
        self.setWindowFlags(self.windowFlags() | QtCore.Qt.CustomizeWindowHint)
        self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowCloseButtonHint)

    def reject(self):
        pass

Here’s the full version of our code, ready for copying and pasting into the QGIS Python console:

icon_path = '/home/nyall/nr_logo.png'

class ProjectWizard(QWizard):
    
    def __init__(self, parent=None):
        super().__init__(parent)
        
        self.addPage(Page1(self))
        self.addPage(Page2(self))
        self.setWindowTitle("New Project")
        
        logo_image=QImage('path_to_logo.png')
        self.setPixmap(QWizard.LogoPixmap, QPixmap.fromImage(logo_image))
        
        self.setOption(QWizard.NoCancelButton, True)
        self.setWindowFlags(self.windowFlags() | QtCore.Qt.CustomizeWindowHint)
        self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowCloseButtonHint)
    def reject(self):
        pass
class Page1(QWizardPage):
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setTitle('General Properties')
        self.setSubTitle('Enter general properties for this project.')

        # create some widgets
        self.project_number_line_edit = QLineEdit()
        self.project_title_line_edit = QLineEdit()
        self.author_line_edit = QLineEdit()        
        
        # set the page layout
        layout = QGridLayout()
        layout.addWidget(QLabel('Project Number'),0,0)
        layout.addWidget(self.project_number_line_edit,0,1)
        layout.addWidget(QLabel('Title'),1,0)
        layout.addWidget(self.project_title_line_edit,1,1)
        layout.addWidget(QLabel('Author'),2,0)
        layout.addWidget(self.author_line_edit,2,1)
        self.setLayout(layout)
        
        self.registerField('number*',self.project_number_line_edit)
        self.registerField('title*',self.project_title_line_edit)
        self.registerField('author*',self.author_line_edit)
 
 
class Page2(QWizardPage):
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setTitle('Project Coordinate System')
        self.setSubTitle('Choosing an appropriate projection is important to ensure accurate distance and area measurements.')
        
        self.proj_selector = QgsProjectionSelectionTreeWidget()
        layout = QVBoxLayout()
        layout.addWidget(self.proj_selector)
        self.setLayout(layout)
        
        self.registerField('crs',self.proj_selector)
        self.proj_selector.crsSelected.connect(self.crs_selected)
        
    def crs_selected(self):
        self.setField('crs',self.proj_selector.crs())
        self.completeChanged.emit()
        
    def isComplete(self):
        return self.proj_selector.crs().isValid()
 
        
def runNewProjectWizard():
    d=ProjectWizard()
    d.exec()
    
    # Set the project crs
    crs=d.field('crs')
    QgsProject.instance().setCrs(crs)
    
    # Set the project title
    title=d.field('title')
    QgsProject.instance().setTitle(d.field('title'))

    # Create expression variables for the author and project number
    number=d.field('number')
    QgsExpressionContextUtils.setProjectVariable(QgsProject.instance(),'project_number', number)
    author=d.field('author')
    QgsExpressionContextUtils.setProjectVariable(QgsProject.instance(),'project_author', author)
    
    
iface.newProjectCreated.connect(runNewProjectWizard)

Exploring Reports in QGIS 3.0 – the Ultimate Guide!

In 2017 North Road ran a crowd funding campaign for extending QGIS’ Print Composer and adding a brand new reporting framework to QGIS. Thanks to numerous generous backers, this campaign was a success. With the final QGIS 3.0 release just around the corner, we thought this was a great time to explore the new reporting engine and what it offers.

We’ll start with a relatively simple project, containing some administrative boundaries, populated places, ports and airports.

Using the “Project” – “New Report” command, we then create a new blank report. Initially, there’s not much to look at – the dialog which is displayed looks much like the QGIS 3.0 Layout Designer, except for the new “Report Organizer” panel shown on the left:

QGIS reports can consist of multiple, nested sections. In our new blank report we initially have only the main report section. The only options present for this report section is to include an optional header and footer for the report. If we enable these, the header will be included as the very first page (or pages… individual parts of reports can be multi-page if desired) in the report, and the footer would be the last page. Let’s go ahead and enable the header, and hit the “Edit” button next to it:

A few things happen as a result. Firstly, an edit pencil is now shown next to the “Report” section in the Report Organizer, indicating that the report section is currently being edited in the designer. We also see a new blank page shown in the designer itself, with the small “Report Header” title. In QGIS reports, every component of the report is made up of individual layouts. They can be created and modified using the exact same tools as are available for standard print layouts – so you can use any desired combination of labels, pictures, maps, tables, etc. Let’s add some items to our report header to demonstrate:

We’ll also create a simple footer for the report, by checking the “Include report footer” option and hitting “Edit“.

Before proceeding further, let’s export this report and see what we get. Exporting is done from the Report menu – in this case we select “Export Report as PDF” to render the whole report to a PDF file. Here’s the not-very-impressive result – a two page PDF consisting of our header and footer:

Let’s make things more interesting. By hitting the green “+” button in the Report Organizer, we’re given a choice of new sections to add to our report.

Currently there’s two options – a “Single section” and a “Field group“. Expect this list to grow in future QGIS releases, but for now we’ll add a Field Group to our report. At its most basic level, you can think of a Field Group as the equivalent of a print atlas. You select a layer to iterate over, and the report will insert a section for each feature found. Selecting the new Field Group section reveals a number of new related settings:

In this case we’ve setup our Field Group so that we iterate over all the states from the “Admin Level 1” layer, using the values from the “adm1name” field. The same options for header and footer are present, together with a new option to include a “body” for this section. We’ll do that, and edit the body:

We’ve setup this body with a map (set to follow the current report feature – just like how a map item in an atlas can follow the current atlas feature), and a label showing the state’s name. If we went ahead and exported our report now, we’d get something like this:

First, the report header, than a page for each state, and finally the report footer. So more or less an atlas, but with a header and footer page. Let’s make things more interesting by adding a subsection to our state group. We do this by first selecting the state field group in the organizer, then hitting the + button and adding a new Field Group:

When a field group is iterating over its features, it will automatically filter these features to match the feature attributes from its parent groups. In this case, the subsection we added will iterate over a “Populated Places” layer, including a body section for each place encountered. The magic here is that the Populated Places layer has an attribute named “adm1name“, tagging each place with the state it’s contained within (if you’re lucky your data will already be structured like this – if not, run the Processing “Join by Location” algorithm and create your own field). When we export this report, QGIS will grab the first state from the Admin Level 1 layer, and then iterate over all the Populated Places with a matching “adm1name” value. Here’s what we get:

(Here we created a basic body for the Populated Places group, including a map of the place and a table of some place attributes). So our report is now a report header, a page for each state followed by a page for every populated place within that state, and finally the report footer. If we were to add a header for the Populated Places group, it would be included just before listing the populated places for each state:

Similarly, a footer for the Populated Places group would be inserted after the final place for each state is included.

In addition to nested subsections, subsections in a report can also be included consecutively. If we add a second subsection to the Admin Level 1 group for Airports, then our report will first list ALL the populated places for each state, followed by all the airports within that state, before proceeding to the next state. In this case our report would be structured like this:

(The key point here is that our Airports group is a subsection of the Admin Level 1 group – not the Populated Places group). Here’s what our report could look like now:

Combining nested and consecutive sections, together with section headers and footers allows for tons of flexibility. For instance, in the below report we add another field group as a child of the main report for the Ports layer. Now, after listing the states together with their populated places and airports, we’ll get a summary list of all the ports in the region:

This results in the last part of our report exporting as:

As you can start to imagine, reports in QGIS are extremely powerful and flexible! We’re extremely thankful for all the backers of our crowd funding campaign, without whom this work would not have been possible.

Stay tuned for more reporting and layouts work we have planned for QGIS 3.2!

 

24 Days of QGIS 3.0 Features

If you’re not following @northroadgeo on Twitter, you’ve probably missed our recent “24 Days of QGIS” countdown. Over December, we’ve been highlighting 24 different features which are coming with the QGIS 3.0 release. We’ve collected all of these below so you can catch up:

We hope you enjoyed the series! In it we’ve only highlighted just a few of the hundreds of new features coming in QGIS 3.0. There’s also a lot of behind-the-scenes changes which we haven’t touched, e.g. a switch to Python 3 and Qt 5 libraries, a brand new, rewritten QGIS server, new QGIS web client, enhanced metadata integration, GeoNode integration, a cleaner, stabler, easier PyQGIS API, 1000s more unit tests, and so much more.

You can download a 3.0 beta from the QGIS webpage, and report feedback at https://issues.qgis.org. A huge thanks to the mammoth effort of all the QGIS contributors, this is going to be a great release!

QGIS layouts rewrite – progress report #1

Following our recent successful QGIS Layout and Reporting Engine crowdfunding campaign, we’ve been hard at working ripping up the internals of the QGIS 2.x print composer and rebuilding a brand new, shiny QGIS layouts engine. This is exciting work – it’s very satisfying to be able to cleanup a lot of the old composer code in QGIS and take opportunities along the way to fix long standing bugs and add new features.

While it’s not ready for daily use yet, there’s already been a lot of interesting changes which have landed in the layouts work as a result of this campaign. Let’s take a look at what’s been implemented so far…

  • We’ve added support for different measurements units all throughout layouts. While this means it’s now possible to set page sizes using centimeters, inches, pixels, points, etc, it goes much deeper than just that. In layouts, everything which has a size or position can take advantage of this unit support. So you can have page sizes in centimeters, but a map item with a size set in points, and positioned in millimeters! Having pixels as a unit type makes creation of screen-based layouts much easier – even right down to pixel perfect positioning and sizing of items…
  • Page handling has been totally reworked. Instead of the single “number of pages” control available in QGIS 2.x, layouts have complete flexibility in page setup. It’s now possible to have a layout with mixed page sizes and orientations (including data defined page size for different pages in the layout!). 
  • A revised status bar, with improved layout interaction widgets. We’ve also taken the opportunity to add some new features like a zoom level slider and option to zoom to layout width:
  • Layout interaction tools (such as pan/zoom/insert item/etc) have been reworked. There’s now a much more flexible framework for creation of layout tools (based off the main QGIS map canvas approach), which even allows for plugins to implement their own layout interaction tools! As part of this we’ve addressed a long standing annoyance which meant that creating new items always drew the “preview” shape of the new item as a rectangle – even for non-rectangular items. Now you get a real shape showing exactly how the created item will be sized and positioned:
  • On the topic of plugins – the layout branch has full support for plugin-provided item types. This means that QGIS plugins can create new classes of items which can be added to a layout. This opens the door for plugins allowing charts and visualisations which take advantage of all the mature Python and JS charting libraries! This is a really exciting change – in 2.x there was no way for plugins to extend or interact with composer, so we’re really keen to see where the community takes this when 3.0 is released.
  • We’ve ported another feature commonly found in illustration/DTP applications. Now, when you’re creating a new item and just click in your layout (instead of click-and-drag), you get a handy dialog allowing you to specify the exact position and dimensions for the created item. You can again see in this dialog how layouts have full support for units for both the position and size:
  • Another oft-requested feature which we’ve finally been able to add (thanks to the refactored and cleaned code) is a context menu for layouts! It’s currently quite empty, but will be expanded as this work progresses…
  • Snapping to guides and grids has been reworked. We’ve added a new snapping marker to show exactly were items will be snapped to:
  • Snapping to guides now occurs when creating new layout items (this didn’t happen in Composer in 2.x – only snapping to grids occurred when drawing new items).
  • The snapped cursor position is shown in status bar whenever a snapped point will be used, instead of the unsnapped position.
  • Unlike in Composers in QGIS 2.x, Layouts in 3.0 adopt the standard UX of dragging out rulers to create guide lines (instead of clicking on a ruler position to create a new guide). Creation of a horizontal guide is now done by grabbing the top ruler and dragging it down, and a vertical guide is created by grabbing the left ruler and dragging it out to the layout.
  • Better feedback is given in the ruler when a guide can be dragged. We now show guide positions in the rulers, and give an indication (via mouse cursor change) when these guides can be repositioned by click-and-drag.
  • Another very exciting change is the addition of a new “Guide Manager”. The guide manager allows numeric modification of existing guides and creation of new guides. Finally it’s possible to position guides at exact locations! Again, you can see the full support for layout units in place here – guides can be positioned using any available unit.
  • There’s also a handy new shortcut in the Guide Manager to allow applying the guides from the current page to all other pages in your layout.
  • We’ve refined the snapping logic. In Composer in QGIS 2.x,  grids would always take precedence whenever both a grid and guide were within tolerance of a point. Now, guides will always take precedence – since they have been manually set by users we make the assumption that they have been explicitly placed at highly desirable snapping locations, and should be selected over the general background grid. Additionally, grid snapping was previously only done if BOTH the x and y of the point could be snapped to the grid. We now snap to the nearest grid line for x/y separately. This means if a point is close to a vertical grid line but not a horizontal one it will still snap to that nearby vertical grid line.
  • Lastly, we’ve added a handy context menu to the rulers:

This is just a taster of the great new functionality coming in QGIS 3.0. This is all a direct result of the forward-thinking investments and generosity of the backers in our QGIS Layout and Reporting Engine crowdfunding campaign. Without their contributions, none of this would be possible – so our thanks go out to those organisations and individuals once again!

Stay tuned for more updates as the work continues…

 

 

QGIS Layout and Reporting Engine Campaign – a success!

Thanks to the tireless efforts and incredible generosity of the QGIS user community, our crowdfunded QGIS Layout and Reporting Engine campaign was a tremendous success! We’ve reached the funding goal for this project, and as a result QGIS 3.0 will include a more powerful print composer with a reworked code base. You can read more about what we have planned at the campaign page.

We’d like to take this opportunity to extend our heartfelt thanks to all the backers who have pledged to support this project:

We’ve also received numerous anonymous contributions in addition to these – please know that the QGIS community extends their gratitude for your contributions too! This campaign was also successful thanks to The Agency for Data Supply and Efficiency, Denmark, who stepped up and have funded an initial component of this project directly.

We’d also like to thank every member of the QGIS community who assisted with promoting this campaign and bringing it to the attention of these backers. Without your efforts we would not have been able to reach these backers and the campaign would not have been successful.

We’ll be posting more updates as this work progresses. Stay tuned…

 

QGIS Composer Rewrite and Layout Engine crowdfund – half way there!

If you’ve been following our recent blog posts, you’ll be aware that we are currently running a crowd funding campaign to extend the capabilities of QGIS’ print composer. You can read full details about this over at the campaign page.

The good news is that we’ve just hit the mid way point of the funds! Many generous backers have stepped up with contributions and we’re well on the way to reaching the funding goal. However, we still need your help make this work a reality.

Right now, what we need most is interested users and community members who will reach out to their local QGIS users and seek more backing for the campaign. We need to publicise the campaign beyond the regular online QGIS community, to the thousands of enterprises and organisations which rely on QGIS for their daily mapping operations. We need community members who can get in contact with these organisations and help convince them that investing back into the open source software they utilise is beneficial (and often will even SAVE them money in the long run, due to the increased productivity that changes like our composer improvements will bring!).

So, while social media reshares have been vital to reaching the current stage, we now need more “hands on” helpers who will take this on. If you know of any organisations which depend on QGIS for their mapping outputs, now’s the time to get in contact with them directly and advise them of this campaign!

 

 

 

QGIS Composer Rewrite and Layout Engine crowdfund launched!

At North Road we believe that crowdfunding is a sustainable way to maintain and enhance open source software, like the QGIS open source GIS package. We’ve run a number of successful crowdfunding campaigns in the past, including support in QGIS for live layer effects, a point cluster renderer, and a unique value renderer for raster layers.

Now, we’re proud to announce our latest crowd funding endeavour, and our biggest to date, the QGIS Layout and Reporting Engine Campaign.

This campaign covers stage 1 of a large, ongoing project to modernise and expand on QGIS’ print composer and layout facilities. Over time QGIS’ composer functionality has grown extensively and now is capable of creating flexible, high quality cartographic outputs. However, we’ve now hit a limit where the current code architecture is prohibiting further improvements and important fixes. In order to add a reporting framework to QGIS, it is necessary for us to refactor and improve large sections of the composer code.

If this campaign is successful, we’ll be adding flexible report generation features to QGIS and cleaning up all the existing composer code. As part of these clean up, we’ll be taking the opportunity to tackle a number of current limitations which cannot be addressed in the current composition code:

  • Layouts will become unit aware, allowing for item placement and properties using millimetres, inches, pixels, centimetres, points, etc.
  • Layouts will have the ability to include mixed page sizes and orientations.
  • Plugins will be able to create custom composer item types (eg allow utilisation of 3rd party graphing and visualisation libraries!).
  • Individual layout items can be rasterised without affecting the rest of the layout. For instance, a map which requires rasterisation due to its use of blend modes will not require all other layout items (such as headings, legends, etc) to be rasterised. This will greatly benefit PDF outputs for complex map layouts.
  • The code refresh will allow more extensive use of data defined layout item properties.
  • A render caching system will be implemented for items, speeding up use of the layout designer and also paving the way for use of live paint effects on layout items (eg dynamic drop shadows).

Full details on what we have planned are available here: QGIS Layout and Reporting Engine Campaign.

To make it possible we need 30,000€ pledged before 31 May 2017. You can help make this a reality by supporting the campaign or by sharing the campaign page and increasing exposure to the campaign. Updates to follow!

  • Page 1 of 2 ( 32 posts )
  • >>

Back to Top

Sponsors