# import libraries
import os
from zipfile import ZipFile
import fiona
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
# configure plot styles
plt.style.use("Solarize_Light2")
plt.rcParams["font.family"] = "Source Sans Pro"
plt.rcParams["figure.dpi"] = 96
plt.rcParams["axes.grid"] = False
plt.rcParams["text.color"] = "darkslategrey"
plt.rcParams["axes.labelcolor"] = "darkslategrey"
plt.rcParams["xtick.labelcolor"] = "darkslategrey"
plt.rcParams["ytick.labelcolor"] = "darkslategrey"
plt.rcParams["figure.titleweight"] = "semibold"
plt.rcParams["axes.titleweight"] = "semibold"
plt.rcParams["figure.titlesize"] = "13"
plt.rcParams["axes.titlesize"] = "12"
plt.rcParams["axes.labelsize"] = "10"
BASE2 = "#eee8d5"
BASE3 = "#fdf6e3"
# define data directories
BASE_PATH = os.path.join("data", "raw", "vector")
OUT_PATH = os.path.join("data", "vector")
# Boundary-Line
scotland = gpd.read_file(
os.path.join(OUT_PATH, "boundaries.gpkg"),
layer="os_bdline_scotland"
)
w_isles = gpd.read_file(
os.path.join(OUT_PATH, "boundaries.gpkg"),
layer="os_bdline_westernisles_const"
)
FILE_NAME = os.path.join(BASE_PATH, "os_bng", "os_bng_grids.gpkg")
layers = fiona.listlayers(FILE_NAME)
layers
['100km_grid', '50km_grid', '20km_grid', '10km_grid', '5km_grid', '1km_grid']
bng = {}
for layer in layers:
bng[layer] = gpd.read_file(FILE_NAME, layer=layer, bbox=scotland)
bng["100km_grid"].head(5)
tile_name | geometry | |
---|---|---|
0 | NQ | POLYGON ((0.000 600000.000, 100000.000 600000.... |
1 | NR | POLYGON ((100000.000 600000.000, 200000.000 60... |
2 | NS | POLYGON ((200000.000 600000.000, 300000.000 60... |
3 | NT | POLYGON ((300000.000 600000.000, 400000.000 60... |
4 | NU | POLYGON ((400000.000 600000.000, 500000.000 60... |
bng["50km_grid"].head(5)
tile_name | geometry | |
---|---|---|
0 | NYSW | POLYGON ((300000.000 500000.000, 350000.000 50... |
1 | NXSW | POLYGON ((200000.000 500000.000, 250000.000 50... |
2 | NXSE | POLYGON ((250000.000 500000.000, 300000.000 50... |
3 | NYNW | POLYGON ((300000.000 550000.000, 350000.000 55... |
4 | NXNW | POLYGON ((200000.000 550000.000, 250000.000 55... |
bng["20km_grid"].head(5)
tile_name | geometry | |
---|---|---|
0 | NV02 | POLYGON ((0.000 520000.000, 20000.000 520000.0... |
1 | NV22 | POLYGON ((20000.000 520000.000, 40000.000 5200... |
2 | NV42 | POLYGON ((40000.000 520000.000, 60000.000 5200... |
3 | NV62 | POLYGON ((60000.000 520000.000, 80000.000 5200... |
4 | NV82 | POLYGON ((80000.000 520000.000, 100000.000 520... |
bng["10km_grid"].head(5)
tile_name | geometry | |
---|---|---|
0 | HS29 | POLYGON ((220000.000 1190000.000, 230000.000 1... |
1 | HS39 | POLYGON ((230000.000 1190000.000, 240000.000 1... |
2 | HS49 | POLYGON ((240000.000 1190000.000, 250000.000 1... |
3 | HS59 | POLYGON ((250000.000 1190000.000, 260000.000 1... |
4 | HS69 | POLYGON ((260000.000 1190000.000, 270000.000 1... |
bng["5km_grid"].head(5)
tile_name | 1km_grid_ref | geometry | |
---|---|---|---|
0 | HV80NE | HV8505 | POLYGON ((85000.000 1005000.000, 90000.000 100... |
1 | HV80NW | HV8005 | POLYGON ((80000.000 1005000.000, 85000.000 100... |
2 | HV80SE | HV8500 | POLYGON ((85000.000 1000000.000, 90000.000 100... |
3 | HV80SW | HV8000 | POLYGON ((80000.000 1000000.000, 85000.000 100... |
4 | HV81NE | HV8515 | POLYGON ((85000.000 1015000.000, 90000.000 101... |
bng["1km_grid"].head(5)
tile_name | geometry | |
---|---|---|
0 | HN1718 | POLYGON ((217000.000 1218000.000, 218000.000 1... |
1 | HN1719 | POLYGON ((217000.000 1219000.000, 218000.000 1... |
2 | HN1720 | POLYGON ((217000.000 1220000.000, 218000.000 1... |
3 | HN1717 | POLYGON ((217000.000 1217000.000, 218000.000 1... |
4 | HN1716 | POLYGON ((217000.000 1216000.000, 218000.000 1... |
bng["5km_grid"].crs
<Derived Projected CRS: EPSG:27700> Name: OSGB36 / British National Grid Axis Info [cartesian]: - E[east]: Easting (metre) - N[north]: Northing (metre) Area of Use: - name: United Kingdom (UK) - offshore to boundary of UKCS within 49°45'N to 61°N and 9°W to 2°E; onshore Great Britain (England, Wales and Scotland). Isle of Man onshore. - bounds: (-9.0, 49.75, 2.01, 61.01) Coordinate Operation: - name: British National Grid - method: Transverse Mercator Datum: Ordnance Survey of Great Britain 1936 - Ellipsoid: Airy 1830 - Prime Meridian: Greenwich
fig, (axa, axb, axc) = plt.subplots(
nrows=3, ncols=2, sharex=True, sharey=True, figsize=(8, 12.5)
)
fig.suptitle("OS BNG grids - Isle of Lewis")
fig.supxlabel("Easting (m)")
fig.supylabel("Northing (m)")
axes = [axa[0], axa[1], axb[0], axb[1], axc[0], axc[1]]
for num, layer in zip(axes, layers):
w_isles.plot(color=BASE3, ax=num)
bng[layer].boundary.plot(ax=num, color="crimson", linewidth=1.5)
w_isles.boundary.plot(ax=num, color="darkslategrey", linewidth=.55)
num.set_title(layer)
num.set_aspect("equal", "box")
axc[0].text(
9e4, 8.875e5,
"Contains OS data \n© Crown copyright and database right 2021"
)
plt.xlim(9e4, 1.6e5)
plt.ylim(9e5, 9.7e5)
plt.ticklabel_format(axis="x", style="sci", scilimits=(0, 0))
plt.tight_layout()
plt.show()
base = w_isles.plot(color=BASE3, figsize=(7.5, 7.5))
w_isles.boundary.plot(ax=base, color="darkslategrey", linewidth=.4)
bng["20km_grid"].boundary.plot(ax=base, color="crimson")
map_labels = zip(
zip(bng["20km_grid"].centroid.x-2500, bng["20km_grid"].centroid.y),
bng["20km_grid"]["tile_name"]
)
for xy, lab in map_labels:
base.annotate(
text=lab, xy=xy, textcoords="data", size=12,
weight="semibold", backgroundcolor=BASE2
)
plt.title("OS 20 km BNG - Isle of Lewis")
plt.xlabel("Easting (m)")
plt.ylabel("Northing (m)")
plt.text(
8.1e4, 9.016e5,
"Contains OS data © Crown copyright and database right 2021",
backgroundcolor=BASE2
)
plt.xlim(8e4, 1.6e5)
plt.ylim(9e5, 9.8e5)
base.set_aspect("equal", "box")
plt.show()
ZIP_FILE = os.path.join(BASE_PATH, "os_opennames", "data.zip")
archive = ZipFile(ZIP_FILE, "r")
files = [
name for name in archive.namelist() if "NA8" in name or "NB" in name and
name.endswith(".csv")
]
files
['Data/NA80.csv', 'Data/NA82.csv', 'Data/NB00.csv', 'Data/NB02.csv', 'Data/NB04.csv', 'Data/NB20.csv', 'Data/NB22.csv', 'Data/NB24.csv', 'Data/NB40.csv', 'Data/NB42.csv', 'Data/NB44.csv', 'Data/NB46.csv', 'Data/NB80.csv']
files = files[:-1]
len(files)
12
headers = gpd.read_file(
"zip://" + ZIP_FILE + "!" +
os.path.join("Docs", "OS_Open_Names_Header.csv")
)
headers
ID | NAMES_URI | NAME1 | NAME1_LANG | NAME2 | NAME2_LANG | TYPE | LOCAL_TYPE | GEOMETRY_X | GEOMETRY_Y | ... | COUNTY_UNITARY_URI | COUNTY_UNITARY_TYPE | REGION | REGION_URI | COUNTRY | COUNTRY_URI | RELATED_SPATIAL_OBJECT | SAME_AS_DBPEDIA | SAME_AS_GEONAMES | geometry |
---|
0 rows × 35 columns
opennames = pd.DataFrame()
for layer in files:
names = gpd.read_file("zip://" + ZIP_FILE + "!" + layer)
opennames = pd.concat([opennames, names])
opennames.columns = list(headers)
opennames.head(5)
ID | NAMES_URI | NAME1 | NAME1_LANG | NAME2 | NAME2_LANG | TYPE | LOCAL_TYPE | GEOMETRY_X | GEOMETRY_Y | ... | COUNTY_UNITARY_URI | COUNTY_UNITARY_TYPE | REGION | REGION_URI | COUNTRY | COUNTRY_URI | RELATED_SPATIAL_OBJECT | SAME_AS_DBPEDIA | SAME_AS_GEONAMES | geometry | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | osgb4000000074547317 | http://data.ordnancesurvey.co.uk/id/4000000074... | Hushinish | eng | Huisinis | gla | populatedPlace | Hamlet | 98978 | 912041 | ... | http://data.ordnancesurvey.co.uk/id/7000000000... | http://data.ordnancesurvey.co.uk/ontology/admi... | Scotland | http://data.ordnancesurvey.co.uk/id/7000000000... | Scotland | http://data.ordnancesurvey.co.uk/id/country/sc... | None | |||
1 | HS33AX | http://data.ordnancesurvey.co.uk/id/postcodeun... | HS3 3AX | other | Postcode | 99831 | 911236 | ... | http://data.ordnancesurvey.co.uk/id/7000000000... | http://data.ordnancesurvey.co.uk/ontology/admi... | Scotland | http://data.ordnancesurvey.co.uk/id/7000000000... | Scotland | http://data.ordnancesurvey.co.uk/id/country/sc... | None | ||||||
2 | HS33AY | http://data.ordnancesurvey.co.uk/id/postcodeun... | HS3 3AY | other | Postcode | 98971 | 912016 | ... | http://data.ordnancesurvey.co.uk/id/7000000000... | http://data.ordnancesurvey.co.uk/ontology/admi... | Scotland | http://data.ordnancesurvey.co.uk/id/7000000000... | Scotland | http://data.ordnancesurvey.co.uk/id/country/sc... | None | ||||||
3 | osgb4000000074774250 | http://data.ordnancesurvey.co.uk/id/4000000074... | Sròn Udemul | landform | Other Landform | 96316 | 915675 | ... | http://data.ordnancesurvey.co.uk/id/7000000000... | http://data.ordnancesurvey.co.uk/ontology/admi... | Scotland | http://data.ordnancesurvey.co.uk/id/7000000000... | Scotland | http://data.ordnancesurvey.co.uk/id/country/sc... | None | ||||||
4 | osgb4000000074787751 | http://data.ordnancesurvey.co.uk/id/4000000074... | Vanna-gya | hydrography | Tidal Water | 99043 | 900816 | ... | http://data.ordnancesurvey.co.uk/id/7000000000... | http://data.ordnancesurvey.co.uk/ontology/admi... | Scotland | http://data.ordnancesurvey.co.uk/id/7000000000... | Scotland | http://data.ordnancesurvey.co.uk/id/country/sc... | None |
5 rows × 35 columns
list(opennames)
['ID', 'NAMES_URI', 'NAME1', 'NAME1_LANG', 'NAME2', 'NAME2_LANG', 'TYPE', 'LOCAL_TYPE', 'GEOMETRY_X', 'GEOMETRY_Y', 'MOST_DETAIL_VIEW_RES', 'LEAST_DETAIL_VIEW_RES', 'MBR_XMIN', 'MBR_YMIN', 'MBR_XMAX', 'MBR_YMAX', 'POSTCODE_DISTRICT', 'POSTCODE_DISTRICT_URI', 'POPULATED_PLACE', 'POPULATED_PLACE_URI', 'POPULATED_PLACE_TYPE', 'DISTRICT_BOROUGH', 'DISTRICT_BOROUGH_URI', 'DISTRICT_BOROUGH_TYPE', 'COUNTY_UNITARY', 'COUNTY_UNITARY_URI', 'COUNTY_UNITARY_TYPE', 'REGION', 'REGION_URI', 'COUNTRY', 'COUNTRY_URI', 'RELATED_SPATIAL_OBJECT', 'SAME_AS_DBPEDIA', 'SAME_AS_GEONAMES', 'geometry']
opennames.shape
(6964, 35)
# well known text with point data
opennames["wkt"] = (
"POINT (" + opennames["GEOMETRY_X"].astype(str) + " " +
opennames["GEOMETRY_Y"].astype(str) + ")"
)
opennames = gpd.GeoDataFrame(
opennames,
geometry=gpd.GeoSeries.from_wkt(opennames["wkt"]),
crs="EPSG:27700"
)
opennames = opennames.drop(columns=["wkt"])
opennames.crs
<Derived Projected CRS: EPSG:27700> Name: OSGB36 / British National Grid Axis Info [cartesian]: - E[east]: Easting (metre) - N[north]: Northing (metre) Area of Use: - name: United Kingdom (UK) - offshore to boundary of UKCS within 49°45'N to 61°N and 9°W to 2°E; onshore Great Britain (England, Wales and Scotland). Isle of Man onshore. - bounds: (-9.0, 49.75, 2.01, 61.01) Coordinate Operation: - name: British National Grid - method: Transverse Mercator Datum: Ordnance Survey of Great Britain 1936 - Ellipsoid: Airy 1830 - Prime Meridian: Greenwich
base = w_isles.plot(color=BASE3, figsize=(7.5, 7.5))
w_isles.boundary.plot(ax=base, color="darkslategrey", linewidth=.4)
opennames.plot(ax=base, color="royalblue", markersize=1)
bng["20km_grid"].boundary.plot(ax=base, color="crimson")
plt.title("OS Open Names data points - Isle of Lewis")
plt.xlabel("Easting (m)")
plt.ylabel("Northing (m)")
plt.text(
8.125e4, 8.963e5,
"Contains OS data © Crown copyright and database right 2021",
backgroundcolor=BASE2
)
plt.xlim(8e4, 1.6e5)
plt.ylim(8.95e5, 9.8e5)
base.set_aspect("equal", "box")
plt.show()