Openlayers 3 将平移限制在OpenLayers3中的WMS范围之外
我有一个小面积的矩形WMS,我想限制WMS扩展外的平移,所以在地图外根本看不到白色或黑色区域。 将Openlayers 3 将平移限制在OpenLayers3中的WMS范围之外,openlayers-3,Openlayers 3,我有一个小面积的矩形WMS,我想限制WMS扩展外的平移,所以在地图外根本看不到白色或黑色区域。 将范围添加到视图对我不起作用,并且在文档中编写了关于此选项的说明 约束中心的范围,换句话说,中心不能 设置在该范围之外 但正如我所理解的,如果中心在范围内,但在拐角处,它将显示该范围外的白色区域,但我根本不想看到白色区域 使用OL3可以实现这一点吗?这是我的解决方案。我刚刚写的,所以没有经过广泛的测试。例如,如果开始旋转贴图,它可能会断开,如果缩小太远,它可能会出现故障 var constrainPa
范围
添加到视图
对我不起作用,并且在文档中编写了关于此选项的说明
约束中心的范围,换句话说,中心不能
设置在该范围之外
但正如我所理解的,如果中心在范围内,但在拐角处,它将显示该范围外的白色区域,但我根本不想看到白色区域
使用OL3可以实现这一点吗?这是我的解决方案。我刚刚写的,所以没有经过广泛的测试。例如,如果开始旋转贴图,它可能会断开,如果缩小太远,它可能会出现故障
var constrainPan = function() {
var visible = view.calculateExtent(map.getSize());
var centre = view.getCenter();
var delta;
var adjust = false;
if ((delta = extent[0] - visible[0]) > 0) {
adjust = true;
centre[0] += delta;
} else if ((delta = extent[2] - visible[2]) < 0) {
adjust = true;
centre[0] += delta;
}
if ((delta = extent[1] - visible[1]) > 0) {
adjust = true;
centre[1] += delta;
} else if ((delta = extent[3] - visible[3]) < 0) {
adjust = true;
centre[1] += delta;
}
if (adjust) {
view.setCenter(centre);
}
};
view.on('change:resolution', constrainPan);
view.on('change:center', constrainPan);
var constraintpan=function(){
var visible=view.calculateExtent(map.getSize());
var center=view.getCenter();
var三角洲;
var-adjust=false;
如果((增量=范围[0]-可见[0])>0){
调整=真;
中心[0]+=delta;
}else如果((增量=范围[2]-可见[2])<0){
调整=真;
中心[0]+=delta;
}
如果((增量=范围[1]-可见[1])>0){
调整=真;
中心[1]+=delta;
}否则如果((增量=范围[3]-可见[3])<0){
调整=真;
中心[1]+=delta;
}
如果(调整){
视图。设置中心(中心);
}
};
关于(‘变更:决议’)的意见;
打开视图('更改:中心',平移);
这要求变量
map
、view
(具有明显的含义)和区段
(希望可见的xmin、ymin、xmax、ymax)可用。这是@tremby answer的一个扩展,但需要一个注释
首先,他的解决方案对我来说非常有效,但它被称为经常使用的方法。因此,我将其包装在一个debounce
函数中
所以
变成
var dConstrainPan = debounce(constrainPan);
view.on('change:resolution', dConstrainPan);
view.on('change:center', dConstrainPan);
这将导致轻微闪烁,当移动到边界框外时,机器人缩放/移动将毫不延迟地工作
仍然不完美,但从我的角度来看,这是一个有益的改进
去盎司代码:
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
Soruce:,在underline.js中,这里有一个更健壮的实现,在任何情况下都应该运行良好。它是用ES6编写的,需要等质量方法(来自lodash或其他任何东西…)
const-extent=[-357823.236526037008.69391313632.36287230727.3772];
const view=this.olMap.getView();
const modifyValues={};
//禁止在范围外平移的技巧
让pan=(e)=>{
const type=e.type;
const newValue=e.target.get(e.key);
const oldValue=e.oldValue;
if(相等(旧值、新值)){
//当事件未更改值时不执行任何操作
返回;
}
if(isEqual(修改值[类型],新值)){
//打破可能的无限循环
删除修改值[类型];
返回;
}
如果(类型=='change:resolution'&&newValue
这是一个好问题。您想要的还不受支持。不久前,我开始开发一个涵盖您的用例的补丁,但这个补丁尚未合并。看见我会再做一次的。哦,太糟糕了。在我看到的大多数在线地图中,这个白色区域是我真正不喜欢的。现在等待OL3支持它。Erilem的补丁可以工作,你可以自己轻松添加它。到erilem的pull请求的链接在末尾有一个隐藏的额外
,并给出一个404。工作链接:我不喜欢看不到范围外的白色区域。这意味着我永远不能集中在可用区域内的区域。这会导致进一步的问题。效果很好,但在全屏模式下会导致缩放和拖动停止工作。是的,我提到过,如果缩放太远,它可能会中断。当你进入全屏时,可能会出现同样的情况。很高兴它仍然有帮助。如果你有特别的建议,使它更可靠,请建议编辑。我得到了“太多的递归”错误,以更快的平移,我的层正在消失。。。只是为了记录在案是的;对于一般情况,它肯定不是生产就绪的代码(尽管它在我的用例中工作得很好)。欢迎进行任何改进。ES6 lodash导入注意:确保从“lodash”导入{isEqual}。如果忘记了大括号,它不会抛出错误,但是isEqual()
对于数组总是返回true。
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
const extent = [-357823.2365, 6037008.6939, 1313632.3628, 7230727.3772];
const view = this.olMap.getView();
const modifyValues = {};
// Trick to forbid panning outside extent
let constrainPan = (e) => {
const type = e.type;
const newValue = e.target.get(e.key);
const oldValue = e.oldValue;
if (isEqual(oldValue, newValue)) {
// Do nothing when event doesn't change the value
return;
}
if (isEqual(modifyValues[type], newValue)) {
// Break possible infinite loop
delete modifyValues[type];
return;
}
if (type === 'change:resolution' && newValue < oldValue) {
// Always allow zoom-in.
return;
}
const visibleExtent = view.calculateExtent(this.olMap.getSize());
const intersection = ol.extent.getIntersection(visibleExtent, extent);
const modify = !isEqual(intersection, visibleExtent);
if (modify) {
if (type === 'change:center') {
const newCenter = newValue.slice(0);
if (ol.extent.getWidth(visibleExtent) !== ol.extent.getWidth(intersection)) {
newCenter[0] = oldValue[0];
}
if (ol.extent.getHeight(visibleExtent) !== ol.extent.getHeight(intersection)) {
newCenter[1] = oldValue[1];
}
modifyValues[type] = newCenter;
view.setCenter(newCenter);
} else if (type === 'change:resolution') {
modifyValues[type] = oldValue;
view.setResolution(oldValue);
}
}
};
view.on('change:resolution', constrainPan);
view.on('change:center', constrainPan);