示例#1
0
def zonalStatistics_rasterZones(rasterzones, rasterpath, indentifier="fid"):
    print("loading zones")
    zones = raster.getRasterBandAsArray(rasterzones, 1)
    print("loading values")
    rasterds = raster.openGDALRaster(rasterpath)
    rastervals = rasterds.GetRasterBand(1).ReadAsArray()
    nodata = rasterds.GetRasterBand(1).GetNoDataValue()
    print("finding unique values, no data", nodata)
    uvals = np.unique(zones)
    zstats = []
    iter = 0
    print("starting loop", len(uvals))
    for uval in uvals:
        vals = rastervals[np.where(zones == uval)]
        vals = vals[vals != nodata]
        if vals.size > 0:
            zstats.append(
                setFeatureStats(uval,
                                max=float(vals.max()),
                                min=float(vals.min()),
                                mean=float(vals.max()),
                                sd=float(vals.std()),
                                median=float(np.median(vals)),
                                majority=float(
                                    stats.mode(vals, axis=None)[0][0]),
                                count=vals.size,
                                idname=indentifier))
        else:
            # print "no values for zone", uval, iter
            zstats.append(setFeatureStats(uval, idname=indentifier))
        iter += 1
        if (iter % 100 == 0):
            print("iter", iter, "of", len(uvals))
    return zstats
示例#2
0
def rasterValueAtPoints(pointshapefile,
                        rasterpath,
                        fieldname,
                        datatype=ogr.OFTReal,
                        idxfield=None):
    """
    Get the value of a raster at point locations.

    Args:
        pointshapefile: Path to point shapefile.
        rasterpath: Path to raster dataset.
        fieldname: Name of field to create and write raster values.
        datatype: OGR datatype of created field (default: ogr.OFTReal)
        idxfield: Shapefile field containing band number to use on multipband rasters (default: None, get value from band 1)

    Returns:

    """
    ras = raster.openGDALRaster(rasterpath)
    geot = ras.GetGeoTransform()
    shp = vector.openOGRDataSource(pointshapefile, 1)
    lyr = shp.GetLayer()
    # if lyr.GetGeomType() is not ogr.wkbPoint:
    #     print "incorrect geometry type, should be points", lyr.GetGeomType()
    #     return None
    vector.createFields(lyr, [fieldname], datatype)
    feat = lyr.GetNextFeature()
    while feat:
        nband = 1
        if idxfield is not None:
            nband = feat.GetField(idxfield)
        geom = feat.GetGeometryRef()
        row, col = raster.getCellAddressOfPoint(geom.GetX(), geom.GetY(), geot)
        if nband <= 0 or nband > ras.RasterCount:
            value = -9999.0
        else:
            value = struct.unpack(
                'f' * 1,
                ras.GetRasterBand(int(nband)).ReadRaster(
                    xoff=col,
                    yoff=row,
                    xsize=1,
                    ysize=1,
                    buf_xsize=1,
                    buf_ysize=1,
                    buf_type=gdal.GDT_Float32))[0]
        feat.SetField(fieldname, value)
        lyr.SetFeature(feat)
        feat = lyr.GetNextFeature()
    lyr = None
    shp.Destroy()
示例#3
0
def zonalStatisticsDelta_methodtest(vectorpath,
                                    rasterpath,
                                    deltapath,
                                    idfield="fid",
                                    deltamax=None,
                                    deltamin=None,
                                    minvalue=0.0):
    """
    Zonal statistics using a second raster layer to exclude values from statistic calculations. Currently,
    This is implemented as follows. For each zone represented in vectorpath, the median of deltapath is identified.
    Cells from deltapath where the absolute value of ((median - deltapath)/median)*100 is greater than delta value are
    excluded from statistical calculations.

    Args:
        vectorpath: Vector zones
        rasterpath: Raster to calculate statistics from
        deltapath: Raster to exclude cells for statistic calculation
        deltavalue: Threshold for exclusion from statistic calculations
        deltatype: Type of theshold to use. Currently, only percent is available.

    Returns:

    """
    np.set_printoptions(suppress=True)
    rasterds = raster.openGDALRaster(rasterpath)
    deltads = raster.openGDALRaster(deltapath)
    vectords = vector.openOGRDataSource(vectorpath)
    lyr = vectords.GetLayer()
    geot = rasterds.GetGeoTransform()
    nodata = rasterds.GetRasterBand(1).GetNoDataValue()
    zstats = []
    outofbounds = []
    feat = lyr.GetNextFeature()
    iter = 0
    while feat:
        if idfield is "fid" or idfield is "FID":
            id = feat.GetFID()
        else:
            id = feat.GetField(idfield)
        tmpds = vector.createOGRDataSource('temp', 'Memory')
        tmplyr = tmpds.CreateLayer('polygons', None, ogr.wkbPolygon)
        tmplyr.CreateFeature(feat.Clone())
        offsets = bboxToOffsets(feat.GetGeometryRef().GetEnvelope(), geot)
        for i in range(0, len(offsets)):
            if offsets[i] < 0:
                offsets[i] = 0
        if not any(x < 0 for x in offsets):
            array = rasterds.GetRasterBand(1).ReadAsArray(
                offsets[2], offsets[0], (offsets[3] - offsets[2]),
                (offsets[1] - offsets[0]))
            deltaarray = deltads.GetRasterBand(1).ReadAsArray(
                offsets[2], offsets[0], (offsets[3] - offsets[2]),
                (offsets[1] - offsets[0]))
            newgeot = raster.getOffsetGeot(offsets[0], offsets[2], geot)
            tmpras = raster.createGDALRaster('',
                                             offsets[1] - offsets[0],
                                             offsets[3] - offsets[2],
                                             datatype=gdal.GDT_Byte,
                                             drivername='MEM',
                                             geot=newgeot)
            if tmpras is not None and array is not None:
                gdal.RasterizeLayer(tmpras, [1], tmplyr, burn_values=[1])
                tmparray = tmpras.ReadAsArray()
                if array.size == np.logical_or(array == nodata,
                                               np.logical_not(tmparray)).size:
                    testmaskarray = np.ma.MaskedArray(
                        array,
                        mask=np.logical_or(array == nodata,
                                           np.logical_not(tmparray)))
                    testmean = np.ma.mean(testmaskarray)

                    if testmean != nodata and deltaarray is not None:
                        deltamaskarray = np.ma.MaskedArray(
                            deltaarray,
                            mask=np.logical_or(array == nodata,
                                               np.logical_not(tmparray)))
                        median = np.ma.median(deltamaskarray)

                        ########################################
                        #Difference calculation here
                        ########################################
                        diff = ((deltamaskarray - median) /
                                (deltamaskarray + median))
                        maskarray = np.ma.MaskedArray(
                            array,
                            mask=np.logical_or(
                                np.ma.getmask(deltamaskarray),
                                np.logical_or(
                                    np.logical_or(diff > deltamax,
                                                  diff < deltamin),
                                    deltaarray < minvalue)))
                        #print feat.GetFID(), maskarray.count(), maskarray.min(), maskarray.mean(), maskarray.max()

                        zstats.append(
                            setFeatureStats(id,
                                            min=float(maskarray.min()),
                                            mean=float(maskarray.mean()),
                                            max=float(maskarray.max()),
                                            sum=float(maskarray.sum()),
                                            sd=float(maskarray.std()),
                                            median=float(
                                                np.ma.median(maskarray)),
                                            majority=float(
                                                stats.mode(maskarray,
                                                           axis=None)[0][0]),
                                            deltamed=float(
                                                (median * 30 * 30) / 1000000),
                                            count=maskarray.count(),
                                            idname=idfield))
                        # if id==22877591:
                        #     print "subtract"
                        #     print deltamaskarray-median
                        #     print "add"
                        #     print deltamaskarray + median
                        #     print "buffer"
                        #     print tmparray
                        #     print "fac"
                        #     print deltaarray
                        #     print "diff"
                        #     print diff
                        #     print "values", deltamin, deltamax
                        #     #print np.where((deltaarray > minvalue) & (tmparray == 1) & (diff > deltamin), deltaarray, 0)
                        #     print np.where((deltaarray > minvalue) & (diff < deltamax) & (diff > deltamin), deltaarray, 0)
                        #     print np.where((deltaarray > minvalue) & (diff < deltamax) & (diff > deltamin), diff, 0)
                        #     print id, "count", maskarray.count(), offsets
                    else:
                        #print "mean = nodata", nodata, testmaskarray
                        zstats.append(setFeatureStats(id, idname=idfield))
                else:
                    #print "array sizes not equal"
                    zstats.append(setFeatureStats(id, idname=idfield))
            else:
                #print "NoneType arrays"
                zstats.append(setFeatureStats(id, idname=idfield))

        else:
            print("out of bounds", feat.GetFID())
            zstats.append(setFeatureStats(id))
            outofbounds.append(feat.GetFID())
        tmpras = None
        tmpds = None
        iter += 1
        if (iter % 10000 == 0):
            print("iter", iter, "of", lyr.GetFeatureCount())
        feat = lyr.GetNextFeature()
    return zstats
示例#4
0
def zonalStatistics(vectorpath,
                    rasterpath,
                    idxfield="fid",
                    snodata=-9999.0,
                    names=[
                        'min', 'mean', 'median', 'max', 'sd', 'sum', 'count',
                        'majority', 'fid', 'deltamed'
                    ]):
    names[8] = idxfield
    rasterds = raster.openGDALRaster(rasterpath)
    vectords = vector.openOGRDataSource(vectorpath)
    lyr = vectords.GetLayer()
    geot = rasterds.GetGeoTransform()
    nodata = rasterds.GetRasterBand(1).GetNoDataValue()
    zstats = []
    feat = lyr.GetNextFeature()
    iter = 0
    while feat:
        if feat.GetGeometryRef() is not None:
            tmpds = vector.createOGRDataSource('temp', 'Memory')
            tmplyr = tmpds.CreateLayer('polygons', None, ogr.wkbPolygon)
            tmplyr.CreateFeature(feat.Clone())
            offsets = bboxToOffsets(feat.GetGeometryRef().GetEnvelope(), geot)
            newgeot = raster.getOffsetGeot(offsets[0], offsets[2], geot)
            tmpras = raster.createGDALRaster('',
                                             offsets[1] - offsets[0],
                                             offsets[3] - offsets[2],
                                             datatype=gdal.GDT_Byte,
                                             drivername='MEM',
                                             geot=newgeot)
            gdal.RasterizeLayer(tmpras, [1], tmplyr, burn_values=[1])
            tmparray = tmpras.ReadAsArray()
            array = rasterds.GetRasterBand(1).ReadAsArray(
                offsets[2], offsets[0], (offsets[3] - offsets[2]),
                (offsets[1] - offsets[0]))
            if idxfield == "FID" or idxfield == "fid":
                id = feat.GetFID()
            else:
                id = feat.GetField(idxfield)

            if array is not None and np.logical_or(
                    array == nodata, np.logical_not(tmparray)) is not None:
                maskarray = np.ma.MaskedArray(array,
                                              mask=np.logical_or(
                                                  array == nodata,
                                                  np.logical_not(tmparray)))

                zstats.append(
                    setFeatureStats(id,
                                    min=float(maskarray.min()),
                                    mean=float(maskarray.mean()),
                                    max=float(maskarray.max()),
                                    sum=float(maskarray.sum()),
                                    sd=float(maskarray.std()),
                                    median=float(np.ma.median(maskarray)),
                                    majority=float(
                                        stats.mode(maskarray,
                                                   axis=None)[0][0]),
                                    count=maskarray.count(),
                                    names=names))
                # print zstats
            else:
                zstats.append(
                    setFeatureStats(id,
                                    min=snodata,
                                    mean=snodata,
                                    max=snodata,
                                    sum=snodata,
                                    sd=snodata,
                                    median=snodata,
                                    majority=snodata,
                                    count=snodata,
                                    names=names))
        tmpras = None
        tmpds = None
        iter += 1
        if (iter % 100000 == 0):
            print("iter", iter, "of", lyr.GetFeatureCount())
        feat = lyr.GetNextFeature()
    return zstats
示例#5
0
def rasterZonesFromVector_delta(vectorpath,
                                rasterpath,
                                outputpath,
                                deltavalue=10000.0,
                                deltatype='percent',
                                minvalue=0.0,
                                outdiff=None):
    print(deltavalue, minvalue)
    np.set_printoptions(suppress=True)
    rasterds = raster.openGDALRaster(rasterpath)
    vectords = vector.openOGRDataSource(vectorpath)
    print("data opened")
    lyr = vectords.GetLayer()
    geot = rasterds.GetGeoTransform()
    nodata = rasterds.GetRasterBand(1).GetNoDataValue()
    outds = raster.createGDALRaster(outputpath,
                                    rasterds.RasterYSize,
                                    rasterds.RasterXSize,
                                    geot=geot,
                                    datatype=gdal.GDT_Int32)
    if outdiff is not None:
        diffds = raster.createGDALRaster(outdiff,
                                         rasterds.RasterYSize,
                                         rasterds.RasterXSize,
                                         geot=geot,
                                         datatype=gdal.GDT_Float32)
        diffds.GetRasterBand(1).SetNoDataValue(-9999.0)
        diffds.SetProjection(rasterds.GetProjection())
    print("datacreated")
    #outds.GetRasterBand(1).Fill(-1)
    print("filled")
    outds.GetRasterBand(1).SetNoDataValue(-1)
    outds.SetProjection(rasterds.GetProjection())
    outofbounds = []
    feat = lyr.GetNextFeature()
    iter = 0
    print("starting loop")
    while feat:
        id = feat.GetFID()
        tmpds = vector.createOGRDataSource('temp', 'Memory')
        tmplyr = tmpds.CreateLayer('polygons', None, ogr.wkbPolygon)
        tmplyr.CreateFeature(feat.Clone())
        offsets = bboxToOffsets(feat.GetGeometryRef().GetEnvelope(), geot)
        for i in range(0, len(offsets)):
            if offsets[i] < 0:
                offsets[i] = 0
        if not any(x < 0 for x in offsets):
            array = rasterds.GetRasterBand(1).ReadAsArray(
                offsets[2], offsets[0], (offsets[3] - offsets[2]),
                (offsets[1] - offsets[0]))
            outarray = outds.GetRasterBand(1).ReadAsArray(
                offsets[2], offsets[0], (offsets[3] - offsets[2]),
                (offsets[1] - offsets[0]))
            newgeot = raster.getOffsetGeot(offsets[0], offsets[2], geot)
            tmpras = raster.createGDALRaster('',
                                             offsets[1] - offsets[0],
                                             offsets[3] - offsets[2],
                                             datatype=gdal.GDT_Byte,
                                             drivername='MEM',
                                             geot=newgeot)
            gdal.RasterizeLayer(tmpras, [1], tmplyr, burn_values=[1])
            tmparray = tmpras.ReadAsArray()
            featarray = np.ma.MaskedArray(array,
                                          mask=np.logical_or(
                                              array < minvalue,
                                              np.logical_not(tmparray)))
            featmean = np.ma.mean(featarray)
            #print id

            if featmean != nodata:
                median = np.ma.median(featarray)
                #diff = (abs(featarray - median) / median) * 100.0
                diff = np.divide((featarray - median), array)
                print("diff", np.min(diff))
                # diff = (abs(featarray - featmean) / featmean) * 100.0

                maskarray = np.ma.MaskedArray(array,
                                              mask=np.logical_or(
                                                  np.ma.getmask(featarray),
                                                  np.logical_or(
                                                      diff > deltavalue,
                                                      array < minvalue)))
                print("mask", np.min(featarray), np.min(array[array >= 125]))
                maskarray.set_fill_value(-1)
                maskarray = maskarray.filled()
                maskarray = np.where(
                    maskarray >= 0, id,
                    np.where(outarray >= 0, outarray, maskarray))
                # if id == 1954:
                #     print "median", median, "mean", featmean
                #     print "feat array"
                #     print featarray
                #     print "tmp array"
                #     print tmparray
                #     print "array"
                #     print np.around(array)
                #     print "diff"
                #     print np.around(diff)
                #     print "result"
                #     print maskarray
                outds.GetRasterBand(1).WriteArray(maskarray, offsets[2],
                                                  offsets[0])
                if outdiff is not None:
                    diff.set_fill_value(-9999.0)
                    diff = diff.filled()
                    diff = np.where(diff >= -9998.9, diff, -9999.0)
                    diffds.GetRasterBand(1).WriteArray(diff, offsets[2],
                                                       offsets[0])

        else:
            print("out of bounds", feat.GetFID())
            outofbounds.append(feat.GetFID())
        tmpras = None
        tmpds = None
        iter += 1
        if (iter % 10000 == 0):
            print("iter", iter, "of", lyr.GetFeatureCount())
        feat = lyr.GetNextFeature()
    #outds = None
    print("done")
    return None