Select to view content in your preferred language

How to access a local geodatabase in .NET MAUI app?

2129
4
Jump to solution
06-07-2023 10:06 AM
Labels (2)
KevinCheriyan
Occasional Contributor

I have a .NET MAUI app in which I'm trying to create a network service area analysis task using a local geodatabase's network dataset. See here for docs. The geodatabase exists directly in the code directory inside a Data assets folder (Project/Data/FT_Data.gdb).

My eventual goal is to use an MMPK that I download from a non-Portal, non-AGOL network server that contains the network dataset in question. But for now, I'm starting off trying to feed the local gdb in. This is where I'm running into issues.

See code below:

 

 

string dbLocation = System.IO.Path.Combine(Environment.CurrentDirectory, @"Data", @"FT_data.gdb");
ServiceAreaTask serviceAreaTask = await ServiceAreaTask.CreateAsync(dbLocation, "network");

 

 

The application crashes at Line 1 here, because it cannot find the geodatabase at this location. I know this logic generally works at finding other files, since I've tried the same line with an MMPK that exists, and it can find it no problem.

The issue results from not being able to set the build action for a geodatabase in Visual Studio's Solution Explorer pane. With an MMPK or other files, I can set the Build action to "Content" and it will work. But for a geodatabase that exists as a directory in Solution Explorer, I don't want to go in and set the build action for each of the binary files.

So, there you have it. How can I reference a local geodatabase that already exists? I'm trying to do a pretty simple task that the .NET Maps SDK tells me I should be able to. But the only examples I could find are gdb downloaded from ArcGIS Enterprise Portal or Online and then stored in a folder outside the code. 

Thank you!


--------------------------------------------------
Application Developer, GeoMarvel
1 Solution

Accepted Solutions
dotMorten_esri
Esri Notable Contributor

How files are packaged varies a lot from platform to platform. For instance on Android it ends up as a stream you can read and not a file on disk. For iOS it ends up as a read-only file, and some datasets require a lock file to be written. So most likely you would want to grab the packaged file and copy it to the local appdata folder on first use.
First you'd want to set the build action in the csproj file to <MauiAsset />. This ensures it's packaged correctly for each platform. Next to get access to the file, you'll use Maui's `FileSystem.Current.OpenAppPackageFileAsync` to get the stream and copy it to FileSystem.Current.AppDataDirectory.

Before doing all of this  you could check if the file already exists, so it'll only do it on first-run.

> The issue results from not being able to set the build action for a geodatabase in Visual Studio's Solution Explorer pane [... ] 

I'm not quite following this. You should be able to set the build action on any file in your project.

> I don't want to go in and set the build action for each of the binary files
You could use * includes. For example <MauiAsset Include="Assets\**\*.*" />

Also as mentioned above, don't use "Content" with MAUI because of mainly Android - MauiAsset is the new way to do this.

View solution in original post

4 Replies
dotMorten_esri
Esri Notable Contributor

How files are packaged varies a lot from platform to platform. For instance on Android it ends up as a stream you can read and not a file on disk. For iOS it ends up as a read-only file, and some datasets require a lock file to be written. So most likely you would want to grab the packaged file and copy it to the local appdata folder on first use.
First you'd want to set the build action in the csproj file to <MauiAsset />. This ensures it's packaged correctly for each platform. Next to get access to the file, you'll use Maui's `FileSystem.Current.OpenAppPackageFileAsync` to get the stream and copy it to FileSystem.Current.AppDataDirectory.

Before doing all of this  you could check if the file already exists, so it'll only do it on first-run.

> The issue results from not being able to set the build action for a geodatabase in Visual Studio's Solution Explorer pane [... ] 

I'm not quite following this. You should be able to set the build action on any file in your project.

> I don't want to go in and set the build action for each of the binary files
You could use * includes. For example <MauiAsset Include="Assets\**\*.*" />

Also as mentioned above, don't use "Content" with MAUI because of mainly Android - MauiAsset is the new way to do this.

KevinCheriyan
Occasional Contributor

Great! Thanks @dotMorten_esri for your explanation. 

So after adding the .gdb as a MauiAsset, I ran the following suggested code edit which sets up the gdb to be streamed. 

 

string databaseLocation = Environment.CurrentDirectory + @"/Data/gdb/FT_data.gdb";
using var fileStream = FileSystem.Current.OpenAppPackageFileAsync(databaseLocation);

 

I'm developing this application primarily for iOS devices, and while running the following suggested code on iOS emulator from Visual Studio, I'm getting a System.UnauthorizedAccessException Error saying Permission to the gdb is denied. I think this is very likely to do with not setting up provisioning profiles for development. I'll be digging into this further...

But here's a related question. Let me know if I should start a separate thread to get answers for it.

Is there a way to use an MMPK's network dataset instead of a .gdb? The documentation explicitly mentions a geodatabase, so wondering what my options are. I already use an MMPK elsewhere in my app, so I have no issue with MAUI recognizing it, just need to know how to prep it for Network Analysis.


--------------------------------------------------
Application Developer, GeoMarvel
0 Kudos
PreetiMaske
Esri Regular Contributor

>Is there a way to use an MMPK's network dataset instead of a .gdb? The documentation explicitly mentions a geodatabase, so wondering what my options are. I already use an MMPK elsewhere in my app, so I have no issue with MAUI recognizing it, just need to know how to prep it for Network Analysis

Yes you can access the dataset if the database is added to map packaged in MobileMapPackage.

// Open a mobilemappackage
string mmpkPath = "PATH_TO_MMPK";
var mapPackage = await MobileMapPackage.OpenAsync(mmpkPath);

If there are UtilityNetworks you can get access to them via:

var gdb= mapPackage.Maps[0].UtilityNetworks[0].Geodatabase;

Or a TransportationNetwork

var gdb = map.TransportationNetworks[0].Geodatabase;

Note, the snippet assumes first map in mobilemappackage has the database. This will change depending on which map in your MMPK has the network dataset.

Hope this helps!

Thanks

Preeti

KevinCheriyan
Occasional Contributor

Thank you for your response @PreetiMaske. Your explanation and me tinkering around with geodatabases inside mobile map packages made me realize what I was doing wrong.

I was using a standard geodatabase in my app bundle and trying to access that without success. But once I started using a mobile geodatabase (.geodatabase extension not .gdb), MAUI is able to recognize the file and I don't get the above "Permission Denied" error anymore, which was prompted by me trying to open a .gdb, which is a directory and not a single file. In this scenario, I would add the .geodatabase to the .csproj file and not the .gdb "directory". This resolves my initial confusion well, so thank you and @dotMorten_esri !!


--------------------------------------------------
Application Developer, GeoMarvel
0 Kudos