-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
144 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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")); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters