Related Plugins and Tags

QGIS Planet

Using valgrind, kcachegrind to evaluate QGIS performance

Valgrind is a nifty too to do code instrumentation - tell you how much time gets spent in different parts of your code tree. KCachegrind is a visualisation tool for valgrind outputs. They are two separate tools that together can provide useful insight into where you code is slow or doing too much work. To [...]

Using valgrind, kcachegrind to evaluate QGIS performance

Valgrind is a nifty too to do code instrumentation - tell you how much time gets spent in different parts of your code tree. KCachegrind is a visualisation tool for valgrind outputs. They are two separate tools that together can provide useful insight into where you code is slow or doing too much work. To set them up on ubuntu is simple:

sudo apt-get install kcachegrind valgrind

After installation, you can lauch QGIS under valgrind like this:

cd /tmp
valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes \
 --collect-jumps=yes /usr/local/bin/qgis

Note that everything you do in QGIS will take 10x longer because of the overhead valgrind places on it. Now load up a project or do something that you feel is taking longer that it should in QGIS. Then exit QGIS. You will be left with a nice big unintelligible xml file in your /tmp directory. Not to worry though, kcachegrind can open it an make sense of it for you. The file will be called something like:

callgrind.out.18364

So to open it with kcachegrind you can simply do:

kcachegrind callgrind.out.18364

KCacheGrind will take a few moments to digest it and then show you something like the screenshot below:

Application call graph for QGIS in KCacheGrind (click for larger image)

The callgraph can be displayed in a number of different ways and provides extremely useful information if you are trying to identify bottlenecks. In the image above, you can see that when QGIS starts, almost 50% of startup time is spent loading python plugins. There are also views that show how many times a given function is called which can provide some helpful hints as to what to optimise.

Valgrind can also be used to detect memory leaks, but unfortunately for GUI lovers, there isn't a nice GUI environment to explore the leak report data. Don't let that put you off though - you can get extremely useful feedback from the tool. Here is the syntax to do a leak check on QGIS:

valgrind  --tool=memcheck -v --error-limit=no --leak-check=full /usr/local/bin/qgis

When it finishes running QGIS you will get an extremely verbose report (printed to stdout) that lists all the potential issues. Here is a short snippet of what you might see:

==3144== 627 errors in context 151 of 997:
==3144== Invalid read of size 1
==3144==    at 0x4C2A06A: __GI_strcmp (mc_replace_strmem.c:540)
==3144==    by 0xA3080BA: _nl_load_locale_from_archive (loadarchive.c:161)
==3144==    by 0xA30750D: _nl_find_locale (findlocale.c:107)
==3144==    by 0xA306B38: setlocale (setlocale.c:379)
==3144==    by 0x680F13F: QgsCoordinateReferenceSystem::setProj4String(QString) (qgscoordinatereferencesystem.cpp:753)
==3144==    by 0x680C262: QgsCoordinateReferenceSystem::loadFromDb(QString, QString, QString) (qgscoordinatereferencesystem.cpp:271)
==3144==    by 0x680B9B3: QgsCoordinateReferenceSystem::createFromSrsId(long) (qgscoordinatereferencesystem.cpp:213)
==3144==    by 0x6776E2B: QgsDistanceArea::setSourceCrs(long) (qgsdistancearea.cpp:64)
==3144==    by 0x6776CF9: QgsDistanceArea::QgsDistanceArea() (qgsdistancearea.cpp:45)
==3144==    by 0x67C06DE: QgsMapRenderer::QgsMapRenderer() (qgsmaprenderer.cpp:46)
==3144==    by 0x71B8D7B: QgsMapCanvas::QgsMapCanvas(QWidget*, char const*) (qgsmapcanvas.cpp:115)
==3144==    by 0x5314EC: QgisApp::QgisApp(QSplashScreen*, bool, QWidget*, QFlags<Qt::WindowType>) (qgisapp.cpp:419)
==3144==  Address 0x144ed1f1 is 1 bytes inside a block of size 12 free'd
==3144==    at 0x4C282ED: free (vg_replace_malloc.c:366)
==3144==    by 0xA306BC8: setlocale (setlocale.c:173)
==3144==    by 0x680F0B0: QgsCoordinateReferenceSystem::setProj4String(QString) (qgscoordinatereferencesystem.cpp:743)
==3144==    by 0x680C262: QgsCoordinateReferenceSystem::loadFromDb(QString, QString, QString) (qgscoordinatereferencesystem.cpp:271)
==3144==    by 0x680B9B3: QgsCoordinateReferenceSystem::createFromSrsId(long) (qgscoordinatereferencesystem.cpp:213)
==3144==    by 0x6776E2B: QgsDistanceArea::setSourceCrs(long) (qgsdistancearea.cpp:64)
==3144==    by 0x6776CF9: QgsDistanceArea::QgsDistanceArea() (qgsdistancearea.cpp:45)
==3144==    by 0x67C06DE: QgsMapRenderer::QgsMapRenderer() (qgsmaprenderer.cpp:46)
==3144==    by 0x71B8D7B: QgsMapCanvas::QgsMapCanvas(QWidget*, char const*) (qgsmapcanvas.cpp:115)
==3144==    by 0x5314EC: QgisApp::QgisApp(QSplashScreen*, bool, QWidget*, QFlags<Qt::WindowType>) (qgisapp.cpp:419)
==3144==    by 0x52DFBE: main (main.cpp:607)

