Jump to content
The simFlight Network Forums

Building airports database offline


Andy B.

Recommended Posts

Hi,

 

I am rebuilding Talking flight monitor with WPF, C#, and dotnet 7. I am trying to rebuild the airports database while disconnected from a simulator. I figured I would try MSFS first because it is easier to code for in this sense. Whenever I try to create or otherwise access the database, I get a null reference exception saying that the database doesn't exist. Here is my build database method. The msfs/p3d database and make runways variables are pointing to the desired path. So, how would I be able to build the database files offline?

 

  

public static async void BuildAirportsDatabaseAsync(string simulator)
{

    // In case a simulator is running, clear the database before rebuilding.
    if (FSUIPCConnection.IsOpen)
    {
        if (FSUIPCConnection.AirportsDatabase.IsLoaded)
        {
            FSUIPCConnection.AirportsDatabase.Clear();
        }
    }

    try
    {
        var db = FSUIPCConnection.AirportsDatabase;
        if (simulator == "MSFS")
        {
            
            db.MakeRunwaysFolder = msfsMakeRunwaysOutputPath;
            db.DatabaseFolder = msfsAirportsDatabaseFolder;
        }

        if (db.MakeRunwaysFilesExist)
        {
            await db.RebuildDatabaseAsync();
            System.Windows.MessageBox.Show($"MSFS airports build successfully. Total {db.Airports.Count}");
            logger.Info($"MSFS airports build successfully. Total {db.Airports.Count}");
        }
    }
    catch(FSUIPCException x)
    {
        System.Windows.MessageBox.Show($"{x.Message}");
    }
    
                }
 

Link to comment
Share on other sites

Hi Andy,

This was a bug on my side. I've just uploaded 3.3.7 to NuGet which fixes this.

Also note that you'll need to load the database after you rebuild it, or you'll get 0 airports:

await db.RebuildDatabaseAsync();
db.Load();
System.Windows.MessageBox.Show($"MSFS airports build successfully. Total {db.Airports.Count}");
logger.Info($"MSFS airports build successfully. Total {db.Airports.Count}");

Paul

Link to comment
Share on other sites

Hi,

 

I tried building and loading the database offline. It works for P3D, but not MSFS. Here is my BuildAirportsAsync method where the "P3D" condition suceeds and the "MSFS" condition fails. In fact, when "MSFS" is passed into this method, db = FSUIPCConnection.AirportsDatabase fails, and the method stops working with no errors or exceptions. What might be wrong?

 

        public static async void BuildAirportsDatabaseAsync(string simulator)
        {

            // In case a simulator is running, clear the database before rebuilding.
            if (FSUIPCConnection.IsOpen)
            {
                if (FSUIPCConnection.AirportsDatabase.IsLoaded)
                {
                    FSUIPCConnection.AirportsDatabase.Clear();
                }
            }

            try
            {
                var db = FSUIPCConnection.AirportsDatabase;
                if (simulator == "MSFS")
                {
                                        db.MakeRunwaysFolder = msfsMakeRunwaysOutputPath;
                    db.DatabaseFolder = msfsAirportsDatabaseFolder;
                }

                if(simulator == "P3D")
                {
                    db.DatabaseFolder = p3dAirportsDatabaseFolder;
                    db.MakeRunwaysFolder = p3dMakeRunwaysOutputPath;
                }

                if (db.MakeRunwaysFilesExist)
                {
                    await db.RebuildDatabaseAsync();
                    db.Load();
                    System.Windows.MessageBox.Show($"{simulator} airports build successfully. Total {db.Airports.Count}");
                    logger.Info($"{simulator} airports build successfully. Total {db.Airports.Count}");
                }
            }
            catch(FSUIPCException x)
            {
                System.Windows.MessageBox.Show($"{x.Message}");
            }
            
                        }
 

Link to comment
Share on other sites

Quote

db = FSUIPCConnection.AirportsDatabase fails, 

I'm not sure what you mean by 'fails' if there are no exceptions or errors. What are you seeing to make you believe it has failed?

If you step through this method does it continue past this line, or does the method just return, or does the whole application just stop?

Paul

 

Link to comment
Share on other sites

I have two methods: RunMakeRunways that takes a parameter from a WPF dialog asking the user to choose a simulator to build the database for. After choosing, then browsing to the P3D install folder if required, pressing the OK button launches a process that runs MakeRwys.exe in the proper location. In case of MSFS, %localappdata%\tfm\Make runways\MSFS. In P3D's case, the install folder with the working path for the process set to the P3D install folder. Once the RunMakeRunways method is complete (it finishes the MakeRwys.exe process), it bases the original simulator choice to BuildAirportsDatabaseAsync (the method in the previous post). Now, in the case of if(simulator == "P3D") block, everything works as expected. As for the if(simulator == "MSFS") block, I have done the following:

 

* Put logging statements after every line of code.

* Ran it through the debugger, which strangely works as expected.

* Ran it outside of the debugger and get this strange behavior.

* Consulted AI models with no luck.

 

At the end of the entire process, the message box is supposed to show how many airports were loaded. Unfortunately, when passing "MSFS" to BuildAirportsDatabaseAsync, execution apparently stops at the line:

 

var db = FSUIPCConnection.AirportsDatabase;

 

The next log statement never appears, and Talking flight monitor is no longer running. No errors or exceptions.

Link to comment
Share on other sites

Some additional info. I tried running the feature again. Everything works as expected with the BuildAirportsDatabaseAsync method until it creates the airports database location (for the binary files). After that, the app dies with no notice to the user.

Link to comment
Share on other sites

I wonder if it's something to do with the data in the MakeRunways files.

 Can you send me your makerunways output files? I can try running them here and see if there's something my code isn't handling. (I don't have MSFS).

They should zip down pretty small - I only need:

Runways.xml
F5.csv
R5.csv
G5.csv
Helipads.csv
T5.csv

Thanks,

Paul

Link to comment
Share on other sites

Thanks,

Work fine here with your code and those files. The rebuild took 20 seconds to run on my rather old machine.

Can you try logging the progress output from the RebuildDatabase method? This will tell us how far it's getting/where it's stopping.

The code will be something like this...

                if (db.MakeRunwaysFilesExist)
                {
                    Progress<string> progress = new Progress<string>();
                    progress.ProgressChanged += (o,s) => logger.Info(s);
                    await db.RebuildDatabaseAsync(progress);
                    db.Load();

I'll look at this again tomorrow morning.

Paul

Link to comment
Share on other sites

Here is the log. BuildAirportsDatabaseAsync never makes it to the build part for some reason. Last log entry was just before the db.MakeRunwaysFiles check. Here is the log.

[Info]: Loading screen reader driver.: [tfm.App.Application_Startup]: [2023-09-18 18:16]
[Debug]: Deleting existing MSFS make runways output folder.: [tfm.App.RunMakeRunways]: [2023-09-18 18:16]
[Debug]: Creating MSFS make runways output folder.: [tfm.App.RunMakeRunways]: [2023-09-18 18:16]
[Debug]: Copying C:\Users\a_bor\Documents\GitHub\talking-flight-monitor\source\bin\Debug\net7.0-windows\data\MakeRwys\MakeRwys.exe to C:\Users\a_bor\AppData\Local\tfm\Make runways\MSFS\MakeRwys.exe.: [tfm.App.RunMakeRunways]: [2023-09-18 18:16]
[Debug]: Waiting for make runways to finish.: [tfm.App.RunMakeRunways]: [2023-09-18 18:16]
[Debug]: Getting a copy of the current airports database.: [tfm.App.BuildAirportsDatabaseAsync]: [2023-09-18 18:40]
[Debug]: Assigned MSFS make runways output folder: C:\Users\a_bor\AppData\Local\tfm\Make runways\MSFS.: [tfm.App.BuildAirportsDatabaseAsync]: [2023-09-18 18:40]
[Debug]: Assigned MSFS airports database folder: C:\Users\a_bor\AppData\Local\tfm\Airports database\MSFS: [tfm.App.BuildAirportsDatabaseAsync]: [2023-09-18 18:40]
 

Link to comment
Share on other sites

After running BuildAirportsDatabaseAsync through the debugger, I found this stack trace. I don't understand where it came from, or why it is causing problems. I have 229GB left on my internal drive and over 3TB on my external. I also have 16GB of memory and 8GB of dedicated video memory. In the event this process is blowing out my memory, is there another way that isn't as resource intence?

 

System.ComponentModel.Win32Exception
  HResult=0x80004005
  Message=Not enough quota is available to process this command.
  Source=WindowsBase
  StackTrace:
   at MS.Win32.UnsafeNativeMethods.PostMessage(HandleRef hwnd, WindowMessage msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndTarget.UpdateWindowSettings(Boolean enableRenderTarget, Nullable`1 channelSet)
   at System.Windows.Interop.HwndTarget.UpdateWindowPos(IntPtr lParam)
   at System.Windows.Interop.HwndTarget.HandleMessage(WindowMessage msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
 

Link to comment
Share on other sites

Quote

 In the event this process is blowing out my memory, is there another way that isn't as resource intence

Yes, I've upload a new version for you to try: 3.3.8-beta.

I've reduced the memory overhead to about 12% of what it was. 

Remember to tick "Show Pre-Release" in the NuGet package manager to see this beta version.

Please let me know how it goes.

Thanks,

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.