Geo-Google

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

     Usage    : my $clean = _html_unescape($dirty);
     Function : does HTML unescape of & > < " special characters
     Returns  : an unescaped HTML string
     Args     : an HTML string.

  _obj2location()
     Usage    : my $loc = _obj2location($obj);
     Function : converts a perl object generated from a Google Maps 
                    JSON response to a Geo::Google::Location object
     Returns  : a Geo::Google::Location object
     Args     : a member of the $obj->{overlays}->{markers}->[] 
                    anonymous array that you get when you read google's 
                    JSON response and parse it using JSON::jsonToObj()

  _JSONrenderSkeleton()
     Usage    : my $perlvariable = _JSONrenderSkeleton();
     Function : creates the skeleton of a perl data structure used by 
                    the Geo::Google::Location and Geo::Google::Path for 
                    rendering to Google Maps JSON format
     Returns  : a mildly complex multi-level anonymous hash/array 
                    perl data structure that corresponds to the Google 

lib/Geo/Google.pm  view on Meta::CPAN

    }
  }
  # Verify that we actually retrieved pages to parse
  if ( scalar(@pages) > 0 ) {
    foreach my $page (@pages) {
      # attempt to locate the JSON formatted data block
      if ($page =~ m#loadVPage\((.+), "\w+"\);}//]]>#is) { $response_json = $json->jsonToObj($1); }
      else {
	$self->error( "Unable to locate the JSON format data in google's response.") and return undef;
      }
      if ( scalar(@{$response_json->{"overlays"}->{"markers"}}) > 0 ) {	
        foreach my $marker (@{$response_json->{"overlays"}->{"markers"}}) {
	  my $loc = $self->_obj2location($marker, %arg);
	  push @result, $loc;
        }		
      }
      else {
	$self->error("Found the JSON Data block and was able to parse it, but it had no location markers "
	  . "in it.  Maybe Google changed their JSON data structure?.") and return undef;
      }
    }
  }

lib/Geo/Google.pm  view on Meta::CPAN

  }
  # attempt to locate the JSON formatted data block
  elsif ($page =~ m#loadVPage\((.+), "\w+"\);}//]]>#is) {
    my $strJSON = $1;
    $response_json = $json->jsonToObj($strJSON);
  }
  else {
    $self->error( "Unable to locate the JSON format data in Google's response.") and return undef;
  }

  if ( scalar(@{$response_json->{"overlays"}->{"markers"}}) > 0 ) {
    my @result = ();
    foreach my $marker (@{$response_json->{"overlays"}->{"markers"}}) {
      my $loc = $self->_obj2location($marker);
      push @result, $loc;
    }		
    return @result;
  }
  else {
    $self->error("Found the JSON Data block and was "
      . "able to parse it, but it had no location markers"
      . "in it.  Maybe Google changed their "
      . "JSON data structure?") and return undef;

lib/Geo/Google.pm  view on Meta::CPAN

  if ($page =~ m#loadVPage\((.+), "\w+"\);}//]]>#s) {
    # Extract the JSON data structure from the response.
    $response_json = $json->jsonToObj( $1 );
  }
  else {
    $self->error( "Unable to locate the JSON format data in Google's response.") and return undef;
  }

  my @points;
  my @enc_points;
  for (my $i = 0; $i<=$#{$response_json->{"overlays"}->{"polylines"}}; $i++) {
    $enc_points[$i] = $response_json->{"overlays"}->{"polylines"}->[$i]->{"points"};
    $points[$i] = [ _decode($enc_points[$i]) ];
  }

  # extract a series of directions from HTML inside the panel 
  # portion of the JSON data response, stuffing them in @html_segs
  my @html_segs;
  my $stepsfound = 0;

  my $panel = $response_json->{'panel'};
  $panel =~ s/&#160;/ /g;

lib/Geo/Google.pm  view on Meta::CPAN

  # Replace XML numeric character references with spaces to make the next regex less dependent upon Google's precise formatting choices
  $response_json->{"printheader"} =~ s/&#\d+;/ /g;
  if ( $response_json->{"printheader"} =~ m#(\d+\.?\d*)\s*(mi|km|m)\s*about\s*(.+?)</td></tr></table>$#s ){
    return Geo::Google::Path->new(
      segments  => \@segments,
      distance  => $1 . " " . $2,
      time      => $3,
      polyline  => [ @enc_points ],
      locations => [ @locations ],
      panel     => $response_json->{"panel"},
      levels    => $response_json->{"overlays"}->{"polylines"}->[0]->{"levels"} );
  } else {
      $self->error("Could not extract the total route distance and time from google's directions") and return undef;
  }

#$Data::Dumper::Maxdepth=6;
#warn Dumper($path);
 
#<segments distance="0.6&#160;mi" meters="865" seconds="56" time="56 secs">
#  <segment distance="0.4&#160;mi" id="seg0" meters="593" pointIndex="0" seconds="38" time="38 secs">Head <b>southwest</b> from <b>Venice Blvd</b></segment>
#  <segment distance="0.2&#160;mi" id="seg1" meters="272" pointIndex="6" seconds="18" time="18 secs">Make a <b>U-turn</b> at <b>Venice Blvd</b></segment>

lib/Geo/Google.pm  view on Meta::CPAN

  }
  return $raw;
}

=head2 _obj2location()

 Usage    : my $loc = _obj2location($obj);
 Function : converts a perl object generated from a Google Maps 
		JSON response to a Geo::Google::Location object
 Returns  : a Geo::Google::Location object
 Args     : a member of the $obj->{overlays}->{markers}->[] 
		anonymous array that you get when you read google's 
		JSON response and parse it using JSON::jsonToObj()

=cut

sub _obj2location {
  my ( $self, $marker, %arg ) = @_;

  my @lines;
  my $title;

lib/Geo/Google.pm  view on Meta::CPAN

                      'q' => {
                               'q' => ''
                             },
                      'd' => {
                               'saddr' => '',
                               'daddr' => '',
                               'dfaddr' => ''
                             },
                      'selected' => ''
                    },
          'overlays' => {
                          'polylines' => [],
                          'markers' => [],
                          'polygons' => []
                        },
          'printheader' => '',
          'modules' => [
                         undef
                       ],
          'viewport' => {
                          'mapType' => '',

lib/Geo/Google/Location.pm  view on Meta::CPAN

	# Construct the shell of a new perl data structure that we
	# can pass off to the JSON module for rendering to a string
	my $preJSON = Geo::Google::_JSONrenderSkeleton();

	# Fill the perl data structure with information from this
	# location
	$preJSON->{"form"}->{"l"}->{"near"} = $self->title();
	$preJSON->{"form"}->{"q"}->{"q"} = $self->title();
	$preJSON->{"form"}->{"d"}->{"daddr"} = $self->title();
	$preJSON->{"form"}->{"selected"} = "q";
	push( @{$preJSON->{"overlays"}->{"markers"}}, {
		"icon" => "addr",
		"laddr" => $self->title(),
		"svaddr" => $self->title(),
		"lat" => $self->latitude(),
		"lng" => $self->longitude(),
		"id" => "addr",
		"adr" => 1,
		"image" => "/mapfiles/arrow.png",
		"elms" => [(3, 2, 6)],
		"dtlsUrl" => "/maps?v=1&q=" . uri_escape($self->title())

lib/Geo/Google/Path.pm  view on Meta::CPAN

		my $image = "/mapfiles/dd-pause.png";
		my $id = "pause";
		if ($i == 0 ) {
			$image = "/mapfiles/dd-start.png";
			$id = "start";
		}
		elsif ($i == $#locations) {
			$image = "/mapfiles/dd-stop.png";
			$id = "stop";
		}
		push( @{$preJSON->{"overlays"}->{"markers"}}, {
			"laddr" => "",
			"svaddr" => "",
			"lat" => $locations[$i]->latitude(),
			"lng" => $locations[$i]->longitude(),
			"id" => $id,
			"image" => $image,
			"elms" => [()],
			"llcid" => "",
			"fid" => "",
			"cid" => "",
			"sig" => "",
			"infoWindow" => {
				"type" => "map",
				"_" => 0
				}
			});
	}
	$preJSON->{"overlays"}->{"polylines"}->[0]->{"levels"} =
		$self->levels();
	$preJSON->{"overlays"}->{"polylines"}->[0]->{"points"} =
		$self->polyline();	
	$preJSON->{"overlays"}->{"polylines"}->[0]->{"outline"} = undef;
	$preJSON->{"overlays"}->{"polylines"}->[0]->{"opacity"} = undef;
	$preJSON->{"overlays"}->{"polylines"}->[0]->{"color"} = undef;
	$preJSON->{"overlays"}->{"polylines"}->[0]->{"weight"} = undef;
	$preJSON->{"overlays"}->{"polylines"}->[0]->{"id"} = "d";
	$preJSON->{"overlays"}->{"polylines"}->[0]->{"numLevels"} = 4;
	$preJSON->{"overlays"}->{"polylines"}->[0]->{"zoomFactor"} = 16;
	$preJSON->{"printheader"} = sprintf("Directions from %s to %s"
					. "<BR />Travel time: %s", 
					$locations[0]->title(),
					$locations[$#locations]->title(),
					$self->time());
	$preJSON->{"modules"} = [(undef, "multiroute")];
	$preJSON->{"panelResizeState"} = "open";
	# step through all points in the directions and determine
	# the maximum and minimum lat/longs
	my $maxlat = -90;



( run in 0.276 second using v1.01-cache-2.11-cpan-49f99fa48dc )