martes, enero 15, 2008

Funciones MySQL que operan sobre datos espaciales I

.
Siguiendo la línea temática relativa a los sistemas de información geográficos y las bases de datos relacionales como soporte de datos, presento una serie de funciones MySQL que operan sobre datos espaciales. En varios ejemplos se hará referencia a la siguiente tabla denominada "elementos"

CREATE TABLE `elementos` (
`id` int NOT NULL,
`nombre` varchar(30),
`objeto` geometry not null
) TYPE=MyISAM;


INSERT INTO elementos (`id`, `nombre`, `objeto`)
VALUES (2, 'ruta provincial 4', GeomFromText('LINESTRING(1 9, 7 9, 12 22)')),
(5, 'Parque Haz', GeomFromText('POLYGON((0 8, 0 12, 10 12, 10 8, 0 8))')),
(6, 'Sector verde',GeomFromText('POLYGON((0 0, 0 9, 9 9, 9 0, 0 0),(1 1, 1 7, 7 7, 7 1, 1 1))')),
(7, 'EGB 8', GeomFromText('POINT(3 3)')),
(9, 'Hospital', GeomFromText('POINT(5 2)'));


Dimension() Devuelve la dimensión de una geometría dada como parámetro. Sus resultados pueden ser: -1 si el objeto es vacío, 0 para un punto, 1 para una línea y 2 para un polígono.

Ejemplos
select dimension(ubicacion) from ciudades;
Devuelve 0 para todas sus filas

select dimension(area) from provincias;
Devuelve 2 para todas sus filas

select dimension(trayecto) from rutas;
Devuelve 1 para todas sus filas


Envelope() Devuelve un rectángulo con los límites de la geometría dada como parámetro.

SET @g1 = GeomFromText('Polygon((0 0, 0 4, 4 4, 4 0,0 0))');
SET @g2 = GeomFromText('Point(8 8)');
SELECT envelope(@g2);
Resultado POLYGON((8 8,8 8,8 8,8 8,8 8))

SET @g1 = GeomFromText('Polygon((0 0, 0 4, 4 4, 4 0,0 0))');
SELECT astext(envelope(@g1));
Resultado POLYGON((0 0,4 0,4 4,0 4,0 0))

SET @g1 = GeomFromText('Polygon((0 0, 3 3, 6 0,0 0))');
SELECT astext(envelope(@g1));
Resultado POLYGON((0 0,6 0,6 3,0 3,0 0))

En el último ejemplo, la geometría original g1 es un triángulo pero la función devolvió el rectángulo mínimo (bounding box) que lo envuelve. A este rectángulo se lo concoe también con las siglas MBR (minimal bounding rectangle) y se lo define como el más pequeño rectángulo que encierra a una forma geométrica. Al analizar el siguiente ejemplo este concepto será ilustrado de mejor forma:

SET @g = GeomFromText('Multipoint(3 0, 6 9, 10 12)');
SELECT astext(envelope(@g));
Resultado POLYGON((3 0,10 0,10 12,3 12,3 0))

SET @g = GeomFromText('LineString(3 0, 6 9, 10 12)');
SELECT astext(envelope(@g));
Resultado POLYGON((3 0,10 0,10 12,3 12,3 0))


La función geometrytype() retorna el tipo de geometría a la cual pertenece un objeto dado como parámetro.

select nombre, geometrytype(objeto) from elementos;

NOMBRE geometrytype(OBJETO)
Ruta provincial 4 linestring
Parque Haz polygon
Sector verde polygon
EGB 8 point
Hospital point


srid() es una función que retorna el sistema de coordenadas asociados a un objeto dado como parámetro.

select nombre, geometrytype(objeto), srid(objeto) from elementos;

NOMBRE geometrytype(OBJETO) srid(OBJETO)
Ruta provincial 4 linestring 0
Parque Haz polygon 0
Sector verde polygon 0
EGB 8 point 0
Hospital point 0

Las funciones x() e y() son solamente aplicadas a geometrías tipo punto. Dado que retornan el valor de la coordenadas X e Y de un punto dado como parámetro.

