如何防止Google Maps SVG标记互相破坏

时间:2018-03-27 17:42:53

标签: javascript google-maps svg

我动态地将SVG标记放在Google Map上。如果2个svg标记碰巧在同一个位置,它们会像下面那样相互碰撞(1)。如果它们甚至有点间隔,它们看起来很好(2):

enter image description here

示例位于codepen。除了手动移动标记或显示它之外,我该怎么做才能解决这个问题?为简洁起见,以下是我构建标记的方法:

var markerA = new google.maps.Marker({
  position: pointA,      
  label: {
    text: "A",
    color: "white"
  },
  icon: {
    url: 'data:image/svg+xml;charset=utf-8,' + 
      encodeURIComponent('<svg viewBox="0 0 220 220" xmlns="http://www.w3.org/2000/svg"><circle cx="110" cy="110" r="100" stroke="black" fill="rgb(78, 144, 217)" fill-opacity="1.0" stroke-width="1" /></svg>'),
    size: new google.maps.Size(32, 32),
    scaledSize: new google.maps.Size(32, 32),
    anchor: new google.maps.Point(16, 16),
    labelOrigin: new google.maps.Point(16, 16)
  },
  optimized: false,
  map: map
});

2 个答案:

答案 0 :(得分:1)

当标记的计算zIndex相同时,看起来会出现问题。

看起来像Google Maps Javascript API v3中的错误。

解决方法是自己设置zIndex,将应该显示在顶部的标记的zIndex设置为更正值。

(请注意,如果您要自己设置zIndex,则必须为所有标记执行此操作才能正常工作)

var markerB = new google.maps.Marker({
  position: pointB,  
  zIndex: 10,
  label: {
    text: "A",
    color: "white"
  },
  icon: {
    url: 'data:image/svg+xml;charset=utf-8,' + 
      encodeURIComponent('<svg viewBox="0 0 220 220" xmlns="http://www.w3.org/2000/svg"><circle cx="110" cy="110" r="100" stroke="black" fill="rgb(78, 144, 217)" fill-opacity="1.0" stroke-width="1" /></svg>'),
    size: new google.maps.Size(32, 32),
    scaledSize: new google.maps.Size(32, 32),
    anchor: new google.maps.Point(16, 16),
    labelOrigin: new google.maps.Point(16, 16)
  },
  map: map
});

proof of concept fiddle

screenshot of map with markers on top of each other

screenshot of map with markers slightly offset

代码段

function initMap() {
  var pointA = new google.maps.LatLng(53.3163803, -6.2676661),
    pointB = new google.maps.LatLng(53.316388, -6.2676661),
    myOptions = {
      zoom: 15,
      center: pointA
    },
    map = new google.maps.Map(document.getElementById('map-canvas'), myOptions),
    markerA = new google.maps.Marker({
      position: pointA,
      zIndex: 0,
      draggable: true,
      title: "SVG icon",
      label: {
        text: "10",
        color: "white"
      },
      icon: {
        url: 'data:image/svg+xml;utf8,<svg viewBox="0 0 220 220" xmlns="http://www.w3.org/2000/svg"><circle cx="110" cy="110" r="100" stroke="black" fill="#4E90D9" fill-opacity="1.0" stroke-width="10" /></svg>',
        size: new google.maps.Size(200, 200),
        scaledSize: new google.maps.Size(32, 32),
        anchor: new google.maps.Point(16, 16),
        labelOrigin: new google.maps.Point(16, 16)
      },
      map: map
    });
  var markerB = new google.maps.Marker({
    position: pointB,
    zIndex: 10,
    draggable: true,
    label: {
      text: "A",
      color: "white"
    },
    icon: {
      url: 'data:image/svg+xml;charset=utf-8,' +
        encodeURIComponent('<svg viewBox="0 0 220 220" xmlns="http://www.w3.org/2000/svg"><circle cx="110" cy="110" r="100" stroke="black" fill="rgb(78, 144, 217)" fill-opacity="1.0" stroke-width="1" /></svg>'),
      size: new google.maps.Size(32, 32),
      scaledSize: new google.maps.Size(32, 32),
      anchor: new google.maps.Point(16, 16),
      labelOrigin: new google.maps.Point(16, 16)
    },
    map: map
  });
}
google.maps.event.addDomListener(window, 'load', initMap);
html,
body,
#map-canvas {
  height: 100%;
  width: 100%;
  padding: 0px;
  margin: 0px;
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id='map-canvas'></div>

答案 1 :(得分:1)

您可能需要查看Javascript API的Overlapping Marker Spiderfier第三方库。它扩展了与谷歌地球如何使用其图钉类似的点。

这里有simple JSBin proof of concept改编自原始代码示例:

<!DOCTYPE html>
<html>
  <head>
    <title>Cluster</title>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <style>
       html, body,
      #map-canvas {
        height: 100%;
        width: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
    <script type='text/javascript' src="https://cdnjs.cloudflare.com/ajax/libs/OverlappingMarkerSpiderfier/1.0.3/oms.min.js"></script>
    <script type='text/javascript' src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY"></script>
    <script>
     function initMap() {
    var infowindow = new google.maps.InfoWindow();

  var pointA = new google.maps.LatLng(53.3163803, -6.2676661);
  var pointB = new google.maps.LatLng(53.3163803, -6.2676661);

  // uncomment below to move the marker a bit and make the clobbering go away
  // var pointB = new google.maps.LatLng(53.3164803, -6.2676661);

  var  myOptions = { zoom: 15, center: pointB };
  var map = new google.maps.Map(document.getElementById('map-canvas'), myOptions);

  var url ='data:image/svg+xml;charset=utf-8,' +
        encodeURIComponent('<svg viewBox="0 0 220 220" xmlns="http://www.w3.org/2000/svg"><circle cx="110" cy="110" r="100" stroke="black" fill="rgb(78, 144, 217)" fill-opacity="1.0" stroke-width="1" /></svg>');

  var markerA = new google.maps.Marker({
    position: pointA,
    label: {
      text: "A",
      color: "white"
    },
    icon: {
      url: url,
      size: new google.maps.Size(32, 32),
      scaledSize: new google.maps.Size(32, 32),
      anchor: new google.maps.Point(16, 16),
      labelOrigin: new google.maps.Point(16, 16)
    },
    optimized: false
  });

  var markerB = new google.maps.Marker({
    position: pointB,
    label: {
      text: "B",
      color: "white"
    },
    icon: {
      url: url,
      size: new google.maps.Size(32, 32),
      scaledSize: new google.maps.Size(32, 32),
      anchor: new google.maps.Point(16, 16),
      labelOrigin: new google.maps.Point(16, 16)
    },
    optimized: false
  });

  //Save the marker labels as separate fields, so that their labels can be changed with OMS
  markerA.id = 'A';
  markerB.id = 'B';

  //Declare the Spiderfier and add the markers
  var oms = new OverlappingMarkerSpiderfier(map);
  oms.addMarker(markerA);
  oms.addMarker(markerB);

  //Check for the 'format' event and update the marker label
  oms.addListener('format', function(marker, status) {
      var label;
        switch (status) {
          //'SPIDERFIABLE' means the markers are clustered up; show a '+' sign to denote they can be
          //expanded
          case OverlappingMarkerSpiderfier.markerStatus.SPIDERFIABLE:
            label = '+';
            break;
          //'SPIDERFIED' means the markers are expanded; restore the original label from the id field
          case OverlappingMarkerSpiderfier.markerStatus.SPIDERFIED:
            label = marker.id;
            break;
        };
        marker.setLabel({text:label, color: "white"});
  });
}
google.maps.event.addDomListener(window, 'load', initMap);
    </script>
  </head>
  <body>
    <div id="map-canvas"></div>
  </body>
</html>