Map.forEachLayerAtPixel 回调函数有一个空的 rgba 数组
Map.forEachLayerAtPixel callback function has an empty rgba array
使用在其中一个示例 (https://openlayers.org/en/latest/examples/getfeatureinfo-image.html) 中找到的一些代码,每当我将鼠标悬停在特定对象的非透明部分时,我都试图更改指针表示层.
map.on('pointermove', function(evt) {
if (evt.dragging) {
return;
}
var pixel = map.getEventPixel(evt.originalEvent);
var hit = map.forEachLayerAtPixel(pixel, function(layer, rgba) {
return rgba[3] == 0;
}, {
'layerFilter': function(layer) {return layer == aisLayer;}
});
map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
很遗憾,Map.forEachLayerAtPixel的回调函数中的rgba变量为空。
根据文档 (https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html#forEachLayerAtPixel),第二个参数应该是一个包含 rgba 值的数组,如果层不支持它,则为 null。
嗯,对我来说,它不是空的,但它没有 rgba 值。它只是一个空的 Uint8array。
有关信息,这是我正在使用的图层,由地理服务器实例生成:
var aisLayer = new TileLayer({
source: new TileWMS({
// url: 'http://192.168.8.157:8600/geoserver/gwc/service/wms',
url: 'http://192.168.8.157:8600/geoserver/ais/wms',
params: {
'LAYERS': 'ais:shipinfosview',
'VERSION': '2.0.0',
'SRS': 'EPSG:900913',
'CQL_FILTER': 'time>2020-05-17T18:10:00'
},
serverType: 'geoserver',
projection: 'EPSG:900913',
})
});
知道这里出了什么问题吗?
谢谢!
正如 Mike 指出的那样,必须指定 crossOrigin 以允许像素操作。
文档中实际上提到了这一点。
但是,仅对我正在使用的层进行更改是不够的。
因为我在处理多个层,所以 Openlayers 似乎将这些层合并为一个层。
其中一层没有那个 crossOrigin
参数,我仍然得到一个空数组。
为了避免这种情况并解决我的问题,Openlayer 必须不要将所有图层合并为一个 canvas。
我胡乱猜测并将 aisLayer
的 className
参数更改为非默认值。事实上,创建了一个没有默认名称的新 canvas。
如果您有任何关于此行为的方式和原因的说明,我将很高兴。
下面是一个可行的解决方案:
let aisLayer = new TileLayer({
className: 'ais-layer',
source: new TileWMS({
// url: 'http://192.168.8.157:8600/geoserver/gwc/service/wms',
url: 'http://192.168.8.157:8600/geoserver/ais/wms',
params: {
'LAYERS': 'ais:shipinfosview',
'VERSION': '2.0.0',
'SRS': 'EPSG:900913',
'CQL_FILTER': 'time>2020-05-17T18:10:00'
},
serverType: 'geoserver',
projection: 'EPSG:900913',
crossOrigin: 'anonymous',
})
});
const source = new VectorSource({
format: new GeoJSON(),
url: './data/countries.json',
});
const layer = new VectorLayer({
source: source,
});
const map = new Map({
target: 'map-container',
layers: [
new TileLayer({
source: new XYZSource({
url: 'http://tile.stamen.com/terrain/{z}/{x}/{y}.jpg'
})
}),
layer,
aisLayer,
],
view: new View({
center: fromLonLat([0, 0]),
zoom: 2
})
});
map.on('pointermove', function(evt) {
if (evt.dragging) {
return;
}
let pixel = map.getEventPixel(evt.originalEvent);
let hit = map.forEachLayerAtPixel(pixel, function(layer, rgba) {
return rgba[4] != 0;
}, {
'layerFilter': function(layer) {
return layer.ol_uid == aisLayer.ol_uid;
}
});
map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
使用在其中一个示例 (https://openlayers.org/en/latest/examples/getfeatureinfo-image.html) 中找到的一些代码,每当我将鼠标悬停在特定对象的非透明部分时,我都试图更改指针表示层.
map.on('pointermove', function(evt) {
if (evt.dragging) {
return;
}
var pixel = map.getEventPixel(evt.originalEvent);
var hit = map.forEachLayerAtPixel(pixel, function(layer, rgba) {
return rgba[3] == 0;
}, {
'layerFilter': function(layer) {return layer == aisLayer;}
});
map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});
很遗憾,Map.forEachLayerAtPixel的回调函数中的rgba变量为空。 根据文档 (https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html#forEachLayerAtPixel),第二个参数应该是一个包含 rgba 值的数组,如果层不支持它,则为 null。
嗯,对我来说,它不是空的,但它没有 rgba 值。它只是一个空的 Uint8array。
有关信息,这是我正在使用的图层,由地理服务器实例生成:
var aisLayer = new TileLayer({
source: new TileWMS({
// url: 'http://192.168.8.157:8600/geoserver/gwc/service/wms',
url: 'http://192.168.8.157:8600/geoserver/ais/wms',
params: {
'LAYERS': 'ais:shipinfosview',
'VERSION': '2.0.0',
'SRS': 'EPSG:900913',
'CQL_FILTER': 'time>2020-05-17T18:10:00'
},
serverType: 'geoserver',
projection: 'EPSG:900913',
})
});
知道这里出了什么问题吗?
谢谢!
正如 Mike 指出的那样,必须指定 crossOrigin 以允许像素操作。 文档中实际上提到了这一点。
但是,仅对我正在使用的层进行更改是不够的。
因为我在处理多个层,所以 Openlayers 似乎将这些层合并为一个层。
其中一层没有那个 crossOrigin
参数,我仍然得到一个空数组。
为了避免这种情况并解决我的问题,Openlayer 必须不要将所有图层合并为一个 canvas。
我胡乱猜测并将 aisLayer
的 className
参数更改为非默认值。事实上,创建了一个没有默认名称的新 canvas。
如果您有任何关于此行为的方式和原因的说明,我将很高兴。
下面是一个可行的解决方案:
let aisLayer = new TileLayer({
className: 'ais-layer',
source: new TileWMS({
// url: 'http://192.168.8.157:8600/geoserver/gwc/service/wms',
url: 'http://192.168.8.157:8600/geoserver/ais/wms',
params: {
'LAYERS': 'ais:shipinfosview',
'VERSION': '2.0.0',
'SRS': 'EPSG:900913',
'CQL_FILTER': 'time>2020-05-17T18:10:00'
},
serverType: 'geoserver',
projection: 'EPSG:900913',
crossOrigin: 'anonymous',
})
});
const source = new VectorSource({
format: new GeoJSON(),
url: './data/countries.json',
});
const layer = new VectorLayer({
source: source,
});
const map = new Map({
target: 'map-container',
layers: [
new TileLayer({
source: new XYZSource({
url: 'http://tile.stamen.com/terrain/{z}/{x}/{y}.jpg'
})
}),
layer,
aisLayer,
],
view: new View({
center: fromLonLat([0, 0]),
zoom: 2
})
});
map.on('pointermove', function(evt) {
if (evt.dragging) {
return;
}
let pixel = map.getEventPixel(evt.originalEvent);
let hit = map.forEachLayerAtPixel(pixel, function(layer, rgba) {
return rgba[4] != 0;
}, {
'layerFilter': function(layer) {
return layer.ol_uid == aisLayer.ol_uid;
}
});
map.getTargetElement().style.cursor = hit ? 'pointer' : '';
});