Geohash.net es una biblioteca Ligera de C# de alto rendimiento para codificar y decodificar cadenas y Geohashes enteros.
HACER
Aquí hay un ejemplo rápido de cómo usar la biblioteca 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 es un sistema de geocodificación que le permite representar una ubicación geográfica utilizando una cadena o entero alfanumérico corta. Fue desarrollado por Gustavo Niemeyer en 2008 y desde entonces se ha convertido en un método popular para codificar e indexar datos espaciales.
El concepto detrás de Geohashing es tomar coordenadas de latitud y longitud y convertirlas en una forma más compacta. Esto se logra subdividiendo recursivamente la superficie de la Tierra en células rectangulares, a las que luego se les asigna un identificador único. La longitud del geohash determina el nivel de precisión, con geohashes más largos que representan áreas más pequeñas.
Las células Geohash tienen algunas propiedades notables:
Por ejemplo, para generar una cadena Geohash para la ubicación con latitud 37.7749 y longitud -122.4194 a un nivel de precisión de 12, podemos seguir estas tres etapas:
Cuantifica la latitud y la longitud a los enteros de 32 bits mapeando al intervalo unitario [0, 1] y multiplicando por 2^32 ( exp2(32) ):
La latitud toma el rango [-90, 90], por lo tanto, la representación entera de la latitud de 32 bits es
lat32 = floor ( exp2 ( 32 ) * ( latitude + 90 ) / 180 ) Que en nuestro caso es igual a 3048827870 ( 0b10110101101110010110101111011110 )
Del mismo modo para la longitud [-180, 180]:
lng32 = floor ( exp2 ( 32 ) * ( longitude + 180 ) / 360 ) Que en nuestro caso es igual a 686963316 ( 0b101000111100100011101001110100 )
La latitud y la longitud cuantificada de 32 bits se interponen bits para producir un valor de 64 bits (el Geohash entero ).
El siguiente diagrama ilustra la operación.

Nota: Latitud y longitud ocupan bits pares y extraños respectivamente .
En nuestro ejemplo en ejecución, el entero Geohash es: 5589511709871930228 ( 0b0100110110010001111011110100100100011110110011010111101101110100 )
Este número debe tomarse a menor precisión. La precisión de Geohash entero consiste en los n altos bits, por lo que necesitamos truncar el exceso de bits. Podemos hacerlo por operación de cambio de bits:
hash = interleaved >> ( sizeof ( ulong ) * BITS_PER_BYTE - log2 ( 32 ) * precision ) // 64 - 5 * precision Que es 349344481866995639 ( 0b010011011001000111101111010010010001111011001101011110110111 ) para nuestro ejemplo.
Nota: Este paso finalmente proporciona la propiedad de prefijo crítico de Geohash: el geohash de un punto a una precisión más baja es un prefijo del Geohash a una precisión más alta. Por lo tanto, las búsquedas de proximidad se pueden reducir a los prefijos de Geohash coincidentes (como un primer pase).
La cadena Geohash se obtiene del entero Geohash por codificación base32. Esto es estándar, excepto por la elección del alfabeto. Cada carácter de Geohash representa un valor binario de 5 bits ( log2(32) ), y toda la cadena Geohash está compuesta por múltiples valores concatenados de 5 bits.
0123456789bcdefghjkmnpqrstuvwxyz
La codificación comienza en los altos bits, consumiendo 5 bits del entero Geohash para cada carácter de precisión. Como resultado, la precisión máxima es de 12 caracteres o 60 bits .
Divida el valor binario en grupos de 5 bits y convierta cada grupo en su carácter base-32 correspondiente:
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
Concatenen todos los caracteres Base-32 para formar la cadena Geohash final: 9q8yyk8ytpxr
Para los casos de uso interno, Geohash, Geohash, suele ser suficiente . El paso Base32 se incluyó aquí para completar.
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
| Método | Aporte | Significar | Error | Stddev | Tamaño del código | Gen0 | Asignado |
|---|---|---|---|---|---|---|---|
| Netgeohash | k | 8.112 ns | 0.1881 ns | 0.2090 ns | 1.717 b | - | - |
| Netcoreohash | 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 | yarda | 8.442 ns | 0.1032 ns | 0.0965 ns | 1.717 b | - | - |
| Netcoreohash | yarda | 166.305 ns | 0.8682 ns | 0.8121 ns | 18 B | 0.0038 | 32 B |
| Ngeohashlib | yarda | 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 | - | - |
| Netcoreohash | 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 | - | - |
| Netcoreohash | 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 | - | - |
| Netcoreohash | 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 | - | - |
| Netcoreohash | 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 | - | - |
| Netcoreohash | 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 | - | - |
| Netcoreohash | 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 | - | - |
| Netcoreohash | 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 | - | - |
| Netcoreohash | 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 | - | - |
| Netcoreohash | 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 | - | - |
| Netcoreohash | 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 |

| Método | latitud | longitud | precisión | Significar | Error | Stddev | Tamaño del código | Gen0 | Asignado |
|---|---|---|---|---|---|---|---|---|---|
| Netgeohash | -89.127865 | -179.438962 | 7 | 20.69 ns | 0.146 ns | 0.129 ns | 906 b | 0.0048 | 40 B |
| Netcoreohash | -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 |
| Netcoreohash | -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 |
| Netcoreohash | -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 |
| Netcoreohash | 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 |
| Netcoreohash | 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 |
| Netcoreohash | 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 |

¡Animo las contribuciones a geohash.net! Si se encuentra con un error o tiene una sugerencia para una nueva característica, no dude en abrir un problema o enviar una solicitud de extracción en GitHub. Estoy constantemente buscando formas de mejorar la biblioteca y proporcionar más valor a la comunidad.
Geohash.net se basa en la investigación y los hallazgos de Michael McLoughlin. Su trabajo sobre geohashing y la implementación de un algoritmo de geohashing de alto rendimiento en GO se puede encontrar en este artículo Geohash en la Asamblea de Golang.