Skip to content

[pull] master from TheAlgorithms:master #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Add Geohashing (TheAlgorithms#486)
  • Loading branch information
ngtduc693 authored Oct 24, 2024
commit 013a6b92fc48d6486ca6f6bca080273c408888cb
59 changes: 59 additions & 0 deletions Algorithms.Tests/Other/GeohashTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Algorithms.Other;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Algorithms.Tests.Other
{
[TestFixture]
public class GeohashTests
{
[Test]
public void Encode_ShouldReturnCorrectGeohash_ForHoChiMinhCity()
{
double latitude = 10.8231;
double longitude = 106.6297;
string result = Geohash.Encode(latitude, longitude);
Assert.That(result, Is.EqualTo("w3gvd6m3hh54"));
}

[Test]
public void Encode_ShouldReturnCorrectGeohash_ForHanoi()
{
double latitude = 21.0285;
double longitude = 105.8542;
string result = Geohash.Encode(latitude, longitude);
Assert.That(result, Is.EqualTo("w7er8u0evss2"));
}

[Test]
public void Encode_ShouldReturnCorrectGeohash_ForDaNang()
{
double latitude = 16.0544;
double longitude = 108.2022;
string result = Geohash.Encode(latitude, longitude);
Assert.That(result, Is.EqualTo("w6ugq4w7wj04"));
}

[Test]
public void Encode_ShouldReturnCorrectGeohash_ForNhaTrang()
{
double latitude = 12.2388;
double longitude = 109.1967;
string result = Geohash.Encode(latitude, longitude);
Assert.That(result, Is.EqualTo("w6jtsu485t8v"));
}

[Test]
public void Encode_ShouldReturnCorrectGeohash_ForVungTau()
{
double latitude = 10.3460;
double longitude = 107.0843;
string result = Geohash.Encode(latitude, longitude);
Assert.That(result, Is.EqualTo("w3u4ug2mv41m"));
}
}
}
84 changes: 84 additions & 0 deletions Algorithms/Other/Geohash.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Algorithms.Other
{
public static class Geohash
{
private const string Base32Characters = "0123456789bcdefghjkmnpqrstuvwxyz"; // Convert latitude and longitude coordinates into a concise string
private const int GeohashLength = 12; // ± 1.86 cm

/// <summary>
/// Encodes the provided latitude and longitude coordinates into a Geohash string.
/// Geohashing is a method to encode geographic coordinates (latitude, longitude).
/// into a short string of letters and digits. Each character in the resulting Geohash .
/// string adds more precision to the location. The longer the Geohash, the smaller the area.
/// </summary>
/// <param name="latitude">The latitude of the location to encode. It must be a value between -90 and 90.</param>
/// <param name="longitude">The longitude of the location to encode. It must be a value between -180 and 180.</param>
/// <returns>
/// A Geohash string of length 12 representing the location with high precision.
/// A longer Geohash provides higher precision in terms of geographic area.
/// and a 12-character Geohash can be accurate down to around 1.86 cm.
/// </returns>
public static string Encode(double latitude, double longitude)
{
double[] latitudeRange = new[] { -90.0, 90.0 };
double[] longitudeRange = new[] { -180.0, 180.0 };
bool isEncodingLongitude = true;
int currentBit = 0;
int base32Index = 0;
StringBuilder geohashResult = new StringBuilder();

while (geohashResult.Length < GeohashLength)
{
double midpoint;

if (isEncodingLongitude)
{
midpoint = (longitudeRange[0] + longitudeRange[1]) / 2;
if (longitude > midpoint)
{
base32Index |= 1 << (4 - currentBit);
longitudeRange[0] = midpoint;
}
else
{
longitudeRange[1] = midpoint;
}
}
else
{
midpoint = (latitudeRange[0] + latitudeRange[1]) / 2;
if (latitude > midpoint)
{
base32Index |= 1 << (4 - currentBit);
latitudeRange[0] = midpoint;
}
else
{
latitudeRange[1] = midpoint;
}
}

isEncodingLongitude = !isEncodingLongitude;

if (currentBit < 4)
{
currentBit++;
}
else
{
geohashResult.Append(Base32Characters[base32Index]);
currentBit = 0;
base32Index = 0;
}
}

return geohashResult.ToString();
}
}
}
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ find more than one implementation for the same objective but using different alg
* [Welford's Variance](./Algorithms/Other/WelfordsVariance.cs)
* [Julian Easter](./Algorithms/Other/JulianEaster.cs)
* [Pollard's Rho](./Algorithms/Other/PollardsRhoFactorizing.cs)
* [GeoLocation Hash](./Algorithms/Other/Geohash.cs)
* [Problems](./Algorithms/Problems)
* [Stable Marriage](./Algorithms/Problems/StableMarriage)
* [Gale-Shapley](./Algorithms/Problems/StableMarriage/GaleShapley.cs)
Expand Down