<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Linfiniti Geo Blog</title>
	<atom:link href="http://linfiniti.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://linfiniti.com</link>
	<description>GIS for Open Source People</description>
	<lastBuildDate>Mon, 08 Mar 2010 09:00:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Django&#8217;s ForeignKey and inheritance limitations &#8211; solved</title>
		<link>http://linfiniti.com/2010/03/django-foreign-key-inheritance-solved/</link>
		<comments>http://linfiniti.com/2010/03/django-foreign-key-inheritance-solved/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 08:57:20 +0000</pubDate>
		<dc:creator>Anne Ghisla</dc:creator>
				<category><![CDATA[General FOSSGIS]]></category>

		<guid isPermaLink="false">http://linfiniti.com/?p=412</guid>
		<description><![CDATA[Last week I had to cope with one of the (few!) limitations of Django ORM model about inheritance. For the GeoDjango website we are developing, we created a model that stores user-layer pairs, so that a logged user can restore the state of map and legend as [s]he left it at previous login, and anonymous [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I had to cope with one of the (few!) limitations of Django ORM model about inheritance. For the GeoDjango website we are developing, we created a model that stores user-layer pairs, so that a logged user can restore the state of map and legend as [s]he left it at previous login, and anonymous users receive a default list of layers. Here is the code for the model:</p>
<pre>
class UserWmsLayer( models.Model ):
  """ Stores custom user preferences for a layer. """
  wmslayer = models.ForeignKey( WmsLayer )
  user = models.ForeignKey( User )
  is_visible = models.NullBooleanField( null=True, blank=True )
  is_deleted =  models.NullBooleanField( null=True, blank=True, default=False )
</pre>
<p>The Layers in Legend can be of <code>WmsLayer</code> class or any of its subclasses, at the moment the only subclass is <code>DateQueryLayer</code>, a WMS layer with a filter on the date attribute. We also have a <code>Layer</code> class, that is an ABC (Abstract Base Class), but it&#8217;s not possible to create a ForeignKey to an ABC as it has no table in the database. So we decided to create the ForeignKey to <code>WmsLayer</code> as a working, half-hack solution.</p>
<p>That worked nicely until I relied on inheritance and method overriding. I expected Django to store the ForeignKey to the actual class of the object, but the ORM stores it as a reference to the superclass, in our case of <code>WmsLayer</code>. This is very well explained in enlightening answer #4 of this <a href="http://stackoverflow.com/questions/313054/django-admin-interface-does-not-use-subclasss-unicode">stackoverflow</a> QA.</p>
<p>In few words, I can actually have a <code>User</code>-<code>DateQueryLayer</code> pair, but in the model it will be stored as <code>WmsLayer</code>, and all methods I call will be <code>WmsLayer</code>&#8217;s, not <code>DateQueryLayer</code>&#8217;s as I would expect from OO programming. <code>DateQueryLayer</code> redefines <code>asOpenLayer</code> method, but due to this ORM limitation I could never call it. </p>
<p>The solutions were multiple, more or less Pythonic, Django-ish, brittle and scalable. I took two days to google and get through them, and the only two applicable solutions seemed to be:</p>
<ol>
<li><strong>Run Time Type identification via a ifelse cascade</strong>: that would be the less scalable and most brittle hack.</li>
<li><strong>Django&#8217;s</strong> <a href="http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1">Generic Relations</a>: better, but still overcomplicated.</li>
</ol>
<p>I was about to implement Generic Relations when I realised that <code>asOpenLayers</code>() simply returns a JavaScript string. A simple solution came to me in a flash. Instead of creating the JavaScript code on the fly every time the layer is used somewhere, I decided to store that string into an attribute owed by <code>Layer</code>, the abstract superclass, so that all subclasses will simply inherit it and populate it at instantiation time using their own <code>asOpenLayers</code> method. The <code>User</code>-*<code>Layer</code> pair will therefore rely on an attribute in <code>WmsLayer</code> table without any inheritance issue. </p>
<p>Here is what the relevant code looks like:</p>
<pre>
class Layer( models.Model ):
  """This is an ABC (Abstract Base Class) for all models that are layers.
  It provides common api so that all layers can be treated in a similar way."""
  name = models.CharField( max_length=256 )
  owner = models.ForeignKey( User, related_name = 'owner' )
  # store the javascript as *attribute*, instead of generating it on-the-fly
  as_open_layer = models.TextField( )

class WmsLayer( Layer ):
  url = models.URLField( max_length=1024, verify_exists=True )
  layers = models.CharField( max_length=256 )
  # link to user-layer model to keep status of legend
  users = models.ManyToManyField(User, through='UserWmsLayer')

  def asOpenLayer( self ):
    """Return a string representation of this model as an open layers
    layer definition. The created layer def will be added
    to the openlayers map of name theMap (which defaults to "map". """
    return "the JavaScript string" #omitted for brevity

  def save( self, *args, **kwargs ):
    """ Overrides standard save, generating the asOpenLayers javascript
    and storing it into as_open_layer attribute. """
    self.as_open_layer = self.asOpenLayer()
    super(WmsLayer, self).save( *args, **kwargs)

class DateQueryLayer( WmsLayer ):
  """A layer model for storing user date range queries persistently"""
  date_query_type = models.ForeignKey( DateQueryType )
  sensor = models.ForeignKey( Sensor )
  start_date = models.DateTimeField( null=True, blank=True )
  end_date = models.DateTimeField( null=True, blank=True )

  def asOpenLayer( self ):
  """ Overrides WmsLayer's method. """
  return "the JavaScript string" #omitted for brevity

  def save( self, *args, **kwargs ):
    self.as_open_layer = self.asOpenLayer()
    super(DateQueryLayer, self).save( *args, **kwargs)
</pre>
<p>That&#8217;s it.</p>
<p>Once you filter the UserWmsLayer table by user, you won&#8217;t call anymore the asOpenLayer method&#8230;</p>
<pre>
myObjects = UserWmsLayer.objects.filter(user__username = "anonymous")
for myObject in myObjects:
  myObjects.asOpenLayer()
</pre>
<p>&#8230; <em>but fetch the <code>as_open_layer</code> attribute instead!</em></p>
<pre>
myObjects = UserWmsLayer.objects.filter(user__username = "anonymous")
for myObject in myObjects:
  myObjects.as_open_layer
</pre>
<p>This allows you to pick up the correct string, without worrying about which type myObject is. This is good. Clean. Scalable. Pythonic. Yes, the <code>asOpenLayer</code> method simply returns a string according to some <code>Layer</code> properties, this solution could not work with more complex methods. But if you face a similar inheritance issue, and your method returns something that can be stored in an attribute of the superclass, that&#8217;s one of the cleanest solutions I&#8217;m aware of.</p>
<p>Hope this helps, and better solutions are most welcome <img src='http://linfiniti.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Happy coding,<br />
&#8211;anne</p>
]]></content:encoded>
			<wfw:commentRss>http://linfiniti.com/2010/03/django-foreign-key-inheritance-solved/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some QGIS Download Stats for Jan and Feb 2010</title>
		<link>http://linfiniti.com/2010/03/some-qgis-download-stats-for-jan-and-feb-2010/</link>
		<comments>http://linfiniti.com/2010/03/some-qgis-download-stats-for-jan-and-feb-2010/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 15:45:53 +0000</pubDate>
		<dc:creator>Tim Sutton</dc:creator>
				<category><![CDATA[QGIS]]></category>

		<guid isPermaLink="false">http://linfiniti.com/?p=410</guid>
		<description><![CDATA[When we released QGIS 1.4 in January, I decided to host the QGIS-1.4.0-1-No-GrassSetup.exe download file here on my server at Linfiniti so I could try to get a sense of how many people are using our software. Estimating users in a FOSS project is a hard thing to do &#8211; our software is free and [...]]]></description>
			<content:encoded><![CDATA[<p>When we released QGIS 1.4 in January, I decided to host the QGIS-1.4.0-1-No-GrassSetup.exe download file here on my server at Linfiniti so I could try to get a sense of how many people are using our software. Estimating users in a FOSS project is a hard thing to do &#8211; our software is free and freely redistributable so one copy of the software may make its way onto many desktops. Also some operating system&#8217;s packaging technology make it hard to track download numbers &#8211; we cant easily see how many downloads have come out of the ubuntu-gis PPA for example. But for the user profile that runs windows and doesn&#8217;t want GRASS functionality, I can reveal that the total downloads from my server for the months of Jan and Feb is:</p>
<blockquote>
<h1 style="text-align: center;">22461</h1>
</blockquote>
<p>To which I can only say: &#8220;Wow! I didn&#8217;t know that many people use Windows!&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://linfiniti.com/2010/03/some-qgis-download-stats-for-jan-and-feb-2010/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Comparing renderers in Mapserver</title>
		<link>http://linfiniti.com/2010/03/comparing-renderers-in-mapserver/</link>
		<comments>http://linfiniti.com/2010/03/comparing-renderers-in-mapserver/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 22:14:14 +0000</pubDate>
		<dc:creator>Tim Sutton</dc:creator>
				<category><![CDATA[QGIS]]></category>

		<guid isPermaLink="false">http://linfiniti.com/?p=397</guid>
		<description><![CDATA[This has been done before by others, but its always interesting to look at image quality versus size when starting a new project. Each project has different types of data and thuse different optimal configuration. Here is a simple breakdown of size vs quality I did for a project.
First let me show you my mapserver [...]]]></description>
			<content:encoded><![CDATA[<p>This has been done before by others, but its always interesting to look at image quality versus size when starting a new project. Each project has different types of data and thuse different optimal configuration. Here is a simple breakdown of size vs quality I did for a project.</p>
<p>First let me show you my mapserver image format definitions&#8230;:</p>
<pre>
  OUTPUTFORMAT
    NAME 'AGG_Q'
    DRIVER AGG/PNG
    IMAGEMODE RGB
    FORMATOPTION "QUANTIZE_FORCE=ON"
    FORMATOPTION "QUANTIZE_DITHER=OFF"
    FORMATOPTION "QUANTIZE_COLORS=256"
  END 

  OUTPUTFORMAT
    NAME 'AGG_JPEG'
    DRIVER AGG/JPEG
    IMAGEMODE RGB
  END 

  OUTPUTFORMAT
    NAME          "AGG_PNG"
    DRIVER        "AGG/PNG"
    IMAGEMODE     RGB
    TRANSPARENT   ON
    EXTENSION     "png"
    FORMATOPTION  "INTERLACE=OFF"
  END 

  OUTPUTFORMAT
    NAME          "AGGA_PNG"
    DRIVER        "AGG/PNG"
    IMAGEMODE     RGBA
    TRANSPARENT   ON
    EXTENSION     "png"
    FORMATOPTION  "INTERLACE=OFF"
  END 

  OUTPUTFORMAT
    NAME "GD_JPEG"
    DRIVER "GD/JPEG"
    MIMETYPE "image/jpeg"
    IMAGEMODE RGB
    EXTENSION "jpg"
  END

  OUTPUTFORMAT
    NAME "GD_PNG"
    DRIVER "GD/PNG"
    MIMETYPE "image/png"
    IMAGEMODE RGB
    EXTENSION "jpg"
  END
</pre>
<p>Now lets look at how each performed in terms of rendering quality versus file size:</p>
<div id="attachment_403" class="wp-caption aligncenter" style="width: 296px"><a href="http://linfiniti.com/wp-content/uploads/2010/03/mapserv_gd_jpeg.jpeg"><img src="http://linfiniti.com/wp-content/uploads/2010/03/mapserv_gd_jpeg.jpeg" alt="" title="mapserv_gd_jpeg" width="286" height="286" class="size-full wp-image-403" /></a><p class="wp-caption-text">File Size : 10.5kb Format: RGB JPEG using GD renderer</p></div>
<div id="attachment_402" class="wp-caption aligncenter" style="width: 296px"><a href="http://linfiniti.com/wp-content/uploads/2010/03/mapserver_gd_png.png"><img src="http://linfiniti.com/wp-content/uploads/2010/03/mapserver_gd_png.png" alt="" title="mapserver_gd_png" width="286" height="286" class="size-full wp-image-402" /></a><p class="wp-caption-text">File Size : 19.7kb Format: RGB  Png using GD renderer</p></div>
<div id="attachment_400" class="wp-caption aligncenter" style="width: 296px"><a href="http://linfiniti.com/wp-content/uploads/2010/02/mapserver_agg_q.png"><img src="http://linfiniti.com/wp-content/uploads/2010/02/mapserver_agg_q.png" alt="" title="mapserver_agg_q" width="286" height="286" class="size-full wp-image-400" /></a><p class="wp-caption-text">File Size : 11.9kb Format: RGB Quantised Png using AGG renderer</p></div>
<div id="attachment_399" class="wp-caption aligncenter" style="width: 296px"><a href="http://linfiniti.com/wp-content/uploads/2010/02/mapserver_agg_png.png"><img src="http://linfiniti.com/wp-content/uploads/2010/02/mapserver_agg_png.png" alt="" title="mapserver_agg_png" width="286" height="286" class="size-full wp-image-399" /></a><p class="wp-caption-text">File Size : 37.6kb Format: RGB Standard PNG using AGG renderer</p></div>
<div id="attachment_398" class="wp-caption aligncenter" style="width: 296px"><a href="http://linfiniti.com/wp-content/uploads/2010/02/mapserver_agga_png.png"><img src="http://linfiniti.com/wp-content/uploads/2010/02/mapserver_agga_png.png" alt="" title="mapserver_agga_png" width="286" height="286" class="size-full wp-image-398" /></a><p class="wp-caption-text">File Size : 37.6kb Format: RGBA Png using AGG renderer</p></div>
<p>To be fair I haven&#8217;t added the needed ANTIALIAS clauses for the GD renderer to produce anti-aliased images for true comparison with AGG. That said even GD at it&#8217;s best isn&#8217;t a patch on AGG in my opinion. Needless to say In this project I&#8217;ve gone with the Quantised AGG outputs which are almost as small as GD JPEG images but with much nicer quality.</p>
<p><strong>Note:</strong> Updated 1 March to inline images rather having to click to view the full size.</p>
]]></content:encoded>
			<wfw:commentRss>http://linfiniti.com/2010/03/comparing-renderers-in-mapserver/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Learning about Free Open Source Software (FOSS) through my Linfiniti internship</title>
		<link>http://linfiniti.com/2010/02/learning-about-free-open-source-software-foss-through-my-linfiniti-internship/</link>
		<comments>http://linfiniti.com/2010/02/learning-about-free-open-source-software-foss-through-my-linfiniti-internship/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 11:09:51 +0000</pubDate>
		<dc:creator>samantha</dc:creator>
				<category><![CDATA[FOSS Training]]></category>

		<guid isPermaLink="false">http://linfiniti.com/?p=381</guid>
		<description><![CDATA[When I started off this internship,  I had little practical experience of Open Source software.  I had heard about it, and knew that it was an interesting, expanding field for a collective good,  but hadn&#8217;t an opportunity to delve in deeper through my education career. 
This internship has given me that opportunity [...]]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --><span style="font-family: Arial,sans-serif;">When I started off this internship,  I had little practical experience of Open Source software.  I had heard about it, and knew that it was an interesting, expanding field for a collective good,  but hadn&#8217;t an opportunity to delve in deeper through my education career. </span></p>
<p><span style="font-family: Arial,sans-serif;">This internship has given me that opportunity and exposed me to a whole range of Open Source tools, especially those related to GIS.  The programme was run so that touched on a variety of sections, explaining basic concepts and applying this information to practical projects.  The sections could later be built on, beyond the internship. The training also included work from live projects running at Linfinti Consulting, which was a rewarding experience because it involved interaction with clients and handing over a product at the end of the day.</span></p>
<p><span style="font-family: Arial,sans-serif;">The days usually began with a session from Tim or Anne explaining what we would be covering that day.  They explained all the necessary theory in a down-to-earth, and understandable way, ensuring that we understood.  And after that we would get busy with our clicking, typing, learning and building.  They would patiently assist us when we got stuck, and help us get to the root of the issue when there were bigger problems.</span></p>
<p><span style="font-family: Arial,sans-serif;">Tim and Anne were both excellent, knowledgable and practical teachers with tremendous enthusiasm for Open Source GIS, which has left me inspired.<br />
</span></p>
<p><span style="font-family: Arial,sans-serif;">Some of the new tools and concepts I was exposed to:</span></p>
<ul>
<li><span style="font-family: Arial,sans-serif;">Concepts 	of FOSS and the FOSS GIS stack<br />
</span></li>
<li><span style="font-family: Arial,sans-serif;">Linux 	operating system &#8211; some bash, basic tools and software on Linux </span></li>
<li><span style="font-family: Arial,sans-serif;">PostGIS 	– (first time I&#8217;ve used a geodatabase through open source <img src='http://linfiniti.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  and seen its practicality!)<br />
</span></li>
<li><span style="font-family: Arial,sans-serif;">Qgis 	– user interface, new symbology and cartography, plugins (very useful!)</span></li>
<li><span style="font-family: Arial,sans-serif;">Programming 	- coding in Python to create our own Qgis plugins, coding standards, SVN </span></li>
<li><span style="font-family: Arial,sans-serif;">Open 	source community support – through IRC, mailing lists and forums</span></li>
<li><span style="font-family: Arial,sans-serif;">GRASS 	-  introduction to the interface and commands, and practical 	application in flood simulation</span></li>
<li><span style="font-family: Arial,sans-serif;">Mapserver, 	Openlayers &#8211; exporting QGIS projects to mapfiles, editing symbology of the mapfiles, displaying through OpenLayers<br />
</span></li>
<li><span style="font-family: Arial,sans-serif;">HTML, 	CSS, Javascript (JQuery) &#8211; linking these up, and building a webpage</span></li>
<li><span style="font-family: Arial,sans-serif;">Joomla CMS</span></li>
</ul>
<p><span style="font-family: Arial,sans-serif;">Tim also expained how all these sections were connected and added to one another, and we got to see this through our own practical work.</span></p>
<p><span style="font-family: Arial,sans-serif;">I really enjoyed and learnt a lot, and would like to thank Tim, Anne, Marcelle and Robert for the valuable time I spent here. It&#8217;s a sad goodbye to the team and office, but I am hoping that the new skills that I have learnt here will contribute positively to the future. </span></p>
<p><span style="font-family: Arial,sans-serif;">Looking foward to FOSS GIS growing in Africa! \o/<br />
</span></p>
<p><span style="font-family: Arial,sans-serif;">- sam<br />
</span></p>
]]></content:encoded>
			<wfw:commentRss>http://linfiniti.com/2010/02/learning-about-free-open-source-software-foss-through-my-linfiniti-internship/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Reflecting on a month of internships at Linfiniti.com</title>
		<link>http://linfiniti.com/2010/02/reflecting-on-a-month-of-internships-at-linfiniti-com/</link>
		<comments>http://linfiniti.com/2010/02/reflecting-on-a-month-of-internships-at-linfiniti-com/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 23:19:13 +0000</pubDate>
		<dc:creator>Tim Sutton</dc:creator>
				<category><![CDATA[FOSS Training]]></category>

		<guid isPermaLink="false">http://linfiniti.com/?p=384</guid>
		<description><![CDATA[Interns
Its been a busy month. A few months ago I set things in motion by advertising for interns to come and work and learn about FOSS GIS at linfiniti.com. In tandem with that I invited Anne Ghisla to come out to South Africa from Italy to act as mentor for the interns.
When Anne arrived we [...]]]></description>
			<content:encoded><![CDATA[<h2>Interns</h2>
<p>Its been a busy month. A few months ago I set things in motion by advertising for interns to come and work and learn about FOSS GIS at linfiniti.com. In tandem with that I invited Anne Ghisla to come out to South Africa from Italy to act as mentor for the interns.</p>
<p>When Anne arrived we interviewed various candidates and selected two &#8211; Robert Makondo and Samantha Lee Pan. You will no doubt read postings from them elsewhere on this blog as I have encouraged them to start writing articles and sharing their learning post publicly. </p>
<p>The aim of the internship programme is simple: transfer real-world FOSS GIS skills to interns so that we can build up the skills base in South Africa and eventually greater Africa. One day I would love to be running a kind of academy where we have a continual succession of interns from all over Africa participating in our internship programme and taking FOSSGIS skills and enthusiasm back to their place of work or study. What we are doing now is a small step in that direction.</p>
<p>Unfortunately Samantha (Sam) could only stay with us for the month of February as she is going into permanent employment next month. I decided to bid Sam farewell by taking the group out for a morning at the Lion and Rhino park about 30 minutes from our Linfiniti Offices in Lanseria, near Johannesburg, SA. Of course being a bunch complete geogeeks we did a GPS drive as we went (i.e. we captured our route using the <a href="http://linfiniti.com/2010/01/gps-tracker-tool-in-qgis-trunk/">new GPS plugin</a> for QGIS that Marco and I wrote). Here is a little map of our trip (click for larger image)!</p>
<p><a href="http://www.flickr.com/photos/linfiniti/4389791659/" title="GPS Drive in the Lion and Rhino Park by linfiniti.com, on Flickr"><img src="http://farm3.static.flickr.com/2787/4389791659_c2eab0f42a.jpg" width="500" height="269" alt="GPS Drive in the Lion and Rhino Park" /></a></p>
<p>Capturing data in this way is a fun and entertaining way to expose interns to the process of primary data capture. The location was also a great choice as some in our group had never before seen lion, buffalo, wild dogs and other charismatic wild animals.</p>
<p><a href="http://www.flickr.com/photos/linfiniti/4390882106/" title="Buffalos on our GPS Drive by linfiniti.com, on Flickr"><img src="http://farm3.static.flickr.com/2680/4390882106_098df07802.jpg" width="500" height="375" alt="Buffalos on our GPS Drive" /></a></p>
<p>Sam and Robert sat in the back and learned to operate the GPS and the GPS Tracker plugin for QGIS.</p>
<p><a href="http://www.flickr.com/photos/linfiniti/4390888398/" title="Sam and Robert capturing data on our drive by linfiniti.com, on Flickr"><img src="http://farm5.static.flickr.com/4004/4390888398_5a97290f00.jpg" width="500" height="375" alt="Sam and Robert capturing data on our drive" /></a></p>
<p>We finished our little outing with a short walk to look at the hippos wallowing in a pond. Heres a shot of us all on the hippo viewing platform (sorry we couldnt get the hippos into the shot too <img src='http://linfiniti.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' />  ).</p>
<p><a href="http://www.flickr.com/photos/linfiniti/4389562197/" title="Linfiniti Team @ Rhino and Lion Nature Reserve by linfiniti.com, on Flickr"><img src="http://farm3.static.flickr.com/2746/4389562197_aea87b8c32.jpg" width="500" height="375" alt="Linfiniti Team @ Rhino and Lion Nature Reserve" /></a></p>
<p>Next week we will say &#8216;goodbye&#8217; to Samantha and &#8216;hello&#8217; to Petronella, a Zimbabwean lady who will be joining us as an intern for the months of March and April. We will also be joined for the week by two other interns from the start-up company of my friend Andiswa Silinga. Andiswa is going to be getting her interns to do some digitising work using FOSSGIS so they will come to Linfiniti for occasional visits to get up to speed with the FOSSGIS way of doing things.</p>
<h2>Training Environment</h2>
<p>One of the cornerstones of my setup for providing a training environment has been LTSP (the Linux Terminal Server Project). I have <a href="http://linfiniti.com/2009/11/mini-review-fujitsu-futro-s450-thin-client-with-ltsp-and-fossgis/">blogged previously</a> about my testing experiences with LTSP. For the LTSP server, I purchased one fairly good spec quad core pc which then acts as a server for up to four thin clients. I bought 3 Fujitsu Futro 100 units for thin clients which connect to the LTSP server. The system works admirably well and we have had &#8216;nary a hiccup over the month of solid production use. There have only been a few small issues. The GIMP for example causes X to hang when opening a file. </p>
<p>Using thin clients has many advantages  &#8211; it is extremely simple for users to share files since they are all logged on to the same system. Also, there is only one server / machine to manage. We can get connected to the internet using a single 3G modem which we plug in to the server and then everyone on the thin clients gets internet access.</p>
<p>Since buying the Futro clients I have also being experimenting with using other clients. I dug out a very old and mostly dead thinkpad laptop and set its bios to do etherboot. I plugged it in to the power (its battery is long since deceased) and into an external CRT monitor (its lcd display has also given up the ghost) and voila we have another client for our network. I will probably avoid using old desktop PC&#8217;s for this purpose since they consume a lot of power and make a lot of noise, but if you are in the position where you want to maximise value and minimise your landfill contribution, using old desktop pc&#8217;s would also work fine.</p>
<p>One more thing I wanted to mention is the the iTalc application that you can run on top of LTSP. iTalc lets you view a gallery of connected thin clients, broadcast a message to any client, share your screen or a window with all clients (e.g. while doing a demo), lock, reboot etc. the clients. I think if I scale up to a classroom environment, it really is going to prove to be a great option.</p>
<h2>Morning Sessions</h2>
<p>We have established a pattern of having morning &#8216;geekout&#8217; sessions of around an hour long where we discuss a topic for the day. I don&#8217;t rigidly plan what the topics will be &#8211; they either relate to some work we are trying to produce, something I have been thinking about, or another piece of the FOSSGIS jigsaw puzzle I want to let the interns know about. Here is a pic of our whiteboard doodlings from such a session:</p>
<p><a href="http://www.flickr.com/photos/linfiniti/4391010544/" title="Intern Training Doodling by linfiniti.com, on Flickr"><img src="http://farm3.static.flickr.com/2788/4391010544_44bf3ac37e.jpg" width="500" height="375" alt="Intern Training Doodling" /></a></p>
<h2>Mentors</h2>
<p>After the morning &#8216;geekout&#8217; session we task the interns with some work for the day and then  I usually run off to a client or try to knuckle down to some work. Anne continues providing mentorship to the interns through the day. The system works really well &#8211; although if I had one complaint it would be that my productivity has been reduced somewhat by the extra activities surrounding the interns. I really can&#8217;t praise Anne enough here &#8211; if it wasn&#8217;t for her, having interns would probably consume far larger amounts of my time. She is patient and enthusiastic and she instills her sense of FOSSGIS enthusiasism into the interns. I will be really sad to see Anne go at the end of March.  However, I&#8217;ve had a couple of other folks in europe interested in providing mentoring services so stay tuned for the musings of other FOSSGIS celebrity guest mentors on this blog!</p>
<h2>Biting off more than I can chew</h2>
<p>Maybe we are biting off more than we can chew trying to launch a internship / mentoring programme from such a small company, but the wheels of government and NGO support and funding turn slowly and I wield little to no influence in the circles where decent funding gets allocated for these activities. So in the spirit of Open Source we are starting something small (like a little bit of code to scratch and itch) and hoping that others will pick up on it and let us expand the concept out to the larger African audience out that is starving to get a leg up in a GIS world dominated by expensive proprietary software that does them no favours.</p>
<p><strong>Note:</strong> Edited Feb 27 to fix some 2am typos and bad grammar.</p>
]]></content:encoded>
			<wfw:commentRss>http://linfiniti.com/2010/02/reflecting-on-a-month-of-internships-at-linfiniti-com/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>creating a simple mapserver project</title>
		<link>http://linfiniti.com/2010/02/creating-a-simple-mapserver-project/</link>
		<comments>http://linfiniti.com/2010/02/creating-a-simple-mapserver-project/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 18:53:25 +0000</pubDate>
		<dc:creator>robertm</dc:creator>
				<category><![CDATA[QGIS]]></category>

		<guid isPermaLink="false">http://linfiniti.com/?p=354</guid>
		<description><![CDATA[Hi my name is Robert. I am an intern at Linfiniti Consulting. I am having a great time at the company, exploring different Open Source GIS technologies. I would like to take a moment to discuss one of the projects i have been working on. I created a simple mapserver project using a mapfile that [...]]]></description>
			<content:encoded><![CDATA[<p>Hi my name is Robert. I am an intern at Linfiniti Consulting. I am having a great time at the company, exploring different Open Source GIS technologies. I would like to take a moment to discuss one of the projects i have been working on. I created a simple mapserver project using a mapfile that I exported from qgis. I used data that covers Mbizana municipality. MapServer is an open source development environment for building spatially-enabled internet applications. The following is a step-by-step explanation of how I did it:</p>
<p>1.Install a maperver export plugin on qgis (if not installed)<br />
  Click Plugins =&gt; Manage plugins<br />
  This will take you to the Qgis plugin manager window<br />
  Click on the checkbox next to Mapserver Export(Version 0.4.3)<br />
  Then click OK<br />
2.Add some layers to your qgis<br />
  I added two layers (roads layer and mbizana_munic layer) using the data of Mbizana municipality<br />
3.Exporting mapfile<br />
  I first saved my qgis project in /home/robert/mapserver<br />
  Then you click Plugins =&gt; Mapserver export =&gt; Mapserver export (will open the mapserver export window)<br />
  Click the &#8220;save as&#8221; and give the name to the mapfile.<br />
  I saved mine as mbizana.map in the mapserver folder (/home/robert/mapserver/).<br />
  Then click OK.<br />
5.Edit the mapfile<br />
  In the mapfile just comment the lines that point to the symbology file and font file, to look like this:<br />
  #SYMBOLSET &#8220;./symbols/symbols.sym&#8221;<br />
  #FONTSET &#8220;./fonts/fonts.list&#8221;<br />
6.Test your  mapserver with your mapfile<br />
  I put this /localhost/cgi-bin/mapserv?map=/home/robert/mapserver/mbizana.map&amp;mode=map</p>
<p>Now i can access the mapserver using Openlayers. Happy mapping !!!!!!!!!!!!</p>
]]></content:encoded>
			<wfw:commentRss>http://linfiniti.com/2010/02/creating-a-simple-mapserver-project/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fancy map toolbar for OpenLayers</title>
		<link>http://linfiniti.com/2010/02/fancy-map-toolbar-for-openlayers/</link>
		<comments>http://linfiniti.com/2010/02/fancy-map-toolbar-for-openlayers/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 10:39:55 +0000</pubDate>
		<dc:creator>Anne Ghisla</dc:creator>
				<category><![CDATA[General FOSSGIS]]></category>

		<guid isPermaLink="false">http://linfiniti.com/?p=328</guid>
		<description><![CDATA[Are you looking for giving your OpenLayers map controls a cool appearance, smoothly integrated with the site&#8217;s theme, without writing a papyrus and scatter code among lot of files?
Then have a look at jQuery UI CSS framework, a system of classes developed for jQuery UI widgets.
This is the map toolbar of the webGIS site we [...]]]></description>
			<content:encoded><![CDATA[<p>Are you looking for giving your OpenLayers map controls a cool appearance, smoothly integrated with the site&#8217;s theme, without writing a papyrus and scatter code among lot of files?</p>
<p>Then have a look at <a href="http://docs.jquery.com/UI/Theming/API">jQuery UI CSS framework</a>, a system of classes developed for <a href="http://jqueryui.com/demos/">jQuery UI widgets</a>.</p>
<p>This is the map toolbar of the webGIS site we are busy developing, rendered with UI-Darkness theme:<br />
<img class="alignnone" title="Fancy OpenLayers control toolbar" src="http://farm3.static.flickr.com/2579/4384736424_85e7f6df2d_o.png" alt="Fancy OpenLayers control toolbar" width='500px' /></p>
<p>The controls (pan, measure and zoom) are OpenLayers&#8217; controls. They are all created in the map&#8217;s init() (see first js snippet below). The binding with the buttons is made by name &#8211; therefore be sure that the names of the OpenLayers controls match exactly the name properties of the respective buttons. The activation of the selected control is done by the toggleControl() function, further below in the js snippet. That way you can add as many control-button pairs as you need.</p>
<p>Let&#8217;s see what the code looks like. It is not so much indeed.. My tribute to the proverbial programmer&#8217;s laziness and to the koan of <a href="http://catb.org/~esr/writings/taoup/html/ten-thousand.html">Master Foo&#8217;s and the Ten Thousand Lines</a>.</p>
<p>First be sure to include all necessary scripts in the html head:<br />
<code><br />
&lt;link type="text/css" href="/static/css/jquery.fancybox-1.2.6.css" rel="stylesheet" media="screen" /&gt;<br />
&lt;script type="text/javascript" src="/static/js/jquery-1.3.2.min.js"&gt;&lt;/script&gt;<br />
&lt;script type="text/javascript" src="/static/js/jquery-ui-1.7.2.custom.min.js"&gt;&lt;/script&gt;<br />
&lt;script type="text/javascript" src="/static/js/jquery.fancybox-1.2.6.pack.js"&gt;&lt;/script&gt;<br />
&lt;script type="text/javascript" src="/static/js/jquery.easing.1.3.js"&gt;&lt;/script&gt;<br />
</code></p>
<p>then add the buttons &#8211; I took inspiration from <a href="http://www.filamentgroup.com/lab/styling_buttons_and_toolbars_with_the_jquery_ui_css_framework/">Filament Group excellent post</a>:<br />
<code><br />
&lt;div id="mapcontrols" class="fg-buttonset fg-buttonset-single ui-helper-clearfix"&gt;<br />
&lt;button name='navigate'class="fg-button ui-state-default ui-state-active ui-priority-primary ui-corner-left" &gt;Navigate&lt;/button&gt;<br />
&lt;button name='line'  class="fg-button ui-state-default ui-priority-primary"&gt;Measure line&lt;/button&gt;<br />
&lt;button name='polygon' class="fg-button ui-state-default ui-priority-primary"&gt;Measure area&lt;/button&gt;<br />
&lt;a href="#" name='zoomin' class="fg-button ui-state-default fg-button-icon-solo" title="Zoom in"&gt;&lt;span class="ui-icon ui-icon-circle-zoomin"&gt;&lt;/span&gt; Zoom in&lt;/a&gt;<br />
&lt;a href="#" name='zoomout' class="fg-button ui-state-default fg-button-icon-solo ui-corner-right" title="Zoom out"&gt;&lt;span class="ui-icon ui-icon-circle-zoomout"&gt;&lt;/span&gt; Zoom out&lt;/a&gt;<br />
&lt;/div&gt;<br />
</code></p>
<p>And in the end the JavaScript &#8211; add the following snippet in the map&#8217;s init() function:</p>
<pre>    mapControls = {
	line: new OpenLayers.Control.Measure(
	    OpenLayers.Handler.Path, {
		persist: true
	    }
	),
	polygon: new OpenLayers.Control.Measure(
	    OpenLayers.Handler.Polygon, {
		persist: true
	    }
	),
	zoomin: new OpenLayers.Control.ZoomBox(
	    {title:"Zoom in box", out: false}
	),
	zoomout: new OpenLayers.Control.ZoomBox(
	    {title:"Zoom out box", out: true}
	)
    };

    var control;
    for(var key in mapControls) {
	control = mapControls[key];
	control.events.on({
	    "measure": handleMeasurements,
	    "measurepartial": handleMeasurements
	});
	map.addControl(control);
    }
</pre>
<p>and these functions at the bottom of your js file:</p>
<pre>
function handleMeasurements(event) {
    var geometry = event.geometry;
    var units = event.units;
    var order = event.order;
    var measure = event.measure;
    var element = document.getElementById('output'); //TODO redirect to other area?
    var out = "";
    if(order == 1) {
	out += "Measure: " + measure.toFixed(3) + " " + units;
    } else {
	out += "Measure: " + measure.toFixed(3) + " " + units + "2";
    }
    element.innerHTML = out;
}

function toggleControl(element) {
    for(key in mapControls) {
	var control = mapControls[key];
	//alert ($(element).is('.ui-state-active'));
	if(element.name == key &amp;&amp; $(element).is('.ui-state-active')) {
	    control.activate();
	} else {
	    control.deactivate();
	}
    }
}

$(function(){
    //all hover and click logic for buttons
    $(".fg-button:not(.ui-state-disabled)")
    .hover(
	function(){
	    $(this).addClass("ui-state-hover");
	},
	function(){
	    $(this).removeClass("ui-state-hover");
	}
    )
    .mousedown(function(){
	$(this).parents('.fg-buttonset-single:first').find\
            (".fg-button.ui-state-active").removeClass("ui-state-active");
	if( $(this).is('.ui-state-active.fg-button-toggleable, \
            .fg-buttonset-multi .ui-state-active') )
	    { $(this).removeClass("ui-state-active"); }
	else { $(this).addClass("ui-state-active"); }
    })
    .mouseup(function(){
	if(! $(this).is('.fg-button-toggleable, .fg-buttonset-single .fg-button,  \
            .fg-buttonset-multi .fg-button') ){
	    $(this).removeClass("ui-state-active");
	}
	//TODO use this else only for measure/pan toggle.
	else {toggleControl(this);}
    });
});
</pre>
<p>Ok, should be all you have to know to set up the toolbar! Feel free to reuse the code and improve it <img src='http://linfiniti.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Oh, and don&#8217;t forget to tweak the CSS to get the perfect look and feel <img src='http://linfiniti.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>&#8211;anne</p>
]]></content:encoded>
			<wfw:commentRss>http://linfiniti.com/2010/02/fancy-map-toolbar-for-openlayers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Saving bandwidth using Python</title>
		<link>http://linfiniti.com/2010/02/saving-bandwidth-using-python/</link>
		<comments>http://linfiniti.com/2010/02/saving-bandwidth-using-python/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 15:05:48 +0000</pubDate>
		<dc:creator>Anne Ghisla</dc:creator>
				<category><![CDATA[QGIS]]></category>

		<guid isPermaLink="false">http://linfiniti.com/?p=316</guid>
		<description><![CDATA[When Internet connection is a limited resource, a well-designed website doesn&#8217;t perform multiple times the same request. This little adjustment can significantly reduce the time required to load and refresh a page. First-world programmers should keep this in mind, or better come to South Africa and experience it in person&#8230;
This reminds me how life forms [...]]]></description>
			<content:encoded><![CDATA[<p>When Internet connection is a limited resource, a well-designed website doesn&#8217;t perform multiple times the same request. This little adjustment can significantly reduce the time required to load and refresh a page. First-world programmers should keep this in mind, or better come to South Africa and experience it in person&#8230;</p>
<p>This reminds me how life forms adapt to severe environmental conditions. But it&#8217;s a wide topic.</p>
<p>Let&#8217;s see how you can easily do this in Python. The snippet is a generic version of a function in views.py of the GeoDjango website we are busy developing. That function caches the result of WMS requests for layer legends in a dedicated directory, assuming that the images are not changing over time.</p>
<pre>
import urllib
import os

def retrieveDataFromUrl():
 myFileName = "file.txt"
 myLocalPath = os.path.join( os.getcwd(), myFileName )

  if not os.path.exists( myLocalPath ):
    print "Downloading data"
    myUrl = "http://whatever"
    # save it where it should have been found
    urllib.urlretrieve(myUrl, myLocalPath)
  else:
    print "Reading from local file" + myLocalPath
  # then read the file...
</pre>
<p>This code only checks if the file <em>exists</em>. If the file downloaded in previous run is outdated, then the newer version must be downloaded. This can be a good task for a cronjob &#8211; but it&#8217;s the topic of another post <img src='http://linfiniti.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Hope this helps!</p>
<p>&#8211; anne</p>
]]></content:encoded>
			<wfw:commentRss>http://linfiniti.com/2010/02/saving-bandwidth-using-python/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dissolving features by an attribute</title>
		<link>http://linfiniti.com/2010/02/dissolving-features-by-an-attribute/</link>
		<comments>http://linfiniti.com/2010/02/dissolving-features-by-an-attribute/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 09:39:08 +0000</pubDate>
		<dc:creator>samantha</dc:creator>
				<category><![CDATA[Postgres & PostGIS]]></category>

		<guid isPermaLink="false">http://linfiniti.com/?p=304</guid>
		<description><![CDATA[Hi, I&#8217;m Sam. I&#8217;ve been learning a lot here at Linfiniti (thanks to the brilliant team!)  Just like to add a quick note on one of the tasks I learnt this week.
I was working on a shapefile of the suburbs in Cape Town.  A client required the suburbs to be grouped by region. [...]]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } -->Hi, I&#8217;m Sam. I&#8217;ve been learning a lot here at Linfiniti (thanks to the brilliant team!)  Just like to add a quick note on one of the tasks I learnt this week.</p>
<p>I was working on a shapefile of the suburbs in Cape Town.  A client required the suburbs to be grouped by region.  After the tedious part of manually grouping the suburbs (using a created field, REGION), the unioning (dissolving) of the suburbs proved to be quick and painless through PostgreSQL, using this SQL command that implements the geomunion function:</p>
<pre>create table ct_regions as select geomunion(the_geom), "REGION" \
 from "ct_suburbs" group by "REGION";</pre>
<p>“ct_suburbs” is the original shapefile that was loaded into the PostGIS database using the Quantum GIS &#8216;SPIT&#8217; plugin. “REGION” is the class (attribute) that I wish to union by.  And ct_regions will be the output shapefile. See the result here:</p>
<p>Before dissolving (ct_suburbs shows suburbs)</p>
<p><a href="http://linfiniti.com/wp-content/uploads/2010/02/before.png"><img class="alignnone size-medium wp-image-310" title="Cape Town suburbs before dissolving" src="http://linfiniti.com/wp-content/uploads/2010/02/before-265x300.png" alt="Cape Town suburbs before dissolving" width="265" height="300" /></a></p>
<p>After dissolving by suburbs (ct_regions shows collections of suburbs that have been merged)</p>
<p><a href="http://linfiniti.com/wp-content/uploads/2010/02/after.png"><img class="alignnone size-medium wp-image-311" title="Cape Town suburbs after dissolving" src="http://linfiniti.com/wp-content/uploads/2010/02/after-258x300.png" alt="Cape Town suburbs after dissolving" width="258" height="300" /></a></p>
<p style="text-align: justify;">Hopefully this will be of some use when it comes to your own mapping!</p>
]]></content:encoded>
			<wfw:commentRss>http://linfiniti.com/2010/02/dissolving-features-by-an-attribute/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Meet the Linfiniti Team</title>
		<link>http://linfiniti.com/2010/02/meet-the-linfiniti-team/</link>
		<comments>http://linfiniti.com/2010/02/meet-the-linfiniti-team/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 08:21:43 +0000</pubDate>
		<dc:creator>Tim Sutton</dc:creator>
				<category><![CDATA[FOSS Training]]></category>

		<guid isPermaLink="false">http://linfiniti.com/?p=299</guid>
		<description><![CDATA[Over the last few months I have been working hard to get an internship programme going here at Linfiniti Consulting. Part of our mission is to build up local skills in FOSS GIS. The internship programme is an adjunct to other initiatives like providing free training courses, open days and so on. 
 We have [...]]]></description>
			<content:encoded><![CDATA[<p>Over the last few months I have been working hard to get an internship programme going here at Linfiniti Consulting. Part of our mission is to build up local skills in FOSS GIS. The internship programme is an adjunct to other initiatives like providing free training courses, open days and so on. </p>
<p><a href="http://www.flickr.com/photos/38241992@N06/4350164923/" title="Anne Ghisla by linfiniti.com, on Flickr"><img src="http://farm3.static.flickr.com/2737/4350164923_a40065379c_t.jpg" width="100" height="100" alt="Anne Ghisla" /></a> We have hired Anne Ghisla (Italian QGIS and GRASS geek) to come over to South Africa and spend two months mentoring our interns.</p>
<p>The interns were offered a two month period during which they would receive a monthly stipend to cover their living expenses, and receive on-the-job experience in the practical use of FOSS GIS to solve real world problems.</p>
<p><a href="http://www.flickr.com/photos/38241992@N06/4350164925/" title="Robert Makondo by linfiniti.com, on Flickr"><img src="http://farm5.static.flickr.com/4004/4350164925_a56a79dcb6_t.jpg" width="93" height="100" alt="Robert Makondo" /></a>Robert Makondo studied computer science in Pretoria and worked for a year as an intern at the State IT Agency (SITA). Robert is a relatively newcomer to FOSS and FOSSGIS but is already showing great enthusiasm in learning the new tools of the trade!</p>
<p><a href="http://www.flickr.com/photos/38241992@N06/4350164929/" title="Samantha Lee Pan by linfiniti.com, on Flickr"><img src="http://farm5.static.flickr.com/4068/4350164929_9ea88f0f61_t.jpg" width="100" height="87" alt="Samantha Pan" /></a>Samantha Pan is from Cape Town where she studied GIS at UCT. Samantha has used GIS during her studies but is new to the world of FOSSGIS (which she is adapting to extremely well!). Unfortunately Samantha is only staying with us for one month but we hope she will use the skills she learns here in her future place of work.</p>
<p>Having the mixture of CS and GIS disciplines in our interns is really nice since they complement each other well and can problem solve together. I think Anne is really enjoying her stay here in South Africa and mentoring our interns. We will be sad to see her go at the end of March <img src='http://linfiniti.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> .</p>
<p>If any readers out there are interested in coming to South Africa for a few months to help with mentoring interns please let me know! We will cover your costs and provide accommodation. In return you get to help bridge the digitial divide between Africa and the western world, while at the same time having a great experience in a different country!</p>
]]></content:encoded>
			<wfw:commentRss>http://linfiniti.com/2010/02/meet-the-linfiniti-team/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
