1

I can add PNG images without issue to change the default MapIcon Image, but as soon as I try to use an SVG the application crashes with 'application.exe has exited with code -529697949 (0xe06d7363) 'Microsoft C++ Exception'.

I am aware of the SvgImageSource class and I can use this fine in other areas of the application to render an SVG image, however when trying to add an SVG to the MapIcon.Image; which is of type IRandomAccessStreamReference, it does not work. I'm just wondering if this is a limitation of the API and if I should just be using bitmaps rather than an SVG when it comes to displaying custom images on the MapIcon?

I've added a quick failing sample below.

MainPage.xaml:

<Page xmlns:my="using:Windows.UI.Xaml.Controls.Maps" 
    x:Class="TestMapWithSVGForMapIcon.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <my:MapControl Loaded="{x:Bind _viewModel.AddMapIcon}"/>
    </Grid>
</Page>

MainPage.xaml.cs:

public sealed partial class MainPage : Page
{
    private MainViewModel _viewModel;

    public MainPage()
    {
        InitializeComponent();

        _viewModel = new MainViewModel();
        DataContext = _viewModel;
    }
}

MainViewModel.cs:

public class MainViewModel
{
    protected MapControl Map { get; set; }

    public void AddMapIcon(object sender, RoutedEventArgs e)
    {
        if (sender is MapControl map)
        {
            Map = map;
        }

        var mapIcon = new MapIcon
        {
            Location = new Geopoint(new BasicGeoposition()
            {
                Latitude = 53.795452,
                Longitude = -4.304733
            }),
            //works Ok with .png files
            Image = RandomAccessStreamReference.CreateFromUri(new Uri($"ms-appx:///Assets/Hazard_H1.svg")),              
        };

        Map.MapElements.Add(mapIcon);    
    }
}
daz_p
  • 13
  • 2

1 Answers1

2

No, SVG is not a supported stream type for MapIcon.Image You can use a stream that contains an encoded raster image in PNG or JPG format, or a raw array of bytes in RGB format.

Duncan Lawler
  • 1,772
  • 8
  • 13
  • Hello Duncan, do you have code sample on how to convert a raw array of bytes to RandomAccessStreamReference ? – Jean-Daniel Gasser Apr 16 '21 at 10:52
  • Never tried that method, but I assume it would be something like this: using (var memStream = new MemoryStream(array)) { var streamReference = RandomAccessStreamReference.CreateFromStream(memStream.AsRandomAccessStream()); } – Duncan Lawler Apr 16 '21 at 16:12
  • Thank you for the answer. I already tried that, but the icon is not set, and I cannot find a way to know exactly why. This is the only synchronous (not async) code working : using (var l_rasMemoryStream = new InMemoryRandomAccessStream()) using (var l_osOutput = l_rasMemoryStream.GetOutputStreamAt(0)) using (var l_dwWriter = new DataWriter(l_osOutput)) { l_dwWriter.WriteBytes(p_arbImage); l_dwWriter.StoreAsync().GetResults(); l_dwWriter.FlushAsync().GetResults(); p_miToSet.Image = RandomAccessStreamReference.CreateFromStream(l_rasMemoryStream); } – Jean-Daniel Gasser Apr 19 '21 at 05:59
  • This code, which is really much simpler, does not work either: p_miToSet.Image = RandomAccessStreamReference.CreateFromStream(p_arbImage.AsBuffer().AsStream().AsRandomAccessStream()); – Jean-Daniel Gasser Apr 19 '21 at 06:01
  • I suspect your stream may be getting disposed before the map control has a chance to read the bitmap from it. Try holding onto the stream reference at the same scope as the map control and not disposing it immediately after the call. – Duncan Lawler Apr 20 '21 at 23:35
  • 1
    You're right, here is my definitive code: `var l_rasStream = new InMemoryRandomAccessStream(); await l_rasStream.WriteAsync(p_arbImage.AsBuffer()); await l_rasStream.FlushAsync(); p_miToSet.Image = RandomAccessStreamReference.CreateFromStream(l_rasStream);` – Jean-Daniel Gasser Apr 21 '21 at 05:04