Page 1 of 6 (105 posts)

  • talks about »
  • osgeo

Tags

Last update:
Fri Jun 23 00:10:15 2017

A Django site.

QGIS Planet

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!

 

 

 

The Inaugural QGIS Australia Hackfest – Noosa 2017

Last week we kicked off the first (of hopefully many) Australian QGIS hackfests Developers Meetings. It was attended by 3 of the core QGIS development team: Nathan Woodrow, Martin Dobias and myself (Nyall Dawson), along with various family members. While there’s been QGIS hackfests in Europe for over 10 years, and others scattered throughout various countries (I think there was a Japanese one recently… but Twitter’s translate tool leaves me with little confidence about this!), there’s been no events like this in the Southern hemisphere yet. I’ve been to a couple in Europe and found them to be a great way to build involvement in the project, for both developers and non-developers alike.

In truth the Australian hackfest plans began mostly an excuse for Nathan and I to catch up with Martin Dobias before he heads back out of this hemisphere and returns to Europe. That said, Nathan and I have long spoken about ways we can build up the QGIS community in Australia, so in many ways this was a trial run for future events. It was based it in Noosa, QLD (and yes, we did manage to tear ourselves away from our screens long enough to visit the beach!).

Nathan Woodrow (@NathanW2), myself (@nyalldawson), and Martin Dobias (@wonder-sk)

Here’s a short summary of what we worked on during the hackfest:

  • Martin implemented a new iterator style accessor for vertices within geometries. The current approach to accessing vertices in QGIS is far from optimal. You either have the choice of an inefficient methods (eg QgsGeometry.asPolyline(), asPolygon(), etc) which requires translations of all vertices to a different data structure (losing any z/m dimensional values in the process), or an equally inefficient QgsAbstractGeometry.coordinateSequence() method, which at least keeps z/m values but still requires expensive copies of every vertex in the geometry. For QGIS 3.0 we’ve made a huge focus on optimising geometry operations and vertex access is one of the largest performance killers remaining in the QGIS code. Martin’s work adds a proper iterator for the vertices within a geometry object, both avoiding all these expensive copies and also simplifying the API for plugins. When this work lands traversing the vertices will become as simple as
for v in geom.vertices():
   ... do something with the vertex!
  • Martin is also planning on extending this work to allow simple iteration over the parts and rings within geometries too. When this lands in QGIS we can expect to see much faster geometry operations.
  • Nathan fixed a long standing hassle with running standalone PyQGIS scripts outside of the QGIS application on Windows. In earlier versions there’s a LOT of batch file mangling and environment variable juggling required before you can safely import the qgis libraries within Python. Thanks to Nathan’s work, in QGIS 3.0 this will be as simple as just making sure that the QGIS python libraries are included in your Python path, and then importing qgis.core/gui etc will work without any need to create environment variables for OSGEO/GDAL/PLUGINS/etc. Anyone who has fought with this in the past will definitely appreciate this change, and users of Python IDEs will also appreciate how simple it is now to make the PyQGIS libraries available in these environments.
  • Nathan also worked on “profiles” support for QGIS 3.0. This work will add isolated user profiles within QGIS, similar to how Chrome handles this. Each profile has it’s own separate set of settings, plugins, etc. This work is designed to benefit both plugin developers and QGIS users within enterprise environments. You can read more about what Nathan has planned for this here.
  • I continued the ongoing work of moving long running interface “blocking” operations to background tasks. In QGIS 3.0 many of these tasks churn away in the background, allowing you to continue work while the operation completes. It’s been implemented so far for vector and raster layer saving, map exports to images/PDF (not composers unfortunately), and obtaining feature counts within legends. During the hackfest I moved the layer import which occurs when you drag and drop a layer to a destination in the browser to a background task.
  • On the same topic, I took some inspiration from a commit in Sourcepole’s QGIS fork and reworked how composer maps are cached. One of my biggest gripes with QGIS’ composer is how slow it is to work with when you’ve got a complex map included. This change pushes the map redrawing into a background thread, so that these redraws no longer “lock up” the UI. It makes a HUGE difference in how usable composer is. This improvement also allowed me to remove those confusing map item “modes” (Cache/Render/Rectangle) – now everything is redrawn silently in the background whenever required.
  • Lastly, I spent a lot of time on a fun feature I’ve long wanted in QGIS – a unified search “locator” bar. This feature is heavily inspired by Qt Creator’s locator bar. It sits away down in the status bar, and entering any text here fires up a bunch of background search tasks. Inbuilt searches include searching the layers within the current project (am I the only one who loses layers in the tree in complex projects!?), print layouts in the project, processing algorithms, and menu/toolbar actions. The intention here is that plugins will “take over” and add additional search functionality, such as OSM place names searching, data catalog searches, etc. I’m sure when QGIS 3.0 is released this will quickly become indispensable!

The upcoming QGIS 3.0 locator bar

Big thanks go out to Nathan’s wife, Stacey, who organized most of the event and without whom it probably would never have happened, and to Lutra Consulting who sponsored an awesome dinner for the attendees.

We’d love this to be the first of many. The mature European hackfests are attended by a huge swath of the community, including translators, documentation writers, and plugin developers (amongst others). If you’ve ever been interested in finding out how you can get more involved in the project it’s a great way to dive in and start contributing. There’s many QGIS users in this part of the world and we really want to encourage a community of contributors who “give back” to the project. So let Nathan or myself know if you’d be interested in attending other events like this, or helping to organize them locally yourself…

GRASS GIS 7.2.1 released

We are pleased to announce the update release GRASS GIS 7.2.1

GRASS GIS 7.2.1 in actionWhat’s new in a nutshell

After four months of development the new update release GRASS GIS 7.2.1 is available. It provides more than 150 stability fixes and manual improvements compared to the first stable release version 7.2.0. An overview of new features in this release series is available at New Features in GRASS GIS 7.2.

About GRASS GIS 7: Its graphical user interface supports the user to make complex GIS operations as simple as possible. The updated Python interface to the C library permits users to create new GRASS GIS-Python modules in a simple way while yet obtaining powerful and fast modules. Furthermore, the libraries were again significantly improved for speed and efficiency, along with support for huge files. A lot of effort has been invested to standardize parameter and flag names. Finally, GRASS GIS 7 comes with a series of new modules to analyse raster and vector data, along with a full temporal framework. For a detailed overview, see the list of new features. As a stable release series, 7.2.x enjoys long-term support.

