Exemplo n.º 1
0
def points_to_facility(netDataset,
                       rdv_name,
                       points,
                       facilities,
                       outTable,
                       oneway=None,
                       save_result_input=None):
    """
    Execute Closest Facility and save the result in the points table
    """

    from glass.cpu.arcg.mng.fld import add_field
    from glass.cpu.arcg.mng.fld import calc_fld
    from glass.cpu.arcg.mng.joins import join_table

    arcpy.env.overwriteOutput = True

    closest_facility(netDataset,
                     rdv_name,
                     facilities,
                     points,
                     outTable,
                     oneway_restriction=oneway)

    if save_result_input:
        add_field(outTable, 'j', "SHORT", 6)
        calc_fld(outTable, 'j', "[IncidentID]-1")
        join_table(points, "FID", outTable, "j", "Total_Minu")
Exemplo n.º 2
0
def aspect(dem, aspect, reclass=None):
    """
    Return Aspect raster reclassified or not
    """

    import os

    outAspect = aspect if not reclass else \
        os.path.join(
            os.path.dirname(aspect),
            '{n}_original{f}'.format(
                n=os.path.splitext(os.path.basename(aspect))[0],
                f=os.path.splitext(os.path.basename(aspect))[1]
            )
        )

    arcpy.gp.Aspect_sa(dem, outAspect)

    if reclass:
        from glass.cpu.arcg.lyr import raster_lyr
        from glass.cpu.arcg.spanlst.rcls import reclassify
        from glass.cpu.arcg.mng.fld import add_field

        __rules = ("-1 0 1;"
                   "0 22,5 2;"
                   "22,5 67,5 3;"
                   "67,5 112,5 4;"
                   "112,5 157,5 5;"
                   "157,5 202,5 6;"
                   "202,5 247,5 7;"
                   "247,5 292,5 8;"
                   "292,5 337,5 9;"
                   "337,5 360 2")

        reclassify(outAspect, "Value", __rules, aspect, template=outAspect)

        d = {
            1: 'Flat',
            2: 'North',
            3: 'Northeast',
            4: 'East',
            5: 'Southeast',
            6: 'South',
            7: 'Southwest',
            8: 'West',
            9: 'Northwest'
        }

        add_field(aspect, 'aspect', "TEXT", "15")

        cursor = arcpy.UpdateCursor(rst_lyr(aspect))
        for lnh in cursor:
            __val = int(lnh.getValue("Value"))

            lnh.setValue('aspect', d[__val])

            cursor.updateRow(lnh)

        del cursor, lnh
Exemplo n.º 3
0
def mean_rst_by_polygon(polygons, raster, work, resultShp):
    """
    Mean of all cells intersect with the input polygon features
    """

    import arcpy
    import os

    from glass.cpu.arcg.lyr import feat_lyr, rst_lyr
    from glass.prop.rst import rst_stats
    from glass.cpu.arcg.mng.fld import add_field
    from glass.mng.gen import copy_feat
    from glass.cpu.arcg.anls.exct import select_by_attr
    from glass.cpu.arcg.mng.rst.proc import clip_raster

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

    # ###### #
    # Do it! #
    # ###### #
    # Copy the Input
    poly_copy = copy_feat(polygons, resultShp, gisApi='arcpy')
    # Create Layers
    lyrShp = feat_lyr(poly_copy)
    lyrRst = rst_lyr(raster)
    # Create field for register calculated statistics
    if len(os.path.basename(raster)) <= 10:
        fld_name = os.path.basename(raster)
    else:
        fld_name = os.path.basename(raster)[:10]
    add_field(lyrShp, fld_name, "DOUBLE", "20", "3")
    # Calculate mean
    c = arcpy.UpdateCursor(lyrShp)
    l = c.next()
    while l:
        fid = str(l.getValue("FID"))
        selection = select_by_attr(lyrShp, "FID={c}".format(c=fid),
                                   "poly_{c}.shp".format(c=fid))
        sel_rst = clip_raster(lyrRst, selection,
                              "clip_rst_{c}.img".format(c=fid))

        mean = rst_stats(sel_rst, api='arcpy')["MEAN"]
        l.setValue(fld_name, mean)
        c.updateRow(l)
        l = c.next()
Exemplo n.º 4
0
def polygons_to_facility(netdataset,
                         polygons,
                         facilities,
                         outTbl,
                         oneway=None,
                         rdv=None,
                         junctions=None,
                         save_result_input=None):
    """
    Execute the Closest Facility tool after calculation of polygons
    centroids
    """

    from glass.cpu.arcg.lyr import feat_lyr
    from glass.cpu.arcg.mng.feat import feat_to_pnt
    from glass.cpu.arcg.mng.fld import add_field
    from glass.cpu.arcg.mng.fld import calc_fld
    from glass.cpu.arcg.mng.joins import join_table

    arcpy.env.overwriteOutput = True

    # Polygons to Points
    polLyr = feat_lyr(polygons)
    pntShp = os.path.join(
        os.path.dirname(polygons),
        os.path.splitext(os.path.basename(polygons))[0] + '_pnt.shp')
    pntShp = feat_to_pnt(polLyr, pntShp, pnt_position='INSIDE')

    closest_facility(netdataset,
                     facilities,
                     pntShp,
                     outTbl,
                     oneway_restriction=oneway,
                     rdv=rdv,
                     junc=junctions)

    field_output = 'dst' + os.path.splitext(os.path.basename(facilities))[0]
    add_field(outTbl, field_output[:10], "FLOAT", "10", "3")
    calc_fld(outTbl, field_output[:10], "[Total_Minu]")

    if save_result_input:
        add_field(outTbl, 'j', "SHORT", "6")
        calc_fld(outTbl, 'j', "[IncidentID]-1")
        join_table(polLyr, "FID", outTbl, "j", field_output[:10])
Exemplo n.º 5
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
Exemplo n.º 6
0
def arcg_mean_time_WByPop2(netDt,
                           rdv,
                           infraestruturas,
                           unidades,
                           conjuntos,
                           popf,
                           w,
                           output,
                           oneway=None):
    """
    Tempo medio ponderado pela populacao residente a infra-estrutura mais
    proxima (min)
    
    * netDt = Path to Network Dataset
    * infraestruturas = Points of destiny
    * unidades = BGRI; Freg; Concelhos
    * conjuntos = Freg; Concelhos; NUT - field
    * popf = Field with the population of the statistic unity
    * w = Workspace
    * output = Path to store the final output
    * rdv = Name of feature class with the streets network
    """

    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.fld import add_field, calc_fld
    from glass.cpu.arcg.mng.joins import join_table
    from glass.mng.genze import dissolve
    from glass.mng.gen import copy_feat
    from glass.mob.arctbx.closest import closest_facility
    from glass.dct import tbl_to_obj

    def get_freg_denominator(shp, groups, population, fld_time="Total_Minu"):
        cursor = arcpy.SearchCursor(shp)

        groups_sum = {}
        for lnh in cursor:
            group = lnh.getValue(groups)
            nrInd = float(lnh.getValue(population))
            time = float(lnh.getValue(fld_time))

            if group not in groups_sum.keys():
                groups_sum[group] = time * nrInd

            else:
                groups_sum[group] += time * nrInd

        del cursor, lnh

        return groups_sum

    if not os.path.exists(w):
        from glass.oss.ops import create_folder
        w = create_folder(w, overwrite=False)

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

    # Start Procedure #
    # Create copy of statitic unities to preserve the original data
    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')

    # Network Processing - Distance between CENTROID and Destiny points
    closest_facility(netDt,
                     rdv,
                     infraestruturas,
                     pnt_unidades,
                     os.path.join(w, "cls_table.dbf"),
                     oneway_restriction=oneway)
    add_field("cls_table.dbf", 'j', "SHORT", "6")
    calc_fld("cls_table.dbf", 'j', "[IncidentID]-1")
    join_table(lyr_unidades, "FID", "cls_table.dbf", "j", "Total_Minu")
    del lyr_unidades

    # Calculo dos somatorios por freguesia (conjunto)
    # To GeoDf
    unidadesDf = tbl_to_obj(copy_unities)
    """
    groups = get_freg_denominator(lyr_unidades, conjuntos, popf)
    add_field(lyr_unidades, "tm", "FLOAT", "10", "3")
    
    cs = arcpy.UpdateCursor(lyr_unidades)
    linha = cs.next()
    while linha:
        group = linha.getValue(conjuntos)
        t = float(linha.getValue("Total_Minu"))
        p = int(linha.getValue(popf))
        total = groups[group]
        indi = ((t * p) / total) * t
        linha.setValue("tm", indi)
        cs.updateRow(linha)
        linha = cs.next()
    
    return dissolve(lyr_unidades, output, conjuntos, "tm SUM")"""
    return unidadesDf
Exemplo n.º 7
0
def mean_time_in_povoated_areas(network,
                                rdv_name,
                                stat_units,
                                popFld,
                                destinations,
                                output,
                                workspace,
                                ONEWAY=True,
                                GRID_REF_CELLSIZE=10):
    """
    Receive statistical units and some destinations. Estimates the mean distance
    to that destinations for each statistical unit.
    The mean for each statistical will be calculated using a point grid:
    -> Statistical unit to grid point;
    -> Distance from grid point to destination;
    -> Mean of these distances.
    
    This method will only do the math for areas (statistic units)
    with population.
    """

    import os
    import arcpy
    from glass.cpu.arcg.lyr import feat_lyr
    from glass.cpu.arcg.anls.exct import select_by_attr
    from glass.cpu.arcg.mng.fld import field_statistics
    from glass.cpu.arcg.mng.fld import add_field
    from glass.cpu.arcg.mng.gen import merge
    from glass.mng.gen import copy_feat
    from glass.mob.arctbx.closest import closest_facility
    from glass.to.shp.arcg import rst_to_pnt
    from glass.to.rst import shp_to_raster

    if arcpy.CheckExtension("Network") == "Available":
        arcpy.CheckOutExtension("Network")

    else:
        raise ValueError('Network analyst extension is not avaiable')

    arcpy.env.overwriteOutput = True

    WORK = workspace

    # Add field
    stat_units = copy_feat(stat_units,
                           os.path.join(WORK, os.path.basename(stat_units)),
                           gisApi='arcpy')
    add_field(stat_units, "TIME", "DOUBLE", "10", precision="3")

    # Split stat_units into two layers
    # One with population
    # One with no population
    withPop = select_by_attr(stat_units, '{}>0'.format(popFld),
                             os.path.join(WORK, 'with_pop.shp'))
    noPop = select_by_attr(stat_units, '{}=0'.format(popFld),
                           os.path.join(WORK, 'no_pop.shp'))

    # For each statistic unit with population
    withLyr = feat_lyr(withPop)
    cursor = arcpy.UpdateCursor(withLyr)

    FID = 0
    for feature in cursor:
        # Create a new file
        unity = select_by_attr(
            withLyr, 'FID = {}'.format(str(FID)),
            os.path.join(WORK, 'unit_{}.shp'.format(str(FID))))

        # Convert to raster
        rst_unity = shp_to_raster(unity,
                                  "FID",
                                  GRID_REF_CELLSIZE,
                                  None,
                                  os.path.join(WORK,
                                               'unit_{}.tif'.format(str(FID))),
                                  api='arcpy')

        # Convert to point
        pnt_unity = rst_to_pnt(
            rst_unity, os.path.join(WORK, 'pnt_un_{}.shp'.format(str(FID))))

        # Execute closest facilitie
        CLOSEST_TABLE = os.path.join(WORK, 'cls_fac_{}.dbf'.format(str(FID)))
        closest_facility(network,
                         rdv_name,
                         destinations,
                         pnt_unity,
                         CLOSEST_TABLE,
                         oneway_restriction=ONEWAY)

        # Get Mean
        MEAN_TIME = field_statistics(CLOSEST_TABLE, 'Total_Minu', 'MEAN')[0]

        # Record Mean
        feature.setValue("TIME", MEAN_TIME)
        cursor.updateRow(feature)

        FID += 1

    merge([withPop, noPop], output)

    return output
Exemplo n.º 8
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')
Exemplo n.º 9
0
def geomArray_to_fc(array,
                    output,
                    GEOM_TYPE,
                    EPSG,
                    overwrite=True,
                    fields=None):
    """
    Convert a array as
    array = [
        {
            "FID" : 0,
            "OTHER_FIELDS" : value
            "GEOM" : [(x1, y1), ..., (xn, yn)]
        },
        ...,
        {
            "FID" : 1,
            "OTHER_FIELDS" : value
            "GEOM" : [(x1, y1), ..., (xn, yn)]
        },
    ]
    
    to a new Feature Class
    
    If fields, it should have a value like:
    {name : [type, length], name: [type, length]}
    """

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

    if overwrite: arcpy.env.overwriteOutput = True

    # Create a new Feature Class
    output = create_feat_class(output, GEOM_TYPE, EPSG)

    outLyr = feat_lyr(output)

    # Create fields
    if fields:
        if type(fields) != dict:
            raise ValueError('FIELDS should be a dict')

        else:
            for fld in fields:
                add_field(outLyr, fld, fields[fld][0], fields[fld][1])

    # Add things to the feature class
    cursor = arcpy.InsertCursor(outLyr)
    point = arcpy.CreateObject("Point")
    for line in array:
        vector = arcpy.CreateObject("Array")

        c = 0
        for pnt in line["GEOM"]:
            point.ID = c
            point.X = pnt[0]
            point.Y = pnt[1]
            vector.add(point)
            c += 1

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

        # Add field values
        if fields:
            for fld in fields:
                if fld in line:
                    new_row.setValue(fld, line[fld])

        cursor.insertRow(new_row)

        vector = 0

    return output