Sunday, July 3, 2011

Create Zoomable Images Using The Google Maps API




I visited the Google+ Project website the other day and to my surprise, it was powered by the Google Maps engine! It is somewhat creative to re-use the Maps engine for any purpose other than mapping. It is just beautiful.

It also reminds me of the Art Project I've seen a while back that uses the Street View engine. A must see.

Anyways, I'm pleased to show you two samples today: they both let you navigate into an image using the Google Maps engine. I'm also giving up the necessary tools to do it yourself. Enjoy!

Table of Contents




Introduction


Hi,

I've decided today to create small Google Maps samples that lets you zoom in and out of two pictures. As I said, I'm giving all the code to reproduce them including a small command line utility that lets you generate, from a source picture, the tiles your map needs to zoom into it. Pretty nice huh?


Sample #1 - Earth


Yes! what you're seeing at the top of this article is actually a Google Maps map! The map contains only custom controls for a richer user experience. Go back to the top if you missed it...

Let's look at a more simple example this time:


Sample #2 - Lara Croft





Possible Applications


The two samples are pretty cool but aren't very useful as they are. But maybe we can think of some possible applications of this technology for...

  • online installation manuals, where you can zoom and interact with some components
  • museums, to display pieces of art in great details
  • learning, by exploring the different layers of something
  • any product showcase, to show in details the features of a product
  • etc...

There's plenty of possible applications and if you're thinking about something interesting, feel free to share your ideas by leaving a comment below!


How it works


If you're not a Google Maps API guru, you may find the recommended reading section of this article quite useful.

Technically, this is pretty simple. At the zoom level 0 (zero). Google Maps displays a single 256px square tile representing "the world" (your whole object). As you zoom to the level 1, Google Maps shows the equivalent of your original tile zoomed to 200%: a 512px square area. But it is not your original 256px tile that is stretched by 200% to fill that area, what happens is that 4 new 256px tiles are loaded. So the same picture is shown, but it has four times the resolution and since the map's viewing area stays the same size, you have the impression that the picture has been zoomed in. At any zoom level, you can find the number of tiles there are on each side of the map with this formula: 2zoom.

The idea here is to find a picture large enough to cover the zoom level 4 or 5 (4096 by 4096 or 8192 by 8192). Then use my utility to split that picture recursively at each zoom level into 256px tiles.

After that it is only a matter of telling Google Maps API to use your tiles instead of the default ones.


HTML/JavaScript Code - Both Samples


This is a complete example of an HTML file containing my 2 samples. Just copy and paste the code into a local .html and open it with your favorite browser. UPDATE: An html file has been provided in the Related Downloads section. If you're looking for the tiles generator, it's here.


C# Code - Tiles Generation


Copy and paste the following C# code into a new Console Application project (lets say "TilesGenerator"). UPDATE: A compiled version has been provided in the Related Downloads section. You can invoke the program like this:

TilesGenerator.exe [maxzoom] [filename]

Where [maxzoom] represents the maximum zoom level you want to achieve. And [filename] represents your huge picture from which you want to generate the tiles for each zoom level.

Remember, at zoom level...

0, you have 1 (256px wide) tile
1, you have 4 tiles
2, you have 16 tiles
3, you have 64 tiles
4, you have 256 tiles
5, you have 1,024 tiles
[...]

So if you choose level 5, the program will resize your original picture to 8192px by 8192px (32 by 32 tiles) and will generate all the 1,024 tiles for that level. It will then resize your original image to 4096px by 4096px to generate the 256 required tiles for the zoom level 4. It will proceed as such for the remaining zoom level until reaching zoom level 0. At the end, you'll be having 1 + 4 + 16 + 64 + 256 + 1024 = 1,365 tiles. It's best to use a square picture.


Credits




Recommended Reading


A great book that I can recommend you is a plain JavaScript book called . This is THE book to have if you want to master the basics of JavaScript. Even today, I can open up the book at any page and learn or re-learn something useful. JavaScript is so rich, having an in-depth knowledge of it is the key to success to build great applications with any library.

Then if you're a beginner with Google Maps API v3, you will definitely find interesting . One reviewer actually said: "The online documentation of the google maps api 3 is pretty good, but I definitely found that using this book helped me get my project done alot faster."


Conclusion


Thank you for reading, don't forget to like the article (if you really did) and buy your books from if you're a reader :) It encourages me to write more and more articles on this blog.

Again, thank you for being here.


Related Downloads


File Name Description Size
index.html Google Maps Demos 11.7 KB download
license.txt TilesGenerator.exe license 799 bytes download
TilesGenerator.exe TilesGenerator Compiled Executable 6.50 KB download
TilesGenerator.zip MS Visual C# 2010 Express Sources 8.56 KB download


Related Articles


107 comments:

moussan said...

Hi, thank you for the excellent guide. I am new to programming. let alone C#. When i try to build the code in visual C# 2010 express, i get 31 errors.

for example;
The type or namespace "Drawing" does not exist in the namespace 'system' (are you missing an assembly reference?)

can you help me compile and run this code. I am better at JavaScript and HTML.

Hi, thanks for reading!

You have to include "System.Drawing" as a reference to your console application!

Let me know if I can be of any further help

Mike

moussan said...

Hi,
So i managed to take my first baby steps in the world of visual C# programming and using the visual studio express tools.

First I added the 'System.Drawing' Reference through the solution explorer. Then i 'Build' the program.

When i use it through the command console i receive the following error.

C:\C#>TilesGenerator.exe 5 PB-profile.png

Parameter is not valid.


I hope i am not troubling you with my simple questions.

Moussa

Anonymous Avatar Anonymous said...

hi mike,
great article - thanks.

i had same as moussan - parameter error, thought it was something duff with png codecs on my system or similar issue but decided that is was the encoding parameters.

within "SavePNG" I replaced

EncoderParameters encoderParams = new EncoderParameters(0);
img.Save(path, codecInfo, encoderParams);

with

System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 0L);
myEncoderParameters.Param[0] = myEncoderParameter;
img.Save(path, codecInfo, myEncoderParameters);

and it worked - moussan give that ago...

otherwise thanks again,
AJP

Congrats!

Thank you very much for stopping by!

moussan said...

AJP - Thank you, it worked like a charm.

Mike - thank you for your guide.

Once i am done with my website, i will come back to show you guys.

Moussan

That is great and good news, can't wait to see what you have for us!

LockeVN said...

It works like a charm, and your code is awesome. Thanks.

Using Google Maps API like this make me feel we have Prezi (with Flash) alike in HTML and JS.

I will make a demo in my next hackday ;))

Anonymous Avatar Anonymous said...

hi

ı don't understand

for example
Console.WriteLine("usage: \"TilesGenerator.exe [4] [C:\\users\\xx\\Desktop\\image.png]\"");

in program?

It tells you how you can invoke the console application...

The first parameter is the zoom depth you want your map to be, the second parameter is the path of the big picture you want to take your tiles from..

If your second parameter (path) contains spaces, you must enclose it in double quotes!

I hope this helps

Thanks

Mark T said...

hello,

I am trying to build an image map into the background of my website. I followed all the instructions, everything is great. tile creation, etc... but the tile pics dont appear on the html page, all i see is empty boxes with broken image placeholders. zooming works, but no images are loading. i made sure the path is defined correctly.
path/tile_zoom_x-y.png
any advice?

Guy said...

Firstly thanks for this extremely well timed post...

My current project is for a charity who wish to promote Public services to the under 25's. They have also drawn the area out by hand. I believe that is something like 10x7 a4 pages... So pretty good for making use of your project...

I've never got involved with c# though and this has been a little stretch for me... Here's what i've done so far:

1) downloaded and installed "Visual C# 2010 Express"
2)Started a new "Console Application" and named "TilesGenerator"
3)Pasted your code into the page (overwriting what was there by default). I also replaced the original "image.save" code as suggested by AJP..
4)Using the "solutions explorer" I right clicked "TilesGenerator" and selected "add Referance"
5) Clicked the ".net" tab, scrolled to and selected System.drawing and hit OK.
6) Right clicked "TilesGenerator" again in "solutions explorer" but this time selected "Build" - "Build Successful"
7) I then run cmd.exe
8) Entered "TilesGenerator.exe 5 c:\LargeMap.png

