Mapsui adding map pins in Xamarin Forms

5.8k views Asked by At


I need to add a bunch of pins on a MapsUI map control that uses OpenStreetMap tiles.

The problem is I cant find anything mentioning pins in their documentation so my question is:

Are there any pins available but have different names or i have to draw pins myself (using Geometry and Points as in some examples i found) and if so how do i keep them the same size when zooming the map ?

Maybe someone can point out where should i look in their documentation in case I'm blind and missed it.

Thanks!

4

There are 4 answers

3
pauldendulk On BEST ANSWER

The idea is that you use your own bitmaps to draw as 'pins'.

Mapsui has features. A feature has a geometry which can be a point, linestring and polygon (and some others). A feature is drawn with some kind of style. What you need to do is create features with point geometry and use a symbolstyle with a bitmap as symbol. You need to register your bitmap and use the bitmapId in the symbol. See the sample here:

https://github.com/Mapsui/Mapsui/blob/master/Samples/Mapsui.Samples.Common/Maps/PointsSample.cs

1
Wasif Mahmood Mustafa On

You can use Xamarin.Forms.GoogleMaps as they give you the feature to add multiple pins of your choice.

Here is the sample code :

var position = new Position(Latitude, Longitude);

        var pin = new Pin
        {
            Type = PinType.Place,
            Position = position,
            Icon = BitmapDescriptorFactory.FromBundle("pin.png"),
            Label = "custom pin",
            Address = "custom detail info",
        };

        MyMap.Pins.Add(pin);
0
Richard On

The following works on version 3.02. I've not checked it on any other version of MapSui. First make sure your pin Bitmap is an embedded resource. You can then get the Bitmap ID like this:

var assembly = typeof(YourClass).GetTypeInfo().Assembly;
var image = assembly.GetManifestResourceStream("YourSolution.YourProject.AFolder.image.png");

If var image returns null, then the image was not found and it's likely not an embedded resource or you got the address/name wrong.

var ID = BitmapRegistry.Instance.Register(image);

The BitmapRegistry method also registers the BitMap for MapSui to use later. I think if it's your first image registered it will be 0.

Then you can create a memory layer as follows:

MemoryLayer PointLayer = new MemoryLayer
        {
            Name = "Points",
            IsMapInfoLayer=true,
            DataSource = new MemoryProvider(GetListOfPoints()),
            Style = new SymbolStyle { BitmapId = ID, SymbolScale = 0.50, SymbolOffset = new Offset(0, bitmapHeight * 0.5) };
            
        };

The DataSource can be generated as follows (I'm just adding one feature, but you can add as many as you like):

private IEnumerable<IFeature> GetListOfPoints()
    {
        List<IFeature> list = new List<IFeature>();

        var feature = new Feature();
        feature.Geometry = new Point(-226787, 7155483);
        feature["name"] = "MyPoint";

        list.Add(feature);

        IEnumerable<IFeature> points = list as IEnumerable<IFeature>;
        return points;
    }

Then add the new MemoryLayer to your Map as follows:

MapControl.Map?.Layers.Add(PointLayer);
0
Alexander Yashyn On

Your Mapsui Map View Mapsui.UI.Forms.MapView has property Pins. You can add pins there. You can access MapView View from code-behind *xaml.cs of your MapView.

For that, first, name your Map View in XAML Page:

<ContentPage
    xmlns:mapsui="clr-namespace:Mapsui.UI.Forms;assembly=Mapsui.UI.Forms"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="YourProject.Pages.YourMap">
  <ContentPage.Content>
     <mapsui:MapView
        x:Name="selectMapControl"/>
  </ContentPage.Content>
</ContentPage>

Then access it from C# code-behind of that Page:

using Mapsui.UI.Forms;

protected override async void OnAppearing()
{
    selectMapControl.Pins.Add(new Pin(new MapView())
    {
       Position = new Position(0, 0),
       Type = PinType.Pin,
       Label = "Zero point",
       Address = "Zero point",
    });
}

Hope this simplest example will help.