Animated setView() in Leaflet - leaflet

I have a search bar in my leaflet map and I would like the map to slowly zoom and pan to the marker when selected from the search bar. I can get it to zoom and pan but not slowly. My desired effect would be similar to when you type in a location in Google Earth and the view 'flys' from one location to the next. This is the code I have which zooms to my location but not slowly.
controlSearch = new L.Control.Search({layer:listOfMarkers, propertyName: 'IntersectionName', circleLocation:true, position:'topleft'});
map.addControl(controlSearch)
controlSearch.on('search_locationfound', function(e){
map.setView(e.latlng,15, {animate:true, duration:10.0})
});
I'm using leaflet v0.7.7.
Thanks!

Unfortunately, there is no way to change the duration of any setView that changes the current zoom level in Leaflet 0.7.7*. The duration of any animated zoom is hard-coded to be 0.25s, and because setView accepts zoom/pan options, which do not include duration, your duration:10.0 will be ignored.
However, setView does accept separate options for panning and zooming, and because the pan options do include duration, you can pan smoothly at the current zoom level using the following:
map.setView(e.latlng, map.getZoom(), {
"animate": true,
"pan": {
"duration": 10
}
});
I realize that this is not quite what you are looking for, but it is one step closer.
*In Leaflet 1.0b, there is a flyTo method, which produces the effect you describe, but there is nothing similar in 0.7.7.

Another way
map.flyTo(e.latlng, map.getZoom(), {
animate: true,
duration: 0.5
});

Related

Leaflet - Allow for switching to another base layer at higher than max zoom

I have 2 base layers (map and satellite) that users can switch between. The satellite layer's max zoom is higher by 2. I am using Leaflet's provided L.control.Layers() to manage the layers
var mapLayer = L.tileLayer('map-tiles.example.com/{z}/{x}/{y}.png', {
maxZoom: 18,
})
var satelliteLayer = L.tileLayer('satellite-tiles.example.com/{z}/{x}/{y}.png', {
maxZoom: 20,
})
var baseLayers = {
'Map': mapLayer,
'Satellite': satelliteLayer
}
var layerControls = L.control.layers(baseLayers).addTo(map);
If the user zooms to 19 or 20 in satellite view, he will not be able to switch back to the map layer (the radio button is disabled) until he zooms back to 18 or lower.
I want the user to be able to switch to the map layer even on zoom 19 or 20. And when the user switches to the map layer, the zoom will be set to 18.
Is there some way to achieve this with Leaflet's layer control? Or do I have to build a custom layer control?
Is there some way to achieve this with Leaflet's layer control?
Not with the default behaviour, no. If you check the relevant portion of the source code, you'll see that a L.Control.Layers always disables checkboxes/radio buttons when the layer is out of its min/maxzoom range.
Or do I have to build a custom layer control?
Yes, you can create your own subclass of L.Control.Layers disabling this functionality, replacing the relevant method with a function that does nothing:
L.Control.Layers.NeverDisable = L.Control.Layers.extend({
_checkDisabledLayers: function(){}
});
var myLayersControl = new L.Control.Layers.NeverDisable(
baselayers, overlayLayers, options);
myLayersControl.addTo(map);
You can check a working example in this plunkr.
An easy workaround to have your mapLayer selectionable on zooms 19-20 is to use the Tile Layer maxNativeZoom option at 18, and increase your maxZoom to 20.
Then if you still want to automatically decrease the zoom back to 18 when mapLayer is selected, use a listener on map "baselayerchange" event, check the map.getZoom() and modify it (map.setZoom(18)) if desired.

Disable double finger zoom after reaching maximum zoom

I had allowed double finger map zoom on mobile devices which is good.
But if maximum zoom level is reached I can zoom more, and when I release fingers from display map zoom is reverted to the max zoom level.
How can I disable further zoom in on mobile devices after max zoom level on the map is reached?
This is a case of RTFM. If you look carefully at the Leaflet API documentation, you'll find the bounceAtZoomLimits option for L.Map. Let me quote:
bounceAtZoomLimits Boolean default true
Set it to false if you don't want the map to zoom beyond min/max zoom and then bounce back when pinch-zooming.
so:
var mymap = L.map('map', {
bounceAtZoomLimits: false
})

How to move geojson polygon in leaflet?

Say I have a geojson box I've added to leaflet. How can I allow the user to "click and drag the box" to a new location, which in turn updates all the coordinates automatically? I know how to edit the boundary/points that make up the shape using leaflet editing, but am not sure how to actually move the shape.
There is a Leaflet.Draw.Drag plugin for Leaflet Draw that allows you to move polygons when you enter edit mode. It does seem to be a bit finicky about the version, though. At least in a few quick experiments, I was only able to get it to work using Leaflet Draw version 0.2.3. If you have an existing L.GeoJson layer, you can simply specify that as the featureGroup in the edit options of the draw control:
var drawControl = new L.Control.Draw({
edit: {
featureGroup: yourGeoJsonLayer,
edit: {
selectedPathOptions: {
maintainColor: true,
moveMarkers: true
}
}
}
});
In the selectedPathOptions, the maintainColor option just keeps the existing style of the layer while you're editing, and the moveMarkers option places a little square marker in the middle of the polygon as a reminder that you can drag the whole thing rather than just edit the vertices.
Here is an example fiddle:
http://fiddle.jshell.net/nathansnider/qk5bsgn8/

Zoom in on maker group in leaflet mapbox?

I have a layerGroup in my map which has a lot of markers and another layerGroup which has a lot of circles. I need to zoom in on these layer groups but I cannot find the exact API method to do so.
I have tried:
var myLayerGroup = L.layerGroup().addTo(map);
myLayerGroup.fitBounds(); // tried this
myLayerGroup.setBounds(); // and this too
I am not sure which method in the API will work for me. How to zoom in on a layer of markers?
Switch from using layerGroup to featureGroup, theb you can use getBounds() on a feature group to retrieve its bounds, then use map.fitBounds(result) to zoom to that view.

Leaflet Map Clustering + Marker Rotation

Has anyone ever tried to use Leaflet Clustering Plugin + Marker Rotation Plugin? I tried to work with both but they work partially.
In a first view, I can see some clusters and some isolated (and rotated) markers. Every time I zoom in into some Cluster the rotated markers disappear. Does anyone have any idea why this happens?
to simply rotate a marker, use :This Leaflet Plugin
include this in your html :
<script src="../leaflet-plugin/Marker.Rotate.js"></script>
wen create a marker :
var marker = new L.Marker(map.getCenter(), {iconAngle: 90});
a complete example
Found a solution provided by Dave Leaver..it works perfectly.
"You can hack it to work with L.MarkerClusterGroup (so it is no worse than it is already) by changing the start of the update function in the rotate plugin to bail if there is no _icon:
update: function() {
if (!this._icon) {
return;
}
The problem is that the rotate plugin is overwriting the transform and fighting with leaflet on it.
I recommend instead using a DivIcon with a child element that has the rotation, that way leaflet can happily update the transform to move the marker independent of the rotation.
As a totally broken example:
var m = new L.Marker(getRandomLatLng(map), { icon: L.divIcon({html:'<img src="http://cdn.leafletjs.com/leaflet-0.5.1/images/marker-icon.png" style="-webkit-transform: rotate(39deg); -moz-transform:rotate(39deg);" />'})});"