Клуб API Карт

Поиск как на яндексе

alexandr2006
23 сентября 2009, 08:57

А как создать такой же цивильный поиск как на яндекс.карты? Т.е ввожу я улицу "Кожуховская", мне не тыкают тупо как вот тут http://api.yandex.ru/maps/jsapi/examples/geocoding.html, не вываливают какой-то левый список, если реализовывать через YMaps.SearchControl, а слева появляется окошечко с найденными результатами, где можно выбрать № дома.


PS. ув. разработчики! Прочтите книгу про юзабилити! То, что кнопку "Открыть тему" пришлось искать это ладно, но ваше руководство разработчика - ужас. Больше примеров!

22 комментария
Подписаться на комментарии к посту
Геокодер представляет из себя группу найденных результатов, по которым Вы можете сформировать список.

Более подробную информацию о работе геоокодеа Вы можете найти, если обратитесь к справочнику по программному интерфейсу и руководству разработчика.

Все вопросы и пожелания касательно сервиса ya.ru лучше писать в офицальный клуб сервиса ya.ru.

Чего не хватает на Ваш взгляд в Руководстве разработчика? Какие примеры необходимо добавить, быть может о чем-то более подробно рассказать?
ну вот он и выведет мне список улиц, а про дома ни звука. Примеры должны быть ко всему. Напр: YMaps.Zoom(options) ниже даны списки опций, но!!! где пример как их вставлять? Надо рыскать! Опять же, на странице много ссылок (напр.: # kind – вид топонима (улица, дом, город и т.д.); # precision – предполагаемая точность ответа; # text ) Благодаря этим ссылкам становится открыто множество страниц, в которых скоро начинаешь путаться.
Список домов получить через API нельзя.

Пример по использованию опций как раз есть:
http://api.yandex.ru/maps/jsapi/doc/ref/reference/zoom.xml#constructor

Мы примем Ваши замечания по руководству разработчика. Спасибо.
аах как жалко. А вот еще проблема, над которой сейчас бьюсь:
Есть пример 1:http://api.yandex.ru/maps/jsapi/examples/markerscustom.html. Тут маркеры ставятся случайным образом. А мне нужно их расставить на основе списка адресов. А для этого надо преобразовать адрес в координаты. В принципе как это сделать показано здесь http://api.yandex.ru/maps/jsapi/examples/geocoding.html.Но вот бьюсь уже 3 часа и никак не могу их скрестить. Ведь как было бы просто задаем в некую ф-ю lalala('Москва, улица Ленина, д.27'), а на выходе получаем массив с вартами координат ("23,45","35,36") Самый первый -самый релевантный, и его и подставляем в YMaps.GeoPoint. Нет, вы сделали настолько все хитро, что мои мозги уже закипают(((
Класс YMaps.Geocoder представляет подобный функционал:
var geocoder = new YMaps.Geocoder("Москва, улица Ленина, д.27", {result: 1});

После геокодирования переменная geocoder будет содержать самый первый релевантный  результат поиска. Обратиться к нему можно будет так:
// Получим первый результат поиска
var geoResult = geocoder.get(0);
// Выведем координаты
alert(geoResult.getGeoPoint());

Однако, учтите, что геокодирование - это асинхронный процесс, обращаться к элементам можно будет только после того как сработает событие Load.
ну вот, я наваял:
 var map, geoResult;
        var myArray=new Array("Россия, Москва, улица Спиридоновка, 27/23","Москва, ул.Самокатная, д.1., стр.21","Москва, ул. Станиславского, д.21, стр.3","Измайловский пр-т, д.73/2","Сергиев Посад, пр-т Красной армии");
        var Comment=new Array("Пункт 1","Главный штаб","Пункт 2","Пункт 3","Пункт 4");


 window.onload = function () {
            map = new YMaps.Map(document.getElementById("YMapsID"));
            map.setCenter(new YMaps.GeoPoint(37.64, 55.76), 10);
            map.addControl(new YMaps.Zoom());


            //Новые метки
var s = new YMaps.Style();
            s.iconStyle = new YMaps.IconStyle("example#customPointIcon");
            s.iconStyle.offset = new YMaps.Point(-22, -46);
            s.iconStyle.href = "dot.png";
            s.iconStyle.size = new YMaps.Point(26, 46);
            s.iconStyle.shadow = new YMaps.IconShadowStyle();
            s.iconStyle.shadow.offset = new YMaps.Point(-20, -42);
            s.iconStyle.shadow.href = "dot_shadow.png";
            s.iconStyle.shadow.size = new YMaps.Point(100, 45);
            YMaps.Styles.add("example#customPoint", s);
        
            var t = new YMaps.Template(">$[name|0]");
            YMaps.Templates.add("example#customPointIcon", t);

            var bounds = map.getBounds(),
                pointLb = bounds.getLeftBottom(),
                span = bounds.getSpan();
           
            for (var i = 0; i < 4; i++) {
               // var point = new YMaps.GeoPoint(pointLb.getLng() + span.x * Math.random(),  pointLb.getLat() + span.y * Math.random());

               var geocoder = new YMaps.Geocoder(myArray[i], {result: 1});
               var geoResult = geocoder.get(0);
                    // Выведем координаты
                    //alert(geoResult.getGeoPoint());
                    var point = new YMaps.GeoPoint(geoResult.getGeoPoint());

                var placemark = new YMaps.Placemark(point, {style: "example#customPoint"});
                placemark.name = Comment[i];
                map.addOverlay(placemark); 
            }
//конец меток

а в результате - шиш((
http://clubs.ya.ru/mapsapi/replies.xml?parent_id=5710&item_no=5688&with_parent=1#reply-mapsapi-5710
Однако, учтите, что геокодирование - это асинхронный процесс, обращаться к элементам можно будет только после того как сработает событие Load.
Ладненько. переписали код:
 var map, geoResult;
        var myArray=new Array("Россия, Москва, улица Спиридоновка, 27/23","Москва, ул.Самокатная, д.1., стр.21","Москва, ул. Живописная, д.52","Измайловский пр-т, д.73/2","Сергиев Посад, пр-т Красной армии");
        var Comment=new Array("Пункт 1","Главный штаб","Пункт 2","Пункт 3","Пункт 4");

        window.onload = function () {
            map = new YMaps.Map(document.getElementById("YMapsID"));
            map.setCenter(new YMaps.GeoPoint(37.64, 55.76), 10);
            map.addControl(new YMaps.Zoom());


            //Новые метки
var s = new YMaps.Style();
            s.iconStyle = new YMaps.IconStyle("example#customPointIcon");
            s.iconStyle.offset = new YMaps.Point(-22, -46);
            s.iconStyle.href = "dot.png";
            s.iconStyle.size = new YMaps.Point(26, 46);
            s.iconStyle.shadow = new YMaps.IconShadowStyle();
            s.iconStyle.shadow.offset = new YMaps.Point(-20, -42);
            s.iconStyle.shadow.href = "dot_shadow.png";
            s.iconStyle.shadow.size = new YMaps.Point(100, 45);
            YMaps.Styles.add("example#customPoint", s);
        
            var t = new YMaps.Template(">$[name|0]");
            YMaps.Templates.add("example#customPointIcon", t);

            var bounds = map.getBounds(),
                pointLb = bounds.getLeftBottom(),
                span = bounds.getSpan();
           
         
  for (var i = 0; i < 5; i++) {

                                            var geocoder = new YMaps.Geocoder(myArray[i], {result: 1})
                                            map.addOverlay(geocoder);
                                                       

                                                        YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
                                                if (this.length()) {

                                                // Получим первый результат поиска
                                            var geoResult = geocoder.get(0);
                                            // Выведем координаты
                                            alert(geoResult.getGeoPoint());
                                                     var point = new YMaps.GeoPoint(geoResult.getGeoPoint());
                var placemark = new YMaps.Placemark(point, {style: "example#customPoint"});
                placemark.name = Comment[i];
                map.addOverlay(placemark);
                                                }else {
                                                    alert("Ничего не найдено")
                                                }
                                            });
                                             
                                            YMaps.Events.observe(geocoder, geocoder.Events.Fault, function (error) {
                                                alert("Произошла ошибка: " + error.message)
                                            });

                }
//конец меток
        }
function showAddress (value) {
                    map.removeOverlay(geoResult);
            var geocoder = new YMaps.Geocoder(value, {results: 1, boundedBy: map.getBounds()});

            YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
                if (this.length()) {
                    geoResult = this.get(0);
                    map.addOverlay(geoResult);

                    map.setBounds(geoResult.getBounds());
                }else {
                    alert("Ничего не найдено")
                }
            });
        }



   

