OpenLayers: Механизм событий (events) в OpenLayers

Решенные задачи, первая запись - описание решения.
Ответить
Аватара пользователя
dobeer
Активный участник
Сообщения: 199
Зарегистрирован: 25 дек 2009, 21:54
Репутация: 1
Откуда: Чита
Контактная информация:

OpenLayers: Механизм событий (events) в OpenLayers

Сообщение dobeer » 19 авг 2011, 17:48

Подскажите где, как... (в документации не нашел) можно обработать события изменения масштаба и движения карты. Например при изменениии (увеличение/уменьшение) масштаба вывыести

Код: Выделить всё

alert('ok');
и также при возникновении события движении карты мышкой вывести тот же

Код: Выделить всё

alert('ok');
.
И вообще хочется подрбнее постичь возникновения различных событий в OL...

Аватара пользователя
Mavka
Гуру
Сообщения: 2060
Зарегистрирован: 14 мар 2008, 17:36
Статьи: 11
Проекты: 2/1
Репутация: 9

Re: OL - события

Сообщение Mavka » 20 авг 2011, 19:34

Механизм событий (events) в OpenLayers

Открываем в документациия API класс Map и смотрим какие события он инициирует - EVENT_TYPES (подобный раздел есть у многих классов). Нас интересуют события "zoomend" и "moveend" (аналогичное событие "move" возникает несколько раз пока вы двигаете карту, а "moveend" - когда отпускается кнопка мышки). Регистрируем обработчик:

Код: Выделить всё

map.events.register("zoomend", map, function(e) { 
    alert('ok');
}); 
В параметре "e" могут содержаться всякие полезные сведения, для разных событий они отличаются, поэтому смотрите подробнее в отладчике.

Инициация события производится вызовом функции triggerEvent:

Код: Выделить всё

this.layer.events.triggerEvent("afterfeaturemodified", {feature: feature}); 
Например, в топике "GetFeature - индикатор загрузки" вместо alert() правильнее было запустить событие и при наличии зарегистрированного обработчика использовать вне класса.

На одно и то же событие можно зарегистрировать несколько обработчиков. (Учтите, что еще встречаются классы в которых эта возможность реализована с ошибками.) Используем функцию console.log() так как alert() прерывает интерактивное перемещение:

Код: Выделить всё

map.events.register("move", map, function(e) { 
    console.log('ok1');
    return true;
});
map.events.register("move", map, function(e) { 
    console.log('ok2');
    return true;
}); 
Обработчик должен возвращать логическое значение true/false. Если в первом обработчике установить "return false", то последующие обработчики вызваны не будут (проверьте в консоли отсутствие "ok2").

Возьмем событие "mousedown". Метод register("mousedown", ...) добавляет в конец массива

Код: Выделить всё

map.events.listeners['mousedown'] 
запись с описанием обработчика. Так как на момент работы пользовательского кода уже зарегистрированы обработчики контроллеров, то может возникнуть необходимость добавить свой обработчик первым в списке:

Код: Выделить всё

map.events.listeners['mousedown'].unshift({
    obj: map,
    func: function(e) { 
        console.log('ok');
        return false;
    }
}); 
Так как здесь использован "return false", то все остальные обработчики работать не будут.

Вот и все что связано с обработкой событий в OpenLayers. Есть еще событийная модель DOM и свои способы работы во фреймворках типа GeoExt и MapQuery.
лангольеры под окном жрали время ом-ном-ном

Аватара пользователя
dobeer
Активный участник
Сообщения: 199
Зарегистрирован: 25 дек 2009, 21:54
Репутация: 1
Откуда: Чита
Контактная информация:

Re: OL - события

Сообщение dobeer » 22 авг 2011, 12:47

Спасибо, Mavka. То что надо было, работает.

Аватара пользователя
dobeer
Активный участник
Сообщения: 199
Зарегистрирован: 25 дек 2009, 21:54
Репутация: 1
Откуда: Чита
Контактная информация:

Re: OL - события

Сообщение dobeer » 22 авг 2011, 18:15

Странное дело...при изменении масштаба, почемуто возникают 2 события "zoomend" и "moveend"! На каждое событие у меня повешена одна и та же функция и нет необходимости выполнять ее 2 раза (лишняя нагрузка на сервер). Есть простой (какойто стандартный выход) способ этого избежать? Пока решил проблему тем, что при запуске 2-го события (ненужного "moveend") делаю проверку не выполняется ли первое.

