Forum Moderators: coopster

Message Too Old, No Replies

Image Generation from Separate Images using GD

memory considerations.

         

brotherhood of LAN

2:06 pm on Apr 27, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I have a map of mainland Britain that is split into 56 separate images, that joined together make a map of Great Britain. The tiles are split using the British national grid reference system [en.wikipedia.org]

I also have a gazetteer of British towns and cities with co-ordinates, which is great as I can map the cities to their respective map locations, which I'm already doing.

To display the town dead-centre, sometimes more than 1 map image is needed, i.e. up to 4.

Each map image was supplied in tiff format, which I've converted to png, in png format they are averaging 1.5MB each.

I'm using GD to generate/centre/slice-dice the maps to display towns in a smaller resized image (i.e. zoom out a bit).

Is there an efficient method of grabbing slices of larger images? i.e. sometimes here I'm taking 4 1.5MB map squares and taking a section of each. I'm thinking it may be memory expensive and there's a better way of going about it.

This is the code I use where just one tile is concerned (i.e. the co-ordinates are not close to the edge of the map tile and other map tiles need to be loaded in)

<?php
// Gets just 1 map tile image and centre on co-ordinates given

$reference = 'NT4936'; // Usually grabbed from _GET
$d = 500; // final image size

$filename = substr($reference,0,2).'.png'; // map square NT (4000x4000 px)
$x = round(40 * substr($reference,2,2)) - ($d/2); // how far along X
$y = round(4000 - (40 * substr($reference,4,2)) - ($d/2); // how far down Y

header('Content-type: image/png');
list($width, $height) = getimagesize($filename);
// Resample
$image_p = imagecreatetruecolor($d,$d);
$image = imagecreatefrompng($filename);
imagecopyresampled($image_p,$image,0,0,$x,$y,$d,$d,$d,$d);
// Output
imagepng($image_p, null,75);
exit(0);
?>


So I guess I'm asking, is it unavoidably memory expensive using this script? Perhaps it is better just to save the image generated for each co-ordinates queried (more disk space required)

jatar_k

4:02 pm on Apr 27, 2010 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



the thing that comes to mind is sectioning the images more or maybe having overlapping pieces so you don't have to load more than one for any given point

coopster

10:00 pm on Apr 27, 2010 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



Also, how about saving a copy of the file once you're done. No sense recreating images over and over again for the same town. Write the newly created image file to disk and check for file existence prior to building it from scratch. If you ever need to do a rebuild of images all you have to do is delete the image from the directory.

brotherhood of LAN

11:58 pm on Apr 27, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Thanks for the suggestions to you both.

Both ideas are something that could be done. There are 60K locations I have in a list, though in practice (on the site containing this data) I limit to locations that have content associated with them. Just now that's <1000, so no big deal.

There are also 1.6 million postcodes in another list that can be converted to map co-ordinates. The maps are just on a scale that this kind of granularity could be useful.

Ideally I could generate the map on the fly but it looks like slicing the map squares up further and/or cacheing them will be a fine solution with a few hundred more MB disk space.

I was kind of hoping one of the image formats would allow accessing a subsection of an image rather than having to load up the whole image into memory. I guess I could spend a few hours looking up the encoding of each graphic format to see if any could allow for that.

astupidname

1:46 am on Apr 28, 2010 (gmt 0)

10+ Year Member



Is there an efficient method of grabbing slices of larger images? i.e. sometimes here I'm taking 4 1.5MB map squares and taking a section of each


Just a thought I have, this could be done in Flash/Actionscript 3 using it's Bitmap & BitmapData classes, offloading all image processing (such as taking matching/non-matching/any parts of 4 or 1 or whatever images and combining to one displayed image) to the client side browser, and eliminating the need for server memory usage and the extra storage of the combined images on the server, if I'm understanding correctly.

astupidname

2:04 am on Apr 28, 2010 (gmt 0)

10+ Year Member



Addendum to my previous post:
I believe, however, that Flash's Bitmap class has a limit of 2800px size for images (supports jpg, gif & png). Have not done much with images that size or larger in flash so don't know if that's entirely true or not, but I do remember reading it in the Flash/Actionscript 3 docs. So if you were to choose the flash route, may need to reduce images to usable size.

astupidname

2:31 am on Apr 28, 2010 (gmt 0)

10+ Year Member



Another question I would ask you, I don't know if I understand why you need your own images for the mapping. Have you considered the OS Openspace API ?

brotherhood of LAN

12:29 pm on Apr 28, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



>Bitmap & BitmapData

Thanks, I had a look into those and will continue to. It looks like why all those online map services load up in blocks. I guess size limits on images won't matter if you can access a 'substring' of the image, i.e. 500px square.

>own images for the mapping

You're right, I probably should. I've been on one of those breadcrumb trails of adding new things to a site that this may end up being the sensible option. It would be nice to generate my own.

There's lots of polygon and polyline data on their site, which I'm sure I'll be using at some point (if only to understand the formats more), so it seemed worthwhile serving the map images too. Still undecided but may use the API in the meantime for the mapping

brotherhood of LAN

6:17 pm on Apr 29, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Just to summarise,

In my case, I'll probably stick with the OS Openspace API. They do have limits and seem to only allow one site per API key, but that's not a problem.

In regards to maps in general, and usage of map data, it seems like creating a basic WMS server [en.wikipedia.org], and use it in conjunction with something like a Javascript library like Open Layers [openlayers.org] is a good permanent solution.

It seems map servers in general will output smaller tiles, typically 255px by 255px, so I think in future I'll probably chunk the images into that size and any user interaction with the map will load up new squares.

The map server is a complicated avenue, but would be a cool 'personal' widget to have for sites.