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 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 gdl_mean_time_wByPop(unities, unities_groups, population_field, destinations, output, workspace=None, unities_epsg=4326, destinations_epsg=4326): """ Tempo medio ponderado pela populacao residente a infra-estrutura mais proxima # TODO: Migrate to Pandas """ import os from osgeo import ogr from gasp.prop.ff import drv_name from gasp.fm import points_to_list from gasp.mng.feat import feat_to_pnt from gasp.mng.prj import project_geom from gasp.mng.fld import add_fields from gasp.mng.genze import dissolve from gasp.web.glg.direct import get_time_pnt_destinations workspace = workspace if workspace else \ os.path.dirname(output) # Unities to centroid pnt_unities = feat_to_pnt( unities, os.path.join(workspace, 'pnt_' + os.path.basename(unities))) # List destinations lst_destinies = points_to_list(destinations, listVal="dict", inEpsg=destinations_epsg, outEpsg=4326) # Calculate indicator polyUnit = ogr.GetDriverByName(drv_name(unities)).Open(unities, 1) polyLyr = polyUnit.GetLayer() polyLyr = add_fields(polyLyr, {'meantime': ogr.OFTReal}) pntUnit = ogr.GetDriverByName(drv_name(pnt_unities)).Open(pnt_unities, 0) pntLyr = pntUnit.GetLayer() polyFeat = polyLyr.GetNextFeature() distUnities = {} groups = {} for pntFeat in pntLyr: geom = pntFeat.GetGeometryRef() if unities_epsg == 4326: originGeom = geom else: originGeom = project_geom(geom, unities_epsg, 4326, api='ogr') _id, duration, distance = get_time_pnt_destinations( originGeom, lst_destinies) __min = duration['value'] / 60.0 pop = polyFeat.GetField(population_field) group = polyFeat.GetField(unities_groups) distUnities[polyFeat.GetFID()] = (__min, __min * pop) if group not in groups: groups[group] = __min * pop else: groups[group] += __min * pop polyFeat = polyLyr.GetNextFeature() del polyLyr polyUnit.Destroy() polyUnit = ogr.GetDriverByName(drv_name(unities)).Open(unities, 1) polyLyr = polyUnit.GetLayer() for feat in polyLyr: unitId = feat.GetFID() groupId = feat.GetField(unities_groups) indicator = (distUnities[unitId][1] / groups[groupId]) * distUnities[unitId][0] feat.SetField('meantime', indicator) polyLyr.SetFeature(feat) del polyLyr, pntLyr polyUnit.Destroy() pntUnit.Destroy() dissolve(unities, output, unities_groups, statistics={'meantime': 'SUM'}, api='ogr')
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')