internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: SciTools/cartopy

Issue:
small-scale OSM example
Please add an example of using _cartopy.io.img_tiles.OSM_ for small scale (such as town-scale) mapping.

Also, it's not in the index.



Discussion:
Good idea. Thanks for the suggestion. In the meantime I've created a gist with an example here: http://nbviewer.ipython.org/gist/pelson/8912530


Resolving patch:
diff --git a/lib/cartopy/examples/tube_stations.py b/lib/cartopy/examples/tube_stations.py
new file mode 100644
--- /dev/null
+++ b/lib/cartopy/examples/tube_stations.py
@@ -0,0 +1,70 @@
+__tags__ = ['Miscellanea']
+"""
+Produces a map showing London Underground station locations with high
+resolution background imagery provided by MapQuest.
+
+"""
+from matplotlib.path import Path
+import matplotlib.pyplot as plt
+import numpy as np
+
+import cartopy.crs as ccrs
+from cartopy.io.img_tiles import MapQuestOSM
+
+
+def tube_locations():
+    """
+    Returns an (n, 2) array of selected London Tube locations in Ordnance
+    Survey GB coordinates.
+
+    Source: http://www.doogal.co.uk/london_stations.php
+
+    """
+    return np.array([[531738., 180890.], [532379., 179734.],
+                     [531096., 181642.], [530234., 180492.],
+                     [531688., 181150.], [530242., 180982.],
+                     [531940., 179144.], [530406., 180380.],
+                     [529012., 180283.], [530553., 181488.],
+                     [531165., 179489.], [529987., 180812.],
+                     [532347., 180962.], [529102., 181227.],
+                     [529612., 180625.], [531566., 180025.],
+                     [529629., 179503.], [532105., 181261.],
+                     [530995., 180810.], [529774., 181354.],
+                     [528941., 179131.], [531050., 179933.],
+                     [530240., 179718.]])
+
+
+def main():
+    imagery = MapQuestOSM()
+
+    ax = plt.axes(projection=imagery.crs)
+    ax.set_extent((-0.14, -0.1, 51.495, 51.515))
+
+    # Construct concentric circles and a rectangle,
+    # suitable for a London Underground logo.
+    theta = np.linspace(0, 2 * np.pi, 100)
+    circle_verts = np.vstack([np.sin(theta), np.cos(theta)]).T
+    concentric_circle = Path.make_compound_path(Path(circle_verts[::-1]),
+                                                Path(circle_verts * 0.6))
+
+    rectangle = Path([[-1.1, -0.2], [1, -0.2], [1, 0.3], [-1.1, 0.3]])
+
+    # Add the imagery to the map.
+    ax.add_image(imagery, 14)
+
+    # Plot the locations twice, first with the red concentric circles,
+    # then with the blue rectangle.
+    xs, ys = tube_locations().T
+    plt.plot(xs, ys, transform=ccrs.OSGB(),
+             marker=concentric_circle, color='red', markersize=9,
+             linestyle='')
+    plt.plot(xs, ys, transform=ccrs.OSGB(),
+             marker=rectangle, color='blue', markersize=11,
+             linestyle='')
+
+    plt.title('London underground locations')
+    plt.show()
+
+
+if __name__ == '__main__':
+    main()


Test patch:
Repository: SciTools/cartopy

Issue:
Increase tolerance of test_pcolormesh_mercator_wrap.
This is the only test that is affected by matplotlib/matplotlib#15970. The new image is correct, but the difference is small enough to just change the tolerance.


Discussion:

Resolving patch:
diff --git a/lib/cartopy/io/srtm.py b/lib/cartopy/io/srtm.py
--- a/lib/cartopy/io/srtm.py
+++ b/lib/cartopy/io/srtm.py
@@ -167,8 +167,8 @@ def SRTM3_retrieve(lon, lat):
     None will be returned.
 
     """
-    x = '%s%03d' % ('E' if lon > 0 else 'W', abs(int(lon)))
-    y = '%s%02d' % ('N' if lat > 0 else 'S', abs(int(lat)))
+    x = '%s%03d' % ('E' if lon >= 0 else 'W', abs(int(lon)))
+    y = '%s%02d' % ('N' if lat >= 0 else 'S', abs(int(lat)))
 
     srtm_downloader = Downloader.from_config(('SRTM', 'SRTM3'))
     params = {'config': config, 'x': x, 'y': y}


Test patch:
Repository: SciTools/cartopy

Issue:
AttributeError: 'LineString' object has no attribute 'exterior'
Running the first example from #13 prints this (snipped) traceback:

```
  File ".../matplotlib/transforms.py", line 2227, in transform_path_non_affine
    return self._a.transform_path_non_affine(path)
  File ".../Cartopy-0.12.x-py2.7-linux-x86_64.egg/cartopy/mpl/geoaxes.py", line 169, in transform_path_non_affine
    getattr(self, 'force_path_ccw', False))
  File ".../Cartopy-0.12.x-py2.7-linux-x86_64.egg/cartopy/mpl/patch.py", line 226, in path_to_geos
    if force_ccw and not geom.exterior.is_ccw:
AttributeError: 'LineString' object has no attribute 'exterior'
```

I'm not sure if this can be triggered by other (i.e., not otherwise known to be broken) usage.



Discussion:
Thanks @QuLogic - looks like an extra check needs to be added to https://github.com/SciTools/cartopy/blob/master/lib/cartopy/mpl/patch.py#L226


Resolving patch:
diff --git a/lib/cartopy/mpl/patch.py b/lib/cartopy/mpl/patch.py
--- a/lib/cartopy/mpl/patch.py
+++ b/lib/cartopy/mpl/patch.py
@@ -213,7 +213,7 @@ def path_to_geos(path, force_ccw=False):
 
     # Convert each (external_geom, [internal_polygons]) pair into a
     # a shapely Polygon that encapsulates the internal polygons, if the
-    # external geom is a LineSting leave it alone.
+    # external geom is a LineString leave it alone.
     geom_collection = []
     for external_geom, internal_polys in collection:
         if internal_polys:
@@ -223,8 +223,9 @@ def path_to_geos(path, force_ccw=False):
             geom = external_geom
 
         # Correctly orientate the polygon (ccw)
-        if force_ccw and not geom.exterior.is_ccw:
-            geom = shapely.geometry.polygon.orient(geom)
+        if isinstance(geom, Polygon):
+            if force_ccw and not geom.exterior.is_ccw:
+                geom = shapely.geometry.polygon.orient(geom)
 
         geom_collection.append(geom)
 


Test patch:
Repository: SciTools/cartopy

Issue:
Invalid WIDTH value, NumberFormatException when using WMS
I am not sure if this is a cartopy bug or if I am doing something wrong.  The code below fails to create an image with the error,

``` python
Invalid WIDTH value, NumberFormatException : For input string: "273.379119692"
```

I notice that, if I force the `width` and `height` to be integers, at slippy_image_artist.py line 55, the figure is created (but I am not sure if I mess up the proportions).

Other WebMapService URLs work fine with the width and height as float.  Just some, like the one below, fails.

``` python
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER

from owslib.wms import WebMapService
url = "http://nowcoast.noaa.gov/wms/com.esri.wms.Esrimap/analyses"
wms = WebMapService(url)

subplot_kw = dict(projection=ccrs.PlateCarree())
fig, ax = plt.subplots(subplot_kw=subplot_kw)
ax.set_extent([-42, 0, -32, 0.5])
ax.add_wms(wms, 'NCEP_RAS_ANAL_RTG_SST')

gl = ax.gridlines(draw_labels=True)
gl.xlabels_top = gl.ylabels_right = False
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
```

Thanks,

-Filipe



Discussion:
It seems kind of crazy to request floating point pixels, so it would be nice if cartopy/owslib could round to nearest integer pixel, no?

This was also asked (unanswered) here:
https://groups.google.com/forum/#!searchin/scitools-iris/Filipe/scitools-iris/rpELfZtdDto/RVo7_kZkEyoJ

Ultimately it boils down to the following URL being passed to OWSLib:

Bad URL (floats):

http://nowcoast.noaa.gov:80/wms/com.esri.wms.Esrimap/analyses?layers=NCEP_RAS_ANAL_RTG_SST&styles=&srs=EPSG%3A4326&format=image%2Fpng&request=GetMap&bgcolor=0xFFFFFF&height=392.0&width=480.0&version=1.1.1&bbox=-42.0%2C-33.790841270378365%2C0.0%2C0.5&exceptions=application%2Fvnd.ogc.se_xml&transparent=TRUE

Good URL (ints):
http://nowcoast.noaa.gov:80/wms/com.esri.wms.Esrimap/analyses?layers=NCEP_RAS_ANAL_RTG_SST&styles=&srs=EPSG%3A4326&format=image%2Fpng&request=GetMap&bgcolor=0xFFFFFF&height=392&width=480&version=1.1.1&bbox=-42.0%2C-33.790841270378365%2C0.0%2C0.5&exceptions=application%2Fvnd.ogc.se_xml&transparent=TRUE

Closed by #587. Thanks for reporting @ocefpaf - this will be fixed by v0.12.0.


Resolving patch:
diff --git a/lib/cartopy/io/ogc_clients.py b/lib/cartopy/io/ogc_clients.py
--- a/lib/cartopy/io/ogc_clients.py
+++ b/lib/cartopy/io/ogc_clients.py
@@ -233,7 +233,7 @@ def _image_and_extent(self, wms_proj, wms_srs, wms_extent, output_proj,
 
     def fetch_raster(self, projection, extent, target_resolution):
         min_x, max_x, min_y, max_y = extent
-        target_resolution = [np.ceil(val) for val in target_resolution]
+        target_resolution = [int(np.ceil(val)) for val in target_resolution]
         wms_srs = self._native_srs(projection)
         if wms_srs is not None:
             wms_proj = projection


Test patch:
Repository: SciTools/cartopy

Issue:
Installing cartopy with pip fails - no cython found and is not a requirement
Installing cartopy on an Ubuntu 14.04 with Python 3 using pip

```
pip install cartopy
```

I get the error

```
Collecting cartopy
  Using cached Cartopy-0.13.0.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "/tmp/pip-build-_hya0obf/cartopy/setup.py", line 36, in <module>
        from Cython.Distutils import build_ext
    ImportError: No module named 'Cython'

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-_hya0obf/cartopy/setup.py", line 38, in <module>
        raise ImportError('Cython 0.15.1+ is required to install cartopy.')
    ImportError: Cython 0.15.1+ is required to install cartopy.
```

I have to manually install `cython` on the same virtualenv:

```
pip install cython
```

and after that I have to issue again the `cartopy` install command:

```
pip install cartopy
```

and now works. 



Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,4 @@
-# (C) British Crown Copyright 2011 - 2015, Met Office
+# (C) British Crown Copyright 2011 - 2016, Met Office
 #
 # This file is part of cartopy.
 #
@@ -21,6 +21,7 @@
 
 """
 
+import setuptools
 from setuptools import setup, Extension
 from setuptools import Command
 from setuptools import convert_path
@@ -32,6 +33,14 @@
 import sys
 import warnings
 
+
+# Ensure build-time dependencies are available.
+# See http://stackoverflow.com/a/12061891
+setuptools.dist.Distribution(
+    dict(
+        setup_requires=['Cython>=0.15.1', 'numpy>=1.6']))
+
+
 try:
     from Cython.Distutils import build_ext
 except ImportError:


Test patch:
Repository: SciTools/cartopy

Issue:
cartopy (assume GEOS via shapely) sometimes emits "Self-intersection at or near point" and/or "Too few points in geometry component at or near point"
I run hundreds of cartopy jobs per day to generate plots via cron.  Of course, when something comes to `stderr` or `stdout`, an email to me is generated denoting the content.  Placing aside the issue of this workflow efficacy, it would be nice to figure out a way to quell messages like these coming from the cartopy stack.  I see messages like this less than 1% of the time.

```
Self-intersection at or near point -8916691.2125412114 4223162.8982788026
```
and/or
```
Too few points in geometry component at or near point -10230261.203901839
5099199.1645516697
```

So I figured I would file an issue and will attempt to create a self contained reproducer.



Discussion:
I am closer to a SSCCE now and just wanted to log that this message is emitted from line 565 of crs.py with the `is_valid` call.

```python
            for ring in interior_rings:
                polygon = sgeom.Polygon(ring)
                if polygon.is_valid:
                    x1, y1, x2, y2 = polygon.bounds
```
and example bad `LINEARRING`
```
LINEARRING (-8916691.212541211 4569429.375334413, 
-8916691.212541211 4569429.375334413, -8916691.212541211 4569429.375334413, 
-8916691.212541211 4569429.375334414, -8916691.212541211 4569429.375334418, 
-8916691.212541211 4569429.375334414, -8916691.212541211 4569429.375334413)
```
Still working on how this self intersecting ring is created. :)

Resolving patch:
diff --git a/lib/cartopy/crs.py b/lib/cartopy/crs.py
--- a/lib/cartopy/crs.py
+++ b/lib/cartopy/crs.py
@@ -561,8 +561,9 @@ def _rings_to_multi_polygon(self, rings, is_ccw):
             x4 += bx
             y4 += by
             for ring in interior_rings:
-                polygon = sgeom.Polygon(ring)
-                if polygon.is_valid:
+                # Use shapely buffer in an attempt to fix invalid geometries
+                polygon = sgeom.Polygon(ring).buffer(0)
+                if not polygon.is_empty and polygon.is_valid:
                     x1, y1, x2, y2 = polygon.bounds
                     bx = (x2 - x1) * 0.1
                     by = (y2 - y1) * 0.1


Test patch:
Repository: SciTools/cartopy

Issue:
Doc: gallery code links don't need to be underlined
As an example, https://2-5282596-gh.circle-artifacts.com/0/root/project/docs/build/html/gallery/miscellanea/star_shaped_boundary.html#sphx-glr-gallery-miscellanea-star-shaped-boundary-py has all of the functions that have links underlined. This adds visual noise that distracts from the message.

We want to keep the links, but define the CSS to avoid the underlining.


Discussion:
We fixed this in MetPy by putting `theme_override.css` in `docs/_static`:

https://github.com/Unidata/MetPy/blob/d66e868e10cb74dfa397f012849f0c6aa01a6416/docs/_static/theme_override.css#L1-L8

It's not pretty, but it's better than the underline.
The following will do the trick.

```
+pre a {
+    // Prevent code examples showing underlines.
+    text-decoration: none !important;
+}
+
```


I'll make a PR with it later on.

Resolving patch:
diff --git a/docs/source/sphinxext/pre_sphinx_gallery.py b/docs/source/sphinxext/pre_sphinx_gallery.py
--- a/docs/source/sphinxext/pre_sphinx_gallery.py
+++ b/docs/source/sphinxext/pre_sphinx_gallery.py
@@ -47,13 +47,12 @@ def example_groups(src_dir):
 
     for fname in sorted_listdir:
         fpath = os.path.join(src_dir, fname)
-        __tags__ = []
         with open(fpath, 'r') as fh:
             for line in fh:
                 # Crudely remove the __tags__ line.
                 if line.startswith('__tags__ = '):
                     exec(line.strip(), locals(), globals())
-                    for tag in __tags__:
+                    for tag in __tags__:  # noqa:
                         tagged_examples.setdefault(tag, []).append(fname)
                     break
             else:


Test patch:
Repository: SciTools/cartopy

Issue:
Adjust `setup.py` to reflect PEP-518, instead of throwing a "you need cython" error.
### Description
Fix `setup.py` to install `cython`, instead of giving the user an error. 

https://github.com/pypa/pip/issues/5761#issuecomment-418395650
https://www.python.org/dev/peps/pep-0518/



#### Code to reproduce
On a fresh vitrual enviroment:
```bash
pip install cartopy
```

#### Traceback 

```
(mypython) me@my_laptop:~/path/tmp$ python
Python 3.5.3+ (default, Nov 29 2017, 08:55:08) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
(mypython) me@my_laptop:~/path/tmp$ pip install cartopy
Collecting cartopy
  Using cached https://files.pythonhosted.org/packages/f5/7a/4a16db7c81f11b3c5889c5b913d9a5724c704a6947c5a87ec59c4a8985ac/Cartopy-0.16.0.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "/tmp/pip-install-7r1fl7u1/cartopy/setup.py", line 47, in <module>
        from Cython.Distutils import build_ext
    ImportError: No module named 'Cython'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-install-7r1fl7u1/cartopy/setup.py", line 49, in <module>
        raise ImportError('Cython 0.15.1+ is required to install cartopy.')
    ImportError: Cython 0.15.1+ is required to install cartopy.
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-7r1fl7u1/cartopy/

```


### Operating system
Ubuntu 16.04



Discussion:
Technically, that's not adding PEP 518 support, just fixing the existing workaround so it works with `setuptools>=36.7.0`.

For PEP 518 support, a new `pyproject.toml` file should be added:
```toml
[build-system]
requires = ["Cython>=0.15.1", "numpy>=1.10", "setuptools", "wheel"]
```

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -36,13 +36,6 @@
 import versioneer
 
 
-# Ensure build-time dependencies are available.
-# See https://stackoverflow.com/a/12061891
-setuptools.dist.Distribution(
-    dict(
-        setup_requires=['Cython>=0.15.1', 'numpy>=1.10']))
-
-
 try:
     from Cython.Distutils import build_ext
 except ImportError:


Test patch:
Repository: SciTools/cartopy

Issue:
SRTM path in USGS server changed
My SRTMDownloader can no longer find SRTM data in the usual location. Please change 

```
_SRTM_BASE_URL = ('https://e4ftl01.cr.usgs.gov/SRTM/SRTMGL{resolution}.'
                      '003/2000.02.11/')
```
to
```
_SRTM_BASE_URL = ('https://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL{resolution}.'
                      '003/2000.02.11/')
```


Discussion:

Resolving patch:
diff --git a/lib/cartopy/io/srtm.py b/lib/cartopy/io/srtm.py
--- a/lib/cartopy/io/srtm.py
+++ b/lib/cartopy/io/srtm.py
@@ -393,8 +393,8 @@ class SRTMDownloader(Downloader):
     """
     FORMAT_KEYS = ('config', 'resolution', 'x', 'y')
 
-    _SRTM_BASE_URL = ('https://e4ftl01.cr.usgs.gov/SRTM/SRTMGL{resolution}.'
-                      '003/2000.02.11/')
+    _SRTM_BASE_URL = ('https://e4ftl01.cr.usgs.gov/MEASURES/'
+                      'SRTMGL{resolution}.003/2000.02.11/')
     _SRTM_LOOKUP_CACHE = os.path.join(os.path.dirname(__file__),
                                       'srtm.npz')
     _SRTM_LOOKUP_MASK = np.load(_SRTM_LOOKUP_CACHE)['mask']


Test patch:
diff --git a/lib/cartopy/tests/io/test_srtm.py b/lib/cartopy/tests/io/test_srtm.py
--- a/lib/cartopy/tests/io/test_srtm.py
+++ b/lib/cartopy/tests/io/test_srtm.py
@@ -26,6 +26,8 @@
 import cartopy.crs as ccrs
 import cartopy.io.srtm
 
+from .test_downloaders import download_to_temp  # noqa: F401 (used as fixture)
+
 
 pytestmark = [pytest.mark.skip('SRTM login not supported'),
               pytest.mark.network]
@@ -89,8 +91,10 @@ def test_out_of_range(self, Source):
     def test_in_range(self, Source):
         if Source == cartopy.io.srtm.SRTM3Source:
             shape = (1201, 1201)
-        elif Source == cartopy.io.srtm.SRTM3Source:
+        elif Source == cartopy.io.srtm.SRTM1Source:
             shape = (3601, 3601)
+        else:
+            raise ValueError('Source is of unexpected type.')
         source = Source()
         img, crs, extent = source.single_tile(-1, 50)
         assert isinstance(img, np.ndarray)
Repository: SciTools/cartopy

Issue:
cartopy.geodesic is undocumented
When looking for the functionality, I realised that ``cartopy.geodesic`` is completely undocumented on http://scitools.org.uk/cartopy/docs/v0.15/cartopy_outline.html#cartopy-geodesic. 

It would be great to fix that....


Discussion:

Resolving patch:
diff --git a/docs/source/conf.py b/docs/source/conf.py
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -124,7 +124,7 @@
 exclude_patterns = []
 
 # The reST default role (used for this markup: `text`) to use for all documents.
-# default_role = None
+default_role = 'py:obj'
 
 # If true, '()' will be appended to :func: etc. cross-reference text.
 # add_function_parentheses = True
@@ -347,6 +347,7 @@
 # Example configuration for intersphinx: refer to the Python standard library.
 intersphinx_mapping = {'python': ('https://docs.python.org/3', None),
                        'matplotlib': ('https://matplotlib.org', None),
+                       'numpy': ('https://docs.scipy.org/doc/numpy/', None),
                        'shapely': ('http://toblerity.org/shapely', None), }
 
 
diff --git a/lib/cartopy/geodesic/__init__.py b/lib/cartopy/geodesic/__init__.py
--- a/lib/cartopy/geodesic/__init__.py
+++ b/lib/cartopy/geodesic/__init__.py
@@ -1,4 +1,4 @@
-# (C) British Crown Copyright 2015 - 2017, Met Office
+# (C) British Crown Copyright 2015 - 2018, Met Office
 #
 # This file is part of cartopy.
 #
@@ -19,3 +19,6 @@
 
 # NOTE: noqa for flake8 = unused import
 from cartopy.geodesic._geodesic import Geodesic  # noqa: F401
+
+# Need to be explicit because it's from a 'different' module.
+__document_these__ = ['Geodesic']


Test patch:
Repository: SciTools/cartopy

Issue:
New release
Latest release is from Feb 21st and there were many improvements and bugfixes since then. (Some people are particular interested in https://github.com/SciTools/cartopy/pull/1150 and https://github.com/SciTools/cartopy/pull/1148)

Maybe it is time to issue a new release :grimacing: 


Discussion:
It's planned for next week.
After in-person discussion with @pelson last week, we decided to push one extra week--to 16 November. This coincides with the Met Office's development schedule. That date is a hard deadline: whatever is unmerged/unfixed will wait for the next release, which will not languish for 9 months.
BTW, I don't know who's going to generate the docs for the release (assuming it's not me), but please use Proj 5.2.0 when doing so.
I'll do it since I've volunteered to be release manager. My last task on this release is the "What's New".
Ugh, conda-forge is currently pinned to Proj 4.9.3. I can build cartopy locally against 5.2.0, but we need to get that updated for the good of the stack.
The soname was bumped, so it had to be one or the other. And our release never worked with >4.9.3 at the time.

Resolving patch:
diff --git a/lib/cartopy/feature/__init__.py b/lib/cartopy/feature/__init__.py
--- a/lib/cartopy/feature/__init__.py
+++ b/lib/cartopy/feature/__init__.py
@@ -152,8 +152,7 @@ def scale_from_extent(self, extent):
 
 class AdaptiveScaler(Scaler):
     """
