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")
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
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"
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()
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])
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
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
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()
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()
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")
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
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
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')
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)
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