Exemple #1
0
 def layout(self):
     self.layouter.layout()
     cw = ContourWriterAGG(self.layouter.shapes)
     LOGGER.debug("Add grid layout")
     cw.add_grid(
         self.layouter.image, self.layouter.area, (30.0, 30.0),
         (10.0, 10.0), **self.grid_values)
Exemple #2
0
    def test_grid_nh(self):
        from pycoast import ContourWriterAGG
        import aggdraw
        grid_img = Image.open(
            os.path.join(os.path.dirname(__file__), 'grid_nh_agg.png'))
        grid_data = np.array(grid_img)
        img = Image.new('RGB', (425, 425))
        proj4_string = '+proj=laea +lat_0=90 +lon_0=0 +a=6371228.0 +units=m'
        area_extent = (-5326849.0625, -5326849.0625, 5326849.0625,
                       5326849.0625)
        area_def = (proj4_string, area_extent)

        cw = ContourWriterAGG(gshhs_root_dir)

        cw.add_coastlines(img, area_def, resolution='l', level=4)
        font = aggdraw.Font('blue',
                            os.path.join(os.path.dirname(__file__),
                                         'test_data', 'DejaVuSerif.ttf'),
                            size=10)
        cw.add_grid(img,
                    area_def, (10.0, 10.0), (2.0, 2.0),
                    font=font,
                    fill='blue',
                    outline='blue',
                    minor_outline='blue',
                    lon_placement='tblr',
                    lat_placement='')

        res = np.array(img)
        self.failUnless(fft_metric(grid_data, res),
                        'Writing of nh grid failed for AGG')
Exemple #3
0
    def test_grid_agg(self):
        from pycoast import ContourWriterAGG
        grid_img = Image.open(
            os.path.join(os.path.dirname(__file__), 'grid_europe_agg.png'))
        grid_data = np.array(grid_img)

        img = Image.new('RGB', (640, 480))
        proj4_string = \
            '+proj=stere +lon_0=8.00 +lat_0=50.00 +lat_ts=50.00 +ellps=WGS84'
        area_extent = (-3363403.31, -2291879.85, 2630596.69, 2203620.1)
        area_def = (proj4_string, area_extent)

        cw = ContourWriterAGG(gshhs_root_dir)

        cw.add_coastlines(img, area_def, resolution='l', level=4)
        cw.add_grid(img,
                    area_def, (10.0, 10.0), (2.0, 2.0),
                    write_text=False,
                    outline='blue',
                    outline_opacity=255,
                    width=1.0,
                    minor_outline='white',
                    minor_outline_opacity=255,
                    minor_width=0.5,
                    minor_is_tick=False)

        res = np.array(img)
        self.assertTrue(fft_metric(grid_data, res),
                        'Writing of grid failed for AGG')
Exemple #4
0
    def test_grid_nh_agg(self):
        from pycoast import ContourWriterAGG
        import aggdraw
        grid_img = Image.open(
            os.path.join(os.path.dirname(__file__), 'grid_nh_agg.png'))
        grid_data = np.array(grid_img)
        img = Image.new('RGB', (425, 425))
        proj4_string = '+proj=laea +lat_0=90 +lon_0=0 +a=6371228.0 +units=m'
        area_extent = (-5326849.0625, -5326849.0625, 5326849.0625,
                       5326849.0625)
        area_def = (proj4_string, area_extent)

        cw = ContourWriterAGG(gshhs_root_dir)

        cw.add_coastlines(img, area_def, resolution='l', level=4)
        font = aggdraw.Font('blue',
                            os.path.join(os.path.dirname(__file__),
                                         'test_data', 'DejaVuSerif.ttf'),
                            size=10)
        cw.add_grid(img,
                    area_def, (10.0, 10.0), (2.0, 2.0),
                    font=font,
                    fill='blue',
                    outline='blue',
                    minor_outline='blue',
                    lon_placement='tblr',
                    lat_placement='')

        res = np.array(img)

        # NOTE: Experience inconsistency in ttf font writing between systems.
        # Still trying to figure out why this test sometimes fails to write
        # correct font markings.
        self.assertTrue(fft_metric(grid_data, res),
                        'Writing of nh grid failed for AGG')
Exemple #5
0
    def test_grid_agg_txt(self):
        from pycoast import ContourWriterAGG
        import aggdraw
        grid_img = Image.open(
            os.path.join(os.path.dirname(__file__), 'grid_europe_agg_txt.png'))
        grid_data = np.array(grid_img)

        img = Image.new('RGB', (640, 480))
        proj4_string = '+proj=stere +lon_0=8.00 +lat_0=50.00 +lat_ts=50.00 +ellps=WGS84'
        area_extent = (-3363403.31, -2291879.85, 2630596.69, 2203620.1)
        area_def = (proj4_string, area_extent)

        cw = ContourWriterAGG(gshhs_root_dir)

        cw.add_coastlines(img, area_def, resolution='l', level=4)
        font = aggdraw.Font('blue',
                            os.path.join(os.path.dirname(__file__),
                                         'test_data', 'DejaVuSerif.ttf'),
                            size=16,
                            opacity=200)
        cw.add_grid(img,
                    area_def, (10.0, 10.0), (2.0, 2.0),
                    font=font,
                    outline='blue',
                    outline_opacity=255,
                    width=1.0,
                    minor_outline='lightblue',
                    minor_outline_opacity=255,
                    minor_width=0.5,
                    minor_is_tick=False)

        res = np.array(img)
        self.failUnless(fft_metric(grid_data, res),
                        'Writing of grid failed for AGG')
    def show_swath_pycoast(self, start, period=None):
        """
        A helper method that displays the orbital swath
        starting at datetime start, for a period number of minutes.
        If, start is iterable, then the method assumes it is an iterable
        of datetimes, plotting a number of swaths at those times.
        """
        # test if start is iterable, EAFP style:
        try:
            for e in start:
                pass
        except TypeError:
            start = [start]
        start.sort()

        from PIL import Image
        from pycoast import ContourWriterAGG
        from pydecorate import DecoratorAGG
        img = Image.new('RGB', (650, 650))
        proj4_string = ""
        for x in self.working_projection:
            proj4_string += "+%s=%s "%(x,self.working_projection[x])
        area_extent = (-6700000.0, -6700000.0, 6700000.0, 6700000.0)
        area_def = (proj4_string, area_extent)
        cw = ContourWriterAGG()

        cw.add_grid(img, area_def, (10.0,10.0),(2.0,2.0), fill='blue',
                    outline='gray', outline_opacity=130, minor_outline=None, write_text=False)

        
        # Plot granules
        for t in start:
            # fetch the coordinates
            xys_segs = self.swath_working_projection(t, period)
            for xys in xys_segs:
                lls = self.proj(xys[0],xys[1],inverse=True)
                cw.add_polygon(img, area_def, zip(lls[0], lls[1]), outline="blue", fill="blue", fill_opacity=70, width=1)
        cw.add_coastlines(img, area_def, resolution='l')
        aoi_coords = zip(*self.aoi)
        ## TODO: Handle single point case properly
        if len(aoi_coords) == 1:
            x, y = aoi_coords[0]
            d =  0.5
            line_coords = [(x-d,y),(x+d,y)]
            cw.add_line(img, area_def, line_coords, 
                        outline="red", fill="red", fill_opacity=100, width=2)
        elif len(aoi_coords) == 2:
            cw.add_line(img, area_def, aoi_coords, outline="red", fill="red", fill_opacity=100, width=10)
        else:
            cw.add_polygon(img, area_def, aoi_coords, outline="red", fill="red", fill_opacity=100, width=2)
        # Decorate
        dc = DecoratorAGG(img)
        text = "Granules from time: %s + %.2f min."%(start[0].strftime('%Y.%m.%d %H:%M:%S'), 
                                            (start[-1]-start[0]).total_seconds()/60.0)
        dc.align_bottom()
        dc.add_text(text,height=0)

        img.show()                
Exemple #7
0
    def test_grid_geos_agg(self):
        from pycoast import ContourWriterAGG
        geos_img = Image.open(os.path.join(os.path.dirname(__file__),
                                           'grid_geos_agg.png'))
        geos_data = np.array(geos_img)
        img = Image.new('RGB', (425, 425))
        proj4_string = '+proj=geos +lon_0=0.0 +a=6378169.00 +b=6356583.80 +h=35785831.0'
        area_extent = (-5570248.4773392612, -5567248.074173444, 5567248.074173444, 5570248.4773392612)
        area_def = (proj4_string, area_extent)
        cw = ContourWriterAGG(gshhs_root_dir)
        cw.add_coastlines(img, area_def, resolution='l')
        cw.add_grid(img, area_def, (10.0, 10.0), (2.0, 2.0), fill='blue', outline='blue', minor_outline='blue',
                    write_text=False)

        res = np.array(img)
        self.failUnless(fft_metric(geos_data, res), 'Writing of geos contours failed')
Exemple #8
0
def add_graticules_to_img(scene):
    cw = ContourWriterAGG(gshhs_dir)

    area_def = (scene.area_def.proj_dict, scene.area_def.area_extent )
    area_def = scene.area_def
    area_def.proj4_string.encode('ascii')
    # cw.add_overlay_from_config('config/pycoast.config', area_def)


    cw.add_coastlines(scene.img, area_def,
                            resolution = 'h',
                            level=4,
                            outline='yellow',
                            width=5)

    cw.add_grid(scene.img, area_def, (5, 5), (2.5, 2.5), font, width=1.4,
            outline='blue', write_text = True, minor_outline='blue')
