Geometry Calculations
Note
Bing Maps Web Control SDK retirement
Bing Maps Web Control SDK is deprecated and will be retired. Free (Basic) account customers can continue to use Bing Maps Web Control SDK until June 30th, 2025. Enterprise account customers can continue to use Bing Maps Web Control SDK until June 30th, 2028. To avoid service disruptions, all implementations using Bing Maps Web Control SDK will need to be updated to use Azure Maps Web SDK by the retirement date that applies to your Bing Maps for Enterprise account type. For detailed migration guidance, see Migrate from Bing Maps Web Control SDK and Migrate Bing Maps Enterprise applications to Azure Maps with GitHub Copilot.
Azure Maps is Microsoft's next-generation maps and geospatial services for developers. Azure Maps has many of the same features as Bing Maps for Enterprise, and more. To get started with Azure Maps, create a free Azure subscription and an Azure Maps account. For more information about azure Maps, see Azure Maps Documentation. For migration guidance, see Bing Maps Migration Overview.
A set of methods that perform spatial calculations against shapes. These static methods are exposed through the Microsoft.Maps.SpatialMath.Geometry
namespace.
Note
Many of these calculations allow an array of IPrimitives shapes to be passed in a single shape. This is to allow complex shapes such as MultiPolygons and GeometryCollections to be used in these calculations.
Name | Return Type | Description |
---|---|---|
area(shape: IPrimitive or IPrimitive[], AreaUnits?: AreaUnits) | number | Calculates the area of a shape and returns a value in the specified area units. Default units is square meters. |
bounds(shapes: Location or IPrimitive or (Location or IPrimitive)[]) | LocationRect | Calculates a bounding box that encloses a set of shapes and/or Locations. |
buffer(shape: Location or IPrimitive or (Location or IPrimitive)[], distance: number, units?: DistanceUnits, endCapType?: BufferEndCap, options?: PolygonOptions) | IPrimitive or IPrimitive[] | Calculates a shape with an updated boundary that has been inflated/deflated by a specified distance. • distance - The distance to buffer the shape by. • units - The distance units to buffer the shape by. • endCapType - The type of end cap to use for the joints of the buffer, default value is round. Tip: If buffering a Location or Pushpin, use the SpatialMath.getRegularPolygon function with 36 or more points to generate an approximated circle. This will result in a more geospatially accurately buffered shape. |
calculateLength(shape: IPrimitive or IPrimitive[], units ?: DistanceUnits, highAccuracy ?: boolean) | number | Calculates the distance between all Locations in a shape. If the shape is a Polygon, the length of the perimeter of all rings is calculated. • units - Unit of distance measurement. Default: Meters • highAccuracy - If set to true, uses the more accurate Vincenty’s algorithm for calculating distances. Otherwise the faster Haversine formula is used. |
centroid(shape: IPrimitive or IPrimitive[]) | Location | Calculates the center of a shape. |
concaveHull(shapes: Location or IPrimitive or (Location or IPrimitive)[], allowMultiPolygons?: boolean, allowHoles?: boolean, options?: PolygonOptions) | IPrimitive or IPrimitive[] | Calculates an approximate concave hull that best fits the data. A concave hull is a shape that represents that a possible concave geometry that encloses all shapes in the specified data set. If a single unique Location is in the data set, a Pushpin is returned. If only two unique Locations are provided, or if all Locations form a line, a Polyline is returned. If 3 or more unique Locations are in the data set a Polygon, or array of Polygons will be returned. • allowMultiPolygons - A boolean indicating if the resulting concave hull can be a MultiPolygon. Default: false • allowHoles - A boolean indicating if the Polygons in the resulting concave hull can have holes in them. Default: false |
contains(shapeA: Location or IPrimitive or (Location or IPrimitive)[], shapeB: Location or IPrimitive or (Location or IPrimitive)[] | boolean | Given two shapes, determines if the first one contains the second one (or, the second shape is a subset of the first shape) or not. |
convexHull(shapes: Location or IPrimitive or (Location or IPrimitive)[], options?: PolygonOptions) | IPrimitive or IPrimitive[] | Calculates a convex hull. A convex hull is a shape that represents that minimum convex geometry that encloses all shapes in the specified data set. |
delaunayTriangles(shapes: Location or IPrimitive or (Location or IPrimitive)[], options?: PolygonOptions) | Polygon[] | Creates Delaunay Triangles from the Location objects of the provided shapes. |
difference(shapeA: IPrimitive or IPrimitive[], shapeB: IPrimitive or IPrimitive[]) | IPrimitive or IPrimitive[] | Returns an object that represents area of an initial shape subtracted by the overlapping area of a second shape. |
distance(shapeA: Location or IPrimitive or (Location or IPrimitive)[], shapeB: Location or IPrimitive or (Location or IPrimitive)[], units?: DistanceUnits, highAccuracy?: boolean) | number | Calculates the approximate shortest distance between any two shapes. • units - Unit of distance measurement. Default: Meters • highAccuracy - If set to true, uses the more accurate Vincenty’s algorithm for calculating distances. Otherwise the faster Haversine formula is used. |
intersection(shapeA: IPrimitive or IPrimitive[], shapeB: IPrimitive or IPrimitive[]) | IPrimitive or IPrimitive[] | Returns an object that represents the area where two shapes intersect. |
intersects(shapeA: Location or IPrimitive or (Location or IPrimitive)[], shapeB: Location or IPrimitive or (Location or IPrimitive)[]) | boolean | Determines if two shapes intersect or not. |
isValid(shape: IPrimitive or IPrimitive[]) | boolean | Tests to see if the shape is valid and meets the requirements of an SQL Geography type and other OGC compliant systems. Polylines & Polygons can't be self-intersecting. For Polygons, coordinates in an exterior rings have a counter-clockwise orientation, while holes have a clockwise orientation. |
makeValid(shape: IPrimitive or IPrimitive[]) | IPrimitive or IPrimitive[] | Takes a shape and returns a copy of it that meets the requirements of an SQL Geography type and other OGC compliant systems. Polylines & Polygons can't be self-intersecting. For Polygons, coordinates in an exterior rings have a counter-clockwise orientation, while holes have a clockwise orientation. |
nearestLocations(shapeA: Location or IPrimitive or (Location or IPrimitive)[], shapeB: Location or IPrimitive or (Location or IPrimitive)[]) | Location[] | Calculates the nearest Location objects between to shapes that lie on the shapes. If the shapes do not overlap, this calculates a Location on each shape that is closest to the other shape. If the shapes overlap, a Location that is within the intersection area of the shapes will be added twice to an array, once for each shape, and returned. |
reduce(shape: IPrimitive or IPrimitive[], tolerance: number) | IPrimitive or IPrimitive[] | Reduces the resolution of a shape using the Douglas-Peucker algorithm. The tolerance parameter is distance in meters used by the reduction algorithms. |
rotate(shape: IPrimitive or IPrimitive[], angle: number, origin?: Location) | Rotates a shape around a given Location for the specified angle of rotation. If an origin is not provided, the centroid of the shape is used. • angle - The amount to rotate the shape in degrees. • origin - The Location to rotate the shape around. Defaults to the centroid of the shape. |
|
shortestLineTo(shapeA: Location or IPrimitive or (Location or IPrimitive)[], shapeB: Location or IPrimitive or (Location or IPrimitive)[], options?: IPolylineOptions) | Polyline | Calculates the shortest path that between two shapes and returns a Polyline. |
snapLocationsToShape(locs: Location or Location[], shape: IPrimitive or IPrimitive[], tolerance?: number, toleranceUnits?: DistanceUnits) | Location or Location[] | Snaps the Locations of one shape that are within the specified tolerance distance away from another shape. • tolerance - A maximum distance (in the specified units) that the snapped Location can be from the input Location. Default: Infinity • toleranceUnits - The distance units of the tolerance value. Default: Meters |
snapShapeToShape(shapeToSnap: IPrimitive or IPrimitive[], shape: IPrimitive or IPrimitive[], tolerance?: number, toleranceUnits?: DistanceUnits) | Snaps the Locations of one shape that are within the specified tolerance distance away from another shape. • tolerance - A maximum distance (in the specified units) that the snapped Location can be from the input Location. Default: Infinity • toleranceUnits - The distance units of the tolerance value. Default: Meters |
|
symDifference(shapeA: IPrimitive or IPrimitive[], shapeB: IPrimitive or IPrimitive[]) | IPrimitive or IPrimitive[] | Returns an object that represents all points that are either in one shape instance or another, but not those points that lie in both instances. "Sym" stands for Symmetric. symDifference is an OGC standard name for this calculation used in most spatial math libraries, including SQL. |
union(shapeA: IPrimitive or IPrimitive[], shapeB: IPrimitive or IPrimitive[]) | IPrimitive or IPrimitive[] | Returns an object that represents the union of two shapes. If shapes don't overlap, an array of each individual shapes will be returned. |
unionAggregate(shapes: IPrimitive[]) | IPrimitive or IPrimitive[] | Performs a union operation on a set of shapes. If a shape doesn't overlap with the rest, the returned result will be an array of shapes containing this shape and the union of the rest. |
voronoiDiagram(shapes: Location or IPrimitive or (Location or IPrimitive)[], clipRegion?: LocationRect or Polygon, options?: PolygonOptions) | Polygon[] | Creates a Voronoi diagram from the Location objects of the provided shapes. The diagram is returned as an array of Polygons. If a clip region is specified, the diagram will be clipped accordingly. |
Important Note: Many of these calculations use 2D geometry calculations with different projected planes to approximate there equivalent spatially accurate calculations. This introduces a margin of error. When testing the area calculation and comparing the results to the geography area calculation in SQL, the following differences in calculated values where observed when testing against shapes of different sizes:
Approximate Boundary Size | V8 Area (meters) | SQL Geography Area (meters) | Difference |
---|---|---|---|
Residential Property | 3721.63 | 3723.94 | 0.062% |
City | 68204696 | 68241644 | 0.054% |
US State Boundary | 186866383894 | 187876559258 | 0.54% |
USA Country | 8569210057215 | 8693955435213 | 1.45% |
If you require higher accuracy spatial calculations, create a web service and use the Microsoft SQL Server Spatial Types library. This is a .NET library that can be used on its own and doesn't require installing SQL.
Also note, there may be instances where, when visualizing results of a calculations, they look to have a larger margin of error. For instance, the calculated centroid of a 100KM line may appear to be several meters away from the line itself. The reason for this is that due to the Mercator projection of the map, “straight lines” between two locations should in fact be rendered as curved geodesic lines, however, for simplicity and performance, the map renders a geometric straight line. If you were to pass the line through the getGeodesicPath
function the line and the centroid would intersect.
There is partial support for shapes which cross the anti-meridian (-180/180 degrees longitude). To help reduce "world wrap" issues, the spatial math module automatically splits result shapes along this line if they cross the anti-meridian.