断言失败:无效:setMap:不是 Map 的实例

Assertion failed: Invalid: setMap: not an instance of Map

我是 JS 的新手并且 google api。去年我开发了一个自定义 google 地图。基本上它从 xml 加载多边形建筑轮廓,然后为特定的兴趣点应用 kml 图层。(非常感谢 geocodezip 为我指明了正确的方向) 这是一个用于加载停止工作的 kml 图层功能的工作测试版。 devbox

但现在有人要求我有一个搜索框,我用搜索框重建了它,但现在加载 kml 层不起作用,我看到错误 Assertion failed: InvalidValueError: setMap: not an instance的地图。

    <!DOCTYPE html>
<html>
  <head>
    <title>Place Autocomplete</title>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="../maps.css">
    <style>
    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      } 
      #map {
        height: 100%;
        width: 800px;
        float: right;
       margin: 0;
        padding: 0;
        /* height: 840px; */
       width: 939px; 
      /*height: 700px;
     width: 700px;*/
       position: relative;
        overflow: hidden;
        transform: translateZ(0px);
        background-color: rgb(229, 227, 223);
    border: 1px solid #8a8c8f 
      }
.controls {
  margin-top: 10px;
  border: 1px solid transparent;
  border-radius: 2px 0 0 2px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  height: 32px;
  outline: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}

#pac-input {
  background-color: #fff;
  font-family: Roboto;
  font-size: 15px;
  font-weight: 300;
  margin-left: 12px;
  padding: 0 11px 0 13px;
  text-overflow: ellipsis;
  width: 300px;
}

#pac-input:focus {
  border-color: #4d90fe;
}

.pac-container {
  font-family: Roboto;
}

#type-selector {
  color: #fff;
  background-color: #4d90fe;
  padding: 5px 11px 0px 11px;
}

#type-selector label {
  font-family: Roboto;
  font-size: 13px;
  font-weight: 300;
}
.instructions {
    height: 100%;
}
.top {
    width: 100%;    
}

    </style>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>
       <script type="text/javascript" src="geoxml3.js"></script>
<script type="text/javascript" src="ProjectedOverlay.js"></script> 

  </head>
  <body>
  <!-- Header Container -->
  <div class="top">
    <div class="header">
        <div class="headerLogo">
            <a href="http://camosun.ca"></a>
        </div>
        <div class="headerTitle">
            <a href="/maps/"></a>
        </div>

    </div>
  </div>
<!-- header div -->
  <section class="instructions">
<h1>Interurban Campus</h1>
<p>Test to create a custom Interurban campus map.</p>
<aside class="functions">
 <!-- begin - MAP LAYERS CHECKBOXES -->
<h3>Points of Interest</h3>
<form action="" method="post">
<input name="checkbox" alt="Parking checkbox"  onClick="boxclick(this,4)" type="checkbox" value="checkbox" > Parking<br>
<input name="checkbox" alt="Parking checkbox"  onClick="boxclick(this,5)" type="checkbox" value="checkbox" > Foodservices<br>
<input name="checkbox" alt="Parking checkbox"  onClick="boxclick(this,6)" type="checkbox" value="checkbox" > Bookstore<br>
<input name="checkbox" alt="Emergency Phones checkbox"  onClick="boxclick(this,3)" type="checkbox" value="checkbox" > Bike Racks<br>
<input name="checkbox" alt="Road Closure checkbox"  onClick="boxclick(this,8)" type="checkbox" value="checkbox" > ATM<br>
<input name="checkbox" alt="Construction checkbox"  onClick="boxclick(this,7)" type="checkbox" value="checkbox" > Coffee<br>
<input name="checkbox" alt="Bike Routes checkbox" onClick="boxclick(this,1)" type="checkbox" value="checkbox" > Bike Routes<br>
<input name="checkbox" alt="Traffic checkbox" onClick="boxclick(this,2)" type="checkbox" value="checkbox"> Traffic<br>
<input name="checkbox" alt="Library checkbox" onClick="boxclick(this,9)" type="checkbox" value="checkbox"> Library</p>
</form>    
<!-- end - MAP LAYERS CHECKBOXES -->   


<!-- begin - Unordered list of locations --> 
<h3>Locations</h3>              
<div id="sidebar"></div>

</aside>
</section>
<script type="text/javascript">

/* *** begin - KML LAYERS *** */
// Random number generated for cache-busting
var seconds = new Date().getTime();
// Google Bike & Traffic Layers
var bikeLayer = new google.maps.BicyclingLayer();
var trafficLayer = new google.maps.TrafficLayer();
// Variables set to URLs of custom KML layers made in Google Earth  
var bikeRacksLayer = new google.maps.KmlLayer('https://webservices.camosun.bc.ca/maps-demo/_data/bike-racks-iu.kml');   
var parkingLayer = new google.maps.KmlLayer('https://webservices.camosun.bc.ca/maps-demo/_data/parking-iu.kml');            
var foodservicesLayer = new google.maps.KmlLayer('https://webservices.camosun.bc.ca/maps-demo/_data/foodservices-iu.kml');  
var bookstoreLayer = new google.maps.KmlLayer('https://webservices.camosun.bc.ca/maps-demo/_data/bookstore-iu.kml');    
var coffeeLayer = new google.maps.KmlLayer('https://webservices.camosun.bc.ca/maps-demo/_data/coffee-iu.kml');  
var atmLayer = new google.maps.KmlLayer('https://webservices.camosun.bc.ca/maps-demo/_data/atm-iu.kml');    
var libraryLayer = new google.maps.KmlLayer('https://webservices.camosun.bc.ca/maps-demo/_data/library-iu.kml');    
// Switch loop to toggle layers on and off  
function boxclick(box,num) { 
    switch (num)
        {
            case 1:
                if (box.checked)
                    {bikeLayer.setMap(map.getMap());} 
                else {bikeLayer.setMap(null);}
                break;
            case 2:
                if (box.checked)
                    {trafficLayer.setMap(map);} 
                else {trafficLayer.setMap(null);} 
                break;  
            case 3:
                if (box.checked)
                    {bikeRacksLayer.setMap(map);} 
                else {bikeRacksLayer.setMap(null);}
                break; 
            case 4:
                if (box.checked)
                    {parkingLayer.setMap(map)} 
                else {parkingLayer.setMap(null);}
                break;
            case 5:
                if (box.checked)
                    {foodservicesLayer.setMap(map);} 
                else {foodservicesLayer.setMap(null);}
                break;   
            case 6:
                if (box.checked)
                    {bookstoreLayer.setMap(map);} 
                else {bookstoreLayer.setMap(null);}
                break; 
            case 7:
                if (box.checked)
                    {coffeeLayer.setMap(map);} 
                else {coffeeLayer.setMap(null);}
                break;   
            case 8:
                if (box.checked)
                    {atmLayer.setMap(map);} 
                else {atmLayer.setMap(null);}
                break;      
            case 9:
                if (box.checked)
                    {libraryLayer.setMap(map);} 
                else {libraryLayer.setMap(null)}
                break;   
            } //Switch 

    } // funtion
    /* *** end - KML Layers *** */

</script>


    <input id="pac-input" class="controls" type="text"
        placeholder="Enter a location">
    <div id="type-selector" class="controls">
      <input type="radio" name="type" id="changetype-all" checked="checked">
      <label for="changetype-all">All</label>

      <input type="radio" name="type" id="changetype-establishment">
      <label for="changetype-establishment">Establishments</label>

      <input type="radio" name="type" id="changetype-address">
      <label for="changetype-address">Addresses</label>

      <input type="radio" name="type" id="changetype-geocode">
      <label for="changetype-geocode">Geocodes</label>
    </div>
    <div id="map"></div>

    <script>
function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 48.490802, lng: -123.416497},
    zoom: 17
  });

    // array of styles
    var styles = [
        {
            "featureType": "poi.school",
            "elementType": "labels",
            "stylers": [{ "visibility": "off" }]
        },{
            "featureType": "poi.business",
            "elementType": "labels",
            "stylers": [{ "visibility": "off" }]
        },{
            "featureType": "landscape.man_made",
            "elementType": "labels.text",
            "stylers": [{ "visibility": "off" }]
        },{
            "featureType": "landscape.man_made",
            "elementType": "geometry",
            "stylers": [{ "visibility": "off" }]
        }];
