Beispiel #1
0
def transformer_1():

    try:
        x = gdal.Transformer
        gdaltest.have_ng = 1
    except:
        gdaltest.have_ng = 0
        return 'skip'

    ds = gdal.Open('data/byte.tif')
    tr = gdal.Transformer( ds, None, [] )

    (success,pnt) = tr.TransformPoint( 0, 20, 10 )

    if not success \
       or abs(pnt[0]- 441920) > 0.00000001 \
       or abs(pnt[1]-3750720) > 0.00000001 \
       or pnt[2] != 0.0:
        print(success, pnt)
        gdaltest.post_reason( 'got wrong forward transform result.' )
        return 'fail'

    (success,pnt) = tr.TransformPoint( 1, pnt[0], pnt[1], pnt[2] )

    if not success \
       or abs(pnt[0]-20) > 0.00000001 \
       or abs(pnt[1]-10) > 0.00000001 \
       or pnt[2] != 0.0:
        print(success, pnt)
        gdaltest.post_reason( 'got wrong reverse transform result.' )
        return 'fail'

    return 'success' 
Beispiel #2
0
def transformer_2():

    if not gdaltest.have_ng:
        return 'skip'

    ds = gdal.Open('data/gcps.vrt')
    tr = gdal.Transformer( ds, None, [ 'METHOD=GCP_POLYNOMIAL' ] )

    (success,pnt) = tr.TransformPoint( 0, 20, 10 )

    if not success \
       or abs(pnt[0]-441920) > 0.001 \
       or abs(pnt[1]-3750720) > 0.001 \
       or pnt[2] != 0:
        print(success, pnt)
        gdaltest.post_reason( 'got wrong forward transform result.' )
        return 'fail'

    (success,pnt) = tr.TransformPoint( 1, pnt[0], pnt[1], pnt[2] )

    if not success \
       or abs(pnt[0]-20) > 0.001 \
       or abs(pnt[1]-10) > 0.001 \
       or pnt[2] != 0:
        print(success, pnt)
        gdaltest.post_reason( 'got wrong reverse transform result.' )
        return 'fail'

    return 'success' 
Beispiel #3
0
def transformer_4():

    if not gdaltest.have_ng:
        return 'skip'

    ds = gdal.Open('data/sstgeo.vrt')
    tr = gdal.Transformer( ds, None, [ 'METHOD=GEOLOC_ARRAY' ] )

    (success,pnt) = tr.TransformPoint( 0, 20, 10 )

    if not success \
       or abs(pnt[0]+81.961341857910156) > 0.000001 \
       or abs(pnt[1]-29.612689971923828) > 0.000001 \
       or pnt[2] != 0:
        print(success, pnt)
        gdaltest.post_reason( 'got wrong forward transform result.' )
        return 'fail'

    (success,pnt) = tr.TransformPoint( 1, pnt[0], pnt[1], pnt[2] )

    if not success \
       or abs(pnt[0]-19.554539744554866) > 0.001 \
       or abs(pnt[1]-9.1910760024906537) > 0.001 \
       or pnt[2] != 0:
        print(success, pnt)
        gdaltest.post_reason( 'got wrong reverse transform result.' )
        return 'fail'

    return 'success' 
def mosaic_geotiff(infiles, outfile):
    x_min, y_max, x_max, y_min = get_extent(infiles)

    file_first = infiles[0]
    gtf = get_gtf(file_first)
    project = get_project(file_first)

    gtf_new = get_new_gtf(gtf, y_max, y_min)
    row, col = get_row_col(gtf, x_min, y_max, x_max, y_min)

    driver = gdal.GetDriverByName('gtiff')
    dataset_out = driver.Create(outfile, col, row)
    dataset_out.SetProjection(project)
    dataset_out.SetGeoTransform(gtf_new)

    band_out = dataset_out.GetRasterBand(1)

    for infile in infiles:
        dataset_in = gdal.Open(infile)
        trans = gdal.Transformer(dataset_in, dataset_out, [])
        success, xyz = trans.TransformPoint(False, 0, 0)
        print(success, xyz)
        x, y, z = map(int, xyz)
        data = dataset_in.GetRasterBand(1).ReadAsArray()
        print(data.shape)
        band_out.WriteArray(data, x, y)
Beispiel #5
0
def mosiac(path):
    print("Fetching all files from directory")
    file_path = str(path)
    os.chdir(file_path)
    file = glob.glob('*.tif')
    #print file
    min_x, max_y, max_x, min_y = get_extent(file[0])
    for fn in file[1:]:
        minx, maxy, maxx, miny = get_extent(fn)
        min_x = min(min_x, minx)
        max_y = max(max_y, maxy)
        max_x = max(max_x, maxx)
        min_y = min(min_y, miny)
    in_ds = gdal.Open(file[0])
    gt = list(in_ds.GetGeoTransform())
    rows = ceil((max_y - min_y) / -gt[5])
    col = ceil((max_x - min_x) / gt[1])
    folderLocation, folderName = creating_directory()
    print(
        "Please Provide Information Regarding New Dataset which will store all Final Information"
    )
    name = input("Enter Dataset Name")
    dstPath = os.path.join(folderLocation, "%s.tif" % name)
    fileformat = in_ds.GetDriver().ShortName
    driver = gdal.GetDriverByName(str(fileformat))
    dst_ds = driver.Create(dstPath, int(col), int(rows), in_ds.RasterCount,
                           GDT_Int16)
    dst_ds.SetProjection(in_ds.GetProjection())
    gt[0], gt[3] = min_x, max_y
    dst_ds.SetGeoTransform(gt)
    out_band = dst_ds.GetRasterBand(1)
    for fn in file:
        in_ds = gdal.Open(fn)
        trans = gdal.Transformer(in_ds, dst_ds, [])
        sucess, xyz = trans.TransformPoint(False, 0, 0)
        x, y, z = map(int, xyz)
        data = in_ds.GetRasterBand(1).ReadAsArray()
        out_band.WriteArray(data, x, y)
    dst_ds.FlushCache()
    for i in range(dst_ds.RasterCount):
        i = i + 1
        dst_ds.GetRasterBand(i).ComputeStatistics(False)
    dst_ds.BuildOverviews('average',
                          [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048])
    out_band.FlushCache()
    dst_ds = None
    dst_ds = None
    in_ds = None
    out_band = None
    return dstPath
def get_shape(dataset, npts=10):
    """
    """
    transformer = gdal.Transformer(dataset, None, ['MAX_GCP_ORDER=-1'])
    npix = dataset.RasterXSize
    nlin = dataset.RasterYSize
    pix = np.hstack(
        (np.round(np.linspace(0, npix, num=npts)), np.repeat(npix, npts),
         np.round(np.linspace(npix, 0, num=npts)), np.repeat(0, npts)))
    lin = np.hstack(
        (np.repeat(0, npts), np.round(np.linspace(0, nlin, num=npts)),
         np.repeat(nlin, npts), np.round(np.linspace(nlin, 0, num=npts))))
    pixlin = np.vstack((pix, lin)).transpose()
    lonlat = np.array(transformer.TransformPoints(0, pixlin)[0])
    return (lonlat[:, 0], lonlat[:, 1])
Beispiel #7
0
def transformer_6():

    if not gdaltest.have_ng:
        return 'skip'

    ds = gdal.Open('data/byte.tif')
    tr = gdal.Transformer( ds, None, [] )

    (pnt, success) = tr.TransformPoints( 0, [(20, 10)] )

    if success[0] == 0 \
       or abs(pnt[0][0]- 441920) > 0.00000001 \
       or abs(pnt[0][1]-3750720) > 0.00000001 \
       or pnt[0][2] != 0.0:
        print(success, pnt)
        gdaltest.post_reason( 'got wrong forward transform result.' )
        return 'fail'

    return 'success' 
def get_gdal_transformer(gcplon, gcplat, gcppixel, gcpline, xsize, ysize):
    """
    """
    gdal.SetCacheMax(2**30)
    gcps = []
    for i, j, k, l in zip(gcplon.flat, gcplat.flat, gcppixel.flat, gcpline.flat):
        gcps.append(gdal.GCP(float(i), float(j), 0., float(k), float(l)))
    srs = osr.SpatialReference()
    srs.SetWellKnownGeogCS('WGS84')
    proj = srs.ExportToWkt()
    drv = gdal.GetDriverByName('MEM')
    dset = drv.Create('tmp', int(xsize), int(ysize))
    #dset = drv.Create(id_generator(), int(xsize), int(ysize))
    dset.SetGCPs(gcps, proj)
    #options = ['']
    #options = ['MAX_GCP_ORDER=3']
    options = ['MAX_GCP_ORDER=-1']
    transformer = gdal.Transformer(dset, None, options)
    return transformer
Beispiel #9
0
def rmseGen(uuid):
    # get the current users job
    job = db.session.query(Jobs).filter(Jobs.uuid == uuid).first()
    if job:  # user has a job
        gcpjson = request.get_json()  # get gcps
        # update job in database with gcps
        res = db.session.query(Jobs).filter(Jobs.id == job.id).update(
            dict(gcps=gcpjson))
        # commit changes
        db.session.commit()
        if gcpjson is not None:  # request returned a gcp json
            if len(gcpjson.keys()) >= 3:
                gcpList = []
                for gcp in gcpjson:
                    # create GCP's and add to gcplist
                    gcpList.append(
                        gdal.GCP(gcpjson[gcp]['lat'], gcpjson[gcp]['lon'], 0,
                                 gcpjson[gcp]['col'], gcpjson[gcp]['row']))
                # open job dataset
                folder = os.path.join(app.config['PUBLIC_UPLOAD_FOLDER'],
                                      job.uuid)
                raw_file = os.path.join(folder, job.imagename)
                ds = gdal.Open(raw_file)
                # set path and file for translation
                translate_image = os.path.join(
                    app.config['PUBLIC_UPLOAD_FOLDER'], job.uuid,
                    job.uuid + "_trans.tif")
                if os.path.exists(translate_image):  # path exists
                    # remove file path to translation
                    os.remove(translate_image)
                # translate dataset given spatial reference and new GCP's
                dsx = gdal.Translate(translate_image, ds, GCPs=gcpList)
                rmsevals = []

                # declare spatial references for transformations
                InSR = osr.SpatialReference()
                InSR.ImportFromEPSG(4326)  # WGS84/Geographic
                OutSR = osr.SpatialReference()
                OutSR.ImportFromEPSG(26913)

                # reopen translated image
                translated_ds = gdal.Open(translate_image)
                tr = gdal.Transformer(translated_ds, None, [])
                GT = translated_ds.GetGeoTransform()
                wktPoints = "MULTIPOINT ("
                errorsum = 0
                errorcount = 0
                for gcp in gcpjson:
                    col = gcpjson[gcp]['col']
                    row = gcpjson[gcp]['row']
                    xp = GT[0] + col * GT[1] + row * GT[2]
                    yp = GT[3] + col * GT[4] + row * GT[5]
                    success, pnt = tr.TransformPoint(0, col, row)
                    # create point, for predicted point
                    predictedPoint = ogr.Geometry(ogr.wkbPoint)
                    predictedPoint.AddPoint(gcpjson[gcp]['lat'],
                                            gcpjson[gcp]['lon'])
                    predictedPoint.AssignSpatialReference(
                        InSR)  # assign srs epsg_4326
                    predictedPoint.TransformTo(
                        OutSR)  # transform to epsg_26913
                    # create point, for observed point
                    observedPoint = ogr.Geometry(ogr.wkbPoint)
                    observedPoint.AddPoint(pnt[0], pnt[1])
                    observedPoint.AssignSpatialReference(
                        InSR)  # assign srs epsg_4326
                    observedPoint.TransformTo(OutSR)  # transform to epsg_26913
                    x1 = predictedPoint.GetX()
                    y1 = predictedPoint.GetY()
                    x2 = observedPoint.GetX()
                    y2 = observedPoint.GetY()
                    a = x1 - x2
                    b = y1 - y2
                    c = math.sqrt(a * a + b * b)
                    errorsum = errorsum + c
                    errorcount = errorcount + 1
                    gcpobj = {
                        gcp: {
                            "predicted": {
                                "lat": predictedPoint.GetX(),
                                "lon": predictedPoint.GetY()
                            },
                            "observed": {
                                "lat": observedPoint.GetX(),
                                "lon": observedPoint.GetY()
                            }
                        }
                    }
                    wktPoints = wktPoints + "(" + str(
                        predictedPoint.GetX()) + " " + str(
                            predictedPoint.GetY()) + "),(" + str(
                                observedPoint.GetX()) + " " + str(
                                    observedPoint.GetY()) + "),"
                    rmsevals.append(gcpobj)

                errormean = errorsum / errorcount
                finalrmse = math.sqrt(errormean)

                returnjson = json.loads('{"status":"success"}')
                returnjson['id'] = job.id
                returnjson['rmsevals'] = rmsevals
                returnjson['rmse'] = finalrmse
            else:
                returnjson = json.loads('{"status":"success"}')
                returnjson['id'] = job.id
                returnjson['rmsevals'] = {}

            return returnjson
    maxX = max(maxX, maxx)
    minY = min(minY, miny)
