{"id":1046,"date":"2020-05-07T09:00:38","date_gmt":"2020-05-07T16:00:38","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cosmosdb\/?p=1046"},"modified":"2020-05-06T10:22:55","modified_gmt":"2020-05-06T17:22:55","slug":"spatial-geometry-data","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cosmosdb\/spatial-geometry-data\/","title":{"rendered":"Using spatial geometry data in Azure Cosmos DB"},"content":{"rendered":"<p><span style=\"color: #000122;\">Many applications use spatial data to represent the physical locations and shapes of objects like cities, roads, and lakes. You can now store both the geography data type and the geometry data type in <a href=\"https:\/\/azure.microsoft.com\/services\/cosmos-db\/\">Azure Cosmos DB<\/a> using the SQL (Core) API. T<\/span>he <strong>geography<\/strong> data type represents data in a round-earth coordinate system, and the <strong>geometry <\/strong>data type represents data in a Euclidean flat coordinate system.<\/p>\n<p>Azure Cosmos DB supports indexing and querying of spatial data represented using the <a href=\"https:\/\/tools.ietf.org\/html\/rfc7946\">GeoJSON specification<\/a>, and <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/sql-query-geospatial-intro#supported-data-types\">four spatial types<\/a>:<\/p>\n<ul>\n<li>Point<\/li>\n<li>Polygon<\/li>\n<li>MultiPolygon<\/li>\n<li>LineString<\/li>\n<\/ul>\n<h5>Indexing geography data<\/h5>\n<p>This is a sample indexing policy that indexes Points, Polygons, MultiPolygons, and LineStrings with <strong>geography<\/strong> data indexing:<\/p>\n<pre>{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"automatic\":true,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"indexingMode\":\"Consistent\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"includedPaths\": [\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"path\": \"\/*\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ],\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"spatialIndexes\": [\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"path\": \"\/*\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"types\": [\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"Point\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"Polygon\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"MultiPolygon\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"LineString\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ]\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0 ],\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"excludedPaths\":[]\r\n\u00a0\u00a0 }<\/pre>\n<h5>Indexing geometry data<\/h5>\n<p>Indexing geometry data is just like indexing geography data, but there are two additional steps that can be done in either the <a href=\"https:\/\/portal.azure.com\/\">Azure Portal<\/a> or Azure Cosmos DB <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/sql-query-geospatial-index#modifying-geospatial-data-type\">.NET SDK<\/a>.<\/p>\n<ol>\n<li><strong>Switch the geospatial configuration from geography (default) to geometry <\/strong>to let the Azure Cosmos DB query engine know what type of spatial data is being indexed. This is important because, though geography data and geometry data are both represented in GeoJSON, Azure Cosmos DB interprets and indexes the data differently, depending on the geospatial configuration.<\/li>\n<\/ol>\n<p><figure id=\"attachment_1049\" aria-labelledby=\"figcaption_attachment_1049\" class=\"wp-caption aligncenter\" ><img decoding=\"async\" class=\"wp-image-1049\" src=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2020\/05\/GeometrySetting-300x126.png\" alt=\"Geometry setting for spatial data in Azure Cosmos DB using SQL (Core) API\" width=\"693\" height=\"291\" srcset=\"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2020\/05\/GeometrySetting-300x126.png 300w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2020\/05\/GeometrySetting-1024x428.png 1024w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2020\/05\/GeometrySetting-768x321.png 768w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2020\/05\/GeometrySetting-1536x643.png 1536w, https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-content\/uploads\/sites\/52\/2020\/05\/GeometrySetting.png 1998w\" sizes=\"(max-width: 693px) 100vw, 693px\" \/><figcaption id=\"figcaption_attachment_1049\" class=\"wp-caption-text\">Setting geometry setting for spatial setting in Azure Cosmos DB<\/figcaption><\/figure><\/p>\n<ol start=\"2\">\n<li><strong>Add a bounding box to your indexing policy for each spatial path <\/strong>when switching to geometry spatial indexing. A bounding box isn\u2019t necessary for geography spatial data because all geography data is based on its position on Earth and relevant GeoJSON types in valid latitude and longitude coordinates are always indexed. However, the two-dimensional Euclidean coordinate plane of geometry data does not have any limits, so you must specify a bounding box when you switch to geometry spatial indexing.<\/li>\n<\/ol>\n<h5>Using a bounding box<\/h5>\n<p>The bounding box consists of the following properties:<\/p>\n<ul>\n<li><strong>xmin<\/strong>: the minimum indexed x coordinate<\/li>\n<li><strong>ymin<\/strong>: the minimum indexed y coordinate<\/li>\n<li><strong>xmax<\/strong>: the maximum indexed x coordinate<\/li>\n<li><strong>ymax<\/strong>: the maximum indexed y coordinate<\/li>\n<\/ul>\n<p><a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/sql-query-geospatial-index#geometry-data-indexing-examples\">Create a bounding box<\/a> that contains all (or most) of your data because only operations computed on the objects that are entirely inside the bounding box will be able to utilize the spatial index. Don&#8217;t make the bounding box significantly larger than necessary because doing so will negatively impact query performance. You can define the <strong>bounding box <\/strong>within your indexing policy like the example below in which all data that has an x coordinate between -10 and 10 and a y coordinate between -20 and 20 is indexed:<\/p>\n<pre>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"boundingBox\": {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"xmin\": -10,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"ymin\": -20,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"xmax\": 10,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"ymax\": 20\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }<\/pre>\n<p>When using spatial data, all possible types should be indexed. In Azure Cosmos DB, indexing additional paths can lead to a higher <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/request-units\">request unit (RU)<\/a> charge for writes. However, only documents with valid GeoJSON paths have spatial indexes created. For example, if you only have Points in your dataset, then you can index both Points and Polygons for the same amount of RUs per write than if you&#8217;d just indexed Points.<\/p>\n<h5>Mixing spatial data with other types<\/h5>\n<p>Geography data and geometry data can&#8217;t be mixed within the same Azure Cosmos DB container, but spatial data can be mixed with other types of data. Spatial indexes can also be used alongside existing range and composite indexes. The same <a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/sql-query-geospatial-query#spatial-sql-built-in-functions\">spatial system functions<\/a> can be used with geography data and geometry data, including:<\/p>\n<table width=\"100%\">\n<tbody>\n<tr>\n<td>ST_DISTANCE (spatial_expr, spatial_expr)<\/td>\n<td>Returns the distance between the two GeoJSON Point, Polygon, or LineString expressions.<\/td>\n<\/tr>\n<tr>\n<td>ST_WITHIN (spatial_expr, spatial_expr)<\/td>\n<td>Returns a Boolean expression indicating whether the first GeoJSON object (Point, Polygon, or LineString) is within the second GeoJSON object (Point, Polygon, or LineString).<\/td>\n<\/tr>\n<tr>\n<td>ST_INTERSECTS (spatial_expr, spatial_expr)<\/td>\n<td>Returns a Boolean expression indicating whether the two specified GeoJSON objects (Point, Polygon, or LineString) intersect.<\/td>\n<\/tr>\n<tr>\n<td>ST_ISVALID<\/td>\n<td>Returns a Boolean value indicating whether the specified GeoJSON Point, Polygon, or LineString expression is valid.<\/td>\n<\/tr>\n<tr>\n<td>ST_ISVALIDDETAILED<\/td>\n<td>Returns a JSON value containing a Boolean value if the specified GeoJSON Point, Polygon, or LineString expression is valid. If invalid, it returns the reason as a string value.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<h5>Get started<\/h5>\n<p>Learn more about using spatial data in Azure Cosmos DB:<\/p>\n<ul>\n<li><a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/sql-query-geospatial-intro\">Overview of spatial data in Azure Cosmos DB <\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/sql-query-geospatial-query\">Querying spatial data in Azure Cosmos DB<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/azure\/cosmos-db\/sql-query-geospatial-index\">Indexing spatial data in Azure Cosmos DB<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Support for two different types of spatial data has been added to Azure Cosmos DB. Using the SQL (Core) API: geography data (round-earth coordinate system), and two-dimensional geometry data.<\/p>\n","protected":false},"author":12128,"featured_media":1084,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[12,14,818],"tags":[1029],"class_list":["post-1046","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcements","category-core-sql-api","category-query","tag-spatial-data"],"acf":[],"blog_post_summary":"<p>Support for two different types of spatial data has been added to Azure Cosmos DB. Using the SQL (Core) API: geography data (round-earth coordinate system), and two-dimensional geometry data.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/1046","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/users\/12128"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/comments?post=1046"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/1046\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media\/1084"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media?parent=1046"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/categories?post=1046"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/tags?post=1046"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}