如何在Google Maps V3中创建编号的地图标记?

mar*_*lar 59 javascript google-maps google-maps-api-3

我正在制作一张有多个标记的地图.

这些标记使用自定义图标,但我也想在顶部添加数字.我已经看到使用旧版本的API如何实现这一点.我怎么能在V3中这样做?

*注意 - 当您将鼠标悬停在标记上时,"title"属性会创建一个工具提示,但我希望即使您没有悬停在自定义图像上,也会在自定义图像上方分层.

以下是标记类的文档,这些属性似乎都没有帮助:http://code.google.com/apis/maps/documentation/v3/reference.html#MarkerOptions

dav*_*010 62

不幸的是,这并不容易.您可以基于OverlayView类(示例)创建自己的自定义标记,并将自己的HTML放入其中,包括计数器.这将为您提供一个非常基本的标记,您不能轻易地拖动或添加阴影,但它是非常可定制的.

或者,您可以将标签添加到默认标记.这将更少可定制,但应该工作.它还保留了标准标记所做的所有有用的事情.

您可以在Google的文章Fun with MVC Objects中阅读有关叠加层的更多信息.

编辑:如果您不想创建JavaScript类,可以使用Google的Chart API.例如:

编号标记:

http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=7|FF0000|000000
Run Code Online (Sandbox Code Playgroud)

文字标记:

http://chart.apis.google.com/chart?chst=d_map_spin&chld=1|0|FF0000|12|_|foo
Run Code Online (Sandbox Code Playgroud)

这是一种快速简便的路线,但它的可定制性较低,并且需要客户端为每个标记下载新图像.

  • 但请注意,Charts API计划于2015年4月折旧 - 因此大约需要6个月. (4认同)
  • 你的意思是"弃用".否则人们找不到这个词 (3认同)
  • 需要明确的是,整个Google Carts API并未弃用,只是图像图表和信息图表工具.但正如约翰所提到的,无论如何,这个答案即将过时3.21版本.见约翰的回答. (2认同)

jak*_*kob 47

这是我在V3中的方式:

我首先加载谷歌地图api,并在回调方法中initialize()加载我在这里找到的MarkerWithLabel.js:

function initialize() {

            $.getScript("/js/site/marker/MarkerWithLabel.js#{applicationBean.version}", function(){

            var mapOptions = {
                zoom: 8,
                center: new google.maps.LatLng(currentLat, currentLng),
                mapTypeId: google.maps.MapTypeId.ROADMAP,
                streetViewControl: false,
                mapTypeControl: false
            };

            var map = new google.maps.Map(document.getElementById('mapholder'),
                    mapOptions);

            var bounds = new google.maps.LatLngBounds();

            for (var i = 0; i < mapData.length; i++) {
                createMarker(i+1, map, mapData[i]); <!-- MARKERS! -->
                extendBounds(bounds, mapData[i]);
            }
            map.fitBounds(bounds);
            var maximumZoomLevel = 16;
            var minimumZoomLevel = 11;
            var ourZoom = defaultZoomLevel; // default zoom level

            var blistener = google.maps.event.addListener((map), 'bounds_changed', function(event) {
                if (this.getZoom(map.getBounds) &gt; 16) {
                    this.setZoom(maximumZoomLevel);
                }
                google.maps.event.removeListener(blistener);
            });
            });
        }

        function loadScript() {
            var script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = "https://maps.googleapis.com/maps/api/js?v=3.exp&amp;libraries=places&amp;sensor=false&amp;callback=initialize";
            document.body.appendChild(script);
        }

        window.onload = loadScript;

    </script> 
Run Code Online (Sandbox Code Playgroud)

然后我创建标记createMarker():

function createMarker(number, currentMap, currentMapData) {

   var marker = new MarkerWithLabel({
       position: new google.maps.LatLng(currentMapData[0], currentMapData[1]),
                 map: currentMap,
                 icon: '/img/sticker/empty.png',
                 shadow: '/img/sticker/bubble_shadow.png',
                 transparent: '/img/sticker/bubble_transparent.png',
                 draggable: false,
                 raiseOnDrag: false,
                 labelContent: ""+number,
                 labelAnchor: new google.maps.Point(3, 30),
                 labelClass: "mapIconLabel", // the CSS class for the label
                 labelInBackground: false
                });
            }
Run Code Online (Sandbox Code Playgroud)

由于我将mapIconLabel类添加到标记中,我可以在我的css中添加一些css规则:

.mapIconLabel {
    font-size: 15px;
    font-weight: bold;
    color: #FFFFFF;
    font-family: 'DINNextRoundedLTProMediumRegular';
}
Run Code Online (Sandbox Code Playgroud)

这是结果:

MarkerWithIconAndLabel

  • 对于今年发现的人:http://google-maps-utility-library-v3.googlecode.com/svn/tags/markerwithlabel/对我所假设的相同源代码进行了多次修订.v1.1.5对我有用,但v1.1.9并非如此,如果上述方法不起作用,也许可以尝试旧版本.感谢雅各布的信息 (4认同)

小智 27

