我正在尝试根据数组中的图像属性生成 Google 地图标记。
使用旧版本的地图 Api 效果很好。 我现在尝试使其与新版本(AdvancedMarkerView)一起使用
控制台说 未捕获的 ReferenceError:AdvancedMarkerView 未定义/ 未捕获(承诺中)类型错误:AdvancedMarkerView 不是构造函数
非常感谢任何帮助
"use strict";
var active_img = 0;
var stage_img;
var img_lat;
var img_lng;
var parsedLat;
var parsedLng;
var autoplayInterval;
var isautoplay = true;
var firstautoplay = 0;
var autoplaylock = 0;
var mouse_onplay = false;
var map_active = false;
var main_visible = false;
var main_v_lock = false;
var myLatLng = {
lat: 0,
lng: 0
};
const images = [{
path: 'img/img_3.webp',
img_lat: '41,47873',
img_lng: '11,99995',
},
{
path: 'img/img_2.webp',
img_lat: '49,47873',
img_lng: '10,99995',
},
];
let map;
async function initMap() {
var position = myLatLng;
const {
Map
} = await google.maps.importLibrary("maps");
const {
AdvancedMarkerView
} = await google.maps.importLibrary("marker");
map = new Map(document.getElementById("map"), {
mapId: "559497c6e95d32fc",
zoom: 18,
center: myLatLng,
fullscreenControl: false,
zoomControl: true,
streetViewControl: false
});
createMarkers(images, map, AdvancedMarkerView);
}
function createMarkers(images, map, AdvancedMarkerView) {
const markers = [];
images.forEach((image, index) => {
const {
img_lat,
img_lng,
path
} = image;
if (img_lat !== '0' && img_lng !== '0') {
const latLng = {
lat: parseFloat(img_lat.replace(',', '.')),
lng: parseFloat(img_lng.replace(',', '.'))
};
const marker = new AdvancedMarkerView({
position: latLng,
map: map,
title: path
});
marker.addListener('click', () => {
handleMarkerClick(index);
});
markers.push(marker);
}
});
return markers;
}
initMap();
function ifLost() {
if (img_lat === '0' && img_lng === '0') {
img_lng = 'data lost';
img_lat = '';
}
}
function img_update() {
document.getElementById('stage_img').src = stage_img;
ifLost();
document.getElementById('lat').innerHTML = `<div>${img_lat}</div>`;
document.getElementById('lng').innerHTML = `<div>${img_lng}</div>`;
}
$(document).ready(function() {
stage_img = images[0].path;
img_lat = images[0].img_lat;
img_lng = images[0].img_lng;
parsedLat = parseFloat(img_lat.replace(',', '.'));
parsedLng = parseFloat(img_lng.replace(',', '.'));
myLatLng = {
lat: parsedLat,
lng: parsedLng
};
if (map) {
map.setCenter(new google.maps.LatLng(parsedLat, parsedLng));
}
function coordinates_update_move() {
img_lat = images[active_img].img_lat;
img_lng = images[active_img].img_lng;
parsedLat = parseFloat(img_lat.replace(',', '.'));
parsedLng = parseFloat(img_lng.replace(',', '.'));
if (map) {
if (img_lat == '0') {} else {
map.panTo(new google.maps.LatLng(parsedLat, parsedLng));
}
}
ifLost();
}
function handleMarkerClick(index) {
active_img = index;
stage_img = images[active_img].path;
img_lat = images[active_img].img_lat;
img_lng = images[active_img].img_lng;
img_update();
coordinates_update_move();
setTimeout(close_btn2, 440);
}
});
body {
position: relative;
width: 100vw;
height: 100vh;
}
#map_stage {
width: 100%;
height: 100%;
}
#map {
height: 50%;
width: 90%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>drau3en</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script>
(g => {
var h, a, k, p = "The Google Maps JavaScript API",
c = "google",
l = "importLibrary",
q = "__ib__",
m = document,
b = window;
b = b[c] || (b[c] = {});
var d = b.maps || (b.maps = {}),
r = new Set,
e = new URLSearchParams,
u = () => h || (h = new Promise(async(f, n) => {
await (a = m.createElement("script"));
e.set("libraries", [...r] + "");
for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]);
e.set("callback", c + ".maps." + q);
a.src = `https://maps.${c}apis.com/maps/api/js?` + e;
d[q] = f;
a.onerror = () => h = n(Error(p + " could not load."));
a.nonce = m.querySelector("script[nonce]") ? .nonce || "";
m.head.append(a)
}));
d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n))
})({
key: "AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk",
v: "weekly",
});
</script>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
<link rel="stylesheet" type="text/css" href="main.css">
<script src="jquery-3.1.0.min.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>
</head>
<body>
<div id="map_stage">
<div id="map"></div>
<p id="lat"></p>
<p id="lng"></p>
</div>
<footer>
</footer>
<script>
</script>
</body>
</html>
如前所述,您需要使用
AdvancedMarkerElement
而不是 AdvancedMarkerView
。进行此更改后,您应该会发现使用 HTML 作为标记内容将您自己的自定义设计的标记添加到地图上的任何位置都相当简单。
也许以下修改后的代码可能会有所帮助。
下面使用的
gmp-click
事件当前在 beta
通道中可用,但这确实有助于简化对 AdvancedMarkerElement 中内容的访问 - 仍然可以使用旧的 click
事件,但需要将 clickhandler 代码修改为适应变化。
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
<style>
:root{--accent:blue}
body { width: 100vw; height: 100vh; overflow:hidden; padding:0; margin:0; display:flex; flex-direction:column; }
body, body *{ box-sizing:border-box; font-family:monospace }
*:focus { outline: none; }
.advmarker{ background:white; padding:0.5rem; border-radius:1rem; border:1px solid var(--accent); display:flex; justify-content:center; align-items:center; flex-direction:column }
.map-icon{ width:50px; height:50px; border-radius:50%; border:2px solid black; }
.advmarker h3{color:var(--accent)}
#map_stage{ width:100%; height:100%; margin:0 auto; display:flex; flex-direction:column; justify-content:flex-start; align-items:center; }
#map_stage p:before,
.advmarker span:before{ content:attr( data-id )':'; color:var(--accent) }
#map { height:65%;width:100%; }
</style>
</head>
<body>
<div id='map_stage'>
<div id='map'></div>
<p data-id='lat' id='lat'></p>
<p data-id='lng' id='lng'></p>
<img id='stage_img' />
</div>
<footer></footer>
<script>
const APIKEY='AIza.....';
(g => {
var h, a, k, p = "The Google Maps JavaScript API",
c = "google",
l = "importLibrary",
q = "__ib__",
m = document,
b = window;
b = b[c] || (b[c] = {});
var d = b.maps || (b.maps = {}),
r = new Set,
e = new URLSearchParams,
u = () => h || (h = new Promise(async(f, n) => {
await (a = m.createElement("script"));
e.set("libraries", [...r] + "");
for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]);
e.set("callback", c + ".maps." + q);
a.src = `https://maps.${c}apis.com/maps/api/js?` + e;
d[q] = f;
m.head.append(a)
}));
d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n))
})({
key:APIKEY,
v:'beta'
});
// above is slightly modified
const myLatLng = {// central europe - ish
'lat':46.553469,
'lng':11.761824
};
const images = [
{
path: '//placekitten.com/200/200?image=1',
img_lat: 41.47873,
img_lng: 11.99995
},
{
path: '//placekitten.com/200/200?image=2',
img_lat: 49.47873,
img_lng: 10.99995
},
{
path: '//placekitten.com/200/200?image=3',
img_lat: 47.013545,
img_lng: 2.373301
},
{
path: '//placekitten.com/200/200?image=4',
img_lat: 47.504609,
img_lng: 19.050323
}
];
async function initMap() {
// store references to each marker here.
let markers={};
const { Map } = await google.maps.importLibrary("maps");
const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
/*
Conventional style callback functions
allow access to the actual AdvancedMarkerElement
via `this`
markers are stored within `markers` object
so you can iterate through that Object to
perform various operations upon each marker
if required.
*/
function clickhandler(e){
document.querySelector('p#lat').textContent=Number(this.position.lat.toFixed(6));
document.querySelector('p#lng').textContent=Number(this.position.lng.toFixed(6));
document.querySelector('img#stage_img').src=this.content.querySelector('img.map-icon').src;
}
function draghandler(e){
console.log( this, e.latLng )
this.content.querySelector('[data-id="lat"]').textContent=Number(e.latLng.lat().toFixed(6));
this.content.querySelector('[data-id="lng"]').textContent=Number(e.latLng.lng().toFixed(6));
}
// utility to generate suitable HTML content used within the AdvancedMarkerElement
const createicon=( obj )=>{
let div=document.createElement('div');
div.className='advmarker';
div.innerHTML=`
<h3>${obj.path.split('?').pop()}</h3>
<img class='map-icon' src='${obj.path}' />
<span data-id='lat'>${obj.img_lat}</span>
<span data-id='lng'>${obj.img_lng}</span>`;
return div;
};
/*
utility to add a reasonable good id to each marker
- allows easy access to each marker within global markers object
-
*/
const createid=()=>window.URL.createObjectURL( new Blob( [] ) ).split('/').pop();
const addmarker=( obj, callbacks={} )=>{
let mkr=new AdvancedMarkerElement({
map:map,
gmpDraggable:obj.draggable || true,
gmpClickable:obj.clickable || true,
position:{
'lat':obj.img_lat,
'lng':obj.img_lng
},
content:createicon( obj )
});
/*
add data and custom propertiesy to the marker which
allows access to them data within click handler.
*/
mkr.data=obj;
mkr.id=obj.id;
if( callbacks && typeof( callbacks )=='object' ) {
Object.keys( callbacks ).forEach( type=>{
mkr.addEventListener( type, callbacks[ type ] );
});
}
return mkr;
};
const createMarkers=()=>{
const callbacks={
'gmp-click':clickhandler,
'dragend':draghandler
};
images.forEach( obj => {
let id=createid();
let args=Object.assign( obj, {'id':id } );
let marker=addmarker( args, callbacks );
markers[ id ]=marker;
});
return markers;
};
const map = new Map(document.getElementById("map"), {
mapId: "559497c6e95d32fc",
zoom: 6,
center: myLatLng,
fullscreenControl: false,
streetViewControl: false,
zoomControl: true
});
return createMarkers();
}
initMap()
.then(console.log)
.catch(console.warn)
</script>
</body>
</html>