Smoothing of the Land-Sea Mask Dataset
The land-sea mask created from the ETOPO dataset comprises of 1s and 0s, where 1 denotes land and 0 denotes the ocean. However, it may often be useful to sort grid points not only by their land-surface type, but how distant they are from the coastline. GeoRegions.jl uses Gaussian Filtering from ImageFiltering.jl to perform a smoothing of the land-sea mask.
The degree of smoothing is expressed by the arguments σlon
and σlat
, which are integer inputs respectively.
You can get a smoothed land-sea mask via two means:
- Calling the smoothing directly when retrieving the Land-Sea Dataset (recommended)
- Smoothing a preexisting Land-Sea Dataset that has been loaded (not recommended)
The API for smoothing is listed below. However, it is worth nothing that when implementing the smoothing, you need to first call a larger GeoRegion around the GeoRegion of interest as a buffer.
Setup
using GeoRegions
using DelimitedFiles
using CairoMakie
download("https://raw.githubusercontent.com/natgeo-wong/GeoPlottingData/main/coastline_resh.txt","coast.cst")
coast = readdlm("coast.cst",comments=true)
clon = coast[:,1]
clat = coast[:,2]
nothing
Example comparison between Smooth and Unsmoothed Masks
geo = RectRegion("ACH","GLB","Aceh",[7,2,99,94],savegeo=false)
lsd_raw = getLandSea(geo,savelsd=false)
lsd_σ05 = getLandSea(geo,savelsd=false,smooth=true,σlon=5,σlat=5)
lsd_σ10 = getLandSea(geo,savelsd=false,smooth=true,σlon=10,σlat=10)
The Land-Sea Dataset (with Topography) has the following properties:
Longitude Points (lon) : Float32[94.00833, 94.025, 94.041664, 94.058334, 94.075, 94.09167, 94.10833, 94.125, 94.14167, 94.15833 … 98.84167, 98.85833, 98.875, 98.89167, 98.90833, 98.925, 98.941666, 98.958336, 98.975, 98.99167]
Latitude Points (lat) : Float32[2.0083334, 2.025, 2.0416667, 2.0583334, 2.075, 2.0916667, 2.1083333, 2.125, 2.1416667, 2.1583333 … 6.8416667, 6.858333, 6.875, 6.891667, 6.9083333, 6.925, 6.9416666, 6.9583335, 6.975, 6.991667]
Region Size (nlon * nlat) : 300 lon points x 300 lat points
fig = Figure()
ax1 = Axis(
fig[1,1],width=225,height=225,
title="Raw Land-Sea Mask",xlabel="Longitude / º",ylabel="Latitude / º",
limits=(93.9,99.1,1.9,7.1)
)
contourf!(
ax1,lsd_raw.lon,lsd_raw.lat,lsd_raw.lsm,
levels=range(0.05,0.95,length=19),extendlow=:auto,extendhigh=:auto
)
lines!(ax1,clon,clat,color=:black,linewidth=2)
ax2 = Axis(
fig[1,2],width=225,height=225,
title="Smoothed (σ=5)",xlabel="Longitude / º",
limits=(93.9,99.1,1.9,7.1)
)
contourf!(
ax2,lsd_σ05.lon,lsd_σ05.lat,lsd_σ05.lsm,
levels=range(0.05,0.95,length=19),extendlow=:auto,extendhigh=:auto
)
lines!(ax2,clon,clat,color=:black,linewidth=2)
ax3 = Axis(
fig[1,3],width=225,height=225,
title="Smoothed (σ=10)",xlabel="Longitude / º",
limits=(93.9,99.1,1.9,7.1)
)
contourf!(
ax3,lsd_σ10.lon,lsd_σ10.lat,lsd_σ10.lsm,
levels=range(0.05,0.95,length=19),extendlow=:auto,extendhigh=:auto
)
lines!(ax3,clon,clat,color=:black,linewidth=2)
resize_to_layout!(fig)
fig
Smoothing Directly from a loaded Land-Sea Mask
smooth!(lsd_raw,σlon=5,σlat=5)
f2 = Figure()
ax1 = Axis(
f2[1,1],width=350,height=350,
title="Smoothed from Global",xlabel="Longitude / º",ylabel="Latitude / º",
limits=(93.9,99.1,1.9,7.1)
)
contourf!(
ax1,lsd_σ05.lon,lsd_σ05.lat,lsd_σ05.lsm,
levels=range(0.05,0.95,length=19),extendlow=:auto,extendhigh=:auto
)
lines!(ax1,clon,clat,color=:black,linewidth=2)
ax2 = Axis(
f2[1,2],width=350,height=350,
title="Directly Smoothed",xlabel="Longitude / º",
limits=(93.9,99.1,1.9,7.1)
)
contourf!(
ax2,lsd_raw.lon,lsd_raw.lat,lsd_raw.lsm,
levels=range(0.05,0.95,length=19),extendlow=:auto,extendhigh=:auto
)
lines!(ax2,clon,clat,color=:black,linewidth=2)
resize_to_layout!(f2)
f2
You see here that smoothing the land-sea mask directly upon itself causes errors at the edges of the grid. This is because the smoothing applied is a circular smoothing, meaning that the boundaries are considered to be doubly-periodic, and thus bleed into each other. Thus, it is always best practice to call the smoothing directly when retrieving the Land-Sea dataset.
API
GeoRegions.smooth!
— Functionsmooth!(
lsd :: LandSeaTopo;
σlon :: Int = 0,
σlat :: Int = 0,
iterations :: Int = 100,
topography :: Bool = false
) --> nothing
Perform a gaussian smoothing on the Land-Sea mask given a LandSeaTopo Mask dataset. If usetopography
is set to true, then before the filtering, any points where height >= 0 is set to 1, and <0 is set = 0.
The smoothed land-sea mask will be saved into lsd.lsm
Arguments
lsd
: A Land-Sea Dataset with Topography
Keyword Arguments
σlon
: Smooth in the longitude direction (every increase of 1 in σlon roughly corresponds to 8 pixels)σlat
: Smooth in the latitude direction (every increase of 1 in σlat roughly corresponds to 8 pixels)iterations
: Iterations of gausssian smoothing, the higher, the closer the smoothing follows a semi-log. 50-100 iterations is generally enough.topography
: Iftrue
, then the land-sea mask that is smoothed will be based on the topography instead of the raw ERA5 land-sea mask
smooth!(
lsd :: LandSeaFlat;
σlon :: Int = 0,
σlat :: Int = 0,
iterations :: Int = 100
) --> nothing
Perform a gaussian smoothing on the Land-Sea mask given a LandSeaFlat Mask dataset.
The smoothed land-sea mask will be saved into lsd.lsm
Arguments
lsd
: A Land-Sea Dataset without Topography
Keyword Arguments
σlon
: Smooth in the longitude direction (every increase of 1 in σlon roughly corresponds to 8 pixels)σlat
: Smooth in the latitude direction (every increase of 1 in σlat roughly corresponds to 8 pixels)iterations
: Iterations of gausssian smoothing, the higher, the closer the smoothing follows a semi-log. 50-100 iterations is generally enough.
smooth!(
lsm :: Array{<:Real,2};
σlon :: Int = 0,
σlat :: Int = 0,
iterations :: Int = 100
) --> nothing
Perform a gaussian smoothing on the Land-Sea mask.
The smoothed land-sea mask will be saved into lsm
.
Arguments
lsm
: A Land-Sea Mask
Keyword Arguments
σlon
: Smooth in the longitude direction (every increase of 1 in σlon roughly corresponds to 8 pixels)σlat
: Smooth in the latitude direction (every increase of 1 in σlat roughly corresponds to 8 pixels)iterations
: Iterations of gausssian smoothing, the higher, the closer the smoothing follows a semi-log. 50-100 iterations is generally enough.
smooth!(
lsm :: Array{<:Real,2},
oro :: Array{<:Real,2};
σlon :: Int = 0,
σlat :: Int = 0,
iterations :: Int = 100
) --> nothing
Perform a gaussian smoothing on the Land-Sea mask given a corresponding topographic dataset.
The smoothed land-sea mask will be saved into lsm
.
Arguments
olsm
: The old Land-Sea Maskoro
: A topographic dataset that the smoothing will be based off
Keyword Arguments
σlon
: Smooth in the longitude direction (every increase of 1 in σlon roughly corresponds to 8 pixels)σlat
: Smooth in the latitude direction (every increase of 1 in σlat roughly corresponds to 8 pixels)iterations
: Iterations of gausssian smoothing, the higher, the closer the smoothing follows a semi-log. 50-100 iterations is generally enough.
GeoRegions.smoothlsm
— Functionsmoothlsm(
oro :: Array{<:Real,2};
σlon :: Int = 0,
σlat :: Int = 0,
iterations :: Int = 100
) --> Array{<:Real,2}
Perform a gaussian smoothing on the Land-Sea mask
Arguments
oro
: A topographic dataset that the smoothing will be based off
Keyword Arguments
σlon
: Smooth in the longitude direction (every increase of 1 in σlon roughly corresponds to 8 pixels)σlat
: Smooth in the latitude direction (every increase of 1 in σlat roughly corresponds to 8 pixels)iterations
: Iterations of gausssian smoothing, the higher, the closer the smoothing follows a semi-log. 50-100 iterations is generally enough.