combining overlays in mapbox / leaflet layers control - javascript

I'm trying to combine 2 or more overlays into one overlay checkbox. I'm using leaflet layers control with mapbox.js 1.6 to toggle my overlays. It doesn't matter to me if I combine them on mapbox.com into one data layer, or if I combine separate data layers in my JS code into one overlay checkbox, but I can't seem to do either. I'm exporting MBTiles from Tilemill to my Mapbox account.
Note that it's not an option to:
combine them in Tilemill (the single zoom level and square bounding box won't work for me across all layers)
add the various data layers to a single map project on Mapbox.com (I'd like it to be toggleabe by the user)

You can use L.layerGroup to combine layers
var group = L.LayerGroup([layer1, layer2];
// add default layers to map
map.addLayer(layer1);
// switcher
var baseLayers = {
"My Group": group,
// more layers
};
// add layer groups to layer switcher control
var controlLayers = L.control.layers(baseLayers).addTo(map);
You may be interested in this thread Leaflet layer control for basemap group layers

You can use the L.control.layers with the L.layerGroup. Here is the JSFiddle I wrote for this. You can add as many base or overlay layers you want.
Once you create the L.layerGroups, define the base and the overlay layers and add them to the control like this:
var controlLayers = L.control.layers(baseLayers, overlayMaps).addTo(map);

Related

Switching between two overlays in leaflet.js

I need to have an optional overlay above map that switches between two different WMS layers in leaflet.js if a certain map is selected (if layerX is turned on in LayerControl, layer1 is to be replaced by layer2, and when (Tile)layerX is no longer selected, replace layer2 by layer1 again), so i have listener on overlayadd and overlayremove (
map.on('overlayadd', function(layer){if(layer.name === "layerX"){
layers_on = !!map.hasLayer(layer1);
layer1.remove();
layer_selector.removeLayer(layer1);
if(layers_on){map.addLayer(layer2);
layer_selector.addOverlay(layer2, "layer2");
}});
map.on('overlayremove', function(layer){if(layer.name === "layerX"){
layers_on = !!map.hasLayer(layer2);
layer2.remove();
layer_selector.removeLayer(layer2);
if(layers_on){map.addLayer(layer1);}
layer_selector.addOverlay(layer1, "layer1");
}});
Code works fine when switching LayerX on, however when I remove it with layer2 on, it doesn't actually remove it, just replaces it in layer_control and adds layer1 on top of it
Simply said I need a overlay in LayerControl that dynamically shows one of two maps, if LayerX in on then show Layer1 in other case show Layer2. (and the layer itself is optional)
Instantiate a L.Control.Layers, and add your two L.TileLayer.WMSs as "base layers" in that control.
The name might be deceiving: what it means is that, for a given L.Control.Layers, the layers passed as "base layers" are mutually exclusive. They do nto need to be thematically base layers, and you can have more than one L.Control.Layers with a set of mutually exclusive L.Layers in each.

The other icon on map disappears when pushpin(layer) is close to the icon(Bing map V8)?

I am using Bing map version 8, earlier with version 7 used entities, now we use layers and create a new layer and add pushpins to that layer and then add the layer to the map.
But, in a situation when an sea port icon is there and a pushpin emerges very close to it, it hides the icon and pushpin stands visible.I want both icon and pin to stay visible. Please help.
var pinLayer = new Microsoft.Maps.Layer();
//Created pins
pinLayer.add(pin); //added the pin to layer
//
map.layers.insert(pinLayer); //Added the layer to map
Earlier in v7 (using entities)-
Now in V8, the same icon of airport is not visible. I want it to show up.
Are you talking about the airport icon that is automatically added by Bing Maps? If so, this is to be expected as it is a map label which is lower priority than your data. Bing Maps uses vector labels and label collision to hide map labels which are overlapped by pushpins to keep the map view nice and clean. If you would prefer to disable the vector labels simply add the following map option when loading: liteMode: true
You can find out more about vector labels in Bing Maps V8 here: https://msdn.microsoft.com/en-us/library/mt750538.aspx

Display popups with leaflet ( large dataset )

Im using Leaflet & Geojson-vt to visualize a large dataset (GeoJSON with 70,000 polylines features)
Is there any way to show smoothly a popup (it contains the polyline data) on click event on one of the multiple polylines ?
I am using geojson-vt and the example from here to add the tiles to the leaflet map.
i tried this
function onEachFeature(feature, layer) {
layer.on('click', function(e) {
layer.bindPopup(feature.properties.NUMERO);
});
}
L.geoJson($scope.dataOfFile.data, {
onEachFeature: onEachFeature
}).addTo(map);
but the map keep freezing.
Not sure I'm understanding... That example draws a canvas layer from vector tiles, this has no interaction method. If it were polygons you could use point in polygon from the original data. Since it's lines you may want to experiment with the almost over plugin using 0 weight (transparent) lines.
I had a similar issue with popups on Markers. If I added the popup before the marker was added to the map then the map would briefly freeze when all the markers were added to the map.
So instead I added the Markers to the map first. I maintained an array of all the markers then added the popups afterwards to each marker and I no longer experienced the map locking up.

Creating a custom control.layers class in leaflet

I have a page that displays maps using leaflet.js with many different base layers and overlays. I'd like to have separate layer controls for selecting the base maps and the overlays, and for the controls to have different icons.
To accomplish that I'm trying to on add a setButtonClass method to leaflet's L.control.layers that I can call after placing my 2nd button on the map, which would change its class and allow me to give it different styling.
So I'd initialize the controls like this:
var baseLayersControl = L.control.layers(baseMaps, null, {position: 'bottomright'});
var overlayControl = L.control.layers(null, overlayMaps, {position: 'bottomright'});
baseLayersControl.addTo(map);
overlayControl.addTo(map);
overlayControl.setButtonClass();
However, I can't get setButtonClass to change the class the way I want. I added this to leaflet-src.js:
setButtonClass: function () {
this.className = 'leaflet-control-layers2';
},
And added styling to leaflet.css for the leaflet-control-layers2 class and related classes with my new icon, but right now I'm just getting two standard layer controls on the map.
Have you checked out Leaflet.groupedlayercontrol? It groups and labels your layer control by base maps and overlays. I'd check there first and then see how you might be able to create two separate icons for base layers and overlays.

mouse drag on kml features with OpenLayers

Link: http://www1.qhoach.com/
When you drag, this map is panned... But if you drag on KML features (icon with circle), nothing happens
First of all,in your application there are four level of maps including the vector layer you mentioned with circle icons in your question.
0: "Đường Sá" ||---> Overlay Tiles
1: "Vệ Tinh" ||---> Overlay Tiles
2: "TMS Overlay" ||---> Markers ~ Icons
3: "KML" ||---> Vector
Analysis:
Starting with zero to last one,only vector seems to be the last one,others stays as overlay tiles.In order to come this problem we have to focus on marker layer,namely features (icons).
As you have seen on map,click event for map has been triggered when you try to drag the map around.You can't drag because event registration is working for marker layer first not for the map.That means in order to drag the map,moving mouse(drag) after click must follow.Since you're trying this on vector layer,there is no chance to pass the event to overlay layers.
Solution:
I propose you two ways to achieve this bug-type problem.
Let this be the long way
There is a control in OpenLayers known as SelectFeature inherited from Handler.Feature.This control generally allows vector feature from a given layer on click on hover.Which means this handler can respond to mouse event related to any drawn features.Only callbacks are associated with features,needing one of them click.Now all we have to do is to fall click event back to as we pan for overlay tiles.
var selectFeat = new OpenLayers.Control.SelectFeature(
vector, {toggle: true, clickout:false});
selectFeat.handlers['feature'].stopDown = false;
selectFeat.handlers['feature'].stopUp = false;
map.addControl(selectFeat);//instance of map
selectFeat.activate();
Once this control is activated you have to ensure your layers to pass events through another layer.To do that,simply
layer.events.fallThrough = true;//both for vector and marker layers
After all these actions we made so far,one last thing left to do:
That's switching the order of markers and kml layer.
And this should be the easiest way
That's z-index on layers.You can check in above sequence of layers that the layer which has highest id has also highest z-index.
layer.setZIndex(...any number...);
In addition to this solution,easy way allows only you to drag through map,when all sudden clicking features of icons may lost without long way,so it's your choice to leave them behind.
Mouse events do not want to propagate through an svg Vector overlay to layers underneath.
The solution above demands all marker HTML layers have higher zindex than all Vector SVG layers.
The following CSS provides a potential/partial work-around, propagating events through the svg element, but only where there is no vector elements within the svg overlay:
/** Hack so mouse events propagate(bubble) through svg elements, but not the
images within svg */
.olLayerDiv svg {
pointer-events: none;
}
.olLayerDiv svg * {
pointer-events: auto;
}
Combine the above CSS while adding fallThrough:true to all OpenLayers events objects within maps, layers, and controls.
// map events
var map = new OpenLayers.Map(div, { fallThrough:true } );
// layer events
var lvec = new OpenLayers.Layer.Vector( .... );
lvec.events.fallThrough = true
map.addLayers([lvec])
// all map controls
var ctrl = new OpenLayers.Control.SelectFeature( lvec, {...
fallThrough: true, autoActivate:true });
map.addControl( ctrl )

Categories