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 gasp.cpu.arcg.mng.fld import add_field
    from gasp.cpu.arcg.mng.fld import calc_fld
    from gasp.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
Arquivo: surf.py Projeto: zonakre/gasp
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 gasp.cpu.arcg.lyr import raster_lyr
        from gasp.cpu.arcg.spanlst.rcls import reclassify
        from gasp.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 WritePopLessXMin(shp, fld_pop, lst_intersected):
     add_field(shp, "poxX", "SHORT", "8")
     cursor = arcpy.UpdateCursor(shp)
     linha = cursor.next()
     while linha:
         bgri = int(linha.getValue("FID"))
         if bgri in lst_intersected:
             p = int(linha.getValue(fld_pop))
             linha.setValue("popX", p)
             cursor.UpdateRow(linha)
         linha = cursor.next()
     return "popX"
Exemplo n.º 4
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 gasp.cpu.arcg.lyr import feat_lyr, rst_lyr
    from gasp.prop.rst import rst_stats
    from gasp.cpu.arcg.mng.fld import add_field
    from gasp.mng.gen import copy_feat
    from gasp.cpu.arcg.anls.exct import select_by_attr
    from gasp.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.º 5
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 gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.mng.feat import feat_to_pnt
    from gasp.cpu.arcg.mng.fld import add_field
    from gasp.cpu.arcg.mng.fld import calc_fld
    from gasp.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.º 6
0
def assign_units_to_polygons(bgri,
                             polygons,
                             id_bgri,
                             id_polygon,
                             field_bgri='pol_assigned',
                             workspace=None):
    """
    Permite verificar a que municipio ou area de influencia uma subsecao
    estatistica pertence (territorialmente).
    
    Se uma subseccao se intersectar com mais de um poligono, a primeira fica
    relacionada ao poligono que ocupa maior parte da sua area (isto pode 
    levantar algumas questoes, mas para ja fica assim).
    
    A relacao entre a subsecao e o poligono que com ela intersecta ficara 
    escrita num novo campo da bgri
    
    Use Arcgis to accomplish this
    """

    import arcpy
    import os
    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg import get_geom_field, get_feat_area
    from gasp.cpu.arcg.anls.ovlay import intersect
    from gasp.cpu.arcg.mng.fld import add_field

    arcpy.env.overwriteOutput = True
    workspace = workspace if workspace else os.path.dirname(bgri)

    # Create feature layers of the inputs
    bgriLyr, polygLyr = [feat_lyr(bgri), feature_lyr(polygons)]

    # Intersect
    int_fc = os.path.join(workspace, 'bgri_and_polygons.shp')
    int_fc = intersect([bgriLyr, polygLyr], int_fc)

    # Relate bgri unit with polygon entities
    intLyr = feat_lyr(int_fc)

    cursor = arcpy.SearchCursor(intLyr)
    bgri_polygons = {}
    geomField = get_geom_field(intLyr)
    for linha in cursor:
        fid_bgri = linha.getValue(id_bgri)
        fid_polygon = linha.getValue(id_polygon)

        area = get_feat_area(linha, geomField)

        if fid_bgri not in bgri_polygons.keys():
            bgri_polygons[fid_bgri] = [fid_polygon, area]

        else:
            if area > bgri_polygons[fid_bgri][1]:
                bgri_polygons[fid_bgri] = [fid_polygon, area]

            else:
                continue

    # Write output
    del cursor, linha

    add_field(bgriLyr, field_bgri, "TEXT", "15")

    cursor = arcpy.UpdateCursor(bgriLyr)
    for linha in cursor:
        fid_bgri = linha.getValue(id_bgri)
        linha.setValue(field_bgri, bgri_polygons[fid_bgri][0])
        cursor.updateRow(linha)

    del cursor, linha, bgriLyr, polygLyr
Exemplo n.º 7
0
Arquivo: feat.py Projeto: zonakre/gasp
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 gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.mng.featcls import create_feat_class
    from gasp.cpu.arcg.mng.fld import add_field
    from gasp.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.º 8
0
Arquivo: calc.py Projeto: zonakre/gasp
def area_by_population(polygons,
                       inhabitants,
                       field_inhabitants,
                       work,
                       area_field='area_pop'):
    """
    Feature area (polygons) by feature inhabitant (inhabitants)
    """

    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.mng.fld import add_field
    from gasp.mng.genze import dissolve
    from gasp.cpu.arcg.anls.ovlay import intersect
    from gasp.cpu.arcg.anls.exct import select_by_attr

    # ArcGIS environment
    arcpy.env.overwriteOutput = True
    arcpy.env.workspace = work

    inhabitant_lyr = feat_lyr(inhabitants)

    add_field(inhabitant_lyr, area_field, "FLOAT", "")

    cursor = arcpy.UpdateCursor(inhabitant_lyr)
    lnh = cursor.next()

    while lnh:
        """TODO: Use intersection only once"""
        f = int(lnh.getValue("FID"))

        poly_extracted = "poly_{fid}.shp".format(fid=str(f))
        select_by_attr(inhabitant_lyr, "FID = {fid}".format(fid=str(f)),
                       poly_extracted)

        intersected = "int_{fid}.shp".format(fid=str(f))
        intersect([polygons, poly_extracted], intersected)

        dissolved = dissolve(intersected,
                             "diss_{f_}.shp".format(f_=str(f)),
                             "FID",
                             api='arcpy')

        cs = arcpy.SearchCursor(dissolved)

        l = cs.next()

        geom = arcpy.Describe(dissolved).shapeFieldName

        while l:
            area = float(l.getValue(geom).area)
            l = cs.next()

        pop = int(lnh.getValue(field_inhabitants))

        try:
            indicator = area / pop
        except:
            indicator = 0.0 / pop

        lnh.setValue(area_field)
        cursor.updateRow(lnh)

        lnh = cursor.next()
Exemplo n.º 9
0
Arquivo: calc.py Projeto: zonakre/gasp
def count_geom_by_polygon(shp_geom,
                          polygons,
                          w,
                          count_geom_field='COUNT',
                          population_field=None):
    """
    Intersect a given geometry with all polygons in a feature class and
    count the number of geometries inside each polygon.

    The user can also give a population field. The method will return the number
    of geometries by person * 1000.

    E.g. Count the number of points (health care centers, sports) by 
    statistical unit;
    E.g. Count the number of points by inhabitants in each statistical unit.
    """

    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.mng.fld import add_field
    from gasp.cpu.arcg.anls.ovlay import intersect
    from gasp.cpu.arcg.anls.exct import select_by_attr

    # ArcGIS environment
    arcpy.env.workspace = w
    arcpy.env.overwriteOutput = True

    polygon_lyr = feat_lyr(polygons)

    add_field(polygon_lyr, count_geom_field, "SHORT", "8")

    if population_field:
        geom_pop = count_geom_field + population_field
        if len(geom_pop) >= 10:
            geom_pop = geom_pop[:10]
        add_field(polygon_lyr, geom_pop, "FLOAT", "")

    # Update polygon layer
    cursor = arcpy.UpdateCursor(polygon_lyr)
    line = cursor.next()
    while line:
        """TODO: Use select by attributes and not select analysis"""
        fid = int(line.getValue("FID"))

        poly_extracted = "poly_{f}.shp".format(f=str(fid))
        select_by_attr(polygon_lyr, "FID = {f}".format(f=str(fid)),
                       poly_extracted)

        intersected = "pnt_{f}.shp".format(f=str(fid))
        intersect([shp_geom, poly_extracted], intersected)

        cs = arcpy.SearchCursor(intersected)
        nr_pnt = 0
        for i in cs:
            nr_pnt += 1

        if population_field:
            population = int(line.getValue(population_field))
            pnt_by_pop = (nr_pnt / float(pnt_by_pop)) * 1000.0
            line.setValue(geom_pop, pnt_by_pop)

        line.setValue(count_geom_field, nr_pnt)

        cursor.updateRow(line)

        line = cursor.next()
Exemplo n.º 10
0
def arcg_mean_time_WByPop(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 gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.mng.feat import feat_to_pnt
    from gasp.cpu.arcg.mng.fld import add_field
    from gasp.cpu.arcg.mng.fld import calc_fld
    from gasp.cpu.arcg.mng.joins import join_table
    from gasp.mng.genze import dissolve
    from gasp.mng.gen import copy_feat
    from gasp.mob.arctbx.closest import closest_facility

    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

    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")

    # Calculo dos somatorios por freguesia (conjunto)
    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,
                    statistics="tm SUM",
                    api="arcpy")
Exemplo n.º 11
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 gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.anls.exct import select_by_attr
    from gasp.cpu.arcg.mng.fld import field_statistics
    from gasp.cpu.arcg.mng.fld import add_field
    from gasp.cpu.arcg.mng.gen import merge
    from gasp.mng.gen import copy_feat
    from gasp.mob.arctbx.closest import closest_facility
    from gasp.to.shp.arcg import rst_to_pnt
    from gasp.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.º 12
0
def pop_less_dist_x(net_dataset, rdv_name, junctions_name, locations, interval,
                    unities, fld_groups, fld_pop, w, output):
    """
    Network processing - executar service area de modo a conhecer as areas a
    menos de x minutos de qualquer coisa
    """

    import arcpy
    import os
    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.mng.genze import dissolve
    from gasp.cpu.arcg.anls.ovlay import intersect
    from gasp.cpu.arcg.mng.fld import add_field
    from gasp.mob.arctbx.svarea import service_area_polygon

    def GetUnitiesIntersected(shpintersected, shpUnities):
        # AND IF SHPUNITIES HAS LESS THAN 6 CHARACTERS
        if len(os.path.basename(shpUnities)) > 6:
            fld_tag = os.path.basename(shpUnities)[:6]
        else:
            fld_tag = os.path.basename(shpUnities)
        c = arcpy.SearchCursor(shpintersected)
        l = c.next()
        u = []
        while l:
            fid_entity = int(l.getValue("FID_{name}".format(name=fld_tag)))
            if fid_entity not in u:
                u.append(fid_entity)
            l = c.next()
            return l

    def WritePopLessXMin(shp, fld_pop, lst_intersected):
        add_field(shp, "poxX", "SHORT", "8")
        cursor = arcpy.UpdateCursor(shp)
        linha = cursor.next()
        while linha:
            bgri = int(linha.getValue("FID"))
            if bgri in lst_intersected:
                p = int(linha.getValue(fld_pop))
                linha.setValue("popX", p)
                cursor.UpdateRow(linha)
            linha = cursor.next()
        return "popX"

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

    # Procedure #
    # Generate Service Area
    ServiceArea = service_area_polygon(net_dataset, rdv_name, junctions_name,
                                       interval, locations, "servarea.shp")

    # Intersect unities with Service Area
    lyr_unities = feat_lyr(unities)
    unities_servarea = intersect([lyr_unities, ServiceArea], "unidades_mx.shp")

    # Get the FID of the unities that intersects with the service area
    id_unities = GetUnitiesIntersected(unities_servarea, unities)
    # Update original shape with the population a menos de x minutes
    fld_pop_less_x = WritePopLessXMin(lyr_unities, fld_pop, id_unities)
    groups = dissolve(
        lyr_unities, output, fld_groups,
        "{pop} SUM;{popx} SUM".format(pop=fld_pop, popx=fld_pop_less_x))
    # Estimate population percent
    if len(fld_pop) > 6:
        fld_pop_tag = fld_pop[:6]
    else:
        fld_pop_tag = fld_pop

    add_field(shp, "lessX", "FLOAT", "8", "3")
    cursor = arcpy.UpdateCursor(output)
    linha = cursor.next()

    while linha:
        p = float(linha.getValue("SUM_{pop}".format(pop=fld_pop_tag)))
        pt = float(linha.getValue("SUM_{p}".format(p=fld_pop_less_x)))
        per = (p / pt) * 100.0
        linha.setValue("lessX", per)
        cursor.updateRow(linha)
        linha = cursor.next()
    return output
Exemplo n.º 13
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 gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.mng.feat import feat_to_pnt
    from gasp.cpu.arcg.mng.gen import merge
    from gasp.mng.gen import copy_feat
    from gasp.mng.genze import dissolve
    from gasp.cpu.arcg.mng.fld import add_field
    from gasp.cpu.arcg.mng.fld import calc_fld
    from gasp.cpu.arcg.mng.fld import field_statistics
    from gasp.cpu.arcg.mng.fld import type_fields
    from gasp.cpu.arcg.mng.joins import join_table
    from gasp.cpu.arcg.anls.exct import select_by_attr
    from gasp.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.º 14
0
Arquivo: prox.py Projeto: zonakre/gasp
def dist_bet_same_points_different_featcls(pntA,
                                           pntB,
                                           attrA,
                                           attrB,
                                           distField='distance'):
    """
    Calculate distance between the same points in different feature classes.
    
    The script knows that the point is the same in pntA and pntB if the
    value of attrA is equal to the value of attrB
    """

    import os
    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.mng.fld import add_field

    arcpy.env.overwriteOutput = True

    # List features in pntA
    lyrA = feat_lyr(pntA)
    cursor = arcpy.SearchCursor(lyrA)
    line = cursor.next()

    dA = {}
    while line:
        attr = line.getValue(attrA)
        geom = line.Shape.centroid

        if attr not in dA:
            dA[attr] = (geom.X, geom.Y)

        else:
            raise ValueError('AttrA and AttrB can not have duplicated values')

        line = cursor.next()

    del cursor
    del line

    # Calculate distance between points
    add_field(lyrA, distField, "DOUBLE", "6", precision="4")

    lyrB = feat_lyr(pntB)
    cursor = arcpy.SearchCursor(lyrB)
    line = cursor.next()

    dist = {}
    while line:
        attr = line.getValue(attrB)

        if attr in dA.keys():
            xa, ya = dA[attr]

            geom = line.Shape.centroid

            xb, yb = (geom.X, geom.Y)

            dist[attr] = ((xb - xa)**2 + (yb - ya)**2)**0.5

        line = cursor.next()

    del cursor
    del line

    cursor = arcpy.UpdateCursor(lyrA)
    for line in cursor:
        attr = line.getValue(attrA)

        if attr in dist:
            line.setValue(distField, dist[attr])

            cursor.updateRow(line)
Exemplo n.º 15
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 gasp.cpu.arcg.mng.featcls import create_feat_class
    from gasp.cpu.arcg.lyr         import feat_lyr
    from gasp.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