Bases de Datos AvanzadasCuarto año
Campus VirtualFCYT - UADER
Cuarto año
CARRERALicenciatura en Sistemas de Información
AÑOS ACADÉMICOS
  • 1
    Primer año7 materias
  • 2
    Segundo año7 materias
  • 3
    Tercer año9 materias
  • 4
    Cuarto año8 materias
  • 5
    Quinto año6 materias
AdministraciónTu cuentaConfigurarPreferencias
Mapa de correlativasRecorrido interactivo
FCYT · UADERv alpha

Materia

Bases de Datos Avanzadas

  • Cuarto añoVolver al año
  • Calendario5 eventos
Licenciatura en Sistemas de Información/Cuarto año/Bases de Datos Avanzadas
Cuarto año

Bases de Datos Avanzadas

Link meet de teoria: https://meet.google.com/auc-jmas-veo
Link meet de practica: https://meet.google.com/wcm-echz-byj

Drive con contenido de la materiaMeet TeoriaMeet Practica
Cuarto año

Bases de Datos Avanzadas

Link meet de teoria: https://meet.google.com/auc-jmas-veo
Link meet de practica: https://meet.google.com/wcm-echz-byj

Drive con contenido de la materiaMeet TeoriaMeet Practica
Eventos5
Apuntes11

Agenda

Calendario de eventos

Seleccionar comisión:

Fechas, entregas y avisos importantes de la materia en un solo lugar.

No hay eventos próximos para mostrar

MES

Noviembre 2026
D
L
M
M
J
V
S
ExamenTrabajo PrácticoExposiciónSuspensión de clasesMesas de examen

Todos los eventos · Noviembre

vie6nov
ExamenRecuperatorio BDABases de Datos Avanzadas

Modo estudio

Poné a prueba lo que sabés

Quiz de Bases de Datos Avanzadas

Elegí uno o varios bancos de preguntas y practicá en modo práctica (con explicaciones) o examen.

Empezar quiz

Quiz de Bases de Datos Avanzadas

Practicá con bancos de preguntas en modo práctica (con explicaciones) o examen.

Empezar quiz

Recursos

Apuntes y descargas

Apunte

Repaso Parcial 2 Consultas Espaciales

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

BD Geográficas

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Guia BD Geograficas postgis

Otro

Guía práctica de PostGIS

Vamos a trabajar en un plano cartesiano artificial, con coordenadas simples. No son coordenadas reales, no son latitud/longitud y no vamos a usar SRID 4326. La idea es dibujar lo que creemos que va a pasar, ejecutar SQL, mirar el resultado y, cuando convenga, verlo en QGIS.


Paso 1. Crear la base y activar PostGIS

Crear una base para la práctica:

CREATE DATABASE bdg_practica;

Conectarse a esa base y activar PostGIS:

CREATE EXTENSION postgis;

Comprobar que está disponible:

SELECT PostGIS_Version();

PostGIS agrega tipos de datos espaciales y funciones para trabajar con geometrías dentro de PostgreSQL.


Paso 2. Crear la primera tabla

CREATE TABLE puntos (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(Point)
);

La columna geom guarda geometrías. En esta tabla sólo vamos a guardar puntos.


Paso 3. Insertar el primer punto

Insertamos el origen:

INSERT INTO puntos (descripcion, geom)
VALUES (
    'Origen',
    ST_GeomFromText('POINT(0 0)')
);

ST_GeomFromText crea una geometría a partir de WKT.

Consultar la tabla:

SELECT *
FROM puntos;

Ver la geometría en formato legible:

SELECT
    id,
    descripcion,
    ST_AsText(geom) AS wkt
FROM puntos;

Resultado esperado:

1 | Origen | POINT(0 0)

ST_AsText muestra la geometría como texto WKT.


Paso 4. Inspeccionar el punto

Antes de ejecutar:

¿Qué dimensión tiene un punto?

SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_Dimension(geom) AS dimension,
    ST_IsEmpty(geom) AS esta_vacia,
    ST_X(geom) AS x,
    ST_Y(geom) AS y
FROM puntos
WHERE descripcion = 'Origen';

Resultado esperado:

Origen | ST_Point | 0 | false | 0 | 0

Un punto tiene dimensión 0. ST_X y ST_Y devuelven sus coordenadas.


Paso 5. Cargar puntos de referencia

Vamos a armar este plano:

              Y+10
               |
              Y+5
               |
X-10 -- X-5 -- Origen -- X+5 -- X+10
               |
              Y-5
               |
              Y-10

Insertar los puntos:

INSERT INTO puntos (descripcion, geom)
VALUES
    ('X-5',  ST_GeomFromText('POINT(-5 0)')),
    ('X-10', ST_GeomFromText('POINT(-10 0)')),
    ('X+5',  ST_GeomFromText('POINT(5 0)')),
    ('X+10', ST_GeomFromText('POINT(10 0)')),
    ('Y-5',  ST_GeomFromText('POINT(0 -5)')),
    ('Y-10', ST_GeomFromText('POINT(0 -10)')),
    ('Y+5',  ST_GeomFromText('POINT(0 5)')),
    ('Y+10', ST_GeomFromText('POINT(0 10)'));

Ver los puntos:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM puntos
ORDER BY id;

Abrir QGIS, cargar la tabla puntos, activar etiquetas con descripcion y hacer zoom a la capa.


Paso 6. Medir distancias

Antes de ejecutar:

¿Cuánto vale la distancia entre (0,0) y (5,0)?

SELECT ST_Distance(
    ST_GeomFromText('POINT(0 0)'),
    ST_GeomFromText('POINT(5 0)')
) AS distancia;

Resultado esperado:

5

Ahora una diagonal:

SELECT ST_Distance(
    ST_GeomFromText('POINT(0 0)'),
    ST_GeomFromText('POINT(5 5)')
) AS distancia;

Resultado esperado aproximado:

7.0710678118654755

En este plano las unidades son unidades abstractas. Todavía no son metros ni grados.

Medir la distancia desde cada punto hasta (15,15):

SELECT
    descripcion,
    ST_AsText(geom) AS punto,
    ST_Distance(
        geom,
        ST_GeomFromText('POINT(15 15)')
    ) AS distancia
FROM puntos
ORDER BY distancia;

Antes de mirar el resultado, pensar cuál debería quedar más cerca.

Ahora medir la distancia de cada punto con cada uno de los otros puntos:

SELECT
    p1.descripcion AS punto_1,
    ST_AsText(p1.geom) AS geom_1,
    p2.descripcion AS punto_2,
    ST_AsText(p2.geom) AS geom_2,
    ST_Distance(p1.geom, p2.geom) AS distancia
FROM puntos p1
JOIN puntos p2
    ON p1.id < p2.id
ORDER BY p1.id, p2.id;

La condición p1.id < p2.id evita dos cosas:

  • comparar un punto consigo mismo;
  • repetir la misma comparación al revés.

Por ejemplo, si ya aparece Origen contra X+5, no necesitamos también X+5 contra Origen.


Paso 7. Crear los ejes del plano

Creamos una tabla para guardar líneas.

CREATE TABLE lineas (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(LineString)
);

Primero insertamos los ejes X e Y.

INSERT INTO lineas (descripcion, geom)
VALUES
    ('Eje X', ST_GeomFromText('LINESTRING(-15 0, 15 0)')),
    ('Eje Y', ST_GeomFromText('LINESTRING(0 -15, 0 15)'));

Los ejes se dibujan más largos que los puntos de referencia para que funcionen visualmente como ejes del plano, no como segmentos que terminan justo en -10 y 10.

Ver las líneas:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM lineas
ORDER BY id;

Cargar lineas en QGIS.

Crear una vista con el plano base:

CREATE OR REPLACE VIEW vista_plano_base AS
SELECT
    'Punto: ' || descripcion AS descripcion,
    geom::geometry AS geom
FROM puntos
WHERE descripcion IN (
    'Origen',
    'X-5', 'X-10', 'X+5', 'X+10',
    'Y-5', 'Y-10', 'Y+5', 'Y+10'
)
UNION ALL
SELECT
    descripcion,
    geom::geometry AS geom
FROM lineas
WHERE descripcion IN ('Eje X', 'Eje Y');

Esta vista junta los puntos de referencia iniciales y los dos ejes. Sirve para abrir el resultado en el visor geométrico o en QGIS y tener contexto visual.

SELECT
    descripcion,
    geom
FROM vista_plano_base;

Paso 8. Agregar una línea oblicua

Ahora agregamos una línea oblicua, como si fuera la gráfica de una función lineal sobre nuestro plano.

Antes de ejecutar:

Dibujá aproximadamente una recta que pase por (-3,-10) y (8,10). ¿Corta al eje X? ¿Corta al eje Y?

INSERT INTO lineas (descripcion, geom)
VALUES (
    'Oblicua',
    ST_GeomFromText('LINESTRING(-3 -10, 8 10)')
);

Volver a consultar:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM lineas
ORDER BY id;

Actualizar la capa lineas en QGIS o volver a cargarla para ver la nueva línea.


Paso 9. Inspeccionar líneas

SELECT
    descripcion,
    ST_Length(geom) AS longitud,
    ST_NumPoints(geom) AS cantidad_puntos,
    ST_AsText(ST_StartPoint(geom)) AS inicio,
    ST_AsText(ST_EndPoint(geom)) AS fin
FROM lineas
ORDER BY id;

ST_Length mide la línea. ST_StartPoint y ST_EndPoint devuelven geometrías.

Ver los vértices:

SELECT
    descripcion,
    ST_AsText(ST_PointN(geom, 1)) AS primer_punto,
    ST_AsText(ST_PointN(geom, 2)) AS segundo_punto
FROM lineas
ORDER BY id;

ST_PointN recupera el punto número N de una línea.


Paso 10. Preguntar relaciones entre líneas

Antes de ejecutar:

¿La línea oblicua corta al eje X?

SELECT ST_Intersects(l1.geom, l2.geom) AS se_intersectan
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Resultado esperado:

true

Probar todas las líneas contra todas:

SELECT
    l1.descripcion AS linea_1,
    l2.descripcion AS linea_2,
    ST_Intersects(l1.geom, l2.geom) AS intersects,
    ST_Disjoint(l1.geom, l2.geom) AS disjoint,
    ST_Touches(l1.geom, l2.geom) AS touches,
    ST_Crosses(l1.geom, l2.geom) AS crosses,
    ST_Equals(l1.geom, l2.geom) AS equals
FROM lineas l1
JOIN lineas l2
    ON l1.id < l2.id
ORDER BY l1.id, l2.id;

Estas funciones devuelven true o false.

Mini machete:

FunciónPregunta que responde
ST_Intersects¿Tienen algún punto en común?
ST_Disjoint¿No tienen ningún punto en común?
ST_Touches¿Se tocan en el borde, sin cruzarse por dentro?
ST_Crosses¿Una geometría cruza a la otra?
ST_Equals¿Representan exactamente la misma geometría?

Ojo: ST_Disjoint es lo contrario de ST_Intersects. Si una da true, la otra debería dar false.


Paso 11. Intersects no es Intersection

Primero preguntamos si se intersectan:

