Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Geometry Client V3 changes #1097

Merged
merged 4 commits into from
Dec 13, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions Microsoft.Azure.Cosmos/src/Resource/Settings/BoundingBoxSpec.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace Microsoft.Azure.Cosmos
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.Azure.Documents;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

/// <summary>
/// Represents bounding box for geometry spatial path in the Azure Cosmos DB service
/// </summary>
/// <example>
/// <![CDATA[
/// {
/// "id": "DocumentCollection Id",
/// "indexingPolicy":{
/// "spatialIndexes":
/// [{
/// "path":"/'region'/?",
/// "types":["Polygon"],
/// "boundingBox":
/// {
/// "xmin":0,
/// "ymin":0,
/// "xmax":10,
/// "ymax":10
/// }
/// }]
/// },
/// "geospatialConfig":
/// {
/// "type": "Geometry"
/// }
/// }
/// ]]>
/// </example>
public sealed class BoundingBoxSpec
LalithaMV marked this conversation as resolved.
Show resolved Hide resolved
{
/// <summary>
/// Gets the x-coordinate of the lower-left corner of the bounding box.
/// </summary>
[JsonProperty(PropertyName = "xmin")]
public double Xmin
{
get; set;
}

/// <summary>
/// Gets the y-coordinate of the lower-left corner of the bounding box.
/// </summary>
[JsonProperty(PropertyName = "ymin")]
public double Ymin
{
get; set;
}

/// <summary>
/// Gets the x-coordinate of the upper-right corner of the bounding box.
/// </summary>
[JsonProperty(PropertyName = "xmax")]
public double Xmax
{
get; set;
}

/// <summary>
/// Gets the y-coordinate of the upper-right corner of the bounding box.
/// </summary>
[JsonProperty(PropertyName = "ymax")]
public double Ymax
{
get; set;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public class ContainerProperties
[JsonProperty(PropertyName = Constants.Properties.IndexingPolicy, NullValueHandling = NullValueHandling.Ignore)]
private IndexingPolicy indexingPolicyInternal;

// TODO: update spatial properties to Constants.Properties.* after the new direct package is released
[JsonProperty(PropertyName = "geospatialConfig", NullValueHandling = NullValueHandling.Ignore)]
private GeospatialConfig geospatialConfigInternal;

[JsonProperty(PropertyName = Constants.Properties.UniqueKeyPolicy, NullValueHandling = NullValueHandling.Ignore)]
private UniqueKeyPolicy uniqueKeyPolicyInternal;

Expand Down Expand Up @@ -240,6 +244,29 @@ public IndexingPolicy IndexingPolicy
}
}

/// <summary>
/// Gets the <see cref="GeospatialConfig"/> associated with the collection from the Azure Cosmos DB service.
/// </summary>
/// <value>
/// Geospatial type of collection i.e. geography or geometry
/// </value>
[JsonProperty(PropertyName = "geospatialConfig")]
public GeospatialConfig GeospatialConfig
{
get
{
if (this.geospatialConfigInternal == null)
{
this.geospatialConfigInternal = new GeospatialConfig();
}

return this.geospatialConfigInternal;
}
set
{
this.geospatialConfigInternal = value;
}
}
/// <summary>
/// JSON path used for containers partitioning
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace Microsoft.Azure.Cosmos
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.Azure.Documents;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

/// <summary>
/// Represents geospatial configuration for a collection in the Azure Cosmos DB service
/// </summary>
/// <example>
/// <![CDATA[
/// {
/// "id": "CollectionId",
/// "indexingPolicy":...,
/// "geospatialConfig":
/// {
/// "type": "Geography"
/// }
/// }
/// ]]>
/// </example>
public sealed class GeospatialConfig
{
/// <summary>
/// Initializes a new instance of the <see cref="GeospatialConfig"/> class for the Azure Cosmos DB service.
/// </summary>
/// <remarks>
/// Geospatial type is set to Geography by default.
/// </remarks>
public GeospatialConfig()
{
this.GeospatialType = GeospatialType.Geography;
}

/// <summary>
/// Initializes a new instance of the <see cref="GeospatialConfig"/> class for the Azure Cosmos DB service.
/// </summary>
/// <param name="geospatialType">Specifies GeospatialType of collection, which can be either Geography or Geometry</param>
public GeospatialConfig(GeospatialType geospatialType)
{
this.GeospatialType = geospatialType;
}

/// <summary>
/// Gets or sets the geospatial type (geography or geometry) in the Azure Cosmos DB service.
/// </summary>
/// <value>
/// One of the values of the <see cref="T:Microsoft.Azure.Documents.GeospatialType"/> enumeration.
/// </value>
[JsonProperty(PropertyName = "type")]
[JsonConverter(typeof(StringEnumConverter))]
public GeospatialType GeospatialType
{
get; set;
}
}
}
21 changes: 21 additions & 0 deletions Microsoft.Azure.Cosmos/src/Resource/Settings/GeospatialType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace Microsoft.Azure.Cosmos
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should all these files be in?

namespace Microsoft.Azure.Cosmos.Spatial

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, those files are serialization related files. those had a separate folder even in V2( SharedFiles\Spatial). However this PR changes the container properties(i.e. collection content), so should remain in this namespace. Its the same even in V2, these files are directly under sharedFiles.

{
/// <summary>
/// Specifies the supported geospatial types in the Azure Cosmos DB service.
/// </summary>
public enum GeospatialType
{
/// <summary>
/// Represents data in round-earth coordinate system.
/// </summary>
Geography,

/// <summary>
/// Represents data in Eucledian(flat) coordinate system.
/// </summary>
Geometry
}
}
27 changes: 27 additions & 0 deletions Microsoft.Azure.Cosmos/src/Resource/Settings/SpatialPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,24 @@ namespace Microsoft.Azure.Cosmos
/// <summary>
/// Spatial index specification
/// </summary>
/// <example>
/// <![CDATA[
/// "spatialIndexes":
/// [
/// {
/// "path":"/'region'/?",
/// "types":["Polygon"],
/// "boundingBox":
/// {
/// "xmin":0,
/// "ymin":0,
/// "xmax":10,
/// "ymax":10
/// }
/// }
/// ]
/// ]]>
/// </example>
public sealed class SpatialPath
{
private Collection<SpatialType> spatialTypesInternal;
Expand Down Expand Up @@ -46,5 +64,14 @@ internal set
this.spatialTypesInternal = value;
}
}

/// <summary>
/// Gets or sets the bounding box
/// </summary>
[JsonProperty(PropertyName = "boundingBox", NullValueHandling = NullValueHandling.Ignore)]
public BoundingBoxSpec BoundingBox
{
get; set;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ public class IndexingPolicyTests
/// </summary>
private static readonly Version GeoFencing = new Version(1, 10, 0);

// TODO (brchon): Fill out this field when the composite sdk gets released
//private static readonly Version Composite = new Version(1, 23, 0);
private static readonly Version AdditionalIndexes = new Version(2, 4, 0);

/// <summary>
/// Reserved version for the latest SDK that got released (note that only the local version can be newer).
Expand All @@ -71,6 +70,7 @@ public class IndexingPolicyTests
IndexingPolicyV2,
Spatial,
GeoFencing,
AdditionalIndexes,
Latest,
Local
};
Expand Down Expand Up @@ -280,6 +280,67 @@ private async Task CompositeIndexImplementation()
await IndexingPolicyTests.RoundTripWithLocal(indexingPolicy);
}

[TestMethod]
public async Task SpatialBoundingBox()
{
await RetryOnNonAssertFailure(this.SpatialBoundingBoxImplementation);
}

private async Task SpatialBoundingBoxImplementation()
{
Cosmos.IndexingPolicy indexingPolicy = new Cosmos.IndexingPolicy()
{
Automatic = true,
IncludedPaths = new Collection<Cosmos.IncludedPath>()
{
new Cosmos.IncludedPath()
{
Path = DefaultPath,
}
},
ExcludedPaths = new Collection<Cosmos.ExcludedPath>(),
IndexingMode = Cosmos.IndexingMode.Consistent,
SpatialIndexes = new Collection<Cosmos.SpatialPath>()
{
new Cosmos.SpatialPath
{
Path = "/location/?",
SpatialTypes = new Collection<Cosmos.SpatialType>()
{
Cosmos.SpatialType.LineString,
Cosmos.SpatialType.MultiPolygon,
Cosmos.SpatialType.Point,
Cosmos.SpatialType.Polygon,
},
BoundingBox = new Cosmos.BoundingBoxSpec()
{
Xmin = 0,
Ymin = 0,
Xmax = 10,
Ymax = 10,
}
},
new Cosmos.SpatialPath
{
Path = "/spatial/*",
SpatialTypes = new Collection<Cosmos.SpatialType>()
{
Cosmos.SpatialType.Point
},
BoundingBox = new Cosmos.BoundingBoxSpec()
{
Xmin = 0,
Ymin = 0,
Xmax = 10,
Ymax = 10,
}
}
}
};

await IndexingPolicyTests.RoundTripWithLocal(indexingPolicy, Cosmos.GeospatialType.Geometry);
}

[TestMethod]
public async Task ExcludeAll()
{
Expand Down Expand Up @@ -332,14 +393,18 @@ public async Task DoubleRoundTrip()
await IndexingPolicyTests.RoundTripWithLocal(indexingPolicy);
}

private static async Task RoundTripWithLocal(Cosmos.IndexingPolicy indexingPolicy)
private static async Task RoundTripWithLocal(Cosmos.IndexingPolicy indexingPolicy, Cosmos.GeospatialType geospatialType = Cosmos.GeospatialType.Geography)
LalithaMV marked this conversation as resolved.
Show resolved Hide resolved
{
PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition { Paths = new System.Collections.ObjectModel.Collection<string>(new[] { "/id" }), Kind = PartitionKind.Hash };
ContainerProperties containerSetting = new ContainerProperties()
{
Id = Guid.NewGuid().ToString(),
IndexingPolicy = indexingPolicy,
PartitionKey = partitionKeyDefinition
PartitionKey = partitionKeyDefinition,
GeospatialConfig = new Cosmos.GeospatialConfig()
{
GeospatialType = geospatialType
}
};

Cosmos.Database cosmosDatabase = await cosmosClient.CreateDatabaseIfNotExistsAsync(IndexingPolicyTests.database.Id);
Expand Down