API Яндекс карт

Qwest-fx

Профессор
Регистрация
3 Апр 2007
Сообщения
134
Реакции
41
Приветствую, появилась задача, вывести несколько меток на карте Яндекса, но проблема в том что нет координат, их нужно получать с помощью
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 должен быть массив, но в результате
Uncaught ReferenceError: firstGeoObject is not defined

Если кто-то найдет рабочий пример с поиском и наложением координат на карту, буду очень благодарен. Документацию смотрел, результата нет.
 
В вашем примере ошибка очевидна:
Код:
// Команда 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);
            });
 
В вашем примере ошибка очевидна:
Мне как раз нужно исправить эту ошибку. Вот решение.

Код:
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();
Метод асинхронный.
 
Мне как раз нужно исправить эту ошибку. Вот решение.

Код:
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();
Метод асинхронный.
Тогда советую сделать так (если можно покажу на старом примере) :
Код:
// Например, в массиве хранятся входящие данные
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();
        });
    })();
}

Код не проверял, могут быть ляпы
 
К сожалению, пройденный этап,
  1. Uncaught ReferenceError: result is not defined
    123.html:28
    1. getNext
      123.html:28
    2. (anonymous function)
      123.html:45
    3. i._Vf
      combine.xml:1
    4. i.resolve
      combine.xml:1
    5. (anonymous function)
      combine.xml:1
    6. i._Vf
      combine.xml:1
    7. i.resolve
      combine.xml:1
    8. e.padding.window.(anonymous function)
      combine.xml:1
    9. (anonymous function)
      geocode-maps.yandex.ru:1
Даже если results = [];
т.е. без Var, еще раз напишу
Метод асинхронный.
Есть так называемая песочница, я там нашёл Для просмотра ссылки Войди или Зарегистрируйся, но сейчас нужно изменить метку.
Метка ставится примерно так
HTML:
myPlacemark1 = new ymaps.Placemark([55.8, 37.6], {
            // Свойства.
            // Содержимое иконки, балуна и хинта.
            iconContent: '1',
            balloonContent: 'Балун',
            hintContent: 'Стандартный значок метки'
        }, {
            // Опции.
            // Стандартная фиолетовая иконка.
            preset: 'twirl#violetIcon'
        }),
 
К сожалению, пройденный этап,
Даже если results = [];
т.е. без Var, еще раз напишу

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

В целом, согласен, пользоваться api Яндекса намного приятнее. Я мало работаю с web-интерфейсами, особенно с картами. Но сам алгоритм, предложенный выше, успешно работает на серверах под нагрузкой на многих моих проектах, и, кстати, вполне даже без утечек. Скорее всего, ошибка связанна вы что-то перепутали с областью видимости названиями в переменных. Или, возможен такой вариант: в коде у меня переменная называлась results, а на ошибке в спойлере - result)
 
Добрый день! Пожалуйста, помогите реализовать следующее:
необходимо на определенных страницах моего сайта выводить карты с метками объектов из поисковой выдачи yandex (отели, бары, рестораны).
То есть, что было как Для просмотра ссылки Войди или Зарегистрируйся. Как это прописать?
 
Назад
Сверху