Как создать нумерованные маркеры на карте в Google Maps V3?
-
19-09-2019 - |
Вопрос
Я работаю над картой, на которой есть несколько маркеров.
Эти маркеры используют собственный значок, но я также хотел бы добавить цифры сверху.Я видел, как это было достигнуто с использованием старых версий 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) > 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&libraries=places&sensor=false&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';
}
И вот результат:
У меня недостаточно репутации, чтобы комментировать ответы, но я хотел бы отметить, что API Google Chart устарел.
Инфографическая часть инструментов диаграммы 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>
Скриншот из приведенного выше примера:
Обратите внимание, что вы можете легко добавить тень за маркерами.Вы можете проверить пример на странице Справка по 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.
Вы можете увидеть код для создания того же изображения, что и на этом изображении, в этом 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
});
Полный код:
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.
Просто обратитесь 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!
Это довольно легко при условии, что у вас есть значок .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
Я особо не играл с ним, но, изменив шестнадцатеричные коды цветов в параметре «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 = &), (пробел = •)
Примеры:
https://raw.githubusercontent.com/Concept211/Google-Maps-Markers/master/images/marker_red1.png
https://raw.githubusercontent.com/Concept211/Google-Maps-Markers/master/images/marker_blue2.png
https://raw.githubusercontent.com/Concept211/Google-Maps-Markers/master/images/marker_green3.png