none
DrawingTools, how to delete shape from the map / How to draw/edit circle using Bing 8 API RRS feed

  • Question

  • Hello,

    I'm a very  newbie to Bing API and have to migrate our application from Bing 7 to the Bing 8.

    I made a custom tool bar for drawing shapes on map v8.

    I'm using DrawingTools class to create shapes (polygon and polyline)  but do not manage to delete the shapes once created.

    I check the entities collection of the map and the Layer collection and they are all empty althought the shape is on the map.

    1) How do I get a reference of the shape drawn on the map, using the  create method of the DrawingTools class ? How do I delete them ?

    2) Is there a way to Create/Edit circle in Bing V8  using a custom toolbar and Bing API ?

    Many thanks for your Help.

    HK

    Wednesday, September 21, 2016 11:30 AM

Answers

  • Ah, you are making things hard for yourself. I thought you wanted to allow multiple shapes to be drawn at the map at once, then retrieve them afterwards. If you draw one shape at a time you can get the shape out of the drawing tools, use the finish function. Here is a simple code sample that lets you draw polygons. When you are done drawing either press the drawing button again, or press esc.

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script type='text/javascript'
                src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap'
                async defer></script>
        <script type='text/javascript'>
        var map;
        var tools;
        var currentShape;
    
        function GetMap() {
            map = new Microsoft.Maps.Map('#myMap', {
                credentials: 'Your Bing Maps Key'
            });
    
            //Load the DrawingTools module.
            Microsoft.Maps.loadModule('Microsoft.Maps.DrawingTools', function () {
                //Create an instance of the DrawingTools class and bind it to the map.
                tools = new Microsoft.Maps.DrawingTools(map);
            
                //When the user presses 'esc', take the polygon out of edit mode and re-add to base map.
                document.getElementById('myMap').onkeypress = function (e) {
                    if (e.charCode === 27) {
                        tools.finish(shapeDrawn);
                        currentShape = null;
                    }
                };
            });
        }
    
        function drawPolygon() {
            //Stop any current drawing. 
            if (currentShape) {
                tools.finish(shapeDrawn);
                currentShape = null;
            }
    
            //Create a new polygon.
            tools.create(Microsoft.Maps.DrawingTools.ShapeType.polygon, function (s) {
                currentShape = s;
            });
        }
    
        function shapeDrawn(s) {
            //Do somethign with the shape that was drawn.
            //For this demo add it as a standard shape on the map.
            map.entities.push(s);
        }
        </script>
    </head>
    <body>
        <div id="myMap" style=";width:600px;height:400px;"></div><br/>
        <input type="button" onclick="drawPolygon()" value="Draw Polygon"/>
    </body>
    </html>


    [Blog] [twitter] [LinkedIn]

    • Proposed as answer by Ricky_Brundritt Thursday, September 22, 2016 5:39 PM
    • Marked as answer by HK2319 Friday, September 23, 2016 7:25 AM
    Thursday, September 22, 2016 5:38 PM
  • As for creating circles, you can use the spatial math library to calculate the points of a circle. Here is a code sample:

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8" />
    
        <script type='text/javascript'
                src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap'
                async defer></script>
    
        <script type='text/javascript'>
            var map,
                outputPanel,
                circle,
                mouseDownEventHandler,
                mouseMoveEventHandler,
                mouseUpEventHandler;
    
        function GetMap()
        {
            map = new Microsoft.Maps.Map('#myMap', {
                credentials: 'Your Bing Maps Key'
            });
    
            Microsoft.Maps.loadModule('Microsoft.Maps.SpatialMath');
    
            outputPanel = document.getElementById('output');
        }
    
        function DrawCircle() {
            ClearDrawing();        
    
            mouseDownEventHandler = Microsoft.Maps.Events.addHandler(map, 'mousedown', function (e) {
                //Lock map so it doesn't move when dragging.
                map.setOptions({ disablePanning: true });
    
                //Create a polygon for the circle.
                circle = new Microsoft.Maps.Polygon([e.location, e.location, e.location]);
    
                //store the center point in the polygons metadata.
                circle.metadata = {
                    center: e.location
                };
    
                map.entities.push(circle);
            });
    
            mouseMoveEventHandler = Microsoft.Maps.Events.addHandler(map, 'mousemove', function (e) {
                if (circle) {
                    UpdateCircle(e);
                }
            });
    
            mouseUpEventHandler = Microsoft.Maps.Events.addHandler(map, 'mouseup', function (e) {
                UpdateCircle(e);
    
                //Unlock map panning.
                map.setOptions({ disablePanning: false });
    
                //Remove event handlers.
                Microsoft.Maps.Events.removeHandler(mouseDownEventHandler);
                Microsoft.Maps.Events.removeHandler(mouseMoveEventHandler);
                Microsoft.Maps.Events.removeHandler(mouseUpEventHandler);
            });
        }
    
        function ClearDrawing() {
            map.entities.clear();
            circle = null;
            outputPanel.innerHTML = '';
        }
    
        function UpdateCircle(e) {
            //Calculate distance from circle center to mouse.
            var distance = Microsoft.Maps.SpatialMath.getDistanceTo(circle.metadata.center, e.location, Microsoft.Maps.SpatialMath.DistanceUnits.Miles);
    
            //Calculate circle locations.
            var locs = Microsoft.Maps.SpatialMath.getRegularPolygon(circle.metadata.center, distance, 36, Microsoft.Maps.SpatialMath.DistanceUnits.Miles);
    
            //Update the circles location.
            circle.setLocations(locs);
    
            //Display the radius in miles rounded to 2 decimal places.
            outputPanel.innerHTML = 'Radius: ' + Math.round(distance*1000)/1000 + ' miles';
        }
        </script>
    </head>
    <body>
        <div id="myMap" style=";width:600px;height:400px;"></div>
        <br/>
        <input type="button" value="Draw Circle" onclick="DrawCircle()"/>
        <br/>
        <div id="output"></div>
    </body>
    </html>


    [Blog] [twitter] [LinkedIn]

    • Proposed as answer by Ricky_Brundritt Thursday, September 22, 2016 5:40 PM
    • Unproposed as answer by Ricky_Brundritt Thursday, September 22, 2016 5:40 PM
    • Proposed as answer by Ricky_Brundritt Thursday, September 22, 2016 5:40 PM
    • Marked as answer by HK2319 Thursday, October 20, 2016 10:53 AM
    Thursday, September 22, 2016 5:40 PM

All replies

  • When using the Drawing Tools shapes are rendered in a separate layer. How you get access to the shapes depends on how you add them. If you are using the built in toolbar and the DrawingManager class, then you can use the getPrimitives function on the drawing manager. Since you created a custom toolbar, you likely aren't using the drawing manager and are managing the data your self. When using the create function of drawing tools you can pass in a callback function which will be called after the shape has been initially created. You can use this to get a reference to a shape. A simple way to track these shapes is to have an array and the shapes to it every time this callback function is triggered. Later, when you want all the shapes that have been drawn, they will be in that array. Alternatively you can also use the finish function as well. The callback function for these functions was added to the main release branch in the August update and the documentation updated here: https://msdn.microsoft.com/en-us/library/mt750463.aspx

    [Blog] [twitter] [LinkedIn]

    • Proposed as answer by Ricky_Brundritt Wednesday, September 21, 2016 8:05 PM
    • Marked as answer by HK2319 Thursday, September 22, 2016 8:46 AM
    • Unmarked as answer by HK2319 Thursday, September 22, 2016 9:13 AM
    Wednesday, September 21, 2016 8:05 PM
  • Hello Ricky_Brundritt,

    Thank you for your answear.

    What I'm trying to do is to remove the polygon from the map once it is drawn using a DrawingTools object.

    I tried to remove all references as you explained but the polygon still remain on the map.

    If I could access the separated layer where shapes are rendered when using the Drawing Tools, that you mentioned in your reply, then I would be able to call its 'clear()' method, to remove the shape from the map.

    Here is the code  :

    The shape is not removed from the map using this code.

    //To collect drawing shapes var shapes = []; //Create polygon function DrawPolygon() { tools.create(Microsoft.Maps.DrawingTools.ShapeType.polygon,getShape); } //Callback function function getShape(polygon){ shapes.push(polygon); } function deletePolygon(){ if(shapes.length != 0){ shapes.splice(0,shapes.length);//Remove all elements from shapes } shapes = null;

    //map.entities.clear();

    //map.layers.clear(); }


    Thanks a lot for your help.

    HK




    • Edited by HK2319 Thursday, September 22, 2016 12:49 PM
    Thursday, September 22, 2016 12:22 PM
  • Ah, you are making things hard for yourself. I thought you wanted to allow multiple shapes to be drawn at the map at once, then retrieve them afterwards. If you draw one shape at a time you can get the shape out of the drawing tools, use the finish function. Here is a simple code sample that lets you draw polygons. When you are done drawing either press the drawing button again, or press esc.

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8" />
        <script type='text/javascript'
                src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap'
                async defer></script>
        <script type='text/javascript'>
        var map;
        var tools;
        var currentShape;
    
        function GetMap() {
            map = new Microsoft.Maps.Map('#myMap', {
                credentials: 'Your Bing Maps Key'
            });
    
            //Load the DrawingTools module.
            Microsoft.Maps.loadModule('Microsoft.Maps.DrawingTools', function () {
                //Create an instance of the DrawingTools class and bind it to the map.
                tools = new Microsoft.Maps.DrawingTools(map);
            
                //When the user presses 'esc', take the polygon out of edit mode and re-add to base map.
                document.getElementById('myMap').onkeypress = function (e) {
                    if (e.charCode === 27) {
                        tools.finish(shapeDrawn);
                        currentShape = null;
                    }
                };
            });
        }
    
        function drawPolygon() {
            //Stop any current drawing. 
            if (currentShape) {
                tools.finish(shapeDrawn);
                currentShape = null;
            }
    
            //Create a new polygon.
            tools.create(Microsoft.Maps.DrawingTools.ShapeType.polygon, function (s) {
                currentShape = s;
            });
        }
    
        function shapeDrawn(s) {
            //Do somethign with the shape that was drawn.
            //For this demo add it as a standard shape on the map.
            map.entities.push(s);
        }
        </script>
    </head>
    <body>
        <div id="myMap" style=";width:600px;height:400px;"></div><br/>
        <input type="button" onclick="drawPolygon()" value="Draw Polygon"/>
    </body>
    </html>


    [Blog] [twitter] [LinkedIn]

    • Proposed as answer by Ricky_Brundritt Thursday, September 22, 2016 5:39 PM
    • Marked as answer by HK2319 Friday, September 23, 2016 7:25 AM
    Thursday, September 22, 2016 5:38 PM
  • As for creating circles, you can use the spatial math library to calculate the points of a circle. Here is a code sample:

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <meta charset="utf-8" />
    
        <script type='text/javascript'
                src='http://www.bing.com/api/maps/mapcontrol?callback=GetMap'
                async defer></script>
    
        <script type='text/javascript'>
            var map,
                outputPanel,
                circle,
                mouseDownEventHandler,
                mouseMoveEventHandler,
                mouseUpEventHandler;
    
        function GetMap()
        {
            map = new Microsoft.Maps.Map('#myMap', {
                credentials: 'Your Bing Maps Key'
            });
    
            Microsoft.Maps.loadModule('Microsoft.Maps.SpatialMath');
    
            outputPanel = document.getElementById('output');
        }
    
        function DrawCircle() {
            ClearDrawing();        
    
            mouseDownEventHandler = Microsoft.Maps.Events.addHandler(map, 'mousedown', function (e) {
                //Lock map so it doesn't move when dragging.
                map.setOptions({ disablePanning: true });
    
                //Create a polygon for the circle.
                circle = new Microsoft.Maps.Polygon([e.location, e.location, e.location]);
    
                //store the center point in the polygons metadata.
                circle.metadata = {
                    center: e.location
                };
    
                map.entities.push(circle);
            });
    
            mouseMoveEventHandler = Microsoft.Maps.Events.addHandler(map, 'mousemove', function (e) {
                if (circle) {
                    UpdateCircle(e);
                }
            });
    
            mouseUpEventHandler = Microsoft.Maps.Events.addHandler(map, 'mouseup', function (e) {
                UpdateCircle(e);
    
                //Unlock map panning.
                map.setOptions({ disablePanning: false });
    
                //Remove event handlers.
                Microsoft.Maps.Events.removeHandler(mouseDownEventHandler);
                Microsoft.Maps.Events.removeHandler(mouseMoveEventHandler);
                Microsoft.Maps.Events.removeHandler(mouseUpEventHandler);
            });
        }
    
        function ClearDrawing() {
            map.entities.clear();
            circle = null;
            outputPanel.innerHTML = '';
        }
    
        function UpdateCircle(e) {
            //Calculate distance from circle center to mouse.
            var distance = Microsoft.Maps.SpatialMath.getDistanceTo(circle.metadata.center, e.location, Microsoft.Maps.SpatialMath.DistanceUnits.Miles);
    
            //Calculate circle locations.
            var locs = Microsoft.Maps.SpatialMath.getRegularPolygon(circle.metadata.center, distance, 36, Microsoft.Maps.SpatialMath.DistanceUnits.Miles);
    
            //Update the circles location.
            circle.setLocations(locs);
    
            //Display the radius in miles rounded to 2 decimal places.
            outputPanel.innerHTML = 'Radius: ' + Math.round(distance*1000)/1000 + ' miles';
        }
        </script>
    </head>
    <body>
        <div id="myMap" style=";width:600px;height:400px;"></div>
        <br/>
        <input type="button" value="Draw Circle" onclick="DrawCircle()"/>
        <br/>
        <div id="output"></div>
    </body>
    </html>


    [Blog] [twitter] [LinkedIn]

    • Proposed as answer by Ricky_Brundritt Thursday, September 22, 2016 5:40 PM
    • Unproposed as answer by Ricky_Brundritt Thursday, September 22, 2016 5:40 PM
    • Proposed as answer by Ricky_Brundritt Thursday, September 22, 2016 5:40 PM
    • Marked as answer by HK2319 Thursday, October 20, 2016 10:53 AM
    Thursday, September 22, 2016 5:40 PM