SELECT ST_Intersects(l1.geom, l2.geom) AS se_intersectan
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Eso devuelve un booleano.

Ahora preguntamos dónde se intersectan:

SELECT
    ST_AsText(ST_Intersection(l1.geom, l2.geom)) AS interseccion
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Resultado esperado:

POINT(2.5 0)

Para verlo con contexto, consultar el plano base junto con el punto de intersección:

SELECT
    descripcion,
    geom
FROM vista_plano_base
UNION ALL
SELECT
    'Intersección oblicua / eje X' AS descripcion,
    ST_Intersection(l1.geom, l2.geom)::geometry AS geom
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X'
UNION ALL
SELECT
	descripcion,
	geom
FROM lineas
WHERE descripcion = 'Oblicua';

En el visor geométrico ahora deberían verse:

  • los puntos de referencia;
  • los ejes X e Y;
  • la línea oblicua;
  • el punto de intersección POINT(2.5 0).

Ese punto debería aparecer exactamente sobre el eje X y también sobre la línea oblicua. La consulta usa UNION ALL para mostrar todas esas geometrías juntas sin perderlas como objetos separados.

FunciónDevuelve
ST_Intersectstrue / false
ST_Intersectionuna geometría

Esta diferencia es clave.


Paso 12. Crear buffers

Antes de ejecutar:

¿Qué forma esperás al hacer un buffer de 2 unidades alrededor del origen?

CREATE TABLE buffers (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(80),
    geom geometry
);
INSERT INTO buffers (descripcion, geom)
SELECT
    'Buffer de 2 unidades alrededor del origen',
    ST_Buffer(geom, 2)
FROM puntos
WHERE descripcion = 'Origen';

Ver el tipo de geometría generado:

SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo
FROM buffers;

ST_Buffer genera una nueva geometría.

Ahora un buffer alrededor del eje X:

INSERT INTO buffers (descripcion, geom)
SELECT
    'Buffer de 1 unidad alrededor del eje X',
    ST_Buffer(geom, 1)
FROM lineas
WHERE descripcion = 'Eje X';

Para visualizar las geometrías originales junto con sus buffers:

SELECT
    'Original: ' || descripcion AS descripcion,
    geom
FROM puntos
WHERE descripcion = 'Origen'
UNION ALL
SELECT
    'Original: ' || descripcion AS descripcion,
    geom
FROM lineas
WHERE descripcion = 'Eje X'
UNION ALL
SELECT
    descripcion,
    geom
FROM buffers
ORDER BY descripcion;

En el visor geométrico deberían verse el punto Origen, el Eje X y los dos buffers generados. La idea es comparar cada geometría original con la zona que produce ST_Buffer.

Cargar buffers en QGIS y usar transparencia para ver las capas anteriores.


Paso 13. Crear polígonos

CREATE TABLE poligonos (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(Polygon)
);

Dibujar tres polígonos:

INSERT INTO poligonos (descripcion, geom)
VALUES
    ('A', ST_GeomFromText('POLYGON((0 0, 6 0, 6 6, 0 6, 0 0))')),
    ('B', ST_GeomFromText('POLYGON((4 2, 10 2, 10 8, 4 8, 4 2))')),
    ('C', ST_GeomFromText('POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))'));

Verlos:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM poligonos
ORDER BY descripcion;

Cargar poligonos en QGIS con relleno transparente.


Paso 14. Relaciones entre polígonos

Antes de ejecutar:

¿A contiene a C?

SELECT ST_Contains(a.geom, c.geom) AS a_contiene_c
FROM poligonos a
JOIN poligonos c
    ON a.descripcion = 'A'
   AND c.descripcion = 'C';

Resultado esperado:

true

Ahora la relación inversa:

SELECT ST_Within(c.geom, a.geom) AS c_dentro_de_a
FROM poligonos c
JOIN poligonos a
    ON c.descripcion = 'C'
   AND a.descripcion = 'A';

Resultado esperado:

true

Ahora comparamos A contra B y A contra C en una sola consulta:

SELECT
    ST_Overlaps(a.geom, b.geom) AS a_b_se_superponen,
    ST_Intersects(a.geom, b.geom) AS a_b_se_intersectan,
    ST_Disjoint(a.geom, b.geom) AS a_b_son_disjuntos,
    ST_Overlaps(a.geom, c.geom) AS a_c_se_superponen,
    ST_Intersects(a.geom, c.geom) AS a_c_se_intersectan,
    ST_Contains(a.geom, c.geom) AS a_contiene_c
FROM poligonos a
JOIN poligonos b
    ON b.descripcion = 'B'
JOIN poligonos c
    ON c.descripcion = 'C'
WHERE a.descripcion = 'A';

Resultado esperado:

true | true | false | false | true | true

A y B se superponen parcialmente. A y C no se superponen parcialmente: C está completamente dentro de A.


Paso 15. Un caso para Touches

Agregamos un polígono D que toca a A por un borde.

INSERT INTO poligonos (descripcion, geom)
VALUES (
    'D',
    ST_GeomFromText('POLYGON((6 0, 9 0, 9 3, 6 3, 6 0))')
);

Antes de ejecutar:

¿D se superpone con A o sólo lo toca?

SELECT
    ST_Touches(a.geom, d.geom) AS toca,
    ST_Intersects(a.geom, d.geom) AS intersecta,
    ST_Overlaps(a.geom, d.geom) AS se_superpone
FROM poligonos a
JOIN poligonos d
    ON a.descripcion = 'A'
   AND d.descripcion = 'D';

Resultado esperado:

true | true | false

Ahora probamos D contra B:

SELECT
    ST_Touches(d.geom, b.geom) AS toca,
    ST_Intersects(d.geom, b.geom) AS intersecta,
    ST_Overlaps(d.geom, b.geom) AS se_superpone
FROM poligonos d
JOIN poligonos b
    ON d.descripcion = 'D'
   AND b.descripcion = 'B';

Resultado esperado:

false | true | true

D y B no sólo se tocan: comparten una región. Por eso ST_Overlaps da true.

Si dos geometrías se tocan, también se intersectan. Pero tocar no es lo mismo que superponerse.


Paso 16. Álgebra espacial

CREATE TABLE resultados_poligonales (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(80),
    geom geometry
);

Intersección entre A y B

