Ejemplo n.º 1
0
def folderShp_Intersection(inFolder, intFeatures, outFolder):
    """
    Intersect all feature classes in a folder with the feature classes
    listed in the argument intFeatures (path to the file).
    """

    import os

    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.oss.ops import create_folder

    # Environment
    arcpy.env.overwriteOutput = True
    # Workspace
    arcpy.env.workspace = inFolder

    if type(intFeatures) != list:
        intFeatures = [intFeatures]

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

    # List feature classes in inFolder
    fc_infld = arcpy.ListFeatureClasses()

    # Create Layer objects
    lyr_infld = [feat_lyr(os.path.join(inFolder, str(fc))) for fc in fc_infld]
    lyr_intFeat = [feat_lyr(fc) for fc in intFeatures]

    # Intersect things
    for i in range(len(lyr_infld)):
        intersect([lyr_infld[i]] + lyr_intFeat,
                  os.path.join(outFolder, os.path.basename(str(fc_infld[i]))))
Ejemplo n.º 2
0
def euclidean_distance(shpRst, cellsize, outRst, template=None,
                       boundary=None, snap=None):
    """
    Euclidean distance from Spatial Analyst
    """
    
    from arcpy import env
    from arcpy.sa import *
    import os
    
    arcpy.CheckOutExtension('Spatial')
    
    from gasp.prop.ff      import vector_formats, raster_formats
    from gasp.cpu.arcg.lyr import feat_lyr, rst_lyr
    
    path_to_output = outRst if not boundary else \
        os.path.join(
            os.path.dirname(outRst),
            '{n}_ext{f}'.format(
                n=os.path.splitext(os.path.basename(outRst))[0],
                f=os.path.splitext(os.path.basename(outRst))[1]
            )
        )
    
    inputFormat = os.path.splitext(shpRst)[1]
    if inputFormat in vector_formats():
        inLyr = feat_lyr(shpRst)
    
    elif inputFormat in raster_formats():
        inLyr = rst_lyr(shpRst)
    
    else:
        raise ValueError(
            'Could not identify if shpRst is a feature class or a raster'
        )
    
    if template:
        tempEnvironment0 = env.extent
        env.extent = template
    
    if snap:
        tempSnap = env.snapRaster
        env.snapRaster = snap
    
    outEucDistance = EucDistance(inLyr, "", cellsize, "")
    outEucDistance.save(path_to_output)
    
    if template: env.extent = tempEnvironment0
    
    if snap: env.snapRaster = tempSnap
    
    if boundary:
        from gasp.cpu.arcg.mng.rst.proc import clip_raster
        
        clipLyr = feat_lyr(boundary)
        
        clip_raster(path_to_output, clipLyr, outRst,
                    template=template, snap=snap)
Ejemplo n.º 3
0
Archivo: exct.py Proyecto: zonakre/gasp
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 gasp.oss.ops import create_folder
    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.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()
Ejemplo n.º 4
0
def lines_polygons_to_txt(lnhShp, outTxt):
    """
    Lines or Polygons Feature Class to Text File
    """
    
    from gasp.cpu.arcg.lyr import feat_lyr
    
    lyr = feat_lyr(lnhShp)
    
    with open(outTxt, mode='w') as txt:
        cursor = arcpy.SearchCursor(lyr)
        
        for reg in cursor:
            fid  = reg.getValue("FID")
            geom = reg.getValue("Shape")
            
            nr_part = 0
            
            for vector in geom:
                for pnt in vector:
                    txt.write(
                        '{_id} {part} {_pnt}\n'.format(
                            _id=str(fid), part=str(nr_part), _pnt=str(pnt)
                        )
                    )
                
                nr_part += 1
        
        txt.close()
    
    return outTxt
