Email

Posted by andrew Thu, 10 Jul 2008 10:30:00 GMT

I dropped out a couple of emails last week. Nothing spectacular, just general enquiries – one to my local council, one to my building society. Maybe it’s me, but in these days of blackberries, ‘always-on’ messaging and twitters going off left, right, and centre I’d be disappointed if I didn’t receive a response within a day or so.

From the council I received this auto reply:

"Thank you for your e-mail you sent to XXXXXX Borough
Council Customer Services. This is to confirm that we
have received your e--mail. If we cannot deal with your
enquiry ourselves then we shall forward it on to the
relevant department/officer who will endeavour to reply
within 7 working days. We will notify you who the email
has been referred to."

Seven working days? To forward and reply to an email? (It’s been six working days and I’ve heard nothing yet.)

I never heard back from the building society – not even an autoreply, and I’d forgotten all about it. Until today that is, when I received a letter from them which started:

"Dear Mr Larcombe
Thank you for your email on the 30th June. I can confirm...."

Yup. They’d replied to an email by letter! I guess it’s all done in the name of security (A Good Thing), it just seems very quaint.

Mapping Drupal 1

Posted by andrew Mon, 16 Jun 2008 10:14:00 GMT

Just finished a quick preview of the upcoming OpenLayers module for Drupal.

At present it provides a per-node and a view type and uses information from the Location module to position the nodes, using the node type to determine the icon to display on the map. Future plans are to use the taxonomy to determine the presentational aspects (node, colour etc) and use other types of geo location (eg geo microformats emedded in the node) to determine location.

The demo can be found at http://drupal.andrewl.net

Going The Right Way

Posted by andrew Wed, 04 Jun 2008 08:43:00 GMT

In a move that is sure to send Jeremy Clarkson into an apoplectic rage, the good councilors of Kensington & Chelsea have decided that cyclists will be allowed to ride the ‘wrong’ way up one-way streets.

The knee-jerk, common-sense reaction is that is just plain dangerous, but like so much alleged ‘common sense’ this kind of thinking is little more than common nonsense. It works well in many other busy European cities, essentially just legitimizes something that many cyclists have been doing for decades, and as for the ‘safety’ argument – cyclists practice Risk Compensation everytime they take to the roads.

Next, lets see on-the-spot £1000 fines for any driver who opens their car door without looking out for bikes, or pedestrians who step off the pavement without so much as a second glance – they’re the real dangers to cyclists. I’m off to find a one-way street to cycle down…

Security!

Posted by andrew Mon, 02 Jun 2008 21:55:00 GMT

I, for one, sleep better knowing just how vigilant BAA security is working to protect the public.

So what if security can be breached by just opening a set of double doors? At least we’re safe from T-shirts depicting armed 40-foot tall robots.

Off the mod_rails...

Posted by andrew Tue, 27 May 2008 16:36:00 GMT

mod_rails promises to be the holy grail for RoR hosting – seamless integration with apache (no more mongrel, lighttpd or proxies) and a simple setup process. Well, one out of two isn’t bad…

The docs say that you just neex to run
gem install passenger
passenger-install-apache2-module

The latter runs rake which compiles the apache library from source using (what appears to be an incomplete) version of the excellent boost templates/libraries.

It might be straightforward installing on a modern package managed distro (ubuntu, centos, etc_ but I had a fair bit of trouble convincing it to play nice. Here’s what I had to do to get it working on a fairly typical, but old, install of RedHat, with Apache2 compiled from source installed in /usr/local/apache2

  1. passenger-install-apache2-module didn’t believe apxs existed, so creating the environment variable APXS2 and adjusting the path was required:
    export APXS2=/usr/local/apache2/bin/apxs
    export PATH=$PATH:/usr/local/apache2/bin
    
  2. Next, the compilation of the apache module failed – the absence of non_type.hpp meant the compiler spewed out this error many times:
    ../../boost/config/suffix.hpp:490:32: boost/non_type.hpp: No such file or directory
    
    I’ve done a bit of work with the boost libraries before – they’re fairly lightweight and self-conained. In this case the fix was just to copy a single file from http://www.boost.org/doc/libs/1_34_1/boost/non_type.hpp to /usr/local/lib/ruby/gems/1.8/gems/passenger-1.0.5/ext/boost
  3. So far, so good – compilation works, but woah! RED FLASHING LIGHTS on linking…
    /usr/bin/ld: mod_passenger.so: undefined versioned symbol name std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::~basic_stringbuf [in-charge]()@@GLIBCPP_3.2
    /usr/bin/ld: failed to set dynamic section sizes: Bad value
    collect2: ld returned 1 exit status
    
    Uh, for some reason my default libstdc++ was only to be found in /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/ and this wasn’t getting picked up by the linker, even when it was added to LD_LIBRARY_PATH. The only thing left to do was hack the Rakefile to ensure that the correct shared libraries were being picked up by replacing
     linkflags << " -lstdc++ -lpthread ../boost/src/libboost_thread.a #{APR_LIBS}" 
    
    with
    linkflags << " -Xlinker -rpath /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/libstdc++.so -lpthre
    ad ../boost/src/libboost_thread.a #{APR_LIBS}" 
    

After those changes passenger-install-apache2-module played nice and compiled the module. And after reconfiguring a virtual host as per the mod_rails docs and restarting apache here we are, running on mod_rails.

Impressions? The very first time an http request to an application is made there seems to be quite a long delay – I guess this is because it practices some sort of lazy initialization. After that it seems to zip along pretty speedily, outperforming the classic Apache+mod_proxy+Mongrel setup.

Banks (still) don't get it... 3

Posted by andrew Thu, 22 May 2008 08:53:00 GMT

So fixated are the media by the technical side of security (chip-and-pin, secure websites, CDs in the post), it’s easy to forget that most fraud is carried out using social engineering techniques. Both parties need to be able to trust that are talking to who they think they are. With that in mind someone called me on the telephone last night purporting to be from my bank:

  • ‘Bank:’ Hello this is yyyy from xxxx bank. Before we continue this conversation I need to confirm that I’m speaking to Mr Larcombe. To confirm this, please could you tell me the first and third numbers of your security code.
  • Me: I’m sorry, I can’t do that until you can confirm that you’re from xxxx bank.
  • Bank:’ Sorry?
  • Me: You want me to tell you some of my security details – how do I know you’re calling from xxxx bank and not a fraudster
  • Bank:’ (Getting increasing perplexed) Well my name is yyyy and I’m from team 302 in building 1234 and the xxxx bank will only ever ask for two digits of your security code, so could I have the the first and third numbers of your security code please?
  • Me: Not until you prove you’re from the bank. Whatever this call is concerning, could you send me a message about it using the banks’ on-line messaging facility?
  • Bank: Errr, no I can’t do that as I’m not calling from Customer Services.
  • Me: Ok, thanks for your call. Goodbye. Bzzzzzzzzt.

Chances are the caller was genuine, but they just couldn’t understand that if they initiate a conversation the onus is on them to prove that they are genuine caller before asking me for sensitive information. No doubt though if this was an elaborate attempt at fraud I’d have been financially liable…

If Dr Frankenstein made bikes...

Posted by andrew Mon, 19 May 2008 21:13:00 GMT

Enter ‘The Mutant’ – an aluminium cross bike with a difference or two…

The Mutant

39×16 Singlespeed thanks to an On-One singlespeed kit and tensioner…

The Mutant

3T ‘Mutant’ stem, narrow, flat bars, dia-compe 288 reverse action brakes topped off with Cinelli cork ribbon…

The Mutant

Mavic MA3 on Shimano Sora hubs topped off with Specialized Borough CX tyres. 4ZA CB2 cyclocross cantis…

The Mutant

Very nippy on the road, not too shabby off road – a great compromise machine.

Digging Kriging

Posted by andrew Fri, 02 May 2008 09:40:00 GMT

Or… Kriging with GRASS, R and OS X

Given a set of points with attributes, how do you go about interpolating between those points to create a surface? The three most common methods of doing this are Inverse Distance Weighting (IDW), Regularized Spline with Tension (RST) and Kriging. GRASS GIS can natively create IDW and RST-based interpolated surfaces, but needs a little help from its friend R to do Kriging. Here’s a quick guide to setting up R with the associated packages on OSX so that you can create Krigged surfaces. This assumes that you’re already running GRASS 6 (if not, grab a copy of OpenOSX GRASS from http://www.openosx.com/grass/freedownload.html)

krig
Krigged surface, rendered with nviz

1. Install MacPorts: Download and install MacPorts, MacPorts is an easy to use system for building linux/unix libraries and apps on OSX

2. Install R, proj, gdal: Use MacPorts to install the statistical computing application ‘R’, cartographic projection library proj and geospatial data abstraction library gdal. Open up a terminal and type this in:

sudo port install R proj gdal

You’ll be asked for your password. Once you’ve done that MacPorts will download the source, compile and install R, proj and gdal. NB This takes a long while (> 1 hour on a MacBook 2.0GHz) so go outside and enjoy the sun, watch a film, go for a walk etc…

Install R packages R requires three additional packages installed before we get going. First off we need to install the rgdal package to get access to the gdal and proj libraries. Start up R by typing r at a terminal and hit enter. Then enter the following to download, compile and install the rgdal package.

install.packages(‘rgdal’, configure.args=’—with-proj-lib=/opt/usr/local/lib’)

Then enter the following to install the spgrass6 which gives R direct access to GRASS6 data:

install.packages(‘spgrass6’)

That’s it

To Krig a surface you’ll need to start GRASS, set the current region to the one that you wish to create a surface within (tip: use integer values for the boundaries of the region), then in a GRASS termnal start R by entering ‘r’

You can then adapt the following script, to create a krigged surface. This script is a modified version of the one found here. This script interpolates the points in the vector map name ‘points_to_krig’ with values in the field ‘dbl_1’. The kriging is carried out using a default linear variogram, and output to the GRASS raster k_surf. Save the script below to a file (eg /tmp/krig.txt) and run using r’s source() function eg source(’/tmp/krig.txt’)

##load the required libraries
library(gstat)
library(spgrass6)

##retrieve the GRASS6 environment
G <- gmeta6()

##load points
source_points <- readVECT6('points_to_krig')

#remove any duplicate points
my_points <- remove.duplicates(source_points)

## create a grid wihch will define the interpolation
grd <- gmeta2grd()

## make a new grid of (1)s
## be sure to use original data's proj data...
## doesn't work with the stuff stored in G...
new_grid <- SpatialGridDataFrame(grd, data=data.frame(k=rep(1,G$cols*G$rows)), proj4string=CRS(my_points@proj4string@projargs))

## init our gstat object, with the model formula
## note that coordinates are auto-identified from the GRASS object
g <- gstat(id="elev", formula=dbl_1 ~ 1, data=my_points)

## default linear variogram model
v.fit <- fit.variogram(variogram(g) ,vgm(model="Lin") )

## update gstat object with fitted variogram model
g <- gstat(g, id="elev", model=v.fit )

## interpolate with ord. kriging
k_surf <- predict(g, id='elev', newdata=new_data)

## write raster back to GRASS: interpolation and kriging variance:
## system('g.remove rast=elev.ok')
writeRAST6(k_surf, 'k_surf', zcol='elev.pred')
writeRAST6(k_surf, 'k_surf.var', zcol='elev.var')

#quit r
q()