【问题标题】:OpenLayer Map restrict panning and zoomingOpenLayer Map 限制平移和缩放
【发布时间】:2013-03-22 13:32:47
【问题描述】:

我是 OpenLayers 的新手,正在尝试弄清楚如何限制用户可以平移和向外缩放的数量。对于此应用程序,用户在地图中选择一个本地区域并单击一个按钮,表示使用该区域,我们希望他们不能平移到该范围之外或缩小到更大的范围。单击按钮时,我使用 map.GetExtent() 将 maxRestrictedExtent 和 maxExtent 设置为当前范围。我还通过调用 map.getResolution() 将 maxResolution 设置为当前分辨率。平移效果很好,但缩放却不行。通过给定的分辨率,用户仍然可以缩小。

我添加了代码,每次范围更改时,都会打印出当前范围和分辨率。在第 6 次范围更改时,我设置了上面列出的三个地图属性并打印出这些设置。这使我可以从完整的世界视图放大到足够本地化的区域进行测试。在第 6 次范围更改时,我用鼠标滚轮缩小并查看选择的范围和分辨率。单击鼠标滚轮进行缩小时,下一个打印输出清楚地显示分辨率确实大于 map.maxResolution 的设置,并且我可以看到可视区域大于选择的区域。我尝试了很多方法,包括设置 maxExtent,但似乎没有什么会导致最大可缩放范围受到限制。如果我愿意,我可以再次放大到完整的世界视图。

您可以在下面看到我编写的测试代码,它使用导航控件和 OSM 层实例化地图,然后注册地图的 moveend 事件,创建执行我描述的回调函数,最后缩放最大程度。

有没有人知道我应该做些什么不同的事情来限制缩小到所选最大范围的能力?我希望我不必手动将范围调整回最大范围内,但如果是这样的话,至少知道这会有所帮助。

附: - 不幸的是,整个 html 没有显示,因为从样式到样式之前,以及最终样式之后都被处理为 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>

【问题讨论】:

    标签: zooming openlayers


    【解决方案1】:

    我刚刚做了你想做的事,它对我有用。

    当我创建地图时,我指定了最小/最大分辨率

      map = new OpenLayers.Map('map_element', {
        minResolution: 0.02197265625,
        maxResolution: 0.00274658203125
    });
    

    添加层时,我还指定了 serverResolutions 列表。

        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 左右。地图似乎在告诉我,我越靠近分辨率越低。
    • 刚和一位地理同事谈过,他说分辨率通常以每像素米数来衡量,这意味着当我非常接近时,我在一个像素中显示的米数较少,甚至小于 1,而且非常远,我将在一个像素中显示更多的米数,这就是我所看到的。所以我不明白为什么 minResolution 会设置为比 maxResolution 更大的数字。
    • 分辨率是每像素地图单位的宽度/高度 - 例如,150 英里除以 512 像素将是 0.29296875 的分辨率。如果您使用切片缓存服务器,则需要指定切片缓存的分辨率(以及设置 serverResolutions 属性,该属性指定切片缓存在服务器上的分辨率)。否则,您通常只需定义 numZoomLevels 即可指定所需的缩放级别。
    • 如果您定义了 numZoomLevels,但没有切片缓存服务器(不确定是否有,我将不得不检查),那么您是否会忽略分辨率数组并将其留给地图来解决这个问题?然后,如果有 20 个缩放级别,我的下一个问题是,当用户为其范围选择一个区域时,我如何知道将我的最大值设置为哪个缩放级别?
    • 好吧,我最初尝试设置 numZoomLevels,但由于某种原因,这种方法存在问题,所以我改用分辨率。我还注意到您使用的图层类型与我完全不同(OSM)。使用 TileCache 图层的问题在于填充地图切片是您的责任。这就是我目前所处的位置 - 获取数据以预填充缓存。
    【解决方案2】:

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

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

    由于世界视图是 0,而最地面视图是 19,那么如果当前视图小于最大值(选择的缩放级别),我们只需缩放到最大值。

    这很好用。当我滚动鼠标缩小时,我确实闪烁了一下,超过了选择的最大缩放级别,但它不再缩小了。此外,此方法不需要我向地图图层添加分辨率数组,或在地图上设置最大/最小分辨率。 (希望我能摆脱那种闪烁......嗯!)

    【讨论】:

      猜你喜欢
      • 2019-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-08
      • 2013-12-12
      • 2016-03-10
      相关资源
      最近更新 更多