Клуб API Карт

Коллекции меток на карте

Пост в архиве.
Пример: коллекции меток на карте
В документации API Яндекс.Карт есть очень востребованный пример «Создание меню для отображения коллекций объектов» или другими словами «Создание фильтров для объектов на карте». Мы доработали этот пример: добавили второй уровень меню.

Открыть пример в новом окне.

Теперь если выбрать, например, «Оригинальные музейчики» откроется список всех музеев, добавленных в эту группу. При клике на любой пункт в списке будет открываться балун у метки выбранного музея, а карта будет центрироваться на данном объекте.

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

Похожие фильтры уже используются на сайте ГдеЭтотДом (API 1.x). Чуть-чуть по-другому фильтры реализованы на сайте «Опись трапезных» (API 2.0). Правда, ни в одном из этих проектов карта не зумиться на выбранный объект, как в нашем примере.
65 комментариев

а можно ли сделать подменю не ссылками, а селектом? у Вас в примере на ссылку вешается .bind('click'), но для option'a селекта это не срабатывает :(

мне бы точно такое же, но с перламутровыми пуговицами )

на селектах надо слушать change

ну я так и думал, что change смотреть(слушать) нужно, но вот при формировании меню с помощью куска кода

$('' + group.properties.get('name') + '')

                .bind("click", function () {

                      var link = $(this);

      map.geoObjects.each(function (group) {

               map.geoObjects.remove(group);

      });

      map.geoObjects.add(group);

 

                })

.appendTo(menuContainer);

уже на этом этапе у меня произошла проблемка - в мазилле у меня выводится в меню только один айтем. В остальных браузерах выводится полный список (пусть пока и не рабочий). 

Да и отловить какой именно фильтр был выбран не получается :(

еще раз

клики слушать на option как то ненатурально )

обычно слушают change на select-е

эт даааа - прогнал я, под конец дня написал что-то непонятное. просто в js новичок. Почти разобрался уже, начинает потихоньку доходить) спс за то, что "пнул" в нужную сторону ;)

Если сдвинуть карту, то открытие баллуна происходит по второму клику. Не могу что-то это вылечить. Есть мысли?

у меня не получилось воспроизвести,

но возможно поможет замена

 

map.panTo(item.geometry.getCoordinates());
if(item.balloon.isOpen()) {
    item.balloon.close();
}
else {
    item.balloon.open();
}

 

 на

 

map.panTo(item.geometry.getCoordinates(), {
    callback: function () {
        if(item.balloon.isOpen()) {
            item.balloon.close();
        }
        else {
            item.balloon.open();
        }
    }
});

 

Явление устойчивое, попробовал на разных компьютерах в хроме. Прямо во фрейме с примером, если сдвинуть карту или отмасштабировать, то баллун открывается по второму клику на пункт списка.

замена не помогла?

Прошу прощения. Я кликнул на ссылку "обсуждение примера клубе" из песочницы (http://api.yandex.ru/maps/jsbox/object_list). Она привела сюда, а вы тут похоже о другом пишите.

В приведенном примере есть 4 коллекции.
а что надо прописать, чтобыисчезали/появлялись сразу все злементы на карте? а не отдельно по коллекциям?

нужна отдельная кнопка "показать все"?

я прошу прощения за неполное описание вопроса.

Да - отдельные кнопки показать все и скрыть все.

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

Вопросы:

1.Будет ли пример работать в кластере?

2.Если список точек реализован не ymaps.geoXml, а массивом как в примере [[координаты], 'balloonContent', 'hintContent'], будет ли пример работать? Т.е. если циклом точки загнать в группы, а затем в кластер.

для кластера есть другой пример

группы и кластеры несовместимы.

кластеризатор работает только с массивами

Не подскажете как сделать что бы .submenu  по умолчанию был скрыт (hide) соответственно и метки? Может вопрос покажеться тривиальным, но я пока только разбираюсь что к чему.

Можно изначально проставить ему css стили

Типа display: none; получаеться с .submenu, но по двойному клику почему то открываеться. 

Не очень понял что именно нужно.

В примере итак второй уровень меню изначально скрыт и меток не видно

Спасибо, именно то. Незаметил этот пример.

Здравствуйте! Вы выше указали ссылку на пример, но пример не работает. Не могли бы Вы привести пример изначально скрытого подменю (не используя css стили, т.к. при их использовании необходимо нажимать на главный пункт меню 2 раза)

Буду очень признателен если Ваш пример будет показан основываясь на этом коде 

stroev@terra.spb.ru
28 января 2016, 04:25

+1 пожалуйста на этом коде 

stroev@terra.spb.ru
28 января 2016, 04:25

сам сделал=) все просто оказалось.

поменять ток вот этот код:

 

        // Добавляем подменю.

        menuItem

            .append(submenu.hide())

            // Добавляем пункт в меню.

            .appendTo(menu)

            // По клику удаляем/добавляем коллекцию на карту и скрываем/отображаем подменю.

            .find('a')

            .toggle(function () {

                myMap.geoObjects.add(collection);

                submenu.show();

            }, function () {

                myMap.geoObjects.remove(collection);

                submenu.hide();

            });

        for (var j = 0, m = group.items.length; j < m; j++) {

            createSubMenu(group.items[j], collection, submenu);

        }

 

products-nutrition
28 января 2016, 04:25

Мне надо сделать немного иначе, кстати думаю так было бы гораздо интереснее и для других, постараюсь объяснить подробно:

 

Пользователь на сайте интернет-магазина открывает карту Яндекс и видит к примеру 200 объектов-магазинов, установленных разработчиком. Карта автоматически передвигается по определению местоположения пользователя (с запросом местоположения разумеется) на то место где пользователь находится. Пользователь видит ближайшие объекты к нему и нажимает на один из объектов, в всплывающем окне объекта описание объекта и ссылка в описании на другую страницу (к примеру стр. может открываться в неполном новом окне это уже на вкус и цвет что наз-ся...). Почему в описание объекта нельзя добавить свою собственную ссылку? Соответственно определение местоположения обязательно. 

Ссылку добавить можно, определение местоположения рассмотрено в других примерах (можете кликнуть на тэг "примеры" в этом посте)

products-nutrition
28 января 2016, 04:25

Что-то я прочитал все руководство API Яндекс карт и не увидел где написано, что можно добавить ссылку, а местоположение посмотрю в примерах, спасибо.

 

Можно пример как создать ссылку в описании метки (объекта) ? С определением местоположения нашел, спасибо.

http://api.yandex.ru/maps/jsbox/balloon_and_hint

 

Просто добавляйте строку, содержащую HTML-разметку, в соотв. поле данных

Александр
28 января 2016, 04:25

А можно сделать привязку обычной ссылки на странице сайта в типа

Точка 1

к точке на карте заданной как Placemark?
У меня всего 5 точек, 5 ссылок на странице (но ссылки должны индексироваться).

Надо чтоб кликнул и карта подъехала к нужной точке и развернула балун. Это реально сделать?

Александр
28 января 2016, 04:25

Спасибо!

А можно сделать чтобы помедленнее шел переброс с точки на точку (когда большие расстояния - ничего понять не успеваешь что произошло) и масштаб менять на разный заданный отдельно на кадую точку?

Метод panTo принимает опции вторым аргументом

тот что вам нужен называется duration

Александр
28 января 2016, 04:25

Сделал, спасибо! А что с разным масштабом на каждую точку? Я так понимаю надо checkZoomRange включить, но где прописать цифру зуммирования для каждой точки отдельно?

Если нужно менять масштаб надо использовать setCenter

Александр
28 января 2016, 04:25

А куда его надо вставлять? Вот, например, точка, которая добавляется в группу:

.add(new ymaps.Placemark([55.234,34.543], { id: 'point1', iconContent: 'Точка 1', balloonContentHeader: 'Точка 1', balloonContentBody: 'Описание 1'}))

setCenter как к ней "прикрепить", чтоб при обращении было зуммирование? Суть в том, что изначально карта выводится в более общем масштабе, а при клике на объект хочется сделлать не только передвидение на центр заданной координаты и открывание балуна, но и приближение к объекту. Причем желательно иметь возможность показывать каждый из объектов с разным масштабом.

 

