Intelligence tracking System using Telerik Map Control in Silverlight 4 - Part I

Vuyiswamb
Posted by in Silverlight category on for Advance level | Points: 250 | Views : 8709 red flag
Rating: 4.67 out of 5  
 3 vote(s)

In most of my career, I worked with these kinds of Systems. How track someone? How to intercept Phone calls, How to Spy on Someone? How to Sniff on Devices? The things you see on TV, some of them are not true and some are true and possible. Before you even try to do something illegal on the internet, you must know that there are people who might be looking at you with basic intelligence systems like the one I mentioned or the one I will present to you now. As you know you can just get the IP address of your client with just one line of code in c# and in this article I will show you how to use it to get their location and possibly more.

Introduction

 

In most of my career, I worked with these kinds of Systems. How track someone? How to intercept Phone calls, How to Spy on Someone?  How to Sniff on Devices? The things you see on TV, some of them are not true and some are true and possible. Before you even try to do something illegal on the internet, you must know that there are people who might be looking at you with basic intelligence systems like the one I mentioned or the one I will present to you now. As you know you can just get the IP address of your client with just one line of code in c# and in this article I will show you how to use it to get their location and possibly more.

Background

The IP address that you use to browse the internet can reveal the nearest location. Meaning that the GPS is not exactly accurate with the location, but it can be just maybe two kilometers or more inaccurate. Also ISP info can be confirming the exact address. There are many ways to deceive the Intelligence Systems, but I will not cover those ways because it is beyond the scope of this article.  In this article I am going to demonstrate to you, a small intelligence system, that will track a person’s location based on the IP address.  

Using the code

We are going to use C# as our main Language.

 

Tools you need

You can look at my previous articles, to see which tools you need to download. If you once followed my previous GIS articles, you can just ignore this part.

 

Start

Most of the Time, the Intelligence will have their database of IP that maps the IP’s to countries and this can drill down to city until a street address more deeper to the owner of the property or more. So for the purpose of your understanding we are going to consume a third party web service that will resolve the IP to a physical location in our map in co-ordinates.

Now this means if you are not sure whose IP is accessing your machine, e.g. if you are on a chat messenger with someone and you are not sure of their the person’s location, you can type “netstat –n” from your cmd window and you will see something like this


Now I can’t show you my whole IP or the IP’s I connect to. So you must look at the Foreign Address and look for those who are established. These are connections to your machine. But now these are the IP should not scare you, some might be Trojans or bots and some might be just normal websites. So now, what you need to do is to convert the IP address into real locations that can be displayed on the map. But let us not move away from the scope of this article. Now the first thing you need to do, is to register on this site,

http://ipinfodb.com/register.php

This is the site that will expose a web service that you will consume in your Silverlight application and display the location (Co-Ordinates) it provides in the map. As you have noticed in my previous articles, in order to use this free service, you need a key that you will need to generate from the website I gave you above. In this API, you don’t need to code it in your System; the key will be added in the URL of the web service.

At first you will get this example from the website,

http://api.ipinfodb.com/v2/ip_query.php?key=<your_api_key>&ip=74.125.45.100&timezone=false

The bold part is where you need to add your key. Replace the brackets and the its contents when you add you’re key and it should look something like this

http://api.ipinfodb.com/v2/ip_query.php?key=sdsds84887e1sdsdsd6b050eca9247c8631c5c9sdsde48f&ip=74.125.45.100&timezone=false

The Following is the Final Product of what we are building. I will not go through the small steps on click there and there.

The Following is the code for the project.

using MapSearch.Model;

using System;

using System.Globalization;

using System.IO;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Browser;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using Telerik.Windows.Controls.Map;

using Telerik.Windows.Examples.Map.Search;

using System.Xml.Linq;

using ItemsControl = Telerik.Windows.Controls.ItemsControl;

 

namespace MapSearch

{

    public partial class MainPage : UserControl

    {

        private string VEKey;

        private MapItemsCollection itemCollection = new MapItemsCollection();

        private BingSearchProvider searchProvider;

        private string  stringApiKey = "b14f16672dfsdfdff884887e1e5ab3e38f051c986b05sdfsdf0eca9247c8631c5c9c88e0ae48f";

        public MapLayer x_map;

        public IpInfo ipInfo = new IpInfo();

        public MainPage()

        {

            InitializeComponent();

 

            bsIndicator.IsBusy = true;

            this.GetVEServiceKey();

 

          

            this.informationLayer.DataMappings.Add(new DataMapping("Location", DataMember.Location));

 

            Binding binding = new Binding();

            binding.Source = this.itemCollection;

            this.informationLayer.SetBinding(ItemsControl.ItemsSourceProperty, binding);

 

            bsIndicator.IsBusy = false;

 

        }

              // Initialize Virtual Earth map provider.

              private void SetProvider()

              {

                     BingMapProvider provider = new BingMapProvider(MapMode.Aerial, true, this.VEKey);

                     this.RadMap1.Provider = provider;

 

                     // Init searh provider.

                     searchProvider = new BingSearchProvider()

                     {

                           ApplicationId = this.VEKey,

                           MapControl = this.RadMap1

                     };

                     searchProvider.SearchCompleted += new EventHandler<SearchCompletedEventArgs>(Provider_SearchCompleted);

              }

 

              private void GetVEServiceKey()

              {

                     WebClient wc = new WebClient();

                     wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc_DownloadStringCompleted);

            Uri keyURI = new Uri(HtmlPage.Document.DocumentUri, "AlTsdTXGRrAlAD_AsdfsdfNxsWHkwshIVLoBLCryJjB5adacusdfsdfGgcQSzd9UQZaow8hsdfsdVLPIUNMV");

                     wc.DownloadStringAsync(keyURI);

              }

 

              void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

              {

            this.VEKey = "AlTTXGRrAlADsdfsfxWHkwshsdffsdIVLoBLCryJadacuGgcQSzs9UQZaors38hVLPIUNMV";//e.Result;

                     this.SetProvider();

              }

 

              private void SearchHandler(object sender, RoutedEventArgs e)

              {

                    

              }

 

        private void Provider_SearchCompleted(object sender, SearchCompletedEventArgs args)

        {

            SearchResponse response = args.Response;

 

            if (response.ResultSets[0].Results.Count > 0)

            {

                this.itemCollection.Clear();

                foreach (SearchResultBase result in response.ResultSets[0].Results)

                {

                    MyMapItem item = new MyMapItem()

                    {

                        Title = result.Name,

                        Location = result.LocationData.Locations[0]

                    };

                    this.itemCollection.Add(item);

                }

            }

 

            if (response.ResultSets[0].SearchRegion != null)

            {

                // Set map viewport to the best view returned in the search result.

                this.RadMap1.SetView(response.ResultSets[0].SearchRegion.GeocodeLocation.BestView);

 

                // Show map shape around bounding area

                if (response.ResultSets[0].SearchRegion.BoundingArea != null)

                {

                    MapShape boundingArea = response.ResultSets[0].SearchRegion.BoundingArea;

                    boundingArea.Stroke = new SolidColorBrush(Colors.Red);

                    boundingArea.StrokeThickness = 1;

                    this.informationLayer2.Items.Add(boundingArea);

                }

 

                if (response.ResultSets[0].SearchRegion.GeocodeLocation.Address != null

                    && response.ResultSets[0].SearchRegion.GeocodeLocation.Locations.Count > 0)

                {

                    foreach (Location location in response.ResultSets[0].SearchRegion.GeocodeLocation.Locations)

                    {

                        MyMapItem item = new MyMapItem()

                        {

                            Title = response.ResultSets[0].SearchRegion.GeocodeLocation.Address.FormattedAddress,

                            Location = location

                        };

                        this.itemCollection.Add(item);

                    }

                }

            }

        }

 

        private void btnSearch_Click(object sender, RoutedEventArgs e)

        {

            string query = this.SearchCondition.Text;

 

            if (!string.IsNullOrEmpty(query))

            {

                SearchRequest request = new SearchRequest()

                {

                    Culture = new System.Globalization.CultureInfo("en-ZA"),

                    Query = query

                };

                this.searchProvider.SearchAsync(request);

            }

        }

 

 

 

        private void ShowMap(String SearchCondition)

        {

            string query = SearchCondition;

 

            if (!string.IsNullOrEmpty(query))

            {

                SearchRequest request = new SearchRequest()

                {

                    Culture = new System.Globalization.CultureInfo("en-ZA"),

                    Query = query

                };

                this.searchProvider.SearchAsync(request);

            }

        }

 

        private void btnGetIPLocation_Click(object sender, RoutedEventArgs e)

        {

            bsIndicator.IsBusy = true;

            if (txtIpaddress.Text != "")

            {

                GetIpInfo();

            }

            else

            {

                txtIpaddress.Background = new SolidColorBrush(Colors.Red);

 

            }

 

            bsIndicator.IsBusy = false;

        }

 

        private void GetIpInfo()

        {

            WebClient wbC = new WebClient();

            wbC.OpenReadAsync(new Uri("http://api.ipinfodb.com/v2/ip_query.php?key=" + stringApiKey + "&ip=" + txtIpaddress.Text));

            wbC.OpenReadCompleted += new OpenReadCompletedEventHandler(wbC_OpenReadCompleted);

        }

 

        void wbC_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)

        {

            if (e.Error != null)

            {

                //show message with error info.

            }

            using (Stream s = e.Result)

            {

 

                XDocument doc = XDocument.Load(s);

               

               

                var local = from text in doc.Descendants("Response")

               

                select new

                {

                    City = text.Element("City").Value.ToString(),

                    Country = text.Element("CountryName").Value.ToString(),

                    CountryCode = text.Element("CountryCode").Value.ToString(),

                    Region = text.Element("RegionName").Value.ToString(),

                    Latitude = text.Element("Latitude").Value.ToString(),

                    Longitude = text.Element("Longitude").Value.ToString(),

                    IpAdress = text.Element("Ip").Value.ToString()

                };

 

 

                NumberFormatInfo provider = new NumberFormatInfo();

                provider.NumberGroupSeparator = ".";

               

 

                foreach (var item in local)

                {

 

                    ipInfo.City = item.City != string.Empty ? item.City : "unknown";

                    ipInfo.Country = item.Country;

                    ipInfo.CountryCode = item.CountryCode;

                    ipInfo.Region = item.Region != string.Empty ? item.Region : "unknown";

                    ipInfo.Latitude = Convert.ToDouble(item.Latitude.ToString(), provider);

                    ipInfo.Longitude = Convert.ToDouble(item.Longitude.ToString(), provider);

                    ipInfo.IpAdress = item.IpAdress;

                }

 

                bsIndicator.IsBusy = true;

                lblcity.Content = ipInfo.City != string.Empty ? ipInfo.City : "none";

                lblCountry.Content = ipInfo.Country != string.Empty ? ipInfo.Country : "none";

                lblregion.Content = ipInfo.Region != string.Empty ? ipInfo.Region : "none";

 

                image1.Source = new BitmapImage(new Uri("http://" + App.Current.Host.Source.Host + "/Flags/" + ipInfo.Country +" -Flag-48" + ".png"));

                image1.Stretch = Stretch.UniformToFill;

            

                ShowMap(ipInfo.Latitude.ToString() + ",  " + ipInfo.Longitude.ToString());

 

                bsIndicator.IsBusy = false;

                RadMap1.ZoomLevel = 10;

 

            }

        }

 

    }

}

As you can see I have some declared objects that I don’t use for this example, it means that I have already started with the part 2 of this article. I am adding more nice functionality that i would like to share with you. Your xaml will look something like this

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

    mc:Ignorable="d"

    d:DesignHeight="761" d:DesignWidth="942" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"

    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">

    <Grid x:Name="LayoutRoot" Background="#FFA5BEB6" Height="741" Width="930">

              <telerik:RadMap  x:Name="RadMap1" ZoomLevel="7" Center="42.358431, -71.059773" Margin="12,210,12,0" Height="519" VerticalAlignment="Top">

                <telerik:InformationLayer Name="informationLayer">

                    <telerik:InformationLayer.ItemTemplate>

                        <DataTemplate>

                            <Border Background="#7FFFFFFF"

                                                       BorderThickness="1"

                                                       Padding="2,2,2,2">

                                <ToolTipService.ToolTip>

                                    <ToolTip Content="{Binding Path=Title}" />

                                </ToolTipService.ToolTip>

                                <telerik:MapLayer.HotSpot>

                                    <telerik:HotSpot X="0.5" Y="0.5" />

                                </telerik:MapLayer.HotSpot>

                                <Grid>

                                    <Grid.ColumnDefinitions>

                                        <ColumnDefinition Width="14" />

                                        <ColumnDefinition Width="Auto" />

                                    </Grid.ColumnDefinitions>

                                    <Path Fill="Red">

                                        <Path.Data>

                                            <GeometryGroup>

                                                <EllipseGeometry Center="7,7" RadiusX="3" RadiusY="3" />

                                                <EllipseGeometry Center="7,7" RadiusX="7" RadiusY="7" />

                                            </GeometryGroup>

                                        </Path.Data>

                                    </Path>

                                </Grid>

                            </Border>

                        </DataTemplate>

                    </telerik:InformationLayer.ItemTemplate>

                </telerik:InformationLayer>

                <telerik:InformationLayer Name="informationLayer2" />

            </telerik:RadMap>

        <TextBox Height="25" HorizontalAlignment="Left" Margin="526,12,0,0" Name="SearchCondition" VerticalAlignment="Top" Width="245" />

            <TextBlock Height="19" HorizontalAlignment="Left" Margin="355,16,0,0" Name="lblSearch" Text="Enter your Search Location:" VerticalAlignment="Top" Width="165" />

            <telerik:RadButton Content="Search" Height="22" HorizontalAlignment="Left" Margin="777,12,0,0" Name="btnSearch" VerticalAlignment="Top" Width="104" Click="btnSearch_Click" />

            <TextBox Height="21" HorizontalAlignment="Left" Margin="526,54,0,0" Name="txtIpaddress" VerticalAlignment="Top" Width="245" />

            <telerik:RadButton Content="Get Location" Height="22" HorizontalAlignment="Left" Margin="777,53,0,0" Name="btnGetIPLocation" VerticalAlignment="Top" Width="104" Click="btnGetIPLocation_Click" />

            <TextBlock Height="21" HorizontalAlignment="Left" Margin="355,58,0,0" Name="textBlock1" Text="IPAddress:" VerticalAlignment="Top" Width="67" />

            <sdk:Label Height="20" Margin="12,155,864,0" Name="label2" VerticalAlignment="Top" Content="Region:" />

            <TextBlock Height="23" HorizontalAlignment="Left" Margin="12,181,0,0" Name="textBlock2" Text="City:" VerticalAlignment="Top" />

            <TextBlock Height="21" VerticalAlignment="Top" FontFamily="Fonts/Fonts.zip#Segoe UI Light" FontSize="16" Text="National flag:" TextWrapping="Wrap" Margin="12,0,802,0" />

            <Image Height="83" HorizontalAlignment="Left" Margin="12,27,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="111" />

            <TextBlock Height="23" HorizontalAlignment="Left" Margin="12,126,0,0" Name="textBlock3" Text="Country:" VerticalAlignment="Top" />

            <sdk:Label Height="18" HorizontalAlignment="Left" Margin="67,126,0,0" Name="lblCountry" VerticalAlignment="Top" Width="119" />

            <sdk:Label Height="20" HorizontalAlignment="Left" Margin="59,155,0,0" Name="lblregion" VerticalAlignment="Top" Width="119" />

            <sdk:Label Height="23" HorizontalAlignment="Left" Margin="45,181,0,0" Name="lblcity" VerticalAlignment="Top" Width="120" />

 

        <controlsToolkit:BusyIndicator  HorizontalAlignment="Center" Name="bsIndicator" VerticalAlignment="Center" />

    </Grid>

   

</UserControl>

And I have an external class that has some property definitions.

using System;

using Telerik.Windows.Controls.Map;

 

namespace Telerik.Windows.Examples.Map.Search

{

    public class MyMapItem

    {

        public Location Location

        {

            get;

            set;

        }

 

        public string Title

        {

            get;

            set;

        }

 

        public string Description

        {

            get;

            set;

        }

    }

}

I have a folder in my project that carries a list of Countries flags that i would like to display every time i find a matching IP. You can download your images and add them to your folder. But most of the things like that will be demonstrated in the next part of this series.

 

Conclusion

This view is nice and cool. But now if someone is hiding his IP Address via the proxy, in the next part of this article I will show you how you can extend this application and see the real IP and I will have more functionality that will make this application a true and real intelligence system. But due to security reason, I can only share with you, what is good for the public only. Since you will not be an intelligence agent, the deep and interesting things that you could do with this application will not be revealed to anyone; even if you can send a private email. Not even Sheo will know them. So don’t bother sending me an email looking for private functionality.

Thank you for reading and visiting Dotnetfunda

Vuyiswa Maseko

Page copy protected against web site content infringement by Copyscape

About the Author

Vuyiswamb
Full Name: Vuyiswa Maseko
Member Level: NotApplicable
Member Status: Member,MVP,Administrator
Member Since: 7/6/2008 11:50:44 PM
Country: South Africa
Thank you for posting at Dotnetfunda [Administrator]
http://www.Dotnetfunda.com
Vuyiswa Junius Maseko is a Founder of Vimalsoft (Pty) Ltd (http://www.vimalsoft.com/) and a forum moderator at www.DotnetFunda. Vuyiswa has been developing for 16 years now. his major strength are C# 1.1,2.0,3.0,3.5,4.0,4.5 and vb.net and sql and his interest were in asp.net, c#, Silverlight,wpf,wcf, wwf and now his interests are in Kinect for Windows,Unity 3D. He has been using .net since the beta version of it. Vuyiswa believes that Kinect and Hololen is the next generation of computing.Thanks to people like Chris Maunder (codeproject), Colin Angus Mackay (codeproject), Dave Kreskowiak (Codeproject), Sheo Narayan (.Netfunda),Rajesh Kumar(Microsoft) They have made vuyiswa what he is today.

Login to vote for this post.

Comments or Responses

Posted by: Madhu.b.rokkam on: 3/2/2011 | Points: 25
Nice article ... Thanks for sharing
Posted by: Vuyiswamb on: 3/2/2011 | Points: 25
welcome :)

Posted by: Venflax on: 3/9/2011 | Points: 25
Good article....Thank you for sharing.

Login to post response

Comment using Facebook(Author doesn't get notification)