Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los datos espaciales representan la ubicación física y la forma de los objetos. Muchas bases de datos proporcionan compatibilidad con este tipo de datos para que se puedan indexar y consultar junto con otros datos. Entre los escenarios comunes se incluyen la consulta de objetos a una distancia determinada desde una ubicación o la selección del objeto cuyo borde contiene una ubicación determinada. EF Core admite la asignación a tipos de datos espaciales utilizando la biblioteca espacial NetTopologySuite.
Instalar
Para usar datos espaciales con EF Core, debe instalar el paquete NuGet compatible adecuado. El paquete que necesita instalar depende del proveedor que use.
Proveedor de EF Core | Paquete espacial de 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 |
FileBaseContext | NetTopologySuite |
NetTopologySuite
NetTopologySuite (NTS) es una biblioteca espacial para .NET. EF Core permite mapear los tipos de datos espaciales de la base de datos mediante los tipos NTS en el modelo.
Para habilitar la asignación a tipos espaciales a través de NTS, llame al método UseNetTopologySuite en el generador de opciones DbContext del proveedor. Por ejemplo, con SQL Server lo llamaría así.
options.UseSqlServer(
@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=WideWorldImporters;ConnectRetryCount=0",
x => x.UseNetTopologySuite());
Hay varios tipos de datos espaciales. El tipo que use depende de los tipos de formas que desee permitir. Esta es la jerarquía de tipos NTS que puede usar para las propiedades del modelo. Se encuentran dentro del NetTopologySuite.Geometries
espacio de nombres.
- Geometría
- Punto
- LineString
- Polígono
- Colección de Geometrías
- MultiPoint
- MultiLineString
- MultiPolygon
Advertencia
NTS no admite CircularString, CompoundCurve y CurePolygon.
El uso del tipo Geometry base permite mediante la propiedad especificar cualquier tipo de forma.
Longitud y latitud
Las coordenadas de NTS se encuentran en términos de valores X e Y. Para representar la longitud y la latitud, use X para longitud e Y para la latitud. Tenga en cuenta que esto es invertido al formato latitude, longitude
en el que normalmente se ven estos valores.
Consulta de datos
Las siguientes clases de entidad se pueden usar para mapear a las tablas en la base de datos de ejemplo 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; }
}
En LINQ, los métodos y propiedades NTS disponibles como funciones de base de datos se traducirán a SQL. Por ejemplo, los métodos Distance y Contains se traducen en las siguientes consultas. Consulte la documentación del proveedor para ver qué métodos se admiten.
// 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));
Ingeniería inversa
Los paquetes NuGet espaciales también habilitan modelos de ingeniería inversa con propiedades espaciales, pero debe instalar el paquete antes de ejecutar Scaffold-DbContext
o dotnet ef dbcontext scaffold
. Si no lo hace, recibirá advertencias por no encontrar asignaciones de tipos para las columnas, lo que resultará en que estas sean omitidas.
SRID ignorado durante las operaciones del cliente
NTS omite los valores SRID durante las operaciones. Se presupone un sistema de coordenadas planar. Esto significa que si especifica coordenadas en términos de longitud y latitud, algunos valores evaluados por el cliente como la distancia, la longitud y el área estarán en grados, no en metros. Para obtener valores más significativos, primero debe proyectar las coordenadas en otro sistema de coordenadas mediante una biblioteca como ProjNet (para GeoAPI).
Nota:
Use el paquete NuGet ProjNet más reciente, no el paquete anterior denominado ProjNet4GeoAPI.
Si EF Core evalúa una operación mediante SQL, la unidad del resultado se determinará por la base de datos.
Este es un ejemplo del uso de ProjNet para calcular la distancia entre dos ciudades.
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));
Nota:
4326 hace referencia a WGS 84, un estándar utilizado en GPS y otros sistemas geográficos.
Recursos adicionales
Información específica de la base de datos
Asegúrese de leer la documentación del proveedor para obtener información adicional sobre cómo trabajar con datos espaciales.
- Datos espaciales en el proveedor de SQL Server
- Datos espaciales en el proveedor de SQLite
- Datos espaciales en el proveedor Npgsql
Otros recursos
- Documentos de NetTopologySuite
- Reunión de la comunidad de datos de .NET, centrada en datos espaciales y NetTopologySuite.