Как создать нумерованные маркеры на карте в Google Maps V3?

StackOverflow https://stackoverflow.com/questions/2436484

Вопрос

Я работаю над картой, на которой есть несколько маркеров.

Эти маркеры используют собственный значок, но я также хотел бы добавить цифры сверху.Я видел, как это было достигнуто с использованием старых версий API.Как это сделать в V3?

* Примечание. Атрибут «title» создает всплывающую подсказку, когда вы наводите курсор мыши на маркер, но я хочу, чтобы что-то было наложено поверх пользовательского изображения, даже если вы не наводите на него курсор.

Вот документация по классу маркера, и ни один из этих атрибутов, похоже, не помогает: http://code.google.com/apis/maps/documentation/v3/reference.html#MarkerOptions

Это было полезно?

Решение

К сожалению, это не очень легко.Вы можете создать свой собственный маркер на основе класса OverlayView (пример) и поместите в него свой собственный HTML, включая счетчик.В результате у вас останется очень простой маркер, который вы не сможете легко перетаскивать или добавлять тени, но он очень настраиваемый.

В качестве альтернативы вы можете добавить метку к маркеру по умолчанию.Это будет менее настраиваемо, но должно работать.Он также сохраняет все полезные функции стандартного маркера.

Подробнее о наложениях можно прочитать в статье Google. Развлечение с объектами MVC.

Редактировать:если вы не хотите создавать класс JavaScript, вы можете использовать API диаграмм Google.Например:

Нумерованный маркер:

http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=7|FF0000|000000

Текстовый маркер:

http://chart.apis.google.com/chart?chst=d_map_spin&chld=1|0|FF0000|12|_|foo

Это быстрый и простой путь, но он менее настраиваемый и требует загрузки клиентом нового изображения для каждого маркера.

Другие советы

Вот как я это делаю в V3:

Я начинаю с загрузки API карт Google и метода обратного вызова. 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> 

Затем я создаю маркеры с помощью 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
                });
            }

Поскольку я добавил КартаЗначокМетка class к маркеру, я могу добавить некоторые правила CSS в свой CSS:

.mapIconLabel {
    font-size: 15px;
    font-weight: bold;
    color: #FFFFFF;
    font-family: 'DINNextRoundedLTProMediumRegular';
}

И вот результат:

MarkerWithIconAndLabel

У меня недостаточно репутации, чтобы комментировать ответы, но я хотел бы отметить, что API Google Chart устарел.

Из Домашняя страница API:

Инфографическая часть инструментов диаграммы Google официально установилась по состоянию на 20 апреля 2012 года.

Вы можете загрузить набор пронумерованных значков из источников, представленных на этом сайте:

Тогда вы сможете сделать следующее:

<!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>

Скриншот из приведенного выше примера:

Google Numbered Marker Icons

Обратите внимание, что вы можете легко добавить тень за маркерами.Вы можете проверить пример на странице Справка по API Карт Google:Сложные маркеры для получения дополнительной информации об этом.

Теперь это добавлено в документацию по сопоставлению и не требует стороннего кода.

Вы можете объединить эти два образца:

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);

Обратите внимание: если у вас более 35 маркеров, этот метод не будет работать, поскольку в метке отображается только первый символ (при использовании A–Z и 0–9 получается 35).Пожалуйста, проголосуйте за это Проблема с Google Картами просить снять это ограничение.

Я сделал это, используя решение, похожее на @ZuzEL.

Вместо использования решения по умолчанию (http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=7|FF0000|000000), вы можете создавать эти изображения по своему желанию, используя JavaScript, без какого-либо серверного кода.

Google google.maps.Marker принимает Base64 в качестве свойства значка.Благодаря этому мы можем создать действительный Base64 из SVG.

enter image description here

Вы можете увидеть код для создания того же изображения, что и на этом изображении, в этом 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();
#map_canvas {
  width: 100%;
  height: 300px;
}
<!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>

В этой демонстрации я создаю SVG с помощью D3.js, затем преобразовываю SVG в Canvas, чтобы можно было изменять размер изображения по своему усмотрению, а после этого я получаю Base64 из метода toDataURL холста.

Вся эта демка была основана на моем коллеге @thiago-mata код.Слава ему.

Как насчет этого?(2015 год)

1) Получите собственное изображение маркера.

var imageObj = new Image();
    imageObj.src = "/markers/blank_pin.png"; 

2) Создайте canvas в RAM и нарисуй на нем это изображение

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

3) Напишите что-нибудь над этим

context.font = "40px Arial";
context.fillText("54", 17, 55);

4) Получите необработанные данные с холста и предоставьте их Google API вместо URL-адреса.

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

enter image description here

Полный код:

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)
    };
});

Карты Google версии 3 имеют встроенную поддержку меток маркеров.Больше не нужно создавать собственные изображения или реализовывать сторонние классы. Маркерные этикетки

Вполне возможно создать значки с метками на стороне сервера, если у вас есть некоторые навыки программирования.Помимо PHP, вам понадобится библиотека GD на сервере.У меня это работает хорошо уже несколько лет, но, по общему признанию, сложно синхронизировать изображения значков.

Я делаю это через AJAX, отправляя несколько параметров для определения пустого значка, текста и цвета, а также применяемого цвета фона.Вот мой PHP:

header("Content-type: image/png");
//$img_url = "./icons/gen_icon5.php?blank=7&text=BB";

function do_icon ($icon, $text, $color) {
$im = imagecreatefrompng($icon);
imageAlphaBlending($im, true);
imageSaveAlpha($im, true);

$len = strlen($text);
$p1 = ($len <= 2)? 1:2 ;
$p2 = ($len <= 2)? 3:2 ;
$px = (imagesx($im) - 7 * $len) / 2 + $p1;
$font = 'arial.ttf';
$contrast = ($color)? imagecolorallocate($im, 255, 255, 255): imagecolorallocate($im, 0, 0, 0); // white on dark?

imagestring($im, $p2, $px, 3, $text, $contrast);    // imagestring  ( $image, $font, $x, $y, $string, $color)

imagepng($im);
imagedestroy($im);
}
$icons =   array("black.png", "blue.png", "green.png", "red.png", "white.png", "yellow.png", "gray.png", "lt_blue.png", "orange.png");      // 1/9/09
$light =   array( TRUE,         TRUE,       FALSE,       FALSE,     FALSE,      FALSE,      FALSE,          FALSE,      FALSE);     // white text?

$the_icon = $icons[$_GET['blank']];             // 0 thru 8 (note: total 9)
$the_text = substr($_GET['text'], 0, 3);        // enforce 2-char limit
do_icon ($the_icon, $the_text,$light[$_GET['blank']] ); 

Он вызывается на стороне клиента примерно следующим образом:var image_file = "./our_icons/gen_icon.php?blank=" + escape(icons[color]) + "&text=" + iconStr;

Мои два цента, показывающие, как использовать API Google Диаграмм Для решения этой проблемы.

На основе @dave1010 ответ, но с обновленным https ссылки.

Нумерованный маркер:

https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=7|FF0000|000000

Текстовый маркер:

https://chart.googleapis.com/chart?chst=d_map_spin&chld=1|0|FF0000|12|_|Marker

Вы можете использовать опцию «Маркер с меткой» в google-maps-utility-library-v3.enter image description here

Просто обратитесь https://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries

Я нашел лучший способ сделать это.Использовать Snap.svg чтобы создать svg, а затем использовать функцию toDataURL(), которая создает графические данные для включения в качестве значка.Обратите внимание, что я использую для маркера класс SlidingMarker, который обеспечивает хорошее перемещение маркера.С помощью Snap.svg вы можете создавать любую графику, и ваша карта будет выглядеть фантастически.

var s = Snap(100, 100);
s.text(50, 50, store.name);
// Use more graphics here.
var marker = new SlidingMarker({
  position: {lat: store.lat, lng: store.lng},
  map: $scope.map,
  label: store.name, // you do not need this
  title: store.name, // nor this
  duration: 2000,
  icon: s.toDataURL()
});

САМОЕ ПРОСТОЕ РЕШЕНИЕ – ИСПОЛЬЗУЙТЕ SVG.

Работает в:в IE9, IE10, ФФ, Хром, Сафари

(если вы используете другие браузеры, пожалуйста, «Запустите фрагмент кода» и оставьте комментарий)

Никаких внешних зависимостей, кроме API Google Maps!

enter image description here

Это довольно легко при условии, что у вас есть значок .svg формат.Если это так, просто добавлять соответствующий текстовый элемент и измените его содержимое в соответствии с вашими потребностями с помощью JS.

Добавьте что-то подобное в свой .svg код (это текстовый «раздел», который позже будет изменен с помощью JS):

<text id="1" fill="#20539F" font-family="NunitoSans-ExtraBold, Nunito Sans" font-size="18" font-weight="600" letter-spacing=".104" text-anchor="middle" x="50%" y="28">1</text>

Пример: (частично скопировано из @EstevãoLucas)

