Asked  2 Months ago    Answers:  5   Viewed   4.2k 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

49

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, September 4, 2021
 
Vikram
answered 2 Months ago
71

you have to put your "var marker" out of the function. Then later you can access it :

var marker;
function onMapClick(e) {
        marker = new L.Marker(e.latlng, {draggable:true});
        map.addLayer(marker);
        marker.bindPopup("<b>Hello world!</b><br />I am a popup.").openPopup();
};

then later :

map.removeLayer(marker)

But you can only have the latest marker that way, because each time, the var marker is erased by the latest. So one way to go is to create a global array of marker, and you add your marker in the global array.

Thursday, June 3, 2021
 
simPod
answered 5 Months ago
38

You need to use the fitBounds() method.

var markers = [];//some array
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
 bounds.extend(markers[i]);
}

map.fitBounds(bounds);

Documentation from developers.google.com/maps/documentation/javascript:

fitBounds(bounds[, padding])

Parameters:

`bounds`:  [`LatLngBounds`][1]|[`LatLngBoundsLiteral`][1]
`padding` (optional):  number|[`Padding`][1]

Return Value: None

Sets the viewport to contain the given bounds.
Note: When the map is set to display: none, the fitBounds function reads the map's size as 0x0, and therefore does not do anything. To change the viewport while the map is hidden, set the map to visibility: hidden, thereby ensuring the map div has an actual size.

Friday, June 11, 2021
 
hillz
answered 5 Months ago
91

While the use of icons is not currently implemented in addLegend(), Yihui suggested the use of addControl(), using raw html - which works perfectly!

library(leaflet)

# Sample Data
data(quakes)
quakes <- quakes[1:10,]

# Choose Icon:
leafIcons <- icons(
  iconUrl = ifelse(quakes$mag < 4.6,
                   "http://leafletjs.com/examples/custom-icons/leaf-green.png",
                   "http://leafletjs.com/examples/custom-icons/leaf-red.png"
  ),
  iconWidth = 38, iconHeight = 95,
  iconAnchorX = 22, iconAnchorY = 94)

html_legend <- "<img src='http://leafletjs.com/examples/custom-icons/leaf-green.png'>green<br/>
<img src='http://leafletjs.com/examples/custom-icons/leaf-red.png'>red"

# Produce Map:
leaflet(data = quakes) %>% addTiles() %>%
  addMarkers(~long, ~lat, icon = leafIcons) %>%
  addControl(html = html_legend, position = "bottomleft")

Links

  • Green: http://leafletjs.com/examples/custom-icons/leaf-green.png
  • Red: http://leafletjs.com/examples/custom-icons/leaf-red.png
  • Orange: http://leafletjs.com/examples/custom-icons/leaf-orange.png

Which produces:

Leaflet Map with Categorical Legend

Wednesday, June 23, 2021
 
tpow
answered 4 Months ago
36

The below will center the camera on a specific node. It can also smoothly transition to the new position over a set time frame.

class CameraScene : SKScene {
    // Flag indicating whether we've setup the camera system yet.
    var isCreated: Bool = false
    // The root node of your game world. Attach game entities 
    // (player, enemies, &c.) to here.
    var world: SKNode?
    // The root node of our UI. Attach control buttons & state
    // indicators here.
    var overlay: SKNode?
    // The camera. Move this node to change what parts of the world are visible.
    var camera: SKNode?

    override func didMoveToView(view: SKView) {
        if !isCreated {
            isCreated = true

            // Camera setup
            self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
            self.world = SKNode()
            self.world?.name = "world"
            addChild(self.world)
            self.camera = SKNode()
            self.camera?.name = "camera"
            self.world?.addChild(self.camera)

            // UI setup
            self.overlay = SKNode()
            self.overlay?.zPosition = 10
            self.overlay?.name = "overlay"
            addChild(self.overlay)
        }
    }


    override func didSimulatePhysics() {
        if self.camera != nil {
            self.centerOnNode(self.camera!)
        }
    }

    func centerOnNode(node: SKNode) {
        let cameraPositionInScene: CGPoint = node.scene.convertPoint(node.position, fromNode: node.parent)

        node.parent.position = CGPoint(x:node.parent.position.x - cameraPositionInScene.x, y:node.parent.position.y - cameraPositionInScene.y)
    }

}

Change what’s visible in the world by moving the camera:

// Lerp the camera to 100, 50 over the next half-second.
self.camera?.runAction(SKAction.moveTo(CGPointMake(100, 50), duration: 0.5))

Source: swiftalicio - 2D Camera in SpriteKit

For additional information, look at Apple's SpriteKit Programming Guide (Example: Centering the Scene on a Node).

Thursday, September 23, 2021
 
silvster27
answered 3 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :