Incluir reportes estadísticas en las ventanas emergentes con Arcade usando GroupBy

Document created by xander_bakker on Oct 19, 2019
Version 1Show Document
  • View in full screen mode

Al inicio de este mes con la actualización de ArcGIS Online (octubre 2019) introdujeron varios funcionalidades en Arcade que podemos aprovechar para incluir información útil en nuestras ventanas emergentes.

 

En el ejemplo abajo se muestra una ventana emergente configurado para sectores operativas donde se muestre un reporte de una capa de tuberías:

  • un recuento de los tubos que se encuentren en el sector
  • un cálculo de la edad promedio de los tubos en el sector
  • un resumen con el recuento y la longitud de tubos por diámetro
  • un resumen con el recuento y la longitud de tubos por material
  • (en caso que tenemos información de profundidad de los tubos se incluye las estadísticas de mínima, máxima y la promedia de la profundidad)

 

 

Primero que todo para poder sacar estos datos debemos contar con los tubos que se encuentren en el sector. Esto podemos hacer con la siguiente linea:

var tuberias = Intersects($feature, FeatureSetByName($map, "Tuberia_P80_updated"));

 

Es importante entender que la precisión del $feature depende de la escala en que se consulta el $feature. La función Intersects devuelve todos los tubos que parcialmente o completamente están dentro el polígono del $feature y por lo tanto el resultado del reporte es solamente una indicación y no un reporte exacta. Para un resultado más exacto sería necesario usar la función Intersection.

 

Cuando tenemos tubos dentro del polígono del sector operativo (lo revisar usando Count), podemos iniciar a construir la información la cual queremos incluir en nuestro ventana emergente.

 

Para la edad promedia debemos revisar si cada registro tiene la fecha de puesta en servicio con el fin de excluir registros sin datos:

    var sum_edad = 0;
    var cnt_edad = 0;
    for (var tubo in tuberias) {
        if (!IsEmpty(tubo.FECHAPUESTASERVICIO)) {
            sum_edad += DateDiff(Now(), tubo.FECHAPUESTASERVICIO, "Year");   
            cnt_edad += 1;
        }
    }
     var avg_edad = sum_edad / cnt_edad;

 

Algo similar hacemos para la profundidad de los tubos:

    var min_prof = 1000;
    var max_prof = 0;
    var sum_prof = 0;
    var cnt_prof = 0;

// en el mismo bucle "for (var tubo in tuberias)"

        if (tubo.PROFUNDIDAD>0) {
            sum_prof += tubo.PROFUNDIDAD
            cnt_prof += 1;
        }
        min_prof = Min([min_prof, tubo.PROFUNDIDAD]);
        max_prof = Max([max_prof, tubo.PROFUNDIDAD]);

// después del bucle
     var avg_prof = sum_prof / cnt_prof;

 

La parte nueva es para la generación del resumen por diámetro y material usando GroupBy:

    var stats_diametro = GroupBy(tuberias, "Diamatro_txt", 
            [{name:"conteo", expression:"Diamatro_txt", statistic:"COUNT"},
             {name:"longitud", expression:"LONGITUDREAL", statistic:"SUM"}]);

 

En este caso generamos estadísticas agrupados por el diámetro, donde estamos interesados en el conteo por diámetro y la longitud de tubos. Luego devolvemos los datos en el formato que queremos usar:

    resultado += TextFormatting.NewLine +"Resumen por DIAMETRO:";
    for (var stat in stats_diametro) {
        resultado += TextFormatting.NewLine + " - " + stat.Diamatro_txt + "  (" + stat.conteo + ")  " + round(stat.longitud, 0) + " m.";
    }   

 

Es importante resaltar cuando se aplique el GroupBy con un campo con un dominio, el proceso devuelve el código y no la descripción. En este ejemplo agregué en la preparación de los datos campos de texto para material y diámetro con la descripción del dominio.

 

La expresión final es así:

var tuberias = Intersects($feature, FeatureSetByName($map, "Tuberia_P80_updated"));

var resultado = "";
var cnt = Count(tuberias);

if (cnt > 0) {
    resultado = "Hay " + cnt + " tuberías P80 en esta zona" + TextFormatting.NewLine;
    Console(resultado);
    var min_prof = 1000;
    var max_prof = 0;
    var sum_prof = 0;
    var sum_edad = 0;
    var cnt_edad = 0;
    var cnt_prof = 0;
    for (var tubo in tuberias) {
        if (!IsEmpty(tubo.FECHAPUESTASERVICIO)) {
            sum_edad += DateDiff(Now(), tubo.FECHAPUESTASERVICIO, "Year");   
            cnt_edad += 1;
        }
        if (tubo.PROFUNDIDAD>0) {
            sum_prof += tubo.PROFUNDIDAD
            cnt_prof += 1;
        }
        min_prof = Min([min_prof, tubo.PROFUNDIDAD]);
        max_prof = Max([max_prof, tubo.PROFUNDIDAD]);
    }
     var avg_prof = sum_prof / cnt_prof;
     var avg_edad = sum_edad / cnt_edad;

    resultado += TextFormatting.NewLine + "Edad promedia: " + Round(avg_edad, 2) + " años" + TextFormatting.NewLine;
    if (cnt_prof>0) {
        resultado += TextFormatting.NewLine + "Profundidad promedia: " + Round(avg_prof, 2) + " m.";
        resultado += TextFormatting.NewLine + "Profundidad mínima: " + Round(min_prof, 2) + " m.";
        resultado += TextFormatting.NewLine + "Profundidad máxima: " + Round(max_prof, 2) + " m.";
    }

    var stats_diametro = GroupBy(tuberias, "Diamatro_txt",
            [{name:"conteo", expression:"Diamatro_txt", statistic:"COUNT"},
             {name:"longitud", expression:"LONGITUDREAL", statistic:"SUM"}]);

    resultado += TextFormatting.NewLine +"Resumen por DIAMETRO:";
    for (var stat in stats_diametro) {
        resultado += TextFormatting.NewLine + " - " + stat.Diamatro_txt + "  (" + stat.conteo + ")  " + round(stat.longitud, 0) + " m.";
    }   
   
    var stats_material = GroupBy(tuberias, "Material_txt",
            [{name:"conteo", expression:"Material_txt", statistic:"COUNT"},
             {name:"longitud", expression:"LONGITUDREAL", statistic:"SUM"}]);

    resultado += TextFormatting.NewLine + TextFormatting.NewLine + "Resumen por material:";
    for (var stat in stats_material) {
        resultado += TextFormatting.NewLine + " - " + stat.Material_txt + "  (" + stat.conteo + ")  " + round(stat.longitud, 0) + " m.";
    }

} else {
    resultado = "No hay tuberías P80 en esta zona";
}

return resultado;

Attachments

    Outcomes