Repository: SciTools/cartopy

Issue:
inline tick labels outside map boundary
### Description

Tickels that are plotted with `x/y_inline = True` may be outside map boundary, like in the code below.
I didn' took time to investigate it.


#### Code to reproduce
```python
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
rotated_crs = ccrs.RotatedPole(pole_longitude=120.0, pole_latitude=70.0)
plt.figure(figsize=(6, 6))
ax = plt.axes(projection=rotated_crs)
ax.set_extent([-6, 3, 48, 58], crs=ccrs.PlateCarree())
ax.coastlines(resolution='50m')
ax.gridlines(draw_labels=True, x_inline=True, y_inline=True)
plt.show()
```
![inline_bug](https://user-images.githubusercontent.com/1941408/79310712-ab5bcd00-7efc-11ea-9403-796104d29dc2.png)



Discussion:
I think this is because it uses `Axes.text` which defaults to `clip_on=False`, but turning it on doesn't seem to clip it.
This is related to #1422, as `clip_on=True` plus reverting that change fixes the clipping, but I'm not sure why it only affects `Text`, and not everything else.
Potentially an instance of https://github.com/matplotlib/matplotlib/issues/8270?

Resolving patch:
diff --git a/lib/cartopy/mpl/gridliner.py b/lib/cartopy/mpl/gridliner.py
--- a/lib/cartopy/mpl/gridliner.py
+++ b/lib/cartopy/mpl/gridliner.py
@@ -599,6 +599,7 @@ def _draw_gridliner(self, nx=None, ny=None, renderer=None):
                                     continue
                                 x = x_midpoints[i]
                                 y = tick_value
+                                kw.update(clip_on=True)
                                 y_set = True
                             else:
                                 x = pt0[0]
@@ -609,6 +610,7 @@ def _draw_gridliner(self, nx=None, ny=None, renderer=None):
                                     continue
                                 x = tick_value
                                 y = y_midpoints[i]
+                                kw.update(clip_on=True)
                             elif not y_set:
                                 y = pt0[1]
 
@@ -739,10 +741,10 @@ def remove_path_dupes(path):
                 warnings.warn('The labels of this gridliner do not belong to '
                               'the gridliner axes')
 
-            # Compute angles to try
             orig_specs = {'rotation': artist.get_rotation(),
                           'ha': artist.get_ha(),
                           'va': artist.get_va()}
+            # Compute angles to try
             angles = [None]
             for abs_delta_angle in np.arange(delta_angle, max_delta_angle+1,
                                              delta_angle):
@@ -765,6 +767,8 @@ def remove_path_dupes(path):
                     this_patch.get_transform())
                 if '3.1.0' <= matplotlib.__version__ <= '3.1.2':
                     this_path = remove_path_dupes(this_path)
+                center = artist.get_transform().transform_point(
+                    artist.get_position())
                 visible = False
 
                 for path in paths:
@@ -781,9 +785,16 @@ def remove_path_dupes(path):
                                         .transformed(self.axes.transData))
                         if '3.1.0' <= matplotlib.__version__ <= '3.1.2':
                             outline_path = remove_path_dupes(outline_path)
-                    visible = (not outline_path.intersects_path(this_path) or
-                               (lonlat == 'lon' and self.x_inline) or
-                               (lonlat == 'lat' and self.y_inline))
+                    # Inline must be within the map.
+                    if ((lonlat == 'lon' and self.x_inline) or
+                            (lonlat == 'lat' and self.y_inline)):
+                        # TODO: When Matplotlib clip path works on text, this
+                        # clipping can be left to it.
+                        if outline_path.contains_point(center):
+                            visible = True
+                    # Non-inline must not run through the outline.
+                    elif not outline_path.intersects_path(this_path):
+                        visible = True
 
                     # Good
                     if visible:


Test patch:
diff --git a/lib/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline_usa.png b/lib/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline_usa.png
Binary files a/lib/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline_usa.png and b/lib/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline_usa.png differ
diff --git a/lib/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline_usa_1.5.png b/lib/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline_usa_1.5.png
Binary files a/lib/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline_usa_1.5.png and b/lib/cartopy/tests/mpl/baseline_images/mpl/test_gridliner/gridliner_labels_inline_usa_1.5.png differ