Duncan's blog

November 4, 2011

Google Maps API – adding infowindows in response to user clicks

In response to my previous post about adding infowindows with the Google Maps API, Frank B asked if it was possible “to write a script where the user clicks on the map, and an infowindow pops up in that location containing information about that place, say the county it belongs to”. Here’s a quick something I rustled up in response to that.

Firstly, let’s just open an infowindow on a map in response to user clicks on the map.

<script type="text/javascript">
function initialize() {
	var myOptions = {
		zoom: 10,
		center: new google.maps.LatLng(50.820645,-0.137376),
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};
	
	var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
	
	var infowindow =  new google.maps.InfoWindow({
		content: 'Hello World!'
	});

	google.maps.event.addListener(map, 'click', function(event) {
		infowindow.setPosition(event.latLng);
		infowindow.open(map);
	}); 
}

google.maps.event.addDomListener(window, 'load', initialize);
</script>

So we simply have an event listener for any click events on the map itself. We can then find out the position of that click using event.latLng, which we can then pass to the setPosition function on the infowindow. The final .open() simply shows the infowindow; if it’s already open, this won’t do anything (but it causes no harm to call it again).

This opens the same infowindow anywhere we click on the map:

Now, let’s get some content about each location we click on, and use that to dynamically set the content of the infowindow. To do this we need to do a reverse Geocoding request (i.e. getting address details from a latlng coordinates). The usual use of the Geocoding service is to do the opposite – find out the coordinates of an address.

Interestingly Google’s API reference says to use a ‘location’ parameter but their Developer documentation says to use a ‘latLng’ parameter. Both seemed to work for me, but I’d say the API reference should be considered the correct source in general.

<script type="text/javascript">
var map, geocoder, infowindow;
	
function initialize() {
	var myOptions = {
		zoom: 10,
		center: new google.maps.LatLng(50.820645,-0.137376),
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};
	
	map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
	
	geocoder = new google.maps.Geocoder();
	
	infowindow =  new google.maps.InfoWindow({
		content: ''
	});

	google.maps.event.addListener(map, 'click', function(event) {
		doGeocoding(event.latLng);
	});
}

function doGeocoding(latLng) {	
	geocoder.geocode({'location': latLng}, function(results, status) {
		if (status == google.maps.GeocoderStatus.OK) {
			if (results[1]) {	// use 2nd array item, a less-specific address
				infowindow.setContent(results[1].formatted_address);
			} else {
				infowindow.setContent('');
			}
		} else {
			infowindow.setContent('no address found');
		}
	});
	
	infowindow.setPosition(latLng);
	infowindow.open(map);
}

google.maps.event.addDomListener(window, 'load', initialize);
</script>

This code does strange things for me when clicking on the area at sea. If it’s the first click on the map, it doesn’t display any infowindow at all. If I initially click on the land to get an address, subsequent clicks on the sea use that same address, unless I click further out from the land, in which case it gives me ‘no address’. Think it’s an issue with trying to do setContent(”). I’m publishing this article despite it not being quite code-complete, in the hope it helps Frank (and I’m happy to take suggestions on how to get it fully working as it should).

7 Comments »

  1. Thanks! This is exactly what I had in mind. One application of this I could see is someone could click on their house and it would return a bunch of information about it: census geography, voting district, names of political representatives, etc. without having to store all of those things as markers or visible layers.

    Comment by Frank B. — November 8, 2011 @ 5:32 pm | Reply

  2. That could be tricky. You’d probably have to use Fusion Tables to get all that.

    Comment by duncan — November 8, 2011 @ 5:58 pm | Reply

  3. I’ve actually gotten my first idea to work. See http://www.albany.edu/~fboscoe/geocode. Note that only the counties beginning with the letter ‘O’ work right now; I’m waiting for more disk space before I can add more (or a way to store the javascript as a compressed file).

    Comment by Frank B. — December 7, 2011 @ 6:46 pm | Reply

  4. Hi Duncan!

    I’ve just picked up coding for a small assignment at school and I was wondering if you would be able to help me out? I’m trying to do something a long these lines, but where i’ve already set up a google map, and populated it with a large amount of markers, that are set by the longitude and latitude of images i have pulled from Flickr, but at the moment I only have the points plotted but I would like to try to learn how to make it so when i hover over the marker it reveals a preview of the image in a small div box i will place in the top right hand corner?

    Many thanks for any help you can supply me with 🙂

    Comment by Denny — October 2, 2012 @ 8:05 am | Reply

  5. I would have an infowindow on the map, which gets triggered to open on hover of the markers. The content of the infowindow would then load in the image from Flickr. You may want to ask your question on StackOverflow, which will make it easier for you to post code and get a more complete answer.

    Comment by duncan — October 7, 2012 @ 12:10 pm | Reply

  6. Thanks for passing knowledge of good and functional contents.

    Comment by Roberto Silva — November 28, 2012 @ 10:51 am | Reply

  7. […] the presentation. I found an example that showed how to create and move an InfoWindow based on the event’s location instead of relying on marker information, so I used that to show the information with better […]

    Pingback by Exploring neighbourhood libraries and other notes from the Toronto Public Library Hackathon - sacha chua :: living an awesome life — November 16, 2015 @ 5:45 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a comment

Create a free website or blog at WordPress.com.