Jump to content
The simFlight Network Forums
idoen

Cant read nearest icao in c#

Recommended Posts

Hi Ido,

 

Declare the offset like this:

private Offset<string> nearestICAO = new Offset<string>(0x0658, 4);

Then in your code, after the process(), read the value like this:

FSUIPCConnection.Process();
MessageBox.Show("Nearest airport is " + this.nearestICAO.Value);

Paul

Share this post


Link to post
Share on other sites

Hi Ido,

 

Declare the offset like this:

private Offset<string> nearestICAO = new Offset<string>(0x0658, 4);

Then in your code, after the process(), read the value like this:

FSUIPCConnection.Process();
MessageBox.Show("Nearest airport is " + this.nearestICAO.Value);

Paul

Hi Paul,

 

Everything works now.

Thank you very much for your quickly reply.

 

Ido

Share this post


Link to post
Share on other sites

In the zip file that you downloaded there is a docs folder. In there is a file called userguide.pdf. On page 7 there is a table explaining how to choose the variable type from the information given in Pete's document "FSUIPC4 Offset Status.pdf".

 

Paul

Share this post


Link to post
Share on other sites

In the zip file that you downloaded there is a docs folder. In there is a file called userguide.pdf. On page 7 there is a table explaining how to choose the variable type from the information given in Pete's document "FSUIPC4 Offset Status.pdf".

 

Paul

Thank you very much!

Share this post


Link to post
Share on other sites

Hi Paul,

 

Is there a way to have the nearest airport from given coordinates ?

 

private Offset<string> nearestICAO = new Offset<string>(0x0658, 4);

...

double Lat = 48.4

double Lon = -4.4

 

private string NearestAirpot(Lat, Lon)

{

...

FSUIPCConnection.Process();
...

return this.nearestICAO.Value;  // "LFRB"

}

 

Thank you for your help !

 

Motus

Share this post


Link to post
Share on other sites

Is there a way to have the nearest airport from given coordinates ?

 

No. FSX/P3D only provides nearest airports to the current user aircraft position. You'd need to search a database for your needs.

 

Pete

Share this post


Link to post
Share on other sites

Ou tu peux lire le fichier runway.csv fait à partir de Makerunways 

 

Ex: http://forum.simflight.com/topic/79503-howto-find-runway-in-use-by-wind-direction/#entry481072

 

You can read runway.csv to know the nearest ICAO

Ex: http://forum.simflight.com/topic/79503-howto-find-runway-in-use-by-wind-direction/#entry481072

 

Look at here (thanks to Paul again).

 

Regards Fred

Share this post


Link to post
Share on other sites
On 13/12/2014 at 2:52 PM, Paul Henty said:

Hi Ido,

 

Declare the offset like this:


private Offset<string> nearestICAO = new Offset<string>(0x0658, 4);

Then in your code, after the process(), read the value like this:


FSUIPCConnection.Process();
MessageBox.Show("Nearest airport is " + this.nearestICAO.Value);

Paul

Hello Paul,

i'm trying this code but in vb.net and only show icao from p3d v4. From fs9/fsx sp2/p3d v3.4 is not showing.

Is there another workaround to show on all simulators? Didnt find anything.

Can you help me with a function to get nearest airport(s) in X miles range with makerunways files like airports.fsm?

Thank you

Share this post


Link to post
Share on other sites

It works fine here on FSX Steam Edition.

    Private NearestICAO As Offset(Of String) = New Offset(Of String)(&H658, 4)
        FSUIPCConnection.Process()
        MessageBox.Show("Nearest Airport is " + NearestICAO.Value)

It won't work on FS9 (this feature is not included in FSUIPC3), and the documentation says it doesn't work on FSX earlier than SP2.

If you want a solution that will work with all sims including FS9 you will need use the makerunways files.

Here is an example of a function that reads the runways.csv file produced by makerunways.exe.

It assembles a list of all airports within a requested radius.

First you'll need to define this structure (outside any other classes)
 

Public Structure AirportInfo
    Public ICAO As String
    Public DistanceNM As Double

    Public Sub New(ICAO As String, DistanceNM As Double)
        Me.ICAO = ICAO
        Me.DistanceNM = DistanceNM
    End Sub

End Structure

Then add this function to your normal class/form:

Private Function getAirportsInRangeNM(ByVal playerPos As FsLatLonPoint, ByVal radiusNM As Double) As List(Of AirportInfo)
        Dim AirportsInRange As List(Of AirportInfo) = New List(Of AirportInfo)()
        ' Search the Runways.csv file
        Dim foundAirports As Dictionary(Of String, Double) = New Dictionary(Of String, Double)()
        Dim runwaysFile As String = "E:\SteamLibrary\steamapps\common\FSX\Runways.csv" ' !!CHANGE THIS!!
        Using MyReader As New FileIO.TextFieldParser(runwaysFile)
            MyReader.TextFieldType = FileIO.FieldType.Delimited
            MyReader.SetDelimiters(",")
            While Not MyReader.EndOfData
                Try
                    Dim currentRow As String() = MyReader.ReadFields()
                    Dim icao As String = currentRow(0)
                    Dim lat As Double = Double.Parse(currentRow(2))
                    Dim lon As Double = Double.Parse(currentRow(3))
                    ' Work out the distance from the player
                    Dim runwayPoint As FsLatLonPoint = New FsLatLonPoint(New FsLatitude(lat), New FsLongitude(lon))
                    Dim distance As Double = runwayPoint.DistanceFromInNauticalMiles(playerPos)
                    If (distance) <= radiusNM Then
                        If (foundAirports.ContainsKey(icao)) Then
                            ' if this runway is closer we'll use this one
                            If distance < (foundAirports(icao)) Then
                                foundAirports(icao) = distance
                            End If
                        Else
                            foundAirports.Add(icao, distance)
                        End If
                    End If
                Catch ex As FileIO.MalformedLineException
                    'MsgBox("Line " & ex.Message & "is not valid and will be skipped.")
                End Try
            End While
            MyReader.Close()
            MyReader.Dispose()
        End Using
        ' Now have all the airports in range
        ' Add them to the output list and sort by distance
        For Each icao As String In foundAirports.Keys
            AirportsInRange.Add(New AirportInfo(icao, foundAirports(icao)))
        Next
        AirportsInRange.Sort(Function(x, y) x.DistanceNM.CompareTo(y.DistanceNM))
        Return AirportsInRange
    End Function

Note that I've hard-coded my path to the runways.csv file. If your app is not just for you, you'll need to have a variable with the users FS install path in.

Here's an example of how it's used:

1. You'll need the current players lon/lat if you haven't got those already:

    Public playerLatitude As Offset(Of Long) = New Offset(Of Long)(&H560)
    Public playerLongitude As Offset(Of Long) = New Offset(Of Long)(&H568)

2. This code calls the function and displays all airports within 50nm in a message box:

        FSUIPCConnection.Process()
        ' Set up current player position
        Dim playerPos As FsLatLonPoint = New FsLatLonPoint(New FsLatitude(playerLatitude.Value), New FsLongitude(playerLongitude.Value))
        ' get list of airports within 50nm
        Dim airports As List(Of AirportInfo) = getAirportsInRangeNM(playerPos, 50)
        ' print them out
        Dim msg As String = ""
        For Each airport As AirportInfo In airports
            msg += airport.ICAO + ": " + airport.DistanceNM.ToString("F0") + "NM" + vbNewLine
        Next
        MessageBox.Show(msg)

The List of airports is in order of distance, the closest will be index 0.

Paul

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Hello Paul thank you for your reply.

I change this to get it working

Dim lat As Double = Double.Parse(currentRow(2))
Dim lon As Double = Double.Parse(currentRow(3))

to this

Dim lat As Double = Double.Parse(currentRow(2), CultureInfo.InvariantCulture)
Dim lon As Double = Double.Parse(currentRow(3), CultureInfo.InvariantCulture)

and now its working perfect, just what i need.

Thank you for your time and help i appreciate.

Helder

Share this post


Link to post
Share on other sites
Dim lat As Double = Double.Parse(currentRow(2), CultureInfo.InvariantCulture)
Dim lon As Double = Double.Parse(currentRow(3), CultureInfo.InvariantCulture)

Ah, yes. I forgot that European number formats are different.

Thanks for the correction.

Paul

Share this post


Link to post
Share on other sites

Hi Paul,

I am also having a problem with this facility in FSX : Steam and cannot find out what is wrong with it:

I am declaring  this for testing purposes,

private Offset<byte[]> nearestAirports = new Offset<byte[]>(0x0658, 120);
   
private Offset<string> nearestAirport = new Offset<string>(0x0658, 4);

but after the call to FSUIPCConnection.Process() I have neither ICAO string in the nearestAirport value, nor in the nearestAirports byte array, which should contain all 6 airport data. All their bytes are zero.

Other facilities like radio altitude at 0x31E4, or startup-situation at 0x0024 are working as expected.

