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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions