# Summary of Chapter 28. Location and maps

PDF for offline use
Related Articles:
Related Samples:

Translation Quality

0/250

last updated: 2017-11

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: `Xamarin.Forms.Maps`.

# 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

The Xamarin.Forms `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 iOS implementation of `ILocationTracker` is a `LocationTracker` class that makes use of the iOS `CLLocationManager`.

### The Android location manager

The Android implementation of `ILocationTracker` is a `LocationTracker` class that makes use of the Android `LocationManager` class.

### The Windows Runtime geo locator

The Windows Runtime implementation of `ILocationTracker` is a `LocationTracker` class that makes use of the UWP `Geolocator`.

## 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.

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 `Toolkit.Init` method.

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 ACCESSFILELOCATION 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 `Map` class.

## 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 `Xamarin.Forms.Forms.Init`.

## Enabling map services

Because the `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 MapDemos sample consists of a MapsDemoHomePage.xaml file and MapsDemoHomePage.xaml.cs code-behind file that allows navigating to various demonstration programs.

The BasicMapPage.xaml file shows how to display the `Map` view. By default it displays the city of Rome, but the map can be manipulated by the user.

To disable horizontal and vertical scrolling, set the `HasScrollEnabled` property to `false`. To disable zooming, set `HasZoomEnabled` to `false`. These properties might not work on all platforms.

## Streets and Terrain

You can display different types of maps by setting the `Map` property `MapType` of type `MapType`, an enumeration with three members:

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.

## Map coordinates

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:

`Position` and `Distance` are both structures. `Position` defines two read-only properties set via the `Position` constructor:

`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:

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.

## Position extensions

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 `Position` values.

## 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:

It's also possible to create a new `MapSpan` from an existing one using the methods `ClampLatitude` or `WithZoom`.

The WyomingPage.xaml file and WyomingPage.xaml.cs code-behind file demonstrates how to use the `MoveToRegion` method to display the state of Wyoming.

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.

## Dynamic zooming

You can use a `Slider` to dynamically zoom a map. The RadiusZoomPage.xaml file and RadiusZoomPage.xaml.cs code-behind file show how to change the radius of a map based on the `Slider` value.

The LongitudeZoomPage.xaml file and LongitudeZoomPage.xaml.cs code-behind file show an alternative approach that works better on Android, but neither approach works well on the Windows platforms.

## The Phone's location

The `IsShowingUser` property of `Map` works a little differently on the three platforms as the ShowLocationPage.xaml file demonstrates:

• 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

The MapDemos project attempts to mimic the Android approach by first defining an icon-based button based on the MyLocationButton.xaml file and MyLocationButton.xaml.cs code-behind file.

The GoToLocationPage.xaml file and GoToLocationPage.xaml.cs code-behind file use this button to navigate to the phone's location.

## Pins and science museums

Finally, the `Map` class defines a `Pins` property of type `IList<Pin>`. The `Pin` class defines four properties:

The MapDemos project contains the file ScienceMuseums.xml, which lists science museums in the United States, and `Locations` and `Site` classes for deserializing this data.

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 `PositionExtensions` class contains a `DistanceTo` method with a simplified calculation of the distance between two geographic locations.

This is used in the LocalMuseumsPage.xaml file and LocalMuseumsPage.xaml.cs code-behind file to also display the distance to the museum from the user's location:

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.

The GeocoderRoundTrip.xaml file and GeocoderRoundTrip.xaml.cs code-behind file demonstrate this facility.

# Xamarin Workbook

If it's not already installed, install the Xamarin Workbooks app first. The workbook file should download automatically, but if it doesn't, just click to start the workbook download manually.