-
Notifications
You must be signed in to change notification settings - Fork 366
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
Conversation
Code tested as an addition to Met Office cartopy install (which is currently non-standard as it uses some old dependencies).
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 and fix the reported error thank you |
Code tested as an addition to Met Office cartopy install (which is currently non-standard as it uses some old dependencies).
Conflicts: lib/cartopy/mpl/geoaxes.py
d7a2701
to
e2e001b
Compare
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 |
Thanks for your help @marqh |
There was a problem hiding this 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.", |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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(): |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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): |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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' |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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))
There was a problem hiding this comment.
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.
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. |
Thanks for the read-through @QuLogic |
…o background_img Conflicts: lib/cartopy/mpl/geoaxes.py
try: | ||
fname = _USER_BG_IMGS[name][resolution] | ||
except KeyError: | ||
msg = ('Image "{} and "resolution "{}" are not present in ' |
There was a problem hiding this comment.
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 ' |
There was a problem hiding this comment.
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.
There was a problem hiding this 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' |
There was a problem hiding this comment.
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.
The pep8 error is your code change though. |
Merge branch 'background_img' of github.com:malcolmbrooks/cartopy into background_img Conflicts: lib/cartopy/mpl/geoaxes.py
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. |
@malcolmbrooks you're right, not your problem; it is now fixed, any future commit should not suffer from this |
this is all looking good to me now, I think there has been plenty of input I'm merging this, thank you @malcolmbrooks |
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