Cookie

Cookie consent

We use some essential cookies to make this website work. We'd like to set additional cookies to help us measure your experience when you view and interact with the website.

Cookie policy

Sample code for rooftop geocoding

This page provides sample code to help you set up Postcoder rooftop geocoding.

Copy any example below and then insert your own API key to make it work. Sign up to get an API key.

Rooftop geocoding using JavaScript

This example uses the pafaddressbase and address endpoints to look up addresses and their coordinates in the UK and Ireland. It can be customised using the config settings at the end of the HTML. The UK address lookups use PAF and AddressBase data, and the Irish address lookups use Eircode data.

AddressBase and Eircode:
Enable access on your API key using the Features page or by contacting us.
class PostcoderRooftop{
  
  constructor(config) {
    this.config = config
    this.init()
  }

  init = () => {

    this.endpointGB = 'https://ws.postcoder.com/pcw/' + this.config.apikey + '/pafaddressbase/'
    this.endpointIE = 'https://ws.postcoder.com/pcw/' + this.config.apikey + '/address/ie/'
    this.addresses = {}

    this.addresslines = 4

    this.searchbutton = document.querySelector(this.config.searchbutton)
    this.searchterminput = document.querySelector(this.config.searchterm)
    this.addressselectioncontainer = document.querySelector(this.config.addressselectioncontainer)


    //hide the no result message
    this.noresultmessage = document.querySelector(this.config.noresultmessage)
    this.noresultmessage.style.display = 'none'

    // add an empty container to show the selected address
    this.addresscontainer = document.createElement('div')
    this.addresscontainer.classList.add('address')
    this.addressselectioncontainer.parentNode.insertBefore(this.addresscontainer, this.addressselectioncontainer.nextSibling)

    // create an empty select and place it hidden in the page
    this.select = document.createElement('select')
    this.select.style.display = 'none'
    this.addressselectioncontainer.appendChild(this.select)

    // create and append the top 'select an address' option.
    let option = document.createElement('option')
    option.text = 'Select an address'
    this.select.appendChild(option)

    // add select change event listener to the dropdown
    this.select.addEventListener('change', this.handleSelectChange )

    // add click event listener to the search button, to call the search function
    this.searchbutton.addEventListener('click', this.search)

    // add 'enter' event listener to the search input, to call the search function
    this.searchterminput.addEventListener('keyup', event =>{
      if (event.keyCode === 13) {
        event.preventDefault()
        this.search()
      }
    })

    // initalise an OpenLayers map and marker, on London
    window.onload = (event) => {
  		
    	const london = ol.proj.fromLonLat([-0.12755, 51.507222])

    	this.view = new ol.View({
  			center: london,
  			zoom: 9,
		  })

    	this.map = new ol.Map({
    		target: this.config.mapcontainer,
    		controls: ol.control.defaults({ attribution: false }),
    		layers: [
	      		new ol.layer.Tile({
    	    		source: new ol.source.OSM()
      			})
    		],
    		view: this.view,
  		})

      this.markerlayer = new ol.layer.Vector({
  			source: new ol.source.Vector(),
  				style: new ol.style.Style({
    				image: new ol.style.Icon({
      				anchor: [0.5, 1],
      				src: 'https://postcoder.com/images/svg/map-pin.svg'
    			})
  			})
		  })

		  this.map.addLayer(this.markerlayer)

		  this.marker = new ol.Feature(new ol.geom.Point(london))
		  this.markerlayer.getSource().addFeature(this.marker)

    }
  
  }

  handleSelectChange = event => {

      // check to see if this selection was to load the next page of results
      if( this.select.value.charAt(0) === 'p'){
      
        // search the next page of results
        let page = this.select.value.substring(1)
        this.search(event, page)

      }else{   

        this.selectAddress( this.select.value )

      }     
  }

  search = (event, page = 0) => {

    let searchterm = encodeURIComponent(this.searchterminput.value)

    //hide the no result message
    this.noresultmessage.style.display = 'none'

    // hide the select
    this.select.style.display = 'none'

    //determine the country
    if(typeof this.config.countrycode !== 'undefined' && this.config.countrycode !== ''){
      // defined in config
      var country = this.config.countrycode
    }else{
      // get from dropdown
      var country = document.querySelector(this.config.country).value
    }

    // if page 0, remove any previous options
    if(page === 0){
      while (this.select.options.length > 1) {                
        this.select.remove(1)
      }
    }else{
      // remove the bottom 'next page' option
      this.select.remove(this.select.options.length - 1)
    }

    // different endpoint for GB and IE
    if( country == 'IE'){
    	var url = this.endpointIE + searchterm + '?lines='+this.addresslines + '&addtags=latitude,longitude&exclude=organisation,country&page=' + page
    }else{
    	var url = this.endpointGB + searchterm + '?lines='+this.addresslines + '&exclude=organisation,country&page=' + page
    }
   	

    // fetch the json formatted result from Postcoder and pass it to processResult
    fetch(url)
      .then( response => {
        if (!response.ok) { 
          throw response 
        }
        return response.json()
      })
      .then( json => {
        this.processResult(json)
      })
      .catch( err => {

        if(typeof err.text === 'function'){
          err.text().then( errorMessage => {
            console.log('Postcoder request error ' + err.status + ' : ' + errorMessage)
          })
        }else{
          console.log(err)
        }
    })
    
  }

  processResult = addresses =>{

    this.addresses = addresses

    //if zero results, ask for manual address entry
    if( addresses.length === 0 ){
      
      //show the no result message
      this.noresultmessage.style.display = 'block'

    }
    // if one result, populate the form
    else if(addresses.length === 1){

      this.selectAddress(0)

    }
    // multiple addresses, show drop down to select from
    else{

      // create and append the address options, using the summaryline of the returned addresses
      for (let i = 0; i < addresses.length; i++) {
        let option = document.createElement('option')
        option.value = i
        option.text = addresses[i].summaryline
        this.select.appendChild(option)
      }

      // if there are morevalues, add paging
      if(this.addresses[this.addresses.length - 1]['morevalues'] === 'true'){

        // add a 'load next page' option
        let option = document.createElement('option')
        option.value = 'p' + this.addresses[this.addresses.length - 1]['nextpage']

        // last address contains total number of results, show the user how many are remaining
        let remainingresults = this.addresses[this.addresses.length - 1]['totalresults'] - this.select.options.length + 1

        option.text = 'Load more results, ' + remainingresults + ' of ' + this.addresses[this.addresses.length - 1]['totalresults'] + ' remaining'
        this.select.appendChild(option)

      }
      
      // ensure the select is visible
      this.select.style.display = 'block'

    }

  }

  selectAddress = i =>{

    // get the selected address
    let address = this.addresses[i]

    let fields = ['organisation','addressline1','addressline2','addressline3','addressline4','posttown','county','postcode']

    let displayaddress = ''

    // display the selected adress in the address container
    for (let i = 0; i < fields.length; i++) {
      if(typeof address[fields[i]] !== 'undefined'){
     	
      	displayaddress += address[fields[i]] + '<br>'

      }
     
    }

    this.addresscontainer.innerHTML = displayaddress

    this.showMap( i )

  }


  showMap = i =>{

    // get the selected address
    let address = this.addresses[i]

    if(address.latitude && address.longitude){

    	let position = ol.proj.fromLonLat([address.longitude, address.latitude])

    	this.view.animate({
    		center: position,
    		zoom: 18,
    		duration: 2000,
  		})

    	this.marker.getGeometry().setCoordinates(position)

    }

  }

}
<!doctype html>
<html lang="en">
  <head>
      <link rel="stylesheet" href="postcoder.css" >   
      <script src="postcoder_rooftop.js"></script>
      <!-- using OpenLayers map -->
      <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.9.0/build/ol.js"></script>
  </head>
  <body>

    <form>
            
      <label for="txt_country">Country</label>
      <select id="txt_country">
        <option value="IE">Ireland</option>
        <option value="GB" selected>Great Britian</option>
      </select>


      <label for="txt_search">Search for an address or postcode</label>
      <button type="button" id="btn_search">
          Search
      </button>
      <div class="search_wrap">
          <input id="txt_search" type="search" autocomplete="off" autocapitalize="off" >
      </div>

      <div id="address_selection_container"></div>

      <div id="no_result_message">
          Address not found, please enter manually.
      </div>
      
      <div id="map" class="map"></div>

    </form>


    <script>
        
        new PostcoderRooftop({
            apikey: 'PCW45-12345-12345-1234X', 
            searchterm: '#txt_search', // query selector of the searchterm input field
            addressselectioncontainer: '#address_selection_container', // container for the address selection drop down
            noresultmessage: '#no_result_message',
            country: '#txt_country',  // Country select list; leave blank if not using a country select list 
            countrycode: '', // Hard code if not using a country select list; leave blank otherwise 
            searchbutton: '#btn_search', 
            mapcontainer: 'map' // id for the map container 
        })

    </script>


  </body>
</html>
input,
select {
	display: block;
	box-sizing: border-box;
	width: 100%;
	padding: 10px;
	height: 40px;
	margin-bottom: 0.5em;
	border-width: 1px;
	border-style: solid;
	border-color: lightgray;
}

.search_wrap {
	overflow: hidden;
}

.search_wrap div {
	font-size: 0.75em;
}

button {
	padding: 8px;
	margin-left: 0.5em;
	float: right;
	font-family: sans-serif;
}

label {
	display: block;
	margin-top: 1.25em;
	margin-bottom: 0.25em;
}
select {
	position: relative;
	z-index: 1;
	padding-right: 40px;
}

.isvalid:after {
	content: "\2713";
	color: green;
}

.notvalid:after {
	content: "\2717";
	color: red;
}

#successindicator {
	float: right;
	margin-left: 0.5em;
	display: flex;
	justify-content: center;
	align-content: center;
	flex-direction: column;
	height: 40px;
}

#json_result_container {
	margin: 5em 0 0;
	background-color: #eee;
	color: #333;
	/* border: solid lightgrey 1px; */
	padding: 1em;
	overflow: auto;
}

#autocomplete_wrap {
	position: relative;
}

#suggestion_list {
	position: absolute;
	background-color: #fff;
	outline: -webkit-focus-ring-color auto 1px;
	list-style-type: none;
	margin: 0;
	padding: 0;
	max-height: 400px;
	overflow-y: auto;
}

#suggestion_list li {
	cursor: pointer;
	padding: 10px 5px;
}

#suggestion_list li.header {
	border-bottom: 2px solid #ddd;
}

#suggestion_list li:hover,
#suggestion_list li.selected {
	background-color: #ddd;
}

#suggestion_list li span.extra-info {
	font-size: 0.75em;
	color: #666;
}

.arrow {
	border: solid black;
	border-width: 0 3px 3px 0;
	display: inline-block;
	padding: 3px;
}

.left {
	margin-left: 3px;
	transform: rotate(135deg);
	-webkit-transform: rotate(135deg);
}

.address {
	height: 140px;
	margin: 8px;
}

.map {
	height: 300px;
	width: 100%;
}

body {
	font-family: sans-serif;
	padding: 0;
	margin: 0;
}
Download this example

Rooftop geocoding using Python, PHP or C#

These examples show how to make a request to the pafaddressbase endpoint to look up a UK address and its coordinates.

AddressBase: Enable access on your API key using the Features page or by contacting us.
from urllib.parse import quote
import requests
import json

# Request parameters
api_key = "PCW45-12345-12345-1234X"
search_term = "NR1 4DH"

# Prepare request and encode user-entered parameters with %xx encoding
request_url = f"https://ws.postcoder.com/pcw/{api_key}/pafaddressbase/{quote(search_term, safe='')}"

# Send request
response = requests.get(request_url)

# Process response
if response.status_code == 200:
    json = response.json()
    if len(json) > 0:
        for address in json:
            print(address["summaryline"], address["latitude"], address["longitude"])
    else:
        print("No results")
else:
    print(f"Request error: {response.content.decode()}")
// Request parameters
$api_key = "PCW45-12345-12345-1234X";
$search_term = "NR1 4DH";

// Prepare request and encode user-entered parameters with %xx encoding
$request_url = "https://ws.postcoder.com/pcw/$api_key/pafaddressbase/" . urlencode($search_term);

// Send request
$result = file_get_contents($request_url, false, stream_context_create(["http" => ["ignore_errors" => true]]));

// Process response
$status_line = $http_response_header[0];
preg_match("{HTTP\/\S*\s(\d{3})}", $status_line, $match);
$status_code = $match[1];

if ($status_code == 200) {
    $json = json_decode($result);
    if (count($json) > 0) {
      foreach ($json as $address) {
        echo("$address->summaryline $address->latitude $address->longitude <br>");
      }
    } else {
      echo("No results");
    }
} else {
    echo("Request error");
}
using System;
using System.Threading.Tasks;
using System.Web;
using System.Net.Http;
using Newtonsoft.Json.Linq;
					
public class Program
{
	public static async Task Main()
	{
		// Request parameters
		string apiKey = "PCW45-12345-12345-1234X";
		string searchTerm = "NR1 4DH";

		// Prepare request and encode user-entered parameters with %xx encoding
		string requestUrl = $"https://ws.postcoder.com/pcw/{apiKey}/pafaddressbase/{HttpUtility.UrlEncode(searchTerm)}";

		using (HttpClient client = new HttpClient())
		{
			// Send request
			var response = await client.GetAsync(requestUrl);
			var responseContent = await response.Content.ReadAsStringAsync();

			// Process response
			if (response.IsSuccessStatusCode)
			{
				JArray responseJson = JArray.Parse(responseContent);
				
				if (responseJson.Count > 0)
				{
					foreach (JObject address in responseJson)
					{
						Console.WriteLine($"{address["summaryline"]}, {address["latitude"]}, {address["longitude"]}");	
					}
				}
				else
				{
					Console.WriteLine("No results");
				}
			}
			else
			{
				Console.WriteLine($"Request error: {responseContent}");
			}
		}
	}
}