Клуб API Карт

Как ограничить перемещение объектов?

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

  К примеру, у меня полигон должен двигаться только в пределах
определенного прямоугольника. Частный случай - разрешить движение только
в одной оси (по вертикали или горизонтали).

Вот так код
"работает", но двигается объект как то нерегулярно - сначала
"оттаскивается" от оси, затем туда "возвращается". Не то что хотелось бы

YMaps.Events.observe(сontrol, сontrol.Events.DragStart, function () {
    position = [this.getPoint(0).getLat(),
this.getPoint(1).getLat(), this.getPoint(2).getLat(),
this.getPoint(3).getLat()]
});
YMaps.Events.observe(сontrol, сontrol.Events.Drag, function () {
    for (var i = 0; i < 4; i++)
        this.getPoint(i).setLat(position[i]);
});

4 комментария
Для решения вашей задачи воспользуйтесь двумя методами многоугольника: contains() и getClosestPoint().

Суть очень простая: слушаете событие Drag у метки, и если она вышла за предел многоугольника (проверка с помощью метода contains()), то ищем ближайшую точку на многоугольне и перемещаем метку туда (в этом помогает метод getClosestPoint()).

Понятнее будет на примере:

// Многоугольник
var polygon = new YMaps.Polygon([
    new YMaps.GeoPoint(37, 57),
    new YMaps.GeoPoint(39, 57),
    new YMaps.GeoPoint(39, 58),
    new YMaps.GeoPoint(37, 58),
    new YMaps.GeoPoint(37, 57)
], {
    // Сделаем заливку полупрозрачной
    style : {
        polygonStyle : {
            fillColor : "FF000088"
        }
    },

    // Сделаем неинтерактивным
    interactive : YMaps.Interactivity.STATIC,

    // Курсор пусть будет такой же, как на карте
    // чтобы не возникало лишнего соблазна кликнуть 
    cursor : YMaps.Cursor.INHERIT
});
map.addOverlay(polygon);

// Метка
var placemark = new YMaps.Placemark(map.getCenter(), { draggable : true });                                                                                                       
map.addOverlay(placemark);

YMaps.Events.observe(placemark, placemark.Events.Drag, function (placemark) {
    var point = placemark.getGeoPoint();
    if (!polygon.contains(point)) {
        var closest = polygon.getClosestPoint(point);
        placemark.setGeoPoint( closest.point);
    }
});

Соответственно, с помощью метода getClosestPoint() можно заставить метку двигать только по границе многоугольника.
в общем вопрос то был не по тому как найти ближайшую точку, а как не дать возможность мышью вытащить объект за этот прямоугольник. я применил другой метод "возврата" - установка в фиксированное значение широты.
результат - как я уже говорил - объект сначала "вытаскивается" а потом (когда мышь останавиливается) - возвращается внутрь прямоугольника.

т.е. возврат происходит после перемещения, а надо, чтобы перемещения не было в принципе
Сохраните пример, который я привел в предыдущем комментарии, и посмотрите на результат. В нем решается именно ваша задача (метка не выходит за рамки многоугольника).
Действительно работает. Спасибо
Непонятно почему не работало у меня, я то же самое по моему делал. Буду разбираться