'''
Autor: Ing. Winston De Oleo
Fecha: 20/04/2025
Descripción:
Este script automatiza un flujo completo de análisis espacial para identificar barrios sin cobertura
hospitalaria en un área determinada.
A través de un proceso de buffering, spatial join y análisis por atributos,
permite determinar qué barrios están dentro de un radio de influencia de hospitales y cuáles no.
'''

import arcpy
import os


#Realizar un intersect de influciencia de hospitales con barrios e identificar los barrios sin influencia hospitalaria
#Funciones

#Variables
workspace_gis = r"C:\Users\winst\OneDrive\Desktop\GIS PRACTICA\Hospital_py"
capa_hospital = r'C:\Users\winst\OneDrive\Desktop\GIS PRACTICA\rd_municipios\Hospitales_Santiago.shp'
capa_barrios = r'C:\Users\winst\OneDrive\Desktop\GIS PRACTICA\rd_municipios\Santiago\parajes.shp'
salidas = [
    r'\hospital_buffer.shp', 
    r'\interset_barrios.shp',
    r'\spatial.shp',
    workspace_gis + r'\reportes\report.txt'
    ]

arcpy.env.workspace = workspace_gis  #Asignando Workspace
arcpy.env.overwriteOutput = True     #Permito sobreescribir

#-----------------------------------------------------------------------------#

def main():

    if os.path.exists(workspace_gis):  #Compruebo si existe el doc.
     print('Carpeta Base encontrada')
    else:
     print("Carpeta Base no encontrada en ruta: " + workspace_gis)
     exit()

    #Aplicar buffer en hospitales
    buffer(capa_hospital,"5000 Meters")
    #Spatial entre buffers y barrios
    spatial(capa_barrios,salidas[0],salidas[2])
    #Identificar los barrios sin hospitales
    identifica(salidas[2],"Join_Count",salidas[3])
    #Extraer la capa de los barrios sin cobertura
    new_shape(salidas[2],'barrios_no_cubiertos.shp')




def buffer(capa,area):
    if arcpy.Exists(capa):
      arcpy.Buffer_analysis(capa_hospital, salidas[0], area)
      print('Buffer Generado')
    else:
     print("Capa No encontrada " + capa_hospital)

def spatial(capa_objetivo,capa2_union,salida):

    if arcpy.Exists(capa_objetivo) and arcpy.Exists(capa2_union):

        arcpy.SpatialJoin_analysis(
        target_features=capa_objetivo,  # Capa objetivo (barrios)
        join_features=capa2_union,     # Capa de unión (buffer de hospitales)
        out_feature_class=salida, # Ruta de salida
        join_operation="JOIN_ONE_TO_ONE",
        join_type="KEEP_ALL",
        match_option="INTERSECT",      # Criterio espacial
        search_radius="5 Meters",   # Tolerancia de búsqueda (opcional)
    #field_mapping="TOPONIMIA"         # Mapeo de atributos (opcional)
    )

        print('Spatial Join Generado')

    else:
        print("Capa No encontrada " + capa_barrios)

def identifica(capa,columna,salida):
    
    with arcpy.da.SearchCursor(capa, columna) as cursor:
        barrios_interceptados =0
        barrios_no_interceptados =0

        for row in cursor:
            join_count = row[0]
            
            # Verificar si el barrio está interceptado por un buffer
            if join_count > 0:
                barrios_interceptados += 1
            else:
                barrios_no_interceptados += 1

        with open(salida, "w") as f:
         f.write(f"Número de barrios influenciados por hospitales: {barrios_interceptados}\n")
         f.write(f"Número de barrios NO influenciados por hospitales: {barrios_no_interceptados}\n")
         print('Barrios Identificados')

def new_shape(capa_in,capa_out_name):

    # 1. Crear una capa temporal
    arcpy.MakeFeatureLayer_management(salidas[2], "capa_temp")
    print('Capa Temporal creada')

    # 2. Seleccionar barrios con Join_Count = 0
    arcpy.SelectLayerByAttribute_management(
     in_layer_or_view="capa_temp",
     selection_type="NEW_SELECTION",
     where_clause="Join_Count = 0"
    )

    # 3. Guardar los barrios no cubiertos en una nueva capa
    barrios_no_cubiertos = os.path.join(workspace_gis, capa_out_name)
    arcpy.CopyFeatures_management("capa_temp", barrios_no_cubiertos)

    print(f"Barrios no cubiertos guardados en: {barrios_no_cubiertos}")
    print('Análisis Completado con Éxito')


if __name__ == "__main__":
    main()













    



