覆盖全球的六边形网格坐标表

4

寻找在PostGIS中实现生成覆盖整个行星的六边形网格以便对每个六边形进行数据聚合的方法。

任何指向正确方向的指导都将是极大的帮助!

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


1
更精确地说:不能用六边形定期覆盖球体(以使每个顶点恰好有三个相邻的六边形)。您仍然可以制作不规则覆盖。您可以使用6个四边形或4个三角形代替12个五边形。@dmuir - Nico Schertler
不需要完美的六边形,略微变形也没关系,只要它们大致相同大小以进行数据分箱即可。即使它们有些重叠也无妨,我只需要找到最近中心点的距离即可。 - user9936632
1
出于好奇:为什么需要六边形?如果您只想将数据累积到等面积的箱中,那么泊松盘采样的沃罗诺伊图也可能适用。 - Nico Schertler
@user9936632,你找到解决方案了吗?我非常感兴趣 :) - Jim Jones
1
@jim-jones,感谢你迄今为止的帮助。正如我之前所写的,我采用了一种完全不使用地图投影等方法的不同方法。 - user9936632
显示剩余3条评论
1个回答

5

一段时间以前,我改编了一个函数来生成六边形,这可能正是你要寻找的。它需要参数单元格宽度、西南角和东北角的坐标,并生成一个六边形网格。

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个六边形网格: Hexagons covering the whole world 以下是更接近的视图,以便您可以查看网格: Hexagons covering the whole world - Europe Overview 如果您只想覆盖陆地,则可以使用ST_Intersects基于所选几何形状创建这些六边形的子集:
CREATE TABLE t_overlap AS 
SELECT t._gid,t._geom FROM t,world 
WHERE ST_Intersects(world.geom,t._geom)

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

enter image description here

此答案中使用的世界地图可以作为 shapefile 从 这里 下载。

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

对于每个六边形生成质心也不是什么大问题(参见 ST_Centroid)。
CREATE TABLE t_overlap_centroid AS
SELECT ST_Centroid(_geom) FROM t_overlap;

enter image description here


谢谢!不过有一个小问题。只有一个小问题。这些区域差别很大,需要大致相同的大小。 - user9936632
1
@user9936632 我知道了。你能告诉我你是怎么发现的吗?至少通过使用“SELECT DISTINCT ST_Area(_geom) FROM t_overlap;”我可以看到网格的所有元素具有完全相同的面积,即0.75。 - Jim Jones
SELECT distinct ST_Area(_geom::geography, FALSE) FROM t - user9936632
我明白了,在一个椭球体上,它们的平方米确实会有所不同。 - Jim Jones
@JimJones 很抱歉再次打扰您,请问有没有办法在北京市的纬度 39.45 - 40.05 和经度 115.4166 - 117.5 周围绘制一个矩形区域。因为我的研究意图覆盖这些坐标定义的市辖区。 - arilwan
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接