Клуб API Карт

Использование YMaps.GeoCollectionBounds.add

e1widget
3 февраля 2011, 10:00

Использую следующий код:

     // Создание обработчика для события window.onLoad
        YMaps.jQuery(function () {
            // Создание экземпляра карты и его привязка к созданному контейнеру
            var map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]);

            map.setCenter(new YMaps.GeoPoint(60.597259, 56.838056), 12);
            map.addControl(new YMaps.Zoom());

            // Создание группы
            var gCollection = new YMaps.GeoObjectCollection();

            // Создание прямоугольной области
            var gBounds = new YMaps.GeoCollectionBounds();

[НАЧАЛО ЦИКЛА]

        // Геокодирование
        var geocoder = new YMaps.Geocoder([АДРЕС_В_ВИДЕ_СТРОКИ], {results:1});
        map.addOverlay(geocoder);

YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
    if (this.length()) {
        gCollection.add(new YMaps.Placemark(this.options.boundedBy));
        gBounds.add(new YMaps.Placemark(this.options.boundedBy));
    } else {
        alert("Ничего не найдено")
    }
});
 
YMaps.Events.observe(geocoder, geocoder.Events.Fault, function (error) {
    alert("Произошла ошибка: " + error.message)
});

[КОНЕЦ ЦИКЛА]

            // Добавление группы на карту
            map.addOverlay(gCollection);

            // Отображение прямоугольной области по центру карты
            map.setBounds(gBounds);
        });

В итоге: все оверлей на карте отображаются, а прямоугольная область по
центру карты не встает (отображается карта в минимальном масштабе по
центру)

Мое предположение: объект

        gBounds.add(new YMaps.Placemark(this.options.boundedBy));

не понимает передаваемую ему точку

15 комментариев
Подписаться на комментарии к посту
Во-первых GeoCollectionBounds
в методе add ждет не плейсмарк а геопоинт или массив геопоинтов.

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

Ну и в-третьих если геокодируется каждый раз одно и тоже,
то лучше это сделать один раз на серверной стороне,
сохранить координаты в базу и рисовать метки по координатам.
Я начал использовать другой подход: делаю множественное геокодирование. А внутри функции создаю прямоугольную область, и добавляю туда массив геопоинтов.

Данные для геокодирования всегда разные, и мне удобнее геокодировать на клиентской стороне.

Вопрос: как мне перевести массив плейсмарков, полученных множественным геокодированием, в геопоинты?
вызывать метод getGeoPoint()
Использую следующий код:


        // Создание обработчика для события window.onLoad
        YMaps.jQuery(function () {
            // Создание экземпляра карты и его привязка к созданному контейнеру
            var map = new YMaps.Map(YMaps.jQuery("#YMapsID")[0]);

            map.setCenter(new YMaps.GeoPoint(60.597259, 56.838056), 12);
            map.addControl(new YMaps.Zoom());

            // Координаты или адреса географических объектов
            var data = [МАССИВ АДРЕСОВ В ВИДЕ СТРОКИ ЧЕРЕЗ ЗАПЯТУЮ];

            // Создание множественного геокодера
            var geocoder = new MultiplyGeocoder(data);

            // Создание прямоугольной области
            var gBounds = new YMaps.GeoCollectionBounds();

            YMaps.Events.observe(geocoder, "Load", function (geocoder) {

                 map.addOverlay(geocoder);

                 gBounds.add(geocoder.getGeoPoint());
                 map.setBounds(gBounds);

                 alert("Геокодирование завершено");
            });

        });

        // Реализует наследование прототипа без исполнения конструктора родителя
        // Подробнее о наследовании: http://javascript.ru/tutorial/object/inheritance
        function extend (child, parent) {
            var c = function () {};
            c.prototype = parent.prototype;
            c.prototype.constructor = parent;
            return child.prototype = new c;
        };

        // Множественный геокодер
        // requests - массив адресов
        function MultiplyGeocoder (requests) {

            // Вызов родительского конструктора
            YMaps.GeoObjectCollection.call(this);

            var _this = this,

                // Количество вызовов геокодера
                geocodeCallCount = 0,

                // Обработчики событий
                listeners = [];

            // Последовательно геокодируем все переданные адреса
            for (var i = 0, l = requests.length; i < l; i++) {
                geocode(requests[i]);
            }

            // Функция, отвечающая за геокодировании одного адреса
            function geocode (request) {
                // Геокодируем
                var geocoder = new YMaps.Geocoder(request);
          
                // Счетчик вызовов геокодирования увеличиваем
                geocodeCallCount++;

                // Сохраняем ссылки на обработчики событий
                listeners = listeners.concat(

                    // Обработка событий Load и Fault
                    YMaps.Events.observe(geocoder, [geocoder.Events.Load, geocoder.Events.Fault], function (geocoder) {
                        if (geocoder.length()) {
                            _this.add(geocoder.get(0));
                        }
                        geocodeCallCount--;
                        isFinish();
                    })
                );
            }

            // Функция для проверки окончания процесса геокодирования
            function isFinish () {
                // Если все объекты сгеокодированы, то генерируем событие завершения
                if (!geocodeCallCount) {

                    // Событие о завершении геокодирования
                    YMaps.Events.notify(_this, "Load", _this);

                    // Удаление обработчиков событий
                    for (var i = 0, l = listeners.length; i < l; i++) {
                        listeners[i].cleanup();
                    }
                }
            }
        }

        var ptp = extend(MultiplyGeocoder, YMaps.GeoObjectCollection);



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

gBounds.add(geocoder.getGeoPoint());
Видимо добавлять надо тут


 if (geocoder.length()) {
    _this.add(geocoder.get(0));
     gBounds.add(geocoder.get(0).getGeoPoint());
 }

А в этом случае перестали рисоваться Оверлеи.
дайте ссылку на страницу
gBounds не доступна в функции геокодирования
Нужно вынести ее объявление выше
 

          var gBounds;
          YMaps.jQuery(function () {
           ...

           // Создание прямоугольной области
           gBounds = new YMaps.GeoCollectionBounds();


Получилось, спасибо!
Далее, буду пробовать рисовать прямые линий между двумя точками.

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

В предыдущем ответе, смайлы автоматом заменили символы ) ; (без пробела)

Неработает gBounds потому что в объекте с которого он склонирован YMaps.GeoCollectionBounds() есть какой-то объект "k" который не объявлен.

 

function (s) {
    var t = new (k.GeoPoint)(0, 0);
    k.GeoBounds.call(this, t, t);
    this._empty = 1;
    this._lngs = [];
    if (s) {
        this.add(s);
    }
}

соответвенно t не создается потому как k.GeoPoint не существует, так как не существует объекта k

 в YMaps.GeoCollectionBounds()

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