Joseph Guadagno

Founder of Southeast Valley .NET User and Microsoft Visual C# MVP

In my previous post, Using the Bing Maps Web Services for Geocoding Addresses, I talk about geocoding addresses using the Bing Maps Web Services. Now it is time to talk about getting imagery of maps, roads or aerials views for addresses or geocodes.

In order to get started using the Bing Maps Web Services, check out the previous post Getting Started section.

Bing Maps Web Services

Bing Maps Web Services is a set of Web services that allow you to add mapping and search functionality to your application, including location finding, map imagery, and routing capabilities. For example, you can:

Use the Imagery Service to:

  • Return a link to a map with a pushpin at a specific location
  • Provide a road map or bird’s eye or aerial imagery to you application

Use the Route Service to:

  • Get directions that include traffic warnings and route hints between multiple locations.
  • Get directions from all major roads to a destination (1-click directions, also referred to as a "party map") and then use the Imagery Service to map those routes.

For this post we will cover the Imagery service.

Just like the Geocode Service, there is a request, MapUriRequest, and response, MapUriResponse, object for the Imagery Service.

In order to get the Uri to display a map in your application you will need to use the imagery service client, ImageryServiceClient. The ImageryServiceClient needs to be instantiated with the WCF endpoint to use, by default it should be ‘BasicHttpBinding_IImageryService’. Then call the GetMapUri method passing your MapUriRequest object.

ImageryServiceClient imageryService = new ImageryServiceClient("BasicHttpBinding_IImageryService");
MapUriResponse mapUriResponse = imageryService.GetMapUri(mapUriRequest);
Building the MapUriRequest

The MapUrilRequest has two properties that need to be populated; the Credentials property which should contain you Bing Maps Id and either the Center, MajorRoutesDestination, or Pushpins property.  The code snippet below demonstrates instantiating the MapUriRequest and setting the properties based on values passed into a method (outlined later).

MapUriRequest mapUriRequest = new MapUriRequest
    {
      Credentials = new Credentials {ApplicationId = appId},
      Pushpins = pushpins,
      Center = new Location {Latitude = latitude, Longitude = longitude}
    };

Now you can customize the options for the map using the MapUriOptions property of the MapUriRequest object. Here is a list of the properties from the MSDN documentation:

Property name Description

DisplayLayers

A string array indicating the layer data to display on the map. Optional. The default value is null.

ImageSize A SizeOfint Class object specifying the height and width of the image to return. Optional. The default width is 350 and the default height is 350.
ImageType An ImageType Enumeration value specifying the format of the image to return. Optional. The default value is ImageType.Default, which means the default changes depending on the map style specified.
PreventIconCollision A bool indicating whether or not to separate pushpin icons that are close to each other on the map so that they are more visible. Optional. The default value is false.
Style A MapStyle Enumeration value specifying the map style of the image to return. Optional. The default value is MapStyle.Road.
UriScheme A UriScheme Enumeration value specifying the URI scheme to return. Optional. The default value is UriScheme.Http.
ZoomLevel An int indicating the zoom level of the map to return. Optional.

Assigning some of the options:

// Set the map options
MapUriOptions mapUriOptions = new MapUriOptions();
mapUriOptions.Style = MapStyle.Road;
mapUriOptions.ZoomLevel = zoom;
mapUriOptions.ImageSize = new SizeOfint {Height = height, Width = width};
// Set the options property of the request.
mapUriRequest.Options = mapUriOptions;

Now you are ready to call the image service client to get the MapUriResponse.

ImageryServiceClient imageryService = new ImageryServiceClient("BasicHttpBinding_IImageryService");
MapUriResponse mapUriResponse = imageryService.GetMapUri(mapUriRequest);

Here is a helper class,

,  which wraps the GetMapUri function with 8 different overloads.

Working with the MapUriResponse

The MapUriResponse object has three properties:

Name Description
BrandLogoUri The System.Uri of the Bing Maps brand logo image.
ResponseSummary A ResponseSummary Class object describing the response that was returned by the service.
Uri A string that is the URI of the requested map.

For brevity sake, we will just use the Uri property.  You should, though, for good programming practices, check the ResponseSummary property for any exceptions.

string mapUri = Imagery.GetMapUri("YourAppId", 47.62, -122.2);
imgMap.imageUrl = mapUri;

This call retrieve the Uri to use to display a 200x200 road map of the area at latitude 47.62 and longitude -122.2 with a zoom of 14, which is downtown Bellevue, WA.

image

