让OpenLayers的SelectFeature控件支持鼠标右键事件

来源:互联网 发布:美国禁枪 知乎 编辑:程序博客网 时间:2024/05/23 02:00
 

 如何让OpenLayers的SelectFeature控件支持鼠标右键事件,这篇文章说得比较清楚了。

http://www.cnblogs.com/lei3389/archive/2009/04/21/1440458.html

但是他是直接对OpenLayers底层进行修改,而且版本是2.7的。我依据最新稳定版2.10,对涉及的相关对象进行了修改,相对于原文增加了提供当前鼠标位置参数。

下列代码放在OpenLayers库文件引用之后

OpenLayers.Events.prototype.BROWSER_EVENTS.push("contextmenu");OpenLayers.Handler.Feature.prototype.EVENTMAP['contextmenu'] = {'in': 'click', 'out': 'clickout'};OpenLayers.Handler.Feature.prototype.contextmenu = function(evt) {     return this.handle(evt) ? !this.stopClick : true;};OpenLayers.Handler.Feature.prototype.handle = function(evt) {    if(this.feature && !this.feature.layer) {        // feature has been destroyed        this.feature = null;    }    var type = evt.type;    var handled = false;    var previouslyIn = !!(this.feature); // previously in a feature    var click = (type == "click" || type == "dblclick" || type == "contextmenu");    this.feature = this.layer.getFeatureFromEvent(evt);    if(this.feature && !this.feature.layer) {        // feature has been destroyed        this.feature = null;    }    if(this.lastFeature && !this.lastFeature.layer) {        // last feature has been destroyed        this.lastFeature = null;    }    if(this.feature) {        var inNew = (this.feature != this.lastFeature);        if(this.geometryTypeMatches(this.feature)) {            // in to a feature            if(previouslyIn && inNew) {                // out of last feature and in to another                if(this.lastFeature) {                    this.triggerCallback(type, 'out', [this.lastFeature]);                }                this.triggerCallback(type, 'in', [this.feature,type,evt.xy]);            } else if(!previouslyIn || click) {                // in feature for the first time                this.triggerCallback(type, 'in', [this.feature,type,evt.xy]);            }            this.lastFeature = this.feature;            handled = true;        } else {            // not in to a feature            if(this.lastFeature && (previouslyIn && inNew || click)) {                // out of last feature for the first time                this.triggerCallback(type, 'out', [this.lastFeature]);            }            // next time the mouse goes in a feature whose geometry type            // doesn't match we don't want to call the 'out' callback            // again, so let's set this.feature to null so that            // previouslyIn will evaluate to false the next time            // we enter handle. Yes, a bit hackish...            this.feature = null;        }    } else {        if(this.lastFeature && (previouslyIn || click)) {            this.triggerCallback(type, 'out', [this.lastFeature]);        }    }    return handled;};OpenLayers.Control.SelectFeature.prototype.clickFeature = function(feature,triggerType,screenPixel) {    if(!this.hover) {        var selected = (OpenLayers.Util.indexOf(            feature.layer.selectedFeatures, feature) > -1);        if(selected) {            if(this.toggleSelect()) {                this.unselect(feature);            } else if(!this.multipleSelect()) {                this.unselectAll({except: feature});            }        } else {            if(!this.multipleSelect()) {                this.unselectAll({except: feature});            }            this.select(feature,triggerType,screenPixel);        }    }}OpenLayers.Control.SelectFeature.prototype.select = function(feature,triggerType,screenPixel) {    var cont = this.onBeforeSelect.call(this.scope, feature);    var layer = feature.layer;    if(cont !== false) {        cont = layer.events.triggerEvent("beforefeatureselected", {            feature: feature        });        if(cont !== false) {            layer.selectedFeatures.push(feature);            this.highlight(feature);            // if the feature handler isn't involved in the feature            // selection (because the box handler is used or the            // feature is selected programatically) we fake the            // feature handler to allow unselecting on click            if(!this.handlers.feature.lastFeature) {                this.handlers.feature.lastFeature = layer.selectedFeatures[0];            }            layer.events.triggerEvent("featureselected", {              feature: feature,              //添加右键事件标识              triggerType: triggerType,              screenPixel: screenPixel            });                        if(triggerType == "contextmenu"){                this.onContextMenuSelect.call(this.scope, feature, screenPixel);            } else {                this.onSelect.call(this.scope, feature);            }                                            }    }}OpenLayers.Control.SelectFeature.prototype.onContextMenuSelect = function(feature,screen){};

右键选择要素后的响应方法:

//要素右键响应方法var contextMenuHandler = function(feature,screen){    var menu = this._menuDiv;    if(!menu){        menu = document.createElement("div");        map.viewPortDiv.appendChild(menu);        this._menuDiv = menu;                menu.style.position = "absolute";        menu.style.background = "white";        menu.style.border = "1px solid gray";        menu.style.padding = "5px";        menu.style.zIndex = this.map.Z_INDEX_BASE['Control'] +                                this.map.controls.length;                                    }    menu.innerHTML = feature.id;    menu.style.left = screen.x + "px";    menu.style.top = screen.y + "px";};

控件的定义示例:

select: new OpenLayers.Control.SelectFeature(    vectors,    {        clickout: false, toggle: false,        multiple: false, hover: false,        toggleKey: "ctrlKey", // ctrl key removes from selection        multipleKey: "shiftKey", // shift key adds to selection        box: true,                //指定右键响应方法        onContextMenuSelect: contextMenuHandler    }),

这里的右键菜单只是写了一个最简陋的形式,真正要达到实用标准需要单独封装一个独立的上下文菜单控件,供这个右键选择要素功能调用。以后再完善吧,先到这里。