Usando las Nuevas Funciones de FeatureSetBy en Arcade para Acceder a otras Capas y Tablas

Document created by xander_bakker on Dec 18, 2018
Version 1Show Document
  • View in full screen mode

En el documento Mejoras en Arcade en ArcGIS Online con la Actualización de 5 de diciembre del 2018 ya mencioné las nuevas funciones de Arcade. En este documento indagamos más para explorar las posibilidades que brinden estas funciones.

 

Objetivo

Considere que contamos con un mapa con 3 capas y una tabla:

 

  • Hidrantes es una capa de puntos con los hidrantes
  • Sub Sector es una capa de polígonos con los subsectores en el área de interés
  • Sector Hidraulico es una capa uniendo los subsectores a un nivel mayor generando los sectores hidráulicos
  • Hist Mantenimiento es una tabla con la historia de todos los mantenimientos efectuados en cada hidrante

 

En este ejercicio queremos hacer lo siguiente:

  1. Desde los hidrantes por medio del código del hidrante se quiere mostrar un listado de los mantenimientos almacenados en la historia de mantenimiento.
  2. En los Subsectores la idea es mostrar la cantidad de hidrantes y la media de la edad de los hidrantes en el subsector mediante una operación espacial.
  3. Para cada Sector Hidráulico presentar un listado de los subsectores en el sector hidráulico mediante una operación espacial.

 

Simbolizar los hidrantes por su edad

Primero que todo, aplicamos una expresión de Arcade para visualizar los hidrantes con base en su edad. Contamos con la fecha de instalación en el campo FECHAINSTALACION y podemos usar la función DateDiff y Now para determinar la edad en años. En la expresión abajo esto se está calculando en las primeras 2 lineas de código. Luego clasificamos el valor en rangos:

 

var fecha_inst = $feature.FECHAINSTALACION;
var edad = DateDiff(Now(), fecha_inst, "years");
var clase_edad = "";
if (edad > 50) {
    clase_edad = "Mayor a 50 años";
} else if (edad > 40) {
    clase_edad = "Entre 40 y 50 años";
} else if (edad > 30) {
    clase_edad = "Entre 30 y 40 años";
} else if (edad > 20) {
    clase_edad = "Entre 20 y 30 años";
} else if (edad > 10) {
    clase_edad = "Entre 10 y 20 años";
} else if (edad > 5) {
    clase_edad = "Entre 5 y 10 años";
} else {
    clase_edad = "Menor a 5 años";
}

return clase_edad;

 

El resultado es un texto a lo cual podemos asignar un símbolo representativo (en este caso hacemos uso de los símbolos Firefly):

Mantenemos unos símbolos sencillos para las dos capas de polígonos para evitar distraer la atención de los hidrantes. Además, usamos el mapa base “Lona gris oscuro” para destacar los símbolos de los hidrantes.

 

 

Paso 1: Historia de mantenimiento por hidrante

Para el primer paso podemos configurar la siguiente expresión de Arcade:

var tbl = FeatureSetByName($datastore,"Hist_Mantenimiento");
var codigo = $feature["COD_HIDRANTE"];
var sql = "COD_HIDRANTE = '" + codigo + "'";
Console(sql);
var mantenimientos = Filter(tbl, sql);
var cnt = Count(mantenimientos);
var historia = "";
if (cnt > 0) {
    historia = cnt + " Mantenimiento(s):";
    for (var mantenimiento in mantenimientos) {
        var txt_fecha = Text(mantenimiento.Fecha_Mantenimiento, ' - (Y/MM/DD) ');
        var txt_man = txt_fecha + mantenimiento.Mantenimiento;
        historia += TextFormatting.NewLine + txt_man;
    }
} else {
    historia = "No hay mantenimientos";
}

return historia;

 

Explicación de la expresión:

  • En la primera línea, usando la nueva función FeatureSetByName accedemos a la tabla con la historia por su nombre “Hist_Mantenimiento” en el datastore.
  • En la segunda línea leemos el código del hidrante actual
  • En la tercera línea creamos una consulta SQL
  • En la quinta línea filtramos la tabla de mantenimientos usando la consulta SQL para quedarnos con los registros de mantenimiento del hidrante actual
  • En las siguientes líneas recorremos por los registros de mantenimiento del hidrante y generamos un texto con cada fecha y tipo de mantenimiento
  • Al final devolvemos este listado

 

