Display WMS Layer Based on Zoom Level - javascript

I've been at this all day long and honestly I'm out of ideas. I have some WMS layers that I would like to display/not display depending on the current zoom level. Yes, I have went through the API docs and they seem to be clear as day, but I follow everything that is suggested and I'm not getting the results desired :(
This was one of the sources that I looked at:
http://trac.osgeo.org/openlayers/wiki/SettingZoomLevels
Then to make matters even worse I found out that if you have an Open Street Map base layer displaying on load it seems to limit your control over the map's numZoomLevels, just what I needed, since I DO want to use this as my loading base layer...
So my questions are:
What am I doing wrong?
Is it true that there really is no workaround on the control of zoom levels when using an Open Street Map base layer on load? Or is there something I just don't know?
Here are some of my code attempts:
Take 1: tib_villages layer should only show when the zoom level is 8-10, doesn't work!
var options = {
controls: [new OpenLayers.Control.Navigation()], //Needed to use GeoExt controls such as the zoomslider
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
units: 'm',
numZoomLevels: null, //setting the map's zoom levels to null
allOverlays: false
}
var osm = new OpenLayers.Layer.OSM(); //MY base layer
//MY overlay layer
var tib_villages = new OpenLayers.Layer.WMS(
"Villages", "http://localhost:8080/geoserver/wms", {layers: 'cite:tib_villages', transparent: true, numZoomLevels: 10, minZoomLevel: 8}, {isBaseLayer: false, displayInLayerSwitcher: true, visibility: true}
);
Take 2: tib_villages layer should only show when the zoom level is 8-10, map should only have 10 zoom levels, but instead has 19 as the Open Street Map Layer enforces it to, doesn't work!
var options = {
controls: [new OpenLayers.Control.Navigation()], //Needed to use GeoExt controls such as the zoomslider
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
units: 'm',
numZoomLevels: 10, //setting the map's zoom levels to 10 only
allOverlays: false
}
var osm = new OpenLayers.Layer.OSM(); //MY base layer
//MY overlay layer
var tib_villages = new OpenLayers.Layer.WMS(
"Villages", "http://localhost:8080/geoserver/wms", {layers: 'cite:tib_villages', transparent: true, numZoomLevels: null, minZoomLevel: 8}, {isBaseLayer: false, displayInLayerSwitcher: true, visibility: true}
)
;
Take 3: After getting rid of the Open Street Map base layer on load, the map only has 10 zoom levels as specified, but tib_villages layer should only show when the zoom level is 8-10, doesn't work!
var options = {
controls: [new OpenLayers.Control.Navigation()], //Needed to use GeoExt controls such as the zoomslider
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
units: 'm',
numZoomLevels: 10, //setting the map's zoom levels to 10
allOverlays: false
}
//MY overlay layer
var tib_villages = new OpenLayers.Layer.WMS(
"Villages", "http://localhost:8080/geoserver/wms", {layers: 'cite:tib_villages', transparent: true, numZoomLevels: 10, minZoomLevel: 8}, {isBaseLayer: false, displayInLayerSwitcher: true, visibility: true}
);
All of your suggestions are sincerely appreciated!
elshae

Try to use minResolution and maxResolution instead of minZoomLevel. It usually works fine. You can get resolution for any zoom lever if you call map.getResolution() method.
Another option is to listen to OpenLayers.Map's zoomend event and toggle layer visibility accordingly. Something like this:
map.events.on({ "zoomend": function (e) {
if (this.getZoom() > 2) {
layer1.setVisibility(false);
layer2.setVisibility(true);
}
else {
layer2.setVisibility(false);
layer1.setVisibility(true);
}
}
});

I would recommend using the maxScale and minScale on the layers instead of resolution, but that maybe is a question of taste. :-) I can't relate to a resolution value, but a scale is easy to understand and to maintain in the longer run, when others look at your code.

Related

openlayers 3: don't zoom in outside the image

