Tuesday, 14 May 2013

Offline Google Maps + Google JavaScript API V3 + HTML5



Hi Guys,

Google poses very strict usage policies on maps. Maps usage for commercial purpose needs purchasing "Maps for Business" license, which costs approx $10,000 "Every Year".

However, if in-case you want to build applications on Google maps using JavaScript API V3, here is the solution. What's even better, build applications using Google map tiles saved in your own server/local system. Hence, I will show you how to build applications using offline Google maps with Google JavaScript API V3.

Recipe:
1) Download Google Map tiles.
2) Organize, rearrange and rename downloaded tiles to be accessed by API.
3) Place the files in your server's hosting space and generate a URL to access the same.
4) Use the same URL in Google JavaScript API to use offline maps to build your application.

Ingredients:
1) Download "Easy Google Maps Downloader"  from this link here.
2) Download "Bulk Rename Utility" from this link here.
3) Use this link to get find the latitude and longitude values of any place in the Google world map.
4) Create a file and give it a suitable name with ".html" extension. Ex. Test.html.

Lets Start Cooking:
Open "Easy Google Maps Downloader", after having downloaded. The tool looks something like this:




This tool helps download Google map tiles to your computer. Its pretty simple to use. Give any crappy Task name,  select the type of Google Map you would like to download, decide the portion of map you would like to download and fill in the appropriate latitude and longitude values. Use this link to retrieve the required latitude and longitude values. Filling the above latitude and longitude details enables the tool to square up the portion to be selected for download.




Select the appropriate zoom level. The maps above is for zoom level 8. Finally, select the path to which the tiles need to be downloaded. So if in-case you want to download the entire world map, your table values would look something like this:




Press start and the map tiles will get downloaded to the given location.

But, what exactly gets downloaded. Well, Google map consists of huge number of small image files, either JPEG or PNG files, called TILES, arranged in a proper order to form map. Number of tiles downloaded are different for different zoom level and number of tiles increase exponentially with increasing zoom levels.




So roughly 4 tiles get downloaded for Zoom level 1 (world map split into 4 parts), 16 tiles for zoom level 2, 56 tiles for zoom level 3 and so on. Hence approximately 16,000 and 64,000 tiles get downloaded for zoom level 7 and 8 respectively. 

Hence, download tiles for required portion of world map to the zoom level to wish your maps to zoom into. Download tiles for different zoom levels in different folders or paths if possible. Once downloaded, here comes the main part, so, follow these instructions carefully. The folder in which you would have downloaded the tiles contains one folder and four other files. You can just retain the folder and delete all the other files. 



Now if you open the folder, you can all see the tiles downloaded for that particular zoom level. For all the tiles you have downloaded for a particular zoom level, please copy/cut the tiles and place the tiles in a folder named only with the zoom level.  For example, as discussed above, you download 4 map tiles for zoom level 1. Place those four tiles in a folder named 1. Create folders names 2, 3, 4... in the same directory and place the tiles downloaded for zoom level 2, 3, 4... etc in the respective folders. 

After, having placed the files in the appropriate zoom level named folders, now comes further segregation of tiles.  Observe carefully the name of the tiles :



Since we have already segregated the files at zoom level, we can neglect the zoom level factor and type of map factor. Now, we need to segregate the tiles by latitude. So create separate folders for different latitudes and place the tiles concerning to particular latitude in that folder.  For example, file names like  gm_8_9_1.png and gm_8_55_1.png would be placed in folder named 8 (latitude), which in-turn would be placed inside an folder named 1(zoom level).

Now all we need to do is rename the tiles with the name of Longitudes. You may remove map type attachment gm, the latitude and zoom level's tagged along the name and leave only longitude name for the tiles. Your file structure should look something like this:



Sometimes, the number of tiles to be renamed to the name of longitude may be very huge. Hence use "Bulk rename utility" tool to rename such huge number of files at once. Below picture may help you grasp some basic idea on  how it works:


  
As you can see, I have just used the high-lightened fields to remove the first 8 characters and last 3 characters to bulk rename the files to longitude name. 

Once we have renamed all the tiles and arranged all the files in above mentioned order, we are ready with offline maps. Hence copy this parent folder containing all this files, example, GoogleRoadMaps or GoogleHybridMaps etc., to your server's hosting space and retrive an URL to access the same. 

For Ex:
http://www.hostingspace.com/GoogleHybridMaps

Alternately if you are using local machine as a local host, you can use, 

http://localhost/GoogleHybridMaps

Now, you can copy and paste the below code into your test.html file and you should be able to open google maps offline. 

