Adicione pontos no Maps – Xamarin.Forms

Olá, neste post irei demonstrar como você pode adicionar pontos (pins) no maps através de cliques do usuário em aplicações Xamarin.Forms.

Com esses pontos você poderá pegar as coordenadas (Latitude x Longitude) do ponto selecionado pelo usuário.

ADICIONANDO NUGET PACKAGES

Clique com o botão direito em cima de sua Solution e selecione “Manage NuGet Packages for Solution…”.

1

 

Digite “Xamarin.Forms.Maps” e selecione o plugin como demonstrado na imagem a seguir.

2

 

Selecione todos os projetos e clique no botão “Install”.

2

 

 

Após a instalação do Xamarin.Forms.Maps será necessãrio a instalaçao do pacote GooglePlayServices.Maps apenas para o projeto .Android.

Digite “Xamarin.GooglePlayServices.Maps” e selecione o plugin como demonstrado na imagem a seguir.

3-android

 

Selecione apenas o projeto .Android e clique no botão “Install”.

4

Adicionando permissões

Android

Edite o manifesto para adicionar algumas permissões, para isso clique com o botão direito no projeto .android e selecione Properties.

p1

 

No Android Manifest selecione as seguintes permissões.

manifesto2

 

O passo seguinte é obter uma chave de API do Google API Console e adiciona-la em nosso manifesto. Para isso acesse https://developers.google.com/maps/documentation/android-api/ com uma conta Google.

Selecione “OBTER UMA CHAVE” e em seguida defina um nome para o seu projeto, selecione Yes e clique em CREATE AND ENABLE API.

2

Copie a API KEY gerada.

3

Edite o arquivo AndroidManifest.xml e dentro de application, adicione uma meta-data com a API KEY gerada, como demonstrado a seguir.

ANDROIDMANIFEST

 

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.PinClickDemo" android:installLocation="auto">
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application android:label="PinClickDemo.Android">
<meta-data android:name="com.google.android.geo.API_KEY" android:value="COLE SUA API KEY AQUI" />
</application>
</manifest>

view raw
AndroidManifest.xml
hosted with ❤ by GitHub

iOS

No projeto .iOS edite o arquivo Info.plist e adicione as seguintes permissões dentro de “dict” como demonstrado a seguir.

 

 

 

 

 

 

 

<key>NSLocationUsageDescription</key>
<string>Esse aplicativo precisa acessar a sua localização.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Esse aplicativo precisa acessar a sua localização.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Esse aplicativo precisa acessar a sua localização.</string>
</dict>
</plist>

view raw
Info.plist
hosted with ❤ by GitHub

 

Portable

Em seu projeto portable crie a classe “ExtendedMap.cs”.
Observe que a classe ExtendedMap está herdando de Xamarin.Forms.Maps.Map.
Crie também a classe TapEventArgs que herda de System.EventArgs.

Dentro de ExtendedMap crie um EventHandler de TapEventArgs chamado Tap e os métodos “OnTap” como demonstrado a seguir.

 

 

 

 

 

using System;
using Xamarin.Forms.Maps;
namespace PinClickDemo
{
public class ExtendedMap : Map
{
public event EventHandler<TapEventArgs> Tap;
public ExtendedMap()
{
}
public ExtendedMap(MapSpan region) : base(region)
{
}
public void OnTap(Position coordinate)
{
OnTap(new TapEventArgs { Position = coordinate });
}
protected virtual void OnTap(TapEventArgs e)
{
var handler = Tap;
if (handler != null) handler(this, e);
}
}
public class TapEventArgs : EventArgs
{
public Position Position { get; set; }
}
}

view raw
ExtendedMap.cs
hosted with ❤ by GitHub

Android

Em seu projeto android crie a classe “ExtendedMapRenderer.cs”.
Observe que a classe herda de MapRenderer e sobrescreve os métodos: OnMapReady, OnElementChanged. Por último crie o método googleMap_MapClick que será responsável por pegar o click do usuário.

 

 

 

using Android.Gms.Maps;
using PinClickDemo;
using PinClickDemo.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Maps.Android;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ExtendedMap), typeof(ExtendedMapRenderer))]
namespace PinClickDemo.Droid
{
public class ExtendedMapRenderer : MapRenderer, IOnMapReadyCallback
{
private GoogleMap _map;
public ExtendedMapRenderer()
{
}
protected override void OnMapReady(GoogleMap googleMap)
{
_map = googleMap;
if (_map != null)
{
_map.MapClick += googleMap_MapClick;
}
}
protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
{
if (_map != null)
{
_map.MapClick -= googleMap_MapClick;
}
base.OnElementChanged(e);
if (Control != null)
((MapView)Control).GetMapAsync(this);
}
private void googleMap_MapClick(object sender, GoogleMap.MapClickEventArgs e)
{
((ExtendedMap)Element).OnTap(new Position(e.Point.Latitude, e.Point.Longitude));
}
}
}

 

iOS

Em seu projeto iOS também crie a classe “ExtendedMapRenderer.cs” herdando de MapRenderer como demonstrado a seguir.

 

 

 

 

 

 

using MapKit;
using PinClickDemo;
using PinClickDemo.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Maps.iOS;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(ExtendedMap), typeof(ExtendedMapRenderer))]
namespace PinClickDemo.iOS
{
public class ExtendedMapRenderer : MapRenderer
{
private readonly UITapGestureRecognizer _tapRecogniser;
public ExtendedMapRenderer()
{
_tapRecogniser = new UITapGestureRecognizer(OnTap)
{
NumberOfTapsRequired = 1,
NumberOfTouchesRequired = 1
};
}
private void OnTap(UITapGestureRecognizer recognizer)
{
var cgPoint = recognizer.LocationInView(Control);
var location = ((MKMapView)Control).ConvertPoint(cgPoint, Control);
((ExtendedMap)Element).OnTap(new Position(location.Latitude, location.Longitude));
}
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
if (Control != null)
Control.RemoveGestureRecognizer(_tapRecogniser);
base.OnElementChanged(e);
if (Control != null)
Control.AddGestureRecognizer(_tapRecogniser);
}
}
}

Xaml

No arquivo xaml crie um ExtendedMap.

 

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:PinClickDemo"
x:Class="PinClickDemo.MainPage">
<StackLayout>
<local:ExtendedMap x:Name="Mapa" Tap="Mapa_OnTap"/>
</StackLayout>
</ContentPage>

view raw
MainPage.xaml
hosted with ❤ by GitHub

CODE-BEHIND

No construtor utilize o MoveToRegion para definir qual a região do mapa que deseja mostrar ao carregar a pagina.

Crie também o método Mapa_OnTap que será responsável por adicionar o pin na lista de pins do maps.

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
namespace PinClickDemo
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
Mapa.MoveToRegion(MapSpan.FromCenterAndRadius(
new Position(23.4859591, 47.4420192),
Distance.FromMiles(0.5)));
}
private void Mapa_OnTap(object sender, TapEventArgs e)
{
var pin = new Pin
{
Type = PinType.Place,
Position = e.Position,
Label = "Cliked",
Address = e.Position.Latitude + " X " + e.Position.Latitude,
};
Mapa.Pins.Add(pin);
}
}
}

view raw
MainPage.xaml.cs
hosted with ❤ by GitHub

Resultado

Android

ezgif.com-gif-maker (1)

 

 

iOS

ezgif.com-gif-maker (5)

 

Esse e todos os exemplos deste blog encontram-se disponíveis no GitHub.

icongithub

4 comentários em “Adicione pontos no Maps – Xamarin.Forms

    1. Opa, consegui acrescentando, no método OnMapReady do Android, o seguinte trecho de código:
      _map.UiSettings.ZoomControlsEnabled = true;
      _map.UiSettings.CompassEnabled = true;

      Esta é a maneira mais correta de fazer? E como fica pro iOS?

      Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s