Australia’s coastline is facing increasing pressures from erosion, exacerbated by rising sea levels and extreme weather events. To determine which parts of the coast are vulnerable, it’s crucial to identify areas protected by coastal structures such as sea walls, groynes, and wharfs.
The Climate Systems Hub, through its knowledge brokers, is helping to address this issue by enquiring with state governments about available spatial data on coastal protection structures. Ideally, these datasets would include vital information such as the location, height, and type of each structure.
Currently, Victoria, Tasmania, Queensland, and Western Australia provide standardised publicly accessible datasets on their coastal protection structures. However, this data is not readily available for South Australia, the Northern Territory, or New South and there is insufficient information regarding potential updates to these datasets. A comprehensive national dataset would help researchers and decision makers assess the risks to Australia’s coastlines and guide efforts to protect vulnerable regions.
A recent report from the Insurance
Council of Australia, titled Actions of the Sea, highlights the need
for consistency in how coastal defence data is gathered and shared. It
recommends that state and local governments develop spatial databases of
coastal defences according to a standard framework.
The framework should capture key details, such as:
The state-based datasets on coastal structures vary in detail and naming conventions, and a limitation is that structures are built yearly, yet these datasets aren’t regularly updated. Depending on the quality and level of detail, the data can inform applications at different scales—from first pass scientific research at the national scale to detailed first-pass analysis to inform planning policy decisions.
Existing national datasets, such as Smartline, are being used to help fill current gaps in our datasets of coastal defences. Smartline is a national product that identifies whether a structure exists or not. OpenStreetMap (OSM), a collaborative project where users contribute geographic information, also includes mapping of coastal structures in Australia. Although OSM is not yet comprehensive, it serves as a useful starting point for understanding where protections exist—and where they do not. By exploring OSM contributions, we aim to inform efforts to collect standardised data and make it more accessible to coastal researchers, engineers, and policy managers.
By collating and highlighting gaps in coastal defence data, the analysis presented complements NESP’s outreach efforts. Together, these initiatives will strengthen our understanding of coastal protection and help identify the areas most vulnerable to erosion, guiding future efforts to safeguard Australia’s shores.
Below, we present R
code analysis of the publicly
available data. If you scroll to the end, you’ll find a interactive map
comparing the national OSM and state based data OR
GO TO THE MAP NOW, along with a Call to Action: Get
Involved! to support our efforts to assemble a national dataset
of coastal structures.
To download the processed national merged data file generated in the code below, click the following button:
The file can be read into GIS software.
Please Cite as O’Grady, Julian; Trenham, Claire; Morris, Rebecca; & NESP Climate Systems Hub Knowledge Brokers (2024): Mapping Australia’s Coastal Defences Structures: Understanding the Gaps and the Need for a National Dataset. v2. CSIRO. Service Collection. http://hdl.handle.net/102.100.100/660109?index=1
In this research-quality dataset, a uniform naming convention is presented, lines are converted to polygons (with a width of 1m), and the data source is noted. There are important limitations in the data which are presented in the analysis, including no government-supplied data for NSW, NT, or SA, no sea walls in the TAS dataset, and the OSM data is provided by citizen scientists without extensive professional review of the labelled coastal structure type.
All information and data were generated for research purposes. While every effort has been made to ensure data accuracy, the developers make no warranty (expressed or implied) regarding the accuracy, completeness, function, or capability of the code and associated data. The data is not provided as professional advice, and the user assumes any risk associated with its use, possession, or reliance on the content for decision-making. The developers expressly disclaim liability for any loss arising from the use of this code and the information contained therein. The code incorporated here is general in nature, and more detailed studies may be required for individual regions.
The NESP knowledge brokers were able to identify the datasets in the
following table. The data was downloaded to and placed in the
/data
folder in this repository along with readme files
that explain the data download. In the R scripts below, the data is read
in, interrogated, and a merged product is provided to inform first-pass
assessments of national coastal structures.
Dataset | Public dataset links |
---|---|
VIC | VIC Data download |
TAS | TAS Data dowloaded and filtered for marine features |
QLD | Searched for “Marine infrastructure lines” on qldspatial, QLD Spatial |
WA | WA Data Downloaded/viewed/exported via QGIS WFS WA WFS and exported as geojsons |
OSM | OpenStreetMap, Downloaded via Overpass Turbo Query: Overpass Query |
Smartline | Smartline, Sharples, C., & Mount, R. E. (2009). The Australian coastal Smartline geomorphic and stability map version 1: manual and data dictionary. |
The sections of code below provide a working example of processes for geospatial data on coastal structures sourced from the table above.
From OpenStreetMap (OSM), the key-value pairs used to filter relevant OSM data include:
1. man_made = groyne: A rigid structure built
from the shore to interrupt water flow and limit sediment movement,
often used to prevent beach erosion. https://wiki.openstreetmap.org/wiki/Tag:man_made%3Dgroyne
2. man_made = embankment: An artificial steep slope
built along coastlines or rivers to prevent water from overflowing and
flooding adjacent land. https://wiki.openstreetmap.org/wiki/Tag:man_made%3Dembankment
3. man_made = dyke: A raised structure designed to
restrict water flow, typically built to protect coastal land from
flooding. https://wiki.openstreetmap.org/wiki/Tag:man_made%3Ddyke
4. man_made = quay: A solid platform along the
shore or a riverbank, built for loading and unloading ships. https://wiki.openstreetmap.org/wiki/Tag:man_made%3Dquay
5. man_made = breakwater: A structure built
offshore to protect a coast or harbour from the force of waves. https://wiki.openstreetmap.org/wiki/Tag:man_made%3Dbreakwater
6. man_made = pier: A raised platform extending
into the sea or a body of water, commonly used for docking boats or
recreational purposes. https://wiki.openstreetmap.org/wiki/Tag:man_made%3Dpier
7. bridge = boardwalk: A wooden or raised path
usually found along coastal areas, providing pedestrian access over
marshes or water. https://wiki.openstreetmap.org/wiki/Tag:bridge%3Dboardwalk
8. barrier = retaining_wall: A wall constructed to
prevent soil or coastal land from eroding or sliding into the water. https://wiki.openstreetmap.org/wiki/Tag:barrier%3Dretaining_wall
9. barrier = wall: A generic wall structure that
can also be used along coasts to define property or act as flood
protection. https://wiki.openstreetmap.org/wiki/Tag:barrier%3Dwall
10. wall = flood_wall: A specific type of wall
designed to keep coastal or river waters from flooding inland areas. https://wiki.openstreetmap.org/wiki/Tag:wall%3Dflood_wall
11. wall = seawall: A structure built parallel to
the coast to protect the shore from erosion and storm surges. https://wiki.openstreetmap.org/wiki/Tag:wall%3Dseawall
12. emergency = lifeguard: A designated spot or
station for lifeguards, typically located on beaches to ensure water
safety. https://wiki.openstreetmap.org/wiki/Tag:emergency%3Dlifeguard
13. leisure = slipway: A ramp leading into the
water, used for launching or retrieving boats. https://wiki.openstreetmap.org/wiki/Tag:leisure%3Dslipway
For each of the key-value pairs, the OSM Overpass API was used to query and extract GeoJSON files for these 13 key-value pairs: - Overpass Turbo Query: https://overpass-turbo.eu/?template=key-value&key=man_made&value=groyne#
The script performs the following steps:
The output is a GeoPackage file containing the filtered and processed coastal structures along the Australian coastline. This file can be used for further analysis or mapping of coastal defences in Australia.
suppressPackageStartupMessages(library(leaflet))
suppressPackageStartupMessages(library(terra))
suppressPackageStartupMessages(library(sf))
suppressPackageStartupMessages(library(dplyr))
suppressPackageStartupMessages(library(tidyr))
datadir = "data/"
Coastal structures are defined here as structures being within 100 m from the shoreline. The coast was made via adding a 200m buffer around a 100m OSM coastline of Australia from the code in https://doi.org/10.25919/mapj-bq95
aus_coast = vect(paste0(datadir,"OSM_AUScoastBuffer200m",".gpkg"))
Here we read in the OSM geoJSONs download on 29th Aug 2024.
OSM_geofiles = list.files(paste0(datadir,"OSM_shapes_20240829"),full.names = TRUE)
OSM_geofiles = paste0(datadir,"OSM_shapes_20240829/export (",1:13,").geojson")
filetxt <- c(
"man_made:groyne",
"man_made:embankment",
"man_made:dyke",
"man_made:quay",
"man_made:breakwater",
"man_made:pier",
"bridge:boardwalk",
"barrier:retaining_wall",
"barrier:wall",
"wall:flood_wall",
"wall:seawall",
"emergency:lifeguard",
"leisure:slipway"
)
#open street map coastal geojsons
geoms = lapply(OSM_geofiles,function(x) sapply(svc(x),function(x) geomtype(x)))
n = length(OSM_geofiles)
#some shapes are lines, here is a list of lines
OSM_cps_pl = lapply(1:n,function(x) {if(any(geoms[[x]]=="polygons")) {y=NULL;y = svc(OSM_geofiles[x])[[which(geoms[[x]]=="polygons")]];y$filetype = filetxt[x];y$drawn = "polygons";y}})
#some shapes are polygons, here is a list of polygons
OSM_cps_ll = lapply(1:n,function(x) {if(any(geoms[[x]]=="lines")) {y=NULL;y = svc(OSM_geofiles[x])[[which(geoms[[x]]=="lines")]];y$filetype = filetxt[x];y$drawn = "lines";y}})
Clean the lists and convert lines to polygons a with width of 1m.
OSM_cps_p = vect(OSM_cps_pl[which(!sapply(OSM_cps_pl,is.null))])
touch = relate(OSM_cps_p,aus_coast,"intersects",pairs = TRUE)
OSM_cps_p = OSM_cps_p[unique(touch[,1])]
OSM_cps_l = vect(OSM_cps_ll[which(!sapply(OSM_cps_ll,is.null))])
touch = relate(OSM_cps_l,aus_coast,"intersects",pairs = TRUE)
OSM_cps_l = buffer(OSM_cps_l[unique(touch[,1])],0.5)
Bring the datasets together and keep only the shapes within 200km of the OSM coast.
OSM_cps_coast = rbind(OSM_cps_l,OSM_cps_p)
OSM_cps_coast = buffer(OSM_cps_coast,0)
#OSM_cps_coast = OSM_cps_coast[which(is.valid(OSM_cps_coast))]
#cols_to_keep <- as.numeric(which(!sapply(OSM_cps_coast, function(x) all(is.na(x) | x == ""))))
#OSM_cps_coast_out <- OSM_cps_coast[,cols_to_keep]
#OSM_cps_coast_out <- OSM_cps_coast_out[,-2]
OSM_cps_coast_out = OSM_cps_coast
values(OSM_cps_coast_out) = NA
OSM_cps_coast_out$filetype = OSM_cps_coast$filetype
OSM_cps_coast_out$FID = 1:length(OSM_cps_coast_out)
OSM_cps_coast_out$MergeName = OSM_cps_coast$filetype
writeVector(OSM_cps_coast_out,paste0(datadir,"OSM_coastalStructures.geojson"), filetype = "GeoJSON",overwrite=TRUE)
Because some shapes are lines and some polygons, lines were converted to a 1m wide polygon
calculate_area_summary <- function(vect_data, group_by_col) {
# Calculate area in square meters
vect_data$area_m <- expanse(vect_data, unit = "m")
# Group by the specified column and summarise
summary_stats <- values(vect_data) %>%
group_by(.data[[group_by_col]]) %>%
summarise(
count = n(),
mean_area_m = round(mean(area_m), 2),
min_area_m = round(min(area_m), 2),
max_area_m = round(max(area_m), 2),
std_area_m = round(sd(area_m), 2)
)
# Rename the grouping column for clarity
names(summary_stats)[1] <- group_by_col
# Display the summary statistics
return(knitr::kable(summary_stats))
}
calculate_area_summary(OSM_cps_coast_out,"filetype")
filetype | count | mean_area_m | min_area_m | max_area_m | std_area_m |
---|---|---|---|---|---|
barrier:retaining_wall | 365 | 138.63 | 3.21 | 12949.15 | 726.77 |
barrier:wall | 491 | 251.97 | 1.02 | 29228.01 | 1644.05 |
bridge:boardwalk | 326 | 80.04 | 1.30 | 1004.98 | 122.93 |
emergency:lifeguard | 219 | 433.17 | 4.90 | 1891.47 | 371.91 |
leisure:slipway | 330 | 52.24 | 5.66 | 2938.12 | 169.15 |
man_made:breakwater | 319 | 4006.00 | 9.12 | 51280.12 | 7145.04 |
man_made:dyke | 11 | 233.38 | 9.87 | 1059.48 | 309.43 |
man_made:embankment | 67 | 2530.07 | 6.71 | 76344.93 | 9448.60 |
man_made:groyne | 200 | 624.30 | 5.92 | 25392.62 | 2132.96 |
man_made:pier | 5380 | 380.84 | 1.18 | 122943.66 | 2890.42 |
man_made:quay | 5 | 3305.54 | 189.55 | 15513.92 | 6825.05 |
wall:flood_wall | 1 | 321.83 | 321.83 | 321.83 | NA |
wall:seawall | 1 | 321.83 | 321.83 | 321.83 | NA |
smartline_data = buffer(vect("data/smartline_basic_artificial_shores"),0.5)
smartline_data$MergeName = smartline_data$erode_v
The Victoria Governments has published the most complete public database of coastal structures https://discover.data.vic.gov.au/dataset/coastal-protection-structures. Here we compare the OSM shapes to the victorian Database.
The Victorian datasets has some similar (Groyne and Breakwater), and some different (Seawall), label types for features compared to OSM.
vicdata <- project(buffer(vect("data/victoria/COASTS"),0.5),OSM_cps_coast_out)
vicdata$MergeName = vicdata$STRUC_TYPE
#calculate_area_summary(crop(OSM_cps_coast_out,ext(vicdata)),"filetype")
calculate_area_summary(vicdata,"STRUC_TYPE")
STRUC_TYPE | count | mean_area_m | min_area_m | max_area_m | std_area_m |
---|---|---|---|---|---|
Breakwater | 62 | 150.31 | 8.16 | 1043.25 | 191.26 |
Groyne | 355 | 29.09 | 2.00 | 217.52 | 30.81 |
Other | 15 | 63.80 | 10.22 | 273.92 | 78.78 |
Revetment | 366 | 174.99 | 2.78 | 2357.83 | 275.89 |
Seawall | 635 | 143.55 | 3.70 | 2608.48 | 206.79 |
Unknown | 57 | 67.82 | 1.68 | 484.67 | 92.24 |
Wharf_commercial | 21 | 649.55 | 21.78 | 2042.68 | 549.61 |
Wharf_noncommercial | 62 | 188.41 | 10.18 | 1643.46 | 244.68 |
The Tasmanian data was sourced from https://www.thelist.tas.gov.au/app/content/data/geo-meta-data-record?detailRecordUID=195c6de2-53e8-4792-84fa-5ab1590b2f8c
Here is a summary of the data for Tasmania
Note, there are no records of sea wall in the Tasmanian dataset, E.g. the extensive rock revietment seawall in Burnie
tas_line = vect(paste0(datadir,"tasmania/built_infrastructure_line_statewide.shp"))
tas_poly = vect(paste0(datadir,"tasmania/built_infrastructure_poly_statewide.shp"))
tasdata = project(rbind(buffer(tas_line[tas_line$INFTY1_TXT == "Marine"],0.5),tas_poly[tas_poly$INFTY1_TXT == "Marine"]),OSM_cps_coast_out)
tasdata$MergeName = tasdata$INFTY2_TXT
calculate_area_summary(tasdata,"INFTY2_TXT")
INFTY2_TXT | count | mean_area_m | min_area_m | max_area_m | std_area_m |
---|---|---|---|---|---|
Boat Ramp | 6 | 170.42 | 43.76 | 365.80 | 139.88 |
Breakwater | 24 | 468.13 | 6.33 | 8912.04 | 1803.60 |
Fish Farm | 59 | 486001.57 | 1118.94 | 15979652.44 | 2068338.82 |
Groyne | 3 | 34.57 | 19.24 | 44.68 | 13.51 |
Jetty | 711 | 112.35 | 4.12 | 3112.33 | 232.28 |
Marina | 53 | 593.39 | 21.68 | 2785.99 | 714.13 |
Navigation Buoy | 3 | 16.82 | 11.63 | 19.42 | 4.50 |
Oyster Bed | 131 | 74867.23 | 472.94 | 392379.11 | 81068.05 |
Pier | 4 | 2378.22 | 646.62 | 5664.50 | 2246.43 |
Slipway | 52 | 341.19 | 6.41 | 8816.33 | 1230.67 |
Wharf | 41 | 5291.02 | 66.68 | 124323.72 | 19735.55 |
The Queensland data was obtained by searching for “Marine infrastructure lines” on qldspatial https://qldspatial.information.qld.gov.au/catalogue/custom/search.page The files where then downloaded from an email sent by an automated API.
qld_lines = vect(paste0(datadir,"queensland/Marine_infrastructure_lines"))
qlddata = buffer(project(qld_lines,rast()), 0.5)
qlddata$MergeName = qlddata$feature_ty
calculate_area_summary(qlddata,"feature_ty")
feature_ty | count | mean_area_m | min_area_m | max_area_m | std_area_m |
---|---|---|---|---|---|
Boat Ramp | 14 | 33.89 | 24.49 | 78.25 | 13.80 |
Breakwater | 122 | 234.49 | 9.20 | 1813.21 | 381.45 |
Dry Dock | 1 | 140.44 | 140.44 | 140.44 | NA |
Groyne | 23 | 38.05 | 24.72 | 86.23 | 14.70 |
Jetty | 11682 | 19.87 | 1.27 | 5736.17 | 83.79 |
Sea Wall | 206 | 471.17 | 24.88 | 5195.84 | 623.17 |
Wharf Line | 20 | 208.17 | 20.35 | 633.68 | 147.80 |
The Western Australian data was downloaded/viewed/exported via QGIS WFS https://public-services.slip.wa.gov.au/public/services/SLIP_Public_Services/Infrastructure_and_Utilities_WFS/MapServer/WFSServer and exported as geojsons
wa_lines = vect(paste0(datadir,"western_australia/Coastal_Infrastructure_polygons_DOT-020.geojson"))
wa_lines$AssumStuct = NA
wa_lines$AssumStuct[wa_lines$structype == "BKW"] = "Breakwater"
wa_lines$AssumStuct[wa_lines$structype == "GRN"] = "Groyne"
wa_lines$AssumStuct[wa_lines$structype == "JET"] = "Jetty"
wa_lines$AssumStuct[wa_lines$structype == "SWL"] = "Seawall"
wa_lines$AssumStuct[wa_lines$structype == "WHF"] = "Wharf"
wa_lines$AssumStuct[wa_lines$structype == "MS_Misc"] = "Other"
wa_lines$AssumStuct[wa_lines$structype == "BDW"] = "Boardwalk"
wa_lines$AssumStuct[wa_lines$structype == "OBW"] = "Offshore breakwater"
wa_lines$AssumStuct[wa_lines$structype == "Buoy"] = "Buoy"
wa_lines$AssumStuct[wa_lines$structype == "BLR"] = "Boat lifter"
wa_lines$AssumStuct[wa_lines$structype == "CSW"] = "Causeway"
wa_lines$AssumStuct[wa_lines$structype == "OFP"] = "Outfall Pipe"
wa_lines$AssumStuct[wa_lines$structype == "CHN"] = "Channel"
wadata = wa_lines[!is.na(wa_lines$AssumStuct)]
wadata$MergeName = wadata$structype
calculate_area_summary(wadata,"structype")
structype | count | mean_area_m | min_area_m | max_area_m | std_area_m |
---|---|---|---|---|---|
BDW | 223 | 465.07 | 8.92 | 50674.77 | 3415.02 |
BKW | 98 | 8664.31 | 81.95 | 87448.14 | 12179.08 |
BLR | 335 | 363.81 | 6.40 | 5478.15 | 591.82 |
CHN | 1 | 15942.77 | 15942.77 | 15942.77 | NA |
CSW | 68 | 49474.31 | 67.40 | 1073687.73 | 157462.25 |
GRN | 280 | 1099.07 | 2.57 | 49397.45 | 4221.64 |
JET | 1591 | 700.56 | 0.00 | 88454.25 | 4361.65 |
MS_Misc | 31 | 6996490.81 | 12.10 | 89705321.76 | 20505449.12 |
OBW | 21 | 1309.02 | 194.53 | 4323.64 | 1018.70 |
OFP | 49 | 1027.99 | 0.45 | 13109.47 | 2904.35 |
SWL | 1042 | 4058.51 | 2.73 | 380849.31 | 21061.71 |
WHF | 119 | 2778.58 | 20.98 | 44724.35 | 5644.36 |
Here we map the Victorian, Tasmanian and OSM shapes starting around Geelong in Western Port Phillip Bay. But you are free to zoom around the state or Tasmania, or country and click on a structure to find more info.
# Convert to 'sf' objects for leaflet compatibility
OSM_cps_sf <- st_as_sf(OSM_cps_coast_out)
vicdata_sf <- st_as_sf(vicdata)
tasdata_sf <- st_as_sf(tasdata)
qlddata_sf <- st_as_sf(qlddata)
wadata_sf <- st_as_sf(wadata)
# Define the bounding box for Geelong (approximate coordinates)
geelong_bbox <- st_bbox(c(xmin = 144.30, ymin = -38.25, xmax = 144.45, ymax = -38.10), crs = st_crs(4326))
# Create the leaflet map
leaflet() %>%
addProviderTiles("OpenStreetMap", group = "OpenStreetMap") %>%
addProviderTiles("Esri.WorldImagery", group = "Satellite") %>%
addPolygons(data = OSM_cps_sf, color = "red", weight = 2, opacity = 0.7, fillOpacity = 0.3,
popup = ~paste("OSM Structure Type:", filetype), group = "OSM Structures") %>%
addPolygons(data = vicdata_sf, color = "blue", weight = 2, opacity = 0.7, fillOpacity = 0.3,
popup = ~paste("Victorian Structure:", STRUC_TYPE), group = "Victorian Structures") %>%
addPolygons(data = tasdata_sf, color = "green", weight = 2, opacity = 0.7, fillOpacity = 0.3,
popup = ~paste("Tasmanian Structure:", INFTY2_TXT), group = "Tasmanian Structures") %>%
addPolygons(data = qlddata_sf, color = "maroon", weight = 2, opacity = 0.7, fillOpacity = 0.3,
popup = ~paste("Queensland Structure:", feature_ty), group = "Queensland Structures") %>%
addPolygons(data = wadata_sf, color = "yellow", weight = 2, opacity = 0.7, fillOpacity = 0.3,
popup = ~paste("WA Structure:", structype), group = "WA Structures") %>%
setView(lng = 144.35, lat = -38.15, zoom = 12) %>%
addLegend("topright", colors = c("red","blue", "green","maroon","yellow"), labels = c("OSM Coastal Structures","Victorian Coastal Structures", "Tasmanian Structures", "Queensland Structures", "WA Structures"), opacity = 1) %>%
addLayersControl(
baseGroups = c("OpenStreetMap", "Satellite"),
overlayGroups = c("OSM Structures", "Victorian Structures", "Tasmanian Structures", "Queensland Structures", "WA Structures"),
options = layersControlOptions(collapsed = FALSE)
)