I'm using openlayers to create a map of a body. It shows the mri-scan of a person en on there are a lot of markers.
Totally zoomed out, there's a lot of whitespace (or in my case black space as the background is black) I've set up openlayers with the extent parameter, so users are not able to pan further than the image is big. However when the user hovers over the whitespace around it, and scrolls to zoom, the image is zoomed into based on the position of the cursor, so the body is out of view. Once the user starts panning again, the extent comes in to play and jumps back to the edge of the image.
Is there a way to disable zooming in/out when the cursor is outside the extent? Or if that is not possible, how can I trigger a move/pan so it jumps automatically to the edge of the image?
EDIT 14/12/2016: Created a JSFiddle to illustrate the issue.
And the code that is running there:
var pbm = {};
pbm.vars = {};
pbm.vars.extent = [0, 0, 1536, 5120];
pbm.vars.projection = new ol.proj.Projection({
code: 'xkcd-image',
units: 'pixels',
extent: pbm.vars.extent
});
/**
* initMap
* --------
* triggered by pbm.parseCases!
* outputs the bodymap to the #body-div
* this functions needs all the other ol-elements to work!
*/
pbm.initMap = function(){
pbm.map = new ol.Map({
layers: [
new ol.layer.Image({
source: new ol.source.ImageStatic({
url: 'https://s3-eu-west-1.amazonaws.com/norvell-philips/bodymap-static-hiress.jpg',
projection: pbm.vars.projection,
imageExtent: pbm.vars.extent
})
})
],
target: 'body',//Div#body
view: new ol.View({
projection: pbm.vars.projection,
center: ol.extent.getCenter(pbm.vars.extent),
zoom: 2,
maxZoom: 5,
minZoom: 1,
extent: pbm.vars.extent
}),
renderer: 'canvas',
controls: ol.control.defaults({attribution:false, rotate: false, zoom:false}),
interactions: pbm.vars.interactions
});
}
$(document).ready(function(){
pbm.initMap();
});
This is a bug that was recently fixed. The first release to contain the fix will be v3.21.0. The ticket with links to the fixes is #5824.

I don't want my Google Map to zoom to extent after user has zoomed in

I have created a map found here: http://userpages.flemingc.on.ca/~eluli/collab.html
Users can toggle between the different layers on the map. As you can see, whenever a user toggles at a new layer, the map extents to the new layer. How can I make so that this does NOT happen? For example, if a user has zoomed into a specific area, I want the map to remain at the same extent whenever a new layer is checked on.
I have written code which has the initial map extents (I deleted the extent in order to experiment but when I did that, the map does not show up).
function initialize() {
var ontario = new google.maps.LatLng(49.2867873, -84.7493416);
var mapOptions = {
zoom: 5,
center: ontario,
styles: ....
var kmlOptions = {
suppressInfoWindows: true,
preserveViewport: false,
map: map
};
//Layer 0
layers [0] = new google.maps.KmlLayer('https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkVGVwdnEtS1puTlE&export=download',
{preserveViewport: false, suppressInfoWindows: true});
//Layer 1
layers [1] = new google.maps.KmlLayer('https://docs.google.com/uc?authuser=0&id=0B79b02nBK5vkdE9DRmxzRHdCN28&export=download',
{preserveViewport: false, suppressInfoWindows: true});
.........................
Let me know if I need to show more of my code
{preserveViewport: true} will keep KmlLayer from zooming to fit its contents

OpenLayers WMS layer doesn't load

I use the following block of JavaScript to try to show a WMS layer. I'm using OpenLayers 2.8.
The map's base layer (Openstreetmap) shows correctly, it zooms to the correct area, the "pyramid" layer is shown in the layer switcher, but no request to its WMS service is ever made (so the fact that the URL, styles and params are dummies shouldn't matter -- it never even attempts to get them).
OpenLayers does try to get a WMS layer once I pan or zoom far enough so that the Gulf of Guinea is in view (but all my data is in the Netherlands). This suggests a projection problem (WGS84's (0, 0) point is there), but I don't understand why OpenLayers doesn't even try to fetch a map layer elsewhere. My data is in EPSG:3857 (Web Mercator) projection.
/*global $, OpenLayers */
(function () {
"use strict";
$(function () {
$(".map").each(function () {
var div = $(this);
var data_bounds = div.attr("data-bounds");
console.log("data_bounds: " + data_bounds);
if (data_bounds !== "") {
var map = new OpenLayers.Map(div.attr("id"), {
projection: "EPSG:3857"});
var extent = JSON.parse(data_bounds);
var bounds = new OpenLayers.Bounds(
extent.minx, extent.miny,
extent.maxx, extent.maxy);
map.addLayer(
new OpenLayers.Layer.OSM(
"OpenStreetMap NL",
"http://tile.openstreetmap.nl/tiles/${z}/${x}/${y}.png",
{buffer: 0}));
map.addLayer(
new OpenLayers.Layer.WMS(
"pyramid", "http://rasterserver.local:5000/wms", {
layers: "test",
styles: "test"
}, {
singleTile: true,
isBaseLayer: false,
displayInLayerSwitcher: true,
units: 'm'
}));
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.zoomToExtent(bounds);
}
});
});
})();
Edit: the 'data_bounds' console print prints (with some added formatting):
data_bounds: {
"minx": 582918.5701295201,
"miny": 6923595.841021758,
"maxx": 821926.9006116659,
"maxy": 7079960.166533174
}
It zooms to the correct region in the north of the Netherlands, so I don't think the problem is there.
Since posting, I found out that if I don't use the OSM layer, and instead use the WMS layer as baselayer, it works. So perhaps there's some incompatibility with a OSM baselayer and a WMS layer added to it? But then I don't get that it does seem to do something near WGS84 (0, 0).
I eventually managed to fix this by giving the map an explicit maxExtent:
var extent = JSON.parse(data_bounds);
var bounds = new OpenLayers.Bounds(
extent.minx, extent.miny,
extent.maxx, extent.maxy);
var map = new OpenLayers.Map(div.attr("id"), {
projection: "EPSG:3857",
maxExtent: bounds
});
Oddly enough this doesn't limit the user's ability to pan and zoom around the world, but it does make the overlay work...

Viewing vector overlay in an OpenLayers Map

I am new to creating maps using HTML and I have been attempting to add two vector layers (places, points) to a base map (roads), however I cannot see the vector layers on the map. The layers should appear as vector overlays to the base map. The layers are there as they are being shown in the layer switcher, but are not being displayed on screen. I believe the problem is to do with the way the vectors layers are being called. What is the solution to get the vector layers to be displayed. Thanks
var map = new OpenLayers.Map("map-id");
var roads= new OpenLayers.Layer.WMS(
"roads",
"http://localhost:8080/geoserver/wms",
{layers: "roads"});
var points= new OpenLayers.Layer.Vector(
"points",
"http://localhost:8080/geoserver/wms",
{layers: "points"});
var places= new OpenLayers.Layer.Vector(
"places",
"http://localhost:8080/geoserver/wms",
{layers: "places"});
map.addLayer(roads);
map.addLayer(points);
map.addLayer(places);
map.addControl(new OpenLayers.Control.LayerSwitcher());
You are trying to display your vector data through WMS protocol. For this purpose you should use OpenLayers.Layer.WMS instances instead OpenLayers.Layer.Vector. For displaying WMS layer as overlay use isBaseLayer option:
map = new OpenLayers.Map('map');
var places = new OpenLayers.Layer.WMS('places',
"http://localhost:8080/geoserver/wms",
{layers: "places", transparent: true},
{isBaseLayer: false, opacity: 1, singleTile: true, visibility: true}
);
map.addLayers([places]);

Targeting and/or modifying a KML region in OpenLayers

I've built several Javascript applications for map charts using google maps, and I was hoping to recreate these in OpenLayers. I'm finding the documentation on their site pretty confusing and tough to navigate.
So far, I'm able to load in my KML, using the following code:
var map = new OpenLayers.Map({
div: divName,
layers: [
new OpenLayers.Layer.OSM(),
new OpenLayers.Layer.Vector("KML", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "data.kml",
format: new OpenLayers.Format.KML({
extractStyles: true,
extractAttributes: true,
maxDepth: 4
})
})
})
],
zoom: 4
});
map.setCenter(
new OpenLayers.LonLat(-97, 38).transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), 4
);
What I'd like to do is be able to modify or target the individual KML regions. For example, just attaching a click event, or changing the background color of the region.
I've looked around and can't seem to find a good example.
I have jQuery loaded also if that helps.
Any help would be greatly appreciated.
You could add events to OpenLayers maps using the OpenLayers.Control.SelectFeature object
To change the background of the objects something like this should work
var myVectorLayer = map.getLayersByName("KML")[0];
var highlightCtrl = new OpenLayers.Control.SelectFeature(myVectorLayer , {
hover: true,
highlightOnly: true,
renderIntent: "temporary"
});
var selectCtrl = new OpenLayers.Control.SelectFeature(myVectorLayer ,
{clickout: true}
);
map.addControl(highlightCtrl);
map.addControl(selectCtrl);
To fire further events / get more details from the selected features you can employ
myVectorLayer.events.on({
"featureselected": function (e) {
alert(e.type + " - " + e.feature.id);
}
});

Categories

Resources