RedisGeoHash 2.0.0
dotnet add package RedisGeoHash --version 2.0.0
NuGet\Install-Package RedisGeoHash -Version 2.0.0
<PackageReference Include="RedisGeoHash" Version="2.0.0" />
<PackageVersion Include="RedisGeoHash" Version="2.0.0" />
<PackageReference Include="RedisGeoHash" />
paket add RedisGeoHash --version 2.0.0
#r "nuget: RedisGeoHash, 2.0.0"
#:package RedisGeoHash@2.0.0
#addin nuget:?package=RedisGeoHash&version=2.0.0
#tool nuget:?package=RedisGeoHash&version=2.0.0
RedisGeoHash
A library for creating RedisGeo Hash values within .NET.
Credits
This is a C# port of the Redis Geo Hash code by antirez: https://github.com/antirez/redis
Why?
When I was involved in the writing of the StackExchange.Redis Geo functionality I became interested in how Redis uses geohashes to store information in sorted sets. Behind the scenes a RedisGeo collection is nothing more than a sorted set: Redis uses a numerical representation of geohashes as the member scores. I wanted to do the same thing from within .NET to implement local GEO collections for caching purposes at work.
How?
using GeoHash;
var hash = new RedisGeoHash(39.923422, -86.1078998); // latitude, longitude
Console.WriteLine(hash.GeoHash); // 1782901374540128
Compared to Redis:
127.0.0.1:6379> GEOADD willt -86.1078998 39.923422 1
(integer) 1
127.0.0.1:6379> ZRANGE willt 0 100 WITHSCORES
1) "1"
2) "1782901374540128"
Note that Redis commands take longitude first; this library's constructor
takes latitude first. Coordinates outside the supported range (latitude
±85.05112878, longitude ±180) throw ArgumentOutOfRangeException.
Decoding
Decode() returns the bounding box of the geohash cell, and
GeohashDecodeToLongLatWgs84 returns its center point:
var area = hash.Decode();
// area.Latitude.Min/Max and area.Longitude.Min/Max bound the original point
var xy = new double[2];
RedisGeoHash.GeohashDecodeToLongLatWgs84(hash.GeoHashBits, xy);
// xy[0] = longitude, xy[1] = latitude of the cell center
Neighbors
Neighbors() returns the eight adjacent cells:
var neighbors = hash.Neighbors();
Console.WriteLine(neighbors.North.Bits);
Building and testing
dotnet build
dotnet test
Mutation testing
Stryker.NET is
pinned as a local dotnet tool and configured by stryker-config.json:
dotnet tool restore
dotnet dotnet-stryker
The run fails if the mutation score drops below the break threshold in
stryker-config.json. The HTML report lands in StrykerOutput/.
Benchmarks
BenchmarkDotNet benchmarks live in
Benchmarks/:
dotnet run -c Release --project Benchmarks -- --filter '*'
CI and releases
.github/workflows/ci.yml runs on every PR and push to master/main:
- Build & Test —
dotnet teston the full solution - Mutation Testing — Stryker, failing below the configured threshold, with the HTML report uploaded as an artifact
- Benchmarks — a short BenchmarkDotNet job, results uploaded as an artifact
On push to master/main, after tests and mutation testing pass, the
Publish to NuGet job packs GeoHash/GeoHash.csproj and pushes it to
nuget.org with --skip-duplicate — so a merge only publishes when
<Version> in the csproj has been bumped; otherwise the push is a no-op.
Publishing uses NuGet Trusted Publishing:
the workflow exchanges a GitHub OIDC token for a short-lived API key via
NuGet/login, so no stored API-key secret is needed. The nuget.org trusted
publishing policy must name this repo with workflow file ci.yml.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.