Integrate Bing Maps With Geonames Database And ASP.NET

8. February 2011 03:11

API ASP.NET Microsoft Utils 

After Microsoft launched Bing Maps, there are few things which lead me not to use Google Maps:

  • Bing Maps are more accurate than Google Maps.
  • Bing Maps looks more pretty than Google Maps.
  • And the main reason I am using Bing Maps is because I am a Microsoft fan Cool

To locate a place on maps (Bing or Google), the best thing is to get the latitude and longitude of the location, this ensures that the place we are pinning on the map is accurate. But the big question is to where to get the latitude and longitude of the location. There might be a web service for getting the latitude and longitude of a location, but wouldn't it be nice if you just have to query a local database?

Get the Geonames data dump

Apart from providing free web services and API Geonames.org also provides their data dumps which gets updated regularly. the best things about the data dumps are that they are distributed country-wise, city-wise etc. If you wish to download the data country wise, then you can download the file(s) which are named according to the countries IATA codes. The one I am using for this example is the allCountries files from the dumps. Download this dump only if you want to have ALL the Geoname data.

 

Import data in SQL Server

The dump can be imported in the database using the Data import-Export wizard present in the SQL Server or you can write a custom tool to import the whole dump. The dump is in a TAB delimited format. Just in case if you are not aware, the file you downloaded is in UTF-8 encoding and therefore you need it to convert it to UTF-16 encoding before you actually import it into the database. There is a command line tool which will help you to convert the database dump to UTF-16 which I got from the Geoname forums.

 

This tool will convert the format of the dump file from UTF-8 to UTF-16. After the successfull conversion of the file, now comes the time to import the data in the database.

Create a database table:

CREATE TABLE GeoNames( 
geonameid int NOT NULL, 
name nvarchar(200) NULL, 
asciiname nvarchar(200) NULL, 
alternatenames nvarchar(max) NULL, 
latitude float NULL, 
longitude float NULL, 
feature_class char(2) NULL, 
feature_code nvarchar(10) NULL, 
country_code char(3) NULL, 
cc2 char(60) NULL, 
admin1_code nvarchar(20) NULL, 
admin2_code nvarchar(80) NULL, 
admin3_code nvarchar(20) NULL, 
admin4_code nvarchar(20) NULL, 
population bigint NULL, 
elevation int NULL, 
gtopo30 int NULL, 
timezone char(31) NULL, 
modification_date date NULL 
)

To import millions of records you can write a custom tool or you can use the SQL Server Data Import/Export Data wizard. I have wrote a custom tool to import, but you can use the T-SQL's BULK INSERT (because it is simple and easy) to import the dump.

BULK 
INSERT GeoNames 
FROM 'I:\Database\Dump.txt' 
WITH( 
DATAFILETYPE = 'widechar', 
FIELDTERMINATOR = '\t', 
ROWTERMINATOR = '\n' 
)

The parameters in the above SQL statement is self-explanatory and therefore I am not going to brief them. But before you can start locating places with ASP.NET make sure you have indexed the table, if not then you will receive a SQL Server timed-out error.

Working with Bing Maps

Our database is now ready and now we can start locating the places on the Bing maps. We have two pages in the project, one which we will be using to get the locations and their details on the basis of city name enter by the user and the other which will show the map with a push pin.

Default.aspx page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="BingMap._Default" EnableViewState="true" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
    <title>Bing Maps with ASP.NET and GeoNames Database</title>
    <link href="Style/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <form id="form1" runat="server" enableviewstate="true">
    Enter Place Name:  <asp:TextBox ID="txtPlaceName" runat="server" />
    <asp:Button ID="btnPlaceName" runat="server" Text="Get GeoData!" OnClick="btnPlaceName_Click" />
     <br />
    <br />
        <table id="GeoData" style="width: 55%;" enableviewstate="true">
            <tr>
                <td class="tdheader">
                      City Name
                </td>
                <td class="tdheader">
                      Lat./Log.
                </td>
                <td class="tdheader">
                     Country
                </td>
                <td>
                </td>
            </tr>
            <%for (int i = 0; i < RecCount; i++)
              {%>
            <tr>
                <td>
                     
                    <%=CityName[i]%>
                </td>
                <td>
                     
                    <%=Lat[i]%>
                    /
                    <%=Log[i]%>
                </td>
                <td class="country">
                     
                    <%=Country[i]%>
                </td>
                <td>
                    <a href="BingMap.aspx?lat=<%=Lat[i]%>&log=<%=Log[i]%>&place=<%=CityName[i]%>" target="_blank">Show on Map</a>
                </td>
            </tr>
            <%}%>
        </table>
    <br />
   <asp:Label ID="RecFound" Text="" runat="server" />
    </form>
</body>
</html>

The above page will get and show the details of the place. Click the Show on Map link to view the map.

 

Code Behind: Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BingMap.DBModel;


namespace BingMap
{
    public partial class _Default : System.Web.UI.Page
    {
        WorldEntities world = new WorldEntities();
        public List<string> CityName = new List<string>();
        public List<string> Country = new List<string>();
        public List<string> Lat = new List<string>();
        public List<string> Log = new List<string>();
        public int RecCount = 0;

        private void GetLocation(string CName)
        {
            try
            {
                var WorldLoc = from l in world.Geonames
                               where l.name == CName
                               select l;

                foreach (var item in WorldLoc)
                {
                    CityName.Add(item.name);
                    Country.Add(item.country_code);
                    Lat.Add(Convert.ToSingle(item.latitude));
                    Log.Add(Convert.ToSingle(item.longitude));
                    RecCount = RecCount + 1;
                }

                if (RecCount == 0)
                {
                    RecFound.Text = "No Record(s) Found!";
                }

                else
                {
                    RecFound.Text = Convert.ToString(RecCount) + " Record(s) Found!";
                }
            }
            catch (Exception x)
            {
                Response.Write(x.ToString());
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btnPlaceName_Click(object sender, EventArgs e)
        {
            if (Page.IsPostBack)
            {
                GetLocation(txtPlaceName.Text);
            }
        }
    }
}

There could be many places with the same name in different geographical locations. For example, if you query the database with San Francisco, you'll find out it is not the only place on the planet in U.S. The same is with the city in India called Hyderabad, one is in India and the other is in Pakistan. But the geographical location is different and thus we can place a push pin on the maps.

I have used a different web page for the map. From the page Default.aspx page I will pass the information (latitude, longitude and place name) in query string to pin the location on the map.

BingMap.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="BingMap.aspx.cs" Inherits="BingMap.BingMap" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Bing Map</title>
    <script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.3"></script>

    <script type="text/javascript">
        function LoadMap() {
            map = new VEMap('BingMap');
            var Latitude = '<%= LocLat %>';
            var Longitude = '<%= LocLog%>';
            var PlaceName = '<%=Place %>';
            if (Latitude.length == 0 || Longitude.length == 0) {
                var latlong = new VELatLong(28.63576, 77.22445);

                map.SetDashboardSize(VEDashboardSize.Large);
                map.LoadMap(latlong, 9, VEMapStyle.Road);

                //Add pushpin
                var pin = new VEShape(VEShapeType.Pushpin, latlong);
                pin.SetCustomIcon(null);
                pin.SetTitle("New Delhi");
                pin.SetDescription("Capital City Of India");
                map.AddShape(pin);
                map.ShowDashboard();
            }
            else {
                var latlong = new VELatLong(Latitude, Longitude);

                map.SetDashboardSize(VEDashboardSize.Large);
                map.LoadMap(latlong, 9, VEMapStyle.Road);

                //Add pushpin
                var pin = new VEShape(VEShapeType.Pushpin, latlong);
                pin.SetCustomIcon(null);
                pin.SetTitle(PlaceName);
                pin.SetDescription("<br/>" + "<strong>Latitude:</strong>" + '<%=LocLat%>' + "<br/>" + "<strong>Longitude:</strong>" + '<%=LocLog%>');
                map.AddShape(pin);
                map.ShowDashboard();
            }
        }
    </script>

</head>
<body onload="LoadMap();">
    <form id="BingForm" runat="server">
    <div id='BingMap' style="position: relative; width: 800px; height: 600px;">
    
    </div>
    </form>
</body>
</html>

The client-side script is used to load the map. I have used the version 6.3 of the Bing Maps but you can also use the version 7.0. Though you need some additional parameters to use the latest one like the Bing Maps developer API key. The map can be set in the script tag.

<script type="text/javascript" src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.3"></script>

A funtion named LoadMap() will doing the rest of the job, like setting the latitude, longitude, adding push pin to the location on the map and customizing other details on the map.

var latlong = new VELatLong(28.63576, 77.22445);
map.SetDashboardSize(VEDashboardSize.Large);
map.LoadMap(latlong, 9, VEMapStyle.Road);

The first line in the above script will set the latitude and longitude. The LoadMap method should always be called after SetDashboardSize. I have set the VEDashboardSize enumeration to Large you can also use Small if you want the navigation controls of the map to appear small. LoadMap method will take 3 parameters, the first is the reference of the latitude and longitude of the location, second is the Zoom Level, which is 9 in my case, you can adjust this value according to your requirement and the third option VEMapStyle enumeration will let you set the style for the map. It can be Road, Aerial, BirdEye etc (Click on the links to know more about these enumerations). And this is it, this will load the map in the browser showing the place of your choice with specified latitude and longitude.

To be more precise an beautify the Bing Map, we can also add a push pin at the specified location and that too can also be done with the help of the client-side script.

var pin = new VEShape(VEShapeType.Pushpin, latlong);
pin.SetCustomIcon(null);
pin.SetTitle(PlaceName);
pin.SetDescription("<br/>" + "<strong>Latitude:</strong>" + '<%=LocLat%>' + "<br/>" + "<strong>Longitude:</strong>" + '<%=LocLog%>');
map.AddShape(pin);

To add a new push pin to our location we need to use VEShape class. SetCustomIcon method allows to set the custom icon for your push pin. SetTitle method will set the description for you push pin. SetDescription method sets the description of the push pin, here in the description I have set the other information like location's latitide and longitude. To add the push pin to the location the AddShape method of the map class will take pin as a parameter and set the push pin on the map.

For showing map I have used a different web page named BingMap.aspx which also includes the code behind (just a few lines) apart from client-side code:

BingMap.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace BingMap
{
    public partial class BingMap : System.Web.UI.Page
    {
        public string LocLat = "";
        public string LocLog = "";
        public string Place = "";

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString.AllKeys.Length > 0)
            {
                LocLat = Request.QueryString["lat"].ToString();
                LocLog = Request.QueryString["log"].ToString();
                Place = Request.QueryString["place"].ToString();
            }

            if (LocLat.Equals("") || LocLog.Equals(""))
            {

            }
        }
    }
}

In the code-behind I will check on page load if the count of the query string passed on to the page is greater than zero, if the condition is true then I will set the values in the public variables and set them on the client-side script which actually handles the loading, locating and adding push pin on the map. The URL on calling the BingMap.aspx page will look like this:

http://localhost:5543/BingMap.aspx?lat=28.35&log=79.41667&place=Bareilly

I have shown my home town on the map. You can also see a push pin and other details in a baloon.

 

And this is it, I can now locate any place on the Bing Maps which is present with me in Geonames database with the help of ASP.NET. The more can be done with the help of Geonames database like postcode lookup. I hope this tutorial will get you started with Bing Maps integrated with Geonames database with the help of ASP.NET.

Download: BingMap.zip (189.44 kb)

Download the UTF8ToUTF16 conversion tool

Related Links:

Currently rated 3.5 by 4 people

Poster: Windows Server 2008 R2 Feature Components

26. October 2010 04:15

Microsoft 

This poster provides a visual reference for understanding key technologies in Windows Server 2008 R2. It focuses on Active Directory Domain Services, Hyper-V, Internet Information Services, Remote Desktop Services (including Virtual Desktop Infrastructure (VDI)), BranchCache, and DirectAccess technologies. In addition, updates to core file services and server management are illustrated. You can use this poster in conjunction with the previously published Windows Server 2008 Component Posters.

Download PDF: Windows Server 2008 R2 Feature Components Poster

 No Rating

Efficient Use Of Windows SkyDrive

30. August 2010 16:05

Microsoft Azure 

If you are not using this free service offered by Microsoft, then stop reading and go to SkyDrive and sign in with your Live ID and get started. A whooping 25 GB of free space to put  all your stuff at one place, access anytime, and anywhere you want and just in case if you are aware, which I hope you already are, why I am mentioning about skydrive here? So, here is the case...

I uploaded some videos on my blog a few month ago, the files were physically hosted on my blog space and hogging a lot of space. I am now using SkyDrive since it final launch in August 2007 (if I am not wrong) and just gave a quick thought on hotlinking my files from SkyDrive to my blog. There are two big benefits of using SkyDrive for file hosting:

  1. Saves Web Space - In terms of any file you upload to your blog, it now get uploaded to SkyDrive and save your web space
  2. Saves Bandwidth - If you have a video or MP3 file host it on SkyDrive and set the hotlink in the player on your blog. The player just plays the files, just like embedding videos from YouTube or Channel9.

So how can you hotlink files from SkyDrive and use it for your purpose. Go to the folder where you have the file, it can be an image, video or a audio file. You will see something like the below. This is one of my publi folder where I have 2 images (funny).

Change the view style from Thumbnail to Details. By default for the folder having images the default view will be Thumbnails.

Now hover the mouse to the image you want to imbed or hotlink in your blog post or on a webpage. Click More and then right-click Download and select Copy Link Location. This will copy the download link on your clicb board and now you require some manual work on the link.

Open notepad and and paste the copied text. The link look something like this.

http://5mr9iq.bay.livefilestore.com/
y1pn6wH-ZKbNE3AMAGeZry5db0ukIQqy2ksda2ZHtegsxyJeeN1ufTs4AbT
-iyG2DnYpkLUFyPw5OnTpE_t7p_duRJ5wcVOHoC_/edin.jpg?download&psid=1

Just to hotlink the file remove the text starting from '?' till end (remove ?download&psid=1) and that's it, your image hotlink is ready and the final version of link looks like this:

http://5mr9iq.bay.livefilestore.com/y1pn6wH-
ZKbNE3AMAGeZry5db0ukIQqy2ksda2ZHtegsxyJeeN1ufTs4AbT-
iyG2DnYpkLUFyPw5OnTpE_t7p_duRJ5wcVOHoC_/edin.jpg

Below is the same image I have hotlinked from my SkyDrive account

The same can be done with videos. I have uploaded a video to my SkyDrive. Let's see how it look like on a Silverlight Player:

Moreover, if you take a look at the status bar of your IE or the browser you are using you will see that the data transfer is from livefilestore.com and not from yourdomain.com. This saves your bandwidth too!!!

This is not enough, now the question here is how can one upload files to SkyDrive, we can use the web interface provided by the SkyDrive.....!!? But how about using it as a network drive on your My Computer. You can download Gladient Cloud Desktop to map the SkyDrive or any other online service you are using to store your files, like Amazon S3 or Picasaweb to share photos.

UPDATE: Greg Duncan share his experience with SkyDrive with me. I recommend you to read it here.

Currently rated 4.5 by 2 people

Windows Phone 7 - Supported Media Codecs For Audio and Video

11. June 2010 07:52

Microsoft 

Today I was just looking at some of the demos on Windows Phone development and I came across a list of all the supported media codecs for Windows Phone 7. here is the list of all the supported audio and video codecs supported by

Codec Type

Decoder Support

Container

Audio

WAV (PCM, MSADPCM, IMAADPCM, G.711)

WAV

Audio

MP3

MP3

Audio

WMA Lossless

ASF (WMA)

Audio

WMA Pro

ASF (WMA)

Audio

WMA Standard v9

ASF (WMA)

Audio

AAC-LC (Low Complexity)

3GP, 3G2, MP4, M4A

Audio

HE-AAC v1 (AAC+)

3GP, 3G2, MP4, M4A

Audio

HE-AAC v2 (eAAC+)

3GP, 3G2, MP4, M4A

Audio

Adaptive Multi-Rate Narrow Band (AMR-NB)

3GP, 3G2, MP4

Audio

Adaptive Multi-Rate ide Band (AMR-WB)

3GP, 3G2, MP4

Audio

Qcelp

3GP, 3G2, MP4

Video

WMV (VC-1) - Simple Profile

ASF (WMV)

Video

WMV (VC-1) - Main Profile

ASF (WMV)

Video

WMV (VC-1) - Advanced Profile

ASF (WMV)

Video

WMV v9

ASF (WMV)

Video

MPEG-4 Part 2 - Simple Profile

3GP, 3G2, MP4, AVI

Video

MPEG-4 Part 2 – Advanced Simple Profile

AVI, MP4

Video

DivX 4.x/5.x/6.x

AVI

Video

MPEG-4 Part 10 (MPEG-4 AVC, H.264) - Baseline Profile

3GP, 3G2, MP4, M4V

Video

MPEG-4 Part 10 (MPEG-4 AVC, H.264) - Main Profile

3GP, 3G2, MP4, M4V

Video

MPEG-4 Part 10 (MPEG-4 AVC, H.264) - High Profile

3GP, 3G2, MP4, M4V

Video

H.263

3GP, 3G2

Images

JPEG

JPG

Images

PNG

PNG

Images

GIF (both GIF87a and GIF89a)

GIF

Original Source: Windows Phone 7 Media Codec Support

 No Rating

First Look At Microsoft Office 2010 - Free E-book From Microsoft Press

10. June 2010 17:27

Microsoft 

I just installed Microsoft Office Professional Plus 2010 and now I am experiencing some new exciting features of Microsoft Office. Here is free e-book from Microsoft press for users to have a glance at the latest version of their Office series. If you haven't tried it but want to go for Office 2010, then take a look at this free e-book.

Download E-Book: PDF Version | XPS Version

 No Rating