Unstructured Grids for Data Extraction
There are also RegionGrid
types without an actual grid, maybe there are a set of coordinates and geometries that define the corners or the centres of a mesh, such as:
- Model output from climate models such as cubed-sphere mesh output of the Community Earth Systems Model 2 (CESM2).
Basically, for each of these datasets, the data is given in such a way that the coordinates of the grid can be expressed via:
- A Vector of
Point2
types, with eachPoint2
type containing (lon,lat)
using GeoRegions
using RegionGrids
using CairoMakie
Creating Unstructured Grids
A Unstructured Grid can be created as follows:
ggrd = RegionGrid(geo,Point2.(lon,lat))
where geo
is a GeoRegion
of interest that is found within the domain defined by the longitude and latitude grid vectors.
lon = collect(10:20:360); nlon = length(lon)
lat = collect(-80:20:90); nlat = length(lat)
glon = zeros(nlon,nlat); glon .= lon; glon = glon[:]
glat = zeros(nlon,nlat); glat .= lat'; glat = glat[:]
plon = glon .+ 14rand(nlon*nlat) .- 7
plat = glat .+ 14rand(nlon*nlat) .- 7
geo = GeoRegion([10,100,-80,10],[50,10,-40,50])
iggrd = RegionGrid(geo,Point2.(glon,glat))
pggrd = RegionGrid(geo,Point2.(plon,plat))
The VectorMask Grid type has the following properties:
Indices (ipoint) : [51, 70, 71, 72, 73, 74, 75, 89, 90, 91, 92, 93, 94, 108, 109, 110]
Longitude Points (lon) : [-73.77791981848617, -56.935678198618064, -35.65020155832315, -16.40735918219866, 9.796008030811326, 34.71431766979874, 48.00688551954834, -30.092138437940093, -3.4753868996899655, 8.406297959567416, 32.30763283618734, 52.226290013433314, 68.14205158455948, -8.17917768734469, 15.084602148364837, 29.347909554580326]
Latitude Points (lat) : [-36.130946628631435, -19.05825358692594, -13.278007038207098, -16.932994914090678, -5.726761952704724, 6.898844542284953, 3.8803770612262625, -6.08658296962939, -5.288787380439857, 15.157694505652255, 13.863055663676352, 21.409432966629357, 15.426830046054672, 20.88112359699238, 37.756847233489836, 34.386369360944556]
Rotated X Coordinates (X)
Rotated Y Coordinates (Y)
Rotation (°) (θ) : 0.0
RegionGrid Weights (weights)
RegionGrid Size : (16,) points
The API for creating a Unstructured Grid can be found here
What is in a Unstructured Grid?
RegionGrids.UnstructuredGrid Type
UnstructuredGrid <: RegionGrid
A UnstructuredGrid
is a RegionGrid
that is created based on an unstructured grid often used in cubed-sphere or unstructured-mesh grids.
All UnstructuredGrid
type will contain the following fields:
lon
- A Vector ofFloat
s, defining the longitudes for each point in the RegionGrid that describe the region.lat
- A Vector ofFloat
s, defining the latitude for each point in the RegionGrid that describe the region.ipoint
- A Vector ofInt
s, defining the indices of the valid points from the original unstructured grid that were extracted into the RegionGrid.weights
- A Vector ofFloat
s, defining the latitude-weights of each valid point in the grid. Will be NaN if outside the bounds of the GeoRegion used to define this RectilinearGrid.X
- A Vector ofFloat
s, defining the X-coordinates (in meters) of each point in the "derotated" RegionGrid about the centroid for the shape of the GeoRegion.Y
- A Vector ofFloat
s, defining the Y-coordinates (in meters) of each point in the "derotated" RegionGrid about the centroid for the shape of the GeoRegion.θ
- AFloat
storing the information on the angle (in degrees) about which the data was rotated in the anti-clockwise direction. Mathematically, it isrotation - geo.θ
.
We see that in a UnstructuredGrid
type, we have the lon
and lat
vectors that defined the longitude and latitude points that are within the GeoRegion.
ggrd.lon
ggrd.lat
An example of using Unstructured Grids
Say we have some sample data, here randomly generated.
data = rand(nlon,nlat)[:]
162-element Vector{Float64}:
0.9457759119324752
0.1518450296836532
0.8848205114529575
0.7611622983588391
0.1324997596879074
0.49753679501673065
0.5254648932992327
0.6930924114377638
0.03941107355510687
0.24611440839810406
⋮
0.6127362166551712
0.403170351642994
0.20613773203763297
0.5843149057953531
0.6675419110248055
0.200981273333655
0.4652938616522969
0.16424651525609069
0.5632079382532902
We extract the valid data within the GeoRegion of interest that we defined above:
ndata = extract(data,iggrd)
pdata = extract(data,pggrd)
16-element Vector{Float64}:
0.3094304723775425
0.4899831710273427
0.049615059744586465
0.30981189086819416
0.4775625939578432
0.3595670117751075
0.7626980372458837
0.03274982213044719
0.9943711636684206
0.7101732729748955
0.09414220864561118
0.7236528788202466
0.3649091073380065
0.8049559425661069
0.06173091573212974
0.8465393145953215
And now let us visualize the results.
slon,slat = coordinates(geo) # extract the coordinates
fig = Figure()
ax1 = Axis(
fig[1,1],width=450,height=150,
limits=(-180,360,-90,90)
)
scatter!(ax1,glon,glat,color=:lightgrey)
scatter!(ax1,plon,plat,color=data)
lines!(ax1,slon,slat,color=:black,linewidth=2)
lines!(ax1,slon.+360,slat,color=:black,linewidth=2,linestyle=:dash)
hidexdecorations!(ax1,ticks=false,grid=false)
ax2 = Axis(
fig[2,1],width=450,height=150,
limits=(-180,360,-90,90)
)
scatter!(ax2,iggrd.lon,iggrd.lat,color=:lightgrey)
scatter!(ax2,pggrd.lon,pggrd.lat,color=pdata)
lines!(ax2,slon,slat,color=:black,linewidth=2)
Label(fig[3,:],"Longitude / º")
Label(fig[:,0],"Latitude / º",rotation=pi/2)
resize_to_layout!(fig)
fig