Patched setup.py file, replacing the original file.
June 25th 2019 by PY Barriat (ELIC - UCL)
--- Cartopy/cartopy-0.17.0/setup.py.orig	2018-11-17 08:25:32.000000000 +0100
+++ Cartopy/cartopy-0.17.0/setup.py		2019-06-25 14:28:37.989843991 +0200
@@ -1,4 +1,4 @@
-# (C) British Crown Copyright 2011 - 2018, Met Office
+# (C) British Crown Copyright 2011 - 2019, Met Office
 #
 # This file is part of cartopy.
 #
@@ -16,30 +16,41 @@
 # along with cartopy.  If not, see <https://www.gnu.org/licenses/>.
 from __future__ import print_function
 
-"""
-Distribution definition for Cartopy.
-
-"""
-
-import setuptools
-from setuptools import setup, Extension
-from setuptools import Command
-from setuptools import convert_path
-from distutils.spawn import find_executable
-from distutils.sysconfig import get_config_var
 import fnmatch
 import os
 import subprocess
 import sys
 import warnings
+from collections import defaultdict
+from distutils.spawn import find_executable
+from distutils.sysconfig import get_config_var
+
+from setuptools import Command, Extension, convert_path, setup
 
 import versioneer
 
+"""
+Distribution definition for Cartopy.
+
+"""
+
+
+
+
+# The existence of a PKG-INFO directory is enough to tell us whether this is a
+# source installation or not (sdist).
+HERE = os.path.dirname(__file__)
+IS_SDIST = os.path.exists(os.path.join(HERE, 'PKG-INFO'))
+
+if not IS_SDIST:
+    import Cython
+    if Cython.__version__ < '0.28':
+        raise ImportError(
+            "Cython 0.28+ is required to install cartopy from source.")
+
+    from Cython.Distutils import build_ext as cy_build_ext
+
 
-try:
-    from Cython.Distutils import build_ext
-except ImportError:
-    raise ImportError('Cython 0.15.1+ is required to install cartopy.')
 try:
     import numpy as np
 except ImportError:
@@ -52,8 +63,6 @@
 GEOS_MIN_VERSION = (3, 3, 3)
 PROJ_MIN_VERSION = (4, 9, 0)
 
