You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Maps Drawing Manager覆盖层移除及访问报错求助

Google Maps Drawing Manager overlay访问报错解决方案

问题概述

开发地理围栏应用时,使用Drawing Manager创建围栏,添加overlaycomplete监听器时触发如下错误,导致无法获取绘制的overlay,进而无法清除重新绘制:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '__e3_')
    at yba (js?key=AIzaSyAksEGQLj6SwcxTQva_Camj-O1skokx-rQ&callback=initMap&v=weekly&libraries=drawing,geometry:128:361)
    at new _.uf (js?key=AIzaSyAksEGQLj6SwcxTQva_Camj-O1skokx-rQ&callback=initMap&v=weekly&libraries=drawing,geometry:129:399)
    at _.L [as addListener] (js?key=AIzaSyAksEGQLj6SwcxTQva_Camj-O1skokx-rQ&callback=initMap&v=weekly&libraries=drawing,geometry:126:108)
    at setListeners (index_Local.js:192:23)
    at initMap (index_Local.js:53:3)
    at js?key=AIzaSyAksEGQLj6SwcxTQva_Camj-O1skokx-rQ&callback=initMap&v=weekly&libraries=drawing,geometry:245:146
    at js?key=AIzaSyAksEGQLj6SwcxTQva_Camj-O1skokx-rQ&callback=initMap&v=weekly&libraries=drawing,geometry:244:238

错误原因

你把overlaycomplete监听器的绑定代码放在了drawGeofenceButton的点击事件外面,但此时drawingManager还未实例化(只有点击按钮后才会创建),所以绑定监听器时drawingManager是undefined,触发类型错误。

解决方案

将overlaycomplete监听器的绑定代码移到drawGeofenceButton的点击事件内部,确保在drawingManager实例化完成后再添加监听器。同时优化deleteSelectedShape方法,避免直接访问未初始化的_myPolygon导致报错。

修改后的关键代码

调整监听器位置

drawGeofenceButton.addEventListener("click", () =>{
    // 清除旧围栏
    if(tri != null && tri != undefined){
        tri.setMap(null);
    }
    // 清除旧的DrawingManager
    if(drawingManager != null && drawingManager != undefined){
        drawingManager.setMap(null);
        drawingManager = null;
    } 
    // 实例化DrawingManager
    drawingManager = new google.maps.drawing.DrawingManager({
        drawingMode: google.maps.drawing.OverlayType.POLYGON,
        drawingControl: true,
        drawingControlOptions: {
            drawingModes: [google.maps.drawing.OverlayType.POLYGON]
        },
        polygonOptions: {
            fillColor: '#FF0000',
            fillOpacity: 0.6,
            strokeWeight: 3,
            clickable: true,
            editable: true,
            zIndex: 1
        }
    });
    drawingManager.setMap(map);
    
    // 在这里绑定overlaycomplete监听器
    google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
        // 清除之前绘制的多边形
        if(_myPolygon){
            _myPolygon.setMap(null);
        }
        _myPolygon = e.overlay;
        // 绘制完成后关闭绘图模式
        drawingManager.setDrawingMode(null);
    });
});

优化deleteSelectedShape方法

function deleteSelectedShape() {
    if(_myPolygon){
        _myPolygon.setMap(null);
        _myPolygon = null;
    }
    // 同时清除手动创建的tri围栏
    if(tri){
        tri.setMap(null);
        tri = null;
    }
}

完整修改后的代码

<html>
  <head>
    <title>Add Map</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
    <style>
     #map {
        height: 100%;
      }
      html,
      body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      .custom-map-control-button {
        background-color: #fff;
        border: 0;
        border-radius: 2px;
        box-shadow: 0 1px 4px -1px rgba(0,0,0,0.3);
        margin: 10px;
        padding: 0 0.5em;
        font: 400 18px Roboto, Arial, sans-serif;
        overflow: hidden;
        height: 40px;
        cursor: pointer;
      }
      .custom-map-control-button:hover {
        background: rgb(235,235,235);
      }
    </style>
    <link rel="stylesheet" type="text/css" href="./style.css" />
  </head>
  <body>
    <meta name="viewport" content="width=device-width">
    <h3>My Google Maps Demo</h3>
    <div id="map"></div>
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAksEGQLj6SwcxTQva_Camj-O1skokx-rQ&callback=initMap&v=weekly&libraries=drawing,geometry"
      defer
    ></script>
    <script>
    let map, infoWindow;
    const locationButton = document.createElement("button");
    const clearButton = document.createElement("button");
    const drawGeofenceButton = document.createElement("button");

    let tri = null;
    var _myPolygon; 
    var selectedShape;
    let drawingManager;

    function initMap() {
      const iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
      map = new google.maps.Map(document.getElementById("map"), {
        center: { lat: 31.800, lng: -95.600 },
        zoom: 6,
      });

      infoWindow = new google.maps.InfoWindow();

      locationButton.textContent = "Pan to Current Location";
      locationButton.classList.add("custom-map-control-button");

      clearButton.textContent = "Clear Geofence";
      clearButton.classList.add("custom-map-control-button");

      drawGeofenceButton.textContent = "Draw Geofence";
      drawGeofenceButton.classList.add("custom-map-control-button");

      map.controls[google.maps.ControlPosition.TOP_CENTER].push(locationButton);
      map.controls[google.maps.ControlPosition.TOP_CENTER].push(drawGeofenceButton);
      map.controls[google.maps.ControlPosition.TOP_CENTER].push(clearButton);
        
      setListeners();   
    }

    function setListeners(){
      drawGeofenceButton.addEventListener("click", () =>{
        if(tri != null && tri != undefined){
            tri.setMap(null);
        }
        if(drawingManager != null && drawingManager != undefined){
            drawingManager.setMap(null);
            drawingManager = null;
        } 
        drawingManager = new google.maps.drawing.DrawingManager({
            drawingMode: google.maps.drawing.OverlayType.POLYGON,
            drawingControl: true,
            drawingControlOptions: {
                drawingModes: [google.maps.drawing.OverlayType.POLYGON]
            },
            polygonOptions: {
                fillColor: '#FF0000',
                fillOpacity: 0.6,
                strokeWeight: 3,
                clickable: true,
                editable: true,
                zIndex: 1
            }
        });
        drawingManager.setMap(map);
        
        google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
            if(_myPolygon){
                _myPolygon.setMap(null);
            }
            _myPolygon = e.overlay;
            drawingManager.setDrawingMode(null);
        });
      });

      locationButton.addEventListener("click", () => {
        if (navigator.geolocation) {
          console.log('Getting current position...');
          navigator.geolocation.getCurrentPosition(
            (position) => {
              const pos = {
                lat: position.coords.latitude,
                lng: position.coords.longitude
              };
              const marker = new google.maps.Marker({
                    position: pos,
                    map: map,
                    icon: "http://maps.google.com/mapfiles/kml/shapes/target.png",
                  });
              console.log('Pos.lat = ' + pos.lat);
              console.log('Pos.lng = ' + pos.lng);
              map.setCenter(pos);
            
              const coords = [
                { lat: (pos.lat - 0.003752),  lng: (pos.lng - 0.003752)},
                { lat: (pos.lat - 0.003752), lng: (pos.lng + 0.003752) },
                { lat: (pos.lat + 0.003752), lng: (pos.lng + 0.003752)},
              ];

              tri = new google.maps.Polygon({
                paths: coords,
                strokeColor: "#FF0000",
                strokeOpacity: 0.8,
                strokeWeight: 3,
                fillColor: "#FF0000",
                fillOpacity: 0.35,
                editable: true
              });

              tri.setMap(map);
              console.log('Set geofence....');
      
              tri.addListener("click", showArrays);
              infoWindow = new google.maps.InfoWindow();
            },
            () => {
              handleLocationError(true, infoWindow, map.getCenter());
            }
          );
        } else {
          handleLocationError(false, infoWindow, map.getCenter());
        }
      });

      clearButton.addEventListener("click", () => {
        deleteSelectedShape();
      });
    }

    function showArrays(event) {
      const polygon = this;
      const vertices = polygon.getPath();
      let contentString =
        "<b>Geofence Triangle polygon</b><br>" +
        "Clicked location: <br>" +
        event.latLng.lat() +
        "," +
        event.latLng.lng() +
        "<br>";

      for (let i = 0; i < vertices.getLength(); i++) {
        const xy = vertices.getAt(i);
        contentString +=
          "<br>" + "Coordinate " + i + ":<br>" + xy.lat() + "," + xy.lng();
      }

      infoWindow.setContent(contentString);
      infoWindow.setPosition(event.latLng);
      infoWindow.open(map);
    }

    function handleLocationError(browserHasGeolocation, infoWindow, pos) {
      infoWindow.setPosition(pos);
      infoWindow.setContent(
        browserHasGeolocation
          ? "Error: The Geolocation service failed."
          : "Error: Your browser doesn't support geolocation."
      );
      infoWindow.open(map);
    }

    function clearSelection() {
      if (selectedShape) {
        selectedShape.setEditable(false);
        selectedShape = null;
      }
    }

    function setSelection(shape) {
      clearSelection();
      selectedShape = shape;
      shape.setEditable(true);
    }

    function deleteSelectedShape() {
      if(_myPolygon){
          _myPolygon.setMap(null);
          _myPolygon = null;
      }
      if(tri){
          tri.setMap(null);
          tri = null;
      }
    }

    window.initMap = initMap;
    </script>
  </body>
</html>

内容的提问来源于stack exchange,提问作者girlcode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 04:38:09