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.
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.
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".
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.
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.
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.
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:
<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.
<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:
<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:
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.