如何为特定区域中的H3六边形生成shapefile

时间:2018-07-03 16:27:34

标签: shapefile h3

我想为特定地理区域中的H3六边形生成shapefile。特别是,我对分辨率为6、7和9的湾区感兴趣。如何为覆盖该区域的六边形创建shapefile?

我是shapefile或任何其他地理数据结构的新手。我对python和R最满意。

3 个答案:

答案 0 :(得分:5)

这里的基本步骤是:

  • 采用所需区域的多边形。边界框应该很好用。
  • 使用polyfill方法以所需的分辨率用六边形填充多边形。
  • 环绕每个六边形并使用h3ToGeoBoundary函数获得边界。
  • 将这些边界放入GeoJSON文件
  • 使用ogr2ogr之类的转换器来转换为shapefile。

Python绑定尚未发布,我不熟悉R绑定,但是JavaScript版本可能如下所示:

var h3 = require('h3-js');

var bbox = [
    [-123.308821530582, 38.28055644998254],
    [-121.30037257250085, 38.28055644998254],
    [-121.30037257250085, 37.242722073589164],
    [-123.308821530582, 37.242722073589164]
];

var hexagons = h3.polyfill(bbox, 6, true);

var geojson = {
    type: 'Feature',
    geometry: {
        type: 'MultiPolygon',
        coordinates: hexagons.map(function toBoundary(hex) {
            return [h3.h3ToGeoBoundary(hex, true)];
        })
    }
};

console.log(JSON.stringify(geojson));

,您将使用如下脚本:

node bbox-geojson.js | ogr2ogr -f "ESRI Shapefile" bbox-hexagons.shp /vsistdin/

答案 1 :(得分:2)

如果您正在R中寻找解决方案,则h3jsr package可以访问Uber的H3库。您的问题的解决方案可以使用函数h3jsr::polyfill()h3jsr::h3_to_polygon完成。

可复制的示例

library(ggplot2)
library(h3jsr)
library(sf)
library(sf)


# read the shapefile of the polygon area you're interested in
  nc <- st_read(system.file("shape/nc.shp", package="sf"), quiet = TRUE)

# projection
  nc <- st_transform(nc, crs = 4326)

# get the unique h3 ids of the hexagons intersecting your polygon at a given resolution
  nc_5 <- polyfill(nc, res = 5, simple = FALSE)

# pass the h3 ids to return the hexagonal grid
  hex_grid5 <- unlist(nc_5$h3_polyfillers) %>% h3_to_polygon(simple = FALSE)

这将返回以下多边形:

enter image description here enter image description here

答案 2 :(得分:1)

在这里回答 John Stud 的问题,因为我遇到了同样的“问题”。下面,我将评论如何读入 shapefile,使用 H3 将其六边形化,并从中获取 Hexagon 地理数据框(并最终将其保存为 shapefile)。

可重现的示例

让我们为美国获取一个 shapefile,例如here(我使用“cb_2018_us_state_500k.zip”一个)。

# Imports
import h3
import geopandas as gpd
import matplotlib.pyplot as plt
import pandas as pd
import shapely
from shapely.ops import unary_union
from shapely.geometry import mapping, Polygon

# Read shapefile
gdf = gpd.read_file("data/cb_2018_us_state_500k.shp")

# Get US without territories / Alaska + Hawaii
us = gdf[~gdf.NAME.isin(["Hawaii", "Alaska", "American Samoa", 
                         "United States Virgin Islands", "Guam",
                         "Commonwealth of the Northern Mariana Islands",
                         "Puerto Rico"])]

# Plot it
fig, ax = plt.subplots(1,1)
us.plot(ax=ax)
plt.show()

enter image description here

# Convert to EPSG 4326 for compatibility with H3 Hexagons
us = us.to_crs(epsg=4326)

# Get union of the shape (whole US)
union_poly = unary_union(us.geometry)

# Find the hexagons within the shape boundary using PolyFill
hex_list=[]
for n,g in enumerate(union_poly):
    if (n+1) % 100 == 0:
        print(str(n+1)+"/"+str(len(union_poly)))
    temp = mapping(g)
    temp['coordinates']=[[[j[1],j[0]] for j in i] for i in temp['coordinates']]  
    hex_list.extend(h3.polyfill(temp,res=5))

# Create hexagon data frame
us_hex = pd.DataFrame(hex_list,columns=["hex_id"])

# Create hexagon geometry and GeoDataFrame
us_hex['geometry'] = [Polygon(h3.h3_to_geo_boundary(x, geo_json=True)) for x in us_hex["hex_id"]]
us_hex = gpd.GeoDataFrame(us_hex)

# Plot the thing
fig, ax = plt.subplots(1,1)
us_hex.plot(ax=ax, cmap="prism")
plt.show()

enter image description here

上图有分辨率“5”(https://h3geo.org/docs/core-library/restable/),我建议你也看看其他分辨率,比如4:

enter image description here

当然,这取决于“缩放级别”,即您是在查看整个国家/地区还是仅查看城市等。

当然,要回答最初的问题:您可以使用

保存生成的 shapefile
us_hex.to_file("us_hex.shp")