-HERE = os.path.dirname(__file__)
-
 
 def file_walk_relative(top, remove=''):
     """
@@ -172,10 +181,7 @@
 
     geos_includes = []
     geos_library_dirs = []
-    if sys.platform.startswith('win'):
-        geos_libraries = ['geos']
-    else:
-        geos_libraries = ['geos_c']
+    geos_libraries = ['geos_c']
 else:
     if geos_version < GEOS_MIN_VERSION:
         print('GEOS version %s is installed, but cartopy requires at least '
@@ -230,6 +236,18 @@
     return proj_version
 
 
+def get_proj_libraries():
+    """
+    This function gets the PROJ libraries to cythonize with
+    """
+    proj_libraries = ["proj"]
+    if os.name == "nt" and proj_version >= (6, 0, 0):
+        proj_libraries = [
+            "proj_{}_{}".format(proj_version[0], proj_version[1])
+        ]
+    return proj_libraries
+
+
 conda = os.getenv('CONDA_DEFAULT_ENV')
 if conda is not None and conda in sys.prefix:
     # Conda does not provide pkg-config compatibility, but the search paths
@@ -245,7 +263,7 @@
         exit(1)
 
     proj_includes = []
-    proj_libraries = ['proj']
+    proj_libraries = get_proj_libraries()
     proj_library_dirs = []
 
 else:
@@ -268,7 +286,7 @@
             exit(1)
 
         proj_includes = []
-        proj_libraries = ['proj']
+        proj_libraries = get_proj_libraries()
         proj_library_dirs = []
     else:
         if proj_version < PROJ_MIN_VERSION:
@@ -283,8 +301,9 @@
             proj_includes = proj_includes.decode()
             proj_clibs = proj_clibs.decode()
 
-        proj_includes = [proj_include[2:] if proj_include.startswith('-I') else
-                         proj_include for proj_include in proj_includes.split()]      
+        proj_includes = [
+            proj_include[2:] if proj_include.startswith('-I') else
+            proj_include for proj_include in proj_includes.split()]
 
         proj_libraries = []
         proj_library_dirs = []
@@ -316,21 +335,90 @@
         return '.'
 include_dir = get_config_var('INCLUDEDIR')
 library_dir = get_config_var('LIBDIR')
-if sys.platform.startswith('win'):
-    extra_extension_args = {}
-else:
-    extra_extension_args = dict(
-        runtime_library_dirs=[get_config_var('LIBDIR')])
+extra_extension_args = defaultdict(list)
+if not sys.platform.startswith('win'):
+    extra_extension_args["runtime_library_dirs"].append(
+        get_config_var('LIBDIR')
+    )
 
 # Description
 # ===========
-
 with open(os.path.join(HERE, 'README.md'), 'r') as fh:
     description = ''.join(fh.readlines())
 
 
+cython_coverage_enabled = os.environ.get('CYTHON_COVERAGE', None)
+if proj_version >= (6, 0, 0):
+    extra_extension_args["define_macros"].append(
+        ('ACCEPT_USE_OF_DEPRECATED_PROJ_API_H', '1')
+    )
+if cython_coverage_enabled:
+    extra_extension_args["define_macros"].append(
+        ('CYTHON_TRACE_NOGIL', '1')
+    )
+
+extensions = [
+    Extension(
+        'cartopy.trace',
+        ['lib/cartopy/trace.pyx'],
+        include_dirs=([include_dir, './lib/cartopy', np.get_include()] +
+                      proj_includes + geos_includes),
+        libraries=proj_libraries + geos_libraries,
+        library_dirs=[library_dir] + proj_library_dirs + geos_library_dirs,
+        language='c++',
+        **extra_extension_args),
+    Extension(
+        'cartopy._crs',
+        ['lib/cartopy/_crs.pyx'],
+        include_dirs=[include_dir, np.get_include()] + proj_includes,
+        libraries=proj_libraries,
+        library_dirs=[library_dir] + proj_library_dirs,
+        **extra_extension_args),
+    # Requires proj v4.9
+    Extension(
+        'cartopy.geodesic._geodesic',
+        ['lib/cartopy/geodesic/_geodesic.pyx'],
+        include_dirs=[include_dir, np.get_include()] + proj_includes,
+        libraries=proj_libraries,
+        library_dirs=[library_dir] + proj_library_dirs,
+        **extra_extension_args),
+]
+
+
+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.
+    for extension in extensions:
+        sources = []
+        for sfile in extension.sources:
+            path, ext = os.path.splitext(sfile)
+            if ext in ('.pyx',):
+                if extension.language == 'c++':
+                    ext = '.cpp'
+                else:
+                    ext = '.c'
+                sfile = path + ext
+            sources.append(sfile)
+        extension.sources[:] = sources
+    return extensions
+
+
 cmdclass = versioneer.get_cmdclass()
-cmdclass.update({'build_ext': build_ext})
+
+if IS_SDIST:
+    extensions = decythonize(extensions)
+else:
+    cmdclass.update({'build_ext': cy_build_ext})
 
 
 # Main setup
@@ -371,37 +459,9 @@
 
 
     # requires proj headers
-    ext_modules=[
-        Extension(
-            'cartopy.trace',
-            ['lib/cartopy/trace.pyx', 'lib/cartopy/_trace.cpp'],
-            include_dirs=[include_dir,
-                          './lib/cartopy'] + proj_includes + geos_includes,
-            libraries=proj_libraries + geos_libraries,
-            library_dirs=[library_dir] + proj_library_dirs + geos_library_dirs,
-            language='c++',
-            **extra_extension_args
-        ),
-        Extension(
-            'cartopy._crs',
-            ['lib/cartopy/_crs.pyx'],
-            include_dirs=[include_dir, np.get_include()] + proj_includes,
-            libraries=proj_libraries,
-            library_dirs=[library_dir] + proj_library_dirs,
-            **extra_extension_args
-        ),
-        # Requires proj v4.9
-        Extension(
-            'cartopy.geodesic._geodesic',
-            ['lib/cartopy/geodesic/_geodesic.pyx'],
-            include_dirs=[include_dir, np.get_include()] + proj_includes,
-            libraries=proj_libraries,
-            library_dirs=[library_dir] + proj_library_dirs,
-            **extra_extension_args
-        ),
-    ],
-
+    ext_modules=extensions,
     cmdclass=cmdclass,
+    python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
     classifiers=[
             'Development Status :: 4 - Beta',
             'License :: OSI Approved :: GNU Lesser General Public License v3 '
@@ -416,9 +476,9 @@
             'Programming Language :: Python :: 2',
             'Programming Language :: Python :: 2.7',
             'Programming Language :: Python :: 3',
-            'Programming Language :: Python :: 3.3',
-            'Programming Language :: Python :: 3.4',
             'Programming Language :: Python :: 3.5',
+            'Programming Language :: Python :: 3.6',
+            'Programming Language :: Python :: 3.7',
             'Topic :: Scientific/Engineering',
             'Topic :: Scientific/Engineering :: GIS',
             'Topic :: Scientific/Engineering :: Visualization',
