OpenLayer地图限制平移和缩放

3
我是OpenLayers的新手,正在尝试弄清楚如何限制用户平移和缩放的程度。对于这个应用程序,用户可以在地图上选择一个本地区域并单击一个按钮以使用该区域,我们希望他们不能超出该范围进行平移或缩小。当单击按钮时,我使用map.GetExtent()将maxRestrictedExtent和maxExtent都设置为当前范围。我还通过调用map.getResolution()将maxResolution设置为当前分辨率。平移工作得很好,但缩放不起作用。用户仍然能够缩小至给定分辨率以下。
我已经添加了代码,每次范围发生变化时,都会打印出当前范围和分辨率。在第6次范围更改时,我设置了上述三个地图属性并打印出设置。这使我能够从完整的世界视图缩放到一个足够局部的区域进行测试。在第6次范围更改时,我使用鼠标滚轮缩小并看到所选的范围和分辨率。在鼠标滚轮点击缩小后,下一次的打印输出清楚地显示分辨率确实大于map.maxResolution的设置,并且我可以看到可视区域大于所选区域。我尝试过许多方法,包括设置maxExtent,但似乎没有任何方法可以限制最大缩放范围。如果需要,我可以随意缩放至完整的世界视图。
下面是我编写的测试代码,它使用导航控件和OSM图层实例化一个地图,然后注册地图的moveend事件,创建一个回调函数来执行我所描述的操作,并最终缩放到最大范围。
有没有人有什么想法,可以使我限制缩小至所选最大范围的能力?我希望不必手动将范围调整回到最大范围内,但如果确实需要这样做,至少知道这一点会有所帮助。
注:遗憾的是,整个HTML不能显示出来,因为从...到style之间以及最后一个

之后的所有内容都被处理为HTML。唯一真正缺失的是我在body的onload事件中调用了init()。
<style type="text/css">    
    html, body {
        width: 100%;
        height: 100%;
        margin: 0;         
    }
    #map {
        width: 100%;
        height: 100%;
        margin: 0;         
    } 
</style>

<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">

var map;
var num;

function init(){
    map = new OpenLayers.Map('map', { controls: [] });       
    map.addControl(new OpenLayers.Control.Navigation());       
    map.addLayer(new OpenLayers.Layer.OSM());

    map.events.register("moveend", this, function (e) {
        if (num == 5)
        {
            map.maxExtent = map.getExtent();
            map.restrictedExtent = map.maxExtent;
            map.maxResolution = map.getResolution();
            console.log(num++ + ": Setting maxExtent/restrictedExtent: " + map.maxExtent + "; resolution: " + map.maxResolution);
        }
        else
        {
            console.log(num++ + ": Changed to extent: " + map.getExtent() + "; resolution: " + map.getResolution());
        }
    });

    num = 0;
    map.zoomToMaxExtent();
}
</script>

2个回答

0
我刚刚完成了你想做的事情,并且对我来说它是有效的。
当我创建地图时,我会指定最小/最大分辨率。
  map = new OpenLayers.Map('map_element', {
    minResolution: 0.02197265625,
    maxResolution: 0.00274658203125
});

当添加一个图层时,我也会指定一组服务器分辨率。

    var tilecache_disk_layer = new OpenLayers.Layer.TileCache("TileCache Layer",
        ["http://" + tilecache_host + "/tilecache/"],
        "basic",
        {
         serverResolutions: [0.703125, 0.3515625, 0.17578125, 0.087890625, 
                        0.0439453125, 0.02197265625, 0.010986328125, 
                        0.0054931640625, 0.00274658203125, 0.001373291015625, 
                        0.0006866455078125, 0.00034332275390625, 0.000171661376953125, 
                        0.0000858306884765625, 0.00004291534423828125, 0.000021457672119140625]
        },
        {wrapDateLine: 'true'},
        {isBaseLayer: true}
    );

以下JavaScript代码会向我的服务器发送请求以获取地图参数。
  if (site_coords == undefined) {
    coordinates = sendHttpRequest("http://" + tile_host + "/ManagerApp/mapView?position=true");
    mapParameters = coordinates.split(",");       
    map.setCenter(new OpenLayers.LonLat(mapParameters[0], mapParameters[1]));
    map.minResolution = mapParameters[2];
    map.maxResolution = mapParameters[3];
    zoom_level = mapParameters[4];
    map.restrictedExtent = new OpenLayers.Bounds(mapParameters[5], mapParameters[6], mapParameters[7], mapParameters[8])
}

我可以看到有很多东西需要学习。我也是地理方面的新手。从你的最小/最大分辨率中,我可以看出你将最小值设置为比最大值大的数字。这有点令人困惑,因为当我第一次打开带有控制台的页面时,我的分辨率为19567.87923828125,而当我最终到达第六个范围变化时,我大约在4.x左右。地图似乎告诉我,我越靠近地图,分辨率就越低。 - bmahf
刚刚和一个地理同事交谈,他说分辨率通常以每像素米数来衡量,这意味着当我非常靠近时,一个像素中显示的米数会更少,甚至小于1,而在远处,一个像素中显示的米数会更多,是一个大数字,这就是我看到的情况。所以我不明白为什么最小分辨率会被设置为比最大分辨率更大的数字。 - bmahf
分辨率是每像素地图单位的宽度/高度,例如,150英里除以512像素的分辨率为0.29296875。如果您正在使用瓦片缓存服务器,则需要指定缓存瓦片的分辨率(以及设置serverResolutions属性,该属性指定在服务器上缓存瓦片的分辨率)。否则,通常只需定义numZoomLevels来指定您想要的缩放级别数量。 - Andrew Fielden
如果您定义了numZoomLevels,但没有瓦片缓存服务器(我不确定我们是否有,我需要检查一下),那么您会省略分辨率数组,并让地图自己解决这个问题吗?然后,如果有20个缩放级别,我的下一个问题是,当用户选择其范围的区域时,我如何知道将我的最大缩放级别设置为哪个缩放级别? - bmahf
我最初尝试设置numZoomLevels,但由于某些原因出现了问题,所以我转而使用分辨率。我还注意到你正在使用与我完全不同的图层类型(OSM)。你使用TileCache图层的问题在于你需要负责填充地图瓦片。这就是我目前所处的位置 - 获取数据以预先填充缓存。 - Andrew Fielden
所以我更新了我的文件,在OpenLayers.Map对象的构造中添加了minResolution和maxResolution设置,并在OSM图层的构造中添加了serverResolutions数组选项。查阅资料发现这是被支持的。从这个链接(http://simonmercier.net/blog/?p=88)获取了我的分辨率。然后,在我的事件中,第六次调用时,我设置了maxRestrictedExtent和maxResolution。但即使我可以看到这些调用已经设置好了,并且分辨率也在我的数组中,我仍然可以缩小到所选择的分辨率以下。还有一些东西缺失。 - bmahf

0

这是我的答案。经过长时间的搜索、发布和发送电子邮件,我找到了一个告诉我简单答案的人。我已经注册了“moveend”事件,捕获所有范围移动,以便我可以查看正在发生的事情。答案是在类上声明一个私有int变量(maxZoomLevel),当地图首次绘制时它的值为零,因为我开始绘制世界视图,然后使用getZoom()设置为当前缩放级别,当用户点击按钮选择当前区域进行操作时。所以,“moveend”事件的注册如下:

    map.events.register("moveend", this, function (e) {
        if (map.getZoom() < maxZoomLevel)
        {
            map.zoomTo(maxZoomLevel);
        }
    });

由于世界视图为0,而地面最低视图为19,因此如果当前视图小于最大值(所选缩放级别),我们只需缩放到最大值。

这个方法非常好用。当我滚动鼠标缩放超过所选的最大缩放级别时,它会有点闪烁,但不再缩放超过它。此外,这种方法不需要我在地图图层上添加分辨率数组,也不需要设置地图的最大/最小分辨率。(希望我能摆脱那个闪烁...嗯!)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接