Клуб API Карт

Управление множественными Placemarkers и GeoObjects

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

Существует форма с множеством input, где при вводе текста появляется подсказка (SuggestViews) для каждого поля, после выбора которой проставляется маркер по координатам результата геокодирования. Инпуты добавляются кнопкой при помощи JQuery

Вопрос в том, что пользователь может в уже "обработанном" инпуте заново начать "уточнять" адрес и именно для этого инпута (ID=3) должны измениться координаты метки, а также он может удалить любой из инпутов с изменением меток.

Как отследить существование метки?

ymaps.ready(init);
var markers=[];
var myMap;
var ch = 1;
var point = [];
var placemark;

function init () {
    myMap = new ymaps.Map('map_canvas', {
        center: [51.1480773, 71.4562873],
        zoom: 12,
        behaviors: ['scrollZoom', 'drag'],
        controls: ['zoomControl', 'typeSelector', 'rulerControl']

    });
}

function onLoad (ymaps) {
    var inputs = document.getElementsByClassName("controlsInput");
    var suggestView = [];
    var coords = [];
    // Создаем коллекцию геообъектов и задаем опции.
    var myGeoObjects = new ymaps.GeoObjectCollection({}, {
        preset: "twirl#blueStretchyIcon",
        strokeWidth: 4,
        geodesic: true,
        zoom:12
    });

    for (var i = 1, count = 0; i < inputs.length+1; i++, count++) {
        suggestView[i] = new ymaps.SuggestView('pac-input'+i, {
            boundedBy: [
                [40.817717596787695, 45.810683499999996],
                [54.95398155782081, 87.99818349999998]
            ]
        });
/** Выбор адреса */
        suggestView[i].events.add('select', function(e){
            var pos = (e.get('item').value);
            var myGeocoder = ymaps.geocode(pos, { results: 1 })
                .then(function(res) {
                    coords = (res.geoObjects.get(0).geometry.getCoordinates())

                    placemark = new ymaps.Placemark(coords, {iconContent: count, id: count});
                    myGeoObjects.add(placemark);

                    markers.push(coords);

                    function calcRoute() {
                        for(var j = 0, m = markers.length; j < m; j++) {
                            point[j] = markers[j];
                        }
                        ymaps.route(point, {
                            // Опции маршрутизатора
                            mapStateAutoApply: true // автоматически позиционировать карту
                        }).then(function (router) {
                            route = router;
                            myMap.geoObjects.add(route);
                        });

                        ch++;
                    }
                    calcRoute();
                    // Добавляем коллекцию на карту.
                    myMap.geoObjects.add(myGeoObjects);
                    myMap.setBounds(myGeoObjects.getBounds(), {checkZoomRange:true}).then(function(){ if(myMap.getZoom() > 12) myMap.setZoom(12);});
            });

        });
/** Выбор адреса / Конец */

    }
}
1 комментарий
Вообще есть такая штука как ООП. Вместо этой нечитаемой многовложенной колбасы с циклами и обработчиками событий, вы можете написать базовый класс-конроллер для каждого инпута, в нем хранить ссылку на DOM-элемент, найденный геообъект, маршрут и пр.
На вход конструктора можно передавать DOM-ноду и карту. 


function GeoInput(input, map) {
  this._elem = input;
  this._map = map;
  this._createSuggest();
  this._setupListeners();
}


var ptp = GeoInput.prototype;


ptp._createSuggest = function () {

this._suggestView = new ymaps.SuggestView(this._elem, ...);
};


ptp._setupListeners = function () {
this._suggestView.events.add('select', this._handleSuggestItemSelect, this);
};


ptp._handleSuggestItemSelect = function (e) {

...
this._geocode(...)
};


// В класс можно добавить метод, геокодирующий полученный из Suggest результат
// и в обработчике then сохранять точку в поле инстанции, типа того


ptp._geocode = function (pos) {
return ymaps.geocode(pos, { results: 1 })
.then(function(res) {
  this._geoObject = res.geoObjects.get(0);
}, this);
};