<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2573156439353370360</id><updated>2012-01-31T04:59:44.837Z</updated><category term='raster'/><category term='optim'/><category term='afripop'/><category term='optimisation'/><category term='maps'/><category term='rstats'/><category term='R'/><title type='text'>Barry Rowlingson's GeoSpatial Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>28</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-3400439599644943458</id><published>2012-01-01T13:57:00.000Z</published><updated>2012-01-01T13:57:03.294Z</updated><title type='text'>Document Management System review - Mayan EDMS</title><content type='html'>We're redoing all our web pages in Maths and Stats. This means getting rid of our old Plone 2.1 CMS and replacing it with a groovy new Django-based system using Arkestra - see previous blog entry for more on that.&lt;br /&gt;&lt;br /&gt;There's a casualty though. We have an archive of old exam papers going back to 1997. These are sitting on our Plone server (technically as Zope File objects in the ZODB) and are accessed via some custom page templates I wrote so students can get them by calendar year, year of study, or search for a string.&lt;br /&gt;&lt;br /&gt;Its a mess. I've been wanting to put them into a proper document management system for a while. Here's my requirements:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Users should be able to search by course code, year of study, and calendar year.&lt;/li&gt;&lt;li&gt;Users should be able to bulk download a zip file of selected PDFs&lt;/li&gt;&lt;li&gt;Admins should be able to bulk upload and enter metadata&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I imagine Sharepoint can do this, but I'm no Sharepoint Wrangler and I don't really want to be one. There are a few open source solutions around, such as&amp;nbsp;&lt;a href="http://www.logicaldoc.com/"&gt;LogicalDoc&lt;/a&gt;&amp;nbsp;and these all seem to be Java-based Enterprisey solutions. Often there's an open-source, or 'community', version, and then an Enterprise supported version with integration features such as drag n drop, OCR, versioning etc.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Then the other day I noticed&amp;nbsp;&lt;a href="http://rosarior.github.com/mayan/"&gt;Mayan EDMS&lt;/a&gt;. Its a Django-based DMS which looks like it might well do everything I want. And being open-source if it doesn't, I can have a go at making it do so.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Installation&lt;/span&gt;&lt;br /&gt;Smooth as you like. The documentation was spot on, just download, get some dependencies with pip, and it all goes nicely in a virtual environment. The whole virtual env ends up about 90M big on my system, which is comparable to Java-based systems when they bundle the JVM with themselves (which they often seem to do).&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Setup&lt;/span&gt;&lt;br /&gt;The included &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;settings.py&lt;/span&gt; file has options for development and production servers. For development you can run from the usual Django dev server, and for production you can collect all your static files into &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/static&lt;/span&gt; for serving from a web server. For test purposes I set the development mode and did the usual Django syncdb/migrate dance. I couldn't see what the default superuser name and password was, so I just created one with &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;./manage.py createsuperuser&lt;/span&gt; and I was in. I was uploading documents in no time.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Features&lt;/span&gt;&lt;br /&gt;Can it do what I want? The version I downloaded currently couldn't. The big missing thing - anonymous read-only access. We don't want our students to need to login to download exam papers, but the permission system on Mayan EDMS doesn't allow anonymous access to anything.&lt;br /&gt;&lt;br /&gt;I had a look at creating a new user with read-only permissions. The system has a very fine level of permission control, with lots of capabilities that can bet set on or off. The access to permission is via the usual Role/Group/User style of thing. You create a Role with permissions, then give that role to a User (or a Group of Users). So I created a 'Reader' role and a 'guest' user with that role, thinking we could use that for anonymous access. But the guest user could still create Folders. At that point I had a look at the code.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Code&lt;/span&gt;&lt;br /&gt;The code is all on &amp;nbsp;&lt;a href="https://github.com/rosarior/mayan"&gt;Github&lt;/a&gt;&amp;nbsp;and it's incredibly well written, seemingly by one person. It uses lots of existing django apps for some of its functionality which is a good thing. It appears to comply with Python and Django best practices, is commented, and easy to find your way around. I found the Folder creation code and noticed there was no permission check like there was with, say, Document creation. I popped a quick issue on the issue tracker.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Author&lt;/span&gt;&lt;/div&gt;&lt;div&gt;The next morning I had a response from Roberto. And that was over New Year's Eve to New Year's Day. He's already added a permission check for Folder creation on a development branch. Coming out in the next version. Not sure if that will also have support for fully anonymous users without logging in (Django returns AnonymousUser if this is the case, rather than a real User object) but it should be sufficient for us. I don't think I've ever had such a quick response from an Open Source dev for a while - and certainly never over New Year celebrations! Credit also goes to Github for its fantastic tracking and notification system, but most of the credit goes to Roberto himself!&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Metadata&lt;/span&gt;&lt;br /&gt;You can define metadata sets in Mayan EDMS, so I defined a set for our exam papers and added the properties we want to classify our papers with - calendar year, year of study, and course code. Documents can also be tagged, so we could tag very old exams with 'obsolete' - since sometimes course codes are re-used for different courses altogether.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Problems&lt;/span&gt;&lt;br /&gt;I'm not sure some of the features are working properly yet. In the document details view, there's a 'Contents' box that I thought would extract the text contents of the document (PDF, OCR'd image etc) but it's blank even for a text document. Searches for text that occurs in that text document don't return the document. Then I noticed one of my PDFs did have text in the box. But only one. Here the text was all run on together with no spaces, but the search engine could find 'scenario' in the text containing 'modelscenariowas', but it would also match on run-on strings like 'wehavealsofoundthat'. This might be a problem but I know it is hard to extract words from PDF files sometimes.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;I also tried the OCR functionality on an image but that returned no text too - looking in the Django admin showed me the OCR Document queue - with an entry in it with an error message: "get_image_cache_name() takes exactly 3 non-keyword argument (2 given)". I can run tessaract from the command line successfully so something isn't quite right. I'll have a look at these issues before reporting them on Github (and checking to see if they are fixed in dev versions!)&lt;br /&gt;&lt;br /&gt;The other missing function I need as far as I can see is bulk downloads. From a search I'd like to click a few boxes and have a 'Download All' option, that gets everything in a ZIP (or tar.gz) file.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;More Features?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The documentation for some of the features are a bit thin. But clicking around and looking at the source code revealed that it has:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Themes: change the look with a config option, several themes supplied&lt;/li&gt;&lt;li&gt;Versioning: keep old docs around. Not sure we need this.&lt;/li&gt;&lt;li&gt;History: show all the changes to files and metadata&lt;/li&gt;&lt;li&gt;Multilingual: with English, Spanish, Portuguese and Russian.&lt;/li&gt;&lt;li&gt;Smart Links, Indexes: I don't know what these are and I couldn't make them do anything. I'm sure they are wonderful.&lt;/li&gt;&lt;li&gt;Signatures: documents can be signed by uploading a signature file. I don't know how this works.&lt;/li&gt;&lt;li&gt;Public Keys: In the setup, you can upload GPG public keys which you can easily get by querying a keyserver. I'm not sure what these keys then let you do.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;So overall I'm very impressed with it - it does a lot of what the Enterprisey, Java-based solutions try to give you but in a light python package. Just about the only Enterprise feature I've seen that's not here is true Filesystem integration via SMB or WebDAV, even though there's "Filesystem Integration" on the features list. I suppose we need to see what that means. I'm sure it's good!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-3400439599644943458?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/3400439599644943458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2012/01/document-management-system-review-mayan.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/3400439599644943458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/3400439599644943458'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2012/01/document-management-system-review-mayan.html' title='Document Management System review - Mayan EDMS'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-820302401430514132</id><published>2011-12-07T10:56:00.001Z</published><updated>2011-12-07T13:10:09.572Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='afripop'/><category scheme='http://www.blogger.com/atom/ns#' term='raster'/><category scheme='http://www.blogger.com/atom/ns#' term='rstats'/><category scheme='http://www.blogger.com/atom/ns#' term='R'/><title type='text'>Reading AfriPop data</title><content type='html'>The &lt;a href="http://www.afripop.org/"&gt;AfriPop&lt;/a&gt; project aims to produce high-resolution population density estimates for Africa. This could be very useful for some of our spatial epi projects. So I thought I'd have a look.&lt;br /&gt;&lt;br /&gt;Their methods for computing population are explained. I can't find any licensing or usage restrictions on the data, so I'll have to clear that up before doing anything serious with it. Let's download something and read it in.&lt;br /&gt;&lt;br /&gt;The download form asks for a few details, but there's no email check (or 'I have read your terms and conditions' checkbox) so fill in as honestly as your conscience requires. You'll get a zip file to download.&lt;br /&gt;&lt;br /&gt;When unzipped you'll have three files. For Benin these are called &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;apben10v3 &lt;/span&gt;&lt;span style="font-family: inherit;"&gt;with extensions &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;hdr&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;, &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;flt&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; and &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;prj.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;The &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;flt&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; file is the data, the &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;hdr&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; is header info, and &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;prj&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; is projection info. Use gdalinfo to get a summary - run it on the &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;flt&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; file:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$ gdalinfo apben10v3.flt&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Driver: EHdr/ESRI .hdr Labelled&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Files: apben10v3.flt&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;apben10v3.hdr&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;apben10v3.prj&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;[WGS84 coordinate system info here]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;Origin = (0.773989957311480,12.409206711176100)&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;Pixel Size = (0.000833300000000,-0.000833300000000)&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;Corner Coordinates:&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;Upper Left (0.7739900,12.4092067) (0d46'26.36"E,12d24'33.14"N)&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;Lower Left &amp;nbsp;(0.7739900,6.2252874) (0d46'26.36"E,6d13'31.03"N)&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;Upper Right (3.8522002,12.4092067)(3d51' 7.92"E,12d24'33.14"N)&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;Lower Right (3.8522002,6.2252874) (3d51' 7.92"E,6d13'31.03"N)&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;Center &amp;nbsp; &amp;nbsp; &amp;nbsp;(2.3130951,9.3172471) (2d18'47.14"E, &amp;nbsp;9d19' 2.09"N)&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;Band 1 Block=3694x1 Type=Byte, ColorInterp=Undefined&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; NoData Value=-9999&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;All pretty good. A standard ESRI file (except there's often nothing really standard about ESRI file formats). Let's read it and plot it using the raster package:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; bpop=raster("./apben10v3.flt")&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; image(bpop)&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-SeHDfZ2vulU/Tt9Zlyim_QI/AAAAAAAADbo/0yMsrhcOkS4/s1600/screen_04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="305" src="http://3.bp.blogspot.com/-SeHDfZ2vulU/Tt9Zlyim_QI/AAAAAAAADbo/0yMsrhcOkS4/s320/screen_04.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;Oh dear. Reading the docs about these files tells me that sometimes &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;gdal&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; just doesn't get it right. It said "Type=Byte", but the file is&amp;nbsp;109652696 bytes long, which is exactly 7421x3694x4 bytes. These are 4 byte values. In fact the AfriPop page says these files are &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;"ESRI Float"&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;. Luckily there's an easy way to persuade gdal these are floats. Open up the &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;hdr&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; file (NOT the &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;flt&lt;/span&gt;&lt;span style="font-family: inherit;"&gt; file. Don't open the &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;flt &lt;/span&gt;&lt;span style="font-family: inherit;"&gt;file!) in a text editor (&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;emacs, vi, notepad++, notepad&lt;/span&gt;&lt;span style="font-family: inherit;"&gt;) and add:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;pixeltype float&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;to the items. Then try again:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; bpop=raster("./apben10v3.flt")&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; plot(bpop,asp=1)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-4W2oCezZejg/Tt9boDL6fzI/AAAAAAAADcA/wQqFS76Jh7E/s1600/screen_08.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://3.bp.blogspot.com/-4W2oCezZejg/Tt9boDL6fzI/AAAAAAAADcA/wQqFS76Jh7E/s320/screen_08.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Looks good. Note we can get away with asp=1 since we're close to the equator. Or we can give it a projection:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;projection(bpop)="+proj=tmerc"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;plot(bpop)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and that's just as good. We can also zoom in using the very nifty &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;zoom&lt;/span&gt; function from the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;raster&lt;/span&gt; package:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-zKT_q2cZ5sA/Tt9bnhINGII/AAAAAAAADb0/BjUQ2vT_HFM/s1600/screen_07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-zKT_q2cZ5sA/Tt9bnhINGII/AAAAAAAADb0/BjUQ2vT_HFM/s1600/screen_07.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-UCbLl84SLm8/Tt9bnO7qyrI/AAAAAAAADbw/-VzLE48lgPM/s1600/screen_06.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="291" src="http://2.bp.blogspot.com/-UCbLl84SLm8/Tt9bnO7qyrI/AAAAAAAADbw/-VzLE48lgPM/s320/screen_06.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;and inspect the data further.&lt;br /&gt;&lt;br /&gt;Note that the raster package does a really good job of dealing with large rasters. When plotting these things it is sampling the raster file so not all of it is read into memory. I don't have a monitor capable of showing 7000x3000 pixels (yet) so raster just grabs enough to look good. But if you try and do anything with this size of raster, you will strangle your machine and it may die. Don't do this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;plot(log(bpop))&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;for example. Let's sample our raster down a bit for some more exploring. First I need to restart R after the last line crashed out. I'll sample down to something of the order of a few hundred pixels by a few hundred pixels by specifying the size as 500*500 - &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;sampleRegular&lt;/span&gt; will work out the exact resolution, keeping the aspect ratio. It's smart like that:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; library(raster)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; bpop=raster("apben10v3.flt")&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; projection(bpop)="+proj=tmerc"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; plot(bpop)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; bpop2 = sampleRegular(bpop, 500*500, asRaster=TRUE)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; bpop2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;class &amp;nbsp; &amp;nbsp; &amp;nbsp; : RasterLayer&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;dimensions &amp;nbsp;: 708, 352, 249216 &amp;nbsp;(nrow, ncol, ncell)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;resolution &amp;nbsp;: 0.008744915, 0.008734349 &amp;nbsp;(x, y)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;extent &amp;nbsp; &amp;nbsp; &amp;nbsp;: 0.77399, 3.8522, 6.225287, 12.40921 &amp;nbsp;(xmin, xmax, ymin, ymax)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;coord. ref. : +proj=tmerc +ellps=WGS84&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;values &amp;nbsp; &amp;nbsp; &amp;nbsp;: in memory&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;min value &amp;nbsp; : 0&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;max value &amp;nbsp; : 336.4539&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; plot(bpop2)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; plot(log(bpop2))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;[Perhaps we should use 'resample' here?] Now the log plot is doable:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-7rNFthdGZpM/Tt9gkvj6i7I/AAAAAAAADcI/XJcA4eqmQTc/s1600/screen_09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="302" src="http://4.bp.blogspot.com/-7rNFthdGZpM/Tt9gkvj6i7I/AAAAAAAADcI/XJcA4eqmQTc/s320/screen_09.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div&gt;BUT these values are now wrong. The units of the original data are persons per grid square. Our grid squares are now bigger then the original grid squares, so more people live in them. We can correct this by scaling by the ratio of the cell sizes:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; bpop2= bpop2 * prod(res(bpop2))/prod(res(bpop))&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; plot(log(bpop2))&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;and now we get a more correct map:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-e7zTBZCunas/Tt9i-l8O-qI/AAAAAAAADcQ/GPgOQz6ojXM/s1600/screen_10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="304" src="http://1.bp.blogspot.com/-e7zTBZCunas/Tt9i-l8O-qI/AAAAAAAADcQ/GPgOQz6ojXM/s320/screen_10.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;I'm not sure how 'correct' or optimal this is of downsampling population density grids is - for example the total population (sum of grid cells) will be slightly different. Perhaps it is better to rescale the sampled grid to keep the total population the same? Thoughts and musings in comments for discussion please!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-820302401430514132?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/820302401430514132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2011/12/reading-afripop-data.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/820302401430514132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/820302401430514132'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2011/12/reading-afripop-data.html' title='Reading AfriPop data'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-SeHDfZ2vulU/Tt9Zlyim_QI/AAAAAAAADbo/0yMsrhcOkS4/s72-c/screen_04.png' height='72' width='72'/><thr:total>0</thr:total><georss:featurename>University of Lancaster, Physics Ave, Lancashire LA1, UK</georss:featurename><georss:point>54.01140032647095 -2.783489227294922</georss:point><georss:box>54.00207032647095 -2.8032302272949217 54.02073032647095 -2.763748227294922</georss:box></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-7201377561947798623</id><published>2011-10-18T14:24:00.000+01:00</published><updated>2011-10-18T14:24:50.425+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='optimisation'/><category scheme='http://www.blogger.com/atom/ns#' term='optim'/><category scheme='http://www.blogger.com/atom/ns#' term='R'/><title type='text'>optifix - optim with fixed values</title><content type='html'>So you've written your objective function, fr, and want to optimise it over the two parameters. Fire &lt;span style="font-family: inherit;"&gt;up optim and away you go:&lt;/span&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; fr &amp;lt;- function(x) { &amp;nbsp; ## Rosenbrock Banana function&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;x1 &amp;lt;- x[1]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;x2 &amp;lt;- x[2]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;100 * (x2 - x1 * x1)^2 + (1 - x1)^2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; optim(c(-1.2,1), fr)[c("par","value")]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$par&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;[1] 1.000260 1.000506&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$value&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;[1] 8.825241e-08&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Great. But sometimes you only want to optimise over some of your parameters, keeping the others fixed. Let's consider optimising the banana function for x2=0.3&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; &amp;nbsp;fr &amp;lt;- function(x) { &amp;nbsp; ## Rosenbrock Banana function&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;x1 &amp;lt;- x[1]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;x2 &amp;lt;- 0.3&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;100 * (x2 - x1 * x1)^2 + (1 - x1)^2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; optim(-1.2, fr,method="BFGS")[c("par","value")]&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;$par&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;[1] -0.5344572&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;$value&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;[1] 2.375167&lt;/div&gt;&lt;div style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;(R gripes about doing 1-d optimisation with Nelder-Mead, so I switch to BFGS)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;Okay, but we had to write a new objective function with 0.3 coded into it. Now repeat for a number of values. That's a pain.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;The conventional solution would be to make x2 an extra parameter of fr:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; &amp;nbsp;fr &amp;lt;- function(x,x2) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;x1 &amp;lt;- x[1]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;100 * (x2 - x1 * x1)^2 + (1 - x1)^2&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: inherit;"&gt;and call optim with this passed in the dot-dot-dots:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; optim(-1.2,fr,method="BFGS",x2=0.3)[c("par","value")]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$par&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;[1] -0.5344572&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$value&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;[1] 2.375167&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;Okay great. But suppose now we want to fix x1 and optimise over x2. You're going to need another objective function. Suppose your function has twelve parameters... This is becoming a pain.&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;You need optifix. Go back to the original 2 parameter banana function, and do:&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;gt; optifix(c(-1.2,0.3),c(FALSE,TRUE), fr,method="BFGS")&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$par&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;[1] -0.5344572&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$value&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;[1] 2.375167&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$counts&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;function gradient&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 27 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;9&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$convergence&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;[1] 0&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$message&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;NULL&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$fullpars&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;[1] -0.5344572 &amp;nbsp;0.3000000&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$fixed&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;[1] FALSE &amp;nbsp;TRUE&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;Here the function call is almost the same as the 2-parameter optimisation, except with a second argument that tells which parameters to fix - and they are fixed at the values given in the first argument. The values in that argument for non-fixed parameters are starting values for the optimiser as usual.&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;The output is the output from the reduced optimiser. In this case it is one parameter value, but there's also a couple of other components, $fullpars and $fixed, to tell you what the overall parameter values were and which ones were fixed.&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;Optifix takes your objective function and your specification of what's fixed to create a wrapper round your function that only takes the variable parameters. The wrapper inserts the fixed values in the right place and calls your original function. It then calls optim with a reduced vector of starting parameters and the wrapped objective function. Hence the wrapped function is only every called with the variable parameters, and the original function is called with the variables and the fixed values.&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;Optifix should work on optim calls that use a supplied gradient function - it wraps that as well to produce a reduced-dimensional gradient function &amp;nbsp;for optim to work on.&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;Code? Oh you want the code? Okay. I've put a file in a &lt;a href="http://www.maths.lancs.ac.uk/~rowlings/R/Optifix/"&gt;folder on a server&lt;/a&gt;&amp;nbsp;for you to download. Its very beta, needs testing and probably should find a package for its home. All things to do.&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-7201377561947798623?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/7201377561947798623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2011/10/optifix-optim-with-fixed-values.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/7201377561947798623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/7201377561947798623'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2011/10/optifix-optim-with-fixed-values.html' title='optifix - optim with fixed values'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>0</thr:total><georss:featurename>Lancaster University, County Ave, Lancaster, Lancashire LA1 4, UK</georss:featurename><georss:point>54.012295559310274 -2.784433364868164</georss:point><georss:box>54.01112905931028 -2.786900864868164 54.01346205931027 -2.781965864868164</georss:box></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-1209001977035332873</id><published>2011-07-26T18:41:00.000+01:00</published><updated>2011-07-26T18:41:43.377+01:00</updated><title type='text'>Mind The Gap</title><content type='html'>Every so often Prof D watches Hans Rosling's TED talk or TV show and thinks to himself, "Barry could do that". And so the other week he said to me, "Could we do graphics like that in R?". Because he only really understands R, and Ben had recently cooked up some interactive R plots using tk widgets. Here's the kind of thing that www.gapminder.org can serve up with their Adobe Flash widget:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Ub3EUZ1m7zI/Ti75HnoaiyI/AAAAAAAADa4/h-cruZhwQLk/s1600/screen_28.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="152" width="200" src="http://1.bp.blogspot.com/-Ub3EUZ1m7zI/Ti75HnoaiyI/AAAAAAAADa4/h-cruZhwQLk/s200/screen_28.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Well obviously you could do this in R. Or something like it. But why? On CRAN there's the googleVis package which pumps your data into google's visualisation library and you can do just this kind of chart. Doing it in vanilla R would be painful, and the whole chart would have to be redrawn every time. It's not really designed for it.&lt;br /&gt;&lt;br /&gt;So I looked for another solution. Javascript in the browser is pretty swift now, and there's visualisation packages. I recently heard of D3, and thought I'd give it a go. Pretty soon I'd knocked out a space-time visualisation plot, and then spent another day or so mimicking gapminder's charts.&lt;br /&gt;&lt;br /&gt;Here then is preview number 1.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-pUIFTyCuOeM/Ti750-cFcWI/AAAAAAAADbA/ZhZfPBexmr8/s1600/screen_27.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="200" width="195" src="http://1.bp.blogspot.com/-pUIFTyCuOeM/Ti750-cFcWI/AAAAAAAADbA/ZhZfPBexmr8/s200/screen_27.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This is created by a pretty tiny (but at the moment, untidy) chunk of javascript plus some R to write out the data in JSON format. The heavy lifting is done by D3, which has nice data-driven ways of controlling the visualisation. The user can click on the back/fwd links and the data advances a year, and it transitions smoothly between the data points. The colouring is by geographic region, and the circle size is by one of the variables. It's easy to switch the axis or size variables from the Firefox javascript console, and will be even easier when a proper GUI is wired up.&lt;br /&gt;&lt;br /&gt;I'll never have the time to make it as polished as Gapminder or Googlevis, but here is the start of an open-source version of these charts.&lt;br /&gt;&lt;br /&gt;Ooh did I say 'open-source'? Anyone want the code?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-1209001977035332873?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/1209001977035332873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2011/07/mind-gap.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/1209001977035332873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/1209001977035332873'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2011/07/mind-gap.html' title='Mind The Gap'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-Ub3EUZ1m7zI/Ti75HnoaiyI/AAAAAAAADa4/h-cruZhwQLk/s72-c/screen_28.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-78320511425088388</id><published>2011-07-25T16:45:00.000+01:00</published><updated>2011-07-25T16:45:15.113+01:00</updated><title type='text'>A Middle-aged Geek's Guide To The Arkestra : First Movement</title><content type='html'>&lt;h1&gt;Intro&lt;/h1&gt;&lt;br /&gt;"Arkestra is an intelligent semantic Django-based CMS for organisations and institutions". Which is seemingly exactly what we want for our department web pages.&lt;br /&gt;&lt;br /&gt;The showcase site, Cardiff University's School Of Medicine is rather impressive.&lt;br /&gt;&lt;br /&gt;Arkestra is built on Django-CMS, and is open source. So I decided to play around with it. This blog entry will relate my progress. All this work is being done on an Ubuntu 10.04 box.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Installation Packages&lt;/h1&gt;&lt;br /&gt;First, create a new virtualenv and get into it. Install the required packages using pip, and the cutting-edge stuff from source. Some of these packages are necessary for django-cms and Arkestra, and some are just necessary for the Arkestra example. I'm not sure which is which, so I grab everything.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;virtualenv --no-site-packages Test&lt;br /&gt;. Test/bin/activate&lt;br /&gt;cd Test&lt;br /&gt;pip install PIL&lt;br /&gt;pip install django&lt;br /&gt;pip install BeautifulSoup&lt;br /&gt;pip install django-typogrify&lt;br /&gt;pip install pyquery&lt;br /&gt;pip install -e git+http://github.com/stefanfoulis/django-widgetry#egg=django-widgetry&lt;br /&gt;pip install django-filer # gets easy-thumbnails, django-mptt&lt;br /&gt;&lt;br /&gt;pip uninstall -y django-mptt&lt;br /&gt;&lt;br /&gt;pip install django-cms&lt;br /&gt;pip install django-polymorphic&lt;br /&gt;pip install django-appmedia&lt;br /&gt;pip install -e hg+https://bitbucket.org/spookylukey/semanticeditor#egg=semanticeditor&lt;br /&gt;pip install -e git+git://github.com/ojii/django-classy-tags.git#egg=classytags&lt;br /&gt;git clone git://github.com/evildmp/Arkestra.git src/arkestra&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I tried to do all this with a pip requirements file but failed - the problem seems to be that django-filer will pull in django-mptt, but django-cms can't work with it.&lt;br /&gt;&lt;br /&gt;For reference, here's the output of pip freeze telling you what versions of what I have this working with:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;BeautifulSoup==3.2.0&lt;br /&gt;Django==1.3&lt;br /&gt;PIL==1.1.7&lt;br /&gt;South==0.7.3&lt;br /&gt;distribute==0.6.10&lt;br /&gt;django-appmedia==1.0.1&lt;br /&gt;-e git://github.com/ojii/django-classy-tags.git@8ad613b3bc0310ba9afb206136cfadbdfa8e6b01#egg=django_classy_tags-dev&lt;br /&gt;django-cms==2.1.3&lt;br /&gt;django-filer==0.8.2&lt;br /&gt;django-polymorphic==0.2&lt;br /&gt;django-typogrify==1.2.2&lt;br /&gt;-e git+http://github.com/stefanfoulis/django-widgetry@57bbf529509e805a74b3e8f36e6938bef591e505#egg=django_widgetry-dev&lt;br /&gt;easy-thumbnails==1.0-alpha-17&lt;br /&gt;lxml==2.3&lt;br /&gt;parti-all==0.0.7.22&lt;br /&gt;pyquery==1.0&lt;br /&gt;-e hg+https://bitbucket.org/spookylukey/semanticeditor@3a40b4766f32262be2cfe131cf20a19703bfc339#egg=semanticeditor-dev&lt;br /&gt;smartypants==1.6.0.3&lt;br /&gt;textile==2.1.5&lt;br /&gt;wsgiref==0.1.2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h1&gt;Config and Run&lt;/h1&gt;&lt;br /&gt;Head into the arkestra directory that git got for you, and try running the server:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;cd src/arkestra/example&lt;br /&gt;export PYTHONPATH=.. # to find the arkestra modules&lt;br /&gt;python manage.py runserver&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It should run, but you will fail to log in because there's no user accounts. Also, the example.db file isn't compatible with the version of django-cms and possibly other packages. So you can move it and run syncdb again:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;mv example.db example.db.orig&lt;br /&gt;python manage.py syncdb   # create db tables, create admin user&lt;br /&gt;python manage.py runserver&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now you can log in and create Page objects, and view them on the site. Don't forget to tick the published and navigation boxes if needed. To add content, you add a Text/Layout plugin and put the content in there.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Some 404s&lt;/h1&gt;&lt;br /&gt;Watch your log output. At some point you may see some 404s caused by some magic autocomplete jQuery javascripts not being found. Try this from the example/ folder:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;cd media&lt;br /&gt;ln -s ../../../arkestra/arkestra_utilities/static/ javascript&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That should stop the 404s.&lt;br /&gt;&lt;br /&gt;&lt;h1&gt;Loading the Demo Site&lt;/h1&gt;&lt;br /&gt;Note that there's a JSON-encoded version of the database supplied in example.json. In theory all you need to do is:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;python manage.py loaddata example.json&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;over an empty database and get it all going. But there's those pesky database differences to deal with. I did go through it editing the changes and got it mostly working, but you'll probably want to build your Arkestra site from scratch. Which is what the second movement in this piece will probably be about.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-78320511425088388?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/78320511425088388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2011/07/middle-aged-geeks-guide-to-arkestra.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/78320511425088388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/78320511425088388'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2011/07/middle-aged-geeks-guide-to-arkestra.html' title='A Middle-aged Geek&apos;s Guide To The Arkestra : First Movement'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-3617682440483348519</id><published>2011-06-26T16:44:00.000+01:00</published><updated>2011-06-26T16:44:01.008+01:00</updated><title type='text'>Thoughts on OSGIS 2011</title><content type='html'>OSGIS is the UK Open-Source GIS conference. This is the third year it has run, and the first time I've made it there. Nottingham University has been its home every time, mostly due to the presence of the Centre for Geospatial Science on campus, and the enthusiasm of Suchith Anand and Jeremy Morley, who seem to be running on free energy all the time.&lt;br /&gt;&lt;br /&gt;The meeting follows the standard template for scientific and technical conferences - there's some workshops, some invited keynote papers, and some general presentations. There's no poster session, and no novel ideas like lightning talks or group discussions - except perhaps in the Open Gov Workshop, but I wasn't there. Not that group discussions don't happen elsewhere, but only over coffee, great lunches, and beers.&lt;br /&gt;&lt;br /&gt;Links to the agenda and presentations are all on the &lt;a href="http://cgs.nottingham.ac.uk/~osgis11/os_committee_scientific.html"&gt;Web Site&lt;/a&gt; so I won't go into details here. The talks were also webcasted live and recorded, and should be available soon.&lt;br /&gt;&lt;br /&gt;The workshop sessions on &lt;a href="http://www.qgis.org/"&gt;QGIS&lt;/a&gt; were run by &lt;a href="http://www.faunalia.co.uk/"&gt;Faunalia&lt;/a&gt; who let us take away their 8Gb memory sticks packed with a bootable Linux. Very handy. There were also lots of OSGEO Live DVD discs kicking around too, used for the workshop on Ordnance Survey data. Clearly open-sourcers are finding more ways of working in labs full of Windows boxes. I once ran a workshop where we used Virtual Box and an OSGEO Live DVD image to hide the horrors of Windows XP.&lt;br /&gt;&lt;br /&gt;So what was hot or not at the conference? Here's my impressions: &lt;br /&gt;&lt;br /&gt;On the desktop:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Hot hot hot: Lots of mentions of QGIS.&lt;/li&gt;&lt;li&gt;Also Hot: gvSIG (a day of workshops), GRASS here and there, OpenJump poked its nose in.&lt;/li&gt;&lt;li&gt;Not Hot: No-show GIS packages: uDig, SAGA.&lt;/li&gt;&lt;li&gt;Hot: OpenLayers and GeoExt.&lt;/li&gt;&lt;li&gt;Not hot: The Cloud. Its not the answer to everything.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;On the server:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Hot: PostGIS continues its dominance.&lt;/li&gt;&lt;li&gt;Not Hot: Mentions of Oracle Spatial were usually accompanied by apologies. Usual excuse was 'we had the license anyway'.&lt;/li&gt;&lt;li&gt;Not Hot: No sign of NoSQL DB technology - where's the MongoDB Spatial people?&lt;/li&gt;&lt;li&gt;Hot: WFS, WMS, WCS and even WPS becoming almost commonplace.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;In the hands of the programmer:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Warm: Only one statistics package mentioned - &lt;a href="http://www.r-project.org/"&gt;R&lt;/a&gt; of course - although the &lt;a href="http://orange.biolab.si/"&gt;Orange Toolbox&lt;/a&gt; gets a look-in.&lt;/li&gt;&lt;li&gt;Hot Programming languages: Python, Java, JavaScript, C, R, SQL. I think I saw some Perl.&lt;/li&gt;&lt;li&gt;Cold Programming languages: C#, Ruby, Visual Basic/C.&lt;/li&gt;&lt;li&gt;Warm and fuzzy feelings from: Drupal, Django, ExtJS.&lt;/li&gt;&lt;li&gt;Cold and dead to us: Sharepoint. IIS. .net. Silverlight. Flash.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Hardware:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Hot: Android phones - nearly everywhere!&lt;/li&gt;&lt;li&gt;Cold: iPhones - hard to spot. Either nobody had them or were ashamed to show them.&lt;/li&gt;&lt;li&gt;Cold: Tablets. Think I saw one Samsung Galaxy Tab but nobody was showing off iPads. Or iPhone Maxis as they are sometimes known.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;No great surprises there.&lt;br /&gt;&lt;br /&gt;A few people were tweeting useful things during the conference, and so I should apologise to Jeremy Morley for not saying hello IRL and only communicating via twitter. I will try and submit a paper on doing GIS in R for next year. It will be more than 140 characters.&lt;br /&gt;&lt;br /&gt;Also great to finally meet Suchith - the force behind lots of interesting things going on at Nottingham.&lt;br /&gt;&lt;br /&gt;Tyler Mitchell rolled in from across the pond and did well against the jet lag to present a keynote speech and network like crazy for two days. OSGEO are very busy both globally and locally.&lt;br /&gt;&lt;br /&gt;In all the conference did feel like a mini &lt;a href="http://2011.foss4g.org/"&gt;FOSS4G&lt;/a&gt;, but with a local feel - but not a restriction that cut down the quality of the talks or the participants or the coffee chat or the lunch discussions or the beer conversations. See you next year!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-3617682440483348519?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/3617682440483348519/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2011/06/thoughts-on-osgis-2011.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/3617682440483348519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/3617682440483348519'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2011/06/thoughts-on-osgis-2011.html' title='Thoughts on OSGIS 2011'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-1221242154909741309</id><published>2011-06-01T18:27:00.001+01:00</published><updated>2011-06-01T18:31:03.970+01:00</updated><title type='text'>Reading Layers from a Qgis Project File.</title><content type='html'>Some notes on reading individual layers out of a Qgis Project file. This should end up in a 'import layers from a project file' plugin.&lt;br /&gt;&lt;br /&gt;1. get the xml into some text:&lt;br /&gt;&lt;br /&gt;xml = file("project.qgs").read()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. make a blank QDomDocument and set the content:&lt;br /&gt;&lt;br /&gt;d = PyQt4.QtXml.QDomDocument()&lt;br /&gt;d.setContent(xml)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3. Now find the maplayers:&lt;br /&gt;&lt;br /&gt;maps = d.elementsByTagName("maplayer")&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4. How many?&lt;br /&gt;&lt;br /&gt;maps.length()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5. Now read the fourth layer (0-index) into running Qgis:&lt;br /&gt;&lt;br /&gt;QgsProject.instance().read(maps.item(3))&lt;br /&gt;&lt;br /&gt;Wrap this in a nice gui that tells the user what the map layers are, lets them check boxes, import the layers, marks the current project as dirty. Jobzagoodun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-1221242154909741309?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/1221242154909741309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2011/06/reading-layers-from-qgis-project-file.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/1221242154909741309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/1221242154909741309'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2011/06/reading-layers-from-qgis-project-file.html' title='Reading Layers from a Qgis Project File.'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-4334999990688159720</id><published>2011-04-12T16:24:00.000+01:00</published><updated>2011-04-12T16:24:37.204+01:00</updated><title type='text'>OpenLayers 2.10 Beginners Guide Book Review</title><content type='html'>A man is out driving in unfamiliar countryside. Inevitably he gets lost, so he pulls over to ask a local farmer for directions. "Oh no", says the farmer, "I wouldn't start from here".&lt;br /&gt;&lt;br /&gt;It's an old joke (and not a very funny one), but one that springs to mind when people ask certain questions on mailing lists. Someone with very little computing experience will appear on the OpenLayers mailing list (or IRC) and say "How do I put a map on my web page?". My answer would be "Well, I wouldn't start from here".&lt;br /&gt;&lt;br /&gt;First, I'd say, learn programming using a nice friendly language - python perhaps. Then get a basic understanding of how client-server systems work, and how the web is implemented via the HTTP protocol. Then follow the 20-something year evolution of HTML - from its humble beginnings through to its happy marriage with CSS and their successful menage-a-trois together with Javascript. Ignore its affair with Java - that was a moment of crazed passion, and Java is now out of the HTML/browser party and busily running the "enterprisey" affairs of corporations. &lt;br /&gt;&lt;br /&gt;With a knowledge of HTTP, HTML, CSS and Javascript, you are ready to put maps on your web pages. And I'd choose OpenLayers to do it.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-ziCdlFAjiFE/TaRm-5aqxMI/AAAAAAAADaI/mwHU_JdzJQ8/s1600/4125OS_OpenLayers%2B2.10%2BBeginner%2527s%2BGuidecov_0.jpg.png" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"&gt;&lt;img border="0" height="152" width="125" src="http://4.bp.blogspot.com/-ziCdlFAjiFE/TaRm-5aqxMI/AAAAAAAADaI/mwHU_JdzJQ8/s200/4125OS_OpenLayers%2B2.10%2BBeginner%2527s%2BGuidecov_0.jpg.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://vasir.net/"&gt;Erik Hazzard&lt;/a&gt;'s book, &lt;a href="http://www.packtpub.com/openlayers-2-1-javascript-web-mapping-library-beginners-guide/book"&gt;"OpenLayers 2.10 Beginner's Guide"&lt;/a&gt;, published by Packt Publishing, is designed to get people with very little computing experience all the way through that process to the point of quite complex map production. He has to cover everything, and does so pretty well (although I'm not sure about his exposition on Object-oriented programming). Although he doesn't teach programming, he encourages users to cut-and-paste code and then experiment. &lt;br /&gt;&lt;br /&gt;The sample chapter will show you how the book works - simple explanations, example code, and open-ended questions and mini-assignments. The Firebug debugger is introduced early on in the book, and I think this is a great idea. Firebug didn't take long to repay me the time I took to grok what it could do. Erik sprinkles it liberally on the examples, since interactive inspection of a program is a great way to really see what it's doing.&lt;br /&gt;&lt;br /&gt;Inevitably with a book like this, large chunks of its 372 pages will be similar to dumps of the API documentation from the OpenLayers web site. Erik has fleshed out a lot of the terse API information to include fuller examples to make the book more than just that - I can imagine hardcopies of this book with a multitude of flapping yellow sticky notes for their owners to get rapid access to useful pages. Packt Publishing will sell you the PDF version for those who like to search, and the paper version for those who like to stick.&lt;br /&gt;&lt;br /&gt;By the end of the book you should have the knowledge to understand how the sample Flickr map application developed in the last chapter works, and you'll also have a handy reference to a large percentage of the features of OpenLayers. The one glaring omission is that there is no mention of the OpenLayers "Popup" class, typically used for "info-balloons" when clicking on map features. But if you can work through the book, then it should be no problem to work out how to use them from the API documentation. &lt;br /&gt;&lt;br /&gt;There seem to be very few books on OpenLayers on the market at the moment, so if you want to make maps and would like a high-quality step-by-step guide to it, then this is the book for you. &lt;br /&gt;&lt;br /&gt;Note that OpenLayers, like all web technologies is evolving fast, so watch out for updates and get the latest version of the book. A recent OpenLayers hackfest concentrated on developing functionality for mobile devices, so expect to see more OpenLayers applications for your smartphone soon. With Google insisting on presenting advertising along with their map images, it might be a good time to switch to OpenStreetMap for your map background and OpenLayers for your mapping client.&lt;br /&gt;&lt;br /&gt;Barry&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note: I was provided with a PDF copy of the book for review, and I have no connection with the author or publisher.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-4334999990688159720?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/4334999990688159720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2011/04/openlayers-210-beginners-guide-book.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/4334999990688159720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/4334999990688159720'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2011/04/openlayers-210-beginners-guide-book.html' title='OpenLayers 2.10 Beginners Guide Book Review'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-ziCdlFAjiFE/TaRm-5aqxMI/AAAAAAAADaI/mwHU_JdzJQ8/s72-c/4125OS_OpenLayers%2B2.10%2BBeginner%2527s%2BGuidecov_0.jpg.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-4108027007500332357</id><published>2011-03-25T12:28:00.000Z</published><updated>2011-03-25T12:28:07.930Z</updated><title type='text'>Tolerance and bridges</title><content type='html'>So I'm modelling the H1N1 Swine Flu outbreak in Glasgow. One of the questions is how different regions (specifically 'datazones') within the study area interact with each other. You'd expect zones next to each other to interact with each other more than those on opposite sides of the city, for example. So our first idea is to use the distance between centroids as an explanatory variable and a distance-decay parameterisation for the effect. That works quite nicely.&lt;br /&gt;&lt;br /&gt;But the real world isn't quite like that. Glasgow has a river running through it, splitting our study region into north and south parts. I wanted a new distance metric to reflect this partition.&lt;br /&gt;&lt;br /&gt;So I came up with this idea - that the distance between two datazones is the minimum distance between the centroids of the graph formed by adjacent datazones.&lt;br /&gt;&lt;br /&gt;First problem of that is computing the adjacencies between datazones. In R, I can just use poly2nb from the spdep package and get that. But I found that the graph created wasn't connected over the study region. Further investigation showed that polygons that clearly looked adjacent weren't being considered as adjacent. Here's a screenshot that shows three regions that look adjacent:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-pUMKBi8ZoaE/TYyHJ20etUI/AAAAAAAADZw/-fszYv2CNPw/s1600/regions1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="266" width="320" src="http://4.bp.blogspot.com/-pUMKBi8ZoaE/TYyHJ20etUI/AAAAAAAADZw/-fszYv2CNPw/s320/regions1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Now why wasn't poly2nb saying they were connected? I zoomed in for the answer:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-0PuIdF7EMC4/TYyHbFmIBsI/AAAAAAAADZ4/hDkUL_cgBVA/s1600/regions2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="266" width="320" src="http://3.bp.blogspot.com/-0PuIdF7EMC4/TYyHbFmIBsI/AAAAAAAADZ4/hDkUL_cgBVA/s320/regions2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Check the scale bar. These polygons are about a hundredth of a millimetre apart. That's a very tiny no-man's land. More like a "no-fly zone".&lt;br /&gt;&lt;br /&gt;I figured I needed some kind of buffer on the polygons, and started looking into the rgeos package, recently released onto CRAN. It'll do that, and all sorts of things, but then when I tried working out adjacencies using its gIntersects function I discovered it worked to those tolerances already. By some magic the apparently adjacent regions were adjacent again.&lt;br /&gt;&lt;br /&gt;However the graph was still not fully connected - it was composed of two subgraphs - the river is wide enough, and runs fully from east to west, that no fuzzy tolerances could really overlap the polygons. And that would probably be the wrong thing to do anyway. &lt;br /&gt;&lt;br /&gt;So I loaded the regions into Quantum GIS and then loaded some Google Maps as underlays using the marvellous Google Maps plugin. I created a new vector layer of lines and started adding extra connections where bridges cross the Clyde:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-utTqJvE_lc4/TYyIpIVM3LI/AAAAAAAADaA/D-P1VMslZP8/s1600/bridges.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="266" width="320" src="http://3.bp.blogspot.com/-utTqJvE_lc4/TYyIpIVM3LI/AAAAAAAADaA/D-P1VMslZP8/s320/bridges.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;These lines, shown in red above, were saved as a shapefile, then loaded into R and their start and endpoints overlaid on the datazones. That gave me some extra edges to add to the adjacency graph, all the graph stuff being handled by R's igraph package (including the distance-weighted minimum distance algorithm along adjacent datazones).&lt;br /&gt;&lt;br /&gt;So now I have a completely-connected graph of datazones, which I can convert into a full distance matrix that reflects the geometry of the study region. The university's High-End Cluster is currently churning out the number for the model fit, and the results will hopefully be published in a journal sometime... &lt;br /&gt;&lt;br /&gt;Thanks to: R, Quantum GIS, Google Maps plugin authors Ivan Mincik and Nungyao Lin, R package developers for sp, spdep, rgeos, igraph.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-4108027007500332357?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/4108027007500332357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2011/03/tolerance-and-bridges.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/4108027007500332357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/4108027007500332357'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2011/03/tolerance-and-bridges.html' title='Tolerance and bridges'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-pUMKBi8ZoaE/TYyHJ20etUI/AAAAAAAADZw/-fszYv2CNPw/s72-c/regions1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-2122534933910376781</id><published>2010-12-22T19:43:00.001Z</published><updated>2010-12-22T20:45:16.637Z</updated><title type='text'>Mapping The Kendal Mint Quake</title><content type='html'>About 11pm last night my wall of photographs rattled. It's not unusual, it seems to happen whenever anyone is having a washing machine delivered and a truck crawls past my house. But a minute after that I was on the computer and someone local was tweeting about her house shaking. Earthquake? A few twitter searches revealed twitterers in Cumbria and North Lancashire had indeed experienced a small earthquake.&lt;br /&gt;&lt;br /&gt;So I did what all statisticians would do - go looking for data. Tweets can be geo-coded, but getting reliable info might be hard. I checked the USGS earthquake site, but it's not real-time. But then I found the &lt;a href="http://www.earthquakes.bgs.ac.uk/"&gt;British Geological Society&lt;/a&gt; earthquakes page, with true real-time reports from a bunch of sensors around the country. Under the Monitoring menu there's the Real-Time Data option.&lt;br /&gt;&lt;br /&gt;Here you can choose the station and a day and get a seismogram. Here's what the one in Keswick (KESW) was showing:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/TRJJr2HeaCI/AAAAAAAADYs/lRk3QuuiViI/s1600/screenshot_003.png" imageanchor="1" &gt;&lt;img border="0" height="292" width="314" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/TRJJr2HeaCI/AAAAAAAADYs/lRk3QuuiViI/s320/screenshot_003.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;BIG spike. It went off the scale of the plot. I looked at a few other plots and discovered most of them had recorded it too. And I noticed the quake had hit at slightly different times. Maybe I could use that information to work out the location of the quake.&lt;br /&gt;&lt;br /&gt;At this point the BGS site was getting slow as worried Cumbrians checked to see if it was an earthquake or if the local nuclear power station had exploded. Anyway, it was bedtime, so I left it to the morning, as something to do in my lunch hour. &lt;br /&gt;&lt;br /&gt;I couldn't find a way to get the raw data, so I decided I'd get what I could from the images. A quick script pulled all the GIF images from the sites, except for a couple that seemed to be off-line. Another script pulled all the station information book HTML files and from there I got the locations.&lt;br /&gt;&lt;br /&gt;I then stepped through each of the 24 images, identifying the point near 11pm where the tremors started, and entered the data. &lt;br /&gt;&lt;br /&gt;Now I had the location and time of the points where the quake had been sensed. This was all converted to OSGB coordinates using rgdal in R.&lt;br /&gt;&lt;br /&gt;I didn't have a zero-time for the quake or a location. A quick plot did show the quake had to be somewhere in Cumbria.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_7N-9AwC5AHs/TRJLRLv_bwI/AAAAAAAADY0/tK3xbRKiFow/s1600/screenshot_001.png" imageanchor="1" &gt;&lt;img border="0" height="320" width="207" src="http://4.bp.blogspot.com/_7N-9AwC5AHs/TRJLRLv_bwI/AAAAAAAADY0/tK3xbRKiFow/s320/screenshot_001.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I don't know how professional seismologists work out earthquake epicentres, so I came up with something quick and dirty.&lt;br /&gt;&lt;br /&gt;Assume the velocity of the quake waves are constant across the UK. Then if the quake was at location (x,y) then a plot of distance against time should be a straight line, with all the points on it. Some quick experiments showed I could fit a straight line then use the sum of the residuals squared as a measure to be minimised over (x,y). A few lines of code later and I had a coordinate!&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&gt; fit$par&lt;br /&gt;[1] 307499.9 506035.7&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;By now the quake had hit the news and the USGS web site was showing it:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_7N-9AwC5AHs/TRJMfYPebgI/AAAAAAAADY8/2uexmlaQHHg/s1600/neic_c0000sdh_2.gif" imageanchor="1" &gt;&lt;img border="0" height="320" width="285" src="http://4.bp.blogspot.com/_7N-9AwC5AHs/TRJMfYPebgI/AAAAAAAADY8/2uexmlaQHHg/s320/neic_c0000sdh_2.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;How did that compare to my point? I converted it to OSGB coordinates:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&gt; coordinates(usgsos)&lt;br /&gt;     coords.x1 coords.x2&lt;br /&gt;[1,]  328994.6  500054.7&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;20km further east, and 6km south. Not bad considering I had to eyeball the time from the seismograms and various other assumptions. I don't know what kind of uncertainty the USGS put on their predictions, and I can't put an uncertainty on my location either since there's not a proper statistical model behind this. I can give you the data if you have a better idea - or you can scrape it again from the web site! Here's a comparison of the epicentre predictions on a map:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_7N-9AwC5AHs/TRJTeAUfELI/AAAAAAAADZM/N716MthWjlk/s1600/screenshot_005.png" imageanchor="1" &gt;&lt;img border="0" height="288" width="320" src="http://4.bp.blogspot.com/_7N-9AwC5AHs/TRJTeAUfELI/AAAAAAAADZM/N716MthWjlk/s320/screenshot_005.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Here's what the distance/time plot looks like for my predicted epicentre:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_7N-9AwC5AHs/TRJOQ4Ux0OI/AAAAAAAADZE/_E3XYz47ILE/s1600/screenshot_002.png" imageanchor="1" &gt;&lt;img border="0" height="200" width="320" src="http://1.bp.blogspot.com/_7N-9AwC5AHs/TRJOQ4Ux0OI/AAAAAAAADZE/_E3XYz47ILE/s320/screenshot_002.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;And from the slope of this we can get the speed of travel of the quake waves - about 7,500 km/s - which is about what a quick google search on earthquakes tells me.&lt;br /&gt;&lt;br /&gt;Footnote: I think on the bike home tonight I worked out a way to do this statistically. Suppose the earthquake is at (x,y), at time t0, and the waves move with speed v. Then suppose the time of arrival of the quake at a point at distance d is Normally distributed with mean time t0+d/v and variance k(d;theta), where k() is some increasing function of d. This allows us to consider the increasing noise in the system for points further away. Fit the whole thing by maximum likelihood and we get estimates (with errors) for location, time of origin, and wave speed. Something for next lunchtime...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-2122534933910376781?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/2122534933910376781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2010/12/mapping-kendal-mint-quake.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/2122534933910376781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/2122534933910376781'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2010/12/mapping-kendal-mint-quake.html' title='Mapping The Kendal Mint Quake'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_7N-9AwC5AHs/TRJJr2HeaCI/AAAAAAAADYs/lRk3QuuiViI/s72-c/screenshot_003.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-4345613452662713049</id><published>2010-12-21T16:03:00.000Z</published><updated>2010-12-21T16:03:40.202Z</updated><title type='text'>Speeding up some R Code</title><content type='html'>Part of my job involves looking at code written by research students and trying to make it do other things. Often a student is focused on their application area or particular dataset, and so the code and data are inextricably linked. Add another observation to the dataset and you'll find yourself having to change 3467 to 3468 in a dozen places. And maybe find some 6934s and change them to 6936s. The other problem is that research students are mostly new to serious programming, and so still need to develop both intuition and formal skills.&lt;br /&gt;&lt;br /&gt;Today I've been working on such code for predicting epidemic outcomes. It was taking 14 seconds to run, which isn't too bad (especially considering some other work I'm doing takes 6 hours using OpenMP on an 8-core machine), but in my inspection I'd spotted some odd R code.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;exp(var%*%t(coef[1,]))&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The oddity here is that var is one-dimensional and so is coef[1,]. This matrix multiply is really just something like exp(sum(var*coef[,1])). So I tried that, and the code took 6 times longer to run. Matrix multiplications are efficient in R, even in one dimension. &lt;br /&gt;&lt;br /&gt;So I switched back to the original code. Time to get profiling. This is easy in R.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Rprof("run.out")&lt;br /&gt;dostuff()&lt;br /&gt;Rprof("")&lt;br /&gt;summaryProfile("run.out")&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This told me most of the time was spent in the &lt;code&gt;t&lt;/code&gt; function, within the function I was playing with earlier. Then I noticed that pretty much wherever &lt;code&gt;coef&lt;/code&gt; was used, it was transposed with the &lt;code&gt;t&lt;/code&gt; function.&lt;br /&gt;&lt;br /&gt;I refactored the code to do &lt;code&gt;t(coef)&lt;/code&gt; once, and then pass the transposed matrix around. That sped the code up from the original 14 seconds to 3 seconds. Sweet.&lt;br /&gt;&lt;br /&gt;Note that at each stage I check that the new output is the same as the old output - it can be useful to write some little test functions at this point, but doing formal test-driven development can be a bit tricky for statistical applications in R.&lt;br /&gt;&lt;br /&gt;There's still a bit of work to do to make this code a bit more general purpose. Currently it works on predictions for one particular country - we want to do predictions over half of Africa!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-4345613452662713049?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/4345613452662713049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2010/12/speeding-up-some-r-code.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/4345613452662713049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/4345613452662713049'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2010/12/speeding-up-some-r-code.html' title='Speeding up some R Code'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-1986763460617913737</id><published>2010-09-07T23:27:00.000+01:00</published><updated>2010-09-07T23:27:46.441+01:00</updated><title type='text'>A queue in R</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Recently someone asked on the R-help mailing list if there was an implementation of a queue in R. I had a quick look (which the poster should have done anyway) and all I could find was an implementation in the filehash package that used database file storage.&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;I figured it couldn't be that hard to implement just by sticking things on one end of a list and taking them off the other, so I wrote one between having breakfast and setting off late for work.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;This evening I polished it off a bit, and even added logging so you could see how big your queue had grown.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;The code is available for download under a CC license from&amp;nbsp;&lt;a href="http://www.maths.lancs.ac.uk/~rowlings/R/Queue/"&gt;my Maths and Stats&lt;/a&gt;&amp;nbsp;web pages.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;If anyone wants to add this to a package or make a package of it, let me know and I'll help you write a stack and a deque too.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-1986763460617913737?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/1986763460617913737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2010/09/queue-in-r.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/1986763460617913737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/1986763460617913737'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2010/09/queue-in-r.html' title='A queue in R'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-9179988470495579944</id><published>2010-05-28T12:49:00.000+01:00</published><updated>2010-05-28T12:49:59.203+01:00</updated><title type='text'>gvSIG, I want to love you...</title><content type='html'>I've just been proofreading an article on gvSIG for the next OSgeo Journal (Volume 6, coming to an HTTP server near you soon). And I so want to love it. The author claims it does everything for him. I want it to do everything for me too.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Currently I use QGis for my day-to-day GIS operations. But the limitations are there - mostly in the geoprocessing arena. Vector and raster operations are a bit fragile and buggy at the moment, mostly because they are fairly new to QGis. A grand effort by Carson Farmer et al has greatly increased the analytical capabilities of QGis but there is still a way to go. Meanwhile gvSIG, with the Sextante toolbox, has it all. At least in theory. Time for me to try it out again.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, off to the web site, and download the latest version. Its a Java app, and I keep getting bitten by incompatible Java environments so I downloaded the version for Linux with the included JRE. It's a big .bin file, so once downloaded you chmod it executable and run it. Choose an install directory and components, and there it goes. All ready to run.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First thing I notice is that the java environment doesn't resize properly. No matter how I stretch or refresh the window, the blue desktop remains fixed size. The grey area is unusable:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_7N-9AwC5AHs/S_-qVUcaDAI/AAAAAAAADXg/QLah7Pm31uk/s1600/initial.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_7N-9AwC5AHs/S_-qVUcaDAI/AAAAAAAADXg/QLah7Pm31uk/s320/initial.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oh well never mind, let's have a look at the interface:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/S_-qt3B5RCI/AAAAAAAADXo/4dUZblmOrBY/s1600/shalom.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/S_-qt3B5RCI/AAAAAAAADXo/4dUZblmOrBY/s320/shalom.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;yes, well peace to you too. This menu has one option concerning DBF file encodings. I went 'huh?' and tried something else. Let's load a shapefile.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First you have to create a new "View", so click on the View icon and there's a new view. Double-click or hit 'open'. Now, how to load that shapefile?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ah, the menu bar has changed. Okay, let's hunt. Layer? No, not there. Shalom? Nope. File? Nope. Oh, it's under View then Add Layer. That's not a standard place for adding things. Usually the View menu is for stuff like zooming in and out. Oh well.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_7N-9AwC5AHs/S_-r9-1vdsI/AAAAAAAADXw/tCvxaIZpq1w/s1600/add.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_7N-9AwC5AHs/S_-r9-1vdsI/AAAAAAAADXw/tCvxaIZpq1w/s320/add.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;At least now I've got the option. Hit it!&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/S_-sOyvpiDI/AAAAAAAADX4/O6Gni-7lyrY/s1600/blank.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/S_-sOyvpiDI/AAAAAAAADX4/O6Gni-7lyrY/s320/blank.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Yeah. Blank. There's controls in there, since random clicking does things. But I see nothing. Oh well, let's quit and try something else:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/S_-sbY6TQMI/AAAAAAAADYA/6vGRauvflek/s1600/quit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/S_-sbY6TQMI/AAAAAAAADYA/6vGRauvflek/s320/quit.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Blank again. Most of the dialogs are blank, including Help. There's no obvious errors on the console either. I have to hit Ctrl-C to kill it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Normally I blame these problems with java apps on JRE incompatibilities, but I have no idea what is going on here. I'm running on Ubuntu Karmic on a PC and everything else works nicely. Obviously something is messing up gvSIG since plenty of other people must be using it. Ideas welcome. I think my next step is to try it with a new clean username. But that shouldn't be necessary in this day and age...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-9179988470495579944?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/9179988470495579944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2010/05/gvsig-i-want-to-love-you.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/9179988470495579944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/9179988470495579944'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2010/05/gvsig-i-want-to-love-you.html' title='gvSIG, I want to love you...'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_7N-9AwC5AHs/S_-qVUcaDAI/AAAAAAAADXg/QLah7Pm31uk/s72-c/initial.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-2641816864302174129</id><published>2010-05-03T11:19:00.000+01:00</published><updated>2010-05-03T11:19:29.055+01:00</updated><title type='text'>Medical Research Council grant success!</title><content type='html'>Back in October I talked about a grant proposal we'd put in to fund some research into disease surveillance. Well, a few weeks ago we heard that our application was successful! So that's nearly half a million pounds coming our way. It'll pay a large chunk of my salary for three years, a smaller chunk of the Prof, and a whole research associate. There's also money for new toys and travel to Africa, the USA and various conferences.&lt;br /&gt;&lt;br /&gt;So if anyone with strong statistical skills in R is interested in a research project involving spatial and temporal statistics in epidemic prediction, get in touch and I'll send you some details. Probably starting in September.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-2641816864302174129?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/2641816864302174129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2010/05/medical-research-council-grant-success.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/2641816864302174129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/2641816864302174129'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2010/05/medical-research-council-grant-success.html' title='Medical Research Council grant success!'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-3917346920938966550</id><published>2010-05-02T16:27:00.000+01:00</published><updated>2010-05-02T16:27:27.774+01:00</updated><title type='text'>Culture Colours and Infographics</title><content type='html'>A graphic from the &lt;a href="http://www.informationisbeautiful.net/visualizations/colours-in-cultures/"&gt;Information Is Beautiful&lt;/a&gt; blog has been doing the rounds lately. I first saw it on &lt;a href="http://www.apartmenttherapy.com/"&gt;Apartment Therapy&lt;/a&gt; and decided to have a little grumble about it. Then it got some coverage on the &lt;a href="http://junkcharts.typepad.com/junk_charts/2010/05/light-entertainment-multiculturalism.html"&gt;Junk Charts&lt;/a&gt; blog. I decided to get the raw data and see what it looked like in a more informative presentation.&lt;br /&gt;&lt;br /&gt;But how to get the raw data? There's no link to it I could find. So I decided to scrape it.&lt;br /&gt;&lt;br /&gt;First, I found the highest resolution image of it I could find on the web. Wasn't massive, but it would do. Then I could load it into R using readGDAL from the rgdal package:&lt;br /&gt;&lt;br /&gt;co=readGDAL("image.png")&lt;br /&gt;image(co,red=1,green=2,blue=3)&lt;br /&gt;&lt;br /&gt;and there it is in my R graphics window. Now I need to generate a whole bunch of circular points where I want to sample the colours. So out with the sines and cosines. Lots of trial and error getting the radii right for all ten sections, but eventually I had it. It was a seconds work with the overlay function from the sp package to get the 860 colour points.&lt;br /&gt;&lt;br /&gt;860? There's only 84 traits? I found and dropped the two rows that corresponded to the A-J index and the J-A index. Now I had all the colours in a nice matrix which I could save to a file for safe keeping.&lt;br /&gt;&lt;br /&gt;For a simple presentation, I just created an HTML table where the cell background was the colour. It's hard to do rotated column headers in HTML, so I added a fixed DIVas index, and multiple row headers so you can always see the column heading letters. I think the resulting HTML page makes it much easier to navigate and find the colour for the thing you are looking for, although nobody will want to buy large-format version posters of it. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_7N-9AwC5AHs/S92ZoosrBgI/AAAAAAAADXY/cl4z6pteLCM/s1600/colours.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_7N-9AwC5AHs/S92ZoosrBgI/AAAAAAAADXY/cl4z6pteLCM/s320/colours.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If anyone wants the raw data, drop me an email.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-3917346920938966550?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/3917346920938966550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2010/05/culture-colours-and-infographics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/3917346920938966550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/3917346920938966550'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2010/05/culture-colours-and-infographics.html' title='Culture Colours and Infographics'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_7N-9AwC5AHs/S92ZoosrBgI/AAAAAAAADXY/cl4z6pteLCM/s72-c/colours.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-7584725703504813727</id><published>2010-03-12T23:11:00.000Z</published><updated>2010-03-12T23:11:08.828Z</updated><title type='text'>Twitter Timeline Visualisations</title><content type='html'>Ever wanted to make scrolling timeline visualisations of tweets?&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/S5rH07-X0SI/AAAAAAAADXQ/62UPeyQTErs/s1600-h/twitline.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="316" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/S5rH07-X0SI/AAAAAAAADXQ/62UPeyQTErs/s640/twitline.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;Here's how.&lt;br /&gt;&lt;br /&gt;You will need:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The R environment for statistics and graphics (www.r-project.org)&lt;/li&gt;&lt;li&gt;The twitteR and brew packages for R&lt;/li&gt;&lt;li&gt;Some web space&lt;/li&gt;&lt;/ul&gt;&amp;nbsp;I'm using the &lt;a href="http://code.google.com/p/simile-widgets/"&gt;MIT Simile Timeline&lt;/a&gt; widget to do all the hard work. All I need to do is get the tweets into the right format. To do that I wrote a little R program using the twitteR package to access tweets via the search API, and the brew package to reformat into XML. Here's my entire twitline function:&lt;br /&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;twitline &amp;lt;- function(q,outfile,num=15,...){&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  require(twitteR)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  require(brew)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  srch=searchTwitter(q,num=num,...)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  brewSrc="&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;data&gt;&lt;/data&gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;% for(tweet in srch){ %&amp;gt;\&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;event %="" start="\&amp;quot;&amp;lt;%=created(tweet)"&gt;\"&lt;/event&gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  title=\"&amp;lt;%=screenName(tweet) %&amp;gt;\"&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;%=text(tweet) %&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;lt;% } %&amp;gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;"&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  brew(text=brewSrc,output=outfile)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;  }&lt;/span&gt;&lt;/blockquote&gt;Now all I do is: twitline("sea otters","twitter.xml",num=100) and I get an XML file in the right format. Read the timeline docs and you'll see that all you need is:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Timeline.loadXML("twitter.xml", function(xml, url) { eventSource.loadXML(xml, url); });&lt;/blockquote&gt;&amp;nbsp;in the right place in your javascript.&lt;br /&gt;&lt;br /&gt;There's a few things need doing here, like scaling the timeline to the events on startup, maybe styling things a bit better, having a way to get more than 100 tweets, linking to twitter.com and so on. Consider it a start.&lt;br /&gt;&lt;br /&gt;Also, the grabbing and conversion could easily be done in Python or [IYFPLH]. Even cooler would be on-the-fly updates. Check out the SIMILE docs for more ideas.&lt;br /&gt;&lt;br /&gt;Barry&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-7584725703504813727?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/7584725703504813727/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2010/03/twitter-timeline-visualisations.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/7584725703504813727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/7584725703504813727'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2010/03/twitter-timeline-visualisations.html' title='Twitter Timeline Visualisations'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_7N-9AwC5AHs/S5rH07-X0SI/AAAAAAAADXQ/62UPeyQTErs/s72-c/twitline.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-2573015108902304682</id><published>2010-03-11T16:45:00.000Z</published><updated>2010-03-11T16:45:44.897Z</updated><title type='text'>Fun With OpenLayers and Flot</title><content type='html'>OpenLayers is a javascript library for doing client-side maps. Flot is a javascript library for doing charts. Put them together and what have you got?&lt;br /&gt;&lt;br /&gt;A system for dynamic interactive spatio-temporal graphics. It's something I've wanted to play with for a while, and now I had an excuse. Our meningitis data from Africa is exactly that - counts of meningitis cases in areas in time periods. Eventually we'll be getting it in real time, and predicting epidemics. But for now everything is simulated data.&lt;br /&gt;&lt;br /&gt;What I wanted was a map of our country of interest (in this example, Niger). Clicking on the regions of Niger would show a time-series plot of the case count history for those regions. Flot can happily show multiple line charts, show dates on the X-axis, adjust its axes automatically, colour-code it's lines and so on.&lt;br /&gt;&lt;br /&gt;So I started with an OpenLayers map and read in my Health District GML file. That's my spatial data. Then I read in a JSON file using JQuery's AJAX api. That's my time-series data (one time series per region). I create a new plot object with Flotr, initially empty.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;Adding a SelectControl to the map lets you hook into clicks and hovers on the regions. Each click toggles a region on or off, and when toggled on the corresponding time-series is added to the Flotr plot. Toggle a region off and the time-series line is removed. Flot takes care of updating the legend and the axes.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;The Flot charts get a bit cluttered with a dozen lines, so I decided to restrict the number of selected regions to ten. If the user tries to select an eleventh, the system doesn't let you. You have to deselect another region first. This was all done in the onSelect action of the controller. I should probably also make it display a message at this point.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;I also decided to match the line colour on the chart with the area colour on the map. I generated a palette of colours from ColorBrewer and used those. When an area is selected a colour is popped from the palette and used to style the area and the line. When an area is deselected its colour is pushed back onto the array.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_7N-9AwC5AHs/S5kdI7rVOJI/AAAAAAAADXI/Nd9O-gdAask/s1600-h/linkPlots.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_7N-9AwC5AHs/S5kdI7rVOJI/AAAAAAAADXI/Nd9O-gdAask/s320/linkPlots.png" /&gt;&lt;/a&gt;&lt;/div&gt;After fixing some dangling commas and a few other annoyances it even worked on Internet Explorer.&lt;br /&gt;&lt;br /&gt;A plain &lt;a href="http://www.maths.lancs.ac.uk/~rowlings/OpenLayers/SpaceTime/"&gt;demo&lt;/a&gt;&amp;nbsp;is available, which possibly needs a bit of tweaking to make good. It doesn't have the styling of the above image, but does work in IE and lets you see how it all works.&lt;br /&gt;&lt;br /&gt;You may use my javascript code in linkedmap.js freely. The map data is an approximate digitisation from a low-resolution image, so does not accurately represent the areas in Niger. All count data is simulated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-2573015108902304682?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/2573015108902304682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2010/03/fun-with-openlayers-and-flot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/2573015108902304682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/2573015108902304682'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2010/03/fun-with-openlayers-and-flot.html' title='Fun With OpenLayers and Flot'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_7N-9AwC5AHs/S5kdI7rVOJI/AAAAAAAADXI/Nd9O-gdAask/s72-c/linkPlots.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-1432622690763223855</id><published>2010-02-02T16:22:00.000Z</published><updated>2010-02-02T16:22:15.518Z</updated><title type='text'>The great British Library DRM Flip-flop</title><content type='html'>Our tech support helpdesk recently received requests from a PhD student and a member of staff to install something they needed to read documents requested from the British Library. A proprietary Adobe system called 'ADEPT' was being used to prevent copying and distribution of papers requested from the BL's loan system.&lt;br /&gt;&lt;br /&gt;Problem number one was that our PhD students, like many scientists, are enlightened enough to use Linux. There is no Linux version of ADEPT. Apparently Adobe promised one a year or so ago, but that promise disappeared from their web page. Now there's no plans for it. Thanks.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;I emailed BL customer service about this. Explaining both how DRM was a stupid idea and DRM with no Linux version was a dumb stupid idea. But not in those terms, of course. The customer services response was fun. First they said:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;"It is unfortunate that your student has problems receiving documents in&amp;nbsp;an elecronic format."&lt;/blockquote&gt;&lt;br /&gt;My response was that misfortune had nothing to do with it, but poor decisions on content-delivery did. They went on:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;"We supply articles via Secure Electronic Delivery as customers want to&amp;nbsp;receive them electronically."&amp;nbsp;&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;Yup, we all love saving trees.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;"The need for encrypted documents is due to&amp;nbsp;the current agreement the British Library has with publishers"&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;Encrypted? Here's my GPG Public Key if you want to encrypt documents. I explained how this was not encryption, this was DRM, and was hence doomed to failure. At some point any DRM system has to let the user read the file, or hear the music, or see the movie, and at that point it is clear that any encryption has been decrypted. At that point the user has had, somehow, the decryption key. DRM is just obfuscation of encryption keys. Find the encryption keys and you can bypass the DRM.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And that has been done. There is published on the web a couple of quite short python scripts for bypassing ADEPT DRM. One gets the decryption key. From my reading of the code it seems to be stored in the Windows registry and mashed together with your PC's CPU identifier to tie it to your hardware. So you need an official ADEPT account and all that.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once that script has got the key, you run the second script on any DRMd files, using the recovered key to produce an unencumbered document (PDF file, usually). This you can print, copy to your laptop, backup and know the backup will be readable in whatever PC you have in ten years time, run through ps2text to create plain text and so on. All the things you'd love to do, and are probably legal, if you had a real copy in the first place.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Customer service went on:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;"Your student may find it helpful to contact your University Library as&amp;nbsp;they may be able to help by receiving and printing the documents for&amp;nbsp;her.&amp;nbsp;We also still supply Xerox copies by post."&lt;/blockquote&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;Tiiiiiimmmmmmberrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr!!!!!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;The great mystery is how the BL's policy has changed in the last four years. I found this quote from a news website:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;&amp;nbsp;[The] British Library when speaking to the All Parliamentary Internet&amp;nbsp;Group in 2006, warned that the adoption of DRM technology would&amp;nbsp;"fundamentally threaten the longstanding and accepted concepts of fair&amp;nbsp;dealing and library privilege and undermine, or even prevent,&amp;nbsp;legitimate public good access.&lt;/blockquote&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp;*sigh*&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-1432622690763223855?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/1432622690763223855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2010/02/great-british-library-drm-flip-flop.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/1432622690763223855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/1432622690763223855'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2010/02/great-british-library-drm-flip-flop.html' title='The great British Library DRM Flip-flop'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-2607572126779608517</id><published>2010-01-04T22:42:00.000Z</published><updated>2010-01-05T19:49:40.037Z</updated><title type='text'>Generating Fake Geographies</title><content type='html'>The other day I asked a question on the R-sig-geo mailing list. How can I generate a set of polygons that look a bit like a real set of districts or other subdivisions? Here's what I came up with:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Take a set of points &lt;/li&gt;&lt;li&gt;Generate the voronoi tiles of the points&lt;/li&gt;&lt;li&gt;Turn the straight-line edges into something wiggly&lt;/li&gt;&lt;li&gt;Clip or cut the resulting polygons&lt;/li&gt;&lt;/ol&gt;So I wrote some R code to do all this. 1 and 2 are pretty easy using the tripack package to generate the voronoi tiles. Making the edges wiggly is a bit trickier. I implemented a fractal algorithm. Split the edge into two pieces by making a new point somewhere near the centre of the edge. Then repeat for the two pieces to make four pieces. Do this three times. This should make a fairly straight wiggly line. For clipping and cutting the polygons I used the gpclib package (free for non-commercial use only - read the license).&lt;br /&gt;&lt;br /&gt;&amp;nbsp;Clipping and cutting is necessary because voronoi tiles can extend way beyond the initial points if the tile edges are nearly parallel. I implemented four clipping modes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No clipping (so you get the full polygons)&lt;/li&gt;&lt;li&gt;Include polygons that overlap a given boundary polygon&lt;/li&gt;&lt;li&gt;Clip polygons to given boundary polygon&lt;/li&gt;&lt;li&gt;Include only polygons completely inside a boundary polygon&lt;/li&gt;&lt;/ul&gt;&amp;nbsp;By default the boundary polygon is the convex hull of the input points, but you can specify another polygon for clipping.&lt;br /&gt;&lt;br /&gt;Here's my sample data - some points and a blue polygon for clipping:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_7N-9AwC5AHs/S0JszaZ7LlI/AAAAAAAADWo/WZQmPLHRgRE/s1600-h/pointsClip.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_7N-9AwC5AHs/S0JszaZ7LlI/AAAAAAAADWo/WZQmPLHRgRE/s320/pointsClip.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Here's a fake geography created using these points and clipmode zero - the blue polygon is ignored here:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/S0JsqWmYv8I/AAAAAAAADWI/wUDN84rVr5M/s1600-h/mode0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/S0JsqWmYv8I/AAAAAAAADWI/wUDN84rVr5M/s320/mode0.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Note that the polygons bottom left head off some distance south-west. The lack of polygons in the north and west is due to these areas being infinite. They don't form closed tiles. This means the number of polygons you get returned wont be the same as the number of input points.&lt;br /&gt;&lt;br /&gt;The wiggling algorithm here may cause lines to cross and overlap. There's no test for that at the moment.&lt;br /&gt;&lt;br /&gt;Clipmode 1 only includes polygons that are partly or wholly inside the clip polygon:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/S0JssEHlbEI/AAAAAAAADWQ/XgJtFETE2Yg/s1600-h/mode1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/S0JssEHlbEI/AAAAAAAADWQ/XgJtFETE2Yg/s320/mode1.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;This has eliminated all the extending polygons in the south-west. Mode 2 clipping results in the polygons being clipped to the boundary polygon. This is useful if you are creating a set of polygon districts within an existing area such as a country boundary:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_7N-9AwC5AHs/S0Jst7TVcCI/AAAAAAAADWY/_dnLShPXaZ0/s1600-h/mode2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_7N-9AwC5AHs/S0Jst7TVcCI/AAAAAAAADWY/_dnLShPXaZ0/s320/mode2.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Note you can't see the red edges under the blue polygon boundary here - they are there though.&lt;br /&gt;&lt;br /&gt;Mode 3 only returns polygons wholly inside the clip polygon:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/S0Jsv5xubUI/AAAAAAAADWg/SMan7NuW-Gs/s1600-h/mode3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/S0Jsv5xubUI/AAAAAAAADWg/SMan7NuW-Gs/s320/mode3.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;This only leaves 8 polygons - it looks like one polygon on the inner corner has just been clipped out.&lt;br /&gt;&lt;br /&gt;So there it is. I've not polished up the code yet, but it's pretty short and sweet. Interested? Let me know.&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;Addendum: I promise I'll bundle the code up shortly, but today I've been making tweaks to produce fake river networks:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_7N-9AwC5AHs/S0OW4bIZrFI/AAAAAAAADWw/1sR5ksbFN2k/s1600-h/fakeRivers.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_7N-9AwC5AHs/S0OW4bIZrFI/AAAAAAAADWw/1sR5ksbFN2k/s320/fakeRivers.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;It's pretty much the same basic procedure - generate a voronoi tiling and wiggle the edges. Then compute a minimum spanning tree (any tree will probably do) with distance as the weight. The resulting map looks a bit like a river network (although I wouldn't want to draw the contours or DEM it came from).&lt;br /&gt;&lt;br /&gt;I tried various weighting schemes for the MST. Using distance means it uses up the small edges before the large edges, which tends to leave those big gaps that could be mountain ridges.&lt;br /&gt;&lt;br /&gt;Other ideas welcome!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-2607572126779608517?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/2607572126779608517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2010/01/generating-fake-geographies.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/2607572126779608517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/2607572126779608517'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2010/01/generating-fake-geographies.html' title='Generating Fake Geographies'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_7N-9AwC5AHs/S0JszaZ7LlI/AAAAAAAADWo/WZQmPLHRgRE/s72-c/pointsClip.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-4026397012213917913</id><published>2009-12-27T19:50:00.000Z</published><updated>2009-12-27T19:50:52.953Z</updated><title type='text'>Making Interactive Plots with Flot</title><content type='html'>I've been working on a demonstration web site of a meningitis case reporting system in Africa. The current demo uses OpenLayers to show a map of the spatial distribution of cases, and a couple of PNG plots generated from R to show the cases in time for a particular area. One plot showed the cases for the past year, and one was a plot of the previous four weeks with our prediction of the next four weeks cases (plus 95% confidence interval).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SzezvSSoGgI/AAAAAAAADVg/f1RFDuxM4GU/s1600-h/oldplots.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SzezvSSoGgI/AAAAAAAADVg/f1RFDuxM4GU/s320/oldplots.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;But I thought these were a bit static. So I thought I'd add a bit more functionality. Options? Well, I could use my imagemap package for R to create hotspot areas on the plot so users can hover over points and get information, or click on points to zoom to epidemic predictions and so on. But I decided to try a Javascript plotting library instead. There's a few out there, and I settled on using &lt;a href="http://code.google.com/p/flot/"&gt;Flot&lt;/a&gt; - although &lt;a href="http://www.jqplot.com/"&gt;jqPlot&lt;/a&gt; looks pretty capable too. &lt;br /&gt;&lt;br /&gt;Flot lets you plot lines, points and bars, and you can make filled areas by constructing a data series that goes along the top and back along the bottom, completing a polygon. You can shade and style the points and lines, and you get a legend. If your X-axis is time, you can feed it milliseconds and get dates. Here's what I've got to start with:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/SzezxcbnsVI/AAAAAAAADVo/tKrvzzsInnE/s1600-h/plot1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/SzezxcbnsVI/AAAAAAAADVo/tKrvzzsInnE/s320/plot1.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;The buttons at the bottom control the time period. By clicking on 'Prediction', the user can zoom in to see the most recent few weeks, plus our two- and four-week predictions with 50% and 95% confidence interval. Flot also lets you add hover and click events to points:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/SzezzYRrZ9I/AAAAAAAADVw/c2LswQnhwzI/s1600-h/plot2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/SzezzYRrZ9I/AAAAAAAADVw/c2LswQnhwzI/s320/plot2.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Here we're showing that our 2-week ahead prediction has a 92% chance of exceeding our 10-case threshold.&lt;br /&gt;&lt;br /&gt;Flot also allows zooming in on plots. See that earlier peak around July? We can select that area:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_7N-9AwC5AHs/Sze3y3aH3rI/AAAAAAAADV4/p_m_hbrVvB0/s1600-h/select.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_7N-9AwC5AHs/Sze3y3aH3rI/AAAAAAAADV4/p_m_hbrVvB0/s320/select.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;and Flot can show that time period in detail:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/Sze302YW0zI/AAAAAAAADWA/XBlyrw5YH6U/s1600-h/zoomed.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/Sze302YW0zI/AAAAAAAADWA/XBlyrw5YH6U/s320/zoomed.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;All very nice. I've note tested this on Internet Explorer yet, but jQuery and Flot should hide browser-specifics from the author so it should work. This all worked out pretty smoothly, except for a few problems. The biggest one is that if the user resizes the browser window, the plot doesn't resize properly. Not a problem if your DIV element has a fixed width, but I had width: 80% in my CSS. The fix was to redo the plot on a resize event of the window. In jQuery, that's:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp; $(window).bind("resize",function(eventObject){&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; plot = $.plot(plotDiv, d, options );&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If anyone wants some more code, or the full example, then just ask!&lt;br /&gt;&lt;br /&gt;Barry&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-4026397012213917913?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/4026397012213917913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2009/12/making-interactive-plots-with-flot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/4026397012213917913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/4026397012213917913'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2009/12/making-interactive-plots-with-flot.html' title='Making Interactive Plots with Flot'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_7N-9AwC5AHs/SzezvSSoGgI/AAAAAAAADVg/f1RFDuxM4GU/s72-c/oldplots.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-6268259799087196242</id><published>2009-12-17T15:40:00.000Z</published><updated>2009-12-17T15:40:55.298Z</updated><title type='text'>Polygon Shapefile Editing with QGIS</title><content type='html'>This is a little excursion into editing polygons with some of the new features in Qgis. I'm using a fresh-out-of-SVN of Qgis 1.4. Thanks to whoever fixed the right-click crash bug one hour after I reported it!&lt;br /&gt;&lt;br /&gt;I was given a bitmap file representing the new boundaries of regions we are supposed to be working on for a project. I couldn't get this in a spatial format no matter how hard I tried. I did have some similar boundaries but there were a few changes here and there. I loaded the bitmap into the Qgis georeferencer and using my old boundary shapefile matched some points up and created a world file. I could then load the bitmap into Qgis. Here it is:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/SypKzat0f1I/AAAAAAAADTY/0DJg635D4OA/s1600-h/part1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/SypKzat0f1I/AAAAAAAADTY/0DJg635D4OA/s320/part1.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;There's no way I want to redigitize the boundaries when I have something pretty close, and all the overlapping labels on this mean it would be tricky to automatically redigitize the boundaries. Zoom in and see the resolution for yourself.&lt;br /&gt;&lt;br /&gt;So I loaded the nearest shapefile and overlaid it, set the fill colour to something transparent (if you set a fill to 'no fill' then you can't see the selection highlight), and activated the magic super labelling from the labelling plugin:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypLdhi87rI/AAAAAAAADTg/mI04DgXTC4w/s1600-h/part2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypLdhi87rI/AAAAAAAADTg/mI04DgXTC4w/s320/part2.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;They match up pretty well, but zooming around shows a few problems:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypLrniYc-I/AAAAAAAADTo/GhxqRErrv5I/s1600-h/part3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypLrniYc-I/AAAAAAAADTo/GhxqRErrv5I/s320/part3.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;I want to fix the border between Loga and Dosso to better match the underlying raster. First up, activate the editing mode:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypL4CMmhOI/AAAAAAAADTw/75pGNE2-iiA/s1600-h/part4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypL4CMmhOI/AAAAAAAADTw/75pGNE2-iiA/s320/part4.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Now I hit a problem. Since polygon shapefiles are doubly-digitised, I couldn't see how to move the points on both polygonal boundaries together. And if I moved first one, and then the other, I would probably end up with slivers or polygons that didn't quite fit. I hit on another strategy.&lt;br /&gt;&lt;br /&gt;First, select Loga region:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypMTes1aZI/AAAAAAAADT4/MJVifruX19U/s1600-h/part5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypMTes1aZI/AAAAAAAADT4/MJVifruX19U/s320/part5.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;then use the 'Split Feature' tool to cut off a little bit of Loga in the corner away from the edge. This is just to keep the attributes of Loga somewhere, since in a second we're going to merge it with Dosso:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_7N-9AwC5AHs/SypMk6GV-WI/AAAAAAAADUA/tW-cqeJHiTs/s1600-h/part6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_7N-9AwC5AHs/SypMk6GV-WI/AAAAAAAADUA/tW-cqeJHiTs/s320/part6.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Now we have two features with the same attributes. It's possible that ID numbers have changed here, so don't rely on them. That might explain a bug to appear later... So now, select Dosso and the main part of Loga, and use the Merge Selected Features tool:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypM-eNRmTI/AAAAAAAADUI/Iaajfn1-x-Y/s1600-h/part7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypM-eNRmTI/AAAAAAAADUI/Iaajfn1-x-Y/s320/part7.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;This pops up the dialog asking you where the merged feature should get its attributes from. In this case we want the feature to take the attributes of Dosso:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypNVNkShhI/AAAAAAAADUQ/WLIZNRZynYk/s1600-h/part8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypNVNkShhI/AAAAAAAADUQ/WLIZNRZynYk/s320/part8.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;This leaves a few stray bits lying around on the border:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypNp463OUI/AAAAAAAADUY/rbSKEUfq8RY/s1600-h/part9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypNp463OUI/AAAAAAAADUY/rbSKEUfq8RY/s320/part9.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;So use the Delete Ring tool to get rid of them:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/SypN2FvdYbI/AAAAAAAADUo/IoGdQB88dUA/s1600-h/part10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/SypN2FvdYbI/AAAAAAAADUo/IoGdQB88dUA/s320/part10.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Now we are going to split Dosso along the new border. First select it:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_7N-9AwC5AHs/SypNyAQrMiI/AAAAAAAADUg/GCsYgVV01tk/s1600-h/part11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_7N-9AwC5AHs/SypNyAQrMiI/AAAAAAAADUg/GCsYgVV01tk/s320/part11.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Then use the Split Feature tool to split by following the border on the underlying raster:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypOI_bzAHI/AAAAAAAADUw/yhtHcUYtNS8/s1600-h/part12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypOI_bzAHI/AAAAAAAADUw/yhtHcUYtNS8/s320/part12.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Here's the bug. It's labelled Dosso with 'Loga'. If you check the attribute table at this point it still says 'Dosso', so maybe everything is okay. We'll press on. What we do next is to select the two parts that will make up the new Loga in preparation for another 'Merge Selected Features':&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_7N-9AwC5AHs/SypOjFzo0xI/AAAAAAAADU4/AVyBpL9ig-w/s1600-h/part13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_7N-9AwC5AHs/SypOjFzo0xI/AAAAAAAADU4/AVyBpL9ig-w/s320/part13.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;We do the merge, and get the attributes from the little corner of Loga that we cut off earlier:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypOs93TsBI/AAAAAAAADVA/Er-u4lVoIrs/s1600-h/part14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypOs93TsBI/AAAAAAAADVA/Er-u4lVoIrs/s320/part14.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Now we have the geometry we want:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypO3hukNVI/AAAAAAAADVI/lDmCUwXcoTk/s1600-h/part15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypO3hukNVI/AAAAAAAADVI/lDmCUwXcoTk/s320/part15.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Except it's still labelled Dosso as Loga. The attribute table seems fine though - if I select Dosso the right line is highlighted in the attribute table:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_7N-9AwC5AHs/SypPDlk1YqI/AAAAAAAADVQ/jbuMh7HOxlI/s1600-h/part16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_7N-9AwC5AHs/SypPDlk1YqI/AAAAAAAADVQ/jbuMh7HOxlI/s320/part16.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Never mind, let's turn off the editing and see what happens:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypPKG1ulNI/AAAAAAAADVY/_U2qNo4x-Cs/s1600-h/part17.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SypPKG1ulNI/AAAAAAAADVY/_U2qNo4x-Cs/s320/part17.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Ooh! It's all looking good! Dosso is Dosso and Loga is Loga.&lt;br /&gt;&lt;br /&gt;Now I hope there is an easier way of doing this - a way of editing points along common boundaries such that both polygons are modified. But I can't find it, and I've asked on #qgis and nobody seems to know. If not, then this might be the best way to do it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-6268259799087196242?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/6268259799087196242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2009/12/polygon-shapefile-editing-with-qgis.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/6268259799087196242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/6268259799087196242'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2009/12/polygon-shapefile-editing-with-qgis.html' title='Polygon Shapefile Editing with QGIS'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_7N-9AwC5AHs/SypKzat0f1I/AAAAAAAADTY/0DJg635D4OA/s72-c/part1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-6003498867978065343</id><published>2009-12-11T22:48:00.000Z</published><updated>2009-12-11T22:48:51.266Z</updated><title type='text'>Why Screencasts Can Suck</title><content type='html'>A screencast is an instructional video where you see someone's computer screen as they do something, together with a voice-over of them telling you what they are doing. Google trends shows them starting in 2006 and increasing in search volume ever since. Everyone wants to do a screencast.&lt;br /&gt;&lt;br /&gt;But are they being used for the right thing? They have their place, just as a screwdriver is the right tool for putting in screws, but there seems to me to be a lot of people using them in the wrong place. &lt;br /&gt;&lt;br /&gt;Here's a few reasons why they suck, together with fixes for ameliorating the suckage:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Speech and graphics aren't searchable in a browser or indexable in a search engine&lt;/b&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Fix: include a transcript or at least a number of keywords and keyphrases on the page. &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Video is hard to jump to a precise point&lt;/b&gt;. If I didn't follow a point, or I want to see how you set something up near the start, I'd like to be able to jump back and forth to key points. This also makes it hard to go through a screencast at your own pace.&lt;br /&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Fix: I think YouTube videos can have chapter points. It may also be possible that screencasting software can give you some links for this. Include them.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Fix: Alternatively, overlay your screencast with big chunky step numbers or text in the corner. Then as I scroll the fiddly little control back I can see it change from (3) to (2).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;Speech and text can't be cut and pasted&lt;/b&gt;. This is a pain with command-line videos, less so with gui clickage.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Fix: supply a text transcript of commands and speech where appropriate.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;b&gt;I'm listening to music.&lt;/b&gt;&amp;nbsp; The voiceover doesn't go with my tunes.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Fix: include subtitles. Also helps people with hearing difficulties, which will include me if I carry on listening to Muse at these volumes.&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;Those problems apply to all screencasts. Here are some things that make bad screencasts: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Loss of resolution.&lt;/b&gt; If you are squeezing your entire monitor onto a little YouTube video something is going to get lost. Zoom in if you need to show detail.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Two Many Misteaks.&lt;/b&gt; I don't want to see you mistyping things. Or going "oops". Or stuttering. Or forgetting something. Shout "cut" to yourself and do another take. Or do several takes and edit. Remember you only have to get this right once, thousands of people may have to watch it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Nothing happening.&lt;/b&gt; Perhaps Andy Warhol would enjoy an unchanging screen with some rambling banter over the top. But I'm not sure everyone else does. This is supposed to be instructable, not minimalist.&lt;/li&gt;&lt;/ul&gt;Most of these problems can be worked round by creating a series of screenshots and annotating them. I've used Wink for this in the past. It creates a Flash file which you can either play or step through one stage at a time. You can add callout annotations and make the mouse cursor sparkle when it clicks something. The user can step back and forth.&lt;br /&gt;&lt;br /&gt;It's extra work to do this, but then it's extra work to do a screencast properly with transcript, subtitles, or key point markers. Terse and precise text is much better than a rambling voice-over. Screencasts may be great for demonstrating anything that has lots of animation in it, but to demonstrate the operation of a piece of point-and-click software it has it's limitations.&lt;br /&gt;&lt;br /&gt;Just sayin'.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-6003498867978065343?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/6003498867978065343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2009/12/why-screencasts-can-suck.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/6003498867978065343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/6003498867978065343'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2009/12/why-screencasts-can-suck.html' title='Why Screencasts Can Suck'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-4516331738548754681</id><published>2009-12-01T19:03:00.000Z</published><updated>2009-12-01T19:03:28.724Z</updated><title type='text'>Converting an mdb to spatialite</title><content type='html'>There's loads of data on the European Environment Agency's &lt;a href="http://www.eea.europa.eu/"&gt;web site&lt;/a&gt;. And I'm looking for data for my Open Source Geospatial course in January. That's next month now. A lot of the data is in shapefile or geoTiff form, which you can read right into Qgis, R, and with a bit of fiddling, OpenLayers. However there are some databases on there in .mdb format. That's Microsoft Access format. Oh great.&lt;br /&gt;&lt;br /&gt;Luckily there's a bunch of command-line tools for extracting data from mdb files. Then I can import them into spatialite and add the geographic data to the tables.&lt;br /&gt;&lt;br /&gt;Here's what I did. First get the mdb file from the&amp;nbsp;&lt;a href="http://www.eea.europa.eu/data-and-maps/data/eper-the-european-pollutant-emission-register-3"&gt;EPER data set&lt;/a&gt; downloads. I'm not sure why the March 2008 version is considered later than the August version, but never mind. We unzip and now have EPER_dataset_27-03-2008.mdb to play with. I'm using the bash shell here for my unix commands.&lt;br /&gt;&lt;br /&gt;Let's just set a variable to the filename because it's such a fiddle to type:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;mdb=EPER_dataset_27-03-2008.mdb&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now fire up spatialite-gui and create a new database called eper.sqlite. It should have some tables in it, namely: geom_cols_ref_sys,  geometry_columns, and   spatial_ref_sys . Quit spatialite-gui.&lt;br /&gt;&lt;br /&gt;The next job is to generate the tables in the spatialite file. You can dump the schema from the mdb file and read it into spatialite easy enough, and I found that the sybase version of the schema was accepted better by spatialite than the default access option, or the oracle version:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;mdb-schema $mdb sybase | spatialite eper.sqlite&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ignore the errors, they occur because the schema script tries to drop all tables before creating them.&lt;br /&gt;&lt;br /&gt;Next up, read all the table data from the mdb and load into sqlite. I use the -I option of mdb-export to dump SQL INSERT statements, and the -R option to add the semicolons that spatialite needs:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;for t in `mdb-tables $mdb` ; do&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;echo $t&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;&amp;nbsp;mdb-export -I -R ";\n" $mdb $t |spatialite eper.sqlite&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;done&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;All my table names and column names are single words, so I don't need any quotes or the -S option to sanitize names. That's not always the case.&lt;br /&gt;&lt;br /&gt;Now we have to spatially enable the Facility table. Fire up the gui again on the eper.sqlite file. You should see the new tables.&lt;br /&gt;&lt;br /&gt;The Facility table has Longitude and Latitude columns which look like WGS84 coords, and indeed there is a Geographic Coordinate System column. Let's just check:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;SELECT * FROM "Facility" where GeographicCoordinateSystem &amp;lt;&amp;gt; 'WGS84'&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Oh dear. 28 of them appear to be in ETRS89. We'll ignore that for now, but it's always good to check. &lt;br /&gt;&lt;br /&gt;The table needs a geometry column, so we add it thus:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;SELECT AddGeometryColumn('Facility', 'the_geom', 4326, 'POINT', 2);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And now we fill that column by making points from the Lat/Long columns:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&lt;span style="color: #666666;"&gt;UPDATE Facility SET the_geom = MakePoint(Longitude,Latitude,4326)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;From that point we can load the database in Qgis 1.4.x using the spatialite layer and plot the points, query them etc etc.&lt;br /&gt;&lt;br /&gt;The database is a complex beast if you wish to relate the other emissions data to the facility points. I've constructed what I think is an approximate picture of the relations between the tables, but I may be wrong!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SxVnQ4EQ2FI/AAAAAAAADTQ/JBozl-_QEw4/s1600/eper.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SxVnQ4EQ2FI/AAAAAAAADTQ/JBozl-_QEw4/s320/eper.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&amp;nbsp;The PDF/DBDesigner XML of this is available from me if you ask nicely! You could probably use this now to do stuff like creating a view in spatialite that mapped all emissions of a certain substance in various countries, or summarise emissions counts in countries and so on. There's a&amp;nbsp;&lt;a href="http://eper.ec.europa.eu/eper/flashmap.asp?sid=40274"&gt;Flash Interface&lt;/a&gt; to the EPER data, but it could easily be done in OpenLayers... Anyone?&lt;br /&gt;&lt;br /&gt;Anyway, that's how to get some mdb database into spatialite and plot it in Qgis!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-4516331738548754681?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/4516331738548754681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2009/12/converting-mdb-to-spatialite.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/4516331738548754681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/4516331738548754681'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2009/12/converting-mdb-to-spatialite.html' title='Converting an mdb to spatialite'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_7N-9AwC5AHs/SxVnQ4EQ2FI/AAAAAAAADTQ/JBozl-_QEw4/s72-c/eper.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-2544086156741838362</id><published>2009-11-16T19:01:00.000Z</published><updated>2009-11-16T19:01:10.398Z</updated><title type='text'>Choropleth mapping challenge in Qgis</title><content type='html'>Making choropleth maps - how hard can it be? It's just a bunch of data colouring another bunch of polygons, right?&lt;br /&gt;&lt;br /&gt;This all started over at&amp;nbsp;&lt;a href="http://flowingdata.com/2009/11/12/how-to-make-a-us-county-thematic-map-using-free-tools/"&gt;Flowing Data&lt;/a&gt; where Nathan used Python to hack an existing SVG file to colour the counties of the US according to data read in from a file of county unemployment levels. Dave Smith of Revolution Computing issued a challenge:&amp;nbsp;&lt;a href="http://blog.revolution-computing.com/2009/11/choropleth-map-r-challenge.html"&gt;do this in R&lt;/a&gt;. I'm always up for a challenge so I found a shapefile of the US counties with the FIPS county codes, and then using the rgdal and sp packages had a plot up in about twenty minutes. The next day Dave posted the&amp;nbsp;&lt;a href="http://blog.revolution-computing.com/2009/11/choropleth-challenge-result.html"&gt;challenge results.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Today on the R-Sig-Geo mailing list there has been a bit of traffic on using R or GIS for cartography. Various people arguing one way or the other about how what constitutes 'publication quality' and various opinions bouncing around. So I thought I'd revisit the challenge - this time using open-source GIS software.&lt;br /&gt;&lt;br /&gt;Problem one is getting the unemployment data and map data - the unemployment data is linked as a CSV file from the Flowing Data blog entry, and shapefiles of US counties are downloadable after a quick google search.&lt;br /&gt;&lt;br /&gt;There are various variations of the US counties depending on the time they were defined, whether Alaska and Hawaii are in their proper place or tucked neatly around the 'lower 48' to make mapping easier, and whether the data has the right FIPS codes. I found a shapefile with county data from 2000, full FIPS codes, and with AK and HI slotted in.&lt;br /&gt;&lt;br /&gt;The next step is to create a geographic data set with the unemployment data as attributes. But first I had to fiddle with the CSV file. It had the FIPS codes in two parts - one for the state and one for the county. The full FIPS code is five digits, made up from the two parts with leading zeroes. I didn't want to use R or Python for this, so I loaded the CSV into Calc, the spreadsheet component of OpenOffice.&lt;br /&gt;&lt;br /&gt;The first thing I did was to shift all the data down one row and add some headers. The only important ones are the two parts of the FIPS codes and the unemployment percentage. &lt;br /&gt;&lt;br /&gt;To create the full FIPS code I have to concatenate the two parts (in columns B and C) with the leading zeroes - I put this formula into J2 and copy it down the column:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New [monotype]&amp;quot;, &amp;quot;Courier [Adobe]&amp;quot;, monospace;"&gt;&amp;nbsp;=CONCATENATE(TEXT(B2;"00");TEXT(C2;"000"))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;then I add the word 'FIPS' as the header in J1 for this column.&lt;br /&gt;&lt;br /&gt;Now I have a spreadsheet with a FIPS and an UNEMPLOYMENT column, and a shapefile with a FIPS attribute. How do I join them?&lt;br /&gt;&lt;br /&gt;A couple of ways spring to mind:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Load everything into PostGIS and do a join or create a view&lt;/li&gt;&lt;li&gt;Create a shapefile with the Unemployment data in the DBF&lt;/li&gt;&lt;/ol&gt;I think doing (1) isn't too difficult, but because I had OpenOffice open I figured I'd save the data as a DBF and see what I could do with &lt;a href="http://www.qgis.org/"&gt;Quantum GIS&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In the Tools menu of Qgis I found the Data Management options and the Join Attributes function. Exactly what I needed! I set my Join Data to be the DBF of the unemployment data and FIPS to be the field to join with. Hit OK, and in under a minute I had a shapefile with the DBF data in place.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_7N-9AwC5AHs/SwGelKX-1BI/AAAAAAAADS4/ikr1T5QBdZ8/s1600/join.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_7N-9AwC5AHs/SwGelKX-1BI/AAAAAAAADS4/ikr1T5QBdZ8/s320/join.png" /&gt;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;/div&gt;The new layer was loaded. Now all that was left was a bit of clicking in the Layer.. Properties.. Symbology dialog to colour the map in six classes with the same intervals as in the challenge, and using the same colours from the Color Brewer system. I also overlaid a state map with transparent fill and a thick solid white outline to get the same effect as the challenge map.&lt;br /&gt;&lt;br /&gt;Here's how it looks in Qgis:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_7N-9AwC5AHs/SwGfXWLWXaI/AAAAAAAADTA/FDS0AFCLVjY/s1600/screen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_7N-9AwC5AHs/SwGfXWLWXaI/AAAAAAAADTA/FDS0AFCLVjY/s320/screen.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Note the large chunk of Alaska missing - that's a non-matching FIPS code. Oh well, nothing's perfect!&lt;br /&gt;&lt;br /&gt;Qgis also has a map composer where you can do basic page layout for cartography. Here's one rendering of the unemployment map:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_7N-9AwC5AHs/SwGgf-SZkwI/AAAAAAAADTI/8AiJm4G9mEk/s1600/composer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_7N-9AwC5AHs/SwGgf-SZkwI/AAAAAAAADTI/8AiJm4G9mEk/s320/composer.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;Here you can add layers, legends, and text, and also play with fonts and spacing and sizes. The maps can be output to SVG and PDF.&lt;br /&gt;&lt;br /&gt;I'd call these publication-quality - at least they're a better quality than many maps I've seen published (wacky handwriting font excepted).&lt;br /&gt;&lt;br /&gt;This has taken me about 45 minutes while waiting for the rain to stop so I can go home. Any gvSIG orArcGIS people out there want to have a go?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-2544086156741838362?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/2544086156741838362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2009/11/choropleth-mapping-challenge-in-qgis.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/2544086156741838362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/2544086156741838362'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2009/11/choropleth-mapping-challenge-in-qgis.html' title='Choropleth mapping challenge in Qgis'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_7N-9AwC5AHs/SwGelKX-1BI/AAAAAAAADS4/ikr1T5QBdZ8/s72-c/join.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-7392364179727701553</id><published>2009-11-05T22:37:00.000Z</published><updated>2009-11-05T22:37:28.620Z</updated><title type='text'>Workshop Report</title><content type='html'>I've just got back from London after a trip for a one-day workshop on mapping software in health research organised by The &lt;a href="http://www.idrn.org/"&gt;Infectious Disease Research Network&lt;/a&gt;. It was held at the Royal Geographical Society buildings - a wonderful place filled with history from RGS expeditions of the past. &lt;br /&gt;&lt;br /&gt;The day was arranged by Mike Head of the IDRN and the meeting chaired by Prof. Graham Moon of Southampton University. The talks were varied enough to sustain interest for over a hundred people stuck in one room for the day. The applied talks before lunch combined the usual stories of fieldwork adventures with the gritty details of database servers and web mapping platforms.&lt;br /&gt;&lt;br /&gt;During lunch I set up my e-presentation. It was a series of animated slides talking about the use of open-source geospatial software. I also took the opportunity to distribute some flyers for my course in January and the OSGeo group. I talked through my case-studies several times to interested people and was losing my voice by the time I was finishing off my little sticky chocolate cake.&lt;br /&gt;&lt;br /&gt;After lunch two talks grabbed the audience - Tim Fendley's amusing tales of new map systems for pedestrians around London was illustrated by screenfuls of comic signage, many of which I encountered on my London wanderings the day after. Chris Phillips from MapAction talked about the work of getting maps and GIS technology out to disaster areas to help co-ordinate search, rescue, and aid deployment.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;The final talk was from Mikaela Keller on the Healthmap.org project. This is a system that takes news feeds and health data and maps it in real time. She talked about how a combination of computer language processing and human scanning produce reliable maps.&amp;nbsp; I'm still not sure how you could use this data to do rigorous statistical analysis but I don't think that's the point of it.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;After a summing-up from Graham we adjourned for wine and juice outside the hall, and then as numbered dwindled we remaining few jumped into a couple of taxis and headed for the John Snow pub in Soho. Dr John Snow was perhaps the first person to combine health and mapping when he plotted cases of cholera in 1854 and concluded the source was a water pump near where the pub that bears his name now stands. We raised our glasses to the good doctor after a day of discussion of the sort of work made possible by standing on his shoulders.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-7392364179727701553?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/7392364179727701553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2009/11/workshop-report.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/7392364179727701553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/7392364179727701553'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2009/11/workshop-report.html' title='Workshop Report'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-1866149031073399801</id><published>2009-10-07T16:00:00.000+01:00</published><updated>2009-10-07T16:00:54.339+01:00</updated><title type='text'>Pushing OpenSource in a grant bid</title><content type='html'>Today I've been writing a section on a research grant (as well as fixing the prof's typos and spellong misteaks). &amp;nbsp;It's great to be able to put the following into a proposal:&lt;br /&gt;&lt;br /&gt;&lt;div align="justify"&gt;&lt;span style="background-color: #ffe599;"&gt;"Software and accompanying documentation and training tools developed and released during the programme will be made available under an Open Source license. This will maximise its accessibility to users, especially those working in health institutions in developing countries. It also enables the project to accept improvements and fixes in the software from the wider community.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="background-color: #ffe599;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align="justify"&gt;&lt;span style="background-color: #ffe599;"&gt;The project will also commit to using Free and Open Source software as widely as possible within the research team, so that software solutions are developed that do not have proprietary components as part of their architecture".&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The computing infrastructure will include a database server (running PostGIS), a front-end (running Apache and serving maps via OpenLayers and maybe WFS/WMS services), and two compute engines churning out statistics with R. It'll be fun to put all these things together if we get the grant. I'm sure I'll blog the result when we get it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-1866149031073399801?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/1866149031073399801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2009/10/pushing-opensource-in-grant-bid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/1866149031073399801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/1866149031073399801'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2009/10/pushing-opensource-in-grant-bid.html' title='Pushing OpenSource in a grant bid'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-7226427077182484350</id><published>2009-10-03T17:52:00.000+01:00</published><updated>2009-10-03T17:52:01.141+01:00</updated><title type='text'>Tools I Use</title><content type='html'>This is just a list of software I use for work. Is there some way I can make these keywords on the blog?&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.ubuntu.com/"&gt;Ubuntu Linux&lt;/a&gt; - the free operating system &lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="href://www.r-project.org/"&gt;R&lt;/a&gt; - statistics software&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt;&amp;nbsp; - flexible programming language&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.qgis.org/"&gt;Quantum GIS&lt;/a&gt; - desktop GIS with Python extensibility&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.postgis.org/"&gt;PostGIS&lt;/a&gt; - spatial database&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.openlayers.org/"&gt;OpenLayers&lt;/a&gt; - Javascript client-side web maps&lt;/li&gt;&lt;/ul&gt;All good free and open source stuff. With these things I can build desktop applications, web maps, spatial data infrastructure and all that good stuff.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-7226427077182484350?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/7226427077182484350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2009/10/tools-i-use.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/7226427077182484350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/7226427077182484350'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2009/10/tools-i-use.html' title='Tools I Use'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2573156439353370360.post-7964600419386375901</id><published>2009-10-03T09:31:00.000+01:00</published><updated>2009-10-03T09:35:24.000+01:00</updated><title type='text'>GeoIntroduction</title><content type='html'>Morning all. This is my new blog site for all things generally work-related.&lt;br /&gt;&lt;br /&gt;I work in the School of Health and Medicine at Lancaster University within the 'CHICAS' group - Combining Health Information, Computation, and Statistics'. Basically a group of numerates doing data analysis of anything health or biomedicine related.&lt;br /&gt;&lt;br /&gt;Most of my activity centres round geographic data, so here I'll be posting useful snippets, questions, comments, rants and opinions, which will not necessarily be those of my employer. I might also wander off into general computing and IT areas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2573156439353370360-7964600419386375901?l=geospaced.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://geospaced.blogspot.com/feeds/7964600419386375901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://geospaced.blogspot.com/2009/10/geointroduction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/7964600419386375901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2573156439353370360/posts/default/7964600419386375901'/><link rel='alternate' type='text/html' href='http://geospaced.blogspot.com/2009/10/geointroduction.html' title='GeoIntroduction'/><author><name>Barry Rowlingson</name><uri>https://profiles.google.com/101824747394051662370</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-DQDd5t5rsV4/AAAAAAAAAAI/AAAAAAAAAAA/zQhCfXeSTcg/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