El resultado presentamos en una ventana emergente donde hacemos uso de una “visualización de atributos personalizado”:

 

Al usuario final se ve así:

 

Paso 2: Resumen de la edad media por subsector

Para el segundo paso queremos desde el subsector encontrar las hidrantes que están ubicados dentro el subsector y determinar su edad media. Este dato nos puede ayudar a enfocar el esfuerzo de nuestras cuadrillas a las zonas que más lo necesiten.

 

En la ventana emergente de los subsectores configuramos la siguiente expresión de Arcade:

var fs = FeatureSetByName($datastore,"Hidrantes");
var hidrantes = Intersects(fs, $feature);
var cnt = Count(hidrantes);

var edad_tot = 0;
for (var hidrante in hidrantes) {
    var edad = DateDiff(Now(), hidrante.FECHAINSTALACION, "years");
    edad_tot += edad;
}

var resultado = "";
if (cnt > 0) {
    var edad_media = edad_tot / cnt;
    resultado = "Hay " + cnt + " hidrantes en el sub sector";
    resultado += TextFormatting.NewLine + "La edad media de los hidrantes es de " + Round(edad_media, 2) + " años";
} else {
    resultado = "No hay hidrantes en el sub sector";
}

return resultado;

 

Explicación de la expresión:

  • En la línea 1 se accede a la capa de hidrantes usando la nueva función FeatureSetByName
  • En la segunda línea hacemos un “Intersects” para quedarnos con los hidrantes que están dentro del subsector actual.
  • En la tercera línea determinamos la cantidad de hidrantes en el subsector usando el “Count”
  • Luego recorremos por los hidrantes y calculamos la edad de cada uno y la edad media de todos los hidrantes en el subsector
  • Al final se genere el texto con el resultado y esto se devuelve

 

El resultado se veré así:

 

En este ejemplo tenemos 93 hidrantes en el subsector y la edad media es de 20,64 años.

 

Paso 3: Listado de subsectores por sector hidráulico

Cada sector hidráulico está compuesto por varios subsectores. En este paso queremos presentar un listado de nombres de subsectores por sector hidráulico. Para este fin intentamos con la siguiente expresión de Arcade:

var fs = FeatureSetByName($datastore,"Sub Sector");
var subsectores = Intersects(fs, $feature);
var cnt = Count(subsectores);

var resultado = "Listado de los " + cnt + " Subsectores:";
for (var subsector in subsectores) {
    resultado += TextFormatting.NewLine + subsector.IDSAP;
}

return resultado;

 

Eso debería devolver el listado de nombres, de los subsectores en el sector hidráulico. Sin embargo, el resultado contiene también subsectores que bordean el sector hidráulico. Aparentemente, la función Intersects devuelve los elementos que comparten el límite.

 

Para evitar esto, podemos aplicar un buffer negativo pequeño al polígono del sector hidráulico con el fin de solamente obtener los subsectores que están dentro del sector hidráulico (ver líneas 2 donde se aplique el buffer y la línea 3 donde se use el resultado):

var fs = FeatureSetByName($datastore,"Sub Sector");
var feature_buf = Buffer($feature, -100, 'meters');
var subsectores = Intersects(fs, feature_buf);
var cnt = Count(subsectores);

var resultado = "Listado de los " + cnt + " Subsectores:";
for (var subsector in subsectores) {
    resultado += TextFormatting.NewLine + subsector.IDSAP;
}

return resultado;

 

El resultado en la ventana emergente es así:

 

El listado no está ordenado y se ve mejor si podemos presentar la información ordenada. Esto se puede lograr con la función “OrderBy” (ver línea 3):

var fs = FeatureSetByName($datastore,"Sub Sector");
var feature_buf = Buffer($feature, -100, 'meters');
var subsectores = OrderBy(Intersects(fs, feature_buf), 'IDSAP ASC');
var cnt = Count(subsectores);

var resultado = "Listado de los " + cnt + " Subsectores:";
for (var subsector in subsectores) {
    resultado += TextFormatting.NewLine + subsector.IDSAP;
}

return resultado;

 

La ventana emergente ahora si muestre el listado ordenado:

 

Espero que este ejemplo les ayuda a entender lo que se puede hacer con las nuevas expresiones de Arcade.

 

OJO: Siempre es necesario validar el rendimiento del resultado de las expresiones. Es importante que la complejidad sea razonable con el fin de lograr un rendimiento aceptable para el usuario final.

1 person found this helpful

Attachments

    Outcomes