з.ы. А, я понял, setCenter можно вставить в panTo в callback, теперь вопрос - можно ли зная id точки получить значение координат, заданных в Placemark([хх.ххх,уу.ууу] и подставить их в setCenter ([хх.ххх, уу.ууу]), 18, ... ? Или каким то другим способом сохранить координаты точки и поменять только её масштаб?

Вы можете использовать setCenter вместо panYo

а масштаб хранить в данных метки вместе с id и iconContent

Пытаюсь использовать данный пример, но вместо пути к xml-файлу прописываюв путь к скрипту, который формирует xml.

Но в итоге группы не выводяться. Вот код скрипта:


header("Content-type: text/xml");

include("settings.php");

echo 'http://maps.yandex.ru/ymaps/1.x" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maps.yandex.ru/schemas/ymaps/1.x/ymaps.xsd">
    http://maps.yandex.ru/representation/1.x">

       




       
           
       
   

   
        Объекты карте
        ';

$query1= "SELECT * FROM district";
$result1 = mysql_query($query1);
while ($par1 = mysql_fetch_array($result1))
{
echo '';
echo '', htmlspecialchars($par1['name']), '';
echo '';
echo '';
echo '';
echo '';
echo '';
echo '', $par1['coord_y'], ' ', $par1['coord_x'], '';
echo '';
echo '';
echo '';

echo "\n";

}

echo '
   
';


?>

Скажите, где я допустил ошибку? Спасибо.

Всем привет!

Вопрос: можно ли фильтровать объекты как в вашем примере или как здесь - http://api.yandex.ru/maps/jsbox/geoobjects_menu

 - Но используя API 2.1 ?

в 2.1 есть всё то же самое что и в 2.0

Тогда я перефразирую вопрос (я чайник в JS, поэтому прошу простить меня за возможно глупые вопросы):

У меня просто два кода (части) которые у меня не хватает ума объеденить:

 

Часть примера (в 2.0):

 

// Создадим объекты из их JSON-описания и добавим их на карту.

window.myObjects = ymaps.geoQuery({

  type: "FeatureCollection",

  features: [ { ...Feature... },{ ...Feature... } ]

}).addToMap(myMap);

 

Часть примера (в 2.0):


myMap.geoObjects

 

.add(new ymaps.Placemark([55.755607,37.657759],{

iconContent: 'Метка 1',

balloonContentBody: [

' бла-бла'

].join('')

}, {

preset: 'islands#nightStretchyIcon'

}))

 

как вторую часть "засунуть" в первую?

никак

вы либо все оформляете в формате GeoJSON и передаете в geoQuery,

либо создаете объекты с помощью функций-конструкторов

Ясно, спасибо.

Похоже что это тупик, и нужно начинать сначала...  

Может подскажете где искать (пример кода)?

И возможно ли вообще сделать фильтр без применения GeoJSON ?

Задача проста:

...есть сеть магазинов которая делится на несколько типов,

 условно:  "Красные" "Синие"  и "Зелёные" ... 

В принципе http://api.yandex.ru/maps/jsbox/geoobjects_menu 

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

 

но как задать  в GeoJSON  все те параметры...

Видимо прочитать на него спецификацию

http://geojson.org/

 

В документации есть пример (5)

http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/GeoQueryResult.xml

преследую цель вывода на карте только тех объектов, которые попадают в зону видимости. прописываю в обсуждаемого примера:

добавляю в конец примера следующий код:

myMap.events.add('boundschange', function () {var visibleObjects = collection.searchInside(myMap).addToMap(myMap);collection.remove(visibleObjects).removeFromMap(myMap); }) ;

результата ноль. куда копать?

незнаю. нужна ссылка на карту

да, конечно: карта 

У вас переменная "collection" не видна там где вы к ней обращаетесь

Uncaught ReferenceError: collection is not defined


Зачем вам эти сложности с областью видимости?

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

куда будет переход с ссылок?

ну, теоретически, предполагал так:

например, есть 3 объекта в коллекции. один виден, другие 2 нет. меню состоит из всех трёхобъектов. тыкаем на тот, которого нет на крте, и у нас карта перемещается на него. он становится видимым и открывается описание. если объект,который был видел до этого на карте, исчезает изполя зрения, то он становится не видимым....

да, сложностей кучма.. но затеял всё это потому, что объекты будут выводиться в засисимости от определённых запросов пользователя. и иногда их кол-во может доходить до 100-200 (редко, но всё же). а это, я так понимаю, очень ресурсозатратно?!

или же не так страшен чёрт, как его молюют? и "забить" на отображение видимых объектов?

нет 200 это немного

можно не заморачиваться

спасибо Вам, бабушка-бэтмен! гора с плеч..

Как я понял в примере по указанной ссылке http://dimik.narod.ru/ymaps/grouping.html вот этим кодом
ymaps.geoXml.load("http://api.yandex.ru/maps/doc/ymapsml/1.x/examples/xml/menufromymapsml.xml") 
подключается xml с уже готовой группировкой объектов на карте. А что делать если пользовательская карта генерирует kml документ, где все объекты просто выданы одним списком без категорий? Вот пример этого kml документа
http://maps.yandex.ru/export/usermaps/eyBQZFQmZ-9Vn4xW14AFpJv6eI5jG032.kml

На моей пользовательской карте добавлено несколько объектов, и они никак не объединены в категории, так интерфейс Яндекс.Карт это делать не позволяет. 

Вы можете предварительно перебрать плоскую коллекцию и сгруппировать метки по каким-то признакам

Нужен совет... Не могу понять, в чём косяк? Фото в балуне отображаются норм, а флэшка отображается только в нижней правой четверти экрана и видна поверх всего (ссылка), тогда как при другом методе (ссылка_2) всё именно так, как мне нужно. До всего дохожу методом "научного тыка", поэтому плиз пните меня в нужном направлении!

Не могу понять: как сделать чтобы метки сразу добавлялись на карту, а не при клике?

Здрасьте, а подскажите,можно ли отдельному элементу из группы прикрепить свою метку-иконку

не дождался ответа. сам нашёл как...

Здравствуйте!а подскажите как для данного примера поменять содержимое балуна?чтоб там не только название и адрес был,а также,например,картинка. Где здесь вообще balloonContent куда можно уже свою HTML разметку с ссылками вставить?

Добрый день. Уже видел здесь свой вопрос, но ответа на него нет, так что задам еще раз. Как к данному примеру прикрутить кнопку (чекбокс,ссылку не важно что) Показать/Скрыть всё. Пытался сам что-то изобразить но не вышло. Буду признателен за помощь.
andrewudovenko,
Тоже интересно, но нигде готового примера нет! Это поле для исследований! Типа диссертация))
Добрый день. Нужна помощь. В  >>>ПРИМЕРЕ<<< карта растянута на весь экран и список объектов в низу под картой. Я пытаюсь сделать несколько карт с левой стороны и список с правой. Карты сделал, а вот список не могу сделать с правой стороны. Уже через таблицу пытался без успешно.
Обновлено 14 февраля 2018, 12:02
a.borichewsky,
Здравствуйте. Технические вопросы Вы можете задать на Stack Overflow: https://ru.stackoverflow.com/questions/tagged/yandex-maps-api
Сергей П.
2 мая 2019, 22:16
А где пример то?
там только реклама казино и всё
Есть вопрос, как мне сделать так, чтобы при клике на метку список элементов, выведенный отдельно скроллился к нужному элементу (соответствующему). Это нужно так как список планируется в виде ограниченного по высоте блока поверх карты, а элементов будет много.


Вот пример - https://www.berryalloc.com/global/en/dealers


Тут список и точки «связаны»: кликая на метку скроллится к элементу внешнего списка, а кликая по элементу списка двигает к метке на карте и открывает балун 
ladisov,
привет нашел решения??? Этого поделись если не жалко
Добрый день,  на основе Вашего примера сделал карту с меню,  и есть один вопрос: Подскажите как сделать, чтобы при нажатии на пункт из списка, к пункту добавлялся класс допустим active... спасибо
Обновлено 30 июня 2022, 01:51
Подскажите, пожалуйста, как сделать так, чтобы карта была в правом div, а список адресов в левом div.