Ordnance Survey Linked Data – Combining postcode and spatial queries
In my previous blog posts (here, here and here) I concentrated on a few simple SPARQL queries. However, these SPARQL queries were only performed on one dataset at a time. With linked data things get more interesting when you combine datasets (even if those datasets are both from the same publisher). The original opendata for Code-Point(R) Open was published as a CSV file, and Boundary-Line(TM) was published as a shape file. Both formats are useful, but combining the two datasets can be tricky if you are not sure how to use shape files. The two datasets are, however, implicitly linked via a key. In the linked data versions we have converted both datasets into a common data language (RDF) and made those implicit links explicit (see https://johngoodwin225.wordpress.com/2013/08/05/ordnance-survey-linked-data-a-simple-postcode-query/ ). We can now easily query both datasets together.
To query both datasets go to the SPARQL endpoint for the combined data:
http://data.ordnancesurvey.co.uk/datasets/os-linked-data/explorer/sparql
Recall that the query:
select ?postcode ?lat ?long
where
{
?x <http://www.w3.org/2000/01/rdf-schema#label> ?postcode .
?x <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat .
?x <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?long .
?x <http://data.ordnancesurvey.co.uk/ontology/postcode/ward>
<http://data.ordnancesurvey.co.uk/id/7000000000017707> .
}
finds all of the postcodes (and their lat/long) in a ward called Bevois. Using the combined datasets we can run queries like: find me all postcodes in the ward Bevois and all the wards touching Bevois. Let’s break this down. To find all postcodes (and their lat/long) in regions that touch Bevois first find all the wards that touch Bevois, and then find all the postcodes within those wards. So the first line in the query below “?y <http://data.ordnancesurvey.co.uk/ontology/spatialrelations/touches> <http://data.ordnancesurvey.co.uk/id/7000000000017707>” finds all wards touching Bevois, and the rest of the query matches postcodes in the wards “?y”:
select ?postcode ?lat ?long
where
{
?y <http://data.ordnancesurvey.co.uk/ontology/spatialrelations/touches>
<http://data.ordnancesurvey.co.uk/id/7000000000017707> .
?x <http://www.w3.org/2000/01/rdf-schema#label> ?postcode .
?x <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat .
?x <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?long .
?x <http://data.ordnancesurvey.co.uk/ontology/postcode/ward> ?y .
}
To find all the postcodes in Bevois and the wards touching Bevois we simply union the two queries above together:
select ?postcode ?lat ?long
where
{{
?x <http://www.w3.org/2000/01/rdf-schema#label> ?postcode .
?x <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat .
?x <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?long .
?x <http://data.ordnancesurvey.co.uk/ontology/postcode/ward>
<http://data.ordnancesurvey.co.uk/id/7000000000017707> .
}
UNION
{
?y <http://data.ordnancesurvey.co.uk/ontology/spatialrelations/touches>
<http://data.ordnancesurvey.co.uk/id/7000000000017707> .
?x <http://www.w3.org/2000/01/rdf-schema#label> ?postcode .
?x <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat .
?x <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?long .
?x <http://data.ordnancesurvey.co.uk/ontology/postcode/ward> ?y .
}}
As an exercise for the reader – find all postcodes in Southampton and districts touching Southampton. Happy SPARQLing…