However i get: 'TilesGenerator.exe' is not a recognised as an internal or external command, operable program or batch file

Any guidance would be much appreciated...

Thanks in advanced,
Guy

Guy said...

Hi,

I had to change the directory in command to where "Visual C# 2010 Express" had saved the built application...

For me this was:

C:\Users\[user name]\Documents\Visual Studio 2010\Projects\TilesGenerator\TilesGenerator\bin\Release

Hope this helps others with limited experience with C#

Mike: Thanks a million for your post... I'll email you the site link once I've developed it... Will certainly mention you when writing the site up on my portfolio...

Bye for now,
Guy

@Mark T: Have you tried looking at the "net" tab of Firebug in Firefox? It will tell you where your browser is trying to get the images from:

http://images.theblog.ca/2011/06/firebug_net_tab.png

(The filename will be in red if not found)

Let me know if there's anything..

@Guy: I'm glad you sorted things out before I had the chance to, I was away from my computer!

Thanks to both of you for your comments! I'm looking forward to see your maps!

Mark T said...

Problem Solved.
"earth" was being prefixed to all file names of the tiles, when the pics are called on the html page.

i think due to this part of the code in the C# file:
// Set custom tiles
this._map.mapTypes.set('earth', new Demo.ImgMapType('earth', '#FFF'));
this._map.setMapTypeId('earth');

and

this part of the code in the html/javascript file

img.src = Demo.Utils.GetImageUrl(this._theme + 'tile_' + zoom + '_' + coord.x + '-' + coord.y + '.png');


i corrected by making the Tilegenerator program, name the tiles correctly with the prefix.

just wanted to share.

I feel dumb here but I do not seem to be able to access your link to your tool that creates the pyramid tiles for the images. It just takes me to the blogger home page.

Has something changed?

The code is embedded in the page, you have to compile your own executable by copying and pasting it in a Console Application!

I should have provided a compiled version, my mistake!

Zoran said...

Thank you very much!!!

Any chance a compiled version could be uploaded? Im not a developer so I dont have the tools or the knowledge, however use of the maps API sounds fun :P

Awesome read anyway, exciting project :)

Sure I'll do it tonight!

Stay tuned and thanks

There you go! All the necessary files in one section.

Happy mapping!

Anonymous Avatar Anonymous said...

I'm on OSX.. but after downloading Mono (stable release), the compiled version works like a charm. Amazing... thanks Mike!!

its quite good tutorial,
i try to customize it for my own .png files. it works!!

any body please provide the shortest code for all ,
because there are two maps, earth and croft added, but i want to edit for one.. and want to delete unnecessary codes from script..
>>>

Awesome. stuff.
Do you happen to know if Google considers it legal to develop google.map apps that use non-map images?

Hi and thanks for the comment!

I will give you my personal opinion and it does not constitute a legal advice and can't be used against me. I do not represent Google in any way :) It is just my experience with a site I've put up online a while back.

