Клуб API Карт

Открыть балун по координатам

Пост в архиве.
Максим
15 октября 2012, 16:44

Привет всем!

Есть карта с множеством плейсмарков, при клике на которые можно посмотреть их содержимое, например http://www.citilink.ru/route/ нижняя карта.

Вопрос в следующем: как при определённом событии открыть балун, если я знаю координаты точки и балун находится уже на карте?

Что-то вроде этого:

$('a.showBalloon').click(function(e){
   e.preventDefault();
   var chords = 'тут координаты плейсмарка, который уже на карте';
   map.setCenter(chords, 15);
   //что тут написать, чтобы просто открыть балун этой точки?
});

10 комментариев

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

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

Во-вторых, потому что в одной точке может оказаться несколько меток.

Спасибо. Это понятно...

Просто я при получении меток в цикле ищу ближайшее метро сл образом:

var map3;

map3 = new YMaps.Map(document.getElementById('map3'));

map3.setCenter(new YMaps.GeoPoint(37.62,55.77), 10);

var placemark = new Array();

var point = new Array();

var obj, mName;

for(var i=0;i

{

 point[i] = new YMaps.GeoPoint(pupX[i], pupY[i]);

 placemark[i] = new YMaps.Placemark(point[i]);

 placemark[i].setIconContent(i+1);

 placemark[i].description = ''+pupName[i]+''+'
Адрес: '+pupAdr[i]+'
Телефон: '+pupPhone[i]+'
Время работы: '+pupTime[i]+'
подробнее';

 var curMetro = new YMaps.Metro.Closest(new YMaps.GeoPoint(pupX[i],pupY[i]), { results : 1 } );

YMaps.Events.observe(curMetro, curMetro.Events.Load, function(curMetro) {

if (curMetro.length()) {

obj = curMetro.get(0);

mName = obj.text.split('метро');

$("#metroMap a").each(function(){

if ($.trim($(this).attr('title')) == $.trim(mName[1])) {

$(this).css('display', 'block');

$(this).attr('id', curMetro.request);

return false;

}

});

}

});

YMaps.Events.observe(curMetro, curMetro.Events.Fault, function (curMetro, error) {

alert("При выполнении запроса произошла ошибка: " + error);

});

}

map3.addOverlay(placemark[i]);

map3.addControl(new YMaps.Zoom());

 

Тоесть, если ближайшая точка найдена, я должен добавить плейсмарк в массив, но проблема в том, что в обработчике Load никакие переменные не видны. Хотя если поставить break после первой итерации и вывести placemark[i].description например, то всё нормально отобразиться, а если убрать break и позволить циклу пройти до конца, то при загрузке страницы в концоле firebug'a, будет много ошибок: TypeError: placemark[i] is undefined.

Я не сильно силён в яваскрипте, может это какая-то особенность?

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

Это типичная ошибка начинающих изучать JavaScript.

Вам нужно поймать переменную в замыкание, например вот так:

for(var i=0;i

function getMetro (n) {

  var curMetro = new YMaps.Metro.Closest(new YMaps.GeoPoint(pupX[n],pupY[n]), { results : 1 } );

  YMaps.Events.observe(curMetro, curMetro.Events.Load, function(curMetro) {

    alert(n); // Здесь n останется равным индексу метки, для которой выполнялся поиск

  });

}

Вот хорошая книжка по js: http://javascript.ru/book/definitiveguide

Интересно) Спасибо, прочту про это замыкание.

Вынес по вашему совету в отдельную функцию, но теперь пишет, что TypeError: pupX is undefined

 

 for(var i=0;i

 {

  point[i] = new YMaps.GeoPoint(pupX[i], pupY[i]);

  placemark[i] = new YMaps.Placemark(point[i]);

  placemark[i].setIconContent(i+1);

  placemark[i].description = ''+pupName[i]+''+'
Адрес: '+pupAdr[i]+'
Телефон: '+pupPhone[i]+'
Время работы: '+pupTime[i]+'
подробнее';

 getMetro(i);

 }

 map3.addOverlay(placemark[i], pupX, pupY);

 map3.addControl(new YMaps.Zoom());

 

Пробовал передавать остальное в функцию: getMetro(i, pupX, pupY), но вылезает такая же ошибка (

По идеи pupX и pupY объявлены глобально.

Функцию getMetro можно объявить прямо там же, перед циклом или после цикла, например.

JS поддерживает объявления функций любой вложенности.

 

Пробовал перенести функцию до цикла, всё равно не работает :(

Телепатически трудно понять, в чем проблема :)

Понимаю)))

Я чуть-чуть приблизился к сути.

Чтобы не писать лишний код, шапку см выше, тоесть инициализацию переменных и объявление цикла.

 

YMaps.Events.observe(curMetro, curMetro.Events.Load, function(curMetro) {

if (curMetro.length()) {

obj = curMetro.get(0);

//alert(i) покажет 0-1-2-3-4 и тд

mName = obj.text.split('метро');

$("#metroMap a").each(function(){

//alert(i) показывает всегда 51, тоесть длину totalPoints

if ($.trim($(this).attr('title')) == $.trim(mName[1])) {

$(this).css('display', 'block');

$(this).attr('id', i);

plMetro[i] = {'chords': curMetro.request, 'mark': placemark[i]};

return false;

}

});

}

});

 

Тоесть внутри функции each переменная i всегда равна финальному значению...

 

Тоесть внутри функции each переменная i всегда равна финальному значению...

прочитайте уже про замыкания

Разобрался!

Надо было замкнуть)))

var obj, mName, ret, curMetro = new YMaps.Metro.Closest(new YMaps.GeoPoint(pupX[i],pupY[i]), { results : 1 } );

(function(i){

YMaps.Events.observe(curMetro, curMetro.Events.Load, function(curMetro) {

if (curMetro.length()) {

obj = curMetro.get(0);

mName = obj.text.split('метро');

$("#metroMap a").each(function(){

if ($.trim($(this).attr('title')) == $.trim(mName[1])) {

$(this).css('display', 'block');

$(this).attr('id', i);

plMetro[i] = {'chords': curMetro.request, 'mark': placemark[i]};

return false;

}

});

}

});

})(i);

Всем спасибо!!!)