Docs 菜单
Docs 主页
/ /
支持的数据类型

地理空间数据类型 - .NET SDK

11.1.0 版新增功能

地理空间数据或“地理数据”指定地球表面上的点和几何对象。 使用地理数据类型,您可以创建查询来检查给定点是否包含在形状中。 例如,您可以查找指定点 15 公里范围内的所有咖啡店。

在版本 11.6.1 中进行了更改: Atlas Device Sync 支持的地理空间数据

Realm .NET SDK 版本 11.16.1 及更高版本增加了对 Atlas Device Sync 中地理空间数据的支持。 这允许您订阅同步 Realm 中的地理空间查询。 如果您尝试使用旧版本的 SDK 订阅地理空间查询,您将收到带有补偿写入的服务器错误。 有关托管同步订阅的更多信息,请参阅托管 Flexible Sync 订阅 - .NET SDK。

有关使用Device Sync查询地理空间数据的更多信息,请参阅App Services文档中的地理空间数据

SDK 支持使用以下数据类型进行地理空间查询:

  • GeoPoint

  • GeoCircle

  • GeoBox

  • GeoPolygon

SDK 提供这些地理空间数据类型是为了简化地理空间数据的查询。 您无法直接持久化这些数据类型。

有关如何保存地理空间数据的信息,请参阅本页的保存GeoPoint 数据部分。

GeoPoint定义了地球表面的特定位置。 所有地理空间数据类型都使用 GeoPoints来定义其位置。

注意

在采用GeoPoint的方法中,您也可以提供一个双精度元组,其中第一个双精度值是纬度,第二个双精度值是经度。 SDK 将这些元组解释为GeoPoints 。 本页上的示例演示了这两种方法。

GeoCircle定义了地球表面上的一个圆。 您可以通过为圆的中心提供GeoPoint和指定圆的半径的Distance对象来定义GeoCircle

注意

您可以以公里、英里、度或弧度为单位定义半径。

以下代码显示了创建圆形的两个示例:

var circle1 = new GeoCircle((47.8, -122.6),
Distance.FromKilometers(44.4));
var circle2 = new GeoCircle(
new GeoPoint(latitude: 47.3, longitude: -121.9),
Distance.FromDegrees(0.25));
两个 GeoCircle
点击放大

GeoBox在地球表面定义了一个矩形。 您可以通过指定左下(西南)角和右上角(东北)角来定义矩形。 以下示例将创建2框:

var box1 = new GeoBox(bottomLeftCorner: (47.3, -122.7),
topRightCorner: (48.1, -122.1));
var box2 = new GeoBox(new GeoPoint(47.5, -122.4),
new GeoPoint(47.9, -121.8));
2 GeoBox
点击放大

GeoPolygon定义了地球表面上的多边形。 由于多边形是闭合形状,因此必须提供至少4个点: 3个点用于定义多边形的形状,以及第四个点用于闭合形状。

重要

多边形中的第四个点必须与第一个点相同。

您还可以通过定义一个或多个“孔”来排除多边形内的区域。 孔洞是指其边界完全位于外部多边形内的另一个多边形。 以下示例创建了 3 个多边形:第一个是具有 5 个点的基本多边形,第一个是具有单孔的相同多边形,第三个是具有两个孔的相同多边形:

var basicPolygon = new GeoPolygon((48, -122.8),
(48.2, -121.8), (47.6, -121.6), (47.0, -122.0),
(47.2, -122.6), (48, -122.8));
// Create a polygon with a single hole
var outerRing = new GeoPoint[] {
(48, -122.8), (48.2, -121.8),
(47.6, -121.6), (47.0, -122.0), (47.2, -122.6),
(48, -122.8) };
var hole1 = new GeoPoint[] {
(47.8, -122.6), (47.7, -122.2),
(47.4, -122.6), (47.6, -122.5),
(47.8, -122.6) };
var polygonWithOneHole = new GeoPolygon(outerRing, hole1);
// Add a second hole to the polygon
var hole2 = new GeoPoint[] {
(47.55, -122.05), (47.5, -121.9),(47.3, -122.1),
(47.55, -122.05) };
var polygonWithTwoHoles =
new GeoPolygon(outerRing, hole1, hole2);
3 GeoPolygons
点击放大

重要

无法保留地理空间数据类型

目前,您只能保留地理空间数据。 地理空间数据类型无法直接持久化。 例如,您不能声明类型为GeoBox的属性。

这些类型只能用作地理空间查询的参数。

如果要持久保存GeoPoint 数据,该数据必须符合GeoJSON规范

要创建符合 GeoJSON 规范的类,您需要:

  1. 创建嵌入式 Realm 对象(从IEmbeddedObject继承的类)。

  2. 至少添加 GeoJSON 规范要求的两个字段:

    • 类型为IList<double>的字段,映射到 Realm 模式中的“坐标”(区分大小写)属性。

    • 类型为string的字段,映射到“类型”属性。 此字段的值必须是“Point”。

以下示例显示了一个名为 "CustomGeoPoint" 的嵌入式类,用于持久保存 GeoPoint 数据:

public partial class CustomGeoPoint : IEmbeddedObject
{
[MapTo("coordinates")]
public IList<double> Coordinates { get; } = null!;
[MapTo("type")]
private string Type { get; set; } = "Point";
public CustomGeoPoint(double latitude, double longitude)
{
Coordinates.Add(longitude);
Coordinates.Add(latitude);
}
}

然后,您可以在 域 模型中使用自定义 GeoPoint 类,如以下示例所示:

public partial class Company : IRealmObject
{
[PrimaryKey]
[MapTo("_id")]
public Guid Id { get; private set; } = Guid.NewGuid();
public CustomGeoPoint? Location { get; set; }
public Company() { }
}

然后,您可以像任何其他 Realm 模型一样将类的实例添加到 Realm:

realm.WriteAsync(() =>
{
realm.Add(new Company
{
Location = new CustomGeoPoint(47.68, -122.35)
});
realm.Add(new Company
{
Location = new CustomGeoPoint(47.9, -121.85)
});
});

下图显示了创建这两个公司对象的结果。

2 个 GeoPoint
点击放大

要查询地理空间数据,可以使用GeoWithin方法,也可以将geoWithin操作符与RQL结合使用。 GeoWithin方法采用嵌入式对象的“坐标”属性(定义我们正在查询的点)和地理空间形状之一来检查该点是否包含在该形状中。

注意

无论地理数据地区的形状如何,查询地理空间数据的格式都是相同的。

以下示例显示了使用GeoWithin方法和 RQL 进行查询之间的区别:

var GeoWthinExample = realm.All<Company>()
.Where(c => QueryMethods.GeoWithin(c.Location, circle1));
var RQLExample = realm.All<Company>()
.Filter("Location geoWithin $0", circle2);

以下示例展示了如何查询各种形状以返回形状内的公司列表:

GeoCircle

var companiesInCircle = realm.All<Company>()
.Where(c => QueryMethods.GeoWithin(c.Location, circle1));
var companiesInSmallerCircle = realm.All<Company>()
.Where(c => QueryMethods.GeoWithin(c.Location, circle2));
查询 GeoCircle 示例。
点击放大

GeoBox

var companiesInBox1 = realm.All<Company>()
.Where(c => QueryMethods.GeoWithin(c.Location, box1));
var companiesInBox2 = realm.All<Company>()
.Where(c => QueryMethods.GeoWithin(c.Location, box2));
查询 GeoBox 示例。

GeoPolygon

var companiesInBasicPolygon = realm.All<Company>()
.Where(c => QueryMethods
.GeoWithin(c.Location, basicPolygon));
var companiesInPolygon = realm.All<Company>()
.Where(c => QueryMethods
.GeoWithin(c.Location, polygonWithTwoHoles));
查询 GeoPolygon 示例。
点击放大

后退

RealmInteger

在此页面上