Just from starting QGIS and then immediately shutting it down, you will see a rather large list of errors - some of which originate from QGIS itself, and others which originate from some of the underlying libraries we use. The leak detection tool is a hand way to debug when you are getting application crashes and when it seems to be using more memory than you think reasonable. One of these days lets hope that it returns a big fat nothing when we run QGIS on it :-)

Making the most of UMN mapserver runtime variable substitution

We are working on a project where we have a django app that dynamically calls mapserver to generate an image of a region with a set of selected properties. We wanted to be able to pass cgi substitution parameters for a list of entities to highlight. Here is how we did it.

UMN Mapserver supports the concept of variable substitution which is documented nicely here. Since version 6 of mapserver, you must define a validation pattern when setting up substitition. A default value is optional but we will be using that too. So lets contrive a simple scenario. You have a layer of municipal boundaries and you want to be able to highlight zero or more of those boundaries on the map. To do that, we will add two nearly identical municipal layer definitions to our map file:

 

  LAYER
    NAME 'Municipality_Outlines'
    TYPE POLYGON
    DUMP true
    TEMPLATE none
    CONNECTIONTYPE postgis
    CONNECTION "dbname='test' host=localhost port=5433 user='{282B61123232131231}' password='{282B6123423423423}' sslmode=disable"
    DATA 'the_geom FROM "municipality" USING UNIQUE id USING srid=4326'
    METADATA
      'ows_title' 'municipality_outlines'
      'ows_srs'   'EPSG:4326'
    END
    STATUS OFF
    TRANSPARENCY 100
    PROJECTION
      'init=epsg:4326'
    END
    LABELITEM 'name'
    CLASS
      NAME 'Municipalities'
      STYLE
        WIDTH 3.0
        OUTLINECOLOR 5 200 200
        COLOR -1 -1 -1
      END
    END
  END
  LAYER
    NAME 'Selected_Municipalities'
    TYPE POLYGON
    DUMP true
    TEMPLATE foo
    CONNECTIONTYPE postgis
    CONNECTION "dbname='test' host=localhost port=5433 user='{282B61D4012321321}' password='{312312312443223423}' sslmode=disable"
    DATA 'the_geom FROM "municipality" USING UNIQUE id USING srid=4326'
    FILTER "id in( %municipalitylist% )"
    METADATA
      'ows_title' 'selected_municipalities'
      'ows_srs'   'EPSG:4326'
      'municipalitylist_validation_pattern' '^[0-9,]+$'
      'default_municipalitylist' '0'
    END
    STATUS OFF
    TRANSPARENCY 100
    PROJECTION
      'init=epsg:4326'
    END
    CLASS
      NAME 'Selected Municipalities'
      STYLE
        WIDTH 2.5
        OUTLINECOLOR 255 255 000
        COLOR -1 -1 -1
      END
    END
  END

 

So the interesting parts are the FILTER and METADATA sections in the Selected_Municipalities layer.

  • The filter part basically applies a where clause to our layer sql definition. What is smart about this filter is that it uses an SQL 'in' clause to allow multiple values (record id's in this case) to be used as the filter.
  • The municipalitylist_validation_pattern is the next interesting bit. I have set it to a regular expression that will allow any number of numbers and commas. The validation pattern is there to prvent sql injection attacks into our database.
  • The default_municipalitylist is set to 0 and will basically allow the user not to specify anything in the url for the municipality list and the query to still be valid without actually selecting anything.
Ok so thats all the grunt work out the way, lets take a look at how to use it (I'm going to wrap the urls below for ease of reading). Lets first make a standard map with no selected items:
http://llocalhost/cgi-bin/mapserv?map=TEST&SERVICE=WMS&VERSION=1.3.0&
REQUEST=GetMap&BBOX=-27,26,-25,30&CRS=EPSG:4326&
WIDTH=1498&HEIGHT=749&LAYERS=Municipality_Outlines,Selected_Municipalities&
STYLES=&FORMAT=image/PNG
Which produces this:
Our map with no selection

Our map with no selection

There are no selected items visible as our filter on our selection layer returns no records when using the default 0 (zero) id which we set up in our map file. Now we can select one item by adding "&municipalitylist=5" to the end of our url:
http://llocalhost/cgi-bin/mapserv?map=TEST&SERVICE=WMS&VERSION=1.3.0&
REQUEST=GetMap&BBOX=-27,26,-25,30&CRS=EPSG:4326&
WIDTH=1498&HEIGHT=749&LAYERS=Municipality_Outlines,Selected_Municipalities&
STYLES=&FORMAT=image/PNG&municipalitylist=5
Which produces this:
One item selected using our filter

One item selected using our filter

Finally the nice part about this is that we can select a list of municipalities by adding "&municipalitylist=5,7" to the end of our url (you can add as many comma separated ids as needed):
http://llocalhost/cgi-bin/mapserv?map=TEST&SERVICE=WMS&VERSION=1.3.0&
REQUEST=GetMap&BBOX=-27,26,-25,30&CRS=EPSG:4326&
WIDTH=1498&HEIGHT=749&LAYERS=Municipality_Outlines,Selected_Municipalities&
STYLES=&FORMAT=image/PNG&municipalitylist=5,7
Which produces this:
Multiple items selected in our map
Multiple items selected in our map
UMN Mapserver is a great help for building mapping enabled web applications and the variable substitution capabilities of Mapserver give you a really flexible way to decide what to display on a map at runtime.
pixelstats trackingpixel

Making the most of UMN mapserver runtime variable substitution

We are working on a project where we have a django app that dynamically calls mapserver to generate an image of a region with a set of selected properties. We wanted to be able to pass cgi substitution parameters for a list of entities to highlight. Here is how we did it.

UMN Mapserver supports the concept of variable substitution which is documented nicely here. Since version 6 of mapserver, you must define a validation pattern when setting up substitition. A default value is optional but we will be using that too. So lets contrive a simple scenario. You have a layer of municipal boundaries and you want to be able to highlight zero or more of those boundaries on the map. To do that, we will add two nearly identical municipal layer definitions to our map file:

LAYER
  NAME 'Municipality_Outlines'
  TYPE POLYGON
  DUMP true
  TEMPLATE none
  CONNECTIONTYPE postgis
  CONNECTION "dbname='test' host=localhost port=5433 user='{282B61123232131231}' password='{282B6123423423423}' sslmode=disable"
  DATA 'the_geom FROM "municipality" USING UNIQUE id USING srid=4326'
  METADATA
    'ows_title' 'municipality_outlines'
    'ows_srs'   'EPSG:4326'
  END
  STATUS OFF
  TRANSPARENCY 100
  PROJECTION
    'init=epsg:4326'
  END
  LABELITEM 'name'
  CLASS
    NAME 'Municipalities'
    STYLE
      WIDTH 3.0
      OUTLINECOLOR 5 200 200
      COLOR -1 -1 -1
    END
  END
END
LAYER
  NAME 'Selected_Municipalities'
  TYPE POLYGON
  DUMP true
  TEMPLATE foo
  CONNECTIONTYPE postgis
  CONNECTION "dbname='test' host=localhost port=5433 user='{282B61D4012321321}' password='{312312312443223423}' sslmode=disable"
  DATA 'the_geom FROM "municipality" USING UNIQUE id USING srid=4326'
  FILTER "id in( %municipalitylist% )"
  METADATA
    'ows_title' 'selected_municipalities'
    'ows_srs'   'EPSG:4326'
    'municipalitylist_validation_pattern' '^[0-9,]+$'
    'default_municipalitylist' '0'
  END
  STATUS OFF
  TRANSPARENCY 100
  PROJECTION
    'init=epsg:4326'
  END
  CLASS
    NAME 'Selected Municipalities'
    STYLE
      WIDTH 2.5
      OUTLINECOLOR 255 255 000
      COLOR -1 -1 -1
    END
  END
END

So the interesting parts are the FILTER and METADATA sections in the Selected_Municipalities layer.

  • The filter part basically applies a where clause to our layer sql definition. What is smart about this filter is that it uses an SQL 'in' clause to allow multiple values (record id's in this case) to be used as the filter.
  • The municipalitylist_validation_pattern is the next interesting bit. I have set it to a regular expression that will allow any number of numbers and commas. The validation pattern is there to prvent sql injection attacks into our database.
  • The default_municipalitylist is set to 0 and will basically allow the user not to specify anything in the url for the municipality list and the query to still be valid without actually selecting anything.

Ok so thats all the grunt work out the way, lets take a look at how to use it (I'm going to wrap the urls below for ease of reading). Lets first make a standard map with no selected items:

http://llocalhost/cgi-bin/mapserv?map=TEST&SERVICE=WMS&VERSION=1.3.0&
REQUEST=GetMap&BBOX=-27,26,-25,30&CRS=EPSG:4326&
WIDTH=1498&HEIGHT=749&LAYERS=Municipality_Outlines,Selected_Municipalities&
STYLES=&FORMAT=image/PNG

Which produces this:

|Our map with no selection|

There are no selected items visible as our filter on our selection layer returns no records when using the default 0 (zero) id which we set up in our map file. Now we can select one item by adding "&municipalitylist=5" to the end of our url:

http://llocalhost/cgi-bin/mapserv?map=TEST&SERVICE=WMS&VERSION=1.3.0&
REQUEST=GetMap&BBOX=-27,26,-25,30&CRS=EPSG:4326&
WIDTH=1498&HEIGHT=749&LAYERS=Municipality_Outlines,Selected_Municipalities&
STYLES=&FORMAT=image/PNG&municipalitylist=5

Which produces this:

|One item selected using our filter|

Finally the nice part about this is that we can select a list of municipalities by adding "&municipalitylist=5,7" to the end of our url (you can add as many comma separated ids as needed):

http://llocalhost/cgi-bin/mapserv?map=TEST&SERVICE=WMS&VERSION=1.3.0&
REQUEST=GetMap&BBOX=-27,26,-25,30&CRS=EPSG:4326&
WIDTH=1498&HEIGHT=749&LAYERS=Municipality_Outlines,Selected_Municipalities&
STYLES=&FORMAT=image/PNG&municipalitylist=5,7

Which produces this:

Multiple items selected in our map
Multiple items selected in our map

UMN Mapserver is a great help for building mapping enabled web applications and the variable substitution capabilities of Mapserver give you a really flexible way to decide what to display on a map at runtime.

Selecting GDAL Drivers on the fly with QGIS

There is quite an old ticket in the QGIS bug tracker relating to the need to be able to select which GDAL drivers to use. The issues is this: GDAL in some cases provides multiple drivers for the same image type. For example, JPEG2000 datasets can be opened using ECW's proprietary driver, KAKADU (gotta love that name!), OpenJPEG etc. The problem is that there isn't actually any way to choose which driver GDAL should use for a given image format - it works on a first come, first served bases. This is a bit of a problem sometimes when you actually want to be using a different driver. In some work I did recently for SANSA (the South African Space Agency), I built a custom version of QGIS for them. They are particularly keen on the JPEG2000 format since it is an open standard and provides good compression. However the custom build of QGIS I made for them includes the ECW JP2000 driver which unfortunately chokes and dies (no fault of GDAL, it happens down in the ECW code itself) when trying to open their JP2 imagery. Also we would prefer to use a FOSS driver for JP2 in keeping with the general ethos of being a FOSS project. So all this prompted me to implement the needed support to let you disable GDAL drivers at runtime in QGIS which is illustrated a little by the screenshots below.

 

By default GDAL want to use the ECW JPG2000 driver...(click to enlarge)

By default GDAL want to use the ECW JPG2000 driver...(click to enlarge)

Using the options dialog, you can now disable a driver....(click to enlarge)

Using the options dialog, you can now disable a driver....(click to enlarge)

After the driver is disabled (and restarting QGIS), the alternate JP2 driver is available (click to enlarge)

After the driver is disabled (and restarting QGIS), the alternate JP2 driver is available (click to enlarge)

pixelstats trackingpixel

Selecting GDAL Drivers on the fly with QGIS

There is quite an old ticket in the QGIS bug tracker relating to the need to be able to select which GDAL drivers to use. The issues is this: GDAL in some cases provides multiple drivers for the same image type. For example, JPEG2000 datasets can be opened using ECW's proprietary driver, KAKADU (gotta love that name!), OpenJPEG etc.

The problem is that there isn't actually any way to choose which driver GDAL should use for a given image format - it works on a first come, first served bases. This is a bit of a problem sometimes when you actually want to be using a different driver. In some work I did recently for SANSA (the South African Space Agency), I built a custom version of QGIS for them. They are particularly keen on the JPEG2000 format since it is an open standard and provides good compression.

However the custom build of QGIS I made for them includes the ECW JP2000 driver which unfortunately chokes and dies (no fault of GDAL, it happens down in the ECW code itself) when trying to open their JP2 imagery. Also we would prefer to use a FOSS driver for JP2 in keeping with the general ethos of being a FOSS project. So all this prompted me to implement the needed support to let you disable GDAL drivers at runtime in QGIS which is illustrated a little by the screenshots below.

By default GDAL want to use the ECW JPG2000 driver...(click to enlarge)

Using the options dialog, you can now disable a driver....(click to enlarge)

After the driver is disabled (and restarting QGIS), the alternate JP2 driver is available (click to enlarge)

Building QGIS in windows from the command line

Here is a handy tip if you are building QGIS under windows using our official INSTALL documentation. The document recommends that you open MSVC Express and then right click the BUILD_ALL and INSTALL targets. I find using a graphical user interface for this kind of thing tedious and so I looked around for a way to carry out the build from the command line. Here is how to do it:

cmake --build . --config RelWithDebInfo
cmake --build . --target install --config RelWithDebInfo

You should run those commands from within your build directory. I made a little batch file called INSTALL.bat containing the above two lines which I just call when I want to build in windows now.


pixelstats trackingpixel

Building QGIS in windows from the command line

Here is a handy tip if you are building QGIS under windows using our official INSTALL documentation. The document recommends that you open MSVC Express and then right click the BUILD_ALL and INSTALL targets. I find using a graphical user interface for this kind of thing tedious and so I looked around for a way to carry out the build from the command line. Here is how to do it:

cmake --build . --config RelWithDebInfo
cmake --build . --target install --config RelWithDebInfo

You should run those commands from within your build directory. I made a little batch file called INSTALL.bat containing the above two lines which I just call when I want to build in windows now.

Norwegian Trekking with QGIS Server

I have blogged about the awesomeness that is QGIS Server before. Maybe you have seen some of the nice maps that Andreas Neumann has made in Uster, Switzerland. Over the past 3 months we were contracted to help prototyping a new mapping service for the Norwegian Trekking Association. We really got a chance to put QGIS Server (and the new QGIS Web Client project) through its paces. Why not take a little look for yourself. We had quite a lot of fun optimising the client's data set for good performance and generally making sure everything works smoothly.

Note:

- the site is still a test site, but the fine folks from Norway gave me the OK to let people take it for a whirl.
- we have not yet implemented search support.
- We made a bunch of different print layouts for you to try out!

It's now incredibly easy to get your QGIS cartography online. In the near future I plan to test out techniques for tilecaching with QGIS Server and once that works it will be the end of the line for my 11+ year love affair with UMN Mapserver for the most part I think.

Get your map on! QGIS Server in action (click for full image)

Get your map on! QGIS Server in action (click for full image)

 

 

 

pixelstats trackingpixel

Norwegian Trekking with QGIS Server

I have bloggedabout the awesomeness that is QGIS Server before. Maybe you have seen some of the nice maps that Andreas Neumann has madein Uster, Switzerland. Over the past 3 months we were contracted to help prototyping a new mapping service for the Norwegian Trekking Association. We really got a chance to put QGIS Server (and the new QGIS Web Client project) through its paces. Why not take a little look for yourself. We had quite a lot of fun optimising the client's data set for good performance and generally making sure everything works smoothly.

Note:

- the site is still a test site, but the fine folks from Norway gave me the OK to let people take it for a whirl.
- we have not yet implemented search support.
- We made a bunch of different print layouts for you to try out!

It's now incredibly easy to get your QGIS cartography online. In the near future I plan to test out techniques for tilecaching with QGIS Server and once that works it will be the end of the line for my 11+ year love affair with UMN Mapserver for the most part I think.

Get your map on! QGIS Server in action (click for full image)

Django: serving an image from a remote server

For a current project (using django), I wanted to get a dynamically generated image from a remote map server and return the image to the django view as an object (as opposed to returning a URL as a string).

Here's how it's done (logic derived from this code snippet):

import urllib
import urllib2
import mimetypes

def serveMapImage( theArea ):
  # omitted: procedure to define the variable zoomExtents
  # from user-specified, database-derived variable theArea
  URI = "http://example.com/mapofsouthafrica-" + zoomExtents
  contents = urllib2.urlopen(URI).read()
  mimetype = mimetypes.guess_type(URI)
  response = HttpResponse(contents, mimetype=mimetype)

  return response
pixelstats trackingpixel

Django: serving an image from a remote server

For a current project (using django), I wanted to get a dynamically generated image from a remote map server and return the image to the django view as an object (as opposed to returning a URL as a string).

Here's how it's done (logic derived from this code snippet):

import urllib
import urllib2
import mimetypes

def serveMapImage( theArea ):
  # omitted: procedure to define the variable zoomExtents
  # from user-specified, database-derived variable theArea
  URI = "http://example.com/mapofsouthafrica-" + zoomExtents
  contents = urllib2.urlopen(URI).read()
  mimetype = mimetypes.guess_type(URI)
  response = HttpResponse(contents, mimetype=mimetype)

  return response

Live vehicle tracking with OpenLayers

The last three or four weeks we have been preparing the Tracks4Africa site for the next season of 'Voetspore' (translated from Afrikaans: 'foot steps') - a South African TV program which follows the adventures of a group of 4x4 drivers as they traverse africa. For this season, one of the vehicles has been fitted with two tracking devices - a satellite transponder and a GSM unit. By wiring up a couple of Django views to deliver GeoJSON, and consuming that from OpenLayers we are able to deliver real time data on the vehicle positions during their excursion. The data is degraded to show one vertex per hour, although the complete dataset is much more detailed.

 

The trip just started this weekend from  Cape Agulhas, the Southern Tip of Africa (and coincidentally not far from where I live) to Alexandria in Egypt (which is coincidentally extremely far from where I live). You can track their progress by visiting the dedicated Tracks4Africa Voetspore page created for this purpose.

Voetspore map on Tracks4Africa (click for large view)

Voetspore map on Tracks4Africa (click for large view)

pixelstats trackingpixel

Live vehicle tracking with OpenLayers

The last three or four weeks we have been preparing the Tracks4Africa site for the next season of 'Voetspore' (translated from Afrikaans: 'foot steps') - a South African TV program which follows the adventures of a group of 4x4 drivers as they traverse africa. For this season, one of the vehicles has been fitted with two tracking devices - a satellite transponder and a GSM unit. By wiring up a couple of Django views to deliver GeoJSON, and consuming that from OpenLayers we are able to deliver real time data on the vehicle positions during their excursion. The data is degraded to show one vertex per hour, although the complete dataset is much more detailed.

The trip just started this weekend from  Cape Agulhas, the Southern Tip of Africa (and coincidentally not far from where I live) to Alexandria in Egypt (which is coincidentally extremely far from where I live). You can track their progress by visiting the dedicated Tracks4Africa Voetspore page created for this purpose.

Voetspore map on Tracks4Africa (click for large view)

GeoInformatics article on QGIS

Otto Dassau and I recently wrote and article for GeoInformatics about the work we have done in in Tanzania and the QGIS project in general. The article is now online here.

GeoInformatics article on QGIS

Otto Dassau and I recently wrote and article for GeoInformatics about the work we have done in in Tanzania and the QGIS project in general. The article is now online here.

pixelstats trackingpixel

Extract projection tool for QGIS

QGIS got another useful feature a few days ago, courtesy of Alexander Bruy. Here's the commit.

What this lets you do is to find out what projection your rasters are in. It then exports this to a .WLD file. It also allows you to create .PRJ files.

If you have GDAL Tools installed (and activated), you'll find this new tool under Raster > Projections > Extract Projection. It gives you this efficient-looking dialog to choose your options in:

Extract projection dialog

The "extract projection" dialog.

The batch- and recursive modes are a great feature as well. You could easily find yourself in a situation where you have a whole project full of rasters, with undocumented projections, in countless subfolders, that got handed to you without comment. Whereas previously that would be a hassle, now you can just point this tool to the right directory and set it loose. Voila, instant projection information! And in your format of choice, no less. Ladies and gentlemen... a round of applause!

pixelstats trackingpixel

Extract projection tool for QGIS

QGIS got another useful feature a few days ago, courtesy of Alexander Bruy. Here's the commit.

What this lets you do is to find out what projection your rasters are in. It then exports this to a .WLD file. It also allows you to create .PRJ files.

If you have GDAL Tools installed (and activated), you'll find this new tool under Raster > Projections > Extract Projection. It gives you this efficient-looking dialog to choose your options in:

Extract projection dialog

The batch- and recursive modes are a great feature as well. You could easily find yourself in a situation where you have a whole project full of rasters, with undocumented projections, in countless subfolders, that got handed to you without comment. Whereas previously that would be a hassle, now you can just point this tool to the right directory and set it loose. Voila, instant projection information! And in your format of choice, no less. Ladies and gentlemen... a round of applause!

Shield Labels for QGIS

QGIS Server (the 'map' part of the name has been dropped) is an awesome way to publish maps and you can make really good looking cartographic products with QGIS. I have been building out a good looking online map for a client and I suddenly realised that we don't have any way to do road shields. This weekend I hacked together basic support for label shields. It integrates with the labelling-NG tool in QGIS master. Currently it provides only basic options - distance from label at which to start the shield and the shield colour. Only rectangular (with slightly rounded corners) shields are currently supported. In the future we could do lots of other fancy shield types and allow setting outline colour, use a gradient for the background, different shapes and so on. In it's current rather basic configuration though it suits my immediate needs and probably I will add to it as the need arises.

Shield options

Shield options (click for larger view)

Yes the screenshot is taken in windows - something for a future blog post :-P Here is a little sample of what you can do with shields  (click for larger image):

Some contrived examples of using the label shields

Some contrived examples of using the label shields

 

If you want to try it out, it is in my github clone here:

git remote add timlinux git://github.com/timlinux/Quantum-GIS.git
git fetch timlinux
git branch --track shield-labels timlinux/shield-labels

 

 

 

pixelstats trackingpixel

Shield Labels for QGIS

QGIS Server (the 'map' part of the name has been dropped) is an awesome way to publish maps and you can make really good looking cartographic products with QGIS. I have been building out a good looking online map for a client and I suddenly realised that we don't have any way to do road shields. This weekend I hacked together basic support for label shields. It integrates with the labelling-NG tool in QGIS master. Currently it provides only basic options - distance from label at which to start the shield and the shield colour. Only rectangular (with slightly rounded corners) shields are currently supported. In the future we could do lots of other fancy shield types and allow setting outline colour, use a gradient for the background, different shapes and so on. In it's current rather basic configuration though it suits my immediate needs and probably I will add to it as the need arises.

Shield options

Yes the screenshot is taken in windows - something for a future blog post :-P Here is a little sample of what you can do with shields  (click for larger image):

Some contrived examples of using the label shields

If you want to try it out, it is in my github clone here:

git remote add timlinux git://github.com/timlinux/Quantum-GIS.git
git fetch timlinux
git branch --track shield-labels timlinux/shield-labels

Back to Top

Sustaining Members