If you want to add pushpins or markers similar to the above image you will need to populate the an array of PushPin objects. A PushPin object has an IconStyle which is the type of icon to use, a Label which an optional text to display on the pushpin (only works with certain pushpins) and the Location which contains the latitude and longitude that the pushpin should be located at.

That’s it.  It seems like a lot of work for a one line call.  With the attached Imagery.cs class, a lot of the overhead work was done for you.


For the MVPSummitEvents and Mix10Events site I wanted to create a map of all of the events listed on the site. In order to do that I needed to Geocode all of the addresses for the events.  There are several services out there for geocoding an address, Microsoft, Yahoo, and Google provide this service as well as others.  I decided to go with the Microsoft Bing services, being a Microsoft MVP.

Getting Started

Let’s get started. MSDN has just about everything you need to get started with using the Bing Map Web Services. 

Step 1: The first step is to get a key or token to use in your application for the Bing Maps Web Services application. This can be done by visiting the Bing Maps Account center and clicking on Create a Bing Maps account.

Step 2: If you are using Visual Studio, add a service reference to one or more Bing Maps Web Services that provide the features you need. See the Generating Client Proxy Classes topic and the Bing Maps Web Services Metadata topic.

VirtualEarthWebServicesWhether you used Visual Studio or the svcutil application you should have one file, most likely named VirtualEarthWebServices.cs. The file will contain a bunch of wrapper classes around the Bing Maps Web Services, and the required Windows Communication Foundation (WCF) classes. You will also see the generated configuration settings for the app or web config files.

Step 3: Set every Bing Maps Web Services request a valid Credentials property. You will see more on this in a bit.

Geocoding an Address

There are two properties that are required to successfully request a GeoCode for an address.

  1. 1) Set the Credential Property of the GeoCodeRequest object
  2. 2) Set either the Query property or Address property of the GeoCodeRequest object.

Here is a helper function that wraps the call to GeoCodeRequest.

/// <summary>
/// Gets the location.
/// </summary>
/// <param name="appId">The app id.</param>
/// <param name="address">The address.</param>
/// <returns></returns>
public static GeocodeResponse GetGeocodeResponse(string appId, string address)
{
    GeocodeRequest geocodeRequest = new GeocodeRequest
      {
          Credentials = new Credentials {ApplicationId = appId},
          Query = address
      };
    ConfidenceFilter[] filters = new ConfidenceFilter[1];
    filters[0] = new ConfidenceFilter {MinimumConfidence = Confidence.High};
    GeocodeOptions geocodeOptions = new GeocodeOptions {Filters = filters};
    geocodeRequest.Options = geocodeOptions;

    GeocodeServiceClient geocodeServiceClient = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
    return geocodeServiceClient.Geocode(geocodeRequest);
}

This method will return a GeocodeResponse object. The GeocodeResponse object contains three properties that are populated based on the query.

Name Description

BrandLogoUri

The System.Uri of the Bing Maps brand logo image. (Inherited from the ResponseBase Class.)

ResponseSummary A ResponseSummary Class object describing the response that was returned by the service. (Inherited from the ResponseBase Class.) This class returns any exceptions that we raised during the request.
Results A GeocodeResult Class array, where each element is a possible match returned by the Geocode Service.

To keep this article short(er) I will just cover the Results object. Depending on the Confidence filter and Geocode options that were set in the call you could receive more than one result.

Let’s assume that we only want to work with the first result and get the Geocode for “1 Microsoft Way, Redmond, WA”. We simply call the static method of GetGeocodeResponse and pass in the Bing Maps API key and the address to search for.

var address = "1 Microsoft Way, Redmond, WA";
GeocodeResponse response = GetGeocodeResponse(appId, address);

Assuming the address was found we can now work with the properties of the GeocodeResult class to find out the Geocode.  The Geocode is located in the Locations property which is an array of GeocodeLocation objects. If the Count of the Locations is greater than one, let’s just take the first one and update the txtLatitude and txtLongitude objects.

if (response.Results != null)
{
	var geocodeLocation = response.Results[0].Locations[0];
	if (geocodeLocation != null)
	{
	    txtLatitude.Value = geocodeLocation.Latitude;
	    txtLongitude.Value = geocodeLocation.Longitude;
	}
	else
	{
	    txtLatitude.Value = txtLongitude.Value = 0;
	}
}

That’s it. Next up, using the Bing Maps Web Services for getting map images.


Mix 10 Events Site Launched

Are you going to Mix10 in March? If so, you might want to check out the new site I launched call Mix 10 Events.  Mix 10 Events will be you one stop shop for all of the events and after parties at Mix10.

Anyone can create an event on the sign. All you need to do is sign in with you Windows Live credentials, and link to create an event will appear.  Please note, the event will not be available until it is reviewed and approved for display.

VisitMixEvents.info

Staying connected

Don’t feel like checking out the site every day to see what is happening? Here are a few resources to help you.

The site http://www.visitmixevents.info/default.aspx
RSS Feed http://www.visitmixevents.info/rss.ashx
GeoRSS Feed http://www.visitmixevents.info/rss.ashx?format=geo
iCal Feed http://www.visitmixevents.info/calendar.ashx
Map of events http://www.visitmixevents.info/map.aspx

Mobile Users

You will be able to view all of the events that are happening, even filter by day. In addition, you can view the events on a Map, and check out the event info.

Mobile Site http://www.visitmixevents.info/m/default.aspx
Mobile Map http://www.visitmixevents.info/m/m.aspx

Las Vegas

In case you do not want to check out the events, I mean “It’s Vegas Baby”. Here are some other resources, also accessible from the site.

Bing Local http://www.bing.com/local/default.aspx?q=Las+Vegas%2C+Nevada
Official Las Vegas Tourism http://www.visitlasvegas.com/vegas/index.jsp
Vegas.com Guide http://www.vegas.com/traveltips/

MVP Summit Events Launched

One thing that I have noticed of the past few years when it comes to conference or “Summits” is that there are a lot of after parties, tweets, etc. that happen.  Most of the time it is difficult to get the word out about these events or even find out about them.  That’s where MVPSummitEvents.com comes in.  The site will hopefully be a one stop shop to find public events that are happening at the Microsoft 2010 MVP Global Summit.

From the site you can add events, create venues, display events, subscribe to the RSS feed or iCal feed, download an event to outlook or calendar client that can consume a .VCS file. Note: the creation of events and venues requires you to sign in using your Windows Live Id account, no information from Live is used within our site.

If the site is successful, I plan to white label it to use with other events like MIX2010, TechEd, PDC, etc.

Let me know what you think at jguadagno@sevdnug.org


A November to Remember

And no it is not because the Yankees won the World Series (although congrats to them) it is because it has been an awesome month for me personally and professionally.

On the personal front…

My son’s baseball team, which I am an assistant coach, finished the season undefeated in regular season games (end of year tournament in next week).  My son hit his first over the fence homerun which was a Grand Slam (technically not November but pretty awesome). My daughter's softball team, which I am an assistant coach, finished the season undefeated in regular season games (end of year tournament in next week).

I get to go to fly back to NY in a few days to see family and friends and wish my mother a happy 60th birthday.

On the professional front…

I was elected to the North American INETA board of directors.

I was elected to the AZGiveCamp executive committee, VP of Operations.  As the VP I will oversee the activities of the Logistics, Sponsorship, Technology and Publicity teams.

I put together my first Code Camp, Desert Code Camp.

I am presenting a Bird of Feather session at PDC with Chris Woodruff on “How to Build and Enrich Your Technical and Local Community” on Tuesday Nov 17 from 11a – 12p.  Stop by if you want to see how to build your community.

 

That’s it for now.  Hopefully I can relax a bit in December.




Add an iCal feed to Sitefinity

iCal feeds let you share your and/or import your events that are stored in Sitefinity.  Here is a library that will let you generate an iCal feed from Sitefinity. Future versions of this library might have us filtering by categories or date.

iCal feed for Sitefinity iCal feed for Sitefinity

I’ve made a few changes since the last release to include some bug fixes.

  • Added Google and Outlook friendly fields in the feed file to describe the iCalendar file as well as the publisher.
  • Added code to the Location and Description fields to keep them at 75 characters or less to comply with the iCal specifications.

Installation

web.config changes

First you need to tell ASP.NET about your new handler. Open up the web config file and look for the httpHandlers section, it’s parent is system.web and add the following:

   1: <add verb="GET" path="GetICSFile.ashx" type="SEVDNUG.Web.HttpHandlers.CalendarHandler, App_Code"/>

Note: The path name can be changed to any legal value like “feeds/ical.ashx” or “ical.ashx”.

Files

Copy the vCalendar.cs and CalendarHandler.cs files to the App_Code directory of your Sitefinity installation.

Customize

Getting the event data from Sitefinity and creating the iCalender objects is handled inside the CalendarHandler class.

The class assumes that your events provider is named “Events”, if not you will have to change line 25 of the class. 

The class maps the following fields to an iCalendar event.