Exemple #9
0
def save(img_data, img_pref, pattern, area_def, shp_path, path, suffix):
    """将数据保存为图像。"""
    #plotImage(img_data)
    aod_min = img_pref['aod_min']
    aod_max = img_pref['aod_max']
    size = img_data.shape[::-1] # (行,列) -> (长,宽)
    img_data = np.uint8(pattern((img_data - aod_min) / (aod_max - aod_min)) * 255)
    img = Image.new(mode='RGBA', size=size, color=(255,255,255,255))
    src = Image.fromarray(img_data, 'RGBA')
    img.paste(src, (0,0), src)
    cw = ContourWriterAGG(shp_path)
    #cw.add_coastlines(img, area_def, resolution='l', width=1, level=1, outline='gray') # 分辨率 {'c', 'l', 'i', 'h', 'f'}
    #cw.add_borders(img, area_def, resolution='l', width=1.0, level=3, outline='black')
    cw.add_shapefile_shapes(img, area_def, filename=os.path.join(shp_path, 'ChinaProvince.shp'), width=1.0, outline='black')
    font = aggdraw.Font('black', r"c:\windows\fonts\times.ttf", size=30) # Times New Roman 字体
    cw.add_grid(img, area_def, (10.0,10.0),(2.0,2.0), font, width=1.0, outline='black', outline_opacity=175,
                 minor_outline='gray', minor_outline_opacity=200, minor_width=0.5, minor_is_tick=False)
    figure = draw_colorbar(img, img_pref, pattern)
    filename = ''.join(("result", suffix, ".png"))
    figure.save(os.path.join(path, filename),'PNG')
Exemple #10
0
    def test_grid_agg(self):
        from pycoast import ContourWriterAGG
        grid_img = Image.open(os.path.join(os.path.dirname(__file__),
                                           'grid_europe_agg.png'))
        grid_data = np.array(grid_img)

        img = Image.new('RGB', (640, 480))
        proj4_string = '+proj=stere +lon_0=8.00 +lat_0=50.00 +lat_ts=50.00 +ellps=WGS84'
        area_extent = (-3363403.31, -2291879.85, 2630596.69, 2203620.1)
        area_def = (proj4_string, area_extent)

        cw = ContourWriterAGG(gshhs_root_dir)

        cw.add_coastlines(img, area_def, resolution='l', level=4)
        cw.add_grid(img, area_def, (10.0, 10.0), (2.0, 2.0), write_text=False,
                    outline='blue', outline_opacity=255, width=1.0,
                    minor_outline='white', minor_outline_opacity=255, minor_width=0.5,
                    minor_is_tick=False)
        res = np.array(img)
        self.failUnless(fft_metric(grid_data, res), 'Writing of grid failed for AGG')
Exemple #11
0
    def test_grid_geos_agg(self):
        from pycoast import ContourWriterAGG
        geos_img = Image.open(os.path.join(os.path.dirname(__file__),
                                           'grid_geos_agg.png'))
        geos_data = np.array(geos_img)
        img = Image.new('RGB', (425, 425))
        proj4_string = \
            '+proj=geos +lon_0=0.0 +a=6378169.00 +b=6356583.80 +h=35785831.0'
        area_extent = (-5570248.4773392612, -5567248.074173444,
                       5567248.074173444, 5570248.4773392612)
        area_def = (proj4_string, area_extent)
        cw = ContourWriterAGG(gshhs_root_dir)
        cw.add_coastlines(img, area_def, resolution='l')
        cw.add_grid(img, area_def, (10.0, 10.0), (2.0, 2.0),
                    fill='blue', outline='blue', minor_outline='blue',
                    write_text=False)

        res = np.array(img)
        self.assertTrue(
            fft_metric(geos_data, res), 'Writing of geos contours failed')
Exemple #12
0
    def test_grid_nh_agg(self):
        from pycoast import ContourWriterAGG
        import aggdraw
        grid_img = Image.open(os.path.join(os.path.dirname(__file__),
                                           'grid_nh_agg.png'))
        grid_data = np.array(grid_img)
        img = Image.new('RGB', (425, 425))
        proj4_string = '+proj=laea +lat_0=90 +lon_0=0 +a=6371228.0 +units=m'
        area_extent = (-5326849.0625, -5326849.0625, 5326849.0625, 5326849.0625)
        area_def = (proj4_string, area_extent)

        cw = ContourWriterAGG(gshhs_root_dir)

        cw.add_coastlines(img, area_def, resolution='l', level=4)
        font = aggdraw.Font('blue', os.path.join(os.path.dirname(__file__), 'test_data', 'DejaVuSerif.ttf'), size=10)
        cw.add_grid(img, area_def, (10.0, 10.0), (2.0, 2.0), font=font, fill='blue',
                    outline='blue', minor_outline='blue',
                    lon_placement='tblr', lat_placement='')

        res = np.array(img)

        ## NOTE: Experience inconsistency in ttf font writing between systems.
        ## Still trying to figure out why this test sometimes fails to write correct font markings.
        self.failUnless(fft_metric(grid_data, res), 'Writing of nh grid failed for AGG')
Exemple #13
0
def main():
    parser = get_parser()
    args = parser.parse_args()

    levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG]
    logging.basicConfig(level=levels[min(3, args.verbosity)])

    if args.output_filename is None:
        args.output_filename = [x[:-3] + "png" for x in args.input_tiff]
    else:
        assert len(args.output_filename) == len(
            args.input_tiff
        ), "Output filenames must be equal to number of input tiffs"

    if not (args.add_borders or args.add_coastlines or args.add_grid
            or args.add_rivers or args.add_colorbar):
        LOG.error(
            "Please specify one of the '--add-X' options to modify the image")
        return -1

    # we may be dealing with large images that look like decompression bombs
    # let's turn off the check for the image size in PIL/Pillow
    Image.MAX_IMAGE_PIXELS = None

    for input_tiff, output_filename in zip(args.input_tiff,
                                           args.output_filename):
        LOG.info("Creating {} from {}".format(output_filename, input_tiff))
        gtiff = gdal.Open(input_tiff)
        proj4_str = osr.SpatialReference(gtiff.GetProjection()).ExportToProj4()
        ul_x, res_x, _, ul_y, _, res_y = gtiff.GetGeoTransform()
        half_pixel_x = res_x / 2.
        half_pixel_y = res_y / 2.
        area_extent = (
            ul_x - half_pixel_x,  # lower-left X
            ul_y + res_y * gtiff.RasterYSize - half_pixel_y,  # lower-left Y
            ul_x + res_x * gtiff.RasterXSize + half_pixel_x,  # upper-right X
            ul_y + half_pixel_y,  # upper-right Y
        )
        img = Image.open(input_tiff).convert('RGBA' if gtiff.RasterCount in (
            2, 4) else 'RGB')
        area_def = (proj4_str, area_extent)

        cw = ContourWriterAGG(args.shapes_dir)

        if args.add_coastlines:
            outline = args.coastlines_outline[0] if len(
                args.coastlines_outline) == 1 else tuple(
                    int(x) for x in args.coastlines_outline)
            if args.coastlines_fill:
                fill = args.coastlines_fill[0] if len(
                    args.coastlines_fill) == 1 else tuple(
                        int(x) for x in args.coastlines_fill)
            else:
                fill = None
            cw.add_coastlines(img,
                              area_def,
                              resolution=args.coastlines_resolution,
                              level=args.coastlines_level,
                              width=args.coastlines_width,
                              outline=outline,
                              fill=fill)

        if args.add_rivers:
            outline = args.rivers_outline[0] if len(
                args.rivers_outline) == 1 else tuple(
                    int(x) for x in args.rivers_outline)
            cw.add_rivers(img,
                          area_def,
                          resolution=args.rivers_resolution,
                          level=args.rivers_level,
                          width=args.rivers_width,
                          outline=outline)

        if args.add_borders:
            outline = args.borders_outline[0] if len(
                args.borders_outline) == 1 else tuple(
                    int(x) for x in args.borders_outline)
            cw.add_borders(img,
                           area_def,
                           resolution=args.borders_resolution,
                           level=args.borders_level,
                           outline=outline,
                           width=args.borders_width)

        if args.add_grid:
            outline = args.grid_outline[0] if len(
                args.grid_outline) == 1 else tuple(
                    int(x) for x in args.grid_outline)
            minor_outline = args.grid_minor_outline[0] if len(
                args.grid_minor_outline) == 1 else tuple(
                    int(x) for x in args.grid_minor_outline)
            fill = args.grid_fill[0] if len(args.grid_fill) == 1 else tuple(
                int(x) for x in args.grid_fill)
            font_path = find_font(args.grid_font, args.grid_text_size)
            font = Font(outline, font_path, size=args.grid_text_size)
            cw.add_grid(img,
                        area_def,
                        args.grid_D,
                        args.grid_d,
                        font,
                        fill=fill,
                        outline=outline,
                        minor_outline=minor_outline,
                        write_text=args.grid_text,
                        width=args.grid_width,
                        lon_placement=args.grid_lon_placement,
                        lat_placement=args.grid_lat_placement)

        if args.add_colorbar:
            from pydecorate import DecoratorAGG
            font_color = args.colorbar_text_color
            font_color = font_color[0] if len(font_color) == 1 else tuple(
                int(x) for x in font_color)
            font_path = find_font(args.colorbar_font, args.colorbar_text_size)
            # this actually needs an aggdraw font
            font = Font(font_color, font_path, size=args.colorbar_text_size)
            band_count = gtiff.RasterCount
            if band_count not in [1, 2]:
                raise ValueError("Can't add colorbar to RGB/RGBA image")

            # figure out what colormap we are dealing with
            band = gtiff.GetRasterBand(1)
            cmap = get_colormap(band, band_count)

            # figure out our limits
            vmin = args.colorbar_min
            vmax = args.colorbar_max
            metadata = gtiff.GetMetadata_Dict()
            vmin = vmin or metadata.get('min_in')
            vmax = vmax or metadata.get('max_in')
            if isinstance(vmin, str):
                vmin = float(vmin)
            if isinstance(vmax, str):
                vmax = float(vmax)
            if vmin is None or vmax is None:
                data = gtiff.GetRasterBand(1).ReadAsArray()
                vmin = vmin or np.iinfo(data.dtype).min
                vmax = vmax or np.iinfo(data.dtype).max
            cmap.set_range(vmin, vmax)

            dc = DecoratorAGG(img)
            if args.colorbar_align == 'top':
                dc.align_top()
            elif args.colorbar_align == 'bottom':
                dc.align_bottom()
            elif args.colorbar_align == 'left':
                dc.align_left()
            elif args.colorbar_align == 'right':
                dc.align_right()

            if args.colorbar_vertical:
                dc.write_vertically()
            else:
                dc.write_horizontally()

            if args.colorbar_width is None or args.colorbar_height is None:
                LOG.warning("'--colorbar-width' or '--colorbar-height' were "
                            "not specified. Forcing '--colorbar-extend'.")
                args.colorbar_extend = True
            kwargs = {}
            if args.colorbar_width:
                kwargs['width'] = args.colorbar_width
            if args.colorbar_height:
                kwargs['height'] = args.colorbar_height
            dc.add_scale(cmap,
                         extend=args.colorbar_extend,
                         font=font,
                         line=font_color,
                         tick_marks=args.colorbar_tick_marks,
                         title=args.colorbar_title,
                         unit=args.colorbar_units,
                         **kwargs)

        img.save(output_filename)
Exemple #14
0
    print("    width: " + str(xsize))
    print("  area_extent:")
    print("    lower_left_xy: [%f, %f]" % (area_extent[0], area_extent[1]))
    print("    upper_right_xy: [%f, %f]" % (area_extent[2], area_extent[3]))

    if args.shapes is None:
        sys.exit(0)
    from PIL import Image
    from pycoast import ContourWriterAGG
    img = Image.new('RGB', (xsize, ysize))
    #proj4_string = '+proj=geos +lon_0=0.0 +a=6378169.00 +b=6356583.80 +h=35785831.0'
    #area_extent = (-5570248.4773392612, -5567248.074173444, 5567248.074173444, 5570248.4773392612)
    area_def = (proj4_string, area_extent)
    cw = ContourWriterAGG(args.shapes)
    #cw = ContourWriterAGG('/usr/share/gshhg-gmt-shp/')
    cw.add_coastlines(img, (proj4_string, area_extent),
                      resolution='l',
                      width=0.5)

    cw.add_grid(img,
                area_def, (10.0, 10.0), (2.0, 2.0),
                write_text=False,
                outline='white',
                outline_opacity=175,
                width=1.0,
                minor_outline='white',
                minor_outline_opacity=175,
                minor_width=0.2,
                minor_is_tick=False)
    img.show()
Exemple #15
0
    print proj4_string

    print "REGION:", name, "{"
    print "\tNAME:\t", name
    print "\tPCS_ID:\t", proj + "_" + str(lon_0) + "_" + str(lat_0)
    print ("\tPCS_DEF:\tproj=" + proj +
           ",lat_0=" + str(lat_0) +
           ",lon_0=" + str(lon_0) +
           ",ellps=WGS84")
    print "\tXSIZE:\t", xsize
    print "\tYSIZE:\t", ysize
    print "\tAREA_EXTENT:\t", area_extent
    print "};"

    if args.shapes is None:
        sys.exit(0)
    from PIL import Image
    from pycoast import ContourWriterAGG
    img = Image.new('RGB', (xsize, ysize))
    #proj4_string = '+proj=geos +lon_0=0.0 +a=6378169.00 +b=6356583.80 +h=35785831.0'
    #area_extent = (-5570248.4773392612, -5567248.074173444, 5567248.074173444, 5570248.4773392612)
    area_def = (proj4_string, area_extent)
    cw = ContourWriterAGG(args.shapes)
    #cw = ContourWriterAGG('/usr/share/gshhg-gmt-shp/')
    cw.add_coastlines(img, (proj4_string, area_extent), resolution='l', width=0.5)

    cw.add_grid(img, area_def, (10.0, 10.0), (2.0, 2.0), write_text=False, outline='white', outline_opacity=175, width=1.0,
                minor_outline='white', minor_outline_opacity=175, minor_width=0.2, minor_is_tick=False)
    img.show()
def main():
    parser = get_parser()
    args = parser.parse_args()

    levels = [logging.ERROR, logging.WARN, logging.INFO, logging.DEBUG]
    logging.basicConfig(level=levels[min(3, args.verbosity)])

    if args.output_filename is None:
        args.output_filename = [x[:-3] + "png" for x in args.input_tiff]
    else:
        assert len(args.output_filename) == len(args.input_tiff), "Output filenames must be equal to number of input tiffs"

    if not (args.add_borders or args.add_coastlines or args.add_grid or
            args.add_rivers or args.add_colorbar):
        LOG.error("Please specify one of the '--add-X' options to modify the image")
        return -1

    # we may be dealing with large images that look like decompression bombs
    # let's turn off the check for the image size in PIL/Pillow
    Image.MAX_IMAGE_PIXELS = None

    for input_tiff, output_filename in zip(args.input_tiff, args.output_filename):
        LOG.info("Creating {} from {}".format(output_filename, input_tiff))
        gtiff = gdal.Open(input_tiff)
        proj4_str = osr.SpatialReference(gtiff.GetProjection()).ExportToProj4()
        ul_x, res_x, _, ul_y, _, res_y = gtiff.GetGeoTransform()
        half_pixel_x = res_x / 2.
        half_pixel_y = res_y / 2.
        area_extent = (
            ul_x - half_pixel_x,  # lower-left X
            ul_y + res_y * gtiff.RasterYSize - half_pixel_y,  # lower-left Y
            ul_x + res_x * gtiff.RasterXSize + half_pixel_x,  # upper-right X
            ul_y + half_pixel_y,  # upper-right Y
        )
        img = Image.open(input_tiff).convert('RGB')
        area_def = (proj4_str, area_extent)

        cw = ContourWriterAGG(args.shapes_dir)

        if args.add_coastlines:
            outline = args.coastlines_outline[0] if len(args.coastlines_outline) == 1 else tuple(int(x) for x in args.coastlines_outline)
            if args.coastlines_fill:
                fill = args.coastlines_fill[0] if len(args.coastlines_fill) == 1 else tuple(int(x) for x in args.coastlines_fill)
            else:
                fill = None
            cw.add_coastlines(img, area_def, resolution=args.coastlines_resolution, level=args.coastlines_level,
                              outline=outline, fill=fill)

        if args.add_rivers:
            outline = args.rivers_outline[0] if len(args.rivers_outline) == 1 else tuple(int(x) for x in args.rivers_outline)
            cw.add_rivers(img, area_def,
                          resolution=args.rivers_resolution, level=args.rivers_level,
                          outline=outline)

        if args.add_borders:
            outline = args.borders_outline[0] if len(args.borders_outline) == 1 else tuple(int(x) for x in args.borders_outline)
            cw.add_borders(img, area_def, resolution=args.borders_resolution, level=args.borders_level, outline=outline)

        if args.add_grid:
            outline = args.grid_outline[0] if len(args.grid_outline) == 1 else tuple(int(x) for x in args.grid_outline)
            minor_outline = args.grid_minor_outline[0] if len(args.grid_minor_outline) == 1 else tuple(int(x) for x in args.grid_minor_outline)
            fill = args.grid_fill[0] if len(args.grid_fill) == 1 else tuple(int(x) for x in args.grid_fill)
            font_path = find_font(args.grid_font, args.grid_text_size)
            font = Font(outline, font_path, size=args.grid_text_size)
            cw.add_grid(img, area_def, args.grid_D, args.grid_d, font,
                        fill=fill, outline=outline, minor_outline=minor_outline,
                        write_text=args.grid_text,
                        lon_placement=args.grid_lon_placement,
                        lat_placement=args.grid_lat_placement)

        if args.add_colorbar:
            from pydecorate import DecoratorAGG
            font_color = args.colorbar_text_color
            font_color = font_color[0] if len(font_color) == 1 else tuple(int(x) for x in font_color)
            font_path = find_font(args.colorbar_font, args.colorbar_text_size)
            # this actually needs an aggdraw font
            font = Font(font_color, font_path, size=args.colorbar_text_size)
            band_count = gtiff.RasterCount
            if band_count not in [1, 2]:
                raise ValueError("Can't add colorbar to RGB/RGBA image")

            # figure out what colormap we are dealing with
            band = gtiff.GetRasterBand(1)
            cmap = get_colormap(band, band_count)

            # figure out our limits
            vmin = args.colorbar_min
            vmax = args.colorbar_max
            metadata = gtiff.GetMetadata_Dict()
            vmin = vmin or metadata.get('min_in')
            vmax = vmax or metadata.get('max_in')
            if isinstance(vmin, str):
                vmin = float(vmin)
            if isinstance(vmax, str):
                vmax = float(vmax)
            if vmin is None or vmax is None:
                data = gtiff.GetRasterBand(1).ReadAsArray()
                vmin = vmin or np.iinfo(data.dtype).min
                vmax = vmax or np.iinfo(data.dtype).max
            cmap.set_range(vmin, vmax)

            dc = DecoratorAGG(img)
            if args.colorbar_align == 'top':
                dc.align_top()
            elif args.colorbar_align == 'bottom':
                dc.align_bottom()
            elif args.colorbar_align == 'left':
                dc.align_left()
            elif args.colorbar_align == 'right':
                dc.align_right()

            if args.colorbar_vertical:
                dc.write_vertically()
            else:
                dc.write_horizontally()

            if args.colorbar_width is None or args.colorbar_height is None:
                LOG.warning("'--colorbar-width' or '--colorbar-height' were "
                            "not specified. Forcing '--colorbar-extend'.")
                args.colorbar_extend = True
            kwargs = {}
            if args.colorbar_width:
                kwargs['width'] = args.colorbar_width
            if args.colorbar_height:
                kwargs['height'] = args.colorbar_height
            dc.add_scale(cmap, extend=args.colorbar_extend,
                         font=font,
                         line=font_color,
                         tick_marks=args.colorbar_tick_marks,
                         title=args.colorbar_title,
                         unit=args.colorbar_units,
                         **kwargs)

        img.save(output_filename)
Exemple #17
0
def add_overlay(orig,
                area,
                coast_dir,
                color=(0, 0, 0),
                width=0.5,
                resolution=None,
                level_coast=1,
                level_borders=1,
                fill_value=None,
                grid=None):
    """Add coastline, political borders and grid(graticules) to image.

    Uses ``color`` for feature colors where ``color`` is a 3-element tuple
    of integers between 0 and 255 representing (R, G, B).

    .. warning::

        This function currently loses the data mask (alpha band).

    ``resolution`` is chosen automatically if None (default),
    otherwise it should be one of:

    +-----+-------------------------+---------+
    | 'f' | Full resolution         | 0.04 km |
    +-----+-------------------------+---------+
    | 'h' | High resolution         | 0.2 km  |
    +-----+-------------------------+---------+
    | 'i' | Intermediate resolution | 1.0 km  |
    +-----+-------------------------+---------+
    | 'l' | Low resolution          | 5.0 km  |
    +-----+-------------------------+---------+
    | 'c' | Crude resolution        | 25  km  |
    +-----+-------------------------+---------+

    ``grid`` is a dictionary with key values as documented in detail in pycoast

    eg. overlay={'grid': {'major_lonlat': (10, 10),
                          'write_text': False,
                          'outline': (224, 224, 224),
                          'width': 0.5}}

    Here major_lonlat is plotted every 10 deg for both longitude and latitude,
    no labels for the grid lines are plotted, the color used for the grid lines
    is light gray, and the width of the gratucules is 0.5 pixels.

    For grid if aggdraw is used, font option is mandatory, if not
    ``write_text`` is set to False::

        font = aggdraw.Font('black', '/usr/share/fonts/truetype/msttcorefonts/Arial.ttf',
                            opacity=127, size=16)

    """

    if area is None:
        raise ValueError("Area of image is None, can't add overlay.")

    from pycoast import ContourWriterAGG
    if isinstance(area, str):
        area = get_area_def(area)
    LOG.info("Add coastlines and political borders to image.")

    if resolution is None:

        x_resolution = ((area.area_extent[2] - area.area_extent[0]) /
                        area.x_size)
        y_resolution = ((area.area_extent[3] - area.area_extent[1]) /
                        area.y_size)
        res = min(x_resolution, y_resolution)

        if res > 25000:
            resolution = "c"
        elif res > 5000:
            resolution = "l"
        elif res > 1000:
            resolution = "i"
        elif res > 200:
            resolution = "h"
        else:
            resolution = "f"

        LOG.debug("Automagically choose resolution %s", resolution)

    if hasattr(orig, 'convert'):
        # image must be in RGB space to work with pycoast/pydecorate
        orig = orig.convert('RGBA' if orig.mode.endswith('A') else 'RGB')
    elif not orig.mode.startswith('RGB'):
        raise RuntimeError("'trollimage' 1.6+ required to support adding "
                           "overlays/decorations to non-RGB data.")
    img = orig.pil_image(fill_value=fill_value)
    cw_ = ContourWriterAGG(coast_dir)
    cw_.add_coastlines(img,
                       area,
                       outline=color,
                       resolution=resolution,
                       width=width,
                       level=level_coast)
    cw_.add_borders(img,
                    area,
                    outline=color,
                    resolution=resolution,
                    width=width,
                    level=level_borders)
    # Only add grid if major_lonlat is given.
    if grid and 'major_lonlat' in grid and grid['major_lonlat']:
        major_lonlat = grid.pop('major_lonlat')
        minor_lonlat = grid.pop('minor_lonlat', major_lonlat)

        cw_.add_grid(img, area, major_lonlat, minor_lonlat, **grid)

    arr = da.from_array(np.array(img) / 255.0, chunks=CHUNK_SIZE)

    new_data = xr.DataArray(arr,
                            dims=['y', 'x', 'bands'],
                            coords={
                                'y': orig.data.coords['y'],
                                'x': orig.data.coords['x'],
                                'bands': list(img.mode)
                            },
                            attrs=orig.data.attrs)
    return XRImage(new_data)
Exemple #18
0
 def layout(self):
     self.layouter.layout()
     cw = ContourWriterAGG(self.layouter.shapes)
     LOGGER.debug("Add grid layout")
     cw.add_grid(self.layouter.image, self.layouter.area, (30.0, 30.0),
                 (10.0, 10.0), **self.grid_values)
Exemple #19
0
    def show_swath_pycoast(self, start, period=None):
        """
        A helper method that displays the orbital swath
        starting at datetime start, for a period number of minutes.
        If, start is iterable, then the method assumes it is an iterable
        of datetimes, plotting a number of swaths at those times.
        """
        # test if start is iterable, EAFP style:
        try:
            for e in start:
                pass
        except TypeError:
            start = [start]
        start.sort()

        from PIL import Image
        from pycoast import ContourWriterAGG
        from pydecorate import DecoratorAGG
        img = Image.new('RGB', (650, 650))
        proj4_string = ""
        for x in self.working_projection:
            proj4_string += "+%s=%s " % (x, self.working_projection[x])
        area_extent = (-6700000.0, -6700000.0, 6700000.0, 6700000.0)
        area_def = (proj4_string, area_extent)
        cw = ContourWriterAGG()

        cw.add_grid(img,
                    area_def, (10.0, 10.0), (2.0, 2.0),
                    fill='blue',
                    outline='gray',
                    outline_opacity=130,
                    minor_outline=None,
                    write_text=False)

        # Plot granules
        for t in start:
            # fetch the coordinates
            xys_segs = self.swath_working_projection(t, period)
            for xys in xys_segs:
                lls = self.proj(xys[0], xys[1], inverse=True)
                cw.add_polygon(img,
                               area_def,
                               zip(lls[0], lls[1]),
                               outline="blue",
                               fill="blue",
                               fill_opacity=70,
                               width=1)
        cw.add_coastlines(img, area_def, resolution='l')
        aoi_coords = zip(*self.aoi)
        ## TODO: Handle single point case properly
        if len(aoi_coords) == 1:
            x, y = aoi_coords[0]
            d = 0.5
            line_coords = [(x - d, y), (x + d, y)]
            cw.add_line(img,
                        area_def,
                        line_coords,
                        outline="red",
                        fill="red",
                        fill_opacity=100,
                        width=2)
        elif len(aoi_coords) == 2:
            cw.add_line(img,
                        area_def,
                        aoi_coords,
                        outline="red",
                        fill="red",
                        fill_opacity=100,
                        width=10)
        else:
            cw.add_polygon(img,
                           area_def,
                           aoi_coords,
                           outline="red",
                           fill="red",
                           fill_opacity=100,
                           width=2)
        # Decorate
        dc = DecoratorAGG(img)
        text = "Granules from time: %s + %.2f min." % (
            start[0].strftime('%Y.%m.%d %H:%M:%S'),
            (start[-1] - start[0]).total_seconds() / 60.0)
        dc.align_bottom()
        dc.add_text(text, height=0)

        img.show()