Example for georeferencing a radar dataset

Example for georeferencing a radar dataset#

[1]:
import wradlib as wrl
import xarray as xr
import xradar as xd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.patches import Rectangle
import warnings

warnings.filterwarnings("ignore")
try:
    get_ipython().run_line_magic("matplotlib inline")
except:
    plt.ion()

1st step: Compute centroid coordinates and vertices of all radar bins in WGS84 (longitude and latitude).

[2]:
swp = (
    xd.model.create_sweep_dataset(rng=1000)
    .swap_dims(time="azimuth")
    .isel(range=slice(0, 100))
)
swp = swp.assign_coords(sweep_mode="azimuthal_surveillance")
swp = swp.wrl.georef.georeference()
swp
[2]:
<xarray.Dataset> Size: 2MB
Dimensions:     (azimuth: 360, range: 100)
Coordinates: (12/15)
    time        (azimuth) datetime64[ns] 3kB 2022-08-27T10:00:00 ... 2022-08-...
  * range       (range) float64 800B 500.0 1.5e+03 2.5e+03 ... 9.85e+04 9.95e+04
  * azimuth     (azimuth) float64 3kB 0.5 1.5 2.5 3.5 ... 357.5 358.5 359.5
    elevation   (azimuth) float64 3kB ...
    longitude   float64 8B ...
    latitude    float64 8B ...
    ...          ...
    y           (azimuth, range) float64 288kB 499.9 1.5e+03 ... 9.945e+04
    z           (azimuth, range) float64 288kB 383.7 401.3 ... 2.694e+03
    gr          (azimuth, range) float64 288kB 499.9 1.5e+03 ... 9.946e+04
    rays        (azimuth, range) float64 288kB 1.0 1.0 1.0 1.0 ... 1.0 1.0 1.0
    bins        (azimuth, range) float64 288kB 500.0 1.5e+03 ... 9.95e+04
    crs_wkt     int64 8B 0
Data variables:
    *empty*

We can now generate the polgon vertices of the radar bins - with each vertex in lon/lat coordinates.

[3]:
proj_wgs84 = wrl.georef.epsg_to_osr(4326)
polygons = swp.wrl.georef.spherical_to_polyvert(crs=proj_wgs84, keep_attrs=True)
polygons
[3]:
<xarray.DataArray 'spherical_to_polyvert' (bins: 36000, vert: 5, xy: 3)> Size: 4MB
array([[[   8.787727  ,   46.172541  ,  375.        ],
        [   8.787727  ,   46.18153568,  392.51128273],
        [   8.78795299,   46.18153431,  392.51128273],
        [   8.787727  ,   46.172541  ,  375.        ],
        [   8.787727  ,   46.172541  ,  375.        ]],

       [[   8.787727  ,   46.18153568,  392.51128273],
        [   8.787727  ,   46.19053031,  410.14031758],
        [   8.78817906,   46.19052756,  410.14031758],
        [   8.78795299,   46.18153431,  392.51128273],
        [   8.787727  ,   46.18153568,  392.51128273]],

       [[   8.787727  ,   46.19053031,  410.14031758],
        [   8.787727  ,   46.19952488,  427.8871038 ],
        [   8.7884052 ,   46.19952077,  427.8871038 ],
        [   8.78817906,   46.19052756,  410.14031758],
        [   8.787727  ,   46.19053031,  410.14031758]],

       ...,

       [[   8.76546085,   47.04461365, 2621.72317735],
        [   8.76522761,   47.05360076, 2650.65223704],
        [   8.78772694,   47.05373714, 2650.65223704],
        [   8.78772694,   47.04474861, 2621.72317735],
        [   8.76546085,   47.04461365, 2621.72317735]],

       [[   8.76522761,   47.05360076, 2650.65223704],
        [   8.76499429,   47.06258781, 2679.69900768],
        [   8.78772694,   47.0627256 , 2679.69900768],
        [   8.78772694,   47.05373714, 2650.65223704],
        [   8.76522761,   47.05360076, 2650.65223704]],

       [[   8.76499429,   47.06258781, 2679.69900768],
        [   8.76476089,   47.07157477, 2708.86342778],
        [   8.78772694,   47.07171398, 2708.86342778],
        [   8.78772694,   47.0627256 , 2679.69900768],
        [   8.76499429,   47.06258781, 2679.69900768]]])
Coordinates:
    longitude   float64 8B 8.788
    latitude    float64 8B 46.17
    altitude    int64 8B 375
    sweep_mode  <U22 88B 'azimuthal_surveillance'
    crs_wkt     int64 8B 0
Dimensions without coordinates: bins, vert, xy

… or we can compute the corresponding centroids of all bins - - with each centroid in lon/lat coordinates.

[4]:
centroids = swp.wrl.georef.spherical_to_centroids(crs=proj_wgs84, keep_attrs=True)
centroids
[4]:
<xarray.DataArray 'spherical_to_centroids' (azimuth: 360, range: 100, xyz: 3)> Size: 864kB
array([[[   8.7877835 ,   46.17703817,  383.74092231],
        [   8.78789652,   46.18603248,  401.31108119],
        [   8.78800957,   46.19502674,  418.99899181],
        ...,
        [   8.79891893,   47.04920895, 2636.17297817],
        [   8.79903558,   47.05819709, 2665.16095378],
        [   8.79915226,   47.06718516, 2694.26651916]],

       [[   8.78789647,   46.1770368 ,  383.74092231],
        [   8.7882355 ,   46.18602837,  401.31108119],
        [   8.78857463,   46.19501989,  418.99899181],
        ...,
        [   8.82129918,   47.04893762, 2636.17297817],
        [   8.82164908,   47.05792293, 2665.16095378],
        [   8.82199909,   47.06690816, 2694.26651916]],

       [[   8.7880094 ,   46.17703406,  383.74092231],
        [   8.78857432,   46.18602015,  401.31108119],
        [   8.78913943,   46.19500619,  418.99899181],
        ...,
...
        ...,
        [   8.73178512,   47.048395  , 2636.17297817],
        [   8.73120208,   47.05737466, 2665.16095378],
        [   8.73061885,   47.06635424, 2694.26651916]],

       [[   8.78755753,   46.1770368 ,  383.74092231],
        [   8.78721851,   46.18602837,  401.31108119],
        [   8.78687937,   46.19501989,  418.99899181],
        ...,
        [   8.75415509,   47.04893762, 2636.17297817],
        [   8.75380519,   47.05792293, 2665.16095378],
        [   8.75345518,   47.06690816, 2694.26651916]],

       [[   8.7876705 ,   46.17703817,  383.74092231],
        [   8.78755749,   46.18603248,  401.31108119],
        [   8.78744443,   46.19502674,  418.99899181],
        ...,
        [   8.77653518,   47.04920895, 2636.17297817],
        [   8.77641854,   47.05819709, 2665.16095378],
        [   8.77630185,   47.06718516, 2694.26651916]]])
Coordinates:
  * range       (range) float64 800B 500.0 1.5e+03 2.5e+03 ... 9.85e+04 9.95e+04
    longitude   float64 8B 8.788
    latitude    float64 8B 46.17
    altitude    int64 8B 375
    sweep_mode  <U22 88B 'azimuthal_surveillance'
    crs_wkt     int64 8B 0
    time        (azimuth) datetime64[ns] 3kB 2022-08-27T10:00:00 ... 2022-08-...
  * azimuth     (azimuth) float64 3kB 0.5 1.5 2.5 3.5 ... 357.5 358.5 359.5
    elevation   (azimuth) float64 3kB ...
Dimensions without coordinates: xyz

In order to understand how vertices and centroids correspond, we can plot them together.

[5]:
fig = plt.figure(figsize=(16, 16))
site = (polygons.longitude.values, polygons.latitude.values)

aspect = (centroids[..., 0].max() - centroids[..., 0].min()) / (
    centroids[..., 1].max() - centroids[..., 1].min()
)
ax = fig.add_subplot(121, aspect=aspect)
polycoll = mpl.collections.PolyCollection(
    polygons.isel(xy=slice(0, 2)), closed=True, facecolors="None", linewidth=0.1
)
ax.add_collection(polycoll, autolim=True)
# ax.plot(centroids[..., 0], centroids[..., 1], 'r+')
plt.title("Zoom in\n(only possible for interactive plots).")
ax.add_patch(
    Rectangle(
        (site[0] + 0.25, site[1] + 0.25),
        0.2,
        0.2 / aspect,
        edgecolor="red",
        facecolor="None",
        zorder=3,
    )
)
plt.xlim(centroids[..., 0].min(), centroids[..., 0].max())
plt.ylim(centroids[..., 1].min(), centroids[..., 1].max())

ax = fig.add_subplot(122, aspect=aspect)
polycoll = mpl.collections.PolyCollection(
    polygons.isel(xy=slice(0, 2)), closed=True, facecolors="None"
)
ax.add_collection(polycoll, autolim=True)
ax.plot(centroids[..., 0], centroids[..., 1], "r+")
plt.title("Zoom into red box of left plot")
plt.xlim(site[0] + 0.25, site[0] + 0.25 + 0.2)
plt.ylim(site[1] + 0.25, site[1] + 0.25 + 0.2 / aspect)
[5]:
(46.422541, 46.56147892646726)
../../_images/notebooks_georeferencing_georef_10_1.png

2nd step: Reproject the centroid coordinates to Gauss-Krueger Zone 3 (i.e. EPSG-Code 31467).

[6]:
centroids_xyz = centroids.assign_coords(xyz=["x", "y", "z"]).to_dataset("xyz")
centroids_xyz
[6]:
<xarray.Dataset> Size: 874kB
Dimensions:     (azimuth: 360, range: 100)
Coordinates:
  * range       (range) float64 800B 500.0 1.5e+03 2.5e+03 ... 9.85e+04 9.95e+04
    longitude   float64 8B 8.788
    latitude    float64 8B 46.17
    altitude    int64 8B 375
    sweep_mode  <U22 88B 'azimuthal_surveillance'
    crs_wkt     int64 8B 0
    time        (azimuth) datetime64[ns] 3kB 2022-08-27T10:00:00 ... 2022-08-...
  * azimuth     (azimuth) float64 3kB 0.5 1.5 2.5 3.5 ... 357.5 358.5 359.5
    elevation   (azimuth) float64 3kB ...
Data variables:
    x           (azimuth, range) float64 288kB 8.788 8.788 8.788 ... 8.776 8.776
    y           (azimuth, range) float64 288kB 46.18 46.19 46.2 ... 47.06 47.07
    z           (azimuth, range) float64 288kB 383.7 401.3 ... 2.694e+03
[7]:
proj_gk3 = wrl.georef.epsg_to_osr(31467)
centroids_xyz = centroids_xyz.wrl.georef.reproject(trg_crs=proj_gk3)
centroids_xyz
[7]:
<xarray.Dataset> Size: 874kB
Dimensions:     (azimuth: 360, range: 100)
Coordinates:
    x           (azimuth, range) float64 288kB 3.484e+06 3.484e+06 ... 3.484e+06
    y           (azimuth, range) float64 288kB 5.115e+06 5.115e+06 ... 5.115e+06
    z           (azimuth, range) float64 288kB 383.7 401.3 ... 2.694e+03
  * range       (range) float64 800B 500.0 1.5e+03 2.5e+03 ... 9.85e+04 9.95e+04
    longitude   float64 8B 8.788
    latitude    float64 8B 46.17
    altitude    int64 8B 375
    sweep_mode  <U22 88B 'azimuthal_surveillance'
    crs_wkt     int64 8B 0
    time        (azimuth) datetime64[ns] 3kB 2022-08-27T10:00:00 ... 2022-08-...
  * azimuth     (azimuth) float64 3kB 0.5 1.5 2.5 3.5 ... 357.5 358.5 359.5
    elevation   (azimuth) float64 3kB ...
Data variables:
    *empty*
[ ]: