简体   繁体   中英

Creating a simple WPF map control from scratch

I really want to create my own map control in WPF because the only one that would be suitable for my requirements would be the Google Maps JavaScript API because it can do almost anything I need but that is only for web and mobile and I have tried the Bing and ESRI maps but they can't do what I want.

I have started a little experiment project to see if I can load the tiles when zooming and it kind of works, here is the code:

    <ScrollViewer Margin="10" PanningMode="Both" HorizontalScrollBarVisibility="Visible">
        <Canvas x:Name="lyrTiles" Height="3000" Width="3000"/>
    </ScrollViewer>

    <Grid x:Name="lyrControl" Margin="10">
        <Button x:Name="moveUp" Content="U" HorizontalAlignment="Left" Margin="35,10,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
        <Button x:Name="moveRight" Content="R" HorizontalAlignment="Left" Margin="55,30,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
        <Button x:Name="moveDown" Content="D" HorizontalAlignment="Left" Margin="35,50,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
        <Button x:Name="moveLeft" Content="L" HorizontalAlignment="Left" Margin="15,30,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
        <Button x:Name="zoomIn" Content="ZI" HorizontalAlignment="Left" Margin="35,81,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
        <Button x:Name="zoomOut" Content="ZO" HorizontalAlignment="Left" Margin="35,311,0,0" VerticalAlignment="Top" Width="20" Height="20"/>
        <Slider x:Name="zoomSlider" HorizontalAlignment="Left" Margin="35,106,0,0" VerticalAlignment="Top" Orientation="Vertical" Height="200" Width="20" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Interval="1"/>
        <Button x:Name="typeHybrid" Content="Hybrid" HorizontalAlignment="Right" Margin="0,10,65,0" VerticalAlignment="Top" Width="50" Height="15" Padding="0,-1,0,0" FontSize="10"/>
        <Button x:Name="typeTerrain" Content="Terrain" HorizontalAlignment="Right" Margin="0,10,10,0" VerticalAlignment="Top" Width="50" Height="15" Padding="0,-1,0,0" FontSize="10"/>
        <Button x:Name="typeSatellite" Content="Satellite" HorizontalAlignment="Right" Margin="0,10,120,0" VerticalAlignment="Top" Width="50" Height="15" Padding="0,-1,0,0" FontSize="10"/>
        <Button x:Name="typeRoad" Content="Road" HorizontalAlignment="Right" Margin="0,10,175,0" VerticalAlignment="Top" Width="50" Height="15" Padding="0,-1,0,0" FontSize="10"/>
        <Label x:Name="copyright" Content="Map data ©2014 Google" HorizontalAlignment="Right" VerticalAlignment="Bottom" Padding="0" Width="200" FontSize="10" FontFamily="Calibri" FontWeight="Bold"/>
    </Grid>
    <Canvas x:Name="lyrActive" Margin="10,10,27,28" MouseWheel="lyrActive_MouseWheel" Background="#00000000"/>




    public int zoomLevel = 0;
    public int zoomWidth = 2;

    public MainWindow()
    {
        InitializeComponent();

        Image i = new Image(); i.Width = 250; i.Height = 250; i.Margin = new Thickness(0, 0, 0, 0);
        i.Source = new BitmapImage(new Uri("https://a.tiles.mapbox.com/v3/examples.map-9ijuk24y/0/0/0.png"));
        lyrTiles.Children.Add(i);
    }

    private void lyrActive_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        if (e.Delta > 0)
        {
            lyrTiles.Children.Clear();
            zoomLevel += 1; zoomWidth = zoomWidth + zoomWidth / 2;
            for (int x = 0; x < zoomWidth; x++)
            {
                for (int y = 0; y < zoomWidth; y++)
                {
                    lyrTiles.Children.Add(new Image()
                    {
                        Margin = new Thickness(250 * x, 250 * y, 0, 0),
                        Source = new BitmapImage(new Uri("https://a.tiles.mapbox.com/v3/examples.map-9ijuk24y/" + zoomLevel + "/" + x + "/" + y + ".png"))
                    });
                }
            }
        }
    }

    private void ScrollViewer_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        if (e.Delta > 0)
        {
            lyrTiles.Children.Clear();
            zoomLevel += 1; zoomWidth = zoomWidth + zoomWidth / 2;
            for (int x = 0; x < zoomWidth; x++)
            {
                for (int y = 0; y < zoomWidth; y++)
                {
                    lyrTiles.Children.Add(new Image()
                    {
                        Margin = new Thickness(250 * x, 250 * y, 0, 0),
                        Source = new BitmapImage(new Uri("https://a.tiles.mapbox.com/v3/examples.map-9ijuk24y/" + zoomLevel + "/" + x + "/" + y + ".png"))
                    });
                }
            }
        }
    }

Is this the correct way I should be rendering the tiles? I know I have to remove ones that are not visible but this is just a very very simple project to see what I can actually do to make a map. How can I start to make this work better?

Also, I think that the biggest and most important thing will be the coordinates because they are used from everything from locating the centre of the map so it can download the correct tiles to placing markers at specific locations. How can I do this, do I need some sort of huge latitude and longitude axis?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM