Bug 58757 - Geocoder reverse geocoding on Android squashes whole address into one line
Summary: Geocoder reverse geocoding on Android squashes whole address into one line
Status: RESOLVED ANSWERED
Alias: None
Product: Android
Classification: Xamarin
Component: Bindings ()
Version: unspecified
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Atsushi Eno
URL:
Depends on:
Blocks:
 
Reported: 2017-08-14 21:28 UTC by Philipp Sumi
Modified: 2017-08-16 07:34 UTC (History)
2 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED ANSWERED

Description Philipp Sumi 2017-08-14 21:28:51 UTC
As seen in the screenshot in your own sample, the Geocoder squashes all lines into one:

https://developer.xamarin.com/recipes/android/os_device_resources/geocoder/reverse_geocode_a_location/

On iOS, when reverse geocoding the same coordinates, I'm getting and Address object with multiple lines that contain street name, zipcode/city and country. On Android, the MaxAddressLineIndex seems to be always 0, with a single string that also contains all those parts, but as one comma-separated string:

    var gc = new Geocoder(Forms.Context);
    var results = await gc.GetFromLocationAsync(position.Latitude, position.Longitude, 1);
    Address address = results?.FirstOrDefault();
    address.MaxAddressLineIndex <-- this is always zero as far as I can tell

This forces me to then separate the strings myself, which is brittle (after all, an address part might contain a comma, too for some reason).
Comment 1 Jon Douglas [MSFT] 2017-08-14 22:50:24 UTC
This is because the APIs offered by Android and iOS are very different. If one wanted to make a cross platform version of Geocoding, they would use these platform APIs and return a new object that is populated by the platform object.

However this is not a bug, but rather how these APIs are designed by Google and Apple. We simply bind to them, and thus we get the objects they return.

Thus for the Android side of things, you get a List<Address>

https://developer.android.com/reference/android/location/Geocoder.html

https://developer.android.com/reference/android/location/Geocoder.html#getFromLocation(double, double, int)

Which in turn gets you an Address object:

https://developer.android.com/reference/android/location/Address.html

iOS uses CLGeocoder which is a much different structure:

https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/UsingGeocoders/UsingGeocoders.html

https://developer.apple.com/documentation/corelocation/clgeocoder

Which you might return a CLPlacemark instead:

https://developer.apple.com/documentation/corelocation/clplacemark

Thus I'm marking this bug as ANSWERED as it does not pertain to Xamarin.Android. Rather a developer could make a more consistent cross platform API if they wanted.
Comment 2 Philipp Sumi 2017-08-15 07:09:50 UTC
Hi Jon

Sorry, I should have made this clear: I actually am using Google's API on both Android and iOS, with the Google.Maps.Geocoder on iOS. So I am assuming the invoked API endpoints and thus retrieved data should the same on both platforms. Here's my iOS code:


            var coordinate = new CLLocationCoordinate2D(lat, long);
            var gc = new Google.Maps.Geocoder();
            gc.ReverseGeocodeCord(coordinate, (r, e) => { ... }


I'm reopening the ticket accordingly in order to get the discussion going. Hope that's ok.

Thanks,
Philipp
Comment 3 Jon Douglas [MSFT] 2017-08-15 16:05:47 UTC
These are still different APIs.

For example iOS Google Maps Geocoder:

https://developers.google.com/maps/documentation/ios-sdk/reference/interface_g_m_s_geocoder

Returns a response: https://developers.google.com/maps/documentation/ios-sdk/reference/interface_g_m_s_reverse_geocode_response

Which is a type GMSAddress:

https://developers.google.com/maps/documentation/ios-sdk/reference/interface_g_m_s_address

Which is very different than https://developer.android.com/reference/android/location/Address.html

Since this is not a bug, I would highly recommend you post this question on our Forums or Stack Overflow for a more appropriate answer of how you can make a cross platform library out of these items.

https://developer.xamarin.com/guides/cross-platform/troubleshooting/support-options/#Summary_of_Support_Options
Comment 4 Philipp Sumi 2017-08-16 07:34:15 UTC
Oh I see - I was assuming they'd provide just one API endpoint no matter the client (it's still a little surprising to me). Thanks for the context Jon!