Esempio n. 1
0
def processShapes(x):
    # Reaging Geometry
    shape = shapes[x]
    p = shape.points
    p = np.array(p)
    lon_g = p[:, 0]
    lat_g = p[:, 1]
    # Reading the Record
    records = sf.record(x)
    rec1 = records[-1]
    #   # Calculating the angle
    #   seg = length.dist(p)
    #   ang = angle.alpha(seg)
    #   rec2 = round(ang,1)
    # Caluculating the vertical surface area
    perim = perimeter.per(p)
    area = perim * rec1
    # Tranforming the coordinates
    [lon_r, lat_r] = geo2rot.g2r(lon_g, lat_g)
    # Calculating the Area
    rec3 = 0.5 * np.abs(
        np.dot(lon_r, np.roll(lat_r, 1)) - np.dot(lat_r, np.roll(lon_r, 1)))
    # Caluculating the vertical surface area
    perim = perimeter.per(p)
    rec2 = perim * rec1
    # Defining back the Geometry
    p_r = [lon_r, lat_r]
    p_r = np.transpose(p_r)
    p_r = np.array(p_r).tolist()
    # Writing the Geometry
    w.poly(parts=[p_r])
    w.record(rec1, rec2, rec3)
Esempio n. 2
0
def wgs(ufrac_path, threshold, thr_val, rlat_v, rlon_v, FR_URBAN):
    # Inizializations
    FR_URBAN_count = copy.deepcopy(FR_URBAN)
    # Read the dataset
    ufrac = gdal.Open(ufrac_path)
    # Create lat and lon arrays
    lon_res = ufrac.GetGeoTransform()[1]
    lon_l = ufrac.GetGeoTransform()[0]
    lon_r = ufrac.GetGeoTransform()[0] + ufrac.RasterXSize * lon_res
    lon = np.arange(lon_l, lon_r, lon_res)
    lat_res = ufrac.GetGeoTransform()[5]
    lat_l = ufrac.GetGeoTransform()[3] + lat_res
    lat_r = ufrac.GetGeoTransform()[3] + ufrac.RasterYSize * lat_res
    lat = np.arange(lat_l, lat_r, lat_res)
    lon_s_1 = np.zeros((len(lat), len(lon)))
    lat_s_1 = np.zeros((len(lat), len(lon)))
    for j in range(0, len(lat)):
        lon_s_1[j, :] = lon

    for j in range(0, len(lon)):
        lat_s_1[:, j] = lat

    # Read band
    data1 = ufrac.ReadAsArray()
    data1 = data1.astype(float)
    # Write FR_URB into cosmo output
    for j in range(0, len(lon)):
        for k in range(0, len(lat)):
            data1_tmp = data1[k, j]
            # Identify corresponding grid cell
            [lonC, latC] = np.array(geo2rot.g2r(lon_s_1[k, j], lat_s_1[k, j]))
            lon_idx = np.abs(rlon_v - lonC).argmin()
            lat_idx = np.abs(rlat_v - latC).argmin()
            # Calculate urban fraction contribution
            data1_tmp = data1_tmp / 100.
            FR_URBAN_count[0, lat_idx, lon_idx] += 1.
            if threshold == 1:
                if data1_tmp >= thr_val:
                    FR_URBAN[0, lat_idx, lon_idx] += 1.

            elif threshold == 0:
                FR_URBAN[0, lat_idx, lon_idx] += data1_tmp

    # Disable division by 0 error
    np.seterr(divide='ignore')
    FR_URBAN = FR_URBAN / FR_URBAN_count

    return FR_URBAN, data1, lat_s_1, lon_s_1
Esempio n. 3
0
def lidar(veg_path, thr_val, data1, rlat_v, rlon_v, lat_s_1, lon_s_1, \
        LAD_C, OMEGA, LAI_URB, greening):
    # Inizializations
    # Read the dataset
    print('Reading tree dataset')
    veg = gdal.Open(veg_path)
    # Create lat and lon arrays
    lon_res = veg.GetGeoTransform()[1]
    lon_l = veg.GetGeoTransform()[0]
    lon_r = veg.GetGeoTransform()[0] + veg.RasterXSize * lon_res
    lon = np.arange(lon_l, lon_r, lon_res)
    lat_res = veg.GetGeoTransform()[5]
    lat_l = veg.GetGeoTransform()[3] + lat_res
    lat_r = veg.GetGeoTransform()[3] + veg.RasterYSize * lat_res
    lat = np.arange(lat_l, lat_r, lat_res)
    lon_s_2 = np.zeros((len(lat), len(lon)))
    lat_s_2 = np.zeros((len(lat), len(lon)))
    for j in range(0, len(lat)):
        lon_s_2[j, :] = lon

    for j in range(0, len(lon)):
        lat_s_2[:, j] = lat

    # Read band
    data2 = veg.ReadAsArray()
    data2 = data2.astype(float)
    # Remove anomalous values
    data2[data2 > 20] = 20  # no trees taller than 20 m
    # Calculations
    print('Calculating LAD')  # status info
    OMEGA[0, :, :] = 0.5  # more relistic value for now
    # Write LAD into cosmo output
    for j in range(0, len(lon)):
        for k in range(0, len(lat)):
            h_veg_tmp = data2[k, j]
            if h_veg_tmp > 0.:
                # Identify corresponding grid cell
                [lonV,
                 latV] = np.array(geo2rot.g2r(lon_s_2[k, j], lat_s_2[k, j]))
                lon_idx = np.abs(rlon_v - lonV).argmin()
                lat_idx = np.abs(rlat_v - latV).argmin()
                # Calculate LAD from Lidar canopy height
                area_lidar = 1.  # m2 mesured in GIS
                LAD_spec = 1.  # m2 m-3 (Klingberg et al., 2017)
                area_grid = 278.93 * 278.93  # m2
                h_ug = 5.  # m, height urban grida
                h_cbase = 3.  # m, height of the canopy base
                # Check if in-canyon vegetation
                lon_urb_idx = np.abs(lon_s_1[0, :] - lon_s_2[k, j]).argmin()
                lat_urb_idx = np.abs(lat_s_1[:, 0] - lat_s_2[k, j]).argmin()
                data1_tmp = data1[lat_urb_idx, lon_urb_idx]
                if data1_tmp >= thr_val:
                    # In-canyon vegetation
                    if h_veg_tmp >= h_cbase:
                        LAD_C[0,:,0,lat_idx,lon_idx] += LAD_spec * area_lidar * \
                            (min(h_veg_tmp,h_ug) - h_cbase) / area_grid / h_ug
                    if h_veg_tmp >= 5:
                        LAD_C[0,:,1,lat_idx,lon_idx] += LAD_spec * (min(h_veg_tmp,10)-5)/h_ug \
                                                        * area_lidar / area_grid
                    if h_veg_tmp >= 10:
                        LAD_C[0,:,2,lat_idx,lon_idx] += LAD_spec * (min(h_veg_tmp,15)-10)/h_ug \
                                                        * area_lidar / area_grid
                    if h_veg_tmp >= 15:
                        LAD_C[0,:,3,lat_idx,lon_idx] += LAD_spec * (min(h_veg_tmp,20)-15)/h_ug \
                                                        * area_lidar / area_grid
                    if h_veg_tmp >= 20:
                        LAD_C[0,:,4,lat_idx,lon_idx] += LAD_spec * (min(h_veg_tmp,25)-20)/h_ug \
                                                        * area_lidar / area_grid
                    if h_veg_tmp >= 25:
                        LAD_C[0,:,5,lat_idx,lon_idx] += LAD_spec * (min(h_veg_tmp,30)-25)/h_ug \
                                                        * area_lidar / area_grid
                    if h_veg_tmp >= 30:
                        LAD_C[0,:,6,lat_idx,lon_idx] += LAD_spec * (min(h_veg_tmp,35)-30)/h_ug \
                                                        * area_lidar / area_grid
                    if h_veg_tmp >= 35:
                        LAD_C[0,:,7,lat_idx,lon_idx] += LAD_spec * (min(h_veg_tmp,40)-35)/h_ug \
                                                        * area_lidar / area_grid
                    if h_veg_tmp >= 40:
                        LAD_C[0,:,8,lat_idx,lon_idx] += LAD_spec * (min(h_veg_tmp,45)-40)/h_ug \
                                                        * area_lidar / area_grid
                    if h_veg_tmp >= 45:
                        LAD_C[0,:,9,lat_idx,lon_idx] += LAD_spec * (min(h_veg_tmp,50)-45)/h_ug \
                                                        * area_lidar / area_grid
                    if h_veg_tmp >= 50:
                        LAD_C[0,:,10,lat_idx,lon_idx] += LAD_spec * (min(h_veg_tmp,55)-50)/h_ug \
                                                        * area_lidar / area_grid
                    if h_veg_tmp >= 55:
                        LAD_C[0,:,11,lat_idx,lon_idx] += LAD_spec * (min(h_veg_tmp,60)-55)/h_ug \
                                                        * area_lidar / area_grid

                else:
                    # Out-canyon vegetation
                    LAI_URB[0,lat_idx,lon_idx] += LAD_spec * area_lidar * (h_veg_tmp-h_cbase) \
                                                    / area_grid

    if greening == True:  # use greening scenario
        print('greeing scenario active')
        LAD_C_tmp = np.ma.masked_where(LAD_C == 0, LAD_C)
        LAD_C = LAD_C * (1 + 2.33 * np.exp(-1 * LAD_C_tmp / LAD_C_tmp.mean()))
        LAD_C = np.ma.filled(LAD_C, 0)

    return LAD_C, OMEGA, LAI_URB
Esempio n. 4
0
def shp(sf_path, rlat_d, rlon_d, udir_d, uheight1_d, rlat_v, rlon_v, \
        FR_URBAN, FR_ROOF, norm_vert):
    # Inizializations
    AREA_BLD = np.zeros((1, rlat_d, rlon_d))
    BUILD_W = np.zeros((1, udir_d, rlat_d, rlon_d))
    FR_STREETD = np.zeros((1, udir_d, rlat_d, rlon_d))
    LAMBDA_F = np.zeros((1, udir_d, rlat_d, rlon_d))
    LAMBDA_P = np.zeros((1, rlat_d, rlon_d))
    MEAN_HEIGHT = np.zeros((1, rlat_d, rlon_d))
    STREET_W = np.zeros((1, udir_d, rlat_d, rlon_d))
    VERT_AREA = np.zeros((1, udir_d, rlat_d, rlon_d))
    # Read the dataset
    sf = shapefile.Reader(sf_path)
    shapes = sf.shapes()
    # Calculations
    N = len(shapes)
    for x in range(0, N):
        # Reading Geometry
        shape = shapes[x]
        p = shape.points
        p = np.array(p)
        # Reading the Area (horizontal)
        area = sf.record(x)[4]
        # Calculating the coordinates of the centroid of the polygon
        lonC = np.mean(p[:, 0])
        latC = np.mean(p[:, 1])
        # Converting centroid to rotated coordinates
        [lonC_r, latC_r] = geo2rot.g2r(lonC, latC)
        # Calculating the index of the correspoding grid point
        lon_idx = np.abs(rlon_v - lonC_r).argmin()
        lat_idx = np.abs(rlat_v - latC_r).argmin()
        # Allocating the total building area
        AREA_BLD[0, lat_idx, lon_idx] += area
        # Clustering the geomerty heights
        hgt = sf.record(x)[0]
        MEAN_HEIGHT[0, lat_idx, lon_idx] += hgt * area
        hgt_class = cluster.height_old(hgt)
        # Looping over building segments (facades)
        for k in range(1, len(p)):
            vert_area = geometry.distWGS(p, k) * hgt
            ang = geometry.angle(p, k)
            ang_class = cluster.angle(ang)
            #
            VERT_AREA[0, ang_class, lat_idx, lon_idx] += vert_area
            # Allocating the building area by direction and height
            FR_ROOF[0, ang_class, hgt_class, lat_idx, lon_idx] += vert_area

    # Calculating the area densities (Grimmond and Oke, 1998)
    np.seterr(divide='ignore')  # disabled division by 0 warning
    area_grid = 77970  # m2, calculated in GIS. TO DO: calculate from grid
    lambda_p = AREA_BLD[0, :, :] / (area_grid * FR_URBAN[0, :, :])
    lambda_p[lambda_p > 0.9] = 0.9  # upper limit
    lambda_p[lambda_p < 0.1] = 0.1  # lower limit
    lambda_f = VERT_AREA[0, :, :, :] / (area_grid * FR_URBAN[0, :, :])
    lambda_f[lambda_f > 0.9] = 0.9  # upper limit
    lambda_f[lambda_f < 0.1] = 0.1  # lower limit
    LAMBDA_P[0, :, :] = lambda_p
    LAMBDA_F[0, :, :, :] = lambda_f
    # Calculating the street and building widths (Martilli, 2009)
    h_m = MEAN_HEIGHT[0, :, :] / AREA_BLD[0, :, :]
    h_m[h_m == 15] = 10.
    BUILD_W[0, :, :, :] = lambda_p[np.newaxis, :, :] / lambda_f[:, :, :] * h_m
    STREET_W[0,:,:,:] = (1 / lambda_p[np.newaxis,:,:] - 1) * lambda_p[np.newaxis,:,:] \
                        / lambda_f * h_m
    #STREET_W[STREET_W<5] = 5  # min aspect ration LCZ 2
    #STREET_W[STREET_W>100] = 100  # max aspect ration LCZ 9

    # Calculating and normalizing the canyon direction distribution
    FR_STREETD = np.sum(FR_ROOF, 2)
    norm_streetd = np.sum(FR_STREETD, 1)
    FR_STREETD = FR_STREETD / norm_streetd

    # Normalizing FR_ROOF
    if norm_vert == True:
        norm_fr_roof = np.sum(FR_ROOF, 2)
    else:
        norm_fr_roof = np.sum(FR_ROOF, 1)

    for j in range(0, udir_d):
        for k in range(0, uheight1_d):
            for o in range(0, rlat_d):
                for z in range(0, rlon_d):
                    if norm_vert == True:
                        if norm_fr_roof[0, j, o, z] != 0:
                            FR_ROOF[0, j, k, o,
                                    z] = FR_ROOF[0, j, k, o,
                                                 z] / norm_fr_roof[0, j, o, z]

                    else:
                        if norm_fr_roof[0, k, o, z] != 0:
                            FR_ROOF[0, j, k, o,
                                    z] = FR_ROOF[0, j, k, o,
                                                 z] / norm_fr_roof[0, k, o, z]

    FR_ROOF[FR_ROOF < 0.001] = 0  # to avoid negative values

    return BUILD_W, STREET_W, FR_ROOF, FR_STREETD, shapes
