четверг, 3 июля 2014 г.

Центрирование Яндекс карты - JavaScript API 2.x


Задача: используя JavaScript API 2.x Яндекс карт, добавить на карту N точек по их координатам и автоматически подобрать масштаб карты (zoom) и координаты центра.

Решение

// Экземпляр Яндекс карт
var myMap;
// Предполагаем, что points - исходный массив координат точек,
//  добавляемых на карту
var points = [
  ["55.768715", "37.510193"],
  ["55.728373", "37.669054"], 
  ["55.823500", "37.631000"],
  ["55.773300", "37.555100"]
];
// Выполняем наш код, когда API загружен - ymaps.ready()
ymaps.ready(function(){
  // Коллекция гео-точек, добавленных на карту
  var myCollection = new ymaps.GeoObjectCollection();
  // Помещаем карту в элемент DIV с id, равным «map»
  myMap = new ymaps.Map("map", {
    center: [50, 50], // Начальные значения центра карты
    zoom: 15,         // Начальное значение зума карты
    controls: ['zoomControl']
  });

  // Перебираем в цикле точки, которые надо добавить на карту
  for (i = 0; i < points.length; i++ ){
    var myPlacemark = new ymaps.Placemark([
      points[i][0], points[i][1]
    ]);
    // Не забываем добавить точку в коллекцию -
    //  впоследствии мы добавим всю коллекцию на карту
    myCollection.add(myPlacemark);
  }

  // Добавляем точки на карту
  myMap.geoObjects.add( myCollection );	
  // Вычисляем необходимые координаты краёв карты и
  //  устанавливаем их для нашего экземпляра карты	
  myMap.setBounds( myCollection.getBounds() );
});


21 комментарий:

  1. подскажи пожалуйста, как быть если var points выглядит так
    [
    {name: '1' , addr1: 'Клуб 1' , addr2: [55.768715,30.768715], url: 'Клуб1' },
    {name: '2' , addr1: 'Клуб 2' , addr2: [55.773300,30.631000], url: 'Клуб2' },
    ]

    ОтветитьУдалить
    Ответы
    1. // Перебираем в цикле точки, которые надо добавить на карту
      for (i = 0; i < points.length; i++ ){
      var myPlacemark = new ymaps.Placemark([
      points[i]['addr2'][0], points[i]['addr2'][1]
      ]);
      ...

      Удалить
    2. Спасибо! заработало. теперь только не знаю как применить
      iconContent: points[i].name,
      balloonContent: points[i].url,
      hintContent: points[i].addr1

      Удалить
    3. не подскажешь?

      Удалить
    4. У яндекс карт классная документация - http://api.yandex.ru/maps/doc/intro/concepts/intro.xml
      И много действительно качественных примеров, покрывающих абсолютное большинство часто используемых вещей - http://api.yandex.ru/maps/jsbox/2.1/

      Касательльно твоего вопроса про iconContent, balloonContent и hintContent - всё просто, my friend:) http://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/Placemark.xml

      var myPlacemark = new ymaps.Placemark([
      points[i]['addr2'][0], points[i]['addr2'][1]
      ], {
      iconContent: points[i]['name'],
      balloonContent: points[i]['url'],
      hintContent: points[i]['addr1']
      });
      ...

      Удалить
    5. спасибо! php так и научился, пробуя чужие примеры. а вот джаваскрип пока темный лес, хотя скорее всего просто лень начать разбираться в азах. еще раз спасибо!

      Удалить
    6. Рад, что помог! Чтение чужого кода - необходимая составляющая изучения новой технологии:)

      Удалить
  2. и соответственно эти данные отображаются в метке. name - в центре метки, addr1 - при наведении на метку, url - при нажатии на метку

    ОтветитьУдалить
  3. Спасибо, очень помогло.

    ОтветитьУдалить
    Ответы
    1. Отлично, рад, что помог! Пришлось как-то потратить время на поиск решения

      Удалить
  4. Огромное вам спасибо! Очень помогли.

    ОтветитьУдалить
  5. Спасибо, полезная информация, украду себе в заметки =)

    ОтветитьУдалить
  6. А мне не могли бы подсказать, как реализовать данный функционал в моем примере?))

    var map = new ymaps.Map("ymaps-map", {center: [45.270289, 34.343789], zoom: 8, type: "yandex#map"});
    map.controls.add("zoomControl").add("mapTools").add(new ymaps.control.TypeSelector(["yandex#map", "yandex#satellite", "yandex#hybrid", "yandex#publicMap"]));

    $.getJSON("json/kvart.php",
    function(json){
    for (i = 0; i < json.markers.length; i++) {

    var myPlacemark = new ymaps.Placemark([json.markers[i].lat,json.markers[i].lon], {
    balloonContentBody: json.markers[i].balloontext
    });

    map.geoObjects.add(myPlacemark);
    }
    });

    ОтветитьУдалить
  7. Решил проблему. Получилось! Огромное спасибо за решение.

    var map = new ymaps.Map("ymaps-map", {center: [45.270289, 34.343789], zoom: 8, type: "yandex#map"});
    map.controls.add("zoomControl").add("mapTools").add(new ymaps.control.TypeSelector(["yandex#map", "yandex#satellite", "yandex#hybrid", "yandex#publicMap"]));
    var kvart = new ymaps.GeoObjectCollection();
    $.getJSON("json/kvart.php",
    function(json){
    for (i = 0; i < json.markers.length; i++) {
    var myPlacemark = new ymaps.Placemark([json.markers[i].lat,json.markers[i].lon], {
    balloonContentBody: json.markers[i].balloontext
    });
    kvart.add(myPlacemark);
    map.geoObjects.add(kvart);
    map.setBounds(kvart.getBounds());
    }
    });

    ОтветитьУдалить
  8. Отличный материал, спасибо за статью.

    Возник такой вопрос:

    Допустим массив в таком варианте:
    var points = [
    [55.768715,37.510193,'Адрес'],
    [55.728373,37.669054,'Адрес'],
    ];

    При переборе точек в цикле вывожу адрес с надеждой на вывод хинта:
    var myPlacemark = new ymaps.Placemark([points[i][0], points[i][1]], {
    address: 'Город, points[i][2]',
    object: 'Название',
    }, {
    hintLayout: HintLayout
    });


    Но к великому сожалению вместо адреса выводиться points[i][2].
    Я так понимаю - это потому что он находится в кавычках и так и прописывается в address.

    Есть здесь какое-нибудь решение ?

    И ещё возник вопрос: если в массиве одна точка, то зум у карты получается сильно приближенный, можно с этим как-то бороться ?!...

    ОтветитьУдалить
    Ответы
    1. Второй параметром прописать вот так:

      myMap.setBounds( myCollection.getBounds(), { checkZoomRange: true } );

      Удалить
    2. Благодарю. Тоже столкнулся с этой проблемой.

      Удалить
  9. В случае если точка одна, а так же в случаях если расстояние между точками мало,
    можно на столько приблизится, что не будет видно ничего (карт с таким разрешением не существует) (404 https://vec03.maps.yandex.net/tiles?l=map&v=4.91.0&x=4838759&y=2703196&z=23&scale=2.2499999403953552&lang=ru_RU )

    Есть мысли как обойти?)

    ОтветитьУдалить
    Ответы
    1. var bounds = myCollection.getBounds();
      this.map.setBounds(bounds)
      .then(function () {
      var center = self.map.getCenter();
      self.map.zoomRange.get(center)
      .then(function(range) {
      self.map.setZoom(range[1]);
      });
      });

      для API 2.0 и API 2.1

      Удалить