Tronald / CoordinateSharp

A library designed to ease geographic coordinate format conversions, and determine sun/moon information in C#
Other
364 stars 59 forks source link

Pure UTM to LatLong and vice versa without Coordinate #105

Closed Rhybo closed 5 years ago

Rhybo commented 5 years ago

Is your feature request related to a problem? Please describe. I'm attempting to use CoordinateSharp to help translate UAV odometry messages from UTM to latitude and longitude doubles, then once again from latitude and longitude back to UTM coordinates without instantiating a Coordinate object. Currently, the amount of time required by a Coordinate object, even with EagerLoad disabled, is insufficient for my purposes since I'm creating a VR application in Unity. I'm receiving odometry messages through ROS (Robot Operating System), which is updating the positions of UAVs in my virtual environment (VE), and each UAV on the network has their own C# controller script which has an instance of Coordinate. When these Coordinate objects are updated (which is once every frame) my FPS drops to ~15, which is untenable for VR applications.

Describe the solution you'd like A rawUTMtoLatLong() that returns a double[ lat, long ]. Honestly, I would be able to use a Coordinate object for going from latitude and longitude to a UTM coordinate, but a function like rawLatLongToUTM() that somehow returns a whole UTM coordinate

Describe alternatives you've considered I've tried to make a DLL wrapper for a C++ script that attempts to do the same thing and I've considered other packages.

Additional Context Our project is developing a network control system that can optimally place UAVs as mobile network nodes and I'm attempting to represent their traditional 2d interfaces with an immersive 3d environment from which you can suggest positions for particular UAVs. For example, the network control system optimizes the topography of the mobile network given certain metrics, however, I'm particularly concerned about one UAV moving to a specific location and the network control system may optimize its topography around my preferences. Given the UAV's UTM coordinates, I'm instantiating them within my VE and constantly updating their positions to represent their actual positions in 3d space (I'm using a program called Mapbox, which has a Unity package, to do this). I need to convert the UTM coordinates to latitude and longitude to represent them above Mapbox's terrain, I need to recommend new positions for UAVs of my choice, and those recommended positions need to be turned back into UTM coordinates to be fed back to the UAVs themselves for navigation.

Long winded, I apologize. You've put together a wonderful product thus far, I just wish it had some side helper functions for folks looking for the raw calculation output and not necessarily storing them within a Coordinate data object.

Tronald commented 5 years ago

Thank you for checking out CoordinateSharp and sharing the details of your project. It sounds really cool!

I just benchmarked the UTM to Coordinate Conversion and it currently take 25ms, which I agree is WAY to long if you are looking for efficiency. Luckily the logic for what you are describing is already in the library, we just need to change and expose a couple things so you can use it.

I just tested a UTM to Signed Degree function that returns a double array, and converted back to Lat/Long with EagerLoad off and it benchmarked at less the 1 ms. Example:

UniversalTransverseMercator utm = new UniversalTransverseMercator("T", 41, 691505, 5022849);
double[] d = UniversalTransverseMercator.ConvertUTMtoSignedDegree(utm);
Coordinate c = new Coordinate(d[0], d[1], new EagerLoad(false));

The library was designed with one way conversion in mind. Converting from other formats back to Lat/Long were an after though, which is why there may be efficiency issues. They are fixed as they are pointed out though so thank you.

We are currently BETA testing 2.1.1.1. I have no problem adding this feature to this version and releasing a new BETA. I will have this out for you by days end :)

Tronald commented 5 years ago

It ended up being a very minimal change. Methods have been exposed and tests added to confirm.

You may download v2.1.1.1 BETA 2 from Nuget or from www.coordinatesharp.com. The Nuget package is a pre-release and may take a bit to index and show available. If you are downloading from Visual Studio, you may need to ensure you can view pre-release packages as well.

You may also fork the Master if you wish.

The method I listed above will work and give you a much faster benchmark. If you need to start with a coordinate object, turn EagerLoad off for everything but UTM and you should still see good benchmarks.

Side Note: The double array returned contains the signed Lat/Long values.

Please let me know if it works out for you, or if you experience any issues. Thank you again for bringing this to our attention.

Rhybo commented 5 years ago

Thank you! I completely missed the UniversalTransverseMercator.ConvertUTMtoSignedDegree(utm); method. I should be able to test the conversion back to LatLong later today and I'll let you know if it is acceptable for my use case... thank you again!

Tronald commented 5 years ago

No worries, the function itself wasn't in there, but the code for it was embedded inside of internal functions (which is why you would have missed it). I just needed to wrap it so it could be used. Can't wait to hear if it works.

Rhybo commented 5 years ago

Thanks again @Tronald, I'm representing UAV positions now without any performance penalty! That being said, I may have discovered a new bug dealing with calling on a new Coordinate's UTM property. Currently, it is giving me a null value:

Debug.Log("suggestedPosition.x is " + suggestedPosition.x + " of type " + suggestedPosition.x.GetType());
            Debug.Log("suggestedPosition.y is " + suggestedPosition.y + " of type " + suggestedPosition.y.GetType());

            c = new Coordinate(suggestedPosition.x, suggestedPosition.y, new EagerLoad(false));
            Debug.Log("The coordinate object c is " + c );

           **Debug.Log("The coordinate object's UTM, c.UTM is " + c.UTM + c.UTM.GetType());**
            Debug.Log(" Evaluating <b>sb.Append(c.UTM.LongZone.ToString())</b> : \n" +
                "c.UTM.LongZone: " + c.UTM.LongZone);
            Debug.Log(c.UTM.LongZone.GetType());
            Debug.Log("c.UTM.LatZone: " + c.UTM.LatZone);
                Debug.Log("c.UTM.LongZone" + c.UTM.LongZone + "\t" + c.UTM.LatZone.GetType() 
                );

The double-asterisks are not in my code, but they indicate where I am currently having a problem. That line returns a NullReference in my Unity logger.

Let me know if you want me to open a new issue.

Tronald commented 5 years ago

This is most likely due to EagerLoading being off. You can turn it on for UTM_MGRS only with minimal performance hit.

Change line 3 in the example I provided from

Coordinate c = new Coordinate(d[0], d[1], new EagerLoad(false));

to

Coordinate c = new Coordinate(d[0], d[1], new EagerLoad(EagerLoadType.UTM_MGRS));

This will allow the UTM values to EagerLoad.

Alternatively you can manually load the values when ready using if you don't wish to EagerLoad. Coordinate.LoadUTM_MGRS_Info(); Once you call this function the UTM values will no longer be null in the coordinate object.

Let me know if that solves your problem.

Rhybo commented 5 years ago

I just realized that it was because I was misunderstanding my EagerLoad settings and moving fast and dumb. You beat me to the punch, thank you for your responsiveness! This fixes all of the issues I was having and it's running smooth now. Thank you again.

Tronald commented 5 years ago

HAHA I totally understand that! Glad you could get it working and thanks again for your suggestions!