Compartir a través de


SQL Server Aplicación Espacial (es-ES)

  

Introducción

Nuestro objetivo inicial es demonstrar las nuevas características de la versión CTP de junio Entity Framework en forma realista. Las características más significativas de esta versión son:

  • Características espaciales de SQL Server
  • enumeraciones
  • funciones con valores de tabla
  • y algunos otros

De estos, las características espaciales parecen tener el mayor impacto sobre el carácter de la aplicación. Además, las aplicaciones espaciales son menos conocidas y entendidos, por ejemplo, aplicaciones de e-commerce/entrada de pedidos o aplicaciones de inventario. Así que nuestra primera tarea fue intercambiar ideas sobre posibles aplicaciones.

No dude en contribuir a este proyecto. NO soy un experto en funciones espaciales de SQL Server y no tengo fondo en este dominio de aplicación. En un sentido ésto es bueno: mi experiencia será semejante a la situación en que su jefe le entrega un proyecto para evaluar posibles usos de esta nueva tecnología cool que ella o él ha oído hablar. Pero mi experiencia definitivamente no simulará a la de un experto en el dominio espacial que está considerando la posibilidad de utilizar SQL Server. Así que siéntase libre de contribuir, comentar, criticar, agregar ideas creativas, etc.. Por favor no.

Hasta ahora, este proyecto ha atravesado las siguientes fases:

  • lluvia de ideas inicial: lanzando ideas sobre posibles aplicaciones, establecer restricciones y supuestos
  • factibilidad: probar piezas de la tecnología necesaria para verificar que parecen funcionar

Intercambio de ideas inicial

Limitaciónes y suposiciónes

Medios de comunicación

Es probable que queremos incluir mapas en la interfaz de usuario. Hay otras posibles aplicaciones espaciales referenciados en internet, que no involucran mapas. Pero en estos casos, los tipos de datos de geometría aparecen en escenarios de tipo CAD/CAM como objetos en modelos; otro caso es que aparecen en diseños de construcción de edificios. Estas aplicaciones parecidas algo más especialización de aplicaciones orientadas al mapa, así que decidí excluir de consideración.

En nuestra sesión de intercambio de ideas iniciales, se señaló que existe un gran cuerpo de fotografías en la web que fueron geo-codificada con datos de ubicación que pueden ser útiles utilizar.

También fue el factor de "frescura" a considerar. Nuestra conclusión provisional inicial fue que idealmente podría implicar la aplicación de mapas y fotos.

Simplicidad

Ya estamos creando una aplicación de muestra que los usuarios pueden instalar, y con que pueden experimentar, los datos que utiliza debe ser algo pequeño y públicamente disponibles de forma gratuita. También es probable que queremos que la aplicación utilice una base de datos preexistente, en lugar de crearlo por medio de un app EF estilo "Modelo Primero", y dejar que el app inicializa la base de datos. Otros opinaron que es probable que queríamos hacer una aplicación de estilo Código Primero porque ahí es dónde está el major interés del cliente, por lo que decidimos tentativamente. Código Primero por supuesto descarta el uso de funciones de valor de tabla.

Disponibilidad de datos

Hay un montón de datos geográficos disponibles de forma gratuita. Necesitamos:

  • que sean capaz de convertirse fácilmente en datos de SQL Server
  • Seleccionar un subconjunto adecuado

Es probable que se seleccione un subconjunto de datos estadounidenses y probablemente en esta área local, para facilitar las pruebas, debido a nuestra familiaridad.

Otra opción que mencionó era tomar fotos geocodificados y cargarlos en la app, mediante instrucciones SQL INSERT espaciales.

Otra opción era obtener datos de algún tipo de servicio (Bing mapas por ejemplo, o el "Dallas" Data Mart).

Ejemplos de aplicaciónes

Hablamos de un número de posibilidades de muestra. Sentíamos que queríamos consultas más complejas que sólo "Mostrar todas las tiendas dentro de x kilómetros de aquí", para que la aplicación podría ejercer algunas de las capacidades de SQL espacial.

Visualizador de Fotos para una Ruta de Viaje

Dada una trayectoria de vuelo del avión, mostrar todas las fotos dentro de una milla del punto en el camino donde estás actualmente.
O mostrar todos los aumentos (con fotos) dentro de 10 millas de una ruta de viaje.

Inmobiliaria: Buscador de Casas

Mostrar todas las casas dentro de un rango de precio en un barrio que son más de x kilómetros de una carretera importante, dentro de un kilometro de una escuela primaria y dentro de algún área que usted no puede representar fácilmente en una tabla (por ejemplo, código postal se representa facilmente en una tabla, pero "dentro de los límites legales de una ciudad" sirve como ejemplo, puesto que casas colindantes en Seattle a menudo usan Seattle en su dirección aun cuando en realidad están fuera de los límites de la ciudad). Éste es un buen ejemplo de una consulta espacial compleja, pero desgraciadamente, a menudo los datos de casa son propietarios.
¿TBD: hay datos de dominio público disponible re "Recientes ventas de casa"?

Investigación inicial

Estamos realmente en una situación similar a alguien cuyo jefe le ha ordenado a investigar esta nueva tecnología que se llama "SQL espacial" y crear un prototipo para evaluar si seguir adelante con ella o no. En este momento parece que lo mejor es un estudio de factibilidad donde tratamos diferentes operaciones espaciales, verificar que funcionan de la manera en que la documentación describe, verificar que funcionan utilizando Entity Framework en estilo Código Primero, y aprender más sobre las cuestiones relacionadas con cualquier aplicación específica. Para ello, una aplicación de consola simple es suficiente, tal como hizo el equipo ADO.Net en su blog sobre las características espaciales de la versión CTP de Junio  , salvo que nos podría ser ampliarlo una cantidad justa para tener en las aplicaciones posibles de la cuenta.

Requisitos previos de software

ADO.Blog del equipo neto contable sobre las características espaciales de CTP de June describe cómo instalar el software necesario.

Prestar atención a la advertencia sobre sólo instalar este software en un equipo ajeno a la producción y si es necesario desinstalar, lea las instrucciones cuidadosamente. Había escuchado el primer bit de asesoramiento, pero no el segundo, y así tuve la deliciosa experiencia de re-paving mi máquina.

Características para investigar

Características de SQL

ADO.Blog del equipo de neta en espacial tiene código que un escenario común de demostraciones: "Mostrar todos los x que están dentro Y {millas | kilómetros | metros etc.} de mi ubicación actual ". Los contabilización código duro-códigos "mi ubicación" y sería cool a recoger desde su teléfono, pero por ahora, vamos a limitar el número de nuevas funciones que implementamos.
Las consultas adicionales que puede que nos guste a ejecutar incluyen:

  • todos los x dentro y kilómetros de una carretera
  • todos los x dentro de un polígono determinado (por ejemplo, código postal, ciudad, Estado, etc.)
  • complicadas combinaciones de estas (todas las casas dentro de ciertos barrios (códigos postales?) que están dentro de una milla de una escuela primaria y menos de la mitad de una milla de una línea de autobuses entre una milla y 2 millas de una importante autopista, etc.).
Funciones no SQL

He mencionado fotos y mapas. Nos deberíamos investigar lo que está involucrado en:

  • llamada Bing mapas para mostrar alrededor de un punto
  • encontrar fotos dentro x millas de un punto
  • puede que queramos investigar anuncios de casa: algunos de estos datos pueden ser propietario (casas en venta), pero algunos de ellos no es (condados de datos sobre ventas de casa)

Investigar estas características iniciales puede revelar otros factores no hemos considerado, más allá de la disponibilidad de datos, complejidad de api para acceder a los datos, etc..

Estudio de factibilidad

¿Podemos empezar usando la app en el ADO.¿Blog del equipo de neta en espacial ? Su sección de código primero con una base de datos existente nos proporciona un número de puntos (hitos) dentro de la ciudad de Seattle, Washington.

Nosotros podemos simular encontrar todos equis y kilómetros de una carretera creando líneas utilizando varios hitos como puntos y luego buscar todos hitos con x distancia de esa línea.

Nosotros podemos simular encontrar todos x dentro de un área mediante la creación de un polígono conformado por líneas.

Podemos crear consultas SQL compuestas de estos dos elementos.

Podemos llamar a Bing mapas en un hito determinado.

Encontrar todas las fotos que cumplan alguna condición requerirá algunas investigaciones sobre fuentes de fotos geo-codificada en la internet. O nos podríamos insertar esas fotos nosotros mismos y consulta contra ellos.

Anuncios de vivienda puede requerir más investigación, pero, sin duda, podemos comenzar.

Así que parece que podemos comenzar con nuestro estudio de factibilidad. A continuación, podemos evaluar los resultados y decidir sobre un prototipo real para implementar.

Características de SQL

Líneas

Primero vamos a crear una clase de líneas, lo que generará una tabla en la base de datos y, a continuación, se rellenarán con instancias de línea. Inicialmente estas instancias contendrá sólo dos puntos, pero al final te queremos crear líneas con varios puntos, para reflejar la situación real con carreteras reales.

Permite así añadir algún código para el tutorial espacial, una nueva clase de líneas y una llamada al método de DbSet para las líneas. Las partes modificadas del código ahora parece esto:

public class Line
{
public int  LineID { get; set; }
public string LineName { get; set; }
public DbGeography LineLocation {  get; set; }
}



public class SeattleLandmarksEntities : DbContext
{
public DbSet<Person> People {  get; set; }
public DbSet<Landmark> Landmarks {  get; set; }
public DbSet<Line> Line { get; set; }

}

A continuación que tenemos que crear una instancia de unas pocas líneas. Ser perezoso, sólo agregaré utilizando unos puntos ya están definidos como monumentos históricos.

Este hecho resultó para ser más difícil de lo que inicialmente pensaba. Hay varios aspectos no intuitivos de la api de SQL Server espacial.

Cada objeto geográfico o geométrica es de tipo DbGeography o DbGeometry, si es un punto, línea, polígono, etc.. Hablando como un novato total en el área, esto parece demasiado abstracta, ya que cabría esperar diferentes métodos para aplicar a los distintos tipos de objetos. Pero esa es la forma es, por lo que me sale "solo tratar con él".

Crear una instancia de un objeto tiene una api oscuro: el método toma un parámetro de cadena única, que es analizado internamente. Aquí es un ejemplo para la creación de un punto, tomado de la muestra que estamos utilizando como una línea de base.

var landmark16 = new Landmark
{
LandmarkID = 16,

Address = "1400 E. Galer Street",

Location = DbGeography.Parse("POINT(-122.31249 47.632342)"),

LandmarkName = "Volunteer Park"
};

El problema con el uso de "cadenas mágicas" como parámetros de entrada es que es difícil de adivinar cuál debe ser la cadena. Como pude determinar, no hay ninguna fuente de información describiendo su formato fácilmente accesible y adjuntan: no pude encontrar nada en libros On Line.

La otra cuestión es que no quiero crear una instancia de una línea de paso en una larga lista de coordenadas. Ya tengo un montón de puntos: ¿por qué no puedo simplemente crear una línea pasando 2 puntos al constructor? Resulta que grandes mentes piensan igual, y utilizando búsqueda encontré un mensaje en el Foro de SQL espaciales preguntando lo mismo (aquí ). Hubo una propuesta de solución (mediante funciones de CLR) que podría tener problemas de rendimiento, pero voy a ignorar por el momento, en aras de la simplicidad. De todos modos, la solución mostraba cómo crear instancias de una línea, por lo que he podido deducir el siguiente código.

// make a line
var line1 = new Line
{
LineID = 1,
LineName = "whatever",
LineLocation = DbGeography.Parse("LINESTRING(-122.31249 47.632342, -122.317575 47.665229)")
};

He añadido este código a la muestra, ejecutaba y obtuvo los mismos resultados que antes. Y podemos mirar en la base de datos en SSMS y compruebe que se ha creado una nueva tabla de línea.

Así que ahora estamos dispuestos a hacer algo productivo: vamos a calcular la distancia entre un punto y esta línea. Realmente si nos fijamos en la consulta existente, que calcula todos los hitos dentro de.5 millas desde un punto fijo, fácilmente podemos modificar para conseguir todos los hitos dentro de x millas de la línea inserta en la tabla de líneas:

// Get landmarks within 2 miles of the line 
var line = context.Line.Find(1); 
var distanceInMiles2 = 2.5; 
var distanceInMeters2 = distanceInMiles * 1609.344; 
var landmarks2 = 
from l in contexto de context.Landmarks  
where l.Location.Distance(line.LineLocation) < distanceInMeters 
select new
{ 
Name = l.LandmarkName, 
Address = l.Address 
}; 
Console.WriteLine("\nLandmarks within " + distanceInMiles2 + " mile(s) of " + 
línea de  line.LineName + "'s location:"); 
foreach (var loc in landmarks2) 
{  
Console.WriteLine("\t" + loc.Name + " (" + loc.Address + ")"); 
}  

Esto funciona, produce plausible buscando salida. Para comprobarlo, sería bueno utilizar mapas de Bing para trazar todos los hitos y la línea. Pasé una hora buscando en los mapas de Bing y satisface esto puede hacerse, pero no encontró una aplicación rápida que podría modificar para ello. Aprender de lo suficiente para estar satisfecho que es anhelado para utilizar mapas como una interfaz espacial, que era la meta en el punto en el proyecto.

También he descubierto un blog discutir datos espaciales disponibles en la Oficina de censo. El autor realmente importa los datos para un condado específico en SQL Server. Por lo que otro objetivo de factibilidad está satisfecho: la libre disponibilidad de un subconjunto de datos espaciales "bonito".

Pero no para conseguir distraído: ¿cómo verificar que los resultados de la consulta anterior son correctos? El conjunto de datos es lo suficientemente pequeño como para que yo debo poder manualmente trazar directamente en los mapas de Bing y comprobar visualmente que está bien. Después de hacerlo, descubro que la consulta devuelve los dos extremos de la línea ("Biblioteca de la Universidad" y "Voluntario Park"), además de "Montlake Bridge", que visualmente se ve menos de 2 kilómetros desde la línea. Sin embargo, hay varios otros puntos que parecen deberían haber sido seleccionado ("Gas Works Park", "Edificio de apartamentos de Anhalt"), pero esto inspeccionar visualmente es bastante aproximada. Mi especulación es que sólo estamos consiguiendo hitos dentro de 2 millas de los extremos de la línea, en lugar de toda la línea. Por lo tanto permite escribir una consulta que nos irá esas edificaciones. Voy a escribir un método que recibirá la distancia de cada hito de un punto especificado, y te llamamos dos veces, una vez para cada extremo.

Realmente mi especulación estaba equivocada, y los errores fueron normalmente bastante tontos, no hay mucho interés; pero lo que podría ser interesante es un método de depuración que escribí al intentar averiguar lo que pasaba. Este método muestra la distancia de cada objeto de referencia de un objeto DbGeography especificado (punto, línea, polígono, etc.). Es código bastante obvio, pero es útil en la depuración de la fuerza bruta. Se sospecha de que necesita filtrarla una vez que el conjunto de edificaciones (u otro objeto espacial) se convirtió en demasiado numerosos.

static void  getLandmarkDistancesFromGeography(SeattleLandmarksEntities context, DbGeography geo, string  Name) 
{  
var landmarks2 = 
from l in contexto de context.Landmarks  
select new
{ 
Name = l.LandmarkName, 
Distance = l.Location.Distance(geo) / 1609.344 
}; 
Console.WriteLine("\nLandmark distances from " + 
Name ); 
foreach (var loc in landmarks2) 
{ 
Console.WriteLine("\t" + loc.Name + " (" + loc.Distance + ")"); 
} 
}  

Y las llamadas, que me permitió descubrir mi problema, parecían esto: tenga en cuenta cómo puede llamarlo con una variedad de objetos espaciales.

getLandmarkDistancesFromGeography(context, person.Location, person.Name); 
getLandmarkDistancesFromGeography(context, context.Landmarks.Find(15).Location, context.Landmarks.Find(15).LandmarkName); 
getLandmarkDistancesFromGeography(context, context.Landmarks.Find(16).Location, context.Landmarks.Find(16).LandmarkName); 
getLandmarkDistancesFromGeography(context, context.Line.Find(1).LineLocation, context.Line.Find(1).LineName); 

La próxima cosa que me gustaría comprobar que está encontrando la distancia desde la línea funciona cuando la línea se compone de más de dos puntos. Esto será claramente la situación real con representaciones de la mayoría de carreteras y autopistas.

Así que vamos a crear una línea consistente en dos segmentos de línea. Queremos que cada segmento tener hitos que será o no seleccionará, exclusivo de otro segmento, por lo que la función de la distancia está haciendo un trabajo un poco más. Aquí está el código que se agrega al archivo SeattleLandmarkSeed.cs.

var line2 = new Line 
{ 
LineID = 2, 
LineName = "Queen Anne Through Downtown", 
LineLocation = DbGeography.Parse("LINESTRING(-122.349755 47.647494, -122.352842 47.6186, -122.334571 47.604009 )") 
}; 

.......  

context.Line.Add(line2); 

Ejecutar el ejemplo, nos encontramos a través de SSMS que la tabla línea tiene ahora dos filas.

Vamos a ver todos los hitos dentro de un kilómetro y medio de esta línea. Y, por lo que el código no llegar demasiado strung out, permite refactorizar mediante la creación de un nuevo método. Aquí es el nuevo método:

private static void  FindLandmarksNearLine(SeattleLandmarksEntities context, int  lineID, double  DistanceInMiles) 
{  
var line = context.Line.Find(lineID); 
var distanceInMeters2 = DistanceInMiles * 1609.344; 
var landmarks2 = 
from l in contexto de context.Landmarks  
where l.Location.Distance(line.LineLocation) < distanceInMeters2 
select new
{ 
Name = l.LandmarkName, 
Distance = l.Location.Distance(line.LineLocation), 
Limit = distanceInMeters2, 
Address = l.Address 
}; 
Console.WriteLine("\nLandmarks within " + DistanceInMiles + " mile(s) of " + 
línea de  line.LineName + "'s location: (limit in meters: "); 
foreach (var loc in landmarks2) 
{ 
Console.WriteLine("\t" + loc.Name 
+ " (" + loc.Address + ")"
+ "\t" + " ("  + loc.Distance + ")"
+ "\t" + " ("  + loc.Limit + ")"
); 
} 
}  

Y aquí es cómo se denomina:

FindLandmarksNearLine(context, 1, 2.5); 
FindLandmarksNearLine(context, 2, 0.5); 

Ahora es el único problema, tenemos que añadir un par de puntos de referencia para que cada segmento de la línea tendrá hitos que seleccione y edificaciones que no seleccione. Por lo que hacemos lo siguiente, en th SeattleLandmarksSeed.cs archivo.

var landmark17 = new Landmark 
{ 
LandmarkID = 17, 
Address = "", 
Location = DbGeography.Parse("POINT(-122.34727 47.64677)"), 
LandmarkName = "Aurora Bridge"
}; 

....  
context.Landmarks.Add(landmark17); 

 

Ahora cada segmento de la línea tiene hitos que consigue seleccionado y que no.

Si estuviéramos en la etapa de hacer pruebas exhaustivas, intentamos agregar una línea con un gran número de segmentos, pero eso para más tarde.

Polígonos

¿El último bit de SQL espacial para probar es polígonos: podemos seleccionamos todos los hitos dentro de un polígono dado?
Primero creamos un polígono que incluye hitos algunos pero no todos, con este código.

Funciones no SQL

Mapas de BING

Para comprobar los resultados del código anterior, pensé que sería bueno utilizar mapas de Bing para trazar todos los hitos y la línea (y polígono). Pasé una hora buscando en los mapas de Bing y satisface esto puede hacerse, pero no encontró una aplicación rápida que podría modificar para ello. Aprender de lo suficiente para estar satisfecho que es anhelado para utilizar mapas como una interfaz espacial, que era la meta en el punto en el proyecto.

Disponibilidad de datos

He descubierto un blog discutir datos espaciales disponibles en la Oficina del censo nos . El autor realmente importan los datos para un condado específico de SQL Server y proporciona código de ejemplo, incluyendo:

  • Cómo importar los datos
  • consultas de ejemplo contra

Además, de boca he oído de numerosas otras fuentes de Gobierno de datos espaciales de dominio público. Por lo que otro objetivo de factibilidad está satisfecho: la libre disponibilidad de un subconjunto de datos espaciales "bonito".

Datos de ventas residenciales y fotos

Fotos siguen siendo investigados. Hay posibles cuestiones jurídicas involucradas que por lo menos deben ser investigados (ver problemas en Europa con fotos de street view de Google) y resuelto.
Datos de ventas residenciales están un subconjunto más especializado que te investigamos más tarde.