【问题标题】:Google maps Marker Label with multiple characters谷歌用多个字符映射标记标签
【发布时间】:2015-12-04 16:39:49
【问题描述】:

我正在尝试将 4 个字符的标签(例如“A123”)添加到具有自定义路径定义的宽图标的 Google 地图标记。

var marker = new google.maps.Marker({
  position: latLon,
  label: { text: 'A123' },
  map: map,
  icon: {
    path: 'custom icon path',
    fillColor: '#000000',
    labelOrigin: new google.maps.Point(26.5, 20),
    anchor: new google.maps.Point(26.5, 43)
    scale: 1,
  }
});

marker label API 仅限于单个字符,因此在上面的示例中只显示带有“A”的标记。我曾尝试使用 chrome 开发人员工具破解由 gmaps 创建的 html 并恢复较长的标签。它显示完美,无需对 css 进行任何修改,因此我只需要找到一种方法来恢复 Google 地图已剥离的其他标签字符。

我提出了Google Maps Issue 请求解除此限制。请考虑通过访问上面的链接为 Google 问题投票并为问题加星标以鼓励 Google 解决它 - 谢谢!

但与此同时,我可以使用一种解决方法来消除一个字符的限制吗?

有没有一种方法可以创建 google.maps.Marker 的自定义扩展来显示我的较长标签?

【问题讨论】:

标签: google-maps google-maps-api-3


【解决方案1】:

好的,这是我想出的一个非常混乱的解决方案。

我使用 fontFamily 标签属性将完整的标签文本放入 div。然后我使用 querySelectorAll 来匹配生成的样式属性,以便在地图加载后提取参考并重写标签:

var label = "A123";
var marker = new google.maps.Marker({
  position: latLon,
  label: {
    text: label,
    // Add in the custom label here
    fontFamily: 'Roboto, Arial, sans-serif, custom-label-' + label
  },
  map: map,
  icon: {
    path: 'custom icon path',
    fillColor: '#000000',
    labelOrigin: new google.maps.Point(26.5, 20),
    anchor: new google.maps.Point(26.5, 43), 
    scale: 1
  }
});

google.maps.event.addListener(map, 'idle', function() {
  var labels = document.querySelectorAll("[style*='custom-label']")
  for (var i = 0; i < labels.length; i++) {
    // Retrieve the custom labels and rewrite the tag content
    var matches = labels[i].getAttribute('style').match(/custom-label-(A\d\d\d)/);
    labels[i].innerHTML = matches[1];
  }
});

这看起来很脆弱。有没有不那么糟糕的方法?

【讨论】:

  • 哈克?是的,完全。完成工作了吗?明确地。在 Google Maps API 更新之前,我认为这是最好的解决方案。
  • 我会为未来的开发者添加:记得更改正则表达式。对我来说,这只是数字,所以[0-9]+ 可以。此外,还需要检查 matches 是否为空。另外,我修改了querySelectorAl("[style*='custom-label']")' to querySelectorAl("[style*='custom-label-']")' 并去掉了标记的icon 部分。
  • 这对我来说是最好的解决方案。对我来说,“空闲”事件侦听器似乎并不总是能接收到缩放时添加的 dom 元素。 (平移似乎没问题,只是缩放不可靠-可能是因为我与 MarkerClusterer 一起使用)。相反,我使用 setTimeout 每 100 毫秒检查一次走私字体系列是否存在。这工作得很好。如果您想要背景颜色或类似颜色,也可用于为标签走私类。
  • 这不那么糟糕,因为标记和标签是独立的对象:github.com/googlemaps/js-map-label
【解决方案2】:

您可以将 MarkerWithLabel 与 SVG 图标一起使用。

更新:Google Maps Javascript API v3 现在原生支持MarkerLabel中的多个字符

proof of concept fiddle(你没有提供你的图标,所以我做了一个)

注意:this fix 解决了重叠标记上的标签问题,感谢 robd 在 cmets 中提出的问题。

代码 sn-p:

function initMap() {
  var latLng = new google.maps.LatLng(49.47805, -123.84716);
  var homeLatLng = new google.maps.LatLng(49.47805, -123.84716);

  var map = new google.maps.Map(document.getElementById('map_canvas'), {
    zoom: 12,
    center: latLng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });

  var marker = new MarkerWithLabel({
    position: homeLatLng,
    map: map,
    draggable: true,
    raiseOnDrag: true,
    labelContent: "ABCD",
    labelAnchor: new google.maps.Point(15, 65),
    labelClass: "labels", // the CSS class for the label
    labelInBackground: false,
    icon: pinSymbol('red')
  });

  var iw = new google.maps.InfoWindow({
    content: "Home For Sale"
  });
  google.maps.event.addListener(marker, "click", function(e) {
    iw.open(map, this);
  });
}

function pinSymbol(color) {
  return {
    path: 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z',
    fillColor: color,
    fillOpacity: 1,
    strokeColor: '#000',
    strokeWeight: 2,
    scale: 2
  };
}
google.maps.event.addDomListener(window, 'load', initMap);
html,
body,
#map_canvas {
  height: 500px;
  width: 500px;
  margin: 0px;
  padding: 0px
}
.labels {
  color: white;
  background-color: red;
  font-family: "Lucida Grande", "Arial", sans-serif;
  font-size: 10px;
  text-align: center;
  width: 30px;
  white-space: nowrap;
}
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry,places&ext=.js"></script>
<script src="https://cdn.rawgit.com/googlemaps/v3-utility-library/master/markerwithlabel/src/markerwithlabel.js"></script>
<div id="map_canvas" style="height: 400px; width: 100%;"></div>

【讨论】:

  • 是的 - 我一直在尝试将 MarkerWithLabel 内联到谷歌地图初始化脚本调用的回调函数中。但是当我尝试拨打 new MarkerWithLabel(...) 时,我看到了 Uncaught ReferenceError: MarkerWithLabel is not defined
  • 好的,我用另一种方式实现了这一点,通过将 MarkerWithLabel 代码包装在函数 function initMarkerWithLabel() 中并从谷歌地图回调中调用它。
  • 嗯,好的,我确实设法让这个工作,但我看到重叠引脚的问题:jsfiddle.net/LLd4drvx/1
  • markerwithlabel googlecode.com 链接已失效,备用链接为 rawgit.com/nmccready/…
  • 有人可以更新重叠标签的“修复”吗?链接坏了
【解决方案3】:

允许字母、数字和单词作为标签的这个问题的一个更简单的解决方案是以下代码。更具体地说,以“icon:”开头的代码行。任何字符串或变量都可以替换“k”。

for (i = 0; i < locations.length; i++) 
      { 
      k = i + 1;
      marker = new google.maps.Marker({
      position: new google.maps.LatLng(locations[i][1], locations[i][2]),     
      map: map,
      icon: 'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=' + k + '|FF0000|000000'
});

--- 位置数组包含经纬度,k 是我正在映射的地址的行号。换句话说,如果我有 100 个地址来映射我的标记标签将是 1 到 100。

【讨论】:

  • 不幸的是,这并没有解决主要问题,即允许带有自定义图标的更长标签可以容纳更多字符。对于 2 个或更多字母的情况,这些字母在标记针之外,看起来一点也不好看:chart.apis.google.com/…chart.apis.google.com/… 我无法在我正在开发的网站上使用它,因为它看起来坏了。
  • chart.apis.google.com 不允许自定义图标。至少它不允许用一个简单的圆圈代替别针。
【解决方案4】:

首先感谢代码作者!

我在谷歌搜索时发现了以下链接,它非常简单并且效果最好。除非 SVG 被弃用,否则永远不会失败。

https://codepen.io/moistpaint/pen/ywFDe/

这里的代码中有一些 js 加载错误,但它在提供的 codepen.io 链接上完美运行。

var mapOptions = {
    zoom: 16,
    center: new google.maps.LatLng(-37.808846, 144.963435)
  };
  map = new google.maps.Map(document.getElementById('map-canvas'),
      mapOptions);


var pinz = [
    {
        'location':{
            'lat' : -37.807817,
            'lon' : 144.958377
        },
        'lable' : 2
    },
    {
        'location':{
            'lat' : -37.807885,
            'lon' : 144.965415
        },
        'lable' : 42
    },
    {
        'location':{
            'lat' : -37.811377,
            'lon' : 144.956596
        },
        'lable' : 87
    },
    {
        'location':{
            'lat' : -37.811293,
            'lon' : 144.962883
        },
        'lable' : 145
    },
    {
        'location':{
            'lat' : -37.808089,
            'lon' : 144.962089
        },
        'lable' : 999
    },
];

 

for(var i = 0; i <= pinz.length; i++){
   var image = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2238%22%20height%3D%2238%22%20viewBox%3D%220%200%2038%2038%22%3E%3Cpath%20fill%3D%22%23808080%22%20stroke%3D%22%23ccc%22%20stroke-width%3D%22.5%22%20d%3D%22M34.305%2016.234c0%208.83-15.148%2019.158-15.148%2019.158S3.507%2025.065%203.507%2016.1c0-8.505%206.894-14.304%2015.4-14.304%208.504%200%2015.398%205.933%2015.398%2014.438z%22%2F%3E%3Ctext%20transform%3D%22translate%2819%2018.5%29%22%20fill%3D%22%23fff%22%20style%3D%22font-family%3A%20Arial%2C%20sans-serif%3Bfont-weight%3Abold%3Btext-align%3Acenter%3B%22%20font-size%3D%2212%22%20text-anchor%3D%22middle%22%3E' + pinz[i].lable + '%3C%2Ftext%3E%3C%2Fsvg%3E';

  
   var myLatLng = new google.maps.LatLng(pinz[i].location.lat, pinz[i].location.lon);
   var marker = new google.maps.Marker({
      position: myLatLng,
      map: map,
      icon: image
  });
}
html, body, #map-canvas {
  height: 100%;
  margin: 0px;
  padding: 0px
}
<div id="map-canvas"></div>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDtc3qowwB96ObzSu2vvjEoM2pVhZRQNSA&signed_in=true&callback=initMap&libraries=drawing,places"></script>

您只需要对您的 SVG html 进行 uri 编码,并在 for 循环中的“data:image/svg+xml”之后替换 image 变量中的那个。

对于 uri 编码,您可以使用uri-encoder-decoder

您可以先对现有的 svg 代码进行解码,以便更好地理解所写的内容。

【讨论】:

  • @Skoua 嘿,这有什么残忍的? ;) 我认为 svg 代码让你这么说。是吗?
  • 是的,这就是 SVG,但我知道这是动态修改 base64 图像的唯一方法。我投了赞成票。 :)
  • 谢谢。实际上 svg 是 uri 编码的。使用给定的解码器对其进行解码,它看起来更容易理解。 :)
  • 我正在使用 Angular 7 和 ngmap,这是唯一有效的解决方案。感谢一个伟大的解决方法
【解决方案5】:

从 API 版本 3.26.10 开始,您可以使用多个字符设置标记标签。解除限制。

试试吧,它有效!

此外,使用 MarkerLabel 对象而不仅仅是一个字符串,您可以为外观设置许多属性,如果使用自定义图标,您可以设置 labelOrigin 属性来重新定位标签。

来源: https://code.google.com/p/gmaps-api-issues/issues/detail?id=8578#c30 (另外,您可以在上面的链接线程中报告与此相关的任何问题)

【讨论】:

  • 由于互联网是一个生命体,我相信我们应该优先考虑边缘解决方案......可悲的 Stackexchange 仅优先考虑票数,这是官方 Google Maps JS API 中 MarkerLabel 的文档部分:@987654322 @
【解决方案6】:

对于任何想要尝试的人

...在 2019 年,值得注意的是这里引用的一些代码 no longer exists(官方)。 Google 很久以前就停止了对“MarkerWithLabel”项目的支持。它最初托管在 Google 代码 here,现在非正式托管在 Github here

但谷歌还有另一个项目维护到 2016 年,称为"MapLabel"s。这种方法是不同的(并且可以说更好)。您创建一个与标记具有相同原点的单独地图标签对象,而不是向标记本身添加 mapLabel 选项。您可以使用js-marker-label 创建marker with label with multiple characters

【讨论】:

  • ...而且...它们已被弃用(顺便说一句,仍然是 2019 年)。令人非常沮丧的是,这里的任何答案都会导致代码被弃用,官方文档仍然链接到丢失的代码等。真的让你想知道长期依赖谷歌的产品是否可行。
【解决方案7】:

您可以在不使用任何额外插件的情况下更改简单的标记标签 css。

var marker = new google.maps.Marker({
        position: this.overlay_text,
        draggable: true,
        icon: '',
        label: {
          text: this.overlay_field_text,
          color: '#fff',
          fontSize: '20px',
          fontWeight: 'bold',
          fontFamily: 'custom-label'
        },
        map:map
      });
      marker.setMap(map);

$("[style*='custom-label']").css({'text-shadow': '2px 2px #000'})

【讨论】:

    猜你喜欢
    • 2018-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-13
    • 2012-07-09
    • 2020-04-25
    • 2015-10-16
    相关资源
    最近更新 更多