Hide layer or features on zooming in openlayers 3? - javascript

Is it possible to hide all features on a layer when zooming occurs? I've tried to set both the visible and opacity properties on the layer itself to now show when zooming. Also i've tried to set style on each feature to 'none' but it dosen't seem to work. I've tried with these two alternatives:
1.
function hideGraphicsFeatures(hide) {
if(hide) {
graphicsLayer.setVisible(false);
} else {
graphicsLayer.setVisible(true);
}
map.render();
}
2.
function hideGraphicsFeatures(hide) {
var features = graphicsLayer.getFeatures();
if(hide) {
for (var i = features.length - 1; i >= 0; i--) {
features[i].style.display = 'none';
};
} else {
for (var i = features.length - 1; i >= 0; i--) {
features[i].style.display = ''; // show. Set to anything but 'none'
};
}
map.render();
}

I believe I know what you are looking for. I had to do something similar to improve the zoom/pan performance when tens of thousands of features on many layers were displayed on the map. For panning I set the layers' visibility to false when the first map 'pointerdrag' event is triggered and set them back to visible in the 'moveend' event (you may need some additional handling to avoid redundant actions and data reloads).
For zooming it is a bit trickier but fortunately you can override the ol.interaction.MouseWheelZoom handler by using a custom function:
ol.interaction.MouseWheelZoom.handleEvent = myFunction(evt){
// here you set the layers to invisible and set the new map zoom level
// based on the event's wheel value...
}
After that in the 'zoomend' event handler you make the layers visible. If you just use buttons to zoom in/out then it's easy to hide/show the layers.
It worked for me and it is a good workaround in some situations.

Try:
function zoomChanged() {
zoom = map.getZoom();
if (zoom >=15) {
graphicsLayer.setVisibility(true);
}
else if (zoom < 15) {
graphicsLayer.setVisibility(false);
}
}
And then call that function using:
map.events.register("zoomend", map, zoomChanged);
Where "map" is the variable of your map initialization. Combined, these toggle a layer's visibility on and off based on your zoom level. If that's not exactly what you're going for, you could use a different indicator in the if/else block. I think you were just missing the event handler.

maybe you can do this one.
But, sorry if this can't help you.
function showGraphic () {
$('#Graphic1').hide();
$('#Graphic2').show(2000);
$('#Graphic3').hide();
$('#Graphic4').hide();
}

Related

Openlayers zoom-based object visibility not working

I would like to have my element zoom-based. I don't need it visible when zooming out of 19, because my map doesn't look nice.
I tried to use the maxResolution method derived from the layers.js file, when it was found, as a whole map was generated by the QGIS2web plugin.
Unfortunately it wasn't working
I tried also the minZoom feature, but in vain.
All the reasonable examples I found here:
https://openlayers.org/en/latest/apidoc/module-ol_View.html
https://openlayers.org/en/latest/examples/layer-zoom-limits.html
https://github.com/Viglino/ol-ext/issues/51
Another thread says about changing the maxResolution value, but it didn't work either.
https://gis.stackexchange.com/questions/160725/vector-layer-visibility-using-min-maxresolution-is-not-working-in-openlayers-2
Finally, my code looks as follows:
var tekst2 = new ol.Overlay({
position: pos3,
minZoom: 19,
element: document.getElementsByClassName('tekscio')[1],
});
map.addOverlay(tekst2);
I see, that the minZoom refers mostly for the lower zoom limit of the map canvas.
But this configuration:
var tekst2 = new ol.Overlay({
position: pos3,
element: document.getElementsByClassName('tekscio')[1],
maxResolution:0.42006699228392946,
});
map.addOverlay(tekst2);
didn't work either.
I also found some methods here:
http://dev.openlayers.org/releases/OpenLayers-2.13.1/doc/apidocs/files/deprecated-js.html
http://dev.openlayers.org/docs/files/OpenLayers/Layer/FixedZoomLevels-js.html#OpenLayers.Layer.FixedZoomLevels.getOLZoomFromMapObjectZoom
but it looks like they have been deprecated.
What should I do in this code? Is there another thing to provide here, which I am missing?
I want to have this text based on the zoom level.
Just in case I am sending the JS fiddle with the javascript code here:
https://jsfiddle.net/uxkcyomf/
I would like to have my element zoom-based. I don't need it visible when zooming out of 19, because my map doesn't look nice.
You can simply show/hide an element depending on the current zoom level in a way similar to this (the zoom change handler was taken from https://gis.stackexchange.com/a/309404/70847):
var currZoom = map.getView().getZoom();
map.on("moveend", function(e) {
var newZoom = map.getView().getZoom();
if (currZoom != newZoom) {
if (newZoom > 19) {
document.getElementById("vienna").style.display = "none";
} else {
document.getElementById("vienna").style.display = "unset";
}
currZoom = newZoom;
}
});

How to use zoomFactor on ZoomControls in AmCharts V4

Hello I want to use larger zooming factors via the ZoomControl Buttons.
How is that possible in AmCharts (Maps) Version 4?
I could find an old documentation which describes my wanted feature:
https://docs.amcharts.com/javascriptmaps/ZoomControl (zoomFactor)
In the new docs I can only find it in "components".
The only way I think I could make it work is listening into the "hit" event on the zoomControl Button, then determine if it was a positive(zoomIn) or negative(zoomOut) event and zoom manually the Chart because the Chart extends the Component which contains the zoomFactor im looking for.
amCharts 4.0.14+: chart.zoomStep
With amCharts 4.0.14+ a MapChart.zoomStep has been implemented which is precisely what you're looking for. As of this writing (January 2, 2019), it is not yet documented except in the changelog.
All you would have to do is:
chart.zoomStep = 3;
Our Zooming to Countries Map demo's default zoomStep is 2. Here's a fork where it's 3:
https://codepen.io/team/amcharts/pen/d454553836da95fe2345a608e1a0efbd
amCharts <= 4.0.13: custom "zoom factor"
If you're referring to Component.zoomFactor, then all charts have this property. Even though it's called zoomFactor, it's not what you're thinking, also, it's read-only anyway.
Unfortunately what you describe as a "zooming factor" cannot be overridden, the buttons basically zoomIn() and zoomOut(), within those methods a zooming factor of 2 is hardcoded. Listening in on the "hit" event wouldn't work because you'd have competing zoom events. If you disabled the original "hit" event and made your own, there is still additional helper logic for keyboards for accessibility purposes, so your custom event and these helpers will have inconsistent zoom factors. So what can be done is to kill the default plusButton and minusButton and roll your own.
To disable them just set their .disabled property to true:
chart.zoomControl.plusButton.disabled = true;
chart.zoomControl.minusButton.disabled = true;
Then we'll make our own versions of the buttons also as children of the ZoomControl container and place them before/after its slider to simulate the original buttons:
var plusButton = chart.zoomControl.createChild(am4core.Button);
plusButton.shouldClone = false;
plusButton.label.text = "+";
plusButton.width = am4core.percent(100);
plusButton.padding(5, 5, 5, 5);
plusButton.marginBottom = 2;
plusButton.insertBefore(chart.zoomControl.slider);
var minusButton = chart.zoomControl.createChild(am4core.Button);
minusButton.shouldClone = false;
minusButton.label.text = "-";
minusButton.width = am4core.percent(100);
minusButton.padding(5, 5, 5, 5);
minusButton.marginTop = 1;
minusButton.insertAfter(chart.zoomControl.slider);
Then we'll provide "hit" events on the buttons that zoom in/out with our own zooming factor (customZoomFactor below):
var customZoomFactor = 3; // default: 2
plusButton.events.on("hit", function() {
chart.zoomToGeoPoint(
chart.zoomGeoPoint,
chart.zoomLevel * customZoomFactor,
false
);
});
minusButton.events.on("hit", function() {
chart.zoomToGeoPoint(
chart.zoomGeoPoint,
chart.zoomLevel / customZoomFactor,
false
);
});
Here's a fork of our Zooming to Countries Map demo that incorporates all of the above code:
https://codepen.io/team/amcharts/pen/f358095c9ea00d875049b67a7bd13df4

OpenLayers DrawFeature control with Point destroys double click to zoom

I have some simple code that I copied from one of the openlayers examples for drawing several different types of geometries on the map. The problem is, whenever the "point" geometry is selected, I lose the ability to double-click to zoom in. The only difference between the examples and my code is I'm registering the handlers to use MOD_SHIFT, because i want to retain the ability to pan/zoom. Here is a snipit of code:
point: new OpenLayers.Control.DrawFeature(this.geometryFilterLayer,
OpenLayers.Handler.Point,
{
'done': console.info("drew point")
},
{
keyMask: OpenLayers.Handler.MOD_SHIFT
}
),
polygon: new OpenLayers.Control.DrawFeature(this.geometryFilterLayer,
OpenLayers.Handler.Polygon,
{
'done': console.info("drew polygon")
},
{
keyMask: OpenLayers.Handler.MOD_SHIFT
}
),
The funny thing about the above code is, the 'done' event only gets fired when the control/handler is created, and the keyMask doesn't work at all -- I have to loop through this object and manually set the keyMask each time, but that's not the real problem at hand.
I've tried every way I can think of to register a dblclick event, but no matter what, I can't get it to zoom in when I double click. It works fine on all the other geometries (bbox, point/radius, and polygon).
Can anybody give me some advice?
I never solved this issue, but ended up doing away with using MOD_XXX altogether. Each different draw control had too much built-in functionality for what happens when you hold shift, ctrl, alt, etc. I ended up using custom Buttons and a toolbar, that way the user can explicitly select the drawing control themselves.
this.toolbar = new OpenLayers.Control.Panel({
displayClass: 'olControlEditingToolbar'
});
map.addControl(this.toolbar);
var navButton = new OpenLayers.Control.Button({
displayClass: "olControlNavigation",
title: "Navigation",
trigger: lang.hitch(this, function(data){
this.toggleDrawControl("navigation");
navButton.activate();
pointButton.deactivate();
bboxButton.deactivate();
pointRadiusButton.deactivate();
polygonButton.deactivate();
})
});
...
this.toolbar.addControls([navButton, pointButton, bboxButton, pointRadiusButton, polygonButton]);
and my function to toggle draw controls (can be called externally, so that's why I re-call the activate and deactivate functions:
toggleDrawControl: function(geometryType){
this.currentGeometryType = geometryType;
for(key in this.drawControls) {
var control = this.drawControls[key];
if(geometryType == key) {
control.activate();
this.drawingButtons[key].activate();
} else {
control.deactivate();
this.drawingButtons[key].deactivate();
}
}
}

Multitouch Pinch, Pan, Zoom in HTML 5 Canvas

I have most of a module written to handle multitouch pinch, pan and zoom on an HTML 5 canvas element. I will share it below. I've been developing in JavaScript for some time now, and this one continues to boggle me. If anybody has any insights, I will post the final version up on stack for everybody to share once it is confirmed working on my iPad.
Here is what I am doing:
touchmove events trigger the changing of variables. I use these variables to change the way in which my image is painted onto the canvas. I have eight variables, each corresponding to the options that can be put into the drawImage() function. These eight variables get updated through functions that increment/decrement their values and keep them within a certain range. The variables are closure variables, so they are global throughout my module. To prevent over-processing, I make a call to this drawImage() function once every 40ms while the user has their finger pressed to the screen using a setInterval().
Here is the problem:
touchmove events seem to be causing a race condition where my variables get updated by many different instances of that same event. I can somewhat confirm this through my console output, that tracks one variable that is bounded to never reach below 20. When I swipe in one direction quickly, that variable dips down far below 20. Then when I release my finger, swipe slowly, it returns to 20. Another thing that points me in this direction, when I look at these variables while stepping through my program, they differ from what my console.log() pumps out.
Note: The code successfully draws the image the first time, but not anytime thereafter. A basic rendition of my code is below... The full version is on GitHub inside the Scripts folder. It is a Sencha Touch v1.1 app at heart
function PinchPanZoomFile(config)
{
/*
* Closure variable declaration here...
* Canvas Declaration here...
*/
function handleTouchStart(e) {
whatDown.oneDown = (e.originalEvent.targetTouches.length == 1) ? true : false;
whatDown.twoDown = (e.originalEvent.targetTouches.length >= 2) ? true : false;
drawInterval = setInterval(draw, 100);
}
function handleTouchEnd(e) {
whatDown.oneDown = (e.originalEvent.targetTouches.length == 1) ? true : false;
whatDown.twoDown = (e.originalEvent.targetTouches.length >= 2) ? true : false;
clearInterval(drawInterval);
}
function handleTouchMove(e) {
if(whatDown.twoDown) {
/*
* Do Panning & Zooming
*/
changeWindowXBy(deltaDistance); //deltaDistance
changeWindowYBy(deltaDistance); //deltaDistance
changeCanvasXBy(deltaX); //Pan
changeCanvasYBy(deltaY); //Pan
changeWindowDimsBy(deltaDistance*-1,deltaDistance*-1); //(deltaDistance)*-1 -- get smaller when zooming in.
changeCanvasWindowDimsBy(deltaDistance,deltaDistance); //deltaDistance -- get bigger when zooming in
} else if(whatDown.oneDown) {
/*
* Do Panning
*/
changeWindowXBy(0);
changeWindowYBy(0);
changeCanvasXBy(deltaX);
changeCanvasYBy(deltaY);
changeWindowDimsBy(0,0);
changeCanvasWindowDimsBy(0,0);
}
}
function draw() {
//Draw Image Off Screen
var offScreenCtx = offScreenCanvas[0].getContext('2d');
offScreenCtx.save();
offScreenCtx.clearRect(0, 0, canvasWidth, canvasHeight);
offScreenCtx.restore();
offScreenCtx.drawImage(base64Image,
parseInt(windowX),
parseInt(windowY),
parseInt(windowWidth),
parseInt(windowHeight),
parseInt(canvasX),
parseInt(canvasY),
parseInt(canvasWindowWidth),
parseInt(canvasWindowHeight)
);
//Draw Image On Screen
var offScreenImageData = offScreenCtx.getImageData(0, 0, canvasWidth, canvasHeight);
var onScreenCtx = canvas[0].getContext('2d');
onScreenCtx.putImageData(offScreenImageData, 0, 0);
}
}
I strongly recommend using Sencha Touch 2.0.1, as it supports a lot of the touch events you need. See http://dev.sencha.com/deploy/touch/examples/production/kitchensink/#demo/touchevents for examples.

Google Maps V3 fitBounds zooms to a closer view when called a second time with the same bounds

function ZoomCenter(bounds, canvas)
{
var center = bounds.getCenter();
if (canvas.getMapTypeId() == "roadmap") canvas.fitBounds(bounds);
else
{
var maxZoomService = new google.maps.MaxZoomService();
maxZoomService.getMaxZoomAtLatLng(center, function(response)
{
if (response.status != google.maps.MaxZoomStatus.OK) alert("Error in Google MaxZoomService");
else
{
var max_zoom = (response.zoom > SATMAP_MAX_ZOOM) ? SATMAP_MAX_ZOOM : response.zoom;
canvas.setOptions( { maxZoom: max_zoom } );
canvas.fitBounds(bounds);
canvas.setOptions( { maxZoom: SATMAP_MAX_ZOOM} );
}
});
}
}
This first time this is called it zooms to 1 less than what will fit on the map. The second time and and every time after the first it will zoom to the correct level using the exact same bounds data.
Is there a bug in fitBounds? or am I missing something?
Without seeing more code and having never experienced this quirk myself, it's difficult to say. However I am always more suspicious that there is a bug in my own code than in Google's, so I would eliminate the obvious possibilities there first.
Therefore, the first thing I would do is use a JS debugger to confirm that:
bounds is identical both times
it's going through the same execution path hitting the same canvas.fitBounds(bounds) call both times. (You have it in there twice. Which one gets executed depends on your conditional involving MapTypeId. If canvas has a different MapTypeId each time through, that could be causing the quirk.)
If that doesn't turn up the problem, the next place to look might be the Google Maps API issue tracker.

Categories