Geeks With Blogs
bobby's blog randomly specific...

Quick Links


Since volcanos are often associated with earthquakes, and vice versa, I decided to show recent volcanic activity on the Earthquake Locator map.  I am pulling the data from a website created for a joint project between the Smithsonian's Global Volcanism Program and the US Geological Survey's Volcano Hazards Program, found here.  They provide a Weekly Volcanic Activity Report as an RSS feed.
 

I started implementing this new functionality by creating a new Volcano entity in the domain model and adding the following to the EarthquakeService class (I also factored out the common reading/parsing helper methods to a separate FeedReader class that can be used by multiple domain service classes):
 

        private static readonly string VolcanoFeedUrl =

            ConfigurationManager.AppSettings["VolcanoFeedUrl"];

 

        /// <summary>

        /// Gets the volcano data for the previous week.

        /// </summary>

        /// <returns>A queryable collection of <see cref="Volcano"/> objects.</returns>

        public IQueryable<Volcano> GetVolcanos()

        {

            var feed = FeedReader.Load(VolcanoFeedUrl);

            var list = new List<Volcano>();

 

            if ( feed != null )

            {

                foreach ( var item in feed.Items )

                {

                    var quake = CreateVolcano(item);

                    if ( quake != null )

                    {

                        list.Add(quake);

                    }

                }

            }

 

            return list.AsQueryable();

        }

 

        /// <summary>

        /// Creates a <see cref="Volcano"/> object for each item in the RSS feed.

        /// </summary>

        /// <param name="item">The RSS item.</param>

        /// <returns></returns>

        private Volcano CreateVolcano(SyndicationItem item)

        {

            Volcano volcano = null;

            string title = item.Title.Text;

            string desc = item.Summary.Text;

            double? latitude = null;

            double? longitude = null;

 

            FeedReader.GetGeoRssPoint(item, out latitude, out longitude);

 

            if ( !String.IsNullOrEmpty(title) )

            {

                title = title.Substring(0, title.IndexOf('-'));

            }

            if ( !String.IsNullOrEmpty(desc) )

            {

                desc = String.Join("\n\n", desc

                        .Replace("<p>", "")

                        .Split(

                            new string[] { "</p>" },

                            StringSplitOptions.RemoveEmptyEntries)

                        .Select(s => s.Trim())

                        .ToArray())

                        .Trim();

            }

 

            if ( latitude != null && longitude != null )

            {

                volcano = new Volcano()

                {

                    Id = item.Id,

                    Title = title,

                    Description = desc,

                    Url = item.Links.Select(l => l.Uri.OriginalString).FirstOrDefault(),

                    Latitude = latitude.GetValueOrDefault(),

                    Longitude = longitude.GetValueOrDefault()

                };

            }

 

            return volcano;

        }


I then added the corresponding LoadVolcanos() method and Volcanos collection to the EarthquakeViewModel class in much the same way I did with the Earthquakes in my previous article in this series.

Now that I am starting to add more information to the map, I wanted to give the user some options as to what is displayed and allowing them to choose what gets turned off.  I have updated the MainPage.xaml to look like this:
 

<UserControl x:Class="EarthquakeLocator.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:basic="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"

    xmlns:bing="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl"

    xmlns:vm="clr-namespace:EarthquakeLocator.ViewModel"

    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"

>

    <UserControl.Resources>

        <DataTemplate x:Key="EarthquakeTemplate">

            <Ellipse Fill="Red" Stroke="Black" StrokeThickness="1"

                     Width="{Binding Size}" Height="{Binding Size}"

                     bing:MapLayer.Position="{Binding Location}"

                     bing:MapLayer.PositionOrigin="Center">

                <ToolTipService.ToolTip>

                    <StackPanel>

                        <TextBlock Text="{Binding Title}" FontSize="14" FontWeight="Bold" />

                        <TextBlock Text="{Binding UtcTime}" />

                        <TextBlock Text="{Binding LocalTime}" />

                        <TextBlock Text="{Binding DepthDesc}" />

                    </StackPanel>

                </ToolTipService.ToolTip>

            </Ellipse>

        </DataTemplate>

 

        <DataTemplate x:Key="VolcanoTemplate">

            <Polygon Fill="Gold" Stroke="Black" StrokeThickness="1" Points="0,10 5,0 10,10"

                     bing:MapLayer.Position="{Binding Location}"

                     bing:MapLayer.PositionOrigin="Center"

                     MouseLeftButtonUp="Volcano_MouseLeftButtonUp">

                <ToolTipService.ToolTip>

                    <StackPanel>

                        <TextBlock Text="{Binding Title}" FontSize="14" FontWeight="Bold" />

                        <TextBlock Text="Click icon for more information..." />

                    </StackPanel>

                </ToolTipService.ToolTip>

            </Polygon>

        </DataTemplate>

    </UserControl.Resources>

 

    <UserControl.DataContext>

        <vm:EarthquakeViewModel AutoLoadData="True" />

    </UserControl.DataContext>

 

    <Grid x:Name="LayoutRoot">

 

        <bing:Map x:Name="map" CredentialsProvider="--Your-Bing-Maps-Key--"

                  Center="{Binding MapCenter, Mode=TwoWay}"

                  ZoomLevel="{Binding ZoomLevel, Mode=TwoWay}">

 

            <bing:MapItemsControl ItemsSource="{Binding Earthquakes}"

                                  ItemTemplate="{StaticResource EarthquakeTemplate}" />

 

            <bing:MapItemsControl ItemsSource="{Binding Volcanos}"

                                  ItemTemplate="{StaticResource VolcanoTemplate}" />

        </bing:Map>

 

        <basic:TabControl x:Name="tabs" VerticalAlignment="Bottom" MaxHeight="25" Opacity="0.7">

            <basic:TabItem Margin="90,0,-90,0" MouseLeftButtonUp="TabItem_MouseLeftButtonUp">

                <basic:TabItem.Header>

                    <TextBlock x:Name="txtHeader" Text="Options"

                               FontSize="13" FontWeight="Bold" />

                </basic:TabItem.Header>

 

                <StackPanel Orientation="Horizontal">

                    <TextBlock Text="Earthquakes:" FontWeight="Bold" Margin="3" />

                    <StackPanel Margin="3">

                        <CheckBox Content=" &lt; 4.0"

                                  IsChecked="{Binding ShowLt4, Mode=TwoWay}" />

                        <CheckBox Content="4.0 - 4.9"

                                  IsChecked="{Binding Show4s, Mode=TwoWay}" />

                        <CheckBox Content="5.0 - 5.9"

                                  IsChecked="{Binding Show5s, Mode=TwoWay}" />

                    </StackPanel>

 

                    <StackPanel Margin="10,3,3,3">

                        <CheckBox Content="6.0 - 6.9"

                                  IsChecked="{Binding Show6s, Mode=TwoWay}" />

                        <CheckBox Content="7.0 - 7.9"

                                  IsChecked="{Binding Show7s, Mode=TwoWay}" />

                        <CheckBox Content="8.0 +"

                                  IsChecked="{Binding ShowGe8, Mode=TwoWay}" />

                    </StackPanel>

 

                    <TextBlock Text="Other:" FontWeight="Bold" Margin="50,3,3,3" />

                    <StackPanel Margin="3">

                        <CheckBox Content="Volcanos"

                                  IsChecked="{Binding ShowVolcanos, Mode=TwoWay}" />

                    </StackPanel>

                </StackPanel>

 

            </basic:TabItem>

        </basic:TabControl>

 

    </Grid>

</UserControl>


Notice that I added a VolcanoTemplate that uses a triangle-shaped Polygon to represent the Volcano locations, and I also added a second <bing:MapItemsControl /> tag to the map to bind to the Volcanos collection.  The TabControl found below the map houses the options panel that will present the user with several checkboxes so they can filter the different points based on type and other properties (i.e. Magnitude).  Initially, the TabItem is collapsed to reduce it's footprint, but the screen shot below shows the options panel expanded to reveal the available settings:
 

 

I have updated the Source Code and Live Demo to include these new features.
 

Happy Mapping!

Posted on Sunday, March 7, 2010 7:40 PM Silverlight , RIA , MVVM , Bing Maps | Back to top


Comments on this post: Adding Volcanos and Options - Earthquake Locator, part 2

# re: Adding Volcanos and Options - Earthquake Locator, part 2
Requesting Gravatar...
Well done. Nice introduction to Bing maps and RIA Services integration.

I would like to see more about which IoC container you are using; but I can understand not wanting to muddy up the introduction with those details.
Left by Jacob Gable on Mar 08, 2010 12:56 PM

# re: Adding Volcanos and Options - Earthquake Locator, part 2
Requesting Gravatar...
Jacob,

Thanks for the kind words! I plan on exploring MEF in greater detail in a separate post, but in the mean time, have you seen Glenn Block's blog post about refactoring his MEF application to use MVVM?

http://codebetter.com/blogs/glenn.block/archive/2010/03/07/building-hellomef-part-v-refactoring-to-viewmodel.aspx
Left by Bobby Diaz on Mar 08, 2010 5:13 PM

# re: Adding Volcanos and Options - Earthquake Locator, part 2
Requesting Gravatar...
Hi , i failed to built the solution on windows 2010 and using SL4 ?

Exactly the convertion failed !!

And you application interest me too much :|

Thaks
Left by Aicha on Oct 14, 2010 6:01 AM

# re: Adding Volcanos and Options - Earthquake Locator, part 2
Requesting Gravatar...
It's run now, but the volcano's xml feeds is not found :(

Thanks
Left by Aicha on Oct 14, 2010 10:50 AM

# Will Bobby Release His VisualStudio.vssettings file?
Requesting Gravatar...
I think it should become a defacto practice to include the .vssettings file with the code being released as it helps to go back and forth from the blog and Visual Studio.

Just a wild thought because I've been trying out a number of settings files and I think the one used for the code in this page is one I could stare at for long periods of time and I could make something up to schmooze Bobby into blogging his copy!
Left by Chief Mouse Operator on Apr 10, 2011 6:41 PM

Your comment:
 (will show your gravatar)


Copyright © Bobby Diaz | Powered by: GeeksWithBlogs.net