Вроде работает,
1)но метки не пользовательские почему-то, а стандартные
2) как-то странно ищет - написал же "Москва, ул. Живописная, д.52", так она мне "Россия, Московская область, Воскресенский район, Воскресенск, улица Живописная" и "Россия, Москва, улица Живописная, 52" выдала, хотя стоит {result: 1})???
Ваше решение можно упростить и все станет более понятно.
Приведу фрагмент кода, описывающего последовательное геокодирование Ваших объектов.
for (var i = 0; i < 5; i++) {
    (function (searchStr, comment) {
        var geocoder = new YMaps.Geocoder(searchStr, {result: 1})

        YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
            if (this.length()) {
                var geoResult = geocoder.get(0);
                geoResult.setStyle("default#redPoint");
                geoResult.setBalloonContent(comment);
                map.addOverlay(geoResult);
            }else {
                alert("Ничего не найдено")
            }
        });

        YMaps.Events.observe(geocoder, geocoder.Events.Fault, function (error) {
            alert("Произошла ошибка: " + error.message)
        });
    })(myArray[i], Comment[i]);
}

Успехов Вам в изучении JavaScript и API Яндекс.Карт!
))спасибо
Где-то в описании видел как (и чем) измереть расстояние между пунктами А и Б и вот посеял(((
Вы имеете ввиду метод distance()?
distance(point) - Возвращает кратчайшее расстояние между двумя точками земной поверхности (в метрах).
point - Точка, расстояние до которой требуется измерить

А как она узнает координаты начальной точки разработчики написать неудосужились))))
По логике - надо передавать 2 координаты. Добавил строчки кода, но расстояние почему-то андефайнид


var map, geoResult;
var myArray=new Array("Россия, Москва, улица Спиридоновка, 27/23","Москва, ул.Самокатная, д.1., стр.21","Москва, ул. Живописная, д.52","Измайловский пр-т, д.73/2","Сергиев Посад, пр-т Красной армии");
var Comment=new Array("Пункт 1","Главный штаб","Пункт 2","Пункт 3","Пункт 4");
var Coord_myArray=new Array();

window.onload = function () {
map = new YMaps.Map(document.getElementById("YMapsID"));
map.setCenter(new YMaps.GeoPoint(37.64, 55.76), 10);
map.addControl(new YMaps.Zoom());


//Новые метки
var s = new YMaps.Style();
s.iconStyle = new YMaps.IconStyle("example#customPointIcon");
s.iconStyle.offset = new YMaps.Point(-22, -46);
s.iconStyle.href = "dot.png";
s.iconStyle.size = new YMaps.Point(26, 46);
s.iconStyle.shadow = new YMaps.IconShadowStyle();
s.iconStyle.shadow.offset = new YMaps.Point(-20, -42);
s.iconStyle.shadow.href = "dot_shadow.png";
s.iconStyle.shadow.size = new YMaps.Point(100, 45);
YMaps.Styles.add("example#customPoint", s);

var t = new YMaps.Template(">$[name|0]");
YMaps.Templates.add("example#customPointIcon", t);

var bounds = map.getBounds(),
pointLb = bounds.getLeftBottom(),
span = bounds.getSpan();

for (var i = 0; i < myArray.length; i++) {
(function (i) {
var geocoder = new YMaps.Geocoder(myArray[i], {result: 1})

YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
if (this.length()) {
var geoResult = geocoder.get(0);
Coord_myArray[i]=geoResult.getGeoPoint();
//alert(i+' '+Coord_myArray[i]);
geoResult.setStyle("default#redPoint");
geoResult.setBalloonContent(myArray[i]);
map.addOverlay(geoResult);
}else {
alert("Ничего не найдено")
}
});

YMaps.Events.observe(geocoder, geocoder.Events.Fault, function (error) {
alert("Произошла ошибка: " + error.message)
});
})(i);
}
//конец меток
}


function showAddress (value) {//alert(Coord_myArray[4]);
map.removeOverlay(geoResult);
var geocoder = new YMaps.Geocoder(value, {results: 1, boundedBy: map.getBounds()});

YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
if (this.length()) {
geoResult = this.get(0);
map.addOverlay(geoResult);

map.setBounds(geoResult.getBounds());

var min_dist=-5;
for (var i = 0; i < myArray.length; i++)
{
var dist=distance(Coord_myArray[1], Coord_myArray[0]); alert("dist"+dist);
if(dist}
alert("min_dist"+min_dist);


var router = new YMaps.Router([
Coord_myArray[1],
geoResult.getGeoPoint()], [1], {viewAutoApply: 1});

YMaps.Events.observe(router, router.Events.Success, function() {
router.getWayPoint(0).setIconContent('Точка отправления');
router.getWayPoint(1).setIconContent('Точка прибытия');
map.addOverlay(router);
});




}else {
alert("Ничего не найдено")
}
});






}
Ахаааа. Нашел я этот пример http://api.yandex.ru/maps/jsapi/doc/dg/concepts/router.xml в самом низу. Молодцы, хорошо спрятали!
Переписал тот код:


var min_dist=1e+25;
                                                                   
                            for (var j = 0; j < myArray.length; j++)
                                                                    {
                                                                    var router = new YMaps.Router([Coord_myArray[j], geoResult.getGeoPoint()]);
                                                                    var fullDistance = router.getDistance(); alert(fullDistance);
                                                                    var firstTime = router.getDuration();
                                                                        if(min_dist>fullDistance) {dist=fullDistance; min_poz=i;}


                                                                    }
alert("min_dist"+min_dist);

и все равно расстояние андефайнид!!!!!!! Хелп!
"Прокладывание маршрута — асинхронная операция. Оперировать объектами класса YMaps.Router можно только после того, как было сгенерировано событие Success." (см. Руководство разработчика).

Т. е. код будет выглядеть следующим образом:
var router = new YMaps.Router(['Арбатская', 'Третьяковская']);
map.addOverlay(router);

YMaps.Events.observe(router, router.Events.Success, function (router) {
    alert(router.getDistance());
});

Метод getDistance() возвращает расстояние в метрах, к удобночитаемому виду можно привести с помощью метода humanDistance().

А может Вы расскажете поподробнее задачу, которую решаете? Постараюсь помочь.
Вот такая вот задачка. Имеется ряд объектов (мы из выводим красными метками). Пользователь в строе поиска вводит свой адрес -> мы определяем коорд. этой точки (ф-я showAddress) и рассчитываем расстояния от этого адреса до наших красных меток. Находим минимальное и прокладываем маршрут. Вуаля, вам сюда. В основном все сделано но вот с расстоянием я застрял.
var router = new YMaps.Router(['Арбатская', 'Третьяковская']); - а страница при этом w1251 или в koi-8?
Ес, сработало! Надо было в ф-ю Events.Success, function (  router передать! Тогда почему при прокладке маршрута (http://api.yandex.ru/maps/jsapi/examples/maprouter.html) в ф-ю ничего не передается???
ааа, еще такой вопрос. Вот натыкал я меток. Как теперь сделать чтобы масштаб так поменялся, чтобы их всех было видно?
 
var min_dist=1e+25;
                                                               
                                                                   
                            for (var j = 0; j < myArray.length; j++)
                                                                    {
                                                                    var router = new YMaps.Router([Coord_myArray[j], geoResult.getGeoPoint()]);
                                                                    YMaps.Events.observe(router, router.Events.Success, function(router,j) {
var fullDistance = router.getDistance(); //alert(fullDistance);
var firstTime = router.getDuration();
                            if (min_dist>fullDistance)
                            {min_dist=fullDistance; marker=j;alert("j="+j+" min_dist="+min_dist);
                            }
});
                                                                   
                                                                    }

                alert("marker="+marker+" min_dist="+min_dist);
 почему-то отчего-то j и маркер андефайнид. Тут какая-то изощренная область видимости?
а min_dist хоть и изменяется, но в финале все рано =1e+25((
Дайте ссылку на страницу, пожалуйста.
Так мы быстрее локализуем и исправим проблему.
Советую при программировании придерживаться как-то определенного стиля отступов. Так будет проще ориентироваться в коде.

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

Вот вариант решения Вашей задачи (всяческие проверки были опущены):
http://rodlex.narod.ru/examples/search-optim-route.html
так как все-таки использовать метод distance() для определения кратчайшего расстояния между двумя точками?
point1.distance(point2)