-    Object for changing scales of geometries based on extent of axes used to
-    plot geometries.
+    Automatically select scale of geometries based on extent of plotted axes.
     """
     def __init__(self, default_scale, limits):
         """
@@ -167,7 +166,8 @@ def __init__(self, default_scale, limits):
             tuple of tuples ordered from coarsest to finest scales. Limit
             values are the upper bounds for their corresponding scale.
 
-        Example:
+        Example
+        -------
 
         >>> s = AdaptiveScaler('coarse',
         ...           (('intermediate', 30), ('fine', 10)))


Test patch:
Repository: SciTools/cartopy

Issue:
Add coveralls
Add code coverage testing (via pytest-cov) to cartopy.


Discussion:
Awesome addition @lbdreyer, thanks! Could you rebase this PR so it can be merged please?

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -334,6 +334,12 @@ def get_config_var(name):
     description = ''.join(fh.readlines())
 
 
+cython_coverage_enabled = os.environ.get('CYTHON_COVERAGE', None)
+if cython_coverage_enabled:
+    extra_cython_args = {'define_macros': [('CYTHON_TRACE_NOGIL', '1')]}
+    extra_extension_args.update(extra_cython_args)
+
+
 extensions = [
     Extension(
         'cartopy.trace',
@@ -362,6 +368,16 @@ def get_config_var(name):
 ]
 
 
+if cython_coverage_enabled:
+    # We need to explicitly cythonize the extension in order
+    # to control the Cython compiler_directives.
+    from Cython.Build import cythonize
+
+    directives = {'linetrace': True,
+                  'binding': True}
+    extensions = cythonize(extensions, compiler_directives=directives)
+
+
 def decythonize(extensions, **_ignore):
     # Remove pyx sources from extensions.
     # Note: even if there are changes to the pyx files, they will be ignored.


Test patch: