2
votes

I am attempting to get Leaflet to work for a standard, non-map image so that I can place markers on the image using pixels, not geographic latitude and longitudinal coordinates.

Here's a fiddle I'm attempting to get working:

http://jsfiddle.net/letsgetsilly/8Neau/4/

<div id="map" style="width: 1500px; height: 2316px"></div>

<script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
<script>

     var map = L.map('map', {
        maxZoom: 4,
        minZoom: 2,
        crs: L.CRS.Simple
     }).setView([0,50], 4);

    var southWest = map.unproject([0, 4000], map.getMaxZoom());
    var northEast = map.unproject([1500, 0], map.getMaxZoom());
    map.setMaxBounds(new L.LatLngBounds(southWest, northEast));


    //actual image dimensions: 1500 x 2000
    var imageUrl = 'https://i.imgur.com/bXA34EQ.jpg';

    var southWestSize = map.unproject([0, 2000], map.getMaxZoom());
    var northEastSize = map.unproject([1500, 0], map.getMaxZoom());
    L.imageOverlay(imageUrl, new L.LatLngBounds(southWestSize, northEastSize)).addTo(map);

    function onMapClick(e) {
        popup
            .setLatLng(e.latlng)
            .setContent("You clicked the map at " + e.latlng.toString())
            .openOn(map);
    }
    map.on('click', onMapClick);

    L.marker(map.unproject([800, 300])).addTo(map).bindPopup("<b>I'm a dog!</b><br />I am a popup.<br /> ").openPopup();


</script>

I'm struggling on a couple of levels:

  1. I don't understand how to setView appropriately for a picture. What does leaflet need?
  2. I don't know how to get lat/lng coordinates of an image
  3. I don't know how to control the image's location on the screen, nor its size, so that it doesn't appear mangled

For those in a similar situation I found partial help from these sources:

Is Leaflet a good tool for non-map images?

http://omarriott.com/aux/leaflet-js-non-geographical-imagery/

http://maps.mixedbredie.net/leaflet/image.html

1
hey letsgetsilly, did you manage to get a solution? thanks!bobleujr

1 Answers

1
votes

I use a much simpler method of displaying a large image with leaflet, and then include a function to show the coordinates when you click on the image. Select the point of interest, click, then copy the coordinates to your code for a marker.

The code below illustrates the main points. I have also written a tutorial at https://peter-thomson.com/leaflet-map-tutorial/leaflet-map-tutorial-how-to-add-markers-and-popups-to-an-image-or-diagram-displayed-using-leaflet.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">

  <title>Display images with icons using leaflet</title>
  <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
  <script src="https://unpkg.com/[email protected]/dist/leaflet.js" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" crossorigin=""></script>
</head>

<body>
  <h1>Display images with icons using leaflet</h1>
  <div id="image-map" style="width: 1152px; height: 864px; border: 1px solid #AAA;"></div>
  <script>
    // Using leaflet.js to pan and zoom a big image.
    var map = L.map('image-map', {
      minZoom: 1,
      maxZoom: 4,
      center: [0, 0],
      zoom: 1,
      maxBoundsViscosity: 1,
      crs: L.CRS.Simple

    });
    //zoom 4 full size image is 4608px * 3456 px
    //zoom 3 2304 * 1728
    //zoom 2 1152 * 864
    //zoom 1 576 * 432

    var image = L.imageOverlay("https://peter-thomson.com/images/Dolomites%202016%20Peter%20A/960/P1050579.JPG", [
      [0, 0],
      [432, 576]
    ]); //initial size ( at zoom 0, double size at zoom 1 )
    image.addTo(map);
    // tell leaflet that the map is exactly as big as the image
    map.setMaxBounds(new L.LatLngBounds([0, 0], [432, 576])); // prevent panning outside the image area 
    L.tileLayer('', {
      attribution: '&copy; <a href="https://peter-thomson.com">Peter Thomson 2018</a>'
    }).addTo(map);
    //note - don't change bounds after adding marker coordinates
    var popup = L.popup();

    function onMapClick(e) {
      popup
        .setLatLng(e.latlng)
        .setContent("You clicked the map at " + e.latlng.toString())
        .openOn(map);
    }
    map.on('click', onMapClick);

    var DownIcon = L.Icon.extend({
      options: {

        iconSize: [40, 40], // size of the icon
        iconAnchor: [20, 40], // point of the icon which will correspond to marker's location
        popupAnchor: [0, 0] // point from which the popup should open relative to the iconAnchor
      }
    });

    var downblueIcon = new DownIcon({
        iconUrl: 'https://peter-thomson.com/appdevelopmenttutorials/leaflet-map/down-blue-icon.png'
      }),
      downyellowIcon = new DownIcon({
        iconUrl: 'https://peter-thomson.com/appdevelopmenttutorials/leaflet-map/down-yellow-icon.png'
      });
    mark1 = L.marker([247.433334, 312.5], {
      icon: downyellowIcon
    }).bindPopup(L.popup({
      maxWidth: 500
    }).setContent("Duron Pass: the far point of the walk. There is a path along the ridge to the left from the top of the pass")).addTo(map);
    mark2 = L.marker([203.933334, 364.5], {
      icon: downblueIcon
    }).bindPopup(L.popup({
      maxWidth: 500
    }).setContent("We followed this path")).addTo(map);
  </script>
</body>

</html>