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
相关产品推荐
相关产品推荐

