0f2b60c1c1c70f2da0929dff5b9ee7f5157a2d99
[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
11 my $zoom        = 0 ;
12 my $lat         = 0 ;
13 my $lng         = 0 ;
14 my $latpix      = 0 ;
15 my $lngpix      = 0 ;
16 my %tiles       = ( ) ;
17 my $tilex       = 0 ;
18 my $tiley       = 0 ;
19 my $nacount     = 0 ;
20 my %tile        = ( ) ;
21 my $top         = 0 ;
22 my $left        = 0 ;
23 my $count       = 0 ;
24 my $x           = '' ;
25 my $y           = '' ;
26 my $i           = 0 ;
27 my $j           = 0 ;
28 my $k           = 0 ;
29 my $ix          = 0 ;
30 my $iy          = 0 ;
31 my $im          = '' ;
32 my $white       = '' ;
33 my $sth         = '' ;
34 my $sti         = '' ;
35 my $curcol      = '' ;
36 my $value       = '' ;
37 my $file        = '' ;
38 my $imicon      = '' ;
39 my $imicon1     = '' ;
40 my $imicon2     = '' ;
41 my $maxzoom     = 10 ;
42 my $minzoom     = 2 ;
43 my $xiconoff    = 12 ;                                  # X Icon offset in pixels (width or lng)
44 my $yiconoff    = 12 ;                                  # Y Icon offset in pixels (height or lat)
45 my $xiconpix    = 24 ;                                  # Icon width in pixels
46 my $yiconpix    = 24 ;                                  # Icon width in pixels
47 my $path        = 'tiles/' ;
48 my $icon1       = 'images/gvp_icon_1.png' ;             # Zooms up to 7
49 my $icon2       = 'images/gvp_icon_2.png' ;             # Zooms after 7
50 my $dbh         = DBI->connect ( "dbi:Pg:dbname=volcano" , "" , "" , { AutoCommit => 1 } ) ;
51
52 # Make sure icon file exists...
53
54 if ( !(-e $icon1) or !(-e $icon2))                                      # Icon file missing - bad thing
55 {
56  print "Map Icon(s) missing\n" ;
57  exit ;
58 }
59
60
61 # Relations: 
62 # Y,Top,N,S,Lat,Height
63 # X,Left,E,W,Lng,Width
64
65 # (35,-89),(34,-90)
66
67 $dbh->do("drop table gvp_world_tiles") ;
68 $dbh->do("create table gvp_world_tiles (zoom int2,tilex int4,tiley int4,latpix int4,lngpix int4)") ;
69
70 $sth = $dbh->prepare("select (volpnt)[0] as lat, (volpnt)[1] as lng from gvp_world") ;
71
72 $sth->execute ;
73
74 while ( ($lat,$lng) = $sth->fetchrow_array )
75 {
76  $count++ ;
77
78  # Figure out what tiles are needed...
79
80  for ( $zoom = $minzoom; $zoom <= $maxzoom; $zoom++ )
81  {
82   $value = &Google_Tile_Factors($zoom) ;                # Calculate Tile Factors
83
84   ($latpix,$lngpix) = &Google_Coord_to_Pix( $value, $lat, $lng ) ;
85   %tiles = ( ) ;
86
87   ($tiley,$tilex) = &Google_Pix_to_Tile( $value, $latpix + $yiconoff, $lngpix + $xiconoff ) ;
88   $tiles{"$tiley $tilex"} = [$tilex, $tiley] ;
89
90   ($tiley,$tilex) = &Google_Pix_to_Tile( $value, $latpix + $yiconoff, $lngpix - $xiconoff ) ;
91   $tiles{"$tiley $tilex"} = [$tilex, $tiley] ;
92
93   ($tiley,$tilex) = &Google_Pix_to_Tile( $value, $latpix - $yiconoff, $lngpix + $xiconoff ) ;
94   $tiles{"$tiley $tilex"} = [$tilex, $tiley] ;
95
96   ($tiley,$tilex) = &Google_Pix_to_Tile( $value, $latpix - $yiconoff, $lngpix - $xiconoff ) ;
97   $tiles{"$tiley $tilex"} = [$tilex, $tiley] ;
98
99   foreach $x (keys %tiles)
100   {
101    $y = $tiles{$x} ;
102    $dbh->do("insert into gvp_world_tiles (zoom,tilex,tiley,latpix,lngpix) values ($zoom,$$y[0],$$y[1],$latpix,$lngpix)" ) ;
103   }
104  }
105
106  if ( int($count/100)*100 == $count )
107  {
108   print "Processed $count points...\n" ;
109  }
110 }
111
112 # Make sure there have been records to process before continuing...
113
114 if ( !$count )
115 {
116  $dbh->disconnect ;
117  print "No records to process...\n" ;
118  exit ;
119 }
120
121 print "Total Points: $count\n" ;
122
123 # Remove old images...
124
125 for ( $zoom = $minzoom; $zoom <= $maxzoom; $zoom++ )
126 {
127  system("rm tiles/$zoom/*") ;
128 }
129 # Open up map icon files as images...
130
131 $imicon1 = GD::Image->newFromPng( $icon1 ) ;
132 $imicon2 = GD::Image->newFromPng( $icon2 ) ;
133
134 # Create index...
135
136 $dbh->do("create index gvp_world_tiles_main on gvp_world_tiles (zoom,tilex,tiley)") ;
137 $dbh->do("analyze gvp_world_tiles") ;
138
139 # Create tiles by zoom...
140
141 $sth = $dbh->prepare("select distinct zoom,tilex,tiley from gvp_world_tiles") ;
142
143 $sth->execute ;
144
145 $count = 0 ;
146
147 while ( ($zoom,$tilex,$tiley) = $sth->fetchrow_array )
148 {
149  $count++ ;
150
151  # Calculate tile fields...
152
153  $file = $path . $zoom . '/v_' . $tilex . '_' . $tiley . '.png' ;
154
155  ($top,$left) = &Google_Tile_to_Pix( $value, $tiley, $tilex ) ;
156
157  # create a new image
158
159  $im = new GD::Image(256,256,0) ;
160
161  $white = $im->colorAllocate(255,255,255) ;
162
163  $im->interlaced('true') ;
164
165  $im->transparent($white) ;
166
167  $im->setThickness(1) ;
168
169  # Calculate which icon to use based on zoom...
170
171  if ( $zoom > 7 )
172  {
173   $imicon = $imicon2 ;
174  } else
175  {
176   $imicon = $imicon1 ;
177  }
178
179  $sti = $dbh->prepare("select latpix,lngpix from gvp_world_tiles where zoom = $zoom and tilex = $tilex and tiley = $tiley") ;
180
181  $sti->execute ;
182
183  while ( ($latpix,$lngpix) = $sti->fetchrow_array )
184  {
185   $ix = $lngpix - $left - $xiconoff ;                   # Remove half image size
186   $iy = $latpix - $top - $yiconoff ;                    # Remove half image size
187   $im->copy($imicon,$ix,$iy,0,0,$xiconpix,$yiconpix) ;
188  }
189
190  open PNG, ">$file" ;
191  print PNG $im->png ;
192  close PNG ;
193  chmod(0444, $file) ;
194  if ( int($count/100)*100 == $count )
195  {
196   print "Processed $count tiles...\n" ;
197  }
198 }
199 print "Processed $count total tiles...\n" ;
200
201 $dbh->do("drop table gvp_world_tiles") ;
202
203 $dbh->disconnect ;
204