File Coverage

blib/lib/Geo/GoogleMaps/OffsetCenter.pm
Criterion Covered Total %
statement 43 43 100.0
branch n/a
condition n/a
subroutine 8 8 100.0
pod 1 1 100.0
total 52 52 100.0


line stmt bran cond sub pod time code
1 1     1   583 use strict;
  1         2  
  1         41  
2 1     1   7 use warnings;
  1         2  
  1         70  
3             our $VERSION = '0.04';
4             package Geo::GoogleMaps::OffsetCenter;
5             # ABSTRACT: Offset a Lat/Long in Google Maps
6              
7              
8 1     1   817 use Params::Validate;
  1         10594  
  1         77  
9 1     1   1372 use Math::Trig qw/ pi /;
  1         16662  
  1         91  
10 1     1   647 use Regexp::Common;
  1         2182  
  1         5  
11             use Exporter::Easy (
12 1         7 OK => [ qw/ offset_center_by_pixel / ],
13 1     1   45378 );
  1         1246  
14              
15 1     1   96 use constant RADIUS_OF_EARTH => 6_378_100;
  1         1  
  1         402  
16              
17              
18             sub offset_center_by_pixel {
19 1     1 1 18 validate_pos(
20             @_,
21             { regex => qr/$RE{num}{real}/, optional => 0 }, # latitude
22             { regex => qr/$RE{num}{real}/, optional => 0 }, # longitude
23             { regex => qr/$RE{num}{int}/, optional => 0 }, # width of the whole image
24             { regex => qr/$RE{num}{int}/, optional => 0 }, # height of the whole image
25             { regex => qr/$RE{num}{int}/, optional => 0 }, # x coordinate of where it should be; x_final
26             { regex => qr/$RE{num}{int}/, optional => 0 }, # y coordinate of where it should be; y_final
27             { regex => qr/$RE{num}{int}/, optional => 0 }, # zoom level
28             );
29              
30             my(
31 1         979 $latitude_geo_entity,
32             $longitude_geo_entity,
33             $width_total,
34             $height_total,
35             $x_final,
36             $y_final,
37             $zoom_level,
38             ) = @_;
39              
40             # important for both vertical and horizontal offset
41 1         4 my $number_of_pixels = 256 * 2**$zoom_level;
42 1         3 my $x_initial = int( $width_total / 2 );
43 1         3 my $y_initial = int( $height_total / 2 );
44              
45             # important for vertical offset
46 1         2 my $meters_per_pixel_vertical = ( pi * RADIUS_OF_EARTH ) / $number_of_pixels; # pi * r = length of longitude
47 1         1 my $meters_per_degree_vertical = ( pi * RADIUS_OF_EARTH ) / 180;
48              
49             # important for horizontal offset
50 1         1 my $meters_per_pixel_horizontal = ( 2 * pi * RADIUS_OF_EARTH ) / $number_of_pixels;
51 1         2 my $meters_per_degree_horizontal = ( 2 * pi * RADIUS_OF_EARTH ) / 360;
52              
53             #####################
54             # horizontal offset #
55             #####################
56              
57 1         2 my $horizontal_offset_in_degrees;
58             {
59 1         2 my $pixels_offset = -1 * ($x_final - $x_initial);
  1         2  
60              
61             # find the number of meters we need to move
62 1         2 my $meters_offset = $pixels_offset * $meters_per_pixel_horizontal;
63              
64             # now find the number of degrees we need to move
65 1         2 $horizontal_offset_in_degrees = $meters_offset / $meters_per_degree_horizontal;
66             }
67              
68             ###################
69             # vertical offset #
70             ###################
71              
72 1         2 my $vertical_offset_in_degrees;
73             {
74 1         1 my $pixels_offset = -1 * ($y_final - $y_initial);
  1         1  
75              
76             # find the number of meters we need to move
77 1         2 my $meters_offset = $pixels_offset * $meters_per_pixel_vertical;
78              
79             # now find the number of degrees we need to move
80 1         2 $vertical_offset_in_degrees = $meters_offset / $meters_per_degree_vertical;
81             }
82              
83 1         2 $latitude_geo_entity += $vertical_offset_in_degrees;
84 1         1 $longitude_geo_entity += $horizontal_offset_in_degrees;
85              
86             return {
87 1         15 latitude => sprintf( '%.6f', $latitude_geo_entity ),
88             longitude => sprintf( '%.6f', $longitude_geo_entity ),
89             };
90             }
91              
92             1;
93              
94             __END__