Skip to content

ENH: Azimuthal rotation for Orthographic projection #2504

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 23, 2025

Conversation

kenhira
Copy link
Contributor

@kenhira kenhira commented Feb 27, 2025

Rationale

This update adds azimuth argument to ccrs.Orthographic(), with a corresponding test. It will enable users to rotate the projection around the central point. It uses new Proj parameter alpha, which was added to Orthographic in Proj version 9.5.0.
https://proj.org/en/stable/operations/projections/ortho.html

An equivalent azimuth argument has already been implemented to ccrs.ObliqueMercator().

Implications

Users will become able to rotate the map as they prefer. For example, one can orient a satellite image along the solar direction to emphasize which direction the sun glint and shadow appear.
This update is a minimal update, adding just one argument to the function.

@greglucas
Copy link
Contributor

I'm guessing you'll need to put a version gate around this parameter so that we only use it if the underlying PROJ library >= 9.5. Here is an example in our tests

if pyproj.__proj_version__ >= '9.2.0':

What happens if we pass this parameter to the projection in earlier versions, do we get a warning or do we need to issue a warning on our side that the parameter has no effect and will be ignored?

@greglucas
Copy link
Contributor

ping @kenhira , are you able to add the version gate on this parameter?

@kenhira
Copy link
Contributor Author

kenhira commented Apr 13, 2025

Apologies for my slow response. I have implemented the version gate (pyproj.__proj_version__ >= '9.5.0').

What happens if we pass this parameter to the projection in earlier versions, do we get a warning or do we need to issue a warning on our side that the parameter has no effect and will be ignored?

I tested on my end with pyproj=3.4.1 and proj=9.1.1, and it seems that we do not get a warning by passing alpha parameter to proj even though it is not an expected input. Therefore I added a warning on cartopy side that the azimuth input will be ignored.

@kenhira
Copy link
Contributor Author

kenhira commented Apr 13, 2025

Here is what the output is like:
With the recent proj version, the azimuthal rotation works.
test_plot_9 5 1

However, with the older proj (tested with proj=9.1.1), the rotation is not effective. With my implementation, the user will get the following warning

.../cartopy/lib/cartopy/crs.py:2100: UserWarning: Setting azimuth is not supported with PROJ versions < 9.5.0. Assuming azimuth=0. Current PROJ version: 9.1.1
  warnings.warn(

test_plot_9 1 1

Here is the test code used for plots above:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.geodesic import Geodesic

if __name__ == "__main__":
    anchorage_lon, anchorage_lat = -149.9003, 61.2181
    denver_lon, denver_lat = -104.9903, 39.7392
    geod = Geodesic()
    heading = geod.inverse((anchorage_lon, anchorage_lat), (denver_lon, denver_lat))[0][1]
    
    fig = plt.figure(figsize=(8, 4))

    ax1 = fig.add_subplot(1, 2, 1, 
        projection=ccrs.Orthographic(central_longitude=anchorage_lon, 
                                     central_latitude=anchorage_lat))
    ax1.coastlines()
    ax1.set_global()
    ax1.plot([anchorage_lon, denver_lon], [anchorage_lat, denver_lat], 
             transform=ccrs.Geodetic(), label="Anchorage to Denver")
    ax1.plot(anchorage_lon, anchorage_lat, 'o', transform=ccrs.Geodetic(), label="Anchorage")
    ax1.plot(denver_lon, denver_lat, 'o', transform=ccrs.Geodetic(), label="Denver")
    ax1.set_title("azimuth=0")

    ax2 = fig.add_subplot(1, 2, 2,
        projection=ccrs.Orthographic(central_longitude=anchorage_lon,
                                     central_latitude=anchorage_lat,
                                     azimuth=heading))
    ax2.coastlines()
    ax2.set_global()
    ax2.plot([anchorage_lon, denver_lon], [anchorage_lat, denver_lat], 
             transform=ccrs.Geodetic())
    ax2.plot(anchorage_lon, anchorage_lat, 'o', transform=ccrs.Geodetic(), label="Anchorage")
    ax2.plot(denver_lon, denver_lat, 'o', transform=ccrs.Geodetic(), label="Denver")
    ax2.set_title("azimuth=%.2f deg" % heading)
    ax2.legend(loc='lower right')

    fig.tight_layout()
    plt.savefig('test_plot.png')
    plt.show()

@greglucas greglucas merged commit 703098c into SciTools:main May 23, 2025
23 checks passed
@greglucas
Copy link
Contributor

Thanks @kenhira! That all looks good to me.

@kenhira kenhira deleted the rotate_orthographic branch May 23, 2025 02:58
@QuLogic QuLogic added this to the Next Release milestone May 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants