Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / XAML

Learn About Places (LAP)

5.00/5 (2 votes)
22 Aug 2013CPOL5 min read 8.4K  
LAP provides an feature rich environment for learning and enjoying history and geography of places across the globe

This article is an entry in our AppInnovation Contest. Articles in this sub-section are not required to be full articles so care should be taken when voting.

Introduction

Many times people while reading and learning history and geography for different places on the globe become a cumbersome job. All the time reading heavy books and no enjoyment in learning the subjects. I myself experienced the need to put some enthusiasm in learning these subjects as you know knowledge of past is important for the improvements in future.

Well this problem is sorted by Learn About Places (LAP). LAP solve these issues by graphically showing different places on the maps, history of those places and geographical location of the places. After studying the history and geography of the relevant places users can solve a quiz to check their learning. Now lets dive into the detailed description of the application showing, how it works, how it is beneficial for the targeted users.

Category and Platform

LAP is an entertainment app with the learning of the subjects. The elements that makes it an entertainment app is the clever use of the Bing Maps, explorative articles, checking your knowledge through fun games including quiz etc. LAP is therefore a complete package for entertainment.

Platform LAP is targeted to is the ALL-In-One PC. The features provided by this new category of devices enhances and explores the app features. Lenovo Horizon All-In-One PC's features such as Aura Interface helps expand the app experience for the users.

Overview

Now we have talked enough about LAP as what it does, let's go into the detailed description of the app from now onwards.

The App is mainly partitioned (in a way) into four categories:

  (a). History of a place.

  (b). Geography of a place.

  (c). Fun Games.

  (d). Quiz. <u3:p>

These three broad categories are not strictly in order in the app, as the uses the app the flow of the app manages the aspects.Now let's look at the main page snapshot. 

Image 1

GUI (Graphical User Interface) of LAP is very simple, as no crome before content. The main page shown above consist of just two options. One is to "Enter a Place" and other "Plan a learning Trip" and a little description of both the options.

Working of LAP

Enter a Place  

"Enter a Place" navigates the user to a panel where he/she can enter a place whose history and geography needs to be known. The place entered will he highlighted on the Map specifying few details, and simultaneously shows the option of history, geography and games for that particular place to the right side in the panel.

Image 2

Image 3

Image 4Image 5

 Plan a Learning Trip 

"Plan a learning Trip" is some what advanced than the other option. It really explores and includes all components of the application. The user navigates to a panel where he/she enters two locations similar to finding the path between two locations on the map. The path between these two locations appears on the map with a list of places long the path highlighted. Now the user starts from source location and travels through the path and explore history and geography of these places along the path. Hence the name "Plan a Learning Trip".

Image 6

Image 7

Image 8 Image 9

App Features

Above were the basic functionality provided by LAP. Now,let's dive deep into the details of the app. Afterentering the places their corresponding name(s) appear in the form of a list inside the panel to the right side as shown above for both the options.

For both options select a place from the list. This navigates to new page listing the categorization shown above.

Image 10

Select any one of the above stated options.

1. History

On selection of this option user is navigated to a new page consisting of articles , videos, and books relevant to the history of that place. Articles are present from any of the writers. Videos consist of clip of history series from different sources for ex-History Channel. Books are present by different writers related to the history of the place.

Image 11

2. Geography

On selection of this option user is navigated to a new page consisting of the geographical listing of the place for eg-Longitude, Latitude, Continent,Country, State, City etc. Along with these details videos, articles and the history of the place options are available. Along with all these feature a map snapshot is available stating the geographic location on the map.

Image 12

3. Quiz

On selection of the quiz option user is navigated to a new page consisting of historic and geographical questions. User can give the quiz and will be give score for the quiz.This brings competitiveness among the users.

4. Games

On selection of this option the user is navigated to a new page consisting of collection of fun games

Developing LAP

Overview 

LAP is developed using Microsoft Visual Studio 2012. Metro apps runs as desktop apps for Lenovo Horizon AlO therefore LAP also does. Designing of LAP was done in VS2012 editor using XAML (eXtensible Application Markup Language). XAML is very convenient for designing windows applications. Logic of LAP was written in C# programming language.

