Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Build Wall Map from Google Map Tiles

by gryphon (Abbot)
on Feb 15, 2005 at 22:23 UTC ( #431361=CUFP: print w/replies, xml ) Need Help??

Greetings fellow monks,

Inspired by Google Maps kung fu and the lack of any decorations on a few of the long hallways at work (plus the fact that I tire of giving people directions), I decided to throw together a script that fetches a bunch of map tiles from Google Maps, merges them into a single, uber map, then splits that map into graphics big enough to fill an 8.5x11 sheet of paper.

The goal was mostly to play with Image::Magick (because I've never played with it before). I added a "sleep" period in the code to keep from spamming Google Maps too badly.

Note: This image scraping is probably not a blessed activity by the folks at Google. I couldn't find any terms of use on the beta site (not that I really looked all that hard). Anyway, be nice and don't flood Google please.

#!/usr/bin/perl use strict; use warnings FATAL => 'all'; use LWP::Simple; use Image::Magick; my %config = ( zoom => 3, # Google Maps zoom level (1 == smallest resol +ution) x_start => -2387, # Upper-left map tile "x" CGI GET parameter y_start => -1095, # Upper-left map tile "y" CGI GET parameter rows => 108, # Number of rows (i.e. y-axis or height) to f +etch cols => 47, # Number of columns (i.e. x-axis or width) to + fetch file => 'map.gif', # Filename to save the merged tiles into s_secs => 5, # Number of seconds to sleep in each fetch in +terval s_every => 18, # Number of tiles to fetch in a given interva +l get_est => 0.21, # Estimated number of seconds to fetch a tile width => 768, # Desired width for cut image plates height => 1008 # Desired height for cut image plates ); my ($tiles_count, $tiles_total) = (0, $config{rows} * $config{cols}); my $eta = $config{rows} * $config{cols} / $config{s_every} * $config{s +_secs} + $config{rows} * $config{cols} * $config{get_est}; my $start_time = time; for (my $y = 0; $y < $config{rows}; $y++) { for (my $x = 0; $x < $config{cols}; $x++) { $tiles_count++; getstore( 'http://mt.google.com/mt?' . 'x=' . ( $config{x_start} + $x ) . '&y=' . ( $config{y_start} + $y ) . '&zoom=' . $config{zoom}, join('_', 'plate', $x, $y) . '.gif' ); sleep $config{s_secs} if (int($tiles_count/$config{s_every}) == $tiles_count/$config{s_ +every}); } } my $plates = new Image::Magick; for (my $y = 0; $y < $config{rows}; $y++) { for (my $x = 0; $x < $config{cols}; $x++) { $plates->Read('plate_' . $x . '_' . $y . '.gif'); } } my $width = $plates->[0]->Get('columns'); my $height = $plates->[0]->Get('rows'); my $single_map = $plates->Montage( geometry => $width . 'x' . $height . '+0+0', tile => $config{cols} ); $single_map->Write($config{file}); for (my $y = 0; $y < $config{rows}; $y++) { for (my $x = 0; $x < $config{cols}; $x++) { unlink 'plate_' . $x . '_' . $y . '.gif'; } } $single_map->Rotate(degrees => 90); $width = $single_map->[0]->Get('columns'); $height = $single_map->[0]->Get('rows'); my $x_count = int($width / $config{width}); my $y_count = int($height / $config{height}); for (my $x = 0; $x <= $x_count; $x++) { for (my $y = 0; $y <= $y_count; $y++) { my ($w, $h) = ($config{width}, $config{height}); $w = $width - $x_count * $config{width} if ($x == $x_count); $h = $height - $y_count * $config{height} if ($y == $y_count); my $geometry = $w . 'x' . $h . '+' . $config{width} * $x . '+' . $config{height} * $y; my $plate = $single_map->Clone; $plate->Crop(geometry => $geometry); $plate->Montage(geometry => $w . 'x' . $h . '+0+0')->Write( 'plate_' . $x . '_' . $y . '.gif' ); } }

gryphon
code('Perl') || die;

Replies are listed 'Best First'.
Re: Build Wall Map from Google Map Tiles
by saskaqueer (Friar) on Feb 15, 2005 at 22:31 UTC
    I couldn't find any terms of use on the beta site (not that I really looked all that hard).

    Well, it took me all of 30 seconds to find it: http://local.google.com/help/terms_local.html. Quote:

    By using Google Local, you agree to be bound by our Google Terms of Service, which are fully incorporated herein, as well as these additional terms and conditions that are specific to the Google Local service.

    Then we look at the Google Terms of Service and quote:

    You may not send automated queries of any sort to Google's system without express permission in advance from Google.
Re: Build Wall Map from Google Map Tiles
by inman (Curate) on Feb 16, 2005 at 09:02 UTC
    I favour this sort of endeavour and I applaud the OP for the idea and the effort involved. Perl as a language has played a fairly major part in the development of many of the great services on the web. Perl users shouldn't be afraid of going out and using their skills to invent new ways of using web based systems.

    I abhor the use of the 'it's against the Terms and Conditions' argument as a reason to avoid doing anything that is innovative. The terms and conditions of a website fall into the category of rules that could be applied to an individual but are unlikely to be. For example - Recording a TV show and then lending the recording to someone else is technically an infringement of the programme maker's copyright but they are unlikely to prosecute you. In a similar vein, constructing a montage from a selection of Google images will undoubtedly infringe copyright, patents, terms and conditions and the personal dignity of Google shareholders. May I suggest that an endeavour that is creative, not for profit and carried out with consideration on the impact of the end system could be called art.

      So i guess itīd be better to use LWP::UserAgent's agent()-method instead of LWP::Simple.


      holli, /regexed monk/
Re: Build Wall Map from Google Map Tiles
by Anonymous Monk on Feb 16, 2005 at 20:05 UTC
    I love this little gem. Especially because I hope to use it to print biking trail maps around my locality. I could not figure out how to specify the center point location for the maps - either as zip code or address. Is this do-able? The google maps URL does not seem to include the location info.
      I'd love to use this to create my own map but I do not know how to "run" the script. is this something that can be pasted into a notepad and i change the filename to .exe or soemthing along those lines? I would also like to know how to adjsut the zoom level. It looks like it is going to start at the lowest level possible but i would like it a little higher. Also, same question, How do I start centered in one place to make sure that I get the actual area that I want?
        1) Not exactly; you need to install Perl, copy the script, and then test it. Then you may well have to revise it, to deal with the changes at big-G since the beta about which OP was talking was G's 2005 state-of-the-art-and-API.

        2) Sorry, I dunno.

        3) likewise...

        But thanks for your interest. If you wish to follow my answer to 1), this is a great place to start. Take a look, for example, at Tutorials.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://431361]
Approved by Tanktalus
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (2)
As of 2020-11-30 04:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?