我没有足够的声誉来评论答案,但想要注意Google Chart API已被弃用.

API主页:

截至2012年4月20日,Google Chart Tools的信息图表部分已正式弃用.


Dan*_*llo 21

您可能需要从此站点提供的来源下载一组带编号的图标:

然后你应该能够做到以下几点:

<!DOCTYPE html>
<html> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
    <title>Google Maps Demo</title> 
    <script type="text/javascript"
            src="http://maps.google.com/maps/api/js?sensor=false"></script> 

    <script type="text/javascript"> 
    function initialize() {

      var myOptions = {
        zoom: 11,
        center: new google.maps.LatLng(-33.9, 151.2),
        mapTypeId: google.maps.MapTypeId.ROADMAP
      }

      var map = new google.maps.Map(document.getElementById("map"), myOptions);

      var locations = [
        ['Bondi Beach', -33.890542, 151.274856, 4],
        ['Coogee Beach', -33.923036, 151.259052, 5],
        ['Cronulla Beach', -34.028249, 151.157507, 3],
        ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
        ['Maroubra Beach', -33.950198, 151.259302, 1]
      ];

      for (var i = 0; i < locations.length; i++) {
          var image = new google.maps.MarkerImage('marker' + i + '.png',
                      new google.maps.Size(20, 34),
                      new google.maps.Point(0, 0),
                      new google.maps.Point(10, 34));

          var location = locations[i];
          var myLatLng = new google.maps.LatLng(location[1], location[2]);
          var marker = new google.maps.Marker({
              position: myLatLng,
              map: map,
              icon: image,
              title: location[0],
              zIndex: location[3]
          });
      }
    }
    </script> 
</head> 
<body style="margin:0px; padding:0px;" onload="initialize();"> 
    <div id="map" style="width:400px; height:500px;"></div> 
</body> 
</html>
Run Code Online (Sandbox Code Playgroud)

以上示例的屏幕截图:

谷歌编号标记图标

请注意,您可以轻松地在标记后面添加阴影.您可以查看Google Maps API参考:复杂标记中的示例,了解有关此内容的详细信息.

  • 我想在顶部添加文字,而不仅仅是使用编号图像.那可能吗? (7认同)

Joh*_*ohn 15

现在,这已添加到Mapping文档中,不需要第三方代码.

您可以组合这两个样本:

https://developers.google.com/maps/documentation/javascript/examples/marker-labels

https://developers.google.com/maps/documentation/javascript/examples/icon-simple

要获得这样的代码:

var labelIndex = 0;
var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';

function initialize() {
  var bangalore = { lat: 12.97, lng: 77.59 };
  var map = new google.maps.Map(document.getElementById('map-canvas'), {
    zoom: 12,
    center: bangalore
  });

  // This event listener calls addMarker() when the map is clicked.
  google.maps.event.addListener(map, 'click', function(event) {
    addMarker(event.latLng, map);
  });

  // Add a marker at the center of the map.
  addMarker(bangalore, map);
}

// Adds a marker to the map.
function addMarker(location, map) {
  // Add the marker at the clicked location, and add the next-available label
  // from the array of alphabetical characters.
  var marker = new google.maps.Marker({
    position: location,
    label: labels[labelIndex],
    map: map,
    icon: 'image.png'
  });
}

google.maps.event.addDomListener(window, 'load', initialize);
Run Code Online (Sandbox Code Playgroud)

请注意,如果您有超过35个标记,则此方法将不起作用,因为标签仅显示第一个字符(使用AZ,0-9表示35).请投票支持此Google地图问题,以请求取消此限制.


Est*_*cas 11

我使用类似于@ZuzEL的解决方案做到了这一点.

您可以使用JavaScript创建这些图像,而无需使用默认解决方案(http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=7|FF0000|000000),而无需使用任何服务器端代码.

Google google.maps.Marker接受Base64作为其图标属性.有了这个,我们可以从SVG创建一个有效的Base64.

在此输入图像描述

您可以在此Plunker中看到与此图像相同的代码:http://plnkr.co/edit/jep5mVN3DsVRgtlz1GGQ?p = preview

var markers = [
  [1002, -14.2350040, -51.9252800],
  [2000, -34.028249, 151.157507],
  [123, 39.0119020, -98.4842460],
  [50, 48.8566140, 2.3522220],
  [22, 38.7755940, -9.1353670],
  [12, 12.0733335, 52.8234367],
];

function initializeMaps() {
  var myLatLng = {
    lat: -25.363,
    lng: 131.044
  };

  var map = new google.maps.Map(document.getElementById('map_canvas'), {
    zoom: 4,
    center: myLatLng
  });

  var bounds = new google.maps.LatLngBounds();

  markers.forEach(function(point) {
    generateIcon(point[0], function(src) {
      var pos = new google.maps.LatLng(point[1], point[2]);

      bounds.extend(pos);

      new google.maps.Marker({
        position: pos,
        map: map,
        icon: src
      });
    });
  });

  map.fitBounds(bounds);
}

var generateIconCache = {};

function generateIcon(number, callback) {
  if (generateIconCache[number] !== undefined) {
    callback(generateIconCache[number]);
  }

  var fontSize = 16,
    imageWidth = imageHeight = 35;

  if (number >= 1000) {
    fontSize = 10;
    imageWidth = imageHeight = 55;
  } else if (number < 1000 && number > 100) {
    fontSize = 14;
    imageWidth = imageHeight = 45;
  }

  var svg = d3.select(document.createElement('div')).append('svg')
    .attr('viewBox', '0 0 54.4 54.4')
    .append('g')

  var circles = svg.append('circle')
    .attr('cx', '27.2')
    .attr('cy', '27.2')
    .attr('r', '21.2')
    .style('fill', '#2063C6');

  var path = svg.append('path')
    .attr('d', 'M27.2,0C12.2,0,0,12.2,0,27.2s12.2,27.2,27.2,27.2s27.2-12.2,27.2-27.2S42.2,0,27.2,0z M6,27.2 C6,15.5,15.5,6,27.2,6s21.2,9.5,21.2,21.2c0,11.7-9.5,21.2-21.2,21.2S6,38.9,6,27.2z')
    .attr('fill', '#FFFFFF');

  var text = svg.append('text')
    .attr('dx', 27)
    .attr('dy', 32)
    .attr('text-anchor', 'middle')
    .attr('style', 'font-size:' + fontSize + 'px; fill: #FFFFFF; font-family: Arial, Verdana; font-weight: bold')
    .text(number);

  var svgNode = svg.node().parentNode.cloneNode(true),
    image = new Image();

  d3.select(svgNode).select('clippath').remove();

  var xmlSource = (new XMLSerializer()).serializeToString(svgNode);

  image.onload = (function(imageWidth, imageHeight) {
    var canvas = document.createElement('canvas'),
      context = canvas.getContext('2d'),
      dataURL;

    d3.select(canvas)
      .attr('width', imageWidth)
      .attr('height', imageHeight);

    context.drawImage(image, 0, 0, imageWidth, imageHeight);

    dataURL = canvas.toDataURL();
    generateIconCache[number] = dataURL;

    callback(dataURL);
  }).bind(this, imageWidth, imageHeight);

  image.src = 'data:image/svg+xml;base64,' + btoa(encodeURIComponent(xmlSource).replace(/%([0-9A-F]{2})/g, function(match, p1) {
    return String.fromCharCode('0x' + p1);
  }));
}

initializeMaps();
Run Code Online (Sandbox Code Playgroud)
#map_canvas {
  width: 100%;
  height: 300px;
}
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    
    <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
    
  </head>

  <body>
    <div id="map_canvas"></div>
  </body>
  
  <script src="script.js"></script>

</html>
Run Code Online (Sandbox Code Playgroud)

在这个演示中,我使用D3.js创建SVG,然后将SVG转换为Canvas,因此我可以根据需要调整图像大小,之后我从canvas'toDataURL方法获得Base64.

所有这个演示都基于我的同事@thiago-mata代码.感谢他.


Zuz*_*zEL 9

这个怎么样?(2015年)

1)获取自定义标记图像.

var imageObj = new Image();
    imageObj.src = "/markers/blank_pin.png"; 
Run Code Online (Sandbox Code Playgroud)

2)创建一个canvasin RAM并在其上绘制此图像

imageObj.onload = function(){
    var canvas = document.createElement('canvas');
    var context = canvas.getContext("2d");
    context.drawImage(imageObj, 0, 0);
}
Run Code Online (Sandbox Code Playgroud)

3)在它上面写任何东西

context.font = "40px Arial";
context.fillText("54", 17, 55);
Run Code Online (Sandbox Code Playgroud)

4)从画布获取原始数据并将其提供给Google API而不是URL

var image = {
    url: canvas.toDataURL(),
 };
 new google.maps.Marker({
    position: position,
    map: map,
    icon: image
 });
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

完整代码:

function addComplexMarker(map, position, label, callback){
    var canvas = document.createElement('canvas');
    var context = canvas.getContext("2d");
    var imageObj = new Image();
    imageObj.src = "/markers/blank_pin.png";
    imageObj.onload = function(){
        context.drawImage(imageObj, 0, 0);

        //Adjustable parameters
        context.font = "40px Arial";
        context.fillText(label, 17, 55);
        //End

        var image = {
            url: canvas.toDataURL(),
            size: new google.maps.Size(80, 104),
            origin: new google.maps.Point(0,0),
            anchor: new google.maps.Point(40, 104)
        };
        // the clickable region of the icon.
        var shape = {
            coords: [1, 1, 1, 104, 80, 104, 80 , 1],
            type: 'poly'
        };
        var marker = new google.maps.Marker({
            position: position,
            map: map,
            labelAnchor: new google.maps.Point(3, 30),
            icon: image,
            shape: shape,
            zIndex: 9999
        });
        callback && callback(marker)
    };
});
Run Code Online (Sandbox Code Playgroud)


umm*_*ian 5

Google地图版本3内置了对标记标签的支持.无需再生成您自己的图像或实施第三方课程.标记标签