But when reading the section 8.1 of the terms (http://code.google.com/apis/maps/terms.html), I think that the custom tiles falls into the "Your Content" category.

So I think it means you are responsible for the tiles you are putting on. If they are ok, then it's ok.

Most sites are doing this: they provide the frame, you provide the content. They can't be held responsible for the user generated content because it remains the property of the user (as per the agreement).

So if you put anything illegal, you would be the one being sued, not Google.

This way, sites don't have to write a clause in their agreement about every single possible things that could appear on it. And it makes the ppl sue each other instead of being sued.

Again, this is my opinion and this comment does not constitute a legal advice!

Thanks!

Matthew said...

Thanks Mike for this awesome generator.

I'm wondering whether you've worked out a way to make the images look nice on the retina display for some iOS devices?

I'll check it out..

But to make the images smoother and visually better (on every platform), I believed I had a bug when I set InterpolationMode.HighQualityBicubic for the InterpolationMode of the Graphics while saving the PNG.

(Line 106 of Program.cs)

Matthew said...

I tried setting it to InterpolationMode.HighQualityBicubic and I didn't see a noticeable difference on the iPhone. I wonder whether I'm coming at this from the wrong angle. I wonder if it would be possible with JavaScript to set the tile size to be 128x128 for the iPhone/iPad? Similar to using the CSS background-size property.

Matthew said...

I'm still testing, but here are the changes I made to the JavaScript to make the graphics look good on a retina display.

// !Added different center for retina display
if(window.devicePixelRatio >= 2) {
var myLatlng = new google.maps.LatLng(66, -90);
} else {
var myLatlng = new google.maps.LatLng(0, -20);
}

// Create map
this._map = new google.maps.Map(container, {
zoom: 1,
center: myLatlng,
mapTypeControl: false,
streetViewControl: false
});

and

// !Added check for retina display
if(window.devicePixelRatio >= 2) {
Demo.ImgMapType.prototype.tileSize = new google.maps.Size(128, 128);
} else {
Demo.ImgMapType.prototype.tileSize = new google.maps.Size(256, 256);
}

Hi Matthew,

Thanks for sharing with us your code!

Josh Lien said...

Hi Mike,

Thank you so much for taking the time to write this post. Your tile generator is perfect (thanks for providing the source). One question, I tried to bump the max zoom to 6 (instead of 5). I changed the logic in the if statement but am still getting "Parameter is not valid" after building. Am I missing something simple?

Thanks again!

Hi and thanks for the comments :)

It should do the trick, line 39 of Program.cs, change 5 for 6.

Let me know if it's still doesn't work.

Thanks

Josh Lien said...

Thanks for responding. Yes, that's the value I changed. After building, I receive "Parameter is not valid". I'll troubleshoot this later today and post back this weekend. Have a good one.

Josh Lien said...

Found my problem! My image resolution was too large at the zoom level I was choosing. I didn't have enough physical memory (including my swap file) to process the bitmap. Hope this helps anyone else getting "Parameter is not valid" while running Mike's (awesome) Tile Generator.

Wow thanks for sharing that with us.. I really was wondering what could be happening.

I hope you will post a link of your (awesome) project when done ;)

Thanks!

Miguel said...

mike im a down right idiot ill be honest. Im trying your tile utility and i just cant get it towork? im windows 7 64 bit machine. i'm trying to use your compile version.
[3]["C:\Users\JAM\Documents\YOUARE HERE\upperLevelImg"]
but im getting no where can you give a noob a helping hand.

Miguel said...

i finally noticed i was not passing the paremeters correctly mike. thanks. now im stuck trying to get the file to read my images...

http://cdn.mikecouturier.com/blog.mikecouturier.com/images/maps-tiles/

Miguel said...

hey mike one question. i have tile my images. and i have put them on a directory image on the root of my site however when i change the location from
'http://cdn.mikecouturier.com/blog.mikecouturier.com/images/maps-tiles/';

to 'image'
my images dont display. can you give me a bump and tell me what i can possibly be doing wrong.

Arjan Duijs said...

Hey Mike,
thanks for the great example.
I am currently playing a bit with the code and trying to get/(re)set the bounderies (so the image doesnt pan outside the viewport).
I have tried to put the listeners and eventfuntion in the Earthmap class .. wel actually i hace tried to put it everywhere.. but without any luck.

any suggestion on where and how to accomplish that?

NATO24 said...

Thanks for sharing your awesome work Mike, helped me tremendously.

-Nathan

Anonymous Avatar Anonymous said...

Hi,

We need to know how to limit the zoom level,it is zooming to infinity.

In my iPad it is zooming to infinity,


I want to use only the image in the window not the total space

When creating the map, you can set some MapOptions including "maxZoom" and "minZoom". (http://code.google.com/apis/maps/documentation/javascript/reference.html#Map)

Concerning restricting the panning of the map to a certain area, there are some workarounds including: http://stackoverflow.com/questions/3125065/how-do-i-limit-panning-in-google-maps-api-v3

Thanks for reading!

http://campus.ciit.net.pk

see & comments plz...

Pedro said...

Amazing post Mike! Thanks! I'm just starting, so it's really useful.

Just one question, is it possible to add links to some areas of the image?

For example, if you click in Lara's head, you go to a site and if you click in one hand you go to a different site.

Is it possible? Thanks!

Yes check out markers or overlays in the Maps Api documentation! Thanks for reading!

Using this method you outline (which works very well,

How do you disable the streetview icon in the navigation controls?

In the Map Options (while creating the map), you can set a flag like:

{
[...]
streetViewControl: false
}

See: http://code.google.com/apis/maps/documentation/javascript/controls.html#Adding_Controls_to_the_Map

Thanks for reading!

I had tried that in this implementation, that you example, and for some reason it causes the entire map to stop rendering.

Still trying to figure out what went wrong.

Thanks for the info though

I did not tried it but this isn't working?

this._map = new google.maps.Map(container, {
  zoom: 1,
  center: new google.maps.LatLng(0, -20),
  mapTypeControl: false,
  streetViewControl: false
});

I'll check this out tonight if you can't get it working...

Thanks

Actually I got it just now.. silly commas.

Thanks! - now just need to add a logo in the corner, and some text. (copyright)

looks amazing when its fucntioning.

check out: http://www.maritimedw.com/products/windows/decorative for a demo (click on configuration examples)

Wow your app is pretty cool :)

I knew it was the comma ;) Happens to me a lot also...

I'm thankful you took the time to share your work with us (a real-world project)

Have you tried a white background in your maps?

Thanks again

Hint: for the logo and the text, I would use custom controls for easy positioning.

Check the first sample and

http://code.google.com/apis/maps/documentation/javascript/controls.html#CustomControls

Dawacks said...

Thank's for this great work.
His it posible to add marker ?
This don't work :
var marqueur = new google.maps.Marker({position: new google.maps.LatLng(0,0),map: croftMap
});

And how can i know the LatLng ?

Dawacks said...

In the croftMap class i put this :
this._marker0 = new google.maps.Marker({position: new google.maps.LatLng(0,0), animation: google.maps.Animation.DROP, icon : bvIcon, map :this._map,
title:"my home"
});

It work's but i'm not sure it's the best way to do it...

Hi,

For marker you can check the v3 documentation here:

http://code.google.com/apis/maps/documentation/javascript/overlays.html#Markers

To know where you want to place the marker, maybe you can bind a temporary click function on the map that shows you the lat/lng where you clicked... something like:
google.maps.event.addListener(map, 'click', function(event){
console.dir(event.latLng);
});

See: http://code.google.com/apis/maps/documentation/javascript/reference.html#MouseEvent


Thanks for reading! Share your work when done!

Hi,

For marker you can check the v3 documentation here:

http://code.google.com/apis/maps/documentation/javascript/overlays.html#Markers

To know where you want to place the marker, maybe you can bind a temporary click function on the map that shows you the lat/lng where you clicked... something like:
google.maps.event.addListener(map, 'click', function(event){
console.dir(event.latLng);
});

See: http://code.google.com/apis/maps/documentation/javascript/reference.html#MouseEvent


Thanks for reading! Share your work when done!

Dawacks said...

Hi,
Thank's for the help.
Here you can see my test map :
http://www.ville-frejus.fr/bvote/BN/gmaps6.html

My last problem is that the map and the marker are repeating out of my image.
I try to fix it, if you have any idea ....

Your marker is repeating because Google Maps wraps the world by default.

Maybe you want to prevent the dragging from happening outside of your "bureaux de vote".

See around the "checkBounds" function in this example:

http://econym.org.uk/gmap/example_range.htm

Merci de partager ta carte avec nous :) Bonne chance et n'hésite pas si tu as d'autres questions.

Mike (Québec, Canada)

Dawacks said...

Merci pour ces quelques mots en Français, ça fait toujours plaisir :)

I think prevent the dragging from happening outside of my tiles is the only way. But for the marker at the limit of the map and the zoom allowed i need to add a white space on my jpg img.

I will update the code of your link for Gmaps V3.

Tony said...

Firstly, many thanks for an excellent "how to" guide. Ive managed to get most of what I need working but am confused over one area. Lat and Long. I'm using a scanned in map rather than lara :-) and set the centre to be the correct geographical long and lat, but my "bounds" seem to be between about -180 and +180, and -75 and +75 whereas I was expecting bounds to be based around my centre point, given that the map is only about 2 square miles. I think its related to the Projection but not sure how? Any help, pointers or guidance would be appreciated.

I don't have a lot of time today to ckeck this out but you can read this portion of the Maps Api documentation in the mean time:

https://developers.google.com/maps/documentation/javascript/maptypes#MapCoordinates

In short, at the lowest zoom level , the Maps API thinks it is showing the whole world. So if your picture is a Map of a subset of the world, I think you would have to map the coordinates with a function.

I'll also read this portion of the documentation and dig a little more.

Thanks!

Tony said...

Mike

That was a fast response! Thank you. Further digging (based on your comments) actually took me here http://universimmedia.pagesperso-orange.fr/geo/loc.htm where it allows you to click a point and see the long and lat and it seems the -180 to +180 and -90 to +90 are the long and lat of the entire world. I think you are right. Because my "world" is approximately 2 square miles, I think I've got to do some kind of (accurate) mapping. It certainly explains why my bounds weren't working ! Thanks again

Anonymous Avatar Anonymous said...

Hi! I'm Nicola,
can you send me all file of demo in a file zip or rar?
My contact is nicopiso@hotmail.com

Tanks.

Marco said...

hi mike,
great article !!

I would to insert in Jquery UI dialog, but map is partially hidden,

could you help me ?

Iroro said...

Hi Mike,

Thanks for sharing your knowledge, I like your blog. I'm currently working on a GIS project and have been trying to download aerial photos from Google Earth and I really hope you can help, any ideas? cheers!

mlee3680 said...

Perfect post. Here’s a tool that helps create Map Mashup providing a step-by-step wizard that generates ready-to-deploy code on any website or blog http://blog.caspio.com/integration/announcing-the-new-and-improved-map-mashup-version-7/

mlee3680 said...

Perfect post. Here’s a tool that helps create Map Mashup providing a step-by-step wizard that generates ready-to-deploy code on any website or blog http://blog.caspio.com/integration/announcing-the-new-and-improved-map-mashup-version-7/

Peter Gulyas said...

I am trying to display an image that naturally is not a square (256x200). I am getting all sorts of interesting stretching happening. Is there a way to fix this without having to re-size my original image?

Peter Gulyas said...

Also I would like to be able to not let the scroll view leave the image area. Any ideas on that?

Mike said...

Peter Gulyas

What I had to do was pad the image to be square in an image editing program (by extending the canvas to square and applying a background color or pattern.

as for the boundry thing I had looked into it before but cannot find my research. This may help though

http://stackoverflow.com/questions/3125065/how-do-i-limit-panning-in-google-maps-api-v3

Peter Gulyas said...

I put this question on stack overflow. http://stackoverflow.com/questions/11724133/google-map-v3-to-display-a-zoomable-image.

I have a solution for part one. Its not very nice but I can display images of any size. this is important because users will be uploading the images.

Malky said...

Just came across this and looks VERY intersting and I can forsee many uses for it.

Thanks and I'll return to post again after trying it out.

Jake Wilson said...

Can you not use your TileGenerator to generate tiles greater than zoom level 5? Why did you limit it like that?

Anonymous Avatar Anonymous said...

Hi Mike,
Thx for this great post.
I would like to develop an app that would be used like a tourist guide in some places.
So i would like to use the API for displaying the map of the place being visited and add markers for the points of interests.
My question is: can i use this API if I want the app to work completely offline with no internet connection?
If not, is there any other API you would recommend?
P.S. I'm currently considering development using HTML5 and then using Phonegap.

Thanks,
Karim

Jake Wilson said...

Mike, great examples. One problem I have is with the map repeating horizontally. I have fixed the map from repeating horizontally easy enough (by not returning tiles for coordinates outside of my bounds). But the problem is when adding Markers to the map, the markers repeat horizontally just as if the map was still repeating horizontally. Do you have any solutions for this problem besides limiting the panning?

Jake Wilson said...

Mike, to reiterate, load up the following example:

http://pastebin.com/05T1HGA1

See how the marker I created repeats horizontally on the lara croft map? How can I prevent this?

Owen Borseth said...

Exactly what I was looking for. Thanks! Worked perfectly for my fantasy map: http://owenborseth.com/legends-of-nuvia-the-soul-of-kaesh/the-world-of-nuvia

uit said...

Hi Mike,

i was playing around with more zoom levels than the 5 your TilesGenerator could do, so i edited your source and got the feared "invalid parameter" error

the cause (on my testing runs) is the lack of reserved memory of an x86-application.

so if you compile your TilesGenerator for an x64-platform it will eat a lot of memory, but it can handle very large files (16384x16384px) an at least 6 zoom levels

Andrew said...

I modified the posted Tile Generator Source to allow for more multi-threading. I got it to run in less than 10 seconds..compared to the previous 20 minutes.

Email me for source

First of all, I've written the program in a couple of minutes just to have a proof of concept working in the web page. I'm glad some of you folks are using it for a base to something more professional!

Right now, in the tile generator, the time spent on anything other that re-sizing and cropping images is virtually non existent. So your cropping technique and the way the problem is solved must be way more efficient to have a 120 fold performance increase!

In any case that's great news for everybody! I don't have access to your e-mail and I'd like to post your version as well if you want to :)

Thanks

lzs said...

Hi..
Is it possible to use not square images?
I did a test.. but my image has 16:9 ratio .. so when I use your TilesGenerator .. it modified my image to square ration.. is it possible to keep the ratio ?
What are the impacts of this ?

tks a lot!!
great work !!

Anonymous Avatar Anonymous said...

Hi Mike,

Thanks so much. A quick question, I work on a mac is it possible to implement this in MacOS? I am very fluent with photoshop and illustrator so perhaps there is a work-around for the tile generation not using c#?

Thank you.

Elaine

After I wrote this, I saw a couple of tools that cut tiles for maps software.

Just google it and I bet you will find a couple of tools written in another langue or even online...

Thank you for your interest!

arnaldor21 said...

Hi Mike
I have been following you blog for a while and really enjoyed this post.
I have been trying to get my site running using your script but seem to have hit a road block. If I send you a zip of of the file and tiles I am trying to view, can you point me in the right the direction? Any help would be greatly appreciated.
Arnold R.

Sure maybe you can post your zip file somewhere or write me on my google mail.. mikegleasonjr

Ula said...

Hi Mike! Thanks for ur guide, it was very helpful:D Thanks)
but, i have some problems with adding events((
for example, i can not re-open InfoWindow, also where i can add piece of code which has deal with events?!
Thank you) ill wait ur answer

Hi,

Even if you change the skinning of the Maps API, the info windows and the events are still managed in the same way as before.. as long as you have the map instance, you can do everything as before.

Please have a look at the events documentation:
https://developers.google.com/maps/documentation/javascript/events

And overlays (in particular, infoWindows):
https://developers.google.com/maps/documentation/javascript/overlays#InfoWindows

In my demos, the map instance is stored in the variable "this._map". See the source of the page: http://cdn.mikecouturier.com/blog.mikecouturier.com/tilesgenerator/index.html

Thank you for your interest!

NATO24 said...

I finally got around to implementing a feature with the help of your library. Thanks again for sharing your code.

View

Nathan

Ula said...

Thanks Mike! I handled it, but now i have another problem. Is it possible to put image with 900px by 800px at the xoom level 0? I know that it is by default 256 x 256 px! thanks)

I needed this Tiles Generation C# Code. Thanks so much for sharing. Appreciate for the important and valuable information blog post.

Tom Safin said...

vttnsguy said:

Hi Mike: Your blog and information is great. I am new to the map api coding, but I was able to take a png and create the zoom wonderfully. My question is how would I add html map areas that would be maintained in the zoom-in and zoom-out phases?

Feldon said...

