So i’ve been busy beavering away on the myDistrict project I’m developing for Stratford-on-Avon District Council, and part of this project is to retrieve various datasets from numerous API’s to enable the Stratford residents to get all their local information in one place.

The basics are there, and we’ll be gathering the residents geo information when they register (or upgrade their existing website account) so we are able to query all these fantastic datasets from www.data.gov.uk and more.

A bit stuck at first, I asked the Open Data guru from Lichfield District CouncilStuart Harrison, for some pointers. Stuart was very kind as to email through some sample code and links to blogs which reference the calls needed to access and unleash the data.

I thought I’d share some of this with you all, do with it what you will!

A few sample snippets are below, but you’ll need to replace some parts (especially the local authority district reference eg 44UE) with your own data to get accurate results.

You can find your ‘id’ number by having a look through the data.gov.uk lists here. This is the Warwickshire County starting point, you’ll need to go up a level to country and search that way. It’s a bit fiddly! Once you’re in the right county, you’ll need to look for local authority district. If I find a better way, I’ll update this post!

UPDATE: Stuart Harrison has kindly written a nice service to allow you to search for your council ID (or SNAC ID for the technical amongst you).

So, starting on the UK Government SPARQL form input page, you can start to play with the various options to tailor your results accordingly.

To call back all the schools in your local authority (in this case, Stratford):

prefix sch-ont:  <http://education.data.gov.uk/def/school/>

SELECT ?name  ?reference  WHERE {
?school a sch-ont:School;
sch-ont:establishmentName ?name;
sch-ont:uniqueReferenceNumber ?reference ;
sch-ont:districtAdministrative

<http://statistics.data.gov.uk/id/local-authority-district/44UE> .

}

ORDER BY ?name

To filter by primary school you can add an extra couple of lines:

prefix sch-ont:  <http://education.data.gov.uk/def/school/>

SELECT ?name  ?reference  WHERE {
?school a sch-ont:School;
sch-ont:establishmentName ?name;
sch-ont:uniqueReferenceNumber ?reference ;
sch-ont:districtAdministrative

<http://statistics.data.gov.uk/id/local-authority-district/44UE>  ;

sch-ont:uniqueReferenceNumber ?reference ; sch-ont:phaseOfEducation <http://education.data.gov.uk/def/school/PhaseOfEducation_Primary> .

}

ORDER BY ?name

And to filter just secondary schools, you can make a small change also:

prefix sch-ont:  <http://education.data.gov.uk/def/school/>

SELECT ?name  ?reference  WHERE {
?school a sch-ont:School;
sch-ont:establishmentName ?name;
sch-ont:uniqueReferenceNumber ?reference ;
sch-ont:districtAdministrative

<http://statistics.data.gov.uk/id/local-authority-district/44UE>  ;

sch-ont:uniqueReferenceNumber ?reference ; sch-ont:phaseOfEducation <http://education.data.gov.uk/def/school/PhaseOfEducation_Secondary> .

}

ORDER BY ?name

You could also pull back which schools have nurseries attached, very handy!

prefix sch-ont: <http://education.data.gov.uk/def/school/>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT ?name WHERE {
?school a sch-ont:School;
sch-ont:establishmentName ?name;
sch-ont:districtAdministrative <http://statistics.data.gov.uk/id/local-authority-district/44UE> ;

sch-ont:nurseryProvision “true”^^xsd:boolean ;

}

ORDER BY ?name

Or you could pull back all the nursery schools available across the whole county. Just by tweaking a couple of search parameters:

prefix sch-ont: <http://education.data.gov.uk/def/school/>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT ?name WHERE {
?school a sch-ont:School;
sch-ont:establishmentName ?name;
sch-ont:localAuthority <http://statistics.data.gov.uk/id/local-education-authority/937> ;

sch-ont:nurseryProvision “true”^^xsd:boolean ;

}

ORDER BY ?name

And then, if you want to get really flash, you can return the 5 closest primary schools to your location. In this example, using easting & northing data and adding address data to the mix as well:

prefix sch-ont: <http://education.data.gov.uk/def/school/>
prefix space: <http://data.ordnancesurvey.co.uk/ontology/spatialrelations/>

SELECT ?name ?address1 ?address2 ?town ?postcode ?easting ?northing ?reference ?WebsiteAddress ?SCUpreferredemail

WHERE { ?school a sch-ont:School ; sch-ont:districtAdministrative

<http://statistics.data.gov.uk/id/local-authority-district/44UE> ;
sch-ont:establishmentName ?name;
sch-ont:uniqueReferenceNumber ?reference ;
space:easting ?easting ;
space:northing ?northing ;

sch-ont:uniqueReferenceNumber ?reference ; sch-ont:phaseOfEducation

<http://education.data.gov.uk/def/school/PhaseOfEducation_Primary> .

OPTIONAL {

?school sch-ont:address ?address .
?address sch-ont:address1 ?address1 ;
sch-ont:address2 ?address2 ;
sch-ont:town ?town ;
sch-ont:postcode ?postcode .

}

OPTIONAL {
?school sch-ont:WebsiteAddress ?WebsiteAddress ;

}

OPTIONAL {

?school sch-ont:SCUpreferredemail ?SCUpreferredemail ;

}

}

ORDER BY ASC(

((419997 – ?easting)* ( 419997 – ?easting))
+ ((254702 – ?northing)* ( 254702 – ?northing))

)
LIMIT 5
OFFSET 0

And this one, using longitude and latitude data:

prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
prefix sch-ont:  <http://education.data.gov.uk/def/school/>
SELECT ?name ?address1 ?address2 ?town ?postcode ?lat ?long ?reference ?WebsiteAddress ?SCUpreferredemail
WHERE {
?school a sch-ont:School;
sch-ont:establishmentName ?name;
sch-ont:districtAdministrative
<http://statistics.data.gov.uk/id/local-authority-district/44UE> ;
sch-ont:phaseOfEducation <http://education.data.gov.uk/def/school/PhaseOfEducation_Primary>;
sch-ont:uniqueReferenceNumber ?reference ;
geo:lat ?lat;
geo:long ?long.
OPTIONAL {
?school sch-ont:address ?address .
?address sch-ont:address1 ?address1 ;
sch-ont:address2 ?address2 ;
sch-ont:town ?town ;
sch-ont:postcode ?postcode .
}
OPTIONAL {
?school sch-ont:WebsiteAddress ?WebsiteAddress ;
}
OPTIONAL {
?school sch-ont:SCUpreferredemail ?SCUpreferredemail ;
}
}
ORDER BY ASC(
((52.190200973202 – ?lat)* ( 52.190200973202 – ?lat))
+ ((-1.7088976710252 – ?long)* ( -1.7088976710252 – ?long))
)
LIMIT 5
OFFSET 0

This is really just touching the surface, I’ve got oodles of examples, far too many to post here.

If you have any questions, feel free to email me and I can help out where possible!