// new styledMapType object, passing the array of styles and the name to be displayed on the map type control.
    var styledMap = new google.maps.StyledMapType(styles,{name: "Styled Map"});
    map.mapTypes.set('map_style', styledMap);
    map.setMapTypeId('map_style');

    // Sets geoxml class options
   geoXml = new geoXML3.parser({
            map: map,
            singleInfoWindow: true,
            afterParse: useTheData
                });
   geoXml.parse('interurb.xml');

        // sets the min and max zoom levels of the map
    var opt = { minZoom: 6, maxZoom: 18 };
    map.setOptions(opt);

  var input = /** @type {!HTMLInputElement} */(
      document.getElementById('pac-input'));

  var types = document.getElementById('type-selector');
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(types);

  var autocomplete = new google.maps.places.Autocomplete(input);
  autocomplete.bindTo('bounds', map);

  var infowindow = new google.maps.InfoWindow();
  var marker = new google.maps.Marker({
    map: map,
    anchorPoint: new google.maps.Point(0, -29)
  });

  autocomplete.addListener('place_changed', function() {
    infowindow.close();
    marker.setVisible(false);
    var place = autocomplete.getPlace();
    if (!place.geometry) {
      window.alert("Autocomplete's returned place contains no geometry");
      return;
    }

    // If the place has a geometry, then present it on a map.
    if (place.geometry.viewport) {
      map.fitBounds(place.geometry.viewport);
    } else {
      map.setCenter(place.geometry.location);
      map.setZoom(17);  // Why 17? Because it looks good.
    }
    marker.setIcon(/** @type {google.maps.Icon} */({
      url: place.icon,
      size: new google.maps.Size(71, 71),
      origin: new google.maps.Point(0, 0),
      anchor: new google.maps.Point(17, 34),
      scaledSize: new google.maps.Size(35, 35)
    }));
    marker.setPosition(place.geometry.location);
    marker.setVisible(true);

    var address = '';
    if (place.address_components) {
      address = [
        (place.address_components[0] && place.address_components[0].short_name || ''),
        (place.address_components[1] && place.address_components[1].short_name || ''),
        (place.address_components[2] && place.address_components[2].short_name || '')
      ].join(' ');
    }

    infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address);
    infowindow.open(map, marker);



  });

  // Sets a listener on a radio button to change the filter type on Places
  // Autocomplete.
  function setupClickListener(id, types) {
    var radioButton = document.getElementById(id);
    radioButton.addEventListener('click', function() {
      autocomplete.setTypes(types);
    });
  }

  setupClickListener('changetype-all', []);
  setupClickListener('changetype-address', ['address']);
  setupClickListener('changetype-establishment', ['establishment']);
  setupClickListener('changetype-geocode', ['geocode']);
}
function kmlClick(marker) {
   google.maps.event.trigger(geoXml.docs[0].markers[marker],"click");
}

function useTheData(doc){
  // Geodata handling goes here, using JSON properties of the doc object
  // Creates side bar navigation
  var sidebarHtml = "<table>";
  for (var i = 0; i < doc[0].markers.length; i++) {
    // console.log(doc[0].markers[i].title);
    sidebarHtml += '<tr><td><a href="javascript:kmlClick('+i+');">'+doc[0].placemarks[i].name+'</a></td></tr>';
  }
  sidebarHtml += "</table>";
  document.getElementById("sidebar").innerHTML = sidebarHtml;
};

    </script>
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyASPL99-mPNhM87jKpOPoALZOUFMHCx1Ag&signed_in=true&libraries=places&callback=initMap"
        async defer></script>

  </body>
</html>

您的 map 变量是 initMap 函数的局部变量(注意它前面的 var)。要在 HTML 单击事件侦听器(如复选框的侦听器)中使用它,它需要在全局范围内。改变这个:

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 48.490802, lng: -123.416497},
    zoom: 17
  });

收件人:

var map;
function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 48.490802, lng: -123.416497},
    zoom: 17
  });

proof of concept fiddle