Как я могу создать пронумерованные маркеры карты в Google Maps V3? - PullRequest
58 голосов
/ 13 марта 2010

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

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

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

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

Ответы [ 16 ]

62 голосов
/ 07 мая 2010

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

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

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

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

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

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

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

47 голосов
/ 21 октября 2013

Вот как я это делаю в 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
                });
            }

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

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

А вот и результат:

MarkerWithIconAndLabel

27 голосов
/ 06 июля 2012

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

С домашней страницы API :

Часть инфографики Google Chart Tools официально устарело по состоянию на 20 апреля 2012 г.

21 голосов
/ 13 марта 2010

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

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

<!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: сложные маркеры для получения дополнительной информации об этом.

15 голосов
/ 04 августа 2015

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

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

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 Maps Issue , чтобы попросить снять это ограничение.

11 голосов
/ 01 октября 2015

Я сделал это, используя решение, похожее на @ 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 из метода canvas toDataURL.

Вся эта демонстрация была основана на коде моего друга @ thiago-mata . Престижность для него.

9 голосов
/ 29 июля 2015

Как насчет этого? (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) Получите необработанные данные с холста и предоставьте их API Google вместо 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)
    };
});
5 голосов
/ 25 ноября 2015

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

3 голосов
/ 27 февраля 2013

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

Я делаю это через AJAX, отправляя несколько параметров для определения пустого значка, текста и цвета, а также применяемого bgcolor. Вот мой 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;

2 голосов
/ 10 октября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...