Ejemplo n.º 5
0
def create_TINdem(elevation, elvfield, lmt, prj, output, hydrology=None):
    """
    Create Raster DEM from TIN
    """
    
    import os
    from gasp.cpu.arcg.lyr         import feat_lyr
    from gasp.cpu.arcg._3D.mng.tin import create_tin
    
    lyr_elev = feat_lyr(elevation, 'elev_lyr')
    lyr_lmt  = feat_lyr(lmt, 'bnd_lyr')
    
    if not hydrology:
        __inputs = (
            "bnd_lyr <None> Soft_Clip <None>; "
            "elev_lyr {fld} Mass_Points <None>"
        ).format(
            bound=os.path.splitext(os.path.basename(lmt))[0],
            alti=os.path.splitext(os.path.basename(elevation))[0],
            fld=str(elvfield)
        )
    
    else:
        lyr_hidro = feat_lyr(hydrology)
        
        __inputs = (
            "bnd_lyr <None> Soft_Clip <None>; "
            "elev_lyr {fld} Mass_Points <None>; "
            "{hidro} <None> Hard_Line <None>"
        ).format(
            bound=os.path.splitext(os.path.basename(lmt))[0],
            alti=os.path.splitext(os.path.basename(elevation))[0],
            fld=str(elvfield),
            hidro=os.path.splitext(os.path.basename(hydrology))[0]
        )
    
    if type(prj) == int:
        from gasp.web.srorg import get_wkt_esri
        
        prjWkt = get_wkt_esri(prj)
    
    create_tin(output, prjWkt, __inputs)
    
    return output
Ejemplo n.º 6
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 gasp.cpu.arcg.lyr import feat_lyr
    from gasp.mng.gen import copy_feat
    from gasp.cpu.arcg.mng.fld import type_fields
    from gasp.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
Ejemplo n.º 7
0
def clip_each_feature(rst, shp, feature_id, work, out_basename):
    """
    Clip a raster dataset for each feature in a feature class
    """

    import arcpy
    import os

    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.lyr import rst_lyr
    from gasp.cpu.arcg.anls.exct import select_by_attr
    from gasp.oss.ops import create_folder

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

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

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

    # Get id's field type
    fields = arcpy.ListFields(lyr_shp)
    for f in fields:
        if str(f.name) == str(feature_id):
            fld_type = f.type
            break

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

    del fields, f

    # Run the clip tool for each feature in the shp input
    c = arcpy.SearchCursor(lyr_shp)
    l = c.next()
    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)))

        clip_rst = clip_raster(lyr_rst, selection,
                               '{b}_{_id}.tif'.format(b=out_basename, _id=fid))

        l = c.next()
Ejemplo n.º 8
0
def TIN_nodata_interpolation(inRst, boundary, prj, cellsize, outRst,
                             workspace=None, template=None):
    """
    Preenche os valores NoData de uma imagem raster usando um TIN
    """
    
    import os
    from gasp.oss                   import get_filename
    from gasp.cpu.arcg.lyr         import rst_lyr
    from gasp.cpu.arcg.lyr         import feat_lyr
    from gasp.cpu.to.shp.arcg      import rst_to_pnt
    from gasp.cpu.arcg._3D.mng.tin import create_tin
    from gasp.cpu.to.rst.arcg      import tin_to_raster
    
    workspace = workspace if workspace else \
        os.path.dirname(outRst)
    
    # Convert Input Raster to a Point Feature Class
    rstLyr = rst_lyr(inRst)
    pntRst = rst_to_pnt(
        rstLyr,
        os.path.join(workspace, get_filename(inRstinRst) + '.shp')
    )
    
    # Create TIN
    pntrstLyr = feat_lyr(  pntRst)
    lmtLyr    = feat_lyr(boundary)
    
    tinInputs = (
        '{bound} <None> Soft_Clip <None>;'
        '{rst_pnt} GRID_CODE Mass_Points <None>'
    )
    
    tinOutput = os.path.join(workspace, 'tin_' + get_filename(inRst))
    
    create_tin(tinOutput, prj, tinInputs)
    
    return tin_to_raster(tinOutput, cellsize, outRst, template=template)
Ejemplo n.º 9
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()
Ejemplo n.º 10
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])
Ejemplo n.º 11
0
def pnt_to_txt(pntShp, outTxt):
    """
    Point Feature Class to Text File
    """

    from gasp.cpu.arcg.lyr import feat_lyr

    lyr = feat_lyr(pntShp)

    with open(outTxt, mode='w') as txt:
        cursor = arcpy.SearchCursor(lyr)

        for linha in cursor:
            txt.write('{fid} {pnt}\n'.format(fid=str(linha.getValue("FID")),
                                             pnt=str(linha.Shape.centroid)))

        txt.close()

    return outTxt
Ejemplo n.º 12
0
Archivo: exct.py Proyecto: zonakre/gasp
def split_shp_by_two_attr(s, f1, f2, w):
    """
    Este script parte uma shpefile segundo a informacao disponivel em dois
    campos, ou seja, cada feature com a mesma combinacao de informacao
    relativa a dois campos e exportada para uma nova shapefile; estas
    combinacoes podem-se repetir em varias features 
    """

    from gasp.cpu.arcg.lyr import feat_lyr

    arcpy.env.workspace = w
    lyr = feat_lyr(s)
    c = arcpy.SearchCursor(lyr)
    l = c.next()
    dic = {}

    while l:
        f1v = l.getValue(f1)
        if f1v not in dic.keys():
            dic.update({l.getValue(f1): [l.getValue(f2)]})
        else:
            if l.getValue(f2) not in dic[f1v]:
                dic[f1v].append(l.getValue(f2))
        l = c.next()

    for v1 in dic.keys():
        for v2 in dic[v1]:
            """
            TODO: DECODE V1 AND V2 and DEL SPACES
            """
            nova_layer = '{f_1}_{v_1}_{f_2}_{v_2}.shp'.format(f_1=f1,
                                                              f_2=f2,
                                                              v_1=str(v1),
                                                              v_2=str(v2))
            """
            TODO: Define SQL based on the type of the fields f1 and f2
            """
            expressao = '{f_1}=\'{v_1}\' AND {f_2}=\'{v_2}\''.format(
                f_1=f1, f_2=f2, v_1=str(v1), v_2=str(v2))

            arcpy.Select_analysis(lyr, nova_layer, expressao)
Ejemplo n.º 13
0
Archivo: exct.py Proyecto: zonakre/gasp
def split_shp_based_on_comparation(shp, f1, f2, inEpsg, outWork):
    """
    Split shp in two datasets:
    
    - shp_equal with the features with the same value in the attributes
    in f1 e f2;
    - shp_diff with the features with different values in the attributes
    in f1 e f2.
    f1 and f2 could be a string or a list 
    """

    import os
    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg import get_geom_type
    from gasp.cpu.arcg.mng.featcls import create_feat_class
    from gasp.cpu.arcg.mng.fld import list_fields
    from gasp.cpu.arcg.mng.fld import copy_fields

    f1 = [f1] if type(f1) == str or type(f1) == unicode else \
        f1 if type(f1) == list else None

    f2 = [f2] if type(f2) == str or type(f2) == unicode else \
        f2 if type(f2) == list else None

    if not f1 or not f2:
        raise ValueError('f1 and f2 values are not valid')

    if len(f1) != len(f2):
        raise ValueError('f1 and f2 should have the same length')

    arcpy.env.overwriteOutput = True

    # Create outputs
    inGeom = get_geom_type(shp)
    equalShp = create_feat_class(
        os.path.join(
            outWork, '{}_equal{}'.format(
                os.path.splitext(os.path.basename(shp))[0],
                os.path.splitext(os.path.basename(shp))[1])), inGeom, inEpsg)
    equalLyr = feat_lyr(equalShp)

    difShp = create_feat_class(
        os.path.join(
            outWork, '{}_dif{}'.format(
                os.path.splitext(os.path.basename(shp))[0],
                os.path.splitext(os.path.basename(shp))[1])), inGeom, inEpsg)
    difLyr = feat_lyr(difShp)

    # Copy Fields
    inLyr = feat_lyr(shp)
    fields = list_fields(inLyr)
    copy_fields(inLyr, equalLyr)
    copy_fields(inLyr, difLyr)

    # Read inputs and write in the outputs
    cursorRead = arcpy.SearchCursor(inLyr)
    cursorEqual = arcpy.InsertCursor(equalLyr)
    cursorDif = arcpy.InsertCursor(difLyr)

    line = cursorRead.next()
    while line:
        val_1 = [line.getValue(f) for f in f1]
        val_2 = [line.getValue(f) for f in f2]

        if val_1 == val_2:
            new_row = cursorEqual.newRow()

        else:
            new_row = cursorDif.newRow()

        new_row.Shape = line.Shape

        for field in fields:
            if field == 'FID' or field == 'Shape' or field == 'ID':
                continue

            new_row.setValue(field, line.getValue(field))

        if val_1 == val_2:
            cursorEqual.insertRow(new_row)

        else:
            cursorDif.insertRow(new_row)

        line = cursorRead.next()
Ejemplo n.º 14
0
Archivo: calc.py Proyecto: 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()
Ejemplo n.º 15
0
Archivo: calc.py Proyecto: 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()
Ejemplo n.º 16
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
Ejemplo n.º 17
0
def service_area_as_sup_cst(networkDataset,
                            rdvName,
                            extentLyr,
                            originsLyr,
                            output,
                            epsg=3763,
                            REF_DISTANCE=3000,
                            NR_INTERVALS=20):
    """
    Create a Cost Distance Surface using Service Area Tool
    
    Same result of the Cost Distance tool but using Service Area Tool
    
    Supported by Google Maps API
    
    PROBLEM: REF_DISTANCE should be greater if the extent is higher.
    """

    import os

    from gasp.prop.ext import get_extent
    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.to.shp.arcg import geomArray_to_fc
    from gasp.mob.arctbx.svarea import service_area_polygon
    from gasp.web.glg.distmatrix import get_max_dist

    if epsg != 4326:
        from gasp.mng.prj import project

    arcpy.env.overwriteOutput = True

    # Get extent
    minX, maxX, minY, maxY = get_extent(extentLyr, gisApi='arcpy')

    # Get Reference points through the boundary
    # Get North West to East
    north_west_east = [(minX, maxY)]
    # Get South West to East
    south_west_east = [(minX, minY)]
    c = minX
    while c < maxX:
        north_west_east.append((c, maxY))
        south_west_east.append((c, minY))
        c += REF_DISTANCE

    north_west_east.append((maxX, maxY))
    south_west_east.append((maxX, minY))

    # Get West North to South
    west_north_to_south = [(minX, maxY)]
    # Get East North to South
    east_north_to_south = [(maxX, maxY)]
    c = maxY
    while c > minY:
        west_north_to_south.append((minX, c))
        east_north_to_south.append((maxX, c))
        c -= REF_DISTANCE

    west_north_to_south.append((minX, minY))
    east_north_to_south.append((maxX, minY))

    south_west_east.reverse()
    west_north_to_south.reverse()

    # Export Ref Points to a file only to see the result
    REF_GEOM = north_west_east + east_north_to_south + \
        south_west_east + west_north_to_south
    line_array = [{'FID': 0, "GEOM": REF_GEOM}]

    REF_POINTS = os.path.join(os.path.dirname(output), 'extent.shp')
    geomArray_to_fc(line_array, REF_POINTS, "POLYLINE", epsg, overwrite=True)

    # Calculate time-distance between origins Lyr and reference points
    # Get Geom of originsLyr
    # Convert to WGS84
    if epsg != 4326:
        originsWGS = project(
            originsLyr,
            os.path.join(os.path.dirname(output), 'origins_wgs84.shp'), 4326)
    else:
        originsWGS = originsLyr

    origLyr = feat_lyr(originsWGS)
    origPoint = []
    for line in arcpy.SearchCursor(origLyr):
        pnt = line.Shape.centroid

        origPoint.append((pnt.X, pnt.Y))

    # Get WGS REF POINTS
    if epsg != 4326:
        refWGS = project(
            REF_POINTS, os.path.join(os.path.dirname(output),
                                     'extent_wgs.shp'), 4326)
    else:
        refWGS = REF_POINTS

    refPointsLyr = feat_lyr(refWGS)
    refPoints = []
    for line in arcpy.SearchCursor(refPointsLyr):
        geom = line.getValue("Shape")

        for vector in geom:
            for pnt in vector:
                pnt_str = str(pnt).split(' ')
                refPoints.append((pnt_str[0], pnt_str[1]))

    # From that distances, get time intervals
    max_distance = get_max_dist(origPoint, refPoints)
    INTERVAL_RANGE = int(round(max_distance / NR_INTERVALS, 0))

    c = 0
    INTERVALS = []
    for i in range(NR_INTERVALS):
        INTERVALS.append(c + INTERVAL_RANGE)
        c += INTERVAL_RANGE

    # Run Service Area Tool
    service_area_polygon(networkDataset, rdvName, INTERVALS, originsLyr,
                         output)

    return output
Ejemplo n.º 18
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")
Ejemplo n.º 19
0
def population_within_point_buffer(netDataset,
                                   rdvName,
                                   pointShp,
                                   populationShp,
                                   popField,
                                   bufferDist,
                                   epsg,
                                   output,
                                   workspace=None,
                                   bufferIsTimeMinutes=None,
                                   useOneway=None):
    """
    Assign to points the population within a certain distance (metric or time)
    
    * Creates a Service Area Polygon for each point in pointShp;
    * Intersect the Service Area Polygons with the populationShp;
    * Count the number of persons within each Service Area Polygon
    (this number will be weighted by the area % of the statistic unit
    intersected with the Service Area Polygon).
    """

    import arcpy
    import os
    from geopandas import GeoDataFrame
    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.anls.ovlay import intersect
    from gasp.mng.gen import copy_feat
    from gasp.cpu.arcg.mng.fld import add_geom_attr
    from gasp.cpu.arcg.mng.fld import add_field
    from gasp.cpu.arcg.mng.fld import calc_fld
    from gasp.mng.genze import dissolve
    from gasp.mob.arctbx.svarea import service_area_use_meters
    from gasp.mob.arctbx.svarea import service_area_polygon
    from gasp.fm import tbl_to_obj
    from gasp.to.shp import df_to_shp

    workspace = os.path.dirname(pointShp) if not workspace else workspace

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

    # Copy population layer
    populationShp = copy_feat(
        populationShp,
        os.path.join(workspace,
                     'cop_{}'.format(os.path.basename(populationShp))),
        gisApi='arcpy')

    # Create layer
    pntLyr = feat_lyr(pointShp)
    popLyr = feat_lyr(populationShp)

    # Create Service Area
    if not bufferIsTimeMinutes:
        servArea = service_area_use_meters(
            netDataset,
            rdvName,
            bufferDist,
            pointShp,
            os.path.join(workspace,
                         'servare_{}'.format(os.path.basename(pointShp))),
            OVERLAP=False,
            ONEWAY=useOneway)

    else:
        servArea = service_area_polygon(
            netDataset,
            rdvName,
            bufferDist,
            pointShp,
            os.path.join(workspace,
                         "servare_{}".format(os.path.basename(pointShp))),
            ONEWAY_RESTRICTION=useOneway,
            OVERLAP=None)

    servAreaLyr = feat_lyr(servArea)

    # Add Column with Polygons area to Feature Class population
    add_geom_attr(popLyr, "total", geom_attr="AREA")

    # Intersect buffer and Population Feature Class
    intSrc = intersect([servAreaLyr, popLyr],
                       os.path.join(workspace, "int_servarea_pop.shp"))

    intLyr = feat_lyr(intSrc)

    # Get area of intersected statistical unities with population
    add_geom_attr(intLyr, "partarea", geom_attr="AREA")

    # Get population weighted by area intersected
    calc_fld(intLyr, "population",
             "((([partarea] * 100) / [total]) * [{}]) / 100".format(popField),
             {
                 "TYPE": "DOUBLE",
                 "LENGTH": "10",
                 "PRECISION": "3"
             })

    # Dissolve service area by Facility ID
    diss = dissolve(intLyr,
                    os.path.join(workspace, 'diss_servpop.shp'),
                    "FacilityID",
                    statistics="population SUM")

    # Get original Point FID from FacilityID
    calc_fld(diss, "pnt_fid", "[FacilityID] - 1", {
        "TYPE": "INTEGER",
        "LENGTH": "5",
        "PRECISION": None
    })

    dfPnt = tbl_to_obj(pointShp)
    dfDiss = tbl_to_obj(diss)

    dfDiss.rename(columns={"SUM_popula": "n_pessoas"}, inplace=True)

    resultDf = dfPnt.merge(dfDiss,
                           how='inner',
                           left_index=True,
                           right_on="pnt_fid")

    resultDf.drop('geometry_y', axis=1, inplace=True)

    resultDf = GeoDataFrame(resultDf,
                            crs={'init': 'epsg:{}'.format(epsg)},
                            geometry='geometry_x')

    df_to_shp(resultDf, output)

    return output
Ejemplo n.º 20
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
Ejemplo n.º 21
0
def closest_facility(network,
                     rdv_name,
                     facilities,
                     incidents,
                     table,
                     oneway_restriction=False):
    """
    Execute the Closest Facility tool - Produce Closest Facility Layer
    
    * facilities = destiny points
    * incidents = start/origins points
    """

    from gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.mng import table_to_table
    """if arcpy.CheckExtension("Network") == "Available":
        arcpy.CheckOutExtension("Network")
    
    else:
        raise ValueError('Network analyst extension is not avaiable')"""

    if oneway_restriction:
        oneway = "Oneway"
    else:
        oneway = ""

    nName = str(os.path.basename(network))
    junc = nName + '_Junctions'

    arcpy.MakeClosestFacilityLayer_na(
        in_network_dataset=network,
        out_network_analysis_layer="cls_fac",
        impedance_attribute="Minutes",
        travel_from_to="TRAVEL_TO",
        default_cutoff="",
        default_number_facilities_to_find="1",
        accumulate_attribute_name="",
        UTurn_policy="NO_UTURNS",
        restriction_attribute_name=oneway,
        hierarchy="NO_HIERARCHY",
        hierarchy_settings="",
        output_path_shape="TRUE_LINES_WITH_MEASURES",
        time_of_day="",
        time_of_day_usage="NOT_USED")

    lyr_fa = feat_lyr(facilities)
    arcpy.AddLocations_na(
        "cls_fac", "Facilities", lyr_fa, "", "5000 Meters", "",
        "{_rdv} SHAPE;{j} NONE".format(_rdv=str(rdv_name), j=str(junc)),
        "MATCH_TO_CLOSEST", "APPEND", "NO_SNAP", "5 Meters", "INCLUDE",
        "{_rdv} #;{j} #".format(_rdv=str(rdv_name), j=str(junc)))

    lyr_in = feat_lyr(incidents)
    arcpy.AddLocations_na(
        "cls_fac", "Incidents", lyr_in, "", "5000 Meters", "",
        "{_rdv} SHAPE;{j} NONE".format(_rdv=str(rdv_name), j=str(junc)),
        "MATCH_TO_CLOSEST", "APPEND", "NO_SNAP", "5 Meters", "INCLUDE",
        "{_rdv} #;{j} #".format(_rdv=str(rdv_name), j=str(junc)))

    arcpy.Solve_na("cls_fac", "SKIP", "TERMINATE", "")

    table_to_table("cls_fac\\Routes", table)
Ejemplo n.º 22
0
def project(inShp, outShp, outEPSG, inEPSG=None, gisApi='ogr', sql=None):
    """
    Project Geodata using GIS
    
    API's Available:
    * arcpy
    * ogr
    * ogr2ogr;
    * pandas
    """
    import os
    
    if gisApi == 'arcpy':
        """
        Execute Data Management > Data Transformations > Projection
        """
        
        import arcpy
        from gasp.cpu.arcg.lyr import feat_lyr
        from gasp.web.srorg    import get_wkt_esri
        
        layer   = feat_lyr(inShp)
        srs_obj = get_wkt_esri(outEPSG)
        
        arcpy.Project_management(layer, outShp, srs_obj)
    
    elif gisApi == 'ogr':
        """
        Using ogr Python API
        """
        
        if not inEPSG:
            raise ValueError(
                'To use ogr API, you should specify the EPSG Code of the'
                ' input data using inEPSG parameter'
            )
        
        from osgeo          import ogr
        from gasp.prop.feat import get_geom_type
        from gasp.prop.ff   import drv_name
        from gasp.mng.fld   import ogr_copy_fields
        from gasp.prop.prj  import get_sref_from_epsg
        from gasp.oss       import get_filename
        
        def copyShp(out, outDefn, lyr_in, trans):
            for f in lyr_in:
                g = f.GetGeometryRef()
                g.Transform(trans)
                new = ogr.Feature(outDefn)
                new.SetGeometry(g)
                for i in range(0, outDefn.GetFieldCount()):
                    new.SetField(outDefn.GetFieldDefn(i).GetNameRef(), f.GetField(i))
                out.CreateFeature(new)
                new.Destroy()
                f.Destroy()
        
        # ####### #
        # Project #
        # ####### #
        transP = get_trans_param(inEPSG, outEPSG)
        
        inData = ogr.GetDriverByName(
            drv_name(inShp)).Open(inShp, 0)
        
        inLyr = inData.GetLayer()
        out = ogr.GetDriverByName(
            drv_name(outShp)).CreateDataSource(outShp)
        
        outlyr = out.CreateLayer(
            get_filename(outShp), get_sref_from_epsg(outEPSG),
            geom_type=get_geom_type(
                inShp, name=None, py_cls=True, gisApi='ogr'
            )
        )
        
        # Copy fields to the output
        ogr_copy_fields(inLyr, outlyr)
        # Copy/transform features from the input to the output
        outlyrDefn = outlyr.GetLayerDefn()
        copyShp(outlyr, outlyrDefn, inLyr, transP)
        
        inData.Destroy()
        out.Destroy()
    
    elif gisApi == 'ogr2ogr':
        """
        Transform SRS of any OGR Compilant Data. Save the transformed data
        in a new file
    
        TODO: DB - only works with sqlite
        """
        
        if not inEPSG:
            raise ValueError('To use ogr2ogr, you must specify inEPSG')
        
        from gasp         import exec_cmd
        from gasp.prop.ff import drv_name
        
        cmd = (
            'ogr2ogr -f "{}" {} {}{} -s_srs EPSG:{} -t_srs:{}'
        ).format(
            drv_name(outShp), outShp, inShp,
            '' if not sql else ' -dialect sqlite -sql "{}"'.format(sql),
            str(inEpsg), str(outEpsg)
        )
        
        outcmd = exec_cmd(cmd)
    
    elif gisApi == 'pandas':
        # Test if input Shp is GeoDataframe
        from geopandas import GeoDataFrame as gdf
        
        if type(inShp) == gdf:
            # Is DataFrame
            df = inShp
        
        else:
            # Assuming is file
            if os.path.exists(inShp):
                # Is File 
                from gasp.fm import tbl_to_obj
                
                df = tbl_to_obj(inShp)
            else:
                raise ValueError((
                    "For pandas API, inShp must be file or GeoDataFrame"
                ))
        
        # Project df
        newDf = df.to_crs({'init' : 'epsg:{}'.format(str(outEPSG))})
        
        if outShp:
            # Try to save as file
            from gasp.to.shp import df_to_shp
            
            return df_to_shp(df, outShp)
        
        else:
            return newDf
    
    else:
        raise ValueError('Sorry, API {} is not available'.format(gisApi))
    
    return outShp
Ejemplo n.º 23
0
Archivo: prox.py Proyecto: 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)
Ejemplo n.º 24
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 gasp.cpu.arcg.lyr import feat_lyr
    from gasp.cpu.arcg.lyr import rst_lyr
    from gasp.cpu.arcg.anls.exct import select_by_attr
    from gasp.cpu.arcg.mng.fld import type_fields
    from gasp.oss.ops import create_folder
    from gasp.oss import list_files

    # ########### #
    # 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 = list_files(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)
Ejemplo n.º 25
0
Archivo: feat.py Proyecto: 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
Ejemplo n.º 26
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')
Ejemplo n.º 27
0
def dem_from_tin(
    countors, elevation_field, boundary_tin, boundary_mdt,
    cellsize, w, output, hidrology=None, __hillshade=None,
    snapRst=None, prj=None):
    """
    Create a Digital Elevation Model based on a TIN
    """
    
    import os
    from gasp.oss                   import get_filename, get_fileformat
    from gasp.cpu.arcg.lyr          import feat_lyr
    from gasp.to.rst.arcg           import tin_to_raster
    from gasp.cpu.arcg.mng.rst.proc import clip_raster
    
    # Check Extension
    arcpy.CheckOutExtension("3D")
    # Configure workspace
    arcpy.env.overwriteOutput = True
    arcpy.env.workspace = w
    
    prj = os.path.splitext(countors)[0] + '.prj' if not prj else prj
    
    if type(prj) == int:
        from gasp.web.srorg import get_prj_web
    
        prj = get_prj_web(prj, os.path.join(
            w, 'prj_{}.prj'.format(str(prj))
        ))
    
    else:
        if not os.path.exists(prj):
            prj = os.path.splitext(boundary_mdt)[0] + '.prj'
            if not os.path.exists(prj):
                proj = os.path.splitext(boundary_tin)[0] + '.prj'
                if not os.path.exists(prj):
                    raise ValueError('On of the inputs must have a prj file')
    
    
    
    # Create TIN
    tin = create_TINdem(countors, elevation_field, boundary_tin, prj,
                       'tin_tmp', hidrology)
    # TIN2Raster
    rst_tin = tin_to_raster(
        tin, cellsize,
        '{}_extra{}'.format(
            get_filename(output), get_fileformat(output)
        ),
        snapRst=snapRst
    )
    
    # Clip Raster
    lmt_clip = feat_lyr(boundary_mdt)
    dem_clip = clip_raster(rst_tin, lmt_clip, output, snap=snapRst)
    
    # Create Hillshade just for fun
    if __hillshade:
        from gasp.cpu.arcg.spanlst.surf import hillshade
        hillshd = hillshade(
            output,
            os.path.join(
                os.path.dirname(output),
                '{}hsd{}'.format(
                    get_filename(output), get_fileformat(output)
                )
            )
        )
Ejemplo n.º 28
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
Ejemplo n.º 29
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
Ejemplo n.º 30
0
def pop_less_dist_x2(net_dataset,
                     rdv_name,
                     locations,
                     interval,
                     unities,
                     fld_groups,
                     fld_pop,
                     w,
                     output,
                     useOneway=None):
    """
    Network processing - executar service area de modo a conhecer as areas a
    menos de x minutos de qualquer coisa
    """

    import arcpy
    import numpy
    import os
    import pandas
    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 calc_fld
    from gasp.mob.arctbx.svarea import service_area_polygon
    from gasp.fm import tbl_to_obj
    from gasp.oss import get_filename
    from gasp.to.shp import df_to_shp
    from gasp.cpu.arcg.mng.fld import del_field

    if arcpy.CheckExtension("Network") == "Available":
        arcpy.CheckOutExtension("Network")
    # Procedure #
    # Generate Service Area
    svArea = service_area_polygon(net_dataset,
                                  rdv_name,
                                  interval,
                                  locations,
                                  os.path.join(w, "servarea.shp"),
                                  ONEWAY_RESTRICTION=useOneway)

    # Dissolve Service Area
    svArea = dissolve(svArea,
                      os.path.join(w, 'svarea_diss.shp'),
                      "FID",
                      api="arcpy")

    # Intersect unities with Service Area
    lyr_unities = feat_lyr(unities)
    unities_servarea = intersect([lyr_unities, svArea],
                                 os.path.join(w, "unidades_mx.shp"))

    # In the original Unities SHP, create a col with the population
    # only for the unities intersected with service area
    intersectDf = tbl_to_obj(unities_servarea)

    unities_less_than = intersectDf[fld_pop].unique()
    unities_less_than = pandas.DataFrame(unities_less_than, columns=['cod_'])

    popDf = tbl_to_obj(unities)
    popDf = popDf.merge(unities_less_than,
                        how='outer',
                        left_on=fld_pop,
                        right_on="cod_")
    popDf["less_than"] = popDf.cod_.fillna(value='0')
    popDf["less_than"] = numpy.where(popDf["less_than"] != '0', '1', '0')
    popDf["population"] = numpy.where(popDf["less_than"] == '1',
                                      popDf[fld_pop], 0)
    popDf["original"] = popDf[fld_pop]

    newUnities = df_to_shp(popDf, os.path.join(w, 'unities_pop.shp'))

    # Dissolve and Get result
    result = dissolve(newUnities,
                      output,
                      fld_groups,
                      statistics="original SUM;population SUM",
                      api="arcpy")

    calc_fld(result, "pop_{}".format(interval), "[SUM_popula]", {
        "TYPE": "INTEGER",
        "LENGTH": "10",
        "PRECISION": ""
    })

    calc_fld(result, fld_pop, "[SUM_origin]", {
        "TYPE": "INTEGER",
        "LENGTH": "10",
        "PRECISION": ""
    })

    calc_fld(result, "pop_{}_p".format(interval),
             "([pop_{}] / [{}]) *100".format(interval, fld_pop), {
                 "TYPE": "DOUBLE",
                 "LENGTH": "6",
                 "PRECISION": "2"
             })

    del_field(result, "SUM_popula")
    del_field(result, "SUM_origin")

    return result