Olá, neste post irei demonstrar como destacar uma determinada região do mapa através de coordenadas (Latitude X Longitude) em aplicações Xamarin.Forms.
As regiões destacadas terão o formato de polígonos, e as coordenadas serão os pontos do polígono. Dessa forma, o tipo do polígono será definido de acordo com a quantidade de pontos adicionados.
Para o exemplo a seguir será utilizado o Nuget Package “Xamarin.Forms.Maps”, irei assumir que você já instalou o package e adicionou as permissões necessárias de acordo com cada plataforma. Caso contrário recomendo ler o post Maps – Xamarin.Forms, antes de proseguir.
CustomMap.cs
Em seu projeto portable adicione a classe CustomMap, como demonstrado a seguir.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using Xamarin.Forms.Maps; | |
namespace App | |
{ | |
public class CustomMap : Map | |
{ | |
public List<Position> ShapeCoordinates { get; set; } | |
public CustomMap() | |
{ | |
ShapeCoordinates = new List<Position>(); | |
} | |
} | |
} |
Xaml
No arquivo Xaml crie uma referência para o namespace local e crie um CustomMap.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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:App" | |
x:Class="App.Square"> | |
<local:CustomMap x:Name="Mapa" MapType="Street" | |
VerticalOptions="FillAndExpand" | |
IsShowingUser="true" /> | |
</ContentPage> |
CODE-BEHIND
Defina a área que será demonstrada no mapa através de Latitude X Longitude e também a proximidade em milhas.
Em seguida, adicione os pontos necessários para definir a região que será destacada, também utilize Latitude X Longitude, lembrando que a quantidade de pontos será determinante para definir qual o polígono será utilizado para destacar a região.
Observações: Os pontos precisam estar próximos da Latitude X Longitude usada para definir a área que será demonstrada no mapa.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Xamarin.Forms; | |
using Xamarin.Forms.Maps; | |
using Xamarin.Forms.Xaml; | |
namespace App | |
{ | |
[XamlCompilation(XamlCompilationOptions.Compile)] | |
public partial class Square : ContentPage | |
{ | |
public Square() | |
{ | |
InitializeComponent(); | |
/*Define área que será demonstrada no mapa*/ | |
Mapa.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(-23.4862658, -47.4443345), Distance.FromMiles(0.2))); | |
/*Define os pontos da região que será destacada*/ | |
Mapa.ShapeCoordinates.Add(new Position(-23.486265, -47.444334)); | |
Mapa.ShapeCoordinates.Add(new Position(-23.486836, -47.443764)); | |
Mapa.ShapeCoordinates.Add(new Position(-23.487302, -47.444504)); | |
Mapa.ShapeCoordinates.Add(new Position(-23.486667, -47.444994)); | |
} | |
} | |
} |
Android
Em seu projeto .android adicione uma classe chamada CustomMapRenderer, essa classe irá realizar a marcação da região de acordo com os pontos informados.
No método “OnElementPropertyChanged” você pode customizar o polígono editando as propriedades da variável polygonOptions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using Android.Views; | |
using App.Droid; | |
using App; | |
using Xamarin.Forms; | |
using Xamarin.Forms.Maps.Android; | |
using Xamarin.Forms.Maps; | |
using Android.Gms.Maps.Model; | |
[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))] | |
namespace App.Droid | |
{ | |
public class CustomMapRenderer : MapRenderer | |
{ | |
List<Position> shapeCoordinates; | |
bool isDrawn; | |
protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Map> e) | |
{ | |
base.OnElementChanged(e); | |
if (e.OldElement != null) | |
{ | |
// Unsubscribe | |
} | |
if (e.NewElement != null) | |
{ | |
var formsMap = (CustomMap)e.NewElement; | |
shapeCoordinates = formsMap.ShapeCoordinates; | |
Control.GetMapAsync(this); | |
} | |
} | |
protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) | |
{ | |
base.OnElementPropertyChanged(sender, e); | |
if (e.PropertyName.Equals("VisibleRegion") && !isDrawn) | |
{ | |
var polygonOptions = new PolygonOptions(); | |
polygonOptions.InvokeFillColor(0x66FF0000); | |
polygonOptions.InvokeStrokeColor(0x660000FF); | |
polygonOptions.InvokeStrokeWidth(30.0f); | |
foreach (var position in shapeCoordinates) | |
{ | |
polygonOptions.Add(new LatLng(position.Latitude, position.Longitude)); | |
} | |
NativeMap.AddPolygon(polygonOptions); | |
isDrawn = true; | |
} | |
} | |
} | |
} |
iOS
Em seu projeto .iOS adicione uma classe chamada CustomMapRenderer, essa classe irá realizar a marcação da região de acordo com os pontos informados.
No método “GetOverlayRenderer” você pode customizar o polígono editando as propriedades da variável polygonRenderer.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UIKit; | |
using Xamarin.Forms; | |
using App.iOS; | |
using Xamarin.Forms.Maps.iOS; | |
using MapKit; | |
using Xamarin.Forms.Platform.iOS; | |
using CoreLocation; | |
using ObjCRuntime; | |
[assembly: ExportRenderer(typeof(global::App.CustomMap), typeof(CustomMapRenderer))] | |
namespace App.iOS | |
{ | |
public class CustomMapRenderer : MapRenderer | |
{ | |
MKPolygonRenderer polygonRenderer; | |
protected override void OnElementChanged(ElementChangedEventArgs<View> e) | |
{ | |
base.OnElementChanged(e); | |
if (e.OldElement != null) | |
{ | |
var nativeMap = Control as MKMapView; | |
if (nativeMap != null) | |
{ | |
nativeMap.RemoveOverlays(nativeMap.Overlays); | |
nativeMap.OverlayRenderer = null; | |
polygonRenderer = null; | |
} | |
} | |
if (e.NewElement != null) | |
{ | |
var formsMap = (global::App.CustomMap)e.NewElement; | |
var nativeMap = Control as MKMapView; | |
nativeMap.OverlayRenderer = GetOverlayRenderer; | |
CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[formsMap.ShapeCoordinates.Count]; | |
int index = 0; | |
foreach (var position in formsMap.ShapeCoordinates) | |
{ | |
coords[index] = new CLLocationCoordinate2D(position.Latitude, position.Longitude); | |
index++; | |
} | |
var blockOverlay = MKPolygon.FromCoordinates(coords); | |
nativeMap.AddOverlay(blockOverlay); | |
} | |
} | |
MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlayWrapper) | |
{ | |
if (polygonRenderer == null && !Equals(overlayWrapper, null)) | |
{ | |
var overlay = Runtime.GetNSObject(overlayWrapper.Handle) as IMKOverlay; | |
polygonRenderer = new MKPolygonRenderer(overlay as MKPolygon) | |
{ | |
FillColor = UIColor.Red, | |
StrokeColor = UIColor.Blue, | |
Alpha = 0.4f, | |
LineWidth = 9 | |
}; | |
} | |
return polygonRenderer; | |
} | |
} | |
} |
Resultados
Adicionando 3 pontos – Triângulo
Adicionando 4 pontos – Quadrado
Adicionando 5 pontos – Pentágono
Esse e todos os exemplos deste blog encontram-se disponíveis no GitHub.
Parabéns pelo post. Muito bom!
Sucesso!
CurtirCurtir
Obrigado Rogelin 🙂
CurtirCurtir