iCalendar event Sitefinity Field
Description Content
Location LocationName (Meta Field)
Summary Title (Meta field)
Url UrlWithExtension
DTStart Start
DTEnd End

I believe these meta values are the default meta keys from Sitefinity. If your values differ, you can modify them on lines 64 and 65.




One of the many features of Sitefinity is the ability to create custom controls to customize the look and feel of your website. The website for the Southeast Valley .NET User Group contains several custom controls. In the next few weeks I will post all of the controls here.

Sponsor ImageOn to the Random Generic Content Control. The purpose of the control is randomly display items that are based on a Generic  Content provider. I use this control to randomly pick sponsors of the Southeast Valley .NET User Group to display on the home page. Here is a snapshot of the control in use.

Installing the Control

Installing the control is a three part process.

The first step is to add the control to Sitefinity.  This can be done one of three ways.  Which way you choose depends on your technical ability. Here is a list of options in order of least technical to most technical.

  1. Add the class RandomGCControl.cs in the zip file to the App_Code folder of your Sitefinity project.
  2. Create a Visual Studio class library project, add the RandomGCControl.cs class to it. You will need to add the following references to the project; Telerik.Cms, Telerik.Cms.Engine, Telerik.Cms.Web.UI, Telerik.Framework, Telerik.Personalization, and Telerik.Web.UI. Compile the class, then upload it as documented by the Sitefinity article “Adding Controls
  3. Create a separate class project as outlined in the step above  then add a reference to this project to your Sitefinity project.

The next step is let Sitefinity know about the new control. Note: this step is not required if you compiled the control and uploaded it through the Sitefinity interface. To do this you need to modify the web.config file.  The controls are listed in the cms/toolboxControls section. Add the following:

<add name="Random Generic Content"
section="SEVDNUG"
type="SEVDNUG.Web.Sitefinity.WebControls.RandomGCContent, 
SEVDNUG.Web.Sitefinity.WebControls"
description="Displays a random generic content items"/>

If you followed the steps, the next you go to edit a page in Sitefinity you should see the Random Generic Content control available in the SEVDNUG group.

Configuring the Control

The Random Generic Content control has four properties that you need configure.

Property name Function
Item List Template File (Appearance Section) Controls the overall look of items that appear. This file dictates the display of the generic content.
Generic Content Details Url (Appearance section) This property points to the single page where you want Sitefinity to navigate to when an item is clicked.  This is typically the same page that hosts this generic item.
Number Of Items (Data section) Indicates how many generic items to display.
Provider Name (Data Section) Indicates which generic item provider to use.

Customizing the Control

To customize the display of the control, you will need to edit the file that you specified in the Item List Template File property of the control.  There is a sample template in the attached file.

<div class="topSponsorsList">
    <h2 class="sf_listTitle">Random Content</h2>
    <h3>
        <asp:Literal ID="GCTitle" runat="server"></asp:Literal>
    </h3>
    
    <asp:Repeater ID="GCRepeater" runat="server">
        <HeaderTemplate><ul class="sf_simpleList">
</HeaderTemplate>
        <ItemTemplate>
            <li class="sf_simpleList">
                <asp:Literal ID="Name" runat="server" />
            </li>
        </ItemTemplate>
        <FooterTemplate></ul></FooterTemplate>
    </asp:Repeater>
</div>

The control will look for form field names that match the names of the meta keys for that provider and replace them with the value of the meta key.

Here is an example of the sponsor template used to generate the image above.

<asp:Repeater ID="GCRepeater" runat="server"> 
 <HeaderTemplate><ul class="sponsorList"></HeaderTemplate> 
  <ItemTemplate> 
   <li class="sponsorList"> 
    <asp:HyperLink ID="fullContent1" runat="server"> 
    <img src='<asp:Literal ID="Company_Logo_Url" runat="server" />' 
    alt= '<asp:Literal ID="Company_Name" runat="server" />' 
    width="120" height="50" onError="img2txt(this)" /> 
    </asp:HyperLink> 
   </li> 
  </ItemTemplate> 
 <FooterTemplate></ul></FooterTemplate> 
</asp:Repeater> 
<script> 
  function img2txt(img)
{   txt = img.alt;   img.parentNode.innerHTML=txt;} 
</script>
Hopefully you will find this control useful.  Look for some more controls a providers soon.

Hats off to Rachel Reese for successfully organizing the first Laid Off Camp Phoenix. The event went smooth as could be.  I think the highlight of the event was watching all of the networking that went on during the event and after the event at Liberty Market.

Thanks to the sponsors below and all of the volunteers for contributing to the success of the event.

Below is a list of resources that were available in the program.

Curtis Miller took some picture of the event and posted them on Flickr.

Sponsors

Gilbert, AZ Economic Growth through innovation, collaboration and job-based economic development strategy.
Flatterline Purveyors of kick a$$ Web Development
Hyatt Place Phoenix/Gilbert Stylish, Thoughtful, Savvy.
TekSystems The Leading Technology Staffing and Services Company
Gangplank Kryptonite for the Status Quo
Hire Flyer Services Find the right job. Without all of the work.
JC Printing Managing the Science of Printing

Resources

Phoenix Workforce Connection

Bureau of Labor Statistics: Resource for Job Seekers

HireFlyer Job Bank

Get a Freelancer

10 til 2

Working in Gilbert, Arizona

Volunteers

Perri Collins

Xanthe Horste

Charlene Kingston

Derek Neighbors

Evo Terra

Lorin Twaits

Debbie Walker

Ann Watson-Barber


T-Mobile WiFi Calling

A month or so ago I signed up for this new T-Mobile plan that allows you to use your cell / mobile phone to make unlimited calls from almost any WiFi connection.  The reason I say almost is because there are two types of WiFi connections it will not make, a secured WiFi network that you do not have the security key for and any "free" WiFi connections that require you to accept the terms of use (most public access points).  When I saw this deal I signed up almost immediately. The idea that you can be on the road using your normal cell phone tower and them walk in to you house and seamlessly have the call transferred to your wireless network was awesome. So I purchased four Samsung Katalyst T-739 phones which have WiFI / UMA calling built in and my journey began.

Since then I have had two months of unreliable WiFi calling connectivity. My first connection attempts were with my AirLink AR430W SuperG Wireless router that I purchased for $15.00 dollars at a local Frys Electronic store. With this router I would get sporadic WiFi/UMA connectivity on all four phones.  Some of them would connect, some of them would not. I would get one of a few T-Mobile errors; W002 and W010.  After googling for days and weeks, there was not a lot of information about these errors on the Internet. Most of the errors pointed to Blackberry connectivity issues and that errors W002 and W010 means that the device could not get an IP address which was quite strange because both laptops, my Wii and Xbox 360 all connected fine.  So I began my troubleshooting...

First I tried to connect to a friends un-secure router, every connection attempt was successful and I was making calls but this was not legal. So I tried to un-secure my wireless network, this worked for some of the phones some of the time. I tried changing the network beacon timeout, this worked for some of the phones some of the times.  The phones would sometimes connect after rebooting the router but this was unacceptable.  After about a month I decided it was my cheap $15 dollar router, so I went out and purchased a TrendNET TEW-631BRP 300Mbps Wireless N Broadband route. I continued to have the the same issues as above so I went back to Google and found a few sites that suggested to turn off MAC filtering, this was not applicable to me, or to try to assign static IP addresses to the phone so I tried this but no dice.  After about six weeks of troubleshooting and phone tag with the T-Mobile WiFi calling help desk we came up with a solution.

The solution

It turned out that the sporadic access was because I had the router set to automatically determine a channel.  The T-Mobile WiFi/UMA service will only work with channels 1,6, or 11, which I why it connected to my neighbors router (channel 6).

Here are all of the settings that you can apply to router to make it function similarly to the T-Mobile branded LinkSys router.

Setting Value
Beacon Period 100
RTS Threshold 2347
Fragmentation Threshold 2346
DTIM Interval 1
Wireless Channel (try in this order) 11, 6, 1
For a secure network WPA 2 is preferred over WEP

I hope this helps solve some of your problems and that T-Mobile documents this somewhere.


New Sitefinity tool created

As some of you know, I have the Southeast Valley .NET User Group web site running on Telerik's Sitefinity product.  The product itself is awesome but needs a few features here an there... One of which is a mechanism to get data into Sitefinity quickly. Luckily, Sitefinity provides a pretty extensive API for you to develop against. So with some free time, the little I have, I put together a Data Importer tool for Sitefinity. This tool will allow you to import data from a Comma Separated file into any Sitefinity generic provider.

The project is open source and available at http://www.codeplex.com/SEVDNUGDataImporter please report any problems or feature request there.

Enjoy!


PhotoStream

About the author

Joseph Guadagno Name: Joseph Guadagno
Occupation: Programmer, SEVDNUG, Microsoft Visual C# MVP
Location: Chandler, AZ

Joseph Guadagno RSS Joseph Guadagno Twitter Joseph Guadagno Linked In