Аватара пользователя
Mavka
Гуру
Сообщения: 2060
Зарегистрирован: 14 мар 2008, 17:36
Статьи: 11
Проекты: 2/1
Репутация: 9

Re: OL - события

Сообщение Mavka » 22 авг 2011, 22:44

Это нормально, в доках написано:
moveend triggered after a drag, pan, or zoom completes
значит он срабатывает не только на движение карты, но и на увеличение.

Там где действует "zoomend" будет срабатывать и "moveend". Может быть "zoomend" вам не нужен вообще?
лангольеры под окном жрали время ом-ном-ном

Аватара пользователя
dobeer
Активный участник
Сообщения: 199
Зарегистрирован: 25 дек 2009, 21:54
Репутация: 1
Откуда: Чита
Контактная информация:

Re: OL - события

Сообщение dobeer » 23 авг 2011, 05:59

Мне необходимо получать координаты текущего эктента при каждом изменении масштаба и при завершении движения карты...как тут обойтись без "zoomend"?

Аватара пользователя
Mavka
Гуру
Сообщения: 2060
Зарегистрирован: 14 мар 2008, 17:36
Статьи: 11
Проекты: 2/1
Репутация: 9

Re: OL - события

Сообщение Mavka » 23 авг 2011, 09:59

Вместо zoomend будет работать moveend
лангольеры под окном жрали время ом-ном-ном

Аватара пользователя
dobeer
Активный участник
Сообщения: 199
Зарегистрирован: 25 дек 2009, 21:54
Репутация: 1
Откуда: Чита
Контактная информация:

Re: OL - события

Сообщение dobeer » 23 авг 2011, 10:22

Действительно работает, что то я неподумал об этом)))

J_Mnemonic
Участник
Сообщения: 59
Зарегистрирован: 15 июн 2013, 20:47
Репутация: 0

Re: OpenLayers: Механизм событий (events) в OpenLayers

Сообщение J_Mnemonic » 18 июн 2013, 10:38

вот вычитал что есть такое:
movestart - triggered after the start of a drag, pan, or zoom. The event object may include a zoomChanged property that tells whether the zoom has changed.

а не подскажете как мне отсеить "drag, pan" события? дело в том что мне нужно отлавливать старт зуминга, чтобы закрывать Popup (иначе какой то глюк происходит - если попап не закрыть, то его уже потом вообще не возможно закрыть после зума)

J_Mnemonic
Участник
Сообщения: 59
Зарегистрирован: 15 июн 2013, 20:47
Репутация: 0

Re: OpenLayers: Механизм событий (events) в OpenLayers

Сообщение J_Mnemonic » 18 июн 2013, 11:43

Нашел вот такой ответ на Stackoverflow
For this purpose you should override moveTo and moveByPx methods of OpenLayers.Map for eliminate movestart event triggering for any actions except zooming.

но не могу понять - как переопределить эти методы (moveTo and moveByPx)?

Аватара пользователя
Denis Rykov
Гуру
Сообщения: 3321
Зарегистрирован: 11 апр 2008, 21:09
Статьи: 33
Проекты: 9
Репутация: 494
Ваше звание: Author
Контактная информация:

Re: OpenLayers: Механизм событий (events) в OpenLayers

Сообщение Denis Rykov » 18 июн 2013, 15:22

Вот прочитайте viewtopic.php?f=41&t=8252

[ Сообщение с мобильного устройства ]
Spatial is now, more than ever, just another column- The Geometry Column.

J_Mnemonic
Участник
Сообщения: 59
Зарегистрирован: 15 июн 2013, 20:47
Репутация: 0

Re: OpenLayers: Механизм событий (events) в OpenLayers

Сообщение J_Mnemonic » 19 июн 2013, 01:16

Спасибо. Статья полезная.
Решил вроде свой вопрос. Но правда для этого пришлось случайно обнаружить начинку оригинальных методов и подкорректировать их. Точнее хватило токо одного - moveByPx.
вместо

Код: Выделить всё

(this.dragging = !0, this.events.triggerEvent("movestart")) 
оставил только

Код: Выделить всё

(this.dragging = !0)
надеюсь кому нибудь пригодится инфа

Ответить

Вернуться в «Рецепты»