Важный:Используйте правильно <text> свойства тега.Примечание text-anchor="middle" x="50%" y="28" в каком центре более длинные числа (подробнее: Как разместить и центрировать текст в прямоугольнике SVG)

Использовать encodeURIComponent() (вероятно, это обеспечивает совместимость с IE9 и 10)

// Most important part (use output as Google Maps icon)
function getMarkerIcon(number) {
  // inline your SVG image with number variable
  var svg = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40" height="40" viewBox="0 0 40 40"> <defs> <rect id="path-1" width="40" height="40"/> <mask id="mask-2" width="40" height="40" x="0" y="0" fill="white"> <use xlink:href="#path-1"/> </mask> </defs> <g id="Page-1" fill="none" fill-rule="evenodd"> <g id="Phone-Portrait---320" transform="translate(-209 -51)"> <g id="Group" transform="translate(209 51)"> <use id="Rectangle" fill="#FFEB3B" stroke="#F44336" stroke-width="4" mask="url(#mask-2)" xlink:href="#path-1"/> <text id="1" fill="#20539F" font-family="NunitoSans-ExtraBold, Nunito Sans" font-size="18" font-weight="600" letter-spacing=".104" text-anchor="middle" x="50%" y="28">' + number + '</text> </g> </g> </g> </svg>';
  // use SVG without base64 see: https://css-tricks.com/probably-dont-base64-svg/
  return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg);
}

// Standard Maps API code
var markers = [
  [1, -14.2350040, -51.9252800],
  [2, -34.028249, 151.157507],
  [3, 39.0119020, -98.4842460],
  [5, 48.8566140, 2.3522220],
  [9, 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) {
      var pos = new google.maps.LatLng(point[1], point[2]);

      new google.maps.Marker({
        position: pos,
        map: map,
        icon: getMarkerIcon(point[0]),         
      });

      bounds.extend(pos);
  });

  map.fitBounds(bounds);
}

initializeMaps();
#map_canvas {
  width: 100%;
  height: 300px;
}
<!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>        
  </head>

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

</html>

Дополнительная информация о встроенном SVG в Картах Google: https://robert.katzki.de/posts/inline-svg-as-google-maps-marker

Возможно, есть те, кто все еще ищет это, но считает, что значки Google Dynamic устарели, а другие библиотеки значков карт слишком уродливы.

Чтобы добавить простой маркер с любым номером внутри, используя URL-адрес.На Google Диске с использованием Google Мои карты он создает пронумерованные значки при использовании слоя карты, для которого установлено значение «Последовательность номеров», а затем добавляет маркеры/точки на карту.

Глядя на исходный код, у Google есть свой способ сделать это через URL-адрес:

https://mt.google.com/vt/icon/name=icons/onion/SHARED-mymaps-container-bg_4x.png,icons/onion/SHARED-mymaps-container_4x.png,icons/onion/1738-blank-sequence_4x.png&highlight=ff000000,0288D1,ff000000&scale=2.0&color=ffffffff&psize=15&text=56&font=fonts/Roboto-Medium.ttf

URL-адрес выше

enter image description here

Я особо не играл с ним, но, изменив шестнадцатеричные коды цветов в параметре «highlight» (параметр цвета не меняет цвет, как вы думаете), значение «text» можно установить в любую строку, и вы можете сделать красивый круглый значок с любым числом/значением внутри.Я уверен, что другие параметры тоже могут быть полезны.

При таком подходе есть одно предостережение: кто знает, когда Google удалит этот URL-адрес из мира!

Вот пользовательские значки с обновленным стилем «визуального обновления», которые вы можете быстро создать с помощью простого сценария .vbs.Я также включил большой предварительно созданный набор, который вы можете сразу использовать с несколькими вариантами цвета: https://github.com/Concept211/Google-Maps-Markers

Используйте следующий формат при создании ссылок на файлы изображений, размещенные на GitHub:

https://raw.githubusercontent.com/Concept211/Google-Maps-Markers/master/images/marker_[color][character].png

цвет
красный, черный, синий, зеленый, серый, оранжевый, фиолетовый, белый, желтый

характер
A-Z, 1-100, !, @, $, +, -, =, (%23 = #), (%25 = %), (%26 = &), (пробел = •)

Примеры:

red1 https://raw.githubusercontent.com/Concept211/Google-Maps-Markers/master/images/marker_red1.png

blue2 https://raw.githubusercontent.com/Concept211/Google-Maps-Markers/master/images/marker_blue2.png

green3 https://raw.githubusercontent.com/Concept211/Google-Maps-Markers/master/images/marker_green3.png

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top