Share a map generated using JavaScript

I’ve created a Google Map on my web page using Google Maps JavaScript API v3. It just has bunch of markers and info windows associated with them, nothing fancy. Now I want to:

  1. Enable the user to share this Google Map (with markers and infoWindows) on social services like Facebook/Twitter
  2. Enable the user to open this map (with markers and infoWindows) in www.google.com/maps… by clicking a “enlarge this map” button, like they’re accustomed to with embedded Google maps.

Actually if I’m only able to achieve (2) and (1) is not possible from my website, then (1) can be achieved on www.google.com/maps.. anyway, so (2) is the critical point.

I’ve searched over the web for a decent amount of time but I couldn’t find any leads.

P.S. I’ve tried to make this question more specific and have highlighted the specific parts for visual convenience as well.

Update

I’m using following code to generate said Google map

var latlng = [{
      title: 'Title 1',
      address: 'Address 1',
      city: 'City 1',
      postcode: 'Postcode 1',
      phone: 'Phone 1',
      lat: 43.7810795,
      lng: -79.3245521
    }, {
      title: 'Title 2',
      address: 'Address 2',
      city: 'City 2',
      postcode: 'Postcode 2',
      phone: 'Phone 2',
      lat: 43.7910795,
      lng: -79.3245521
    }
    /* the are many more objects like the two above ... */
  ],
  markers = [],
  infoWindows = [],
  bounds = new google.maps.LatLngBounds();

function addMarker(info, map) {
  var marker = new google.maps.Marker({
    position: new google.maps.LatLng(info.lat, info.lng),
    map: map,
    title: info.title,
    animation: google.maps.Animation.DROP
  });
  bounds.extend(marker.getPosition());
  markers.push(marker);

  var infoWindow = new google.maps.InfoWindow({
    content: '<div class="infowindow"><h3>' + info.title + '</h3><div>' + info.address + '<br />' + info.phone + '</div></div>',
    maxWidth: 200
  });

  infoWindows.push(infoWindow);

  google.maps.event.addListener(marker, 'click', function() {
    for (var k = 0; k < infoWindows.length; k++) {
      if (infoWindows[k] !== infoWindow) {
        infoWindows[k].close();
      }
    }
    infoWindow.open(map, marker);
  });
}


function gmapInitialize() {
  var mapOptions = {
    zoom: 8,
    center: {
      lat: latlng[0].lat,
      lng: latlng[0].lng
    }
  };

  var map = new google.maps.Map(document.querySelector('#loc_map_14'), mapOptions);

  for (var i = 0; i < latlng.length; i++) {
    addMarker(latlng[i], map);
  }

  map.fitBounds(bounds);

  (function($) {
    var map_enlarge = $('.map-enlarge'),
      map_restore = $('.map-restore'),
      site_main = $('.site-main');
    map_restore.hide();

    map_enlarge.click(function() {
      site_main.addClass('sidebar-extended');
      $(this).closest('.locations-map-cntnr').css('height', 600);
      $(this).hide();
      map_restore.show();

      google.maps.event.trigger(map, 'resize');

      map.fitBounds(bounds);

      return false;
    });

    map_restore.click(function() {
      site_main.removeClass('sidebar-extended');
      $(this).closest('.locations-map-cntnr').removeAttr('style');
      $(this).hide();
      map_enlarge.show();
      google.maps.event.trigger(map, 'resize');

      map.fitBounds(bounds);

      return false;
    });

  })(jQuery);
}

google.maps.event.addDomListener(window, 'load', gmapInitialize);

@MrUpsidown thanks for the comment, so the answer to (1) is “deliver this same map as the only content through a separate/dedicated URL of my website as well and then share that URL on social services”. That’s a good solution.

Why would you want users to open the same map with maps.google.com? My objective is to replace an embedded Google map with this map and keep the “Open in Google maps” option/button too so that they’re seamlessly redirected to google.com and still see this map.

I think I’m going to look into creating a static map using Google map’s API. Will look into that.

Answer

For social sharing, you will need to encode the entirety of your maps configuration into the querystring. A mediocre version might look something like:

location.hash = '#' + JSON.stringify({ m:markers, i:infoWindows });

However, this would never work for Twitter given the imposed URL length restrictions. You could use a URL shortening service to shorten the ugly JSON URLs. Or, use a decent querystring builder, there are a multitude available on GitHub.

// at some point restore from the hash:
function restore() {
  var hash = location.hash.substring(1),
      json = hash && JSON.parse(hash);
  // do what you gotta do.
  json.m.forEach(addMarker);
  json.w.forEach(addWindow);
}
restore();  // on DOMContentLoaded or whatever

function share(markers, windows) {
  var url = location.href.replace(/#.*$/,'') + '#';
  // swap this for something less terrible:
  url += JSON.stringify({ m:markers, w:infoWindows });
  shorten(url, function(short) {
    window.open('//www.twitter.com/share?url=' + encodeURIComponent(short));
  });
}

function shorten(url, callback) {
  // use what you know. example is http://github.com/synacorinc/jan
  http.get('https://api-ssl.bitly.com/v3/shorten?access_token=ACCESS_TOKEN'+
    '&format=txt&longUrl='+encodeURIComponent(url),
    function(err, res, body) {
      callback(body);
    }
  });
}

Leave a Reply

Your email address will not be published. Required fields are marked *