Answered by:
Bing map V8 Drawing shape question.
Question

Hi,
We have one requirement two find the interaction or common area between two draw shapes and is there any way to merge common area into one shape. Please check following image that we are looking for.
Also is there any way to undo the draw shape as we do in word document/mspaint.
We are planning to use the drawing tool of bing map V8.
Can you please let us know how to achieve this.
Thanks!
Balasaheb
 Edited by Balasaheb Molawade Wednesday, October 5, 2016 11:42 AM
Answers

Calculating the intersection and merging (union) of shapes can be done using the Spatial Math module in Bing Maps V8:
http://www.bing.com/api/maps/sdk/mapcontrol/isdk#binaryOperations+JS
https://msdn.microsoft.com/enus/library/mt712834.aspx
There is no undo option for drawn shapes. You could potentially manage this yourself by using the change events in the drawing manager.
 Proposed as answer by Ricky_Brundritt Wednesday, October 5, 2016 5:34 PM
 Marked as answer by Ricky_Brundritt Tuesday, October 25, 2016 6:16 PM

Please use the documented API: https://msdn.microsoft.com/enus/library/mt712542.aspx
First you will need to get the shape. If you are loading in the data from the Bing Spatial Data Services, an array of shapes are returned when you make a query. You can grab the Locations of the shape then. Since you are working with polygons you can use the getRings function which will return and array of location arrays as polygons can be made up of several rings. There is also a getLocations function on polygons as well which will only return the first ring of a polygon.
If the polygon has already been added to the map and you don't have a reference to it, you can get it in a couple of different ways. If you added it to the map using map.entities (which is an EntityCollection), you can use the getLength and get functions to loop through the shapes: https://msdn.microsoft.com/enus/library/mt736910.aspx If you are using the new Layer classes you can use the getPrimitives to get an array of shapes in the layer, then simply loop through the array like you would any other array.
When using the drawing tools, see this documentation on how to get the drawn shapes: https://msdn.microsoft.com/enUS/library/mt757098.aspx
 Proposed as answer by Ricky_Brundritt Wednesday, November 9, 2016 7:59 PM
 Marked as answer by Ricky_Brundritt Wednesday, November 9, 2016 7:59 PM

Your code works fine for me. Here is the full sample:
<!DOCTYPE html> <html> <head> <title></title> <meta httpequiv="ContentType" content="text/html; charset=utf8"/> <script type='text/javascript' src='https://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script> <script type="text/javascript"> var map; function GetMap() { map = new Microsoft.Maps.Map(document.getElementById("myMap"), { credentials: "YOUR_BING_MAPS_KEY" }); drawCircle(map.getCenter(), "1", "mile"); var pushpin = new Microsoft.Maps.Pushpin(map.getCenter()); var layer = new Microsoft.Maps.Layer(); layer.add(pushpin); map.layers.insert(layer); } function drawCircle(origin, radius, disUnit){ var RadPerDeg = 0; var earthRadius = 0; var RadPerDeg = Math.PI / 180; //get the earth radius based on unit disUnit.toLowerCase() == "mile" ? earthRadius = 3959 : earthRadius = 6371; var lat = origin.latitude * RadPerDeg; var lon = origin.longitude * RadPerDeg; var locs = new Array(); var AngDist = parseFloat(radius) / earthRadius; for (x = 0; x <= 360; x++) { //making a 360sided polygon var pLatitude, pLongitude; brng = x * RadPerDeg; pLatitude = Math.asin(Math.sin(lat) * Math.cos(AngDist) + Math.cos(lat) * Math.sin(AngDist) * Math.cos(brng)); //still in radians pLongitude = lon + Math.atan2(Math.sin(brng) * Math.sin(AngDist) * Math.cos(lat), Math.cos(AngDist)  Math.sin(lat) * Math.sin(pLatitude)); pLatitude = pLatitude / RadPerDeg; pLongitude = pLongitude / RadPerDeg; locs.push(new Microsoft.Maps.Location(pLatitude, pLongitude)); //_locations.push(new Microsoft.Maps.Location(pLatitude, pLongitude)); } //create the cirlce object circle = new Microsoft.Maps.Polygon(locs, { visible: true, strokeThickness: 4, strokeColor: new Microsoft.Maps.Color(75, 0, 0, 255), fillColor: new Microsoft.Maps.Color(50, 0, 255, 0) }); //add circle into map map.entities.push(circle); } </script> </head> <body> <div id='myMap' style=";width:800px;height:600px;"></div> </body> </html>
That said, there is a much easier way to create a circle in the Bing Maps V8 control: https://msdn.microsoft.com/enus/library/mt750638.aspx
 Proposed as answer by Ricky_Brundritt Monday, November 14, 2016 5:26 PM
 Marked as answer by Ricky_Brundritt Friday, December 30, 2016 10:22 AM
All replies

Calculating the intersection and merging (union) of shapes can be done using the Spatial Math module in Bing Maps V8:
http://www.bing.com/api/maps/sdk/mapcontrol/isdk#binaryOperations+JS
https://msdn.microsoft.com/enus/library/mt712834.aspx
There is no undo option for drawn shapes. You could potentially manage this yourself by using the change events in the drawing manager.
 Proposed as answer by Ricky_Brundritt Wednesday, October 5, 2016 5:34 PM
 Marked as answer by Ricky_Brundritt Tuesday, October 25, 2016 6:16 PM

Hi,
We have used the SpatialDataService to plot the regions as shown in below screenshot.
We also used the Microsoft.Maps.DrawingTools to draw the shape.
Can you please let us know better way to get the collection of Location(lat/long) defined in that shape.
We used following code to get the Location.
map.entities.get(0).geometry.rings[0].x
map.entities.get(0).geometry.rings[0].y
Thanks
Balasaheb

Please use the documented API: https://msdn.microsoft.com/enus/library/mt712542.aspx
First you will need to get the shape. If you are loading in the data from the Bing Spatial Data Services, an array of shapes are returned when you make a query. You can grab the Locations of the shape then. Since you are working with polygons you can use the getRings function which will return and array of location arrays as polygons can be made up of several rings. There is also a getLocations function on polygons as well which will only return the first ring of a polygon.
If the polygon has already been added to the map and you don't have a reference to it, you can get it in a couple of different ways. If you added it to the map using map.entities (which is an EntityCollection), you can use the getLength and get functions to loop through the shapes: https://msdn.microsoft.com/enus/library/mt736910.aspx If you are using the new Layer classes you can use the getPrimitives to get an array of shapes in the layer, then simply loop through the array like you would any other array.
When using the drawing tools, see this documentation on how to get the drawn shapes: https://msdn.microsoft.com/enUS/library/mt757098.aspx
 Proposed as answer by Ricky_Brundritt Wednesday, November 9, 2016 7:59 PM
 Marked as answer by Ricky_Brundritt Wednesday, November 9, 2016 7:59 PM

Hi Ricky,
Thanks for your reply. It work.
We have getting following error when we plot the circle and cluster pushpin at same time.
Uncaught TypeError: Cannot read property 'currentFrameData' of undefined
Can you please let us know reason for above error.
Thanks!
Balasaheb

Hi Ricky,
Here is more info.
We are drawing circle on map and then try to plot the pushpin from collection of data inside that circle. Some time it works but some times throws following error.
We tried to replicate the issue but not all times it throws.
Any possible reason for this issue.
Thanks!
Balasaheb

Can you provide a code sample that reproduces your issue as it's very unclear what your doing. When you say drawing, are you simply creating a polygon in the shape of a circle and adding to the map or are you using a custom drawing tool to allow the user to draw a circle on the map?
The collection of Pushpin data, is this being queried from a service, or do you have a local array that you are going through and filtering the data?

Hi,
We have used following code to draw circle map.
var RadPerDeg = 0;
var earthRadius = 0;
try {
RadPerDeg = Math.PI / 180;
//get the earth radius based on unit
disUnit.toLowerCase() == "mile" ? earthRadius = 3959 : earthRadius = 6371;
var lat = origin.latitude * RadPerDeg;
var lon = origin.longitude * RadPerDeg;
var locs = new Array();
var AngDist = parseFloat(radius) / earthRadius;
for (x = 0; x <= 360; x++) { //making a 360sided polygon
var pLatitude, pLongitude;
brng = x * RadPerDeg;
pLatitude = Math.asin(Math.sin(lat) * Math.cos(AngDist) + Math.cos(lat) * Math.sin(AngDist) * Math.cos(brng)); //still in radians
pLongitude = lon + Math.atan2(Math.sin(brng) * Math.sin(AngDist) * Math.cos(lat), Math.cos(AngDist)  Math.sin(lat) * Math.sin(pLatitude));
pLatitude = pLatitude / RadPerDeg;
pLongitude = pLongitude / RadPerDeg;
locs.push(new Microsoft.Maps.Location(pLatitude, pLongitude));
_locations.push(new Microsoft.Maps.Location(pLatitude, pLongitude));
}
//create the cirlce object
circle = new Microsoft.Maps.Polygon(locs, { visible: true, strokeThickness: 4, strokeColor: new Microsoft.Maps.Color(75, 0, 0, 255), fillColor: new Microsoft.Maps.Color(50, 0, 255, 0) });
//add circle into map
map.entities.push(circle);
once we plot the circle then we plot the pushpin inside it. While plotting push we got above error. some times it did not throws error.
To plot pushpin we used layer.
Hope this will clarify. Please let us know if you want more info to identify issue.
Thanks!Balasaheb

Your code works fine for me. Here is the full sample:
<!DOCTYPE html> <html> <head> <title></title> <meta httpequiv="ContentType" content="text/html; charset=utf8"/> <script type='text/javascript' src='https://www.bing.com/api/maps/mapcontrol?callback=GetMap' async defer></script> <script type="text/javascript"> var map; function GetMap() { map = new Microsoft.Maps.Map(document.getElementById("myMap"), { credentials: "YOUR_BING_MAPS_KEY" }); drawCircle(map.getCenter(), "1", "mile"); var pushpin = new Microsoft.Maps.Pushpin(map.getCenter()); var layer = new Microsoft.Maps.Layer(); layer.add(pushpin); map.layers.insert(layer); } function drawCircle(origin, radius, disUnit){ var RadPerDeg = 0; var earthRadius = 0; var RadPerDeg = Math.PI / 180; //get the earth radius based on unit disUnit.toLowerCase() == "mile" ? earthRadius = 3959 : earthRadius = 6371; var lat = origin.latitude * RadPerDeg; var lon = origin.longitude * RadPerDeg; var locs = new Array(); var AngDist = parseFloat(radius) / earthRadius; for (x = 0; x <= 360; x++) { //making a 360sided polygon var pLatitude, pLongitude; brng = x * RadPerDeg; pLatitude = Math.asin(Math.sin(lat) * Math.cos(AngDist) + Math.cos(lat) * Math.sin(AngDist) * Math.cos(brng)); //still in radians pLongitude = lon + Math.atan2(Math.sin(brng) * Math.sin(AngDist) * Math.cos(lat), Math.cos(AngDist)  Math.sin(lat) * Math.sin(pLatitude)); pLatitude = pLatitude / RadPerDeg; pLongitude = pLongitude / RadPerDeg; locs.push(new Microsoft.Maps.Location(pLatitude, pLongitude)); //_locations.push(new Microsoft.Maps.Location(pLatitude, pLongitude)); } //create the cirlce object circle = new Microsoft.Maps.Polygon(locs, { visible: true, strokeThickness: 4, strokeColor: new Microsoft.Maps.Color(75, 0, 0, 255), fillColor: new Microsoft.Maps.Color(50, 0, 255, 0) }); //add circle into map map.entities.push(circle); } </script> </head> <body> <div id='myMap' style=";width:800px;height:600px;"></div> </body> </html>
That said, there is a much easier way to create a circle in the Bing Maps V8 control: https://msdn.microsoft.com/enus/library/mt750638.aspx
 Proposed as answer by Ricky_Brundritt Monday, November 14, 2016 5:26 PM
 Marked as answer by Ricky_Brundritt Friday, December 30, 2016 10:22 AM