<!DOCTYPE html>
<html>
     <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
        <title>OpenStreetMap with Google Maps v3 API</title>
        <style type="text/css">
            html, body, #map {
                height: 100%;
                width:100%;
                margin: 0;
                padding: 0;
            }
            .main {
                position:relative;
                width:100%;
                height:100%;
            }
            .topButton {
                position: absolute;
                bottom:0;
                right:0;
                z-index:10;
            }
        </style>
    </head>
    
    <body onload="initialize()">
        <div id="map"></div>
        <div class="topButton">
            <button type="button" onclick="initialize()">Google Maps</button>
        </div>
        <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry"></script>
        <script type="text/javascript">
            var element = document.getElementById("map");
            var map;
            var zoomParameter = 8;

            function initialize() {
                var mapTypeIds = [];
                for (var type in google.maps.MapTypeId) {
                }
                
                mapTypeIds.push("GoogleRoadMaps");

                map = new google.maps.Map(element, {
                    center: new google.maps.LatLng(29.442, 47.611),
                    zoom: 2,
                    mapTypeId: "GoogleRoadMaps",
                    mapTypeControlOptions: {
                        mapTypeIds: mapTypeIds
                    }
                });

                map.mapTypes.set("GoogleRoadMaps", new google.maps.ImageMapType({
                    getTileUrl: function (coord, zoom) {

                        return "http://hostingspace.com/googlehybridmap/" + zoom + "/" + coord.x + "/" + coord.y + ".png";
                    },
                    tileSize: new google.maps.Size(256, 256),
                    name: "GoogleRoadMaps",
                    maxZoom: 16
                }));
                }
                </script>
    </body>

</html>

I hope the above HTML code is pretty self explanatory. But, just in case you find any difficulty running through the code, kindly me let me know. I would provide an explanation for the same in the portion here.

Thanks guys. Have a good day.

40 comments:

  1. the api requires internet to run.
    how to run the api offline.

    ReplyDelete
    Replies
    1. Well, yes, do internet for using these maps. But alternately, you can use INTRANET for accessing these maps as well. Another alternative suggestion, to go completely offline, would be to save the maps tiles folder in your mobile device and use api like leaflet (http://leafletjs.com/) to access the same () in case you are trying to use the maps offline in mobile devices). Thanks.

      Delete
  2. Hi Anil Suri,

    I appreciate your work. Could I ask you a question? I haven't worked with Google Maps API before but how could I change the url into a directory path which contains those map tiles? Or could we use another JS function instead of " getTileUrl: function (coord, zoom) " to do so?

    Thanks in advance.

    ReplyDelete
    Replies
    1. Dear Chi,

      Thanks for the comment. As far as the first question is concerned, you can definitely use any URL containing the map tiles. Like you could place your map tiles in any public server and use the URL as:

      http://212.232.23.43/RoadMaps/" + zoom + "/" + coord.x + "/" + coord.y + ".png";

      Where 212.232.23.43 is the static Ip of your server and RoadMap is the folder containing tiles, you have hosted.

      As far as the second part is concerned, I would suggest you not to use any other another JS function instead of " getTileUrl: function (coord, zoom)", for the function is already sufficing all your needs.

      Delete
    2. Thanks for your reply Anil:)

      I mean I want to store these map data into a directory such as "/D:/GoogleMapTiles". I understand "offline google map" as we can use google map tiles without localhos or any server, just store tiles in computer directory. Is it possible to do so?

      I appreciate your help.

      Delete
    3. Hi Chi,

      My Apologies for late reply. As for downloading the files and keeping it, even I have kept the downloaded files in my local drives (C:/ D:/ etc), as long they are not being used for any map application. As for their usage in map application, I fear you cant use the map tiles from these local drives. They have to be kept in appropriate folder for using in local network or can be kept in any folder and hosted from server for usage from any location/ network.

      Thanks.

      Delete
  3. Hi Anri,

    Thanks for this very enlightening. I have a mobile requirement for this functionality. Have you a smal working example in zip format I could test?

    ReplyDelete
    Replies
    1. Hi Anri,

      I now have it working nicely although it looks like Google blocked my IP addess after a while dowmloading the files.I was expecting to be able to use the other API functionality but currently I cannot even load a marker. Is this a limitation or should I revisit my code?

      Delete
    2. Yup I re-visited my code and all now good. Restarted my hub to get a new IP address also overcame the Google blocking issue-

      Delete
  4. Yup, even I faced the same problem. Good to know its all good :)

    ReplyDelete
  5. Great post! I'm having some trouble with my code. I followed your instructions and saved two zoom levels. The html loads fine in my browser but no tiles appear. When I pull the url for a tile on my server the tile appears as it should, just not in my map. I would be happy to share the full code. Thank you.

    ReplyDelete
    Replies
    1. Hi jgpierce,

      This is a very common problem which even I faced in the beginning. Browsers usually have some sort of web security which causes the above mentioned issue.

      To resolve this, please close all your internet browsers and open your command prompt.

      Please key in the below command:

      C:\Program Files (x86)\Google\Chrome\Application>chrome.exe --disable-web-security

      where the first URL part is the path where your chrome.exe exists(in case you are using Google chrome), and the second command helps launch the browser disabling web security. Now your browser launches with a warning saying that the browser is unsafe and stuff, but believe me, its completely harmless.

      Now try loading the HTML page and it should work like charm. Kindly let me know if in case the issue still exists.

      Have a good day.

      Delete
  6. I need to run my maps application completely offline. Is there any way to get an offline Google JavaScript API version ?

    thanx :)

    ReplyDelete
  7. Hey, Your code works smooth,Thanks:)
    Can you please help me with some more code to manually put GPS coordinates in a text box and show those coordinates with a marker on the map. further i want to synchronize those marks with a compass.
    Thanks in advance :)

    ReplyDelete
  8. hi thanks your code and instructions are working fine , am able to see the maps with zoom in and out. Only problem is that it does not work offline fully it needs internet connection,

    Is their any other way to make the maps offline without any internet connection.

    ReplyDelete
  9. Hi thanks for sharing! Please give me advice how can I creation application to Mark some location on this offline map! I wanna try Google Mark making in this offline mode! Is there anyway?

    ReplyDelete
  10. Hi Anil, Thank you very much for your code and instructions. Everything is working fine for me, loading offline tiles instead of google map. But still it is not working offline. Seems Google API needs internet to work.

    Is it possible to make this completely offline ? I need to work this within my intranet.

    ReplyDelete
  11. Hello Everyone,
    did you guys find any way to work Google Map API work totally offline?

    Awaiting for answer
    Sudip Barman

    ReplyDelete
    Replies
    1. download required java script files in your local computer such as common.js, control.js, onion.js, marker.js, etc multiple java script file. you can see all required files on browser inspector. and change localhost in google map api.

      Delete
  12. This comment has been removed by the author.

    ReplyDelete
  13. i have worked completely offline. hello guys what is the problem ? describes it.

    ReplyDelete
    Replies
    1. this is maybe a silly question, but how did you overcome the API key when calling the js? do you have the google map api library (js) on your own, so you dont need to access the source (maps.googleapis.com)?
      big thanks.

      Delete
    2. first of all you should take api key from google and then you download google map api with api key and store in your local drive. i have used this . work perfactly.

      Delete
  14. thanks alot for this article my question is how to but marks on map offline thanks alot

    ReplyDelete
  15. how to put Marks on Map offline

    ReplyDelete
  16. same like online. download markes images in your local drives.

    ReplyDelete
  17. i add this code
    but no thing appear on map


    var marker = new google.maps.Marker
    (
    {
    position: new google.maps.LatLng(-34.397, 150.644),
    map: map,
    title: 'Click me'
    }
    );

    ReplyDelete
    Replies
    1. add this code......
      var marker = new google.maps.Marker({
      position:myCenter,
      animation:google.maps.Animation.BOUNCE
      });

      marker.setMap(map);

      Delete
  18. i have a problem with authenticationService

    ReplyDelete
  19. I think I did the steps correctly but get,

    Oops! Something went wrong.
    This page didn't load Google Maps correctly. See the JavaScript console for technical details.

    So something must be a miss
    Changed http://localhost/WebIMS/maps

    Any help? Next up is using off line with no Internet connection..

    ReplyDelete
  20. doing it now would also like maps available off line

    ReplyDelete
  21. Fixed the page error problem with API Key
    Now just shows page with no maps with GoogleRoadMap button top left & the scroll movement hand icon ? Played around with the zoom level in the script.

    ReplyDelete
  22. goes to console and send screenshot

    ReplyDelete
  23. Did anyone try the Offline Map with the api javascript module and the directions module? does it work? Their online api does not return all the route details now, just the last waypoint and I can't use it in my app.

    ReplyDelete
  24. Hello.. your blog is great. I read your blog and like it very much. Thanks for sharing.
    How to Use Google Maps Offline

    ReplyDelete
  25. For sure this idea was revolutionary. consider teaming up with tom tom maps. the 3D model is still needed

    ReplyDelete
  26. Dont tell me u gave up man.arise and shine u can do it

    ReplyDelete
  27. is there any way to use any map either it is google map or openstreetmap totally offline in an angular project. it would be vary helpful if one example you can provide.
    thanks in advance

    ReplyDelete