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

Add a user/site specified background image directory #815

Merged
merged 27 commits into from
Jan 10, 2017

Conversation

melissaebrooks
Copy link

Issue #786 requests additional options for the stock image which would allow other images to be presented. Ideally new images would be available at a high enough resolution to allow plots over small areas to produce high quality images. For this to happen, the size of the raster data on the repository would have to increase to an inappropriate size.

To get around this, but still have the flexibility and speed of pre-downloaded and pre-resized images, I suggest having a directory of images defined by an environment variable which can be set to a site specifc default or changed by the user. That directory can hold an appropriate background images for multiple types of image, and resolution of the image. In order to define the contents of the image, I suggest it should contain a JSON file which sets up a dictionary of images by type and resolution.

To achieve fast plotting the I found it was necessary to add options to define the extent of the background image used in a plot, and the ability to cache the (whole) image into memory.

A tar file containing a set of images to do the Natural Earth Shaded Relief and Grey Earth, at a variety of resolutions, and the JSON file for them, is available at:
http://gws-access.ceda.ac.uk/public/mo_forecasts/natural_earth_backgrounds.tar

Malcolm Brooks added 4 commits November 16, 2016 21:52
Code tested as an addition to Met Office cartopy install (which is currently non-standard as it uses some old dependencies).
@marqh
Copy link
Member

marqh commented Dec 20, 2016

Hi @malcolmbrooks

the master tests are now passing, which is a relief (#818)

the remaining test failure on this PR is a PEP8 failure

please may you
pep8 lib/cartopy/mpl/geoaxes.py

and fix the reported error

thank you
mark

@marqh
Copy link
Member

marqh commented Dec 21, 2016

this is all passing now, which is grand

I am supportive of this new interface to share local data, it has some useful potential for performance and to help deployment

@melissaebrooks
Copy link
Author

Thanks for your help @marqh

Copy link
Member

@QuLogic QuLogic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally reasonable, but this seems to box one in with a single directory (which granted, are able to contain multiple directories, I think). Is there a way to get the fall back to be <repo_data_dir>/raster/<name>? And additionally, <data_dir> (which is in user-space.)

@@ -0,0 +1,7 @@
{"__comment__": "JSON file specifying the image to use for a given type/name and resolution. Read in by cartopy.mpl.geoaxes.read_user_backgound_images.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

background

def background_img(self, name='ne_shaded', resln='low', extent=None,
cache=False):
"""
Adds from a selection of prepared images to the map where the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First sentence should be a single line.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm not quite sure what you mean. pep8 compliance forces short lines here.

cache=False):
"""
Adds from a selection of prepared images to the map where the
available files are held in the CARTOPY_USER_BACKGROUNDS environment
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CARTOPY_USER_BACKGROUNDS is a directory? This sentence implies it's a list of files.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope this is clearer now.

available files are held in the CARTOPY_USER_BACKGROUNDS environment
variable.

That directory is checked with read_user_backgound_images and needs to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

backgound -> background; add back ticks for cross-reference.


* name - the name of the image to read according to the contents of
the JSON file. A typical file might have, for instance:
'ne_shaded' : Natrual Earth Shaded Relief
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Natural

# Now obtain the image data from file or cache:
fpath = os.path.join(bgdir, fname)
if cache:
if fname in _BACKG_IMG_CACHE.keys():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.keys() is redundant.

# which points are in range:
lat_in_range = np.logical_and(lat_pts >= extent[2],
lat_pts <= extent[3])
if extent[0] < 180 and extent[1] > 180:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if it could handle extent[1] that was negative.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That bit of logic catches extents that cross the dateline. An extent[1] that's negative doens't span the dateline so works in the else block.

transform=source_proj,
extent=ret_extent)

def read_user_backgound_images(self, verify=True):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

background


The metadata should be a standard JSON file which specifies a two
level dictionary. The first level is the image type.
For each image type there needs to be the fields:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs to -> must

# check that this image type has the required info:
for required in required_info:
if required not in _USER_BG_IMGS[img_type]:
err_str = 'User background metadata file'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like this +=ing stuff; just write the whole string and format it in one go.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like it either but the pep8 compliance demands short lines, so it's a choice between useful error messages and += or useless error messages (or ignoring pep8 compliance).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take advantage of other mechanisms for breaking lines, the += method makes the message unreadable in the source. Try something like this:

msg = ('User background metadata file "{}", image type "{}", does not '
       'specify metadata item {}')
raise ValueError(msg.format(json_file, img_type, required))

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would be much better.

@QuLogic
Copy link
Member

QuLogic commented Dec 22, 2016

And additionally, <data_dir> (which is in user-space.)

Though, since this exists, do we really need the environment variable at all?

@marqh
Copy link
Member

marqh commented Dec 28, 2016

And additionally, <data_dir> (which is in user-space.)

Though, since this exists, do we really need the environment variable at all?

There seems to me a significant difference here.

With this environment variable, I can specify, at run time, a pre-prepared selection of data, ready to use. This has significant benefits in a shared environment, where cartographic data sets can be prepared in advance, then used by multiple systems in an optimised fashion.

This is a useful extension use case, which I don't think is covered by data_dir or individual user space.

@melissaebrooks
Copy link
Author

Thanks for the read-through @QuLogic
Your typo spotting is much appreciated.

try:
fname = _USER_BG_IMGS[name][resolution]
except KeyError:
msg = ('Image "{} and "resolution "{}" are not present in '
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the " is in the wrong place here.

try:
fname = _USER_BG_IMGS[name][resolution]
except KeyError:
msg = ('Image "{}" and "resolution "{}" are not present in '
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need the " before resolution? It doesn't have a corresponding closing quote.

Copy link
Author

@melissaebrooks melissaebrooks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change is now passing tests, apart from the python 3.6 one which doesn't have anything to do with this change. The first of the recent changes also failed it, and that only made a change to the comment in the JSON file.

The environment variable declaring a directory does fall back to the repo dir if it's unset. That's what is done in the tests.

# check that this image type has the required info:
for required in required_info:
if required not in _USER_BG_IMGS[img_type]:
err_str = 'User background metadata file'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would be much better.

@ajdawson
Copy link
Member

The pep8 error is your code change though.

Malcolm Brooks added 2 commits January 3, 2017 11:31
Merge branch 'background_img' of github.com:malcolmbrooks/cartopy into background_img

Conflicts:
	lib/cartopy/mpl/geoaxes.py
@melissaebrooks
Copy link
Author

Thanks @ajdawson; the change is now passing tests, apart from the python 3.6 one which doesn't have anything to do with this change. The first of the recent changes also failed it, and that only made a change to the comment in the JSON file.

@marqh
Copy link
Member

marqh commented Jan 6, 2017

Thanks @ajdawson; the change is now passing tests, apart from the python 3.6 one which doesn't have anything to do with this change.

@malcolmbrooks you're right, not your problem; it is now fixed, any future commit should not suffer from this

@marqh
Copy link
Member

marqh commented Jan 10, 2017

this is all looking good to me now, I think there has been plenty of input

I'm merging this, thank you @malcolmbrooks

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.

4 participants