Display the distance or length of the drawn line

Balasaheb Molawade 136 Reputation points
2024-05-14T10:56:26.46+00:00

Hi,

We are utilizing the Bing Maps drawing tool to create lines on the map, and we have successfully drawn the desired line. Additionally, we have a further requirement to display the distance or length of the drawn line. We are seeking a method within Bing Maps to showcase this information atop the line.

Bing map draw line:

1

Below is what we are looking for: a line with length and distance displayed.

2

Azure Maps
Azure Maps
An Azure service that provides geospatial APIs to add maps, spatial analytics, and mobility solutions to apps.
608 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. rbrundritt 15,546 Reputation points Microsoft Employee
    2024-05-14T14:58:37.26+00:00

    I've took a stab at this using these steps:

    • Use the drawing tools to enable a drawing experience.
    • Use the drawing started, erased, and changing events to monitor the drawing state.
    • When drawing started, create a layer for the distance labels of that shape. Add a reference to that layer in the metadata of that shape so we can remove that layer when the shape is erased. Measure the shape.
    • When a shape is erased, grab the label layer reference from the shapes metadata and delete the layer.
    • When the shape is changing, measure the length of each line segment and create a pushpin (or infobox) for each line. Choose where you want to display it. I choose 3/4 of the way down the line so that the both the end points and the middle point of the lines are not covered and can be grabbed with the mouse when editing. Replace the pushpins layer.

    Here is a code sample (I didn't bother customizing the pushpin icon):

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title></title>
    
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
        
        <script>
        var map, drawingManager, currentLayer;
    
        function GetMap() {
            map = new Microsoft.Maps.Map('#myMap', {});		
    
            //Load the Drawing Tools and Spatial Math modules.
            Microsoft.Maps.loadModule(['Microsoft.Maps.DrawingTools', 'Microsoft.Maps.SpatialMath'], function () {
                var tools = new Microsoft.Maps.DrawingTools(map);
                tools.showDrawingManager(function (manager) {
                    //Store a reference to the drawing manager as it will be useful later.
                    drawingManager = manager;
    				
    				var da = Microsoft.Maps.DrawingTools.DrawingBarAction;
    				manager.setOptions({
    					drawingBarActions:  da.polyline | da.edit | da.erase
    				});
    
                    Microsoft.Maps.Events.addHandler(drawingManager, 'drawingChanging', measureShape);
    
                    Microsoft.Maps.Events.addHandler(drawingManager, 'drawingStarted', drawStarted);
    				
    				Microsoft.Maps.Events.addHandler(drawingManager, 'drawingErased', drawingErased);
                })
            });
        }
    
    	function drawStarted(shape) {
    		//Make sure the shape isn't attached to a layer for labels already.
    		if(!shape.metadata || !shape.metadata.layer) {
    			//Create a layer for current shape being drawn.
    			currentLayer = new Microsoft.Maps.Layer();
    			map.layers.insert(currentLayer);
    			
    			//Add a reference to the shape in the metadata of the shape so we can remove the labels when the line is erased.
    			shape.metadata = {
    				layer: currentLayer 
    			};
    			
    			//Measure the shape.
    			measureShape(shape);
    		}
    	}
    	
    	function drawingErased(shape) {
    		if(shape.metadata && shape.metadata.layer) {
    			map.layers.remove(shape.metadata.layer);
    		}
    	}
    
        function measureShape(shape) {
    		if (shape instanceof Microsoft.Maps.Polyline) {
    			var points = shape.getLocations();
    			
    			var distancePins = [];
    			
    			//Measure the length of each line segment in a polyline, and calculate midpoints for the labels pins.
    			for(var i = 0; i < points.length - 1; i++) {
    				var length = Microsoft.Maps.SpatialMath.getDistanceTo(points[i], points[i + 1], Microsoft.Maps.SpatialMath.DistanceUnits.Kilometers);
    				
    				//Round values to 2 decimals. 
    				length = Math.round(length * 100) / 100;
    				
    				//Add the pin close to the end of the line, but not at the very end, otherwise we won't be able to grab the point for editting the line.
    				//Keep the middle clear so that the midpoint can be grabbed for inserting points when drawing.
    				var pinLocation = Microsoft.Maps.SpatialMath.interpolate(points[i], points[i + 1], 0.75);				
    				
    				distancePins.push(new Microsoft.Maps.Pushpin(pinLocation, {
    					text: length + 'km'
    				}));
    			}
    			
    			//Replace pins in layer.
    			currentLayer.clear();
    			currentLayer.add(distancePins);
            }
        }
        </script>
    </head>
    <body>
        <div id="myMap" style="position:relative;width:100%;height:800px;"></div>
    
    	<script src="https://www.bing.com/api/maps/mapcontrol?callback=GetMap&key=<YOUR_BING_MAPS_KEY>"></script>
    </body>
    </html>