天天看點

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

postgresql , vector grid , polygon grid , square grid , hexagon grid , 矢量網格 , 幾何網格 , 線段網格 , 多邊形網格 , 四邊形網格 , 六邊形網格 , 蜂巢 , postgis , 地圖 , 轉換

人們為了更好的描述一個東西,有一種将大化小的思路,比如時鐘被分為了12個區域,每個區域表示一個小時,然後每個小的區域又被劃分為更小的區域表示分鐘。

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

在gis系統中,也有類似的思想,比如将地圖劃分成網格。通過編碼來簡化地理位置的判斷(比如相交,包含,距離計算等),但是請注意使用網格帶來的問題,比如精度的問題,網格的大小決定了精度,又比如相對坐标的問題,可能無法描述清楚邊界的歸屬。

ps:

1. 在postgis中雖然也支援網格對象的描述方式,但是并不是使用這種方法來進行幾何運算(比如相交,包含,距離計算等),是以不存在類似的精度問題,個人建議沒有強需求的話,不必做這樣的網格轉換。

postgresql gis索引的原理請參考

<a href="https://github.com/digoal/blog/blob/master/201612/20161231_01.md">《從難纏的模糊查詢聊開 - postgresql獨門絕招之一 gin , gist , sp-gist , rum 索引原理與技術背景》</a>

2. 如果是多種精度地圖的切換(比如多個圖層,每個圖層代表一種地圖精度),建議使用輻射的方式逐漸展開更精細的圖層,以點為中心,逐漸輻射。(很多專業的地圖軟體是這樣做的)

回到主題,還記得最強大腦的蜂巢迷宮嗎?

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

還有勤勞的蜜蜂兄弟

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

我們接下來要做的就是如何将幾何圖形轉換為網格對象。

首先要了解一下六邊形的幾何特性,提供轉換的計算基礎。

六邊形可以切分為6個等邊三角形

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

是以它的邊長關系如下

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

面積計算

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

更多細節詳見

<a href="https://hexnet.org/content/hexagonal-geometry">https://hexnet.org/content/hexagonal-geometry</a>

比如要将澳洲的版圖,轉換為六邊形網格,

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

有兩種方法,一種使用geotools的java 類(在程式中轉換),另一種是使用postgis插件的udf(在資料庫中轉換)。

當然,如果postgresql安裝了pljava插件的話,那麼也可以在postgresql中調用geotools提供的java類進行轉換。

下面是例子

<a href="http://docs.geotools.org/latest/userguide/extension/grid.html">http://docs.geotools.org/latest/userguide/extension/grid.html</a>

使用geotools vector grids class生成網格,傳回 simplefeaturesource 類型。

geotools vector grids class支援将幾何圖形轉換為 polygon網格 或者 line網格 。

舉幾個例子

1. 将澳洲地圖轉換為10度邊長的正方形網格

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

輸入澳洲的經緯度範圍,轉換

2. 将澳洲地圖轉換為最大20度邊長的扇形網格

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

3. 建立縱橫寬100,變長為5.0的六邊形網格

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

4. 導入圖形、将澳洲地圖轉換為邊長1度的六邊形網格

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

自定義圖形邊界判斷的類

導入地圖,在createhexagonalgrid中使用邊界判斷的類,生成六邊形網格

5. 生成的六邊形網格的擺放參數,橫(flat)的還是豎(angled)的?

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

預設為flat網格,如果要生成angled網格,如下

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

轉換為line 網格

例子

<a href="https://github.com/minus34/postgis-scripts/tree/master/hex-grid">https://github.com/minus34/postgis-scripts/tree/master/hex-grid</a>

postgis不需要多介紹了,幾十年的老牌gis插件,在軍方、科研、民用等各個領域有着非常廣泛對應用。

如果你使用了postgis插件的話,在裡面存儲了不管是geometry, polygon還是其他的地圖類型,都可以轉換為六邊形網格。

轉換時使用這些定義好的udf即可。

udf使用方法

see the 2 sample usage scripts to see how to create a national hex grid, using the function.

udf輸入參數

parameter

description

areakm2

area of each hexagon in square km. note: output hexagon sizes can be off slightly due to coordinate rounding in the calcs.

xmin,ymin

minimum coordinates of the grid extents (i.e. bottom, left).

xmax,ymax

maximum coordinates of the grid extents (i.e. top, right).

inputsrid

the coordinate system (srid) of the min/max coordinates.

workingsrid

the srid used to process the hexagons:

-

srid must be a projected coord sys (i.e. in metres) as the calcs require ints. degrees are out.

should be an equal area srid - i.e. albers or lambert azimuthal (e.g. australia = 3577, us = 2163).

using a mercator projection will not return hexagons of equal area (don't try it in greenland).

ouputsrid

the srid of the output hexagons.

輸出

a set of hexagonal polygons as postgis geometries

蜂巢的藝術與技術價值 - PostgreSQL PostGIS's hex-grid

轉換基礎,參考如下

<a href="https://trac.osgeo.org/postgis/wiki/userswikigeneratehexagonalgrid">https://trac.osgeo.org/postgis/wiki/userswikigeneratehexagonalgrid</a>

1. 在postgis中雖然也支援網格對象的描述方式,但是并不是使用網格編碼的方法來進行幾何運算(比如相交,包含,距離計算等),而是類似矢量的計算方法,是以不存在網格的精度問題,個人建議沒有強需求的話,不必将幾何圖形轉換為網格。

3. 如果要将圖形轉換為網格,可以使用geotools提供的java class來轉換,也可以使用postgis的udf來轉換,當然postgresql如果安裝了pljava過程語言的話,可以直接在資料庫中調用geotools提供的java class對圖形進行轉換。

4. pljava

https://tada.github.io/pljava/ 

1. geotools vector grid包

2. postgis 生成六邊形網格的udf

3. postgis 生成六邊形網格的算法基礎

4. 六邊形幾何公式