Exemple #1
0
def test_web_tiles():
    extent = [-15, 0.1, 50, 60]
    target_domain = sgeom.Polygon([[extent[0], extent[1]],
                                   [extent[2], extent[1]],
                                   [extent[2], extent[3]],
                                   [extent[0], extent[3]],
                                   [extent[0], extent[1]]])
    map_prj = cimgt.GoogleTiles().crs

    ax = plt.subplot(3, 2, 1, projection=map_prj)
    gt = cimgt.GoogleTiles()
    gt._image_url = types.MethodType(ctest_tiles.GOOGLE_IMAGE_URL_REPLACEMENT,
                                     gt)
    img, extent, origin = gt.image_for_domain(target_domain, 1)
    ax.imshow(np.array(img),
              extent=extent,
              transform=gt.crs,
              interpolation='bilinear',
              origin=origin)
    ax.coastlines(color='white')

    ax = plt.subplot(3, 2, 2, projection=map_prj)
    qt = cimgt.QuadtreeTiles()
    img, extent, origin = qt.image_for_domain(target_domain, 1)
    ax.imshow(np.array(img),
              extent=extent,
              transform=qt.crs,
              interpolation='bilinear',
              origin=origin)
    ax.coastlines(color='white')

    ax = plt.subplot(3, 2, 3, projection=map_prj)
    mq_osm = cimgt.MapQuestOSM()
    img, extent, origin = mq_osm.image_for_domain(target_domain, 1)
    ax.imshow(np.array(img),
              extent=extent,
              transform=mq_osm.crs,
              interpolation='bilinear',
              origin=origin)
    ax.coastlines()

    ax = plt.subplot(3, 2, 4, projection=map_prj)
    mq_oa = cimgt.MapQuestOpenAerial()
    img, extent, origin = mq_oa.image_for_domain(target_domain, 1)
    ax.imshow(np.array(img),
              extent=extent,
              transform=mq_oa.crs,
              interpolation='bilinear',
              origin=origin)
    ax.coastlines()

    ax = plt.subplot(3, 2, 5, projection=map_prj)
    osm = cimgt.OSM()
    img, extent, origin = osm.image_for_domain(target_domain, 1)
    ax.imshow(np.array(img),
              extent=extent,
              transform=osm.crs,
              interpolation='bilinear',
              origin=origin)
    ax.coastlines()
Exemple #2
0
def plot_cartopy_cont (proj, C, spc, figtitle, amsx, amsy, amsname, outfile, aspect):
    '''
    Funkcia na vykreslovanie rastra xarray, CONTOURS Parametre:
    C - geodataframe s mriezkou a hodnotami na zobrazenie v stlpci 'col'
    unit - string s jednotkami 
    figtitle - nazov mapy ktory chceme zobrazit
    ams - tuple alebo list s x a y suradnicou stanice ktoru chceme zobrazit
    amsname - string s nazvom stanice ktory chceme zobrazit
    outfile - cesta k vyslednemu obrazku
    aspect - pomer vysky a sirky domeny
    '''    
    cmap = 'CMRmap_r'
    plt.rcParams.update({'font.size': 16})        
    plt.rcParams.update({'xtick.labelsize': 16})
    plt.rcParams.update({'ytick.labelsize': 16})
    plt.rcParams['figure.figsize'] = 15, 15*aspect
    
    mapsource = cimgt.GoogleTiles(style='satellite')
    extent = get_lalo_extent_from_xarray(C)
    
    ax = plt.axes(projection=proj)
    ax.set_extent(extent)
    ax.add_image(mapsource, 13, interpolation='bilinear')
    a = C.plot.contour(cmap=cmap, add_colorbar=False, linewidths=3)
    # a = c.plot( levels=levely[spc], alpha=0.5, cmap=cmap, add_colorbar=False)
    cb = plt.colorbar(a,label=unit_string(spc), orientation="vertical", shrink=0.62)
    cb.outline.set_visible(False)
    ax.set_title(figtitle, fontdict={'fontsize': '20', 'fontweight' : '4'})
    
    plt.plot(amsx, amsy,'o', markerfacecolor='red', markeredgecolor='black')
    plt.text(amsx-400, amsy+150 , amsname, color='white', fontsize=12)
    
    plt.tight_layout()
    
    plt.savefig(outfile, dpi=300, bbox_inches='tight')    
Exemple #3
0
def test_google_wts():
    gt = cimgt.GoogleTiles()

    ll_target_domain = sgeom.box(-15, 50, 0, 60)
    multi_poly = gt.crs.project_geometry(ll_target_domain, ccrs.PlateCarree())
    target_domain = multi_poly.geoms[0]

    with pytest.raises(AssertionError):
        list(gt.find_images(target_domain, -1))
    assert (tuple(gt.find_images(target_domain, 0)) == ((0, 0, 0), ))
    assert (tuple(gt.find_images(target_domain, 2)) == ((1, 1, 2), (2, 1, 2)))

    assert (list(gt.subtiles((0, 0, 0))) == [(0, 0, 1), (0, 1, 1), (1, 0, 1),
                                             (1, 1, 1)])
    assert (list(gt.subtiles((1, 0, 1))) == [(2, 0, 2), (2, 1, 2), (3, 0, 2),
                                             (3, 1, 2)])

    with pytest.raises(AssertionError):
        gt.tileextent((0, 1, 0))

    assert_arr_almost(gt.tileextent((0, 0, 0)), KNOWN_EXTENTS[(0, 0, 0)])
    assert_arr_almost(gt.tileextent((2, 0, 2)), KNOWN_EXTENTS[(2, 0, 2)])
    assert_arr_almost(gt.tileextent((0, 2, 2)), KNOWN_EXTENTS[(0, 2, 2)])
    assert_arr_almost(gt.tileextent((2, 2, 2)), KNOWN_EXTENTS[(2, 2, 2)])
    assert_arr_almost(gt.tileextent((8, 9, 4)), KNOWN_EXTENTS[(8, 9, 4)])
Exemple #4
0
def mapImg(img, lons, lats, vmin, vmax, pad, title):

    minlat = lats.min()
    maxlat = lats.max()
    minlon = lons.min()
    maxlon = lons.max()

    url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}.jpg'
    image = cimgt.GoogleTiles(url=url)
    data_crs = ccrs.PlateCarree()
    fig = plt.figure()
    ax = plt.axes(projection=data_crs)
    img_handle = plt.pcolormesh(lons, lats, img, transform=data_crs)

    lon_range = (pad + maxlon) - (minlon - pad)
    lat_range = (pad + maxlat) - (minlat - pad)
    rangeMin = np.min(np.array([lon_range, lat_range]))
    tick_increment = round(rangeMin / 4, 1)

    ax.set_xticks(np.arange(np.floor(minlon - pad), np.ceil(maxlon + pad),
                            tick_increment),
                  crs=ccrs.PlateCarree())
    ax.set_yticks(np.arange(np.floor(minlat - pad), np.ceil(maxlat + pad),
                            tick_increment),
                  crs=ccrs.PlateCarree())
    lon_formatter = LongitudeFormatter(zero_direction_label=True)
    lat_formatter = LatitudeFormatter()
    ax.xaxis.set_major_formatter(lon_formatter)
    ax.yaxis.set_major_formatter(lat_formatter)
    ax.add_image(image, 8)  #zoom level
    plt.colorbar(img_handle, fraction=0.03, pad=0.09, orientation='horizontal')
    plt.title(title)
    plt.show()
Exemple #5
0
def test_image_merge():
    # tests the basic image merging functionality
    tiles = []
    for i in range(1, 4):
        for j in range(0, 3):
            tiles.append((i, j, 2))

    gt = cimgt.GoogleTiles()
    gt._image_url = types.MethodType(ctest_tiles.GOOGLE_IMAGE_URL_REPLACEMENT,
                                     gt)
    images_to_merge = []
    for tile in tiles:
        img, extent, origin = gt.get_image(tile)
        img = np.array(img)
        x = np.linspace(extent[0], extent[1], img.shape[1], endpoint=False)
        y = np.linspace(extent[2], extent[3], img.shape[0], endpoint=False)
        images_to_merge.append([img, x, y, origin])

    img, extent, origin = cimgt._merge_tiles(images_to_merge)
    ax = plt.axes(projection=gt.crs)
    ax.set_global()
    ax.coastlines()
    ax.imshow(img, origin=origin, extent=extent, alpha=0.5)

    return ax.figure
Exemple #6
0
def background(extent=[-81.15, -80.51, 26.65, 27.24],
               request=cimgt.GoogleTiles(style='satellite'),
               ax=None,
               projection=None,
               out=False):
    # Plots lake O background map

    if request is None:
        projection = projection
        image = False
    else:
        projection = request.crs
        image = True

    if ax is None:
        fig = plt.figure(figsize=(10, 10))
        ax = plt.axes(projection=projection)

    ax.set_extent(extent)

    try:
        gl = ax.gridlines(draw_labels=True, alpha=0.2)
        gl.xlabels_top = gl.ylabels_right = False
        gl.xformatter = LONGITUDE_FORMATTER
        gl.yformatter = LATITUDE_FORMATTER
    except:
        print('Projection does not allow gridlines')

    if image:
        ax.add_image(request, 10)

    if out is True:
        return fig, ax
Exemple #7
0
def tester_bg3():
    """specify extent, and use caropy.io.img_tiles.GootleTiles"""
    from plotter import calpost_reader as reader
    import cartopy.crs as ccrs
    import cartopy.io.img_tiles as cimgt
    with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f:
        dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10))

    # background
    bext = [-11344200.0, -11338900.0, 3724300.0, 3731100.0]
    plotter_options = {
        'contour_options': {
            'alpha': .2
        },
        'extent':
        bext,
        'projection':
        ccrs.epsg(3857),
        # GoogleMap, we may need license
        'customize_once':
        lambda p: p.ax.add_image(cimgt.GoogleTiles(style='satellite'), 15)
    }

    x = dat['x'] * 1000
    y = dat['y'] * 1000
    p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options)
    p(outdir / 'test_bg3.png')
Exemple #8
0
def test_google_wts():
    gt = cimgt.GoogleTiles()

    extent = [-15, 00, 50, 60]
    target_domain = shapely.geometry.Polygon([[extent[0], extent[1]],
                                              [extent[2], extent[1]],
                                              [extent[2], extent[3]],
                                              [extent[0], extent[3]],
                                              [extent[0], extent[1]]])

    with assert_raises(AssertionError):
        list(gt.find_images(target_domain, -1))
    assert_equal(tuple(gt.find_images(target_domain, 0)), ((0, 0, 0), ))
    assert_equal(tuple(gt.find_images(target_domain, 2)),
                 ((1, 1, 2), (2, 1, 2)))

    assert_equal(list(gt.subtiles((0, 0, 0))), [(0, 0, 1), (0, 1, 1),
                                                (1, 0, 1), (1, 1, 1)])
    assert_equal(list(gt.subtiles((1, 0, 1))), [(2, 0, 2), (2, 1, 2),
                                                (3, 0, 2), (3, 1, 2)])

    with assert_raises(AssertionError):
        gt.tileextent((0, 1, 0))

    assert_equal(gt.tileextent((0, 0, 0)),
                 (-180.0, 180.0, 179.41035067677481, -179.41035067677487))
    assert_equal(gt.tileextent((2, 0, 2)),
                 (0.0, 90.0, 179.41035067677481, 89.705175338387392))
    assert_equal(gt.tileextent((0, 2, 2)),
                 (-180.0, -90.0, -2.8421709430404007e-14, -89.70517533838742))
    assert_equal(gt.tileextent((2, 2, 2)),
                 (0.0, 90.0, -2.8421709430404007e-14, -89.70517533838742))
    assert_equal(gt.tileextent((8, 9, 4)),
                 (0.0, 22.5, -22.426293834596891, -44.852587669193753))
def save_map_image(loc):
    """
    Code adapted from https://ocefpaf.github.io/python4oceanographers/blog/2015/06/22/osm/
    Grab google maps image covering geographic area given by 'extent'
     and save image to file for use as background map.
    Use this function to generate the basemap image. It is also possible to plot data
    directly on the cartopy object (map_ax) which provides higher resolution,
     however that requires an internet connection onsite.
    :param loc: path defining location to save image
    :return: nothing
    """

    import cartopy.io.img_tiles as cimgt
    extent = [left_lon, right_lon, bottom_lat, top_lat]
    request = cimgt.GoogleTiles()
    map_fig, map_ax = make_map(projection=request.crs)
    map_ax.set_extent(extent)
    map_ax.add_image(request, 10)
    # put star at launch site
    map_ax.plot(home_lon,
                home_lat,
                marker='*',
                color='black',
                markersize=10,
                transform=ccrs.Geodetic())
    map_ax.savefig(loc)
def scale_bar(ax, length, location=(0.5, 0.05), linewidth=3):
    """
    ax is the axes to draw the scalebar on.
    location is center of the scalebar in axis coordinates ie. 0.5 is the middle of the plot
    length is the length of the scalebar in km.
    linewidth is the thickness of the scalebar.
    """
    #Projection in metres, need to change this to suit your own figure
    utm = img_tiles.GoogleTiles().crs  #ccrs.UTM(36)
    #Get the extent of the plotted area in coordinates in metres
    x0, x1, y0, y1 = ax.get_extent(utm)
    #Turn the specified scalebar location into coordinates in metres
    sbcx, sbcy = x0 + (x1 - x0) * location[0], y0 + (y1 - y0) * location[1]
    #Generate the x coordinate for the ends of the scalebar
    bar_xs = [sbcx - length * 500, sbcx + length * 500]
    #Plot the scalebar
    ax.plot(bar_xs, [sbcy, sbcy],
            transform=utm,
            color='k',
            linewidth=linewidth)
    #Plot the scalebar label
    ax.text(sbcx,
            sbcy,
            str(length) + ' km',
            transform=utm,
            horizontalalignment='center',
            verticalalignment='bottom',
            size=13)
Exemple #11
0
def background():
    """
    This comes from the tests of the Cartopy library. It ensures that the background
    will never be changed by google and is only used in tests.
    """
    gt = cimgt.GoogleTiles()
    gt._image_url = types.MethodType(GOOGLE_IMAGE_URL_REPLACEMENT, gt)
    return gt
Exemple #12
0
def gmaps():
    request = cimgt.GoogleTiles()
    fig, ax = make_map(projection=request.crs)
    extent = [-50, -47.4, -30.5, -25]
    ax.set_extent(extent)
    ax.add_image(request, 10)

    plt.show()
Exemple #13
0
def mapImg(img, lons, lats, vmin, vmax, pad, zoom, title):

    minlat = lats.min()
    maxlat = lats.max()
    minlon = lons.min()
    maxlon = lons.max()
    bg = 'World_Imagery'
    url = 'https://server.arcgisonline.com/ArcGIS/rest/services/' + bg + '/MapServer/tile/{z}/{y}/{x}.jpg'
    image = cimgt.GoogleTiles(url=url)
    data_crs = ccrs.PlateCarree()
    fig = plt.figure(figsize=(6, 8))
    ax = plt.axes(projection=data_crs)
    img_handle = plt.pcolormesh(lons,
                                lats,
                                img,
                                vmin=vmin,
                                vmax=vmax,
                                transform=data_crs,
                                rasterized=True)

    lon_range = (pad + maxlon) - (minlon - pad)
    lat_range = (pad + maxlat) - (minlat - pad)
    rangeMin = np.min(np.array([lon_range, lat_range]))
    tick_increment = round(rangeMin / 4, 1)

    import matplotlib.ticker as mticker
    from cartopy.mpl.ticker import (LongitudeFormatter, LatitudeFormatter,
                                    LatitudeLocator)

    gl = ax.gridlines(crs=ccrs.PlateCarree(),
                      draw_labels=True,
                      linewidth=0.5,
                      color='gray',
                      alpha=0.5,
                      linestyle='--')
    gl.xlocator = mticker.FixedLocator(
        np.arange(np.floor(minlon - pad), np.ceil(maxlon + pad),
                  tick_increment))
    gl.ylocator = LatitudeLocator()
    gl.xformatter = LongitudeFormatter()
    gl.yformatter = LatitudeFormatter()
    gl.ylabel_style = {'size': 8, 'color': 'black'}
    gl.xlabel_style = {'size': 8, 'color': 'black'}
    gl.top_labels = False
    gl.right_labels = False

    # ax.set_xticks(np.arange(np.floor(minlon-pad),np.ceil(maxlon+pad),tick_increment), crs=ccrs.PlateCarree())
    # ax.set_yticks(np.arange(np.floor(minlat-pad),np.ceil(maxlat+pad),tick_increment), crs=ccrs.PlateCarree())
    # ax.lon_formatter = LongitudeFormatter(zero_direction_label=True)
    # lat_formatter = LatitudeFormatter()
    # ax.xlabel_style = {'size': 15, 'color': 'gray'}
    # ax.xlabel_style = {'color': 'red', 'weight': 'bold'}
    # ax.xaxis.set_major_formatter(lon_formatter)
    # ax.yaxis.set_major_formatter(lat_formatter)
    ax.add_image(image, zoom)  #zoom level
    plt.colorbar(img_handle, fraction=0.03, pad=0.05, orientation='horizontal')
    plt.title(title)
    plt.show()
Exemple #14
0
def test_web_tiles():
    extent = [-15, 0.1, 50, 60]
    target_domain = shapely.geometry.Polygon([[extent[0], extent[1]],
                                              [extent[2], extent[1]],
                                              [extent[2], extent[3]],
                                              [extent[0], extent[3]],
                                              [extent[0], extent[1]]])

    ax = plt.subplot(3, 2, 1, projection=ccrs.Mercator())
    gt = cimgt.GoogleTiles()
    img, extent, origin = gt.image_for_domain(target_domain, 1)
    ax.imshow(np.array(img),
              extent=extent,
              transform=ccrs.Mercator(),
              interpolation='bilinear',
              origin=origin)
    ax.coastlines(color='white')

    ax = plt.subplot(3, 2, 2, projection=ccrs.Mercator())
    qt = cimgt.QuadtreeTiles()
    img, extent, origin = qt.image_for_domain(target_domain, 1)
    ax.imshow(np.array(img),
              extent=extent,
              transform=ccrs.Mercator(),
              interpolation='bilinear',
              origin=origin)
    ax.coastlines(color='white')

    ax = plt.subplot(3, 2, 3, projection=ccrs.Mercator())
    mq_osm = cimgt.MapQuestOSM()
    img, extent, origin = mq_osm.image_for_domain(target_domain, 1)
    ax.imshow(np.array(img),
              extent=extent,
              transform=ccrs.Mercator(),
              interpolation='bilinear',
              origin=origin)
    ax.coastlines()

    ax = plt.subplot(3, 2, 4, projection=ccrs.Mercator())
    mq_oa = cimgt.MapQuestOpenAerial()
    img, extent, origin = mq_oa.image_for_domain(target_domain, 1)
    ax.imshow(np.array(img),
              extent=extent,
              transform=ccrs.Mercator(),
              interpolation='bilinear',
              origin=origin)
    ax.coastlines()

    ax = plt.subplot(3, 2, 5, projection=ccrs.Mercator())
    osm = cimgt.OSM()
    img, extent, origin = osm.image_for_domain(target_domain, 1)
    ax.imshow(np.array(img),
              extent=extent,
              transform=ccrs.Mercator(),
              interpolation='bilinear',
              origin=origin)
    ax.coastlines()
def plot_google_map(extent, size=(13, 13)):
    plt.figure(figsize=size)

    img = cimgt.GoogleTiles()

    ax = plt.axes(projection=img.crs)
    ax.set_extent(extent)

    ax.add_image(img, 9, interpolation='bicubic')  # should be 7
Exemple #16
0
def test_tile_find_images():
    gt = cimgt.GoogleTiles()
    # Test the find_images method on a GoogleTiles instance.
    ll_target_domain = sgeom.box(-10, 50, 10, 60)
    multi_poly = gt.crs.project_geometry(ll_target_domain, ccrs.PlateCarree())
    target_domain = multi_poly.geoms[0]

    assert (list(gt.find_images(target_domain, 4)) == [(7, 4, 4), (7, 5, 4),
                                                       (8, 4, 4), (8, 5, 4)])
Exemple #17
0
def arcgisimage(ax, service="World_Shaded_Relief", zoom=1):
    """
    Duplicate the functionality of Basemap `arcgisimage()` function.
    
    My favorite background is the "World_Shaded_Relief"
    """
    url = 'https://server.arcgisonline.com/ArcGIS/rest/services/' \
          '%s/MapServer/tile/{z}/{y}/{x}.jpg' % service

    image = cimgt.GoogleTiles(url=url)
    ax.add_image(image, zoom)
Exemple #18
0
def gen_nest():
    from_config = cimg_nest.NestedImageCollection.from_configuration

    files = [['aerial z0 test', os.path.join(_TEST_DATA_DIR, 'z_0')],
             ['aerial z1 test', os.path.join(_TEST_DATA_DIR, 'z_1')],
             ]

    crs = cimgt.GoogleTiles().crs

    nest_z0_z1 = from_config('aerial test',
                             crs, files, glob_pattern='*.png',
                             img_class=RoundedImg)
    return nest_z0_z1
Exemple #19
0
    def make_cartopy(self, projection, ax=None, figsize=(10, 10)):
        self.projection = projection
        if ax is None:
            # Create figure instance
            fig, ax = plt.subplots(figsize=figsize,
                                   subplot_kw=dict(projection=projection))
        Lat_1 = self.mapcorners[1]
        Lat_2 = self.mapcorners[3]
        Lon_1 = self.mapcorners[0]
        Lon_2 = self.mapcorners[2]
        xlocs_1 = ((round(Lon_1 / 10)) - 1) * 10
        xlocs_2 = ((round(Lon_2 / 10)) + 1) * 10
        ylocs_1 = ((round(Lat_1 / 10)) - 1) * 10
        ylocs_2 = ((round(Lat_2 / 10)) + 1) * 10
        extent = [Lon_1, Lon_2, Lat_1, Lat_2]
        x_space = self.latlon_spacing[0]
        y_space = self.latlon_spacing[1]
        xlocs = np.arange(xlocs_1, xlocs_2, x_space)
        ylocs = np.arange(ylocs_1, ylocs_2, y_space)
        import cartopy.io.img_tiles as cimgt
        if self.bg_service == 'Stamen':
            request = cimgt.Stamen(style=self.bg_style)
            ax.set_extent(extent, crs=self.projection)
            ax.add_image(request, self.xsize, interpolation='spline36')
        if self.bg_service == 'OSM':
            request = cimgt.OSM()
            ax.set_extent(extent, crs=self.projection)
            ax.add_image(request, self.xsize, interpolation='spline36')
        if self.bg_service == 'Google':
            request = cimgt.GoogleTiles(style=self.bg_style)
            ax.set_extent(extent)
            ax.add_image(request, self.xsize, interpolation='spline36')
        if self.bg_service == 'Esri':
            request = cimgt.Esri(style=self.bg_style)
            ax.set_extent(extent, crs=self.projection)
            ax.add_image(request, self.xsize, interpolation='spline36')

        gl = ax.gridlines(draw_labels=self.draw_labels,
                          xlocs=xlocs,
                          ylocs=ylocs,
                          alpha=self.alpha_gl)
        gl.ylabels_left = self.ylabels_left
        gl.ylabels_right = self.ylabels_right
        gl.xlabels_top = self.xlabels_top
        gl.xlabels_bottom = self.xlabels_bottom
        gl.xformatter = LONGITUDE_FORMATTER
        gl.yformatter = LATITUDE_FORMATTER
        gl.xlabel_style = self.xlabel_style
        gl.ylabel_style = self.ylabel_style

        return ax
def test_image_for_domain():
    gt = cimgt.GoogleTiles()
    gt._image_url = types.MethodType(GOOGLE_IMAGE_URL_REPLACEMENT, gt)

    ll_target_domain = sgeom.box(-10, 50, 10, 60)
    multi_poly = gt.crs.project_geometry(ll_target_domain, ccrs.PlateCarree())
    target_domain = multi_poly.geoms[0]

    _, extent, _ = gt.image_for_domain(target_domain, 6)

    ll_extent = ccrs.Geodetic().transform_points(gt.crs, np.array(extent[:2]),
                                                 np.array(extent[2:]))
    assert_arr_almost(ll_extent[:, :2],
                      [[-11.25, 48.92249926], [11.25, 61.60639637]])
def setup_axis(ax=None,
               extent=None,
               projection=None,
               background=False,
               zoom=10):
    """Setup a ``matplotlib.pyplot.Axes`` instance.

    Args:
        ax (``matplotlib.pyplot.Axes``, optional): The axis object to update.
        extent (:py:class:`~gps_data_analyzer.raster_analysis.Extent` or :py:obj:`list`\
            of :py:obj:`float`): The extent to set.
        projection (:py:class:`cartopy.crs.Projection`, optional): The projection of the
            axis (:py:class:`~cartopy.crs.PlateCarree` by default).
        background (bool or :py:class:`cartopy.io.img_tiles.GoogleWTS`, optional): If
            true, a default background is added using Google Satellite. If a
            :obj:`~cartopy.io.img_tiles.GoogleWTS` object is given, it is used.
        zoom (int, mandatory if :py:obj:`background` is not :py:obj:`None`): The zoom
            value used to generate the background.
    """

    # Define projection
    if projection is None:
        projection = ccrs.PlateCarree()

    # Create the figure instance
    if ax is None:
        fig = plt.figure()

        # Create a GeoAxes in the tile's projection.
        ax = fig.add_subplot(1, 1, 1, projection=projection)
    else:
        fig = None  # pragma: no cover

    # Limit the extent of the map to the min/max coords
    if extent is not None:  # pragma: no cover - Should usually not happen
        ax.set_extent(extent, crs=projection)

    # Create a terrain background instance
    if background is True:
        background = cimgt.GoogleTiles(style="satellite")  # pragma: no cover

    # Add the background data
    if background is not False:
        ax.add_image(background, zoom)

    return fig, ax
Exemple #22
0
def plot_map(longitude_lim, latitude_lim, map_quality=11):
    """
    Plot map.

    Parameters
    ----------
    longitude_lim : list(2)

    latitude_lim : list(2)

    map_quality : int
        Map rendering quality.
        6 is very bad, 10 is ok, 12 is good, 13 is very good, 14 excellent.

    """
    # Map extent
    eps = 0*0.01
    extent = [longitude_lim[0] - eps, longitude_lim[1] + eps,
              latitude_lim[0] - eps, latitude_lim[1] + eps]
    # Plot map of Stockholm
    map_design = 'StamenTerrain'
    if map_design == 'GoogleTiles':
        request = cimgt.GoogleTiles()
    elif map_design == 'QuadtreeTiles':
        request = cimgt.QuadtreeTiles()
    elif map_design == 'StamenTerrain':
        request = cimgt.Stamen('terrain-background')
    else:
        # Map designs 'OSM' and 'MapboxTiles' do not work
        raise Exception('Untested map design')
    ax = plt.axes(projection=request.crs)
    gl = ax.gridlines(draw_labels=True, alpha=0., linewidth=0, linestyle='-')
    gl.top_labels = False
    gl.right_labels = False
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    gl.xlabel_style = {'size': 10, 'color': 'black'}
    gl.ylabel_style = {'size': 10, 'color': 'black', 'weight': 'normal'}
    ax.set_extent(extent)
    ax.add_image(request, map_quality)
Exemple #23
0
    def tianditu(self, ax=None, scale=5, map_type='VECTOR', token=None):
        """
        增加天地图作为地图背景.
        http://lbs.tianditu.gov.cn/server/MapService.html

        Parameters:
        ----------------------
        ax
            Axes instance, if not None then overrides the default axes instance.
        scale
            Map scale, large value for detail map.
        token
            Tianditu api token, if not given, default token will be used.
        type
            map type, 'VECTOR', 'TERAIN', or 'SATELLITE'.
        """

        #Get current axes if not specified
        ax = ax or self._check_ax()

        #Check token
        if token is None:
            # token =  CONFIG.CONFIG['TIANDITU']['token']
            token = '4267820f43926eaf808d61dc07269beb'

        #Create image tile URL
        map_types = {
            'VECTOR': 'vec_w',
            'TERAIN': 'ter_w',
            'SATELLITE': 'img_w'
        }
        map_type = map_types.get(map_type.upper(), 'VECTOR')
        url = "http://t3.tianditu.gov.cn/DataServer?T=%s&x={x}&y={y}&l={z}&tk=%s" % (
            map_type, token)

        # add image
        image = cimgt.GoogleTiles(url=url)
        return ax.add_image(image, scale)
Exemple #24
0
    def arcgis(self,
               ax=None,
               scale=4,
               map_type='World_Physical_Map',
               service='server.arcgisonline.com'):
        """
        以ArcGIS地图在线服务为背景.

        refer to:
        https://server.arcgisonline.com/arcgis/rest/services
        http://map.geoq.cn/arcgis/rest/services

        Args:
            ax (object, optional): Axes instance, if not None then overrides the default axes instance.
            scale (int, optional): Map scale, large value for detail map, defaults to 5.
            type (str, optional): Map type string. Defaults to 'World_Physical_Map'.
                                  'server.arcgisonline.com', scale 0~8,
                                      NatGeo_World_Map, USA_Topo_Maps, World_Imagery,
                                      World_Physical_Map, World_Shaded_Relief,
                                      World_Street_Map, World_Terrain_Base, World_Topo_Map
                                  'map.geoq.cn', scale 0-19
                                      ChinaOnlineCommunity_Mobile, ChinaOnlineCommunityENG,
                                      ChinaOnlineCommunity, ChinaOnlineStreetGray, 
                                      ChinaOnlineStreetPurplishBlue, ChinaOnlineStreetWarm
            service (str, optional): Map service, Detaults to 'server.arcgisonline.com'.
        """

        #Get current axes if not specified
        ax = ax or self._check_ax()

        #Create image tile URL
        url = "http://%s/arcgis/rest/services/%s/MapServer/tile/{z}/{y}/{x}" % (
            service, map_type)

        # add image
        image = cimgt.GoogleTiles(url=url)
        return ax.add_image(image, scale)
Exemple #25
0
def test_google_wts():
    gt = cimgt.GoogleTiles()

    extent = [-15, 0.1, 50, 60]
    target_domain = shapely.geometry.Polygon([[extent[0], extent[1]],
                                              [extent[2], extent[1]],
                                              [extent[2], extent[3]],
                                              [extent[0], extent[3]],
                                              [extent[0], extent[1]]])

    with assert_raises(AssertionError):
        list(gt.find_images(target_domain, -1))
    assert_equal(tuple(gt.find_images(target_domain, 0)), ((0, 0, 0), ))
    assert_equal(tuple(gt.find_images(target_domain, 2)),
                 ((1, 1, 2), (2, 1, 2)))

    assert_equal(list(gt.subtiles((0, 0, 0))), [(0, 0, 1), (0, 1, 1),
                                                (1, 0, 1), (1, 1, 1)])
    assert_equal(list(gt.subtiles((1, 0, 1))), [(2, 0, 2), (2, 1, 2),
                                                (3, 0, 2), (3, 1, 2)])

    with assert_raises(AssertionError):
        gt.tileextent((0, 1, 0))

    assert_arr_almost(gt.tileextent((0, 0, 0)),
                      (-180.0, 180.0, 179.02740096396502, -179.02740096396491))
    assert_arr_almost(gt.tileextent((2, 0, 2)),
                      (0.0, 90.0, 179.02740096396502, 89.513700481982539))
    assert_arr_almost(gt.tileextent(
        (0, 2,
         2)), (-180.0, -90.0, 5.6843418860808015e-14, -89.513700481982426))
    assert_arr_almost(gt.tileextent((2, 2, 2)),
                      (0.0, 90.0, 5.6843418860808015e-14, -89.513700481982426))
    assert_arr_almost(gt.tileextent((8, 9, 4)),
                      (0.0, 22.5, -22.37842512,
                       -44.75685024))  # <- zoom 4, contains cape town.
Exemple #26
0
def test_google_tile_styles():
    """
    Tests that setting the Google Maps tile style works as expected.

    This is essentially just assures information is properly propagated through
    the class structure.
    """
    reference_url = ("https://mts0.google.com/vt/lyrs={style}@177000000&hl=en"
                     "&src=api&x=1&y=2&z=3&s=G")
    tile = ["1", "2", "3"]

    # Default is street.
    gt = cimgt.GoogleTiles()
    url = gt._image_url(tile)
    assert reference_url.format(style="m") == url

    # Street
    gt = cimgt.GoogleTiles(style="street")
    url = gt._image_url(tile)
    assert reference_url.format(style="m") == url

    # Satellite
    gt = cimgt.GoogleTiles(style="satellite")
    url = gt._image_url(tile)
    assert reference_url.format(style="s") == url

    # Terrain
    gt = cimgt.GoogleTiles(style="terrain")
    url = gt._image_url(tile)
    assert reference_url.format(style="t") == url

    # Streets only
    gt = cimgt.GoogleTiles(style="only_streets")
    url = gt._image_url(tile)
    assert reference_url.format(style="h") == url

    # Exception is raised if unknown style is passed.
    with pytest.raises(ValueError):
        cimgt.GoogleTiles(style="random_style")
Exemple #27
0
def test_nest(nest_from_config):
    crs = cimgt.GoogleTiles().crs
    z0 = cimg_nest.ImageCollection('aerial z0 test', crs)
    z0.scan_dir_for_imgs(os.path.join(_TEST_DATA_DIR, 'z_0'),
                         glob_pattern='*.png',
                         img_class=RoundedImg)

    z1 = cimg_nest.ImageCollection('aerial z1 test', crs)
    z1.scan_dir_for_imgs(os.path.join(_TEST_DATA_DIR, 'z_1'),
                         glob_pattern='*.png',
                         img_class=RoundedImg)

    z2 = cimg_nest.ImageCollection('aerial z2 test', crs)
    z2.scan_dir_for_imgs(os.path.join(_TEST_DATA_DIR, 'z_2'),
                         glob_pattern='*.png',
                         img_class=RoundedImg)

    # make sure all the images from z1 are contained by the z0 image. The
    # only reason this might occur is if the tfw files are handling
    # floating point values badly
    for img in z1.images:
        if not z0.images[0].bbox().contains(img.bbox()):
            raise OSError(
                'The test images aren\'t all "contained" by the z0 images, '
                'the nest cannot possibly work.\n'
                f'img {img!s} not contained by {z0.images[0]!s}\n'
                f'Extents: {img.extent!s}; {z0.images[0].extent!s}')
    nest_z0_z1 = cimg_nest.NestedImageCollection('aerial test', crs, [z0, z1])

    nest = cimg_nest.NestedImageCollection('aerial test', crs, [z0, z1, z2])

    z0_key = ('aerial z0 test', z0.images[0])

    assert z0_key in nest_z0_z1._ancestry.keys()
    assert len(nest_z0_z1._ancestry) == 1

    # check that it has figured out that all the z1 images are children of
    # the only z0 image
    for img in z1.images:
        key = ('aerial z0 test', z0.images[0])
        assert ('aerial z1 test', img) in nest_z0_z1._ancestry[key]

    x1_y0_z1, = [
        img for img in z1.images if img.filename.endswith('z_1/x_1_y_0.png')
    ]

    assert (1, 0, 1) == _tile_from_img(x1_y0_z1)

    assert ([(2, 0, 2), (2, 1, 2), (3, 0, 2), (3, 1, 2)] == sorted([
        _tile_from_img(img)
        for z, img in nest.subtiles(('aerial z1 test', x1_y0_z1))
    ]))

    # check that the the images in the nest from configuration are the
    # same as those created by hand.
    for name in nest_z0_z1._collections_by_name.keys():
        for img in nest_z0_z1._collections_by_name[name].images:
            collection = nest_from_config._collections_by_name[name]
            assert img in collection.images

    assert nest_z0_z1._ancestry == nest_from_config._ancestry

    # check that a nest can be pickled and unpickled easily.
    s = io.BytesIO()
    pickle.dump(nest_z0_z1, s)
    s.seek(0)
    nest_z0_z1_from_pickle = pickle.load(s)

    assert nest_z0_z1._ancestry == nest_z0_z1_from_pickle._ancestry
Exemple #28
0
import cartopy.io.img_tiles as cimgt


url = "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
esri = cimgt.GoogleTiles(url=url)

fig, ax = plt.subplots(
    figsize=(14, 14),
    subplot_kw={"projection": esri.crs}
)

ax.set_extent(extent)
ax.add_image(esri, 11)
# ax.images[0].write_png("data/esri-image-floripa.png")

data = sul.groupby("balneario_nome").mean()
ax.plot(
    data["lon"], data["lat"], linestyle="none",
    marker="o", label="Sul", transform=ccrs.PlateCarree(),
)

data = norte.groupby("balneario_nome").mean()
ax.plot(
    data["lon"], data["lat"], linestyle="none",
    marker="o", label="Norte", transform=ccrs.PlateCarree()
);
def plot_from_wps(
        patch_nml_path: str,
        figFilename: str = None,
        display: bool = True,
        useCartopy: bool = True,
        TileService: bool = False,
        xyzTiles: str = 'http://tile.openstreetmap.org/{z}/{x}/{y}.png'):

    # namelist options to be passed as kwargs dict to projparams
    namelist_patch = f90nml.read(patch_nml_path)

    # Strip out all namelist classes
    plot_options = namelist_patch['geogrid']
    plot_options = dict(plot_options)

    # get options not used by proj_params
    e_we = plot_options['e_we']
    e_sn = plot_options['e_sn']

    # Remove unnescesary information
    keys_to_keep = [
        'ref_lat', 'ref_lon', 'dx', 'dy', 'map_proj', 'truelat1', 'truelat2',
        'stand_lon'
    ]
    keys_to_keep = set(keys_to_keep)
    all_keys = set(plot_options.keys())
    keys_to_delete = all_keys - keys_to_keep
    for key in keys_to_delete:
        del plot_options[key]

    tic = time.time()

    # Gather parameters from WPS namelist and submit to function
    projparams = build_projparams(**plot_options,
                                  pole_lat=90.0,
                                  pole_lon=0.0,
                                  known_x=0.0,
                                  known_y=0.0)

    # Resolve parameter inconsistencies
    # ################################################################## #
    #
    # MOAD_CEN_LAT is calculated internally by WPS, not provided in the WPS namelist.
    # wrf-python requires either a defined MOAD_CEN_LAT or CEN_LAT to build the CRS.
    # The projection origin (MOAD_CEN_LAT,STAND_LON) is not necessarily going to be
    # identical to each grid origin (like with nested or subsetted domains), thus
    # MOAD_CEN_LAT can be anywhere (?).
    #
    # Make up a MOAD_CEN_LAT in order to use wrf-python
    if projparams['MOAD_CEN_LAT'] is None:
        # Fill with a dummy latitude (average the standard parallell latitudes)
        somelat = 0.5 * (projparams['TRUELAT1'] + projparams['TRUELAT2'])
        projparams['MOAD_CEN_LAT'] = somelat
    # ################################################################## #

    # ################################################################## #
    # Hack to get the projection away from the ref_lat and ref_lon
    #
    # The issue is that if ref_lat and ref_lon are provided to the projection.getproj
    # function, then they are not used in building the projection definition, but
    # they do get used later on by the _ll_to_xy and _xy_to_ll functions as the CRS origin.
    # That causes issues when trying to offset the grid origin from it's coordinate
    # system origin. To solve, set REF_LAT and REF_LON to the CRS origin
    # (MOAD_CEN_LAT,STAND_LON) and that will persist the CRS origin even when using
    # _ll_to_xy and _xy_to_ll functions.
    #
    reflat = projparams[
        'REF_LAT']  # To be used later in calculating domain center xy
    reflon = projparams[
        'REF_LON']  # To be used later in calculating domain center xy
    #
    # Set the ref_lat and ref_lon parameters to match MOAD_CEN_LAT and STAND_LON for
    # the purposes of building a coordinate system
    projparams['REF_LAT'] = projparams['MOAD_CEN_LAT']
    projparams['REF_LON'] = projparams['STAND_LON']
    # ################################################################## #

    # ################################################################## #
    # Use the wrf-python funcitonality to define the coordinate system given the input parameters
    inproj = projection.getproj(**projparams)
    wrf_proj4 = inproj.proj4()  # Test the coordinate system definition
    print('Proj4: %s' % wrf_proj4)
    # ################################################################## #

    # ################################################################## #
    # the wrf-python functions _xy_to_ll and _ll_to_xy provide the xy in cell coordinates,
    # not projected coordinates. Be sure to convert to projected coordinates by multiplying
    # by the resolution.
    #
    center_xy = latlonutils._ll_to_xy(reflat,
                                      reflon,
                                      as_int=False,
                                      **projparams)
    center_ll = latlonutils._xy_to_ll(center_xy[0],
                                      center_xy[0],
                                      as_int=False,
                                      **projparams)
    center_xy[0] = center_xy[0] * projparams[
        'DX']  # Rescale from pixel coords to projected coords
    center_xy[1] = center_xy[1] * projparams[
        'DY']  # Rescale from pixel coords to projected coords
    print('Grid center x,y: %s' % center_xy)
    print('Grid center lat,lon: %s' % center_ll)
    # ################################################################## #

    # ################################################################## #
    # Build exent and handle any false_easting and false_northings
    nrows = e_sn - 1  # Subtract 1 for the number of rows in y
    ncols = e_we - 1  # Subtract 1 for the number of columns in x
    minX, maxX, minY, maxY = find_corner(projparams['DX'],
                                         projparams['DY'],
                                         nrows,
                                         ncols,
                                         2,
                                         xOffset=center_xy[0],
                                         yOffset=center_xy[1])
    xbbox = [minX, minX, maxX, maxX, minX]  # Used to draw a box in ax.plot()
    ybbox = [minY, maxY, maxY, minY, minY]  # Used to draw a box in ax.plot()
    img_extent = find_corner(projparams['DX'],
                             projparams['DY'],
                             nrows,
                             ncols,
                             1.75,
                             xOffset=center_xy[0],
                             yOffset=center_xy[1])
    print('Domain extent: %s' % [minX, maxX, minY, maxY])
    # ################################################################## #

    # --- PLOTTING --- #
    wrf_crs = inproj.cartopy()  # Create a cartopy projection object

    # Create the plot image
    fig = plt.figure(figsize=(12, 12))
    ax = fig.add_subplot(1, 1, 1, projection=wrf_crs)
    ax.set_extent(img_extent, crs=wrf_crs)
    figsize = fig.get_size_inches() * fig.dpi  # Figure size in pixels

    # Add the polygon boundary extent
    ax.plot(xbbox, ybbox, color='red', transform=wrf_crs)

    #You have to calculate the tile zoom level manually
    dist = img_extent[1] - img_extent[
        0]  # Horizontal distance of the map image
    percent_of_image = 0.85  # The percent of the image a horizontal line should cover
    zoomLev = calculateZoom(figsize[1], percent_of_image, center_ll[0], dist)

    # Request the XYZ tiles
    request = cimgt.GoogleTiles(url=xyzTiles)
    ax.add_image(request, zoomLev, interpolation='bicubic')
    ax.gridlines()

    if figFilename is not None:
        plt.savefig(figFilename)
    if display:
        plt.show()

    print('Process completed after %3.2f seconds.' % (time.time() - tic))
def draw_total_precipitation(prep, map_extent=(107., 112, 23.2, 26.5),
                             back_image='terrain-background', back_image_zoom=8, title="降水量实况图",
                             draw_station=True, station_info='cities', station_size=22, 
                             just_contourf=False):
    """
    该程序用于显示多日的累积降水量分布特征, 2020/6/7按业务要求制作.

    Args:
        ax (matplotlib.axes.Axes): the `Axes` instance used for plotting.
        prep (dictionary): precipitation, dictionary: {'lon': 1D array, 'lat': 1D array, 'data': 2D array}
        map_extent (tuple, optional): (lonmin, lonmax, latmin, latmax),. Defaults to (107., 112, 23.2, 26.5).
        back_image (str, opional): the background image name. Default is stamen 'terrain-background', else is
                                      arcgis map server 'World_Physical_Map' (max zoom level is 8)
        back_image_zoom (int, optional): the zoom level for background image. Defaults to 8.
        draw_station (bool, optional): draw station name. Defaults to True.
        station_info (str, optional): station information, 'cities' is 260 city names, or province captial shows.
        station_size (int, optional): station font size. Defaults to 22.
        title (str, optional): title string. Defaults to "降水量实况图".
    
    Example:
        import pandas as pd
        from nmc_met_graphics.plot.precipitation import draw_total_precipitation
        from nmc_met_io.retrieve_micaps_server import get_model_grids

        # read data
        times = pd.date_range(start = pd.to_datetime('2020-06-02 08:00'), end =  pd.to_datetime('2020-06-07 08:00'), freq='1H')
        dataset = get_model_grids("CLDAS/RAIN01_TRI_DATA_SOURCE", times.strftime("%y%m%d%H.000"))
        data = dataset.sum(dim="time")
        data['data'].values[data['data'].values > 2400.0] = np.nan
        prep = {'lon': data['lon'].values, 'lat': data['lat'].values, 'data': data['data'].values}

        # draw the figure
        draw_total_precipitation(prep);
    """

    # set figure size
    fig = plt.figure(figsize=(16, 14.5))

    # set map projection
    datacrs = ccrs.PlateCarree()
    mapcrs = ccrs.LambertConformal(
        central_longitude=np.mean(map_extent[0:1]), central_latitude=np.mean(map_extent[2:3]),
        standard_parallels=(30, 60))
    ax = plt.axes((0.1, 0.08, 0.85, 0.92), projection=mapcrs)
    ax.set_extent(map_extent, crs=datacrs)

    # add map background
    add_china_map_2cartopy(ax, name='province', edgecolor='k', lw=1)
    add_china_map_2cartopy(ax, name='river', edgecolor='cyan', lw=1)
    if back_image == 'terrain-background':
        stamen_terrain = cimg.Stamen('terrain-background')
        ax.add_image(stamen_terrain, back_image_zoom)
    else:
        image = cimg.GoogleTiles(url="https://server.arcgisonline.com/arcgis/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}.jpg")
        ax.add_image(image, back_image_zoom)

    # set colors and levels
    clevs = [50, 100, 200, 300, 400, 500, 600]
    colors = ['#6ab4f1', '#0001f6', '#f405ee', '#ffa900', '#fc6408', '#e80000', '#9a0001']
    linewidths = [1, 1, 2, 2, 3, 4, 4]
    cmap, norm = mpl.colors.from_levels_and_colors(clevs, colors, extend='max')

    # draw precipitation contour map
    x, y = np.meshgrid(prep['lon'], prep['lat'])
    if just_contourf:
        _ = ax.contourf(
            x, y, np.squeeze(prep['data']), clevs, norm=norm,
            cmap=cmap, transform=datacrs, extend='max', alpha=0.5)
    else:
        _ = ax.contourf(
            x, y, np.squeeze(prep['data']), clevs, norm=norm,
            cmap=cmap, transform=datacrs, extend='max', alpha=0.1)
        con2 = ax.contour(
            x, y, np.squeeze(prep['data']), clevs, norm=norm,
            cmap=cmap, transform=datacrs, linewidths=linewidths)
        # add path effects
        plt.setp(con2.collections, path_effects=[
            path_effects.SimpleLineShadow(), path_effects.Normal()])

    # add title and legend
    font = FontProperties(family='Microsoft YaHei', size=32)
    ax.set_title('降水量实况图(累计降水: 6月02日—6月06日)', loc='center', fontproperties=font)
    font = FontProperties(family='Microsoft YaHei', size=16)
    plt.legend([mpatches.Patch(color=b) for b in colors],[
        '50~100 毫米', '100~200 毫米', '200-300 毫米', '300~400 毫米', '400~500 毫米', '500~600 毫米', '>=600毫米'],
        prop=font)

    # add city information
    if draw_station:
        if station_info == 'cities':
            cities = pd.read_csv(pkg_resources.resource_filename(
                'nmc_met_graphics', "resources/stations/cma_city_station_info.dat"),  delimiter=r"\s+")
        else:
            cities = pd.read_csv(pkg_resources.resource_filename(
                'nmc_met_graphics', "resources/stations/provincial_capital.csv"))
        font = FontProperties(family='SimHei', size=22, weight='bold')
        geodetic_transform = ccrs.Geodetic()._as_mpl_transform(ax)
        for _, row in cities.iterrows():
            text_transform = offset_copy(geodetic_transform, units='dots', x=-5)
            ax.plot(row['lon'], row['lat'], marker='o', color='white', markersize=8,
                    alpha=0.7, transform=datacrs)
            ax.text(row['lon'], row['lat'], row['city_name'], clip_on=True,
                    verticalalignment='center', horizontalalignment='right',
                    transform=text_transform, fontproperties=font, color='white',
                    path_effects=[
                        path_effects.Stroke(linewidth=1, foreground='black'),path_effects.Normal()])
    
    return fig