示例#1
0
文件: warp.py 项目: zhouhbsea/gdal
def warp_27():

    if test_cli_utilities.get_gdalwarp_path() is None:
        return 'skip'

    # Open source dataset
    src_ds = gdal.Open('../gcore/data/byte.tif')

    # Desfine target SRS
    dst_srs = osr.SpatialReference()
    dst_srs.ImportFromEPSG(4326)
    dst_wkt = dst_srs.ExportToWkt()

    error_threshold = 0.125  # error threshold --> use same value as in gdalwarp
    resampling = gdal.GRA_Bilinear

    # Call AutoCreateWarpedVRT() to fetch default values for target raster dimensions and geotransform
    tmp_ds = gdal.AutoCreateWarpedVRT( src_ds, \
                                       None, # src_wkt : left to default value --> will use the one from source \
                                       dst_wkt, \
                                       resampling, \
                                       error_threshold )
    dst_xsize = tmp_ds.RasterXSize
    dst_ysize = tmp_ds.RasterYSize
    dst_gt = tmp_ds.GetGeoTransform()
    tmp_ds = None

    # Now create the true target dataset
    dst_ds = gdal.GetDriverByName('GTiff').Create('tmp/warp_27.tif', dst_xsize,
                                                  dst_ysize,
                                                  src_ds.RasterCount)
    dst_ds.SetProjection(dst_wkt)
    dst_ds.SetGeoTransform(dst_gt)

    # And run the reprojection

    cbk = warp_27_progress_callback
    cbk_user_data = None  # value for last parameter of above warp_27_progress_callback

    gdal.ReprojectImage( src_ds, \
                         dst_ds, \
                         None, # src_wkt : left to default value --> will use the one from source \
                         None, # dst_wkt : left to default value --> will use the one from destination \
                         resampling, \
                         0, # WarpMemoryLimit : left to default value \
                         error_threshold,
                         cbk, # Progress callback : could be left to None or unspecified for silent progress
                         cbk_user_data)  # Progress callback user data

    # Done !
    dst_ds = None

    # Check that we have the same result as produced by 'gdalwarp -rb -t_srs EPSG:4326 ../gcore/data/byte.tif tmp/warp_27.tif'
    ds = gdal.Open('tmp/warp_27.tif')
    cs = ds.GetRasterBand(1).Checksum()
    ds = None

    gdaltest.runexternal(
        test_cli_utilities.get_gdalwarp_path() +
        ' -rb -t_srs EPSG:4326 ../gcore/data/byte.tif tmp/warp_27_ref.tif')
    ds = gdal.Open('tmp/warp_27_ref.tif')
    ref_cs = ds.GetRasterBand(1).Checksum()
    ds = None

    if cs != ref_cs:
        return 'fail'

    gdal.Unlink('tmp/warp_27.tif')
    gdal.Unlink('tmp/warp_27_ref.tif')

    return 'success'
示例#2
0
文件: warp.py 项目: zhouhbsea/gdal
def warp_30():

    # Open source dataset
    src_ds = gdal.Open('../gcore/data/byte.tif')

    # Desfine target SRS
    dst_srs = osr.SpatialReference()
    dst_srs.ImportFromEPSG(4326)
    dst_wkt = dst_srs.ExportToWkt()

    error_threshold = 0.125  # error threshold --> use same value as in gdalwarp
    resampling = gdal.GRA_Bilinear

    # Call AutoCreateWarpedVRT() to fetch default values for target raster dimensions and geotransform
    tmp_ds = gdal.AutoCreateWarpedVRT( src_ds, \
                                       None, # src_wkt : left to default value --> will use the one from source \
                                       dst_wkt, \
                                       resampling, \
                                       error_threshold )
    dst_xsize = tmp_ds.RasterXSize
    dst_ysize = tmp_ds.RasterYSize
    dst_gt = tmp_ds.GetGeoTransform()
    tmp_ds = None

    # Now create the true target dataset
    dst_ds = gdal.GetDriverByName('GTiff').Create('/vsimem/warp_30.tif',
                                                  dst_xsize, dst_ysize,
                                                  src_ds.RasterCount)
    dst_ds.SetProjection(dst_wkt)
    dst_ds.SetGeoTransform(dst_gt)

    # And run the reprojection

    cbk = warp_30_progress_callback
    cbk_user_data = None  # value for last parameter of above warp_27_progress_callback

    gdal.PushErrorHandler('CPLQuietErrorHandler')
    ret = gdal.ReprojectImage( src_ds, \
                         dst_ds, \
                         None, # src_wkt : left to default value --> will use the one from source \
                         None, # dst_wkt : left to default value --> will use the one from destination \
                         resampling, \
                         0, # WarpMemoryLimit : left to default value \
                         error_threshold,
                         cbk, # Progress callback : could be left to None or unspecified for silent progress
                         cbk_user_data)  # Progress callback user data
    gdal.PopErrorHandler()

    if ret == 0:
        gdaltest.post_reason('failed')
        return 'fail'

    old_val = gdal.GetConfigOption('GDAL_NUM_THREADS')
    gdal.SetConfigOption('GDAL_NUM_THREADS', '2')
    gdal.PushErrorHandler('CPLQuietErrorHandler')
    ret = gdal.ReprojectImage( src_ds, \
                         dst_ds, \
                         None, # src_wkt : left to default value --> will use the one from source \
                         None, # dst_wkt : left to default value --> will use the one from destination \
                         resampling, \
                         0, # WarpMemoryLimit : left to default value \
                         error_threshold,
                         cbk, # Progress callback : could be left to None or unspecified for silent progress
                         cbk_user_data)  # Progress callback user data
    gdal.PopErrorHandler()
    gdal.SetConfigOption('GDAL_NUM_THREADS', old_val)

    if ret == 0:
        gdaltest.post_reason('failed')
        return 'fail'

    return 'success'
示例#3
0
def prepare(inputfile, logger, exc, **options):
    gdal.AllRegister()
    # Spatial Reference System of tiles
    out_srs = osr.SpatialReference()
    out_srs.ImportFromEPSG(3857)
    # Set output directory
    if not options.get('output'):
        # Directory with input filename without extension in actual directory
        output = os.path.abspath(
            os.path.join("%s.tiles" % os.path.splitext(inputfile)[0]))
        logger.info('No output specified, using %s', output)
    else:
        output = options.get('output')
    if os.path.exists(output):
        if not options.get('resume'):
            raise exc(
                'Output %s already exists and resume is not enabled, aborting!'
                % output)
    else:
        if not options.get('dry_run'):
            os.makedirs(output)

    out_drv = gdal.GetDriverByName(options.get('format'))
    if not out_drv:
        raise exc(
            "The '%s' driver was not found, is it available in this GDAL build?",
            options.get('format'))

    # Open the input file
    in_ds = gdal.Open(inputfile, gdal.GA_ReadOnly)

    if not in_ds:
        raise exc("It is not possible to open the input file '%s'." %
                  inputfile)

    logger.info("Input file: %s ( %sP x %sL - %s bands)", inputfile,
                in_ds.RasterXSize, in_ds.RasterYSize, in_ds.RasterCount)

    if (in_ds.GetGeoTransform()
            == (0.0, 1.0, 0.0, 0.0, 0.0, 1.0)) and (in_ds.GetGCPCount() == 0):
        raise exc("Input file %s is not georeferenced!" % inputfile)

    # Read metadata from the input file
    if in_ds.RasterCount == 0:
        raise exc("Input file '%s' has no raster band" % inputfile)

    if in_ds.GetRasterBand(1).GetRasterColorTable():
        # TODO: Process directly paletted dataset by generating VRT in memory
        raise exc("Please convert %s to RGB/RGBA with gdal_translate." %
                  inputfile)

    # Get NODATA value
    in_nodata = []
    for i in range(1, in_ds.RasterCount + 1):
        if in_ds.GetRasterBand(i).GetNoDataValue() != None:
            in_nodata.append(in_ds.GetRasterBand(i).GetNoDataValue())

    logger.info("NODATA: %s", in_nodata)

    # Here we should have RGBA input dataset opened in in_ds

    logger.info("Preprocessed file: %s ( %sP x %sL - %s bands)", inputfile,
                in_ds.RasterXSize, in_ds.RasterYSize, in_ds.RasterCount)

    # Spatial Reference System of the input raster
    in_srs = None
    if options.get('srs'):
        in_srs = osr.SpatialReference()
        in_srs.SetFromUserInput(options.get('srs'))
        in_srs_wkt = in_srs.ExportToWkt()
    else:
        in_srs_wkt = in_ds.GetProjection()
        if not in_srs_wkt and in_ds.GetGCPCount() != 0:
            in_srs_wkt = in_ds.GetGCPProjection()
        if in_srs_wkt:
            in_srs = osr.SpatialReference()
            in_srs.ImportFromWkt(in_srs_wkt)

    if not in_srs:
        raise exc(
            "Input file %s has unknown SRS. Use --srs=ESPG:xyz (or similar) to provide source reference system."
            % inputfile)

    logger.info("Input SRS: %s", in_srs.ExportToProj4())
    logger.info("Output SRS: %s", out_srs.ExportToProj4())

    out_ds = None

    # Are the reference systems the same? Reproject if necessary.
    if (in_srs.ExportToProj4() !=
            out_srs.ExportToProj4()) or (in_ds.GetGCPCount() != 0):
        logger.info("Creating AutoCreateWarpedVRT.")

        # Generation of VRT dataset in tile projection, default 'nearest neighbour' warping
        out_ds = gdal.AutoCreateWarpedVRT(in_ds, in_srs_wkt,
                                          out_srs.ExportToWkt())

        # TODO: HIGH PRIORITY: Correction of AutoCreateWarpedVRT according the max zoomlevel for correct direct warping!!!

        #logger.info("Warping of the raster by AutoCreateWarpedVRT (result saved into 'tiles.vrt')")
        #out_ds.GetDriver().CreateCopy("tiles.vrt", out_ds)

        # Note: in_srs and in_srs_wkt contain still the non-warped reference system!!!

        # Correction of AutoCreateWarpedVRT for NODATA values
        if in_nodata != []:
            tempfilename = tempfile.mktemp('-bands.vrt')  # TODO
            out_ds.GetDriver().CreateCopy(tempfilename, out_ds)
            # open as a text file
            s = open(tempfilename).read()
            # Add the warping options
            s = s.replace(
                """<GDALWarpOptions>""", """<GDALWarpOptions>
<Option name="INIT_DEST">NO_DATA</Option>
<Option name="UNIFIED_SRC_NODATA">YES</Option>""")
            # replace BandMapping tag for NODATA bands....
            for i in range(len(in_nodata)):
                s = s.replace("""<BandMapping src="%i" dst="%i"/>""" %
                              ((i + 1), (i + 1)),
                              """<BandMapping src="%i" dst="%i">
<SrcNoDataReal>%i</SrcNoDataReal>
<SrcNoDataImag>0</SrcNoDataImag>
<DstNoDataReal>%i</DstNoDataReal>
<DstNoDataImag>0</DstNoDataImag>
</BandMapping>""" % ((i + 1), (i + 1), in_nodata[i],
                     in_nodata[i]))  # Or rewrite to white by: , 255 ))
            # save the corrected VRT
            open(tempfilename, "w").write(s)
            # open by GDAL as out_ds
            out_ds = gdal.Open(tempfilename)  #, gdal.GA_ReadOnly)
            # delete the temporary file
            os.unlink(tempfilename)

            # set NODATA_VALUE metadata
            out_ds.SetMetadataItem(
                'NODATA_VALUES',
                '%i %i %i' % (in_nodata[0], in_nodata[1], in_nodata[2]))

            #logger.info("Modified warping result saved into 'tiles1.vrt'")
            #open("tiles1.vrt","w").write(s)

        # -----------------------------------
        # Correction of AutoCreateWarpedVRT for Mono (1 band) and RGB (3 bands) files without NODATA:
        # equivalent of gdalwarp -dstalpha
        if in_nodata == [] and out_ds.RasterCount in [1, 3]:
            tempfilename = tempfile.mktemp('-alpha.vrt')
            out_ds.GetDriver().CreateCopy(tempfilename, out_ds)
            # open as a text file
            s = open(tempfilename).read()
            # Add the warping options
            s = s.replace(
                """<BlockXSize>""",
                """<VRTRasterBand dataType="Byte" band="%i" subClass="VRTWarpedRasterBand">
<ColorInterp>Alpha</ColorInterp>
</VRTRasterBand>
<BlockXSize>""" % (out_ds.RasterCount + 1))
            s = s.replace(
                """</GDALWarpOptions>""", """<DstAlphaBand>%i</DstAlphaBand>
</GDALWarpOptions>""" % (out_ds.RasterCount + 1))
            s = s.replace(
                """</WorkingDataType>""", """</WorkingDataType>
<Option name="INIT_DEST">0</Option>""")
            # save the corrected VRT
            open(tempfilename, "w").write(s)
            # open by GDAL as out_ds
            out_ds = gdal.Open(tempfilename)  #, gdal.GA_ReadOnly)
            # delete the temporary file
            os.unlink(tempfilename)

    if not out_ds:
        out_ds = in_ds

    # Here we should have a raster (out_ds) in the correct Spatial Reference system

    # Get alpha band (either directly or from NODATA value)
    alphaband = out_ds.GetRasterBand(1).GetMaskBand()
    if (alphaband.GetMaskFlags() & gdal.GMF_ALPHA
        ) or out_ds.RasterCount == 4 or out_ds.RasterCount == 2:
        # TODO: Better test for alpha band in the dataset
        dataBandsCount = out_ds.RasterCount - 1
    else:
        dataBandsCount = out_ds.RasterCount
    logger.info("dataBandsCount: %s", dataBandsCount)

    # Read the georeference

    out_gt = out_ds.GetGeoTransform()

    # Report error in case rotation/skew is in geotransform (possible only in 'raster' profile)
    if (out_gt[2], out_gt[4]) != (0, 0):
        # TODO: Do the warping in this case automaticaly
        raise exc(
            "Georeference of the raster in input file %s contains rotation or skew. Such raster is not supported. Please use gdalwarp first."
            % inputfile)

    # Here we expect: pixel is square, no rotation on the raster

    # Output Bounds - coordinates in the output SRS
    ominx = out_gt[0]
    omaxx = out_gt[0] + out_ds.RasterXSize * out_gt[1]
    omaxy = out_gt[3]
    ominy = out_gt[3] + out_ds.RasterYSize * out_gt[5]
    # Note: maybe round(x, 14) to avoid the gdal_translate behaviour, when 0 becomes -1e-15

    logger.info("Bounds (output srs): minX:%d minY:%d maxX:%d maxY:%d", ominx,
                ominy, omaxx, omaxy)

    # Calculating ranges for tiles in different zoom levels
    mercator = GlobalMercator(
        tilesize=options.get('tilesize'))  # from globalmaptiles.py

    logger.info(
        'Bounds (latlong): minX:%f minY:%f maxX:%f maxY:%f',
        *mercator.MetersToLatLon(ominx, ominy) +
        mercator.MetersToLatLon(omaxx, omaxy))

    # Get the minimal zoom level (map covers area equivalent to one tile)
    tminz = mercator.ZoomForPixelSize(
        out_gt[1] * max(out_ds.RasterXSize, out_ds.RasterYSize) /
        float(options.get('tilesize')))

    # Get the maximal zoom level (closest possible zoom level up on the resolution of raster)
    tmaxz = mercator.ZoomForPixelSize(out_gt[1])

    logger.info('MinZoomLevel: %d (res:%f)', tminz, mercator.Resolution(tminz))
    logger.info('MaxZoomLevel: %d (res:%f)', tmaxz, mercator.Resolution(tmaxz))

    # Generate table with min max tile coordinates for all zoomlevels
    tminmax = {k: 0 for k in range(tminz, tmaxz + 1)}
    for tz in range(tminz, tmaxz + 1):
        tminx, tminy = mercator.MetersToTile(ominx, ominy, tz)
        tmaxx, tmaxy = mercator.MetersToTile(omaxx, omaxy, tz)
        # crop tiles extending world limits (+-180,+-90)
        tminx, tminy = max(0, tminx), max(0, tminy)
        tmaxx, tmaxy = min(2**tz - 1, tmaxx), min(2**tz - 1, tmaxy)
        logger.info("tiles at zoom %d: %d", tz,
                    (tmaxy - tminy + 1) * (tmaxx - tminx + 1))
        tminmax[tz] = (tminx, tminy, tmaxx, tmaxy)

    # TODO: Maps crossing 180E (Alaska?)

    if options.get('dry_run'):
        logger.info(
            "This is only a dry-run, stopping before any tasks are dispatched ..."
        )

    workerfile = os.path.abspath("%s.worker" % inputfile)
    out_ds.GetDriver().CreateCopy(workerfile, out_ds)
    tr = TileRenderer()
    for tz in range(tmaxz, tminz - 1, -1):
        tminx, tminy, tmaxx, tmaxy = tminmax[tz]
        for tx in range(tminx, tmaxx + 1):
            tiledir = os.path.abspath(os.path.join(output, str(tz), str(tx)))
            if not os.path.exists(tiledir) and not options.get('dry_run'):
                logger.debug("Creating tile directory: %s", tiledir)
                os.makedirs(tiledir)
            for ty in range(tmaxy, tminy - 1, -1):
                tilefile = os.path.join(
                    tiledir, "%s.%s" % (ty, options.get('format').lower()))
                if options.get('resume') and os.path.exists(tilefile):
                    logger.debug("Skip existing tile: %s", tilefile)
                    continue
                args = (workerfile, tilefile, tx, ty, tz,
                        options.get('tilesize'), dataBandsCount)
                kwargs = {'driver': options.get('format')}
                logger.debug("Task: %s, %s", repr(args), repr(kwargs))
                if not options.get('dry_run'):
                    tr.apply_async(args, kwargs)
示例#4
0
    def init_map(self, zoom_parm):
        'initialize geo-parameters and generate base zoom level'
        #----------------------------

        # init variables
        self.tiles_prefix = self.options.tiles_prefix
        self.src_dir, src_f = os.path.split(self.src)
        self.base = os.path.splitext(src_f)[0]
        self.base_resampling = base_resampling_map[
            self.options.base_resampling]
        self.resampling = resampling_map[self.options.overview_resampling]

        #~ if self.options.verbose > 0:
        #~ print('\n%s -> %s '%(self.src, self.dest), end='')
        logging.info(' %s -> %s ' % (self.src, self.dest))

        if os.path.isdir(self.dest):
            if self.options.noclobber and os.path.exists(self.dest):
                logging.error('Target already exists: skipping')
                return False
            else:
                shutil.rmtree(self.dest, ignore_errors=True)

        # connect to src dataset
        try:
            self.get_src_ds()
        except RuntimeError as exc:
            if self.options.skip_invalid:
                logging.error('%s' % exc.message[:-1])
                return False
            else:
                raise

        # calculate zoom range
        self.calc_zoom(zoom_parm)
        self.max_zoom = self.zoom_range[0]

        # shift target SRS to avoid crossing 180 meridian
        shifted_srs = self.shift_srs(self.max_zoom)
        shift_x = GdalTransformer(SRC_SRS=shifted_srs,
                                  DST_SRS=self.proj_srs).transform_point(
                                      (0, 0))[0]
        if shift_x != 0:
            self.proj_srs = shifted_srs
            self.proj2geog = GdalTransformer(SRC_SRS=self.proj_srs,
                                             DST_SRS=self.geog_srs)
            self.pix_origin = (self.pix_origin[0] - shift_x,
                               self.pix_origin[1])
            self.tile_origin = (self.tile_origin[0] - shift_x,
                                self.tile_origin[1])
            ld('new_srs', shifted_srs, 'shift_x', shift_x, 'pix_origin',
               self.pix_origin)

        # get corners at the target SRS
        target_ds = gdal.AutoCreateWarpedVRT(self.src_ds, None,
                                             txt2wkt(shifted_srs))
        target_bounds = GdalTransformer(target_ds).transform([
            (0, 0), (target_ds.RasterXSize, target_ds.RasterYSize)
        ])

        # self.bounds are set to a world raster, now clip to the max tileset area
        self.bounds = ((target_bounds[0][0],
                        min(self.bounds[0][1], target_bounds[0][1])),
                       (target_bounds[1][0],
                        max(self.bounds[1][1], target_bounds[1][1])))

        ld('target raster')
        ld('Upper Left', self.bounds[0], target_bounds[0],
           self.proj2geog.transform([self.bounds[0], target_bounds[0]]))
        ld('Lower Right', self.bounds[1], target_bounds[1],
           self.proj2geog.transform([self.bounds[1], target_bounds[1]]))
        #        orig_ul = GdalTransformer(SRC_SRS=self.geog_srs, DST_SRS=self.srs).transform_point(
        #            self.proj2geog.transform_point(target_bounds[0]))
        #        ld(orig_ul[0]-target_bounds[0][0], orig_ul)
        return True
示例#5
0
    def pre_process_inumpyut(self, _inumpyut):
        """Initialization of the inumpyut raster, reprojection if necessary"""
        print "Processing: %s" % _inumpyut

        inumpyut_or_vrt = _inumpyut

        if not self.mem_drv:
            raise Exception(
                "The 'MEM' driver was not found, is it available in this GDAL build?"
            )

        # Open the inumpyut file
        if self.inumpyut:
            in_ds = gdal.Open(_inumpyut, gdal.GA_ReadOnly)
        else:
            raise Exception("No inumpyut file was specified")

        if self.options.verbose:
            print(
                "Inumpyut file:", "( %sP x %sL - %s bands)" %
                (self.in_ds.RasterXSize, self.in_ds.RasterYSize,
                 self.in_ds.RasterCount))

        if not in_ds:
            # Note: GDAL prints the ERROR message too
            self.error("It is not possible to open the inumpyut file '%s'." %
                       _inumpyut)

        # Read metadata from the inumpyut file
        if in_ds.RasterCount == 0:
            self.error("Inumpyut file '%s' has no raster band" % _inumpyut)

        if in_ds.GetRasterBand(1).GetRasterColorTable():
            # TODO: Process directly paletted dataset by generating VRT in memory
            self.error(
                "Please convert this file to RGB/RGBA and run gdal2tiles on the result.",
                """From paletted file you can create RGBA file (temp.vrt) by:
gdal_translate -of vrt -expand rgba %s temp.vrt
then run:
gdal2tiles temp.vrt""" % _inumpyut)

        # Get NODATA value
        in_nodata = []
        for i in range(1, in_ds.RasterCount + 1):
            if in_ds.GetRasterBand(i).GetNoDataValue() != None:
                ndata = in_ds.GetRasterBand(i).GetNoDataValue()
                if math.isnan(ndata):
                    ndata = 'none'
                in_nodata.append(ndata)
        if self.options.srcnodata:
            nds = list(map(float, self.options.srcnodata.split(',')))
            if len(nds) < in_ds.RasterCount:
                in_nodata = (nds * in_ds.RasterCount)[:in_ds.RasterCount]
            else:
                in_nodata = nds

        if self.options.verbose:
            print("NODATA: %s" % in_nodata)

        #
        # Here we should have RGBA inumpyut dataset opened in in_ds
        #
        if self.options.verbose:
            print(
                "Preprocessed file:", "( %sP x %sL - %s bands)" %
                (in_ds.RasterXSize, in_ds.RasterYSize, in_ds.RasterCount))

        # Spatial Reference System of the inumpyut raster
        self.in_srs = None

        if self.options.s_srs:
            self.in_srs = osr.SpatialReference()
            self.in_srs.SetFromUserInumpyut(self.options.s_srs)
            self.in_srs_wkt = self.in_srs.ExportToWkt()
        else:
            self.in_srs_wkt = in_ds.GetProjection()
            if not self.in_srs_wkt and in_ds.GetGCPCount() != 0:
                self.in_srs_wkt = in_ds.GetGCPProjection()
            if self.in_srs_wkt:
                self.in_srs = osr.SpatialReference()
                self.in_srs.ImportFromWkt(self.in_srs_wkt)

        # Spatial Reference System of tiles
        self.out_srs = osr.SpatialReference()
        self.out_srs.ImportFromEPSG(4326)

        # Are the reference systems the same? Reproject if necessary.
        out_ds = None

        if (in_ds.GetGeoTransform() == (0.0, 1.0, 0.0, 0.0, 0.0,
                                        1.0)) and (in_ds.GetGCPCount() == 0):
            self.error(
                "There is no georeference - neither affine transformation (worldfile) nor GCPs. You can generate only 'raster' profile tiles.",
                "Either gdal2tiles with parameter -p 'raster' or use another GIS software for georeference e.g. gdal_transform -gcp / -a_ullr / -a_srs"
            )

        in_srs_code = self.in_srs.GetAttrValue("AUTHORITY", 0)
        in_ds_srs = osr.SpatialReference()
        res = in_ds_srs.ImportFromWkt(in_ds.GetProjection())

        if res != 0 and in_srs_code is None:
            print "ERROR! The inumpyut file %s has no SRS associated and no SRS has been defined in inumpyut (-s parameter)" % _inumpyut
            exit(1)

        if self.in_srs:
            if in_ds_srs.ExportToProj4() != self.out_srs.ExportToProj4():
                if (self.in_srs.ExportToProj4() !=
                        self.out_srs.ExportToProj4()) or (in_ds.GetGCPCount()
                                                          != 0):
                    print "WARNING! Inumpyut file %s has a SR different from EPSG:4326 (WGS84). This can make the processing significantly slow." % _inumpyut
                    # Generation of VRT dataset in tile projection, default 'nearest neighbour' warping
                    out_ds = gdal.AutoCreateWarpedVRT(
                        in_ds, self.in_srs_wkt, self.out_srs.ExportToWkt())

                    # TODO: HIGH PRIORITY: Correction of AutoCreateWarpedVRT according the max zoomlevel for correct direct warping!!!

                    if self.options.verbose:
                        print(
                            "Warping of the raster by AutoCreateWarpedVRT (result saved into 'tiles.vrt')"
                        )
                    out_ds.GetDriver().CreateCopy("%s.vrt" % _inumpyut, out_ds)
                    inumpyut_or_vrt = "%s.vrt" % _inumpyut

                    # Note: self.in_srs and self.in_srs_wkt contain still the non-warped reference system!!!

        else:
            self.error(
                "Inumpyut file has unknown SRS.",
                "Use --s_srs ESPG:xyz (or similar) to provide source reference system."
            )

        if out_ds and self.options.verbose:
            print(
                "Projected file:", "tiles.vrt", "( %sP x %sL - %s bands)" %
                (out_ds.RasterXSize, out_ds.RasterYSize, out_ds.RasterCount))

        if not out_ds:
            out_ds = in_ds

        #
        # Here we should have a raster (out_ds) in the correct Spatial Reference system
        #

        # Get alpha band (either directly or from NODATA value)
        alphaband = out_ds.GetRasterBand(1).GetMaskBand()
        if (alphaband.GetMaskFlags() & gdal.GMF_ALPHA
            ) or out_ds.RasterCount == 4 or out_ds.RasterCount == 2:
            # TODO: Better test for alpha band in the dataset
            dataBandsCount = out_ds.RasterCount - 1
        else:
            dataBandsCount = out_ds.RasterCount

        # Read the georeference
        out_gt = out_ds.GetGeoTransform()

        # Report error in case rotation/skew is in geotransform (possible only in 'raster' profile)
        if (out_gt[2], out_gt[4]) != (0, 0):
            self.error(
                "Georeference of the raster contains rotation or skew. Such raster is not supported. Please use gdalwarp first."
            )
            # TODO: Do the warping in this case automaticaly

        #
        # Here we expect: pixel is square, no rotation on the raster
        #

        # Output Bounds - coordinates in the output SRS
        ominx = out_gt[0]
        omaxx = out_gt[0] + out_ds.RasterXSize * out_gt[1]
        omaxy = out_gt[3]
        ominy = out_gt[3] - out_ds.RasterYSize * out_gt[1]
        # Note: maybe round(x, 14) to avoid the gdal_translate behaviour, when 0 becomes -1e-15

        if self.options.verbose:
            print("Bounds (output srs):", round(ominx,
                                                13), ominy, omaxx, omaxy)

        #
        # Calculating ranges for tiles in different zoom levels
        #

        geodetic = GlobalGeodetic()  # from globalmaptiles.py

        # Generate table with min max tile coordinates for all zoomlevels
        tminmax = list(range(0, 32))
        for tz in range(0, 32):
            tminx, tminy = geodetic.LatLonToTile(ominx, ominy, tz)
            tmaxx, tmaxy = geodetic.LatLonToTile(omaxx, omaxy, tz)
            # crop tiles extending world limits (+-180,+-90)
            tminx, tminy = max(0, tminx), max(0, tminy)
            tmaxx, tmaxy = min(2**(tz + 1) - 1, tmaxx), min(2**tz - 1, tmaxy)
            tminmax[tz] = (tminx, tminy, tmaxx, tmaxy)

        # Get the maximal zoom level (closest possible zoom level up on the resolution of raster)
        tminz = geodetic.ZoomForPixelSize(
            out_gt[1] * max(out_ds.RasterXSize, out_ds.RasterYSize) /
            float(self.tilesize))
        if self.options.verbose:
            print('Min Zoom: %s' % tminz)

        # Get the maximal zoom level (closest possible zoom level up on the resolution of raster)
        tmaxz = geodetic.ZoomForPixelSize(out_gt[1])
        if self.options.verbose:
            print('Max Zoom: %s' % tmaxz)

        self.inumpyuts_data[_inumpyut] = [
            tminz, tmaxz, tminmax, out_gt[1], out_gt[5]
        ]

        self.inumpyuts_files_or_vrt.append(inumpyut_or_vrt)

        if self.options.verbose:
            print("Bounds (latlong):", ominx, ominy, omaxx, omaxy)
示例#6
0
def process_file(spath, tpath):
    old_ds = gdal.Open(spath)
    vrt_ds = gdal.AutoCreateWarpedVRT(old_ds, None, srs.ExportToWkt(),
                                      gdal.GRA_Bilinear)
    gdal.GetDriverByName('gtiff').CreateCopy(tpath, vrt_ds)
示例#7
0
def _get_map(obj, params, request):
    p_layers = params['LAYERS'].split(',')
    p_bbox = _validate_bbox([float(v) for v in params['BBOX'].split(',', 3)])
    p_width = int(params['WIDTH'])
    p_height = int(params['HEIGHT'])
    p_format = params.get('FORMAT', IMAGE_FORMAT.PNG)
    p_style = params.get('STYLES')
    p_bgcolor = params.get('BGCOLOR')
    p_transparent = params.get('TRANSPARENT', 'FALSE')
    p_srs = params.get('SRS', params.get('CRS'))

    if p_format not in IMAGE_FORMAT.enum:
        raise ValidationError("Invalid FORMAT parameter.",
                              data=dict(code="InvalidFormat"))
    if p_style and not (p_style == "," * (len(p_layers) - 1)):
        raise ValidationError("Style not found.",
                              data=dict(code="StyleNotDefined"))
    if p_srs is None:
        raise ValidationError(message="CRS/SRS parameter required.")
    if p_bgcolor:
        r, g, b = _validate_bgcolor(p_bgcolor)
        bgcolor = (r, g, b)
    else:
        bgcolor = (255, 255, 255)

    if p_transparent.upper() == 'TRUE':
        img_mode = 'RGBA'
        bgcolor = bgcolor + (0, )
    else:
        img_mode = 'RGB'

    p_size = (p_width, p_height)

    img = Image.new(img_mode, p_size, bgcolor)

    try:
        epsg, axis_sy = parse_srs(p_srs)
    except SRSParseError as e:
        raise ValidationError(message=str(e), data=dict(code="InvalidSRS"))
    try:
        srs = SRS.filter_by(id=epsg).one()
    except NoResultFound:
        raise ValidationError(message="SRS (id=%d) not found." % epsg,
                              data=dict(code="InvalidSRS"))

    def scale(delta, img_px):
        dpi = 96
        img_inch = float(img_px) / dpi
        img_m = img_inch * 0.0254

        return delta / img_m

    xmin, ymin, xmax, ymax = p_bbox

    if srs.is_geographic:
        distance = geographic_distance(xmin, ymin, xmax, ymax)
    else:
        distance = xmax - xmin
    w_scale = scale(distance, p_width)

    for lname in p_layers:
        lobj = layer_by_keyname(obj, lname)

        res = lobj.resource
        request.resource_permission(DataScope.read, res)

        if (lobj.min_scale_denom is None or lobj.min_scale_denom >= w_scale) and \
                (lobj.max_scale_denom is None or w_scale >= lobj.max_scale_denom):
            req = res.render_request(res.srs)

            # Do not use foreign SRS as it does not work correctly yet
            if srs.id == res.srs.id:
                limg = req.render_extent(p_bbox, p_size)
            else:
                mem = gdal.GetDriverByName('MEM')

                dst_geo = (xmin, (xmax - xmin) / p_width, 0, ymax, 0,
                           (ymin - ymax) / p_height)
                dst_ds = mem.Create('', p_width, p_height, 4, gdal.GDT_Byte)
                dst_ds.SetGeoTransform(dst_geo)

                vrt = gdal.AutoCreateWarpedVRT(dst_ds, srs.wkt, res.srs.wkt)
                src_width = vrt.RasterXSize
                src_height = vrt.RasterYSize
                src_geo = vrt.GetGeoTransform()
                vrt = None

                src_bbox = (src_geo[0], src_geo[3] + src_geo[5] * src_height,
                            src_geo[0] + src_geo[1] * src_width, src_geo[3])
                limg = req.render_extent(src_bbox, (src_width, src_height))

                if limg is not None:
                    data = numpy.asarray(limg)
                    img_h, img_w, band_count = data.shape

                    src_ds = mem.Create('', src_width, src_height, band_count,
                                        gdal.GDT_Byte)
                    src_ds.SetGeoTransform(src_geo)
                    for i in range(band_count):
                        bandArray = data[:, :, i]
                        src_ds.GetRasterBand(i + 1).WriteArray(bandArray)

                    gdal.ReprojectImage(src_ds, dst_ds, res.srs.wkt, srs.wkt)

                    array = numpy.zeros((p_height, p_width, band_count),
                                        numpy.uint8)
                    for i in range(band_count):
                        array[:, :, i] = gdal_array.BandReadAsArray(
                            dst_ds.GetRasterBand(i + 1))
                    limg = Image.fromarray(array)

                    src_ds = dst_ds = None

            if limg is not None:
                img.paste(limg, (0, 0), limg)

    buf = BytesIO()

    if p_format == IMAGE_FORMAT.JPEG:
        img.convert('RGB').save(buf, 'jpeg')
    elif p_format == IMAGE_FORMAT.PNG:
        img.save(buf, 'png', compress_level=3)

    buf.seek(0)

    return Response(body_file=buf, content_type=p_format)
示例#8
0
文件: netcdf_cf.py 项目: sotex/gdal
def netcdf_cfproj_testcopy(projTuples, origTiff, interFormats, inPath, outPath,
                           resFilename):
    """Test a Geotiff file can be converted to NetCDF, and projection in
    CF-1 conventions can be successfully maintained. Save results to file.

    :arg: projTuples - list of tuples
    :arg: interFormats - dict of intermediate format overrides
    :arg: outPath - path to save output
    :arg: resFilename - results filename to write to.
    """

    silent = True
    gdaltest.netcdf_drv_silent = True
    bWriteGdalTags = "YES"
    # silent = False
    gdaltest.netcdf_drv_silent = False
    #    bWriteGdalTags="NO"

    result = 'success'

    # Test if ncdump is available
    try:
        (_, err) = gdaltest.runexternal_out_and_err('ncdump -h')
    except OSError:
        # nothing is supported as ncdump not found
        pytest.skip('NOTICE: netcdf version not found')

    i = err.find('netcdf library version ')
    # version not found
    if i == -1:
        pytest.skip('NOTICE: netcdf version not found')

    if not os.path.exists(outPath):
        os.makedirs(outPath)
    resFile = open(os.path.join(outPath, resFilename), "w")

    if not os.path.exists(outPath):
        os.makedirs(outPath)

    heading = "Testing GDAL translation results to NetCDF\n"
    resFile.write(heading)
    resFile.write(len(heading) * "=" + "\n")

    #    now = datetime.datetime.now()
    #    resFile.write("*Date/time:* %s\n" % (now.strftime("%Y-%m-%d %H:%M")))
    resFile.write("\n")

    resPerProj = {}

    dsTiff = gdal.Open(os.path.join(inPath, origTiff), gdal.GA_ReadOnly)
    s_srs_wkt = dsTiff.GetProjection()

    # objects to hold the various tests
    i_t = 0
    tst_res = {}

    for proj in projTuples:
        try:
            intFmt = interFormats[proj[0]]
        except KeyError:
            intFmt = netcdf_cfproj_def_int_format

        intExt = netcdf_cfproj_format_fnames[intFmt]

        # Our little results data structures
        if not silent:
            print("")
            print("Testing %s (%s) translation:" % (proj[0], proj[1]))

        if not silent:
            print("About to create raster in chosen SRS")
        # projVrt = os.path.join(outPath, "%s_%s.vrt" % \
        #    (origTiff.rstrip('.tif'), proj[0] ))
        projRaster = os.path.join(
            outPath, "%s_%s.%s" %
            (os.path.basename(origTiff).rstrip('.tif'), proj[0], intExt))
        srs = osr.SpatialReference()
        srs.SetFromUserInput(proj[2])
        t_srs_wkt = srs.ExportToWkt()
        if not silent:
            print("going to warp file " + origTiff + "\n" + s_srs_wkt +
                  "\ninto file " + projRaster + "\n" + t_srs_wkt)
        dswarp = gdal.AutoCreateWarpedVRT(dsTiff, s_srs_wkt, t_srs_wkt,
                                          gdal.GRA_NearestNeighbour, 0)
        drv_inter = gdal.GetDriverByName(intFmt)
        drv_netcdf = gdal.GetDriverByName("netcdf")
        dsw = drv_inter.CreateCopy(projRaster, dswarp, 0)
        if not silent:
            print("Warped %s to %s" % (proj[0], projRaster))

        projNc = os.path.join(outPath,
                              "%s_%s.nc" % (origTiff.rstrip('.tif'), proj[0]))
        # Force GDAL tags to be written to make testing easier, with preserved datum etc
        # ncCoOpts = "-co WRITE_GDAL_TAGS=yes"
        if not silent:
            print("About to translate to NetCDF")
        dst = drv_netcdf.CreateCopy(projNc, dsw, 0,
                                    ['WRITE_GDAL_TAGS=' + bWriteGdalTags])
        # For drivers like HFA, line below ESSENTIAL so that all info is
        # saved to new raster file - which we'll reopen later and want
        # to be fully updated.
        dsw = None
        del dst
        if not silent:
            print("Translated to %s" % (projNc))

        transWorked, resDetails = netcdf_cfproj_test_cf(proj, projNc)
        resPerProj[proj[0]] = resDetails

        resFile.write("%s (%s): " % (proj[0], proj[1]))
        if transWorked:
            resFile.write("OK\n")
        else:
            resFile.write("BAD\n")
            if 'missingProjName' in resPerProj[proj[0]]:
                resFile.write("\tMissing proj name '%s'\n" %
                              (resPerProj[proj[0]]['missingProjName']))
            for attrib in resPerProj[proj[0]]['missingAttrs']:
                resFile.write("\tMissing attrib '%s'\n" % (attrib))
            for cVarStdName in resPerProj[proj[0]]['missingCoordVarStdNames']:
                resFile.write("\tMissing coord var with std name '%s'\n" %
                              (cVarStdName))
            if 'cfcheck_error' in resPerProj[proj[0]]:
                resFile.write("\tFailed cf check: %s\n" %
                              (resPerProj[proj[0]]['cfcheck_error']))

        # test file copy
        # We now copy to a new file, just to be safe
        projNc2 = projNc.rstrip('.nc') + '2.nc'
        projRaster2 = os.path.join(
            outPath, "%s_%s2.%s" % (origTiff.rstrip('.tif'), proj[0], intExt))

        tst_res[i_t + 1] = netcdf_test_copy(projRaster, 1, None, projNc2, [],
                                            'NETCDF')
        tst_res[i_t + 2] = netcdf_test_copy(projNc2, 1, None, projRaster2, [],
                                            intFmt)

        if tst_res[i_t + 1] == 'fail' or tst_res[i_t + 2] == 'fail':
            result = 'fail'

        i_t = i_t + 2

    resFile.close()

    if not silent:
        print("\n" + "*" * 80)
        print("Saved results to file %s" %
              (os.path.join(outPath, resFilename)))

    # result = 'success'
    resFile = open(os.path.join(outPath, resFilename), "r")
    resStr = resFile.read()
    if resStr.find('BAD') != -1:
        print(
            '\nCF projection tests failed, here is the output (stored in file %s)\n'
            % (os.path.join(outPath, resFilename)))
        print(resStr)
        result = 'fail'

    return result
示例#9
0
def gdal_reproject(src,
                   dst=None,
                   src_srs=None,
                   dst_srs=None,
                   epsg=None,
                   error_threshold=0.125,
                   resampling=gdalconst.GRA_NearestNeighbour,
                   as_gdal_grid=False):
    """
    Reproject a raster image.

    Based on: https://github.com/OpenDataAnalytics/
            gaia/blob/master/gaia/geo/gdal_functions.py

    Parameters
    ----------
        src: :obj:`str` or :func:`gdal.Dataset` or :func:`~GDALGrid`
            The source image.
        dst: :obj:`str`, optional
            The filepath of the output image to write to.
        src_srs: :func:`osr.SpatialReference`, optional
            The source image projection.
        dst_srs: :func:`osr.SpatialReference`, optional
            The destination projection. If not provided,
            the code will use `epsg`.
        epsg: int, optional
            The EPSG code to reproject to. If not provided,
            the code will use `dst_srs`.
        error_threshold: float, optional
            Default is 0.125 (same as gdalwarp commandline).
        resampling: :func:`osgeo.gdalconst`
            Method to use for resampling. Default method is
            `gdalconst.GRA_NearestNeighbour`.
        as_gdal_grid: bool, optional
            Return as :func:`~GDALGrid`. Default is False.

    Returns
    -------
    :func:`gdal.Dataset` or :func:`~GDALGrid`
        By default, it returns `gdal.Dataset`.
        It will return :func:`~GDALGrid` if `as_gdal_grid` is True.
    """
    # Open source dataset
    src_ds = load_raster(src)[0]

    # Define target SRS
    if dst_srs is None:
        dst_srs = osr.SpatialReference()
        dst_srs.ImportFromEPSG(int(epsg))

    dst_wkt = dst_srs.ExportToWkt()

    # Resampling might be passed as a string
    if not isinstance(resampling, int):
        resampling = getattr(gdal, resampling)

    src_wkt = None
    if src_srs is not None:
        src_wkt = src_srs.ExportToWkt()

    # Call AutoCreateWarpedVRT() to fetch default values
    # for target raster dimensions and geotransform
    reprojected_ds = gdal.AutoCreateWarpedVRT(src_ds, src_wkt, dst_wkt,
                                              resampling, error_threshold)

    # Create the final warped raster
    if dst:
        gdal.GetDriverByName('GTiff').CreateCopy(dst, reprojected_ds)
    if as_gdal_grid:
        return GDALGrid(reprojected_ds)
    return reprojected_ds
