def plot_station_mapping(
    target_latitude,
    target_longitude,
    isd_station,
    distance_meters,
    target_label="target",
):  # pragma: no cover
    """ Plots this mapping on a map."""
    try:
        import matplotlib.pyplot as plt
    except ImportError:
        raise ImportError("Plotting requires matplotlib.")

    try:
        import cartopy.crs as ccrs
        import cartopy.feature as cfeature
        import cartopy.io.img_tiles as cimgt
    except ImportError:
        raise ImportError("Plotting requires cartopy.")

    lat, lng = isd_station.coords
    t_lat, t_lng = float(target_latitude), float(target_longitude)

    # fiture
    fig = plt.figure(figsize=(16, 8))

    # axes
    tiles = cimgt.StamenTerrain()
    ax = plt.subplot(1, 1, 1, projection=tiles.crs)

    # offsets for labels
    x_max = max([lng, t_lng])
    x_min = min([lng, t_lng])
    x_diff = x_max - x_min

    y_max = max([lat, t_lat])
    y_min = min([lat, t_lat])
    y_diff = y_max - y_min

    xoffset = x_diff * 0.05
    yoffset = y_diff * 0.05

    # minimum
    left = x_min - x_diff * 0.5
    right = x_max + x_diff * 0.5
    bottom = y_min - y_diff * 0.3
    top = y_max + y_diff * 0.3

    width_ratio = 2.
    height_ratio = 1.

    if (right - left) / (top - bottom) > width_ratio / height_ratio:
        # too short
        goal = (right - left) * height_ratio / width_ratio
        diff = goal - (top - bottom)
        bottom = bottom - diff / 2.
        top = top + diff / 2.
    else:
        # too skinny
        goal = (top - bottom) * width_ratio / height_ratio
        diff = goal - (right - left)
        left = left - diff / 2.
        right = right + diff / 2.

    ax.set_extent([left, right, bottom, top])

    # determine zoom level
    # tile size at level 1 = 64 km
    # level 2 = 32 km, level 3 = 16 km, etc, i.e. 128/(2^n) km
    N_TILES = 600  # (how many tiles approximately fit in distance)
    km = distance_meters / 1000.0
    zoom_level = int(np.log2(128 * N_TILES / km))

    ax.add_image(tiles, zoom_level)

    # line between
    plt.plot(
        [lng, t_lng],
        [lat, t_lat],
        linestyle="-",
        dashes=[2, 2],
        transform=ccrs.Geodetic(),
    )

    # station
    ax.plot(lng, lat, "ko", markersize=7, transform=ccrs.Geodetic())

    # target
    ax.plot(t_lng, t_lat, "ro", markersize=7, transform=ccrs.Geodetic())

    # station label
    station_label = "{} ({})".format(isd_station.usaf_id, isd_station.name)
    ax.text(lng + xoffset, lat + yoffset, station_label, transform=ccrs.Geodetic())

    # target label
    ax.text(t_lng + xoffset, t_lat + yoffset, target_label, transform=ccrs.Geodetic())

    # distance labels
    mid_lng = (lng + t_lng) / 2
    mid_lat = (lat + t_lat) / 2
    dist_text = "{:.01f} km".format(km)
    ax.text(mid_lng + xoffset, mid_lat + yoffset, dist_text, transform=ccrs.Geodetic())

    plt.show()