Geocoding: Text Scanning (Part 4)

Geocoding can automatically extract geolocations from text. This example also shows a new way of submitting information to a server: in the example below, data is posted to the server using the same mechanism that is used in HTML forms. This is typically done to avoid having to URL-encode large amounts of data because when POST is used, the data travels in the header of the request, not the URL. This also allows more data to be sent:

'Ma io stasera volevo cenare al lume di candela, non cucinarci! #Milano #blackout' |
  ForEach-Object -Begin {$url='https://geocode.xyz'
    $null = Invoke-RestMethod $url -S session
  } -Process {
    Invoke-RestMethod $url -W $session -Method Post -Body @{scantext=$_;geoit='json'}

  }

The result looks similar to this:

 
longt   matches match                                                                                      
-----   ------- -----                                                                                      
9.18067 1       {@{longt=9.18067; location=MILANO,IT; matchtype=locality; confidence=0.9; MentionIndices...
 

Twitter This Tip! ReTweet this Tip!

Geocoding: Converting Addresses to Lat/Long (Part 2)

Let’s start with translating addresses into latitude and longitude coordinates. We assume you read the previous parts to fully understand the code sample.

Here is some sample code that takes any number of addresses, and returns their latitude and longitude for you:

'One Microsoft Way, Redmond',
'Bahnhofstrasse 12, Hannover, Germany' |
  ForEach-Object -Begin {$url = 'https://geocode.xyz'
    $null = Invoke-RestMethod $url -S session
  } -Process {
    $address = $_
    $encoded = [Net.WebUtility]::UrlEncode($address)
    Invoke-RestMethod "$url/${encoded}?json=1" -W $session|
      ForEach-Object {
        [PSCustomObject]@{
          Address = $address
          Long = $_.longt
          Lat = $_.latt
        }
      }
  }

The result looks similar to this:

 
Address                              Long       Lat     
-------                              ----       ---     
One Microsoft Way, Redmond           -122.13061 47.64373
Bahnhofstrasse 12, Hannover, Germany 9.75195    52.37799 
 

Twitter This Tip! ReTweet this Tip!

Working with GeoCoding (Part 1)

Last year, Google changed their terms and requires an individual API key now to use their geocode API. Fortunately, there are free alternatives, so in this mini series we’d like to show you what can be done with PowerShell to handle addresses and coordinates.

All of this requires REST API calls, so whatever information you want to send to the REST API, it needs to be encoded in a way that can be sent as part of a web URL.

Let’s first focus on how text can be encoded to be part of REST API calls:

$address = 'Bahnhofstrasse 12, Hannover'
$encoded = [Net.WebUtility]::UrlEncode($address)
$encoded

When you look at the result, you can easily see that a number of modifications were made:

 
Bahnhofstrasse+12%2C+Hannover 
 

Twitter This Tip! ReTweet this Tip!

Using Session Variables in Web Requests

Sometimes, web requests that work fine in a browser do not seem to work well in PowerShell. For example, when you navigate to http://www.geocode.xyz/Bahnhofstrasse,Hannover?json=1 in a browser, you get back the coordinates of that address in JSON format.

When you try the same within PowerShell, you get back awkward exceptions:

$url = 'http://www.geocode.xyz/Bahnhofstrasse,Hannover?json=1'
Invoke-RestMethod -Uri $url

The result is:

 
Invoke-RestMethod : { "success": false, "error": { "code": "006", "message": "Request Throttled." } }
 

The secret here is to get the session state first which includes the cookies and other details, then repeat the actual web service request with the session state. Here is how it works:

$url = 'http://www.geocode.xyz'
$urlLocation = "$url/Bahnhofstrasse,Hannover?json=1"

$null = Invoke-RestMethod -Uri $url -SessionVariable session
Invoke-RestMethod -Uri $urlLocation -WebSession $session

Now the result looks right:

 
standard  : @{stnumber=1; addresst=Bahnhofstrasse; postal=30159; region=DE; prov=DE; city=Hannover; 
            countryname=Germany; confidence=0.8}
longt     : 9.73885
alt       : 
elevation : 
latt      : 52.37418  
 

Twitter This Tip! ReTweet this Tip!

Left Side of Comparison

When using comparison operators, always make sure the relevant part is placed left. That’s because PowerShell looks at the left side of an operator and may automatically change types of the right side. Also, comparison operators may work as filters when there is an array on the left side.

Check out the differences:

$array = @()

'-'* 80
$array -eq $null
'-'* 80
$null -eq $array
'-'* 80

Since you are comparing an array, the comparison operator works like a filter and returns nothing in the first comparison. When you swap operands, it returns $false which is the right answer: an array, even an empty array, is not null.


Twitter This Tip! ReTweet this Tip!