Skip to content
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

AttributeError returned by caropy.crs.CRS with proj4_params #710

Closed
itcarroll opened this issue Jan 7, 2016 · 4 comments
Closed

AttributeError returned by caropy.crs.CRS with proj4_params #710

itcarroll opened this issue Jan 7, 2016 · 4 comments

Comments

@itcarroll
Copy link

Example:

Python 3.5.1 (default, Dec  7 2015, 21:59:10) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.1.76)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cartopy
>>> crs = cartopy.crs.Mercator()
>>> crs
<cartopy.crs.Mercator object at 0x1039d5a40>
>>> proj4 = crs.proj4_params
>>> proj4
{'ellps': 'WGS84', 'k': 1, 'proj': 'merc', 'lon_0': 0.0, 'units': 'm'}
>>> cartopy.crs.CRS(proj4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "cartopy/_crs.pyx", line 142, in cartopy._crs.CRS.__init__ (lib/cartopy/_crs.c:2771)
AttributeError: 'cartopy._crs.CRS' object has no attribute 'globe'
>>> 

What am I missing? Or is this a bug?

@rhattersley
Copy link
Member

That's a really interesting question - thank you!

The CRS class wasn't really designed for direct use (the focus is more on Projection), but if you're just doing low-level point/vector transformations then I suppose there's no reason why you couldn't use it... except for the problem you've found.

CRS is a class defined in Cython code, so in reality it's a C extension type. This means it doesn't have an attribute dictionary - only explicitly declared attributes exist. Looking in _crs.pxd we can see the declared attributes are only: proj4, proj4_init, and proj4_params. Hence the error that you're seeing - there really is no globe attribute for the code to access.

So how come Mercator and the other CRS subclasses actually work? A Python subclass of CRS does have an attribute dictionary, so it's possible to add any attributes. In the general case:

>>> class Foo(object): pass
...
>>> foo = Foo()
>>> foo.bar = 'This works!'

So... where does that leave us? A simple workaround for now is just to create a trivial Python subclass:

>>> class Foo(cartopy.crs.CRS): pass
...
>>> Foo({'proj': 'lonlat'}).proj4_params
{'ellps': 'WGS84', 'proj': 'lonlat'}

But it seems reasonable that we should also make CRS usable on its own! (i.e. possibly just as simple as adding globe to the list of declared attributes, possibly we'll also need to define a property) @pelson - any idea why CRS shouldn't be usable?

@rhattersley
Copy link
Member

... cartopy.crs.CRS(proj4) ...

NB. If you're trying to define a new map then you don't want to be doing this. A map needs to be a subclass of Projection with a defined boundary, etc.

@pelson
Copy link
Member

pelson commented Nov 20, 2017

Same issue as #813.

@pelson pelson closed this as completed Nov 20, 2017
@adomakor412
Copy link

You guys should fix this issue. I suggest removing the raise error:
@property def crs(self): """Return the coordinate reference system (CRS) as a CFProjection object.""" if 'crs' in self._data_array.coords: return self._data_array.coords['crs'].item() raise AttributeError('crs attribute is not available.')

This will allow coders to abstract the class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants