Rendering of UK post codes

The other night I decided to download a database from wikileaks.org. It was from 2009 and contained all the UK post codes and their corresponding geolocation.

The most interesting thing I could think of to do with such a large dataset was to render it all out with colours matched to the intensity of spatial concentration of post codes.

The database came as a csv and I found that wasn’t very useful because the dataset was too large to load it all into memory at once. I needed a way to access bits and bits. At first I thought to read it part by part with PHP or Python, but then I realised it would be far easier to convert it to MySQL.

Converting the CSV with code was not an option because the same rules would apply, the database was to large to read in one go. I would have to split it up and it would just be too much work.

I remembered that phpMyAdmin had features to import a variety of formats so I tried that first. Three problems, two relates to upload limits and the third was the memory limit of the conversion itself. Basically the same as doing it myself with code, it was too large.

After some research I figured out that mysql comes bundled with an import tool so I tried that. Sure enough after a bit of configuring I got it running!

I had to manually create the table structure before I could import. Here is the structure I used:

CREATE TABLE `uk-post-codes-2009` (
 `PZ_Postcode` varchar(16) NOT NULL,
 `PZ_IntroductionDate` int(16) NOT NULL,
 `PZ_GridRefEast` int(11) NOT NULL,
 `PZ_GridRefNorth` int(11) NOT NULL,
 `PZ_County` varchar(8) NOT NULL,
 `PZ_District` varchar(8) NOT NULL,
 `PZ_Ward` varchar(8) NOT NULL,
 `PZ_UserType` int(11) NOT NULL,
 `PZ_GridStatus` int(11) NOT NULL,
 `PZ_Country` int(11) NOT NULL,
 `PZ_WardStatus` int(11) NOT NULL,
 `PZ_NHS_Code` varchar(8) NOT NULL,
 `PZ_NHS_Region` varchar(8) NOT NULL,
 `PZ_Long` float NOT NULL,
 `PZ_Lat` float NOT NULL,
 `PZ_OSRef` varchar(255) NOT NULL,
 `PZ_Update` varchar(17) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Then I simply ran the import tool in terminal.

mysqlimport -u root -proot uk_postcodes uk-post-codes-2009.csv

With the database imported I made a small php script to interface with the database.

<?php
if (isset($_GET['p'])) {
 $items = 10000;
 $off = (int) $_GET['p'];
 $off*= $items;
 $db = new PDO('mysql:host=localhost;dbname=uk_postcodes;charset=utf8', 'root', 'root');
 $stmt = $db->query('SELECT PZ_Long, PZ_Lat FROM `uk-post-codes-2009` LIMIT '. $off .' , ' . $items);
 $results = $stmt->fetchAll(PDO::FETCH_NUM);
 echo(json_encode($results));
 die();
}
?>

Then it was just a matter of plotting the geolocations to canvas.

<script type="text/javascript">
 var planet_size = 1200;
 var bounds = [49.724, -11.470, 62, 1.450];
 var _scale = planet_size * 0.9/ (bounds[3] - bounds[1]);
 var ctx, image, image_data, x, y, i, j;
 var draw_pixel = function(vec, radius) {
 x = vec[1];
 y = vec[0];
 if (x === "0" && y ==="0") {
 return 0;
 }
 x = parseFloat(x);
 y = parseFloat(y);
 x-= bounds[0]; y-= bounds[1];
 if (x * _scale >= planet_size || y * _scale >= planet_size) debugger;
 if (x * _scale < 0 || y * _scale < 0) debugger;
 x = planet_size - parseInt(x * _scale, 10);
 y = parseInt(y * _scale, 10);
 i = x * planet_size + y;
 for (j = 0; j < 3; j++) {
 if (image.data[i * 4+j] > 1)
 image.data[i * 4+j]--;
 if (image.data[i * 4+j] == 0) {
 image.data[i * 4+j] = 254;
 }
 }
 image.data[i * 4+3] = 255;
 return 1;
 }
 $(document).ready(function() {
 var canvas = $('#canvas')[0];
 ctx = canvas.getContext('2d');
 var json, vec;
 var start_n = function (n) {
 $.get('?p=' + n, function(data) {
 json = JSON.parse(data);
 image = ctx.getImageData(0, 0, planet_size, planet_size);
 for (var i = 0; i < json.length; i++) {
 vec = json[i];
 draw_pixel(vec, 2);
 }
 image.data = image_data;
 ctx.putImageData( image, 0, 0 );
 if (json.length) {start_n(n+1);}
 });
 };
 start_n(1);
 });
</script>

To get the geo-bounds I simply used OpenStreet maps export tool.

The render itself came out in black dots and lines on white. To invert it I used photoshop and applied a gradient mask.

Uk post codes render

 

Gameplay death system

Singleplayer

The player dies:

  • Player respawns at the last checkpoint after a few seconds.
  • All NPC respawn from that checkpoint on.

Multiplayer

A player dies:

  • Player is deactivated.
  • The teams move speed is reduced
  • Menu on the left with a count-down starts (60 seconds).
  • Once the count-down reaches zero the player can click a button to respawn at another random (alive) player that is not under threat.
  • Another player can revive the dead player before the count-down finishes.

All players dies / are dead:

  • All players are respawned at the last checkpoint after a few seconds.
  • All NPC respawn from that checkpoint on.