多个地图标记

Posted

技术标签:

【中文标题】多个地图标记【英文标题】:Multiple Map Markers 【发布时间】:2021-12-19 11:26:38 【问题描述】:

我正在尝试在点击时设置不同的标记图标大小。我遇到的麻烦是所有带有信息窗口的图标都更改为数组中的第一个图标项。信息窗口和里面的数据是正确的。

我一直在摸索这个问题,知道为什么点击时变量会有所不同吗?它们使用相同的文件路径设置,只是使用不同的缩放大小。

目前有没有更好的方法来完成这项工作?

var markers = new Array();
var mapMultiple;

function initMap() 

  // Get focus point
  var mapLat = parseFloat(mapVar.lat);
  var mapLng = parseFloat(mapVar.lng);
  var myLatLng = lat: mapLat, lng: mapLng;
  

  // Get locations
  var locationsMultipleMarkers = mapVar.locationsMultipleMarkers;


  // Map Defaults
  var mapMultiple = new google.maps.Map(document.getElementById('map-multiple'), 
    zoom: 9,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  );


  // Markers and info popup
  var markerMultipleMarkers, i;

  for (i = 0; i < locationsMultipleMarkers.length; i++)   

    var iconMultiple = locationsMultipleMarkers[i]['icon']; 

    if(!iconMultiple) 
      iconMultiple = mapVar.path + '/assets/svg/marker-default.svg';
    

    // Icon ready state
    var iconMultipleMarkers = 
        url: iconMultiple,
        scaledSize: new google.maps.Size(60, 60)
    ;

    // Icon active state
    var iconMultipleMarkersActive = 
        url: iconMultiple,
        scaledSize: new google.maps.Size(120, 120)
    ;

    // Markers and info popup
    var infowindowMultipleMarkers = new google.maps.InfoWindow();
    var markerMultipleMarkers, i;

    markerMultipleMarkers = new google.maps.Marker(
      position: new google.maps.LatLng(locationsMultipleMarkers[i]['lat'], locationsMultipleMarkers[i]['lng']),
      map: mapMultiple,
      animation: google.maps.Animation.DROP,
      icon: iconMultipleMarkers
    );

    markers.push(markerMultipleMarkers);

    google.maps.event.addListener(markerMultipleMarkers, 'click', (function(markerMultipleMarkers, i) 

      return function() 
        if(locationsMultipleMarkers[i]['marker_info']) 
          for (var j = 0; j < markers.length; j++) 
            markers[j].setIcon(iconMultipleMarkers);
          
          this.setIcon(iconMultipleMarkersActive);
          infowindowMultipleMarkers.setContent(locationsMultipleMarkers[i]['marker_info']);
          infowindowMultipleMarkers.open(mapMultiple, markerMultipleMarkers);
        
      
    )(markerMultipleMarkers, i));

  
 

【问题讨论】:

请提供一个minimal reproducible example 来证明您的问题。 Change Google Maps marker icon when clicking on other 的可能重复项 【参考方案1】:

根据您的代码,经过一些(好的,很多)修改和一定程度的创意许可,我整理了一个演示,说明如何基本上在两个状态之间切换加载到地图上的每个标记 - 这里只是不同仅据我从您的代码中得知的scaledSize 属性。就我个人而言,当有几个具有相似长名称的变量时,我发现它有点令人困惑 - 只是让我的头脑变得混乱。

假设源数据可能来自数据库查询并以 JSON 格式输出,我根据 mapVar 变量的各种属性生成了一些虚拟数据。

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Google Maps: </title>
        <style>
            #map
                width:800px;
                height:600px;
                float:none;
                margin:auto;
            
        </style>
        <script>
        
            const mapVar=
                path:'/path/to/images/markers',
                sizes:         //  sizes used to build `Icons`
                    ready:32,   //  default ->  60
                    active:60   //  default ->  120
                ,
                lat:56.522556,  //  default latitude ~ details unknown
                lng:-2.969856,  //  default longitude ~ details unknown
                locations:[     //  example data
                    
                        "name": "Glaxo - 2 x 132m turbines",
                        "lat": "56.70431711148748",
                        "lng": "-2.4660869436035",
                        "marker_info": "Glaxo - 2 x 132m turbines, 2 Blade Turbine, 5 Meridian St, Montrose, Angus DD10 8DS, UK",
                        "icon": "/images/css/2_blade_turbine.png"
                    ,
                    
                        "name": "Carsegownie - 1 x78m turbine",
                        "lat": "56.67951330362271",
                        "lng": "-2.8062983350524746",
                        "marker_info": "Carsegownie - 1 x78m turbine, Anemometer, B9134, Forfar, Angus DD8, UK",
                        "icon": "/images/css/mappoint-anemometer.png"
                    ,
                    
                        "name": "Frawney - Over Finlarg - 5x100m turbines",
                        "lat": "56.56806620951482",
                        "lng": "-2.9501720266113125",
                        "marker_info": "Frawney - Over Finlarg - 5x100m turbines, Antenna, Kerton Farm, Forfar, Angus DD8, UK",
                        "icon": "/images/css/mappoint-antenna.png"
                    ,
                    
                        "name": "Dodd Hill - 5 x 125m turbines",
                        "lat": "56.54251020079966",
                        "lng": "-2.9051538305053555",
                        "marker_info": "Dodd Hill - 5 x 125m turbines, Simple, 4 Backmuir Rd, Duntrune, Tealing, Dundee, Angus DD4 0PT, UK.",
                        "icon": "/images/css/mappoint-blue.png"
                    ,
                    
                        "name": "Ark Hill - 8 x 81m turbines",
                        "lat": "56.57065514278748",
                        "lng": "-3.0511732892761074",
                        "marker_info": "Ark Hill - 8 x 81m turbines, New location, 3 Dryburn Cottages, Glenogilvy, Forfar, Angus DD8 1UP, UK",
                        "icon": "/images/css/mappoint-green.png"
                    ,
                    
                        "name": "Nathro 17 x 135m turbines",
                        "lat": "56.793249595719956",
                        "lng": "-2.8623101711273193",
                        "marker_info": "Nathro 17 x 135m turbines, House, 1 Goynd Steading, Glenogil, Forfar, Angus DD8 3SW, UK.",
                        "icon": "/images/css/mappoint_house.png"
                    ,
                    
                        "name": "Govals - 6 x 87m turbines",
                        "lat": "56.582320876071854",
                        "lng": "-2.9509015874633633",
                        "marker_info": "Govals - 6 x 87m turbines, McDonalds, B9127, Forfar, Angus DD8, UK.",
                        "icon": "/images/css/mappoint_mcdonalds.png"
                    ,
                    
                        "name": "The Carrach - 9 x 84m turbines",
                        "lat": "56.6938437674986",
                        "lng": "-3.131382067657455",
                        "marker_info": "The Carrach - 9 x 84m turbines, vawt, B951, Kirriemuir, Angus DD8, UK",
                        "icon": "/images/css/vawt.png"
                    
                ]
            ;
        
            class marker
                /*
                    simple class to add new marker and assign callbacks.
                    Override default options by giving different args at
                    runtime.
                */
                constructor( map, latlng, args=, callbacks=false )
                    this.map=map;
                    this.latlng=latlng;
                    this.args=args;
                    this.callbacks=callbacks;
                    return this.create();
                ;
                create()
                    let options=Object.assign(
                        clickable:true,
                        draggable:false,
                        position:this.latlng,
                        map:this.map
                    ,this.args );
                    
                    let mkr=new google.maps.Marker( options );
                    if( this.callbacks && Object.keys( this.callbacks ).length > 0 )
                        Object.keys( this.callbacks ).forEach( event => 
                            google.maps.event.addListener( mkr, event, this.callbacks[ event ] );
                        )
                    
                    return mkr;
                ;
            ;
        
        
            function initMap()
                let markers=[];
                let latlng = new google.maps.LatLng( mapVar.lat, mapVar.lng );
                let locations=mapVar.locations;
                
                let map = new google.maps.Map( document.getElementById('map'), 
                    zoom: 9,
                    center: latlng,
                    mapTypeId:google.maps.MapTypeId.ROADMAP
                );
                
                locations.forEach( obj=>
                    let icon=obj.icon || mapVar.path + '/assets/svg/marker-default.svg';
                    
                    // A default Icon to be used when creating the map
                    let _default=
                        url:icon,
                        scaledSize:new google.maps.Size( mapVar.sizes.ready, mapVar.sizes.ready )
                    ;
                    // The alternative state Icon to be displayed when marker is clicked.
                    let _active=
                        url:icon,
                        scaledSize:new google.maps.Size( mapVar.sizes.active, mapVar.sizes.active )
                    ;
                    /*
                        custom properties to assign to the marker using the marker class above.
                        
                        The `content` is used to build the infowindow - from mapVar data.
                        The `index` is used to determine which marker to select from the array.
                        The `infowindow` becomes a property of the marker... many markers might cause issues!
                    */
                    let args=
                        index:0,
                        infowindow:new google.maps.InfoWindow(),
                        content:obj.marker_info,
                        icon:_default
                    ;
                    
                    // toggle between these Icons
                    let Icons=[ _default, _active ];
                    
                    // assign whatever callbacks are needed to be used with the new marker.
                    let callbacks=
                        click:function(e)
                            this.index = 1 - this.index;
                            this.setIcon( Icons[ this.index ] );
                            
                            // open the infowindow
                            with( this.infowindow )
                                setContent( this.content );
                                setPosition( e.latLng );
                                open( map, this );
                            
                            
                            // if the infowindow is open, close it
                            if( !this.index )this.infowindow.close()
                        
                    ;
                    
                    markers.push( new marker( map, new google.maps.LatLng( obj.lat, obj.lng ), args, callbacks ) );
                );
            ;
        </script>
    </head>
    <body>
        <div id='map'></div>
        <script async defer src='//maps.googleapis.com/maps/api/js?key=<APIKEY>&callback=initMap'></script>
    </body>
</html>

如果需要,图标可以完全不同,而不仅仅是不同的大小。

Working example

【讨论】:

以上是关于多个地图标记的主要内容,如果未能解决你的问题,请参考以下文章

如何在百度地图上标注多个地点

需要在全国地图上做标记。多个城市

百度地图javascript api怎么实现自定义标记然后将多个标记点连线起来

vue高德地图 如何一次添加多个点标记到地图实例?

高德地图上如何标记多个地

用户如何在谷歌地图颤振上添加多个标记