Search code examples
c#uwpbing-mapsuwp-maps

UWP MapControl: MapElement fixed heading


I'm adding a MapElement to my MapControl but when I rotate the MapControl, my MapElement rotates along with it. Is it possible to have a fixed heading on the element?

I've tried using a RotateTransform on the MapElement but the Element seems to just completely disappear.

I'm using the following code:
Also, the <Planes:Airplane /> object is just a custom drawn path.

    <Maps:MapControl x:Name="Map" Style="None" Grid.Row="2" TiltInteractionMode="GestureAndControl" ZoomInteractionMode="GestureAndControl" RotateInteractionMode="GestureAndControl" MapServiceToken="TOKEN HERE">
        <!-- Airplane Layer -->
        <Planes:Airplane x:Name="Airplane" Type="Prop" MaxHeight="80" Maps:MapControl.NormalizedAnchorPoint="0.5,0.5" />
    </Maps:MapControl>

Solution

  • I'm adding a MapElement to my MapControl but when I rotate the MapControl, my MapElement rotates along with it. Is it possible to have a fixed heading on the element?

    MapElement doesn't inherit from UIElement, which is the origin of RenderTransform. So it is not possible to use RenderTransform on an MapElement.

    But as a workaround you can consider using MapItemsControl to put any control or image on the map as you want and you can rotate or translate the image when you rotate the MapControl.

    MainPage.Xaml:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel VerticalAlignment="Center">
            <Maps:MapControl
            Width="500"
            Height="500"
            x:Name="myMap"            
            ZoomInteractionMode="GestureAndControl"
            TiltInteractionMode="GestureAndControl"   
            MapServiceToken="MapServiceToken">
                <Maps:MapItemsControl x:Name="mapItems">
                    <Maps:MapItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <Image Source="{Binding ImageSourceUri}" 
                                       Maps:MapControl.Location="{Binding Location}">
                                    <Image.RenderTransform>
                                        <TransformGroup>
                                            <RotateTransform Angle="{Binding Rotate.Angle}"
                                                             CenterX="{Binding Rotate.CenterX}"
                                                             CenterY="{Binding Rotate.CenterY}"/>
                                            <TranslateTransform X="{Binding Translate.X}"
                                                                Y="{Binding Translate.Y}"/>
                                        </TransformGroup>
                                    </Image.RenderTransform>
                                </Image>
                            </StackPanel>
                        </DataTemplate>
                    </Maps:MapItemsControl.ItemTemplate>
                </Maps:MapItemsControl>
            </Maps:MapControl>
            <Button Name="myAdd" Click="myAdd_Click">Click Me to Add Element</Button>
            <Button Name="btnRotate" Click="btnRotate_Click">Click Me to Rotate Element</Button>
        </StackPanel>
    </Grid>
    

    MainPage.xaml.cs:

    public class InterestPoint
    {
        public Uri ImageSourceUri { get; set; }
        public Geopoint Location { get; set; }
        public RotateTransform Rotate{ get; set; }
        public TranslateTransform Translate { get; set; }
        public Point CenterPoint { get; set; }
    }
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }
    
        private List<InterestPoint> InitInterestPoints(BasicGeoposition location)
        {
            List<InterestPoint> points = new List<InterestPoint>();
            points.Add(new InterestPoint {
                ImageSourceUri = new Uri("ms-appx:///Assets/mappin.png"),
                Location = new Geopoint(location),
                Rotate=new RotateTransform
                {
                    Angle=15,
                    CenterX=28.5,
                    CenterY=88
                },
                Translate=new TranslateTransform
                {
                    X=-28.5,
                    Y=-90
                }
            });
    
            return points;
        }
    
        private void myAdd_Click(object sender, RoutedEventArgs e)
        {
            mapItems.ItemsSource = InitInterestPoints(myMap.Center.Position);
        }
    
        private void btnRotate_Click(object sender, RoutedEventArgs e)
        {
            var points = mapItems.ItemsSource as List<InterestPoint>;
            points[0].Rotate.Angle += 10;
        }
    }
    

    Here is the Effect: enter image description here

    And Here is the link to the whole demo: MapElementRotationSample.

    Notes: The Image is added taking the left up point as anchor point. So you need to translate the image according to the image size.(My image is 57*90, so I need to translate it (-28.5,-88) to let the needle point be the center point).