Giter Site home page Giter Site logo

h3net's Introduction

H3NET: A Hexagonal Hierarchical Geospatial Indexing System In C#

H3Net is a geospatial indexing system using hexagonal grid that can be (approximately) subdivided into finer and finer hexagonal grids, combining the benefits of a hexagonal grid with S2 hierarchical subdivisions, mostly translated from the original C code from Uber's H3 project. h3net logo

Why? There's already a version in C!

The short version:

I'm working on a project that needs H3 capabilities in C#. When I first started this, I could make the bindings work on desktop, but not mobile, so I wrote the 3.1.1 version. Working with it in my project over the past couple of years, along with some of the new things in H3, I came back to it to work with 3.7.1 capabilities.

That's what's here now. I'm still working on it, but it's now at a usable, albeit lightly documented state. You really should check out the H3 link I placed before, if you want to know what's involved here.

History

  • Current (3rd round) - Currently has the same capability as 3.7.2, if not exactly the same syntax.
  • Version 2 - A horrible attempt to implement H3 v3.2.1, and I've removed the branch for it.
  • Version 1 - According to my Git repository, I pushed it on November 16, 2018. It has the capability of Uber H3 3.1.1, but it has a horrible API.

Caveat Emptor

This doesn't work exactly like H3, especially under the hood, but it's close enough for most work, I feel.

Right now, you can probably work your way through the syntax in Api.cs in the lib directory. For actual use, I've got a fluid API to chain commands together, though most of that is being used internally.

I'm also going to be closing off access to the internals shortly so that functionality reflecting the API will be the only direct access to the code.

At this point, the only comprehensive documentation is the auto-generated file at H3Lib/Documentation. Keep an eye on that directory as I'll be cleaning that up next.

Input

I'm going to be doing the following:

  • Cleaning up the code, including some of the brute force translations
  • Extracting/writing documentation for the library
  • Probably adding a few unit tests for the modifications I've made.

You can help too. Fork and make a PR, and we'll go from there.

Caveat Emptor II

I wanted to get this done in a month. I have. It's nowhere near the polished state I want it to be, but it works, and it passes 200+ unit tests. It's now ready to be played with.

Don't go crazy with it just yet, as I'm going to clean it up some more, work on documentation, deal with TODO's in the code, and so forth. At some point after that, I'll have an actual release.

Testing

For the most part, I've converted the unit tests from the original H3 project to work in h3net. They were extremely helpful with the architecture change going from 3.1.1 to 3.7.1.

Some corner cases weren't convertible as they tested for null objects while h3net uses primarily extension methods on readonly structs. Where this has come up, I've documented it in the appropriate unit test file.

Version

I will be keeping the version number the same as the functionality of H3 that I'm matching.

Currently: 3.7.2

Previous: 3.7.1

Badges

.NET Maintainability JetBrains Rider H3 3.7.2 Burma Shave

Fin

Hexagons are the bestagons

h3net's People

Contributors

mattias01 avatar richardvasquez 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

Watchers

 avatar  avatar  avatar  avatar  avatar

h3net's Issues

Rename assembly to h3net not h3lib to avoid conflicts with bindings lib

Hi!

The assembly for h3net is h3lib.dll which creates conflicts as the DLL requirement of the bindings library H3.Standard (nuget package seems different from code, as code expects h3.dll and nuget package wants h3lib.dll) which requires a DLL h3lib.dll to be built and copied from the C library.

This means these two libraries cannot be easily used side by side 🤔

Unit Test Failure: h3_136

TestSuite.TestPolyfillReported.h3_136

Expected: 4355
But was: 4353

at TestSuite.TestPolyfillReported.h3_136() in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\TestPolyfillReported.cs:line 140

Unit Test Failure: cell_area_positive

TestSuite.TestH3CellAreaExhaustive.cell_area_positive

Expected: greater than 0.0d
But was: NaN

at TestSuite.TestH3CellAreaExhaustive.cell_area_assert(H3Index cell) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\TestH3CellAreaExhaustive.cs:line 73
at TestSuite.Lib.Utility.IterateBaseCellIndexesAtRes(Int32 res, Action1 callback, Int32 baseCell) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\Lib\Utility.cs:line 51 at TestSuite.Lib.Utility.IterateAllIndexesAtResPartial(Int32 res, Action1 callback, Int32 baseCells) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\Lib\Utility.cs:line 35
at TestSuite.Lib.Utility.IterateAllIndexesAtRes(Int32 res, Action`1 callback) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\Lib\Utility.cs:line 20
at TestSuite.TestH3CellAreaExhaustive.cell_area_positive() in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\TestH3CellAreaExhaustive.cs:line 120

Unite Test Failure: h3UniEdgeBoundary

Expected: 2
But was: 3

at TestSuite.TestH3UniEdgeExhaustive.H3UniEdgeBoundaryAssertions(H3Index h3) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\TestH3UniEdgeExhaustive.cs:line 55
at TestSuite.Lib.Utility.IterateBaseCellIndexesAtRes(Int32 res, Action1 callback, Int32 baseCell) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\Lib\Utility.cs:line 51 at TestSuite.Lib.Utility.IterateAllIndexesAtResPartial(Int32 res, Action1 callback, Int32 baseCells) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\Lib\Utility.cs:line 35
at TestSuite.Lib.Utility.IterateAllIndexesAtRes(Int32 res, Action`1 callback) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\Lib\Utility.cs:line 20
at TestSuite.TestH3UniEdgeExhaustive.h3UniEdgeBoundary() in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\TestH3UniEdgeExhaustive.cs:line 90

.NET target framework support

The purpose of #14 was so that I can use this library in a .NET 4.6.2 project that I have.
The choice of targeting the older .NET standard 2.0 and not using C# 8 features was delibarate, so that projects not using the latest .NET versions can use this library.

Supported frameworks are detailed here:
https://docs.microsoft.com/en-us/dotnet/standard/net-standard

For example:

  • .NET standard 2.0 supports .NET 4.6.1+ (2015) and .NET Core 2.0+
  • .NET standard 2.1 only supports .NET Core 3.0+ (2019)

Since #14, the library itself does not need to target .NET standard 2.1 and C# 8, but some of the code in the test suite does. The test suite code can of course also be ported to not use C# 8 features, but I'm not sure I see the value of doing that.

I'm suggesting retargeting the library back to .NET standard 2.0 (instead of .NET standard 2.1), removing the C# 8 requirement and letting the test suite only target .NET 5.

I can supply a PR if necessary.

Need to complete XML documentation

There's about 130 90 public elements that need to be examined and determinations as to whether they need to be documented or need to be made internal.

Implementation is not the same as Uber's C library

Hello, I've tried to integrate two services - one to populate the DB with h3 hashes (using Java h3 bindings) and the other for searching (using your .Net Core implementation), and found out that your implementation does not match Uber's.
For the same coordinates (i.e., 52.353553,4.883015) and resolution (i.e., 5) I get:

  • 599166370717892607 => 0x0850aaa3bfffffff from your library
  • 599425793185021951 => 0x085196953fffffff from Java bindings

I've double checked with Python bindings, and as they have the same C lib underneath I got the same result as Java.

Is it intended to be that way or is it a bug? Because it works fine when using only your library, but integration with different implementations is not possible

Unit Test Failure: FillIndex

h: 0801dfffffffffff
nextRes: 1
currentRes: 0
Expected: 6
But was: 5

at TestSuite.TestPolyfill.fillIndex_assertions(H3Index h) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\TestPolyfill.cs:line 114
at TestSuite.Lib.Utility.IterateBaseCellIndexesAtRes(Int32 res, Action1 callback, Int32 baseCell) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\Lib\Utility.cs:line 51 at TestSuite.Lib.Utility.IterateAllIndexesAtResPartial(Int32 res, Action1 callback, Int32 baseCells) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\Lib\Utility.cs:line 35
at TestSuite.Lib.Utility.IterateAllIndexesAtRes(Int32 res, Action`1 callback) in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\Lib\Utility.cs:line 20
at TestSuite.TestPolyfill.FillIndex() in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\TestPolyfill.cs:line 338

Overall accuracy

I'm going to try integrating a library to increase the accuracy of trig functions as that seems to be the breaking point from the C source

Inaccurate API results

Hey thanks for the library. I am trying to use this but I am getting inconsistent behavior and after doing some debugging some APIs just seem to return incorrect results

If I run this for example the boundaries returned are nowhere near the original coordinates

var index = Api.GeoToH3(new GeoCoord(40.759114m, -73.988546m), 6);
Api.H3ToGeoBoundary(index, out var boundary);
foreach (var vert in boundary.Verts)
{
    Console.WriteLine(vert);
}

The results I get are

GeoCoord: (Lat,Lng) 0.082073252, -1.731777291
GeoCoord: (Lat,Lng) 0.081735427, -1.732271961
GeoCoord: (Lat,Lng) 0.081157382, -1.732255957
GeoCoord: (Lat,Lng) 0.080917029, -1.731745166
GeoCoord: (Lat,Lng) 0.081254917, -1.731250309
GeoCoord: (Lat,Lng) 0.081833095, -1.731266429
GeoCoord: (Lat,Lng) 0.000000000, 0.000000000
GeoCoord: (Lat,Lng) 0.000000000, 0.000000000
GeoCoord: (Lat,Lng) 0.000000000, 0.000000000
GeoCoord: (Lat,Lng) 0.000000000, 0.000000000

If I do the same in the h3 js library with the following code

let testIndex = h3.geoToH3(40.759114, -73.988546, 6);
let testBoundaries = h3.h3ToGeoBoundary(testIndex);
for (let test of testBoundaries)
{
    console.log(test);
}

I get the results

(2) [40.77396440203853, -73.94384490497664]
(2) [40.76659438221225, -73.98852232840895]
(2) [40.73537602621502, -74.0022744646159]
(2) [40.71154393543933, -73.97139376102862]
(2) [40.71890320501306, -73.92676660481357]
(2) [40.75010530534532, -73.91296992347031]

I noticed this behavior as I was trying to investigate why I couldn't get kring to work correctly in this library. I dont get results similar to what I'd expect if I write similar code to what works in the uber js lib.

Thanks

Indexing moving points

I'm developing a system, where I have a list of 100,000 geolocations and 10,000 geolocations of cars that are moving, and every X seconds, the vehicle's location update occurs, that is, at the same time I can receive N vehicle location updates .
My problem is, every X seconds, the system needs to search for all vehicles that are close to a location L, currently, the system goes through the list of geolocations looking for all vehicles that are within the specific radius.

My doubt is whether it is possible to use this lib, and the index part of it, to reduce the overhead in this process of searching vehicles near a location L, and, it is thread safe ?
Thanks

Unit Test Failure: h3ToGeoBoundary_classIIIEdgeVertex

TestSuite.TestH3Api.h3ToGeoBoundary_classIIIEdgeVertex

Expected: 7
But was: 8

at TestSuite.TestH3Api.h3ToGeoBoundary_classIIIEdgeVertex() in C:\Users\catch\Documents\JetBrainsGitHub\h3\Tests\NUnit\H3Suite\TestH3Api.cs:line 45

GeoJSON

What's the recommended way to load geojson files into h3net?

Nuget package?

Usage via a package manager would be a nice QoL addition.

The setup is pretty easy, setup package info & build output in the .csproj, version it, and upload it to nuget.org.


If you want I can setup the .csproj & build output and make a PR, though the actual upload to nuget has to be done by you.

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.