aboutsummaryrefslogtreecommitdiffstats
path: root/maketiles
diff options
context:
space:
mode:
Diffstat (limited to 'maketiles')
-rwxr-xr-xmaketiles/10kfull192
-rwxr-xr-xmaketiles/10khalf180
-rw-r--r--maketiles/README28
-rwxr-xr-xmaketiles/fixindex26
-rwxr-xr-xmaketiles/packtiles157
5 files changed, 0 insertions, 583 deletions
diff --git a/maketiles/10kfull b/maketiles/10kfull
deleted file mode 100755
index 873818092..000000000
--- a/maketiles/10kfull
+++ /dev/null
@@ -1,192 +0,0 @@
-#!/usr/bin/perl -w
-#
-# 10kfull:
-# Turn the 1:10,000 Ordnance Survey map tiles into 254-by-254 pixmaps at full
-# resolution.
-#
-# Copyright (c) 2005 UK Citizens Online Democracy. All rights reserved.
-# Email: chris@mysociety.org; WWW: http://www.mysociety.org/
-#
-
-my $rcsid = ''; $rcsid .= '$Id: 10kfull,v 1.5 2006-09-20 15:01:56 chris Exp $';
-
-use strict;
-
-use Digest::SHA1;
-use Errno;
-use File::stat;
-use Geography::NationalGrid;
-use IO::Dir;
-use IO::File;
-
-use constant TILE_SIZE_PX => 7874;
-use constant TILE_SIZE_M => 5000;
-
-use constant SUBTILE_SIZE_PX => 254;
-use constant SUBTILES_PER_TILE => (TILE_SIZE_PX / SUBTILE_SIZE_PX);
-
-sub debug (@) {
- print STDERR @_;
-}
-
-sub System (@) {
- debug("executing command: ", @_, "\n");
- system(@_);
- die "command failed with status $?" if ($?);
-}
-
-die "arguments are directories containing input tiles in TIFF format and\n"
- . "to which output tiles are to be written, and optional eastings and\n"
- . "northings ranges, in the order west, east, south, north\n"
- if (@ARGV != 2 && @ARGV != 6);
-
-my ($inputdir, $outputdir) = @ARGV;
-$inputdir =~ s#/$##;
-$outputdir =~ s#/$##;
-die "$inputdir: not a directory" if (!-d $inputdir);
-die "$outputdir: not a directory" if (!-d $outputdir);
-
-my $inarea = 0;
-my ($west, $east, $south, $north);
-
-if (@ARGV == 6) {
- $inarea = 1;
- foreach (@ARGV[2 .. 5]) {
- die "'$_' is not a valid number\n" if (!/^[1-9]\d*$/);
- }
- ($west, $east, $south, $north) = @ARGV[2 .. 5];
- die "EAST must be greater than WEST" unless ($east > $west);
- die "NORTH must be greater than SOUTH" unless ($north > $south);
-
- debug("area of interest: west $west, east $east, south $south, north $north\n");
-}
-
-#
-# Within the output directory we create a subdirectory tiles/ containing tile
-# images named for their SHA1 checksums, and a text file mapping tile
-# coordinates to the SHA1 sums.
-#
-
-die "$outputdir/tiles: $!"
- if (!mkdir("$outputdir/tiles", 0755) && !$!{EEXIST});
-
-my $index = new IO::File("$outputdir/index", O_WRONLY | O_CREAT | O_TRUNC, 0644)
- or die "$outputdir/index: $!";
-
-$index->print(<<EOF);
-# This index file connects individual tiles of the 1:10,000 Ordnance Survey
-# maps at their full resolution (0.635m/px). Each such tile is 254 by 254
-# pixels. The tiles are indexed according to their coordinates within the full
-# Ordnance Survey grid, with (0, 0) being the tile at the SW corner of the grid
-# (immediately NE of the origin), (1, 0) being the tile to its east, and (0, 1)
-# the tile immediately to its north. Note that not all tiles are present. For
-# each such tile position this file lists the SHA1 message-digest of the image
-# file which represents the tile.
-EOF
-
-my $d = new IO::Dir($inputdir)
- or die "$inputdir: $!";
-
-my $total_input_size = 0; # KB
-my $total_output_size = 0; # KB
-while (my $name = $d->read()) {
- next unless ($name =~ /\.tiff?$/i);
- debug("have image file $inputdir/$name\n");
-
- my ($gridsq, $offset, $quadrant)
- = map { uc($_) } ($name =~ /^([A-Z]{2})(\d{2})([NS][EW])\./i);
-
- if (!$gridsq) {
- debug(" -> doesn't seem to be a valid 1:10,000 image tile; ignoring\n");
- next;
- }
-
- debug(" -> grid square = $gridsq; offset = $offset; quadrant = $quadrant\n");
- my $p = new Geography::NationalGrid('GB',
- GridReference => "$gridsq $offset");
-
- my ($E, $N) = ($p->easting(), $p->northing());
- debug(" -> SW corner of grid square is at ($E, $N)\n");
-
- $N += TILE_SIZE_M if ($quadrant =~ /^N/);
- $E += TILE_SIZE_M if ($quadrant =~ /E$/);
- debug(" => SW corner of tile is at ($E, $N)\n");
-
- if ($inarea) {
- my $tE = $E + TILE_SIZE_M;
- my $tW = $E;
- my $tN = $N + TILE_SIZE_M;
- my $tS = $N;
-
- if ($tE < $west || $tW > $east
- || $tN < $south || $tS > $north) {
- debug(" tile is outside area of interest; skipping\n");
- next;
- }
- }
-
- my $st = stat("$inputdir/$name");
- my $input_tile_size = $st->size();
- debug(" tile size = $input_tile_size bytes\n");
- $total_input_size += $input_tile_size / 1024.;
-
-
-
- # Figure out the tile offsets.
- my $x = ($E / TILE_SIZE_M) * SUBTILES_PER_TILE;
- my $y = ($N / TILE_SIZE_M) * SUBTILES_PER_TILE;
- debug(" => subtile col/row for SW-most subtile is ($x, $y)\n");
-
- # Now split this tile into subtiles.
- System("tifftopnm $inputdir/$name |"
- . " pnmtilesplit -P -f '$outputdir/%d,%d.png'"
- . " -p 'pnmtopng -compression 9 2>/dev/null' 254 254");
-
- # Consider each of the subtiles.
- debug("finding SHA1 digests of tiles and adding them to index...\n");
- my $nduplicates = 0;
- my $nnew = 0;
- my $size = 0;
- for (my $j = 0; $j < SUBTILES_PER_TILE; ++$j) {
- debug("\r$j/", SUBTILES_PER_TILE);
- my $j2 = SUBTILES_PER_TILE - 1 - $j;
- for (my $i = 0; $i < SUBTILES_PER_TILE; ++$i) {
- my $fn = "$outputdir/$i,$j2.png";
- my $f = new IO::File($fn, O_RDONLY)
- or die "$fn: $!";
- my $sha = new Digest::SHA1();
- $sha->addfile($f);
- $sha = $sha->hexdigest();
- $f->close();
- $index->printf("%d %d %s\n", $x + $i, $y + $j, $sha);
- my ($n1, $n2, $n3) = ($sha =~ /^(.)(.)(.)/);
- mkdir("$outputdir/tiles/$n1");
- mkdir("$outputdir/tiles/$n1/$n2");
- mkdir("$outputdir/tiles/$n1/$n2/$n3");
- my $fn2 = "$outputdir/tiles/$n1/$n2/$n3/$sha.png";
- if (-e $fn2) {
- unlink($fn);
- ++$nduplicates;
- } else {
- rename($fn, $fn2) or die "rename: $!";
- ++$nnew;
- my $st = stat($fn2);
- $size += $st->size();
- }
- }
- }
- debug("\r", SUBTILES_PER_TILE, "/", SUBTILES_PER_TILE, "\n");
- debug("had $nduplicates duplicate tiles + $nnew new, $size bytes\n");
- debug(" output subtiles are ",
- sprintf('%.1f%%', 100 * $size / $input_tile_size),
- " of input tile size for this tile\n");
- $total_output_size += $size / 1024.;
- debug(" so far total input size ",
- sprintf('%.1fKB', $total_input_size), "\n");
- debug(" so far total output size ",
- sprintf('%.1fKB', $total_output_size), "\n");
- debug(" output subtiles are ",
- sprintf('%.1f%%', 100 * $total_output_size / $total_input_size),
- " of input tile size so far overall\n");
- $index->flush();
-}
diff --git a/maketiles/10khalf b/maketiles/10khalf
deleted file mode 100755
index 48d59bc24..000000000
--- a/maketiles/10khalf
+++ /dev/null
@@ -1,180 +0,0 @@
-#!/usr/bin/perl -w
-#
-# 10khalf:
-# Generate half-scale 1:10,000 Ordnance Survey map tiles from the
-# full-resolution ones generated by 10kfull.
-#
-# Copyright (c) 2005 UK Citizens Online Democracy. All rights reserved.
-# Email: chris@mysociety.org; WWW: http://www.mysociety.org/
-#
-
-my $rcsid = ''; $rcsid .= '$Id: 10khalf,v 1.1 2006-09-14 21:43:15 chris Exp $';
-
-use strict;
-
-use Digest::SHA1;
-use File::stat;
-use IO::File;
-
-sub debug (@) {
- print STDERR @_;
-}
-
-sub System (@) {
- #debug("executing command: ", @_, "\n");
- # need bash for <( ) command substitution
- system("/bin/bash", '-c', join(' ', @_));
- die "command failed with status $?" if ($?);
-}
-
-die "arguments are directory containing output files from 10kfull and directory to which the half-resolution tiles are to be written"
- if (2 != @ARGV);
-
-my ($inputdir, $outputdir) = @ARGV;
-$inputdir =~ s#/$##;
-$outputdir =~ s#/$##;
-die "$inputdir: not a directory" if (!-d $inputdir);
-die "$outputdir: not a directory" if (!-d $outputdir);
-
-#
-# Within the output directory we create a subdirectory tiles/ containing tile
-# images named for their SHA1 checksums, and a text file mapping tile
-# coordinates to the SHA1 sums.
-#
-
-die "$outputdir/tiles: $!"
- if (!mkdir("$outputdir/tiles", 0755) && !$!{EEXIST});
-
-my $index = new IO::File("$outputdir/index", O_WRONLY | O_CREAT | O_TRUNC, 0644)
- or die "$outputdir/index: $!";
-
-$index->print(<<EOF);
-# This index file connects individual tiles of the 1:10,000 Ordnance Survey
-# maps at half their original resolution (1.27m/px). Each such tile is 254 by
-# 254 pixels. The tiles are indexed according to their coordinates within the
-# full Ordnance Survey grid, with (0, 0) being the tile at the SW corner of the
-# grid (immediately NE of the origin), (1, 0) being the tile to its east, and
-# (0, 1) the tile immediately to its north. Note that not all tiles are
-# present. For each such tile position this file lists the SHA1 message-digest
-# of the image file which represents the tile.
-EOF
-
-my $in_index = new IO::File("$inputdir/index", O_RDONLY)
- or die "$inputdir/index: $!";
-
-my %fullrestiles = ( );
-my %halfrestiles = ( );
-
-my $line;
-while (defined($line = $in_index->getline()) && $line =~ /^#/) { }
-if (!defined($line)) {
- if ($in_index->error()) {
- die "$inputdir/index: $! (while reading header)";
- } else {
- die "$inputdir/index: premature EOF (while reading header)";
- }
-}
-
-debug("reading $inputdir/index... ");
-my $ntiles = 0;
-my $nhalfrestiles = 0;
-do {
- chomp($line);
- my ($i, $j, $sha1) = split(/\s+/, $line);
- die "$inputdir/index: bad index line '$line'"
- unless (defined($i) && defined($j) && defined($sha1)
- && $i =~ /^(0|[1-9]\d*)$/ && $j =~ /^(0|[1-9]\d*)$/
- && $sha1 =~ /^[0-9a-f]{40}$/);
-
- my $i2 = int($i / 2);
- my $j2 = int($j / 2);
- my $k = pack('II', $i2, $j2);
- if (!exists($halfrestiles{$k})) {
- ++$nhalfrestiles;
- $halfrestiles{$k} = undef;
- }
-
- $fullrestiles{pack('II', $i, $j)} = $sha1;
- ++$ntiles;
-} while (defined($line = $in_index->getline()));
-
-die "$inputdir/index: $!" if ($in_index->error());
-$in_index->close();
-debug("done\n");
-
-debug("read $ntiles from index\n");
-debug("have $nhalfrestiles to generate\n");
-
-System("ppmmake '#ffffff' 254 254 > $outputdir/blank.ppm");
-
-sub imgname ($) {
- my $sha1 = shift;
- if (!defined($sha1)) {
- return "$outputdir/blank.ppm";
- } else {
- $sha1 =~ s#^(.)(.)(.)(.+)$#$1/$2/$3/$1$2$3$4#;
- return "<( pngtopnm $inputdir/tiles/$sha1.png )";
- }
-}
-
-my %compose = ( );
-my $nnew = 0;
-my $nduplicates = 0;
-my $size = 0;
-foreach my $k (keys(%halfrestiles)) {
- my ($i2, $j2) = unpack('II', $k);
- my @t = ( );
- my $n = 0;
- for (my $j = 0; $j <= 1; ++$j) {
- for (my $i = 0; $i <= 1; ++$i) {
- $t[$n] = $fullrestiles{pack('II', 2 * $i2 + $i, 2 * $j2 + $j)};
-# debug("img #$n is ", defined($t[$n]) ? $t[$n] : '(blank)', "\n");
- ++$n;
- }
- }
-
- my $c = join(',', map { defined($_) ? $_ : '*' } @t);
- my $fn = "$outputdir/out.png";
- my $sha;
-
- if (exists($compose{$c})) {
- # we've already made this image
- $sha = $compose{$c};
- } else {
- # make it
- @t = map { imgname($_) } @t;
- System("pnmcat -tb <( pnmcat -lr $t[0] $t[1] ) <( pnmcat -lr $t[2] $t[3] )"
- . " | pnmscale -reduce 2 2>/dev/null"
- . " | pnmtopng -compression 9 2>/dev/null > $fn");
-
- my $f = new IO::File($fn, O_RDONLY)
- or die "$fn: $!";
- $sha = new Digest::SHA1();
- $sha->addfile($f);
- $sha = $sha->hexdigest();
- $f->close();
-
- $compose{$c} = $sha;
- }
-
- $index->printf("%d %d %s\n", $i2, $j2, $sha);
- my ($n1, $n2, $n3) = ($sha =~ /^(.)(.)(.)/);
- mkdir("$outputdir/tiles/$n1");
- mkdir("$outputdir/tiles/$n1/$n2");
- mkdir("$outputdir/tiles/$n1/$n2/$n3");
- my $fn2 = "$outputdir/tiles/$n1/$n2/$n3/$sha.png";
- if (-e $fn2) {
- unlink($fn);
- ++$nduplicates;
- } else {
- rename($fn, $fn2) or die "rename: $!";
- ++$nnew;
- my $st = stat($fn2);
- $size += $st->size();
- }
-
- debug("have $nnew new, $nduplicates duplicates, total size $size bytes\n");
-}
-
-# get rid of the blank PPM.
-unlink("$outputdir/blank.ppm");
diff --git a/maketiles/README b/maketiles/README
deleted file mode 100644
index 64c6bb380..000000000
--- a/maketiles/README
+++ /dev/null
@@ -1,28 +0,0 @@
-File formats and structures
-
-Tiles are generated as PNG files. At the moment these are full-colour PNGs but
-in due course we will probably want to use dithered images with a limited
-palette. Generated tiles are named for their own SHA1 checksums, so that we
-can eliminate duplicate tiles. The first-stage output of these scripts,
-therefore, consists of a set of PNG files named by SHA1 and a text index which
-maps tile locations to SHA1s. These are arranged as:
-
- toplevel/index text index of tiles
- toplevel/tiles/0/0/0 location for images with SHA1s beginning
- 000
- toplevel/tiles/0/0/0/00000000000000000000.png
- first possible image file
-
-This format is not really acceptable for final deployment because many of the
-image files won't be much larger than a filesystem block, so a large amount of
-disk space would be wasted in storing them. Nor is the text index from tile
-location to SHA1 acceptable. So a second program packs the image files into
-catenated files with an index from SHA1 to offset and length in each file.
-Separately, the index from tile location to SHA1 is turned into another index.
-Both indices use Bernstein-style CDB files.
-
- toplevel/index.cdb binary index from tile location to SHA1
- toplevel/tiles/0/0/0/packed catenated file of images with SHA1s
- beginning 000
- toplevel/tiles/0/0/0/index.cdb index of images in packed
-
diff --git a/maketiles/fixindex b/maketiles/fixindex
deleted file mode 100755
index 8bfed69db..000000000
--- a/maketiles/fixindex
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/perl -w
-#
-# fixindex:
-# Fix the indices generated by the buggy version of 10kfull.
-#
-# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved.
-# Email: chris@mysociety.org; WWW: http://www.mysociety.org/
-#
-
-my $rcsid = ''; $rcsid .= '$Id: fixindex,v 1.2 2006-09-20 15:20:30 chris Exp $';
-
-use strict;
-
-use constant SUBTILES_PER_TILE => 31;
-
-while (defined(my $line = <STDIN>)) {
- chomp($line);
- if ($line =~ /^(0|[1-9]\d*) (0|[1-9]\d*) ([0-9a-f]+)$/) {
- my ($x, $y, $id) = ($1, $2, $3);
- $y = int($y / SUBTILES_PER_TILE) * SUBTILES_PER_TILE
- + SUBTILES_PER_TILE - 1 - ($y % SUBTILES_PER_TILE);
- print "$x $y $id\n";
- } else {
- print "$line\n";
- }
-}
diff --git a/maketiles/packtiles b/maketiles/packtiles
deleted file mode 100755
index dd12ae94f..000000000
--- a/maketiles/packtiles
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/usr/bin/perl -w
-#
-# packtiles:
-# Pack a tree of tiles etc. as generated by 10kfull etc. into the more efficient
-# packed format which is read by the tile server.
-#
-# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved.
-# Email: chris@mysociety.org; WWW: http://www.mysociety.org/
-#
-
-my $rcsid = ''; $rcsid .= '$Id: packtiles,v 1.3 2006-09-20 14:57:42 chris Exp $';
-
-use strict;
-
-use CDB_File;
-use Errno;
-use File::Slurp;
-use File::stat;
-use IO::Dir;
-use IO::File;
-
-use constant TILEID_LEN => 20;
-use constant BLOCKING => 14;
-
-sub debug (@) {
- print STDERR @_;
-}
-
-sub pack_tile_dir ($$) {
- my ($indir, $outdir) = @_;
-
-}
-
-# new_index_block
-#
-sub new_index_block () {
- # Initially all tiles are null so all bits are set.
- my $bitmaplen = int((BLOCKING * BLOCKING + 8) / 8);
- my $buf = "\xff" x $bitmaplen;
- $buf .= "\00" x (BLOCKING * BLOCKING * TILEID_LEN);
-}
-
-# add_tile_to_index_block BLOCK X Y ID
-#
-sub add_tile_to_index_block ($$$$) {
- my $x = $_[1];
- my $y = $_[2];
- my $id = $_[3];
-
- # clear the nullness bit.
- my $off = $x + $y * BLOCKING;
- my $b = unpack('C', substr($_[0], $off >> 3, 1));
- $b &= ~(1 << ($off & 7));
- substr($_[0], $off >> 3, 1) = pack('C', $b);
-
- # stick the tile itself in.
- my $bitmaplen = int((BLOCKING * BLOCKING + 8) / 8);
- substr($_[0], $bitmaplen + $off * TILEID_LEN, TILEID_LEN) = $id;
-}
-
-die "arguments are input (unpacked) tile directory, and output (packed)\n"
- . "tileset directories\n"
- if (@ARGV != 2);
-
-my ($inputdir, $outputdir) = @ARGV;
-$inputdir =~ s#/$##;
-$outputdir =~ s#/$##;
-die "$inputdir: not a directory" if (!-d $inputdir);
-die "$outputdir: not a directory" if (!-d $outputdir);
-
-# first make the index of tile locations to IDs.
-my %index;
-debug("reading index of tile locations to IDs...\n");
-my $f = new IO::File("$inputdir/index", O_RDONLY);
-my $len = stat($f)->size();
-my $n = 0;
-while (defined(my $line = $f->getline())) {
- debug("\rreading index: ", $f->tell(), "/$len bytes")
- if (0 == ($n % 100));
- ++$n;
-
- next if ($line =~ /^#/);
-
- chomp($line);
- my ($x, $y, $hash) = split(/ /, $line);
- my $id = pack('H*', $hash);
-
- my $x2 = int($x / BLOCKING);
- my $y2 = int($y / BLOCKING);
-
- $index{"$x2,$y2"} ||= new_index_block();
- add_tile_to_index_block(
- $index{"$x2,$y2"},
- $x % BLOCKING, $y % BLOCKING,
- $id);
-}
-debug("\rreading index: $len/$len bytes\n");
-
-die "$inputdir/index: $!" if ($f->error());
-$f->close();
-
-debug("writing index blocks to index.cdb... ");
-my $C = new CDB_File("$outputdir/index.cdb", "$outputdir/index.new");
-$C->insert(blocking => BLOCKING);
-foreach (keys(%index)) {
- $C->insert($_, $index{$_});
-}
-debug("done\n");
-debug("finalising index.cdb... ");
-$C->finish();
-debug("done\n");
-
-debug("packing individual tile directories...\n");
-$n = 0;
-mkdir("$outputdir/tiles");
-for (my $u = 0; $u < 4096; ++$u) {
- my $subpath = sprintf('%x/%x/%x', $u & 0xf, ($u >> 4) & 0xf, $u >> 8);
-
- next unless (-d "$inputdir/tiles/$subpath");
-
- # Ensure the path exists.
- foreach my $p (qw(1 3 5)) {
- my $d = "$outputdir/tiles/" . substr($subpath, 0, $p);
- die "$d: mkdir: $!" if (!mkdir($d) && !$!{EEXIST});
- }
-
- my $in = "$inputdir/tiles/$subpath";
- my $out = "$outputdir/tiles/$subpath";
-
- my $f = new IO::File("$out/tiles", O_WRONLY | O_CREAT | O_TRUNC, 0644)
- or die "$out/tiles: open: $!";
- $C = new CDB_File("$out/tiles.cdb", "$out/tiles.tmp");
- my $d = new IO::Dir($in) or die "$in: $!";
- while (my $name = $d->read()) {
- next unless ($name =~ /^([0-9a-f]+)\.png$/);
- my $id = pack('H*', $1);
- my $buf = read_file("$in/$name") or die "$in/$name: $!";
-
- die "$in/$name: length of file read by File::Slurp did not match stat"
- unless (stat("$in/$name")->size() == length($buf));
-
- my $rec = sprintf('%x:%x', $f->tell(), length($buf));
- $C->insert($id, $rec);
-
- $f->print($buf) or die "$out/tiles: $!";
-
- ++$n;
- }
-
- $f->close();
- $C->finish();
-
- debug("\rpacking tiles: $u/4096");
-}
-
-debug("\rpacking tiles: 4096/4096\n");
-debug("packed $n tiles total\n");