Esempio n. 1
0
def test_eccentric_globe():
    globe = ccrs.Globe(semimajor_axis=10000, semiminor_axis=5000, ellipse=None)
    crs = ccrs.Mercator(globe=globe, min_latitude=-40, max_latitude=40)
    other_args = {
        'a=10000', 'b=5000', 'lon_0=0.0', 'x_0=0.0', 'y_0=0.0', 'units=m'
    }
    check_proj_params('merc', crs, other_args)

    assert_almost_equal(crs.boundary.bounds,
                        [-31415.93, -2190.5, 31415.93, 2190.5],
                        decimal=2)

    assert_almost_equal(crs.x_limits, [-31415.93, 31415.93], decimal=2)
    assert_almost_equal(crs.y_limits, [-2190.5, 2190.5], decimal=2)
Esempio n. 2
0
def test_ellipse_globe():
    globe = ccrs.Globe(ellipse='WGS84')
    with pytest.warns(UserWarning,
                      match='does not handle elliptical globes.') as w:
        robin = ccrs.Robinson(globe=globe)
        assert len(w) == 1

    other_args = {'ellps=WGS84', 'lon_0=0'}
    check_proj_params('robin', robin, other_args)

    # Limits are the same as default since ellipses are not supported.
    assert_almost_equal(robin.x_limits, [-17005833.3305252, 17005833.3305252])
    assert_almost_equal(robin.y_limits, [-8625154.6651000, 8625154.6651000],
                        _LIMIT_TOL)
Esempio n. 3
0
def test_scale_factor():
    # Should be same as lat_ts=20 for a sphere
    scale_factor = 0.939692620786
    crs = ccrs.Mercator(scale_factor=scale_factor,
                        globe=ccrs.Globe(ellipse='sphere'))
    other_args = {
        'ellps=sphere', 'lon_0=0.0', 'x_0=0.0', 'y_0=0.0', 'units=m',
        'k_0={:.12f}'.format(scale_factor)
    }
    check_proj_params('merc', crs, other_args)

    assert_almost_equal(crs.boundary.bounds,
                        [-18808021, -14585266, 18808021, 17653216],
                        decimal=0)
Esempio n. 4
0
def test_eccentric_globe():
    globe = ccrs.Globe(semimajor_axis=1000, semiminor_axis=500, ellipse=None)
    eqearth = ccrs.EqualEarth(globe=globe)
    other_args = {'a=1000', 'b=500', 'lon_0=0'}
    check_proj_params('eqearth', eqearth, other_args)

    assert_almost_equal(eqearth.x_limits,
                        [-2248.43664092550, 2248.43664092550])
    assert_almost_equal(eqearth.y_limits,
                        [-1094.35228122148, 1094.35228122148])
    # Expected aspect ratio from the paper.
    assert_almost_equal(np.diff(eqearth.x_limits) / np.diff(eqearth.y_limits),
                        2.05458,
                        decimal=5)
Esempio n. 5
0
def test_eccentric_globe():
    globe = ccrs.Globe(semimajor_axis=1000, semiminor_axis=500, ellipse=None)
    with pytest.warns(UserWarning,
                      match='does not handle elliptical globes.') as w:
        robin = ccrs.Robinson(globe=globe)
        assert len(w) == 1

    other_args = {'a=1000', 'b=500', 'lon_0=0'}
    check_proj_params('robin', robin, other_args)

    # Limits are the same as spheres since ellipses are not supported.
    assert_almost_equal(robin.x_limits, [-2666.2696851, 2666.2696851])
    assert_almost_equal(robin.y_limits, [-1352.3000000, 1352.3000000],
                        _LIMIT_TOL)
    def test_eccentric_globe(self):
        globe = ccrs.Globe(semimajor_axis=1000, semiminor_axis=500,
                           ellipse=None)
        eqdc = ccrs.EquidistantConic(globe=globe)
        other_args = {'a=1000', 'b=500', 'lon_0=0.0', 'lat_0=0.0', 'x_0=0.0',
                      'y_0=0.0', 'lat_1=20.0', 'lat_2=50.0'}
        check_proj4_params(eqdc, other_args)

        assert_almost_equal(np.array(eqdc.x_limits),
                            (-3016.869847713461, 3016.869847713461),
                            decimal=7)
        assert_almost_equal(np.array(eqdc.y_limits),
                            (-1216.6029342241113, 2511.0574375797723),
                            decimal=7)
