I have a single-page HTML5 app that consumes a bunch of different map providers. One of my requirements is that this work with no internet connection and some sort of map provider running on the box itself.

What , if any, providers -- free or commercial can give me something along the lines of an offline google maps or google earth that I can use in a web application?



I addition to the answers provided in the Mapperz' link, another option you might consider is to set up your own instance of GeoServer with a suitable area of data from OSM loaded into a PostGIS database. You can obviously add in other data as well but OSM is a good start. All of this is free. I have this set-up as an off-line test-rig for web mapping development.

  • Thanks for the pointers, I ended up going a slightly different route. Through sheer luck or whatever, I was able to get a working mapserver up in a couple of hours without much pain – Yablargo Oct 17 '13 at 13:08

After reading around, I was able to get a running map server up in about 2 hours work overall. I am very happy with the result!

First, I loaded OpenLayers directly into my local HTML app from http://www.openlayers.org/

Cloning from their public github, one only needs to copy the img and theme folders, as well as openlayers.js.

I created a MBTiles file using TileMill @ https://www.mapbox.com/tilemill/

This was awesome and quick. I used a default project and removed some of the styles to get me a more regular map. Using a pre-existing mbtiles file( where do I find some good prefabs?) would speed up this step.

I exported my TileMill project as a MbTiles project.

Since my app already has an optional NodeJS server, I used the following code to serve up my mbtiles:

new MBTiles('openlayers/map.mbtiles', function(err, mbtiles) {
  if (err) throw err;
  app.get('/mbtiles/:z/:x/:y.*', function(req, res) {     
    var extension = req.param(0);

    switch (extension) {
      case "png": {
        mbtiles.getTile(req.param('z'), req.param('x'), req.param('y'), function(err, tile, headers) {
          if (err) {
            res.status(404).send('Tile rendering error: ' + err + '\n');
          } else {
            res.header("Content-Type", "image/png");
      case "grid.json": {
        mbtiles.getGrid(req.param('z'), req.param('x'), req.param('y'), function(err, grid, headers) {
          if (err) {
            res.status(404).send('Grid rendering error: ' + err + '\n');
          } else {
            res.header("Content-Type", "text/json");


Then, in my openlayers map provider:

 map = new OpenLayers.Map('map', options);

            // create TMS layer using MBTiles sqlite database
            var mbtilesLayer = new OpenLayers.Layer.TMS("MBTiles Overlay", url, {
            getURL: mbtilesURL,
            isBaseLayer: true,
            type: "png",
            //opacity: 0.7,
            layername: "map"
         // See: http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection
            function mbtilesURL (bounds) {            
             var res = this.map.getResolution();
    var x = Math.round ((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
    var y = Math.round ((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
    var z = this.map.getZoom();

    var path =  z + "/" + x + "/" + y + "." + this.type; 
    var url = this.url;
    if (url instanceof Array) {
        url = this.selectUrl(path, url);
    return url + path;


         //   map2.addLayer(layer);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.