Summary of Chapter 28. Location and maps
Xamarin.Forms supports a
Map element that derives from
View. Because of the special platform requirements involved in using maps, they are implemented in a separate assembly, Xamarin.Forms.Maps, and involve a different namespace:
The geographic coordinate system
A geographic coordinate system identifies positions on a spherical (or nearly spherical) object like the Earth. A coordinate consists of both a latitude and longitude expressed in angles.
A great circle called the
equator is midway between the two poles through which the Earth's axis conceptually extends.
Parallels and latitude
An angle measured north or south of the equator from the center of the Earth marks lines of equal latitude known as parallels. These range from 0 degrees at the equator to 90 degrees at the north and south poles. By convention, latitudes north of the equator are positive values, and those south of the equator are negative values.
Longitude and meridians
Halves of great circles from the north pole to the south pole are lines of equal longitude, also known as meridians. These are relative to the Prime Meridian in Greenwich, England. By convention, longitudes east of the Prime Meridian are positive values from 0 degrees to 180 degrees, and longitudes west of the Prime Meridian are negative values from 0 degrees to –180 degrees.
The equirectangular projection
Any flat map of the Earth introduces distortions. If all the lines of latitude and longitude are straight, and if equal differences in latitude and longitude angles correspond to equal distances on the map, the result is an equirectangular projection. This map distorts areas closer to the poles because they are horizontally stretched out.
The Mercator projection
The popular Mercator projection attempts to compensate for the horizontal stretching by also stretching these areas vertically. This results in a map where areas near the poles appear much larger than they really are, but any local area conforms quite closely with the actual area.
Map services and tiles
Map services use a variation of the Mercator projection called
Web Mercator. The map services deliver bitmap tiles to a client based on location and zoom level.
Getting the user's location
Map classes do not include a facility to obtain the user's geographic location, but this is often desirable when working with maps, so a dependency service must handle it.
The location tracker API
The Xamarin.FormsBook.Platform solution contains code for a location tracker API. The
GeographicLocation structure encapsulates a latitude and longitude. The
ILocationTracker interface defines two methods to start and pause the location tracker, and an event when a new location is available.
The iOS location manager
The Android location manager
The Windows Runtime geo locator
Display the phone's location
The WhereAmI sample uses the location tracker to display the phone's location, both in text and on a equirectangular map.
The required overhead
Some overhead is required for WhereAmI to use the location tracker. First, all of the projects in the WhereAmI solution must have references to the corresponding projects in Xamarin.FormsBook.Platform, and each WhereAmI project must call the
Some additional platform-specific overhead, in the form of location permissions, is required.
Location permission for iOS
For iOS, the info.plist file must include items containing the text of a question asking the user to allow getting that user's location.
Location permissions for Android
Android applications that obtain the user's location must have an ACCESS_FILE_LOCATION permission in the AndroidManifest.xml file.
Location permissions for the Windows Runtime
A Windows or Windows Phone application must have a
location device capability marked in the Package.appxmanifest file.
Working with Xamarin.Forms.Maps
Several requirements are involved in using the
The NuGet package
The Xamarin.Forms.Maps NuGet library must be added to the application solution. The version number should be the same as the Xamarin.Forms package currently installed.
Initializing the Maps package
The application projects must call the
Xamarin.FormsMaps.Init method after making a call to
Enabling map services
Map can obtain the user's location, the application must obtain permission for the user in the manner described earlier in this chapter:
Enabling iOS maps
An iOS application using
Map needs two lines in the info.plist file.
Enabling Android maps
An authorization key is required for using Google Map services. This key is inserted in the AndroidManifest.xml file. In addition, the AndroidManifest.xml file requires
manifest tags involved in obtaining the user's location.
Enabling Windows Runtime maps
A Windows Runtime application requires an authorization key for using Bing Maps. This key is passed as an argument to the
Xamarin.FormsMaps.Init method. The application must also be enabled for location services.
The unadorned map
Streets and Terrain
The MapTypesPage.xaml file shows how to use a radio button to select the map type. It makes use of the
RadioButtonManager class in the Xamarin.FormsBook.Toolkit library and a class based on the MapTypeRadioButton.xaml file.
A program can obtain the current area that the
Map is displaying through the
VisibleRegion property. This property is not backed by a bindable property, and there is no notification mechanism to indicate when it has changed, so a program that wishes to monitor the property should probably use a timer for that purpose.
VisibleRegion is of type
MapSpan, a class with four read-only properties:
double, indicating the height of the displayed area of the map
double, indicating the width of the displayed area of the map
Distance, indicating the size of the largest circular area visible on the map
Distance are both structures.
Position defines two read-only properties set via the
Distance is intended to provide a unit-independent distance by converting between metric and English units. A
Distance value can be created in several ways:
Distanceconstructor with a distance in meters
The value is available from three properties:
The MapCoordinatesPage.xaml file contains several
Label elements for displaying the
MapSpan information. The MapCoordinatesPage.xaml.cs code-behind file uses a timer to keep the information updated as the user manipulates the map.
A new library for this book named Xamarin.FormsBook.Toolkit.Maps contains map-specific but platform-independent types. The
PositionExtensions class has a
ToString method for
Position, and a method to calculate the distance between two
Setting an initial location
You can call the
MoveToRegion method of
Map to programmatically set a location and zoom level on the map. The argument is of type
MapSpan. You can create a
MapSpan object using either of the following:
MapSpanconstructor with a
Position, and latitude and longitude span
You can alternatively use the
Map constructor with a
MapSpan object to initialize the location of the map. The XamarinHQPage.xaml file shows how to do this entirely in XAML to display Xamarin's headquarters in San Francisco.
The Phone's location
- On iOS, a blue dot indicates the phone's location but you must manually navigate there
- On Android, an icon is displayed that when pushed moves the map to the phone's location
- The UWP is similar to iOS but sometimes automatically navigates to the location
Pins and science museums
string, a required property
string, an optional human-readable address
Position, indicating where the pin is displayed on the map
PinType, an enumeration, which is not used
The ScienceMuseumsPage.xaml file and ScienceMuseumsPage.xaml.cs code-behind file display pins for these science museums in the map. When the user taps a pin, it displays the address and a website for the museum.
The distance between two points
The program also demonstrates how to dynamically restrict the number of pins based on the location of the map.
Geocoding and back again
The Xamarin.Forms.Maps assembly also contains a
Geocoder class with a
GetPositionsForAddressAsync method that converts a text address into zero or more possible geographic positions, and another method
GetAddressesForPositionAsync that converts in the other direction.