SELECT X(GeomFromText('POINT(4 6)'))
SELECT Y(GeomFromText('POINT(4 6)'))
Devuelve 4 y 6 respectivamente

SELECT localidad, x(ubicacion), y(ubicacion) FROM ciudades;

LOCALIDAD x(UBICACION) y(UBICACION)
A1 1 1
A2 2 4
B1 4 2
B2 5 1
...

La función glength() se aplica a objetos tipo LineString y devuelve el largo de una línea.

SELECT ruta, glength(trayecto) FROM rutas;

RUTA glength(TRAYECTO)
R1 6
R2 7
R3 10
R4 2
R5 8.5440037453175
R6 3

isclosed() se aplica a un objeto LineString y devuelve 1 si es cerrado o 0 en caso de ser abierto, es decir que su punto inicial sea distinto a su punto final.

SELECT ruta, isclosed(trayecto) FROM rutas;

RUTA isclosed(TRAYECTO)
R1 0
R2 0
...
Si glength() e isclosed() se aplican a objetos MultiLineString el resultado será la suma de todos los largos, para glength, y 1 en isclosed, si todas las líneas son cerradas. También aplicable a objetos LineString están las funciones numpoints() que devuelve el número de puntos de un objeto dado y startpoint() y endpoint() que devuelven el punto inicial y final de una línea respectivamente.

SELECT ruta, numpoints(trayecto), astext(startpoint(trayecto)) FROM rutas;

RUTA numpoints(TRAYECTO) startpoint(TRAYECTO)
R1 2 POINT(1 9)
R2 3 POINT(2 11)

Pointn() aplicado sobre un objeto LineString devuelve el punto numero n dado como segundo parámetro.

SELECT ruta, ASTEXT(pointn(trayecto,2)) FROM rutas;

RUTA astext(startpoint(TRAYECTO))
R1 POINT(7 9)
R2 POINT(2 6)

En polígonos se aplican las funciones area() la cual devuelve su superficie, exteriorring() que dado un polígono devuelve un objeto linestring con los puntos que conforman su exterior. Luego interiorringn(g,n) devuelve como un objeto linestring los puntos de un anillo n interior. Finalmente numinteriorrings() devuelve la cantidad de anillos internos de un polígono.

SET @g = POLYFROMTEXT('POLYGON((0 0, 0 7, 7 7, 7 0, 0 0))');
SELECT area(@g);
Devuelve 49

SET @g = geomfromtext('POLYGON((0 0, 0 7, 7 7, 7 0, 0 0),(1 1, 1 6, 6 6, 6 1, 1 1))');
SELECT area(@g);
Devuelve 24, dado que le resta el área interna que no pertenece al polígono.

SET @g = geomfromtext('POLYGON((0 0, 0 7, 7 7, 7 0, 0 0),(1 1, 1 6, 6 6, 6 1, 1 1))');
SELECT numinteriorrings(@g);
Devuelve 1

SET @g = geomfromtext('POLYGON((0 0, 0 7, 7 7, 7 0, 0 0),(1 1, 1 6, 6 6, 6 1, 1 1))');
SELECT astext(interiorringn(@g,1));
Devuelve LINESTRING(1 1,1 6,6 6,6 1,1 1)

Las siguientes funciones operan sobre objetos GeometryCollection. Geometryn(g,n) devuelve el objeto geométrico que se halla en la posición n y numgeometries() devuelve el número de objetos existentes en una colección dada como parámetro.

SET @g = GEOMFROMTEXT('GEOMETRYCOLLECTION(POINT(3 11),
POINT(4 8), LINESTRING(0 6, 9 10, 20 10))');
SELECT GLENGTH(GEOMETRYN(@g, 3));
Devuelve 20.84

2 comentarios:

Kokoto dijo...

Alucinate. Es una información que ma ha servido de mucho.

Anónimo dijo...

Muy buena data, no conseguía nada de esto por ningún lado. Me sirvio muchisimo, muchas gracias