fix biblionumber
[google-map-tiles.git] / tiles.pl
1 #!/usr/bin/perl -w
2 # Create Map overlay of worldwide volcanoes...
3 # Author. John D. Coryat 02/2010...
4 # Copyright 1997-2010 USNaviguide LLC. All rights reserved.
5
6 use DBI ;
7 use strict ;
8 use GD ;
9 use USNaviguide_Google_Tiles ;
10 use File::Path;
11
12 my $name = shift @ARGV || die "usage: $0 database\n";
13
14 warn "WORKING on $name\n";
15
16 my $zoom        = 0 ;
17 my $lat         = 0 ;
18 my $lng         = 0 ;
19 my $latpix      = 0 ;
20 my $lngpix      = 0 ;
21 my %tiles       = ( ) ;
22 my $nacount     = 0 ;
23 my %tile        = ( ) ;
24 my $top         = 0 ;
25 my $left        = 0 ;
26 my $count       = 0 ;
27 my $x           = '' ;
28 my $y           = '' ;
29 my $i           = 0 ;
30 my $j           = 0 ;
31 my $k           = 0 ;
32 my $ix          = 0 ;
33 my $iy          = 0 ;
34 my $im          = '' ;
35 my $white       = '' ;
36 my $sth         = '' ;
37 my $sti         = '' ;
38 my $curcol      = '' ;
39 my $value       = '' ;
40 my $file        = '' ;
41 my $imicon      = '' ;
42 my $imicon1     = '' ;
43 my $imicon2     = '' ;
44 my $maxzoom     = 10 ;
45 my $minzoom     = 2 ;
46 my $path        = "$name/tiles" ;
47 my $icon1       = 'images/gvp_icon_1.png' ;             # Zooms up to 7
48 my $icon2       = 'images/gvp_icon_2.png' ;             # Zooms after 7
49 my $dbh         = DBI->connect ( "dbi:Pg:dbname=$name" , "" , "" , { AutoCommit => 1 } ) ;
50
51 # Make sure icon file exists...
52
53 if ( !(-e $icon1) or !(-e $icon2))                                      # Icon file missing - bad thing
54 {
55  print "Map Icon(s) missing\n" ;
56  exit ;
57 }
58
59 sub get_icon {
60         my $zoom = shift;
61
62         # Calculate which icon to use based on zoom...
63         $imicon = GD::Image->newFromPng( $zoom > 7 ? $icon2 : $icon1 ) ;
64         my $merge = 90;
65
66         my $custom_icon = "$name/icons/$zoom.png";
67         if ( -e $custom_icon ) {
68                 $imicon = GD::Image->newFromPng( $custom_icon );
69                 $merge = 50;
70         }
71
72         my $xiconpix = $imicon->width;
73         my $yiconpix = $imicon->height;
74
75         # FIXME make click position configurable
76         my $xiconoff = $xiconpix / 2;
77         my $yiconoff = $yiconpix / 2;
78
79         return ( $xiconpix, $yiconpix, $xiconoff, $yiconoff, $merge );
80 }
81
82 # Relations: 
83 # Y,Top,N,S,Lat,Height
84 # X,Left,E,W,Lng,Width
85
86 # (35,-89),(34,-90)
87
88 eval { $dbh->do("drop table gvp_world_tiles") };
89 $dbh->do("create table gvp_world_tiles (zoom int2,tilex int4,tiley int4,latpix int4,lngpix int4)") ;
90
91 my $sql = "select (volpnt)[0] as lat, (volpnt)[1] as lng from gvp_world" ;
92 $sql    = "select (point)[0]  as lat, (point) [1] as lng from geo_count" if $name =~ m/koha/;
93 $sth = $dbh->prepare( $sql );
94
95 $sth->execute ;
96
97 while ( ($lat,$lng) = $sth->fetchrow_array )
98 {
99  $count++ ;
100
101  # Figure out what tiles are needed...
102
103  for ( my $zoom = $minzoom; $zoom <= $maxzoom; $zoom++ )
104  {
105   $value = &Google_Tile_Factors($zoom) ;                # Calculate Tile Factors
106
107   ($latpix,$lngpix) = &Google_Coord_to_Pix( $value, $lat, $lng ) ;
108   %tiles = ( ) ;
109
110   my ( $xiconpix, $yiconpix, $xiconoff, $yiconoff ) = get_icon $zoom;
111
112   my ($tiley,$tilex) = &Google_Pix_to_Tile( $value, $latpix + $yiconoff, $lngpix + $xiconoff ) ;
113   $tiles{"$tiley $tilex"} = [$tilex, $tiley] ;
114
115   ($tiley,$tilex) = &Google_Pix_to_Tile( $value, $latpix + $yiconoff, $lngpix - $xiconoff ) ;
116   $tiles{"$tiley $tilex"} = [$tilex, $tiley] ;
117
118   ($tiley,$tilex) = &Google_Pix_to_Tile( $value, $latpix - $yiconoff, $lngpix + $xiconoff ) ;
119   $tiles{"$tiley $tilex"} = [$tilex, $tiley] ;
120
121   ($tiley,$tilex) = &Google_Pix_to_Tile( $value, $latpix - $yiconoff, $lngpix - $xiconoff ) ;
122   $tiles{"$tiley $tilex"} = [$tilex, $tiley] ;
123
124   foreach $x (keys %tiles)
125   {
126    $y = $tiles{$x} ;
127    $dbh->do("insert into gvp_world_tiles (zoom,tilex,tiley,latpix,lngpix) values ($zoom,$$y[0],$$y[1],$latpix,$lngpix)" ) ;
128   }
129  }
130
131  if ( int($count/100)*100 == $count )
132  {
133   print "Processed $count points...\n" ;
134  }
135 }
136
137 # Make sure there have been records to process before continuing...
138
139 if ( !$count )
140 {
141  $dbh->disconnect ;
142  print "No records to process...\n" ;
143  exit ;
144 }
145
146 print "Total Points: $count\n" ;
147
148 # Remove old images...
149
150 for ( $zoom = $minzoom; $zoom <= $maxzoom; $zoom++ )
151 {
152  warn "clean $path/$zoom\n";
153  rmtree "$path/$zoom";
154  mkpath "$path/$zoom";
155 }
156 # Open up map icon files as images...
157
158 # Create index...
159
160 $dbh->do("create index gvp_world_tiles_main on gvp_world_tiles (zoom,tilex,tiley)") ;
161 $dbh->do("analyze gvp_world_tiles") ;
162
163 # Create tiles by zoom...
164
165 $sth = $dbh->prepare("select distinct zoom,tilex,tiley from gvp_world_tiles") ;
166
167 $sth->execute ;
168
169 $count = 0 ;
170
171 while ( my ($zoom,$tilex,$tiley) = $sth->fetchrow_array )
172 {
173  $count++ ;
174
175  # Calculate tile fields...
176
177  $file = $path . '/' . $zoom . '/v_' . $tilex . '_' . $tiley . '.png' ;
178
179  ($top,$left) = &Google_Tile_to_Pix( $value, $tiley, $tilex ) ;
180
181  # create a new image
182
183  $im = new GD::Image(256,256,0) ;
184
185  $white = $im->colorAllocate(255,255,255) ;
186
187  $im->interlaced('true') ;
188
189  $im->transparent($white) ;
190
191  $im->setThickness(1) ;
192
193  my ( $xiconpix, $yiconpix, $xiconoff, $yiconoff, $merge ) = get_icon $zoom;
194
195  $sti = $dbh->prepare("select latpix,lngpix from gvp_world_tiles where zoom = $zoom and tilex = $tilex and tiley = $tiley") ;
196
197  $sti->execute ;
198
199  while ( ($latpix,$lngpix) = $sti->fetchrow_array )
200  {
201   $ix = $lngpix - $left - $xiconoff ;                   # Remove half image size
202   $iy = $latpix - $top - $yiconoff ;                    # Remove half image size
203 #  $im->copy($imicon,$ix,$iy,0,0,$xiconpix,$yiconpix) ;
204   $im->copyMerge($imicon,$ix,$iy,0,0,$xiconpix,$yiconpix,$merge) ;
205  }
206
207  open(my $PNG, '>', $file) || die "$file: $!";
208  print $PNG $im->png ;
209  close $PNG ;
210 # chmod(0444, $file) ;
211  if ( int($count/100)*100 == $count )
212  {
213   print "Processed $count tiles...\n" ;
214  }
215 }
216 print "Processed $count total tiles...\n" ;
217
218 #$dbh->do("drop table gvp_world_tiles") ;
219
220 # allow web server to select data
221 $dbh->do("grant select on gvp_world to public") ;
222
223 $dbh->disconnect ;
224