Search code examples
javascripthtmlgoogle-mapsgoogle-maps-api-3google-fusion-tables

Only open Google Fusion Table for one map type/ Remove Google Fusion table for certain map types


I am trying to make a web map using the Google Maps Javascript API. I want a Google Fusion Table of buildings in Boston to appear only on the stylized map which I called "Buildings." When I click on the Buildings map type, the buildings layer appears. Then when I click on the road and satellite map, the buildings layer disappears just how I want it to. However, if I first click on the road or satellite map type and then click the Buildings map type, the buildings layer doesn't load. I can't figure out why. Thanks!

<!DOCTYPE html>
<html>
<head>
<h3 align="center">Boston, MA</h3>
<title>Massachusetts, USA</title>
<meta name="Running Destinations" content="initial-scale=1.0, user-scalable=no">
<meta name="author" content="CodingGrandma">
<meta charset="utf-8">
<style>
    /* formatting for html containing the map */
    body {background-color: White;}
    h3 {color: Black;}
    /* formatting for map */
  #map {
    height: 75%;
  }
  html, body {
    height: 100%;
    margin: 1;
    padding: 0;
  }
    </style>
  </head>
  <body>
    1 foot<input type="radio" name="Storm Surge" value="1 foot" id="1_ft_surge"/><br/>
    2 foot<input type="radio" name="Storm Surge" value="2 foot" id="2_ft_surge"/><br/>
<div id="map"></div>
<script>
var map;
var mapType;
var layer = new google.maps.FusionTablesLayer(null);
function initMap() {
    // Create Styled Map Object 
    var styledMapType = new google.maps.StyledMapType(
        [
{
    "featureType": "administrative",
    "stylers": [
        {
            "visibility": "off"
        }
    ]
},
{
    "featureType": "poi",
    "stylers": [
        {
            "visibility": "simplified"
        }
    ]
},
{
    "featureType": "road",
    "elementType": "labels",
    "stylers": [
        {
            "visibility": "simplified"
        }
    ]
},
{
    "featureType": "water",
    "stylers": [
        {
            "visibility": "simplified"
        }
    ]
},
{
    "featureType": "transit",
    "stylers": [
        {
            "visibility": "simplified"
        }
    ]
},
{
    "featureType": "landscape",
    "stylers": [
        {
            "visibility": "simplified"
        }
    ]
},
{
    "featureType": "road.highway",
    "stylers": [
        {
            "visibility": "off"
        }
    ]
},
{
    "featureType": "road.local",
    "stylers": [
        {
            "visibility": "on"
        }
    ]
},
{
    "featureType": "road.highway",
    "elementType": "geometry",
    "stylers": [
        {
            "visibility": "on"
        }
    ]
},
{
    "featureType": "water",
    "stylers": [
        {
            "color": "#84afa3"
        },
        {
            "lightness": 52
        }
    ]
},
{
    "stylers": [
        {
            "saturation": -17
        },
        {
            "gamma": 0.36
        }
    ]
},
{
    "featureType": "transit.line",
    "elementType": "geometry",
    "stylers": [
        {
            "color": "#3f518c"
        }
    ]
}
],
        //Remember to include name for map style you created
        {name: 'Buildings'});
      map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: 42.340885, lng: -71.047289},
      zoom: 13,
      panControl:true,
      scaleControl:true,
      zoomControl:true,
      zoomControlOptions:{
        style: google.maps.ZoomControlStyle.LARGE},
      mapTypeControl: true,
      streetViewControl:true,
      overviewMapControl:true,
      rotateControl:true,
      zoomControlOptions:{
        style:google.maps.ZoomControlStyle.LARGE,
        position:google.maps.ControlPosition.RIGHT_CENTER
        },
      //add your style to MapTypeOptions below
      mapTypeControlOptions: {
        mapTypeIds: ['roadmap', 'satellite', 'hybrid', 'terrain',
                'styled_map']
      }
    });
    google.maps.event.addListener(map, 'maptypeid_changed', function() {
        mapType = map.getMapTypeId();
        AddBuildings()
    });
    map.mapTypes.set('styled_map',styledMapType);
  }
     function AddBuildings(){
if (mapType == "styled_map") {
         layer = new google.maps.FusionTablesLayer({
            query:{
            select: 'geometry',
            from: '1mzPT_gVGQRujbzIdPTzV8swo2AI611PEwIKwzgj7',
            }
        });
        layer.setMap(map);
    } else {
        layer.setMap(null);
  }
  }

</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBV-z3Aar9YGZXept2AXxLY_70TL317mPA&callback=initMap">
</script>


Solution

  • I get javascript errors with the posted code:

    • Uncaught ReferenceError: google is not defined
    • Uncaught TypeError: Cannot read property 'setMap' of undefined.

    You can't use the Google Maps Javascript API v3 until it is loaded.

    Move the initialization of layer:

    var layer = new google.maps.FusionTablesLayer(null);
    

    inside the initMap function (like map and mapType), that function runs once the API has finished loading and is available for use.

    var layer;
    function initMap() {
      layer = new google.maps.FusionTablesLayer(null);
    

    proof of concept fiddle (loads the API synchronously)

    code snippet:

    var map;
    var mapType;
    var layer;
    
    function initMap() {
      layer = new google.maps.FusionTablesLayer(null);
      // Create Styled Map Object 
      var styledMapType = new google.maps.StyledMapType(
        [{
            "featureType": "administrative",
            "stylers": [{
              "visibility": "off"
            }]
          },
          {
            "featureType": "poi",
            "stylers": [{
              "visibility": "simplified"
            }]
          },
          {
            "featureType": "road",
            "elementType": "labels",
            "stylers": [{
              "visibility": "simplified"
            }]
          },
          {
            "featureType": "water",
            "stylers": [{
              "visibility": "simplified"
            }]
          },
          {
            "featureType": "transit",
            "stylers": [{
              "visibility": "simplified"
            }]
          },
          {
            "featureType": "landscape",
            "stylers": [{
              "visibility": "simplified"
            }]
          },
          {
            "featureType": "road.highway",
            "stylers": [{
              "visibility": "off"
            }]
          },
          {
            "featureType": "road.local",
            "stylers": [{
              "visibility": "on"
            }]
          },
          {
            "featureType": "road.highway",
            "elementType": "geometry",
            "stylers": [{
              "visibility": "on"
            }]
          },
          {
            "featureType": "water",
            "stylers": [{
                "color": "#84afa3"
              },
              {
                "lightness": 52
              }
            ]
          },
          {
            "stylers": [{
                "saturation": -17
              },
              {
                "gamma": 0.36
              }
            ]
          },
          {
            "featureType": "transit.line",
            "elementType": "geometry",
            "stylers": [{
              "color": "#3f518c"
            }]
          }
        ],
        //Remember to include name for map style you created
        {
          name: 'Buildings'
        });
      map = new google.maps.Map(document.getElementById('map'), {
        center: {
          lat: 42.340885,
          lng: -71.047289
        },
        zoom: 13,
        panControl: true,
        scaleControl: true,
        zoomControl: true,
        zoomControlOptions: {
          style: google.maps.ZoomControlStyle.LARGE
        },
        mapTypeControl: true,
        streetViewControl: true,
        overviewMapControl: true,
        rotateControl: true,
        zoomControlOptions: {
          style: google.maps.ZoomControlStyle.LARGE,
          position: google.maps.ControlPosition.RIGHT_CENTER
        },
        //add your style to MapTypeOptions below
        mapTypeControlOptions: {
          mapTypeIds: ['roadmap', 'satellite', 'hybrid', 'terrain',
            'styled_map'
          ]
        }
      });
      google.maps.event.addListener(map, 'maptypeid_changed', function() {
        mapType = map.getMapTypeId();
        AddBuildings()
      });
      map.mapTypes.set('styled_map', styledMapType);
    }
    
    function AddBuildings() {
      if (mapType == "styled_map") {
        layer = new google.maps.FusionTablesLayer({
          query: {
            select: 'geometry',
            from: '1mzPT_gVGQRujbzIdPTzV8swo2AI611PEwIKwzgj7',
          }
        });
        layer.setMap(map);
      } else {
        layer.setMap(null);
      }
    }
    /* formatting for html containing the map */
    body {
      background-color: White;
    }
    h3 {
      color: Black;
    }
    /* formatting for map */
    #map {
      height: 75%;
    }
    html,
    body {
      height: 100%;
      margin: 1;
      padding: 0;
    }
    1 foot<input type="radio" name="Storm Surge" value="1 foot" id="1_ft_surge" /><br/> 2 foot<input type="radio" name="Storm Surge" value="2 foot" id="2_ft_surge" /><br/>
    <div id="map"></div>
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBV-z3Aar9YGZXept2AXxLY_70TL317mPA&callback=initMap"></script>