| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package HTML::GoogleMaps::V3; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | =head1 NAME | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  | HTML::GoogleMaps::V3 - a simple wrapper around the Google Maps API | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | =for html | 
| 8 |  |  |  |  |  |  |   | 
| 9 |  |  |  |  |  |  |   | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | =head1 VERSION | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | 0.15 | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | use HTML::GoogleMaps::V3 | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | $map = HTML::GoogleMaps::V3->new; | 
| 20 |  |  |  |  |  |  | $map->center("1810 Melrose St, Madison, WI"); | 
| 21 |  |  |  |  |  |  | $map->add_marker(point => "1210 W Dayton St, Madison, WI"); | 
| 22 |  |  |  |  |  |  | $map->add_marker(point => [ 51, 0 ] );   # Greenwich | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | my ($head, $map_div) = $map->onload_render; | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | =head1 NOTE | 
| 27 |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  | This module is forked from L and updated to use V3 of | 
| 29 |  |  |  |  |  |  | the API. Note that the module isn't quite a drop in replacement, although | 
| 30 |  |  |  |  |  |  | it should be trivial to update your code to use it. | 
| 31 |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  | Note that V3 of the API does not require an API key, however you can pass | 
| 33 |  |  |  |  |  |  | one and it will be used (useful for analytics). | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | Also note that this library only implements a subset of the functionality | 
| 36 |  |  |  |  |  |  | available in the maps API, if you want more then raise an issue or create | 
| 37 |  |  |  |  |  |  | a pull request. | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 40 |  |  |  |  |  |  |  | 
| 41 |  |  |  |  |  |  | HTML::GoogleMaps::V3 provides a simple wrapper around the Google Maps | 
| 42 |  |  |  |  |  |  | API. It allows you to easily create maps with markers, polylines and | 
| 43 |  |  |  |  |  |  | information windows. Thanks to Geo::Coder::Google you can now look | 
| 44 |  |  |  |  |  |  | up locations around the world without having to install a local database. | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | =head1 CONSTRUCTOR | 
| 47 |  |  |  |  |  |  |  | 
| 48 |  |  |  |  |  |  | =over 4 | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | =item $map = HTML::GoogleMaps::V3->new; | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | Creates a new HTML::GoogleMaps::V3 object. Takes a hash of options. | 
| 53 |  |  |  |  |  |  | Valid options are: | 
| 54 |  |  |  |  |  |  |  | 
| 55 |  |  |  |  |  |  | =over 4 | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | =item api_key => key (your Google Maps API key) | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | =item height => height (in pixels or using your own unit) | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | =item width => width (in pixels or using your own unit) | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | =item z_index => place on z-axis (e.g. -1 to ensure scrolling works) | 
| 64 |  |  |  |  |  |  |  | 
| 65 |  |  |  |  |  |  | =item geocoder => an object such as Geo::Coder::Google | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | =back | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | =back | 
| 70 |  |  |  |  |  |  |  | 
| 71 |  |  |  |  |  |  | =cut | 
| 72 |  |  |  |  |  |  |  | 
| 73 | 1 |  |  | 1 |  | 61002 | use strict; | 
|  | 1 |  |  |  |  | 10 |  | 
|  | 1 |  |  |  |  | 34 |  | 
| 74 | 1 |  |  | 1 |  | 4 | use warnings; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 29 |  | 
| 75 |  |  |  |  |  |  |  | 
| 76 | 1 |  |  | 1 |  | 689 | use Template; | 
|  | 1 |  |  |  |  | 21323 |  | 
|  | 1 |  |  |  |  | 1204 |  | 
| 77 |  |  |  |  |  |  |  | 
| 78 |  |  |  |  |  |  | our $VERSION = '0.15'; | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | sub new { | 
| 81 | 18 |  |  | 18 | 1 | 51565 | my ( $class,%opts ) = @_; | 
| 82 |  |  |  |  |  |  |  | 
| 83 | 18 | 50 |  |  |  | 75 | if ( !defined($opts{geocoder} ) ) { | 
| 84 | 18 |  |  |  |  | 534 | require Geo::Coder::Google; | 
| 85 | 18 |  |  |  |  | 234 | Geo::Coder::Google->import(); | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | $opts{'geocoder'} = Geo::Coder::Google->new( | 
| 88 |  |  |  |  |  |  | apidriver => 3, | 
| 89 | 18 | 100 |  |  |  | 124 | ( $opts{'api_key'} ? ( key => $opts{'api_key'}, sensor => 'false' ) : () ), | 
| 90 |  |  |  |  |  |  | ); | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  |  | 
| 93 | 18 |  |  |  |  | 74434 | $opts{'points'} = []; | 
| 94 | 18 |  |  |  |  | 44 | $opts{'poly_lines'} = []; | 
| 95 |  |  |  |  |  |  |  | 
| 96 | 18 |  |  |  |  | 162 | return bless \%opts, $class; | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | sub _text_to_point { | 
| 100 | 27 |  |  | 27 |  | 45 | my ( $self,$point_text ) = @_; | 
| 101 |  |  |  |  |  |  |  | 
| 102 |  |  |  |  |  |  | # IE, already a long/lat pair | 
| 103 | 27 | 100 |  |  |  | 124 | return [ reverse @$point_text ] if ref( $point_text ) eq "ARRAY"; | 
| 104 |  |  |  |  |  |  |  | 
| 105 | 2 | 50 |  |  |  | 10 | if ( my @loc = $self->{geocoder}->geocode( location => $point_text ) ) { | 
| 106 | 2 | 50 |  |  |  | 21 | if ( my $location = $loc[0] ) { | 
| 107 |  |  |  |  |  |  |  | 
| 108 | 2 | 50 |  |  |  | 8 | if ( ref( $location ) ne 'HASH' ) { | 
| 109 | 0 |  |  |  |  | 0 | warn "$point_text didn't return a HASH ref as first element from ->geocode"; | 
| 110 | 0 |  |  |  |  | 0 | return 0; | 
| 111 |  |  |  |  |  |  | } | 
| 112 |  |  |  |  |  |  |  | 
| 113 | 2 | 50 | 33 |  |  | 12 | if(defined($location->{geometry}{location}{lat}) && defined($location->{geometry}{location}{lng})) { | 
| 114 |  |  |  |  |  |  | return [ | 
| 115 |  |  |  |  |  |  | $location->{geometry}{location}{lat}, | 
| 116 |  |  |  |  |  |  | $location->{geometry}{location}{lng}, | 
| 117 | 2 |  |  |  |  | 10 | ]; | 
| 118 |  |  |  |  |  |  | } | 
| 119 |  |  |  |  |  |  | } | 
| 120 |  |  |  |  |  |  | } | 
| 121 |  |  |  |  |  |  |  | 
| 122 |  |  |  |  |  |  | # Unknown | 
| 123 | 0 |  |  |  |  | 0 | return 0; | 
| 124 |  |  |  |  |  |  | } | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | sub _find_center { | 
| 127 | 19 |  |  | 19 |  | 52 | my ( $self ) = @_; | 
| 128 |  |  |  |  |  |  |  | 
| 129 |  |  |  |  |  |  | # Null case | 
| 130 | 19 | 100 |  |  |  | 26 | return unless @{$self->{points}}; | 
|  | 19 |  |  |  |  | 58 |  | 
| 131 |  |  |  |  |  |  |  | 
| 132 | 12 |  |  |  |  | 19 | my ( $total_lat,$total_lng,$total_abs_lng ); | 
| 133 |  |  |  |  |  |  |  | 
| 134 | 12 |  |  |  |  | 16 | foreach ( @{$self->{points}} ) { | 
|  | 12 |  |  |  |  | 24 |  | 
| 135 | 16 |  |  |  |  | 21 | my ( $lat,$lng ) = @{ $_->{point} }; | 
|  | 16 |  |  |  |  | 29 |  | 
| 136 | 16 | 50 |  |  |  | 345 | $total_lat     += defined $lat ? $lat : 0; | 
| 137 | 16 | 50 |  |  |  | 31 | $total_lng     += defined $lng ? $lng : 0; | 
| 138 | 16 | 50 |  |  |  | 36 | $total_abs_lng += abs( defined $lng ? $lng : 0 ); | 
| 139 |  |  |  |  |  |  | } | 
| 140 |  |  |  |  |  |  |  | 
| 141 |  |  |  |  |  |  | # Latitude is easy, just an average | 
| 142 | 12 |  |  |  |  | 25 | my $center_lat = $total_lat/@{$self->{points}}; | 
|  | 12 |  |  |  |  | 47 |  | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | # Longitude, on the other hand, is trickier. If points are | 
| 145 |  |  |  |  |  |  | # clustered around the international date line a raw average | 
| 146 |  |  |  |  |  |  | # would produce a center around longitude 0 instead of -180. | 
| 147 | 12 |  |  |  |  | 17 | my $avg_lng     = $total_lng/@{$self->{points}}; | 
|  | 12 |  |  |  |  | 26 |  | 
| 148 | 12 |  |  |  |  | 18 | my $avg_abs_lng = $total_abs_lng/@{$self->{points}}; | 
|  | 12 |  |  |  |  | 18 |  | 
| 149 |  |  |  |  |  |  |  | 
| 150 | 12 | 100 |  |  |  | 64 | return [ $center_lat,$avg_lng ] # All points are on the | 
| 151 |  |  |  |  |  |  | if abs( $avg_lng ) == $avg_abs_lng; # same hemasphere | 
| 152 |  |  |  |  |  |  |  | 
| 153 | 2 | 100 |  |  |  | 7 | if ( $avg_abs_lng > 90 ) { # Closer to the IDL | 
| 154 | 1 | 50 | 33 |  |  | 9 | if ( $avg_lng < 0 && abs( $avg_lng ) <= 90) { | 
|  |  | 0 |  |  |  |  |  | 
| 155 | 1 |  |  |  |  | 2 | $avg_lng += 180; | 
| 156 |  |  |  |  |  |  | } elsif ( abs( $avg_lng ) <= 90 ) { | 
| 157 | 0 |  |  |  |  | 0 | $avg_lng -= 180; | 
| 158 |  |  |  |  |  |  | } | 
| 159 |  |  |  |  |  |  | } | 
| 160 |  |  |  |  |  |  |  | 
| 161 | 2 |  |  |  |  | 10 | return [ $center_lat,$avg_lng ]; | 
| 162 |  |  |  |  |  |  | } | 
| 163 |  |  |  |  |  |  |  | 
| 164 |  |  |  |  |  |  | =head1 METHODS | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | =over 4 | 
| 167 |  |  |  |  |  |  |  | 
| 168 |  |  |  |  |  |  | =item $map->center($point) | 
| 169 |  |  |  |  |  |  |  | 
| 170 |  |  |  |  |  |  | Center the map at a given point. Returns 1 on success, 0 if | 
| 171 |  |  |  |  |  |  | the point could not be found. | 
| 172 |  |  |  |  |  |  |  | 
| 173 |  |  |  |  |  |  | =cut | 
| 174 |  |  |  |  |  |  |  | 
| 175 |  |  |  |  |  |  | sub center { | 
| 176 | 1 |  |  | 1 | 1 | 409 | my ( $self,$point_text ) = @_; | 
| 177 |  |  |  |  |  |  |  | 
| 178 | 1 |  | 50 |  |  | 5 | my $point = $self->_text_to_point( $point_text ) | 
| 179 |  |  |  |  |  |  | || return 0; | 
| 180 |  |  |  |  |  |  |  | 
| 181 | 1 |  |  |  |  | 3 | $self->{center} = $point; | 
| 182 | 1 |  |  |  |  | 4 | return 1; | 
| 183 |  |  |  |  |  |  | } | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | =item $map->zoom($level) | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | Set the new zoom level (0 is corsest) | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | =cut | 
| 190 |  |  |  |  |  |  |  | 
| 191 |  |  |  |  |  |  | =item $map->dragging($enable) | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | Enable or disable dragging. | 
| 194 |  |  |  |  |  |  |  | 
| 195 |  |  |  |  |  |  | =cut | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  | =item $map->info_window($enable) | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | Enable or disable info windows. | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | =cut | 
| 202 |  |  |  |  |  |  |  | 
| 203 |  |  |  |  |  |  | =item $map->map_id($id) | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | Set the id of the map div | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | =cut | 
| 208 |  |  |  |  |  |  |  | 
| 209 | 1 |  |  | 1 | 0 | 9 | sub add_icon    { 1; } | 
| 210 | 1 |  |  | 1 | 0 | 4 | sub controls    { 1; } | 
| 211 | 2 |  |  | 2 | 1 | 9597 | sub dragging    { $_[0]->{dragging}    = $_[1]; } | 
| 212 | 1 |  |  | 1 | 1 | 723 | sub info_window { $_[0]->{info_window} = $_[1]; } | 
| 213 | 1 |  |  | 1 | 1 | 7 | sub map_id      { $_[0]->{id}          = $_[1]; } | 
| 214 | 1 |  |  | 1 | 1 | 9326 | sub zoom        { $_[0]->{zoom}        = $_[1]; } | 
| 215 | 1 |  |  | 1 | 0 | 618 | sub v2_zoom     { $_[0]->{zoom}        = $_[1]; } | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | =item $map->map_type($type) | 
| 218 |  |  |  |  |  |  |  | 
| 219 |  |  |  |  |  |  | Set the map type. Either B, B, B, or B. | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  | =cut | 
| 222 |  |  |  |  |  |  |  | 
| 223 |  |  |  |  |  |  | sub map_type { | 
| 224 | 6 |  |  | 6 | 1 | 42433 | my ( $self,$type ) = @_; | 
| 225 |  |  |  |  |  |  |  | 
| 226 |  |  |  |  |  |  | $type = { | 
| 227 |  |  |  |  |  |  | normal         => 'NORMAL', | 
| 228 |  |  |  |  |  |  | map_type       => 'NORMAL', | 
| 229 |  |  |  |  |  |  | satellite_type => 'SATELLITE', | 
| 230 |  |  |  |  |  |  | satellite      => 'SATELLITE', | 
| 231 |  |  |  |  |  |  | hybrid         => 'HYBRID', | 
| 232 |  |  |  |  |  |  | road           => 'ROADMAP', | 
| 233 | 6 |  | 50 |  |  | 59 | }->{ $type } || return 0; | 
| 234 |  |  |  |  |  |  |  | 
| 235 | 6 |  |  |  |  | 30 | $self->{type} = $type; | 
| 236 |  |  |  |  |  |  | } | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | =item $map->add_marker(point => $point, html => $info_window_html) | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | Add a marker to the map at the given point. A point can be a unique | 
| 241 |  |  |  |  |  |  | place name, like an address, or a pair of coordinates passed in as | 
| 242 |  |  |  |  |  |  | an arrayref: [ longitude, latitude ]. Will return 0 if the point | 
| 243 |  |  |  |  |  |  | is not found and 1 on success. | 
| 244 |  |  |  |  |  |  |  | 
| 245 |  |  |  |  |  |  | If B is specified, add a popup info window as well. | 
| 246 |  |  |  |  |  |  |  | 
| 247 |  |  |  |  |  |  | =cut | 
| 248 |  |  |  |  |  |  |  | 
| 249 |  |  |  |  |  |  | sub add_marker { | 
| 250 | 16 |  |  | 16 | 1 | 143 | my ( $self,%opts ) = @_; | 
| 251 |  |  |  |  |  |  |  | 
| 252 |  |  |  |  |  |  | my $point = $self->_text_to_point($opts{point}) | 
| 253 | 16 |  | 50 |  |  | 39 | || return 0; | 
| 254 |  |  |  |  |  |  |  | 
| 255 | 16 |  |  |  |  | 76 | push( @{$self->{points}}, { | 
| 256 |  |  |  |  |  |  | point  => $point, | 
| 257 |  |  |  |  |  |  | html   => $opts{html}, | 
| 258 |  |  |  |  |  |  | format => !$opts{noformat} | 
| 259 | 16 |  |  |  |  | 28 | } ); | 
| 260 |  |  |  |  |  |  | } | 
| 261 |  |  |  |  |  |  |  | 
| 262 |  |  |  |  |  |  | =item $map->add_polyline(points => [ $point1, $point2 ]) | 
| 263 |  |  |  |  |  |  |  | 
| 264 |  |  |  |  |  |  | Add a polyline that connects the list of points. Other options | 
| 265 |  |  |  |  |  |  | include B (any valid HTML color), B (line width in | 
| 266 |  |  |  |  |  |  | pixels) and B (between 0 and 1). Will return 0 if the points | 
| 267 |  |  |  |  |  |  | are not found and 1 on success. | 
| 268 |  |  |  |  |  |  |  | 
| 269 |  |  |  |  |  |  | =cut | 
| 270 |  |  |  |  |  |  |  | 
| 271 |  |  |  |  |  |  | sub add_polyline { | 
| 272 | 5 |  |  | 5 | 1 | 10038 | my ( $self,%opts ) = @_; | 
| 273 |  |  |  |  |  |  |  | 
| 274 | 5 |  |  |  |  | 11 | my @points = map { $self->_text_to_point($_) } @{$opts{points}}; | 
|  | 10 |  |  |  |  | 21 |  | 
|  | 5 |  |  |  |  | 16 |  | 
| 275 | 5 | 50 |  |  |  | 9 | return 0 if grep { !$_ } @points; | 
|  | 10 |  |  |  |  | 25 |  | 
| 276 |  |  |  |  |  |  |  | 
| 277 | 5 |  |  |  |  | 68 | push( @{$self->{poly_lines}}, { | 
| 278 |  |  |  |  |  |  | points  => \@points, | 
| 279 |  |  |  |  |  |  | color   => $opts{color} || "\#0000ff", | 
| 280 |  |  |  |  |  |  | weight  => $opts{weight} || 5, | 
| 281 | 5 |  | 100 |  |  | 8 | opacity => $opts{opacity} || .5 } | 
|  |  |  | 100 |  |  |  |  | 
|  |  |  | 100 |  |  |  |  | 
| 282 |  |  |  |  |  |  | ); | 
| 283 |  |  |  |  |  |  | } | 
| 284 |  |  |  |  |  |  |  | 
| 285 |  |  |  |  |  |  | sub _js_template { | 
| 286 |  |  |  |  |  |  |  | 
| 287 | 17 |  |  | 17 |  | 47783 | my $template =<<"EndOfTemplate"; | 
| 288 |  |  |  |  |  |  |  | 
| 289 |  |  |  |  |  |  | function html_googlemaps_initialize() { | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | [% # Github issue 22 %] | 
| 292 |  |  |  |  |  |  | [% IF center %] | 
| 293 |  |  |  |  |  |  | myCenterLatLng = new google.maps.LatLng({lat: [% center.0 %], lng: [% center.1 %]}); | 
| 294 |  |  |  |  |  |  | [% END %] | 
| 295 |  |  |  |  |  |  |  | 
| 296 |  |  |  |  |  |  | // key map controls | 
| 297 |  |  |  |  |  |  | var map = new google.maps.Map(document.getElementById('[% id %]'), { | 
| 298 |  |  |  |  |  |  | mapTypeId: google.maps.MapTypeId.[% type %], | 
| 299 |  |  |  |  |  |  | [% IF center %]center: myCenterLatLng,[% END %] | 
| 300 |  |  |  |  |  |  | scrollwheel: false, | 
| 301 |  |  |  |  |  |  | zoom: [% zoom %], | 
| 302 |  |  |  |  |  |  | draggable: [% dragging ? 'true' : 'false' %] | 
| 303 |  |  |  |  |  |  | }); | 
| 304 |  |  |  |  |  |  |  | 
| 305 |  |  |  |  |  |  | [% FOREACH point IN points %] | 
| 306 |  |  |  |  |  |  |  | 
| 307 |  |  |  |  |  |  | // marker | 
| 308 |  |  |  |  |  |  | myMarker[% loop.count %]LatLng = new google.maps.LatLng({lat: [% point.point.0 %], lng: [% point.point.1 %]}); | 
| 309 |  |  |  |  |  |  | var marker[% loop.count %] = new google.maps.Marker({ | 
| 310 |  |  |  |  |  |  | map: map, | 
| 311 |  |  |  |  |  |  | position: myMarker[% loop.count %]LatLng, | 
| 312 |  |  |  |  |  |  | }); | 
| 313 |  |  |  |  |  |  |  | 
| 314 |  |  |  |  |  |  | // marker infoWindow | 
| 315 |  |  |  |  |  |  | [% IF info_window AND point.html %] | 
| 316 |  |  |  |  |  |  | var contentString[% loop.count %] = '[% point.html %]'; | 
| 317 |  |  |  |  |  |  | var infowindow[% loop.count %] = new google.maps.InfoWindow({ | 
| 318 |  |  |  |  |  |  | content: contentString[% loop.count %] | 
| 319 |  |  |  |  |  |  | }); | 
| 320 |  |  |  |  |  |  |  | 
| 321 |  |  |  |  |  |  | marker[% loop.count %].addListener('click', function() { | 
| 322 |  |  |  |  |  |  | infowindow[% loop.count %].open(map, marker[% loop.count %]); | 
| 323 |  |  |  |  |  |  | }); | 
| 324 |  |  |  |  |  |  | [% END %] | 
| 325 |  |  |  |  |  |  |  | 
| 326 |  |  |  |  |  |  | [% END -%] | 
| 327 |  |  |  |  |  |  |  | 
| 328 |  |  |  |  |  |  | [% FOREACH route IN poly_lines %] | 
| 329 |  |  |  |  |  |  |  | 
| 330 |  |  |  |  |  |  | // polylines | 
| 331 |  |  |  |  |  |  | var route[% loop.count %]Coordinates = [ | 
| 332 |  |  |  |  |  |  | [% FOREACH point IN route.points %]{lat: [% point.0 %], lng: [% point.1 %]}[% loop.last ? '' : ',' %] | 
| 333 |  |  |  |  |  |  | [% END %] | 
| 334 |  |  |  |  |  |  | ]; | 
| 335 |  |  |  |  |  |  |  | 
| 336 |  |  |  |  |  |  | var route[% loop.count %] = new google.maps.Polyline({ | 
| 337 |  |  |  |  |  |  | path: route[% loop.count %]Coordinates, | 
| 338 |  |  |  |  |  |  | geodesic: true, | 
| 339 |  |  |  |  |  |  | strokeColor: '[% route.color %]', | 
| 340 |  |  |  |  |  |  | strokeOpacity: [% route.opacity %], | 
| 341 |  |  |  |  |  |  | strokeWeight: [% route.weight %] | 
| 342 |  |  |  |  |  |  | }); | 
| 343 |  |  |  |  |  |  |  | 
| 344 |  |  |  |  |  |  | route[% loop.count %].setMap(map); | 
| 345 |  |  |  |  |  |  | [% END %] | 
| 346 |  |  |  |  |  |  | } | 
| 347 |  |  |  |  |  |  | EndOfTemplate | 
| 348 |  |  |  |  |  |  | } | 
| 349 |  |  |  |  |  |  |  | 
| 350 |  |  |  |  |  |  | =item $map->onload_render | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | Renders the map and returns a two element list. The first element | 
| 353 |  |  |  |  |  |  | needs to be placed in the head section of your HTML document. The | 
| 354 |  |  |  |  |  |  | second in the body where you want the map to appear. You will also | 
| 355 |  |  |  |  |  |  | need to add a call to html_googlemaps_initialize() in your page's | 
| 356 |  |  |  |  |  |  | onload handler. The easiest way to do this is adding it to the body | 
| 357 |  |  |  |  |  |  | tag: | 
| 358 |  |  |  |  |  |  |  | 
| 359 |  |  |  |  |  |  |  | 
| 360 |  |  |  |  |  |  |  | 
| 361 |  |  |  |  |  |  | =back | 
| 362 |  |  |  |  |  |  |  | 
| 363 |  |  |  |  |  |  | =cut | 
| 364 |  |  |  |  |  |  |  | 
| 365 |  |  |  |  |  |  | sub onload_render { | 
| 366 | 17 |  |  | 17 | 1 | 90 | my ( $self ) = @_; | 
| 367 |  |  |  |  |  |  |  | 
| 368 |  |  |  |  |  |  | # Add in all the defaults | 
| 369 | 17 |  | 100 |  |  | 81 | $self->{id}         ||= 'map'; | 
| 370 | 17 |  | 100 |  |  | 57 | $self->{height}     ||= '400px'; | 
| 371 | 17 |  | 100 |  |  | 73 | $self->{width}      ||= '600px'; | 
| 372 | 17 |  | 100 |  |  | 56 | $self->{type}       ||= "NORMAL"; | 
| 373 | 17 |  | 100 |  |  | 68 | $self->{zoom}       ||= 13; | 
| 374 | 17 |  | 100 |  |  | 74 | $self->{center}     ||= $self->_find_center; | 
| 375 | 17 | 100 |  |  |  | 52 | $self->{dragging}     = 1 unless defined $self->{dragging}; | 
| 376 | 17 | 100 |  |  |  | 49 | $self->{info_window}  = 1 unless defined $self->{info_window}; | 
| 377 |  |  |  |  |  |  |  | 
| 378 | 17 | 100 |  |  |  | 116 | $self->{width}  .= 'px' if $self->{width} =~ m/^\d+$/; | 
| 379 | 17 | 100 |  |  |  | 69 | $self->{height} .= 'px' if $self->{height} =~ m/^\d+$/; | 
| 380 |  |  |  |  |  |  |  | 
| 381 | 17 |  |  |  |  | 46 | my $header = '' | 
| 383 |  |  |  |  |  |  | ; | 
| 384 |  |  |  |  |  |  |  | 
| 385 |  |  |  |  |  |  | my $key = $self->{api_key} | 
| 386 | 17 | 100 |  |  |  | 59 | ? "?key=@{[ $self->{api_key} ]}" : ""; | 
|  | 3 |  |  |  |  | 13 |  | 
| 387 |  |  |  |  |  |  |  | 
| 388 | 17 |  |  |  |  | 89 | $header =~ s/__KEY__/$key/; | 
| 389 |  |  |  |  |  |  |  | 
| 390 |  |  |  |  |  |  | my $map = sprintf( | 
| 391 |  |  |  |  |  |  | '', | 
| 392 | 17 |  |  |  |  | 121 | @{$self}{qw/ id width height / }, | 
| 393 |  |  |  |  |  |  | exists($self->{'z_index'}) | 
| 394 | 17 | 100 |  |  |  | 42 | ? '; z-index: ' . $self->{'z_index'} : '' | 
| 395 |  |  |  |  |  |  | ); | 
| 396 |  |  |  |  |  |  |  | 
| 397 | 17 |  |  |  |  | 28 | my $out; | 
| 398 | 17 |  |  |  |  | 107 | Template->new->process( \$self->_js_template,$self,\$out ); | 
| 399 |  |  |  |  |  |  |  | 
| 400 | 17 |  |  |  |  | 473356 | $header .= ""; | 
| 401 |  |  |  |  |  |  |  | 
| 402 | 17 |  |  |  |  | 1032 | return ( $header,$map ); | 
| 403 |  |  |  |  |  |  | } | 
| 404 |  |  |  |  |  |  |  | 
| 405 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 406 |  |  |  |  |  |  |  | 
| 407 |  |  |  |  |  |  | L | 
| 408 |  |  |  |  |  |  |  | 
| 409 |  |  |  |  |  |  | =head1 LICENSE | 
| 410 |  |  |  |  |  |  |  | 
| 411 |  |  |  |  |  |  | This library is free software; you can redistribute it and/or modify it under | 
| 412 |  |  |  |  |  |  | the same terms as Perl itself. If you would like to contribute documentation, | 
| 413 |  |  |  |  |  |  | features, bug fixes, or anything else then please raise an issue / pull request: | 
| 414 |  |  |  |  |  |  |  | 
| 415 |  |  |  |  |  |  | https://github.com/Humanstate/html-googlemaps-v3 | 
| 416 |  |  |  |  |  |  |  | 
| 417 |  |  |  |  |  |  | =cut | 
| 418 |  |  |  |  |  |  |  | 
| 419 |  |  |  |  |  |  | =head1 AUTHORS | 
| 420 |  |  |  |  |  |  |  | 
| 421 |  |  |  |  |  |  | Nate Mueller  - Original Author | 
| 422 |  |  |  |  |  |  |  | 
| 423 |  |  |  |  |  |  | Lee Johnson  - Maintainer of this fork | 
| 424 |  |  |  |  |  |  |  | 
| 425 |  |  |  |  |  |  | Nigel Horne - Contributor of several patches | 
| 426 |  |  |  |  |  |  |  | 
| 427 |  |  |  |  |  |  | =cut | 
| 428 |  |  |  |  |  |  |  | 
| 429 |  |  |  |  |  |  | 1; | 
| 430 |  |  |  |  |  |  |  | 
| 431 |  |  |  |  |  |  | # vim: ts=4:sw=4:et |