sql >> Database teknologi >  >> RDS >> PostgreSQL

Bord med koordinater for et sekskantet gitter, der dækker verden

For noget tid siden tilpassede jeg en function at generere sekskanter, der kan være præcis, hvad du leder efter. Den tager parametrene cellebredde og koordinaterne for sydvestlige og nordøstlige hjørner og genererer et sekskantet gitter.

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;

Denne funktion returnerer en tabel med kolonnerne _gid og _geom , der indeholder henholdsvis en identifikator og geometrien for hver sekskant.

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

Med disse parametre genererer funktionen et gitter med 98192 sekskanter, der dækker hele verden:

Her lidt tættere på, så du kan se gitteret:

Hvis du kun er interesseret i at dække land, kan du oprette en undergruppe af disse sekskanter baseret på en geometri efter eget valg ved at bruge ST_Intersects :

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

Denne forespørgsel vil oprette et undersæt med et gitter, der indeholder 35911 sekskanter, som krydser geometrierne fra verdenskortet:

Verdenskortet brugt i dette svar kan downloades som shapefile here .

Slutprodukt:- En tabel med midtpunktet for hver sekskant i et sekskantet gitter, der dækker hele verden. - Sekskanterne har fastgjort areal

Det er heller ikke en stor sag at generere tyngdepunkter for hver sekskant (se ST_Centroid ):

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




  1. Indstil nøgle/værdipar i sessionskonteksten i SQL Server (sp_set_session_context)

  2. Hvordan tester man, om en streng er JSON eller ej?

  3. EM12c tillader nu DB12c til Repos

  4. Ret Msg 512 "Underforespørgsel returnerede mere end 1 værdi" i SQL Server