<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Search results matching tags 'powershell' and 'spatial'</title><link>http://sqlblog.com/search/SearchResults.aspx?o=DateDescending&amp;tag=powershell,spatial&amp;orTags=0</link><description>Search results matching tags 'powershell' and 'spatial'</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Fetching Latitude and Longitude Co-ordinates for Addresses using PowerShell</title><link>http://sqlblog.com/blogs/rob_farley/archive/2010/05/23/fetching-latitude-and-longitude-co-ordinates-for-addresses-using-powershell.aspx</link><pubDate>Sun, 23 May 2010 06:59:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:25440</guid><dc:creator>rob_farley</dc:creator><description>&lt;P&gt;Regular readers of my blog (at &lt;A href="http://sqlblog.com/blogs/rob_farley/" target=_blank&gt;sqlblog.com&lt;/A&gt; – please let me know if you’re reading this elsewhere) may be aware that I’ve been doing more and more with spatial data recently. With the now-available SQL Server 2008 R2 Reporting Services including maps, it’s a topic that interests many people.&lt;/P&gt;
&lt;P&gt;Interestingly though, although many people have plenty of addresses in their various databases (whether they be CRM systems, HR systems or whatever), my experience shows that many people do not store the latitude and longitude co-ordinates for those addresses.&lt;/P&gt;
&lt;P&gt;Luckily, the Bing Maps API provides everything you need!&lt;/P&gt;
&lt;P&gt;Start by going to &lt;A href="https://www.bingmapsportal.com/" target=_blank&gt;bingmapsportal.com&lt;/A&gt;, logging in using a LiveID and creating an account:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/rob_farley/image_56B3B5E3.png"&gt;&lt;IMG style="BORDER-BOTTOM:0px;BORDER-LEFT:0px;DISPLAY:inline;BORDER-TOP:0px;BORDER-RIGHT:0px;" title=image border=0 alt=image src="http://sqlblog.com/blogs/rob_farley/image_thumb_5A651EB6.png" width=570 height=484&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Then you can create a key using the link on the left. This key will be attached to a website, and looks something like: Apsjm7zVthPFMxlfpQqKhPPZrAupI-_aGH-CvT2b... Now you can use the Bing Maps API to fetch the information you need. Obviously check the terms and conditions to see if you will need to pay for your usage or not. The Bing Maps API works through web services, so it’s easy enough to use almost any system for this. You could easily make a CLR Function for use within T-SQL, but I’m going to show you how to do it using PowerShell.&lt;/P&gt;
&lt;P&gt;Let’s start by creating a Web Service Proxy to the URL of the webservice.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;$ws = New-WebServiceProxy -uri http://dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc?wsdl;&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;By passing $ws into Get-Member (using the command: &lt;EM&gt;$ws | Get-Member&lt;/EM&gt;), we can see that there is a Geocode method, which requires a parameter of type GeocodeRequest. Actually, the type to use is much more complicated, but it’s easy to create a variable for it using:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;$wsgr = new-object Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1ervice_geocodeservice_svc_wsdl.GeocodeRequest;&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This variable will take the address to look up in its Query property, but we’ll do that in a moment. First we need to provide credentials, which is that key we created on the website. I’ve stored mine in a variable called $key, so that I don’t have to display it in demonstrations that might be recorded.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;$wsgrc = new-object Microsoft.PowerShell.Commands.NewWebserviceProxy.AutogeneratedTypes.WebServiceProxy1ervice_geocodeservice_svc_wsdl.Credentials; &lt;BR&gt;$wsgrc.ApplicationId = $key; &lt;BR&gt;$wsgr.Credentials = $wsgrc;&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now when we call the method on our web service, Bing Maps will know that it’s us that have called it.&lt;/P&gt;
&lt;P&gt;Now I can make a request. If I use a single address, I can just use the Query property of the GeocodeRequest object, as I mentioned earlier. When I get my results from the Geocode() call, I can get multiple lines, and each of them has a bunch of useful information including (as I find most useful), the Formatted Address, and location co-ordinates. I can easily display this by passing the Results into a Select-Object call. I’m just handling the first result of each call, as will become clear in a moment.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;$wsgr.Query = 'Adelaide, Australia'; &lt;BR&gt;$wsr = $ws.Geocode($wsgr); &lt;BR&gt;$wsr.Results[0] | select {$_.Address.FormattedAddress}, {$_.Locations[0].Longitude}, {$_.Locations[0].Latitude};&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As readers familiar with PowerShell will already appreciate, there is a good potential for looping through many addresses. I did this with locations in the world that have &lt;A href="http://www.sqlpass.org/PASSChapters.aspx" target=_blank&gt;PASS chapters&lt;/A&gt; recently, but to simplify this, my example uses just four.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;$uglist = 'Adelaide, AU', 'Aukland, NZ', 'South Africa', 'San Deigo, USA'; &lt;BR&gt;$uglist | % {$wsgr.Query = [string] $_; $wsr = $ws.Geocode($wsgr); $wsr.Results[0] | select {$_.Address.FormattedAddress}, {$_.Locations[0].Longitude}, {$_.Locations[0].Latitude};} &lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This gives the following results:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Consolas&gt;$_.Address.FormattedAddress&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $_.Locations[0].Longitude&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $_.Locations[0].Latitude &lt;BR&gt;---------------------------&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -------------------------&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ------------------------ &lt;BR&gt;Adelaide, Australia&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 138.599731698632&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -34.925769791007 &lt;BR&gt;Auckland, New Zealand&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 174.765734821558&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -36.8473847955465 &lt;BR&gt;South Africa&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 25.0630002468824&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -29.0459994971752 &lt;BR&gt;San Diego, CA&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -117.161724865437&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 32.7156852185726&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;You’ll notice that the FormattedAddress property shows the address in a standard format. This is great, because it will handle spelling mistakes (see how I left the ‘c’ out of ‘Auckland’ when I wrote it – for me I did this on purpose, but in most user-input systems, spelling mistakes are a common problem), and it will provide a consistency for punctuation, abbreviations, etc. Notice that I used ‘AU’, ‘NZ’ and ‘USA’, which were all transformed into something else in the web-service call.&lt;/P&gt;
&lt;P&gt;With the Lat/Long details here, it’s very simple to get this into a database, or a file, or whatever format is required. For me, I put them into a database along with all the other PASS Chapter locations I had looked up (using the public data from the website), and using the Bing Maps Silverlight control, came up with something like this:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://sqlblog.com/blogs/rob_farley/image_0D913253.png"&gt;&lt;IMG style="BORDER-BOTTOM:0px;BORDER-LEFT:0px;DISPLAY:inline;BORDER-TOP:0px;BORDER-RIGHT:0px;" title=image border=0 alt=image src="http://sqlblog.com/blogs/rob_farley/image_thumb_58940748.png" width=596 height=484&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;It was a bit more work to colour the pushpins by the region, and putting tooltips in with extra information, but bridging the gap between a pile of addresses and a map is actually remarkably straight-forward with the Bing Maps API.&lt;/P&gt;</description></item></channel></rss>