Skip to content

Possible vector rotation issue #1778

Description

@gauteh

Code from Lenny

import numpy as np
import pyproj
import matplotlib.pyplot as plt
import cartopy.crs as ccrs

# -------------------------------------------------------
# Projection definitions
# -------------------------------------------------------

proj_from = pyproj.Proj("+proj=stere +lat_0=90 +lon_0=0 +lat_ts=70 +datum=WGS84")
proj_to = pyproj.Proj("+proj=latlong +datum=WGS84")

proj_from_crs = ccrs.Stereographic(
    central_latitude=90,
    central_longitude=0,
    true_scale_latitude=70
)

transformer = pyproj.Transformer.from_proj(proj_from, proj_to)
geod = pyproj.Geod(ellps="WGS84")

# -------------------------------------------------------
# Create a small 3x3 polar stereographic grid
# -------------------------------------------------------

x0 = 1000000 # 1000 km 
y0 = - 1000000 # 10000 km 
dx = 100000  # 100 km spacing

x = np.array([x0-dx, x0, x0+dx])
y = np.array([y0-dx, y0, y0+dx])

X, Y = np.meshgrid(x, y)

# -------------------------------------------------------
# Define grid unit vectors
# -------------------------------------------------------

# grid x-direction vector
u_x = np.ones_like(X)
v_x = np.zeros_like(X)

# grid y-direction vector
u_y = np.zeros_like(X)
v_y = np.ones_like(X)

# -------------------------------------------------------
# Rotation function (simplified version of repo code)
# -------------------------------------------------------

def rotate_vectors(reader_x, reader_y, u_component, v_component, proj_from, proj_to):

    delta_y = 10  # 10 meters northward in projection space

    transformer = pyproj.Transformer.from_proj(proj_from, proj_to)

    # transform base points
    lon, lat = transformer.transform(reader_x, reader_y)

    # transform northward shifted points
    lon2, lat2 = transformer.transform(reader_x, reader_y + delta_y)

    # compute azimuth of projected north
    azimuth = geod.inv(lon, lat, lon2, lat2)[0]

    rot_angle_vectors_rad = np.radians(azimuth)

    rot_angle_rad = -rot_angle_vectors_rad

    u_rot = (
        u_component * np.cos(rot_angle_rad)
        - v_component * np.sin(rot_angle_rad)
    )

    v_rot = (
        u_component * np.sin(rot_angle_rad)
        + v_component * np.cos(rot_angle_rad)
    )

    return u_rot, v_rot, lon, lat


# -------------------------------------------------------
# Rotate vectors
# -------------------------------------------------------

u_x_geo, v_x_geo, lon, lat = rotate_vectors(X, Y, u_x, v_x, proj_from, proj_to)
u_y_geo, v_y_geo, _, _ = rotate_vectors(X, Y, u_y, v_y, proj_from, proj_to)

# -------------------------------------------------------
# Plot grid vectors in stereographic coordinates
# -------------------------------------------------------

fig = plt.figure(figsize=(12,5))

pad = 50000 # 50 km
pad_deg = 2 # degrees

ax1 = fig.add_subplot(121,projection=proj_from_crs)
ax1.set_extent([x[0]-pad,x[-1]+pad,y[0]-pad ,y[-1]+pad],crs=proj_from_crs)
ax1.quiver(X, Y, u_x, v_x, color="blue", scale=10)
ax1.quiver(X, Y, u_y, v_y, color="red", scale=10)

ax1.set_title("Grid vectors in stereographic coordinates")
ax1.set_aspect("equal")

# -------------------------------------------------------
# Plot rotated vectors on lon/lat map
# -------------------------------------------------------

ax2 = fig.add_subplot(122, projection=ccrs.PlateCarree())

ax2.coastlines()
ax2.set_global()

ax2.set_extent([np.min(lon)-pad_deg,np.max(lon)+pad_deg,np.min(lat)-pad_deg ,np.max(lat)+pad_deg],crs=ccrs.PlateCarree())
# ax2.set_extent([x[0]-pad,x[-1]+pad,y[0]-pad ,y[-1]+pad],crs=proj_from_crs)

for seg in [(X[0,:],Y[0,:]), (X[-1,:],Y[-1,:]),
            (X[:,0],Y[:,0]), (X[:,-1],Y[:,-1])]:
    ax2.plot(seg[0], seg[1], color='blue', lw=1, transform=proj_from_crs)

ax2.quiver(
    lon, lat,
    u_x_geo, v_x_geo,
    color="blue",
    transform=ccrs.PlateCarree(),
    scale=10
)

ax2.quiver(
    lon, lat,
    u_y_geo, v_y_geo,
    color="red",
    transform=ccrs.PlateCarree(),
    scale=10
)
ax2.quiver(
    X, Y,
    u_x, v_x,
    color="black",
    transform=proj_from_crs,
    scale=10
)

ax2.quiver(
    X, Y,
    u_y, v_y,
    color="black",
    transform=proj_from_crs,
    scale=10
)

ax2.set_title("Vectors rotated into geographic coordinates")

plt.show()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions