Пространственные данные
Пространственные данные представляют физическое расположение и форму объектов. Многие базы данных поддерживают этот тип данных, поэтому их можно индексировать и запрашивать вместе с другими данными. Распространенные сценарии включают запросы к объектам в пределах заданного расстояния от расположения или выбор объекта, граница которого содержит заданное расположение. EF Core поддерживает сопоставление с пространственными типами данных с помощью пространственной библиотеки NetTopologySuite.
Чтобы использовать пространственные данные с EF Core, необходимо установить соответствующий вспомогательный пакет NuGet. Какой пакет необходимо установить, зависит от используемого поставщика.
Поставщик EF Core | Пространственный пакет NuGet |
---|---|
Microsoft.EntityFrameworkCore.SqlServer | Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite |
Microsoft.EntityFrameworkCore.Sqlite | Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite |
Microsoft.EntityFrameworkCore.InMemory | NetTopologySuite |
Npgsql.EntityFrameworkCore.PostgreSQL | Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite |
Pomelo.EntityFrameworkCore.MySql | Pomelo.EntityFrameworkCore.MySql.NetTopologySuite |
Devart.Data.MySql.EFCore | Devart.Data.MySql.EFCore.NetTopologySuite |
Devart.Data.Oracle.EFCore | Devart.Data.Oracle.EFCore.NetTopologySuite |
Devart.Data.PostgreSql.EFCore | Devart.Data.PostgreSql.EFCore.NetTopologySuite |
Devart.Data.SQLite.EFCore | Devart.Data.SQLite.EFCore.NetTopologySuite |
Teradata.EntityFrameworkCore | Teradata.EntityFrameworkCore.NetTopologySuite |
NetTopologySuite (NTS) — это пространственная библиотека для .NET. EF Core позволяет сопоставлять пространственные типы данных в базе данных с помощью типов NTS в модели.
Чтобы включить сопоставление пространственных типов с помощью NTS, вызовите метод UseNetTopologySuite в построителе параметров DbContext поставщика. Например, при использовании SQL Server вы будете называть его следующим образом.
options.UseSqlServer(
@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WideWorldImporters;ConnectRetryCount=0",
x => x.UseNetTopologySuite());
Существует несколько типов пространственных данных. Используемый тип зависит от типов фигур, которые требуется разрешить. Ниже приведена иерархия типов NTS, которые можно использовать для свойств в модели. Они находятся в NetTopologySuite.Geometries
пространстве имен.
- Геометрии
- Point
- LineString
- Многоугольник
- GeometryCollection
- MultiPoint
- MultiLineString
- MultiPolygon
Предупреждение
CircularString, CompoundCurve и CurePolygon не поддерживаются NTS.
Использование базового геометрического типа позволяет задать любой тип фигуры свойством.
Координаты в NTS относятся к значениям X и Y. Для представления долготы и широты используйте X для долготы и Y для широты. Обратите внимание, что это обратно от latitude, longitude
формата, в котором обычно отображаются эти значения.
Следующие классы сущностей можно использовать для сопоставления с таблицами в образце базы данных Wide World Importers.
[Table("Cities", Schema = "Application")]
public class City
{
public int CityID { get; set; }
public string CityName { get; set; }
public Point Location { get; set; }
}
[Table("Countries", Schema = "Application")]
public class Country
{
public int CountryID { get; set; }
public string CountryName { get; set; }
// Database includes both Polygon and MultiPolygon values
public Geometry Border { get; set; }
}
В LINQ методы и свойства NTS, доступные в качестве функций базы данных, будут переведены в SQL. Например, методы Distance и Contains претворяются в следующие запросы. Ознакомьтесь с документацией поставщика, для которой поддерживаются методы.
// Find the nearest city
var nearestCity = db.Cities
.OrderBy(c => c.Location.Distance(currentLocation))
.FirstOrDefault();
// Find the containing country
var currentCountry = db.Countries
.FirstOrDefault(c => c.Border.Contains(currentLocation));
Пакеты пространственных NuGet также позволяют модели обратной инженерии с пространственными свойствами, но перед выполнением Scaffold-DbContext
пакета необходимо установить пакет.dotnet ef dbcontext scaffold
Если вы этого не сделали, вы получите предупреждения о том, что не найти сопоставления типов для столбцов, и столбцы будут пропущены.
NTS игнорирует значения SRID во время операций. Предполагается, что планарная система координат. Это означает, что если вы указываете координаты с точки зрения долготы и широты, некоторые вычисляемые клиентом значения, такие как расстояние, длина и область будут находиться в градусах, а не в метрах. Для получения более значимых значений сначала необходимо проецировать координаты в другую систему координат, используя библиотеку, например ProjNet (для GeoAPI).
Примечание
Используйте новый пакет NuGet ProjNet, а не старый пакет ProjNet4GeoAPI.
Если операция оценивается с помощью EF Core с помощью SQL, то единица результата будет определена базой данных.
Ниже приведен пример использования ProjNet для вычисления расстояния между двумя городами.
public static class GeometryExtensions
{
private static readonly CoordinateSystemServices _coordinateSystemServices
= new CoordinateSystemServices(
new Dictionary<int, string>
{
// Coordinate systems:
[4326] = GeographicCoordinateSystem.WGS84.WKT,
// This coordinate system covers the area of our data.
// Different data requires a different coordinate system.
[2855] =
@"
PROJCS[""NAD83(HARN) / Washington North"",
GEOGCS[""NAD83(HARN)"",
DATUM[""NAD83_High_Accuracy_Regional_Network"",
SPHEROID[""GRS 1980"",6378137,298.257222101,
AUTHORITY[""EPSG"",""7019""]],
AUTHORITY[""EPSG"",""6152""]],
PRIMEM[""Greenwich"",0,
AUTHORITY[""EPSG"",""8901""]],
UNIT[""degree"",0.01745329251994328,
AUTHORITY[""EPSG"",""9122""]],
AUTHORITY[""EPSG"",""4152""]],
PROJECTION[""Lambert_Conformal_Conic_2SP""],
PARAMETER[""standard_parallel_1"",48.73333333333333],
PARAMETER[""standard_parallel_2"",47.5],
PARAMETER[""latitude_of_origin"",47],
PARAMETER[""central_meridian"",-120.8333333333333],
PARAMETER[""false_easting"",500000],
PARAMETER[""false_northing"",0],
UNIT[""metre"",1,
AUTHORITY[""EPSG"",""9001""]],
AUTHORITY[""EPSG"",""2855""]]
"
});
public static Geometry ProjectTo(this Geometry geometry, int srid)
{
var transformation = _coordinateSystemServices.CreateTransformation(geometry.SRID, srid);
var result = geometry.Copy();
result.Apply(new MathTransformFilter(transformation.MathTransform));
return result;
}
private class MathTransformFilter : ICoordinateSequenceFilter
{
private readonly MathTransform _transform;
public MathTransformFilter(MathTransform transform)
=> _transform = transform;
public bool Done => false;
public bool GeometryChanged => true;
public void Filter(CoordinateSequence seq, int i)
{
var x = seq.GetX(i);
var y = seq.GetY(i);
var z = seq.GetZ(i);
_transform.Transform(ref x, ref y, ref z);
seq.SetX(i, x);
seq.SetY(i, y);
seq.SetZ(i, z);
}
}
}
var seattle = new Point(-122.333056, 47.609722) { SRID = 4326 };
var redmond = new Point(-122.123889, 47.669444) { SRID = 4326 };
// In order to get the distance in meters, we need to project to an appropriate
// coordinate system. In this case, we're using SRID 2855 since it covers the
// geographic area of our data
var distanceInDegrees = seattle.Distance(redmond);
var distanceInMeters = seattle.ProjectTo(2855).Distance(redmond.ProjectTo(2855));
Примечание
4326 относится к WGS 84, стандарту, используемому в GPS и других географических системах.
Обязательно ознакомьтесь с документацией поставщика для получения дополнительных сведений о работе с пространственными данными.
- Пространственные данные в поставщике SQL Server
- Пространственные данные в поставщике SQLite
- Пространственные данные в поставщике Npgsql
- Документация NetTopologySuite
- Сеанс стенда сообщества данных .NET, ориентированный на пространственные данные и NetTopologySuite.
Отзыв о .NET
.NET — это проект с открытым исходным кодом. Выберите ссылку, чтобы оставить отзыв: