Foro de elhacker.net

Programación => Bases de Datos => Mensaje iniciado por: [D4N93R] en 23 Agosto 2010, 19:28 pm



Título: [Tutorial] Introducción al tipo de datos geography en Sql Server
Publicado por: [D4N93R] en 23 Agosto 2010, 19:28 pm
Geography es de tipo espacial, y está implementado como un tipo de datos CLR en Sql Server, es decir es una clase administrada  ::) . Este tipo representa daata en un sistema de coordenadas de la tierra, la cual almacena información elipsoidal como latitud y longitud.

Ahora veremos un pequeño ejemplo de como hacer una consulta pero antes necesitamos crear nuestra tabla:

Código
  1. CREATE TABLE [dbo].[Customer](
  2. [ID] [DECIMAL](18, 0) IDENTITY(1,1) NOT NULL,
  3. [Name] [VARCHAR](250) NOT NULL,
  4. [Location] [geography] NOT NULL,
  5. CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED
  6. (
  7. [ID] ASC
  8. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  9. ) ON [PRIMARY]
  10.  

Simplemente creamos una tabla de clientes, con un ID, Nombre y su posición espacial utilizando el tipo geography. Ejecutamos el Script para crear la tabla y listo.

Ya con nuestra tabla creada ingresaremos la data. Hay que tener en cuenta que la posición es parecido a X,Y, (Longitud y latitud). Otro punto es que la data para ser convertida hay que utilizar ciertos métodos del tipo geography, la lista de métodos pueden verla en http://msdn.microsoft.com/en-us/library/bb933988.aspx los cuales soportan las especificaciones de Open Geospatial Consortium (OGC).

En este caso usaremos STGeomFromText, el cual según msdn se define como: "STGeomFromText (geography Data Type): Returns a geography instance from an Open Geospatial Consortium (OGC) Well-Known Text (WKT) representation augmented with any Z (elevation) and M (measure) values carried by the instance."

La sintaxis es la siguiente:
Código:
STGeomFromText ( 'geography_tagged_text' , SRID )

El primer parámetro es el texto que queremos parsear como coordenadas, puede ser algo como 'POINT(-81.13 -6.17)'

El segundo parámetro es el identificador de referencia espacial. En nuestro caso usaremos el del planeta tierra que es el World Geodetic System 1984 (WGS 84) en donde el valor es: 4326 segun la tabla de sqlserver sys.spatial_reference_systems.

Con todo esto explicado el insert quedaría algo así:
Código
  1. INSERT INTO Customer VALUES('Juan', geography::STGeomFromText('POINT(-81.13 -6.17)',4326))




Hacemos un Query:
Código
  1. SELECT * FROM Customer
Código:
1	Juan	0xE6100000010CAE47E17A14AE18C0B81E85EB514854C0




Pero es muy dificil de comprender, por lo que hacemos un cast a Point:
Código
  1. SELECT ID,Name,Location,CONVERT(VARCHAR(MAX),Location) AS Point FROM Customer
Código:
1	0xE6100000010CAE47E17A14AE18C0B81E85EB514854C0	POINT (-81.13 -6.17)



Intentemos algo más interesante: Hay un método llamado STDistance, el cual te regresa la distancia entre dos puntos, entonces hacemos la siguiente consulta:

Código
  1. INSERT INTO Customer VALUES('Juan', geography::STGeomFromText('POINT(-60.13 -6.17)',4326))
  2. GO
  3.  
  4. SELECT ID,Name,CONVERT(VARCHAR(MAX),Location) AS Point,
  5. Location.STDistance(geography::STGeomFromText('POINT(-50.13 -6.17)',4326))
  6. FROM Customer
  7. GO

¿Qué hace?  Pues, primero añadimos otro registro para darle un poco más valor a esto. Luego ejecutamos el Select, el cual calcula por cada registro la distancia sobre un punto en común: geography::STGeomFromText('POINT(-50.13 -6.17)',4326)

Cuando vemos el resultado es más fácil de entender:

Código:
ID	Name	Location			Distance
1 Juan POINT (-81.13 -6.17) 3430549.19165979
3 Pedro POINT (-60.13 -6.17) 1106773.11874875

De esta forma podemos hacer que la consulta nos traiga los 10 Clientes más cercanos a X punto, qué es mucho más preciso que hacerlo por ciudad o algo parecido.

Un saludo, espero seguir con el tema en cuanto pueda.