This is nice, but why oh why did you have to combine both demos into a SINGLE html file with ALL the javascript stacked together? This means hunting and pecking through unfamiliar code, trying to remove one of the two examples without breaking anything. It would be much better to have Earth and Croft as 2 separate files with independent Javascript.

I know -- looking a gift horse.

muy muy bueno, gracias, es lo que buscaba

De nada :)

Maxwell said...

Hey there,

Can this technique be implemented on squarespace? they let you do code injections --

Just thought I would ask if you knew off the top of your head so I don't waste time trying to fig. out how to get this image working

thanks so much,this rules.

if you're getting grey and no loaded images, make sure you check to see if you have a "max-width" setting on all of your images.

if so

add
div#your-map img { max-width:inherit; }

Anonymous Avatar Anonymous said...

Hi Mike!

One question, I want to use the tiles on my PC with a path like this 'C:\Users\...' instead of an URL.

Is it possible? Do I have to change the "Demo.ImagesBaseUrl = 'http://cdn.mikecouturier.com/blog.mikecouturier.com/images/maps-tiles/'" to "Demo.ImagesBasePath = 'C:\Users\...'" or something like this?

I hope you understand what i mean.

Dominik said...

Andrew, you mentioned you had a multi-threaded version available, could this be shared (since the code is GPL licensed) ?

Thanks ;-)

lv hung said...

Hi Mike!

I have one question about copy right when using google map API script to zoom image. If I apply for enterprise website, is it correct? (I also hide logo and link of google)

Thank

MikeO said...

Hi Mike,

really nice job! Were you ever thinking of another extension like to make the "map" click-able? Would it be possible to combine it with standard HTML map&area tags and make it interactive while keeping the zoom function? Let's say we will define the area borders as polygons at the max-zoom level and your app will not only resize the picture (tiles) but the areas as well?

Thanks :-)

Anonymous Avatar Anonymous said...

That was really helpful, especially the tile generator exe :-) Thanks a lot for the effort!

Anonymous Avatar Anonymous said...

What's the name of the suggested book about javascript? There's no title in the recommended reading paragraph.

Anonymous Avatar Anonymous said...

Thank you so much for this awesome article, this was extremely useful!

All the best to you, Mike! =)

Anonymous Avatar Anonymous said...


Could your technique be used to allow "searching" for a name on a memorial wall image like this page?

http://www.fold3.com/image/48064217/

Our local Veterans Memorial would like to have this feature on our website so visitors could actually "see" their loved-ones names on our stones. Our site here:
www.assumptionveteransmemorial.com

we can get high-res images of our stones with the name on them. Do you think this could work? My email is mconnolly(of course add the @)live.com and any help you could give us would be much appreciated! Thanks a bunch

Anonymous Avatar Anonymous said...

I added a Java based implementation if it helps anyone.

https://github.com/devldevelopment/googlemaptiler

Louis said...

You don't need multithreading to get a HUGE performance increase..

Just move the "new Bitmap()" call in CropSaveAndTile, move it outside the for loops. It will make execution from 10 minutes to 10 seconds.

Resulting methods look like:

private static void CropAndSaveTile(Bitmap bmpImage, int x, int y, int level)
{
Rectangle cropArea = new Rectangle(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);

using (Bitmap bmpCrop = bmpImage.Clone(cropArea, bmpImage.PixelFormat))
{
string filename = String.Format(TILE_FILENAME, level, x, y);

// the Portable Network Graphics (PNG) encoder is used implicitly
bmpCrop.Save(Path.Combine(OUTPUT_DIR, filename));
Console.WriteLine("Processed " + filename);
}
}

static void SplitTilesRecursive(Image original, int level)
{
int mapWidth = GetMapWidth(level);
int tilesOnSide = mapWidth / TILE_SIZE;

using (Bitmap resized = new Bitmap(ResizeImage(original, new Size(mapWidth, mapWidth))))
{
for (int x = 0; x < tilesOnSide; x++)
for (int y = 0; y < tilesOnSide; y++)
CropAndSaveTile(resized, x, y, level);
}

if (level > 0)
SplitTilesRecursive(original, level - 1);
}

©2009-2011 Mike Gleason jr Couturier All Rights Reserved