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

Google Maps Snap to Road演示报错MissingKeyMapError,已加密钥仍无效

解决Google Maps Snap to Road演示的MissingKeyMapError与空白页面问题

我仔细检查了你的代码,发现两个核心问题导致了错误和空白页面,还有一个小的潜在冲突点,下面逐一说明并给出修复方案:

1. Maps JavaScript API加载时未传入API密钥(直接触发MissingKeyMapError)

你虽然在调用Roads API的AJAX请求里使用了apiKey变量,但加载Google Maps JavaScript API本身的<script>标签没有携带密钥参数。Google Maps JS API要求必须在加载URL中指定key,否则会直接抛出MissingKeyMapError,这是你看到错误的根本原因。

修复方法:
修改加载Maps API的script标签,在URL末尾添加&key=你的API密钥:

<script src="https://maps.googleapis.com/maps/api/js?libraries=drawing,places&key=AIzaSyB3kpx3fgR9VT3WL2tp49QrbnyDdgygGeo"></script>

2. 地图初始化函数未正确执行(导致空白页面)

你的代码最后一行是:

$(window).on('load', function() { initialize });

这里你只是引用了initialize函数,但没有调用它(缺少括号())。这意味着页面加载完成后,初始化函数根本没有运行,地图容器自然是空的。

修复方法:
改成以下两种写法之一都可以:

// 写法一:直接传入函数引用
$(window).on('load', initialize);

// 写法二:在匿名函数里调用
$(window).on('load', function() { initialize(); });

3. 额外优化:移除重复的jQuery引入

你的代码里引入了两次jQuery:一次是页面最顶部的CDN版本,一次是head里的本地版本jquery-3.2.1.js。重复引入可能导致版本冲突,建议只保留一个(推荐使用CDN版本,更稳定)。


修复后的完整代码片段(关键修改已标注)

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Roads API Demo</title>
<style>
html, body, #map { height: 100%; margin: 0px; padding: 0px }
#panel { position: absolute; top: 5px; left: 50%; margin-left: -180px; z-index: 5; background-color: #fff; padding: 5px; border: 1px solid #999; }
#bar { width: 240px; background-color: rgba(255, 255, 255, 0.75); margin: 8px; padding: 4px; border-radius: 4px; }
#autoc { width: 100%; box-sizing: border-box; }
</style>
<!-- 保留一个jQuery引入即可 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- 修复:Maps API加载URL添加key参数 -->
<script src="https://maps.googleapis.com/maps/api/js?libraries=drawing,places&key=AIzaSyB3kpx3fgR9VT3WL2tp49QrbnyDdgygGeo"></script>
<script>
var apiKey = 'AIzaSyB3kpx3fgR9VT3WL2tp49QrbnyDdgygGeo';
var map;
var drawingManager;
var placeIdArray = [];
var polylines = [];
var snappedCoordinates = [];

function initialize() {
var mapOptions = {
zoom: 17,
center: { lat: -33.8667, lng: 151.1955 }
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);

// Adds a Places search box. Searching for a place will center the map on that
// location.
map.controls[google.maps.ControlPosition.RIGHT_TOP].push(
document.getElementById('bar'));
var autocomplete = new google.maps.places.Autocomplete(
document.getElementById('autoc'));
autocomplete.bindTo('bounds', map);
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17);
}
});

// Enables the polyline drawing control. Click on the map to start drawing a
// polyline. Each click will add a new vertice. Double-click to stop drawing.
drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.POLYLINE,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.POLYLINE
]
},
polylineOptions: {
strokeColor: '#696969',
strokeWeight: 2
}
});
drawingManager.setMap(map);

// Snap-to-road when the polyline is completed.
drawingManager.addListener('polylinecomplete', function(poly) {
var path = poly.getPath();
polylines.push(poly);
placeIdArray = [];
runSnapToRoad(path);
});

// Clear button. Click to remove all polylines.
$('#clear').click(function(ev) {
for (var i = 0; i < polylines.length; ++i) {
polylines[i].setMap(null);
}
polylines = [];
ev.preventDefault();
return false;
});
}

// Snap a user-created polyline to roads and draw the snapped path
function runSnapToRoad(path) {
var pathValues = [];
for (var i = 0; i < path.getLength(); i++) {
pathValues.push(path.getAt(i).toUrlValue());
}
$.get('https://roads.googleapis.com/v1/snapToRoads', {
interpolate: true,
key: apiKey,
path: pathValues.join('|')
}, function(data) {
processSnapToRoadResponse(data);
drawSnappedPolyline();
getAndDrawSpeedLimits();
});
}

// Store snapped polyline returned by the snap-to-road service.
function processSnapToRoadResponse(data) {
snappedCoordinates = [];
placeIdArray = [];
for (var i = 0; i < data.snappedPoints.length; i++) {
var latlng = new google.maps.LatLng(
data.snappedPoints[i].location.latitude,
data.snappedPoints[i].location.longitude);
snappedCoordinates.push(latlng);
placeIdArray.push(data.snappedPoints[i].placeId);
}
}

// Draws the snapped polyline (after processing snap-to-road response).
function drawSnappedPolyline() {
var snappedPolyline = new google.maps.Polyline({
path: snappedCoordinates,
strokeColor: 'black',
strokeWeight: 3
});
snappedPolyline.setMap(map);
polylines.push(snappedPolyline);
}

// Gets speed limits (for 100 segments at a time) and draws a polyline
// color-coded by speed limit. Must be called after processing snap-to-road
// response.
function getAndDrawSpeedLimits() {
for (var i = 0; i <= placeIdArray.length / 100; i++) {
// Ensure that no query exceeds the max 100 placeID limit.
var start = i * 100;
var end = Math.min((i + 1) * 100 - 1, placeIdArray.length);
drawSpeedLimits(start, end);
}
}

// Gets speed limits for a 100-segment path and draws a polyline color-coded by
// speed limit. Must be called after processing snap-to-road response.
function drawSpeedLimits(start, end) {
var placeIdQuery = '';
for (var i = start; i < end; i++) {
placeIdQuery += '&placeId=' + placeIdArray[i];
}
$.get('https://roads.googleapis.com/v1/speedLimits', 'key=' + apiKey + placeIdQuery,
function(speedData) {
processSpeedLimitResponse(speedData, start);
}
);
}

// Draw a polyline segment (up to 100 road segments) color-coded by speed limit.
function processSpeedLimitResponse(speedData, start) {
var end = start + speedData.speedLimits.length;
for (var i = 0; i < speedData.speedLimits.length - 1; i++) {
var speedLimit = speedData.speedLimits[i].speedLimit;
var color = getColorForSpeed(speedLimit);
// Take two points for a single-segment polyline.
var coords = snappedCoordinates.slice(start + i, start + i + 2);
var snappedPolyline = new google.maps.Polyline({
path: coords,
strokeColor: color,
strokeWeight: 6
});
snappedPolyline.setMap(map);
polylines.push(snappedPolyline);
}
}

function getColorForSpeed(speed_kph) {
if (speed_kph <= 40) {
return 'purple';
}
if (speed_kph <= 50) {
return 'blue';
}
if (speed_kph <= 60) {
return 'green';
}
if (speed_kph <= 80) {
return 'yellow';
}
if (speed_kph <= 100) {
return 'orange';
}
return 'red';
}

// 修复:正确调用initialize函数
$(window).on('load', initialize);
</script>
</head>
<body>
<div id="map"></div>
<div id="bar">
<p class="auto"><input type="text" id="autoc" /></p>
<p><a id="clear" href="#">Click here</a> to clear map.</p>
</div>
</body>
</html>

最后别忘了检查你的API密钥是否已经启用了Maps JavaScript API和Roads API,如果没启用的话,即使密钥正确也会报错。你可以在Google Cloud Console的API库中搜索并启用这两个API。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:30:07