Brendan Gillatt
Meizu-Mapper

Note -

My Miniplayer has stopped working (battery failure) so, until I can find a replacement, I can't continue developing this app. If you come across a battery manufacturer that will supply a li-poly battery with maximum dimensions of 42mm x 42mm x 3.5mm and a capacity of at least 600mAh, I would be very grateful to hear from you!

What It Does & Why

'member', a user of the MeizuMe Forums, thought of a way of putting large maps onto the Meizu MiniPlayer despite the fact that the built in image viewer cannot zoom.

The idea is to split a large image, in this case 1600 by 960 pixels, into a grid of twenty 320 by 240 pixel images. When the directory containing the images is viewed, small thumbnails are created of the 320 by 240 pixel images which align to show the complete map. A smaller image is then opened to full size, giving the effect of 'zooming' in on a map.

I thought there must be an easier way than fiddling around with GIMP to splice the images, hence the reason I coded this up. It retrieves the map from Google Maps, splices it into the correct sized pieces and zips them up.

For more details of how it came about and an explanation of the manual process, see his/her post.

Generate Your Map!

  1. Find your map on Google Maps as you would do normally
  2. Copy the 'Link to this page' link into the form below and click 'Meizu-Map!'.
  3. Download the zip file to a convenient location and extract the images to a new folder on your MiniPlayer.

Get The Code

Requirements:

<?php

/*
Meizu-Mapper

License: GNU GPLv2

Original Author:
	Brendan Gillatt
	http://www.brendangillatt.co.uk
	brendan -at- brendangillatt . co . uk
	GPG: 6E265E61

Version History:
	1.0	Original Release	3rd May 2007


Information:
	'member', a user of the MeizuMe Forums, thought of a way of putting large maps onto the Meizu MiniPlayer
	despite the fact that the built in image viewer cannot zoom.
	
	The idea is to split a large image, in this case 1600 by 960 pixels into a grid of twenty 320 by 240 pixel
	images. When the directory containing the images is viewed, small thumbnails are created of the 320 by
	240 pixel images which align to show the complete map. A smaller image is then opened to full size,
	giving the effect of 'zooming' in on a map.
	
	I thought their must be an easier way than fiddling around with GIMP to splice the images, hence the
	reason I coded this up. It retrieves the map from Google Maps, splices it into the correct sized pieces
	and zips them up.
	
	For more details and a better explanation of the process, see his/her post at
	http://www.meizume.com/showthread.php?t=1607.
	
	
Installation:
	Copy the PHP file to any convenient location ( directory needs R/W permissions ).
	Make a form which will send an inputted url to the script-named 'url'-using the GET method.
	Make sure you have a ZIP application available for execution. Most *nix already do so; a DOS
	binary is included with a compatible license.
	Change some of the code such as the error message and the webserver locations to match you're site.


Note:
	You must link back to my site, or make the source code readily available.
	If you require an archive of past versions, please E-Mail me using the address above.
	Please post any code changes or bugfixes back to me - be fair with GNU GPL =].
*/


function get_image_url ( $url ) { // get the url of a google maps image from the 'print' page.

	$error_message = 'The address you entered is not suitable, sorry =[. Please re-read the instructions and try again. <a href="http://www.brendangillatt.co.uk/?p=meizumapper">Go Back</a>.';

	$url_pieces = parse_url ( $url ); // get the parts of the url ( host, get query, etc. )

	if ( $url_pieces [ 'host' ] != 'maps.google.com' ) die ( $error_message ."2" ); // if somthing is being requested from another server ( security risk )

	$query = $url_pieces [ 'query' ];
	
	$query_array = explode ( '&', $query ); // get the individual parts of the query
	
	$found = 0; // both the zoom and the coordinates haven't been found.
	
	foreach ( $query_array as $item ) { // for every query part
		
		if ( $item {0} == 'l' ) { // if the query is 'll=' ( latitude & longitude )

			$found++; // mark that another required part was found.
			
			$coords = explode ( ',', str_replace ( '.', '', substr ( $item, 3 ) ) ); // remove the get variable names, remove decimal points and then split into two co-ords
			
			if ( count ( $coords ) == 0 ) die ( $error_message ."3" ); // if something went wrong with the coordinates.
			
			$coord_1 = $coords [ 0 ];
			
			$coord_2 = $coords [ 1 ];
			
			$reversed_coords = $coord_2 . ',' . $coord_1; // actaully retrieving the map requires the coords to be reversed for some reason O-o
			
		} elseif ( $item {0} == 'z' ) { // the zoom query.
			
			$found++;
			
			$zoom = 17 - substr ( $item, 2 ); // no idea why we must subtract the zoom from 17 - that's what happens, however.
		
		}
		
	}
	
	if ( $found < 2 ) die ( $error_message ."4" ); // if both needed bits of info were not found. (zoom & coords)
	
	$image_url = "http://www.google.com/mapprint?c=$reversed_coords&r=1600,960&z=$zoom"; // build up the url to request.
	
	return $image_url;
}


function retrieve_image ( $url ) {
	
	$google_image_hd = fopen ( get_image_url ( $url ), 'rb' ) or die ( $error_message ."1" ); // open the image ( must have url wrappers enabled )
	
	while ( !feof ( $google_image_hd ) ) { // have to read the image in in parts because my webserver only has PHP4 and therefore doesn't support stream_get_contents()
	
		$image_data .= fread ( $google_image_hd, 8192 );
  
	}
	
	fclose ( $google_image_hd ); // clean up
	
	
	
	// Save the image
	
	$rand = rand ( 0, 500 ); // stop temporary file conflicts if two images are being processed at once
	
	$filename = "tempimage-$rand.gif"; // name the file with the random number.
	
	$temp_image_handle = fopen ( $filename, 'wb' );
	
	fwrite ( $temp_image_handle, $image_data ); // write the image to a temporary file
	
	fclose ( $temp_image_handle );
	
	return $filename; // filename of temp image
}


function process_image ( $filename ) { // splits the image up into sections, saves as individuals, zips them up, deleted them then returns the zipfile name... phew!
	
	$image = imagecreatefromgif ( $filename ); // open the temporary image

	unlink ( $filename ); // delete the big image from disk

	$rand = rand ( 0, 500 ); // stop temporary file conflicts if two images are being processed at once

	$count = 0;
	
	for ( $row = 0; $row < 4; $row++ ) { // for every to-be-created row.
		
		for ( $column = 0; $column < 5; $column++, $count++ ) { // for every column in each row; also increment an image counter

			$smallimage = imagecreatetruecolor ( 320, 240 ); // allocate memory for the image.
			
			imagecopy ( $smallimage, $image, 0, 0, $column*320, $row*240, 320, 240 ); // copy the row and column from the large image to the small one.
			
			$paddedcount = str_pad ( $count, 2, "0", STR_PAD_LEFT ); // turn the count into two digits - sorted by the meizu properly
			
			$filename = "$paddedcount-$rand.jpg"; // make a temporary filename based on the random number created above.
			
			imagejpeg ( $smallimage, $filename ); // save image
			
			imagedestroy ( $smallimage ); // free memory
			
			$namelist .= " " . $filename; // build up a list of filenames suitable for the 'zip' command			
			
		}
		
	}
	
	imagedestroy ( $image ); // free memory taken by the big image
		
	exec ( "zip $rand.zip $namelist" ); // put the images into a zipfile
	
	for ( $count = 0; $count < 20; $count++ ) { // delete all small temporary files from disk
	
		$paddedcount = str_pad ( $count, 2, "0", STR_PAD_LEFT );
		
		$filename = "$paddedcount-$rand.jpg";
		
		unlink ( $filename );
	
	}
	
	return "$rand.zip"; // return the zipfile name
	
}


if ( !isset ( $_GET ['url'] ) ) { // if there was no url entered.
	header ( 'Location: http://www.brendangillatt.co.uk/?p=meizumapper' );
}


$url = $_GET [ 'url' ];

$zipfilename = process_image ( retrieve_image ( $url ) );

header ( 'Content-Type: application/zip' );
header('Content-Disposition: attachment; filename="map.zip"'); // makes IE open it properly.

readfile ( $zipfilename );

unlink ( $zipfilename ); // clean up

?>