-
Notifications
You must be signed in to change notification settings - Fork 368
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
Create Cartopy projection from pyproj.Proj #813
Comments
No, but I'd love to have it too. |
I've come up with a quick n dirty solution here There should be a more generic way to do it (both pyproj and cartopy use the proj4 engine) but I don't know cartopy well enough to help here... |
I know that this is crude, but... |
Just to be clear on this, I am against using a proj4 string as a constructor of a "Proj4Projection" - the solution I'd be looking for is to construct a proper cartopy Projection instance from the proj4 string. For example:
|
I'd be willing to work on this if everyone can agree on how it should be done. To do the above behavior where I was thinking the |
I cannot comment on the details here, but I can only emphasize again that a proj4 string -> cartopy converter would be extremely useful... |
In general, I'm completely OK with that (and potentially even automatically adding those kwargs through to the |
Without thinking about it too much maybe a |
Somewhat OT: what was the rationale behind creating cartopy-specific semantics for projection kwargs and names, instead of relying on PROJ4 conventions? |
It isn't something that was done lightly, but given there are a number of cases where the proj4 kwargs aren't the defacto standard within other fields. Rotated pole is a good example, where the pole longitude is more common than the central longitude in environmental science.
Yep, sounds sensible. Another complication that I've remembered from having a 30 minute go at doing this several years ago... projection classes aren't 1:1 with proj.4 projections either. Case in point: NorthPolarStereographic. I can completely live with that though - we quickly descend get into a conversation about what is a projection and what is an instance of a projection 😄. If you're really keen to have a go at this, I'd encourage you to produce something rough and ready, rather than polishing too much - it might take several iterations until we know we are on the right lines, and only then would I be looking to add some polish to the code. 👍 |
@pelson Sounds good. I've started on the basics. I'll make a PR hopefully in the next hour or so. |
Why not just "extending" the cartopy.crs.epsg(code) in order to offer two diffrent uses :
in _epsg.py there is :
so the use of proj4's style str is already there. Am i wrong ? |
@moccand As mentioned in my PR for adding this functionality, see #1023 (comment) So yes, you're on the right track, but in the current EPSG code the It has been a long time since I've looked at this, but iirc this is essentially what I was doing. Making a PROJ.4 CRS object that the EPSG code could use. It got more complicated when @pelson pointed out that they would rather have "fully qualified" CRS objects returned rather than a single object that can be all projections. |
I will take time to read previous posts. regarding projection.domain_of_validity(), it returns the WGS84 bounds ("extent") as shown in epsg.io website or in http://epsg.io/?q=2154&format=json&trans=1 for EPSG:2154 WGS84 bounds are : {"status": "ok", "number_result": 1, "results": [{"code": "2154", "kind": "CRS-PROJCRS", "bbox": [51.56, -9.86, 41.15, 10.38], "wkt": "PROJCS["RGF93 / Lambert-93",GEOGCS["RGF93",DATUM["Reseau_Geodesique_Francais_1993",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6171"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4171"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",49],PARAMETER["standard_parallel_2",44],PARAMETER["latitude_of_origin",46.5],PARAMETER["central_meridian",3],PARAMETER["false_easting",700000],PARAMETER["false_northing",6600000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],AUTHORITY["EPSG","2154"]]", "unit": "metre", "proj4": "+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs", "name": "RGF93 / Lambert-93", "area": "France - onshore and offshore, mainland and Corsica.", "default_trans": 1671, "trans": [{"proj4": "", "bbox": [51.56, -9.86, 41.15, 10.38], "area": "France - onshore and offshore, mainland and Corsica.", "code_trans": 1671, "accuracy": 1.0, "wkt": "", "unit": "metre", "name": "RGF93 to WGS 84 (1)"}, {"proj4": "", "bbox": [51.56, -9.86, 41.15, 10.38], "area": "France - onshore and offshore, mainland and Corsica.", "code_trans": 8573, "accuracy": "", "wkt": "", "unit": "metre", "name": "RGF93 to WGS 84 (1)"}], "accuracy": 1.0}]}
setting both proj4 string and extents (in WGS84 or in targeted system with transformation) would not be so far from what openlayers (+ proj4js) needs : https://openlayers.org/en/latest/examples/wms-image-custom-proj.html
|
👍 to the increased interop btw cartopy and pyproj. Thanks to those who are working on this. |
It looks like the corresponding pull request made a ton of progress on this. It would be a shame to lose that! Thanks all (+1/bump/pretty please) :) |
Thank you for the work already done in this direction! Any further activity on this? |
@amundvedal The last I heard on this, at least on the "wish list" level of things, was the idea to try and make pyproj's relatively new Edit: Found it #1477 |
@djhoese Thank you for the answer! I found the following away around my issue, and posting it here to help others in a similar situation: Issue: Solution: Code: import geopandas
from cartopy.crs import GOOGLE_MERCATOR
paths = gv.Path(gpd.read_file('shapefile.shp').to_crs(epsg=3857), crs=GOOGLE_MERCATOR) |
With #1808 merged I think the original issue here can be closed, but it also doesn't cover all cases. I'm wondering if I can get @snowman2 and the rest of the community here to help me add a little more functionality to completely handle my use case (and I think @fmaussion's). The
class Projection(CRS, metaclass=ABCMeta):
...
def __init__(self, *args, bounds=None, transform_bounds=True, **kwargs):
super().__init__(*args, **kwargs)
self.bounds = None
bounds = bounds if bounds is not None else self.area_of_use
if bounds and transform_bounds:
# existing transformation logic This may kind of break the idea of a "Projection" though, but also fits decently well in my opinion. Side note: The existing |
I like the idea of 3 (bounds kwarg for Projection). Adding in 3 and tinkering a bit may help answer 1 & 2. |
I don't think that Cartopy actually restricts the transforms based on the bounds, so setting the bounds would only affect the drawn boundary. For example, if you limit the extent of your projection but then start zooming/panning around and your dataset was outside of the initial extent it will come into view later. If you do want to restrict the bounds for the transforms maybe you'd need to update the It looks like the bounds currently have to be specified in degrees since that is what the Line 651 in 019f013
3 seems pretty reasonable and wouldn't be very invasive. |
I'm testing something to be included in pyresample since it currently doesn't work with cartopy 0.20.0. We previously had a custom subclass of the cartopy CRS which sparked my work in #1023. Here's the replacement that I'll try to submit as a PR tomorrow if I can find the time:
Seems to work for pyresample's use cases so far. The |
Also as to answer number 2, it seems that for a CRS for EPSG:4326 that the bounds are stored as degrees so I think radians being used is no longer needed (at least I had to use them in pyresample's code) for geographic CRS objects or at least the ones that don't explicitly define themselves as being in radians. |
See #1888 |
Maybe I missed it, but since the issues #153 and #710 are still open I thought I would ask this too:
is it possible to create a cartopy projection from a pyproj.Proj instance?
The text was updated successfully, but these errors were encountered: