EzDevInfo.com

Leaflet

JavaScript library for mobile-friendly interactive maps Leaflet - a JavaScript library for interactive maps

Zoom to fit all markers in Mapbox or Leaflet

How do I set view to see all markers on map in Mapbox or Leaflet? Like Google Maps API does with bounds?

E.g:

var latlngbounds = new google.maps.LatLngBounds();
for (var i = 0; i < latlng.length; i++) {
  latlngbounds.extend(latlng[i]);
}
map.fitBounds(latlngbounds);

Source: (StackOverflow)

Leaflet.js center the map on a group of markers

im using Leaflet.js and would like some way to center the map on the markers i have, so that all are within the users view when the page launches. If all the markers are clustered in a small area i would like the map to zoom down to a level that still displays all of them.

I know google maps has an autocenter function but how would i go about this with Leaflet.js?


Source: (StackOverflow)

Advertisements

how to pass data with marker in leaflet js

I am using leaflet js with openstreetmap in my project.
I have multiple circlemarkers at same place in my map.
I want to store some Id in that circlemarkers so that I can Identify that which data should be refereed when circlemarker is clicked.

My circlemarker is

var myMarker = L.circleMarker(myPoint, { title: 'unselected', radius: 20 });
myMarker.addTo(map); 

Here I am using title for other purpose that's why I cant use it.
Can any one tell me some way to do this.


Source: (StackOverflow)

Achieving animated zoom with d3 and Leaflet

Using d3 to plot SVG artefacts on top of a Leaflet map is a simple way to get a solid map controller combined with the strength of d3. There are numerous examples and guides as how to achieve this and the two main approaches seem to be:

  1. Appending a new SVG element on Leaflet's "overlay pane" as demonstrated by Bostock here: http://bost.ocks.org/mike/leaflet/

  2. Implementing a custom vector tile layer that hooks in to Leaflets native tile layer ecosystem as demonstrated by Nelson Minar here: http://bl.ocks.org/NelsonMinar/5624141

The first approach avoids Leaflets scale-based zooming by attaching a leaflet-class so that any d3-elements are hidden while the scaling takes place. When the zoom animation is over, the element coordinates are re-calculated and redrawn whereafter the hide-class is removed to expose the elements again. This works, but gives a less clean zoom in/out experience than with Leaflet's native GeoJSON layer, as the latter supports animated zoom.

The second approach does not contain any implementation specific code that adress the zooming behaviour but does somehow work anyway! The d3 elements are scaled during animated zoom and then replaced neatly with the next zoom levels vectors.

What I would like to achieve is a combination of the two. I would like to plot non-tile-based vectors based on Geo/TopoJSON that are animated during zoom in/out. I've fiddled around with using different leaflet css-classes, different event-hooks, and attaching and/or reusing the SVG elements in numerous ways but have not yet achieved a behaviour that is similar to the behaviour experienced when using Leaflet's native GeoJSON vector layer. The reason I don't want to use the native layer is that I want to make use of plenty of other d3 functionality simply not part of the Leaflet implementation.

Question: Has anyone achieved animated zooming when combining Leaflet and d3 using non-tile-based vectors? If so - how?


Source: (StackOverflow)

Leaflet.draw retrieve layer type on draw:edited event

I'm using the https://github.com/Leaflet/Leaflet.draw plugin and I'm trying to figure out how I can retrieve the layer type of the edited layer.

On the draw:created event, I have the layer and layerType, but on draw:edited (Triggered when saving all edits) I get a list of layers that were edited.

The draw:created event

map.on('draw:created', function (e) {
    var type = e.layerType,
        layer = e.layer;

    if (type === 'marker') {
        // Do marker specific actions
    }

    // Do whatever else you need to. (save to db, add to map etc)
    map.addLayer(layer);
});

The draw:edited event

map.on('draw:edited', function (e) {
    var layers = e.layers;
    layers.eachLayer(function (layer) {
        //do stuff, but I can't check which type I'm working with
        // the layer parameter doesn't mention its type
    });
});

Thank you for your time.


Source: (StackOverflow)

Fastclick.js causes Leaflet.js clicks to be ignored

I am developing a Cordova app which has a map built with Leafletjs at the heart of it. The map has markers which when clicked pop up an info box.

I want to get rid of the 300ms delay on links around the site in general - basically on all of the anchors (a tags). I don't need to apply it to the Leafletjs markers because there is currently no delay when a user taps a marker.

I have installed fastclick (https://github.com/ftlabs/fastclick/) - it removed the delay from the a tags brilliantly - however it created problems on the Leafletjs markers which now sometimes need two cicks to fire.

I have tried adding the class 'needsclick' on the markers Leafletjs creates which according to the fastclick documentation should make Fastclick ignore them - however it does not seem to have any affect. (Example:)

$('.leaflet-marker-icon').addClass('needsclick');
$(function() {
    FastClick.attach(document.body);
});

As the leafletjs markers click events are on img rather than a tags, if I could attach Fastclick to only a tags I think this would fix my issue, however I have tried passing a tags as the layer to Fastclick but this doesn't work either. (Example:)

$(function() {
    var Anchors = document.getElementsByTagName("a");
    FastClick.attach(Anchors);
});

Here is a minimal jsfiddle demonstrating the behavior (requires iDevice): https://jsfiddle.net/y723oet0/2/

If anyone has any advice, it would be appreciated.


Source: (StackOverflow)

How to trigger events on Leaflet map polygons?

I'm trying to figure out how to manually trigger events for Leaflet polygons (loaded via GeoJSON).

In a nutshell, I have a Leaflet map with numerous polygons. I also have a regular hyperlink outside of the map that when clicked, should trigger a mouseover event (or any event really) on a particular polygon.

How do I assign ID's to all of my polygons so that I can bind hyperlink(s) to a specific polygon's event? Or is that even the most logical way of doing this?

Ultimately, I'm trying to create a map with numerous polygons along with an HTML table of text labels that are associated to each polygon. When clicking on the HTML table text, I'd like to trigger events on the map polygons (and vice versa). I just don't know how to reference each polygon.

Here is my very simplified HTML:

<body>

    <div id="map" style="height: 550px; width:940px"></div>

    <a rel='nofollow' href="#" id="testlink">Click to trigger a specific polygon mouseover event</a>

</body>

Here is my very simplified JS:

$(document).ready(function () {

// build the map and polygon layer
function buildMap(data) {

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

    var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/***yourkeyhere***/66267/256/{z}/{x}/{y}.png',
        cloudmadeAttribution = '',
        cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttribution});

    var mapLoc = new L.LatLng(43.675198,-79.383287);
    map.setView(mapLoc, 12).addLayer(cloudmade);

    var geojsonLayer = new L.GeoJSON(null, {});

    geojsonLayer.on("featureparse", function (e){

        // apply the polygon style
        e.layer.setStyle(polyStyle);

        (function(layer, properties) {
            layer.on("mouseover", function (e) {
                // change the style to the hover version
                layer.setStyle(polyHover);
                });
            });
            layer.on("mouseout", function (e) {
                // reverting the style back
                layer.setStyle(polyStyle);
            });
            layer.on("click", function (e) {
                // do something here like display a popup
                console.log(e);
            });
        })(e.layer, e.properties);

    });

    map.addLayer(geojsonLayer);

    geojsonLayer.addGeoJSON(myPolygons);    

}

// bind the hyperlink to trigger event on specific polygon (by polygon ID?)
$('#testlink').click(function(){
    // trigger a specific polygon mouseover event here
});

});

Source: (StackOverflow)

update marker location with leaflet API

I want to build web app with the Leaflet API. First my user is geolocated with IP then if he accepts I try to update his position with HTML5 geolocation (accuracy is better).

My problem is that the marker position is not updated on the map and the code bellow fails with no error. I have try hundred of different syntax and methods from leaflet documentation to update marker position (ie. setLatLng) but I did not succeed. I would like to understand what's wrong with my code.


My problem is solved by doing like this :

    var lat = (e.latlng.lat);
    var lng = (e.latlng.lng);
    var newLatLng = new L.LatLng(lat, lng);
    marker.setLatLng(newLatLng); 

Old code was:

//initial IP based geolocation

var lat = google.loader.ClientLocation.latitude;
var lng = google.loader.ClientLocation.longitude;

//place marker on the map

var marker = L.marker([lat,lng]).addTo(map);

//start HTML5 geolocation 

map.locate({setView: true, maxZoom: 16});

function onLocationFound(e) {

    var marker = L.marker([e.latlng.lat,e.latlng.lng]).update(marker);
    alert ('New latitude is ' + e.latlng.lat)
}

map.on('locationfound', onLocationFound);

Source: (StackOverflow)

Simple label on a leaflet (geojson) polygon

I am attempting what I imagine to be a fairly common use-case with a leaflet multipolygon object.

I create the MultiPolygon using geojson:

var layer = L.GeoJSON(g, style_opts);

What I'd like is to put a simple text label in the center of each polygon. (For example, something like putting state name in the center of each state).

I've looked at: https://groups.google.com/forum/?fromgroups=#!topic/leaflet-js/sA2HnU5W9Fw

Which actually overlays the text, but when I add a bunch of polygons, it appears to put the label off-center in weird ways, and I'm currently unable to track down the problem.

I've also looked at: https://github.com/jacobtoye/Leaflet.label

but that appears to only put the label on polygons when you mouse over the polygon, and does not stay statically on the polygon.

I think my best course of action is to use that first link, and track down why it's changing the location, but in the meantime, if anyone knows of a quick and easy way to lay a label on a polygon in leaflet, I'd be much obliged.

Also, if I have any faulty assumptions about the two links above, please feel free to straighten me out.

Thanks very much in advance.


Source: (StackOverflow)

Click link inside Leaflet Popup and do Javascript

I have a leaflet map up and running. It overlays a series of polygons (via GeoJSON) on the map and attaches popups to each polygon. Each of the popups display information about that polygon.

I'd like to have inside the popup a link that, when clicked, runs a javascript function that pulls further smaller polygons via AJAX and shows them.

