Generalized Grids for Data Extraction
Not all longitude-latitude grids are rectilinear in the lon/lat space. RegionGrid classifies this type as a GeneralizedGrid. Examples of such datasets include:
Level 2 products from the Global Precipitation Measurement Mission
Model output from climate models such as Weather Research & Forecasting Model (WRF)
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 2D array of
Point2types, with eachPoint2type containing (lon,lat)
using GeoRegions
using RegionGrids
using CairoMakieCreating Generalized Grids
A Generalized 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.
nlon = 51; nlat = 31
lon = zeros(nlon,nlat)
lat = zeros(nlon,nlat)
for ilat = 1 : nlat, ilon = 1 : nlon
lon[ilon,ilat] = (ilon-26) * (5 + (ilat-16) * 0.1)
lat[ilon,ilat] = (ilat-16) * 5
end
geo = GeoRegion([10,100,-80,10],[50,10,-40,50])
ggrd = RegionGrid(geo,Point2.(lon,lat))The GeneralMask type has the following properties:
Longitude Indices (ilon)
Latitude Indices (ilat)
Longitude Points (lon)
Latitude Points (lat)
Rotated X Coordinates (X)
Rotated Y Coordinates (Y)
Rotation (°) (θ) : 0.0
RegionGrid Mask (mask)
RegionGrid Weights (weights)
RegionGrid Size : 37 lon points x 17 lat points
RegionGrid Validity : 230 / 629The API for creating a Generalized Grid can be found here
What is in a Generalized Grid?
RegionGrids.GeneralizedGrid Type
GeneralizedGrid <: RegionGridA GeneralizedGrid is a RegionGrid that is created based on longitude/latitude grids that are not rectilinear - this can range from curvilinear grids to unstructured grids. It has its own subtypes: RegionMask and VectorMask.
All GeneralizedGrid type will contain the following fields:
lon- A Matrix ofFloats, defining the longitudes for each point in the RegionGrid that describe the region.lat- A Matrix ofFloats, defining the latitude for each point in the RegionGrid that describe the region.ilon- A Matrix ofInts, defining the indices used to extract the longitude vector from the input longitude vector.ilat- A Matrix ofInts, defining the indices used to extract the latitude vector from the input latitude vector.mask- An Matrix of NaNs and 1s, defining the gridpoints in the RegionGrid where the data is valid.weights- A Matrix ofFloats, 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 Matrix ofFloats, defining the X-coordinates (in meters) of each point in the "derotated" RegionGrid about the centroid for the shape of the GeoRegion.Y- A Matrix ofFloats, defining the Y-coordinates (in meters) of each point in the "derotated" RegionGrid about the centroid for the shape of the GeoRegion.θ- AFloatstoring 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 GeneralizedGrid type, we have the lon and lat arrays that defined the longitude and latitude points that have been cropped to fit the GeoRegion bounds.
ggrd.lon37×17 Matrix{Float64}:
-73.1 -74.8 -76.5 -78.2 -79.9 … 266.5 264.8 263.1 261.4 259.7
-68.8 -70.4 -72.0 -73.6 -75.2 272.0 270.4 268.8 267.2 265.6
-64.5 -66.0 -67.5 -69.0 -70.5 277.5 276.0 274.5 273.0 271.5
-60.2 -61.6 -63.0 -64.4 -65.8 -77.0 -78.4 -79.8 278.8 277.4
-55.9 -57.2 -58.5 -59.8 -61.1 -71.5 -72.8 -74.1 -75.4 -76.7
-51.6 -52.8 -54.0 -55.2 -56.4 … -66.0 -67.2 -68.4 -69.6 -70.8
-47.3 -48.4 -49.5 -50.6 -51.7 -60.5 -61.6 -62.7 -63.8 -64.9
-43.0 -44.0 -45.0 -46.0 -47.0 -55.0 -56.0 -57.0 -58.0 -59.0
-38.7 -39.6 -40.5 -41.4 -42.3 -49.5 -50.4 -51.3 -52.2 -53.1
-34.4 -35.2 -36.0 -36.8 -37.6 -44.0 -44.8 -45.6 -46.4 -47.2
⋮ ⋱ ⋮
47.3 48.4 49.5 50.6 51.7 60.5 61.6 62.7 63.8 64.9
51.6 52.8 54.0 55.2 56.4 66.0 67.2 68.4 69.6 70.8
55.9 57.2 58.5 59.8 61.1 … 71.5 72.8 74.1 75.4 76.7
60.2 61.6 63.0 64.4 65.8 77.0 78.4 79.8 81.2 82.6
64.5 66.0 67.5 69.0 70.5 82.5 84.0 85.5 87.0 88.5
68.8 70.4 72.0 73.6 75.2 88.0 89.6 91.2 92.8 94.4
73.1 74.8 76.5 78.2 79.9 93.5 95.2 96.9 98.6 100.3
77.4 79.2 81.0 82.8 84.6 … 99.0 100.8 102.6 104.4 106.2
81.7 83.6 85.5 87.4 89.3 104.5 106.4 108.3 110.2 112.1ggrd.lat37×17 Matrix{Float64}:
-35.0 -30.0 -25.0 -20.0 -15.0 … 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 … 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
⋮ ⋱ ⋮
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 … 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 … 20.0 25.0 30.0 35.0 40.0 45.0
-35.0 -30.0 -25.0 -20.0 -15.0 20.0 25.0 30.0 35.0 40.0 45.0An example of using Generalized Grids
Say we have some sample data, here randomly generated.
data = rand(nlon,nlat)51×31 Matrix{Float64}:
0.53108 0.17684 0.54905 0.305573 … 0.318892 0.970287 0.0686291
0.73413 0.759152 0.398304 0.589168 0.78196 0.187578 0.289443
0.738938 0.670924 0.728828 0.159227 0.294332 0.29337 0.782444
0.696393 0.175888 0.460012 0.083934 0.273476 0.480084 0.405746
0.099843 0.851633 0.795971 0.367553 0.874152 0.801502 0.876561
0.602986 0.338695 0.176294 0.447672 … 0.347771 0.315526 0.498787
0.539071 0.377013 0.955979 0.731399 0.785671 0.532301 0.457637
0.790467 0.960946 0.483743 0.192521 0.67063 0.226547 0.433676
0.160371 0.774666 0.980595 0.689099 0.518534 0.411293 0.509587
0.577863 0.928506 0.249101 0.908835 0.149798 0.977879 0.592066
⋮ ⋱ ⋮
0.560348 0.918557 0.50893 0.150222 0.775301 0.806882 0.868738
0.577521 0.473348 0.314098 0.0889282 0.161115 0.579904 0.659775
0.73955 0.409827 0.141313 0.723843 0.805903 0.115318 0.208798
0.293711 0.551327 0.858414 0.805769 … 0.517286 0.794724 0.102391
0.109861 0.294478 0.0982347 0.897494 0.909969 0.904182 0.801225
0.0410006 0.656416 0.19578 0.609709 0.873161 0.53614 0.0623198
0.0998535 0.276967 0.506402 0.0574143 0.189917 0.169985 0.173523
0.586492 0.264134 0.129241 0.365886 0.0722822 0.332523 0.709687
0.884621 0.566991 0.895009 0.0169939 … 0.736358 0.164532 0.711089We extract the valid data within the GeoRegion of interest that we defined above:
ndata = extract(data,ggrd)37×17 Matrix{Float64}:
0.412016 NaN NaN … NaN NaN NaN NaN NaN
0.880892 NaN NaN NaN NaN NaN NaN NaN
0.270462 0.782957 NaN NaN NaN NaN NaN NaN
NaN 0.0948201 0.847412 NaN NaN NaN NaN NaN
NaN 0.814465 0.1671 NaN NaN NaN NaN NaN
NaN 0.513255 0.918268 … NaN NaN NaN NaN NaN
NaN 0.00794297 0.581573 NaN NaN NaN NaN NaN
NaN 0.145615 0.123219 NaN NaN NaN NaN NaN
NaN NaN 0.3398 NaN NaN NaN NaN NaN
NaN NaN 0.377908 NaN NaN NaN NaN NaN
⋮ ⋱ ⋮
NaN NaN NaN 0.465109 NaN NaN NaN NaN
NaN NaN NaN 0.611672 NaN NaN NaN NaN
NaN NaN NaN … NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaN
NaN NaN NaN … NaN NaN NaN NaN NaN
NaN NaN NaN NaN NaN NaN NaN NaNAnd now let us visualize the results.
slon,slat = coordinates(geo) # extract the coordinates
fig = Figure()
ax1 = Axis(
fig[1,1],width=300,height=150,
limits=(-180,180,-90,90)
)
contourf!(ax1,lon,lat,data,levels=-1:0.2:1)
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[1,2],width=300,height=150,
limits=(-180,180,-90,90)
)
contourf!(ax2,ggrd.lon,ggrd.lat,ndata,levels=-1:0.2:1)
lines!(ax2,slon,slat,color=:black,linewidth=2)
Label(fig[2,:],"Longitude / º")
Label(fig[:,0],"Latitude / º",rotation=pi/2)
resize_to_layout!(fig)
fig