Git Product home page Git Product logo

geohash-dotnet's Introduction

geohash-dotnet

Easy-to-use and feature-rich geohash library. It has three main components:

  1. Geohasher
  2. PolygonHasher
  3. GeohashCompressor

Installation

To use the geohash library in your projects run the following command in the Package Manager Console:

 Install-Package geohash-dotnet

NuGet version (blazor-dragdrop) Nuget

Getting Started

To start using geohash-dotnet, you need to import the Geohash namespace and create a new instance of the Geohasher class.

using Geohash;

// Create a new Geohasher instance
var geohasher = new Geohasher();

// Encode latitude and longitude into a geohash string
string geohash = geohasher.Encode(37.4219999, -122.0840575, 9);

// Decode the geohash back to latitude and longitude
(double latitude, double longitude) = geohasher.Decode(geohash);

// Get subhashes of a geohash
string[] subhashes = geohasher.GetSubhashes(geohash);

// Get neighbors of a geohash
Dictionary<Direction, string> neighbors = geohasher.GetNeighbors(geohash);

// Get parent of a geohash
string parent = geohasher.GetParent(geohash);

// Get the bounding box of a geohash
BoundingBox bbox = geohasher.GetBoundingBox(geohash);

Geohasher

Geohashing is a spatial indexing technique that allows for the encoding and decoding of geographic coordinates, as well as performing various geospatial operations. The Geohasher class provided in this library offers an easy-to-use implementation of the geohashing algorithm, supporting a range of functionalities such as encoding, decoding, finding neighbors, generating subhashes, calculating parents, and retrieving bounding boxes of geohashes.

General Information

Geohashes are base32-encoded strings that represent a specific rectangular region on Earth. The length of the geohash determines its precision. Shorter geohashes cover larger areas, while longer geohashes cover smaller areas. The Geohasher class supports geohashes with a precision between 1 and 12 characters.

The geohashing algorithm works by recursively dividing the latitude and longitude intervals into smaller intervals and selecting the corresponding base32 character for each subdivision. The even bits of the geohash represent longitude, while the odd bits represent latitude.

Finding Neighbors

You can find the neighbors of a geohash in all eight cardinal directions (north, northeast, east, southeast, south, southwest, west, and northwest) using the GetNeighbors() method:

Dictionary<Direction, string> neighbors = geohasher.GetNeighbors(geohash);

The GetNeighbors() method returns a dictionary with keys representing the eight cardinal directions (North, Northeast, East, Southeast, South, Southwest, West, and Northwest). Each key corresponds to a Direction enum value, and each value in the dictionary is a geohash string representing the neighboring geohash in the respective direction.

You can access a specific neighbor using the appropriate Direction enum value:

string northNeighbor = neighbors[Direction.North];
string southNeighbor = neighbors[Direction.South];
// ... and so on for the other directions

If you need to find the neighbor hash in a specific direction, use the GetNeighbor() method:

string northNeighbor = geohasher.GetNeighbor(geohash, Direction.North);

Subhashes

Subhashes represent smaller, equally-sized regions within a geohash's bounding box. To retrieve the 32 subhashes of a geohash, use the GetSubhashes() method:

string[] subhashes = geohasher.GetSubhashes(geohash);

Parent Geohash

The parent of a geohash is the geohash that covers the same area but at a lower precision level. You can get the parent geohash using the GetParent() method:

string parent = geohasher.GetParent(geohash);

Keep in mind that the parent geohash will be less precise and cover a larger area.

Bounding Box

To obtain the bounding box (minimum and maximum latitude and longitude) of a geohash, use the GetBoundingBox() method:

BoundingBox bbox = geohasher.GetBoundingBox(geohash);

The GetBoundingBox() method returns a BoundingBox object that represents the geographical bounding box of a given geohash. A bounding box is defined by two pairs of latitude and longitude coordinates, representing the southwest (bottom-left) and northeast (top-right) corners of the rectangular area.

You can use the bounding box to display the geohash on a Leaflet map by creating a rectangle with the coordinates obtained from the bounding box:

  // Assuming you have a BoundingBox object `bbox` from geohasher.GetBoundingBox(geohash)
  var southWest = L.latLng(bbox.MinLatitude, bbox.MinLongitude);
  var northEast = L.latLng(bbox.MaxLatitude, bbox.MaxLongitude);
  var bounds = L.latLngBounds(southWest, northEast);

  // Create a rectangle using the bounds and add it to the map
  var rectangle = L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map);

PolygonHasher

The PolygonHasher class is an extension of the Geohasher class that provides the functionality to generate geohashes within a polygon based on the specified precision and inclusion criteria. This class is useful in applications that require spatial indexing of data within a specific polygonal area.

General Information

The algorithm used by PolygonHasher has a time complexity of O(N^2), where N is the number of geohashes generated within the bounding box. The performance of this algorithm can vary greatly depending on the size and complexity of the polygon, as well as the desired precision of the geohashes. In general, larger polygons and higher precision levels will result in longer processing times.

Usage

// Create a new instance of the PolygonHasher class
PolygonHasher polygonHasher = new PolygonHasher();

// Create a polygon
Polygon polygon = new Polygon(new LinearRing(new Coordinate[] {
  new Coordinate(-122.4183, 37.7755),
  new Coordinate(-122.4183, 37.7814),
  new Coordinate(-122.4085, 37.7814),
  new Coordinate(-122.4085, 37.7755),
  new Coordinate(-122.4183, 37.7755) // Close the ring
}));

// Get geohashes with precision 6 that intersect the polygon
HashSet<string> geohashes = polygonHasher.GetHashes(polygon, 6, PolygonHasher.GeohashInclusionCriteria.Intersects);

// Print the geohashes
foreach (string geohash in geohashes)
{
  Console.WriteLine(geohash);
}

GeohashCompressor

The GeohashCompressor class is designed to compress an array of geohashes by finding the smallest possible set of geohashes that still cover the same area.

General Information

The GeohashCompressor algorithm has a time complexity of O(N^2), where N is the number of geohashes in the input array. The algorithm iteratively checks each input geohash and its parent geohash to determine if all subhashes are present in the input set. If they are, it replaces the input geohashes with the parent geohash, effectively compressing the geohashes. This process is repeated until no further compression can be achieved, resulting in a smaller set of geohashes that still covers the same area as the input geohashes.The performance of this algorithm can vary greatly depending on the size and complexity of the area covered by the input geohashes, as well as the desired precision of the compressed geohashes (determined by minlevel and maxlevel). In general, larger areas and higher precision levels will result in longer processing times.

Usage

GeohashCompressor compressor = new GeohashCompressor();
var input = new[] {
       "tdnu20", "tdnu21", "tdnu22", "tdnu23", "tdnu24", "tdnu25", "tdnu26", "tdnu27", "tdnu28", "tdnu29",
       "tdnu2b", "tdnu2c", "tdnu2d", "tdnu2e", "tdnu2f", "tdnu2g", "tdnu2h", "tdnu2j", "tdnu2k", "tdnu2m",
       "tdnu2n", "tdnu2p", "tdnu2q", "tdnu2r", "tdnu2s", "tdnu2t", "tdnu2u", "tdnu2v", "tdnu2w", "tdnu2x",
       "tdnu2y", "tdnu2z"
   };

var result = compressor.Compress(input); // Will return "tdnu2"

geohash-dotnet's People

Contributors

dependabot-preview[bot] avatar postlagerkarte avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

geohash-dotnet's Issues

polygon hasher has latitude and longitude swapped

private Geometry GeohashToPolygon(string geohash)
{
    var corners = geohasher.GetBoundingBox(geohash);

    var coordinates = new Coordinate[]
    {
        new Coordinate(corners[0], corners[2]),
        new Coordinate(corners[1], corners[2]),
        new Coordinate(corners[1], corners[3]),
        new Coordinate(corners[0], corners[3]),
        new Coordinate(corners[0], corners[2]),
    };

    var geometryFactory = new GeometryFactory();

    return geometryFactory.CreatePolygon(coordinates);

}

is incorrect the latitude and longitude are in the wrong order

public Coordinate(double x, double y);
// <returns>bounding box as double[] containing latInterval[0], latInterval[1], lonInterval[0], lonInterval[1]</returns>
public double[] GetBoundingBox(string geohash)

that is corners[0] and corners[1] are latittude/Y coordinates and corners[2] and corners[3] are longitude/X coordinates

code needs to be

private Geometry GeohashToPolygon(string geohash)
{
    var corners = geohasher.GetBoundingBox(geohash);

    var coordinates = new Coordinate[]
    {
        new Coordinate(corners[2], corners[0]),
        new Coordinate(corners[2], corners[1]),
        new Coordinate(corners[3], corners[1]),
        new Coordinate(corners[3], corners[0]),
        new Coordinate(corners[2], corners[0]),
    };

    var geometryFactory = new GeometryFactory();

    return geometryFactory.CreatePolygon(coordinates);

}

or

private Geometry GeohashToPolygon(string geohash)
{
    var corners = geohasher.GetBoundingBox(geohash);

    var coordinates = new Coordinate[]
    {
        new Coordinate {Y = corners[0], X = corners[2] },
        new Coordinate {Y = corners[1], X = corners[2] },
        new Coordinate {Y = corners[1], X = corners[3] },
        new Coordinate {Y = corners[0], X = corners[3] },
        new Coordinate {Y = corners[0], X = corners[2] },
    };


    var geometryFactory = new GeometryFactory();

    return geometryFactory.CreatePolygon(coordinates);

}

GetHashesAsync method not present in Geohasher class

i'm trying to build the project but geohash_test fails on the four calls to GetHashesAsync. there also appears to be a mismatch between the nuget package and this code. no worries as i can make tweaks and build a local library. thanks for the great work on this.

step for large polygons leads to gaps in the area coverage

double latStep = (maxy - miny) / 100;
double lonStep = (maxx - minx) / 100;

this step for large polygons leads to gaps in the coverage of the area with geohashes:

image

I suggest replacing it with the length and width of the geohash box:

double latStep = 180 / Math.Pow(2, (5*geohashPrecision-geohashPrecision%2)/2);
double lngStep = 180 / Math.Pow(2, (5*geohashPrecision+geohashPrecision%2)/2-1);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.