0

I am working with the application Beta_Here which uses leaflet plugins, all libraries are local except for few(css related)

Usage of application live

First View:This application get input from user and set the distance calculation formula accordingly....

Second View : After entering input e.g 9, second view will be loaded where we can draw shapes....

Introduction

I have setup the script which will load two imageoverlays(layers) and we can toggle them from top right and we can draw or measure from bottom left....

Problem

When we draw shapes or put markers on an image, controls work nearly perfect but when we toggle the layers, there starts the problem.... all shapes go to the background or (it seems they disappeared)

Main Question

How can we bind the drawings and marker to the specific layer(imageoverlay) if there is a way as we can see the drawing are not bind with the images but the map container..... (Pardon me if you feel i am doing something stupid because i have limited knowledge about layers so i came up with my question here....

If someone has idea about how to solve this problem, please do help or any kind of reference will be appreciated... Thanks for your time

Working Script

var map = L.map('map', {
                    minZoom: 1,
                    maxZoom: 4,
                    center: [0, 0],
                    zoom: 0,
                    crs: L.CRS.Simple
                });

                // dimensions of the image
                var w = 3200,
                    h = 1900,
                    mainurl = 'assets/img/isbimg.jpg';
                childurl = 'assets/img/fjmap.png';
                // calculate the edges of the image, in coordinate space
                var southWest = map.unproject([0, h], map.getMaxZoom() - 1);
                var northEast = map.unproject([w, 0], map.getMaxZoom() - 1);
                var bounds = new L.LatLngBounds(southWest, northEast);

                var featureGroup = L.featureGroup().addTo(map);

                var drawControl = new L.Control.Draw({
                    edit: {
                        featureGroup: featureGroup
                    },
                    draw: {
                        polygon: true,
                        polyline: true,
                        rectangle: true,
                        circle: true,
                        marker: true
                    }
                }).addTo(map);

                map.on('draw:created', showPolygonArea);
                map.on('draw:edited', showPolygonAreaEdited);
                // add the image overlay,so that it covers the entire map
                L.control.layers({
                    Main: L.imageOverlay(mainurl, bounds),
                    Child: L.imageOverlay(childurl, bounds)
                }, null, { collapsed: false }).addTo(map);

                L.control.nanomeasure({ nanometersPerPixel: 10000 }).addTo(map);

                // tell leaflet that the map is exactly as big as the image
                map.setMaxBounds(bounds);

                L.tileLayer({
                    attribution: '<a href="http://smartminds.co">SmartMinds</a>',
                    maxZoom: 18
                }).addTo(map);

                //polygon area customization
                function showPolygonAreaEdited(e) {
                    e.layers.eachLayer(function (layer) {
                        showPolygonArea({ layer: layer });
                    });
                }
                function showPolygonArea(e) {
                    var userInputCustom = prompt("Please enter image name : choose between a to f");
                    featureGroup.addLayer(e.layer);
                    e.layer.bindPopup("<div style='width:200px;height:200px;background-image: url(assets/img/" + userInputCustom + ".png);background-size: 195px 195px;;background-repeat: no-repeat;'></div>");
                    e.layer.openPopup();
                }

            });
user229044
  • 232,980
  • 40
  • 330
  • 338
Suhail Mumtaz Awan
  • 3,295
  • 8
  • 43
  • 77

1 Answers1

1

I would contain those FeatureGroup and ImageOverlay pairs into L.LayerGroup's. Then you can switch between those groups. Then you can keep track of the currently selected group, and add your features to the featurelayer of that group. I can explain it better with code through comments:

Basic map, nothing special:

var map = L.map('map', {
  'center': [0, 0],
  'zoom': 1,
  'layers': [
    L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      'attribution': 'Map data &copy; OpenStreetMap contributors'
    })
  ]
});

// Bounds for the map and imageoverlays    
var bounds = L.latLngBounds([[40.712216, -74.22655],[40.773941, -74.12544]]);

// Set bounds on the map
map.fitBounds(bounds);

The grouping part:

// New layergroup, note it's not added to the map yet
var layerGroup = new L.LayerGroup(),
    imageOverlayUrl = 'https://placeholdit.imgix.net/~text?txtsize=33&txt=Overlay 1&w=294&h=238',
    // New imageoverlay added to the layergroup
    imageOverlay = new L.ImageOverlay(imageOverlayUrl, bounds).addTo(layerGroup),
    // New featuregroup added to the layergroup
    featureGroup = new L.FeatureGroup().addTo(layerGroup);

// Second layergroup not added to the map yet
var layerGroup2 = new L.LayerGroup(),
    imageOverlayUrl2 = 'https://placeholdit.imgix.net/~text?txtsize=33&txt=Overlay 2&w=294&h=238',
    // New imageoverlay added to the second layergroup
    imageOverlay2 = new L.imageOverlay(imageOverlayUrl2, bounds).addTo(layerGroup2),
    // New featuregroup added to the second layergroup
    featureGroup2 = new L.FeatureGroup().addTo(layerGroup2);

Default drawcontrol and layercontrol with both layergroups added as baselayers:

var layerControl = new L.control.layers({
  'Group 1': layerGroup,
  'Group 2': layerGroup2
}).addTo(map);

var drawControl = new L.Control.Draw().addTo(map);

Here's where the magic happens ;) :

// Variable to hold the selected layergroup's featuregroup.
var currentFeatureGroup;

// Catch the layer change event
map.on('baselayerchange', function (layersControlEvent) {
  // Loop over the layers contained in the current group
  layersControlEvent.layer.eachLayer(function (layer) {
    // If it's the imageoverlay make sure it's in the background
    if (layer instanceof L.ImageOverlay) {
      layer.bringToBack();
    // If not then it's the featuregroup, reference with variable.
    } else {
      currentFeatureGroup = layer;
    }
  });
});

// Catch draw created event    
map.on('draw:created', function (e) {
    // Store created feature into the current featuregroup
    currentFeatureGroup.addLayer(e.layer);
});

That's it. Pretty basic just meant as an example but it does what you want it to do. A real implementation would look different, with errorhandling because for instance when you draw and have no baselayer/overlay selected it fail etc. Here's a working example on Plunker to play with: http://plnkr.co/edit/6cGceX?p=preview

iH8
  • 27,722
  • 4
  • 67
  • 76