What would be the best way to display a label once the zoom level exceeds a certain threshold in Leaflet?

As someone new to the Leaflet library and JavaScript in general, I'm currently facing a challenge with showing/hiding a leaflet label based on the zoom level. The markers are within a 'cluster' layer loaded via AJAX callback, and I bind the popup and label using the onEachFeature. Afterwards, I add the geoJson marker layer to the map.

I've attempted to display the labels only when zoomed in to a certain level without success. I even tried integrating the leaflet.zoomcss.js, but it seems like my implementation is not correct.

Sample:


var officesLayerGroup = L.markerClusterGroup();
var currentMakers;
function DisplayLocalOffices(jqOffices) {

    currentMakers = new L.geoJson(jqOffices, {
        style: function (feature) {
            var c = feature.properties.markercolor;
            if (feature.properties.OfficeID == 0) {
                c = 'yellow';
            }
            return { color: c };
        },
        pointToLayer: function (feature, latlng) {
            return new L.CircleMarker(latlng, { radius: 7, fillOpacity: 0.5 });
        },

        onEachFeature: bindOfficePopup
    });
    officesLayerGroup.addLayer(currentMakers);
    map.addLayer(officesLayerGroup); 
}

function bindOfficePopup(feature, layer) {
    // Function to add popup based on information in the 'layer' or marker
    // Keeping track of the layer(marker)
    feature.layer = layer;

    var props = feature.properties;
    if (props) {
        var desc = '<span id="feature-popup">';
        //.. additional HTML content here!
    
        // Binding label with specific options
        layer.bindPopup(desc);
        layer.bindLabel('Hi Label!', { noHide: true, className: 'my-css-styled-labels'});

    }
}

Another attempt I made was:

   
    layer.on({
          zoomend: showLabel(e)
    });

Alongside this simplified function:


function showLabel(e) {
    z = map.getZoom();
    if (z > 6) {
        layer.bindLabel("HIYA", { noHide: true, className: 'my-css-styled-labels' });
    }
}

Despite trying different approaches, including adding the library and CSS styles for leaflet.zoomcss.js, I haven't had any success. I apologize for the detailed explanation, but any assistance would be greatly appreciated!

Answer №1

When using Leaflet, the layers do not trigger events when zooming the map. Instead, the map instance itself does. Attaching an event handler to each feature could lead to performance issues as more features are added. It's recommended to handle the map's zoom event and then display labels for the features in your layer accordingly. Take a look at this sample code:

var geoJsonLayer = L.geoJson(featureCollection, {
    onEachFeature: function (feature, layer) {
        layer.bindLabel(feature.geometry.coordinates.toString());
    }
}).addTo(map);

var visible;

// Map zoom event handler
map.on('zoomend', function (e) {
    // Check zoom level
    if (map.getZoom() > 10) {
        // Check visibility status
        if (!visible) {
            // Iterate through layers
            geoJsonLayer.eachLayer(function (layer) {
                // Show label
                layer.showLabel();
            });
            // Update visibility flag
            visible = true;
        }
    } else {
        // Check visibility status
        if (visible) {
            // Iterate through layers
            geoJsonLayer.eachLayer(function (layer) {
                // Hide label
                layer.hideLabel();
            });
            // Update visibility flag
            visible = false;
        }
    }
});

// Fit the map to the bounds of the layer triggering the zoom event
map.fitBounds(geoJsonLayer.getBounds());

You can view a live example on Plunker: http://plnkr.co/edit/V8duPDjKlY48MTHOU35F?p=preview

Answer №2

After struggling with various solutions without success, I decided to share the code that finally worked for me. This code is specifically designed for maps where not every layer object is considered a marker object. If you have already created an object called L.Map and stored it in a variable named map, simply add the following code snippet after your map initialization:

var show_label_zoom = 20; // threshold zoom level for label visibility
var labels_visible = true;
function show_hide_labels() {
    var cur_zoom = map.getZoom();
    if(labels_visible && cur_zoom < show_label_zoom) {          
        labels_visible = false;
        map.eachLayer(layer => layer.hideLabel && layer.hideLabel());               
    }
    else if(!labels_visible && cur_zoom >= show_label_zoom) {           
        labels_visible = true;
        map.eachLayer(layer => layer.showLabel && layer.showLabel());               
    }
}
map.on('zoomend', show_hide_labels);
show_hide_labels();

Answer №3

After previously making an AJAX callback in my situation, the following rules were set up based on an example I found here:

map.on('zoomstart', function () {
try{
var zoomLevel = map.getZoom();
    //alert(zoomLevel);
    console.log(zoomLevel);
    //alert(zoomLevel);
var tooltip = $('.label');
    
    //alert(zoomLevel);
    console.log("zoomLevel");
    console.log(zoomLevel);

switch (zoomLevel) {
    default:
        tooltip.css('font-size', 0)
    if(zoomLevel>5)
    {
        tooltip.css('font-size', 10);
    }
    if(zoomLevel>13)
    {
        tooltip.css('font-size',20);
    }
}
}catch(ex)
{
alert(ex);  
} 
});

The line var tooltip = $('.label') refers to a CSS style that was applied earlier for the tooltip properties in my code. I specifically set two different font sizes for two different zoom levels.

