QGIS « Linfiniti Geo Blog

By: Linfiniti  11-11-2011

Just a quick note on something I noticed earlier this week. Since we've been using a combination of Django and JavaScript for our websites, we're passing a lot of values around between the two, including booleans. Unexpectedly, something stopped working as soon as I started sending Python booleans to a Django template. The template was supposed to create valid JSON, but the JavaScript on the other end didn't seem to know whether the original (Python) boolean was true or false.

The answer turned out to be quite simple: whereas Python uses an initial upper-case letter for its booleans, JavaScript does not. So don't just pass Python booleans on to a Django template if JavaScript is getting that value next. Instead, evaluate the boolean variable beforehand and pass the strings "true"/"false" on to your template accordingly.

I was using Openlayers to chuck a map up onto a page - but I couldn't get it to allow other elements to render above it. Since I wanted a full-screen map, you could basically see only the map and nothing else.

What happens here is that Openlayers uses the z-index CSS property for its own internal layer arrangements. By default, it reserves quite a large range of z-indexes for itself, so if you're using it on a page with anything besides the map on it, the rest of your page would need to be rejigged merely for Openlayers' benefit. Obviously you'd want to save on the effort if possible.

So in other words:

 div.olMapViewport {
 z-index :  0 ;
 } 

If your z-indexes still don't work, you may have fallen prey to a bit of a CSS gotcha. You need to assign a position (relative/absolute) to a CSS element before it starts taking orders from your z-index property.

For example:

 #element {
position:absolute;
z-index:0;
} 

Its probably folly to stare at download numbers too much, but it has become something of a tradition for me to post them here, so here are the results for the 1.7.0 run (which is now superceded by 1.7.1). With over 100,000 downloads in just over 3 months we are doing well! Note that as before these stats only cover the windows standalone installer.

Cumulative downloads for QGIS 1.7.0

Download decay graph for QGIS 1.7.0

Looks like they are having some post announcement jitters at apple.com:

Apple.com being evasive..

Glad its not just me who sometimes gets things screwed up..

Last week I did a short interview with Gary Sherman (the founder of the Quantum GIS project). I am busy putting together a nice presentation of the human side of the project and I thought I would start with him. Here is the first part (of two parts)  for your viewing pleasure:

metaTile=True
metaBuffer=256

Note that the cache is not pre-seeded, so if you are the first to visit an AOI of interest, it will take a little longer to render.

Lately I have been delving deeper into the (aweful) world of Microsoft Windows - specifically looking to be able to better support Windows users trying to get to grips with running FOSSGIS on that platform. I have mentioned before on this blog how dependent I am on GDAL for my daily work. GDAL is also one of the pillars of any FOSSGIS stack (especially if you 'belong to the c-tribe'), so being able to build it yourself on a given platform os always useful. In my case I wanted to include openjpeg V2.0 support in my Windows builds of QGIS (and hence in my windows build of GDAL).

There are several options for building GDAL under windwos yourself (ranked from insane to mindless):

  • Build all the dependencies yourself from scratch and then download GDAL from SVN and build against those dependencies.
  • Download and install OSGEO4W including the developer packages it provides, and then build GDAL against that.
  • Download an SDK created by a very fine fellow by the name of Tamas Szekeres (thanks to the folks on #gdal IRC channel for putting me on to this).

Tamas' SDK is available in

- for different MSVC versions and different versions of GDAL. Also he provides two options:

  • GDAL and its dependencies provided as pre-built runtimes without.libs  and headers (around 20mb) - this is most useful if you want up to date versions of the GDAL command line tools and don't need to compile and link against the GDAL library.
  • A complete build it yourself environment with GDAL and Mapserver source code and all the dependencies needed to build them (around 60mb).

The runtime packages are available as nightly builds so you can use bleeding edge versions of GDAL like that if you want to. The SDK is provided as a simple .zip file which you can unpack and then run the following command (you need to have MSVC installed) in order to build GDL:

nmake gdal

Simply wait a few minutes and you will have  a fresh build of the stable GDAL created in the directory called release-1500 (if you are using MSVC2008). If you want to build GDAL Trunk, I could't find a download on Tamas' site that directly supports that so I switched the gdal checkout inside his SDK to use trunk:

cd gdal
svn switch https://svn.osgeo.org/gdal/trunk/gdal

If may take a few minutes or longer to do the switch if you are on a slow connection like I have. After that step is done, go back up a level in the directory tree and rebuld GDAL:

cd .
nmake gdal

Once again, go have a cup of fine South African Rooibos Tea while you wait because it may take a few minutes..

Replace:

GDAL_INCLUDE_DIR   : C:/OSGeo4W/include/
 GDAL_LIBRARY     : C:/OSGeo4W/lib/gdal_i.lib

With

GDAL_INCLUDE_DIR   :  C:/dev/cpp/gdal-sdk/release-1500/include
GDAL_LIBRARY       :  C:/dev/cpp/gdal-sdk/release-1500/lib/gdal_i.lib

Then generate and configure and build QGIS as per the documentation. One last thing you need to remember  : all the SDK binaries need to be copied into your QGIS runtime directory otherwise it will complain about missing GDAL.

Tamas' work to create a GDAL SDK for Windows takes away a lot of the pain of developing 'C-tribe' applications under Microsoft Windows and is well worth using if you are stuck in MS land. Thanks Tamas for your efforts!

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:

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


Other products and services from Linfiniti

11-11-2011

Uncategorized « Linfiniti Geo Blog

I was lucky enough to be an intern earlier in the year, and am happy to be part of the team again, and helping in bringing Open Source GIS to Africa and other parts of the world. At one of my clients we manage a petabyte heirachical storage system and several high capacity SAN enclosures. I am also looking at doing a masters degree in the environmental field. Just an update to let you know that I have recently joined Linfiniti.


11-11-2011

GeoDjango « Linfiniti Geo Blog

We do a lot of django work here at Linfiniti and always use a python virtual environment with each project so that the runtime requirements are isolated to that project. To allow the user to administer the extended flat pages, you need to register your custom flatpages model with the admin interface and deregister the existing one.