PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Table avec les coordonnées d'une grille hexagonale qui couvre le monde

Il y a quelque temps j'ai adapté une function pour générer des hexagones qui pourraient être exactement ce que vous recherchez. Il prend les paramètres de largeur de cellule et les coordonnées des coins sud-ouest et nord-est, et génère une grille hexagonale.

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;

Cette fonction retourne une table avec les colonnes _gid et _geom , contenant respectivement un identifiant et la géométrie de chaque hexagone.

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

Avec ces paramètres, la fonction génère une grille avec 98192 hexagones couvrant le monde entier :

Ici d'un peu plus près, pour que vous puissiez voir la grille :

Si vous souhaitez uniquement couvrir le terrain, vous pouvez créer un sous-ensemble de ces hexagones en fonction de la géométrie de votre choix à l'aide de ST_Intersects :

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

Cette requête créera un sous-ensemble avec une grille contenant 35911 hexagones, qui se croisent avec les géométries de la carte du monde :

La carte du monde utilisée dans cette réponse peut être téléchargée sous forme de fichier de formes here .

Produit final :- Un tableau contenant le point central de chaque hexagone dans une grille hexagonale couvrant le monde entier. - Les hexagones ont une surface fixe

Générer les centroïdes pour chaque hexagone n'est pas un gros problème non plus (voir ST_Centroid ):

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