Skip to content

Multiple CRS in one axis

This is an example of how you can use multiple CRS in one plot.

julia
using CairoMakie, GeoMakie
using Rasters, RasterDataSources, ArchGDAL

ras = Raster(EarthEnv{HabitatHeterogeneity}, :homogeneity)
╭───────────────────────────────────────╮
│ 1728×696 Raster{UInt16,2} homogeneity │
├───────────────────────────────────────┴──────────────────────────────── dims ┐
  ↓ X Projected{Float64} LinRange{Float64}(-180.0, 179.79166666666669, 1728) ForwardOrdered Regular Intervals{Start},
  → Y Projected{Float64} LinRange{Float64}(84.79166666666667, -60.0, 696) ReverseOrdered Regular Intervals{Start}
├──────────────────────────────────────────────────────────────────── metadata ┤
  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
  "units"    => ""
  "offset"   => 0.0
  "filepath" => "/home/runner/.julia/artifacts/EarthEnv/HabitatHeterogeneity/25…
  "scale"    => 1.0
├────────────────────────────────────────────────────────────────────── raster ┤
  extent: Extent(X = (-180.0, 180.00000000000003), Y = (-60.0, 85.0))
  missingval: 0xffff
  crs: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
└──────────────────────────────────────────────────────────────────────────────┘
    ↓ →        84.7917      84.5833  …     -59.5833     -59.7917     -60.0
 -180.0    0xffff       0xffff          0xffff       0xffff       0xffff
    ⋮                                ⋱                    ⋮       
  179.792  0xffff       0xffff          0xffff       0xffff       0xffff
julia
heatmap(ras; axis = (; aspect = DataAspect()))

Let's simulate a new CRS, assuming this was an image taken from a geostationary satellite, hovering above 72° E:

julia
projected_ras = Rasters.warp(
        ras,
        Dict(
            "s_srs" => convert(GeoFormatTypes.ProjString, Rasters.crs(ras)).val, # source CRS
            "t_srs" => "+proj=geos +h=3578600 +lon_0=72" # the CRS to which this should be transformed
        )
    )
╭────────────────────────────────────────╮
│ 1320×1315 Raster{UInt16,2} homogeneity │
├────────────────────────────────────────┴─────────────────────────────── dims ┐
  ↓ X Projected{Float64} LinRange{Float64}(-2.486249645439198e6, 2.482616027312147e6, 1320) ForwardOrdered Regular Intervals{Start},
  → Y Projected{Float64} LinRange{Float64}(2.4773207062691883e6, -2.472709236107815e6, 1315) ReverseOrdered Regular Intervals{Start}
├──────────────────────────────────────────────────────────────────── metadata ┤
  Metadata{Rasters.GDALsource} of Dict{String, Any} with 4 entries:
  "units"    => ""
  "offset"   => 0.0
  "filepath" => "/vsimem/tmp"
  "scale"    => 1.0
├────────────────────────────────────────────────────────────────────── raster ┤
  extent: Extent(X = (-2.486249645439198e6, 2.4863831733870152e6), Y = (-2.472709236107815e6, 2.4810878523440566e6))
  missingval: 0xffff
  crs: PROJCS["unknown",GEOGCS["unknown",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]]],PROJECTION["Geostationary_Satellite"],PARAMETER["central_meridian",72],PARAMETER["satellite_height",3578600],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH]]
└──────────────────────────────────────────────────────────────────────────────┘
  ↓ →             2.47732e6  …      -2.46894e6      -2.47271e6
 -2.48625e6  0xffff             0xffff          0xffff
  ⋮                          ⋱       ⋮          
  2.48262e6  0xffff             0xffff          0xffff

This is what the raster would look like, if it were taken directly from a satellite image:

julia
heatmap(projected_ras; axis = (; aspect = DataAspect()))

Now, we can create a GeoAxis with coastlines in the equal earth projection:

julia
fig = Figure()
ga = GeoAxis(fig[1, 1])
lines!(ga, GeoMakie.coastlines())
fig

The coastlines function returns points in the (lon, lat) coordinate reference system.

We will now plot our image, from the geostationary coordinate system:

julia
heatmap!(ga, projected_ras)
fig

Success! You can clearly see how the raster was adapted here.


This page was generated using Literate.jl.