问题:来自图像数组的 Google 地图 AdvancedMarkerView

问题描述 投票:0回答:1

我正在尝试根据数组中的图像属性生成 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>

google-maps google-maps-api-3 google-maps-advanced-marker-element
1个回答
0
投票

如前所述,您需要使用

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>
© www.soinside.com 2019 - 2024. All rights reserved.