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;