Клуб API Карт

Не работает обработчик ошибки геокодера

Пост в архиве.

Здравствуйте!

Пытаюсь отловить ошибку когда пользователь вводить несуществующий адрес.

 

    var fromAddr = 'Ололололололо';
    var fromError = '', toError = '', fromHas = '', toHas = '';
    
    var fromGeocoder = ymaps.geocode(fromAddr, {boundedBy : myMap.getBounds(), results : 1}).then(function (res)
    {
        console.log(res.metaData.geocoder.found);
      
            var point = res.geoObjects.get(0).geometry.getCoordinates();

            var from = new ymaps.Placemark(
                point, {
                    iconContent: "От",
                    balloonContent: fromAddr
                }, {
                    draggable: true
                }
            );
            myCollection.add(from);
            
            //myMap.setCenter(point, 16);
            
            
            var polygon = new ymaps.geometry.Polygon(ttk);
            polygon.setMap(myMap);
            polygon.options.setParent(myMap.options);
            if (polygon.contains(point))
            {
                fromHas = 'inside'
            }
            else
            {
                fromHas = 'outside'
            }       
    }, function (err) {
        fromError = 'Точка не найдена';
    });

 

У меня здесь 2 проблемы:

1) Точка не найдена, она не рисуется, но в function (err) не заходит.

2) Как отслеживать ошибку и уже потом рисовать route? Мне необходимо узнать есть ли точка или нет, а геокодирование выполняется вообще в самый последний момент. Как видите у меня есть некоторые определения переменных внутри геокодирования, но т.к. это всё выполняется самым последним, то я не знаю как работать с ней.

11 комментариев

надо проверить что res.geoObjects.get(0) == null

значит точка не найдена

Есть такая проверка, но для чего тогда function (err) ?

И как быть со вторым вопросом? Допустим я делаю провеку на null и надо как-то продолжить проверки других точек. Смотреть рисовать route или нет.

не понимаю в чем именно проблема


        ymaps.ready(yandexInit);

        function yandexInit()
        {
            window.myMap = new ymaps.Map('yamap', {
                center: [55.745, 37.6425],
                zoom: 10,
                behaviors: ["default", "scrollZoom"]
            });
}
function setRoute(fromAddr, toAddr)
{
    //Координаты ТТК
    var ttk = [[[55.79120925603273, 37.63474653447042], [55.794304024593224, 37.649166090134486], [55.79024209021341, 37.65671919072044], [55.78095607123407, 37.667705518845416], [55.77611872265281, 37.68315504277121], [55.767409975511654, 37.69173811161887], [55.74669466236358, 37.69723127568136], [55.735073763115395, 37.70135114872823], [55.72286807833515, 37.71302412236105], [55.70329223712887, 37.65500257695089], [55.70639401720582, 37.61964033329855], [55.69999632487194, 37.611743909958705], [55.71705450052017, 37.569515211228236], [55.7327491662182, 37.54170606816184], [55.75114841902614, 37.53037641728294], [55.77263545827282, 37.54307935917746], [55.77476415698664, 37.55303571904074], [55.79120925603273, 37.57329176152121], [55.79198297132429, 37.59492109501731], [55.79314351532218, 37.61517713749776], [55.79120925603273, 37.63474653447042]]];
   
   
    var myCollection = new ymaps.GeoObjectCollection();
   
    var fromError = '', toError = '', fromHas = '', toHas = '';
   
    var fromGeocoder = ymaps.geocode(fromAddr, {boundedBy : myMap.getBounds(), results : 1}).then(function (res)
    {
        alert('from');
        console.log(res.metaData.geocoder.found);
        if (res.geoObjects.get(0) === null)
        {
            fromError = 'Точка не найдена';
        }
        else
        {
            var point = res.geoObjects.get(0).geometry.getCoordinates();

            var from = new ymaps.Placemark(
                point, {
                    iconContent: "От",
                    balloonContent: fromAddr
                }, {
                    draggable: true
                }
            );
            myCollection.add(from);
           
            //myMap.setCenter(point, 16);
           
           
            var polygon = new ymaps.geometry.Polygon(ttk);
            polygon.setMap(myMap);
            polygon.options.setParent(myMap.options);
            if (polygon.contains(point))
            {
                fromHas = 'inside'
            }
            else
            {
                fromHas = 'outside'
            }
        }
       
    }, function (err) {
        fromError = 'Точка не найдена';
    });
   
    var toGeocoder = ymaps.geocode(toAddr, {boundedBy : myMap.getBounds(), results : 1});   
    toGeocoder.then(function (res)
    {
        var point = res.geoObjects.get(0).geometry.getCoordinates();
       
        var to = new ymaps.Placemark(
            point, {
                iconContent: "До",
                balloonContent: toAddr
            }, {
                draggable: true
            }
        );
        myCollection.add(to);
       
        var polygon = new ymaps.geometry.Polygon(ttk);
        polygon.setMap(myMap);
        polygon.options.setParent(myMap.options);
        if (polygon.contains(point))
        {
            toHas = 'inside'
        }
        else
        {
            toHas = 'outside'
        }
    }, function (err) {       
        toError = 'Точка не найдена';
    });
   
    myMap.geoObjects.add(myCollection);
   
    var glError = '';
   
    if (fromError != '')
    {
        var glError = 'Начальная точка не найдена';
    }
    else
    if (toError != '')
    {
        var glError = 'Конечная точка не найдена';
    }
   
    if (glError == '')
    {   
        var price = 0;
        if (toHas == fromHas)
        {
            price = price + 500;
        }
       
        ymaps.route([
            fromAddr,
            toAddr
        ], {}).then(function (route) {
            myMap.geoObjects.add(route);
        }, function (error) {
            $('#result').html(error.message);
        });
    }
    else
    {
        $('#result').html();
    }
    alert('end');
}