Designing

Designing and architecture of LAP is done carefully. Any loose coupling between the elements is omitted. Such coupling is removed because a methodology MVVM (Model View View Model) is used for developing LAP.<u3:p>

LAP uses Bing Maps therefore Bing Maps api is used to include the Map element. Startup Page of the app opens with a map showing two options as stated in the "Working of LAP" section. Startup page code of LAP is as follows:

XML
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <Maps:Map x:Name="BingMap" 
              HomeRegion="US" Culture="en-US"
              Credentials="{StaticResource BingCredentials}"/>
    <Grid Background="#FFF5810D" Margin="134,40,475,52">
        <Grid.RowDefinitions>
            <RowDefinition Height="127*"/>
            <RowDefinition Height="641*"/>
        </Grid.RowDefinitions>
        <TextBlock HorizontalAlignment="Left" 
               Margin="45,42,0,0" TextWrapping="Wrap"
               VerticalAlignment="Top" FontSize="50">
        <Underline>Categories</Underline>
        </TextBlock>
        <Grid Grid.Row="1" Background="#FFF7E209">
            
            <Button Content="History" HorizontalAlignment="Left" 
              Margin="97,83,0,0" VerticalAlignment="Top" 
              Height="152" Width="200" FontSize="30" 
              Background="#FFB4B429"/>
            <Button Content="Games" HorizontalAlignment="Left" 
              Margin="97,284,0,0" VerticalAlignment="Top" 
              Width="200" Height="152" FontSize="30" 
              Background="#FFB4B429"/>
            <Button Content="Geography" HorizontalAlignment="Left" 
              Margin="404,83,0,0" VerticalAlignment="Top" 
              Height="152" Width="200" FontSize="30" 
              Background="#FFB4B429"/>
            <Button Content="Quiz" HorizontalAlignment="Left" 
              Margin="404,284,0,0" VerticalAlignment="Top" 
              Height="152" Width="200" FontSize="30" 
              Background="#FFB4B429"/>
        </Grid>
    </Grid>
    <StackPanel x:Name="_MainStackPanel"
                HorizontalAlignment="Left"  Height="768"
                VerticalAlignment="Top" Width="337" 
                Margin="1029,0,0,0" Background="#FFD8A840">
       
        <Button Content="Enter a Place" HorizontalAlignment="Stretch" 
                 VerticalAlignment="Stretch" Margin="5,20,5,5"
                 Background="#FFDE6B35" Height="52" 
                 FontSize="20" Click="Enter_Place_Event_Click"/>

        <Button Content="Plan a learning Trip" 
                 HorizontalAlignment="Stretch" 
                 VerticalAlignment="Stretch" Margin="5,5,5,5"
                 Background="#FFDE6B35" Height="52" FontSize="20"/>
        <TextBlock TextWrapping="Wrap" FontSize="22" Margin="12,20,0,0">
            <Underline>Places:</Underline>
        </TextBlock>
       
        <TextBlock Margin="12,15,5,5" FontSize="17" TextWrapping="Wrap">
                
            <Underline FontSize="20">Enter a Place:</Underline>
             Click on the button, a panel opens where you enter a place to explore and learn about it
            <LineBreak/>
            <LineBreak/>
            <Underline FontSize="20">Plan a Learning Trip</Underline>
            Click on the button, a panel opens where you enter two places.
            The places between these places including them are their
            present for exploration

        </TextBlock>
    </StackPanel>
</Grid>

History page design code, listing articles, videos, and books.

XML
<Grid Style="{StaticResource LayoutRootStyle}">
    <Grid.RowDefinitions>
        <RowDefinition Height="140"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

      <GridView
        x:Name="itemGridView"
        AutomationProperties.AutomationId="ItemGridView"
        AutomationProperties.Name="Grouped Items"
        Grid.RowSpan="2"
        Padding="116,137,40,46"
        ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
        ItemTemplate="{StaticResource Standard250x250ItemTemplate}"
        SelectionMode="None"
        IsSwipeEnabled="false"
        IsItemClickEnabled="True"
        ItemClick="ItemView_ItemClick">

        <GridView.ItemsPanel>
            <ItemsPanelTemplate>                        
                <VirtualizingStackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>
        <GridView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <Grid Margin="1,0,0,6">
                            <Button
                                AutomationProperties.Name="Group Title"
                                Click="Header_Click"
                                Style="{StaticResource TextPrimaryButtonStyle}" >
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding Title}" Margin="3,-7,10,10" 
                                      Style="{StaticResource GroupHeaderTextStyle}" />
                                    <TextBlock Text="{StaticResource ChevronGlyph}" 
                                      FontFamily="Segoe UI Symbol" Margin="0,-7,0,10" 
                                      Style="{StaticResource GroupHeaderTextStyle}"/>
                                </StackPanel>
                            </Button>
                        </Grid>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
                <GroupStyle.Panel>
                    <ItemsPanelTemplate>
                        <VariableSizedWrapGrid Orientation="Vertical" 
                              Margin="0,0,80,0"/>
                    </ItemsPanelTemplate>
                </GroupStyle.Panel>
            </GroupStyle>
        </GridView.GroupStyle>
    </GridView>

    <ListView
        x:Name="itemListView"
        AutomationProperties.AutomationId="ItemListView"
        AutomationProperties.Name="Grouped Items"
        Grid.Row="1"
        Visibility="Collapsed"
        Margin="0,-10,0,0"
        Padding="10,0,0,60"
        ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
        ItemTemplate="{StaticResource Standard80ItemTemplate}"
        SelectionMode="None"
        IsSwipeEnabled="false"
        IsItemClickEnabled="True"
        ItemClick="ItemView_ItemClick">

        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <Grid Margin="7,7,0,0">
                            <Button
                                AutomationProperties.Name="Group Title"
                                Click="Header_Click"
                                Style="{StaticResource TextPrimaryButtonStyle}">
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding Title}" Margin="3,-7,10,10" 
                                      Style="{StaticResource GroupHeaderTextStyle}" />
                                    <TextBlock Text="{StaticResource ChevronGlyph}" 
                                      FontFamily="Segoe UI Symbol" Margin="0,-7,0,10" 
                                      Style="{StaticResource GroupHeaderTextStyle}"/>
                                </StackPanel>
                            </Button>
                        </Grid>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ListView.GroupStyle>
    </ListView>

       
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="backButton" Click="GoBack" 
              IsEnabled="{Binding Frame.CanGoBack, ElementName=pageRoot}" 
              Style="{StaticResource BackButtonStyle}"/>
            <TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" 
              Grid.Column="1" IsHitTestVisible="false" 
              Style="{StaticResource PageHeaderTextStyle}"/>
        </Grid>

        <VisualStateManager.VisualStateGroups>

           
        <VisualStateGroup x:Name="ApplicationViewStates">
            <VisualState x:Name="FullScreenLandscape"/>
            <VisualState x:Name="Filled"/>

         
            <VisualState x:Name="FullScreenPortrait">
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames 
                            Storyboard.TargetName="backButton" 
                            Storyboard.TargetProperty="Style">
                        <DiscreteObjectKeyFrame KeyTime="0" 
                          Value="{StaticResource PortraitBackButtonStyle}"/>
                    </ObjectAnimationUsingKeyFrames>

                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" 
                            Storyboard.TargetProperty="Padding">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="96,137,10,56"/>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>

           
            <VisualState x:Name="Snapped">
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames 
                            Storyboard.TargetName="backButton" 
                            Storyboard.TargetProperty="Style">
                        <DiscreteObjectKeyFrame KeyTime="0" 
                          Value="{StaticResource SnappedBackButtonStyle}"/>
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" 
                      Storyboard.TargetProperty="Style">
                        <DiscreteObjectKeyFrame KeyTime="0" 
                          Value="{StaticResource SnappedPageHeaderTextStyle}"/>
                    </ObjectAnimationUsingKeyFrames>

                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" 
                             Storyboard.TargetProperty="Visibility">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" 
                              Storyboard.TargetProperty="Visibility">
                        <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Grid>

Category UI XAML code,which shows different categorizations:

XML
<Grid Background="#FFF5810D" Margin="134,40,475,52">
    <Grid.RowDefinitions>
        <RowDefinition Height="127*"/>
        <RowDefinition Height="641*"/>
    </Grid.RowDefinitions>
    <TextBlock HorizontalAlignment="Left" Margin="45,42,0,0" TextWrapping="Wrap"
           VerticalAlignment="Top" FontSize="50">
    <Underline>Categories</Underline>
    </TextBlock>
    <Grid Grid.Row="1" Background="#FFF7E209">
        
        <Button Content="History" HorizontalAlignment="Left" Margin="97,83,0,0" 
           VerticalAlignment="Top" Height="152" Width="200" 
           FontSize="30" Background="#FFB4B429"/>
        <Button Content="Games" HorizontalAlignment="Left" 
          Margin="97,284,0,0" VerticalAlignment="Top" Width="200" 
          Height="152" FontSize="30" Background="#FFB4B429"/>
        <Button Content="Geography" HorizontalAlignment="Left" 
          Margin="404,83,0,0" VerticalAlignment="Top" 
          Height="152" Width="200" FontSize="30" 
          Background="#FFB4B429"/>
        <Button Content="Quiz" HorizontalAlignment="Left" 
          Margin="404,284,0,0" VerticalAlignment="Top" 
          Height="152" Width="200" FontSize="30" 
          Background="#FFB4B429"/>
    </Grid>
</Grid>

Code

The code behind file handles the business logic of the application. C# programming language is used for programming the app business logic. In developing LAP Bing Maps sdk is used and therefore it's reference is added to the project. Bing Map REST Services are used and it's route and location api to find the path and respective locations.

Following is the Startup page code behind:

C#
private async Task<BingMapsRESTService.Response> GetResponse(Uri uri)
{
    System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
    var response = await client.GetAsync(uri);
    using (var stream = await response.Content.ReadAsStreamAsync())
    {
        DataContractJsonSerializer ser = 
          new DataContractJsonSerializer(typeof(BingMapsRESTService.Response));
        return ser.ReadObject(stream) as BingMapsRESTService.Response;
    }
}

 async private void Button_To_Search_Route_Click(object sender, RoutedEventArgs e)
 {
     Button_To_Search_Route.IsEnabled = false;
     if (Text_For_From_Location.Text == "" || TextBox_To_Enter_To_Location.Text == "")
     {
         
         Popup_Notification(2);
     }
     else
     {
         try
         {
             ProgressBar.IsIndeterminate = true;
             ProgressBar.Visibility = Visibility.Visible;
             Canvas_To_Find_Route.Visibility = Visibility.Collapsed;
             URL = "http://dev.virtualearth.net/REST/V1/Routes/Driving?o=json&wp.0=" + 
               TextBox_To_Enter_To_Location.Text + "&wp.1=" + 
               Text_For_From_Location.Text + "&optmz=distance&rpo=Points&key=" + map.Credentials;
             Uri geocodeRequest = new Uri(URL);
             BingMapsRESTService.Response r = await GetResponse(geocodeRequest);
             geolocator = new Geolocator();
             pushpin = new Pushpin();
             FromLatitude = ((BingMapsRESTService.Route)(r.ResourceSets[0].Resources[0])).RoutePath.Line.Coordinates[0][0];
             FromLongitude = ((BingMapsRESTService.Route)(r.ResourceSets[0].Resources[0])).RoutePath.Line.Coordinates[0][1];
            
             location = new Bing.Maps.Location(FromLatitude, FromLongitude);
             MapLayer.SetPosition(pushpin, location);
             map.Children.Add(pushpin);
             map.SetView(location, 8.0f);

             MapPolyline routeLine = new MapPolyline();
             routeLine.Locations = new LocationCollection();
             routeLine.Color = Windows.UI.Colors.Red;
             routeLine.Width = 5.0;
             int bound = ((BingMapsRESTService.Route)(
               r.ResourceSets[0].Resources[0])).RoutePath.Line.Coordinates.GetUpperBound(0);
             for (int i = 0; i < bound; i++)
             {
                 routeLine.Locations.Add(new Bing.Maps.Location
                 {
                     Latitude = ((BingMapsRESTService.Route)(
                       r.ResourceSets[0].Resources[0])).RoutePath.Line.Coordinates[i][0],
                     Longitude = ((BingMapsRESTService.Route)(
                       r.ResourceSets[0].Resources[0])).RoutePath.Line.Coordinates[i][1]
                 });
                 
             }
             pushpin1 = new Pushpin();
             location1 = new Bing.Maps.Location(routeLine.Locations[0]);
             MapLayer.SetPosition(pushpin1, location1);
            
             MapShapeLayer shapeLayer = new MapShapeLayer();
             shapeLayer.Shapes.Add(routeLine);
             map.ShapeLayers.Add(shapeLayer);
             ProgressBar.IsIndeterminate = false;
             ProgressBar.Visibility = Visibility.Collapsed;
             Canvas_For_Searching_Location.Visibility = Visibility.Collapsed;
         }
         catch (Exception ex)
         {
             var dialog = new MessageDialog(ex.Message);
         }
     }
     Button_To_Search_Route.IsEnabled = true;
}

