Пример #1
0
def perform_sanity_checks():
    logging.info("Performing sanity checks on output PRODUCTs")
    tif_list = glob.glob("PRODUCT/*.tif")
    for myfile in tif_list:
        if "VV" in myfile or "HH" in myfile or "VH" in myfile or "HV" in myfile:
            # Check that the main polarization file is on a 30 meter posting
            x, y, trans, proj = saa.read_gdal_file_geo(saa.open_gdal_file(myfile))
            logging.debug("    trans[1] = {}; trans[5] = {}".format(trans[1], trans[5]))
            if abs(trans[5]) > 10 and abs(trans[1]) > 10:
                logging.debug("Checking corner coordinates...")
                ul1 = trans[3]
                lr1 = trans[3] + y * trans[5]
                ul2 = trans[0]
                lr2 = trans[0] + x * trans[1]
                if ul1 % 30 != 0:
                    logging.error("ERROR: Corner coordinates are amiss")
                    logging.error("ERROR: ul1 coordinate not on a 30 meter posting")
                    logging.error("ERROR: ul1 = {}".format(ul1))
                elif lr1 % 30 != 0:
                    logging.error("ERROR: Corner coordinates are amiss")
                    logging.error("ERROR: lr1 coordinate not on a 30 meter posting")
                    logging.error("ERROR: lr1 = {}".format(lr1))
                elif ul2 % 30 != 0:
                    logging.error("ERROR: Corner coordinates are amiss")
                    logging.error("ERROR: ul2 coordinate not on a 30 meter posting")
                    logging.error("ERROR: ul2 = {}".format(ul2))
                elif lr2 % 30 != 0:
                    logging.error("ERROR: Corner coordinates are amiss")
                    logging.error("ERROR: lr2 coordinate not on a 30 meter posting")
                    logging.error("ERROR: lr2 = {}".format(lr2))
                else:
                    logging.debug("...ok")
Пример #2
0
def fix_geotiff_locations(dir="PRODUCT"):
    back = os.getcwd()
    os.chdir(dir)
    for myfile in glob.glob("*.tif"):
        x1, y1, t1, p1, data = saa.read_gdal_file(saa.open_gdal_file(myfile))
        easting = t1[0]
        resx = t1[1]
        rotx = t1[2]
        northing = t1[3]
        roty = t1[4]
        resy = t1[5]
        easting = easting + resx / 2.0
        northing = northing + resy / 2.0
        t1 = [easting, resx, rotx, northing, roty, resy]
        tmpfile = "tmp_tiff_{}.tif".format(os.getpid())
        if "dem" in myfile or "DEM" in myfile:
            saa.write_gdal_file(tmpfile, t1, p1, data)
        elif "ls_map" in myfile or "LS" in myfile:
            saa.write_gdal_file_byte(tmpfile, t1, p1, data)
        else:
            saa.write_gdal_file_float(tmpfile, t1, p1, data, nodata=0)
        gdal.Translate(myfile,
                       tmpfile,
                       metadataOptions=['AREA_OR_POINT=Point'],
                       noData="0")
        os.remove(tmpfile)
    os.chdir(back)
Пример #3
0
def createAmp(fi):
    (x, y, trans, proj, data) = saa.read_gdal_file(saa.open_gdal_file(fi))
    ampdata = np.sqrt(data)
    outfile = fi.replace('.tif', '-amp.tif')
    print(outfile)
    saa.write_gdal_file_float(outfile, trans, proj, ampdata)
    return outfile
Пример #4
0
def getCorners(fi):
    (x1, y1, t1, p1) = saa.read_gdal_file_geo(saa.open_gdal_file(fi))
    ullon1 = t1[0]
    ullat1 = t1[3]
    lrlon1 = t1[0] + x1 * t1[1]
    lrlat1 = t1[3] + y1 * t1[5]
    return (ullon1, ullat1, lrlon1, lrlat1)
Пример #5
0
def get2sigmacutoffs(fi):
    (x, y, trans, proj, data) = saa.read_gdal_file(saa.open_gdal_file(fi))
    top = np.percentile(data, 98)
    data[data > top] = top
    stddev = np.std(data)
    mean = np.mean(data)
    lo = mean - 2 * stddev
    hi = mean + 2 * stddev
    return lo, hi
Пример #6
0
def byteSigmaScale(infile, outfile):
    lo, hi = get2sigmacutoffs(infile)
    print("2-sigma cutoffs are {} {}".format(lo, hi))
    gdal.Translate(outfile,
                   infile,
                   outputType=gdal.GDT_Byte,
                   scaleParams=[[lo, hi, 1, 255]],
                   resampleAlg="average",
                   noData="0")

    # For some reason, I'm still getting zeros in my byte images eventhough I'm using 1,255 scaling!
    # The following in an attempt to fix that!
    (x, y, trans, proj, data) = saa.read_gdal_file(saa.open_gdal_file(infile))
    mask = (data > 0).astype(bool)
    (x, y, trans, proj, data) = saa.read_gdal_file(saa.open_gdal_file(outfile))
    mask2 = (data > 0).astype(bool)
    mask3 = mask ^ mask2
    data[mask3 == True] = 1
    saa.write_gdal_file_byte(outfile, trans, proj, data, nodata=0)
Пример #7
0
def copy_metadata(infile, outfile):
    ds = saa.open_gdal_file(infile)
    md = ds.GetMetadata()
    print(md)

    # ds = saa.open_gdal_file(outfile)
    # ds.SetMetadata(md)

    # outfile2 = "tmp_outfile.tif"
    # gdal.Translate(outfile2,outfile, metadataOptions = md)
    # shutil.move(outfile2,outfile)

    ds = saa.open_gdal_file(outfile)
    for item in md:
        ds1 = gdal.Translate('',
                             ds,
                             format='MEM',
                             metadataOptions=['{}={}'.format(item, md[item])])
        ds = ds1
    gdal.Translate(outfile, ds1)
Пример #8
0
def get2sigmacutoffs(fi):
    (x, y, trans, proj, data) = saa.read_gdal_file(saa.open_gdal_file(fi))
    data = data.astype(float)
    data[data == 0] = np.nan
    top = np.nanpercentile(data, 99)
    data[data > top] = top
    stddev = np.nanstd(data)
    mean = np.nanmean(data)
    lo = mean - 2 * stddev
    hi = mean + 2 * stddev
    return lo, hi
Пример #9
0
def clean_dem(in_dem, out_dem):
    (x, y, trans, proj, data) = saa.read_gdal_file(saa.open_gdal_file(in_dem))
    logging.info("Replacing values less than -1000 with zero")
    data[data <= -1000] = -32767
    logging.info(f"DEM Maximum value: {np.max(data)}")
    logging.info(f"DEM minimum value: {np.min(data)}")

    if data.dtype == np.float32:
        saa.write_gdal_file_float(out_dem, trans, proj, data.astype(np.float32))
    elif data.dtype == np.uint16:
        saa.write_gdal_file(out_dem, trans, proj, data)
    else:
        logging.error(f"ERROR: Unknown DEM data type {data.dtype}")
        sys.exit(1)
Пример #10
0
def getOrigins(files):

    ul = np.zeros((2, len(files)))
    lr = np.zeros((2, len(files)))

    for i in range(len(files)):
        x, y, trans, proj = saa.read_gdal_file_geo(saa.open_gdal_file(
            files[i]))
        ul[0, i] = trans[0]
        lr[0, i] = trans[0] + x * trans[1]
        ul[1, i] = trans[3]
        lr[1, i] = trans[3] + y * trans[5]

    return ul, lr, trans[1], trans[5]
Пример #11
0
def getOverlap(coords, fi):
    (x1, y1, t1, p1) = saa.read_gdal_file_geo(saa.open_gdal_file(fi))

    ullon1 = t1[0]
    ullat1 = t1[3]
    lrlon1 = t1[0] + x1 * t1[1]
    lrlat1 = t1[3] + y1 * t1[5]

    ullon2 = coords[0]
    ullat2 = coords[1]
    lrlon2 = coords[2]
    lrlat2 = coords[3]

    ullat = min(ullat1, ullat2)
    ullon = max(ullon1, ullon2)
    lrlat = max(lrlat1, lrlat2)
    lrlon = min(lrlon1, lrlon2)

    return (ullon, ullat, lrlon, lrlat)