Binaries/Installer download:

Source code download:

More details:

See also our detailed announcement:

https://trac.osgeo.org/grass/wiki/Grass7/NewFeatures72 (overview of new 7.2 stable release series)

https://grass.osgeo.org/grass72/manuals/addons/ (list of available addons)

First time users may explore the first steps tutorial after installation.

About GRASS GIS

The Geographic Resources Analysis Support System (https://grass.osgeo.org/), commonly referred to as GRASS GIS, is an Open Source Geographic Information System providing powerful raster, vector and geospatial processing capabilities in a single integrated software suite. GRASS GIS includes tools for spatial modeling, visualization of raster and vector data, management and analysis of geospatial data, and the processing of satellite and aerial imagery. It also provides the capability to produce sophisticated presentation graphics and hardcopy maps. GRASS GIS has been translated into about twenty languages and supports a huge array of data formats. It can be used either as a stand-alone application or as backend for other software packages such as QGIS and R geostatistics. It is distributed freely under the terms of the GNU General Public License (GPL). GRASS GIS is a founding member of the Open Source Geospatial Foundation (OSGeo).

The GRASS Development Team, May 2017

The post GRASS GIS 7.2.1 released appeared first on GFOSS Blog | GRASS GIS Courses.

About label halos

A lot of cartographers have a love/hate relationship with label halos. On one hand they can be an essential technique for improving label readability, especially against complex background layers. On the other hand they tend to dominate maps and draw unwanted attention to the map labels.

In this post I’m going to share my preferred techniques for using label halos. I personally find this technique is a good approach which minimises the negative effects of halos, while still providing a good boost to label readability. (I’m also going to share some related QGIS 3.0 news at the end of this post!)

Let’s start with some simple white labels over an aerial image:

These labels aren’t very effective. The complex background makes them hard to read, especially the “Winton Shire” label at the bottom of the image. A quick and nasty way to improve readability is to add a black halo around the labels:

Sure, it’s easy to read the labels now, but they stand out way too much and it’s difficult to see anything here except the labels!

We can improve this somewhat through a better choice of halo colour:

This is much better. We’ve got readable labels which aren’t too domineering. Unfortunately the halo effect is still very prominent, especially where the background image varies a lot. In this case it works well for the labels toward the middle of the map, but not so well for the labels at the top and bottom.

A good way to improve this is to take advantage of blending (or “composition”) modes (which QGIS has native support for). The white labels will be most readable when there’s a good contrast with the background map, i.e. when the background map is dark. That’s why we choose a halo colour which is darker than the text colour (or vice versa if you’ve got dark coloured labels). Unfortunately, by choosing the mid-toned brown colour to make the halos blend in more, we are actually lightening up parts of this background layer and both reducing the contrast with the label and also making the halo more visible. By using the “darken” blend mode, the brown halo will only be drawn for pixels were the brown is darker then the existing background. It will darken light areas of the image, but avoid lightening pixels which are already dark and providing good contrast. Here’s what this looks like:

The most noticeable differences are the labels shown above darker areas – the “Winton Shire” label at the bottom and the “Etheridge Shire” at the top. For both these labels the halo is almost imperceptible whilst still subtly doing it’s part to make the label readable. (If you had dark label text with a lighter halo color, you can use the “lighten” blend mode for the same result).

The only issue with this map is that the halo is still very obvious around “Shire” in “Richmond Shire” and “McKinlay” on the left of the map. This can be reduced by applying a light blur to the halo:

There’s almost no loss of readability by applying this blur, but it’s made those last prominent halos disappear into the map. At first glance you probably wouldn’t even notice that there’s any halos being used here. But if we compare back against the original map (which used no halos) we can see the huge difference in readability:

Compare especially the Winton Shire label at the bottom, and the Richmond Shire label in the middle. These are much clearer on our tweaked map versus the above image.

Now for the good news… when QGIS 3.0 is released you’ll no longer have to rely on an external illustration/editing application to get this effect with your maps. In fact, QGIS 3.0 is bringing native support for applying many types of live layer effects to label buffers and background shapes, including blur. This means it will be possible to reproduce this technique directly inside your GIS, no external editing or tweaking required!

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!

New map coloring algorithms in QGIS 3.0

It’s been a long time since I last blogged here. Let’s just blame that on the amount of changes going into QGIS 3.0 and move on…

One new feature which landed in QGIS 3.0 today is a processing algorithm for automatic coloring of a map in such a way that adjoining polygons are all assigned different color indexes. Astute readers may be aware that this was possible in earlier versions of QGIS through the use of either the (QGIS 1.x only!) Topocolor plugin, or the Coloring a map plugin (2.x).

What’s interesting about this new processing algorithm is that it introduces several refinements for cartographically optimising the coloring. The earlier plugins both operated by pure “graph” coloring techniques. What this means is that first a graph consisting of each set of adjoining features is generated. Then, based purely on this abstract graph, the coloring algorithms are applied to optimise the solution so that connected graph nodes are assigned different colors, whilst keeping the total number of colors required minimised.

The new QGIS algorithm works in a different way. Whilst the first step is still calculating the graph of adjoining features (now super-fast due to use of spatial indexes and prepared geometry intersection tests!), the colors for the graph are assigned while considering the spatial arrangement of all features. It’s gone from a purely abstract mathematical solution to a context-sensitive cartographic solution.

The “Topological coloring” processing algorithm

Let’s explore the differences. First up, the algorithm has an option for the “minimum distance between features”. It’s often the case that features aren’t really touching, but are instead just very close to each other. Even though they aren’t touching, we still don’t want these features to be assigned the same color. This option allows you to control the minimum distance which two features can be to each other before they can be assigned the same color.

The biggest change comes in the “balancing” techniques available in the new algorithm. By default, the algorithm now tries to assign colors in such a way that the total number of features assigned each color is equalised. This avoids having a color which is only assigned to a couple of features in a large dataset, resulting in an odd looking map coloration.

Balancing color assignment by count – notice how each class has a (almost!) equal count

Another available balancing technique is to balance the color assignment by total area. This technique assigns colors so that the total area of the features assigned to each color is balanced. This mode can be useful to help avoid large features resulting in one of the colors appearing more dominant on a colored map.

Balancing assignment by area – note how only one large feature is assigned the red color

The final technique, and my personal preference, is to balance colors by distance between colors. This mode will assign colors in order to maximize the distance between features of the same color. Maximising the distance helps to create a more uniform distribution of colors across a map, and avoids certain colors clustering in a particular area of the map. It’s my preference as it creates a really nice balanced map – at a glance the colors look “randomly” assigned with no discernible pattern to the arrangement.

Balancing colors by distance

As these examples show, considering the geographic arrangement of features while coloring allows us to optimise the assigned colors for cartographic output.

The other nice thing about having this feature implemented as a processing algorithm is that unlike standalone plugins, processing algorithms can be incorporated as just one step of a larger model (and also reused by other plugins!).

QGIS 3.0 has tons of great new features, speed boosts and stability bumps. This is just a tiny taste of the handy new features which will be available when 3.0 is released!

New major release: GRASS GIS 7.2.0 available

We are pleased to announce the stable release of GRASS GIS 7.2.0

What’s new in a nutshell

After almost two years of development the new stable major release GRASS GIS 7.2.0 is available. It provides more than 1950 stability fixes and manual improvements compared to the former stable release version 7.0.5. The new version includes a series of new modules to analyse raster and vector data along with new temporal algebra functionality.More than 50 new addons are also available. A summary of the new features is available at New Features in GRASS GIS 7.2.

About GRASS GIS 7: Its graphical user interface supports the user to make complex GIS operations as simple as possible. The updated Python interface to the C library permits users to create new GRASS GIS-Python modules in a simple way while yet obtaining powerful and fast modules. Furthermore, the libraries were again significantly improved for speed and efficiency, along with support for huge files. A lot of effort has been invested to standardize parameter and flag names. Finally, GRASS GIS 7 comes with a series of new modules to analyse raster and vector data, along with a full temporal framework. For a detailed overview, see the list of new features. As a stable release series, 7.2.x enjoys long-term support.

Binaries/Installer download:

Source code download:

More details:

See also our detailed announcement:

First time users may explore the first steps tutorial after installation.

About GRASS GIS

The Geographic Resources Analysis Support System (https://grass.osgeo.org/), commonly referred to as GRASS GIS, is an Open Source Geographic Information System providing powerful raster, vector and geospatial processing capabilities in a single integrated software suite. GRASS GIS includes tools for spatial modeling, visualization of raster and vector data, management and analysis of geospatial data, and the processing of satellite and aerial imagery. It also provides the capability to produce sophisticated presentation graphics and hardcopy maps. GRASS GIS has been translated into about twenty languages and supports a huge array of data formats. It can be used either as a stand-alone application or as backend for other software packages such as QGIS and R geostatistics. It is distributed freely under the terms of the GNU General Public License (GPL). GRASS GIS is a founding member of the Open Source Geospatial Foundation (OSGeo).

The GRASS Development Team, December 2016

The post New major release: GRASS GIS 7.2.0 available appeared first on GFOSS Blog | GRASS GIS Courses.

QGIS 2.18 packaged for Fedora 23 and 24

qgis-icon_smallThanks to the work of Volker Fröhlich and other Fedora packagers I was able to create RPM packages of QGIS 2.18 Las Palmas for Fedora 23 and 24 using Fedora’s COPR platform.

Repo: https://copr.fedorainfracloud.org/coprs/neteler/QGIS-2.18-Las-Palmas

The following packages can now be installed:

  • qgis 2.18.0
  • qgis-debuginfo 2.18.0
  • qgis-devel 2.18.0
  • qgis-grass 2.18.0
  • qgis-python 2.18.0
  • qgis-server 2.18.0

Installation instructions (run as “root” user or use “sudo”):

su

# Fedora 23, Fedora 24:
dnf copr enable neteler/QGIS-2.18-Las-Palmas
dnf update
# note: the "qca-ossl" package is the OpenSSL plugin for QCA
dnf install qgis qgis-grass qgis-python qca-ossl

Enjoy!

The post QGIS 2.18 packaged for Fedora 23 and 24 appeared first on GFOSS Blog | GRASS GIS Courses.

GDAL 2.1 packaged for Fedora 23 and 24

GDAL logoThe new GDAL 2.1 is now also packaged for Fedora 23 and 24 which is possible due to the tireless efforts of various Fedora packagers.

Repo: https://copr.fedorainfracloud.org/coprs/neteler/GDAL/

Installation Instructions:

su

# Fedora 23+24:
# install this extra repo
dnf copr enable neteler/GDAL

# A) in case of update, simply
dnf update

# B) in case of new installation (gdal-devel is optional)
dnf install gdal gdal-python gdal-devel

The post GDAL 2.1 packaged for Fedora 23 and 24 appeared first on GFOSS Blog | GRASS GIS Courses.

GRASS GIS 7.2.0RC1 released

We are pleased to announce the first release candidate of GRASS GIS 7.2.0

What’s new in a nutshell

This is the first release candidate of the upcoming major release GRASS GIS 7.2.0.

The new GRASS GIS 7.2.0RC1 release provides more than 1900 stability fixes and manual improvements compared to the stable releases 7.0.x.

hexagons_python_editorAbout GRASS GIS 7: Its graphical user interface supports the user to make complex GIS operations as simple as possible. The updated Python interface to the C library permits users to create new GRASS GIS-Python modules in a simple way while yet obtaining powerful and fast modules. Furthermore, the libraries were significantly improved for speed and efficiency, along with support for huge files. A lot of effort has been invested to standardize parameter and flag names. Finally, GRASS GIS 7 comes with a series of new modules to analyse raster and vector data, along with a full temporal framework. For a detailed overview, see the list of new features. As a stable release series, 7.2.x enjoys long-term support.

Binaries/Installer download:

Source code download:

More details:

See also our detailed announcement:

http://trac.osgeo.org/grass/wiki/Grass7/NewFeatures (overview of new 7 stable release series)

First time users may explore the first steps tutorial after installation.

About GRASS GIS

The Geographic Resources Analysis Support System (http://grass.osgeo.org/), commonly referred to as GRASS GIS, is an Open Source Geographic Information System providing powerful raster, vector and geospatial processing capabilities in a single integrated software suite. GRASS GIS includes tools for spatial modeling, visualization of raster and vector data, management and analysis of geospatial data, and the processing of satellite and aerial imagery. It also provides the capability to produce sophisticated presentation graphics and hardcopy maps. GRASS GIS has been translated into about twenty languages and supports a huge array of data formats. It can be used either as a stand-alone application or as backend for other software packages such as QGIS and R geostatistics. It is distributed freely under the terms of the GNU General Public License (GPL). GRASS GIS is a founding member of the Open Source Geospatial Foundation (OSGeo).

The GRASS Development Team, October 2016

The post GRASS GIS 7.2.0RC1 released appeared first on GFOSS Blog | GRASS GIS Courses.

Speeding up your PyQGIS scripts

I’ve recently spent some time optimising the performance of various QGIS plugins and algorithms, and I’ve noticed that there’s a few common performance traps which developers fall into when fetching features from a vector layer. In this post I’m going to explore these traps, what makes them slow, and how to avoid them.

As a bit of background, features are fetched from a vector layer in QGIS using a QgsFeatureRequest object. Common use is something like this:

request = QgsFeatureRequest()
for feature in vector_layer.getFeatures(request):
    # do something

This code would iterate over all the features in layer. Filtering the features is done by tweaking the QgsFeatureRequest, such as:

request = QgsFeatureRequest().setFilterFid(1001)
feature_1001 = next(vector_layer.getFeatures(request))

In this case calling getFeatures(request) just returns the single feature with an ID of 1001 (which is why we shortcut and use next(…) here instead of iterating over the results).

Now, here’s the trap: calling getFeatures is expensive. If you call it on a vector layer, QGIS will be required to setup an new connection to the data store (the layer provider), create some query to return data, and parse each result as it is returned from the provider. This can be slow, especially if you’re working with some type of remote layer, such as a PostGIS table over a VPN connection. This brings us to our first trap:

Trap #1: Minimise the calls to getFeatures()

A common task in PyQGIS code is to take a list of feature IDs and then request those features from the layer. A see a lot of older code which does this using something like:

for id in some_list_of_feature_ids:
    request = QgsFeatureRequest().setFilterFid(id)
    feature = next(vector_layer.getFeatures(request))
    # do something with the feature

Why is this a bad idea? Well, remember that every time you call getFeatures() QGIS needs to do a whole bunch of things before it can start giving you the matching features. In this case, the code is calling getFeatures() once for every feature ID in the list. So if the list had 100 features, that means QGIS is having to create a connection to the data source, set up and prepare a query to match a single feature, wait for the provider to process that, and then finally parse the single feature result. That’s a lot of wasted processing!

If the code is rewritten to take the call to getFeatures() outside of the loop, then the result is:

request = QgsFeatureRequest().setFilterFids(some_list_of_feature_ids)
for feature in vector_layer.getFeatures(request):
    # do something with the feature

Now there’s just a single call to getFeatures() here. QGIS optimises this request by using a single connection to the data source, preparing the query just once, and fetching the results in appropriately sized batches. The difference is huge, especially if you’re dealing with a large number of features.

Trap #2: Use QgsFeatureRequest filters appropriately

Here’s another common mistake I see in PyQGIS code. I often see this one when an author is trying to do something with all the selected features in a layer:

for feature in vector_layer.getFeatures():
    if not feature.id() in vector_layer.selectedFeaturesIds():
        continue

    # do something with the feature

What’s happening here is that the code is iterating over all the features in the layer, and then skipping over any which aren’t in the list of selected features. See the problem here? This code iterates over EVERY feature in the layer. If you’re layer has 10 million features, we are fetching every one of these from the data source, going through all the work of parsing it into a QGIS feature, and then promptly discarding it if it’s not in our list of selected features. It’s very inefficient, especially if fetching features is slow (such as when connecting to a remote database source).

Instead, this code should use the setFilterFids() method for QgsFeatureRequest:

request = QgsFeatureRequest().setFilterFids(vector_layer.selectedFeaturesIds())
for feature in vector_layer.getFeatures(request):
    # do something with the feature

Now, QGIS will only fetch features from the provider with matching feature IDs from the list. Instead of fetching and processing every feature in the layer, only the actual selected features will be fetched. It’s not uncommon to see operations which previously took many minutes (or hours!) drop down to a few seconds after applying this fix.

Another variant of this trap uses expressions to test the returned features:

filter_expression = QgsExpression('my_field > 20')
for feature in vector_layer.getFeatures():
    if not filter_expression.evaluate(feature):
        continue

    # do something with the feature

Again, this code is fetching every single feature from the layer and then discarding it if it doesn’t match the “my_field > 20” filter expression. By rewriting this to:

request = QgsFeatureRequest().setFilterExpression('my_field > 20')
for feature in vector_layer.getFeatures(request):
    # do something with the feature

we hand over the bulk of the filtering to the data source itself. Recent QGIS versions intelligently translate the filter into a format which can be applied directly at the provider, meaning that any relevant indexes and other optimisations can be applied by the provider itself. In this case the rewritten code means that ONLY the features matching the ‘my_field > 20’ criteria are fetched from the provider – there’s no time wasted messing around with features we don’t need.

 

Trap #3: Only request values you need

The last trap I often see is that more values are requested from the layer then are actually required. Let’s take the code:

my_sum = 0
for feature in vector_layer.getFeatures(request):
    my_sum += feature['value']

In this case there’s no way we can optimise the filters applied, since we need to process every feature in the layer. But – this code is still inefficient. By default QGIS will fetch all the details for a feature from the provider. This includes all attribute values and the feature’s geometry. That’s a lot of processing – QGIS needs to transform the values from their original format into a format usable by QGIS, and the feature’s geometry needs to be parsed from it’s original type and rebuilt as a QgsGeometry object. In our sample code above we aren’t doing anything with the geometry, and we are only using a single attribute from the layer. By calling setFlags( QgsFeatureRequest.NoGeometry ) and setSubsetOfAttributes() we can tell QGIS that we don’t need the geometry, and we only require a single attribute’s value:

my_sum = 0
request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes(['value'], vector_layer.fields() )
for feature in vector_layer.getFeatures(request):
    my_sum += feature['value']

None of the unnecessary geometry parsing will occur, and only the ‘value’ attribute will be fetched and populated in the features. This cuts down both on the processing required AND the amount of data transfer between the layer’s provider and QGIS. It’s a significant improvement if you’re dealing with larger layers.

Conclusion

Optimising your feature requests is one of the easiest ways to speed up your PyQGIS script! It’s worth spending some time looking over all your uses of getFeatures() to see whether you can cut down on what you’re requesting – the results can often be mind blowing!

Point cluster renderer crowdfunding – successful!

Great news! Thanks in part to some generous last minute pledges, our QGIS Point Cluster Renderer campaign has successfully reached its target. This means that QGIS 3.0 will now include a full feature and flexible cluster renderer.

In the meantime, we’d like to extend our warmest thanks to the following generous contributors, whose pledges have made this work possible:

  • Andreas Neumann
  • Qtibia Engineering (Tudor Barascu)
  • Karl-Magnus Jönsson
  • Geonesia (Nicolas Ponzo)

Plus numerous additional anonymous backers whose generous contributions are also highly valued. If you run into any of these funders at a QGIS user group or conference, make sure you treat them like the GIS rock-stars they are!

Keep an eye out on our social media accounts as we’ll be posting more video demonstrations of this work as it lands in the QGIS codebase.

BOTH

GRASS GIS PSC election 2016 results

The new GRASS GIS Project Steering Committee (PSC) is composed of the following nine members (ranking, name, votes):

1 Markus Neteler 62
2 Helena Mitasova 53
3 Martin Landa 52
4 Anna Petrasova 45
5 Moritz Lennert 41
6 Margherita Di Leo 39
7 Michael Barton 35
8 Peter Löwe 33
9 Vaclav Petras 31

More details in earlier announcement sent to the “grass-psc” mailing list:
https://lists.osgeo.org/pipermail/grass-psc/2016-August/001571.html.

For completeness, all relevant candidacy communications, as well as details about the voting process, are published at
https://trac.osgeo.org/grass/wiki/PSC/Election2016

Cited from the original announcement email:
https://lists.osgeo.org/pipermail/grass-announce/2016-September/000119.html

The post GRASS GIS PSC election 2016 results appeared first on GFOSS Blog | GRASS GIS Courses.

Point cluster renderer crowdfunding – the final countdown!

At North Road we are currently running a crowdfunding campaign to sponsor work on a new “Point Cluster Renderer” for QGIS. This is a really exciting new feature which would help make possible some neat styling effects which just aren’t possible in QGIS at the moment. The campaign is now in its final hours and we’ve still got some way to go to reach the campaign goals. If you’re interested in seeing this feature happen, now’s the time to jump onboard and contribute to the campaign!

Before time runs out we’d like to share some more details on how the cluster renderer can be enhanced through the use of data defined symbol overrides. Data defined overrides are where a huge part of QGIS’ symbology power resides. If you’re not familiar with them, we’d suggest grabbing a copy of Anita Graser and Gretchen Peterson’s reference “QGIS Map Design” (seriously – buy this book. You won’t regret it!). Basically, data defined properties allow you to set rules in place which control exactly how each individual feature in a layer is rendered. So, for instance, you can create an override which makes just a single feature render in a different color, or with a larger label, or so that all features with a value over 100 render with a bold label.

We’ve designed the point cluster renderer to take full advantage of QGIS data defined symbology. What this means is that the cluster symbol (ie, the marker which is rendered when 2 or more points are sufficiently close together) will respect any data defined overrides you set for this symbol, and each individual cluster symbol can have a different appearance as a result.

To make this even more flexible, the clusterer will also provide two additional new variables which can be used in data defined overrides for the symbol. The first of these, @cluster_size, will be preset to equal the number of features which have been clustered together at that point. Eg, if the cluster consists of 4 individual neighbouring features, then @cluster_size will be 4 when the cluster symbol is rendered. This can be used to alter the appearance of the cluster symbol based on the number of associated points. The mockup below shows how this could be used to scale the cluster symbol size so that clusters with more points are rendered larger than clusters with less points:

symbol_sizeIn this mockup we’ve also used a font marker symbol layer to render the actual cluster size inside the symbol too. Of course, because almost every property of symbols in QGIS can be data defined there’s almost no limit how @cluster_size could be used – you could use it to change the symbol color by pairing it with QGIS’ ramp_color function, or alter the symbol opacity, or the outline width… basically anything!

The second new expression variable which would be introduced with the cluster renderer is @cluster_color. This variable allows you to access the color of the points contained within each cluster. Since the cluster renderer is built “on top” of an existing renderer, any point which is NOT contained within a cluster is rendered using the specified renderer. For example, if you use a categorized symbol renderer then all points which aren’t in clusters will be drawn using these categorized classes. In this case isolated points will be drawn using different colors to match the predefined classes.

When multiple points are clustered together, @cluster_color will be set to match the color of any contained points. The points must all have the same color, if they differ then @cluster_color will be null. It’s easiest to illustrate this concept! In the below mockup, we’ve used a categorized render to shade points by an attribute (in this case rail line segment name), and used an uninspiring dark grey circle for the cluster markers:

clusters_categorized

Using @cluster_color together with a data defined color override, we can force these cluster markers to retain the colors from the points within each cluster:

clusters_categorized2

Much nicer! You’ll note that a single dark grey point remains, which is where the cluster consists of stations from multiple different line segments. In this case @cluster_color is null, so the data defined override is not applied and the marker falls back to the dark grey color.

Of course, both @cluster_size and @cluster_color can be combined to create some very nice results:

BOTH

So there we have it – using data defined overrides with the cluster marker renderer allows for extremely flexible, powerful cartography!

Now’s the time to get involved… if you’re wanting to see this feature in QGIS, head over to the crowd funding page to find out how YOU can contribute!

 

How to effectively get things changed in QGIS – a follow up

Last week I posted regarding some thoughts I’ve had recently concerning what I perceive as a general confusion about how QGIS is developed and how users can successfully get things to change in the project. The post certainly started a lot of conversation! However, based on feedback received I realise some parts of the posts were being misinterpreted and some clarification is needed. So here we go…

1. Please keep filing bug reports/feature requests

I don’t think I was very clear about this – but my original post wasn’t meant to be a discouragement from filing bug reports or feature requests. The truth is that there is a LOT of value in these reports, and if you don’t file a report then the QGIS team will never be aware of the bug or your feature idea. Here’s some reasons why you SHOULD file a report:

  • QGIS developers are a conscientious mob, and generally take responsibility for any regressions they’ve caused by changes they’ve made. In other words, there’s very much an attitude of “I-broke-it, I’ll-fix-it” in the project. So, if a new feature is buggy or has broken something else then filing bugs ASAP is the best way to make the developer aware of these issues. In my experience they’ll usually be addressed rapidly.
  • As mentioned in the original post – there’s always a pre-release bug fix sprint, so filing a bug (especially if it’s a critical one) may mean that it’s addressed during this sprint.
  • Filing feature requests can gain traction if your idea is innovative, novel, or interesting enough to grab a developer’s attention!

Speaking for myself, I regularly check new incoming tickets (at least once a day), and I know I’m not the only one. So filing a report WILL bring your issue to developer’s attention. Which leads to…

2. Frustration is understandable!

I can honestly understand why people get frustrated and resort to an aggressive “why hasn’t this been fixed yet?!” style reply. I believe that these complaints are caused because people have the misunderstanding that filing a bug report is the ONLY thing they can do to get an issue fixed. If filing a report IS the only avenue you have to get something fixed/implemented, then it’s totally understandable to be annoyed when your ticket gets no results. This is a failing on behalf of the project though – we need to be clearly communicating that filing a report is the LEAST you can do. It’s a good first step, but on its own it’s just the beginning and needs to be followed up by one of the methods I described in the initial post.

3. It applies to more than just code

When I wrote the original piece I focused on just the code aspect of the QGIS project. That’s only because I’m a developer and it’s the area I know best. But it applies equally across the whole project, including documentation, translations, infrastructure, websites, packaging QGIS releases, etc. In fact, some of these non-code areas are the best entry points into the project as they don’t require a development background, and eg the documentation and translation teams have done a great job making it easy to submit contributions. Find something missing in the QGIS documentation? Add it yourself! Missing a translation of the website which prevents QGIS adoption within your community? Why not sponsor a translator to tackle this task?!

4. It applies to more than just QGIS!

Again, I wrote the original piece focusing on QGIS because that’s the project I’m most familiar with. You could just as easily substitute GDAL, GEOS, OpenLayers, PostGIS, Geoserver, R, D3, etc… in and it would be equally valid!

Hopefully that helps clarify some of the points raised by the earlier article. Let’s keep the discussion flowing – I’d love to hear if you have any other suggestions or questions raised by this topic.

 

 

 

 

The road to QGIS 3.0 – part 1

qgis_icon.svgAs we discussed in QGIS 3 is under way, the QGIS project is working toward the next major version of the application and these developments have major impact on any custom scripts or plugins you’ve developed for QGIS.

We’re now just over a week into this work, and already there’s been tons of API breaking changes landing the code base. In this post we’ll explore some of these changes, what’s motivated them, and what they mean for your scripts.

The best source for keeping track of these breaking changes is to watch the API break documentation on GitHub. This file is updated whenever a change lands which potentially breaks plugins/scripts, and will eventually become a low-level guide to porting plugins to QGIS 3.0.

API clean-ups

So far, lots of the changes which have landed have related to cleaning up the existing API. These include:

Removal of deprecated API calls

The API has been frozen since QGIS 2.0 was released in 2013, and in the years since then many things have changed. As a result, different parts of the API were deprecated along the way as newer, better ways of doing things were introduced. The deprecated code was left intact so that QGIS 2.x plugins would still all function correctly. By removing these older, deprecated code paths it enables the QGIS developers to streamline the code, remove hacky workarounds, untested methods, and just generally “clean things up”. As an example, the older labelling system which pre-dates QGIS 2.0 (it had no collision detection, no curved labels, no fancy data defined properties or rule based labelling!) was still floating around just in case someone tried to open a QGIS 1.8 project. That’s all gone now, culling over 5000 lines of outdated, unmaintained code. Chances are this won’t affect your plugins in the slightest. Other removals, like the removal of QgsMapRenderer (the renderer used before multi-threaded rendering was introduced) likely have a much larger impact, as many scripts and plugins were still using QgsMapRenderer classes and calls. These all need to be migrated to the new QgsMapRendererJob and QgsMapSettings classes.

Renaming things for consistency

Consistent naming helps keep the API predictable and more user friendly. Lots of changes have landed so far to make the naming of classes and methods more consistent. These include things like:

  • Making sure names use consistent capitalization. Eg, there was previously methods named “writeXML” and “writeXml”. These have all been renamed to consistently use camel case, including for acronyms. (In case you’re wondering – this convention is used to follow the Qt library conventions).
  • Consistent use of terms. The API previously used a mix of “CRS” and “SRS” for similar purposes – it now consistently uses “CRS” for a coordinate reference system.
  • Removal of abbreviations. Lots of abbreviated words have been removed from the names, eg “destCrs” has become “destinationCrs”. The API wasn’t consistently using the same abbreviations (ie “dest”/”dst”/”destination”), so it was decided to remove all use of abbreviated words and replace them with the full word. This helps keep things predictable, and is also a bit friendlier for non-native English speakers.

The naming changes all need to be addressed to make existing scripts and plugins compatible with QGIS 3.0. It’s potentially quite a lot of work for plugin developers, but in the long term it will make the API easier to use.

Changes to return and argument types

There’s also been lots of changes relating to the types of objects returned by functions, or the types of objects used as function arguments. Most of these involve changing the c++ types from pointers to references, or from references to copies. These changes are being made to strengthen the API and avoid potential crashes. In most cases they don’t have any affect on PyQGIS code, with some exceptions:

  • Don’t pass Python “None” objects as QgsCoordinateReferenceSystems or as QgsCoordinateTransforms. In QGIS 3.0 you must pass invalid QgsCoordinateReferenceSystem objects (“QgsCoordinateReferenceSystem()”) or invalid QgsCoordinateTransform (“QgsCoordinateTransform()”) objects instead.

Transparent caching of CRS creation

The existing QgsCRSCache class has been removed. This class was used to cache the expensive results of initializing a QgsCoordinateReferenceSystem object, so that creating the same CRS could be done instantly and avoid slow databases lookups. In QGIS 3.0 this caching is now handled transparently, so there is no longer a need for the separate QgsCRSCache and it has been removed. If you were using QgsCRSCache in your PyQGIS code, it will need to be removed and replaced with the standard QgsCoordinateReferenceSystem constructors.

This change has the benefit that many existing plugins which were not explicitly using QgsCRSCache will now gain the benefits of the faster caching mechanism – potentially this could dramatically speed up existing plugin algorithms.

In summary

The QGIS developers have been busy fixing, improving and cleaning up the PyQGIS API. We recognise that these changes result in significant work for plugin and script developers, so we’re committed to providing quality documentation for how to adapt your code for these changes, and we will also investigate the use of automated tools to help ease your code transition to QGIS 3.0. We aren’t making changes lightly, but instead are carefully refining the API to make it more predictable, streamlined and stable.

If you’d like assistance with (or to outsource) the transition of your existing QGIS scripts and plugins to QGIS 3.0, just contact us at North Road to discuss. Every day we’re directly involved in the changes moving to QGIS 3.0, so we’re ideally placed to make this transition painless for you!

Exploring variables in QGIS pt 3: layer level variables

In part 3 of my exploration of variables in QGIS 2.12, I’m going to dig into how variables are scoped in QGIS and what layer level variables are available (you can read parts 1 and 2 for a general introduction to variables).

Some background

Before we get to the good stuff, a bit of background in how variables work behind-the-scenes is important. Whenever an expression is evaluated in QGIS the context of the expression is considered. The context is built up from a set of scopes, which are all stacked on top of each other in order from least-specific to most-specific. It’s easier to explain with an example. Let’s take an expression used to set the source of a picture in a map composer. When this expression is evaluated, the context will consist of:

  1. The global scope, consisting of variables set in the QGIS options dialog, and other installation-wide properties
  2. The project scope, which includes variables set in the Project Properties dialog and the auto-generated project variables like @project_path, @project_title (you can read more about this in part 2)
  3. composer scope, with any variables set for the current composer, plus variables for @layout_pagewidth, @layout_pageheight, @layout_numpages, etc.
  4. composer item scope for the picture, with item-specific variables including @item_id

The more specific scopes will override any existing clashing variables from less specific scopes. So a global @my_var variable will be overridden by an @my_var variable set for the composer:

overridden

Another example. Let’s consider now an expression set for a data-defined label size. When this expression is evaluated the context will depend on where the map is being rendered. If it’s in the main map canvas then the context will be:

  1. The global scope
  2. The project scope
  3. map settings scope, with variables relating to how the map is being rendered. Eg @map_rotation, @map_scale, etc
  4. layer scope. More on this later, but the layer scope includes layer-level variables plus preset variables for @layer_name and @layer_id

If instead the map is being rendered inside a map item in a map composer, the context will be:

  1. The global scope
  2. The project scope
  3. The composer scope
  4. An atlas scope, if atlas is enabled. This contains variables like @atlas_pagename, @atlas_feature, @atlas_totalfeatures.
  5. composer item scope for the map item
  6. map settings scope (with scale and rotation determined by the map item’s settings)
  7. The layer scope

Using layer level variables

Ok, enough with the details. The reason I’ve explained all this is to help explain when layer level variables come into play. Basically, they’ll be available whenever an expression is evaluated inside of a particular layer. This includes data defined symbology and labeling, field calculator, and diagrams. You can’t use a layer-level variable inside a composer label, because there’s no layer scope used when evaluating this. Make sense? Great! To set a layer level variable, you use the Variables section in the Layer Properties dialog:

Setting a layer variablee
Setting a layer variable

Any layer level variables you set will be saved inside your current project, i.e. layer variables are per-layer and per-project. You can also see in the above screenshot that as well as the layer level variables QGIS also lists the existing variables from the Project and Global scopes. This helps show exactly what variables are accessible by the layer and whether they’ve been overridden by any scopes. You can also see that there’s two automatic variables, @layer_id and @layer_name, which contain the unique layer ID and user-set layer name too.

Potential use cases for layer-level variables

In the screenshot above I’ve set two variables, @class1_threshold and @class2_threshold. I’m going to use these to sync up some manual class breaks between rule based symbology and rule based labeling. Here’s how I’ve set up the rule-based symbols for the layer:

Rule based symbology using layer level variables
Rule based symbology using layer level variables

In a similar way, I’ve also created matching rule-based labeling (another new feature in QGIS 2.12):

Matching rule-based labels
Matching rule-based labels

Here’s what my map looks like now, with label and symbol colors matched:

*Map for illustrative purposes only... not for cartographic/visual design excellence!
*Map for illustrative purposes only… not for cartographic/visual design excellence!

If I’d hard-coded the manual class breaks, it would be a pain to keep the labeling and symbology in sync. I’d have to make sure that the breaks are updated everywhere I’ve used them in both the symbology and labeling settings. Aside from being boring, tedious work, this would also prevent immediate before/after comparisons. Using variables instead means that I can update the break value in a single place (the variables panel) and have all my labeling and symbols immediately reflect this change when I hit apply!

Another recent use case I had was teaming layer-level variables along with Time Manager. I wanted my points to falloff in both transparency and size with age, and this involved data defined symbol settings scattered all throughout my layer symbology. By storing the decay fall-off rate in a variable, I could again tweak this falloff by changing the value in a single place and immediately see the result. It also helps with readability of the data defined expressions. Instead of trying to decipher a random, hard-coded value, it’s instead immediately obvious that this value relates to a decay fall-off rate. Much nicer!

I’m sure there’s going to be hundreds of novel uses of layer-level variables which I never planned for when adding this feature. I’d love to hear about them though – leave a comment if you’d like to share your ideas!

One last thing – the new “layer_property” function

This isn’t strictly related to variables, but another new feature which was introduced in QGIS 2.12 was a new “layer_property” expression function. This function allows you to retrieve any one of a bunch of properties relating to a specific map layer, including the layer CRS, metadata, source path, etc.

This function can be used anywhere in QGIS. For instance, it allows you to insert dynamic metadata about layers into a print composer layout. In the screenshot below I’ve used expressions like layer_property(‘patron’,’crs’) and layer_property(‘patron’,’source’) to insert the CRS and source path of the “patron” layer into the label. If either the CRS or the file path ever changes, this label will be automatically updated to reflect the new values.

Inserting dynamic layer properties into a composer label
Inserting dynamic layer properties into a composer label

 

So there you go – layer level variables and the layer_property function – here in QGIS 2.12 and making your workflow in QGIS easier. In the final part of this series, we’ll explore the magical @value variable. Trust me, I’ve saved the best for last!

Want to sponsor some QGIS features? Here’s some ideas…

I’ve been working on QGIS for a number of years now and, contrary to what I thought when I started, my wishlist seems to grow longer with every feature I add to QGIS! Unfortunately, almost all of my QGIS development work is done on a volunteer basis and it’s sometimes hard to justify the time required to tackle items on this list. So here’s your chance to help me fix this!

Here’s a quick list of things which I’d love to add to QGIS (or improve), but would need someone to step up and help sponsor their development:

  • Raster marker symbol type: Currently QGIS supports a number of marker symbol types (simple markers, font markers, SVG markers) but there’s no option to just use a raster image file for a symbol. A few versions back I added support for a raster image fill type, and now I’d love to do the same for markers. Options could include overriding the image size, rotation and opacity. And of course, all of these properties would be data-definable.
  • Paint effects for diagrams: The successful Kickstarter campaign meant that QGIS 2.10 includes a powerful framework for applying live effects to layers, including drop shadows, outer glows, blurs, and colour effects (plus lots of others!). I’d like to take this framework and allow effects to be applied to diagrams on a layer. Drop shadows and outer glows would really help aid the readability of diagrams by allowing them to sit on a different visual layer to the rest of the map. The effects framework was designed to allow reuse across all of QGIS, and diagrams would be the next logical step in this.

    Layer effects for diagrams! (Well... a mockup of them...)
    Layer effects for diagrams! (Well… a mockup of them…)
  • Additional diagram types/options: While we’re on the topic of diagrams, there’s lots more that we could do with QGIS’ diagram support. We’ve currently got support for pie charts, text diagrams and histograms, but there’s a lot of really nice diagram styles which we don’t yet support. Everybody loves infographics with nicely designed diagrams… so I’d love the chance to extend what’s possible using QGIS diagram engine. Some ideas include icon arrays, circle packing.
  • Adding a geometry widget in the attribute table: This feature has been on my mind a lot lately. What I’d like to add is a new “geometry widget” as the last column in a layer’s attribute table. This widget would allow you to do all sorts of modifications to the geometry attached to a feature. Possible options include clearing the geometry (resetting it to null), copying the geometry as WKT or GeoJSON, or pasting geometry into the feature from a WKT string (making it super easy to copy the geometry between features). This could also be extended in future to start incorporating the editing capabilities current possible through the Plain Geometry Editor plugin.

    Poor quality mockup of a geometry widget...
    Poor quality mockup of a geometry widget…
  • Options for non square/straight line legend patches: QGIS’ legend currently has no options for customising the shape of legend patches. Polygon layers in the legend are rectangles, line layers are straight lines — that’s it. There’s lots of room for improvement here. I’d like to add options for shapes such as circles, rounded rectangles, jagged lines, and possibly even custom shapes (via a WKT string or something similar).

    Custom legend shapes anyone?
    Custom legend shapes anyone?
  • Improving the heatmap plugin: The current heatmap plugin needs some love. The code and UI could do with a big refresh. I’d love a chance to totally revamp this plugin and move it into QGIS core code, and allow it to be used from within processing models. I’d also like to add additional hotspot techniques, such as Getis Ord Gi* hotspotting, to the plugin.
  • Extending the raster calculator: QGIS’ raster calculator was given a bunch of needed fixes and improvements in 2.10, but there’s more we could do. The major limitation with the calculator is that it currently only supports functions with at most two parameters. This needs to be fixed so that we can add a bunch of much desired functions to the calculator – eg min, max, avg, coalesce, if, etc… Lack of support for multi-parameter functions is really holding back what’s possible in the calculator.

Of course, this list is just a start. I’m always keen to chat about any other features you’d like to see added to QGIS (or even tackle specific pet-hate bugs or frustrations!). Just drop me an email at nyall.dawson@gmail.com to discuss.

Oh, one last thing – I’m in the process of preparing for my next crowd funded feature for QGIS – and this one is big! More on that shortly.

 

Customising the TimeManager time stamp

TimeManager is a fantastic plugin for QGIS which allows you to create animated maps from your data. You can read all about it here and here, and there’s a really nice demonstration of it here.

I’ve been playing with TimeManager a fair bit over the last month, and thought I’d share a quick tip on improving the appearance of TimeManager’s time stamp. TimeManager includes some basic functionality for placing a time stamp in the corner of your outputs, but it’s fairly limited. There’s only some basic appearance options, and no way to control the date or time formats displayed.

Default TimeManager time stamp
Default TimeManager time stamp

But, there’s a trick we can use to get around this: use a temporary point layer for the time stamp label. Let me elaborate:

  1. Create a throwaway point layer. It doesn’t matter what fields or format this layer has.
  2. Add a single point feature to this layer at the place you’d like the improved time stamp to appear at.

    Add a single point feature
    …add a single point feature
  3. We don’t want to see the marker, so hide the symbol for this layer by setting it to use a transparent fill and outline.

    Transparent fill and outline
    Transparent fill and outline
  4. Then, enable labels for this layer. Here’s the trick – set the label expression for the label to use “animation_datetime()” (or for QGIS 2.8, “$animation_datetime”). This is a custom function provided by the TimeManager plugin which evaluates to the current frame’s date and time.

    Setting the layer's label expression
    Setting the layer’s label expression
  5. Now, you can use all the built-in options within QGIS for styling this label. Buffers, drop shadows, background shapes… anything!

    ...tweaking the label appearance
    …tweaking the label appearance
  6. Apply and check. Much nicer!

    Formatted timestamp
    A nicely formatted time stamp
  7. To tweak the formatting of the time stamp’s date and time, you can modify the label expression using the built-in ‘format_date’, ‘year’, ‘month’, etc functions. Let’s try “format_date(animation_datetime(),’ddd dd MMM yyyy’)”:

    Tweaked expression
    Tweaked expression

Now, our final formatted time stamp looks like this:

Final, formatted time stamp
Final, formatted time stamp

…and there we go. Using this simple trick allows you to take advantage of all the possibilities which the QGIS labelling and expression engines allow!

*Bonus points for the first person to use this technique along with data defined controls for animating the label colour/size!

  • Page 1 of 6 ( 105 posts )
  • >>
  • osgeo

Back to Top

Sponsors