鐵人賽2019 Day06 其它資料聚合與geohash

  1. 1. Geohash
  2. 2. project point to geohash
  3. 3. 後記

前一天的資料聚合,所舉的應用例是行政區村里,實作簡單的點資料與空間單元做結合,然而事實上,聚合的單元不限於行政區村里,以台灣來說,可以使用內政部最小統計區的空間單元來做資料聚合,最小統計區與其發佈區的劃設主要是根據人口,有關最小統計區請參考最小統計區圖|MOI Open Data

另外,也有特別針對其他用途的統計區:經濟統計區圖資| 政府資料開放平臺,或是如集水區等都可以採用前一天的方法,與點資料做整合,相關資料請自行參閱。

今天要介紹的也與昨日的資料聚合有一點關係-geohash

Geohash

geohash故名意思是一種編碼,包含了多層級的架構,將空間劃分為網格(分為1-12層),Geohash的產生是根據Z-order curve的方式產生的,這樣的特性讓查詢上可以透過hash編碼的前綴來加快空間搜尋速度。

geohash被很常用在GIS資料的indexing上,他有點類似R-tree或Quadtree

以示意圖來理解geohash
687474703a2f2f692e737461636b2e696d6775722e636f6d2f74563953372e6a7067
(取自GitHub - stephenlb/geohash-chat-by-proximity: Geo Hashing Chat by Proximity to connect two or more users to a group chat.)

geohash的每個層級的網格的解析度大致如下:
1 5,009.4km x 4,992.6km
2 1,252.3km x 624.1km
3 156.5km x 156km
4 39.1km x 19.5km
5 4.9km x 4.9km
6 1.2km x 609.4m
7 152.9m x 152.4m
8 38.2m x 19m
9 4.8m x 4.8m
10 1.2m x 59.5cm
11 14.9cm x 14.9cm
12 3.7cm x 1.9cm

線上也有一些工具可以檢視及瀏覽geohash編碼
Geohash encoding/decoding

瀏覽這個網站也會對geohash更有感覺
GeohashExplorer

project point to geohash

我們直接簡單從python做一些測試,geohash是透過經緯度坐標系統建構的:

路燈資料為例,先轉為經緯度資料

1
2
3
4
5
6
7
import geopandas as gpd
light=gpd.read_file('output/light.shp',encoding='utf-8')
light=light[light.is_valid]
light=light[light['district']=='永和區']
light.crs = {'init' :'epsg:3826'}
light=light.to_crs(epsg=4326)
light

Screen Shot 2018-10-21 at 11.57.40.png

接著,直接我們使用pygeohash,precision 7 代表第七層

須先安裝,使用 pip install python-geohash

1
2
3
import geohash
light['geohash']=[geohash.encode(row['geometry'].y,row['geometry'].x, precision=7) for idx,row in light.iterrows()]
light

Screen Shot 2018-10-21 at 12.08.16.png

接著使用groupby

1
2
group=light.groupby('geohash')
group=group.size().reset_index(name='counts')

Screen Shot 2018-10-21 at 12.12.37.png

我們試著把geohash解碼,geohash.bbox(0)提供geohash的邊界,我們把它轉為Polygob,把它存進去一個新的array

1
2
3
4
5
from shapely.geometry import Polygon
geohashs=[]
for idx,row in group.iterrows():
decoded=geohash.bbox(row['geohash'])
geohashs.append(Polygon([(decoded['s'], decoded['w']), (decoded['s'],decoded['e']), (decoded['n'], decoded['e']), (decoded['n'],decoded['w'])]))

我們把資訊畫出來吧:

1
2
3
4
g = gpd.GeoSeries(geohashs)        
g_aggr = gpd.GeoDataFrame(group)
g_aggr['geometry']=g
g_aggr.plot('counts')

Screen Shot 2018-10-21 at 13.38.20.png

後記

透過今天的練習,利用geohash也可以進行網格式的資料聚合以及多時期的資料分析。

今天的相關測試可以參考GitHub