Antes de ejecutar, sombrear la zona común entre A y B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Intersección entre A y B',
    ST_Intersection(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Intersección entre A y B';

Unión entre A y B

Antes de ejecutar, sombrear toda la región cubierta por A o por B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Unión entre A y B',
    ST_Union(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Unión entre A y B';

Diferencia A menos B

Antes de ejecutar, sombrear la parte de A que no está cubierta por B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Diferencia A menos B',
    ST_Difference(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Diferencia A menos B';

Cargar resultados_poligonales en QGIS y comparar con A y B.

Unión espacial del plano base

Antes usamos UNION ALL para mostrar varias geometrías juntas sin fusionarlas. Ahora usamos ST_Union para unir espacialmente todas las geometrías de vista_plano_base en una sola geometría.

SELECT
    'Plano base unido' AS descripcion,
    ST_Union(geom) AS geom
FROM vista_plano_base;

Ahora intersectamos la línea oblicua contra ese plano base unido y lo mostramos todo junto:

SELECT
    descripcion,
    geom
FROM vista_plano_base
UNION ALL
SELECT
    descripcion,
    geom
FROM lineas
WHERE descripcion = 'Oblicua'
UNION ALL
SELECT
    'Intersección oblicua / plano base unido' AS descripcion,
    ST_Intersection(l.geom, plano.geom)::geometry AS geom
FROM lineas l
CROSS JOIN (
    SELECT ST_Union(geom) AS geom
    FROM vista_plano_base
) plano
WHERE l.descripcion = 'Oblicua';

Resultado esperado: deberían verse el plano base, la oblicua y dos puntos de intersección, porque la oblicua corta al eje X y también al eje Y.

Para leerlos como texto:

SELECT
    ST_AsText(
        ST_Intersection(l.geom, plano.geom)
    ) AS interseccion
FROM lineas l
CROSS JOIN (
    SELECT ST_Union(geom) AS geom
    FROM vista_plano_base
) plano
WHERE l.descripcion = 'Oblicua';

La diferencia importante:

OperaciónQué hace
UNION ALLJunta filas en una consulta
ST_UnionUne geometrías espacialmente

Paso 17. Envolventes: Convex Hull y Envelope

Volvemos a los puntos.

Convex Hull

Antes de ejecutar:

¿Cuál sería el polígono convexo más chico que contiene todos los puntos?

SELECT
    ST_AsText(
        ST_ConvexHull(
            ST_Collect(geom)
        )
    ) AS convex_hull
FROM puntos;

ST_Collect agrupa los puntos. ST_ConvexHull calcula el polígono convexo que los envuelve.

Guardar el resultado:

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Convex hull de los puntos',
    ST_ConvexHull(ST_Collect(geom))
FROM puntos;

Verlo en QGIS.


Envelope

ST_Envelope devuelve el rectángulo mínimo alineado a los ejes que contiene una geometría.

Antes de ejecutar:

Si los puntos llegan hasta -10 y 10 en los ejes, ¿qué rectángulo esperás obtener?

SELECT
    ST_AsText(
        ST_Envelope(
            ST_Collect(geom)
        )
    ) AS envelope
FROM puntos;

Guardar el resultado:

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Envelope de los puntos',
    ST_Envelope(ST_Collect(geom))
FROM puntos;

Ver juntos Convex hull y Envelope:

SELECT
    descripcion,
    geom
FROM resultados_poligonales
WHERE descripcion IN (
    'Convex hull de los puntos',
    'Envelope de los puntos'
);

El Convex Hull se ajusta a la forma convexa más chica. El Envelope siempre devuelve un rectángulo alineado a los ejes.


Paso 18. LINESTRING y MULTILINESTRING

Una línea puede tener muchos vértices y seguir siendo una sola LINESTRING.

INSERT INTO lineas (descripcion, geom)
VALUES (
    'Línea con varios vértices',
    ST_GeomFromText(
        'LINESTRING(1 1, 2 5, 3 4, 4 8, 5 9, 6 3, 7 5, 8 7, 9 6, 10 10)'
    )
);
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_NumPoints(geom) AS vertices,
    ST_AsText(geom) AS wkt
FROM lineas
WHERE descripcion = 'Línea con varios vértices';

Aunque tenga muchos puntos, sigue siendo una única línea.

Ahora creamos una geometría múltiple:

CREATE TABLE multilines (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(MultiLineString)
);
INSERT INTO multilines (descripcion, geom)
VALUES (
    'Dos líneas independientes',
    ST_GeomFromText('MULTILINESTRING((0 0, 5 5), (0 5, 5 0))')
);
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_AsText(geom) AS wkt
FROM multilines;

MULTILINESTRING contiene varias líneas independientes.


Fin

Apunte

BD Geometrica

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Parcial 1 Preguntas Desarrollo Posibles Repaso

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Machete para SGBDA

DocumentoOtro

Archivo de Drive

Abrir en Drive
Vista previa de Archivo de DriveAbrir archivo

Apunte

Resumen para el parcial 1

Documento

Archivo de Drive

Abrir en Drive
Vista previa de Archivo de DriveAbrir archivo

Apunte

Apunte Distribuidas Alternativo Mejorado

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Apunte BD Distribuidas

Interactivo

By ChatGPT 5.5 High

Abrir apunte

Apunte interactivo

By ChatGPT 5.5 High

Tocá para abrir la vista previa.

Apariencia alternativa

Abrir apunte

Apunte interactivo

Apariencia alternativa

Tocá para abrir la vista previa.

Apunte

Apunte Bases Temporales

DocumentoInteractivo

by Claude Fable 5

Abrir apunte

Apunte interactivo

by Claude Fable 5

Tocá para abrir la vista previa.

Apunte

Que es un trigger, y lenguaje PLPGSQL

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Repaso Parcial 2 Consultas Espaciales

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

BD Geográficas

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Guia BD Geograficas postgis

Otro

Guía práctica de PostGIS

Vamos a trabajar en un plano cartesiano artificial, con coordenadas simples. No son coordenadas reales, no son latitud/longitud y no vamos a usar SRID 4326. La idea es dibujar lo que creemos que va a pasar, ejecutar SQL, mirar el resultado y, cuando convenga, verlo en QGIS.


Paso 1. Crear la base y activar PostGIS

Crear una base para la práctica:

CREATE DATABASE bdg_practica;

Conectarse a esa base y activar PostGIS:

CREATE EXTENSION postgis;

Comprobar que está disponible:

SELECT PostGIS_Version();

PostGIS agrega tipos de datos espaciales y funciones para trabajar con geometrías dentro de PostgreSQL.


Paso 2. Crear la primera tabla

CREATE TABLE puntos (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(Point)
);

La columna geom guarda geometrías. En esta tabla sólo vamos a guardar puntos.


Paso 3. Insertar el primer punto

Insertamos el origen:

INSERT INTO puntos (descripcion, geom)
VALUES (
    'Origen',
    ST_GeomFromText('POINT(0 0)')
);

ST_GeomFromText crea una geometría a partir de WKT.

Consultar la tabla:

SELECT *
FROM puntos;

Ver la geometría en formato legible:

SELECT
    id,
    descripcion,
    ST_AsText(geom) AS wkt
FROM puntos;

Resultado esperado:

1 | Origen | POINT(0 0)

ST_AsText muestra la geometría como texto WKT.


Paso 4. Inspeccionar el punto

Antes de ejecutar:

¿Qué dimensión tiene un punto?

SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_Dimension(geom) AS dimension,
    ST_IsEmpty(geom) AS esta_vacia,
    ST_X(geom) AS x,
    ST_Y(geom) AS y
FROM puntos
WHERE descripcion = 'Origen';

Resultado esperado:

Origen | ST_Point | 0 | false | 0 | 0

Un punto tiene dimensión 0. ST_X y ST_Y devuelven sus coordenadas.


Paso 5. Cargar puntos de referencia

Vamos a armar este plano:

              Y+10
               |
              Y+5
               |
X-10 -- X-5 -- Origen -- X+5 -- X+10
               |
              Y-5
               |
              Y-10

Insertar los puntos:

INSERT INTO puntos (descripcion, geom)
VALUES
    ('X-5',  ST_GeomFromText('POINT(-5 0)')),
    ('X-10', ST_GeomFromText('POINT(-10 0)')),
    ('X+5',  ST_GeomFromText('POINT(5 0)')),
    ('X+10', ST_GeomFromText('POINT(10 0)')),
    ('Y-5',  ST_GeomFromText('POINT(0 -5)')),
    ('Y-10', ST_GeomFromText('POINT(0 -10)')),
    ('Y+5',  ST_GeomFromText('POINT(0 5)')),
    ('Y+10', ST_GeomFromText('POINT(0 10)'));

Ver los puntos:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM puntos
ORDER BY id;

Abrir QGIS, cargar la tabla puntos, activar etiquetas con descripcion y hacer zoom a la capa.


Paso 6. Medir distancias

Antes de ejecutar:

¿Cuánto vale la distancia entre (0,0) y (5,0)?

SELECT ST_Distance(
    ST_GeomFromText('POINT(0 0)'),
    ST_GeomFromText('POINT(5 0)')
) AS distancia;

Resultado esperado:

5

Ahora una diagonal:

SELECT ST_Distance(
    ST_GeomFromText('POINT(0 0)'),
    ST_GeomFromText('POINT(5 5)')
) AS distancia;

Resultado esperado aproximado:

7.0710678118654755

En este plano las unidades son unidades abstractas. Todavía no son metros ni grados.

Medir la distancia desde cada punto hasta (15,15):

SELECT
    descripcion,
    ST_AsText(geom) AS punto,
    ST_Distance(
        geom,
        ST_GeomFromText('POINT(15 15)')
    ) AS distancia
FROM puntos
ORDER BY distancia;

Antes de mirar el resultado, pensar cuál debería quedar más cerca.

Ahora medir la distancia de cada punto con cada uno de los otros puntos:

SELECT
    p1.descripcion AS punto_1,
    ST_AsText(p1.geom) AS geom_1,
    p2.descripcion AS punto_2,
    ST_AsText(p2.geom) AS geom_2,
    ST_Distance(p1.geom, p2.geom) AS distancia
FROM puntos p1
JOIN puntos p2
    ON p1.id < p2.id
ORDER BY p1.id, p2.id;

La condición p1.id < p2.id evita dos cosas:

  • comparar un punto consigo mismo;
  • repetir la misma comparación al revés.

Por ejemplo, si ya aparece Origen contra X+5, no necesitamos también X+5 contra Origen.


Paso 7. Crear los ejes del plano

Creamos una tabla para guardar líneas.

CREATE TABLE lineas (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(LineString)
);

Primero insertamos los ejes X e Y.

INSERT INTO lineas (descripcion, geom)
VALUES
    ('Eje X', ST_GeomFromText('LINESTRING(-15 0, 15 0)')),
    ('Eje Y', ST_GeomFromText('LINESTRING(0 -15, 0 15)'));

Los ejes se dibujan más largos que los puntos de referencia para que funcionen visualmente como ejes del plano, no como segmentos que terminan justo en -10 y 10.

Ver las líneas:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM lineas
ORDER BY id;

Cargar lineas en QGIS.

Crear una vista con el plano base:

CREATE OR REPLACE VIEW vista_plano_base AS
SELECT
    'Punto: ' || descripcion AS descripcion,
    geom::geometry AS geom
FROM puntos
WHERE descripcion IN (
    'Origen',
    'X-5', 'X-10', 'X+5', 'X+10',
    'Y-5', 'Y-10', 'Y+5', 'Y+10'
)
UNION ALL
SELECT
    descripcion,
    geom::geometry AS geom
FROM lineas
WHERE descripcion IN ('Eje X', 'Eje Y');

Esta vista junta los puntos de referencia iniciales y los dos ejes. Sirve para abrir el resultado en el visor geométrico o en QGIS y tener contexto visual.

SELECT
    descripcion,
    geom
FROM vista_plano_base;

Paso 8. Agregar una línea oblicua

Ahora agregamos una línea oblicua, como si fuera la gráfica de una función lineal sobre nuestro plano.

Antes de ejecutar:

Dibujá aproximadamente una recta que pase por (-3,-10) y (8,10). ¿Corta al eje X? ¿Corta al eje Y?

INSERT INTO lineas (descripcion, geom)
VALUES (
    'Oblicua',
    ST_GeomFromText('LINESTRING(-3 -10, 8 10)')
);

Volver a consultar:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM lineas
ORDER BY id;

Actualizar la capa lineas en QGIS o volver a cargarla para ver la nueva línea.


Paso 9. Inspeccionar líneas

SELECT
    descripcion,
    ST_Length(geom) AS longitud,
    ST_NumPoints(geom) AS cantidad_puntos,
    ST_AsText(ST_StartPoint(geom)) AS inicio,
    ST_AsText(ST_EndPoint(geom)) AS fin
FROM lineas
ORDER BY id;

ST_Length mide la línea. ST_StartPoint y ST_EndPoint devuelven geometrías.

Ver los vértices:

SELECT
    descripcion,
    ST_AsText(ST_PointN(geom, 1)) AS primer_punto,
    ST_AsText(ST_PointN(geom, 2)) AS segundo_punto
FROM lineas
ORDER BY id;

ST_PointN recupera el punto número N de una línea.


Paso 10. Preguntar relaciones entre líneas

Antes de ejecutar:

¿La línea oblicua corta al eje X?

SELECT ST_Intersects(l1.geom, l2.geom) AS se_intersectan
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Resultado esperado:

true

Probar todas las líneas contra todas:

SELECT
    l1.descripcion AS linea_1,
    l2.descripcion AS linea_2,
    ST_Intersects(l1.geom, l2.geom) AS intersects,
    ST_Disjoint(l1.geom, l2.geom) AS disjoint,
    ST_Touches(l1.geom, l2.geom) AS touches,
    ST_Crosses(l1.geom, l2.geom) AS crosses,
    ST_Equals(l1.geom, l2.geom) AS equals
FROM lineas l1
JOIN lineas l2
    ON l1.id < l2.id
ORDER BY l1.id, l2.id;

Estas funciones devuelven true o false.

Mini machete:

FunciónPregunta que responde
ST_Intersects¿Tienen algún punto en común?
ST_Disjoint¿No tienen ningún punto en común?
ST_Touches¿Se tocan en el borde, sin cruzarse por dentro?
ST_Crosses¿Una geometría cruza a la otra?
ST_Equals¿Representan exactamente la misma geometría?

Ojo: ST_Disjoint es lo contrario de ST_Intersects. Si una da true, la otra debería dar false.


Paso 11. Intersects no es Intersection

Primero preguntamos si se intersectan:

SELECT ST_Intersects(l1.geom, l2.geom) AS se_intersectan
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Eso devuelve un booleano.

Ahora preguntamos dónde se intersectan:

SELECT
    ST_AsText(ST_Intersection(l1.geom, l2.geom)) AS interseccion
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Resultado esperado:

POINT(2.5 0)

Para verlo con contexto, consultar el plano base junto con el punto de intersección:

SELECT
    descripcion,
    geom
FROM vista_plano_base
UNION ALL
SELECT
    'Intersección oblicua / eje X' AS descripcion,
    ST_Intersection(l1.geom, l2.geom)::geometry AS geom
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X'
UNION ALL
SELECT
	descripcion,
	geom
FROM lineas
WHERE descripcion = 'Oblicua';

En el visor geométrico ahora deberían verse:

  • los puntos de referencia;
  • los ejes X e Y;
  • la línea oblicua;
  • el punto de intersección POINT(2.5 0).

Ese punto debería aparecer exactamente sobre el eje X y también sobre la línea oblicua. La consulta usa UNION ALL para mostrar todas esas geometrías juntas sin perderlas como objetos separados.

FunciónDevuelve
ST_Intersectstrue / false
ST_Intersectionuna geometría

Esta diferencia es clave.


Paso 12. Crear buffers

Antes de ejecutar:

¿Qué forma esperás al hacer un buffer de 2 unidades alrededor del origen?

CREATE TABLE buffers (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(80),
    geom geometry
);
INSERT INTO buffers (descripcion, geom)
SELECT
    'Buffer de 2 unidades alrededor del origen',
    ST_Buffer(geom, 2)
FROM puntos
WHERE descripcion = 'Origen';

Ver el tipo de geometría generado:

SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo
FROM buffers;

ST_Buffer genera una nueva geometría.

Ahora un buffer alrededor del eje X:

INSERT INTO buffers (descripcion, geom)
SELECT
    'Buffer de 1 unidad alrededor del eje X',
    ST_Buffer(geom, 1)
FROM lineas
WHERE descripcion = 'Eje X';

Para visualizar las geometrías originales junto con sus buffers:

SELECT
    'Original: ' || descripcion AS descripcion,
    geom
FROM puntos
WHERE descripcion = 'Origen'
UNION ALL
SELECT
    'Original: ' || descripcion AS descripcion,
    geom
FROM lineas
WHERE descripcion = 'Eje X'
UNION ALL
SELECT
    descripcion,
    geom
FROM buffers
ORDER BY descripcion;

En el visor geométrico deberían verse el punto Origen, el Eje X y los dos buffers generados. La idea es comparar cada geometría original con la zona que produce ST_Buffer.

Cargar buffers en QGIS y usar transparencia para ver las capas anteriores.


Paso 13. Crear polígonos

CREATE TABLE poligonos (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(Polygon)
);

Dibujar tres polígonos:

INSERT INTO poligonos (descripcion, geom)
VALUES
    ('A', ST_GeomFromText('POLYGON((0 0, 6 0, 6 6, 0 6, 0 0))')),
    ('B', ST_GeomFromText('POLYGON((4 2, 10 2, 10 8, 4 8, 4 2))')),
    ('C', ST_GeomFromText('POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))'));

Verlos:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM poligonos
ORDER BY descripcion;

Cargar poligonos en QGIS con relleno transparente.


Paso 14. Relaciones entre polígonos

Antes de ejecutar:

¿A contiene a C?

SELECT ST_Contains(a.geom, c.geom) AS a_contiene_c
FROM poligonos a
JOIN poligonos c
    ON a.descripcion = 'A'
   AND c.descripcion = 'C';

Resultado esperado:

true

Ahora la relación inversa:

SELECT ST_Within(c.geom, a.geom) AS c_dentro_de_a
FROM poligonos c
JOIN poligonos a
    ON c.descripcion = 'C'
   AND a.descripcion = 'A';

Resultado esperado:

true

Ahora comparamos A contra B y A contra C en una sola consulta:

SELECT
    ST_Overlaps(a.geom, b.geom) AS a_b_se_superponen,
    ST_Intersects(a.geom, b.geom) AS a_b_se_intersectan,
    ST_Disjoint(a.geom, b.geom) AS a_b_son_disjuntos,
    ST_Overlaps(a.geom, c.geom) AS a_c_se_superponen,
    ST_Intersects(a.geom, c.geom) AS a_c_se_intersectan,
    ST_Contains(a.geom, c.geom) AS a_contiene_c
FROM poligonos a
JOIN poligonos b
    ON b.descripcion = 'B'
JOIN poligonos c
    ON c.descripcion = 'C'
WHERE a.descripcion = 'A';

Resultado esperado:

true | true | false | false | true | true

A y B se superponen parcialmente. A y C no se superponen parcialmente: C está completamente dentro de A.


Paso 15. Un caso para Touches

Agregamos un polígono D que toca a A por un borde.

INSERT INTO poligonos (descripcion, geom)
VALUES (
    'D',
    ST_GeomFromText('POLYGON((6 0, 9 0, 9 3, 6 3, 6 0))')
);

Antes de ejecutar:

¿D se superpone con A o sólo lo toca?

SELECT
    ST_Touches(a.geom, d.geom) AS toca,
    ST_Intersects(a.geom, d.geom) AS intersecta,
    ST_Overlaps(a.geom, d.geom) AS se_superpone
FROM poligonos a
JOIN poligonos d
    ON a.descripcion = 'A'
   AND d.descripcion = 'D';

Resultado esperado:

true | true | false

Ahora probamos D contra B:

SELECT
    ST_Touches(d.geom, b.geom) AS toca,
    ST_Intersects(d.geom, b.geom) AS intersecta,
    ST_Overlaps(d.geom, b.geom) AS se_superpone
FROM poligonos d
JOIN poligonos b
    ON d.descripcion = 'D'
   AND b.descripcion = 'B';

Resultado esperado:

false | true | true

D y B no sólo se tocan: comparten una región. Por eso ST_Overlaps da true.

Si dos geometrías se tocan, también se intersectan. Pero tocar no es lo mismo que superponerse.


Paso 16. Álgebra espacial

CREATE TABLE resultados_poligonales (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(80),
    geom geometry
);

Intersección entre A y B

Antes de ejecutar, sombrear la zona común entre A y B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Intersección entre A y B',
    ST_Intersection(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Intersección entre A y B';

Unión entre A y B

Antes de ejecutar, sombrear toda la región cubierta por A o por B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Unión entre A y B',
    ST_Union(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Unión entre A y B';

Diferencia A menos B

Antes de ejecutar, sombrear la parte de A que no está cubierta por B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Diferencia A menos B',
    ST_Difference(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Diferencia A menos B';

Cargar resultados_poligonales en QGIS y comparar con A y B.

Unión espacial del plano base

Antes usamos UNION ALL para mostrar varias geometrías juntas sin fusionarlas. Ahora usamos ST_Union para unir espacialmente todas las geometrías de vista_plano_base en una sola geometría.

SELECT
    'Plano base unido' AS descripcion,
    ST_Union(geom) AS geom
FROM vista_plano_base;

Ahora intersectamos la línea oblicua contra ese plano base unido y lo mostramos todo junto:

SELECT
    descripcion,
    geom
FROM vista_plano_base
UNION ALL
SELECT
    descripcion,
    geom
FROM lineas
WHERE descripcion = 'Oblicua'
UNION ALL
SELECT
    'Intersección oblicua / plano base unido' AS descripcion,
    ST_Intersection(l.geom, plano.geom)::geometry AS geom
FROM lineas l
CROSS JOIN (
    SELECT ST_Union(geom) AS geom
    FROM vista_plano_base
) plano
WHERE l.descripcion = 'Oblicua';

Resultado esperado: deberían verse el plano base, la oblicua y dos puntos de intersección, porque la oblicua corta al eje X y también al eje Y.

Para leerlos como texto:

SELECT
    ST_AsText(
        ST_Intersection(l.geom, plano.geom)
    ) AS interseccion
FROM lineas l
CROSS JOIN (
    SELECT ST_Union(geom) AS geom
    FROM vista_plano_base
) plano
WHERE l.descripcion = 'Oblicua';

La diferencia importante:

OperaciónQué hace
UNION ALLJunta filas en una consulta
ST_UnionUne geometrías espacialmente

Paso 17. Envolventes: Convex Hull y Envelope

Volvemos a los puntos.

Convex Hull

Antes de ejecutar:

¿Cuál sería el polígono convexo más chico que contiene todos los puntos?

SELECT
    ST_AsText(
        ST_ConvexHull(
            ST_Collect(geom)
        )
    ) AS convex_hull
FROM puntos;

ST_Collect agrupa los puntos. ST_ConvexHull calcula el polígono convexo que los envuelve.

Guardar el resultado:

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Convex hull de los puntos',
    ST_ConvexHull(ST_Collect(geom))
FROM puntos;

Verlo en QGIS.


Envelope

ST_Envelope devuelve el rectángulo mínimo alineado a los ejes que contiene una geometría.

Antes de ejecutar:

Si los puntos llegan hasta -10 y 10 en los ejes, ¿qué rectángulo esperás obtener?

SELECT
    ST_AsText(
        ST_Envelope(
            ST_Collect(geom)
        )
    ) AS envelope
FROM puntos;

Guardar el resultado:

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Envelope de los puntos',
    ST_Envelope(ST_Collect(geom))
FROM puntos;

Ver juntos Convex hull y Envelope:

SELECT
    descripcion,
    geom
FROM resultados_poligonales
WHERE descripcion IN (
    'Convex hull de los puntos',
    'Envelope de los puntos'
);

El Convex Hull se ajusta a la forma convexa más chica. El Envelope siempre devuelve un rectángulo alineado a los ejes.


Paso 18. LINESTRING y MULTILINESTRING

Una línea puede tener muchos vértices y seguir siendo una sola LINESTRING.

INSERT INTO lineas (descripcion, geom)
VALUES (
    'Línea con varios vértices',
    ST_GeomFromText(
        'LINESTRING(1 1, 2 5, 3 4, 4 8, 5 9, 6 3, 7 5, 8 7, 9 6, 10 10)'
    )
);
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_NumPoints(geom) AS vertices,
    ST_AsText(geom) AS wkt
FROM lineas
WHERE descripcion = 'Línea con varios vértices';

Aunque tenga muchos puntos, sigue siendo una única línea.

Ahora creamos una geometría múltiple:

CREATE TABLE multilines (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(MultiLineString)
);
INSERT INTO multilines (descripcion, geom)
VALUES (
    'Dos líneas independientes',
    ST_GeomFromText('MULTILINESTRING((0 0, 5 5), (0 5, 5 0))')
);
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_AsText(geom) AS wkt
FROM multilines;

MULTILINESTRING contiene varias líneas independientes.


Fin

Apunte

BD Geometrica

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Parcial 1 Preguntas Desarrollo Posibles Repaso

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Machete para SGBDA

DocumentoOtro

Archivo de Drive

Abrir en Drive
Vista previa de Archivo de DriveAbrir archivo

Apunte

Resumen para el parcial 1

Documento

Archivo de Drive

Abrir en Drive
Vista previa de Archivo de DriveAbrir archivo

Apunte

Apunte Distribuidas Alternativo Mejorado

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Apunte BD Distribuidas

Interactivo

By ChatGPT 5.5 High

Abrir apunte

Apunte interactivo

By ChatGPT 5.5 High

Tocá para abrir la vista previa.

Apariencia alternativa

Abrir apunte

Apunte interactivo

Apariencia alternativa

Tocá para abrir la vista previa.

Apunte

Apunte Bases Temporales

DocumentoInteractivo

by Claude Fable 5

Abrir apunte

Apunte interactivo

by Claude Fable 5

Tocá para abrir la vista previa.

Apunte

Que es un trigger, y lenguaje PLPGSQL

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Ya viste todos los apuntes disponibles.

Bases de Datos AvanzadasCuarto año
Campus VirtualFCYT - UADER
Cuarto año
CARRERALicenciatura en Sistemas de Información
AÑOS ACADÉMICOS
  • 1
    Primer año7 materias
  • 2
    Segundo año7 materias
  • 3
    Tercer año9 materias
  • 4
    Cuarto año8 materias
  • 5
    Quinto año6 materias
AdministraciónTu cuentaConfigurarPreferencias
Mapa de correlativasRecorrido interactivo
FCYT · UADERv alpha

Materia

Bases de Datos Avanzadas

  • Cuarto añoVolver al año
  • Calendario5 eventos
Licenciatura en Sistemas de Información/Cuarto año/Bases de Datos Avanzadas
Cuarto año

Bases de Datos Avanzadas

Link meet de teoria: https://meet.google.com/auc-jmas-veo
Link meet de practica: https://meet.google.com/wcm-echz-byj

Drive con contenido de la materiaMeet TeoriaMeet Practica
Cuarto año

Bases de Datos Avanzadas

Link meet de teoria: https://meet.google.com/auc-jmas-veo
Link meet de practica: https://meet.google.com/wcm-echz-byj

Drive con contenido de la materiaMeet TeoriaMeet Practica
Eventos5
Apuntes11

Agenda

Calendario de eventos

Seleccionar comisión:

Fechas, entregas y avisos importantes de la materia en un solo lugar.

No hay eventos próximos para mostrar

MES

Noviembre 2026
D
L
M
M
J
V
S
ExamenTrabajo PrácticoExposiciónSuspensión de clasesMesas de examen

Todos los eventos · Noviembre

vie6nov
ExamenRecuperatorio BDABases de Datos Avanzadas

Modo estudio

Poné a prueba lo que sabés

Quiz de Bases de Datos Avanzadas

Elegí uno o varios bancos de preguntas y practicá en modo práctica (con explicaciones) o examen.

Empezar quiz

Quiz de Bases de Datos Avanzadas

Practicá con bancos de preguntas en modo práctica (con explicaciones) o examen.

Empezar quiz

Recursos

Apuntes y descargas

Apunte

Repaso Parcial 2 Consultas Espaciales

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

BD Geográficas

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Guia BD Geograficas postgis

Otro

Guía práctica de PostGIS

Vamos a trabajar en un plano cartesiano artificial, con coordenadas simples. No son coordenadas reales, no son latitud/longitud y no vamos a usar SRID 4326. La idea es dibujar lo que creemos que va a pasar, ejecutar SQL, mirar el resultado y, cuando convenga, verlo en QGIS.


Paso 1. Crear la base y activar PostGIS

Crear una base para la práctica:

CREATE DATABASE bdg_practica;

Conectarse a esa base y activar PostGIS:

CREATE EXTENSION postgis;

Comprobar que está disponible:

SELECT PostGIS_Version();

PostGIS agrega tipos de datos espaciales y funciones para trabajar con geometrías dentro de PostgreSQL.


Paso 2. Crear la primera tabla

CREATE TABLE puntos (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(Point)
);

La columna geom guarda geometrías. En esta tabla sólo vamos a guardar puntos.


Paso 3. Insertar el primer punto

Insertamos el origen:

INSERT INTO puntos (descripcion, geom)
VALUES (
    'Origen',
    ST_GeomFromText('POINT(0 0)')
);

ST_GeomFromText crea una geometría a partir de WKT.

Consultar la tabla:

SELECT *
FROM puntos;

Ver la geometría en formato legible:

SELECT
    id,
    descripcion,
    ST_AsText(geom) AS wkt
FROM puntos;

Resultado esperado:

1 | Origen | POINT(0 0)

ST_AsText muestra la geometría como texto WKT.


Paso 4. Inspeccionar el punto

Antes de ejecutar:

¿Qué dimensión tiene un punto?

SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_Dimension(geom) AS dimension,
    ST_IsEmpty(geom) AS esta_vacia,
    ST_X(geom) AS x,
    ST_Y(geom) AS y
FROM puntos
WHERE descripcion = 'Origen';

Resultado esperado:

Origen | ST_Point | 0 | false | 0 | 0

Un punto tiene dimensión 0. ST_X y ST_Y devuelven sus coordenadas.


Paso 5. Cargar puntos de referencia

Vamos a armar este plano:

              Y+10
               |
              Y+5
               |
X-10 -- X-5 -- Origen -- X+5 -- X+10
               |
              Y-5
               |
              Y-10

Insertar los puntos:

INSERT INTO puntos (descripcion, geom)
VALUES
    ('X-5',  ST_GeomFromText('POINT(-5 0)')),
    ('X-10', ST_GeomFromText('POINT(-10 0)')),
    ('X+5',  ST_GeomFromText('POINT(5 0)')),
    ('X+10', ST_GeomFromText('POINT(10 0)')),
    ('Y-5',  ST_GeomFromText('POINT(0 -5)')),
    ('Y-10', ST_GeomFromText('POINT(0 -10)')),
    ('Y+5',  ST_GeomFromText('POINT(0 5)')),
    ('Y+10', ST_GeomFromText('POINT(0 10)'));

Ver los puntos:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM puntos
ORDER BY id;

Abrir QGIS, cargar la tabla puntos, activar etiquetas con descripcion y hacer zoom a la capa.


Paso 6. Medir distancias

Antes de ejecutar:

¿Cuánto vale la distancia entre (0,0) y (5,0)?

SELECT ST_Distance(
    ST_GeomFromText('POINT(0 0)'),
    ST_GeomFromText('POINT(5 0)')
) AS distancia;

Resultado esperado:

5

Ahora una diagonal:

SELECT ST_Distance(
    ST_GeomFromText('POINT(0 0)'),
    ST_GeomFromText('POINT(5 5)')
) AS distancia;

Resultado esperado aproximado:

7.0710678118654755

En este plano las unidades son unidades abstractas. Todavía no son metros ni grados.

Medir la distancia desde cada punto hasta (15,15):

SELECT
    descripcion,
    ST_AsText(geom) AS punto,
    ST_Distance(
        geom,
        ST_GeomFromText('POINT(15 15)')
    ) AS distancia
FROM puntos
ORDER BY distancia;

Antes de mirar el resultado, pensar cuál debería quedar más cerca.

Ahora medir la distancia de cada punto con cada uno de los otros puntos:

SELECT
    p1.descripcion AS punto_1,
    ST_AsText(p1.geom) AS geom_1,
    p2.descripcion AS punto_2,
    ST_AsText(p2.geom) AS geom_2,
    ST_Distance(p1.geom, p2.geom) AS distancia
FROM puntos p1
JOIN puntos p2
    ON p1.id < p2.id
ORDER BY p1.id, p2.id;

La condición p1.id < p2.id evita dos cosas:

  • comparar un punto consigo mismo;
  • repetir la misma comparación al revés.

Por ejemplo, si ya aparece Origen contra X+5, no necesitamos también X+5 contra Origen.


Paso 7. Crear los ejes del plano

Creamos una tabla para guardar líneas.

CREATE TABLE lineas (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(LineString)
);

Primero insertamos los ejes X e Y.

INSERT INTO lineas (descripcion, geom)
VALUES
    ('Eje X', ST_GeomFromText('LINESTRING(-15 0, 15 0)')),
    ('Eje Y', ST_GeomFromText('LINESTRING(0 -15, 0 15)'));

Los ejes se dibujan más largos que los puntos de referencia para que funcionen visualmente como ejes del plano, no como segmentos que terminan justo en -10 y 10.

Ver las líneas:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM lineas
ORDER BY id;

Cargar lineas en QGIS.

Crear una vista con el plano base:

CREATE OR REPLACE VIEW vista_plano_base AS
SELECT
    'Punto: ' || descripcion AS descripcion,
    geom::geometry AS geom
FROM puntos
WHERE descripcion IN (
    'Origen',
    'X-5', 'X-10', 'X+5', 'X+10',
    'Y-5', 'Y-10', 'Y+5', 'Y+10'
)
UNION ALL
SELECT
    descripcion,
    geom::geometry AS geom
FROM lineas
WHERE descripcion IN ('Eje X', 'Eje Y');

Esta vista junta los puntos de referencia iniciales y los dos ejes. Sirve para abrir el resultado en el visor geométrico o en QGIS y tener contexto visual.

SELECT
    descripcion,
    geom
FROM vista_plano_base;

Paso 8. Agregar una línea oblicua

Ahora agregamos una línea oblicua, como si fuera la gráfica de una función lineal sobre nuestro plano.

Antes de ejecutar:

Dibujá aproximadamente una recta que pase por (-3,-10) y (8,10). ¿Corta al eje X? ¿Corta al eje Y?

INSERT INTO lineas (descripcion, geom)
VALUES (
    'Oblicua',
    ST_GeomFromText('LINESTRING(-3 -10, 8 10)')
);

Volver a consultar:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM lineas
ORDER BY id;

Actualizar la capa lineas en QGIS o volver a cargarla para ver la nueva línea.


Paso 9. Inspeccionar líneas

SELECT
    descripcion,
    ST_Length(geom) AS longitud,
    ST_NumPoints(geom) AS cantidad_puntos,
    ST_AsText(ST_StartPoint(geom)) AS inicio,
    ST_AsText(ST_EndPoint(geom)) AS fin
FROM lineas
ORDER BY id;

ST_Length mide la línea. ST_StartPoint y ST_EndPoint devuelven geometrías.

Ver los vértices:

SELECT
    descripcion,
    ST_AsText(ST_PointN(geom, 1)) AS primer_punto,
    ST_AsText(ST_PointN(geom, 2)) AS segundo_punto
FROM lineas
ORDER BY id;

ST_PointN recupera el punto número N de una línea.


Paso 10. Preguntar relaciones entre líneas

Antes de ejecutar:

¿La línea oblicua corta al eje X?

SELECT ST_Intersects(l1.geom, l2.geom) AS se_intersectan
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Resultado esperado:

true

Probar todas las líneas contra todas:

SELECT
    l1.descripcion AS linea_1,
    l2.descripcion AS linea_2,
    ST_Intersects(l1.geom, l2.geom) AS intersects,
    ST_Disjoint(l1.geom, l2.geom) AS disjoint,
    ST_Touches(l1.geom, l2.geom) AS touches,
    ST_Crosses(l1.geom, l2.geom) AS crosses,
    ST_Equals(l1.geom, l2.geom) AS equals
FROM lineas l1
JOIN lineas l2
    ON l1.id < l2.id
ORDER BY l1.id, l2.id;

Estas funciones devuelven true o false.

Mini machete:

FunciónPregunta que responde
ST_Intersects¿Tienen algún punto en común?
ST_Disjoint¿No tienen ningún punto en común?
ST_Touches¿Se tocan en el borde, sin cruzarse por dentro?
ST_Crosses¿Una geometría cruza a la otra?
ST_Equals¿Representan exactamente la misma geometría?

Ojo: ST_Disjoint es lo contrario de ST_Intersects. Si una da true, la otra debería dar false.


Paso 11. Intersects no es Intersection

Primero preguntamos si se intersectan:

SELECT ST_Intersects(l1.geom, l2.geom) AS se_intersectan
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Eso devuelve un booleano.

Ahora preguntamos dónde se intersectan:

SELECT
    ST_AsText(ST_Intersection(l1.geom, l2.geom)) AS interseccion
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Resultado esperado:

POINT(2.5 0)

Para verlo con contexto, consultar el plano base junto con el punto de intersección:

SELECT
    descripcion,
    geom
FROM vista_plano_base
UNION ALL
SELECT
    'Intersección oblicua / eje X' AS descripcion,
    ST_Intersection(l1.geom, l2.geom)::geometry AS geom
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X'
UNION ALL
SELECT
	descripcion,
	geom
FROM lineas
WHERE descripcion = 'Oblicua';

En el visor geométrico ahora deberían verse:

  • los puntos de referencia;
  • los ejes X e Y;
  • la línea oblicua;
  • el punto de intersección POINT(2.5 0).

Ese punto debería aparecer exactamente sobre el eje X y también sobre la línea oblicua. La consulta usa UNION ALL para mostrar todas esas geometrías juntas sin perderlas como objetos separados.

FunciónDevuelve
ST_Intersectstrue / false
ST_Intersectionuna geometría

Esta diferencia es clave.


Paso 12. Crear buffers

Antes de ejecutar:

¿Qué forma esperás al hacer un buffer de 2 unidades alrededor del origen?

CREATE TABLE buffers (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(80),
    geom geometry
);
INSERT INTO buffers (descripcion, geom)
SELECT
    'Buffer de 2 unidades alrededor del origen',
    ST_Buffer(geom, 2)
FROM puntos
WHERE descripcion = 'Origen';

Ver el tipo de geometría generado:

SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo
FROM buffers;

ST_Buffer genera una nueva geometría.

Ahora un buffer alrededor del eje X:

INSERT INTO buffers (descripcion, geom)
SELECT
    'Buffer de 1 unidad alrededor del eje X',
    ST_Buffer(geom, 1)
FROM lineas
WHERE descripcion = 'Eje X';

Para visualizar las geometrías originales junto con sus buffers:

SELECT
    'Original: ' || descripcion AS descripcion,
    geom
FROM puntos
WHERE descripcion = 'Origen'
UNION ALL
SELECT
    'Original: ' || descripcion AS descripcion,
    geom
FROM lineas
WHERE descripcion = 'Eje X'
UNION ALL
SELECT
    descripcion,
    geom
FROM buffers
ORDER BY descripcion;

En el visor geométrico deberían verse el punto Origen, el Eje X y los dos buffers generados. La idea es comparar cada geometría original con la zona que produce ST_Buffer.

Cargar buffers en QGIS y usar transparencia para ver las capas anteriores.


Paso 13. Crear polígonos

CREATE TABLE poligonos (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(Polygon)
);

Dibujar tres polígonos:

INSERT INTO poligonos (descripcion, geom)
VALUES
    ('A', ST_GeomFromText('POLYGON((0 0, 6 0, 6 6, 0 6, 0 0))')),
    ('B', ST_GeomFromText('POLYGON((4 2, 10 2, 10 8, 4 8, 4 2))')),
    ('C', ST_GeomFromText('POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))'));

Verlos:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM poligonos
ORDER BY descripcion;

Cargar poligonos en QGIS con relleno transparente.


Paso 14. Relaciones entre polígonos

Antes de ejecutar:

¿A contiene a C?

SELECT ST_Contains(a.geom, c.geom) AS a_contiene_c
FROM poligonos a
JOIN poligonos c
    ON a.descripcion = 'A'
   AND c.descripcion = 'C';

Resultado esperado:

true

Ahora la relación inversa:

SELECT ST_Within(c.geom, a.geom) AS c_dentro_de_a
FROM poligonos c
JOIN poligonos a
    ON c.descripcion = 'C'
   AND a.descripcion = 'A';

Resultado esperado:

true

Ahora comparamos A contra B y A contra C en una sola consulta:

SELECT
    ST_Overlaps(a.geom, b.geom) AS a_b_se_superponen,
    ST_Intersects(a.geom, b.geom) AS a_b_se_intersectan,
    ST_Disjoint(a.geom, b.geom) AS a_b_son_disjuntos,
    ST_Overlaps(a.geom, c.geom) AS a_c_se_superponen,
    ST_Intersects(a.geom, c.geom) AS a_c_se_intersectan,
    ST_Contains(a.geom, c.geom) AS a_contiene_c
FROM poligonos a
JOIN poligonos b
    ON b.descripcion = 'B'
JOIN poligonos c
    ON c.descripcion = 'C'
WHERE a.descripcion = 'A';

Resultado esperado:

true | true | false | false | true | true

A y B se superponen parcialmente. A y C no se superponen parcialmente: C está completamente dentro de A.


Paso 15. Un caso para Touches

Agregamos un polígono D que toca a A por un borde.

INSERT INTO poligonos (descripcion, geom)
VALUES (
    'D',
    ST_GeomFromText('POLYGON((6 0, 9 0, 9 3, 6 3, 6 0))')
);

Antes de ejecutar:

¿D se superpone con A o sólo lo toca?

SELECT
    ST_Touches(a.geom, d.geom) AS toca,
    ST_Intersects(a.geom, d.geom) AS intersecta,
    ST_Overlaps(a.geom, d.geom) AS se_superpone
FROM poligonos a
JOIN poligonos d
    ON a.descripcion = 'A'
   AND d.descripcion = 'D';

Resultado esperado:

true | true | false

Ahora probamos D contra B:

SELECT
    ST_Touches(d.geom, b.geom) AS toca,
    ST_Intersects(d.geom, b.geom) AS intersecta,
    ST_Overlaps(d.geom, b.geom) AS se_superpone
FROM poligonos d
JOIN poligonos b
    ON d.descripcion = 'D'
   AND b.descripcion = 'B';

Resultado esperado:

false | true | true

D y B no sólo se tocan: comparten una región. Por eso ST_Overlaps da true.

Si dos geometrías se tocan, también se intersectan. Pero tocar no es lo mismo que superponerse.


Paso 16. Álgebra espacial

CREATE TABLE resultados_poligonales (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(80),
    geom geometry
);

Intersección entre A y B

Antes de ejecutar, sombrear la zona común entre A y B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Intersección entre A y B',
    ST_Intersection(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Intersección entre A y B';

Unión entre A y B

Antes de ejecutar, sombrear toda la región cubierta por A o por B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Unión entre A y B',
    ST_Union(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Unión entre A y B';

Diferencia A menos B

Antes de ejecutar, sombrear la parte de A que no está cubierta por B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Diferencia A menos B',
    ST_Difference(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Diferencia A menos B';

Cargar resultados_poligonales en QGIS y comparar con A y B.

Unión espacial del plano base

Antes usamos UNION ALL para mostrar varias geometrías juntas sin fusionarlas. Ahora usamos ST_Union para unir espacialmente todas las geometrías de vista_plano_base en una sola geometría.

SELECT
    'Plano base unido' AS descripcion,
    ST_Union(geom) AS geom
FROM vista_plano_base;

Ahora intersectamos la línea oblicua contra ese plano base unido y lo mostramos todo junto:

SELECT
    descripcion,
    geom
FROM vista_plano_base
UNION ALL
SELECT
    descripcion,
    geom
FROM lineas
WHERE descripcion = 'Oblicua'
UNION ALL
SELECT
    'Intersección oblicua / plano base unido' AS descripcion,
    ST_Intersection(l.geom, plano.geom)::geometry AS geom
FROM lineas l
CROSS JOIN (
    SELECT ST_Union(geom) AS geom
    FROM vista_plano_base
) plano
WHERE l.descripcion = 'Oblicua';

Resultado esperado: deberían verse el plano base, la oblicua y dos puntos de intersección, porque la oblicua corta al eje X y también al eje Y.

Para leerlos como texto:

SELECT
    ST_AsText(
        ST_Intersection(l.geom, plano.geom)
    ) AS interseccion
FROM lineas l
CROSS JOIN (
    SELECT ST_Union(geom) AS geom
    FROM vista_plano_base
) plano
WHERE l.descripcion = 'Oblicua';

La diferencia importante:

OperaciónQué hace
UNION ALLJunta filas en una consulta
ST_UnionUne geometrías espacialmente

Paso 17. Envolventes: Convex Hull y Envelope

Volvemos a los puntos.

Convex Hull

Antes de ejecutar:

¿Cuál sería el polígono convexo más chico que contiene todos los puntos?

SELECT
    ST_AsText(
        ST_ConvexHull(
            ST_Collect(geom)
        )
    ) AS convex_hull
FROM puntos;

ST_Collect agrupa los puntos. ST_ConvexHull calcula el polígono convexo que los envuelve.

Guardar el resultado:

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Convex hull de los puntos',
    ST_ConvexHull(ST_Collect(geom))
FROM puntos;

Verlo en QGIS.


Envelope

ST_Envelope devuelve el rectángulo mínimo alineado a los ejes que contiene una geometría.

Antes de ejecutar:

Si los puntos llegan hasta -10 y 10 en los ejes, ¿qué rectángulo esperás obtener?

SELECT
    ST_AsText(
        ST_Envelope(
            ST_Collect(geom)
        )
    ) AS envelope
FROM puntos;

Guardar el resultado:

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Envelope de los puntos',
    ST_Envelope(ST_Collect(geom))
FROM puntos;

Ver juntos Convex hull y Envelope:

SELECT
    descripcion,
    geom
FROM resultados_poligonales
WHERE descripcion IN (
    'Convex hull de los puntos',
    'Envelope de los puntos'
);

El Convex Hull se ajusta a la forma convexa más chica. El Envelope siempre devuelve un rectángulo alineado a los ejes.


Paso 18. LINESTRING y MULTILINESTRING

Una línea puede tener muchos vértices y seguir siendo una sola LINESTRING.

INSERT INTO lineas (descripcion, geom)
VALUES (
    'Línea con varios vértices',
    ST_GeomFromText(
        'LINESTRING(1 1, 2 5, 3 4, 4 8, 5 9, 6 3, 7 5, 8 7, 9 6, 10 10)'
    )
);
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_NumPoints(geom) AS vertices,
    ST_AsText(geom) AS wkt
FROM lineas
WHERE descripcion = 'Línea con varios vértices';

Aunque tenga muchos puntos, sigue siendo una única línea.

Ahora creamos una geometría múltiple:

CREATE TABLE multilines (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(MultiLineString)
);
INSERT INTO multilines (descripcion, geom)
VALUES (
    'Dos líneas independientes',
    ST_GeomFromText('MULTILINESTRING((0 0, 5 5), (0 5, 5 0))')
);
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_AsText(geom) AS wkt
FROM multilines;

MULTILINESTRING contiene varias líneas independientes.


Fin

Apunte

BD Geometrica

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Parcial 1 Preguntas Desarrollo Posibles Repaso

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Machete para SGBDA

DocumentoOtro

Archivo de Drive

Abrir en Drive
Vista previa de Archivo de DriveAbrir archivo

Apunte

Resumen para el parcial 1

Documento

Archivo de Drive

Abrir en Drive
Vista previa de Archivo de DriveAbrir archivo

Apunte

Apunte Distribuidas Alternativo Mejorado

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Apunte BD Distribuidas

Interactivo

By ChatGPT 5.5 High

Abrir apunte

Apunte interactivo

By ChatGPT 5.5 High

Tocá para abrir la vista previa.

Apariencia alternativa

Abrir apunte

Apunte interactivo

Apariencia alternativa

Tocá para abrir la vista previa.

Apunte

Apunte Bases Temporales

DocumentoInteractivo

by Claude Fable 5

Abrir apunte

Apunte interactivo

by Claude Fable 5

Tocá para abrir la vista previa.

Apunte

Que es un trigger, y lenguaje PLPGSQL

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Repaso Parcial 2 Consultas Espaciales

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

BD Geográficas

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Guia BD Geograficas postgis

Otro

Guía práctica de PostGIS

Vamos a trabajar en un plano cartesiano artificial, con coordenadas simples. No son coordenadas reales, no son latitud/longitud y no vamos a usar SRID 4326. La idea es dibujar lo que creemos que va a pasar, ejecutar SQL, mirar el resultado y, cuando convenga, verlo en QGIS.


Paso 1. Crear la base y activar PostGIS

Crear una base para la práctica:

CREATE DATABASE bdg_practica;

Conectarse a esa base y activar PostGIS:

CREATE EXTENSION postgis;

Comprobar que está disponible:

SELECT PostGIS_Version();

PostGIS agrega tipos de datos espaciales y funciones para trabajar con geometrías dentro de PostgreSQL.


Paso 2. Crear la primera tabla

CREATE TABLE puntos (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(Point)
);

La columna geom guarda geometrías. En esta tabla sólo vamos a guardar puntos.


Paso 3. Insertar el primer punto

Insertamos el origen:

INSERT INTO puntos (descripcion, geom)
VALUES (
    'Origen',
    ST_GeomFromText('POINT(0 0)')
);

ST_GeomFromText crea una geometría a partir de WKT.

Consultar la tabla:

SELECT *
FROM puntos;

Ver la geometría en formato legible:

SELECT
    id,
    descripcion,
    ST_AsText(geom) AS wkt
FROM puntos;

Resultado esperado:

1 | Origen | POINT(0 0)

ST_AsText muestra la geometría como texto WKT.


Paso 4. Inspeccionar el punto

Antes de ejecutar:

¿Qué dimensión tiene un punto?

SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_Dimension(geom) AS dimension,
    ST_IsEmpty(geom) AS esta_vacia,
    ST_X(geom) AS x,
    ST_Y(geom) AS y
FROM puntos
WHERE descripcion = 'Origen';

Resultado esperado:

Origen | ST_Point | 0 | false | 0 | 0

Un punto tiene dimensión 0. ST_X y ST_Y devuelven sus coordenadas.


Paso 5. Cargar puntos de referencia

Vamos a armar este plano:

              Y+10
               |
              Y+5
               |
X-10 -- X-5 -- Origen -- X+5 -- X+10
               |
              Y-5
               |
              Y-10

Insertar los puntos:

INSERT INTO puntos (descripcion, geom)
VALUES
    ('X-5',  ST_GeomFromText('POINT(-5 0)')),
    ('X-10', ST_GeomFromText('POINT(-10 0)')),
    ('X+5',  ST_GeomFromText('POINT(5 0)')),
    ('X+10', ST_GeomFromText('POINT(10 0)')),
    ('Y-5',  ST_GeomFromText('POINT(0 -5)')),
    ('Y-10', ST_GeomFromText('POINT(0 -10)')),
    ('Y+5',  ST_GeomFromText('POINT(0 5)')),
    ('Y+10', ST_GeomFromText('POINT(0 10)'));

Ver los puntos:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM puntos
ORDER BY id;

Abrir QGIS, cargar la tabla puntos, activar etiquetas con descripcion y hacer zoom a la capa.


Paso 6. Medir distancias

Antes de ejecutar:

¿Cuánto vale la distancia entre (0,0) y (5,0)?

SELECT ST_Distance(
    ST_GeomFromText('POINT(0 0)'),
    ST_GeomFromText('POINT(5 0)')
) AS distancia;

Resultado esperado:

5

Ahora una diagonal:

SELECT ST_Distance(
    ST_GeomFromText('POINT(0 0)'),
    ST_GeomFromText('POINT(5 5)')
) AS distancia;

Resultado esperado aproximado:

7.0710678118654755

En este plano las unidades son unidades abstractas. Todavía no son metros ni grados.

Medir la distancia desde cada punto hasta (15,15):

SELECT
    descripcion,
    ST_AsText(geom) AS punto,
    ST_Distance(
        geom,
        ST_GeomFromText('POINT(15 15)')
    ) AS distancia
FROM puntos
ORDER BY distancia;

Antes de mirar el resultado, pensar cuál debería quedar más cerca.

Ahora medir la distancia de cada punto con cada uno de los otros puntos:

SELECT
    p1.descripcion AS punto_1,
    ST_AsText(p1.geom) AS geom_1,
    p2.descripcion AS punto_2,
    ST_AsText(p2.geom) AS geom_2,
    ST_Distance(p1.geom, p2.geom) AS distancia
FROM puntos p1
JOIN puntos p2
    ON p1.id < p2.id
ORDER BY p1.id, p2.id;

La condición p1.id < p2.id evita dos cosas:

  • comparar un punto consigo mismo;
  • repetir la misma comparación al revés.

Por ejemplo, si ya aparece Origen contra X+5, no necesitamos también X+5 contra Origen.


Paso 7. Crear los ejes del plano

Creamos una tabla para guardar líneas.

CREATE TABLE lineas (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(LineString)
);

Primero insertamos los ejes X e Y.

INSERT INTO lineas (descripcion, geom)
VALUES
    ('Eje X', ST_GeomFromText('LINESTRING(-15 0, 15 0)')),
    ('Eje Y', ST_GeomFromText('LINESTRING(0 -15, 0 15)'));

Los ejes se dibujan más largos que los puntos de referencia para que funcionen visualmente como ejes del plano, no como segmentos que terminan justo en -10 y 10.

Ver las líneas:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM lineas
ORDER BY id;

Cargar lineas en QGIS.

Crear una vista con el plano base:

CREATE OR REPLACE VIEW vista_plano_base AS
SELECT
    'Punto: ' || descripcion AS descripcion,
    geom::geometry AS geom
FROM puntos
WHERE descripcion IN (
    'Origen',
    'X-5', 'X-10', 'X+5', 'X+10',
    'Y-5', 'Y-10', 'Y+5', 'Y+10'
)
UNION ALL
SELECT
    descripcion,
    geom::geometry AS geom
FROM lineas
WHERE descripcion IN ('Eje X', 'Eje Y');

Esta vista junta los puntos de referencia iniciales y los dos ejes. Sirve para abrir el resultado en el visor geométrico o en QGIS y tener contexto visual.

SELECT
    descripcion,
    geom
FROM vista_plano_base;

Paso 8. Agregar una línea oblicua

Ahora agregamos una línea oblicua, como si fuera la gráfica de una función lineal sobre nuestro plano.

Antes de ejecutar:

Dibujá aproximadamente una recta que pase por (-3,-10) y (8,10). ¿Corta al eje X? ¿Corta al eje Y?

INSERT INTO lineas (descripcion, geom)
VALUES (
    'Oblicua',
    ST_GeomFromText('LINESTRING(-3 -10, 8 10)')
);

Volver a consultar:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM lineas
ORDER BY id;

Actualizar la capa lineas en QGIS o volver a cargarla para ver la nueva línea.


Paso 9. Inspeccionar líneas

SELECT
    descripcion,
    ST_Length(geom) AS longitud,
    ST_NumPoints(geom) AS cantidad_puntos,
    ST_AsText(ST_StartPoint(geom)) AS inicio,
    ST_AsText(ST_EndPoint(geom)) AS fin
FROM lineas
ORDER BY id;

ST_Length mide la línea. ST_StartPoint y ST_EndPoint devuelven geometrías.

Ver los vértices:

SELECT
    descripcion,
    ST_AsText(ST_PointN(geom, 1)) AS primer_punto,
    ST_AsText(ST_PointN(geom, 2)) AS segundo_punto
FROM lineas
ORDER BY id;

ST_PointN recupera el punto número N de una línea.


Paso 10. Preguntar relaciones entre líneas

Antes de ejecutar:

¿La línea oblicua corta al eje X?

SELECT ST_Intersects(l1.geom, l2.geom) AS se_intersectan
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Resultado esperado:

true

Probar todas las líneas contra todas:

SELECT
    l1.descripcion AS linea_1,
    l2.descripcion AS linea_2,
    ST_Intersects(l1.geom, l2.geom) AS intersects,
    ST_Disjoint(l1.geom, l2.geom) AS disjoint,
    ST_Touches(l1.geom, l2.geom) AS touches,
    ST_Crosses(l1.geom, l2.geom) AS crosses,
    ST_Equals(l1.geom, l2.geom) AS equals
FROM lineas l1
JOIN lineas l2
    ON l1.id < l2.id
ORDER BY l1.id, l2.id;

Estas funciones devuelven true o false.

Mini machete:

FunciónPregunta que responde
ST_Intersects¿Tienen algún punto en común?
ST_Disjoint¿No tienen ningún punto en común?
ST_Touches¿Se tocan en el borde, sin cruzarse por dentro?
ST_Crosses¿Una geometría cruza a la otra?
ST_Equals¿Representan exactamente la misma geometría?

Ojo: ST_Disjoint es lo contrario de ST_Intersects. Si una da true, la otra debería dar false.


Paso 11. Intersects no es Intersection

Primero preguntamos si se intersectan:

SELECT ST_Intersects(l1.geom, l2.geom) AS se_intersectan
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Eso devuelve un booleano.

Ahora preguntamos dónde se intersectan:

SELECT
    ST_AsText(ST_Intersection(l1.geom, l2.geom)) AS interseccion
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X';

Resultado esperado:

POINT(2.5 0)

Para verlo con contexto, consultar el plano base junto con el punto de intersección:

SELECT
    descripcion,
    geom
FROM vista_plano_base
UNION ALL
SELECT
    'Intersección oblicua / eje X' AS descripcion,
    ST_Intersection(l1.geom, l2.geom)::geometry AS geom
FROM lineas l1
JOIN lineas l2
    ON l1.descripcion = 'Oblicua'
   AND l2.descripcion = 'Eje X'
UNION ALL
SELECT
	descripcion,
	geom
FROM lineas
WHERE descripcion = 'Oblicua';

En el visor geométrico ahora deberían verse:

  • los puntos de referencia;
  • los ejes X e Y;
  • la línea oblicua;
  • el punto de intersección POINT(2.5 0).

Ese punto debería aparecer exactamente sobre el eje X y también sobre la línea oblicua. La consulta usa UNION ALL para mostrar todas esas geometrías juntas sin perderlas como objetos separados.

FunciónDevuelve
ST_Intersectstrue / false
ST_Intersectionuna geometría

Esta diferencia es clave.


Paso 12. Crear buffers

Antes de ejecutar:

¿Qué forma esperás al hacer un buffer de 2 unidades alrededor del origen?

CREATE TABLE buffers (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(80),
    geom geometry
);
INSERT INTO buffers (descripcion, geom)
SELECT
    'Buffer de 2 unidades alrededor del origen',
    ST_Buffer(geom, 2)
FROM puntos
WHERE descripcion = 'Origen';

Ver el tipo de geometría generado:

SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo
FROM buffers;

ST_Buffer genera una nueva geometría.

Ahora un buffer alrededor del eje X:

INSERT INTO buffers (descripcion, geom)
SELECT
    'Buffer de 1 unidad alrededor del eje X',
    ST_Buffer(geom, 1)
FROM lineas
WHERE descripcion = 'Eje X';

Para visualizar las geometrías originales junto con sus buffers:

SELECT
    'Original: ' || descripcion AS descripcion,
    geom
FROM puntos
WHERE descripcion = 'Origen'
UNION ALL
SELECT
    'Original: ' || descripcion AS descripcion,
    geom
FROM lineas
WHERE descripcion = 'Eje X'
UNION ALL
SELECT
    descripcion,
    geom
FROM buffers
ORDER BY descripcion;

En el visor geométrico deberían verse el punto Origen, el Eje X y los dos buffers generados. La idea es comparar cada geometría original con la zona que produce ST_Buffer.

Cargar buffers en QGIS y usar transparencia para ver las capas anteriores.


Paso 13. Crear polígonos

CREATE TABLE poligonos (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(Polygon)
);

Dibujar tres polígonos:

INSERT INTO poligonos (descripcion, geom)
VALUES
    ('A', ST_GeomFromText('POLYGON((0 0, 6 0, 6 6, 0 6, 0 0))')),
    ('B', ST_GeomFromText('POLYGON((4 2, 10 2, 10 8, 4 8, 4 2))')),
    ('C', ST_GeomFromText('POLYGON((1 1, 2 1, 2 2, 1 2, 1 1))'));

Verlos:

SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM poligonos
ORDER BY descripcion;

Cargar poligonos en QGIS con relleno transparente.


Paso 14. Relaciones entre polígonos

Antes de ejecutar:

¿A contiene a C?

SELECT ST_Contains(a.geom, c.geom) AS a_contiene_c
FROM poligonos a
JOIN poligonos c
    ON a.descripcion = 'A'
   AND c.descripcion = 'C';

Resultado esperado:

true

Ahora la relación inversa:

SELECT ST_Within(c.geom, a.geom) AS c_dentro_de_a
FROM poligonos c
JOIN poligonos a
    ON c.descripcion = 'C'
   AND a.descripcion = 'A';

Resultado esperado:

true

Ahora comparamos A contra B y A contra C en una sola consulta:

SELECT
    ST_Overlaps(a.geom, b.geom) AS a_b_se_superponen,
    ST_Intersects(a.geom, b.geom) AS a_b_se_intersectan,
    ST_Disjoint(a.geom, b.geom) AS a_b_son_disjuntos,
    ST_Overlaps(a.geom, c.geom) AS a_c_se_superponen,
    ST_Intersects(a.geom, c.geom) AS a_c_se_intersectan,
    ST_Contains(a.geom, c.geom) AS a_contiene_c
FROM poligonos a
JOIN poligonos b
    ON b.descripcion = 'B'
JOIN poligonos c
    ON c.descripcion = 'C'
WHERE a.descripcion = 'A';

Resultado esperado:

true | true | false | false | true | true

A y B se superponen parcialmente. A y C no se superponen parcialmente: C está completamente dentro de A.


Paso 15. Un caso para Touches

Agregamos un polígono D que toca a A por un borde.

INSERT INTO poligonos (descripcion, geom)
VALUES (
    'D',
    ST_GeomFromText('POLYGON((6 0, 9 0, 9 3, 6 3, 6 0))')
);

Antes de ejecutar:

¿D se superpone con A o sólo lo toca?

SELECT
    ST_Touches(a.geom, d.geom) AS toca,
    ST_Intersects(a.geom, d.geom) AS intersecta,
    ST_Overlaps(a.geom, d.geom) AS se_superpone
FROM poligonos a
JOIN poligonos d
    ON a.descripcion = 'A'
   AND d.descripcion = 'D';

Resultado esperado:

true | true | false

Ahora probamos D contra B:

SELECT
    ST_Touches(d.geom, b.geom) AS toca,
    ST_Intersects(d.geom, b.geom) AS intersecta,
    ST_Overlaps(d.geom, b.geom) AS se_superpone
FROM poligonos d
JOIN poligonos b
    ON d.descripcion = 'D'
   AND b.descripcion = 'B';

Resultado esperado:

false | true | true

D y B no sólo se tocan: comparten una región. Por eso ST_Overlaps da true.

Si dos geometrías se tocan, también se intersectan. Pero tocar no es lo mismo que superponerse.


Paso 16. Álgebra espacial

CREATE TABLE resultados_poligonales (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(80),
    geom geometry
);

Intersección entre A y B

Antes de ejecutar, sombrear la zona común entre A y B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Intersección entre A y B',
    ST_Intersection(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Intersección entre A y B';

Unión entre A y B

Antes de ejecutar, sombrear toda la región cubierta por A o por B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Unión entre A y B',
    ST_Union(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Unión entre A y B';

Diferencia A menos B

Antes de ejecutar, sombrear la parte de A que no está cubierta por B.

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Diferencia A menos B',
    ST_Difference(a.geom, b.geom)
FROM poligonos a
JOIN poligonos b
    ON a.descripcion = 'A'
   AND b.descripcion = 'B';
SELECT
    descripcion,
    ST_AsText(geom) AS wkt
FROM resultados_poligonales
WHERE descripcion = 'Diferencia A menos B';

Cargar resultados_poligonales en QGIS y comparar con A y B.

Unión espacial del plano base

Antes usamos UNION ALL para mostrar varias geometrías juntas sin fusionarlas. Ahora usamos ST_Union para unir espacialmente todas las geometrías de vista_plano_base en una sola geometría.

SELECT
    'Plano base unido' AS descripcion,
    ST_Union(geom) AS geom
FROM vista_plano_base;

Ahora intersectamos la línea oblicua contra ese plano base unido y lo mostramos todo junto:

SELECT
    descripcion,
    geom
FROM vista_plano_base
UNION ALL
SELECT
    descripcion,
    geom
FROM lineas
WHERE descripcion = 'Oblicua'
UNION ALL
SELECT
    'Intersección oblicua / plano base unido' AS descripcion,
    ST_Intersection(l.geom, plano.geom)::geometry AS geom
FROM lineas l
CROSS JOIN (
    SELECT ST_Union(geom) AS geom
    FROM vista_plano_base
) plano
WHERE l.descripcion = 'Oblicua';

Resultado esperado: deberían verse el plano base, la oblicua y dos puntos de intersección, porque la oblicua corta al eje X y también al eje Y.

Para leerlos como texto:

SELECT
    ST_AsText(
        ST_Intersection(l.geom, plano.geom)
    ) AS interseccion
FROM lineas l
CROSS JOIN (
    SELECT ST_Union(geom) AS geom
    FROM vista_plano_base
) plano
WHERE l.descripcion = 'Oblicua';

La diferencia importante:

OperaciónQué hace
UNION ALLJunta filas en una consulta
ST_UnionUne geometrías espacialmente

Paso 17. Envolventes: Convex Hull y Envelope

Volvemos a los puntos.

Convex Hull

Antes de ejecutar:

¿Cuál sería el polígono convexo más chico que contiene todos los puntos?

SELECT
    ST_AsText(
        ST_ConvexHull(
            ST_Collect(geom)
        )
    ) AS convex_hull
FROM puntos;

ST_Collect agrupa los puntos. ST_ConvexHull calcula el polígono convexo que los envuelve.

Guardar el resultado:

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Convex hull de los puntos',
    ST_ConvexHull(ST_Collect(geom))
FROM puntos;

Verlo en QGIS.


Envelope

ST_Envelope devuelve el rectángulo mínimo alineado a los ejes que contiene una geometría.

Antes de ejecutar:

Si los puntos llegan hasta -10 y 10 en los ejes, ¿qué rectángulo esperás obtener?

SELECT
    ST_AsText(
        ST_Envelope(
            ST_Collect(geom)
        )
    ) AS envelope
FROM puntos;

Guardar el resultado:

INSERT INTO resultados_poligonales (descripcion, geom)
SELECT
    'Envelope de los puntos',
    ST_Envelope(ST_Collect(geom))
FROM puntos;

Ver juntos Convex hull y Envelope:

SELECT
    descripcion,
    geom
FROM resultados_poligonales
WHERE descripcion IN (
    'Convex hull de los puntos',
    'Envelope de los puntos'
);

El Convex Hull se ajusta a la forma convexa más chica. El Envelope siempre devuelve un rectángulo alineado a los ejes.


Paso 18. LINESTRING y MULTILINESTRING

Una línea puede tener muchos vértices y seguir siendo una sola LINESTRING.

INSERT INTO lineas (descripcion, geom)
VALUES (
    'Línea con varios vértices',
    ST_GeomFromText(
        'LINESTRING(1 1, 2 5, 3 4, 4 8, 5 9, 6 3, 7 5, 8 7, 9 6, 10 10)'
    )
);
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_NumPoints(geom) AS vertices,
    ST_AsText(geom) AS wkt
FROM lineas
WHERE descripcion = 'Línea con varios vértices';

Aunque tenga muchos puntos, sigue siendo una única línea.

Ahora creamos una geometría múltiple:

CREATE TABLE multilines (
    id SERIAL PRIMARY KEY,
    descripcion VARCHAR(50),
    geom geometry(MultiLineString)
);
INSERT INTO multilines (descripcion, geom)
VALUES (
    'Dos líneas independientes',
    ST_GeomFromText('MULTILINESTRING((0 0, 5 5), (0 5, 5 0))')
);
SELECT
    descripcion,
    ST_GeometryType(geom) AS tipo,
    ST_AsText(geom) AS wkt
FROM multilines;

MULTILINESTRING contiene varias líneas independientes.


Fin

Apunte

BD Geometrica

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Parcial 1 Preguntas Desarrollo Posibles Repaso

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Machete para SGBDA

DocumentoOtro

Archivo de Drive

Abrir en Drive
Vista previa de Archivo de DriveAbrir archivo

Apunte

Resumen para el parcial 1

Documento

Archivo de Drive

Abrir en Drive
Vista previa de Archivo de DriveAbrir archivo

Apunte

Apunte Distribuidas Alternativo Mejorado

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Apunte

Apunte BD Distribuidas

Interactivo

By ChatGPT 5.5 High

Abrir apunte

Apunte interactivo

By ChatGPT 5.5 High

Tocá para abrir la vista previa.

Apariencia alternativa

Abrir apunte

Apunte interactivo

Apariencia alternativa

Tocá para abrir la vista previa.

Apunte

Apunte Bases Temporales

DocumentoInteractivo

by Claude Fable 5

Abrir apunte

Apunte interactivo

by Claude Fable 5

Tocá para abrir la vista previa.

Apunte

Que es un trigger, y lenguaje PLPGSQL

Interactivo

Vista interactiva

Abrir apunte

Apunte interactivo

Vista interactiva

Tocá para abrir la vista previa.

Ya viste todos los apuntes disponibles.

QuizPracticá
  • Apuntes11 recursos
  • CorrelativasMapa interactivo

    Resumen

    Eventos5
    Apuntes11
    QuizPracticá
  • Apuntes11 recursos
  • CorrelativasMapa interactivo

    Resumen

    Eventos5
    Apuntes11