Такой код не работает т.к. fromGeocoder и toGeocoder выполняются после выполнения всей функции.
Т..е сначала я вижу алерт end, потом алерт from. А хотелось бы чтобы функция работала так же как написана, по порядку.

 

А хотелось бы чтобы функция работала так же как написана, по порядку.

так бывает только в пэхапэ и т.п.

 

Напишите свой класс, который кинет событие (или вызовет callback, или вернет интерфейс promise) после того как все данные будут получены и слушайте это событие, и при его получении стройте маршрут

 

Мы недавно делились в клубе примером множественного геокодирования на клиенте.

Там используется этот класс, как раз возвращающий promises.

Можно взять его за основу

кстати отличная либа.

очень часто ее использую в основном на nodejs

Алексей Yarrr!
28 января 2016, 03:33

function (err) вызывается при исключительных ситуациях, когда была какая-то ошибка. Ничего не найдено — это штатная ситуация.

Сделал, работает. Скажите, всё ли правильно с точки зрения оптимизации

 

function SetRoute(options) {
    this._options = options || {};
}

SetRoute.prototype.geocode = function (requests, options) {
    //Координаты ТТК
    var ttk = [[[55.79120925603273, 37.63474653447042], [55.794304024593224, 37.649166090134486], [55.79024209021341, 37.65671919072044], [55.78095607123407, 37.667705518845416], [55.77611872265281, 37.68315504277121], [55.767409975511654, 37.69173811161887], [55.74669466236358, 37.69723127568136], [55.735073763115395, 37.70135114872823], [55.72286807833515, 37.71302412236105], [55.70329223712887, 37.65500257695089], [55.70639401720582, 37.61964033329855], [55.69999632487194, 37.611743909958705], [55.71705450052017, 37.569515211228236], [55.7327491662182, 37.54170606816184], [55.75114841902614, 37.53037641728294], [55.77263545827282, 37.54307935917746], [55.77476415698664, 37.55303571904074], [55.79120925603273, 37.57329176152121], [55.79198297132429, 37.59492109501731], [55.79314351532218, 37.61517713749776], [55.79120925603273, 37.63474653447042]]];
    var self = this,
        size = requests.length,
        promise = new ymaps.util.Promise(),
        result = [],
        geoObjects = new ymaps.GeoObjectArray(),
        myCollection = new ymaps.GeoObjectCollection(),
        fromError = '',
        toError = '',
        fromHas = '',
        toHas = '';

    requests.forEach(function (request, index) {
        ymaps.geocode(request, ymaps.util.extend({}, self._options, options))
        .then(
            function (res) {
                var geoObject = res.geoObjects.get(0);
                
                if (index == 0)
                {
                    if (geoObject === null)
                    {
                        fromError = 'Точка не найдена';
                    }
                    else
                    {
                        var point = res.geoObjects.get(0).geometry.getCoordinates();
                        
                        // Добавляем метку
                        myCollection.add(new ymaps.Placemark(point, {iconContent: "От", balloonContent: request}, {draggable: true}));
                        
                        // Проверяем наличие внутри ТТК
                        var polygon = new ymaps.geometry.Polygon(ttk);
                        polygon.setMap(myMap);
                        polygon.options.setParent(myMap.options);
                        if (polygon.contains(point))
                        {
                            fromHas = 'inside'
                        }
                        else
                        {
                            fromHas = 'outside'
                        }
                    }
                }
                else
                if (index == 1)
                {
                    if (geoObject === null)
                    {
                        toError = 'Точка не найдена';
                    }
                    else
                    {
                        var point = res.geoObjects.get(0).geometry.getCoordinates();
                        
                        // Добавляем метку
                        myCollection.add(new ymaps.Placemark(point, {iconContent: "До", balloonContent: request}, {draggable: true}));
                        
                        // Проверяем наличие внутри ТТК
                        var polygon = new ymaps.geometry.Polygon(ttk);
                        polygon.setMap(myMap);
                        polygon.options.setParent(myMap.options);
                        if (polygon.contains(point))
                        {
                            toHas = 'inside'
                        }
                        else
                        {
                            toHas = 'outside'
                        }
                    }
                }
                
                var glError = '';
    
                if (fromError != '')
                {
                    var glError = 'Начальная точка не найдена';
                }
                else
                if (toError != '')
                {
                    var glError = 'Конечная точка не найдена';
                }

                geoObject && (result[index] = geoObject);
                --size || (result.forEach(geoObjects.add, geoObjects), promise.resolve({ geoObjects : geoObjects, myCollection : myCollection, toHas: toHas, fromHas: fromHas, error: glError}));
            },
            function (err) {
                promise.reject(err);
            }
        );        
    });
    return promise;
};

function setRoute(fromAddr, toAddr)
{
    var mGeocoder = new SetRoute({ boundedBy : myMap.getBounds() });
    mGeocoder.geocode([fromAddr,toAddr]).then(
        function (res) {
            if (res.error != '')
            {
                $('#result').html(res.error);
            }
            else
            {
                myMap.geoObjects.add(res.myCollection);
                var price = 0;
                if (res.toHas == res.fromHas)
                {
                    price = price + 500;
                }
                
                ymaps.route([
                    fromAddr,
                    toAddr
                ], {}).then(function (route) {
                    myMap.geoObjects.add(route);
                }, function (error) {
                    console.log(error.message);
                });
            }
        }
    );
}

 

                        // Проверяем наличие внутри ТТК
                        var polygon = new ymaps.geometry.Polygon(ttk);
                        polygon.setMap(myMap);
                        polygon.options.setParent(myMap.options);

это лучше не делать в цикле

а сделать один раз

Спасибо!

 

По коду плейсмарки должны быть с именем "от" и "до". Так получается не всегда. Иногда на них надпись 1 и 2.