sql >> Base de Datos >  >> RDS >> PostgreSQL

Tabla con coordenadas de una cuadrícula hexagonal que cubre el mundo

Hace algún tiempo adapté una function para generar hexágonos que podrían ser exactamente lo que estás buscando. Toma los parámetros de ancho de celda y las coordenadas de las esquinas suroeste y noreste, y genera una cuadrícula hexagonal.

CREATE OR REPLACE FUNCTION create_hexagons(width FLOAT, xmin FLOAT, ymin FLOAT, xmax FLOAT, ymax FLOAT)
RETURNS TABLE (_gid INTEGER, _geom GEOMETRY) AS $$
DECLARE
  b FLOAT := width/2;
  a FLOAT := b/2;
  c FLOAT := 2*a;
  height FLOAT := 2*a+c;
  ncol FLOAT := ceil(abs(xmax-xmin)/width);
  nrow FLOAT := ceil(abs(ymax-ymin)/height);
  polygon_string VARCHAR := 'POLYGON((' || 
    0 || ' ' || 0 || ' , ' || b || ' ' || a || ' , ' || b || ' ' || a+c || ' , ' || 0 || ' ' || a+c+a || ' , ' ||
   -1*b || ' ' || a+c || ' , ' || -1*b || ' ' || a || ' , ' || 0 || ' ' || 0 || '))';
BEGIN
  CREATE TEMPORARY TABLE tmp (gid serial NOT NULL PRIMARY KEY,geom GEOMETRY(POLYGON)) ON COMMIT DROP;
  INSERT INTO tmp (geom)   
  SELECT ST_Translate(geom, x_series*(2*a+c)+xmin, y_series*(2*(c+a))+ymin)
  FROM generate_series(0, ncol::INT, 1) AS x_series,
       generate_series(0, nrow::INT,1 ) AS y_series,
    (SELECT polygon_string::GEOMETRY AS geom
     UNION
     SELECT ST_Translate(polygon_string::GEOMETRY, b, a + c) AS geom) AS two_hex;
    ALTER TABLE tmp ALTER COLUMN geom TYPE GEOMETRY(POLYGON, 4326) USING ST_SetSRID(geom, 4326);   
    RETURN QUERY (SELECT gid, geom FROM tmp);    
END;
$$ LANGUAGE plpgsql;

Esta función devuelve una tabla con las columnas _gid y _geom , que contiene un identificador y la geometría de cada hexágono, respectivamente.

CREATE TABLE t AS
SELECT * FROM create_hexagons(1.0, -180, -90, 180, 45) 

Con estos parámetros, la función genera una grilla con 98192 hexágonos que cubren el mundo entero:

Aquí un poco más cerca, para que puedas ver la grilla:

Si solo está interesado en cubrir la tierra, puede crear un subconjunto de estos hexágonos en función de una geometría de su elección usando ST_Intersects :

CREATE TABLE t_overlap AS 
SELECT t._gid,t._geom FROM t,world 
WHERE ST_Intersects(world.geom,t._geom)

Esta consulta creará un subconjunto con una cuadrícula que contiene 35911 hexágonos, que se cruzan con las geometrías del mapa mundial:

El mapa mundial utilizado en esta respuesta se puede descargar como archivo de forma here .

Producto final:- Una tabla que contiene el punto central de cada hexágono en una cuadrícula hexagonal que cubre todo el mundo. - Los hexágonos tienen un área fija

Generar los centroides para cada hexágono tampoco es gran cosa (ver ST_Centroid ):

CREATE TABLE t_overlap_centroid AS
SELECT ST_Centroid(_geom) FROM t_overlap;