Пример #12
0
def makeChangeBrowse(geotiff, type="MSCD"):

    # read in the data
    x, y, trans, proj, data = saa.read_gdal_file(saa.open_gdal_file(geotiff))

    red = np.zeros(data.shape, dtype=np.uint8)
    blue = np.zeros(data.shape, dtype=np.uint8)
    green = np.zeros(data.shape, dtype=np.uint8)
    newData = np.zeros(data.shape, dtype=np.uint8)

    if type == "SACD":

        #
        # Make the greyscale image
        #
        lut = [0, 64, 0, 192]

        #
        # Make the color images
        #
        red_lut = [0, 255, 0, 1]
        green_lut = [0, 1, 0, 1]
        blue_lut = [0, 1, 0, 255]

        for i in range(y):
            for j in range(x):
                newData[i, j] = lut[data[i, j]]
                red[i, j] = red_lut[data[i, j]]
                green[i, j] = green_lut[data[i, j]]
                blue[i, j] = blue_lut[data[i, j]]

    else:

        #
        # get data median and histogram
        #
        median = np.median(data)
        bins = np.zeros(MAX_CLASSES, dtype=np.int8)
        for i in range(MAX_CLASSES):
            bins[i] = i
        hist = np.histogram(data, bins=bins)

        #
        # count the number of classes present in histogram and set class number,
        # making the median class 0, keeping all zeors as class 0, and all others
        # with histogram values to a linear sequence 1, 2, 3, ...
        #
        class_cnt = 0
        next_class = 1
        classifications = np.zeros(MAX_CLASSES, dtype=np.int8)
        classifications[:] = -1
        classifications[0] = 0
        for i in range(0, len(hist[0])):
            if hist[0][i] != 0:
                class_cnt = class_cnt + 1
                if hist[1][i] == 0:
                    # we have zeros in the image - need to be handled as background
                    classifications[i] = 0
                elif i == median:
                    classifications[i] = 0
                else:
                    classifications[i] = next_class
                    next_class = next_class + 1

        #
        # Make LUT to map classifications to greyscale values
        # Start at 64, increment by 192/(#classes-2) to get
        # sequences like {64,255}, {64,160,255}, {64,128,192,256}, etc,
        # always leaving the median class and zero pixels as zero valued
        #
        lut = np.zeros(class_cnt, dtype=np.uint8)
        if class_cnt == 1:
            print("ERROR: Only found one class")
            exit(1)
        if (class_cnt == 2):
            lut[0] = 0
            lut[1] = 255
        else:
            val = 64
            inc = 192 / (class_cnt - 2)
            for i in range(class_cnt):
                if i != median and hist[1][i] != 0:
                    lut[classifications[i]] = int(val)
                    val = val + inc
                    if val > 255:
                        val = int(255)

        #
        # Use the look up table to set the values in newData array
        #
        newData = lut[classifications[data]]

        #
        # Create the color version of the data
        # Here, we use the same classifications as
        # an index into a color look up table.
        #
        red_lut = [1, 255, 1, 1, 255, 255, 1, 128, 128, 1]
        green_lut = [1, 1, 1, 255, 128, 1, 255, 255, 1, 128]
        blue_lut = [1, 1, 255, 1, 1, 128, 128, 1, 255, 255]

        for i in range(y):
            for j in range(x):
                k = classifications[data[i, j]]
                red[i, j] = red_lut[k]
                blue[i, j] = blue_lut[k]
                green[i, j] = green_lut[k]

    #
    # Write out the greyscale png files
    #
    outName = geotiff.replace(".tif", "_byte.tif")
    pngName = geotiff.replace(".tif", "_byte_full.png")
    saa.write_gdal_file_byte(outName, trans, proj, newData.astype(np.byte))
    gdal.Translate(pngName,
                   outName,
                   format="PNG",
                   outputType=gdal.GDT_Byte,
                   scaleParams=[[0, 255]],
                   noData="0 0 0")
    os.remove(outName)

    #
    # Write out the RGB tif
    #
    outName = geotiff.replace(".tif", "_rgb.tif")
    pngName = geotiff.replace(".tif", "_rgb_full.png")
    saa.write_gdal_file_rgb(outName, trans, proj, red, green, blue)
    gdal.Translate(pngName,
                   outName,
                   format="PNG",
                   outputType=gdal.GDT_Byte,
                   scaleParams=[[0, 255]],
                   noData="0 0 0")

    #
    # Make the ASF standard browse and kmz images
    #
    tmpName = geotiff.replace(".tif", "_rgb")
    makeAsfBrowse(outName, tmpName, use_nn=True)
    os.remove(outName)
Пример #13
0
def getPixSize(fi):
    (x1, y1, t1, p1) = saa.read_gdal_file_geo(saa.open_gdal_file(fi))
    return (t1[1])
Пример #14
0
def makeColorPhase(inFile,
                   rateReduction=1,
                   shift=0,
                   ampFile=None,
                   scale=0,
                   table='CMY'):

    samples = 1024

    pinf = float('+inf')
    ninf = float('-inf')
    # fnan = float('nan')

    mod2pi = False
    if table == 'CMY':
        mod2pi = True
        R, G, B = makeCycleColor(samples)
    elif table == 'RYB':
        R, G, B = makeContinuousColor(samples)
    elif table == 'RWB':
        R, G, B = makeRWBColor(samples)
    else:
        print("ERROR: Unknown color table: {}".format(table))
        exit(1)

    #
    # Read in the phase data
    #
    x, y, trans, proj = saa.read_gdal_file_geo(saa.open_gdal_file(inFile))

    # If data if too big, resize it
    if x > 4096 or y > 4096:
        phaseTmp = "{}_small.tif".format(
            os.path.basename(inFile.replace(".tif", "")))
        gdal.Translate(phaseTmp, inFile, height=4096)
        x, y, trans, proj, data = saa.read_gdal_file(
            saa.open_gdal_file(phaseTmp))
        print("Created small tif of size {} x {}".format(x, y))
    else:
        x, y, trans, proj, data = saa.read_gdal_file(
            saa.open_gdal_file(inFile))
        print("Using full size tif of size {} x {}".format(x, y))
        phaseTmp = inFile

    # Make a black mask for use after colorization
    mask = np.ones(data.shape, dtype=np.uint8)
    mask[data[:] == 0] = 0

    # Scale to 0 .. samples-1
    data[:] = data[:] + shift
    if mod2pi == True:
        data[:] = data[:] % (2 * rateReduction * np.pi)
        const = samples / (2 * rateReduction * np.pi)
        data[:] = data[:] * const
    else:

        mask = np.ones(data.shape, dtype=np.uint8)
        mask[data == pinf] = 0
        mask[data == ninf] = 0
        mask[np.isnan(data)] = 0
        data[mask == 0] = 0

        #        mini = np.min(data)
        #        maxi = np.max(data)

        mini = np.percentile(data, 2)
        maxi = np.percentile(data, 98)
        data[data < mini] = mini
        data[data > maxi] = maxi

        data[:] = (data[:] - mini) / (maxi - mini)
        data[:] = data * float(samples)

        print(np.max(data))
        print(np.min(data))

        hist = np.histogram(data)
        print(hist[1])
        print(hist[0])

    data[data == samples] = samples - 1

    # Convert to integer for indexing
    idata = np.zeros(data.shape, dtype=np.uint16)
    idata[:] = data[:]

    # Make the red, green, and blue versions
    red = np.zeros(data.shape, dtype=np.uint8)
    green = np.zeros(data.shape, dtype=np.uint8)
    blue = np.zeros(data.shape, dtype=np.uint8)

    red = R[idata[:]]
    green = G[idata[:]]
    blue = B[idata[:]]

    # Apply the black mask
    red[mask == 0] = 0
    green[mask == 0] = 0
    blue[mask == 0] = 0

    if ampFile is None:
        # Write out the RGB phase image
        fileName = inFile.replace(".tif", "_rgb.tif")
        saa.write_gdal_file_rgb(fileName, trans, proj, red, green, blue)

    # If we have amplitude, use that
    else:
        # Make the red, green, and blue floating point versions
        redf = np.zeros(data.shape)
        greenf = np.zeros(data.shape)
        bluef = np.zeros(data.shape)

        # Scale from 0 .. 1
        redf[::] = red[::] / 255.0
        greenf[::] = green[::] / 255.0
        bluef[::] = blue[::] / 255.0

        # Read in the amplitude data
        x1, y1, trans1, proj1 = saa.read_gdal_file_geo(
            saa.open_gdal_file(ampFile))

        # If too large, resize the data
        if x1 > 4096 or y1 > 4096:
            ampTmp = "{}_small.tif".format(
                os.path.basename(ampFile.replace(".tif", "")))
            gdal.Translate(ampTmp, ampFile, height=y, width=x)
            x1, y1, trans1, proj1, amp = saa.read_gdal_file(
                saa.open_gdal_file(ampTmp))
        else:
            x1, y1, trans1, proj1, amp = saa.read_gdal_file(
                saa.open_gdal_file(ampFile))
            ampTmp = ampFile

        if (x != x1) or (y != y1):
            cutFiles([phaseTmp, ampTmp])
            #            if phaseTmp != inFile:
            #                os.remove(phaseTmp)
            phaseTmp = phaseTmp.replace(".tif", "_clip.tif")
            x, y, trans, proj, data = saa.read_gdal_file(
                saa.open_gdal_file(phaseTmp))

            #            if ampTmp != ampFile:
            #                os.remove(ampTmp)
            ampTmp = ampTmp.replace(".tif", "_clip.tif")
            x1, y1, trans1, proj1, amp = saa.read_gdal_file(
                saa.open_gdal_file(ampTmp))

        print("Data shape is {}".format(data.shape))
        print("Amp shape is {}".format(amp.shape))

        # Make a black mask for use after colorization
        mask = np.ones(amp.shape, dtype=np.uint8)
        mask[amp == pinf] = 0
        mask[amp == ninf] = 0
        mask[np.isnan(amp)] = 0
        amp[mask == 0] = 0

        ave = np.mean(amp)
        print("Mean of amp data is {}".format(ave))
        amp[mask == 0] = ave

        print("AMP HISTOGRAM:")
        hist = np.histogram(amp)
        print(hist[1])
        print(hist[0])

        ave = np.mean(amp)
        print("Amp average is {}".format(ave))
        print("Amp median is {}".format(np.median(amp)))
        print("Amp stddev is {}".format(np.std(amp)))

        # Rescale amplitude to 2-sigma byte range, otherwise may be all dark
        amp2File = createAmp(ampTmp)
        myrange = get2sigmacutoffs(amp2File)
        newFile = "tmp.tif"
        gdal.Translate(newFile,
                       amp2File,
                       outputType=gdal.GDT_Byte,
                       scaleParams=[myrange],
                       resampleAlg="average")
        x, y, trans, proj, amp = saa.read_gdal_file(
            saa.open_gdal_file(newFile))
        #        if ampTmp != ampFile:
        #            os.remove(ampTmp)
        #        os.remove(amp2File)
        #        os.remove(newFile)

        print("2-sigma AMP HISTOGRAM:")
        hist = np.histogram(amp)
        print(hist[1])
        print(hist[0])

        # Scale amplitude from 0.0 to 1.0
        ampf = np.zeros(data.shape)
        ampf = amp / 255.0
        ampf = ampf + float(scale)
        ampf[ampf > 1.0] = 1.0

        print("SCALED AMP HISTOGRAM:")
        hist = np.histogram(ampf)
        print(hist[1])
        print(hist[0])

        # Perform color transformation
        h = np.zeros(data.shape)
        l = np.zeros(data.shape)
        s = np.zeros(data.shape)

        for j in range(x):
            for i in range(y):
                h[i,
                  j], l[i,
                        j], s[i,
                              j] = colorsys.rgb_to_hls(redf[i, j],
                                                       greenf[i, j], bluef[i,
                                                                           j])

        print("LIGHTNESS HISTOGRAM:")
        hist = np.histogram(l)
        print(hist[1])
        print(hist[0])

        l = l * ampf

        print("NEW LIGHTNESS HISTOGRAM:")
        hist = np.histogram(l)
        print(hist[1])
        print(hist[0])

        for j in range(x):
            for i in range(y):
                redf[i, j], greenf[i, j], bluef[i, j] = colorsys.hls_to_rgb(
                    h[i, j], l[i, j], s[i, j])

        red = redf * 255
        green = greenf * 255
        blue = bluef * 255

        print("TRANFORMED RED HISTOGRAM:")
        hist = np.histogram(red)
        print(hist[1])
        print(hist[0])

        # Apply mask
        red[mask == 0] = 0
        green[mask == 0] = 0
        blue[mask == 0] = 0

        # Write out the RGB phase image
        fileName = inFile.replace(".tif", "_amp_rgb.tif")
        saa.write_gdal_file_rgb(fileName, trans, proj, red, green, blue)


#
# This code makes an image to show off the color table
#
#    rainbow_red = np.zeros((1024,1024),np.uint8)
#    rainbow_green = np.zeros((1024,1024),np.uint8)
#    rainbow_blue = np.zeros((1024,1024),np.uint8)
#    for i in range(1024):
#        for j in range(1024):
#            idx = int((float(i)/1024.0)*samples)
#            rainbow_red[i,j] = R[idx]
#            rainbow_green[i,j] = G[idx]
#            rainbow_blue[i,j] = B[idx]
#    saa.write_gdal_file_rgb("rainbow.tif",trans,proj,rainbow_red,rainbow_green,rainbow_blue)

    return (fileName)
Пример #15
0
def utm2dem(inDem, outDem, demPar, dataType="float"):
    demParIn = "dem_par.in"
    dataType = dataType.lower()
    basename = os.path.basename(inDem)
    logname = basename + "_utm_dem.log"
    log = open(logname, "w")

    print("UTM DEM in GEOTIFF format: {}".format(inDem))
    print("output DEM: {}".format(outDem))
    print("output DEM parameter file: {}".format(demPar))
    print("log file: {}".format(logname))

    (x, y, trans, proj, data) = saa.read_gdal_file(saa.open_gdal_file(inDem))

    xsize = x
    ysize = y
    east = trans[0]
    north = trans[3]
    pix_east = trans[1]
    pix_north = trans[5]

    ds = gdal.Open(inDem)
    prj = ds.GetProjection()
    s = prj.split("[")
    for t in s:
        if "false_northing" in t:
            u = t.split('"')
            v = u[2].split(",")
            w = v[1].split("]")
            false_north = w[0]
    print("found false_north {}".format(false_north))

    srs = osr.SpatialReference(wkt=prj)
    string = srs.GetAttrValue('projcs')
    t = string.split(" ")
    zone = t[5]
    print("Found zone string {} of length {}".format(zone, len(zone)))

    if len(zone) == 3:
        zone = zone[0:2]
    else:
        zone = zone[0]
    print("found zone {}".format(zone))

    src = gdal.Open(inDem, gdalconst.GA_ReadOnly)
    string = src.GetMetadata()
    pixasarea = string["AREA_OR_POINT"]
    if "AREA" in pixasarea:
        print("Pixel as Area! Updating corner coordinates to pixel as point")
        print("pixel upper northing (m): {}    easting (m): {}".format(
            north, east))
        east = east + pix_east / 2.0
        north = north + pix_north / 2.0
        print("Update pixel upper northing (m): {}    easting (m): {}".format(
            north, east))

    pix_size = pix_east
    print("approximate DEM latitude pixel spacing (m): {}".format(pix_size))

    # Create the input file for create_dem_par
    f = open(demParIn, "w")
    f.write("UTM\n")
    f.write("WGS84\n")
    f.write("1\n")
    f.write("{}\n".format(zone))
    f.write("{}\n".format(false_north))
    f.write("{}\n".format(basename))
    if "float" in dataType:
        f.write("REAL*4\n")
    elif "int16" in dataType:
        f.write("INTEGER*2\n")
    f.write("0.0\n")
    f.write("1.0\n")
    f.write("{}\n".format(xsize))
    f.write("{}\n".format(ysize))
    f.write("{} {}\n".format(pix_north, pix_east))
    f.write("{} {}\n".format(north, east))
    f.close()

    # Create a new dem par file
    if os.path.isfile(demPar):
        os.remove(demPar)
    execute("create_dem_par {} < {}".format(demPar, demParIn), logfile=log)

    # Replace 0 with 1; Replace anything <= -32767 with 0; byteswap
    data[data == 0] = 1
    data[data <= -32767] = 0
    data = data.byteswap()

    # Convert to ENVI (binary) format
    tmptif = "temporary_dem_file.tif"
    if "float" in dataType:
        saa.write_gdal_file_float(tmptif, trans, proj, data.astype(np.float32))
    elif "int16" in dataType:
        saa.write_gdal_file(tmptif, trans, proj, data)
    gdal.Translate(outDem, tmptif, format="ENVI")
    os.remove(tmptif)
    os.remove(outDem + ".aux.xml")
    filename, file_extension = os.path.splitext(outDem)
    os.remove(outDem.replace(file_extension, ".hdr"))
Пример #16
0
def get_dem(x_min, y_min, x_max, y_max, outfile, post=None, processes=1, dem_name=None, leave=False, dem_type='utm'):
    if post is not None:
        logging.info(f"Snapping to grid at posting of {post} meters")

    if y_min < -90 or y_max > 90:
        raise ValueError(f"Please use latitude in range (-90, 90) ({y_min}, {y_max})")

    if x_min > x_max:
        logging.warning("WARNING: minimum easting > maximum easting - swapping")
        (x_min, x_max) = (x_max, x_min)

    if y_min > y_max:
        logging.warning("WARNING: minimum northing > maximum northing - swapping")
        (y_min, y_max) = (y_max, y_min)

    # Figure out which DEM and get the tile list
    (demname, demproj, tile_list, poly_list) = get_best_dem(y_min, y_max, x_min, x_max, dem_name=dem_name)
    demproj = int(demproj)
    logging.info(f"demproj is {demproj}")

    # Add buffer for REMA
    if 'REMA' in demname or 'GIMP' in demname:
        x_min -= 4
        x_max += 4
    if 'EU_DEM' in demname:
        y_min -= 2
        y_max += 2

    # Copy the files into a dem directory
    if not os.path.isdir("DEM"):
        os.mkdir("DEM")

    # Download tiles in parallel
    logging.info("Fetching DEM tiles to local storage")
    p = mp.Pool(processes=processes)
    p.map(
        get_tile_for,
        [(demname, fi) for fi in tile_list]
    )
    p.close()
    p.join()

    # os.system("gdalbuildvrt temp.vrt DEM/*.tif")
    if "SRTMGL" in demname:
        nodata = -32768
    elif "GIMP" in demname:
        nodata = None
    elif "REMA" in demname:
        nodata = 0
    elif "NED" in demname or "EU_DEM_V11" in demname:
        nodata = -3.4028234663852886e+38
    else:
        raise DemError(f'Unable to determine NoData value for DEM {demname}')

    write_vrt(demproj, nodata, tile_list, poly_list, 'temp.vrt')

    #
    # Set the output projection to either NPS, SPS, or UTM
    #
    if demproj == 3413:  # North Polar Stereo
        outproj = 'EPSG:3413'
        outproj_num = 3413
    elif demproj == 3031:  # South Polar Stereo
        outproj = 'EPSG:3031'
        outproj_num = 3031
    else:
        lon = (x_max + x_min) / 2
        zone = math.floor((lon + 180) / 6 + 1)
        if zone > 60:
            zone -= 60
        if (y_min + y_max) / 2 > 0:
            outproj = ('EPSG:326%02d' % int(zone))
            outproj_num = int("326%02d" % int(zone))
        else:
            outproj = ('EPSG:327%02d' % int(zone))
            outproj_num = int("327%02d" % int(zone))

    tmpdem = "xxyyzz_img.tif"
    tmpdem2 = "aabbcc_img.tif"
    tmpproj = "lmnopqr_img.tif"
    if os.path.isfile(tmpdem):
        logging.info(f"Removing old file {tmpdem}")
        os.remove(tmpdem)
    if os.path.isfile(tmpproj):
        logging.info("Removing old file projected dem file")
        os.remove(tmpproj)

    pixsize = 30.0
    gcssize = 0.00027777777778

    if demname == "SRTMGL3":
        pixsize = 90.
        gcssize *= 3
    if demname == "NED2":
        pixsize = 60.
        gcssize *= 2

    logging.info("Creating initial raster file")
    logging.info(f"    tmpdem {tmpdem}")
    logging.info(f"    pixsize {pixsize}")
    logging.info(f"    bounds: x_min {x_min}; y_min {y_min}; x_max {x_max}; y_max {y_max}")

    # xform bounds to projection of the DEM
    if demproj != 4326:
        transformer = Transformer.from_crs('epsg:4326', f'epsg:{demproj}')
        t_x, t_y = transformer.transform([x_min, x_max], [y_min, y_max])
        x_min, x_max = sorted(t_x)
        y_min, y_max = sorted(t_y)
        logging.info(f"    transformed bounds: x_min {x_min}; y_min {y_min}; x_max {x_max}; y_max {y_max}")

    if demproj == 4269 or demproj == 4326:
        res = gcssize
    else:
        res = pixsize
    gdal.Warp(tmpdem, "temp.vrt", xRes=res, yRes=res, outputBounds=[x_min, y_min, x_max, y_max],
              resampleAlg="cubic", dstNodata=-32767)

    # If DEM is from NED collection, then it will have a NAD83 ellipse -
    # need to convert to WGS84
    # Also, need to convert from pixel as area to pixel as point
    if "NED" in demname:
        logging.info("Converting to WGS84")
        gdal.Warp("temp_dem_wgs84.tif", tmpdem, dstSRS="EPSG:4326")
        logging.info("Converting to pixel as point")
        x1, y1, t1, p1, data = \
            saa.read_gdal_file(saa.open_gdal_file("temp_dem_wgs84.tif"))
        lon = t1[0]
        resx = t1[1]
        rotx = t1[2]
        lat = t1[3]
        roty = t1[4]
        resy = t1[5]
        lon = lon + resx / 2.0
        lat = lat + resy / 2.0
        t1 = [lon, resx, rotx, lat, roty, resy]
        saa.write_gdal_file_float(tmpdem, t1, p1, data)
        if not leave:
            os.remove("temp_dem_wgs84.tif")

    clean_dem(tmpdem, tmpdem2)
    shutil.move(tmpdem2, tmpdem)
    gdal.Translate(tmpdem2, tmpdem, metadataOptions=['AREA_OR_POINT=Point'])
    shutil.move(tmpdem2, tmpdem)

    # Reproject the DEM file into UTM space
    if demproj != outproj_num:
        logging.info(f"Translating raster file to projected coordinates ({outproj})")
        gdal.Warp(tmpproj, tmpdem, dstSRS=outproj, xRes=pixsize, yRes=pixsize, resampleAlg="cubic",
                  srcNodata=-32767, dstNodata=-32767)
        infile = tmpproj
    else:
        infile = tmpdem

    report_min(infile)

    # Snap to posting grid
    if post:
        snap_to_grid(post, pixsize, infile, outfile)
    else:
        shutil.copy(infile, outfile)

    report_min(outfile)

    # Clean up intermediate files
    if not leave:
        if os.path.isfile(tmpdem):
            logging.info(f"Removing temp file {tmpdem}")
            os.remove(tmpdem)
        if os.path.isfile(tmpproj):
            logging.info(f"Removing temp file {tmpproj}")
            os.remove(tmpproj)

    logging.info("Successful Completion!")
    if dem_type.lower() == 'utm':
        return demname

    elif dem_type.lower() == 'latlon':
        pixsize = 0.000277777777778
        gdal.Warp(
            "temp_dem.tif", outfile, dstSRS="EPSG:4326", xRes=pixsize, yRes=pixsize, resampleAlg="cubic",
            dstNodata=-32767
        )
        shutil.move("temp_dem.tif", outfile)

    elif dem_type.lower() == 'isce':
        pixsize = 0.000277777777778
        gdal.Warp("temp_dem.tif", outfile, format="ENVI", dstSRS="EPSG:4326", xRes=pixsize, yRes=pixsize,
                  resampleAlg="cubic", dstNodata=-32767)
        shutil.move("temp_dem.tif", outfile)
        hdr_name = os.path.splitext(outfile)[0] + ".hdr"
        dem2isce.dem2isce(outfile, hdr_name, f'{outfile}.xml')

    else:
        raise NotImplementedError(f'Cannot get DEM for unkown type {dem_type}')

    return demname
Пример #17
0
def report_min(in_dem):
    (x, y, trans, proj, data) = saa.read_gdal_file(saa.open_gdal_file(in_dem))
    logging.debug(f"DEM file {in_dem} minimum is {np.min(data)}")