I can't get the script to catch a click on the link via the normal jQuery/Javascript click events. Here's what I mean by normal (the following doesn't work):

$('a .smallPolygonLink').click(function(e){
  console.log("One of the many Small Polygon Links was clicked");
});

The bindPopup part is as follows. It runs on each polygon when made and it pops up correctly on clicking on a polygon. It does show the link, just won't run the above code on click.

var popupContent = "Basic Information..." + '<a class="smallPolygonLink" rel='nofollow' href="#">Click here to see the smaller polygons</a>';
layer.bindPopup(popupContent);

Here's a JSFiddle illustrating the example, though in a far simpler form. http://jsfiddle.net/2XfVc/4/


Source: (StackOverflow)

How to interact with leaflet marker layer from outside the map

I am hitting a wall. I have a leaflet map showing points for public art pieces, rendered from GeoJson. Next to the map, I have also rendered a list of the pieces from the same GeoJson data and want to be able to click on an item from the list outside of the map and have the related marker on the map's popup come up.

The Question: How do I make it so that my list of items can be linked to their respective markers on the map through a click event?

My map.js file looks like this:

var map;
var pointsLayer;
$(document).ready(function () {
    map = new L.Map('mapContainer');
    var url = 'http://{s}.tiles.mapbox.com/v3/mapbox.mapbox-streets/{z}/{x}/{y}.png';
    var copyright = 'Map data &copy; 2011 OpenStreetMap contributors, Imagery &copy; 2011 CloudMade';
    var tileLayer = new L.TileLayer(url, {
        attribution: copyright
    });
    var startPosition = new L.LatLng(41.883333, - 87.633333);
    map.on('load', function (e) {
        requestUpdatedPoints(e.target.getBounds())
    });
    map.setView(startPosition, 13).addLayer(tileLayer);
    map.on('moveend', function (e) {
        requestUpdatedPoints(e.target.getBounds())
    })
});

function requestUpdatedPoints(bounds) {
    $.ajax({
        type: 'GET',
        url: '/SeeAll',
        dataType: 'json',
        data: JSON.stringify(bounds),
        contentType: 'application/json; charset=utf-8',
        success: function (result) {
            parseNewPoints(result);
            addToList(result)
        },
        error: function (req, status, error) {
            alert('what happen? did you lose conn. to server ?')
        }
    })
}
function addToList(data) {
    for (var i = 0; i < data.features.length; i++) {
        var art = data.features[i];
        $('div#infoContainer').append('<a rel='nofollow' href="#" class="list-link" title="' + art.properties.descfin + '"><div class="info-list-item">' + '<div class="info-list-txt">' + '<div class="title">' + art.properties.wrknm + '</div>' + '<br />' + art.properties.location + '</div>' + '<div class="info-list-img">' + art.properties.img_src + '</div>' + '<br />' + '</div></a>')
    }
    $('a.list-link').click(function (e) {
        alert('now you see what happens when you click a list item!');
        e.preventDefault()
    })
}
function parseNewPoints(data) {
    if (pointsLayer != undefined) {
        map.removeLayer(pointsLayer)
    }
    pointsLayer = new L.GeoJSON();
    var geojsonMarkerOptions = {
        radius: 8,
        fillColor: "#FF6788",
        color: "YELLOW",
        weight: 1,
        opacity: 1,
        fillOpacity: 0.5
    };
    L.geoJson(data, {
        pointToLayer: function (feature, latlng) {
            return L.circleMarker(latlng, geojsonMarkerOptions)
        },
        onEachFeature: function (feature, pointsLayer) {
            pointsLayer.bindPopup(feature.properties.img_src + "<br />" + feature.properties.wrknm + "<br />" + feature.properties.artist + "<br />" + feature.properties.location + '<div class="description">' + feature.properties.descfin + '</div>')
        }
    }).addTo(map)
}

Source: (StackOverflow)

How to use Google Maps API in leaflet-cloudmade

Is there any way to integrate Google Maps with leaflet-cloudmade? I mean, I don't want to use the original cloudmade map, but I want to use Google Maps instead. I want to show a map of Alaska (not many roads there). If I use a cloudmade map, it would be just white.

This is what I do if I want to use cloudmade map:

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

I know I should change the 'http://{s}.tile.cloudmade.com/YOUR-API-KEY/997/256/{z}/{x}/{y}.png' part. But, what should I write there if I want to use google map (or any other map)?

This is the documentation of leaflet-cloudmade (they don't say that much about using third-party map provider. They say they are agnostic about map-provider used in our application, so I think it should be possible to use Google Maps).


Source: (StackOverflow)

Is Leaflet a good tool for non-map images?

I am writing a web app that involves navigating technical illustrations (pan, zoom, click). I assume that Cloudmade Leaflet a good tool for this, only because someone used it to make XKCD 1110 pan/zoomable and I really like how it turned out.

Obviously, I would need to tile and scale my original technical illustration, but let's say that's a trivial problem that I have solved. Looking at the Leaflet API, however, it appears I would have to convert my tech illustrations (.ai, .svg, and .png files) to a geographical standard like GeoJSON. That seems like an awkward proposition.

Can anyone recommend Leaflet, or any other tool, for navigating non-map imagery?


Source: (StackOverflow)

How to change the map center in leaflet

The following code initializes a leaflet map. The initialize function centers the map based on user location. How do I change the center of the map to a new position after calling the initialize function?

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

map.locate({setView: true, maxZoom: 8});    
} 

Source: (StackOverflow)

Using custom map image tiles in LeafletJS?

Do my tiles need to adhere to any particular specs?

I have a large image file which I'd like to turn into a map with LeafletJS. I am going to be using the Python Imaging Library to cut it up into all the various tiles I need.

However, I can't find any information about using custom maps in Leaflet. Do I provide Leaflet with the range of X,Y,Z info somehow? Do I give it the pixel size of each tile? Does it figure this out on its own?

To put my question into one concise question: What do I need to do in order to have image files that can double as map tiles with LeafletJS, and what, if anything, do I need to do in my front-end script? (beyond the obvious specifying of my custom URL)


Source: (StackOverflow)