Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
The attached patch allows administrators to limit the zoom levels where Views powered vector layers are available. This makes it possible to have different local data shown depending on your zoom level.
One issue with the current patch is that it assumes you'll be using the google projection, I'm not sure the best way to handle that assumption.
Comment | File | Size | Author |
---|---|---|---|
#40 | openlayers_layerzoom.zip | 2.25 KB | treckstar |
#35 | openlayers_layerzoom.zip | 2.55 KB | japo32 |
#34 | openlayers_behaviors.zip | 2.54 KB | japo32 |
#29 | limit-zoom-levels.805796.29.patch | 3.95 KB | katbailey |
#5 | 805796_20100524.patch | 3.33 KB | jmiccolis |
Comments
Comment #1
seanrAfter I apply the patch, I end up with this warning on the map page and when saving a preset:
Comment #2
seanrEditing the layer made that go away, but the layer data still shows at all zoom levels even after I limited it from 0 - 5. Here's the layer export:
Here's the preset export:
Comment #3
jmiccolis CreditAttribution: jmiccolis commentedAttached is a patch that fixes the `array_values` issue. I'm still debugging why the new settings for the layer don't take effect, but I'm curious - if you clone the layer and update your preset to use the clone does that work? (That's how I developed initially and had this working)
Comment #4
seanrJust noticed when going to apply the new patch that the original one failed on one of the hunks. I reverted to the dev version and the new patch applied cleanly. I cloned the layer and changed the preset to use that, but it still shows the points at all zoom levels.
Comment #5
jmiccolis CreditAttribution: jmiccolis commentedLast patch had a small bug where it would over-write the resolutions immediately after writing them. This patches fixes that.
Comment #6
zzolo CreditAttribution: zzolo commented@jmiccolis, thanks for the patch. This looks pretty good except for the 900913 resolution hard-coded thing.
I think
openlayers_get_resolutions()
and how we manage resolutions could be handled better overall, but that is for another ticket, and @tmcw would probably have better insight on that.As for a current work around, we could utilize the CTools form API stuff to have dependencies for each projection and only present the relevant resolutions for each.
Comment #7
darksnow CreditAttribution: darksnow commentedThis is something I've been looking for in my map application.
When I get the time I'd be more than happy to help test this, what are the chances it will make it into the core OpenLayers Module?
The other thing I was planning on having a look at was AJAX capabilities. When the map is zoomed, or panned, the bounds and zoom level are passed to the appropriate views which in turn can load, using AJAX, the correct results using exposed arguments. Any pointers on where I could start looking, and sorry that this last paragraph went off to topic.
Keep up the good work, I'd be very keen to see this working and added.
Comment #8
tmcw CreditAttribution: tmcw commenteddarksnow:
This feature, abstractly, is a very high priority to get into the module, but not in the current patch-implementation. To be committed, we need to switch to storing limited zoom levels in the view configuration itself, so that there isn't a loose conglomeration of layer-views and view-views lying around as this solution ended up creating. There will also need to be smarter logic for choosing the resolutions array based on projection, because Views layers support any underlying projection
This problem has been in the works for a while. It's very complex - in terms of formats, in terms of performance, as far as handling views parameters and arguments correctly. It's possible to do something halfway by using the KML module, but that's far from optimal. In all, it'll probably take four or five days of work to get that kind of feature done.
Comment #9
darksnow CreditAttribution: darksnow commentedWell, that sounds encouraging.
Sorry to push, and I'd be more than happy to help, but what sort of time scale are we looking at for the zoom capabilities? If it's a high priority I assume somebody more qualified than me is already working on it?
As for the AJAX thing, four or five days doesn't sound so bad, I thought it was going to take a long time ;)
I've never written any modules but I have had a look at the code and made some rudimentary changes, so if you have any pointers of where I should start or where I should look, or any work already underway that I can add to, please let me know and I'll see what I can come up with.
Finally, and perhaps most importantly, what are the implications of Drupal 7 to all this work? Is there any point in doing all this if it's going to be obsolete when D7 is released or will features from this work be directly applicable to the D7 version of the OpenLayers module?
Comment #10
tmcw CreditAttribution: tmcw commentedIt's a high priority task, but there's nobody currently working on it. zzolo's in Italy and I'm currently on a few other projects and just trying to keep bugs down on this one. It'd be awesome if you want to look at it.
The jist is:
zoom levels should be stored in the options array of OpenLayers Data layers, and it'd be best if they're stored as 0-19 (or any specific zoom range) rather than 'resolutions'. A little backstory on resolutions: OpenLayers handles multiple projections (like EPSG:900913 and EPSG:4326, mainly), so it can't think of a pixel as a simple thing, or assume that a tile's pixel coordinates assign it to a certain lat/lon value. So there's a ton of abstraction when it comes to things like zoom levels. Thus resolutions - they're ratios between geographical units, like meters or degrees or minutes, to pixels. As such, they're kind of obscure. But they're the only reliable way to define resolutions in OpenLayers - otherwise the library tries to be 'too clever' and interpolate resolutions between your min and max.
So, the moral of the story is that the openlayers_get_resolutions() function should be used during the render() call of the layer to pull the 0-10 or 0-19 or 5-7 or whatnot zoom range from the Views options and turn it into a resolutions array, and then push that into the layer.
As far as AJAX: possibly that's a low estimate. I was thinking that it would take about 60 hours of a maintainer's time to really iron out the situation. It would be much more difficult to start from scratch with that kind of solution, but we should at least have a ticket about it.
Drupal 7: we're planning on doing a fast, semi-automated port of the module to Drupal 7 when it is released as a stable and starts to pick up adoption. There is very little functionality-wise that will change D6-D7, and porting now and integrating changes would be more difficult than having a stopping point and then push for a D7 port.
Comment #11
darksnow CreditAttribution: darksnow commentedOK, all that's clear. I work in marine navigation so I know a bit about geodetic and reference systems, it is interesting to see that some of the maps available don't use WGS84 as the GPS system and google maps does.
Anyway, my proposal for this is in two parts.
Firstly, I'd like to be able to set a max and min zoom level for each layer added to a given map. That way we could have the terrain map for the high level map of the world, then change to the satellite, or hybrid layers lower down, and have different views based layers for different zoom ranges for whatever reason.
Secondly, and more importantly, I'd like to have the views layers take the zoom level and current bounds as parameters and dynamically, with AJAX, show any markers or polygons that are in the given range. This would require a given node type to include CCK based max and min zoom fields, which would be mapped like the Location module's position fields are currently.
So, for non-AJAX layers, all markers are loaded but can be selectively removed from display in JavaScript, which will provide a performance boost in a lot of cases, but still requires loading all the data into the map at load time. But, for the AJAX maps, it will only load what is needed into the browser based in location and zoom level. Additionally, by combining these two, an AJAX layer which will not display anything at high zoom levels, for example, can be excluded from even being called, given further performance improvements.
So, two changes related to zoom levels, neither sounds trivial, but together could really help the OpenLayers module, especially when dealing with high numbers of markers.
Comment #12
tmcw CreditAttribution: tmcw commentedWhatever you can do in this direction would be very useful if it's stable and well-written. Currently I don't have the time to devote to these new features, which really constitute a great deal of investment.
Comment #13
darksnow CreditAttribution: darksnow commentedI know I've mention two future enhancements above, but I think I might have a solution to the limited zoom levels.
I've been putting together small JavaScript pages to test the internals of the OpenLayers API before trying to tackle anything Drupal specific and I made a small test page which automatically changes between the Hybrid and Physical Google maps at a certain zoom level.
This is achieved, I think, by limiting which zoom levels each of those Layers, neither as a base layer, are displayed.
There's not much to it but have a look at http://www.darksnow.net/test/map/zoom.html
My idea, through a read of the OpenLayers API, is to allow the resolutions arrays to be created as normal, which already works in the Drupal module, then set the min and max resolutions of the layers to the computed values from the resolutions array.
So, to limit a layer to be only shown between zoom levels 9 and 14, for example, you would set:
layer.minResolution = layer.resolutions[14]
layer.maxResolution = layer.resolutions[9]
It appears that the zoom levels are the wrong way round, max smaller than min, but it's the max and min numbers in the resolutions array, so makes sense.
Anyway, this seems to work and I thought might be a good fit for this patch, and side steps the resolutions issue. Though it does seem too simple to me, so maybe I've missed something.
Work continues so I may add another thread here for the AJAX thing.
Cheers.
Comment #14
zzolo CreditAttribution: zzolo commented"To be committed, we need to switch to storing limited zoom levels in the view configuration itself, so that there isn't a loose conglomeration of layer-views and view-views lying around as this solution ended up creating."
I think I am a little confused on this.
Wouldn't it make the most sense to have zoom level limitation settings in the layer definition itself, as the first patch suggests? A perfect example is the one @darksnow suggests above which are layers that are not Views Data Overlays, let alone logically it seems to make the most sense. The OL Views module could just have this option in the data layer options, and when producing those layers, just set the correct options. Maybe I am missing something?
Comment #15
tmcw CreditAttribution: tmcw commentedIt makes sense to store zoom levels in the views config, rather than in a layer instantiation, because the management of both views layers and layer objects that refer to views layers becomes horrible quickly. You create a OpenLayers Data view, clone the layer 'of it' in the OpenLayers module, and customize its zoom levels there. Now, when you export, you need to export both? If you rename the view, how does the layer object track it? If it's missing, what does it do? And, in the process, don't we just add to the annoyance involved with switching between the OpenLayers and Views UIs in order to create basic maps?
@darksnow, please open a new thread for the AJAX discussion, it's a much larger topic than this one.
Comment #16
darksnow CreditAttribution: darksnow commentedI tend to agree with zzolo on this one.
What if, for a given preset, you only wanted to use the layer for certain zoom levels?
The demo I put together above uses this limited zoom level technique to force that background layer (not really the base layer here) to change between two Google maps layers at a certain zoom level. Since we could have no control over a given layer it makes sense that either the layer configuration, or perhaps more sensibly, the preset that includes that layer, contains the zoom level limits.
As for views layers, where we will have this control. I think it does make sense to have the zoom levels part of the views definition, but I think it is far more important to keep things consistent, which again points to restricting zoom levels in the presets.
The other, AJAX, side of this is that the zoom level gets passed as an argument to views, which can filter their results as they see fit, but, as you say, that is a much bigger discussion for another thread.
Comment #17
tmcw CreditAttribution: tmcw commentedYou'd clone it and create a view with different zoom levels. Just as you'd do for any other kind of layer - you'd clone it. There's no efficiency or architectural win of cloning layers rather than views.
Comment #18
darksnow CreditAttribution: darksnow commentedIf you clone views for this so you not end up with loads of views that show the same data causing the loose conglomeration you wanted to avoid?
Seems to me that the view should get whatever data is needed, the display of that data is handled by a layer and how that layer is used is handled by presets. For views layers the zoom levels could go anywhere, but it seems most sensible to me to allow users to selectively apply zoom levels to any layer, view or not, depending on what is needed.
In short, it seems most sensible to set limited zoom levels in presets.
Comment #19
tmcw CreditAttribution: tmcw commentedI think we may be missing each other here: when you're referring to limited zoom levels in presets, you're talking about limited map zoom levels or layer zoom levels? The map's zoom levels are, of course, managed in presets, but layer zoom levels are managed in layers.
Not quite. If you have views and then 'layer instances' referring to those views, we end up with
n + 1
objects, whereas if we have zoom levels in views and duplicates of views displays (note that we're talking about displays - we don't need multiple views here), we end up with n objects.If you're arguing for people to be able to set layer zoom levels on a preset basis, then that's fine and is actually a reasonable feature request - I think that that hits a lot of bases. However, that isn't the system that's in place right now, for OpenLayers Data layers or any other layers, so it's not pertinent.
Comment #20
darksnow CreditAttribution: darksnow commentedPerhaps my terminology is off.
What you are saying above makes sense.
What I am arguing for is exactly as you say. We limit the zoom level of any given layer on a preset basis. While this is not how things are working now, it is what I was proposing to add, using the min and max resolution settings I've been looking at and described above. I think this would allow us to easily apply zoom levels, as map zoom levels, not resolutions, to restricting when a given layer appears on the map.
I hope that makes sense and that I've used the right terminology.
If my solution above, using the zoom levels as indexes into a computed resolutions array to get the min and max resolution, is a bit too hacky or just wrong, let me know and we'll see if we can come up with something better.
Comment #21
lucascaro CreditAttribution: lucascaro commentedI like this idea (#13)! When using this method, in my case, i had to set layer.alwaysInRange to false to make it work.
Comment #23
zzolo CreditAttribution: zzolo commentedI think this is still a valid feature request. Moving to D7. This will not have high priority until we can push out a 2.0 (eventually :). Also, this issue will probably be related: #818302: Abstract out layer types
Comment #24
zzolo CreditAttribution: zzolo commentedChanging this into a general issue about zoom level restrictions. In theory, regardless of technological issues, we should be able to have both preset/map level zoom restrictions and layer level zoom restrictions.
Here is a duplicate issue: #887904: Provide a map (preset) level zoom restriction option
Also, check out this OL page for some background: http://trac.osgeo.org/openlayers/wiki/SettingZoomLevels
Comment #25
Summit CreditAttribution: Summit commentedSubscribing, greetings, Martijn
Comment #26
dawnlight CreditAttribution: dawnlight commentedopenlayers_vector_zoom_level_range.patch queued for re-testing.
// ======
It seems not to work for me when I overwrote the default OpenLayers_Views (I can't reach the zone limit option without overwriting it).
Any hint?
Thanks.
// ======
I found that it works for the views layer, but not for the map. Herhaps it's the problem of wrong setting with the PanZoomBar (behavior, herhaps the navigate mouse scroll too).
It can also be changed by directly adding "minZoomLevel" to options_init() function in includes/layer_types/xxx.inc. But adding a value input option in backoffice and load it when initialization is better.
Sorry for having reported a wrong message yesterday.
Comment #28
omasal CreditAttribution: omasal commentedopenlayers_vector_zoom_level_range.patch queued for re-testing.
Comment #29
katbailey CreditAttribution: katbailey commentedHey All,
I'm pretty new to OpenLayers but I do need this functionality for a client site I'm working on. In my case, I need to be able to prevent a particular views-based vector layer from rendering until a certain zoom level is reached. The solution I've come up with so far is to add a new behavior plugin that allows this. I'll most likely just add this behavior plugin in a custom module, but thought I'd just attach it as a patch to the openlayers module here to get feedback from others who've been thinking about this issue. It is by no means perfect but it seems to work for my purposes. Here's a screenshot of how you configure it in the behaviors section of your map: https://skitch.com/katbailey/g55ji/openlayers-zoom-levels-per-layer
Katherine
Comment #30
katbailey CreditAttribution: katbailey commentedMeh, there's no actual performance gain with this approach, which is what I'm really looking for. Going to look into ajax-loading the layers.
Comment #31
zzolo CreditAttribution: zzolo commentedHEy @katbailey. What were your findings here?
Comment #32
katbailey CreditAttribution: katbailey commentedWell, the fact that the data was still being loaded to the page even though it wasn't being rendered at the higher zoom levels meant it was still really slow with large amounts of data.
So I wrote a sandbox project called OpenLayers BBox: http://drupal.org/sandbox/katbailey/1445310
Here's the description from the sandbox project page:
Provides a GeoJSON BBox layer type plugin for the OpenLayers module, which uses the BBox layer strategy provided by the OpenLayers js library for loading only the features of the layer that lie within the current bounding box. It also provides a behavior plugin which permits the activation of the strategy based on zoom level.
Comment #33
Countzero CreditAttribution: Countzero commentedI find it difficult to understand the status of this. I came here searching for a solution to limit the maximum zoom level for all maps on the site, and I see you people are talking about much more complex issues like performance and clustering et al.
Also, this thread is now 7.x-3.x oriented.
Is there a solution somewhere, even a stupid and ugly one, to limit the max zoom level of a map in 7.x-2.x using gmap type layers ? Sorry if I'm in the wrong place to ask.
EDIT :
Kind of found it : As per this, I overrode the value returned by getNumZoomLevels in OpenLayers.js from numZoomLevels to a plain 12 at line 505 (V 2.11). Ugly but works if you want a sitewide max zoom level.
Comment #34
japo32 CreditAttribution: japo32 commentedHi, I'm trying to make this patch into a module. It's enabled and I can see the interface in the Behaviors tab.
Then I set the zoom levels and check the "Enable dymamic zoom levels for this layer" box.
When I save nothing happens to the map. Did I miss something?
attached is the module.
I think this would be an awesome addition to the openlayers behaviors collection.
Comment #35
japo32 CreditAttribution: japo32 commentedUPDATE:
I managed to make it work. I'll attach the module for the next guy like me who needs this feature.
Comment #36
PolI think this could go in a patch and included in OpenLayers!
Comment #37
japo32 CreditAttribution: japo32 commentedI recently installed the dev version for D7 and found that it's already part of the code. :p
Comment #38
PolComment #40
treckstar CreditAttribution: treckstar commentedHi everyone, ran into a situation where I needed to use the module linked in #35 by japo32. The module works great, thanks dude!
In the version of OpenLayers I was using (7.x-2.0-beta3), ran into this little bug.
http://drupal.org/node/1876702
After several patches not applying to fix this bug, I opted to use the OpenLayers (7.x-2.x-dev) release. Everything was good until I ran into this message with the japo32's module.
"There's a problem in the definition of the behavior !behavior. The behavior will be disabled."
This is because some fields are mandatory for behaviors.
http://drupalcode.org/project/openlayers.git/blob/91523146d6a31b11b8daa2...
I made the changes to the module japo32 wrote to comply with this definition check. The attached file works with the dev release.
Hope this helps anyone who ended up in the same situation as me.
Comment #41
PolI like a lot :-)
I'll include it in the next dev version !
Many thanks !
Comment #42
PolHello @Treckstar,
I've tried the script on my local install and I do not find a way to get it working, could you explain a working use case so I can test it myself ?
thanks !
Comment #43
PolOk I got it working.
This is not about limiting zoom level for layers and maps, it's about limiting the display of features only.
Committed in 7.x-2.x: http://drupalcode.org/project/openlayers.git/commit/7709de5
Comment #45
basvredelingFYI, for views_geojson I've created a custom views argument handler which allows you to return no results if the zoom argument doesn't meet certain criteria (for instance: zoom > 5). The current solution for this issue doesn't display layers for specific zoom ranges, but it does load the data. To minimise the data on requests of hidden layers, use the aforementioned argument handler as inspiration: #2813059: Zoom argument handler