none
Multiple pin layers; deleting pins from the bottom layer RRS feed

  • Question

  • Hi everyone,

    I am currently developing a disaster app using Bing maps. I have two pin layers:

    1) The first layer (User layer) allows the user to plot their own location or another location they are interested in. For the pins in this layer, I have created a table for the user to track their plots and I have delete buttons for each pin in the table that allows the user to delete that location and pin.

    2) The second layer (Events layer) currently pulls earthquake data from USGS and plots it on the map. I activate this using a button.

    After activating the Events layer, I am still able to delete pins from the User layer if they are added before I activate the Events layer. However, I am no longer able to delete pins that are on the User layer if they are added after activating the Events layer. Does anyone know why?

    Wednesday, July 26, 2017 12:46 PM

Answers

  • You are creating a Layer, but adding it to map.entities which will not work. You need to add layers to map.layers using the insert function. So this "map.entities.push(pinLayer);" should be "map.layers.insert(pinLayer);". Then to remove you can use 

    You are also calling "addPinToMap(pinLayer, coordinates);" inside of a loop which means you are adding the same layer multiple times to the map which will cause issues. Move this outside of your for loop. 

    To remove the layer by index use, "map.layers.removeAt(idx);".

    Minor improvement, move this "Microsoft.Maps.Events.addHandler(pin, 'click', displayInfobox);" outside of the for loop and replace "pin" with "pinLayer". This will add the click event to the layer rather than to individual pushpins. It will fire only when the pushpins are clicked but adds a small performance boost as there would be a lot less event handlers for the map to deal with.


    [Blog] [twitter] [LinkedIn]

    Monday, July 31, 2017 1:18 PM

All replies

  • Can you provide a code sample. I'm not able to reproduce this. I have had several apps that use multiple layers and have been able to ad/remove data from each layer at any time without any issue.

    [Blog] [twitter] [LinkedIn]

    Wednesday, July 26, 2017 4:21 PM
  • <g class="gr_ gr_3 gr-alert gr_gramm gr_inline_cards gr_run_anim Punctuation only-ins replaceWithoutSep" data-gr-id="3" id="3">Hi</g> Ricky, this is the relevant code:

    $(document).ready(function() {
                    
                    //apiKey info
                    var apiKey = "BING MAP API KEY";
    
                    //array that stores pushpin info
                    var pushPinInfo = [];
                    var location = [];
                    var eventPin = [];
                    
                    //delay calling map
                    var timeoutID = window.setTimeout(createMap, 1500);
    
                    //get current time
                    var time = new Date().getTime();
    
                    //create map
                    function createMap() {
                        //generating map options
                        var mapOptions = {
                            credentials: apiKey,
                            mapTypeId: Microsoft.Maps.MapTypeId.road,
                            zoom: 9
                            
                        };
    
                        //print map
                        map = new Microsoft.Maps.Map("#myMap", mapOptions);
                        
                    };
    
                    //add entered primary form data to pinLayer
                    function addPinLayer() {
    
                        //creating layers
                        var pinLayer = new Microsoft.Maps.Layer();
    
                        //generating pushpins and placing them in pin layer
                        var coordinates = new Microsoft.Maps.Location(pushPinInfo[pushPinInfo.length - 1][0], 
                            pushPinInfo[pushPinInfo.length - 1][1]);
                        var pin = new Microsoft.Maps.Pushpin(coordinates, 
                            {title:pushPinInfo[pushPinInfo.length - 1][3], 
                            color:pushPinInfo[pushPinInfo.length - 1][4],
                            'draggable': true});                   
                        pinLayer.add(pin);
                                            
                        //placing pin on map
                        addPinToMap(pinLayer, coordinates);
    
                    };
    
                    
    
                    //function to add pin to map and zoom to coordinates
                    function addPinToMap(pinLayer, coordinates) {
    
                        map.entities.push(pinLayer);
                        bestView(coordinates);
    
                    };
                    
                    function bestView(coordinates) {
    
                        var maxLat = -90;
                        var minLat = 90;
                        var maxLong = -180;
                        var minLong = 180;
                        var centerLat = 0;
                        var centerLong = 0;
    
                        for (var i = 0; i < pushPinInfo.length; i++) {
                            if (maxLat < pushPinInfo[i][0]) {
                                maxLat = pushPinInfo[i][0]
                            }
    
                            if (minLat > pushPinInfo[i][0]) {
                                minLat = pushPinInfo[i][0]
                            }
    
                            if (maxLong < pushPinInfo[i][1]) {
                                maxLong = pushPinInfo[i][1]
                            }
    
                            if (minLong > pushPinInfo[i][1]) {
                                minLong = pushPinInfo[i][1]
                            }
    
                        };
    
                        centerLat = (maxLat + minLat) / 2;
                        centerLong = (maxLong + minLong) / 2;
                        var centerPoint = new Microsoft.Maps.Location(centerLat, centerLong);
    
                        var sw = new Microsoft.Maps.Location(minLat, minLong);
                        var ne = new Microsoft.Maps.Location(maxLat, maxLong);
                        var rectangle = new Microsoft.Maps.LocationRect.fromCorners(sw, ne);
    
                        if (pushPinInfo.length == 1) {
    
                            map.setView({center: coordinates});
                        
                        } else {
    
                            map.setView({bounds:rectangle});
    
                        }
    
                    };
    
     
                    //update table info
                    function updateTable() {
    
                        //remove table hidden attribute
                        $("#outputPanel").removeAttr("hidden");
    
                        //delete table contents for refresh of table
                        //easier to reload information from array
                        $(".tableItem").empty();
    
                        //add row for latest pin added
                        for (var j = 0; j <pushPinInfo.length; j++) {        
                            $("#table tbody:last-child").append(
                                "<tr class='tableItem'>" + 
                                "<th>" + (j + 1) + "</th>" +
                                "<th>" + pushPinInfo[j][2] + "</th>" +
                                "<th>" + pushPinInfo[j][0].toFixed(5) + "</th>" +
                                "<th>" + pushPinInfo[j][1].toFixed(5) + "</th>" +
                                "<th>" + '<button type="button" class="btn btn-info btn-sm deletePin" id="delButton' + (j) + '">Delete Pin</button>' + "</th>" +
                                "</tr>");                  
                        }
    
                    };
    
                    //remove pin handler
                    function removePinFromMap(index) {
                        
                            map.entities.removeAt(index);
                        
                    };
    
                    function timeSince(date) {
    
                        var seconds = Math.floor((new Date() - date) / 1000);
    
                        var interval = Math.floor(seconds / 31536000);
    
                        if (interval > 1) {
                            return interval + " years";
                        }
                        interval = Math.floor(seconds / 2592000);
                        if (interval > 1) {
                            return interval + " months";
                        }
                        interval = Math.floor(seconds / 86400);
                        if (interval > 1) {
                            return interval + " days";
                        }
                        interval = Math.floor(seconds / 3600);
                        if (interval > 1) {
                            return interval + " hours";
                        }
                        interval = Math.floor(seconds / 60);
                        if (interval > 1) {
                            return interval + " minutes";
                        }
                        
                        return Math.floor(seconds) + " seconds";
                    }
    
                    //click function for primary submit button
                    $("#submitPrimaryForm").click(function () {
    
                        //check user has entered something
                        if ($("#location").val().length > 0) {
                            
                            //send location query to bing maps REST api
                            var query = $("#location").val();
                            $.getJSON('http://dev.virtualearth.net/REST/v1/Locations?query=' + encodeURIComponent(query) + "&key=" + apiKey +"&jsonp=?", function (result) {
                                if (result.resourceSets[0].estimatedTotal > 0) {
                                    
                                    //check user has entered description
                                    if ($("#description").val().length != 0) {
                                        //get coordinates
                                        var loc = result.resourceSets[0].resources[0].point.coordinates;
                                        
                                        //description of the venue
                                        var description = $("#description").val();
                                        var des;
    
                                        //check if checkboxed is checked
                                        if ($("#desCheck").prop("checked")) {
                                            des = description;
                                        } else {
                                            des = "";
                                        };
                                        
                                        //if pin color is checked in form
                                        var col = $('input[name=pinColor]:checked', "#pinDetails").val();
                                        
                                        //form array of pin details and add to pushPinInfo array
                                        var addPin = [loc[0], loc[1], description, des, col];
                                        pushPinInfo.push(addPin);
    
                                        //take new pin info and publish pin layer and table
                                        addPinLayer();               
                                        updateTable();
    
                                        $("#errorPanel").removeAttr("hidden").addClass("alert-success").removeClass("alert-danger").html("<strong>Pin added.</strong>");
                                        
                                    } else {
    
                                        $("#errorPanel").removeAttr("hidden").addClass("alert-danger").removeClass("alert-success").html("<strong>Please enter a description.</strong>");
                                    }
                                }
                                else {
    
                                    $("#errorPanel").removeAttr("hidden").addClass("alert-danger").removeClass("alert-success").html("<strong>Sorry that address cannot be found.</strong>");
                                }
                            });
                        }
                        else {
                            $("#errorPanel").removeAttr("hidden").addClass("alert-danger").removeClass("alert-success").html("<strong>Please enter an address</strong>");
                        }
                    });
    
                    //delegated click handler for delete pin button
                    $(document).delegate(".deletePin", "click", function(e) {
    
                        //get button id
                        var buttonId = e.target.id;
                        var index = buttonId[buttonId.length - 1];
                        pushPinInfo.splice(index, 1);
                        removePinFromMap(index);
                        updateTable();
                        $("#errorPanel").addClass("alert-success").removeClass("alert-danger").html("<strong>Pin deleted.</strong>");
    
                    });
    
    //add event pin with infobox
                    function eventPinLoad() {
                        
                        var pinLayer = new Microsoft.Maps.Layer();
                      
                        for (var i = 0; i < eventPin.length; i++) {
    
                            //generating pushpins and placing them in pin layer
                            var coordinates = new Microsoft.Maps.Location(eventPin[i][0], 
                                eventPin[i][1]);
                            var pin = new Microsoft.Maps.Pushpin(coordinates, 
                                {'draggable': false});
    
                            //Create an infobox at the center of the map but don't show it.
                            infobox = new Microsoft.Maps.Infobox(pin.getLocation(), {
                                visible: false
                            });
    
                            //Assign the infobox to a map instance.
                            infobox.setMap(map);
    
                            //Store some metadata with the pushpin.
                            pin.metadata = {
                                title: eventPin[i][2],
                                description: eventPin[i][3]
                                
                            };
    
                            pinLayer.add(pin);
                            addPinToMap(pinLayer, coordinates);
                            Microsoft.Maps.Events.addHandler(pin, 'click', displayInfobox);
                            
                        }
                    };
    
                    function displayInfobox(e) {
                        //Make sure the infobox has metadata to display.
                        if (e.target.metadata) {
                            //Set the infobox options with the metadata of the pushpin.
                            infobox.setOptions({
                                location: e.target.getLocation(),
                                title: e.target.metadata.title,
                                description: e.target.metadata.description,
                                visible: true
                            });
    
                        }
                    }
                    
                    function earthquakes() {
    
                        callUSGS();
                        // Loop through the results array and place a marker for each
                        // set of coordinates.
                        var latestEarthquake;
                        
                        window.eqfeed_callback = function(results) {
    
                            // latestEarthquake = results.features[0].properties.title;
                            // alert(latestEarthquake);
                            
                            for (var i = 0; i < results.features.length; i++) {
                                
                                var loc = results.features[i].geometry.coordinates;
                                // var coordinates = new Microsoft.Maps.Location(loc[1],loc[0]);
                                                           
                                //create description
                                var mag = (results.features[i].properties.mag).toString();
    
                                // add title
                                var title = "M" + mag + " Earthquake";
    
                                //add description
                                var eventTime = results.features[i].properties.time;
                                var timeString = (timeSince(eventTime)).toString();
                                var earthquakePlace = (results.features[i].properties.place).toString();
                                var url = results.features[i].properties.url;
                                var des = "<a href='" + url + "'>A M" + mag + " earthquake occured " + timeString + " ago at " + earthquakePlace + ".</a>";
    
                                var earthquakeArray = [loc[1], loc[0], title, des];
                                eventPin.push(earthquakeArray);
                                
                                eventPinLoad()
                                
                            }
                                                                                          
                        }
       
                    }
    
                    $("#test").on("click", earthquakes)
    
                });

    Hope this clarifies my problem.

    -Tim

    Monday, July 31, 2017 9:31 AM
  • You are creating a Layer, but adding it to map.entities which will not work. You need to add layers to map.layers using the insert function. So this "map.entities.push(pinLayer);" should be "map.layers.insert(pinLayer);". Then to remove you can use 

    You are also calling "addPinToMap(pinLayer, coordinates);" inside of a loop which means you are adding the same layer multiple times to the map which will cause issues. Move this outside of your for loop. 

    To remove the layer by index use, "map.layers.removeAt(idx);".

    Minor improvement, move this "Microsoft.Maps.Events.addHandler(pin, 'click', displayInfobox);" outside of the for loop and replace "pin" with "pinLayer". This will add the click event to the layer rather than to individual pushpins. It will fire only when the pushpins are clicked but adds a small performance boost as there would be a lot less event handlers for the map to deal with.


    [Blog] [twitter] [LinkedIn]

    Monday, July 31, 2017 1:18 PM
  • You are creating a Layer, but adding it to map.entities which will not work. You need to add layers to map.layers using the insert function. So this "map.entities.push(pinLayer);" should be "map.layers.insert(pinLayer);". Then to remove you can use 

    The sentence above is cut off. Is there another line of code that should be there?

    Tuesday, August 1, 2017 7:20 AM
  • Wierd typo, I added the info to remove a few lines later.

    [Blog] [twitter] [LinkedIn]

    Tuesday, August 1, 2017 1:19 PM