Leaflet: How can I veto turning on an overlay layer? - javascript

My leaflet app has two overlay layers. One of them has a lot of data, so that if the user selects it when not zoomed in pretty far, there is too much data to display without severely impacting the performance of the app (and the data is not useful at wide zoom levels anyway).
So when the user selects the layer in the layer control, the app checks how much data would be displayed at that zoom level. If it's beyond a certain threshold, an alert is given that they need to zoom in more to turn on that layer. The app has essentially vetoed the layer selection, but there seems to be no way to uncheck the checkbox input so that the UI is in sync with the internal state of the app wrt the activation of that layer.
I can programmatically remove the layer altogether, but I don't see any way to uncheck the checkbox input for the layer. Even a brute force approach by getting the layer control HTML container and walking the DOM doesn't seem to be feasible, as there are no IDs or unique attribute values that I can use to get a reference to the checkbox for the desired layer. I also tried removing the layer and re-adding it, but it comes back still checked.
Is there a way to programmatically uncheck the layer checkbox?
EDIT: Here's how I'm creating the overlay layer:
baseMaps = ...
map = ...
myBaseLayer = ...
myOverlayLayer = L.featureGroup();
myOverlayLayer.id = "theId";
let overlayMaps = {
"Base Objects": myBaseLayer,
"Overlay Layer": myOverlayLater
}
L.controlLayer.layers(baseMaps, overlayMaps).addTo(map)

Programmatically removing / adding your layer from/to map should automatically untick/tick the checkbox in the default Leaflet Layers Control.
What you describe sounds to need usage of minZoom option on your overlay layer. If I remember correctly it should also automatically reflect in the Layers Control when the layer is removed due to minZoom threshold.

Related

How to activate multiple L.markerClusterGroup() using L.control.layers in leafletjs, instead of just toggling? [duplicate]

Is there an easy way to make a leaflet layers control (L.control.layers) use checkboxes rather than radio buttons?
I have multiple WMS tile layers, and I'd like to be able to have more than one on the map at the same time. For context, the WMS tile layers include bathymetry and contours (topo lines), so it'd be more informative to visualize both at the same time, rather than just having some lines floating in the ocean.
In the leaflet example it says the layers control is "smart enough" to know which to assign radio buttons and which checkboxes, but it'd be nice to have more customized control.
Relevant code:
L.control.layers(WMS, null, {collapsed: false}).addTo(map);
where WMS is multiple L.tileLayer.wms layers.
Pass your WMS as the 2nd argument (i.e. as overlays) instead of the 1st (basemaps) of L.control.layers.
Overlays use check boxes, whereas basemaps use radio buttons.
Here i create an example to demonstrate what ghybs said.
L.control.layers(null, mixed).addTo(map);
Checkout my jsfiddle http://jsfiddle.net/iofirag/Ltub5bgv/18/.

CartoDB - Zoom to specific extent when clicking on a point?

I have a map of points, and for each of those points, a specific extent that I want the map to zoom into when I click on it.
I assume I will need to tabulate the bounds of those extents and add them as another column in the data.
Is there a way for Carto to automatically zoom to the bounds once I do this?
Yes you need to develop a CARTO.js web application. You need of course to store the bounds somehow on your table in a set of columns or in one single column using a format you can later parse. Next, you need to add that/those fields to a custom infowindow so they are passed to the web application in the interactivity. Finally, you need to listen to the feature click event in order to retrieve the interactivity data and using Leaflet map methods move its bounds.
You have all CARTO.js documentation here and a tutorial and many examples here. It's easier than it seems.

getFeatureFromEvent from multiple layers simultaneously in OpenLayers

I'm trying to return multiple features from two layers from a user click (one feature on each layer)?
I'm using openLayers 2.12. I have 2 vector layers containing polygons, and a container layer containing both.
When clicking where both layers contain a feature, only the layer2 feature is returned.
How do I also get the feature at layer1 of the same position?
Is there away to get a feature from a specific layer at a viewport position?
Explanation: the SelectFeature-Control uses the layers getFeatureFromEvent()method to find one feature for a click, hover, touch etc. event. If SelectFeature controls more than one layer, it glues the layers to a virtual single layer, therefore you get at max one feature in this case, too.
Your 1st question: if you want to select more than one feature, you can use the SelectFeature's selectBox(OpenLayers.Bounds) method: if you create a small Bounds from your position and call selectBox(), all features from all layers controlled by your SC intersecting your bounds get selected.
Your 2nd question: you may make up an OpenLayer.Event from your viewport position and call the getFeatureFromEvent() for the specific layer. This will of course return only one feature, even if a lot features are overlapping at your position.
Hope that helps a little.

Leaflet layerGroup controls

I have a series of Leaflet FeatureGroups that are made up of a series of GeoJSON layers. The FeatureGroups are conceptually similar but I need them to be separate for certain control reasons. I also need to be able to turn them all on and off at once. Is there a way to do this?
I looked in the documentation and couldn't find an event that fires when the FeatureGroup is switched on and off. There is also no documented way of lumping the FeatureGroups into some kind of superGroup.
For those who want to picture it, here is the workflow:
GeoJSON gets data that is turned into layers in Leaflet. This is of different administration boundaries (e.g. States, Counties, etc...). Each of the layers goes into a different FeatureGroup based on its type (e.g. Arkansas and New York go into the State FeatureGroup, Ford and Lincoln counties go into the County FeatureGroup). This way I have control over opacity and styling for the different FeatureGroups (e.g. when I'm looking at the Counties of a state, I can lower the opacity of all the other states). I also need a way of turning all of this off and back on again. Leaflet provides the ability to do that on a FeatureGroup by FeatureGroup basis, but not a super set of that.
Any ideas on how to achieve this?
New version of question:
What is the event that fires when turning a LayerGroup On and Off? Is there anyway to hook into that?
I ended up having my usual LayerGroups or FeatureGroups, and then a FeatureGroup that contains all the layers on all the groups. So when you add a shape or layer to a FeatureGroup, also add it to the FeatureGroup that you are using to keep track of everything. And of course if you remove don't forget to remove it.
You can add this base FeatureGroup to the map along with the other groups and it should be fine.
I don't think Leaflet currently provides an event when a LayerGroup is turned on or off (you are talking about with the L.Control, right?). I agree that it would be useful. For now, you can just extend the code to do whatever you need to be done. For example:
var customLayerControl = L.Control.Layer.extend({
_onInputClick: function(Layer, name){
// This is just like calling super() if this confuses you!
L.Control.Layers.prototype._onInputClick.call(this,Layer,name);
// Do stuff
}
});
Then instead of using the L.Control.Layers, use your custom layer control:
map.addControl(new customLayerControl({}, {'Custom Layer':customLayer},{}));
I hope this helps.

Disabling interaction in OpenLayers

I have a silly problem with an OpenLayers Map where I want to show a non-interactive picture on one site, where all clicks and such are disabled. I've tried capturing the clicks on the element but OpenLayers seems to still be able to get these events which makes the map interactive. There should be a simple solution to this but I can't figure it out.
Setting the control property to the empty array does not have any effect on the interaction.
Edit: We could not find a way to do this easily on an already existing map, so what we did was to re-use the old map initiation code in this new page, with added parameters that can remove all controls upon the creation and initiation of the map.
Setting the control property to the empty array does not have any effect on the interaction.
Wierd, this should do the trick:
map = new OpenLayers.Map('map', {controls: []});

Categories

Resources