Select to view content in your preferred language

Esri global map showing instead of map at requested location - Xamarin iOS and Android app

1250
6
02-03-2022 09:44 AM
AnglrTech
Emerging Contributor
We have a Xamarin-based app that we have migrated from the Esri for Startups program to the Esri Developer program.  As part of that migration, we needed to change our app to use the new Esri License Key and Esri Api Keys.  That part of the migration was straightforward and is working fine.  But the part that has not been working reliably is the request of the Esri map for presentation.  At random times, our map page, that is supposed to show the user's current location, instead shows the default Esri Global Map.  
 
Please see the attached video for an example of this behavior.  At the end of the video, the Esri global map is shown.
 
Here is the code we use to create the Esri map:
GetMap.png
 
A few things of note:
  • the Anglr app is a Xamarin native app for iOS and Android
  • this occurs with more frequency on Android than iOS
  • with this same code, we never saw this behavior when we were part of the Startups program
  • we are using 100.13.0 version of the ArcGISRuntime nugets for both platforms

I've been banging on this one for a few weeks now, any help/suggestions/comments are greatly appreciated!

-Tom Klempay (Senior Software Engineer, AnglerLabs)

Tags (1)
0 Kudos
6 Replies
RexHansen
Esri Contributor

Hi Tom,   

Thanks for the write-up and video showing the issue.  A couple questions:  
1) Once the basemap is shown at full extent, if you back out of the map and reopen again, does it honor the initial viewpoint?   Just curious if once the viewpoint is not honored, it remains so.   
2)  If you use a basemap that does not require an API Key, do you see the same issue?  This is just for testing, not for production.    
3)  Are you creating a new MapView and Map each time you open a trip - or just a new Map?  

Thanks
-Rex

0 Kudos
AnglrTech
Emerging Contributor

1) for iOS, it does seem that once it shows the global map, its stuck on it until I restart the app.  Android does not behave that way but I think it's because on Android, a new instance of the Map is created each time you enter the page.

2) Not sure, I'll have to try that and get back to you.

3) For Android, yes, a new Map/MapView is created each time.  For iOS, only one instance of a Map/MapView is created.

Let me know if you need any other info.  Thanks!

0 Kudos
NathanCastle1
Esri Contributor

Hi,

I’m sorry to hear you’re seeing problems with Map display. It is hard to tell for certain what is going on without seeing the full code, but I do have some ideas based on what you’ve shared.

  • The InitialViewpoint property is mostly intended for use in situations where a map is being opened from a Portal item. In cases involving programmatic creation of maps, it is preferred to set the viewpoint on the MapView directly. Setting the viewpoint after the map loads should be more reliable.
  • What is happening in the _currentMapStyle.ToEsri()? Consider trying to await the basemap creation, using the basemap as a constructor parameter for the map, and then setting the InitialViewpoint on the map. My hunch is that maybe in the process of applying the basemap, is resetting the initial viewpoint.
  • You might also consider waiting for the map to load before returning the map, to rule out any timing issues.

I see in the video that the map appears to be moving in the cases where the viewpoint successfully loads. Are you using a LocationDisplay or LocationDataSource to navigate the map based on device location after the map is displayed?

Thanks,

Nathan

0 Kudos
AnglrTech
Emerging Contributor

Nathan,

re: your bullet points

  • Are you saying to set the Viewpoint after a successful MapLoaded status is returned?
  • Our app makes use of Esri maps and Google maps so we have an internal enum to manage the different map types between the two platforms.  The _currentMapStyle.ToEsri method is a mapping function from an internal enum value to the associated Esri Basemap.  
  • I've been wondering if there was a timing element to this problem.  It will take me some work to change the return of the map for that but that makes a lot of sense to me.

Thanks much for your suggestions!

Regards,

-Tom

0 Kudos
NathanCastle1
Esri Contributor

Tom,

 

Yes, ideally viewpoint should be set after the map is added to the MapView. That may require a small amount of refactoring to break this code into two parts, one to create the map, another to call `mapView.SetViewpoint` or `mapView.SetViewpointAsync`. Alternatively, you might be able to follow the pattern in `AddGraphicsOverlays` to interact with the MapView.

Since the GetMap is already an async Task, you should be able to insert `await _map.LoadAsync` before returning the map. That will ensure the map is loaded before it is added to the map. If you explicitly load the map by calling `_map.LoadAsync` before returning, you can then check `_map.LoadStatus` rather than setting up an event. Although if you are already making the change to calling SetViewpoint on the MapView, then you should only need the explicit loading step if you want to do error handling.

 

Updated code might look something like the following:

 

try
{
    var basemap = await _currentMapStyle.ToEsri();

    _map = new Map(basemap);

    await _map.LoadAsync();

    _mapView.Map = _map; // Or alternatively do this in a separate method

    AddGraphicsOverlays();

    await _mapView.SetViewpointAsync(initialLatitude, initialLongitude, _defaultZoom);
}
catch //... error handling - explicit loading of map should throw exceptions that you can catch

 

0 Kudos
AnglrTech
Emerging Contributor

Hi Nathan,

Want to give you a quick update.  I was able to incorporate much of what you suggested and in my dev testing, things are really looking good on both iOS and Android.  Our next step is to push my changes into our test environment.  We're rolling that out today.  I'll let you know how it goes.

-Tom

0 Kudos