print( maxX - minX, maxY - minY)

# 获取输出图像的行列数
in_ds = gdal.Open(in_files[0])
gt = in_ds.GetGeoTransform()
cols = int(maxX - minX) / abs(gt[5])
rows = int(maxY - minY) / gt[1]
print(abs(gt[5]), gt[1])
print(cols, rows)

# 创建输出图像
driver = gdal.GetDriverByName('gtiff')
out_ds = driver.Create('mosaic.tif', int(cols), int(rows))
out_ds.SetProjection(in_ds.GetProjection())
out_band = out_ds.GetRasterBand(1)

gt = list(in_ds.GetGeoTransform())
gt[0], gt[3] = minX, maxY
out_ds.SetGeoTransform(gt)

for fn in in_files:
    in_ds = gdal.Open(fn)
    trans = gdal.Transformer(in_ds, out_ds, [])
    success, xyz = trans.TransformPoint(False, 0, 0)
    x, y, z = map(int, xyz)
    data = in_ds.GetRasterBand(1).ReadAsArray()
    out_band.WriteArray(data, x, y)

del in_ds, out_band, out_ds
def write_netcdf(ncfile,
                 metadata,
                 geolocation,
                 band,
                 model,
                 ngcps=None,
                 dgcps=None):
    """
    """
    nband = len(band)
    nlin, npix = band[0]['array'].shape

    # GCPs
    if ngcps is None and dgcps is None:
        raise Exception('Need number of GCPs or pixel distance between GCPs.')
    elif ngcps is None:
        ngcps = (np.ceil(nlin / float(dgcps[0])).astype('int') + 1,
                 np.ceil(npix / float(dgcps[1])).astype('int') + 1)
    elif dgcps is None:
        dgcps = (np.ceil(nlin / (ngcps[0] - 1.)).astype('int'),
                 np.ceil(npix / (ngcps[1] - 1.)).astype('int'))
    gcplin = np.concatenate((np.arange(ngcps[0] - 1) * dgcps[0], [nlin]))
    gcppix = np.concatenate((np.arange(ngcps[1] - 1) * dgcps[1], [npix]))
    if 'geotransform' in geolocation.keys():
        x0, dxx, dxy, y0, dyx, dyy = geolocation['geotransform']
        gcpy = y0 + dyx * gcppix[np.newaxis, :] + dyy * gcplin[:, np.newaxis]
        gcpx = x0 + dxx * gcppix[np.newaxis, :] + dxy * gcplin[:, np.newaxis]
        srs = osr.SpatialReference()
        srs.ImportFromWkt(geolocation['projection'])
        srs4326 = osr.SpatialReference()
        srs4326.ImportFromEPSG(4326)
        if srs.IsSame(srs4326) == 1:
            gcplat = gcpy
            gcplon = gcpx
        else:
            proj = pyproj.Proj(srs.ExportToProj4())
            gcplon, gcplat = proj(gcpx, gcpy, inverse=True)
    elif 'gcps' in geolocation.keys():
        drv = gdal.GetDriverByName('MEM')
        dset = drv.Create('tmp', npix, nlin)
        dset.SetGCPs(geolocation['gcps'], geolocation['projection'])
        options = ['MAX_GCP_ORDER=-1']
        transformer = gdal.Transformer(dset, None, options)
        _gcplin = np.tile(gcplin[:, np.newaxis], (1, ngcps[1]))
        _gcppix = np.tile(gcppix[np.newaxis, :], (ngcps[0], 1))
        inputs = np.vstack((_gcppix.flatten(), _gcplin.flatten())).transpose()
        outputs = np.array(transformer.TransformPoints(0, inputs)[0])[:, 0:2]
        gcplat = outputs[:, 1].reshape(ngcps)
        gcplon = outputs[:, 0].reshape(ngcps)
        dset = None

    # Time
    time = datetime.strptime(metadata['datetime'], TIMEFMT)
    time_range = []
    for dts in metadata['time_range']:
        if dts.endswith('ms'):
            timed = timedelta(milliseconds=int(dts[:-2]))
        elif dts.endswith('s'):
            timed = timedelta(seconds=int(dts[:-1]))
        elif dts.endswith('m'):
            timed = timedelta(minutes=int(dts[:-1]))
        elif dts.endswith('h'):
            timed = timedelta(hours=int(dts[:-1]))
        elif dts.endswith('d'):
            timed = timedelta(days=int(dts[:-1]))
        else:
            raise Exception()
        time_range.append(time + timed)

    # Model
    if model == 'grid_lonlat':
        dim1name = 'lat'
        dim2name = 'lon'
        lonlat1d = True
        unlimtime = True
    elif model == 'grid_proj':
        dim1name = 'y'
        dim2name = 'x'
        lonlat1d = False
        unlimtime = True
    elif model == 'swath':
        dim1name = 'row'
        dim2name = 'cell'
        lonlat1d = False
        unlimtime = False
    else:
        raise Exception('')
    dim1gcpname = '{}_gcp'.format(dim1name)
    dim2gcpname = '{}_gcp'.format(dim2name)

    # Write
    dset = Dataset(ncfile, mode='w', format='NETCDF4', clobber=True)
    ## Dimensions
    if unlimtime:
        _dimtime = dset.createDimension('time', None)
    else:
        _dimtime = dset.createDimension('time', 1)
    _dim1 = dset.createDimension(dim1name, nlin)
    _dim2 = dset.createDimension(dim2name, npix)
    _dim1gcp = dset.createDimension(dim1gcpname, ngcps[0])
    _dim2gcp = dset.createDimension(dim2gcpname, ngcps[1])
    ## Variables
    _time = dset.createVariable('time', 'f8', ('time', ))
    _time.long_name = 'time'
    _time.standard_name = 'time'
    _time.units = 'seconds since 1970-01-01T00:00:00.000000Z'
    _time.calendar = 'standard'
    _time[:] = (time - datetime(1970, 1, 1)).total_seconds()
    if lonlat1d:
        _latgcp = dset.createVariable('lat_gcp', 'f4', (dim1gcpname, ))
        _latgcp[:] = gcplat[:, 0].astype('float32')
    else:
        _latgcp = dset.createVariable('lat_gcp', 'f4',
                                      (dim1gcpname, dim2gcpname))
        _latgcp[:] = gcplat.astype('float32')
    _latgcp.long_name = 'ground control points latitude'
    _latgcp.standard_name = 'latitude'
    _latgcp.units = 'degrees_north'
    if lonlat1d:
        _longcp = dset.createVariable('lon_gcp', 'f4', (dim2gcpname, ))
        _longcp[:] = gcplon[0, :].astype('float32')
    else:
        _longcp = dset.createVariable('lon_gcp', 'f4',
                                      (dim1gcpname, dim2gcpname))
        _longcp[:] = gcplon.astype('float32')
    _longcp.long_name = 'ground control points longitude'
    _longcp.standard_name = 'longitude'
    _longcp.units = 'degrees_east'
    _indexdim1gcp = dset.createVariable('index_{}_gcp'.format(dim1name), 'i4',
                                        (dim1gcpname, ))
    _indexdim1gcp[:] = gcplin.astype('int32')
    _indexdim1gcp.long_name = 'index of ground control points in {} dimension'.format(
        dim1name)
    _indexdim1gcp.comment = 'index goes from 0 (start of first pixel) to dimension value '\
                            '(end of last pixel)'
    _indexdim2gcp = dset.createVariable('index_{}_gcp'.format(dim2name), 'i4',
                                        (dim2gcpname, ))
    _indexdim2gcp[:] = gcppix.astype('int32')
    _indexdim2gcp.long_name = 'index of ground control points in {} dimension'.format(
        dim2name)
    _indexdim2gcp.comment = 'index goes from 0 (start of first pixel) to dimension value '\
                            '(end of last pixel)'
    for ibnd in range(nband):
        if 'name' in band[ibnd]:
            varname = band[ibnd]['name']
        elif 'description' in band[ibnd]:
            varname = band[ibnd]['description'].replace(' ', '_')
        else:
            varname = 'value_{}'.format(ibnd)
        dtype = band[ibnd]['array'].dtype
        fill_value = None
        if 'nodatavalue' in band[ibnd]:
            fill_value = dtype.type(band[ibnd]['nodatavalue'])
        _value = dset.createVariable(varname,
                                     dtype, ('time', dim1name, dim2name),
                                     fill_value=fill_value)
        _value[:] = band[ibnd]['array'][np.newaxis, :, :]
        if 'long_name' in band[ibnd]:
            _value.long_name = band[ibnd]['long_name']
        if 'standard_name' in band[ibnd]:
            _value.standard_name = band[ibnd]['standard_name']
        if 'comment' in band[ibnd]:
            _value.comment = band[ibnd]['comment']
        # if 'description' in band[ibnd]:
        #     _value.long_name = band[ibnd]['description']
        if 'unittype' in band[ibnd]:
            _value.units = band[ibnd]['unittype']
        if 'offset' in band[ibnd]:
            _value.add_offset = np.float32(band[ibnd]['offset'])
        if 'scale' in band[ibnd]:
            _value.scale_factor = np.float32(band[ibnd]['scale'])
        if 'valid_range' in band[ibnd]:
            _value.valid_min = dtype.type(band[ibnd]['valid_range'][0])
            _value.valid_max = dtype.type(band[ibnd]['valid_range'][1])
        if 'parameter_range' in band[ibnd]:
            offset = 0.
            if 'offset' in band[ibnd]:
                offset = band[ibnd]['offset']
            scale = 1.
            if 'scale' in band[ibnd]:
                scale = band[ibnd]['scale']
            vran = [(p - offset) / scale
                    for p in band[ibnd]['parameter_range']]
            vran = np.sort(np.array(vran))
            if issubclass(dtype.type, np.integer):
                vran = np.round(vran).astype(dtype)
            else:
                vran = vran.astype(dtype)
            _value.valid_min = vran[0]
            _value.valid_max = vran[1]
    ## Global attributes
    dset.idf_granule_id = metadata['name']
    dset.time_coverage_start = time_range[0].strftime('%Y-%m-%dT%H:%M:%S.%fZ')
    dset.time_coverage_end = time_range[1].strftime('%Y-%m-%dT%H:%M:%S.%fZ')
    dset.idf_subsampling_factor = np.int32(0)
    if 'spatial_resolution' in metadata:
        dset.idf_spatial_resolution = np.float32(
            metadata['spatial_resolution'])
    else:
        raise Exception('IDF spatial resolution ?')
    dset.idf_spatial_resolution_units = 'm'
    dset.close()
Beispiel #12
0
def transformer_5():

    if not gdaltest.have_ng:
        return 'skip'

    ds = gdal.Open('data/rpc.vrt')
    tr = gdal.Transformer( ds, None, [ 'METHOD=RPC' ] )

    (success,pnt) = tr.TransformPoint( 0, 20, 10 )

    if not success \
       or abs(pnt[0]-125.64830100509131) > 0.000001 \
       or abs(pnt[1]-39.869433991997553) > 0.000001 \
       or pnt[2] != 0:
        print(success, pnt)
        gdaltest.post_reason( 'got wrong forward transform result.' )
        return 'fail'

    (success,pnt) = tr.TransformPoint( 1, pnt[0], pnt[1], pnt[2] )

    if not success \
       or abs(pnt[0]-20) > 0.001 \
       or abs(pnt[1]-10) > 0.001 \
       or pnt[2] != 0:
        print(success, pnt)
        gdaltest.post_reason( 'got wrong reverse transform result.' )
        return 'fail'

    # Try with a different height.
    
    (success,pnt) = tr.TransformPoint( 0, 20, 10, 30 )

    if not success \
       or abs(pnt[0]-125.64828521533849) > 0.000001 \
       or abs(pnt[1]-39.869345204440144) > 0.000001 \
       or pnt[2] != 30:
        print(success, pnt)
        gdaltest.post_reason( 'got wrong forward transform result.(2)' )
        return 'fail'

    (success,pnt) = tr.TransformPoint( 1, pnt[0], pnt[1], pnt[2] )

    if not success \
       or abs(pnt[0]-20) > 0.001 \
       or abs(pnt[1]-10) > 0.001 \
       or pnt[2] != 30:
        print(success, pnt)
        gdaltest.post_reason( 'got wrong reverse transform result.(2)' )
        return 'fail'

    # Test RPC_HEIGHT option
    tr = gdal.Transformer( ds, None, [ 'METHOD=RPC', 'RPC_HEIGHT=30' ] )

    (success,pnt) = tr.TransformPoint( 0, 20, 10 )

    if not success \
       or abs(pnt[0]-125.64828521533849) > 0.000001 \
       or abs(pnt[1]-39.869345204440144) > 0.000001 :
        print(success, pnt)
        gdaltest.post_reason( 'got wrong forward transform result.(3)' )
        return 'fail'

    (success,pnt) = tr.TransformPoint( 1, pnt[0], pnt[1], pnt[2] )

    if not success \
       or abs(pnt[0]-20) > 0.001 \
       or abs(pnt[1]-10) > 0.001 :
        print(success, pnt)
        gdaltest.post_reason( 'got wrong reverse transform result.(3)' )
        return 'fail'

    # Test RPC_DEM and RPC_HEIGHT_SCALE options

    # (long,lat)=(125.64828521533849 39.869345204440144) -> (Easting,Northing)=(213324.662167036 4418634.47813677) in EPSG:32652
    ds_dem = gdal.GetDriverByName('GTiff').Create('/vsimem/dem.tif', 100, 100, 1)
    sr = osr.SpatialReference()
    sr.ImportFromEPSG(32652)
    ds_dem.SetProjection(sr.ExportToWkt())
    ds_dem.SetGeoTransform([213300,1,0,4418700,0,-1])
    ds_dem.GetRasterBand(1).Fill(15)
    ds_dem = None

    tr = gdal.Transformer( ds, None, [ 'METHOD=RPC', 'RPC_HEIGHT_SCALE=2', 'RPC_DEM=/vsimem/dem.tif' ] )

    (success,pnt) = tr.TransformPoint( 0, 20, 10, 0 )

    if not success \
       or abs(pnt[0]-125.64828521533849) > 0.000001 \
       or abs(pnt[1]-39.869345204440144) > 0.000001 :
        print(success, pnt)
        gdaltest.post_reason( 'got wrong forward transform result.(4)' )
        return 'fail'

    (success,pnt) = tr.TransformPoint( 1, pnt[0], pnt[1], pnt[2] )

    if not success \
       or abs(pnt[0]-20) > 0.001 \
       or abs(pnt[1]-10) > 0.001 :
        print(success, pnt)
        gdaltest.post_reason( 'got wrong reverse transform result.(4)' )
        return 'fail'

    tr = None
    gdal.Unlink('/vsimem/dem.tif')

    return 'success'