讓OpenLayers的SelectFeature控件支持鼠標右鍵事件

 

 如何讓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
    }
),

這裏的右鍵菜單只是寫了一個最簡陋的形式,真正要達到實用標準需要單獨封裝一個獨立的上下文菜單控件,供這個右鍵選擇要素功能調用。以後再完善吧,先到這裏。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章