【问题标题】:Table with coordinates of a hexagonal grid that covers the world带有覆盖世界的六边形网格坐标的表格
【发布时间】:2018-11-23 04:39:55
【问题描述】:

在 PostGIS 中寻找一种实现,用于生成覆盖整个星球的六边形网格,以便在每个六边形上聚合数据。

任何指向正确方向的指针都会有很大帮助!

最终产品: - 一个表格,其中包含覆盖整个世界的六边形网格中每个六边形的中心点。 - 六边形有一个固定的面积

【问题讨论】:

  • 你不能覆盖六边形的球体(或模糊的球形斑点)。如果使用六边形和五边形,则需要 12 个五边形。
  • @dmuir:更准确地说:不可能用六边形定期覆盖球体(这样每个顶点都恰好有三个入射六边形)。您仍然可以制作不规则的封面。除了 12 个五边形,您还可以使用 6 个四边形或 4 个三角形。
  • 如果它们不是完美的六边形并不重要。如果它们被扭曲,我很好,只需要它们的大小大致相同即可进行数据分箱。我什至不介意它们是否在这里和那里重叠。我只想找到到最近中心的距离。
  • 出于好奇:为什么它必须是六边形?如果您只想将数据累积到等面积箱中,泊松圆盘采样的 Voronoi 图可能也可以。
  • @jim-jones,感谢您到目前为止的帮助。正如我上面所写,我采用了一种不同的方法,根本不使用地图投影等。

标签: postgresql geolocation geometry postgis


【解决方案1】:

前段时间我修改了function 来生成可能正是您正在寻找的六边形。它采用参数单元格宽度以及西南角和东北角的坐标,并生成一个六边形网格。

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;

此函数返回一个包含_gid_geom 列的表,分别包含一个标识符和每个六边形的几何形状。

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

使用这些参数,函数会生成一个覆盖整个世界的98192六边形网格:

这里再靠近一点,这样就可以看到网格了:

如果您只对覆盖土地感兴趣,您可以使用ST_Intersects,根据您选择的几何形状创建这些六边形的子集:

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

此查询将创建一个包含 35911 六边形的网格子集,这些六边形与世界地图中的几何图形相交:

此答案中使用的世界地图可以下载为 shapefile here

最终产品: - 包含每个六边形中心点的表格 覆盖整个世界的六边形网格。 - 六边形有一个 固定区域

为每个六边形生成质心也不是什么大问题(请参阅ST_Centroid):

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

【讨论】:

  • 谢谢!不过有点小问题。不过有个小问题。地区差异很大。它们的大小需要大致相同。
  • @user9936632 我明白了。你能告诉我你是怎么发现的吗?至少对于SELECT DISTINCT ST_Area(_geom) FROM t_overlap;,我可以看到网格的所有元素完全具有相同的区域,即0.75
  • SELECT distinct ST_Area(_geom::geography, FALSE) FROM t
  • 需要它们大致相同的地理区域。
  • 我明白了,在椭球体上,它们的平方米确实会有所不同。
猜你喜欢
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
  • 2014-01-11
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
  • 2023-01-10
  • 2019-09-11
相关资源
最近更新 更多