I'm developing a web page with a Google maps application. Currently, I have a functional search bar and map that displays three KML/KMZ layers. I need to be able to toggle between each of the layers, either display one of them, two of them or all three. There is a similar function in Google Earth, but I need it in Google Maps. How can I do this?
Here is my code for the map and search bar:
<script type="text/javascript">
var geocoder;
var map;
var marker;
function initialize() {
geocoder = new google.maps.Geocoder ();
var latlng = new google.maps.LatLng (40.43, -74.00);
var myOptions = {
zoom: 5,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
marker = new google.maps.Marker({map:map});
var ctaLayer = new google.maps.KmlLayer('http://dl.dropbox.com/u/80233620/NY_Radar_data.kmz');
ctaLayer.setMap(map);
var ctaLayer = new google.maps.KmlLayer('http://www.nyc.gov/html/dot/downloads/misc/cityracks.kml');
ctaLayer.setMap(map);
var ctaLayer = new google.maps.KmlLayer('http://dl.dropbox.com/u/80233620/OKX_Radar_data%20(1).kmz');
ctaLayer.setMap(map);
}
function codeAddress () {
var address = document.getElementById ("address").value;
geocoder.geocode ( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results [0].geometry.location);
marker.setPosition(results [0].geometry.location);
map.setZoom(14);
}
else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
</script>
It's simply setMap(null)
to hide one, setMap(map)
to show. I keep a global array variable layers
, to keep track of which layer to toggle:
var layers = [];
layers[0] = new google.maps.KmlLayer('http://dl.dropbox.com/u/80233620/NY_Radar_data.kmz',
{preserveViewport: true});
layers[1] = new google.maps.KmlLayer('http://www.nyc.gov/html/dot/downloads/misc/cityracks.kml',
{preserveViewport: true});
layers[2] = new google.maps.KmlLayer('http://dl.dropbox.com/u/80233620/OKX_Radar_data%20(1).kmz',
{preserveViewport: true});
The preserveViewport option stops the map from jumping around when the layers are toggled.
Here's the function to toggle:
function toggleLayer(i) {
if(layers[i].getMap() === null) {
layers[i].setMap(map);
}
else {
layers[i].setMap(null);
}
}
Note it's using the global variable. Finally the HTML, you can use checkboxes or buttons, and even a radio button by setting only one active layer at first and enabling the right one when the radio set is updated.
Large weather <input type="checkbox" id="layer0" onclick="toggleLayer(0)" checked>
<input type="button" id="layer1" onclick="toggleLayer(1)" value="Racks">
Small weather <input type="checkbox" id="layer2" onclick="toggleLayer(2)" checked>
The whole demo is here, controls on top left of map: http://jsbin.com/irahef/edit#preview
Heiter's answer is good but a little addition to the code in the jsbin example, if you want to have the layers be undisplayed on initialization is to change
layers[i].setMap(map);
to
layers[i].setMap(null);
and then make sure your checkboxes are unchecked.
I tried the code posted above by Heitor, and noticed that clicking the layers on and off changes the order that they are displayed on the map. I implemented this solution to preserve the order of the layers, but it might be somewhat inefficient. If anyone has any suggestions please share.
function toggleLayer(i) {
var j;
for (j = 0; j < layers.length ; j++ )
{
if (j != i)
{
if (layers[j].getMap() === null)
{
layers[j].setMap(null);
} else {
layers[j].setMap(map);
}
} else { //toggle the selected layer
if (layers[j].getMap() === null)
{
layers[j].setMap(map);
} else {
layers[j].setMap(null);
}
}
}
}