Přejít k navigační liště

Zdroják » Různé » Microsoft Virtual Earth Silverlight Map Control

Microsoft Virtual Earth Silverlight Map Control

Články Různé

Ovládací prvek Microsoft Virtual Earth Silverlight Map Control je velmi komplexní prvek, který usnadňuje práci s online mapami v Silverlight aplikacích. V dnešním článku si na několika příkladech prakticky ukážeme základy jeho používání.

Ovládací prvek Microsoft Virtual Earth Silverlight Map Control usnadňuje práci s online mapami v Silverlight aplikaci. Výhoda tohoto řešení je především ve výkonu a v možnostech, které poskytuje WPF. Ovládací prvek Microsoft Virtual Earth Silverlight Map Control má totiž jako svého předka objekt System.Window­s.UIElement, tím pádem s ním můžeme dělat vše, co s jinými ovládacími prvky, takže není problém například aplikovat animace nebo datové vazby na tento ovládací prvek.

Co budete potřebovat?

Vše potřebné pro vývoj Silverlight aplikací najdete na adrese http://silverlight.net/GetStarted/. Vlastní ovládací prvek získáte po registraci na serveru Microsoft Connect (http://connect.microsoft.com/…apcontrolctp). Pokud budete chtít vytvářet vrstvy s použitím vlastních mapových podkladů, např. historických map, budete ještě potřebovat aplikaci MapCruncher Beta for Microsoft Virtual Earth (http://www.microsoft.com/…runcher.aspx). K čemu je dobrá si vysvětlíme později.

První úkol – zobrazit na mapě místa, o kterých se píše na Wikipedii

Jedna z možností, kterou nabízí Wikipedie, je přiřazení geografických souřadnic k článku. Pokud se podíváte například na heslo Praha, tak vpravo nahoře najdete zeměpisné souřadnice. Pokud se toto heslo rozhodnete editovat, tak zeměpisné souřadnice najdete v šabloně Geo:

{{Geo dms|50|05|14|N|s|14|25|16|E|v|type:city_region:CZ}}

Na základě této šablony poskytuje služba GeoNames seznam článků, které se nacházejí v určité oblasti.

Po vytvoření nového Silverlight projektu ve Visual Studiu musíte přidat referenci na knihovnu obsahující Microsoft Virtual Earth Silverlight Map Control, která je umístěna v instalačním adresáři ovládacího prvku, typicky %programfiles%Microsoft
Virtual Earth Silverlight Map ControlCTPLibraries
Microsoft.VirtualEarth.MapControl.dll
. Po přidání reference je ještě třeba ovládací prvek zaregistrovat v XAML souboru, kde ho budete chtít použít. Následující kód ukazuje, jak přidat mapu do Silverlight aplikace.

<UserControl x:Class="Maps.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"
   xmlns:m="clr-namespace:Microsoft.VirtualEarth.MapControl;assembly=Microsoft.VirtualEarth.MapControl"
   mc:Ignorable="d"
   d:DesignWidth="640" d:DesignHeight="480"
   Loaded="UserControl_Loaded">
  <Grid x:Name="LayoutRoot">
        <m:Map Name="mapa" Center="50.047665116, 14.45436553" ZoomLevel="8" />
    </Grid>
</UserControl>

K označení oblasti, kterou chce uživatel zobrazit, se používá tažení myší se stisknutou klávesou Ctrl. Tato akce vyvolá událost MouseDragBox, která nám umožní zjistit hranice oblasti, kde budeme hledat články.

private void map_MouseDragBox(object sender, MapMouseDragEventArgs e)
     {
         // Sestaveni url pro volání služby GeoNames
         string url = String.Format
         ("http://ws.geonames.org/wikipediaBoundingBox?north={0}&west={1}&south={2}&east={3}&lang=cs",
         mapa.ViewportPointToLocation(e.FromViewportPoint).Latitude.ToString
            (CultureInfo.InvariantCulture.NumberFormat),
         mapa.ViewportPointToLocation(e.FromViewportPoint).Longitude.ToString
            (CultureInfo.InvariantCulture.NumberFormat),
         mapa.ViewportPointToLocation(e.ViewportPoint).Latitude.ToString
            (CultureInfo.InvariantCulture.NumberFormat),
         mapa.ViewportPointToLocation(e.ViewportPoint).Longitude.ToString
            (CultureInfo.InvariantCulture.NumberFormat));

         // Asynchroní volání služby
         WebClient wb = new WebClient();
         wb.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wb_DownloadStringCompleted);
         wb.DownloadStringAsync(new Uri(url));
     }

Vlastnost FromViewportPoint obsahuje souřadnice počátku tažení myší a ViewportPoint osahuje souřadnice konce tažení myší. Pozor, nejedná se o geografické souřadnice, ale o souřadnice v rámci ovládacího prvku, které je nutné přepočítat metodou ViewportPointTo­Location na geografické souřadnice. Url sestavujeme podle dokumentace uvedené na webu GeoNames. Nezapomeňte, že volání služby je asynchronní a při zpracování odpovědi a přidání bodů na mapu budete muset synchronizovat hlavní vlákno aplikace s vláknem vytvořeným při asynchronním volání služby. Pro zpracování výsledku použijeme LINQ to XML. Je to jednoduché cvičení s XML a objekty, proto ho vynechám. Zaměřme se na zobrazení bodu na mapě. Jako bod na mapě můžete použít libovolný objekt odvozený od UIElement. My použijeme objekt Ellipse:

...
MapLayer pushpinsLayer = new MapLayer();
foreach (var entry in entries)
{
    Ellipse pushpin = new Ellipse();
    pushpin.Width = 10;
    pushpin.Height = 10;
    pushpin.Opacity = 0.7;
    pushpin.Tag = entry;
    pushpin.Fill = new SolidColorBrush(Colors.Red);

    pushpin.MouseMove += new MouseEventHandler(pushpin_MouseMove);              

    Location l = new Location();
    l.Latitude = Double.Parse(entry.Latitude, CultureInfo.InvariantCulture.NumberFormat);
    l.Longitude = Double.Parse(entry.Longitude, CultureInfo.InvariantCulture.NumberFormat);
    l.Altitude = Double.Parse(entry.Elevation, CultureInfo.InvariantCulture.NumberFormat);
    pushpinsLayer.AddChild(pushpin, l, PositionMethod.Center);
}

// Synchronizace s hlavním vláknem
Dispatcher.BeginInvoke(() => { mapa.AddChild(pushpinsLayer);
});
...

 Tím máme základ aplikace hotový. Ukázkový kód najdete ke stažení na konci článku nebo se podívejte na živou ukázku.

Druhý úkol – zobrazte hranice krajů v České republice

Tady využijeme databázi, kterou jsme použili v článku GIS, PHP a SQL Server 2008. Výstup jsem udělal velmi jednoduchý do textového souboru, kde jeden řádek odpovídá jednomu kraji a obsahuje název kraje a souřadnice vrcholů polygonu, který kraj ohraničuje. Přidání polygonu na mapu je následující:

...
MapPolygon polygon = new MapPolygon();
polygon.Fill = new SolidColorBrush(Colors.Red);
polygon.Stroke = new SolidColorBrush(Colors.Yellow);
polygon.StrokeThickness = 2;
polygon.Opacity = 0.6;
polygon.Locations = new LocationCollection();

foreach (string coordinate in coordinates)
{
    int i = coordinate.Trim().IndexOf(' ');
    Location l = new Location();
    l.Latitude = Double.Parse(coordinate.Substring(0, i).Trim(), CultureInfo.InvariantCulture.NumberFormat);
    l.Longitude = Double.Parse(coordinate.Substring(i + 1).Trim(),CultureInfo.InvariantCulture.NumberFormat);
    polygon.Locations.Add(l);
}

mapa.AddChild(polygon);
...

Pro vykreslení lomené čáry (polyline) bychom postupovali v podstatě identicky, jen bychom místo objektu MapPolygon použili objekt MapPolyline. Ukázkový kód najdete ke stažení opět na konci článku, a k dispozici je také živá ukázka.

Úkol třetí – mám vlastní mapové podklady a chci je zobrazit přes Bing Maps

Jako vlastní mapový podklad můžete použít libovolný obrázek, třeba naskenovanou mapu. My použijeme jeden naskenovaný list v rozlišení 600 dpi z publikace Turistický atlas Česko 1:50 000, který vydala společnost SHOCart, a díky vstřícnému přístupu ho mohu použít v rámci ukázkové aplikace. Jedná se konkrétně o stranu 205 s oříznutým okrajem. V tuto chvíli přichází ke slovu aplikace MapCruncher Beta for Microsoft Virtual Earth, která slouží k vytvoření „dlaždic“, ze kterých je mapa sestavena.

  1. Spusťte aplikaci MapCruncher Beta for Microsoft Virtual Earth.
  2. Otevřete váš mapový podklad File → Add Source Map…
  3. V levé části okna nastavte vaši mapu tak, aby kříž ukazoval na nějaký významný bod mapy, třeba křižovatku.
  4. V pravé části okna najděte stejný bod na Bing Maps.
  5. Pomocí tlačítka Add vlevo dole bod uložte.
  6. Stejným postupem přidejte alespoň jeden další bod.
  7. Kliknutím na tlačítko Lock mapy spojíte, takže když pohnete jednou mapou, pohne se odpovídajícím způsobem i druhá.
  8. Tlačítkem Render… spustíte proces vytvoření dlaždic. V našem případě se jich vytvořilo 1401.

MAP01

Takto vytvořené „dlaždice“ najdete v podadresáři Layer_NewLayer, jehož obsah musí být přístupný Silverlight aplikaci. Nejjednodušší je ho překopírovat přímo do webové aplikace, která bude hostovat vaši mapovou aplikaci. Dále se vytvořil soubor MapCruncherMe­tadata.xml, který obsahuje některé informace, které budeme dále potřebovat. Pro zobrazení vlastních mapových podkladů musíte vytvořit novou vrstvu, která bude přistupovat k vygenerovaným „dlaždicím“.

MapTileLayer customTileLayer = new MapTileLayer();
//Hranice vlastní vrstvy, najdete je v souboru MapCruncherMetadata.xml
LocationRect boundingRect = new LocationRect(
    new Location(49.9915720948007, 14.5791563924893),
    new Location(50.1252788649904, 14.7184119383853)
);
LocationRectTileSource customTileSource = new LocationRectTileSource();
// URL, kde se nacházejí „dlaždice“, URL musí být absolutní
customTileSource.UriFormat = "http://localhost:19738/CustomTiles/{0}.png";
// rozsah přiblížení, pro které se dlaždice vygenerovaly.
// Závisí na kvalitě mapového podkladu.
// Opět najdete v souboru MapCruncherMetadata.xml
customTileSource.ZoomRange = new Range<double>(11, 16);
customTileSource.BoundingRectangle = boundingRect;
customTileLayer.TileSources.Add(customTileSource);
customTileLayer.Opacity = 0.7;
mapa.Children.Add(customTileLayer);

Pokud chcete skrýt základní mapový podklad Bing Maps, nastavíte vlastnost Mode objektu Map na MercatorMode:

<UserControl
   x:Class="CustomMapImagery.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:m="clr-namespace:Microsoft.VirtualEarth.MapControl;assembly=Microsoft.VirtualEarth.MapControl"
   xmlns:mCore="clr-namespace:Microsoft.VirtualEarth.MapControl.Core;assembly=Microsoft.VirtualEarth.MapControl"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc:Ignorable="d"
   d:DesignWidth="640" d:DesignHeight="480">
  <Grid x:Name="LayoutRoot">
        <m:Map Name="mapa">
            <m:Map.Mode>
               <mCore:MercatorMode></mCore:MercatorMode>
            </m:Map.Mode>
        </m:Map>
    </Grid>
</UserControl>

 Výsledek se základním mapovým podkladem vypadá takto:

MAP02

Na podobném principu funguje i použití mapových podkladů z jiných mapových služeb, např. z OpenStreetMap. Princip je velmi jednoduchý. Musíte umět vytvořit URL, které bude z mapového serveru stahovat jednotlivé „dlaždice“ na základě parametrů X, Y, zoom. Tyto parametry u OpenStreetMap odpovídají 1:1 definici „dlaždic“ z Bing Maps, takže není třeba nic přepočítávat. Pokud byste chtěli použít jiné mapy, např. Yahoo, bylo by nutné parametry přepočítat. Nyní stačí vytvořit nový objekt, který dědí z objektu TileSource a přetížit metodu GetUri:

using System;

namespace OpenStreetMap
{
    public class OpenStreetMapTileSource : Microsoft.VirtualEarth.MapControl.TileSource
    {
        public OpenStreetMapTileSource(): base("http://tile.openstreetmap.org/{2}/{0}/{1}.png")
        {
        }

        public override Uri GetUri(int x, int
y, int zoomLevel)
        {
            return new Uri(String.Format(this.UriFormat, x, y, zoomLevel));
        }
    }
}

Tento objekt pak nastavíme jako zdroj „dlaždic“ objektu mapy:

...
<m:Map.Children>
   
<m:MapTileLayer>
        <m:MapTileLayer.TileSources>
           
<local:OpenStreetMapTileSource></local:OpenStreetMapTileSource>
        </m:MapTileLayer.TileSources>
    </m:MapTileLayer>
</m:Map.Children>
...

Ukázkový kód, bez vygenerovaných „dlaždic“, najdete na konci článku. Dále se můžete podívat na ukázku vlastního použití mapového podkladu nebo na využití OpenStreetMaps.

Závěr

Bing Maps jsou otevřená platforma pro vývoj mapových aplikací, která umožňuje bezproblematickou podporu pro integraci s jinými mapovými podklady. Kromě ovládacího prvku, který je v článku popsán, je ještě k dispozici obdobný ovládací prvek pro WPF aplikace a pro Microsoft Surface. Najdete ho na serveru CodePlex: http://virtualearthwpf.codeplex.com/.

Kód ukázek ke stažení: MS Virtual Earth Silverlight Control


Autorem článku je Štěpán Bechynský, specialista pro vývojové nástroje ve společnosti Microsoft v České republice. Informace pro vývojáře také najdete na blogu odborníků z českého Microsoftu.

Komentáře

Subscribe
Upozornit na
guest
1 Komentář
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
jesusatan

Zdravim, pekny clanek, chtel bych se zeptat jak je to s pravy pro komercni ucely,kdyz mapy si budu nacitat svoje.
Jedna se mi o odstraneni loga Microsoft, a VirutalEarh atd.
diky.

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.