sql >> Databasteknik >  >> RDS >> PostgreSQL

Tabell med koordinater för ett hexagonalt rutnät som täcker världen

För en tid sedan anpassade jag en function att generera hexagoner som kan vara precis vad du letar efter. Den tar parametrarna cellbredd och koordinaterna för sydvästra och nordöstra hörn och genererar ett hexagonalt rutnät.

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;

Denna funktion returnerar en tabell med kolumnerna _gid och _geom , som innehåller en identifierare respektive geometrin för varje hexagon.

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

Med dessa parametrar genererar funktionen ett rutnät med 98192 hexagoner som täcker hela världen:

Här lite närmare, så att du kan se rutnätet:

Om du bara är intresserad av att täcka land kan du skapa en delmängd av dessa hexagoner baserat på en valfri geometri med ST_Intersects :

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

Den här frågan skapar en delmängd med ett rutnät som innehåller 35911 hexagoner, som korsar geometrierna från världskartan:

Världskartan som används i detta svar kan laddas ner som shapefil here .

Slutprodukt:- En tabell som innehåller mittpunkten för varje hexagon i ett hexagonalt rutnät som täcker hela världen. - Hexagonerna har fixerad area

Att generera tyngdpunkterna för varje hexagon är inte heller en stor sak (se ST_Centroid ):

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




  1. Hitta maxvärde och visa motsvarande värde från olika fält i SQL-servern

  2. En översikt över olika hjälpplannoder i PostgreSQL

  3. Hantera MySQL Long Running Queries

  4. SELECT / GROUP BY - tidssegment (10 sekunder, 30 sekunder, etc)