I hope this information proves helpful to you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

My React project is unable to import the foundation SCSS file into the App.scss file

After installing zurb-foundation using npm, I attempted to import the .scss file into my App.scss file. Utilizing the "live sass server" for compiling the .scss code into .css code, a .css file was generated but did not display any code despite successfull ...

Populate Android Spinner with data retrieved from XML response

I received a response from a webservice in this format. [{"text":"1001","val":"1"},{"text":"2005","val":"2"},{"text":"2791","val":"3"}] I am looking to populate this data in an Android spinner. Can someone please provide guidance as I am new to developme ...

Looking for visible elements in WebDriverIO?

Currently, I am developing a test suite using WebDriverIO for a website with multiple duplicate elements that are selectively displayed based on user interaction... For example, the site may contain five buttons that each open a tooltip. These tooltips ar ...

What is the method for activating -webkit-animation/transition-property for :before and :after pseudo elements?

Is there a way to activate the -webkit-animation for :before and :after pseudo elements? It seems that in this demo http://jsfiddle.net/4rnsx/, the animation is not working for :before and :after elements. I am attempting to make it work using Mootools ...

In the following command, where is the PORT stored: ~PORT=8080 npm App.js?

section: Let's consider the following code snippet located in the App.js file: console.log(`This is the port ${process.env.PORT}`); Is there a method to retrieve the value of PORT from outside the running process? ...

Steps to turn off a Material UI CSS class for an element universally

Utilizing the Material UI Typography element with the css class MuiTypography-h1, I am seeking to globally disable its usage throughout the entire codebase. <Typography variant="h1" sx={{ width: '100px', height: '55px ...

Issue with unapplied nullable type during export操作

I'm struggling to understand why my nullable type isn't being applied properly Here's an illustration interface Book { name: string; author: string; reference: string; category: string; } async function handleFetch<T>(endpoin ...

Having trouble retrieving JSON file in Next.js from Nest.js app on the local server

Having just started with Next.js and Nest.js, I'm struggling to identify the issue at hand. In my backend nest.js app, I have a JSON API running on http://localhost:3081/v1/transactions. When I attempt a GET request through postman, everything functi ...

Display HTML components depending on an object's property using AngularJS

Here is the code I have created to display a simple drop down list: var products = [ { "id": 1, "name": "Product 1", "price": 2200, "category": "c1" }, { "id": 2, "name": "Product 2", "p ...

The resolution of Q.all does not occur in the expected order

I'm currently facing an issue with the order in which promises are being executed in Node.js. The goal of the code is as follows: a) Run a query and use the resulting latitude/longitude pairs to b) Calculate the shortest paths (using an async funct ...

Send the value from $_request to the Datatable Ajax script

I'm using DataTables and need to pass a REQUEST value to the PHP script. Firebug keeps reporting an undefined index. Check out the PHP script below: $sIndexColumn = "opportunity_acccount_id"; $sTable = "opportunities_base"; $sWhere = "opportuni ...

click event not triggering custom hook

I have developed a custom hook for fetching data and am struggling to implement it successfully. Below is my custom hook: import { useReducer } from "react"; import axios from "axios"; const dataFetchReducer = (state, action) => { ...

Create a project in asp.net core API that allows for CRUD operations using JSON and static data

What is the process for performing CRUD operations on a locally stored JSON file? Specifically, with an example where there are fields like id, name, and roll number. I am looking to implement GET, POST, PUT, and DELETE functionalities using ASP.NET Core ...

Adding information to a database by utilizing Jquery, Ajax, and PHP

Trying to use ajax to submit data to a database has been a challenge for me. Even with a simple code test, I can't seem to make it work. Here is the HTML/ajax code snippet: <?php include("osb.php");?> <script type = "text ...

Adjusting the margin on an element causes a shift in the entire page's

Why is the margin of an h2 element on my page displacing the entire body downward? This seems abnormal since the h2 element is within a div container. Is there a way to address this issue? ...

Javascript time intervals run rapidly during tab changes

I am facing an issue where my neck is constrained at regular time intervals. I have a function that helps me calculate time one second at a time: Header.prototype= { time_changed : function(time){ var that = this; var clock_handle; ...

What is the best way to use ajax/jquery to load blade or php content into a view in Laravel?

Can anyone advise on how to dynamically load content in a view using ajax requests? I am familiar with loading html elements like this: ("#div_place").html(<p>...), but I'm facing an issue when trying to load php/blade objects into a div. Is the ...

JavaScript: function that operates asynchronously

I am new to JavaScript and encountered some issues with async functions. I have a function that fetches data from MongoDB by creating a promise, but it returns a collection with an empty object. async function getRating(item, applicant) { let arr = await ...

Parsing dynamic keys and field names in JSON format

I am faced with a JSON string {"key": "2021-01-01 22:59:59", "data": {"field1": "newvalue1", "field2": "newvalue2"}} My task is to transform this JSON into the following structure: ...

What is the best way to show a border-left outside of the list marker in Internet Explorer 8?

I have a numbered list that I would like to add a left border to. <ol class="steps"> <li>item 1</li> <li>item 2</li> <li>item 3</li> <ol> .steps {border-left: 5px double #7ab800;} When viewing in Fir ...