Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Os dados espaciais representam a localização física e a forma dos objetos. Muitos bancos de dados dão suporte a esse tipo de dados para que possam ser indexados e consultados junto com outros dados. Cenários comuns incluem a consulta de objetos a uma determinada distância de um local ou a seleção do objeto cuja borda contém um determinado local. O EF Core dá suporte ao mapeamento para tipos de dados espaciais usando a biblioteca espacial NetTopologySuite.
Instalar
Para usar dados espaciais com o EF Core, você precisa instalar o pacote NuGet de suporte apropriado. Qual pacote você precisa instalar depende do provedor que você está usando.
| Provedor EF Core | Pacote NuGet Espacial |
|---|---|
| Microsoft.EntityFrameworkCore.SqlServer | Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite |
| Microsoft.EntityFrameworkCore.Sqlite | Microsoft.EntityFrameworkCore.Sqlite.NetTopologySuite |
| Microsoft.EntityFrameworkCore.InMemory | NetTopologySuite |
| Oracle.EntityFrameworkCore | Oracle.EntityFrameworkCore.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 |
| FileBaseContext | NetTopologySuite |
NetTopologySuite
NetTopologySuite (NTS) é uma biblioteca espacial para .NET. O EF Core permite o mapeamento para tipos de dados espaciais no banco de dados usando tipos NTS em seu modelo.
Para habilitar o mapeamento para tipos espaciais por meio do NTS, chame o método UseNetTopologySuite no construtor de opções DbContext do provedor. Por exemplo, com o SQL Server, você o chamaria assim.
options.UseSqlServer(
@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WideWorldImporters;ConnectRetryCount=0",
x => x.UseNetTopologySuite());
Há vários tipos de dados espaciais. Qual tipo você usa depende dos tipos de formas que você deseja permitir. Aqui está a hierarquia de tipos NTS que você pode usar para propriedades em seu modelo. Eles estão localizados no NetTopologySuite.Geometries namespace.
- Geometria
- Ponto
- LineString
- Polígono
- ColeçãoDeGeometria
- MultiPoint
- CadeiaDeLinhasMúltiplas
- MultiPolygon
Aviso
CircularString, CompoundCurve e CurePolygon não são compatíveis com o NTS.
O uso do tipo base Geometry permite que qualquer tipo de forma seja especificado através da propriedade.
Longitude e Latitude
As coordenadas no NTS são em termos de valores X e Y. Para representar longitude e latitude, use X para longitude e Y para latitude. Observe que isso é retrógrado do latitude, longitude formato no qual normalmente você vê esses valores.
Consulta de dados
As classes de entidade a seguir podem ser usadas para mapear para tabelas no banco de dados de exemplo 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; }
}
No LINQ, os métodos e as propriedades NTS disponíveis como funções de banco de dados serão convertidos em SQL. Por exemplo, os métodos Distance e Contains são traduzidos nas consultas a seguir. Consulte a documentação do provedor para quais métodos têm suporte.
// 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));
Engenharia reversa
Os pacotes NuGet espaciais também permitem modelos de engenharia reversa com propriedades espaciais, mas você precisa instalar o pacote antes de executar Scaffold-DbContext ou dotnet ef dbcontext scaffold. Caso não faça isso, você receberá avisos sobre a ausência de mapeamentos de tipo para as colunas, que serão ignoradas.
SRID ignorado durante operações de cliente
O NTS ignora valores SRID durante as operações. Ele pressupõe um sistema de coordenadas planar. Isso significa que, se você especificar coordenadas em termos de longitude e latitude, alguns valores avaliados, como distância, comprimento e área, estarão em graus, não em metros. Para valores mais significativos, primeiro você precisa projetar as coordenadas para outro sistema de coordenadas usando uma biblioteca como ProjNet (para GeoAPI).
Observação
Use o pacote NuGet ProjNet mais recente, não o pacote mais antigo chamado ProjNet4GeoAPI.
Se uma operação for avaliada pelo servidor pelo EF Core via SQL, a unidade do resultado será determinada pelo banco de dados.
Aqui está um exemplo de como usar o ProjNet para calcular a distância entre duas cidades.
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));
Observação
4326 refere-se ao WGS 84, um padrão usado em GPS e outros sistemas geográficos.
Recursos adicionais
Informações específicas do banco de dados
Leia a documentação do provedor para obter informações adicionais sobre como trabalhar com dados espaciais.
- Dados espaciais no provedor do SQL Server
- Dados espaciais no provedor SQLite
- Dados Espaciais no Oracle Data Provider para .NET
- Dados espaciais no provedor Npgsql
Outros recursos
- Documentos do NetTopologySuite
- Sessão standup da Comunidade de Dados do .NET, com foco em dados espaciais e NetTopologySuite.