Hello,

I have rewritten the code of the script, since my first approach
was using an incredible amount of RAM if large areas like a whole country were 
defined.

So the below script will clean up ~/.viking-maps and only keep tiles
of areas defined in @boxes_degrees.


# cat list_unwanted_tiles.pl

#!/usr/bin/perl -w

# Author: Lixus Zoran <g...@muellers.ms>
# Function: List all map tiles that are not included in areas defined in 
@boxes_degrees
# Version: 0.2 
# Date: 16.04.2010
#
# Usage: list_unwanted_tiles.pl | tar --remove-files -cvf bakup_$(date 
+%F-%s).tar -T -

use strict;
use Math::Trig;

# bounding boxes of areas from which we like to to keep map the map tiles. 
# Format is: North South West East in HH.DDDDD format
my @boxes_degrees = (
  { N => '52.027', S => '51.884', W => '7.4984', E => '7.7498'},    # 
muenster/germany
  { N => '54.72', S => '54.179', W => '12.893', E => '13.897'},     # 
ruegen/germany
);

# build a data structure for each zoom level and for each bounding box 
# describing which tile numbers to keep ( most left, most right, most top, most 
bottom)
my %hash;
foreach my $box (@boxes_degrees) {
  for my $z ( 0 .. 17 ) {
    push(@{$hash{$z}}, TileBoundingBox(${$box}{N}, ${$box}{W}, ${$box}{S}, 
${$box}{E}, $z ));
  }
} 

open(FIND, "find $ENV{HOME}/.viking-maps/t* -type f |") or die "find open 
failed\n";
while (<FIND>) {
  chop;
  my ($tileT, $tileV, $tileY, $tileX) = m/t(\d+)s(\d+)z0\/(\d+)\/(\d+)/;
  my $tileZ = 17 - $tileV;
  my $keep=0;

  foreach my $bbox (@{$hash{$tileZ}}) {
    if ( $tileY ge $bbox->{N} and $tileY le $bbox->{S} ) {
      if ( $tileX ge $bbox->{W} and $tileX le $bbox->{E} ) {
        $keep=1;
      }
    }
  } 
  print $_,"\n" unless $keep;
} 
close(FIND) or die "find close failed";

# calculate the bounding box as tile numbers for a given zoom level
sub TileBoundingBox {
  my ($lat1, $lon1, $lat2, $lon2, $z) = @_;
  my ($N, $W) = getTileNumber($lat1, $lon1, $z);
  my ($S, $E) = getTileNumber($lat2, $lon2, $z);
  return {N => $N, S => $S, W => $W, E => $E};
} 

# calculate the tile number from lat/lon and zoom level
sub getTileNumber {
  my ($lat, $lon, $zoom) = @_;
  my $xtile = int(($lon + 180) / 360 * 2**$zoom);
  my $ytile = int( ( 1 - log(tan($lat * pi / 180) + sec($lat * pi /180))/pi) / 
2 * 2**$zoom);
  return (($xtile, $ytile));
} 

------------------------------------------------------------------------------
_______________________________________________
Viking-devel mailing list
Viking-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/viking-devel
Viking home page: http://viking.sf.net/

Reply via email to