Finding a new home for our FPV drone racing club by mining Scotland’s open land data.
We’re a registered charity and a recognised sport, with full BMFA membership and public liability insurance. We currently fly on a football-pitch-sized plot at Craufurdland Castle near Fenwick (East Ayrshire), and we’re looking for a site in and around Glasgow that the club can grow into.
This repo takes the Scottish Vacant and Derelict Land Survey (SVDLS) — a national record of vacant and derelict land — and filters it down to realistic, council-owned candidate sites, then ranks them for how well they’d suit a drone racing course.
As a registered charity and recognised sport, we can make a credible case to a local authority for recreational use of land they’re not developing. So we filter to council-owned sites and favour land the council has no active plans to build on — that means both more secure tenure for us and an easier ask of them.
A good FPV racing site is:
We use GitHub Issues to track which sites we’ve approached and where each conversation stands — one issue per site. Each issue carries the site’s satellite view, its member-travel report (how far each of us drives to it vs the castle now, and the average), and the Community Asset Transfer contact for the relevant council — the statutory route for a charity to take on council land. See docs/outreach-tracking.md for how it works.
Add your postcode to data/members.md (postcode only — no
names). We geocode it (postcodes.io) and get real driving distance/time (OSRM),
both free and keyless, comparing every site against the current base at
Craufurdland Castle. After adding members, refresh the issues with
./scripts/backfill_issues.sh.
Sites with a home within 50 m of the (approximate) edge are omitted from the
shortlist entirely — a hard filter, listed in outputs/excluded_by_housing.csv.
The screen also appears on each issue: real building footprints from
OpenStreetMap, the nearest home to the site, and an annotated map showing the
site’s approximate extent and a separation line. Two honest limits:
--gap, e.g.
python3 analysis/site_proximity.py --code <code> --gap 150 --print.Pure Python 3, no dependencies to install.
python3 analysis/find_sites.py
This reads data/Vacant_and_Derelict_Land_-_Scotland.csv and regenerates
everything in outputs/.
| File | What it does |
|---|---|
analysis/find_sites.py |
Filters, scores and ranks the sites. All the tunable knobs (region, size band, scoring weights) are at the top. |
analysis/osgb.py |
Converts the survey’s OS grid references to WGS84 lat/long for map links. |
analysis/fetch_satellite.py |
Downloads & annotates a satellite view per shortlisted site. Needs requests + Pillow (pip install -r requirements.txt). |
analysis/members.py |
Member-travel report for a site (geocoding + driving times). Needs requests. |
analysis/site_proximity.py |
Housing-proximity screen + annotated map (OpenStreetMap buildings). Needs requests + Pillow. |
analysis/housing.py |
Sweeps every candidate for the nearest home, caching to housing_screen.json (feeds the hard filter). Needs requests. |
analysis/basemap.py |
Shared satellite-tile fetching and lat/lon↔pixel maths. |
analysis/issue_body.py |
Assembles a site issue’s full Markdown body (single source of truth). |
Each site gets a score from five factors — site type, the council’s development
intentions, the previous use, size, and member proximity (up to +4 for being
close to members’ postcodes). The exact weights live at the top of
analysis/find_sites.py; edit them and re-run to re-rank. Higher is better.
Proximity is read from outputs/member_locations.json. After editing
data/members.md, regenerate it and re-score:
python3 analysis/members.py --dump # geocode members -> member_locations.json
python3 analysis/find_sites.py # re-score with the new members
./scripts/backfill_issues.sh # update the open issues' scores + travel
The housing hard-filter reads outputs/housing_screen.json, built once by a
sweep over all candidates (cached, so re-runs are cheap):
python3 analysis/housing.py --build # screen every candidate for nearby homes
python3 analysis/find_sites.py # re-rank, omitting homes-within-50m sites
To use a different separation (e.g. the 150 m A3 figure), change HOUSING_GAP_M
at the top of find_sites.py and re-run it — no re-sweep needed (distances are
cached out to ~175 m).
Source data: Scottish Vacant and Derelict Land Survey, published under the Open Government Licence v3.0. Our analysis code in this repo is released under the MIT Licence (see LICENSE).