How to add different style marker pins to Xamarin.Forms maps (SfMaps)
Description
This article explains how to add the different style marker pins to the Xamarin.Forms Syncfusion imagery layer maps.
Solution
Step 1: Initialize the SfMaps control and add the Imagery layer with default OSM map type to the layer collection of the control.
… <maps:SfMaps x:Name="sfmap" BackgroundColor="White"> <maps:SfMaps.Layers> <maps:ImageryLayer > </maps:ImageryLayer> </maps:SfMaps.Layers> </maps:SfMaps> …
Step 2: Create a custom marker by extending the MapMarker with required additional properties and add the custom markers with latitude, longitude, and population (in million) values to the Imagery layer using the Markers property as shown in the following code.
XAML:
<maps:SfMaps> <maps:SfMaps.Layers> <maps:ImageryLayer MarkerTemplate="{StaticResource personDataTemplateSelector}"> <maps:ImageryLayer.Markers> <local:CustomMarker Label="United States" Population="321" Latitude="37.090240" Longitude="-95.712891" /> <local:CustomMarker Label="Congo" Population="204" Latitude="-4.038333" Longitude="21.758663" /> <local:CustomMarker Label="Kazakhstan" Population="137" Latitude="48.019573" Longitude="66.923683" /> <local:CustomMarker Label="Australia" Population="255" Latitude="-25.274399" Longitude="133.775131" /> </maps:ImageryLayer.Markers> </maps:ImageryLayer> </maps:SfMaps.Layers> </maps:SfMaps>
C#:
… public class CustomMarker : MapMarker { /// <summary> /// Gets or sets marker image for high population. /// </summary> public ImageSource HighPopulationMarker { get; set; } /// <summary> /// Gets or sets marker image for low population. /// </summary> public ImageSource LowPopulationMarker { get; set; } /// <summary> /// Gets or sets population (in million) /// </summary> public int Population { get; set; } } …
Step 3: You can define the own marker style using the MarkerTemplate property of Imagery layer. To add the different style marker based on the marker data, change the MarkerTemplate using the DataTemplateSelector as shown in the following code.
XAML:
… <ContentPage.Resources> <ResourceDictionary> <DataTemplate x:Key="HighPopulationTemplate"> <StackLayout IsClippedToBounds="false" HorizontalOptions="StartAndExpand" VerticalOptions="Center" HeightRequest="30"> <Image Source="{Binding HighPopulationMarker}" Scale="1" Aspect="AspectFit " HorizontalOptions="StartAndExpand" VerticalOptions="Center" HeightRequest="15" WidthRequest="23" /> </StackLayout> </DataTemplate> <DataTemplate x:Key="LowPopulationTemplate"> <StackLayout IsClippedToBounds="false" HorizontalOptions="StartAndExpand" VerticalOptions="Center" HeightRequest="30"> <Image Source="{Binding LowPopulationMarker}" Scale="1" Aspect="AspectFit " HorizontalOptions="StartAndExpand" VerticalOptions="Center" HeightRequest="15" WidthRequest="23" /> </StackLayout> </DataTemplate> <local:MapsDataTemplateSelector x:Key="personDataTemplateSelector" HighPopulationTemplate="{StaticResource HighPopulationTemplate}" LowPopulationTemplate="{StaticResource LowPopulationTemplate}" /> </ResourceDictionary> </ContentPage.Resources> … <maps:SfMaps.Layers> <maps:ImageryLayer MarkerTemplate="{StaticResource personDataTemplateSelector}"> </maps:ImageryLayer> </maps:SfMaps.Layers> </maps:SfMaps> …
C#:
class MapsDataTemplateSelector : DataTemplateSelector { public DataTemplate HighPopulationTemplate { get; set; } public DataTemplate LowPopulationTemplate { get; set; } protected override DataTemplate OnSelectTemplate(object item, BindableObject container) { return ((CustomMarker)item).Population >= 250 ? HighPopulationTemplate : LowPopulationTemplate; } }
Output
You can find the complete sample in this link.