Repository: SciTools/cartopy

Issue:
Map Feature Improvements
Two things I'd like to see, and I'll submit a PR if there's interest:

1. A feature for states/provinces
1. The ability to more easily take, say `RIVERS` and get a higher resolution version 


Discussion:
There are two examples of states/provinces in the gallery: [for USA](http://scitools.org.uk/cartopy/docs/latest/examples/hurricane_katrina.html) and [for Australia](http://scitools.org.uk/cartopy/docs/latest/examples/feature_creation.html).

Higher resolution rivers can be had by copying the line out of the source and changing the resolution; I thought there was another issue asking for an easier method, but I can't seem to find it.
So the point in adding a states/provinces feature would be to avoid having to show the learners I'm training this:
```
'admin_1_states_provinces_lakes'
```
And try to explain how they're supposed to identify that string on their own on the Natural Earth site. For our uses, it stands in stark contrast to the ease of doing `cartopy.feature.LAKES`.

As far as the resolution yes, I can do that. Again, I would like not to stand in front of a room of novice to intermediate Python users and try to suggest that that's their best course of action.

What I'm asking for (really, what I'm asking to create and have merged) is nothing that can't be done, but it would make it easier to do, easier to teach, and shorten my training materials. I can put these in MetPy, but it seems better to have these upstream.
Agreed. Adding state outlines would greatly simplify the workflow of a lot of map making and seems like it would be a good addition to cartopy vs. metpy.
Don't wait for more discussion here, go forth and submit PRs @dopplershift

Resolving patch:
diff --git a/lib/cartopy/feature.py b/lib/cartopy/feature.py
--- a/lib/cartopy/feature.py
+++ b/lib/cartopy/feature.py
@@ -187,6 +187,21 @@ def geometries(self):
 
         return iter(geometries)
 
+    def with_scale(self, new_scale):
+        """
+        Return a copy of the feature with a new scale.
+
+        Args:
+
+        * new_scale:
+            The new dataset scale, i.e. one of '10m', '50m', or '110m'.
+            Corresponding to 1:10,000,000, 1:50,000,000, and 1:110,000,000
+            respectively.
+
+        """
+        return NaturalEarthFeature(self.category, self.name, new_scale,
+                                   **self.kwargs)
+
 
 class GSHHSFeature(Feature):
     """
@@ -345,6 +360,9 @@ def intersecting_geometries(self, extent):
                               '110m', edgecolor='black', facecolor='none')
 """Small scale (1:110m) country boundaries."""
 
+STATES = NaturalEarthFeature('cultural', 'admin_1_states_provinces_lakes',
+                             '110m', edgecolor='black', facecolor='none')
+"""Small scale (1:110m) state and province boundaries."""
 
 COASTLINE = NaturalEarthFeature('physical', 'coastline', '110m',
                                 edgecolor='black', facecolor='none')


Test patch:
diff --git a/lib/cartopy/tests/test_features.py b/lib/cartopy/tests/test_features.py
new file mode 100644
--- /dev/null
+++ b/lib/cartopy/tests/test_features.py
@@ -0,0 +1,30 @@
+# (C) British Crown Copyright 2017, Met Office
+#
+# This file is part of cartopy.
+#
+# cartopy is free software: you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# cartopy is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with cartopy.  If not, see <https://www.gnu.org/licenses/>.
+
+from __future__ import (absolute_import, division, print_function)
+
+import cartopy.feature as cfeature
+
+
+class TestFeatures(object):
+    def test_change_scale(self):
+        # Check that features can easily be retrieved with a different scale.
+        new_lakes = cfeature.LAKES.with_scale('10m')
+        assert new_lakes.scale == '10m'
+        assert new_lakes.kwargs == cfeature.LAKES.kwargs
+        assert new_lakes.category == cfeature.LAKES.category
+        assert new_lakes.name == cfeature.LAKES.name