Subscribe RSS Join our Facebook Group Follow us on Twitter!
in Search

All about GIS

April 2011 - Posts

  • Bing Maps and OData (part 6)

    Dear readers, first of all I wanted to say sorry because my last post about Bing Maps and OData wasn’t really my last post after all because I wanted to try something interesting. I wanted to port my NerdDinner silverlight application to Windows Phone. It’s not that hard actually. All you need to do is just a little bit of tuning because the map control in Windows Phone is a bit different with the Bing Maps Silverlight Control. And don’t forget the most important thing: you can’t add a service reference to OData service like you did in a Silverlight project. So, how can I get the data then? I’ll explain to you how.

    Generating WCF Data Services class

    Untuk bisa menggunakan OData service dari NerdDinner, kalian harus men-generate sendiri data service class-nya dengan cara menggunakan DataSvcUtil.exe. Untuk contoh penggunaannya bisa dilihat di sini. Jadi, kurang lebih yang akan kalian tuliskan di command prompt adalah seperti ini bila versi .NET Framework kalian adalah versi 4 “%windir%\Microsoft.NET\Framework\v4.0.30319\DataSvcUtil.exe” /dataservicecollection /version:2.0 /language:CSharp /out:NerdDinner.cs /uri:http://www.nerddinner.com/Services/OData.svc/

    Setelah selesai di generate, include file NerdDinner.cs hasil generate tadi ke dalam project Windows Phone Anda.

    Untuk keseluruhan projectnya sendiri, tidak banyak berbeda dengan versi silverlight-nya tapi tentu saja tidak akan ada Child Window-nya. Versi Windows Phone ini hanya untuk melihat lokasi dinnernya saja, tidak seperti versi silverlight. Hasil akhirnya akan tampak seperti pada gambar berikut.

    Result

    The source code can be downloaded from here. Enjoy…

    476 Views, 0 Comment(s), Published on: 04-30-2011 10:16 by veri to All about GIS
  • Bing Maps and OData (part 5)

    This is the last post from a series that talked about Bing Maps and OData. I’ve told you how to retrieve and how to consume the OData in here, how to create the ViewModel that will be used for data binding in here, and how to create the Child Window in here. Finally, in this post I will show you how to make the main UX for the NerdDinner web application. Just copy and paste the code below to your MainPage.xaml.

       1: <UserControl x:Class="BingMapsOData.MainPage"
       2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       4:     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
       5:     xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
       6:     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       7:     xmlns:local="clr-namespace:BingMapsOData"
       8:     xmlns:m="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"
       9:     xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
      10:     mc:Ignorable="d"
      11:     d:DesignHeight="300" d:DesignWidth="400">
      12:     
      13:     <UserControl.Resources>
      14:         <DataTemplate x:Key="DinnerTemplate">
      15:             <m:Pushpin Name="DinnerPushpin" m:MapLayer.Position="{Binding Location}" Content="{Binding Attendees}">
      16:                 <i:Interaction.Triggers>
      17:                     <i:EventTrigger EventName="MouseLeftButtonDown">
      18:                         <local:ShowChildWindowAction ChildWindowType="BingMapsOData.DetailsChildWindow"/>
      19:                     </i:EventTrigger>
      20:                 </i:Interaction.Triggers>
      21:                 <ToolTipService.ToolTip>
      22:                     <StackPanel>
      23:                         <StackPanel Margin="2" Orientation="Horizontal">
      24:                             <Image Source="Images/dinner.png" Width="16" Height="16"/>
      25:                             <TextBlock Text="{Binding Title}" Padding="2" FontWeight="Bold" TextWrapping="Wrap"/>
      26:                         </StackPanel>
      27:                         <TextBlock Text="{Binding Date}" Padding="2" Margin="2" TextWrapping="Wrap"/>
      28:                         <TextBlock Text="{Binding Address}" Padding="2" Margin="2" TextWrapping="Wrap"/>
      29:                         <TextBlock Text="Click Pushpin for details" Foreground="Gray" Padding="2" Margin="2" TextWrapping="Wrap"/>
      30:                     </StackPanel>
      31:                 </ToolTipService.ToolTip>
      32:             </m:Pushpin>
      33:         </DataTemplate>
      34:     </UserControl.Resources>
      35:  
      36:     <Grid x:Name="LayoutRoot" Background="Black">
      37:         <Grid.RowDefinitions>
      38:             <RowDefinition Height="40"/>
      39:             <RowDefinition Height="37"/>
      40:             <RowDefinition Height="*"/>
      41:             <RowDefinition Height="20"/>
      42:         </Grid.RowDefinitions>
      43:         <Grid.ColumnDefinitions>
      44:             <ColumnDefinition />
      45:             <ColumnDefinition Width="Auto" />
      46:         </Grid.ColumnDefinitions>
      47:         
      48:         <m:Map x:Name="dinnerMap"
      49:                Grid.Row="0" Grid.RowSpan="3"
      50:                Grid.Column="0" Grid.ColumnSpan="2"
      51:                CacheMode="BitmapCache"
      52:                CredentialsProvider="{StaticResource MyCredentials}"
      53:                Mode="AerialWithLabels"
      54:                NavigationVisibility="Collapsed">
      55:             <m:MapItemsControl x:Name="dinnerList"
      56:                                ItemTemplate="{StaticResource DinnerTemplate}"
      57:                                ItemsSource="{Binding Dinners}">
      58:             </m:MapItemsControl>
      59:         </m:Map>
      60:  
      61:         <StackPanel Grid.Row="0" Grid.Column="0" Background="Black" Opacity="0.8">
      62:             <StackPanel Orientation="Horizontal">
      63:                 <TextBlock Text="Nerd Dinner Browser" FontSize="20" Padding="6" Foreground="White"/>
      64:                 <TextBlock Text="{Binding Status}" FontSize="14" Padding="12" Foreground="LightGray" Name="txtStatus" >
      65:                     <TextBlock.Triggers>
      66:                     </TextBlock.Triggers>
      67:                 </TextBlock>
      68:             </StackPanel>
      69:         </StackPanel>
      70:  
      71:         <StackPanel Grid.Row="1" Grid.Column="0">
      72:             <Border BorderThickness="1" BorderBrush="LightGray" Background="LightGray" CornerRadius="5" Padding="5" Margin="1">
      73:                 <StackPanel Orientation="Horizontal">
      74:                     <TextBlock Text="Dinners From " Padding="4"/>
      75:                     <controls:DatePicker SelectedDate="{Binding From, Mode=TwoWay}" Name="dtFrom" Width="130"/>
      76:                     <TextBlock Text=" To " Padding="4"/>
      77:                     <controls:DatePicker SelectedDate="{Binding To, Mode=TwoWay}" Name="dtTo" Width="130"/>
      78:                     <TextBlock Text=" Near " Padding="4"/>
      79:                     <TextBox Name="txtPlace" ToolTipService.ToolTip="Optional, Leave blank for a high level view" Width="130"/>
      80:                     <Button Name="SearchDinners" Click="SearchDinners_Click" Margin="1" Padding="3">
      81:                         <StackPanel Orientation="Horizontal" >
      82:                             <Image Source="Images/dinner.png" Width="16" Height="16"/>
      83:                             <TextBlock Text=" Grab The Dinners "/>
      84:                         </StackPanel>
      85:                     </Button>
      86:                     <TextBlock Width="6"/>
      87:                     <StackPanel Background="Gray" Width="2" Margin="2"/>
      88:                 </StackPanel>
      89:             </Border>
      90:         </StackPanel>
      91:  
      92:         <Canvas x:Name="cMiniMap" 
      93:                 Width="150" 
      94:                 Height="150" 
      95:                 HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Grid.Row="2" >
      96:             <m:Map x:Name="MiniMap" 
      97:                    CredentialsProvider="{StaticResource MyCredentials}"
      98:                    CacheMode="BitmapCache"
      99:                    Width="150" 
     100:                    Height="150" 
     101:                    Mode="Road" 
     102:                    NavigationVisibility="Collapsed" 
     103:                    ScaleVisibility="Collapsed" 
     104:                    LogoVisibility="Collapsed"
     105:                    CopyrightVisibility="Collapsed" Foreground="{x:Null}">
     106:                 <m:Map.Clip>
     107:                     <EllipseGeometry RadiusX="69" RadiusY="69" Center="75,75" />
     108:                 </m:Map.Clip>
     109:             </m:Map>
     110:             <Ellipse Width="150" Height="150" Stroke="#CC4C4C4C" StrokeThickness="6" Margin="0,0,0,0" CacheMode="BitmapCache" />
     111:             <Ellipse Height="10" Width="10" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="70,70,0,0" x:Name="ellipse" Fill="#CC205A5B" />
     112:         </Canvas>
     113:  
     114:         <Canvas x:Name="cNavControl" 
     115:                 Width="100" 
     116:                 HorizontalAlignment="Left" 
     117:                 VerticalAlignment="Top" Grid.Row="2" Margin="60,155,0,0" Grid.RowSpan="3" >
     118:             <StackPanel Width="50">
     119:                 <Ellipse x:Name="ePan" Fill="#CC4C4C4C" Height="50" Canvas.ZIndex="1" Width="50"/>
     120:                 <Path x:Name="pathMiniMap" Stretch="Fill" Stroke="#CCFFFFFF" Height="195" Margin="-50,-195,-50,0" UseLayoutRounding="False" Canvas.ZIndex="1" Data="M75,0.5 C116.14521,0.5 149.5,33.854782 149.5,75 C149.5,111.64496 123.04255,142.11044 88.187729,148.3364 L86.852966,148.55754 L87.70414,149.04695 C94.776031,153.34393 99.5,161.1203 99.5,170 C99.5,183.53098 88.530975,194.5 75,194.5 C61.469025,194.5 50.5,183.53098 50.5,170 C50.5,161.1203 55.223965,153.34393 62.29586,149.04695 L63.14703,148.55754 L61.812263,148.3364 C26.957447,142.11044 0.5,111.64496 0.5,75 C0.5,33.854782 33.854786,0.5 75,0.5 z"/>
     121:                 <Grid x:Name="gridPan" Height="50" Margin="0,-50,0,0" Width="50" Canvas.ZIndex="1">
     122:                     <Grid.RowDefinitions>
     123:                         <RowDefinition Height="12"/>
     124:                         <RowDefinition Height="26" />
     125:                         <RowDefinition Height="12"/>
     126:                     </Grid.RowDefinitions>
     127:                     <Grid.ColumnDefinitions>
     128:                         <ColumnDefinition Width="12" />
     129:                         <ColumnDefinition Width="26" />
     130:                         <ColumnDefinition Width="12"/>
     131:                     </Grid.ColumnDefinitions>
     132:  
     133:                     <Image Source="Images/PanUp.png" Stretch="Fill" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Top" Height="20" Margin="0,5,0,0" Width="34" MouseLeftButtonDown="PanMapUp"/>
     134:                     <Image Source="Images/PanLeft.png" Stretch="Fill" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="20" Margin="5,0,0,0" Height="34" MouseLeftButtonDown="PanMapLeft"/>
     135:                     <Image Source="Images/PanRight.png" Stretch="Fill" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Right" VerticalAlignment="Center" Width="20" Margin="0,0,5,0" Height="34" MouseLeftButtonDown="PanMapRight"/>
     136:                     <Image Source="Images/PanDown.png" Stretch="Fill" Height="20" Margin="0,0,0,5" VerticalAlignment="Bottom" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" Width="34" MouseLeftButtonDown="PanMapDown"/>
     137:                 </Grid>
     138:                 <Border Margin="0,5,0,0" Width="15" Background="#CC4C4C4C" BorderThickness="1,1,1,0" BorderBrush="#CCFFFFFF" Height="15">
     139:                     <TextBlock Foreground="White" HorizontalAlignment="Center" Text="+" MouseLeftButtonDown="ZoomIn" VerticalAlignment="Center"/>
     140:                 </Border>
     141:                 <Border Height="160" HorizontalAlignment="Center" Margin="0" Width="15" RenderTransformOrigin="0.5,0.5" BorderThickness="1" Background="#CC4C4C4C" BorderBrush="#CCFFFFFF">
     142:                     <Slider x:Name="sldZoom" Orientation="Vertical" Maximum="21" Minimum="1" Height="150" Value="0" HorizontalAlignment="Center" Margin="0" SmallChange="1" BorderBrush="{x:Null}" BorderThickness="1" Width="15" Canvas.ZIndex="1" Foreground="{x:Null}" >
     143:                         <i:Interaction.Behaviors>
     144:                             <local:SnappingSlider/>
     145:                         </i:Interaction.Behaviors>
     146:                     </Slider>
     147:                 </Border>
     148:                 <Border Margin="0,0,0,5" Width="15" Background="#CC4C4C4C" BorderThickness="1,0,1,1" BorderBrush="#CCFFFFFF" Height="15">
     149:                     <TextBlock Foreground="White" HorizontalAlignment="Center" Text="-" MouseLeftButtonDown="ZoomOut" VerticalAlignment="Center"/>
     150:                 </Border>
     151:                 <Border Margin="0" Width="50" Background="#CC4C4C4C" BorderThickness="1" BorderBrush="#CCFFFFFF">
     152:                     <TextBlock Foreground="White" HorizontalAlignment="Center" Text="Road" MouseLeftButtonDown="MapStyleRoad" VerticalAlignment="Center"/>
     153:                 </Border>
     154:                 <Border Height="15" Margin="0" Width="50" Background="#CC4C4C4C" BorderThickness="1,0,1,1" BorderBrush="#CCFFFFFF">
     155:                     <TextBlock Foreground="White" HorizontalAlignment="Center" Text="Aerial" MouseLeftButtonDown="MapStyleAerial" VerticalAlignment="Center"/>
     156:                 </Border>
     157:                 <Border Height="15" Margin="0" Width="50" Background="#CC4C4C4C" BorderThickness="1,0,1,1" BorderBrush="#CCFFFFFF">
     158:                     <TextBlock Foreground="White" HorizontalAlignment="Center" Text="Hybrid" MouseLeftButtonDown="MapStyleHybrid" VerticalAlignment="Center"/>
     159:                 </Border>
     160:             </StackPanel>
     161:         </Canvas>
     162:  
     163:         <StackPanel Orientation="Horizontal" Grid.Row="3" HorizontalAlignment="Center">
     164:             <HyperlinkButton NavigateUri="http://students.netindonesia.net/blogs/veri" Content="My Blog" TargetName="_blank" FontFamily="Verdana" FontSize="12" Foreground="#FFFFFFFF"/>
     165:             <TextBlock Foreground="White" Text="|"></TextBlock>
     166:             <HyperlinkButton NavigateUri="http://twitter.com/vferdiansyah" Content="Twitter" TargetName="_blank" FontFamily="Verdana" FontSize="12" Foreground="#FFFFFFFF"/>
     167:             <TextBlock Foreground="White" Text="|"></TextBlock>
     168:             <HyperlinkButton NavigateUri="http://www.facebook.com/verif" Content="Facebook" TargetName="_blank" FontFamily="Verdana" FontSize="12" Foreground="#FFFFFFFF"/>
     169:             <TextBlock Foreground="White" Text="|"></TextBlock>
     170:             <HyperlinkButton NavigateUri="http://www.linkedin.com/pub/veri-ferdiansyah/21/a14/593" Content="Linked In" TargetName="_blank" FontFamily="Verdana" FontSize="12" Foreground="#FFFFFFFF"/>
     171:         </StackPanel>
     172:     </Grid>
     173: </UserControl>

    After that, you also need to copy and paste the code below to your MainPage.xaml.cs.

       1: using System;
       2: using System.Windows;
       3: using System.Windows.Browser;
       4: using System.Windows.Controls;
       5: using System.Windows.Input;
       6: using BingMapsOData.Helpers;
       7: using BingMapsOData.ViewModels;
       8: using Microsoft.Maps.MapControl;
       9:  
      10: namespace BingMapsOData
      11: {
      12:     public partial class MainPage : UserControl
      13:     {
      14:         NerdDinnerViewModel vm;
      15:         MapSearchHelper searchHelper = new MapSearchHelper();
      16:         
      17:         public MainPage()
      18:         {
      19:             InitializeComponent();
      20:             InitializeViewModel();
      21:  
      22:             dinnerMap.TargetViewChanged += new EventHandler<MapEventArgs>(dinnerMap_TargetViewChanged);
      23:  
      24:             sldZoom.Value = dinnerMap.ZoomLevel;
      25:             sldZoom.ValueChanged += new RoutedPropertyChangedEventHandler<double>(ZoomChange);
      26:  
      27:             MiniMap.MouseClick += new EventHandler<MapMouseEventArgs>(MiniMap_MouseClick);
      28:             MiniMap.MouseDoubleClick += new EventHandler<MapMouseEventArgs>(MiniMap_MouseDoubleClick);
      29:             MiniMap.MouseDragBox += new EventHandler<MapMouseDragEventArgs>(MiniMap_MouseDragBox);
      30:             MiniMap.MousePan += new EventHandler<MapMouseDragEventArgs>(MiniMap_MousePan);
      31:             MiniMap.MouseWheel += new System.Windows.Input.MouseWheelEventHandler(MiniMap_MouseWheel);
      32:             MiniMap.KeyUp += new System.Windows.Input.KeyEventHandler(MiniMap_KeyUp);
      33:             MiniMap.KeyDown += new System.Windows.Input.KeyEventHandler(MiniMap_KeyDown);
      34:             MiniMap.KeyPress += new EventHandler<MapKeyPressEventArgs>(MiniMap_KeyPress);
      35:             MiniMap.KeyHeld += new EventHandler<MapKeyHeldEventArgs>(MiniMap_KeyHeld);
      36:             MiniMap.SetView(dinnerMap.TargetCenter, Math.Max(1.0, dinnerMap.TargetZoomLevel - 5));
      37:         }
      38:  
      39:         #region MainPage Events
      40:  
      41:         private void dinnerMap_TargetViewChanged(object sender, MapEventArgs e)
      42:         {
      43:             MiniMap.SetView(dinnerMap.TargetCenter, Math.Max(1.0, dinnerMap.TargetZoomLevel - 5));
      44:             sldZoom.Value = dinnerMap.TargetZoomLevel;
      45:         }
      46:  
      47:         #endregion
      48:  
      49:         #region MiniMap Events
      50:  
      51:         private void MiniMap_KeyHeld(object sender, MapKeyHeldEventArgs e)
      52:         {
      53:             e.Handled = true;
      54:         }
      55:  
      56:         private void MiniMap_KeyPress(object sender, MapKeyPressEventArgs e)
      57:         {
      58:             e.Handled = true;
      59:         }
      60:  
      61:         private void MiniMap_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
      62:         {
      63:             e.Handled = true;
      64:         }
      65:  
      66:         private void MiniMap_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
      67:         {
      68:             e.Handled = true;
      69:         }
      70:  
      71:         private void MiniMap_MouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
      72:         {
      73:             e.Handled = true;
      74:         }
      75:  
      76:         private void MiniMap_MousePan(object sender, MapMouseDragEventArgs e)
      77:         {
      78:             e.Handled = true;
      79:         }
      80:  
      81:         private void MiniMap_MouseDragBox(object sender, MapMouseDragEventArgs e)
      82:         {
      83:             e.Handled = true;
      84:         }
      85:  
      86:         private void MiniMap_MouseDoubleClick(object sender, MapMouseEventArgs e)
      87:         {
      88:             e.Handled = true;
      89:         }
      90:  
      91:         private void MiniMap_MouseClick(object sender, MapMouseEventArgs e)
      92:         {
      93:             e.Handled = true;
      94:         }
      95:  
      96:         #endregion
      97:  
      98:         #region Map Navigation
      99:  
     100:         private void ZoomChange(object sender, RoutedPropertyChangedEventArgs<double> e)
     101:         {
     102:             dinnerMap.ZoomLevel = sldZoom.Value;
     103:         }
     104:  
     105:         private void ZoomIn(object sender, MouseButtonEventArgs e)
     106:         {
     107:             dinnerMap.ZoomLevel = dinnerMap.TargetZoomLevel + 1;
     108:         }
     109:  
     110:         private void ZoomOut(object sender, MouseButtonEventArgs e)
     111:         {
     112:             dinnerMap.ZoomLevel = dinnerMap.TargetZoomLevel - 1;
     113:         }
     114:  
     115:         private void PanMapLeft(object sender, MouseButtonEventArgs e)
     116:         {
     117:             dinnerMap.Center = dinnerMap.ViewportPointToLocation(new Point(dinnerMap.ViewportSize.Width / 2 - 50, dinnerMap.ViewportSize.Height / 2));
     118:         }
     119:  
     120:         private void PanMapRight(object sender, MouseButtonEventArgs e)
     121:         {
     122:             dinnerMap.Center = dinnerMap.ViewportPointToLocation(new Point(dinnerMap.ViewportSize.Width / 2 + 50, dinnerMap.ViewportSize.Height / 2));
     123:         }
     124:  
     125:         private void PanMapUp(object sender, MouseButtonEventArgs e)
     126:         {
     127:             dinnerMap.Center = dinnerMap.ViewportPointToLocation(new Point(dinnerMap.ViewportSize.Width / 2, dinnerMap.ViewportSize.Height / 2 - 50));
     128:         }
     129:  
     130:         private void PanMapDown(object sender, MouseButtonEventArgs e)
     131:         {
     132:             dinnerMap.Center = dinnerMap.ViewportPointToLocation(new Point(dinnerMap.ViewportSize.Width / 2, dinnerMap.ViewportSize.Height / 2 + 50));
     133:         }
     134:  
     135:         private void MapStyleRoad(object sender, MouseButtonEventArgs e)
     136:         {
     137:             dinnerMap.Mode = new RoadMode();
     138:         }
     139:  
     140:         private void MapStyleAerial(object sender, MouseButtonEventArgs e)
     141:         {
     142:             dinnerMap.Mode = new AerialMode(false);
     143:         }
     144:  
     145:         private void MapStyleHybrid(object sender, MouseButtonEventArgs e)
     146:         {
     147:             dinnerMap.Mode = new AerialMode(true);
     148:         }
     149:  
     150:         #endregion
     151:  
     152:         /// <summary>
     153:         /// Initialize our view model, and assign it to the view
     154:         /// </summary>
     155:         private void InitializeViewModel()
     156:         {
     157:             vm = new NerdDinnerViewModel();
     158:             this.DataContext = vm;
     159:             try
     160:             {
     161:                 vm.QueryDinners();
     162:             }
     163:             catch (Exception ex)
     164:             {
     165:                 MessageBox.Show("Error loading the dinners. Make sure you are online. " + ex.Message);
     166:             }
     167:         }
     168:  
     169:         private void SearchDinners_Click(object sender, RoutedEventArgs e)
     170:         {
     171:             try
     172:             {
     173:                 if (!string.IsNullOrEmpty(txtPlace.Text))
     174:                     searchHelper.ExecuteSearch(txtPlace.Text, this.dinnerMap);
     175:             }
     176:             catch (Exception ex)
     177:             {
     178:                 MessageBox.Show("Error zooming in to " + txtPlace.Text + ex.Message);
     179:             }
     180:  
     181:             try
     182:             {
     183:                 vm.QueryDinners();
     184:             }
     185:             catch (Exception ex)
     186:             {
     187:                 MessageBox.Show("Error loading the dinners. Make sure you are online. " + ex.Message);
     188:             }
     189:         }
     190:     }
     191: }

    Don’t forget to change the Bing Maps credentials in App.xaml with your own key. Hit F5 and your NerdDinner web application is ready to go!

    Result

    You can download the sample code in here. Enjoy…

    459 Views, 1 Comment(s), Published on: 04-25-2011 8:51 by veri to All about GIS
    | More