async private void Button_To_Search_Location_Click(object sender, RoutedEventArgs e)
{
    Button_To_Search_Location.IsEnabled = false;
    if (TextBox_To_Enter_Location.Text == "")
    {
        Canvas_For_Searching_Location.Visibility = Visibility.Collapsed;
        Popup_Notification(1);

    }
    else
    {
        try
        {
            
            Canvas_For_Searching_Location.Visibility = Visibility.Collapsed;
            ProgressBar.IsIndeterminate = true;
            ProgressBar.Visibility = Visibility.Visible;
            URL = "http://dev.virtualearth.net/REST/V1/Routes/Driving?o=json&wp.0=" + 
                  TextBox_To_Enter_Location.Text + "&wp.1=" + 
                  TextBox_To_Enter_Location.Text + 
                  "&optmz=distance&rpo=Points&key=" + map.Credentials;

            string value = "Ar1AUldQavUnDzLKSQtJ-9evD7v8uA-v6ZdJNpCx7Swkuxif5X1l7FPbx6v";
            GeocodeRequest geocoderequest = new GeocodeRequest();


            geocoderequest.Credentials = new WowZapp_Application.Geocode_Service.Credentials();
            geocoderequest.Credentials.ApplicationId = value;


            geocoderequest.Query = TextBox_To_Enter_Location.Text;


            ConfidenceFilter[] filters = new ConfidenceFilter[1];
            filters[0] = new ConfidenceFilter();
            filters[0].MinimumConfidence = WowZapp_Application.Geocode_Service.Confidence.High;


            GeocodeServiceClient geocodeservice = new GeocodeServiceClient(
              GeocodeServiceClient.EndpointConfiguration.BasicHttpBinding_IGeocodeService);
            GeocodeResponse geocoderesponse = await geocodeservice.GeocodeAsync(geocoderequest);
           
            if (geocoderesponse.Results.Count > 0)
            {
                Bing.Maps.Location location = new Bing.Maps.Location(
                  geocoderesponse.Results[0].Locations[0].Latitude, 
                  geocoderesponse.Results[0].Locations[0].Longitude);
                MapLayer.SetPosition(pushpin1, location);
                map.SetView(location, 10.0f);
                ProgressBar.IsIndeterminate = false;
                ProgressBar.Visibility = Visibility.Collapsed;
            }
        }

        catch (Exception ex)
        {
            var dialog = new MessageDialog(ex.Message);
        }
       
    }
    Button_To_Search_Location.IsEnabled = true;
}

Intented Users

LAP is a global application, and it can be used by any users. But the more targeted user of LAP application are the students, professors, historians, geologist and ofcourse for any common man who wants to enjoy the learning.

History

This is my first post on CodeProject.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)