Esempio n. 7
0
def test_eccentric_globe():
    globe = ccrs.Globe(semimajor_axis=1000, semiminor_axis=500,
                       ellipse=None)
    with pytest.warns(UserWarning,
                      match='does not handle elliptical globes.') as w:
        gnom = ccrs.Gnomonic(globe=globe)
        assert len(w) == 1

    other_args = {'a=1000', 'b=500', 'lon_0=0.0', 'lat_0=0.0'}
    check_proj_params('gnom', gnom, other_args)

    # Limits are the same as spheres since ellipses are not supported.
    assert_almost_equal(gnom.x_limits, [-5e7, 5e7])
    assert_almost_equal(gnom.y_limits, [-5e7, 5e7])
Esempio n. 8
0
    def test_eccentric_globe(self):
        globe = ccrs.Globe(semimajor_axis=1000, semiminor_axis=500,
                           ellipse=None)
        aea = ccrs.AlbersEqualArea(globe=globe)
        other_args = {'a=1000', 'b=500', 'lon_0=0.0', 'lat_0=0.0', 'x_0=0.0',
                      'y_0=0.0', 'lat_1=20.0', 'lat_2=50.0'}
        check_proj_params('aea', aea, other_args)

        assert_almost_equal(np.array(aea.x_limits),
                            [-2323.47073363411, 2323.47073363411],
                            decimal=-2)
        assert_almost_equal(np.array(aea.y_limits),
                            [-572.556243423972, 2402.36176984391],
                            decimal=10)
Esempio n. 9
0
def test_eccentric_globe():
    globe = ccrs.Globe(semimajor_axis=1000, semiminor_axis=500, ellipse=None)
    with pytest.warns(UserWarning,
                      match='does not handle elliptical globes.') as w:
        ortho = ccrs.Orthographic(globe=globe)
        assert len(w) == (2 if (5, 0, 0) <= ccrs.PROJ4_VERSION <
                          (5, 1, 0) else 1)

    other_args = {'a=1000', 'b=500', 'lon_0=0.0', 'lat_0=0.0'}
    check_proj_params('ortho', ortho, other_args)

    # Limits are the same as spheres since ellipses are not supported.
    assert_almost_equal(ortho.x_limits, [-999.99, 999.99])
    assert_almost_equal(ortho.y_limits, [-999.99, 999.99])
Esempio n. 10
0
def test_ellipse_globe():
    globe = ccrs.Globe(ellipse='WGS84')
    with pytest.warns(UserWarning,
                      match='does not handle elliptical globes.') as w:
        ortho = ccrs.Orthographic(globe=globe)
        assert len(w) == (2 if (5, 0, 0) <= ccrs.PROJ4_VERSION <
                          (5, 1, 0) else 1)

    other_args = {'ellps=WGS84', 'lon_0=0.0', 'lat_0=0.0'}
    check_proj_params('ortho', ortho, other_args)

    # Limits are the same as default since ellipses are not supported.
    assert_almost_equal(ortho.x_limits, [-6378073.21863, 6378073.21863])
    assert_almost_equal(ortho.y_limits, [-6378073.21863, 6378073.21863])
Esempio n. 11
0
    def test_eccentric_globe(self):
        globe = ccrs.Globe(semimajor_axis=10000,
                           semiminor_axis=5000,
                           ellipse=None)
        geos = ccrs.Geostationary(satellite_height=50000, globe=globe)
        expected = [
            '+a=10000', 'b=5000', 'h=50000', 'lat_0=0', 'lon_0=0.0', 'no_defs',
            'proj=geos', 'units=m', 'x_0=0', 'y_0=0'
        ]
        self.check_proj4_params(geos, expected)

        assert_almost_equal(geos.boundary.bounds,
                            (-8245.7306, -4531.3879, 8257.4339, 4531.3879),
                            decimal=4)
    def __init__(self, dataset_path, dx, dy, name):
        """Store the grid information.

        Parameters
        ----------
        dataset_path : str
            Is used to read the gridcell coordinates
        dx : float
            Longitudinal size of a gridcell in meters
        dy : float
            Latitudinal size of a gridcell in meters
        name : str, optional
        """
        self.dx = dx
        self.dy = dy

        projection = ccrs.LambertConformal(
            central_longitude=12.5,
            central_latitude=51.604,
            standard_parallels=[51.604],
            globe=ccrs.Globe(
                ellipse=None, semimajor_axis=6370000, semiminor_axis=6370000
            ),
        )

        # Read grid-values in lat/lon, which are distorted, then
        # project them to LambertConformal where the grid is
        # regular and rectangular.
        with Dataset(dataset_path) as dataset:
            proj_lon = np.array(dataset["lon"][:])
            proj_lat = np.array(dataset["lat"][:])

        self.lon_vals = projection.transform_points(
            ccrs.PlateCarree(), proj_lon[0, :], proj_lat[0, :]
        )[:, 0]
        self.lat_vals = projection.transform_points(
            ccrs.PlateCarree(), proj_lon[:, 0], proj_lat[:, 0]
        )[:, 1]

        # Cell corners
        x = self.lon_vals
        y = self.lat_vals
        dx2 = self.dx / 2
        dy2 = self.dy / 2

        self.cell_x = np.array([x + dx2, x + dx2, x - dx2, x - dx2])
        self.cell_y = np.array([y + dy2, y - dy2, y - dy2, y + dy2])

        super().__init__(name, projection)
Esempio n. 13
0
 def test_projection_creation(self):
     res = self.laea_cs.as_cartopy_projection()
     globe = ccrs.Globe(
         semimajor_axis=self.semi_major_axis,
         semiminor_axis=self.semi_minor_axis,
         ellipse=None,
     )
     expected = ccrs.LambertAzimuthalEqualArea(
         self.latitude_of_projection_origin,
         self.longitude_of_projection_origin,
         self.false_easting,
         self.false_northing,
         globe=globe,
     )
     self.assertEqual(res, expected)
Esempio n. 14
0
    def test_eccentric_globe(self):
        globe = ccrs.Globe(semimajor_axis=1000,
                           semiminor_axis=500,
                           ellipse=None)
        aeqd = ccrs.AzimuthalEquidistant(globe=globe)
        expected = ('+a=1000 +b=500 +proj=aeqd +lon_0=0.0 +lat_0=0.0 '
                    '+x_0=0.0 +y_0=0.0 +no_defs')
        assert aeqd.proj4_init == expected

        assert_almost_equal(np.array(aeqd.x_limits),
                            [-3141.59265359, 3141.59265359],
                            decimal=6)
        assert_almost_equal(np.array(aeqd.y_limits),
                            [-1570.796326795, 1570.796326795],
                            decimal=6)
