Makale Özeti

Bu makalemizde Windows Phone uygulamalarımız için Silverlight Bing Map kullanımını inceleyeceğiz.

Makale

Merhaba, bu yazımızda Windows Phone 7 cihazımızda (emulator ile) 'Silverlight Bing Map' i incelemeye çalışacağız. Uygulamalarımızda oldukça sık ihtiyaç duyulabilecek harita üzerinde yer göstermek, bu yere raptiye (pushpin) ekleyerek belirtmek ve belirttiğimiz yer üzerine bir not düşmek, belirli bir noktadan, bir diğer noktaya yolun rotasını gösterebilmek gibi konular için bing map bulunmaz bir araç.

Örnek bir uygulama geliştirmeden önce, bir takım ön hazırlıklar yapmamız gerekiyor. İşe Bing Map Sdk'yı bilgisayarımıza kurarak başlayabiliriz. Tabii bu sdk'dan da önce pc'mizde VS 2010 ve phone developer tools'un kurulu olduğunu varsayalım.

Bing Map Silverlight Control SDK'yı buradan indirebilirsiniz. Bing Map'i çok daha yakından, silverlight (xaml ve cs) örnek source kodlarıyla birlikte incelemek isteyenler de buradan (Interactive SDK) erişebilirler.

Bilgisayarımıza map sdk'yı da kurduğumuzu varsaydıktan sonra, şimdi de sıra MS Live acount'umuzu kullanarak bir bing map ID'si almaya geldi. Bunun için microsoft'un Maps Account Center portal adresine gitmemiz gerekiyor. Accout adrese buradan (http://www.bingmapsportal.com/) erişilebilir.

Maps Accout Portal'a gittiğimizde ise karşımıza şöyle bir ekran görüntüsü çıkacaktır;

Live account'umuzu kullanarak giriş yaptıktan (Sign In) sonra, Create or view keys linki kullanarak, yeni bir bing map ID (ya da Key) oluşturabilir veya görüntüleyebiliriz.

Key oluşturduğumuzda veya görüntülediğimizde aşağıdaki gibi bir ekran görüntüsü ile karşılaşırız.

Portal'dan bir Key'de elde ettiğimize göre şimdi örnek uygulamamızı geliştirmeye başlayabiliriz. Öncelikle VS 2010 / File / New Project / Silverlight for Windows Phone template ile yeni bir proje oluşturalım. Oluşturduğumuz projemize defaul olarak MainPage.xaml ve App.xaml gelmektedir.

App.xaml dosyası cs editörümüzü açarak aşağıdaki gibi bing map portal'dan elde ettiğimiz Key'imizi Id adıyla diğer sayfalardan erişilebilecek şekilde tanımlayalım.

public partial class App : Application {

  internal const string Id = "<Bing Map Key>";

Sdk kurulumundan sonra aşağıdaki resimde de görüleceği gibi pek çok kontrolün eklendiğini göreceğiz.

Şimdi MainPage.xaml Grid içerisine silverlight bing map sdk ile birlikte gelen Map kontrolümüzü aşağıdaki gibi ekleyelim. Xaml kodlarından da görüleceği gibi copright ve logo'yu görünmez hale getirmemiz de mümkün.

MainPage.xaml

<!--LayoutRoot is the root grid where all page content is placed-->

<Grid x:Name="LayoutRoot" Background="Transparent">

  <Grid.RowDefinitions>

    <RowDefinition Height="Auto"/>

    <RowDefinition Height="*"/>

  </Grid.RowDefinitions>

 

  <!--TitlePanel contains the name of the application and page title-->

  <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">

    <TextBlock x:Name="ApplicationTitle" Text="Enlem  :  Boylam" FontSize="26"/>

    <TextBlock x:Name="PageTitle" Text="Lat. : Long. " FontSize="22" />

  </StackPanel>

 

  <!--ContentPanel - place additional content here-->

  <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

    <Microsoft_Phone_Controls_Maps:Map

        x:Name="myMap"

        d:LayoutOverrides="Width, Height"

        CopyrightVisibility="Collapsed"

        LogoVisibility="Collapsed"

         TargetViewChanged="myMap_TargetViewChanged">

      <Microsoft_Phone_Controls_Maps:Map.Mode>

        <Microsoft_Phone_Controls_Maps:AerialMode ShouldDisplayLabels="True" />

      </Microsoft_Phone_Controls_Maps:Map.Mode>

    </Microsoft_Phone_Controls_Maps:Map>

  </Grid>

</Grid>

 

<!--Sample code showing usage of ApplicationBar-->

<phone:PhoneApplicationPage.ApplicationBar>

  <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">

    <shell:ApplicationBarIconButton IconUri="/icons/reload_alt1_18x21.png"  Text="Change Map Mode" Click="btnChangeMode_Click"/>

    <shell:ApplicationBarIconButton IconUri="/icons/plus_alt_32x32.png" Text="Zoom In" x:Name="btnZoomIn" Click="btnZoomIn_Click" />

    <shell:ApplicationBarIconButton IconUri="/icons/minus_24x6.png" Text="Zoom Out" x:Name="btnZoomOut" Click="btnZoomOut_Click"/>

    <shell:ApplicationBarIconButton IconUri="/icons/home_24x24.png" Text="Home" x:Name="btnCenter" Click="btnCenter_Click"/>

  </shell:ApplicationBar>

</phone:PhoneApplicationPage.ApplicationBar>

MainPage.cs sınıfımıza map kontrol yüklendiğinde default zoomlevel (yükseklik) , bing map portal'dan elde ettiğimiz Key'i tanımlayacağımız CredentialsProvider nesnemizi ve haritamızın ekranda görüleceği ilk konumu private olarak tanımlayalım.

 private const double DefaultZoomLevel = 17.0;

 private readonly CredentialsProvider _credentialsProvider = new ApplicationIdCredentialsProvider(App.Id);

 private static readonly GeoCoordinate DefaultLocation = new GeoCoordinate(38.3744951212275, 26.8655549034000);

Hemen ardından MainPage load event'ı kullanarak default location üzerine harita üzerinde özellikle dikkat çekmek istediğimiz ya da bir makanın yerini tarif etmek istediğimiz noktaya bir Pushpin (Raptiye) ekleyelim. Biz kendi örneğimizde İzmir, Güzelbahçe'de bir balıkçı barınağında günlük, taze balık satılan bir yerin tarifini yapalım. :) Pushpin nesnemizi aşağıdaki kod satırlarında görüldüğü gibi oluşturalım.

Pushpin myPushpin_1 = new Pushpin();

myPushpin_1.Location = new GeoCoordinate(38.3744951212275, 26.8655549034000);

myPushpin_1.Content = "Günlük taze balık alınabilir..";

myPushpin_1.Background = new SolidColorBrush(Colors.Red);

MainPage.cs sınıfımızın son halini de aşağıdaki gibi tamamlayalım.

C#

public partial class MainPage : PhoneApplicationPage {

  private const double DefaultZoomLevel = 17.0;

  private readonly CredentialsProvider _credentialsProvider = new ApplicationIdCredentialsProvider(App.Id);

  private static readonly GeoCoordinate DefaultLocation = new GeoCoordinate(38.3744951212275, 26.8655549034000);

 

  public MainPage() {

    InitializeComponent();

    Loaded += MainPage_Loaded;

  }

 

  private void MainPage_Loaded(object sender, RoutedEventArgs e) {

 

    myMap.CredentialsProvider = _credentialsProvider;

 

    Pushpin myPushpin_1 = new Pushpin();

    myPushpin_1.Location = new GeoCoordinate(38.3744951212275, 26.8655549034000);

    myPushpin_1.Content = "Günlük taze balık alınabilir..";

    myPushpin_1.Background = new SolidColorBrush(Colors.Red);

 

 

    myMap.Children.Add(myPushpin_1);

 

    myMap.Center = DefaultLocation;

    myMap.ZoomLevel = DefaultZoomLevel;

 

  }

 

  private void changeMapMode() {

    if (myMap.Mode is AerialMode) {

      myMap.Mode = new RoadMode();

    }

    else {

      myMap.Mode = new AerialMode(true);

    }

  }

 

  private void btnChangeMode_Click(object sender, EventArgs e) {

    changeMapMode();

  }

 

  private void btnZoomIn_Click(object sender, EventArgs e) {

    myMap.ZoomLevel = myMap.ZoomLevel + 1;

  }

 

  private void btnZoomOut_Click(object sender, EventArgs e) {

    myMap.ZoomLevel = myMap.ZoomLevel - 1;

  }

 

  private void btnCenter_Click(object sender, EventArgs e) {

    myMap.Center = DefaultLocation;

    myMap.ZoomLevel = DefaultZoomLevel;

  }

 

  private void myMap_TargetViewChanged(object sender, MapEventArgs e) {

    // Enlem ve Boylam

    PageTitle.Text = string.Format("{0} : {1}", myMap.Mode.TargetCenter.Latitude, myMap.Mode.TargetCenter.Longitude);

  }

}

ZoomIn, ZoomOut, Map Mode ve Map Center özellikleri için Application Bar icon butonlarından faydalanabiliriz. Her bir icon button için o özelliğe uygun iconlar set ediyoruz.

F5 ile projemizi çalıştırarak emulatör ile haritamız üzerinde gezebiliriz. Map.Center özelliğini kullandığımız için haritamız ilk açılışında enlem ve boylam coordinatlarını verdiğimiz yere konumlanacaktır.

Haritamız üzerinde gezerken enlem ve boylam koordinat bilgilerini de aynı anda görebilmek haritamızın TargetViewChanged event'ını kullandık ve bu değerleri ekranımızın üst kısmındaki textblock'larına yazdırmış olduk.

 private void myMap_TargetViewChanged(object sender, MapEventArgs e) {

   // Enlem ve Boylam

   PageTitle.Text = string.Format("{0} : {1}", myMap.Mode.TargetCenter.Latitude, myMap.Mode.TargetCenter.Longitude);

 }

Haritamız üzerinde yapabileceklerimiz tabiki bunlarla sınırlı değil, örneğin aramak istediğimiz bir yeri adına göre arayabilir veya iki nokta arasındaki yolu (ya da rotayı) da haritamız üzerinde gösterebiliriz.

Yer arama ya da rota belirtme gibi işlemler için Bing Map'in SOAP servislerini kullanabiliriz. Bu servislerin erişim adresleri aşağıdaki gibidir. Projemiz'e service referans olarak ekledikten sonra kullanıma hazır durumda olacaktır.

http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc

http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc

http://dev.virtualearth.net/webservices/v1/searchservice/searchservice.svc

Projemize servislerimizi ekledikten sonra otomatik olarak oluşan ServiceReferences.ClientConfig configurasyon dosyasının da aşağıdaki gibi oluştuğunu göreceğiz.

<configuration>

  <system.serviceModel>

    <bindings>

      <basicHttpBinding>

        <binding name="BasicHttpBinding_IGeocodeService" maxBufferSize="2147483647"

            maxReceivedMessageSize="2147483647">

          <security mode="None" />

        </binding>

        <binding name="BasicHttpBinding_IRouteService" maxBufferSize="2147483647"

            maxReceivedMessageSize="2147483647">

          <security mode="None" />

        </binding>

        <binding name="BasicHttpBinding_ISearchService" maxBufferSize="2147483647"

            maxReceivedMessageSize="2147483647">

          <security mode="None" />

        </binding>

      </basicHttpBinding>

    </bindings>

    <client>

      <endpoint address="http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc"

          binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IGeocodeService"

          contract="service.geocode.IGeocodeService" name="BasicHttpBinding_IGeocodeService" />

      <endpoint address="http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc"

          binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IRouteService"

          contract="service.route.IRouteService" name="BasicHttpBinding_IRouteService" />

      <endpoint address="http://dev.virtualearth.net/webservices/v1/searchservice/searchservice.svc"

          binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISearchService"

          contract="service.search.ISearchService" name="BasicHttpBinding_ISearchService" />

    </client>

  </system.serviceModel>

</configuration>

Yukarıdaki gibi servislerimizi ekledikten sonra, örneğin iki nokta arasındaki yolu (rotayı) gösterebilmek için öncelikle GeocodeService'i kullanıp GeocodeResult nesnesini result olarak elde ettikten sonra (GeocodeResult içerisinde bulunan iki yere ait location (coordinat) bilgileri yer alacaktır) RouteService ile bu noktaların oluşturduğu rotaya harita üzerinde konumlanlanılacaktır. RouteServis çağrısı sonucunda RouteResponce nesnesi olarak geri dönecek ve RouteResponce.RoutePath içerisinde iki nokta arasındaki yolu oluşturan noktalar yer alacaktır. Noktalar elimize geçtikten sonra, bu noktalar ile  MapPolyLine kontrolünü oluşturabiliriz. Oluşturduğumuz MapPolyLine kontrolünüde Map kontrolü içine ekleyerek, rotamızı harita üzerinde gösterebileceğiz.

Tabii bu servisleri de kullanabilek için Bing Map Portal'dan aldığımız Key'imizi servis request nesnelerinin, credential'ına set etmemiz gerekmektedir.

Silverlight Bing Map'in Search, Route v.s. gibi özelliklere ait tüm source code'larına aşağıdaki adresden ulaşılabileceğini bir kere daha hatırlatarak makalemizi burada sonlandıralım.( http://www.microsoft.com/maps/isdk/silverlight/#MapControlInteractiveSdk.Tutorials.Services.Route )

Kolay gelsin.

Gökhan Manduz  - gokhanmanduz@hotmail.com