GeoHash.net是一個輕巧的高性能C#庫,用於編碼和解碼字符串和整數地理句。
托多
這是如何使用geohash.net庫的快速示例:
using NetGeohash ;
// Encode latitude and longitude coordinates into a geohash string
string geohash = Geohash . Encode ( 37.421999 , - 122.084057 , 9 ) ;
// Decode the geohash string into latitude and longitude coordinates
( double latitude , double longitude ) = Geohash . Decode ( geohash ) ;
// Encode the geohash string into an integer format
ulong geohashInt = Geohash . EncodeToInt64 ( 37.421999 , - 122.084057 , 9 ) ;
// Decode the integer geohash into latitude and longitude coordinates
( latitude , longitude ) = Geohash . DecodeFromInt64 ( geohashInt ) ; GeoHash是一個地理編碼系統,可讓您使用短的字母字符串或整數來表示地理位置。它是由Gustavo Niemeyer於2008年開發的,此後已成為編碼和索引空間數據的流行方法。
地理施工背後的概念是採用緯度和經度坐標,並將其轉換為更緊湊的形式。這是通過將地球表面遞歸分為矩形細胞而實現的,然後將其分配給唯一的標識符。地球上的長度決定了精度的水平,較長的地理位化代表較小的區域。
GeoHash細胞具有一些值得注意的特性:
例如,要為緯度37.7749和經度的位置生成一個地理字符串,精確水平為12,我們可以遵循這三個階段:
通過映射到單位間隔[0,1],將緯度和經度量化為32位整數,並乘以2^32( exp2(32) ):
緯度採用[-90,90]的範圍,因此,緯度的32位整數表示為
lat32 = floor ( exp2 ( 32 ) * ( latitude + 90 ) / 180 )在我們的情況下,它等於3048827870( 0b10110101101110010110101111011110 )
同樣對於經度[-180,180]:
lng32 = floor ( exp2 ( 32 ) * ( longitude + 180 ) / 360 )在我們的情況下,它等於686963316( 0b101000111100100011101001110100 )
32位量化的緯度和經度被咬合,以產生64位值(整數地理)。
下圖說明了操作。

注意:緯度和經度分別佔據均勻和奇數。
在我們的運行示例中,整數GeoHash是:5589511709871930228( 0b0100110110010001111011110100100100011110110011010111101101110100 )
該數字應以較低的精度進行。整數GeoHash的精度由N高點組成,因此我們需要截斷多餘的位。我們可以通過位移動操作來做到這一點:
hash = interleaved >> ( sizeof ( ulong ) * BITS_PER_BYTE - log2 ( 32 ) * precision ) // 64 - 5 * precision對於我們的示例,為349344481866995639( 0b010011011001000111101111010010010001111011001101011110110111 )。
注意:此步驟最終提供了GeoHash的關鍵前綴屬性:以較低精度為點的Geohash是Geohash的前綴,以較高的精度為前綴。因此,接近搜索可以簡化為匹配的GeoHash前綴(作為第一次通過)。
字符串GeoHash是通過Base32編碼從整數GeoHash獲得的。這是標準的,除了選擇字母。每個GeoHash字符代表一個5位( log2(32) )二進制值,整個GeoHash字符串由多個串聯的5位值組成。
0123456789bcdefghjkmnpqrstuvwxyz
編碼始於高點,為每個精度的每個字符都消耗5位整數地理什。結果,最大精度是12個字符或60位。
將二進制值分為5位的組,然後將每個組轉換為相應的基本-32字符:
01001 ( 9) - 9
10110 (22) - q
01000 ( 8) - 8
11110 (30) - y
11110 (30) - y
10010 (18) - k
01000 ( 8) - 8
11110 (30) - y
11001 (25) - t
10101 (21) - p
11101 (29) - x
10111 (23) - r
加入所有基本32個字符,形成最終的GeoHash字符串: 9q8yyk8ytpxr
對於內部用例,整數GeoHash通常就足夠了。 Base32步驟在此處包括在內。
BenchmarkDotNet =v0.13.5, OS =Windows 11 (10.0.22000.1696/21H2/SunValley)
AMD Ryzen 9 3900X, 1 CPU, 24 logical and 12 physical cores
.NET SDK =8.0.100-preview.1.23115.2
[Host] : .NET 8.0.0 (8.0.23.11008), X64 RyuJIT AVX2
Job-KKMPKU : .NET 8.0.0 (8.0.23.11008), X64 RyuJIT AVX2
Jit =RyuJit Platform =X64 Runtime =.NET 8.0
| 方法 | 輸入 | 意思是 | 錯誤 | stddev | 代碼大小 | Gen0 | 分配 |
|---|---|---|---|---|---|---|---|
| Netgeohash | k | 8.112 ns | 0.1881 ns | 0.2090 ns | 1,717 b | - | - |
| NetCoreGeoHash | k | 145.271 ns | 0.8736 ns | 0.7295 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | k | 143.414 ns | 0.8529 ns | 0.7561 ns | 9 b | 0.0229 | 192 b |
| Netgeohash | yd | 8.442 ns | 0.1032 ns | 0.0965 ns | 1,717 b | - | - |
| NetCoreGeoHash | yd | 166.305 ns | 0.8682 ns | 0.8121 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | yd | 169.663 ns | 1.0957 ns | 1.0249 ns | 9 b | 0.0229 | 192 b |
| Netgeohash | 6n3 | 9.442 ns | 0.1746 ns | 0.1633 ns | 1,717 b | - | - |
| NetCoreGeoHash | 6n3 | 192.502 ns | 2.0566 ns | 1.9238 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | 6n3 | 202.150 ns | 1.9676 ns | 1.8405 ns | 9 b | 0.0229 | 192 b |
| Netgeohash | zvgk | 10.183 ns | 0.1023 ns | 0.0907 ns | 1,717 b | - | - |
| NetCoreGeoHash | zvgk | 218.244 ns | 1.4455 ns | 1.3521 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | zvgk | 223.580 ns | 0.7643 ns | 0.6776 ns | 9 b | 0.0229 | 192 b |
| Netgeohash | T05KH | 10.726 ns | 0.2016 ns | 0.1886 ns | 1,717 b | - | - |
| NetCoreGeoHash | T05KH | 310.208 ns | 0.9773 ns | 0.8663 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | T05KH | 263.364 ns | 2.2418 ns | 2.0970 ns | 9 b | 0.0229 | 192 b |
| Netgeohash | B5CV2H | 11.413 ns | 0.0796 ns | 0.0706 ns | 1,717 b | - | - |
| NetCoreGeoHash | B5CV2H | 328.490 ns | 2.4518 ns | 2.1735 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | B5CV2H | 283.862 ns | 2.9657 ns | 2.7741 ns | 9 b | 0.0229 | 192 b |
| Netgeohash | VVEYJ80 | 12.114 ns | 0.1749 ns | 0.1636 ns | 1,717 b | - | - |
| NetCoreGeoHash | VVEYJ80 | 358.143 ns | 0.9470 ns | 0.7908 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | VVEYJ80 | 318.725 ns | 1.7533 ns | 1.6400 ns | 9 b | 0.0229 | 192 b |
| Netgeohash | F7Y53XJT | 12.676 ns | 0.2287 ns | 0.2140 ns | 1,717 b | - | - |
| NetCoreGeoHash | F7Y53XJT | 380.157 ns | 2.2520 ns | 2.1065 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | F7Y53XJT | 334.277 ns | 1.0733 ns | 1.0039 ns | 9 b | 0.0229 | 192 b |
| Netgeohash | TRM92JKBV | 12.990 ns | 0.1217 ns | 0.1139 ns | 1,717 b | - | - |
| NetCoreGeoHash | TRM92JKBV | 404.136 ns | 1.9322 ns | 1.7128 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | TRM92JKBV | 374.209 ns | 1.0807 ns | 1.0109 ns | 9 b | 0.0229 | 192 b |
| Netgeohash | DRMQ3GX6ZT | 13.861 ns | 0.1824 ns | 0.1706 ns | 1,717 b | - | - |
| NetCoreGeoHash | DRMQ3GX6ZT | 429.735 ns | 1.6946 ns | 1.4151 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | DRMQ3GX6ZT | 400.585 ns | 1.9080 ns | 1.7847 ns | 9 b | 0.0229 | 192 b |
| Netgeohash | 9zefgnuj7dw | 14.265 ns | 0.2997 ns | 0.2803 ns | 1,717 b | - | - |
| NetCoreGeoHash | 9zefgnuj7dw | 455.781 ns | 3.3098 ns | 2.9341 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | 9zefgnuj7dw | 416.747 ns | 2.7821 ns | 2.6023 ns | 9 b | 0.0229 | 192 b |
| Netgeohash | K9M2H7T1N0C2 | 14.864 ns | 0.3210 ns | 0.3153 ns | 1,717 b | - | - |
| NetCoreGeoHash | K9M2H7T1N0C2 | 479.624 ns | 1.5628 ns | 1.3854 ns | 18 b | 0.0038 | 32 b |
| ngeohashlib | K9M2H7T1N0C2 | 467.252 ns | 1.3795 ns | 1.2904 ns | 9 b | 0.0229 | 192 b |

| 方法 | 緯度 | 經度 | 精確 | 意思是 | 錯誤 | stddev | 代碼大小 | Gen0 | 分配 |
|---|---|---|---|---|---|---|---|---|---|
| Netgeohash | -89.127865 | -179.438962 | 7 | 20.69 ns | 0.146 ns | 0.129 ns | 906 b | 0.0048 | 40 b |
| NetCoreGeoHash | -89.127865 | -179.438962 | 7 | 195.04 ns | 0.632 ns | 0.528 ns | 14 b | 0.0172 | 144 b |
| ngeohashlib | -89.127865 | -179.438962 | 7 | 324.45 ns | 3.044 ns | 2.848 ns | 19 b | 0.0458 | 384 b |
| Netgeohash | -41.2858 | 174.7868 | 12 | 24.77 ns | 0.352 ns | 0.329 ns | 906 b | 0.0057 | 48 b |
| NetCoreGeoHash | -41.2858 | 174.7868 | 12 | 318.08 ns | 2.079 ns | 1.944 ns | 14 b | 0.0181 | 152 b |
| ngeohashlib | -41.2858 | 174.7868 | 12 | 493.78 ns | 2.879 ns | 2.552 ns | 19 b | 0.0687 | 576 b |
| Netgeohash | -12.347856 | 34.890273 | 3 | 17.95 ns | 0.215 ns | 0.201 ns | 906 b | 0.0038 | 32 b |
| NetCoreGeoHash | -12.347856 | 34.890273 | 3 | 104.91 ns | 0.616 ns | 0.546 ns | 14 b | 0.0162 | 136 b |
| ngeohashlib | -12.347856 | 34.890273 | 3 | 167.74 ns | 2.523 ns | 2.360 ns | 19 b | 0.0277 | 232 b |
| Netgeohash | 45.678912 | 92.45236 | 4 | 18.39 ns | 0.313 ns | 0.293 ns | 906 b | 0.0038 | 32 b |
| NetCoreGeoHash | 45.678912 | 92.45236 | 4 | 127.05 ns | 1.053 ns | 0.985 ns | 14 b | 0.0162 | 136 b |
| ngeohashlib | 45.678912 | 92.45236 | 4 | 209.17 ns | 1.549 ns | 1.449 ns | 19 b | 0.0305 | 256 b |
| Netgeohash | 52.5174 | 13.409 | 12 | 24.64 ns | 0.299 ns | 0.280 ns | 906 b | 0.0057 | 48 b |
| NetCoreGeoHash | 52.5174 | 13.409 | 12 | 310.05 ns | 1.637 ns | 1.451 ns | 14 b | 0.0181 | 152 b |
| ngeohashlib | 52.5174 | 13.409 | 12 | 498.72 ns | 5.374 ns | 5.027 ns | 19 b | 0.0687 | 576 b |
| Netgeohash | 80.294617 | 19.543821 | 5 | 18.82 ns | 0.228 ns | 0.191 ns | 906 b | 0.0038 | 32 b |
| NetCoreGeoHash | 80.294617 | 19.543821 | 5 | 152.24 ns | 0.561 ns | 0.498 ns | 14 b | 0.0162 | 136 b |
| ngeohashlib | 80.294617 | 19.543821 | 5 | 242.98 ns | 2.265 ns | 2.008 ns | 19 b | 0.0391 | 328 b |

我鼓勵Geohash.net貢獻!如果您遇到錯誤或對新功能有建議,請隨時在Github上打開問題或提交拉動請求。我一直在尋找增強圖書館並為社區提供更多價值的方法。
GeoHash.net基於Michael McLoughlin的研究和發現。他在GO中的Geohash算法上的地理塑料工作以及實施高性能地塑料算法的實施,可以在Golang大會的Geohash中找到。