Esempio n. 15
0
    def test_eccentric_globe(self):
        globe = ccrs.Globe(semimajor_axis=1000, semiminor_axis=500,
                           ellipse=None)
        stereo = ccrs.Stereographic(globe=globe)
        expected = ('+a=1000 +b=500 +proj=stere +lat_0=0.0 +lon_0=0.0 '
                    '+x_0=0.0 +y_0=0.0 +no_defs')
        assert_equal(stereo.proj4_init, expected)

        # The limits in this test are sensible values, but are by no means
        # a "correct" answer - they mean that plotting the crs results in a
        # reasonable map.
        assert_almost_equal(np.array(stereo.x_limits),
                            [-7839.27971444, 7839.27971444], decimal=4)
        assert_almost_equal(np.array(stereo.y_limits),
                            [-3932.82587779, 3932.82587779], decimal=4)
 def test_osgb_vals(self, approx):
     proj = ccrs.TransverseMercator(central_longitude=-2,
                                    central_latitude=49,
                                    scale_factor=0.9996012717,
                                    false_easting=400000,
                                    false_northing=-100000,
                                    globe=ccrs.Globe(datum='OSGB36',
                                                     ellipse='airy'),
                                    approx=approx)
     res = proj.transform_point(*self.point_a, src_crs=self.src_crs)
     np.testing.assert_array_almost_equal(res, (295971.28668, 93064.27666),
                                          decimal=5)
     res = proj.transform_point(*self.point_b, src_crs=self.src_crs)
     np.testing.assert_array_almost_equal(res, (577274.98380, 69740.49227),
                                          decimal=5)
Esempio n. 17
0
    def test_eccentric_globe(self):
        globe = ccrs.Globe(semimajor_axis=1000, semiminor_axis=500,
                           ellipse=None)
        stereo = ccrs.Stereographic(globe=globe)
        other_args = {'a=1000', 'b=500', 'lat_0=0.0', 'lon_0=0.0', 'x_0=0.0',
                      'y_0=0.0'}
        check_proj_params('stere', stereo, other_args)

        # The limits in this test are sensible values, but are by no means
        # a "correct" answer - they mean that plotting the crs results in a
        # reasonable map.
        assert_almost_equal(np.array(stereo.x_limits),
                            [-7839.27971444, 7839.27971444], decimal=4)
        assert_almost_equal(np.array(stereo.y_limits),
                            [-3932.82587779, 3932.82587779], decimal=4)
Esempio n. 18
0
def test_set_xyticks():
    fig = plt.figure(figsize=(10, 10))
    projections = (ccrs.PlateCarree(),
                   ccrs.Mercator(globe=ccrs.Globe(
                       semimajor_axis=math.degrees(1))),
                   ccrs.TransverseMercator(approx=False))
    x = -3.275024
    y = 50.753998
    for i, prj in enumerate(projections, 1):
        ax = fig.add_subplot(3, 1, i, projection=prj)
        ax.set_extent([-12.5, 4, 49, 60], ccrs.Geodetic())
        ax.coastlines('110m')
        p, q = prj.transform_point(x, y, ccrs.Geodetic())
        ax.set_xticks([p])
        ax.set_yticks([q])
    def test_eccentric_globe(self):
        globe = ccrs.Globe(semimajor_axis=1000,
                           semiminor_axis=500,
                           ellipse=None)
        crs = ccrs.LambertAzimuthalEqualArea(globe=globe)
        other_args = {
            'a=1000', 'b=500', 'lon_0=0.0', 'lat_0=0.0', 'x_0=0.0', 'y_0=0.0'
        }
        check_proj_params('laea', crs, other_args)

        assert_almost_equal(np.array(crs.x_limits), [-1999.9, 1999.9],
                            decimal=1)
        assert_almost_equal(np.array(crs.y_limits),
                            [-1380.17298647, 1380.17298647],
                            decimal=4)
Esempio n. 20
0
    def __init__(self, lon0, lat0, Size, path_pdsfile=defaut_pdsfile):

        self.path_pdsfiles = path_pdsfile
        self.lat0 = lat0
        self.lon0 = lon0
        self.ppdlola = 512
        self.ppdwac = 128
        self.globe = ccrs.Globe(semimajor_axis=self.rsphere,
                                semiminor_axis=self.rsphere)
        self.laea = ccrs.LambertAzimuthalEqualArea(central_longitude=self.lon0,
                                                   central_latitude=self.lat0,
                                                   globe=self.globe)
        assert (self.lon0 > 0.0) and (self.lon0 <
                                      360.0), 'Longitude has to span 0-360 !!!'
        self.change_window(Size)
Esempio n. 21
0
 def test_inverted_poly_removed_hole(self):
     proj = ccrs.NorthPolarStereo(globe=ccrs.Globe(ellipse='WGS84'))
     poly = sgeom.Polygon([(0, 0), (-90, 0), (-180, 0),
                           (-270, 0)], [[(-135, -75), (-45, -75), (45, -75),
                                         (135, -75)]])
     multi_polygon = proj.project_geometry(poly)
     # Check the structure
     self.assertEqual(len(multi_polygon), 1)
     self.assertEqual(len(multi_polygon[0].interiors), 1)
     # Check the rough shape
     polygon = multi_polygon[0]
     self._assert_bounds(polygon.bounds, -5.0e7, -5.0e7, 5.0e7, 5.0e7, 1e6)
     self._assert_bounds(polygon.interiors[0].bounds, -1.2e7, -1.2e7, 1.2e7,
                         1.2e7, 1e6)
     self.assertAlmostEqual(polygon.area, 7.34e15, delta=1e13)
Esempio n. 22
0
    def test_eccentric_globe(self):
        globe = ccrs.Globe(semimajor_axis=10000,
                           semiminor_axis=5000,
                           ellipse=None)
        geos = self.test_class(satellite_height=50000, globe=globe)
        expected = [
            '+a=10000', 'b=5000', 'h=50000', 'lat_0=0.0', 'lon_0=0.0',
            'no_defs', 'proj={}'.format(self.expected_proj_name), 'units=m',
            'x_0=0', 'y_0=0'
        ]
        check_proj4_params(geos, expected)

        assert_almost_equal(geos.boundary.bounds,
                            (-8372.4040, -4171.5043, 8372.4040, 4171.5043),
                            decimal=4)
    def test_as_cartopy_projection(self):
        longitude_of_projection_origin = 90.0
        ellipsoid = GeogCS(semi_major_axis=6377563.396,
                           semi_minor_axis=6356256.909)

        merc_cs = Mercator(longitude_of_projection_origin, ellipsoid=ellipsoid)

        expected = ccrs.Mercator(
            central_longitude=longitude_of_projection_origin,
            globe=ccrs.Globe(semimajor_axis=6377563.396,
                             semiminor_axis=6356256.909,
                             ellipse=None))

        res = merc_cs.as_cartopy_projection()
        self.assertEqual(res, expected)
Esempio n. 24
0
def test_eckert_sphere_transform(name, proj, lim, expected):
    globe = ccrs.Globe(semimajor_axis=1.0, ellipse=None)
    eck = proj(central_longitude=-90.0, globe=globe)
    geodetic = eck.as_geodetic()

    other_args = {'a=1.0', 'lon_0=-90.0'}
    check_proj_params(name, eck, other_args)

    assert_almost_equal(eck.x_limits, [-lim, lim], decimal=2)
    assert_almost_equal(eck.y_limits, [-lim / 2, lim / 2])

    result = eck.transform_point(-75.0, -50.0, geodetic)
    assert_almost_equal(result, expected)

    inverse_result = geodetic.transform_point(result[0], result[1], eck)
    assert_almost_equal(inverse_result, [-75.0, -50.0])
    def test_eccentric_globe(self):
        globe = ccrs.Globe(semimajor_axis=1000,
                           semiminor_axis=500,
                           ellipse=None)
        aeqd = ccrs.AzimuthalEquidistant(globe=globe)
        other_args = {
            'a=1000', 'b=500', 'lon_0=0.0', 'lat_0=0.0', 'x_0=0.0', 'y_0=0.0'
        }
        check_proj_params('aeqd', aeqd, other_args)

        assert_almost_equal(np.array(aeqd.x_limits),
                            [-3141.59265359, 3141.59265359],
                            decimal=6)
        assert_almost_equal(np.array(aeqd.y_limits),
                            [-1570.796326795, 1570.796326795],
                            decimal=6)
Esempio n. 26
0
    def test_eccentric_globe(self):
        globe = ccrs.Globe(semimajor_axis=10000,
                           semiminor_axis=5000,
                           ellipse=None)
        geos = self.test_class(satellite_height=50000, globe=globe)
        other_args = {
            'a=10000', 'b=5000', 'h=50000', 'lat_0=0.0', 'lon_0=0.0', 'x_0=0',
            'y_0=0'
        }
        self.adjust_expected_params(other_args)

        check_proj4_params(self.expected_proj_name, geos, other_args)

        assert_almost_equal(geos.boundary.bounds,
                            (-8372.4040, -4171.5043, 8372.4040, 4171.5043),
                            decimal=4)
Esempio n. 27
0
 def test_projection_creation(self):
     res = self.aea_cs.as_cartopy_projection()
     globe = ccrs.Globe(
         semimajor_axis=self.semi_major_axis,
         semiminor_axis=self.semi_minor_axis,
         ellipse=None,
     )
     expected = ccrs.AlbersEqualArea(
         self.latitude_of_projection_origin,
         self.longitude_of_central_meridian,
         self.false_easting,
         self.false_northing,
         self.standard_parallels,
         globe=globe,
     )
     self.assertEqual(res, expected)
Esempio n. 28
0
def test_multiple_projections():

    projections = [
        ccrs.PlateCarree(),
        ccrs.Robinson(),
        ccrs.RotatedPole(pole_latitude=45, pole_longitude=180),
        ccrs.OSGB(approx=True),
        ccrs.TransverseMercator(approx=True),
        ccrs.Mercator(globe=ccrs.Globe(semimajor_axis=math.degrees(1)),
                      min_latitude=-85.,
                      max_latitude=85.),
        ccrs.LambertCylindrical(),
        ccrs.Miller(),
        ccrs.Gnomonic(),
        ccrs.Stereographic(),
        ccrs.NorthPolarStereo(),
        ccrs.SouthPolarStereo(),
        ccrs.Orthographic(),
        ccrs.Mollweide(),
        ccrs.InterruptedGoodeHomolosine(emphasis='land'),
        ccrs.EckertI(),
        ccrs.EckertII(),
        ccrs.EckertIII(),
        ccrs.EckertIV(),
        ccrs.EckertV(),
        ccrs.EckertVI(),
    ]

    rows = np.ceil(len(projections) / 5).astype(int)

    fig = plt.figure(figsize=(10, 2 * rows))
    for i, prj in enumerate(projections, 1):
        ax = fig.add_subplot(rows, 5, i, projection=prj)

        ax.set_global()

        ax.coastlines(resolution="110m")

        plt.plot(-0.08, 51.53, 'o', transform=ccrs.PlateCarree())

        plt.plot([-0.08, 132], [51.53, 43.17],
                 color='red',
                 transform=ccrs.PlateCarree())

        plt.plot([-0.08, 132], [51.53, 43.17],
                 color='blue',
                 transform=ccrs.Geodetic())
Esempio n. 29
0
def overplot_craters():
    """Overplot a lunar map with known crater outlines"""

    imdata_small = mio.load_lola_downsampled()
    smalldata = downscale_local_mean(imdata_small, factors=(10, 10))

    moon_globe = ccrs.Globe(ellipse=None,  # can remove after #1588/#564
                            semimajor_axis=Constants.moon_radius,
                            flattening=Constants.moon_flattening)
    moon_crs = ccrs.Robinson(globe=moon_globe)
    moon_transform = ccrs.PlateCarree(globe=moon_globe)

    plt.rc('text', usetex=True)
    fig = plt.figure(figsize=(12, 6), dpi=120)
    ax = plt.axes(projection=moon_crs)
    ax.gridlines(color='#252525', linestyle='dotted')
    im = ax.imshow(smalldata, origin="upper", transform=moon_transform)
    cbar = fig.colorbar(im, orientation='vertical', shrink=0.7)
    cbar.set_label(r'$\mathrm{LOLA~digital~elevation~model~(m)}$')
    ax.set_global()

    # Reference: International Astronomical Union (IAU) Planetary Gazetteer
    # CSV data downloaded from:  https://planetarynames.wr.usgs.gov/
    # Check the page here for all the history behind the moon feature naming:
    # https://the-moon.us/wiki/IAU_nomenclature
    iau_fname = os.path.join(Paths.table_dir, 'iau_approved_craters.csv')
    #iau_fname = os.path.join(Paths.table_dir, 'iau_approved_features.csv')
    iau_lunar_craters = pd.read_csv(iau_fname)
    lons = iau_lunar_craters.Center_Longitude
    lats = iau_lunar_craters.Center_Latitude
    radii_in_meters = iau_lunar_craters.Diameter * 500  # km to m
    moon_geodesic = geodesic.Geodesic(radius=Constants.moon_radius,
                                      flattening=Constants.moon_flattening)
    craters = []
    crater_proj = ccrs.Geodetic(globe=moon_globe)
    for lon, lat, radius in zip(lons, lats, radii_in_meters):
        if not radius:
            continue

        crater = moon_geodesic.circle(lon=lon, lat=lat, radius=radius,
                                      n_samples=15)
        craters.append(crater)
        geom = shapely.geometry.Polygon(crater)
        ax.add_geometries((geom,), crs=crater_proj, alpha=0.6,
                          facecolor='none', edgecolor='white', linewidth=0.5)

    plt.savefig(os.path.join(Paths.fig_dir, "lunar_craters.png"), dpi=120)
Esempio n. 30
0
def get_closest_satellite_vis(time):
    """
    Get the super national 8 km visible satellite image. The image closest to
    the requested time will be returned.

    time : datetime object of image
    """

    catalog = TDSCatalog(
        'http://thredds.ucar.edu/thredds/catalog/satellite/VIS/'
        'SUPER-NATIONAL_8km/current/catalog.xml')

    # Figure out the closest image to the requested time in the catalog
    datasets = list(catalog.datasets)
    dt_stamps = []
    for dataset in datasets:
        fmt = 'SUPER-NATIONAL_8km_VIS_%Y%m%d_%H%M.gini'
        dt_stamps.append(datetime.strptime(dataset, fmt))
    closest_time = min(dt_stamps, key=lambda x: abs(x - time))
    index = dt_stamps.index(closest_time)

    # Request that image and convert it to a netCDF like dataset
    satellite = list(catalog.datasets.values())[index]
    sat_data = GiniFile(
        urllib.request.urlopen(satellite.access_urls['HTTPServer']))
    ds = sat_data.to_dataset()

    # Pull out the variables we need
    x = ds.variables['x'][:]
    y = ds.variables['y'][:]
    channel_data = ds.variables['Visible']
    time_var = ds.variables['time']
    proj_var = ds.variables[channel_data.grid_mapping]

    # Make a globe and projection for this dataset
    globe = ccrs.Globe(ellipse='sphere',
                       semimajor_axis=proj_var.earth_radius,
                       semiminor_axis=proj_var.earth_radius)

    proj = ccrs.Stereographic(
        central_longitude=proj_var.straight_vertical_longitude_from_pole,
        central_latitude=proj_var.latitude_of_projection_origin,
        true_scale_latitude=proj_var.standard_parallel,
        globe=globe)

    timestamp = netCDF4.num2date(time_var[:].squeeze(), time_var.units)
    return timestamp, globe, proj, x, y, channel_data