PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Tabela ze współrzędnymi siatki heksagonalnej, która obejmuje świat

Jakiś czas temu zaadaptowałem function aby wygenerować sześciokąty, które mogą być dokładnie tym, czego szukasz. Pobiera parametry szerokości komórki oraz współrzędne południowo-zachodniego i północno-wschodniego narożnika i generuje siatkę sześciokątną.

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;

Ta funkcja zwraca tabelę z kolumnami _gid i _geom , zawierający odpowiednio identyfikator i geometrię każdego sześciokąta.

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

Dzięki tym parametrom funkcja generuje siatkę z 98192 sześciokąty obejmujące cały świat:

Tutaj trochę bliżej, aby zobaczyć siatkę:

Jeśli interesuje Cię tylko pokrycie terenu, możesz utworzyć podzbiór tych sześciokątów w oparciu o wybraną geometrię za pomocą ST_Intersects :

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

To zapytanie utworzy podzbiór z siatką zawierającą 35911 sześciokąty, które przecinają się z geometriami z mapy świata:

Mapę świata użytą w tej odpowiedzi można pobrać jako plik shape here .

Produkt końcowy:- Tabela zawierająca punkt środkowy dla każdego sześciokąta w sześciokątnej siatce, która obejmuje cały świat. - Sześciokąty mają stały obszar

Generowanie centroidów dla każdego sześciokąta również nie jest wielkim problemem (zobacz ST_Centroid ):

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




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zaimplementować relację wiele-do-wielu w PostgreSQL?

  2. Jak zmienić schemat wielu tabel PostgreSQL w jednej operacji?

  3. Odpowiednik Postgresql GROUP_CONCAT?

  4. MNIEJSZE PODOBNE vs iLIKE

  5. Pobierz nazwę miesiąca z daty w PostgreSQL