Saltar a contenido

Regiones

Dos tablas en la app mangroove_regiones: la región con su grilla y las celdas que la componen.

La región es la única entidad cuya forma decide la de todas las demás: cada recorte, cada grilla agregada y cada resultado se alinea con su grilla. Por eso su grilla es inmutable desde la creación (RN-03).

Requerimientos cubiertos

Diagrama

---
config:
  elk:
    nodePlacementStrategy: NETWORK_SIMPLEX
  fontFamily: monospace
  layout: elk
---
classDiagram
    class Region {
        +uuid id
        +varchar(50) codigo
        +varchar(150) nombre
        +text aoi_wkt
        +float8 lon_min
        +float8 lat_min
        +float8 lon_max
        +float8 lat_max
        +float8 centro_lon
        +float8 centro_lat
        +smallint zoom_inicial
        +varchar(50) zona_horaria
        +integer epsg
        +smallint celda_m
        +float8 x0
        +float8 y0
        +integer ancho
        +integer alto
        +integer n_celdas
        +integer margen_m
        +float8 marea_lon
        +float8 marea_lat
        +boolean is_active
        +timestamptz created_at
        +timestamptz updated_at
    }
    class Celda {
        +uuid id
        +uuid region_id
        +integer fila
        +integer columna
        +integer este_m
        +integer norte_m
        +varchar(24) codigo
        +float8 lon
        +float8 lat
        +timestamptz created_at
    }
    Region "1" --> "*" Celda

Region

Un área de estudio con su polígono, su proyección y su grilla.

Columnas

Campo Tipo Nulo Predeterminado Descripción
codigo varchar(50) no Identificador estable en rutas: estero_real
nombre varchar(150) no Nombre para mostrar
aoi_wkt text no Polígono del área en WKT, lon/lat
lon_min a lat_max float8 no Caja envolvente del polígono, WGS84
centro_lon, centro_lat float8 no Donde abre el mapa
zoom_inicial smallint no 11 Zoom inicial del mapa
zona_horaria varchar(50) no 'America/Managua' Zona IANA para fechas locales, por RN-18
epsg integer no Zona UTM del centroide
celda_m smallint no 100 Lado de la celda en metros
x0, y0 float8 no Esquina superior izquierda de la grilla, en metros
ancho, alto integer no Columnas y filas de la grilla
n_celdas integer no generada Almacenada. ancho * alto
margen_m integer no 2000 Margen alrededor del polígono al recortar
marea_lon, marea_lat float8 no Punto en agua donde se estima la marea

Constraints

CONSTRAINT chk_region_codigo
CHECK (codigo ~ '^[a-z][a-z0-9_]*$')

CONSTRAINT chk_region_caja
CHECK (
  lon_min BETWEEN -180 AND 180 AND lon_max BETWEEN -180 AND 180
  AND lat_min BETWEEN -90 AND 90 AND lat_max BETWEEN -90 AND 90
  AND lon_min < lon_max AND lat_min < lat_max
)

CONSTRAINT chk_region_epsg_utm
CHECK (epsg BETWEEN 32601 AND 32660 OR epsg BETWEEN 32701 AND 32760)

CONSTRAINT chk_region_celda
CHECK (celda_m BETWEEN 10 AND 1000)

CONSTRAINT chk_region_tamano
CHECK (ancho > 0 AND alto > 0 AND ancho::bigint * alto <= 1000000)

CONSTRAINT chk_region_zoom
CHECK (zoom_inicial BETWEEN 0 AND 22)
Nombre Definición
unq_region_codigo (codigo)

Triggers

Nombre Evento Momento Nivel Regla Origen
trg_readonly_grilla UPDATE OF epsg, celda_m, x0, y0, ancho, alto, codigo BEFORE ROW Rechaza cualquier cambio de la grilla RN-03

Cálculo de la grilla

Al crear la región, el servicio proyecta la caja envolvente al EPSG del centroide y fija:

  • x0 = floor(min(E) / celda_m) * celda_m
  • y0 = ceil(max(N) / celda_m) * celda_m
  • ancho = ceil((max(E) - x0) / celda_m)
  • alto = ceil((y0 - min(N)) / celda_m)

El origen queda alineado a múltiplos del tamaño de celda, así que dos regiones con el mismo EPSG y el mismo tamaño de celda comparten bordes de celda donde se solapan.


Celda

Un cuadro de la grilla. Solo geometría: la máscara, el humedal y el país dependen de los insumos y viven en los resultados de cada corrida (D-10).

Columnas

Campo Tipo Nulo Predeterminado Descripción
region_id uuid no
fila integer no Desde 0, de norte a sur
columna integer no Desde 0, de oeste a este
este_m integer no derivada Coordenada E del centro; la fija el trigger
norte_m integer no derivada Coordenada N del centro; la fija el trigger
codigo varchar(24) no generada Almacenada. 'c_' \|\| este_m \|\| '_' \|\| norte_m
lon, lat float8 no Centro en WGS84, calculado con pyproj en el servicio

Unicidad

Nombre Definición
unq_celda_region_fila_columna (region_id, fila, columna)
unq_celda_region_codigo (region_id, codigo)

Triggers

Nombre Evento Momento Nivel Regla Origen
trg_celda_derivar_centro INSERT BEFORE ROW Sobrescribe este_m y norte_m con x0 + (columna + 0,5) · celda_m y y0 − (fila + 0,5) · celda_m RN-04
trg_celda_dentro_grilla INSERT BEFORE ROW Rechaza filas o columnas fuera de alto y ancho RN-03

Ubicar una celda desde un punto

RF-C-08 no consulta esta tabla para encontrar la celda: proyecta el punto al EPSG de la región y calcula columna = floor((E − x0) / celda_m) y fila = floor((y0 − N) / celda_m). La tabla solo se lee después, por unq_celda_region_fila_columna, para unirla con su resultado. Un punto sobre el borde exacto entre dos celdas cae siempre en la de mayor columna y mayor fila, porque floor es determinista.