Viewed   5.7k times

I'm using Leaflet.js and would like some way to centre the map on the markers I have so that all are within the user's 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 auto-centre function but how would I go about this with Leaflet.js?

 Answers

4

You can use L.LatLngBounds in order to create an area to zoom to.

First, create a bounds and pass it an array of L.LatLngs:

var bounds = new L.LatLngBounds(arrayOfLatLngs);

This will create a bounds that will encapsulate every point that is contained in the array. Once you have the bounds, you can fit the bounds of the map to match your created bound:

 map.fitBounds(bounds);

This will zoom the map in as far as it can go, while still containing every point in your array.

Alternatively, you can also call the fitBounds method by simply calling it and passing in an array of L.LatLng objects. For example:

map.fitBounds([[1,1],[2,2],[3,3]]);

This would function exactly the same, without the need to create a specific L.LatLngBounds object.

Saturday, October 1, 2022
 
5

The performance issue is due to the fact that each marker is an individual DOM element. Browsers struggle in rendering thousands of them.

In your case, an easy workaround would be instead to use Circle Markers and have them rendered on a Canvas (e.g. using map preferCanvas option, or with a specific canvas renderer that you pass as renderer option for each of your Circle Marker). That is how Google Maps works by default: its markers are actually drawn on a Canvas.

var map = L.map('map', {
    preferCanvas: true
});
var circleMarker = L.circleMarker(latLng, {
    color: '#3388ff'
}).addTo(map);

or

var map = L.map('map');
var myRenderer = L.canvas({ padding: 0.5 });
var circleMarker = L.circleMarker(latLng, {
    renderer: myRenderer,
    color: '#3388ff'
}).addTo(map);

With this solution, each Circle Marker is no longer an individual DOM element, but instead is drawn by Leaflet onto a single Canvas, which is much easier to handle for the browser.

Furthermore, Leaflet still tracks the mouse position and related events and triggers the corresponding events on your Circle Markers, so that you can still listen to such events (like mouse click, etc.).

Demo with 100k points: https://jsfiddle.net/sgu5dc0k/

Saturday, November 26, 2022
4

Reference: https://leafletjs.com/reference-1.3.4.html#geojson

Methods inherited from LayerGroup:

getLayers() Layer[]

Returns an array of all the layers added to the group.

var pins = L.geoJson(geojsonFeature, {}).addTo(map); var totalPins = pins.getLayers().length;

Wednesday, December 7, 2022
 
n_1.1
 
3

The problem with your code is that you're trying to point the map to the user's location when the user gives location permission, you're not waiting for the CoreLocation to give you the actual user location. You need to use the CLLocationManagerDelegate method locationManager(_:didUpdateLocations:) to be notified of when you get the user's actual location, and there you can set the map to point to the user's location.

class ViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet var mapView: MKMapView!
    var locationManager: CLLocationManager?

    override func viewDidLoad() {
        super.viewDidLoad()

        locationManager = CLLocationManager()
        locationManager!.delegate = self

        if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
            locationManager!.startUpdatingLocation()
        } else {
            locationManager!.requestWhenInUseAuthorization()
        }
    }

    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {


        switch status {
        case .NotDetermined:
            print("NotDetermined")
        case .Restricted:
            print("Restricted")
        case .Denied:
            print("Denied")
        case .AuthorizedAlways:
            print("AuthorizedAlways")
        case .AuthorizedWhenInUse:
            print("AuthorizedWhenInUse")
            locationManager!.startUpdatingLocation()
        }
    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

        let location = locations.first!
        let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, 500, 500)
        mapView.setRegion(coordinateRegion, animated: true)
        locationManager?.stopUpdatingLocation()
        locationManager = nil
    }

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        print("Failed to initialize GPS: ", error.description)
    }
}
Saturday, October 15, 2022
 
john_s
 
5

Try with

SELECT 
    AVG(tyd.price) AS avg_price, COUNT(tyd.id_product) AS cnt_id_p,
    catalog.id_marchand, catalog.id_product, catalog.price AS c_price, 
    catalog.img_src, tyd.login AS tyd_l
FROM catalog 
INNER JOIN tyd ON catalog.id_marchand = tyd.id_marchand 
              AND catalog.id_product =   tyd.id_product
              AND tyd.step = "0" 
GROUP BY catalog.id_product, catalog.id_marchand
HAVING tyd.login = "user1@tyd.fr"
Saturday, October 15, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :