PowerShell Geocoding Tutorial

This is a tutorial for using the OpenCage geocoding API in PowerShell.

Topics covered in this tutorial

Background

The code examples below will use your geocoding API key once you log in.

Before we dive in to the tutorial

  1. Sign up for an OpenCage geocoding API key.
  2. Play with the demo page, so that you see the actual response the API returns.
  3. Browse the API reference, so you understand the optional parameters, best practices, possible response codes, and the rate limiting on free trial accounts.

Requirements

Tested with PowerShell 7. You might need to add the System.Web assembly. It's usually available if you have the .NET framework installed:

Add-Type -AssemblyName System.Web

Geocode one address in PowerShell

$apiKey = "YOUR-API-KEY"
$address = "Philipsbornstraße 2, 30165 Hanover, Germany"

# Generate request URL
$params = @{ key = $apiKey; q = $address; limit = 1 }

$queryString = ($params.GetEnumerator() | ForEach-Object { "$($_.Key)=$([System.Web.HttpUtility]::UrlEncode($_.Value))" }) -join "&"

$fullUrl = "https://api.opencagedata.com/geocode/v1/json?${queryString}"

# HTTP API request and parse JSON response
$response = Invoke-RestMethod -Method Get -Uri $fullUrl

if ($response.results.Count -gt 0) {
    $lat    = $response.results[0].geometry.lat
    $lng    = $response.results[0].geometry.lng
    $tzname = $response.results[0].annotations.timezone.name

    Write-Output "Latitude: $lat, Longitude: $lng, Timezone: $tzname"
} else {
    Write-Host "No results found."
}

# Latitude: 52.387783, Longitude: 9.7334394, Timezone: Europe/Berlin

Geocoding a CSV file of coordinates

A more advanced example including error handling and parsing and printing CSV.

Create a file coordinates.csv
latitude,longitude
43.2915,5.37101
48.15154,17.09895
51.5074,-0.1278

$apiKey = "YOUR-API-KEY"

$csvData = Import-Csv -Path "coordinates.csv"

# Process line by line
foreach ($row in $csvData) {
    $lat = $row.latitude
    $lng = $row.longitude

    # Generate request URL
    $params = @{
        key   = $apiKey
        q     = "$lat,$lng"
    }
    $queryString = ($params.GetEnumerator() | ForEach-Object { "$($_.Key)=$([System.Web.HttpUtility]::UrlEncode($_.Value))" }) -join "&"

    $fullUrl = "https://api.opencagedata.com/geocode/v1/json?${queryString}"

     # HTTP API request and parse JSON response
    try {
        $response = Invoke-RestMethod -Method Get -Uri $fullUrl
    }
    catch {
        Write-Host "$($_.Exception.Message)" -ForegroundColor Red
        continue
    }

    if ($response.results.Count -gt 0) {
        $country_code = $response.results[0].components.country_code
        $country = $response.results[0].components.country
        $address = $response.results[0].formatted

        # Note: the address could contain " which would make the CSV invalid
        Write-Output "$lat,$lng,$country_code,$country,$timezone,`"$address`""
    } else {
        $message = $response.status.message
        if ($message -eq 'OK') {
            Write-Host "${lat},${lng},No results found."
        } else {
            Write-Host "${lat},${lng},Error - $message"
        }
    }
}

The script output will be:
43.2915,5.37101,fr,France,Europe/London,"81 Rue Sainte, 13007 Marseille, France"
48.15154,17.09895,sk,Slovakia,Europe/London,"Mišíkova 1111/9, 811 04 Bratislava, Slovakia"
51.5074,-0.1278,gb,United Kingdom,Europe/London,"Charing Cross, London, SW1A 2DX, United Kingdom"

Start your free trial

2,500 geocoding API requests per day.

No credit card required.