Skip to content
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

Examples #48

Closed
infinityplusb opened this issue Oct 19, 2021 · 9 comments
Closed

Examples #48

infinityplusb opened this issue Oct 19, 2021 · 9 comments
Labels
documentation Improvements or additions to documentation

Comments

@infinityplusb
Copy link

Just trying to get some of the library working, but running into some issues.
In particular, at the moment is finding the vertices of a H3 cell.
I'm trying to use

var vertices = index.GetCellBoundary().Coordinates

but vertices is of length 0. :(
if I use

var vertices = index.GetCellBoundaryVertices().ToArray();

that doesn't seem to be returning anything useful.
It'd be great to have some examples of simple stuff like that, and/or some sort of comparison between this api and the "standard" api.

TIA

@pocketken
Copy link
Owner

Hi @infinityplusb,

Agreed -- documentation / examples (and in particular, differences vs. the upstream library) are on my list of things to try and improve for the next release. I've just been swamped with other work-things as of late and haven't had any time yet to crank it out.

GetCellBoundryVertices() returns an IEnumerable<GeoCoord>, so for that you'll definitely need to use .ToList(), .ToArray() or iterate through in order to get all the vertices. Presently that returns H3.Model.GeoCoord objects, corresponding with the same in the upstream lib -- although I think that's being renamed to LngLat or something in 4.0. In any case, its lon/lat in radians. You should be able to use .ToCoordinate() on a GeoCoord if you want a NTS Coordinate in degrees (or .ToPoint() if you want a Point).

GetCellBoundary() should be returning a NTS Polygon, so, in that case as long as it's returning a valid polygon I can't see any reason why Coordinates would be giving you an empty result. Is vertices.IsEmpty true? If you could provide the index value you're using I can always try and reproduce here. GetCellBoundary uses GetCellBoundaryVertices, so, if you're not getting the individual vertices that would obviously explain an empty polygon.

@infinityplusb
Copy link
Author

So, I actually tried to port it to netstandard2.0 (because I am actually wanting to use it as part of Unity Game Engine for some displays), so it's possible I messed up something on the port.
I'm getting vertex length, cause it iterates correctly through all 6 vertices, but it's either it's returning back gibberish vertex values, I'm decoding them incorrectly, or something else.

Anyway the code I'm trying to run:

static void Main(string[] args)
{
    Console.WriteLine("Hello World!");
    
    double lat = -37.81753;
    double lng = 144.96715;
    GeoCoord melb = new GeoCoord(lat, lng);
    // 10 - 622496586184982527
    //  9 - 617992986557677567
    H3Index melbH3 = H3Index.FromGeoCoord(melb, 10);
    Console.WriteLine(melbH3);
    Console.WriteLine("Melb Lat, Long: " + melb.Latitude + "," + melb.Longitude);
    
    var CellBoundariesVertArray = melbH3.GetCellBoundaryVertices().ToArray();
    Console.WriteLine("Cell Boundaries Vertices: ");
    for (int i = 0; i< CellBoundariesVertArray.Length; i++)
    {
        Console.WriteLine("Vertex: " + (i+1));
        var thing = CellBoundariesVertArray[i];
        
        // Trying a few different things to test
        Console.WriteLine("ToCoordinate: " + thing.ToCoordinate());
        Console.WriteLine("ToPoint: " + thing.ToPoint());
        Console.WriteLine("ToPoint Length: " + thing.ToPoint().Length);
    
        Console.WriteLine("Lat, Long: " + thing.Latitude + "," + thing.Longitude);
        
        Console.WriteLine();
    }
}

The output I get looks like:

Hello World!
624149068197953535
Melb Lat, Long: -37.81753,144.96715
Cell Boundaries Vertices:
Vertex: 1
ToCoordinate: (0, 90)
ToPoint: POINT (0 90)
ToPoint Length: 0
Lat, Long: 1.5707963267949,0

Vertex: 2
ToCoordinate: (0, 90)
ToPoint: POINT (0 90)
ToPoint Length: 0
Lat, Long: 1.5707963267949,0
... etc

@pocketken
Copy link
Owner

So, I actually tried to port it to netstandard2.0 (because I am actually wanting to use it as part of Unity Game Engine for some displays), so it's possible I messed up something on the port. I'm getting vertex length, cause it iterates correctly through all 6 vertices, but it's either it's returning back gibberish vertex values, I'm decoding them incorrectly, or something else.

Ah, interesting ok. I'd be interested in seeing what you ended up having to do to go back to netstandard2.0 -- I have 2.1 in progress in another branch. Probably wouldn't hurt to support 2.0 as well.

In this case, I think I've found your issue though:

    double lat = -37.81753;
    double lng = 144.96715;
    GeoCoord melb = new GeoCoord(lat, lng);

As I mentioned previously, GeoCoord takes lat/lon in radians not degrees. Try var melb = GeoCoord.FromCoordinate(144.96715, -37.81753) and let me know if that works any better for you.

@infinityplusb
Copy link
Author

So that doesn't let me call use GeoCoord.FromCoordinates() like that:

No overload for method 'FromCoordinate' takes 2 arguments	

I can add in an overload

public static GeoCoord FromCoordinate(double latd, double lngd) => new()
{
    Latitude = latd * M_PI_180,
    Longitude = lngd * M_PI_180
};

which means I end up with a different hash value 624846090291314687 but again when I iterate through the vertices, it just gives me gibberish:

Cell Boundaries Vertices:
Vertex: 1
ToCoordinate: (0, 90)
ToPoint: POINT (0 90)
ToPoint Length: 0
Lat, Long: 1.5707963267949,0
...

@pocketken
Copy link
Owner

So that doesn't let me call use GeoCoord.FromCoordinates() like that:

No overload for method 'FromCoordinate' takes 2 arguments	

Err.. yeah, see that's what happens when I respond to issues before coffee. I meant GeoCoord.FromCoordinate(new Coordinate(lon, lat)). My bad..

which means I end up with a different hash value 624846090291314687 but again when I iterate through the vertices, it just gives me gibberish:

So, in net5.0 and netcoreapp3.1, I just tried this:

using H3.Extensions;
using H3.Model;
using NetTopologySuite.Geometries;
using System;
using System.Linq;

namespace H3.Test {

    public class Program {

        static void Main(string[] args) {
            var melbCoord = new Coordinate(144.96715, -37.81753);
            var melb = H3Index.FromGeoCoord(GeoCoord.FromCoordinate(melbCoord), 10);
            Console.WriteLine(melb.ToString());

            var vertices = melb.GetCellBoundaryVertices().ToArray();

            foreach (var vertex in vertices) {
                Console.WriteLine(vertex.ToCoordinate());
            }

        }

    }
}

And I get:

8abe635631affff
(144.96778125123538, -37.817743157190876)
(144.96795254146156, -37.817013693350674)
(144.96724330949056, -37.816526409416625)
(144.9663627878137, -37.81676858358098)
(144.96619148449943, -37.81749804339748)
(144.96690071594998, -37.81798533307338)

Or POLYGON ((144.96778125123538 -37.817743157190876, 144.96795254146156 -37.817013693350674, 144.96724330949056 -37.816526409416625, 144.9663627878137 -37.81676858358098, 144.96619148449943 -37.81749804339748, 144.96690071594998 -37.81798533307338, 144.96778125123538 -37.817743157190876)) which looks like this:

image

Which looks like its working ok.. so if you're still having issues then it could be related to your port. I'll create a new issue to formally support netstandard2.0 and take a crack at it myself for the next release. You're not the first person to mention support for older versions of .NET, so, I might as well.

@pocketken
Copy link
Owner

@infinityplusb I had a quick look at your fork and used that as a guide for implementing support for netstandard2.0 in the dev/km/moar-fastar branch -- thanks!. It's passing the test suite for net5.0, netcoreapp3.1 and net48, but I don't have Unity installed myself to be able to do any specific testing related to that. If you want to try that branch out and let me know if it's working for you that'd be great.

Along those lines, if there's anything else package or documentation-wise that helps for utilizing this in Unity, it'd be great if you would be able to contribute those bits so that I can include them in the next release.

FYI, I think this might actually be your bug -- your "polyfill" for Math.Clamp has min and max swapped:

                    double sinLon = Clamp(Math.Sin(az) * sinDist / cosP2Lat, -1.0, 1.0);
                    double cosLon = Clamp((cosDist - sinP1Lat * Math.Sin(p2.Latitude)) / cosP1Lat / cosP2Lat, -1.0, 1.0);
        public static T Clamp<T>(T value, T max, T min)
            where T : System.IComparable<T>
        {
            T result = value;
            if (value.CompareTo(max) > 0)
                result = max;
            if (value.CompareTo(min) < 0)
                result = min;
            return result;
        }

whereas Math.Clamp would be T value, T min, T max.

Cheers!

@pocketken
Copy link
Owner

@infinityplusb I've added some basic documentation in this branch as well. I'm hoping to release in the next week or two depending on how busy things are with work.

Let me know if there's anything else in particular you're looking for and I'd be happy to help.

@pocketken pocketken added the documentation Improvements or additions to documentation label Oct 24, 2021
@infinityplusb
Copy link
Author

That's what I get for copy-pasting stuff from StackOverflow!
Thanks. Swapping the max and min in the function call fixed the issue.
I still get a fully numeric id, and not a alphanumeric, not sure if that'll be a problem later. :)

I'll try draw it and see what that looks like :)

@pocketken
Copy link
Owner

I still get a fully numeric id, and not a alphanumeric, not sure if that'll be a problem later. :)

I think that's because of the implicit operator for converting to ulong; seems Console.WriteLine wants to give you that instead of calling .ToString(). If you explicitly throw the .ToString() you should get the hex instead of base 10 value.

Glad to hear that was your issue. I am going to go ahead and close this now; feel free to yell at me or open a new issue if you have any further questions or difficulties!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

2 participants