Esempio n. 5
0
def point(ncd_name, lon, lat):
    ##########################
    # Inputs
    # ncd = path to netcdf file
    # lon = geographical longitude
    # lat = geographical latitude
    # Outputs
    # dq = convective heat flux [W m-2]
    #############################
    # constants
    cps = 1000  # J kg-1 K-1 heat capacity of the air
    # read grid variables
    ncd = Dataset(ncd_name, 'r')
    rlon = ncd.variables['rlon'][:]
    rlat = ncd.variables['rlat'][:]
    vcoord = ncd.variables['vcoord']
    # indexes from lon and lat
    [lon_r, lat_r] = geo2rot.g2r(lon, lat)
    idx = np.abs(rlon - (lon_r)).argmin()
    idy = np.abs(rlat - (lat_r)).argmin()
    # read variables
    u = ncd.variables['U'][0, -1, :, :]
    v = ncd.variables['V'][0, -1, :, :]
    t = ncd.variables['T'][0, -1, :, :]
    #w = ncd.variables['W'][0,-1,:,:] only horizontal
    tup = ncd.variables['T'][0, -2, :, :]
    rho = ncd.variables['RHO'][0, -1, :, :]
    rhoup = ncd.variables['RHO'][0, -2, :, :]
    # additional variables
    lat = ncd.variables['lat'][:, :]
    lon = ncd.variables['lon'][:, :]
    # cell size
    dx1 = abs(
        geom.dist(lon[idy, idx], lat[idy, idx], lon[idy, idx - 1],
                  lat[idy, idx - 1]))
    dx2 = abs(
        geom.dist(lon[idy, idx], lat[idy, idx], lon[idy, idx + 1],
                  lat[idy, idx + 1]))
    dx = (dx1 + dx2) / 2
    dy1 = abs(
        geom.dist(lon[idy, idx], lat[idy, idx], lon[idy - 1, idx], lat[idy - 1,
                                                                       idx]))
    dy2 = abs(
        geom.dist(lon[idy, idx], lat[idy, idx], lon[idy + 1, idx], lat[idy + 1,
                                                                       idx]))
    dy = (dy1 + dy2) / 2
    # convert to horizontal
    h = vcoord[-2] - vcoord[-1]
    Ax1 = dx1 * h
    Ax2 = dx2 * h
    Ay1 = dy1 * h
    Ay2 = dy2 * h
    # advective flux
    q_in_x = Ax1 * cps * ((rho[idy,idx]+rho[idy,idx-1])/2) *   \
             u[idy,idx] * ((t[idy,idx]+t[idy,idx-1])/2)
    q_out_x = Ax2 * cps * ((rho[idy,idx]+rho[idy,idx+1])/2) *  \
             u[idy,idx+1] * ((t[idy,idx]+t[idy,idx+1])/2)
    q_in_y = Ay1 * cps * ((rho[idy,idx]+rho[idy-1,idx])/2) *   \
             v[idy,idx] * ((t[idy,idx]+t[idy-1,idx])/2)
    q_out_y = Ay2 * cps * ((rho[idy,idx]+rho[idy+1,idx])/2) *  \
             v[idy+1,idx] * ((t[idy,idx]+t[idy+1,idx])/2)
    Dq_tot = q_in_x - q_out_x + q_in_y - q_out_y  # in W
    Dq_flux = Dq_vol * (dx * dy
                        )  # W / m2 as other turbulent (unresolved) fluxes
    # vertical component not considered
    #q_out_z = cps * ((rhoup[idy,idx]+rho[idy,idx])/2) *         \
    #         w[idy+1,idx] * ((tup[idy,idx]+t[idy,idx])/2)
    return Dq_flux