閱讀820 返回首頁    go 阿裏雲 go 技術社區[雲棲]


geohash vs PostGIS

標簽

PostgreSQL , PostGIS , GEOHASH , 經緯度 , geometry , geography


背景

業界有幾種地理位置的表示方法。

通常我們使用經緯度表示地球上的位置,PostgreSQL的PostGIS可以很好的描述這種類型,包括海拔在內。使用最為廣泛,精度、功能最高的應該是PostGIS。

但是並不是所有的數據庫都有這樣的技術(或者實現難度的問題導致了很多數據庫在初期會選擇較為簡單的geohash)。

什麼是geohash呢?

geohash 原理

通常我們使用經緯度表示地球上的位置,PostgreSQL的PostGIS可以很好的描述這種類型,包括海拔在內。

但是並不是所有的數據庫都有這樣的技術(或者實現難度的問題導致了很多數據庫在初期會選擇較為簡單的geohash)。

什麼是geohash呢?

實際上geohash是一套網格化的編碼方式,經過編碼,可以將經緯度對應的點,表示為一個網格,網格的大小,取決於geohash的精度。

通常,geohash使用32個字符進行編碼。業界也有使用geo base 36的編碼,即36個字符來表示的。

編碼後,離得越近的點,編碼值也是越近的。prefix永遠會包含更長的編碼字符表示的範圍。(例如wb12x是5位的,包含了wb12x..........的網格,即wb12x是個大格子,wb12x....是更小的格子。),但是請注意,邊界問題,例如-180和180實際上是一個地方。但是它們的geohash編碼卻完全不一樣。這也是geohash的問題之一。

如何將geohash編碼轉換為經緯度?

首先有一個base32的映射表(以32個字符進行編碼為例)

pic

例如一個hash=ezs42的geohash值,通過這個表,可以翻譯成 13, 31, 24, 4, 2。

將以上每個數字,使用5位BIT表示,進而翻譯成 01101 11111 11000 00100 00010 。

接下來是關鍵不走,以上BIT串,位置從0開始,偶數的BIT位連起來作為 longitude code (0111110000000), 奇數比特位連起來作為 latitude code (101111001001).

得到了經緯度BIT串後,該怎麼辦呢?

經度範圍-180 ~ 180

緯度範圍-90 ~ 90

每次將範圍對半拆開,例如-180, 0, 180。當bit=0時,表示點落在左邊的範圍,當bit=1時,表示點落在右邊的範圍。然後再將下一個範圍對半拆開,例如-180, -90, 0。繼續根據BIT選擇範圍,循環往複。

得到一個範圍,取範圍的中值,作為對應的經度或者緯度。

pic

上圖就是101111001001的計算過程,右,左,右,右,右,右,左,左,右,左,左,右。

value指範圍的中間值,ERR指誤差。

當geohash的字符串長度越長時,誤差越小,我們來看看誤差表如下。

pic

geohash缺陷

由於編碼,地球非正球體,等問題。導致了geohash 存在幾個比較致命的缺陷。

1. 網格化算法帶來的精度問題

2. 地球是不規則橢圓,geohash的偏差會隨著緯度的變大驟變,越接南北極地,距離計算越不準確。

  • At the Equator (0 Degrees) the length of a degree of longitude is 111.320 km, while a degree of latitude measures 110.574 km, an error of 0.67%.

  • At 30 Degrees (Mid Latitudes) the error is 110.852/96.486 = 14.89%

  • At 60 Degrees (High Arctic) the error is 111.412/55.800 = 99.67%, reaching infinity at the poles.

3. 經度邊界(-180,180)數據的處理,邊界的哈希值完全不同,但是他們卻相鄰,不利於相鄰計算。

PostGIS geometry, geography, raster, ...

PostgreSQL PostGIS 發展了幾十年,有非常深厚的理論背景,廣泛應用於軍工、科研、商業場景。

PostGIS adds extra types (geometry, geography, raster and others) to the PostgreSQL database.

It also adds functions, operators, and index enhancements that apply to these spatial types.

These additonal functions, operators, index bindings and types augment the power of the core PostgreSQL DBMS, making it a fast, feature-plenty, and robust spatial database management system.

Feature List

The PostGIS 2+ series provides:

  • Processing and analytic functions for both vector and raster data for splicing, dicing, morphing, reclassifying, and collecting/unioning with the power of SQL

  • raster map algebra for fine-grained raster processing

  • Spatial reprojection SQL callable functions for both vector and raster data

  • Support for importing / exporting ESRI shapefile vector data via both commandline and GUI packaged tools and support for more formats via other 3rd-party Open Source tools

  • Packaged command-line for importing raster data from many standard formats: GeoTiff, NetCDF, PNG, JPG to name a few

  • Rendering and importing vector data support functions for standard textual formats such as KML,GML, GeoJSON,GeoHash and WKT using SQL

  • Rendering raster data in various standard formats GeoTIFF, PNG, JPG, NetCDF, to name a few using SQL

  • Seamless raster/vector SQL callable functions for extrusion of pixel values by geometric region, running stats by region, clipping rasters by a geometry, and vectorizing rasters

  • 3D object support, spatial index, and functions

  • Network Topology support

  • Packaged Tiger Loader / Geocoder/ Reverse Geocoder / utilizing US Census Tiger data

geohash vs PostGIS

參考自

https://www.cnblogs.com/LBSer/p/3629149.html

一個玩具級場景(PostGIS說:我可不是玩具^_^....)的對比

功能 Mysql spatial extension PostGIS
空間索引 僅MyISAM支持R樹索引,InnoDB不支持 GIST樹索引(R樹的變種)
支持的空間類型 僅二維數據 二維、三維以及曲線
空間操作函數 有限的空間函數 基本實現OGC標準定義的空間操作函數
空間投影 不支持 支持多種常用投影坐標係
事務支持 不支持 PostGIS提供了一係列的長事務支持,可以有效支持複雜的空間分析功能
加載速度 MySQL > PostGIS (事務) (作者可能沒有進行優化,性能不會更差)。 -
空間索引的創建速度 MySQL < PostGIS (diff split algo)。 -
查詢效率 MySQL PostGIS(不同性質查詢結果不一樣,各有千秋) -
GIS係統使用 使用較少 使用較多,例如openstreetmap的數據庫後台就是Postgresql+Postgis

例:想查找藍色多邊形內的點,mysql空間擴展僅能查出在最小外包矩形(紅色框)內的點,而postgis能查出任意多邊形內的點。

pic

例:想查找兩點間距離。MySQL Spatial僅能計算歐式空間距離,而PostGIS能計算不同投影坐標係下的真實空間距離

PostGIS不僅支持geometry,geography也支持geohash

PostGIS雖然不推薦使用geohash,但是它內置了轉換函數,可以將geometry轉換為geohash

Name

ST_GeoHash — Return a GeoHash representation of the geometry.  

Synopsis

text ST_GeoHash(geometry geom, integer maxchars=full_precision_of_point);  

Description

Return a GeoHash representation (https://en.wikipedia.org/wiki/Geohash) of the geometry. A GeoHash encodes a point into a text form that is sortable and searchable based on prefixing. A shorter GeoHash is a less precise representation of a point. It can also be thought of as a box, that contains the actual point.

If no maxchars is specified ST_GeoHash returns a GeoHash based on full precision of the input geometry type. Points return a GeoHash with 20 characters of precision (about enough to hold the full double precision of the input). Other types return a GeoHash with a variable amount of precision, based on the size of the feature. Larger features are represented with less precision, smaller features with more precision. The idea is that the box implied by the GeoHash will always contain the input feature.

If maxchars is specified ST_GeoHash returns a GeoHash with at most that many characters so a possibly lower precision representation of the input geometry. For non-points, the starting point of the calculation is the center of the bounding box of the geometry.

Availability: 1.4.0

[Note]

ST_GeoHash will not work with geometries that are not in geographic (lon/lat) coordinates.

This method supports Circular Strings and Curves

Examples

SELECT ST_GeoHash(ST_SetSRID(ST_MakePoint(-126,48),4326));  
  
	 st_geohash  
----------------------  
 c0w3hf1s70w3hf1s70w3  
  
SELECT ST_GeoHash(ST_SetSRID(ST_MakePoint(-126,48),4326),5);  
  
 st_geohash  
------------  
 c0w3h  

參考

https://en.wikipedia.org/wiki/Geohash

https://postgis.net/docs/ST_GeoHash.html

https://www.cnblogs.com/LBSer/p/3629149.html

https://planet.postgis.net/

最後更新:2017-04-22 17:01:48

  上一篇:go Test2
  下一篇:go PostgreSQL 10.0 preview 功能增強 - 老板特性, LONG SQL過程可視 pg_stat_progress_vacuum