Should it matter, I am using the latest registered FSUIPC (4.972) and FSX:SE in version 10.0.62615.0, which should be up-to-date, either.

Do you have any idea, if it is still supposed to work and if yes, what then might be the culprit for my problem?

All the best,

Benny

 

Share this post


Link to post
Share on other sites

Hi Benny,

It should work. I have the same version of FSX:SE and FSUIPC as you and it's fine here:

        private Offset<string> nearestICAO = new Offset<string>(0x0658, 4);
        private Offset<string> secondNearestICAO = new Offset<string>(0x066C, 4);
            FSUIPCConnection.Process();
            MessageBox.Show("Nearest airport is " + this.nearestICAO.Value + ", then " + this.secondNearestICAO.Value);

 

Try monitoring offset 0658 using the logging features of FSUIPC. Display on the FS Window like this...

fsuipcLogging.png.2e048a1305c1f1c21d198e0a5745a1d5.png

There'll be a few extra characters at the end because the string isn't 0 terminated. But just make sure the first 4 are correct.

If the logged value is not okay then you'll need to ask Pete about it in the main support forum.

If it is okay, then there is something wrong in your program, or the version of the DLL you're using. I've attached the latest for you to try in this case. Note however that it only targets the .Net 4.0 framework (not Client Profile). It's also okay if your program uses a later version of the framework.

Paul

FSUIPCClient3.0_RC5.zip

Share this post


Link to post
Share on other sites

Thanks Paul, for the very quick and detailed response. Had already tried the FSUIPC logging facilities with the same results, unfortunately...all zeros. But reading through the forums, I accidentally already found on of your mentioned solutions: I wasn't using the latest version of your dll and using the 3.0RC5 fixed the all-zero-bytes problem.

But now comes the next one: tried out EDDC, EDDF and KJFK I am not getting those airports in the 6 airports list that are returned by 0x0658...only ones that are farther away. So this looks quite similar in unreliability to me like using SimConnect's RequestFacilitiesList with the SIMCONNECT_FACILITY_LIST_TYPE.AIRPORT parameter which I was testingbefore.

But maybe, I am still doing something wrong here? So, any further advide would be highly appreciated :-).

Thanks in advance.

Greets, Benny

Share this post


Link to post
Share on other sites

I tried here with EDDC and I'm not getting that back in the list. The nearest reported is EDBZ.

Quote

this looks quite similar in unreliability to me like using SimConnect's RequestFacilitiesList with the SIMCONNECT_FACILITY_LIST_TYPE.AIRPORT parameter which I was testingbefore.

FSUIPC4 gets most of its data from SimConnect so it's probably using that same call to get this airport list.

Paul

Share this post


Link to post
Share on other sites

Yes...this is what I am seeing with EDDC, too. Nearest airport is EDBZ, according to 0x0658. What is bothering me with this is that all 3 airports I tried didn't work as I expected them to do. 

As far as I understood, FSUIPC isn't relying on SimConnect for this facility as stated here by Pete. Plus, also in the FSUIPC4 Offsets Status.pdf it reads "Intl" which translates into FSUIPC "internal" for me, but maybe this changed somewhere down the development line of FSUIPC.

So, maybe I should gonna go ask Pete on the matter?

Greets, Benny

Share this post


Link to post
Share on other sites
1 hour ago, BenBaron said:

As far as I understood, FSUIPC isn't relying on SimConnect for this facility as stated here by Pete. Plus, also in the FSUIPC4 Offsets Status.pdf it reads "Intl" which translates into FSUIPC "internal" for me, but maybe this changed somewhere down the development line of FSUIPC.

It gets the list using values in ATC.DLL, but only in FSX SP2 and Acceleration.  It isn't available at all in FSX RTM or SP1. 

In FSX-SE and P3D it uses SimConnect_RequestFacilitiesList.

You can log what it gets by adding these two lines to the [General] section of FSUIPC4.INI:

Debug=Please
LogExtras=32

If this list includes the aiport name, as the last item in each one, then the data comes direct from the ATC.DLL hack. Otherwise it's all from SimConnect. And I did report the SimConnect problem with not including all near airports, even sometimes omitting the actual one you are at. I think it was fixed in P3D, but I'm not sure. I'll try your example here.

Pete

 

 

 

Share this post


Link to post
Share on other sites

Thanks Pete for your help,

so in the end I guess, until now, to get a reliable solution that works with all FSX platforms (and most probably P3D as well) one would need to implement a self-created airport database solution and query it against the aircraft position to find out, where it actually is. Or do you see another way to do it?

Greets, Benny

Share this post


Link to post
Share on other sites
5 minutes ago, BenBaron said:

Or do you see another way to do it?

No, sorry. 

I've just tested on P3D4.1 and it's just as bad:

EDDC nearest EDCM (17nm)
EDDF  nearest ETOU (7nm)
KJFK  nearest 4NY2 (8nm)

The only add-on airports I have installed on this test system are EGLL and EGCC. EGLL seems okay, but EGCC gives EGCB as nearet.

I'll report it to L-M so that it might just get fixed one day ... 

Pete

 

  • Thanks 1

Share this post


Link to post
Share on other sites

I've recently added a new feature in the DLL that reads various data files from Pete's MakeRunways program. This creates an database in memory of all airports (with runways) which you can query with LINQ.

It can also return a list of airports within a certain range of the player.

It requires you (and users if you have them) to download and run the MakeRunways program.

If you're interesting in trying this out/testing it let me know and I'll post some example code here.

Paul

Share this post


Link to post
Share on other sites

Hi Paul,

sounds like a great facility. Does it only produce an "internal" database within your dll or does it create an external file each time the simulator is run?

If you would be willing to share something more about the mechanics I might take a look at it :).

Greets, Benny

Share this post


Link to post
Share on other sites

Hi Benny,

The database is just in-memory, internal the the DLL. There are no external files produced.

The airport data is stored in an FsAirport class which are all stored in a single List<FsAirport>. This collection can then be used in the normal ways including filtering with LINQ (either extension methods or the query language).

The data is read from the various output files from MakeRunways. These are a mixture of XML and CSV. These are placed in the main FS folder by MakeRunways every time you run it. When you add new scenery you need to rerun Makerunways. I just read those current files from the main FS folder.

The initial read and parsing takes about 3 seconds on my machines here, which is quite old now (about 7 years). This only has to be done once when your application starts and after that the operations on the database are instant. I'm still optimising so this parse time might improve.

For the 'airports in-range' operations you call a method that sets a reference point. This can be any Lon/Lat, an airport or, if nothing is specified the DLL will read the current player Lon/Lat automatically and use that. When you set the reference point each airport is updated with the distance from that point and its relative bearing.

After setting the reference point you can use a helper method or plain LINQ to query all airports within a certain distance, and any other requirements as well.

To use the database, call the load() method AFTER the connection is open: (Note, you must have the makerunways files in the main FS folder).

FSUIPCConnection.AirportsDatabase.Load();

Then you can get a specific airport or query the database with LINQ. e.g:
         

            // Get shortcut to the database
            AirportsDatabase db = FSUIPCConnection.AirportsDatabase;

            // Get airport by ICAO
            FsAirport heathrow = db.Airports["EGLL"];
            
            // get list of airports with 'ranch' in the name and order by name
            List<FsAirport> ranchList = db.Airports.FindAll(ap => ap.Name.ToLower().Contains("ranch")).OrderBy(ap => ap.Name).ToList();

            // Same as above, but done using LINQ Query
            var ranchListQuery = from ap in db.Airports
                             where ap.Name.ToLower().Contains("ranch")
                             orderby ap.Name
                             select ap;
            List<FsAirport> ranchList2 = ranchListQuery.ToList();

To use the distance/bearing feature, set a reference position. Here we just use the player position by passing no parameters.

            // Set reference position to player
            db.SetReferencePosition();

Now you can get airports in range using the helper method:

            // Get all airports within 50nm
            // (InRange method automatically sorts by distance)
            List<FsAirport> inRange = db.Airports.InRangeOfNauticalMiles(50);

You can further narrow down the list using the WithRunway helper method, or a LINQ Query.
 

            // Get all airports within 50nm with ILS and has a runway over 1500m.
            List<FsAirport> inRange2 = db.Airports.InRangeOfNauticalMiles(50).WithRunway(runway => runway.ILSInfo != null && runway.LengthMeters >= 1500);

            // Save as above but with LINQ Query
            var inRangeQuery = from ap in db.Airports
                               where ap.DistanceNauticalMiles <= 50 && (from rw in ap.Runways
                                                                        where rw.ILSInfo != null && rw.LengthMeters >= 1500
                                                                        select rw).Count() > 0
                               orderby ap.DistanceNauticalMiles
                               select ap;
            List<FsAirport> inRange3 = inRangeQuery.ToList();

There is a quite a bit of information about airports, runways, helipads, coms frequencies and gates. The property names will appear on the Intellisense, but I haven't added any comments yet.

Paul

  • Thanks 1

Share this post


Link to post
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


×