Beispiel #1
0
def round_table_values(table, decimal_by_col_file, outputFile):
    """
    Round all column values using the number of decimal places written
    in a excel file
    
    COL_NAME | nr_decimal_places
    COL_1    | 1
    COL_2    | 0
    ...      | ...
    COL_N    | 2
    """
    
    from glass.cpu.arcg.lyr     import feat_lyr
    from glass.mng.gen          import copy_feat
    from glass.cpu.arcg.mng.fld import type_fields
    from glass.fm               import tbl_to_obj
    
    arcpy.env.overwriteOutput = True
    
    # Get number of decimal places for the values of each column
    places_by_col = tbl_to_obj(
        decimal_by_col_file, sheet=0, output='dict', useFirstColAsIndex=True
    )
    
    PLACES_FIELD = places_by_col[places_by_col.keys()[0]].keys()[0]
    
    # Copy table
    outTable = copy_feat(table, outputFile, gisApi='arcpy')
    
    # Edit copy putting the correct decimal places in each column
    lyr = feat_lyr(outTable)
    
    # List table fields
    fields = type_fields(lyr)
    cursor = arcpy.UpdateCursor(lyr)
    for lnh in cursor:
        for col in fields:
            if col in places_by_col:
                if fields[col] == 'Integer' or fields[col] == 'Double' \
                   or fields[col] == 'SmallInteger':
                    value = lnh.getValue(col)
                
                    lnh.setValue(
                        col, 
                        round(value, int(places_by_col[col][PLACES_FIELD]))
                    )
                else:
                    continue
            else:
                print("{} not in {}".format(col, decimal_by_col_file))
        
        cursor.updateRow(lnh)
    
    del lyr
    
    return outputFile
Beispiel #2
0
def clip_by_feature(inputFeatures,
                    clipFeatures,
                    folderOutputs,
                    base_name,
                    clip_feat_id='FID'):
    """
    Clip inputFeatures for each feature in the clipFeatures layer
    Store all produced layers in the folderOutputs.
    """

    import os
    from glass.pys.oss import create_folder
    from gesri.df.lyr import feat_lyr
    from glass.cpu.arcg.mng.fld import type_fields

    # ########### #
    # Environment #
    # ########### #
    arcpy.env.overwriteOutput = True

    # ################ #
    # Now, is for real #
    # ################ #
    inputLyr = feat_lyr(inputFeatures)
    clipLyr = feat_lyr(clipFeatures)

    if not os.path.exists(folderOutputs):
        create_folder(folderOutputs)

    wTmp = create_folder(os.path.join(folderOutputs, 'tmp_clip'))

    # Get id's field type
    fld_type = type_fields(clipLyr, field=str(clip_feat_id))

    expression = '{fld}=\'{_id}\'' if str(fld_type) == 'String' else \
        '{fld}={_id}'

    c = arcpy.SearchCursor(clipLyr)
    l = c.next()
    while l:
        fid = str(l.getValue(clip_feat_id))

        selection = select_by_attr(
            clipLyr, expression.format(fld=clip_feat_id, _id=fid),
            os.path.join(wTmp, 'clp_{}.shp'.format(fid)))

        clip_f = clip(
            inputLyr, selection,
            os.path.join(folderOutputs, '{}_{}.shp'.format(base_name, fid)))

        l = c.next()
Beispiel #3
0
def polygons_from_points(inputPnt,
                         outputPol,
                         prj,
                         POLYGON_FIELD,
                         ORDER_FIELD=None):
    """
    Create a Polygon Table from a Point Table
    
    A given Point Table:
    FID | POLYGON_ID | ORDER_FIELD
     0  |    P1      |      1
     1  |    P1      |      2
     2  |    P1      |      3
     3  |    P1      |      4
     4  |    P2      |      1
     5  |    P2      |      2
     6  |    P2      |      3
     7  |    P2      |      4
     
    Will be converted into a new Polygon Table:
    FID | POLYGON_ID
     0  |    P1
     1  |    P2
     
    In the Point Table, the POLYGON_ID field identifies the Polygon of that point,
    the ORDER FIELD specifies the position (first point, second point, etc.)
    of the point in the polygon.
    
    If no ORDER field is specified, the points will be assigned to polygons
    by reading order.
    """

    import os
    from glass.cpu.arcg.lyr import feat_lyr
    from glass.cpu.arcg.mng.featcls import create_feat_class
    from glass.cpu.arcg.mng.fld import add_field
    from glass.cpu.arcg.mng.fld import type_fields

    arcpy.env.overwriteOutput = True

    # TODO: Check Geometry of the Inputs

    # List all point
    pntLyr = feat_lyr(inputPnt)
    cursor = arcpy.SearchCursor(pntLyr)
    line = cursor.next()

    lPnt = {}
    cnt = 0
    while line:
        # Get Point Geom
        pnt = line.Shape.centroid
        # Get Polygon Identification
        polygon = line.getValue(POLYGON_FIELD)
        # Get position in the polygon
        order = line.getValue(ORDER_FIELD) if ORDER_FIELD else cnt

        # Store data
        if polygon not in lPnt.keys():
            lPnt[polygon] = {order: (pnt.X, pnt.Y)}

        else:
            lPnt[polygon].update({order: (pnt.X, pnt.Y)})

        line = cursor.next()
        cnt += 1

    del line
    del cursor

    # Write Output
    create_feat_class(outputPol, "POLYGON", prj)

    outLyr = feat_lyr(outputPol)

    # Add polygon ID
    fieldsPnt = type_fields(pntLyr)

    POLYGON_FIELD_TYPE = "TEXT" if fieldsPnt[POLYGON_FIELD] == 'String' \
        else "SHORT" if fieldsPnt[POLYGON_FIELD] == 'Integer' else \
        "TEXT"
    POLYGON_FIELD_PRECISION = 50 if POLYGON_FIELD_TYPE == "TEXT" else \
        15

    add_field(outLyr, POLYGON_FIELD, POLYGON_FIELD_TYPE,
              POLYGON_FIELD_PRECISION)

    cursor = arcpy.InsertCursor(outLyr)

    # Add Polygons
    point = arcpy.CreateObject("Point")
    for polygon in lPnt:
        vector = arcpy.CreateObject("Array")

        pnt_order = lPnt[polygon].keys()
        pnt_order.sort()

        for p in pnt_order:
            point.ID = p
            point.X = lPnt[polygon][p][0]
            point.Y = lPnt[polygon][p][1]
            vector.add(point)

        # Add last point
        point.X = lPnt[polygon][pnt_order[0]][0]
        point.Y = lPnt[polygon][pnt_order[0]][1]
        vector.add(point)

        new_row = cursor.newRow()
        new_row.Shape = vector

        new_row.setValue(POLYGON_FIELD, str(polygon))

        cursor.insertRow(new_row)

        vector = 0
Beispiel #4
0
def mean_time_by_influence_area(netDt,
                                rdv,
                                infraestruturas,
                                fld_infraestruturas,
                                unidades,
                                id_unidade,
                                conjuntos,
                                popf,
                                influence_areas_unities,
                                w,
                                output,
                                oneway=True):
    """
    Tempo medio ponderado pela populacao residente a infra-estrutura mais
    proxima (min), por area de influencia
    
    * netDt - Path to Network Dataset
    * infraestruturas - Points of destiny
    * fld_infraestruturas - Field on destiny points to relate with influence area
    * unidades - BGRI; Freg; Concelhos
    * conjuntos - Freg; Concelhos; NUT - field
    * popf - Field with the population of the statistic unity
    * influence_areas_unities - Field on statistic unities layer to relate
    with influence area
    * w = Workspace
    * output = Path to store the final output
    * rdv - Name of feature class with the streets network
    * junctions - Name of feature class with the junctions
    """

    import arcpy
    import os
    from glass.cpu.arcg.lyr import feat_lyr
    from glass.cpu.arcg.mng.feat import feat_to_pnt
    from glass.cpu.arcg.mng.gen import merge
    from glass.mng.gen import copy_feat
    from glass.mng.genze import dissolve
    from glass.cpu.arcg.mng.fld import add_field
    from glass.cpu.arcg.mng.fld import calc_fld
    from glass.cpu.arcg.mng.fld import field_statistics
    from glass.cpu.arcg.mng.fld import type_fields
    from glass.cpu.arcg.mng.joins import join_table
    from glass.cpu.arcg.anls.exct import select_by_attr
    from glass.cpu.arcg.netanlst.closest import closest_facility
    """if arcpy.CheckExtension("Network") == "Available":
        arcpy.CheckOutExtension("Network")
    
    else:
        raise ValueError('Network analyst extension is not avaiable')"""
    def ListGroupArea(lyr, fld_ia, fld_grp):
        d = {}
        cs = arcpy.SearchCursor(lyr)
        for lnh in cs:
            id_group = lnh.getValue(fld_grp)
            id_ia = lnh.getValue(fld_ia)
            if id_group not in d.keys():
                d[id_group] = [id_ia]
            else:
                if id_ia not in d[id_group]:
                    d[id_group].append(id_ia)
        return d

    arcpy.env.overwriteOutput = True
    arcpy.env.workspace = w

    # Procedure #
    copy_unities = copy_feat(unidades,
                             os.path.join(w, os.path.basename(unidades)),
                             gisApi='arcpy')

    # Generate centroids of the statistic unities - unidades
    lyr_unidades = feat_lyr(copy_unities)
    pnt_unidades = feat_to_pnt(lyr_unidades,
                               'pnt_unidades.shp',
                               pnt_position="INSIDE")
    # List all groups of unities (conjuntos)
    group_areas = ListGroupArea(lyr_unidades, influence_areas_unities,
                                conjuntos)
    # Create Layers
    lyr_pnt_unidades = feat_lyr(pnt_unidades)
    lyr_pnt_facilities = feat_lyr(infraestruturas)

    result_list = []

    fld_type_unities = type_fields(lyr_pnt_unidades, field=conjuntos)
    SELECT_UNITIES = '{fld}=\'{c}\'' if str(fld_type_unities) == 'String' \
        else '{fld}={c}'

    fld_type_facilities = type_fields(lyr_pnt_facilities,
                                      field=fld_infraestruturas)
    SELECT_FACILITIES = '{fld}=\'{obj}\'' if str(fld_type_facilities) == 'String' \
        else '{fld}={obj}'
    for group in group_areas.keys():
        # Select centroids of interest
        interest_centroids = select_by_attr(
            lyr_pnt_unidades, SELECT_UNITIES.format(c=str(group),
                                                    fld=conjuntos),
            'pnt_{c}.shp'.format(c=str(group)))
        # Select facilities of interest
        expression = ' OR '.join([
            SELECT_FACILITIES.format(fld=fld_infraestruturas,
                                     obj=str(group_areas[group][i]))
            for i in range(len(group_areas[group]))
        ])

        interest_facilities = select_by_attr(
            lyr_pnt_facilities, expression,
            'facilities_{c}.shp'.format(c=str(group)))
        # Run closest facilitie - Distance between selected CENTROID and selected facilities
        cls_fac_table = os.path.join(w, "clsf_{c}.dbf".format(c=str(group)))
        closest_facility(netDt,
                         rdv,
                         interest_facilities,
                         interest_centroids,
                         cls_fac_table,
                         oneway_restriction=oneway)
        add_field(cls_fac_table, 'j', "SHORT", "6")
        calc_fld(cls_fac_table, 'j', "[IncidentID]-1")
        join_table(interest_centroids, "FID", cls_fac_table, "j", "Total_Minu")
        # Calculate sum of time x population
        add_field(interest_centroids, 'sum', "DOUBLE", "10", "3")
        calc_fld(interest_centroids, 'sum',
                 "[{pop}]*[Total_Minu]".format(pop=popf))
        denominador = field_statistics(interest_centroids, 'sum', 'SUM')
        add_field(interest_centroids, 'tm', "DOUBLE", "10", "3")
        calc_fld(
            interest_centroids, 'tm',
            "([sum]/{sumatorio})*[Total_Minu]".format(
                sumatorio=str(denominador)))
        result_list.append(interest_centroids)

    merge_shp = merge(result_list, "merge_centroids.shp")
    join_table(lyr_unidades, id_unidade, "merge_centroids.shp", id_unidade,
               "tm")

    return dissolve(lyr_unidades,
                    output,
                    conjuntos,
                    statistics="tm SUM",
                    api='arcpy')
Beispiel #5
0
def clip_several_each_feature(rst_folder,
                              shp,
                              feature_id,
                              work,
                              template=None,
                              rst_file_format='.tif'):
    """
    Clip a folder of rasters by each feature in a feature class

    The rasters clipped for a feature will be in an individual folder
    """

    import arcpy
    import os

    from glass.cpu.arcg.lyr import feat_lyr
    from glass.cpu.arcg.lyr import rst_lyr
    from glass.cpu.arcg.anls.exct import select_by_attr
    from glass.cpu.arcg.mng.fld import type_fields
    from glass.oss.ops import create_folder
    from glass.pys.oss import lst_ff

    # ########### #
    # Environment #
    # ########### #
    arcpy.env.overwriteOutput = True
    arcpy.env.workspace = work

    # ###### #
    # Do it! #
    # ###### #
    # Open feature class
    lyr_shp = feat_lyr(shp)

    # Create folder for some temporary files
    wTmp = create_folder(os.path.join(work, 'tmp'))

    # Split feature class in parts
    c = arcpy.SearchCursor(lyr_shp)
    l = c.next()
    features = {}

    # Get id's field type
    fld_type = type_fields(lyr_shp, field=feature_id)

    expression = '{fld}=\'{_id}\'' if str(fld_type) == 'String' else \
        '{fld}={_id}'

    del fields, f

    while l:
        fid = str(l.getValue(feature_id))

        selection = select_by_attr(
            lyr_shp, expression.format(fld=feature_id, _id=fid),
            os.path.join(wTmp, 'each_{}.shp'.format(fid)))

        f_lyr = feat_lyr(selection)
        features[fid] = f_lyr

        l = c.next()

    rasters = lst_ff(rst_folder, file_format='.tif')

    for raster in rasters:
        r_lyr = rst_lyr(raster)
        for feat in features:
            clip_rst = clip_raster(
                r_lyr, features[feat],
                os.path.join(work,
                             os.path.splitext(os.path.basename(feat))[0],
                             os.path.basename(raster)), template)