Magic Rescue

December 13th, 2009

I needed to recover some photos from a memory card which had been wiped clean. After some basic research, I installed magicrescue. It is a command line program for Linux, and worked very well. It was able to recover 448MB files from a 512MB memory card.

Installing was simple using synaptic package manager in Ubuntu 9.10, then I had to plug in the memory card and find out what the device name was (Note: this is not the same as where the drive is mounted). For this I used the System > Administration > Disk Utility and found that it was /dev/sdc1

A folder was created to house the rescued photos,

mkdir ~/rec

Then the magic program run.

sudo magicrescue -r jpeg-exif -d ~/rec /dev/sdc1

About 4 minutes later, 160 photos were rescued. Now that is magic!

Troubleshooting gettext for php translation

April 18th, 2009

I was trying to deploy a translated peice of software on a newly installed server running debian, but whatever I did, the strings would not appear in the translated language.

A sample php page might look something like this:

<?php
$locale = "fr_FR";
putenv("LC_ALL=$locale");
setlocale(LC_ALL, $locale);
bindtextdomain("messages", "../locale");
textdomain("messages");
echo _("Name");
?>

Eventually I figured out that the setlocale() command was returning false, which means that the desired locale is not installed on the server.

To fix this, login as root and edit the file /etc/locale.gen

I have looked at another clean debian install, and it would appear that the default file only contains a single entry:

en_GB.UTF-8 UTF-8

I added a few more lines to this file, such as

de_DE.UTF-8 UTF-8
de_DE ISO-8859-1

and then (as root) ran

$ locale-gen

which generates the locales for the server. Then the gettext translation worked fine!

If your gettext does not work, check that your server is setup with the desired locale. You can get a list of them by running

$ locale -a

What country are you in?

March 31st, 2009

In a web application that I have been working on recently, it has been necessary to answer the question: what country is lat,lon in?

There are a number of ways of determining this, but as a starting point I decided to find the boundary of each country from osm data as a set of polygons.

After extracting the boundary data from osm, I found that the linestrings or ways (which when joined together form a polygon) where badly ordered and had lots of holes in them.

I spent a day trying to beat the osm boundaries into something decent, until I finally decided that there had to be an easier way. Then I stumbled across world boundaries at thematicmapping.org. The dataset is available under a Creative Commons Attribution-Share Alike License, so I’m sharing my success and files here.

I extracted the boundaries from shape files into mysql with some inspiration from Spincloud Labs, and then set about writing some basic spatial sql queries.

The information on the internet about the current state of mysql spatial queries is not extensive, so I updated my test mysql server to the latest version in case anything had changed and set about finding out if the within or contains functions work properly with mysql multipolygons. Even in MySQL 5.1.32 these two functions use MBR – minimum bounding rectangle. So rather than answer the point in poly question, queries such as

SELECT ID, NAME, CONTAINS( ogc_geom, GeomFromText('POINT(15 60)') ) AS C
FROM `world_boundaries` ORDER BY C DESC

would return Norway, Sweden, Russia and United States.

From there, it would be necessary to extract the multipolygon data, parse it into x and y values, then see which polygon it is within. I have written code for the point in poly before in a few languages, but parsing the whole of US,Norway,Swedish and Russian boundaries when a position is well within Sweden seemed a bit silly. There had to be a better way!

world_boundaries

In order to inspect the boundaries, I had written a simple polygon renderer. I set it to work on the worlds boundaries. Even at a multiplier of 20 (pixel width of the map is 360 times the multiplier, so for a multiplier value of 20 the map is 7200 x 3600 pixels) it only took a few seconds to render the map. Here each country is its ID in the rgb values of each pixel. Now, with a simple ‘what is the colour of pixel lat,lon‘ you can find out what country a pixel is in! Once the image is loaded in memory, this lookup is fast. (I have made it faster later – read on!)

Now it is important to ensure that there is no anti-aliasing on the image – otherwise it could cause problems. But still at country borders 1 pixel (1/20th of a degree) is a big brush, and I needed some way of flagging that a pixel is a country border, perhaps to use a finer algorithm to find out exactly which country. So, at any country borders, I changed the pixel colour to black. If the search returns 0 (black) as the country, then it must be ambigous! If the search retuns 255 (white) then it is sea. Otherwise, it is a country! I also performed quite a bit of cleaning up the data, such as removing small holes and expanding the edges at the coast.

I overlaid the map on the vector data, and found the two to be quite consistent with each other.

boundary_on_data

Now for some fine tuning to remove the need to load the whole 25 million pixels into memory before a search begins.

There are 246 countries in the dataset, plus 2 extra (black and white) which I have added for ambigous and sea. Thats a total of 248 – handy for fitting in 1 byte! Now we simply go along each x and y value of the image, look at the pixel rgb value, fit it into 1 byte ( & 0xFF ) and then stick it into a binary file. That file does end up being 25MB, but I can cope with that.

Now, to find the country ID of a latitude and longitude. I think some code here would be easier than explaining it! Here is some php:

$handle = fopen("world_boundaries.bin",'r');
function get_country(&$handle,$long,$lat){
	$mult = 20;
	$x = round(($long+180)*$mult);
	$y = round((90-$lat)*$mult);
	$pos = round( ($y*360*$mult) + $x);
	fseek($handle, (int)$pos, SEEK_SET);
	return ord(fgetc($handle));
}
print "You are in country ".get_country($handle,-2.0,53.1);
fclose($handle);

The x value is between 0 and 7200, and y value is (negative downwards) between 0 and 3200. From this the position is found in the file, and the easiest way to return 1 byte in a file in php to to use fgetc.

I expect this to be fast. There is only one file involved, as there is no locking or checking for pretty much anything!

When looking up random locations around the world, each lookup would take about 0.02 milliseconds on my test server. That I suggest is pretty good!

Now, if this function returns 255, you are at sea. If it returns 0, you are on a country border and you will need to check in more detail.

Downloads:

The dataset is available under a Creative Commons Attribution-Share Alike License

World image file: 7200 x 3600. 375kB

World boundary binary file. Compressed, 215kB

Simple Guitar Songs

January 1st, 2009

I enjoy playing tunes on the guitar. People around me probably don’t appreciate the out of time and out of tune nature of my playing as much as I do, but that is their loss.
There are a few chords on the guitar that are easy to play, and these include A, Am, D, G, C, E, Em. There are other common chords which are harder play, especially bar chords including F and Bm.
So the trick when looking for songs is to find songs which use the simple chords, and hold them for at least a few beats each. Some tunes change chords so quickly that it is hard to keep up!
Here is a jumbled list of some tunes that I sometimes play, and if I can play them they must be simple.

Christian Tunes

Check out http://www.eileenjahna.com/worship/

Random Tunes

Check out http://www.ultimate-guitar.com/

  • Country Roads :  John Denver
  • The town I loved so well : Phil Coulter
  • The Fields of Athenry
  • Everything I do : Bryan Adams
  • Radio : Corrs

Victoria Sponge / Chocolate Sponge

January 1st, 2009

I’m sure most grandma’s bake cakes, but my grandma makes a particularly good sponge cake so I asked her for the recipe. I have no idea if this is the same as is found in other recipe books. Taste and see…

For 1 Cake
4 oz Marg/Butter
4 oz Caster Sugar
2 eggs, beaten
4 oz S R flour
Vanilla Essence

For Chocolate cake add 1 heaped desert spoon of coca, sieved together with
flour.

Method
Cream butter and sugar; add beaten eggs slowly while beating butter & sugar.
Gently stir in flour
Cook in 8″ tin which has been greased for 40/50 minutes at 160

Onward Christian Centre Service Times

December 28th, 2008

I find it hard to believe that any organisation does not have a website, or at least some basic web presence in our internet-based age. So when I decided I would pay a local church a visit, I wanted to know when their meeting times were. I looked and looked, and whilst I found a telephone number I could not find an email address or a website for them, and also could find no record of their service times.

In an attempt to fix this rift between the real and virtual worlds, I decided that I would document the service times here, both for my future benefit and any other casual observer. I take no responsibility for the accuracy or relevancy of this information!

OCC : Onward Christian Centre

71 Mottram Road, Hyde, SK14 2NR
Tel: 0161 351 9899

Sunday Service Times: 10.30 am and 6.30 pm

It is a small church, but the people there are very friendly, and I’m sure I will be going there again as soon as I have a Sunday morning free.

substr versus direct character reference in php

December 13th, 2008

In php there are a few ways to get a few characters from the middle of a string. One is to use substr:

string substr ( string $string, int $start [, int $length  ] )

another is by direct character reference:

string $chars = $string[0].$string[1];

When you only require a single character from a string, one would assume that direct character reference is quickest, and lots of characters are required, the overhead of a function call would be offset against the many string lookups.

One of the projects I am working on at the moment required the unpacking of fairly long strings, sometimes over 1024 bytes. Each byte dictated what the next few bytes are, and so every byte has to be analysed. Therefore I setup a simple test case to find out what the fastest way to do this was.

First, a simple timer function was needed. Here is the code I wrote a long time ago, and used many times.

function timer($stime=0,$btime=0){
   $time = explode(' ', microtime());
   $time = $time[1] + $time[0];
   if($stime){
      return round(($time - $stime - $btime)*1000,3);
   }
   return $time;
}

If you call this function with no arguments, it returns the current time in seconds, to many decimal places. If you then give this time value back to the function later, it will tell you the time difference in milliseconds

A single request for each of above methods would not suffice to compare them, and so each method is done many times within a for loop. This for loop has a fair amount of overhead, and so first the base time is calculated by running an empty for loop.

$num = 1000000;
$s = timer();
for($i=0;$i&lt;$num;$i++){}
$base = timer($s);
print "Loop test took ".$base." milliseconds\n";

When executed, we find that the for loop takes around 225 milliseconds to complete 1 million iterations.

Now for the actual tests (this one is for four characters, starting from the third character):

$s = timer();
for($i=0;$i&lt;$num;$i++){
	$var = substr($input,2,5);
}
print "substr() test took ".(timer($s)-$base)." milliseconds\n";

$s = timer();
for($i=0;$i&lt;$num;$i++){
	$var = $input[2].$input[3].$input[4].$input[5].$input[6];
}
print "char ref test took ".(timer($s)-$base)." milliseconds\n";

This outputs something like:

Loop test took 230.988 milliseconds
substr() test took 728.633 milliseconds
char ref test took 1263.388 milliseconds

so we can see that for extracting four characters, using substr is faster. The same is not true for one and two characters, as the following results show (averages of four runs):

Number of chars      substr() time/ms    direct char time/ms
   1                  713                 358
   2                  770                 630
   3                  753                 945
   4                  751                 1280
   5                  733                 1557

It can be seen that on my development system, using direct character reference is faster for two or less characters, and substr() is faster for three or more characters.

Trip round Europe

October 1st, 2008

European FlagI have wanted to do some travelling for a long while now, and had earmarked October this year for travelling around Eastern Europe with John. We hadn’t planned anthing until two days ago when we sat down and figured out some plans. We found that it took around one hour to plan each day’s trip, when you are looking at planes, trains and coaches, hostels etc. around an aread.

map of our trip round europe

Later today we are flying out of Liverpool Airport to Stockholm (Sweden), staying there a few days and then getting the ferry across to Tallinn (Estonia) to stay a few days there. After Tallinn we are moving on to Vilnius (Lithuania) and then onto Riga (Latvia). Anyone looking at a map might find this order strange, but the coaches worked better having longer journeys as it allowed a sleeper coach (~9 hours) rather than a ’short’ 4 hour hop which is inconvenient. Additionally, the coaches from Vilnius to Warsaw (Poland) went via Riga anyway, and Warsaw is our next destination. There we are spending a night before moving onto Vienna (Austria) for two nights.

From Vienna we are travelling by overnight coach to Split (Croatia) where we are going to hire a car for four days. Croatia is supposed to be a beautiful country, and from the pictures and stories that I have come across it looks amazing! We will be travelling all over Croatia by car, including staying at Zadar, Rijeka and Zagreb. Hopefully we will get time to climb some of the hills in Croatia too, as the scenery looks stunning.

Images from an amusing film, which involves a silly small car

Olympic Stadium, MunichFrom Zagreb we are travelling by overnight coach to Munich (Germany) where we are staying with a friend for a couple of days. Whilst there I really want to see the Olympic park. I have seen it on Google Earth and think that from a structural engineering viewpoint it looks really interesting.

After Munich, we are travelling across to Baden, which is near Zurich in Switzerland to see another friend. Hopefully whilst there we will get to do some hiking in the Alps and see some of the amazing Swiss countryside.

Finally, about a month after setting off I will be heading back to Liverpool airport from Basel airport. John is continuing on to Amsterdam, Frankfurt, Liepzig, Prague and some other random places before returning to Belfast via Birmingham. I would love to carry on, but I thought that four weeks was pushing it as I’m supposed to be working!

When I return I hope to have lots of photos and stories which I can share, but now I need to go and pack!

Blowout and new tyres on my bike

April 5th, 2008

Bike TyresThe tyres that I had on my red hybrid bike were getting a bit thin, and since pushing them to their limits the back tyre was showing the nylon threads. I decided it was time to get some new tyres, but as with most things kept putting it off.

When cycling to my sisters a week ago, I head a very loud ‘phftt’ which sounded like a gunshot, and my back tyre went flat. It didn’t surprise me, but was slightly annoying.

Schwalbe City tyresOnce back home (after walking the remainder of the way) I looked on ebay for some more tyres. The ones I had put on there a couple of years ago for my land end to John ‘O’ Groats trip were still available, but I decided to go for something a bit more stylish, and so opted for Schwalbe City kevlar lined tyre. I found it cheaper from an online shop (link) than on ebay, and so promptly trusted an online retailer that I had never seen before with £8.50 of my hard earned cash, and awaited delivery. It came very promptly, and I put it on with a new tube, and cycled 12 miles to Manchester and back. One of the concerns with this tyre is that it can slip in the wet, but the road was wet and in places snowy, and it didn’t seem to have any problems. Over the next few weeks if the road is deserted I might try to make it slip to find it’s limits, and until then I hope it doesn’t.

Nokia N95 and Ubuntu – Mobile Internet

April 2nd, 2008

T-mobile data card and its boxSince I had gotten rid of my T-Mobile contract for my laptop data card, when I needed internet on the move I needed to either rely on the browser and applications on my N95, or connect it to my laptop. Connecting in windows turned out to be harder than I expected, as the Nokia PC Suite really didn’t like my cheap bluetooth dongle. Ubuntu, however turned out to be a lot simpler than I expected. Here is a quick guide to what I did in case I ever need to do it again, or in case it helps you. Use it at your own risk!

Step 1: Check that GPRS data connection works on your mobile phone using the web browser included on the phone

Step 2: Check that your bluetooth dongle works in linux. You might need to install bluetooth utils for this.

Step 3: Turn on bluetooth on your phone. I recommend leaving it off most of the time for security reasons, but now is a good time to turn it on.

Step 4: Pair the phone and the computer: From your phone, go to the bluetooth menu (use the left and right arrow keys to move between tabs at the top) and select ’setup new pairing’. Your phone will search for devices, and hopefully find your computer which will be called <hostname>-0. Click on ‘pair’ and enter a pass code which you can choose. Your computer should then ask you for this pass code which you can enter again in the popup box.

I think that KPPP is one of the best dial-up programs, or at least one of the ones which I know how to use. If you don’t have it installed, install it with

sudo apt-get install kppp

This will add a button in the Application > Internet menu named ‘KPPP’. Click on this, and then you need to add a connection and modem. Click on ‘Configure’ and then ‘New’ (under the Accounts tab). Select ‘Manual Setup’. Then under the ‘Dial’ Tab, enter a connection name. I call mine ‘Vodafone 3G’. Add a number (*99***1#) to this connection by clicking on the ‘Add’ next to the ‘Phone number’ box. Click on ‘OK’ to save the number, then click on ‘OK’ again to get back to the KPPP configuration page. Select the ‘modems’ tab and click on ‘new’. Give the modem a name, I call mine ‘Nokia-N95′. In the Modem device box, select ‘/dev/rfcomm0′, and change the connection speed to 115200. Select the ‘Modem’ tab, and then click on ‘Modem Commands’ Set the ‘Initialisation String 2′ to ‘ATM0′

Click ‘OK’ a few times to get back to ‘KPPP’, and then click on ‘Connect’. If all is well, it should start talking to your modem and connect to the internet.

This could perhaps be a lot clearer, but if you have any questions please feel free to contact me.