Клуб API Карт

Поиск по карте и перемещение найденной точки

Пост в архиве.
e1widget
14 марта 2011, 14:46

 Не могу победить небольшую проблемку:

Изначально, известен адрес и координаты точки. Рисуется точка на карте (по известным координатам), с возможностью перетаскивания по карте. После каждого перетаскивания, определяются новые координаты точки и записываются в поле geocoords1. Т.е. в этом случае все работает.

Если воспользоваться поиском (поле geopoint1), то результат поиска отобразится на карте, найденная точка будет доступна для перетаскивания, но не будут определяться новые координаты точки после перетаскивания.

На кнопку "Искать" навешан вызов функции showAddress(value), которая определяет координаты точки и рисует ее на карте.

Действия при завершении перемещения точки:

        YMaps.Events.observe(geoResult, geoResult.Events.DragEnd, function (obj) {
             ...
        }

описаны в блоке обработчика для события window.onLoad.

Исходник:
geopoint1: <input type="text" id="geopoint1" name="geopoint1" value="Екатеринбург, ул. Антона Валека, 13" style="width:235px;" />
<input type="button" value="Искать" onclick="javascript:showAddress(document.getElementById('geopoint1').value);return false;" />
<br />geocoords1: <input type="text" id="geocoords1" name="geocoords1" value="60.592695,56.838844" style="width:235px;" disabled="disabled" />

<script src="http://api-maps.yandex.ru/1.1/index.xml?key=YANDEX_API_KEY" type="text/javascript"></script>
<script type="text/javascript">
    var map, geoResult, s;
    var new_coords;
    
    // Создание обработчика для события window.onLoad
    YMaps.jQuery(function () {

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

        // установка центра карты и элементов управления
        map.setCenter(new YMaps.GeoPoint(60.592695,56.838844), 12);
        map.addControl(new YMaps.SmallZoom(), new YMaps.ControlPosition(YMaps.ControlPosition.TOP_LEFT, new YMaps.Point(5,5))

        // Создание стиля для значка метки
        s = new YMaps.Style(
        s.iconStyle = new YMaps.IconStyle(
        s.iconStyle.href = "images/house_icon.png";
        s.iconStyle.offset = new YMaps.Point(-10, -15);
        s.iconStyle.size = new YMaps.Point(30, 20);
        
        // определение точек
        var geopoint  = new YMaps.GeoPoint(60.592695,56.838844);
        geoResult = new YMaps.Placemark(geopoint, {draggable: true, style: s}

        // добавление описания к точкам
        geoResult.description = 'Екатеринбург, ул. Антона Валека, 13';

        // добавление точек на карту
        map.addOverlay(geoResult);

        // действия при завершении перемещения точки
            YMaps.Events.observe(geoResult, geoResult.Events.DragEnd, function (obj) {

            new_coords = obj.getGeoPoint().copy(

            // Задаем контент для балуна
            geoResult.description = new_coords;

            obj.update(
            
            // новые координаты записываем в соответствующее поле формы
            document.getElementById("geocoords1").value = new_coords;
        }

    }

    // Функция для отображения результата геокодирования
    // Параметр value - адрес объекта для поиска
    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);
                geoResult.setOptions({draggable: true, style: s}
                map.addOverlay(geoResult);
                map.setBounds(geoResult.getBounds()
            } else {
                alert("Ничего не найдено");
            }
        }
        
        // Процесс геокодирования завершен неудачно
        YMaps.Events.observe(geocoder, geocoder.Events.Fault, function (geocoder, error) {
            alert("Произошла ошибка: " + error);
        })

    }
</script>
<div id="YMapsID" style="width:300px;height:200px"></div>

 

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

Вы создали метку geoResult и навесили обработчик на Drag. Когда вы производите поиск, то вы заменяете значение в переменной geoResult на новое (найденное), а обработчик у вас рассчитан для старой метки.

Решить можно двумя способами:

1. После поиска для результата поиска создавать обработчик.

2. Не заменять метку, а смещать имеющуюся.

Я рекомендую выбрать второй вариант. Для этого нужно будет немножко переписать функцию showAddress:

...

YMaps.Events.observe(geocoder, geocoder.Events.Load, function () {
    if (this.length()) {
        var searchResult = this.get(0);  
        geoResult.setGeoPoint(searchResult.getGeoPoint());

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

...

На самом деле, я уже нашел решение указанной мной проблемы. И он совпал с вашим первым способом.

Но второй вариант, действительно красивее. Буду использовать его. Спасибо!

Решив этот вопрос, у меня появился еще один:

могу ли я в блоке обработчика:

        YMaps.Events.observe(geoResult, geoResult.Events.DragEnd, function (obj) {

            new_coords = obj.getGeoPoint().copy();

            // Задаем контент для балуна
            geoResult.description = new_coords;

            obj.update();
            
            // новые координаты записываем в соответствующее поле формы
            document.getElementById("geocoords1").value = new_coords;
        });

выдернуть еще и адрес точки (город, улица, дом)?

Я пробовал добавить в этот блок следующие строки:

                var city   = obj.AddressDetails.Country.AdministrativeArea.Locality.LocalityName;
                var street = obj.AddressDetails.Country.AdministrativeArea.Locality.Thoroughfare.ThoroughfareName;
                var build  = obj.AddressDetails.Country.AdministrativeArea.Locality.Thoroughfare.Premise.PremiseNumber;

, но это не работает.

Или же придется юзать обратное геокодирование по известным координатам точки?

obj.text - адрес одной строкой

obj.text возвращает 'undefined'

Фрагмент кода:

 

...
var map, s, geoResult, newCoords;
...
        // определение точек
        geoResult = new YMaps.Placemark(new YMaps.GeoPoint(60.585829,56.838091), {draggable: true, style: s, hasBalloon: false});
        // добавление точек на карту
        map.addOverlay(geoResult);

        // действия при завершении перемещения точки
        YMaps.Events.observe(geoResult, geoResult.Events.DragEnd, function (obj) {
            newCoords = obj.getGeoPoint().copy();
            obj.update();
            alert(obj.text);
        });

Это поле доступно только у результатов геокодирования.

Вам нужно прокидывать text из обработчика Load геокодера в объект, например, так:

geoResult.text = obj.text;

Неболшой вопрос - что за объект такой "obj", который мы передаем в функцию  function (obj)? Это и есть объект который возвращает геокодер?

YMaps.Events.observe(geoResult, geoResult.Events.DragEnd, function (obj) {

это метка (у геокодера нет события DragEnd)

и obj, конечно, плохое имя для параметра

 

 

напишите, пожалуйста, подробнее как получить адрес строкой

чтобы вместо new_coords в балун и в поле формы записывать адрес