Dane przestrzenne
Dane przestrzenne reprezentują lokalizację fizyczną i kształt obiektów. Wiele baz danych zapewnia obsługę tego typu danych, dzięki czemu można je indeksować i wykonywać zapytania obok innych danych. Typowe scenariusze obejmują wykonywanie zapytań dotyczących obiektów w danej odległości od lokalizacji lub wybieranie obiektu, którego obramowanie zawiera daną lokalizację. Program EF Core obsługuje mapowanie na typy danych przestrzennych przy użyciu biblioteki przestrzennej NetTopologySuite.
Trwa instalowanie
Aby używać danych przestrzennych w programie EF Core, należy zainstalować odpowiedni pakiet NuGet obsługujący. Pakiet, który należy zainstalować, zależy od używanego dostawcy.
Dostawca platformy EF Core | Pakiet NuGet przestrzenny |
---|---|
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
NetTopologySuite (NTS) to biblioteka przestrzenna platformy .NET. Program EF Core umożliwia mapowanie na typy danych przestrzennych w bazie danych przy użyciu typów NTS w modelu.
Aby włączyć mapowanie typów przestrzennych za pośrednictwem NTS, wywołaj metodę UseNetTopologySuite w konstruktorze opcji DbContext dostawcy. Na przykład za pomocą programu SQL Server należy nazwać go w następujący sposób.
options.UseSqlServer(
@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WideWorldImporters;ConnectRetryCount=0",
x => x.UseNetTopologySuite());
Istnieje kilka typów danych przestrzennych. Używany typ zależy od typów kształtów, które mają być dozwolone. Oto hierarchia typów NTS, których można użyć dla właściwości w modelu. Znajdują się one w NetTopologySuite.Geometries
przestrzeni nazw.
- Geometrii
- Punkt
- Linestring
- Wielokąt
- Geometrycollection
- Multipoint
- Multilinestring
- Multipolygon
Ostrzeżenie
Cykliczne ciągi, CompoundCurve i CurePolygon nie są obsługiwane przez NTS.
Użycie podstawowego typu Geometria umożliwia określenie dowolnego typu kształtu przez właściwość .
Długość geograficzna i szerokość geograficzna
Współrzędne w NTS są wartościami X i Y. Aby reprezentować długość geograficzną i szerokość geograficzną, użyj wartości X dla długości geograficznej i Y dla szerokości geograficznej. Należy pamiętać, że jest to wstecz z latitude, longitude
formatu, w którym zazwyczaj są widoczne te wartości.
Wykonanie zapytania o dane
Poniższe klasy jednostek mogą służyć do mapowania na tabele w przykładowej bazie danych 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; }
}
W LINQ metody i właściwości NTS dostępne jako funkcje bazy danych zostaną przetłumaczone na język SQL. Na przykład metody Distance i Contains są tłumaczone w następujących zapytaniach. Zapoznaj się z dokumentacją dostawcy, dla której metody są obsługiwane.
// Find the nearest city
var nearestCity = await db.Cities
.OrderBy(c => c.Location.Distance(currentLocation))
.FirstOrDefaultAsync();
// Find the containing country
var currentCountry = await db.Countries
.FirstOrDefaultAsync(c => c.Border.Contains(currentLocation));
Inżynieria odwrotna
Pakiety NuGet przestrzenne włączają również modele inżynierii odwrotnej z właściwościami przestrzennymi, ale należy zainstalować pakiet przed uruchomieniem Scaffold-DbContext
polecenia lub dotnet ef dbcontext scaffold
. Jeśli tego nie zrobisz, otrzymasz ostrzeżenia dotyczące braku znajdowania mapowań typów dla kolumn, a kolumny zostaną pominięte.
Identyfikator SRID ignorowany podczas operacji klienta
NTS ignoruje wartości SRID podczas operacji. Przyjęto założenie, że planarny układ współrzędnych. Oznacza to, że jeśli określisz współrzędne pod względem długości geograficznej i szerokości geograficznej, niektóre wartości oceniane przez klienta, takie jak odległość, długość i obszar będą w stopniach, a nie metrach. Aby uzyskać bardziej znaczące wartości, należy najpierw projektować współrzędne do innego systemu współrzędnych przy użyciu biblioteki, takiej jak ProjNet (for GeoAPI).
Uwaga
Użyj nowszego pakietu NuGet ProjNet, a nie starszego pakietu o nazwie ProjNet4GeoAPI.
Jeśli operacja jest obliczana przez program EF Core za pośrednictwem programu SQL, jednostka wyniku zostanie określona przez bazę danych.
Oto przykład użycia sieci ProjNet do obliczenia odległości między dwoma miastami.
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));
Uwaga
4326 odnosi się do WGS 84, standard używany w GPS i innych systemach geograficznych.
Dodatkowe zasoby
Informacje specyficzne dla bazy danych
Zapoznaj się z dokumentacją dostawcy, aby uzyskać dodatkowe informacje na temat pracy z danymi przestrzennymi.
- Dane przestrzenne w dostawcy programu SQL Server
- Dane przestrzenne w dostawcy SQLite
- Dane przestrzenne w dostawcy npgsql
Inne zasoby
- NetTopologySuite Docs
- Sesja standupu społeczności danych platformy .NET, koncentrująca się na danych przestrzennych i aplikacji NetTopologySuite.