Create shapefiles#

Merge LSOAs to create shapefiles for:

  • IVT catchment areas

  • Ambulance trusts

1 Import libraries and set file paths#

from dataclasses import dataclass
import geopandas as gpd
import os
import pandas as pd
# Define file paths
@dataclass(frozen=True)
class Paths:
    '''Singleton object for storing paths to data and database.'''

    data = './data'
    collated = 'collated_data_amb.csv'

    shapefiles = 'shapefiles'
    ivt_catchment = 'ivt_catchment.shp'
    amb_catchment = 'amb_catchment.shp'
    lsoa_shp = ('Lower_layer_super_output_areas_(E+W)_2011_Boundaries_' +
                '(Generalised_Clipped)_V2.zip')


paths = Paths()

2 Load data#

2.1 Load data with closest IVT and ambulance trust per LSOA#

df_lsoa = pd.read_csv(os.path.join(paths.data, paths.collated))
df_lsoa.head()
LSOA admissions closest_ivt_unit closest_ivt_unit_time closest_mt_unit closest_mt_unit_time closest_mt_transfer closest_mt_transfer_time total_mt_time ivt_rate ... age_band_males_65 age_band_males_70 age_band_males_75 age_band_males_80 age_band_males_85 age_band_males_90 ambulance_service local_authority_district_22 LAD22NM country
0 Welwyn Hatfield 010F 0.666667 SG14AB 18.7 NW12BU 36.9 CB20QQ 39.1 57.8 6.8 ... 33 28 26 14 5 3 East of England Welwyn Hatfield Welwyn Hatfield England
1 Welwyn Hatfield 012A 4.000000 SG14AB 19.8 NW12BU 36.9 CB20QQ 39.1 58.9 6.8 ... 24 18 21 12 5 4 East of England Welwyn Hatfield Welwyn Hatfield England
2 Welwyn Hatfield 002F 2.000000 SG14AB 18.7 NW12BU 38.0 CB20QQ 39.1 57.8 6.8 ... 33 28 7 5 9 2 East of England Welwyn Hatfield Welwyn Hatfield England
3 Welwyn Hatfield 002E 0.666667 SG14AB 18.7 NW12BU 36.9 CB20QQ 39.1 57.8 6.8 ... 24 17 15 16 9 1 East of England Welwyn Hatfield Welwyn Hatfield England
4 Welwyn Hatfield 010A 3.333333 SG14AB 18.7 NW12BU 36.9 CB20QQ 39.1 57.8 6.8 ... 33 28 28 13 10 3 East of England Welwyn Hatfield Welwyn Hatfield England

5 rows × 115 columns

2.2 Load LSOA shape file#

The following will load the shape file of the England and Wales LSOA (Lower Super Output Areas) into a GeoPandas DataFrame. Note that we can set the crs (Coordinate Reference System) when loading a GeoPandas DataFrame. EPSG:27700 is the crs to use when geography is in BNG (British National Grid Eastings and Northings).

Other crs to consider for other data projections:

  • EPSG:27700 OSGB 1936 / British National Grid – United Kingdom Ordnance Survey. Co-ordinates are in Eastings (X) and Northings (Y).

  • EPSG:4326 WGS 84 – WGS84 - World Geodetic System 1984. Co-ordinates are in Longitude (X) and Latitude (Y).

  • EPSG:3857 - projection for displaying lat/long as a flat map

gdf_lsoa = gpd.read_file(os.path.join(
    paths.data, paths.shapefiles, paths.lsoa_shp),
    crs='EPSG:27700')
gdf_lsoa.head()
LSOA11CD LSOA11NM LSOA11NMW geometry
0 E01000001 City of London 001A City of London 001A POLYGON ((532105.092 182011.230, 532162.491 18...
1 E01000002 City of London 001B City of London 001B POLYGON ((532746.813 181786.891, 532671.688 18...
2 E01000003 City of London 001C City of London 001C POLYGON ((532135.145 182198.119, 532158.250 18...
3 E01000005 City of London 001E City of London 001E POLYGON ((533807.946 180767.770, 533649.063 18...
4 E01000006 Barking and Dagenham 016A Barking and Dagenham 016A POLYGON ((545122.049 184314.931, 545271.917 18...

View a simple map of this data.

gdf_lsoa.plot(figsize=(8,8));
_images/a0730a7744fe66d5e200343d3deecc6e87aebe38361dd8f89f5674d03649b5fe.png

3 Merge LSOAs together to create shapefiles#

3.1 Define function for creating shapefiles#

The method used is explained with the example of creating a shapefile of IVT catchment areas:

  1. Add column to geopandas dataframe - using LSOA as common value, add field ‘closest_ivt_unit’. Match gdf_lsoa[‘LSOA11NMW’] with df_lsoa[‘LSOA’] and add df_lsoa[‘closest_ivt_unit’] to gdf_lsoa[‘closest_ivt_unit’] - see here for stackoverflow explanation

  2. Ensure no inner lines from original polygons using buffer(0.0001) - see here for stackoverflow explanation

  3. Merge LSOA polygons that are in same IVT unit catchment area using dissolve() - see here for geopandas tutorial on aggregation with dissolve

def create_shapefile(col, file_path, gdf=gdf_lsoa, df=df_lsoa):
    '''
    Merges LSOAs together based on specified column to create a shapefile
    Inputs:
    - col - string, column to group LSOAs based on
    - file_path - string, file path to save shapefile to
    - gdf - geopandas dataframe, created from LSOA shapefile
    - df - dataframe, information for each LSOA
    '''
    # Add column to geopandas LSOA dataframe
    gdf = gdf.merge(
        df[[col, 'LSOA']], left_on='LSOA11NM', right_on='LSOA', how='left')
    gdf = gdf.drop('LSOA', axis=1)

    # Shortern column to first 10 characters (since that's what it will be
    # renamed to for the shapefile) (else get warning message)
    shp_col = col[:10]
    gdf = gdf.rename(columns={col: shp_col})

    # Ensure no inner lines (from the original polygons)
    gdf['geometry'] = gdf['geometry'].buffer(0.0001)

    # Now merge LSOA on specified column
    gdf_catchment = gdf.dissolve(by=shp_col)

    # Save to shapefile
    gdf_catchment.to_file(file_path)

    # Show save location
    display(f'Saved to {file_path}')

    # Display head of dataframe
    display(gdf_catchment.head())

    # Plot shapefile
    gdf_catchment.plot(figsize=(8,8));

3.2 Create IVT catchment shapefile#

create_shapefile(
    'closest_ivt_unit',
    os.path.join(paths.data, paths.shapefiles, paths.ivt_catchment))
'Saved to ./data/shapefiles/ivt_catchment.shp'
geometry LSOA11CD LSOA11NM LSOA11NMW
closest_iv
B152TH MULTIPOLYGON (((403011.723 266679.152, 402597.... E01008881 Birmingham 067A Birmingham 067A
B714HJ MULTIPOLYGON (((395950.714 272162.470, 395950.... E01008899 Birmingham 037A Birmingham 037A
BA13NG POLYGON ((354665.594 144552.500, 354665.594 14... E01014370 Bath and North East Somerset 007A Bath and North East Somerset 007A
BA214AT MULTIPOLYGON (((330365.588 98427.209, 330281.9... E01019886 East Devon 005A East Devon 005A
BB23HH POLYGON ((369965.000 416593.000, 370071.000 41... E01004803 Bolton 001B Bolton 001B
_images/e675ebc9a6e308ba76947287cc24f97f0c8776301462114c4d2956d7c0b8f42b.png

3.3 Create ambulance trust shapefile#

create_shapefile(
    'ambulance_service',
    os.path.join(paths.data, paths.shapefiles, paths.amb_catchment))
'Saved to ./data/shapefiles/amb_catchment.shp'
geometry LSOA11CD LSOA11NM LSOA11NMW
ambulance_
East Midlands MULTIPOLYGON (((433631.972 296489.554, 433631.... E01013128 North East Lincolnshire 010A North East Lincolnshire 010A
East of England MULTIPOLYGON (((503939.688 193345.500, 503939.... E01015589 Peterborough 004A Peterborough 004A
Isle of Wight MULTIPOLYGON (((451071.500 75523.100, 451071.5... E01017282 Isle of Wight 006A Isle of Wight 006A
London MULTIPOLYGON (((510971.125 170480.219, 510971.... E01000001 City of London 001A City of London 001A
North East MULTIPOLYGON (((418029.261 516224.682, 418029.... E01008162 Gateshead 027A Gateshead 027A
_images/9973ce5dc40bac1a1d17efa014c10463866d6e4fa3a832b523fed1f35a2c96bf.png