Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to change the icon image depending on the zoom level? (leaflet.js)

I am making a region drawing tool for a web application and I am using markers as anchors that the user can use to change the shape of a polygon.

This is what I have so far. http://demos.nodeline.com/leaflet_development/

the repo is at https://github.com/SpencerCooley/Leaflet_development

$(document).ready(function(){

var map, cloudmade, sanAntonio, polygonPoints  


 map = new L.Map('map');

 cloudmade = new L.TileLayer('http://{s}.tile.cloudmade.com/d4334cd6077140e3b92ccfae2b363070/997/256/{z}/{x}/{y}.png', {
    attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://cloudmade.com">CloudMade</a>',
    maxZoom: 18
});


 sanAntonio = new L.LatLng(29.4238889, -98.4933333); // geographical point (longitude and latitude)


 map.setView(sanAntonio, 13).addLayer(cloudmade);




polygonPoints = [];

var polygon = new L.Polygon(polygonPoints);
map.addLayer(polygon);

map.on('click', function(e) {  


  var marker = new L.Marker(e.latlng, {draggable:true});
  polygonPoints.push(e.latlng);
  var markerId = polygonPoints.length -1 
  map.addLayer(marker);
  polygon.setLatLngs(polygonPoints);



  marker.on('drag', function(){
    var locationWhileDrag = marker.getLatLng();
    $('#first_marker').val(locationWhileDrag);
    polygonPoints.splice(markerId,1,locationWhileDrag);
    polygon.setLatLngs(polygonPoints);
  });      



});







});

I only want the markers to be normal size when the user is zoomed in to street level. When you zoom out the normal sized markers completely drown out the polygon. I looked through the docs but couldn't find anything about this.

I am mainly looking for suggestions/brainstorming. I am thinking maybe there is a way to detect which zoom state you are currently in? If so, I could use an if statement to change the icon.

like image 927
Spencer Cooley Avatar asked Apr 09 '12 03:04

Spencer Cooley


People also ask

How do you remove zoom control in leaflet?

You can remove the default zoom control by setting the zoomControl option of the map options to false.

What is tile layer in leaflet?

Used to load and display tile layers on the map, implements ILayer interface.

What is zoom level?

A zoom level or scale is a number that defines how large or small the contents of a map appear in a map view . Scale is a ratio between measurements on a map view and measurements in the real-world.


2 Answers

Ok so I found a few methods and came up with this:

//this sets up an icon to be replaced on redraw. 
var MyIcon = L.Icon.extend({
    iconUrl: 'marker.png',
    iconSize: new L.Point(10, 16),
    shadowSize: new L.Point(10, 16),
    iconAnchor: new L.Point(10, 16)
});

var icon = new MyIcon();

//When view resets use the smaller icon if zoom level is less than 13
map.on('viewreset', function(){
    if(map.getZoom() < 13){
        marker.setIcon(icon);
    }
});

The setIcon() method was not in the docs, I found it in a google forum and it worked.I made a smaller icon and I am basically just replacing the original icon when the zoom level is less than 13. I am going to implement different markers for different zoom levels now to give the markers 'further away' effect.

Here is the revised code.

$(document).ready(function(){

var map, cloudmade, sanAntonio, polygonPoints  

map = new L.Map('map');

cloudmade = new L.TileLayer('http://{s}.tile.cloudmade.com/d4334cd6077140e3b92ccfae2b363070/997/256/{z}/{x}/{y}.png', {
    attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://cloudmade.com">CloudMade</a>',
    maxZoom: 18
});

sanAntonio = new L.LatLng(29.4238889, -98.4933333); // geographical point (longitude and latitude)

map.setView(sanAntonio, 13).addLayer(cloudmade);

polygonPoints = [];

var polygon = new L.Polygon(polygonPoints);
map.addLayer(polygon);

map.on('click', function(e) {  
    //this sets up an icon to be replaced when redraw. 
    var MyIcon = L.Icon.extend({
        iconUrl: 'marker.png',
        iconSize: new L.Point(10, 16),
        shadowSize: new L.Point(10, 16),
        iconAnchor: new L.Point(10, 16)
    });

    var icon = new MyIcon(); 
    //this sets up an icon to be replaced when redraw.

    var marker = new L.Marker(e.latlng, {draggable:true});
    polygonPoints.push(e.latlng);
    var markerId = polygonPoints.length -1 
    map.addLayer(marker);
    polygon.setLatLngs(polygonPoints);

    marker.on('drag', function(){
        var locationWhileDrag = marker.getLatLng();
        $('#first_marker').val(locationWhileDrag);
        polygonPoints.splice(markerId,1,locationWhileDrag);
        polygon.setLatLngs(polygonPoints);
    });      

    //When view resets use the small icon if zoom level is less than 13
    map.on('viewreset', function(){
        if(map.getZoom() < 13){
            marker.setIcon(icon);
        }
    });
});

});

here is the demo: http://demos.nodeline.com/leaflet_development/

like image 87
Spencer Cooley Avatar answered Sep 18 '22 05:09

Spencer Cooley


You could also change a generic class on zoom and make the change with CSS.

map.on('zoomend', function(event) {
    document.body.className = "zoom"+map.getZoom();
});

then your CSS would be:

.myIcon{background:red;}
.zoom4 .myIcon{background:pint;}

I use it to hide the name of my marker until you zoom in past level 10.

like image 28
sidonaldson Avatar answered Sep 19 '22 05:09

sidonaldson