- PVSM.RU - https://www.pvsm.ru -
Работаю я в одном проекте с картами Google. Новыми, версии 3. Новые карты всем хороши: и быстрые, и дизайн симпатичный, и клевая клиентская библиотека [1] для них есть. Одна проблема — маркеры одноцветные, а мне нужны разноцветные. В этой статье мы эту проблему будем решать — сделаем маленький сервис, который будет отдавать перекрашенный стандартный маркер нужного нам цвета.
Результат, для нетерпеливых, доступен здесь [2].
Стандартный маркер берется гуглокартами по адресу mt.googleapis.com/vt/icon/name=icons/spotlight/spotlight-poi.png&scale=2 [3] (выяснить это можно с помощью, например, Firebug, просмотрев список загружаемых страницей изображений во вкладке «Сеть»).
В зависимости от параметра scale по ссылке возвращаются изображения разного размера:
scale | Размер изображения |
---|---|
1 | 22px × 40px |
2 | 44px × 80px |
3 | 66px × 120px |
4 | 88px × 160px |
Перекрашивать маркеры мы будем следующим образом:
Выполнять необходимые нам преобразования изображений для перекраски маркера программно удобнее всего, используя пакет консольных утилит Imagemagick [4]:
convert -size 88x160 xc:"#0000ff" mask.png # создаем маску
convert marker-bw.png mask.png -compose Overlay -composite temp.png # накладываем оверлей
convert temp.png marker-bw.png -compose copy-opacity -composite ready.png # копируем альфа-канал
Сервер для отдачи получаемых изображений в сеть реализован на Node.js. Давайте посмотрим, как происходим на нем обработка запроса /getmarker?scale={размер маркера}&color={HEX-код цвета маркера} на получения маркера с заданным размером и цветом:
var colorRegexp = /^(?:[0-9a-f]{3}){1,2}$/i; //задаем регулярное выражение, по которому мы будем проверять правильность запрошенного цвета
var scales = ["22x40", "44x80", "66x120", "88x160"]; //создадим массив, описывающий доступные размеры маркера
app.get('/getmarker',function(req, res){
//проверим переданный в метод цвет, либо установим цвет по умолчанию
var color = req.query["color"];
if (!color || !colorRegexp.test(color)){
color = "f55850"
} else {
color.toLowerCase();
}
//проверим переданный в метод размер маркера, либо установим его по умолчанию
var scale = req.query["scale"];
var scale = new Number(req.query["scale"]);
if (!scale){
scale = 1;
}
scale--;
if (scale < 0) scale = 0;
if (scale > scales.length - 1) scale = scales.length - 1;
//зададим имя файла, куда мы будем сохранять полученный маркер, чтобы не генерировать его заново при повторном запросе
var filename = "./markers/marker-" + color + "-" + scale + ".png";
fs.exists(filename, function(exists) {
if (exists) {
//если мы уже сгенерировали такой маркер, вернем готовую картинку
console.log(filename + " exists, sended");
res.sendfile(filename);
} else {
exec(
//создаем цветовую маску
'convert -size ' + scales[scale] + ' xc:#"' + color + '" mask' + color + scale +'.png n' +
//накладываем маску на черно-белое изображение маркера
'convert marker-bw-' + scale + '.png mask' + color + scale +'.png -compose Overlay -composite temp' + color + scale +'.png n' +
//копируем прозрачность на временное изображение, полученное после оверлея
'convert temp' + color + scale +'.png marker-bw-' + scale + '.png -compose copy-opacity -composite ' + filename,
console.log(filename + " created and sended");
res.sendfile(filename, function(){
//почистим мусор
exec('rm temp' + color + scale +'.png mask' + color + scale +'.png');
});
);
}
});
});
Полный код доступен на GitHub [5].
Сервис доступен по адресу http://gmapsmarkergenerator.eu01.aws.af.cm [6]. Сами же маркеры — gmapsmarkergenerator.eu01.aws.af.cm/getmarker?scale={размер маркера}&color={HEX-код цвета маркера}. Как использовать их на карте?
Рассмотрим пример, работающий на библиотеке gmaps.js [1]:
var map = new GMaps({
div: '#gmap',
lat: 55.7722200,
lng: 37.6155600,
zoom: 11
});
map.addMarkers(
[{
"lat": "55.767293",
"lng": "37.544298",
"icon": "gmapsmarkergenerator.eu01.aws.af.cm/getmarker?scale=1&color=00ffff"
},
{
"lat": "55.747215",
"lng": "37.655428",
"icon": "gmapsmarkergenerator.eu01.aws.af.cm/getmarker?scale=1&color=ff00ff"
},
{
"lat": "55.741408",
"lng": "37.629908",
"icon": "gmapsmarkergenerator.eu01.aws.af.cm/getmarker?scale=1&color=ffff00"
},
{
"lat": "55.799994",
"lng": "37.618375",
"icon": "gmapsmarkergenerator.eu01.aws.af.cm/getmarker?scale=1&color=ff0000"
},
{
"lat": "55.730858",
"lng": "37.561649",
"icon": "gmapsmarkergenerator.eu01.aws.af.cm/getmarker?scale=1&color=00ff00"
},
{
"lat": "55.800309",
"lng": "37.639824",
"icon": "gmapsmarkergenerator.eu01.aws.af.cm/getmarker?scale=1&color=0000ff"
}]
);
Как видите, все очень просто, нужно только указать у каждого маркера параметр icon.
Автор: MAD_GooZe
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/44032
Ссылки в тексте:
[1] клевая клиентская библиотека: http://hpneo.github.io/gmaps/
[2] здесь: http://gmapsmarkergenerator.eu01.aws.af.cm/
[3] mt.googleapis.com/vt/icon/name=icons/spotlight/spotlight-poi.png&scale=2: http://mt.googleapis.com/vt/icon/name=icons/spotlight/spotlight-poi.png&scale=2
[4] Imagemagick: http://www.imagemagick.org/script/index.php
[5] GitHub: https://github.com/MAD-GooZe/gmapsmarkergenerator
[6] http://gmapsmarkergenerator.eu01.aws.af.cm: http://gmapsmarkergenerator.eu01.aws.af.cm
[7] Источник: http://habrahabr.ru/post/194784/
Нажмите здесь для печати.