http://www.cnblogs.com/lei3389/archive/2009/04/21/1440458.html
OpenLayers上的一个Feature对象单击出现一个气泡很容易实现,但是右键出现点菜单什么的就不容易了,关键在于SelectFeature控件不支持右键事件,所以我就改之。。
修改的源文件是基于OpenLayers2.7+changeset9116
changeset9116修复了SelectFeature不能选取两个以上图层的bug,具体参见http://trac.openlayers.org/changeset/9116
所以有些源代码和官网上下的OpenLayers2.7有点不一样
代码太多了,显得文章比较长,懒得看的就直接下载修改后的用就行了:
OpenLayers2.7 lei3389修改版下载地址:
http://files.cnblogs.com/lei3389/OpenLayers27_ModedBy_lei3389.rar
使用方法本文最后有个例子的
1.首先修改【OpenLayers\Events.js】
修改OL能够捕获的鼠标事件,添加右键事件“contextmenu”
BROWSER_EVENTS: [
"
mouseover
"
,
"
mouseout
"
,
"
mousedown
"
,
"
mouseup
"
,
"
mousemove
"
,
"
click
"
,
"
dblclick
"
,
"
rightclick
"
,
"
dblrightclick
"
,
"
resize
"
,
"
focus
"
,
"
blur
"
//
added by lei3389
,
"
contextmenu
"
//
added end
],
现在OL已经可以截获鼠标右键了,只是handler没有去处理,下面我们再继续
2.进入【OpenLayers\Handler\Feature.js】
修改这个handler能够处理的事件表
EVENTMAP: {
//
added by lei
'
contextmenu
'
: {
'
in
'
:
'
click
'
,
'
out
'
:
'
clickout
'
},
//
added end
'
click
'
: {
'
in
'
:
'
click
'
,
'
out
'
:
'
clickout
'
},
'
mousemove
'
: {
'
in
'
:
'
over
'
,
'
out
'
:
'
out
'
},
'
dblclick
'
: {
'
in
'
:
'
dblclick
'
,
'
out
'
:
null
},
'
mousedown
'
: {
'
in
'
:
null
,
'
out
'
:
null
},
'
mouseup
'
: {
'
in
'
:
null
,
'
out
'
:
null
}
},
这里的in和out可以理解为选中和取消选中
这样,这个handler就能够处理contextmenu事件了,但是谁去处理你的事件呢?只能自己添加了:
/*
*
*added by lei3389!!!
* Method: contextmenu
* Handle contextmenu. Call the "contextmenu" callback if contextmenu on a feature,
* or the "clickout" callback if rightclick outside any feature.
*
* Parameters:
* evt - {Event}
*
* Returns:
* {Boolean}
*/
contextmenu:
function
(evt) {
return
this
.handle(evt)
?
!
this
.stopClick :
true
;
},
这样就交给handle去处理了
触发选中的本来是左键单击和左键双击,现在我们添加上右击
handle:
{
//
var click = (type == "click" || type == "dblclick");
//
moded by lei
//
for right click on feature
var
click
=
(type
==
"
click
"
||
type
==
"
dblclick
"
||
type
==
"
contextmenu
"
);
//
moded end
}
我们添加右键点击只是利用左键点击触发的事件,所以我们要在触发的事件中添加一个参数,以区分是左键还是右键
if
(previouslyIn
&&
inNew) {
//
out of last feature and in to another
this
.triggerCallback(type,
'
out
'
, [
this
.lastFeature]);
//
this.triggerCallback(type, 'in', [this.feature]);
//
moded by lei3389
//
for add a param
this
.triggerCallback(type,
'
in
'
, [
this
.feature,type]);
//
end
}
else
if
(
!
previouslyIn
||
click) {
//
in feature for the first time
//
this.triggerCallback(type, 'in', [this.feature]);
//
moded by lei3389
//
for add a param
this
.triggerCallback(type,
'
in
'
, [
this
.feature,type]);
//
end
}
3.进入【OpenLayers\Control\SelectFeature.js】
handler只是为control服务的,我们让handler处理了右键事件也是为control处理的
刚刚添加的参数就要有用了:
/*
*
* Method: clickFeature
* Called on click in a feature
* Only responds if this.hover is false.
*
* Parameters:
* feature - {}
*/
//
clickFeature: function(feature)
//
moded by lei3389
//
for add a param
clickFeature:
function
(feature,triggertype) {
//
end
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});
}
//
moded by lei3389
//
this.select(feature);
this
.select(feature,triggertype);
//
end
}
}
},
然后这里也得添加一个参数:
/*
*
* Method: select
* Add feature to the layer's selectedFeature array, render the feature as
* selected, and call the onSelect function.
*
* Parameters:
* feature - {}
*/
//
moded by lei3389
//
for add a param ---triggertype
//
select: function(feature)
select:
function
(feature,triggertype){
//
end
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
.layerData
=
{};
var
selectStyle
=
this
.selectStyle
||
this
.renderIntent;
layer.drawFeature(feature, selectStyle);
layer.events.triggerEvent(
"
featureselected
"
, {feature: feature});
//
moded by lei3389
//
for add another "handler"
//
this.onSelect.call(this.scope, feature);
switch
(triggertype){
case
"
click
"
:
this
.onSelect.call(
this
.scope, feature);
break
;
case
"
contextmenu
"
:
this
.onRightSelect.call(
this
.scope, feature);
break
;
default
:
this
.onSelect.call(
this
.scope, feature);
}
//
end
}
}
},
当然还得添加一个属性,为使用我们刚才修改的成果提供一个调用的接口
Code
/*************************
*added by lei3389!!!!
*APIProperty: onRightSelect
*{Function} Optional function to be called when a feature is selected by RighClick of mouse .
*The function should expect to be called with a feature.
*/
onRightSelect: function(){},
4.现在对OL库的修改已经over了,我们自己使用的时候就可以用了
到自己的代码中来
首先屏蔽掉默认的右键:
//forbid the mouse's default rightclick
map.div.oncontextmenu = function () { return false;}
然后就可以像定义左键一样来定义鼠标右键了:
sample:
//
add selectStationControl
selectFeatureControl
=
new
OpenLayers.Control.SelectFeature([VectorLayer1,VectorLayer2,VectorLayer3],
{onSelect: onFeatureSelect,
onUnselect: onFeatureUnselect,
onRightSelect: onFeatureRightSelect
});
map.addControl(selectFeatureControl);
selectFeatureControl.activate();
5.应该这样就对右键的修改就over了吧,我把我自己用的OL上传了.
其中包括了SelectFeature控件对多层选择的支持+右键支持
另外还有和本文不相干的一点修改:
是关于ol解析GML v3.0的posList节点的问题,也可能是esri生成gml的时候esri本身的问题,但是arcgis的源代码我改不了。。只能对OL动手了~~
【OpenLayers.Format.GML】
linestring:
function
(node, ring) {
/*
*
* Two coordinate variations to consider:
* 1) x0 y0 z0 x1 y1 z1
* 2) x0, y0, z0 x1, y1, z1
*/
var
dim
=
parseInt(nodeList[
0
].getAttribute(
"
dimension
"
));
/*
*
* added by lei3389
*dim will be 'NAN' for esri didnot give GML V3 the dimension attribute!
*/
if
(dim
=
'
NAN
'
)dim
=
2
;
/*
*
* end
*/
6.终于完了,好长啊
OpenLayers2.7 lei3389修改版下载地址:
http://files.cnblogs.com/lei3389/OpenLayers27_ModedBy_lei3389.rar