Jump to content
The simFlight Network Forums

calculating distance and heading to a defined series of GPS coordinates


Jason Fayre

Recommended Posts

Hi,

This may be out of the scope of what the .net library is meant to do, but thought I would post this here in case anyone has an idea.

We're working on integrating Bing Maps into the Talking Flight Monitor accessibility add-on.

Initially, this will tell the user what city, country, etc. that the user is flying over.

What we would like to do is give the user a virtual "look around" feature. So, for example, provide a key to list what features are coming up in the aircraft's current heading. So if the user is heading south out of Toronto, they might be told the US boarder is in 50 Nautical miles.

From Bing Maps, we can pull GPS coordinates that outline a city, country, State, etc. They are returned as a series of GPS coordinates outlining the geographic location. For example, the outline of Toronto is around 3000 points.

My question is, can anyone figure out a way of determining how far you are from a series of points like this, and then calculate distance and baring?

Trigonometry is definitely not my strong point, so I'm hoping someone has figured this out or something similar.

I know the .net DLL has functions for calculating distance between two points, but not sure how I would use that with a outline like this.

Any help or suggestions would be appreciated.

 

 

 

 

 

Link to comment
Share on other sites

Hi Jason,

There are some well-known methods for doing this that you can find on the net, but they do involve a bit of trigonometry.

I can add a class for this to the dll over the Christmas/New Year period. It will be a polygon class that will take in the list of Lon/Lat points for the outline of the area. You'll then be able to query if a location is inside or outside the area. Also, given a location and heading it will tell you if you will enter or exit the area and the distance to the crossing.

I think that covers what you want but let me know if there's anything else.

Paul

Link to comment
Share on other sites

11 minutes ago, Paul Henty said:

Hi Jason,

There are some well-known methods for doing this that you can find on the net, but they do involve a bit of trigonometry.

I can add a class for this to the dll over the Christmas/New Year period. It will be a polygon class that will take in the list of Lon/Lat points for the outline of the area. You'll then be able to query if a location is inside or outside the area. Also, given a location and heading it will tell you if you will enter or exit the area and the distance to the crossing.

I think that covers what you want but let me know if there's anything else.

Paul

Wow, just WOW. I can envision several uses for this. Awesome stuff sir.

James

 

Link to comment
Share on other sites

Hi,

 

I am the one working on this part of the project. To make clear, the lat/long of the plane is the only known constant. I will not know when, or where the points on the outline will appear in relation to the airplane. So, if I am flying heading 0, and want to take a "look" at heading 5, I will not know what points will appear at the given heading. This does solve 90% of our problems. The only thing left to figure out is the names of major bodies of water, given a GPS lat/long pair. At this point, Bing maps doesn't do this.

Link to comment
Share on other sites

Hi all,

I have this working. I've attached some screen shots below of my testing.

Before I release it, I'd like to know what kind of format you typically get the lon/lat points in. It'll make constructing the FsPolygons easier if you don't need to shuffle the point data around too much. e.g. It'll be a pain if my class wants lon, lat and your getting data with lat, lon.

Paul

image.thumb.png.99cf09e279a0d5973e7605c0002dbb0e.png

Link to comment
Share on other sites

8 minutes ago, Andy B. said:

The typical representation of a coordinate pair is lat, long as a decimal or double. Keeping it in this format will make things easier. Let me know if there is anything else you need before release.

Thanks. Do you have all the points in an array of lon, lat pairs, or in one continuous array?

e.g.

[
	[lat1, lon1],
	[lat2, lon2],
	etc
]

or 

[lat1, lon1, lat2, lon2, etc]

or something different?

Paul

Link to comment
Share on other sites

Hi,

 

I would certainly leave those options available. Our current mapping system uses a class to represent a coordinate pare, so the order doesn't really matter. Here is some sample code to demonstrate the GeoDataLocation class:

 

var request = new GetBoundaryRequest()
            {
                EntityType = BoundaryEntityType.PopulatedPlace,
                LevelOfDetail = 3,
                GetAllPolygons = true,
                GetEntityMetadata = true,
                Coordinate = new GeodataLocation(43.7001, -79.4163),
            }; // End request.
            var response = await GeodataManager.GetBoundary(request, "api key goes here");
            MessageBox.Show(response[0].Name.EntityName + response[0].EntityMetadata.PopulationClass).ToString();

            foreach (GeodataPolygon location in response[0].GetPolygons())
            {
                foreach(GeodataLocation point in location.ExteriorRing)
                {
                    latLongListBox.Items.Add($"{point.Latitude}, {point.Longitude}");
                }
            }
        }

Link to comment
Share on other sites

Version 3.1.25 is now available.

Overview:

There is a new class called FsLatLonPolygon. Its constructor takes in an array of FsLatLonPoint that defines the points (vertices) of a closed polygon. There can be any number of points. The polygon can be convex, concave or complex (having self-intersecting sides). 


Testing if a point is in a poylgon:

Once the polygon has been defined you can use the ContainsPoint() method to test if the given point is contained within the polygon. 

            FsLatLonPolygon london = new FsLatLonPolygon(londonOutline);
            FsLatLonPoint aircraftPosition = new FsLatLonPoint(currentLat, currentLon);
            if (london.ContainsPoint(aircraftPosition))
            {
                // over London
            }
            else
            {
                // not over London
            }

In the above code 'londonOutline' is an array of FsLatLonPoints that have been built from map data.


Searching for intersections on the polygon:

You can also test if you will cross the boundary of the polygon given your current location, heading and range. Use the method called GetIntersectionFromPointMetres (or use the feet or nautical mile version). In the code below we test if we'll cross the boundary given our current location and heading. The 'range' value limits the look ahead distance so you can exclude the polygon if its boundary is too far away.

The return value is a struct that contains various information about the intersection. These properties are shown in the code:

            // Look ahead to see if we are intersecting the London boundary on our current heading. Limit to 100km ahead.
            FsPolygonIntersection intersection = this.london.GetIntersectionFromPointMetres(aircraftPosition, currentHeadingTrue, 100000);

            // examine the FsPolygonIntersection object returned to get the results. The following information is avilable:
            bool inside = intersection.InsidePolygon; // true if the test point (aircraft position) was inside the polygon.
                                                      // If inside then any boundary crossing will be us LEAVING the zone.
                                                      // If outside then any boundary crossing will be us ENTERING the zone.
            if (intersection.Found)
            {
                // We will cross the boundary - get more info
                double distanceToGo = intersection.DistanceToMetres; // distance to the boundary. also avilable in feet and nautical miles
                FsLatLonPoint crossingPoint = intersection.Point; // The location of the crossing
                FsLatLonLineSegment crossingLineSegment = intersection.LineSegment; // The line segmeent of the polygon that we will cross.
            }
            else
            {
                // We will not cross the boundary
            }

The searches are very fast because the algorithms can very quickly reject polygons that can't possibly contain the point, or have any intersections, without an exhaustive search of every line segment. Only if an intersection is possible will it run the detailed checks using all the points and line segments.     

Paul

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.