API Яндекс карт

Тема в разделе "JavaScript", создана пользователем Qwest-fx, 3 дек 2012.

Модераторы: ZiX
  1. Qwest-fx

    Qwest-fx Постоялец

    Регистр.:
    3 апр 2007
    Сообщения:
    129
    Симпатии:
    39
    Приветствую, появилась задача, вывести несколько меток на карте Яндекса, но проблема в том что нет координат, их нужно получать с помощью
    HTML:
                ymaps.geocode('Москва').then(function (res) {
                    // первый геообъект в коллекции результатов
                    firstGeoObject = res.geoObjects.get(0).geometry.getCoordinates();
                });
    console.log(firstGeoObject); // Uncaught ReferenceError: firstGeoObject is not defined
    
    Под спойлером, пример, чтобы ничего не искать.


    HTML:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Быстрый старт. Размещение интерактивной карты на странице</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <script src="http://api-maps.yandex.ru/2.0-stable/?load=package.standard&lang=ru-RU"
                type="text/javascript"></script>
        <script src="http://yandex.st/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            ymaps.ready(init);
            var myMap,
                    myPlacemark;
     
            function init() {
    //            myMap = new ymaps.Map ("map", {
    //                center: [55.76, 37.64],
    //                zoom: 7
    //            });
    //
    //            myPlacemark = new ymaps.Placemark([55.76, 37.64], {
    //                content: 'Москва!',
    //                balloonContent: 'Столица России'
    //            });
    //
    //            myMap.geoObjects.add(myPlacemark);
     
     
                ymaps.geocode('Москва').then(function (res) {
                    // первый геообъект в коллекции результатов
                    var firstGeoObject = res.geoObjects.get(0).geometry.getCoordinates();
                  //  console.log(firstGeoObject);
    //                    // все данные геообъекта
    //                    console.log(firstGeoObject.properties.getAll());
    //                    // Область видимости геообъекта
    //                    console.log(firstGeoObject.properties.get('boundedBy'));
    //                    // Данные об адресе геообъекта
    //                    console.log(firstGeoObject.properties.get('metaDataProperty.GeocoderMetaData.AddressDetails'));
    //                    // Точность поиска
    //                    console.log('precision', firstGeoObject.properties.get('metaDataProperty.GeocoderMetaData.precision'));
    //                    // Поля геообъекта
    //                    console.log(firstGeoObject.properties.get('text'));
    //                    console.log(firstGeoObject.properties.get('name'));
    //                    console.log(firstGeoObject.properties.get('description'));
     
                });
                console.log(firstGeoObject);
            }
            console.log(firstGeoObject);
        </script>
     
    </head>
     
    <body>
    <div id="map" style="width: 600px; height: 400px"></div>
    </body>
     
    </html>





    Точек несколько, соответственно, нужно нужно несколько раз запрашивать координаты, предварительно сохранив результаты например в массив.
    Проблема в том, что если запустить по циклу код описанный выше, то результаты не видны их родительского класса. Т.е. по идеи в firstGeoObject должен быть массив, но в результате
    Если кто-то найдет рабочий пример с поиском и наложением координат на карту, буду очень благодарен. Документацию смотрел, результата нет.
     
  2. recasher2k12

    recasher2k12

    Регистр.:
    19 фев 2012
    Сообщения:
    156
    Симпатии:
    78
    В вашем примере ошибка очевидна:
    Код:
    // Команда ymaps.geocode('Москва') выполнится первой [1]
    ymaps.geocode('Москва').then(function (res) {
                    // команда выполнится после загрузки координат,
                    // т.е. спустя какое-то время, которое необходимо для загрузки, т.е.
                    // т.е. третей [3]
                    firstGeoObject = res.geoObjects.get(0).geometry.getCoordinates();
                });
    // Команда обращения к firstGeoObject выполнится второй [2], моментально сразу после [1]
    // т.е. не ждет пока координаты загрузятся, соответственоо переменная firstGeoObject не определена
    console.log(firstGeoObject);
    Правильнее будет так:
    Код:
    // [1]
    ymaps.geocode('Москва').then(function (res) {
                    // т.е. [2]
                    firstGeoObject = res.geoObjects.get(0).geometry.getCoordinates();
                    // т.е. [3]
                    console.log(firstGeoObject);
                });
     
  3. Qwest-fx

    Qwest-fx Постоялец

    Регистр.:
    3 апр 2007
    Сообщения:
    129
    Симпатии:
    39
    Мне как раз нужно исправить эту ошибку. Вот решение.

    Код:
    function init() {
        var myMap = new ymaps.Map('map', {
                center: [55.734046, 37.588628],
                zoom: 9,
                behaviors: ['default', 'scrollZoom']
            }),
            myMultiGeocoder = new MultiGeocoder({ boundedBy: myMap.getBounds() });
     
        // Геокодирование массива адресов и координат.
        myMultiGeocoder.geocode([
            'Москва, Слесарный переулок, д.3',
            'Люберцы, Октябрьский проспект д.143',
            [55.734046, 37.588628],
            'Мытищи, ул. Олимпийский проспект, владение 13, корпус А',
            'Москва, 3-я Хорошовская улица д.2, стр.1',
            'Москва, Нижний Сусальный переулок, д.5, стр.4'
        ])
        .then(
            function (res) {
                myMap.geoObjects.add(res.geoObjects);
            },
            function (err) {
                alert(err);
            }
        );
    }
     
    /**
    * Класс для геокодирования списка адресов или координат.
    * @see https://github.com/dimik/ymaps/blob/master/multi-geocoder.js
    * @class
    * @name MultiGeocoder
    * @param {Object} [options={}] Дефолтные опции мультигеокодера.
    */
    function MultiGeocoder(options) {
        this._options = options || {};
    }
     
    /**
    * Функция множественнеого геокодирования.
    * @function
    * @requires ymaps.util.extend
    * @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/util.extend.xml
    * @requires ymaps.util.Promise
    * @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/util.Promise.xml
    * @name MultiGeocoder.geocode
    * @param {Array} requests Массив строк-имен топонимов и/или геометрий точек (обратное геокодирование)
    * @returns {Object} Как и в обычном геокодере, вернем объект-обещание.
    */
    MultiGeocoder.prototype.geocode = function (requests, options) {
        var self = this,
            opts = ymaps.util.extend({}, self._options, options),
            size = requests.length,
            promise = new ymaps.util.Promise(),
            result = [],
            geoObjects = new ymaps.GeoObjectArray();
     
        requests.forEach(function (request, index) {
            ymaps.geocode(request, opts).then(
                function (response) {
                    var geoObject = response.geoObjects.get(0);
     
                    geoObject && (result[index] = geoObject);
                    --size || (result.forEach(geoObjects.add, geoObjects), promise.resolve({ geoObjects: geoObjects }));
                },
                function (err) {
                    promise.reject(err);
                }
            );
        });
     
        return promise;
    };
     
    ymaps.ready(init);
    А не просто, перенести в метод console.log();
    Метод асинхронный.
     
  4. recasher2k12

    recasher2k12

    Регистр.:
    19 фев 2012
    Сообщения:
    156
    Симпатии:
    78
    Тогда советую сделать так (если можно покажу на старом примере) :
    Код:
    // Например, в массиве хранятся входящие данные
    var allMyGeoPlaces = ['Москва', 'Казань'];
     
    // Вызов функции
    getAll(allMyGeoPlaces, function(res) {
                              console.log('Все координаты получены:', res);
                              // Все действия, которые требуются выполнить после
                              // получения координат следует вызывать здесь
                          });
     
    // А вот и сам код функции
    // @param {string[]} places
    // @param {function} callback функция возврата значения
    //                    @param {object[]} result массив результатов
    function getAll(places, callback) {
        // Массив с результатами
        var results = [];
       
        // Внутренняя функция получить следующую координату
        (function getNext(){       
            // Если массив уже пустой, то наша работа выполнена,
            // и мы вызываем функцию возврата callback()
            if(places.length == 0){
                callback(result);
                return;
            }
           
            // Выдергиваем последний элемент из массива
            // Вытаскивать элементы массива с конца работает быстрее,
            // чем вытаскивать элементы сначала массива
            // Если вытаскивать надо сначала массива, замени метод pop() на shift()
            var place = places.pop();
           
            // Получаем координаты
            ymaps.geocode(place).then(function (res) {
                var geoObject = res.geoObjects.get(0).geometry.getCoordinates();
                console.log('Координата получена', geoObject);
                // Сохраняем результаты в массив result
                results.push(geoObject);
                // Рекурсивно вызываем функцию
                getNext();
            });
        })();
    }
    Код не проверял, могут быть ляпы
     
  5. Qwest-fx

    Qwest-fx Постоялец

    Регистр.:
    3 апр 2007
    Сообщения:
    129
    Симпатии:
    39
    К сожалению, пройденный этап,

    Даже если results = [];
    т.е. без Var, еще раз напишу
    Есть так называемая песочница, я там нашёл что мне требовалось, но сейчас нужно изменить метку.
    Метка ставится примерно так
    HTML:
    myPlacemark1 = new ymaps.Placemark([55.8, 37.6], {
                // Свойства.
                // Содержимое иконки, балуна и хинта.
                iconContent: '1',
                balloonContent: 'Балун',
                hintContent: 'Стандартный значок метки'
            }, {
                // Опции.
                // Стандартная фиолетовая иконка.
                preset: 'twirl#violetIcon'
            }),
     
    recasher2k12 нравится это.
  6. recasher2k12

    recasher2k12

    Регистр.:
    19 фев 2012
    Сообщения:
    156
    Симпатии:
    78
    В целом, согласен, пользоваться api Яндекса намного приятнее. Я мало работаю с web-интерфейсами, особенно с картами. Но сам алгоритм, предложенный выше, успешно работает на серверах под нагрузкой на многих моих проектах, и, кстати, вполне даже без утечек. Скорее всего, ошибка связанна вы что-то перепутали с областью видимости названиями в переменных. Или, возможен такой вариант: в коде у меня переменная называлась results, а на ошибке в спойлере - result)
     
  7. Grisha

    Grisha ♙ ▁ ▂ ▃ ▅ ▆ █ ♚

    Регистр.:
    30 сен 2012
    Сообщения:
    168
    Симпатии:
    212
    Добрый день! Пожалуйста, помогите реализовать следующее:
    необходимо на определенных страницах моего сайта выводить карты с метками объектов из поисковой выдачи yandex (отели, бары, рестораны).
    То есть, что было как ТУТ. Как это прописать?