示例#10
0
    def run(self):
        """Run method that performs all the real work"""
        # prepare dialog parameters
        settings = QSettings()
        lastDir = settings.value("/UI/lastShapefileDir")
        filter = "GarminCustomMap-files (*.kmz)"
        out_putFile = QgsEncodingFileDialog(None, "Select output file",
                                            'My_CustomMap.kmz',
                                            "GarminCustomMap (*.kmz)")
        out_putFile.setDefaultSuffix("kmz")
        out_putFile.setFileMode(QFileDialog.AnyFile)
        out_putFile.setAcceptMode(QFileDialog.AcceptSave)
        # out_putFile.setConfirmOverwrite(True)
        if out_putFile.exec_() == QDialog.Accepted:
            kmz_file = out_putFile.selectedFiles()[0]
            # Get mapCanvas and mapRenderer variables
            canvas = self.iface.mapCanvas()
            scale = canvas.scale()
            mapSettings = canvas.mapSettings()
            mapRect = canvas.extent()
            width = int(round(mapSettings.outputSize().width()))
            height = int(round(mapSettings.outputSize().height()))
            srs = mapSettings.destinationCrs()
            SourceCRS = str(srs.authid())
            # Save settings for resetting the mapRenderer after GCM production
            old_width = mapSettings.outputSize().width()
            old_height = mapSettings.outputSize().height()
            old_dpi = mapSettings.outputDpi()
            # Give information about project projection, mapCanvas size and Custom map settings
            if (height * width) % (1024.0 * 1024.0) >= 1:
                expected_tile_n_unzoomed = int(
                    (height * width) / (1024.0 * 1024.0)) + 1
            else:
                expected_tile_n_unzoomed = int(
                    (height * width) / (1024.0 * 1024.0))

            if len(str(int(sqrt(100 / ((height * width) /
                                       (1024.0 * 1024.0)))))) == 1:
                max_zoom_100 = str(
                    sqrt(100 / ((height * width) / (1024.0 * 1024.0))))[0:3]
            else:
                max_zoom_100 = str(
                    sqrt(100 / ((height * width) / (1024.0 * 1024.0))))[0:4]

            if len(str(int(sqrt(500 / ((height * width) /
                                       (1024.0 * 1024.0)))))) == 1:
                max_zoom_500 = str(
                    sqrt(500 / ((height * width) / (1024.0 * 1024.0))))[0:3]
            else:
                max_zoom_500 = str(
                    sqrt(500 / ((height * width) / (1024.0 * 1024.0))))[0:4]

            if SourceCRS != 'EPSG:4326':

                def projWaring():
                    proj_msg = QMessageBox()
                    proj_msg.setWindowTitle(
                        "Coordinate Reference System mismatch")
                    proj_msg.setText(
                        "The coordinate reference system (CRS) of your project differs from WGS84 (EPSG: 4326). "
                        "It is likely, that you will produce a better Custom Map "
                        "when your project and data has CRS WGS84!\n"
                        "\n"
                        "The number of rows and columns in the exported image "
                        "will be affected by reprojecting to WGS84 and estimates for "
                        "the number of tiles etc. in the \"Setting hints\"-Tab will be incorrect!"
                    )
                    proj_msg.exec_()

                widget = iface.messageBar().createMessage(
                    "WARNING", "Project CRS differs from WGS84 (EPSG: 4326)")
                button = QPushButton(widget)
                button.setText("Info")
                button.pressed.connect(projWaring)
                widget.layout().addWidget(button)
                iface.messageBar().pushWidget(widget,
                                              Qgis.Critical,
                                              duration=10)

            # create the dialog
            dlg = GarminCustomMapDialog()

            # Update the dialog
            dlg.textBrowser.setHtml(
                "<p>The following information should help you "
                "to adjust the settings for your Garmin Custom Map.</p>"
                "<p>Your current map canvas contains<br>" + str(height) +
                " rows and<br>" + str(width) + " colums.</p>"
                "<p>Zooming level 1.0 (map scale of the current map canvas which is 1:"
                + str(round(scale)) + ") will result in " +
                str(expected_tile_n_unzoomed) + " tile(s) "
                "(single images within your Garmin Custom Map).</p>"
                "<p>In general, Garmin Custom Maps are limited to a number of 100 tiles in total (across all Garmin Custom Maps on the device). "
                "A Garmin Custom Map produced with the current Zoom level will occupy "
                + str(expected_tile_n_unzoomed) + "% "
                "of the total capacity of most types of Garmin GPS units.<br>"
                "To comply with a limit of 100 tiles, you should use a zoom factor &lt;= "
                + max_zoom_100 + ". "
                "This will result in a scale of your Garmin Custom Map of 1 : "
                + str(int(round(scale / float(max_zoom_100)))) + ".</p>"
                "<p>However, newer Garmin GPS units (Montana, Oregon 6x0, and GPSMAP 64) have a limit of 500 tiles in total (across all Garmin Custom Maps on the device. "
                "For such GPS units, a Garmin Custom Map produced with the current Zoom level will occupy"
                + str(round((expected_tile_n_unzoomed / 5.0), 1)) + "% "
                "of the maximum possible number of tiles across all Custom Maps on your GPS unit.<br>"
                "To comply with a limit of 500 tiles, you should use a zoom factor &lt;= "
                + max_zoom_500 + ". "
                "This will result in a scale of your Garmin Custom Map of 1 : "
                + str(int(round(scale / float(max_zoom_500)))) + ".</p>"
                "<p>For more information on size limits and technical details regarding the "
                """Garmin Custom Maps format see \"About-Tab\" and/or <a href="https://forums.garmin.com/showthread.php?t=2646">https://forums.garmin.com/showthread.php?t=2646</a></p> """
            )

            dlg.zoom_100.setText(
                "Max. zoom for devices with  &lt;= 100 tiles: " +
                max_zoom_100 + " (1:" +
                str(int(round(scale / float(max_zoom_100)))) + ")")
            dlg.zoom_500.setText(
                "Max. zoom for devices with  &lt;= 500 tiles: " +
                max_zoom_500 + " (1:" +
                str(int(round(scale / float(max_zoom_500)))) + ")")

            # Show the dialog
            dlg.show()
            result = dlg.exec_()
            # See if OK was pressed
            if result == 1:
                # Set variables
                optimize = int(dlg.flag_optimize.isChecked())
                skip_empty = int(dlg.flag_skip_empty.isChecked())
                max_y_ext_general = int(dlg.nrows.value())
                max_x_ext_general = int(dlg.ncols.value())
                qual = int(dlg.jpg_quality.value())
                # Set options for jpg-production
                options = []
                options.append("QUALITY=" + str(qual))
                draworder = dlg.draworder.value()
                zoom = float(dlg.zoom.value())
                in_file = os.path.basename(kmz_file[0:(len(kmz_file) - 4)])
                max_pix = (1024 * 1024)
                # Create tmp-folder
                out_folder = tempfile.mkdtemp('_tmp', 'gcm_')
                out_put = os.path.join(out_folder, in_file)
                input_file = out_put + u'.png'

                tname = in_file
                # Set QGIS objects
                target_dpi = int(round(zoom * mapSettings.outputDpi()))
                # Initialise temporary output image
                x, y = 0, 0
                width = mapSettings.outputSize().width() * zoom
                height = mapSettings.outputSize().height() * zoom
                mapSettings.setOutputSize(QSize(width, height))
                mapSettings.setOutputDpi(target_dpi)
                mapSettings.setExtent(mapRect)
                mapSettings.setFlags(QgsMapSettings.Antialiasing
                                     | QgsMapSettings.UseAdvancedEffects
                                     | QgsMapSettings.ForceVectorOutput
                                     | QgsMapSettings.DrawLabeling)

                # create output image and initialize it
                image = QImage(QSize(width, height), QImage.Format_RGB555)
                image.fill(qRgb(255, 255, 255))

                # adjust map canvas (renderer) to the image size and render
                imagePainter = QPainter(image)
                imagePainter.begin(image)
                mapRenderer = QgsMapRendererCustomPainterJob(
                    mapSettings, imagePainter)
                mapRenderer.start()
                mapRenderer.waitForFinished()
                imagePainter.end()

                # Save the image
                image.save(input_file, "png")

                # Set Geotransform and NoData values
                input_dataset = gdal.Open(input_file)

                # Set Geotransform values
                ULy = mapRect.yMaximum()
                ULx = mapRect.xMinimum()
                LRx = mapRect.xMaximum()
                LRy = mapRect.yMinimum()
                xScale = (LRx - ULx) / width
                yScale = (LRy - ULy) / height
                input_dataset.SetGeoTransform([ULx, xScale, 0, ULy, 0, yScale])

                # Close dataset
                input_dataset = None

                # Reset mapSettings to old size (monitor)
                mapSettings.setOutputSize(QSize(old_width, old_height))

                # Warp the exported image to WGS84 if necessary
                if SourceCRS != 'EPSG:4326':
                    # Define input and output file
                    input_geofile = out_put + "wgs84.tif"
                    output_geofile = os.path.join(out_folder, input_geofile)
                    # Register tif-driver
                    driver = gdal.GetDriverByName("GTiff")
                    driver.Register()
                    # Define input CRS
                    in_CRS = srs.toWkt()
                    # in_CRS = srs.toWkt().encode('UTF-8')
                    # print type(in_CRS)
                    # Define output CRS
                    out_CRS = QgsCoordinateReferenceSystem(
                        4326, QgsCoordinateReferenceSystem.EpsgCrsId).toWkt()
                    # out_CRS = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId).toWkt().encode('UTF-8')
                    # print type(out_CRS)
                    # Open input dataset
                    input_dataset = gdal.Open(input_file)

                    # Create VRT
                    reproj_file = gdal.AutoCreateWarpedVRT(
                        input_dataset, in_CRS, out_CRS)
                    reproj_file.GetRasterBand(1).Fill(255)
                    reproj_file.GetRasterBand(2).Fill(255)
                    reproj_file.GetRasterBand(3).Fill(255)

                    # Reproject
                    gdal.ReprojectImage(input_dataset, reproj_file, in_CRS,
                                        out_CRS)
                    reproj_attributes = reproj_file.GetGeoTransform()

                    # Update relevant georef variables
                    ULx = reproj_attributes[0]
                    ULy = reproj_attributes[3]
                    xScale = reproj_attributes[1]
                    yScale = reproj_attributes[5]

                    driver = gdal.GetDriverByName("GTiff")
                    warped_input = driver.CreateCopy(output_geofile,
                                                     reproj_file, 0)

                    input_dataset = None
                    reproj_file = None
                    warped_input = None
                    input_file = output_geofile

                # Calculate tile size and number of tiles
                indataset = gdal.Open(input_file)

                x_extent = indataset.RasterXSize
                y_extent = indataset.RasterYSize
                if optimize == 1:
                    # Identify length of the short and long side of the map canvas and their relation
                    short_ext = min(x_extent, y_extent)
                    long_ext = max(x_extent, y_extent)
                    s_l_side_relation = 0

                    # Estimate number of tiles in the result
                    if float(x_extent * y_extent) % (1024 * 1024) >= 1:
                        expected_tile_n = int(
                            float(x_extent * y_extent) / (1024 * 1024)) + 1
                    else:
                        expected_tile_n = int(
                            float(x_extent * y_extent) / (1024 * 1024))

                    # Find settings for tiling with:
                    # 1 minimum number of tiles,
                    # 2 a short / long size relation close to 1,
                    # 3 and a minimum numer of pixels in each tile
                    for tc in range(1, expected_tile_n + 1, 1):
                        if expected_tile_n % tc >= 1:
                            continue
                        else:

                            if short_ext % tc >= 1:
                                s_pix = int(short_ext / tc) + 1
                            else:
                                s_pix = int(short_ext / tc)

                            if long_ext % tc >= 1:
                                l_pix = int(long_ext /
                                            (expected_tile_n / tc)) + 1
                            else:
                                l_pix = int(long_ext / (expected_tile_n / tc))

                            if (s_pix * l_pix) <= (1024 * 1024):
                                if min((float(s_pix) / float(l_pix)),
                                       (float(l_pix) /
                                        float(s_pix))) >= s_l_side_relation:
                                    s_l_side_relation = min(
                                        (float(s_pix) / float(l_pix)),
                                        (float(l_pix) / float(s_pix)))
                                    s_pix_opt = s_pix
                                    l_pix_opt = l_pix

                    # Set tile size variable according to optimal setings
                    if short_ext == x_extent:
                        max_x_ext_general = s_pix_opt
                        max_y_ext_general = l_pix_opt
                    else:
                        max_y_ext_general = s_pix_opt
                        max_x_ext_general = l_pix_opt

                # Identify number of rows and columns
                n_cols_rest = x_extent % max_x_ext_general
                n_rows_rest = y_extent % max_y_ext_general
                #
                if n_cols_rest >= 1:
                    n_cols = (x_extent / max_x_ext_general) + 1
                else:
                    n_cols = (x_extent / max_x_ext_general)

                #
                if n_rows_rest >= 1:
                    n_rows = (y_extent / max_y_ext_general) + 1
                else:
                    n_rows = (y_extent / max_y_ext_general)

                # Check if number of tiles is below Garmins limit of 100 tiles (across all custom maps)
                n_tiles = (n_rows * n_cols)
                if n_tiles > 100:
                    iface.messageBar().pushMessage(
                        "WARNING",
                        "The number of tiles is likely to exceed Garmins limit of 100 tiles! Not all tiles will be displayed on your GPS unit. Consider reducing your map size (extend or zoom-factor).",
                        duration=5)

                progressMessageBar = iface.messageBar().createMessage(
                    "Producing tiles...")
                progress = QProgressBar()
                progress.setMaximum(n_tiles)
                progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
                progressMessageBar.layout().addWidget(progress)
                iface.messageBar().pushWidget(progressMessageBar, Qgis.Info)

                # Check if size of tiles is below Garmins limit of 1 megapixel (for each tile)
                n_pix = (max_x_ext_general * max_y_ext_general)

                if n_pix > max_pix:
                    iface.messageBar().pushMessage(
                        "WARNING",
                        "The number of pixels in a tile exceeds Garmins limit of 1 megapixel per tile! Images will not be displayed properly.",
                        level=Qgis.Warning,
                        duration=5)

                kmz = zipfile.ZipFile(kmz_file, 'w')
                with open(os.path.join(out_folder, 'doc.kml'), 'w') as kml:

                    # Write kml header
                    kml.write('<?xml version="1.0" encoding="UTF-8"?>\n')
                    kml.write('<kml xmlns="http://www.opengis.net/kml/2.2">\n')
                    kml.write('  <Document>\n')
                    kml.write('    <name>' +
                              tname.encode('UTF-8').decode('utf-8') +
                              '</name>\n')

                    # Produce .jpg tiles using gdal_translate looping through the complete rows and columns (1024x1024 pixel)
                    y_offset = 0
                    x_offset = 0
                    r = 1
                    c = 1
                    n_tiles = 0
                    empty_tiles = 0
                    # Loop through rows
                    for r in range(1, int(n_rows) + 1, 1):
                        # Define maximum Y-extend of tiles
                        if r == (n_rows) and n_rows_rest > 0:
                            max_y_ext = n_rows_rest
                        else:
                            max_y_ext = max_y_ext_general

                        # (Within row-loop) Loop through columns
                        for c in range(1, int(n_cols) + 1, 1):
                            # Define maximum X-extend of tiles
                            if c == int(n_cols) and n_cols_rest > 0:
                                max_x_ext = n_cols_rest
                            else:
                                max_x_ext = max_x_ext_general
                            # Define name for tile-jpg
                            t_name = tname + '_%(r)d_%(c)d.jpg' % {
                                "r": r,
                                "c": c
                            }
                            # Set parameters for "gdal_translate" (JPEG-driver has no Create() (but CreateCopy()) method so first a VRT has to be created band by band
                            # Create VRT dataset for tile
                            mem_driver = gdal.GetDriverByName("MEM")
                            mem_driver.Register()
                            t_file = mem_driver.Create('', max_x_ext,
                                                       max_y_ext, 3,
                                                       gdalconst.GDT_Byte)
                            t_band_1 = indataset.GetRasterBand(1).ReadAsArray(
                                x_offset, y_offset, max_x_ext, max_y_ext)
                            t_band_2 = indataset.GetRasterBand(2).ReadAsArray(
                                x_offset, y_offset, max_x_ext, max_y_ext)
                            t_band_3 = indataset.GetRasterBand(3).ReadAsArray(
                                x_offset, y_offset, max_x_ext, max_y_ext)

                            if skip_empty == 1:
                                if t_band_1.min() == 255 and t_band_2.min(
                                ) == 255 and t_band_3.min() == 255:
                                    empty_tiles = empty_tiles + 1

                            t_file.GetRasterBand(1).WriteArray(t_band_1)
                            t_file.GetRasterBand(2).WriteArray(t_band_2)
                            t_file.GetRasterBand(3).WriteArray(t_band_3)
                            t_band_1 = None
                            t_band_2 = None
                            t_band_3 = None

                            # Translate MEM dataset to JPG
                            jpg_driver = gdal.GetDriverByName("JPEG")
                            jpg_driver.Register()
                            jpg_driver.CreateCopy(os.path.join(
                                out_folder, t_name),
                                                  t_file,
                                                  options=options)

                            # Close GDAL-datasets
                            t_file = None
                            t_jpg = None
                            # Get bounding box for tile
                            n = ULy + (y_offset * yScale)
                            s = ULy + ((y_offset + max_y_ext) * yScale)
                            e = ULx + ((x_offset + max_x_ext) * xScale)
                            w = ULx + (x_offset * xScale)
                            # Add .jpg to .kmz-file and remove it together with its meta-data afterwards
                            kmz.write(os.path.join(out_folder, t_name), t_name)
                            os.remove(os.path.join(out_folder, t_name))

                            # Write kml-tags for each tile (Name, DrawOrder, JPEG-Reference, GroundOverlay)
                            kml.write('')
                            kml.write('    <GroundOverlay>\n')
                            kml.write('        <name>' +
                                      tname.encode('UTF-8').decode('utf-8') +
                                      ' Tile ' + str(r) + '_' + str(c) +
                                      '</name>\n')  # %{"r":r, "c":c}
                            kml.write(
                                '        <drawOrder>' + str(draworder) +
                                '</drawOrder>\n')  # %{"draworder":draworder}
                            kml.write('        <Icon>\n')
                            kml.write('          <href>' +
                                      tname.encode('UTF-8').decode('utf-8') +
                                      '_' + str(r) + '_' + str(c) +
                                      '.jpg</href>\n')  # %{"r":r, "c":c}
                            kml.write('        </Icon>\n')
                            kml.write('        <LatLonBox>\n')
                            kml.write('          <north>' + str(n) +
                                      '</north>\n')
                            kml.write('          <south>' + str(s) +
                                      '</south>\n')
                            kml.write('          <east>' + str(e) +
                                      '</east>\n')
                            kml.write('          <west>' + str(w) +
                                      '</west>\n')
                            kml.write('        </LatLonBox>\n')
                            kml.write('    </GroundOverlay>\n')

                            # Calculate new X-offset
                            x_offset = (x_offset + max_x_ext)
                            n_tiles = (n_tiles + 1)
                            # Update progress bar
                            progress.setValue(n_tiles)
                        # Calculate new Y-offset
                        y_offset = (y_offset + max_y_ext)
                        # Reset X-offset
                        x_offset = 0

                    # Write kml footer
                    kml.write('  </Document>\n')
                    kml.write('</kml>\n')
                # Close kml file
                # kml.close()

                # Close GDAL dataset
                indataset = None

                # Remove temporary geo-tif file
                os.remove(out_put + u'.png')
                os.remove(out_put + u'.png.aux.xml')

                # Remove reprojected temporary geo-tif file if necessary
                if SourceCRS != 'EPSG:4326':
                    os.remove(output_geofile)

                # Add .kml to .kmz-file and remove it together with the rest of the temporary files
                kmz.write(os.path.join(out_folder, u'doc.kml'), u'doc.kml')
                os.remove(os.path.join(out_folder, u'doc.kml'))
                kmz.close()
                os.rmdir(out_folder)
                # Clear progressbar
                iface.messageBar().clearWidgets()

                tiles_total = n_tiles - empty_tiles
                # Give success message
                iface.messageBar().pushMessage(
                    "Done",
                    "Produced " + str(tiles_total) + " tiles, with " +
                    str(n_rows) + " rows and " + str(int(n_cols)) + " colums.",
                    level=Qgis.Info,
                    duration=5)
示例#11
0
def get_aster(ifile):
    """
    Gets ASTER Data

    Parameters
    ----------
    ifile : str
        filename to import

    Returns
    -------
    dat : PyGMI raster Data
        dataset imported
    """

    dat = []
    ifile = ifile[:]

    dataset = gdal.Open(ifile, gdal.GA_ReadOnly)

    subdata = dataset.GetSubDatasets()

    latentry = [i for i in subdata if 'Latitude' in i[1]]
    subdata.pop(subdata.index(latentry[0]))
    dataset = gdal.Open(latentry[0][0], gdal.GA_ReadOnly)
    rtmp = dataset.GetRasterBand(1)
    lats = rtmp.ReadAsArray()
    latsdim = ((lats.max() - lats.min()) / (lats.shape[0] - 1)) / 2

    lonentry = [i for i in subdata if 'Longitude' in i[1]]
    subdata.pop(subdata.index(lonentry[0]))
    dataset = gdal.Open(lonentry[0][0], gdal.GA_ReadOnly)
    rtmp = dataset.GetRasterBand(1)
    lons = rtmp.ReadAsArray()
    lonsdim = ((lons.max() - lons.min()) / (lons.shape[1] - 1)) / 2

    lonsdim = latsdim
    tlx = lons.min() - abs(lonsdim / 2)
    tly = lats.max() + abs(latsdim / 2)
    cols = int((lons.max() - lons.min()) / lonsdim) + 1
    rows = int((lats.max() - lats.min()) / latsdim) + 1

    newx2, newy2 = np.mgrid[0:rows, 0:cols]
    newx2 = newx2 * lonsdim + tlx
    newy2 = tlx - newy2 * latsdim

    subdata = [i for i in subdata if 'ImageData' in i[0]]

    i = -1
    for ifile2, bandid2 in subdata:
        dataset = gdal.Open(ifile2, gdal.GA_ReadOnly)

        rtmp2 = dataset.ReadAsArray()

        tmpds = gdal.AutoCreateWarpedVRT(dataset)
        rtmp2 = tmpds.ReadAsArray()
        gtr = tmpds.GetGeoTransform()
        tlx, lonsdim, _, tly, _, latsdim = gtr

        nval = 0

        i += 1

        dat.append(Data())
        dat[i].data = rtmp2

        if dat[i].data.dtype.kind == 'i':
            if nval is None:
                nval = 999999
            nval = int(nval)
        elif dat[i].data.dtype.kind == 'u':
            if nval is None:
                nval = 0
            nval = int(nval)
        else:
            if nval is None:
                nval = 1e+20
            nval = float(nval)

        dat[i].data = np.ma.masked_invalid(dat[i].data)
        dat[i].data.mask = dat[i].data.mask | (dat[i].data == nval)
        if dat[i].data.mask.size == 1:
            dat[i].data.mask = (np.ma.make_mask_none(dat[i].data.shape) +
                                dat[i].data.mask)

        dat[i].nrofbands = dataset.RasterCount
        dat[i].tlx = tlx
        dat[i].tly = tly
        dat[i].dataid = bandid2
        dat[i].nullvalue = nval
        dat[i].rows = dat[i].data.shape[0]
        dat[i].cols = dat[i].data.shape[1]
        dat[i].xdim = abs(lonsdim)
        dat[i].ydim = abs(latsdim)
        dat[i].gtr = gtr

        srs = osr.SpatialReference()
        srs.ImportFromWkt(dataset.GetProjection())
        srs.AutoIdentifyEPSG()

        dat[i].wkt = srs.ExportToWkt()

    if dat == []:
        dat = None
    return dat
示例#12
0
    def load_file(self, filename, env, cog=False):
        ds, imfilename = self._gdalds(filename)

        dsdriver = ds.GetDriver()
        dsproj = ds.GetProjection()
        dsgtran = ds.GetGeoTransform()

        if dsdriver.ShortName not in DRIVERS.enum:
            raise ValidationError(
                _("Raster has format '%(format)s', however only following formats are supported: %(all_formats)s."
                  )  # NOQA: E501
                % dict(format=dsdriver.ShortName,
                       all_formats=", ".join(SUPPORTED_DRIVERS)))

        if not dsproj or not dsgtran:
            raise ValidationError(
                _("Raster files without projection info are not supported."))

        # Workaround for broken encoding in WKT. Otherwise, it'll cause SWIG
        # TypeError (not a string) while passing to GDAL.
        try:
            dsproj.encode('utf-8', 'strict')
        except UnicodeEncodeError:
            dsproj = dsproj.encode('utf-8', 'replace').decode('utf-8')

        data_type = None
        alpha_band = None
        has_nodata = None
        for bidx in range(1, ds.RasterCount + 1):
            band = ds.GetRasterBand(bidx)

            if data_type is None:
                data_type = band.DataType
            elif data_type != band.DataType:
                raise ValidationError(
                    _("Mixed band data types are not supported."))

            if band.GetRasterColorInterpretation() == gdal.GCI_AlphaBand:
                assert alpha_band is None, "Multiple alpha bands found!"
                alpha_band = bidx
            else:
                has_nodata = (has_nodata is None
                              or has_nodata) and (band.GetNoDataValue()
                                                  is not None)

        src_osr = osr.SpatialReference()
        if src_osr.ImportFromWkt(dsproj) != 0:
            raise ValidationError(
                _("GDAL was uanble to parse the raster coordinate system."))

        if src_osr.IsLocal():
            raise ValidationError(
                _("The source raster has a local coordinate system and can't be "
                  "reprojected to the target coordinate system."))

        dst_osr = osr.SpatialReference()
        dst_osr.ImportFromEPSG(int(self.srs.id))

        reproject = not src_osr.IsSame(dst_osr)
        add_alpha = reproject and not has_nodata and alpha_band is None

        if reproject:
            cmd = [
                'gdalwarp', '-of', 'GTiff', '-t_srs',
                'EPSG:%d' % self.srs.id
            ]
            if add_alpha:
                cmd.append('-dstalpha')
            ds_measure = gdal.AutoCreateWarpedVRT(ds, src_osr.ExportToWkt(),
                                                  dst_osr.ExportToWkt())
            assert ds_measure is not None, gdal.GetLastErrorMsg()
        else:
            cmd = ['gdal_translate', '-of', 'GTiff']
            ds_measure = ds

        size_expected = raster_size(ds_measure, 1 if add_alpha else 0)
        ds_measure = None

        size_limit = env.raster_layer.options['size_limit']
        if size_limit is not None and size_expected > size_limit:
            raise ValidationError(message=_(
                "The uncompressed raster size (%(size)s) exceeds the limit "
                "(%(limit)s) by %(delta)s. Reduce raster size to fit the limit."
            ) % dict(
                size=format_size(size_expected),
                limit=format_size(size_limit),
                delta=format_size(size_expected - size_limit),
            ))

        cmd.extend(('-co', 'COMPRESS=DEFLATE', '-co', 'TILED=YES', '-co',
                    'BIGTIFF=YES', imfilename))

        fobj = FileObj(component='raster_layer')
        dst_file = env.raster_layer.workdir_filename(fobj, makedirs=True)
        self.fileobj = fobj

        self.cog = cog
        if not cog:
            subprocess.check_call(cmd + [dst_file])
            self.build_overview()
        else:
            # TODO: COG driver
            with NamedTemporaryFile() as tf:
                tmp_file = tf.name
                subprocess.check_call(cmd + [tmp_file])
                self.build_overview(fn=tmp_file)

                cmd = ['gdal_translate', '-of', 'Gtiff']
                cmd.extend(('-co', 'COMPRESS=DEFLATE', '-co', 'TILED=YES',
                            '-co', 'BIGTIFF=YES', '-co',
                            'COPY_SRC_OVERVIEWS=YES', tmp_file, dst_file))
                subprocess.check_call(cmd)
                os.unlink(tmp_file + '.ovr')

        ds = gdal.Open(dst_file, gdalconst.GA_ReadOnly)

        assert raster_size(ds) == size_expected, "Expected size mismatch"

        self.dtype = gdal.GetDataTypeName(data_type)
        self.xsize = ds.RasterXSize
        self.ysize = ds.RasterYSize
        self.band_count = ds.RasterCount
def main(argv):
    argv = ogr.GeneralCmdLineProcessor(argv)

    ogr_ds_name = None
    lyr_name = None

    tileitem = 'location'
    tilesrs = None
    srsname = None

    nArgc = len(argv)
    iArg = 1
    while iArg < nArgc:

        if argv[iArg] == "-lyr_name" and iArg < nArgc - 1:
            iArg = iArg + 1
            lyr_name = argv[iArg]

        elif argv[iArg] == "-tileindex" and iArg < nArgc - 1:
            iArg = iArg + 1
            tileitem = argv[iArg]

        elif argv[iArg] == "-src_srs_name" and iArg < nArgc - 1:
            iArg = iArg + 1
            tilesrs = argv[iArg]

        elif argv[iArg] == "-t_srs" and iArg < nArgc - 1:
            iArg = iArg + 1
            srsname = argv[iArg]

        elif argv[iArg][0] == '-':
            return Usage()

        elif ogr_ds_name is None:
            ogr_ds_name = argv[iArg]

        iArg = iArg + 1

    if ogr_ds_name is None or tilesrs is None:
        return Usage()

    ogr_ds = ogr.Open(ogr_ds_name)
    if ogr_ds is None:
        raise Exception('cannot open %s' % ogr_ds_name)
    if ogr_ds.GetLayerCount() == 1:
        lyr = ogr_ds.GetLayer(0)
    elif lyr_name is None:
        raise Exception('-lyr_name should be specified')
    else:
        lyr = ogr_ds.GetLayerByName(lyr_name)

    if lyr.GetLayerDefn().GetFieldIndex(tileitem) < 0:
        raise Exception('%s field cannot be found in layer definition' %
                        tileitem)

    if lyr.GetLayerDefn().GetFieldIndex(tilesrs) < 0:
        raise Exception('%s field cannot be found in layer definition' %
                        tilesrs)

    lyr_srs = lyr.GetSpatialRef()
    if srsname is not None:
        srs = osr.SpatialReference()
        if srs.SetFromUserInput(srsname) != 0:
            raise Exception('invalid value for -t_srs : %s' % srsname)

        # Sanity check
        if lyr_srs is not None:
            lyr_srs_proj4 = lyr_srs.ExportToProj4()
            lyr_srs = osr.SpatialReference()
            lyr_srs.SetFromUserInput(lyr_srs_proj4)
            lyr_srs_proj4 = lyr_srs.ExportToProj4()

            srs_proj4 = srs.ExportToProj4()
            if lyr_srs_proj4 != srs_proj4:
                raise Exception(
                    '-t_srs overrides the layer SRS in an incompatible way : (%s, %s)'
                    % (srs_proj4, lyr_srs_proj4))
    else:
        srs = lyr_srs

    if srs is None:
        raise Exception('cannot fetch source SRS')

    srs.AutoIdentifyEPSG()
    authority_name = srs.GetAuthorityName(None)
    authority_code = srs.GetAuthorityCode(None)
    dst_wkt = srs.ExportToWkt()
    if authority_name != 'EPSG' or authority_code is None:
        raise Exception('cannot fetch source SRS as EPSG:XXXX code : %s' %
                        dst_wkt)

    counter = 0
    xres = 0
    yres = 0

    while True:
        feat = lyr.GetNextFeature()
        if feat is None:
            break
        # feat.DumpReadable()

        gdal_ds_name = feat.GetField(tileitem)
        if not os.path.isabs(gdal_ds_name):
            gdal_ds_name = os.path.join(os.path.dirname(ogr_ds_name),
                                        gdal_ds_name)
        gdal_ds = gdal.Open(gdal_ds_name)
        if gdal_ds is None:
            raise Exception('cannot open %s' % gdal_ds_name)
        warped_vrt_ds = gdal.AutoCreateWarpedVRT(gdal_ds, None, dst_wkt)
        if warped_vrt_ds is None:
            raise Exception('cannot warp %s to %s' % (gdal_ds_name, dst_wkt))
        gt = warped_vrt_ds.GetGeoTransform()
        xres += gt[1]
        yres += gt[5]
        warped_vrt_ds = None

        counter = counter + 1

    if counter == 0:
        raise Exception('tileindex is empty')

    xres /= counter
    yres /= counter
    (xmin, xmax, ymin, ymax) = lyr.GetExtent()
    xsize = (int)((xmax - xmin) / xres + 0.5)
    ysize = (int)((ymax - ymin) / abs(yres) + 0.5)

    layername = lyr.GetName()

    if ogr_ds.GetDriver().GetName() != 'ESRI Shapefile':
        print("""LAYER
      NAME "%s_tileindex"
      TYPE POLYGON
      STATUS OFF
      CONNECTIONTYPE OGR
      CONNECTION "%s,%s"
      PROJECTION
        "+init=epsg:%s"
      END
    END""" % (layername, ogr_ds_name, lyr.GetName(), authority_code))
        print("")

        tileindex = "%s_tileindex" % layername
    else:
        tileindex = ogr_ds_name

    print("""LAYER
      NAME "%s"
      TYPE RASTER
      STATUS ON
      TILEINDEX "%s"
      TILEITEM "%s"
      TILESRS "%s"
      PROJECTION
        "+init=epsg:%s"
      END
      METADATA
       "wcs_label"       "%s"
       "wcs_rangeset_name"   "Range 1"  ### required to support DescribeCoverage request
       "wcs_rangeset_label"  "My Label" ### required to support DescribeCoverage request
       "wcs_extent"      "%f %f %f %f"
       "wcs_size"        "%d %d"
       "wcs_resolution"  "%f %f"
      END
    END""" %
          (layername, tileindex, tileitem, tilesrs, authority_code, layername,
           xmin, ymin, xmax, ymax, xsize, ysize, xres, abs(yres)))

    return 0
示例#14
0
文件: geo.py 项目: hexiang6666/pySW4
    def reproject(self,
                  epsg=None,
                  proj4=None,
                  match=None,
                  error_threshold=0.125,
                  target_filename=None):
        """
        Reproject the data from the current projection to the specified
        target projection `epsg` or `proj4` or to `match` an
        existing GeoTIFF file.

        .. warning:: **Watch Out!** This operation is performed in place
                     on the actual data. The raw data will no longer be
                     accessible afterwards. To keep the original data,
                     use the :meth:`~pySW4.utils.geo.GeoTIFF.copy`
                     method to create a copy of the current object.

        Parameters
        ----------
        epsg : int
            The target projection EPSG code. See the
            `Geodetic Parameter Dataset Registry
            <http://www.epsg-registry.org/>`_ for more information.

        proj4 : str
            The target Proj4 string. If the EPSG code is unknown or a
            custom projection is required, a Proj4 string can be passed.
            See the `Proj4 <https://trac.osgeo.org/proj/wiki/GenParms>`_
            documentation for a list of general Proj4 parameters.

        match : str or :class:`~pySW4.utils.geo.GeoTIFF` instance
            Path (relative or absolute) to an existing GeoTIFF file or
            :class:`~pySW4.utils.geo.GeoTIFF` instance (already in
            memory) to match size and projection of. Current data is
            resampled to match the shape and number of pixels of the
            existing GeoTIFF file or object.
            It is assumed that both GeoTIFF objects cover the same
            extent.

        error_threshold : float
            Error threshold for transformation approximation in pixel
            units. (default is 0.125 for compatibility with  gdalwarp)

        target_filename : str
            If a target filename is given then the reprojected data is
            saved as target_filename and read into memory replacing
            the current data. This is faster than reprojecting and then
            saving. Otherwise the
            :meth:`~pySW4.utils.geo.GeoTIFF.write_GeoTIFF` method can be
            used to save the data at a later point if further
            manipulations are needed.

        Notes
        -----
        Examples of some EPSG codes and their equivalent Proj4 strings
        are::

            4326   -> '+proj=longlat +datum=WGS84 +no_defs'

            32636  -> '+proj=utm +zone=36 +datum=WGS84 +units=m +no_defs'

            102009 -> '+proj=lcc +lat_1=20 +lat_2=60 +lat_0=40
                       +lon_0=-96 +x_0=0 +y_0=0 +datum=NAD83 +units=m
                       +no_defs'

        and so on ... See the `Geodetic Parameter Dataset Registry
        <http://www.epsg-registry.org/>`_ for more information.
        """
        if epsg and proj4 and match:
            msg = 'Only `epsg`, `proj4`, or `match` should be specified.'
            raise ValueError(msg)
        elif not epsg and not proj4 and not match:
            msg = '`epsg`, `proj4`, or `match` MUST be specified.'
            raise ValueError(msg)

        if not target_filename:
            target_filename = 'dst_temp.tif'

        dstSRS = osr.SpatialReference()

        if epsg or proj4:
            try:
                dstSRS.ImportFromEPSG(epsg)
            except TypeError:
                dstSRS.ImportFromProj4(proj4)

            temp_ds = gdal.AutoCreateWarpedVRT(self._src_ds, None,
                                               dstSRS.ExportToWkt(),
                                               gdal.GRA_NearestNeighbour,
                                               error_threshold)
            dst_ds = gdal.GetDriverByName('GTiff').CreateCopy(
                target_filename, temp_ds)

        # isinstance(match, GeoTIFF)
        elif match:
            self.write_GeoTIFF('src_temp.tif')
            src_ds = gdal.Open('src_temp.tif')
            src_proj = src_ds.GetProjection()
            src_geotrans = src_ds.GetGeoTransform()

            if type(match) is str:
                match = read_GeoTIFF(match, 1)

            gdal_dtype = gdal_array.NumericTypeCodeToGDALTypeCode(self.dtype)
            dstSRS.ImportFromProj4(match.proj4)
            dst_ds = gdal.GetDriverByName('GTiff').Create(
                target_filename, match.nx, match.ny, 1, gdal_dtype)
            dst_ds.SetGeoTransform(match.geotransform)
            dst_ds.SetProjection(dstSRS.ExportToWkt())

            gdal.ReprojectImage(src_ds, dst_ds, src_proj, dstSRS.ExportToWkt(),
                                gdal.GRA_NearestNeighbour, error_threshold)
            os.remove('src_temp.tif')

        dst_ds = None
        self._read(target_filename, 1)
        try:
            os.remove('dst_temp.tif')
        except OSError:
            pass
示例#15
0
    def open_input(self):
        gdal.AllRegister()

        # Initialize necessary GDAL drivers
        self.out_drv = gdal.GetDriverByName(self.tiledriver)
        self.mem_drv = gdal.GetDriverByName('MEM')

        if not self.out_drv:
            raise Exception(
                "The '%s' driver was not found, is it available in this GDAL build?",
                self.tiledriver)
        if not self.mem_drv:
            raise Exception(
                "The 'MEM' driver was not found, is it available in this GDAL build?"
            )

        # Open the input file
        self.in_ds = gdal.Open(self.input, gdal.GA_ReadOnly)

        # Get base image data & info
        self.width = self.in_ds.RasterXSize
        self.height = self.in_ds.RasterYSize
        self.bandnum = self.in_ds.RasterCount

        # Spatial Reference System of tiles
        out_srs = osr.SpatialReference()
        out_srs.ImportFromEPSG(3857)

        # Spatial Reference System of input
        self.wkt = self.in_ds.GetProjection()
        srs_in = osr.SpatialReference()
        srs_in.ImportFromWkt(self.wkt)

        # WGS84 Reference System
        srs4326 = osr.SpatialReference()
        srs4326.ImportFromEPSG(4326)

        # Are the reference systems the same? Reproject if necessary.
        self.out_ds = None
        if (srs_in.ExportToProj4() != out_srs.ExportToProj4()):

            # Generation of VRT dataset in tile projection, default 'nearest neighbour' warping
            self.out_ds = gdal.AutoCreateWarpedVRT(self.in_ds, self.wkt,
                                                   out_srs.ExportToWkt())

        if not self.out_ds:
            self.out_ds = self.in_ds

        # Get alpha band (either directly or from NODATA value)
        self.alphaband = self.in_ds.GetRasterBand(1).GetMaskBand()

        # Get reference systems transformer
        self.ctutmto84 = osr.CoordinateTransformation(srs_in, srs4326)
        self.ct84toutm = osr.CoordinateTransformation(srs4326, srs_in)
        self.ctmerto84 = osr.CoordinateTransformation(out_srs, srs4326)
        self.ct84tomer = osr.CoordinateTransformation(srs4326, out_srs)

        # Get GeoTransform
        self.transform = self.out_ds.GetGeoTransform()

        # Get input bounds in WGS84 Coordinate System
        lu = self.MERtoWGS84(self.transform[0], self.transform[3])
        rl = self.MERtoWGS84(
            self.transform[0] + self.transform[1] * self.out_ds.RasterXSize,
            self.transform[3] + self.transform[5] * self.out_ds.RasterYSize)
        self.omaxx = rl[0]
        self.ominx = lu[0]
        self.omaxy = lu[1]
        self.ominy = rl[1]

        # Generate table with min max tile coordinates for all zoomlevels
        self.tminmax = list(range(0, MAXZOOMLEVEL))
        for tz in range(0, MAXZOOMLEVEL):
            tminy, tminx = self.tools.BLHtoRowCol(tz, self.ominy, self.ominx)
            tmaxy, tmaxx = self.tools.BLHtoRowCol(tz, self.omaxy, self.omaxx)
            # crop tiles extending world limits (+-180,+-90)
            tminx, tminy = max(0, tminx), max(0, tminy)
            tmaxx, tmaxy = min(10 * 2**tz - 1,
                               tmaxx), min(5 * 2**tz - 1, tmaxy)
            self.tminmax[tz] = (tminx, tminy, tmaxx, tmaxy)
示例#16
0
文件: vrtwarp.py 项目: garnertb/gdal
def vrtwarp_4():

    src_ds = gdal.Open('../gcore/data/byte.tif')
    tmp_ds = gdal.GetDriverByName('GTiff').CreateCopy('tmp/vrtwarp_4.tif',
                                                      src_ds)
    cs_main = tmp_ds.GetRasterBand(1).Checksum()
    tmp_ds.BuildOverviews('NONE', overviewlist=[2, 4])
    tmp_ds.GetRasterBand(1).GetOverview(0).Fill(127)
    cs_ov0 = tmp_ds.GetRasterBand(1).GetOverview(0).Checksum()
    tmp_ds.GetRasterBand(1).GetOverview(1).Fill(255)
    cs_ov1 = tmp_ds.GetRasterBand(1).GetOverview(1).Checksum()

    vrtwarp_ds = gdal.AutoCreateWarpedVRT(tmp_ds)
    tmp_ds = None

    for i in range(3):
        if vrtwarp_ds.GetRasterBand(1).GetOverviewCount() != 2:
            gdaltest.post_reason('fail')
            return 'fail'
        if vrtwarp_ds.GetRasterBand(1).Checksum() != cs_main:
            print(i)
            gdaltest.post_reason('fail')
            return 'fail'
        if vrtwarp_ds.GetRasterBand(1).GetOverview(0).Checksum() != cs_ov0:
            gdaltest.post_reason('fail')
            return 'fail'
        if vrtwarp_ds.GetRasterBand(1).GetOverview(1).Checksum() != cs_ov1:
            gdaltest.post_reason('fail')
            return 'fail'
        if i == 0:
            vrtwarp_ds.SetDescription('tmp/vrtwarp_4.vrt')
            vrtwarp_ds = None
            vrtwarp_ds = gdal.Open('tmp/vrtwarp_4.vrt')
        elif i == 1:
            vrtwarp_ds = None
            tmp_ds = gdal.Open('tmp/vrtwarp_4.tif')
            vrtwarp_ds = gdal.AutoCreateWarpedVRT(tmp_ds)
            vrtwarp_ds.SetMetadataItem('SrcOvrLevel', 'AUTO')
            vrtwarp_ds.SetDescription('tmp/vrtwarp_4.vrt')
            tmp_ds = None

    # Add an explicit overview
    vrtwarp_ds.BuildOverviews('NEAR', overviewlist=[2, 4, 8])
    vrtwarp_ds = None

    ds = gdal.GetDriverByName('MEM').Create('', 3, 3, 1)
    ds.GetRasterBand(1).Fill(255)
    expected_cs_ov2 = ds.GetRasterBand(1).Checksum()
    ds = None

    vrtwarp_ds = gdal.Open('tmp/vrtwarp_4.vrt')
    if vrtwarp_ds.GetRasterBand(1).GetOverviewCount() != 3:
        gdaltest.post_reason('fail')
        return 'fail'
    if vrtwarp_ds.GetRasterBand(1).Checksum() != cs_main:
        gdaltest.post_reason('fail')
        return 'fail'
    if vrtwarp_ds.GetRasterBand(1).GetOverview(0).Checksum() != cs_ov0:
        gdaltest.post_reason('fail')
        return 'fail'
    if vrtwarp_ds.GetRasterBand(1).GetOverview(1).Checksum() != cs_ov1:
        gdaltest.post_reason('fail')
        return 'fail'
    if vrtwarp_ds.GetRasterBand(1).GetOverview(
            2).Checksum() != expected_cs_ov2:
        gdaltest.post_reason('fail')
        return 'fail'
    vrtwarp_ds = None

    gdal.Unlink('tmp/vrtwarp_4.vrt')
    gdal.Unlink('tmp/vrtwarp_4.tif')

    return 'success'
示例#17
0


##########################  10.6.3 Reprojecting images  ########################

# Reproject the nat_color.tif from UTM to unprojected lat/lon. First create
# the output SRS.
srs = osr.SpatialReference()
srs.SetWellKnownGeogCS('WGS84')

# Open the nat_color file.
os.chdir(os.path.join(data_dir, 'Landsat', 'Washington'))
old_ds = gdal.Open('nat_color.tif')

# Create a VRT in memory that does the reproject.
vrt_ds = gdal.AutoCreateWarpedVRT(old_ds, None, srs.ExportToWkt(),
    gdal.GRA_Bilinear)

# Copy the VRT to a GeoTIFF so we have a file on disk.
gdal.GetDriverByName('gtiff').CreateCopy('nat_color_wgs84.tif', vrt_ds)



###########################  10.7 Callback functions  ##########################

# Let's calculate statistics on the natural color Landsat image and show
# progress while it does it (this image probably already has stats, so this
# will go really fast). Watch your output window to see what happens.
os.chdir(os.path.join(data_dir, 'Landsat', 'Washington'))
ds = gdal.Open('nat_color.tif')
for i in range(ds.RasterCount):
    ds.GetRasterBand(i + 1).ComputeStatistics(False, gdal.TermProgress_nocb)
示例#18
0
xres = 0
yres = 0

while True:
    feat = lyr.GetNextFeature()
    if feat is None:
        break
    # feat.DumpReadable()

    gdal_ds_name = feat.GetField(tileitem)
    if not os.path.isabs(gdal_ds_name):
        gdal_ds_name = os.path.join(os.path.dirname(ogr_ds_name), gdal_ds_name)
    gdal_ds = gdal.Open(gdal_ds_name)
    if gdal_ds is None:
        raise Exception('cannot open %s' % gdal_ds_name)
    warped_vrt_ds = gdal.AutoCreateWarpedVRT(gdal_ds, None, dst_wkt)
    if warped_vrt_ds is None:
        raise Exception('cannot warp %s to %s' % (gdal_ds_name, dst_wkt))
    gt = warped_vrt_ds.GetGeoTransform()
    xres += gt[1]
    yres += gt[5]
    warped_vrt_ds = None

    counter = counter + 1

if counter == 0:
    raise Exception('tileindex is empty')

xres /= counter
yres /= counter
(xmin, xmax, ymin, ymax) = lyr.GetExtent()
示例#19
0
def reproject_raster(dataset,
                     epsg_from=None,
                     epsg_to=None,
                     fltr=gdal.GRA_NearestNeighbour):
    """reproject a gdal raster dataset
    :param dataset: a gdal dataset
    :param epsg_from: the input epsg; if None get from the sorce
    :param epsg_to: the output epsg; if None throw exception
    :param fltr: the filter to apply when reprojecting
        GRA_NearestNeighbour
        Nearest neighbour (select on one input pixel)
        GRA_Bilinear
        Bilinear (2x2 kernel)
        GRA_Cubic
        Cubic Convolution Approximation (4x4 kernel)
        GRA_CubicSpline
        Cubic B-Spline Approximation (4x4 kernel)
        GRA_Lanczos
        Lanczos windowed sinc interpolation (6x6 kernel)
        GRA_Average
        Average (computes the average of all non-NODATA contributing pixels)
        GRA_Mode
        Mode (selects the value which appears most often of all the sampled points)

    #############NearestNeighbour filter is good for categorical data###########

    :return: the reprojected dataset
    """

    try:

        if epsg_to is None:
            raise Exception(
                "select the destination projected spatial reference!!!")

        if epsg_from == epsg_to:
            print("the input and output projections are the same!")
            return dataset

        # Define input/output spatial references
        if epsg_from:
            source = osr.SpatialReference()
            source.ImportFromEPSG(epsg_from)
            inwkt = source.ExportToWkt()
        else:
            source = osr.SpatialReference()
            source.ImportFromWkt(dataset.GetProjection())
            source.MorphFromESRI()  #this is to avoid reprojection errors
            inwkt = source.ExportToWkt()

        destination = osr.SpatialReference()
        destination.ImportFromEPSG(epsg_to)
        outwkt = destination.ExportToWkt()

        vrt_ds = gdal.AutoCreateWarpedVRT(dataset, inwkt, outwkt, fltr)

        return vrt_ds

    except RuntimeError as err:
        raise err
    except Exception as e:
        raise e