# Dec 23rd, 2021: \[es\] Aumentando documentos con la política geo\_match

**URL:** <https://discuss.elastic.co/t/dec-23rd-2021-es-aumentando-documentos-con-la-politica-geo-match/292462>\
**Category:** Advent Calendar\
**Created:** [December 23, 2021, 8:00am UTC](https://discuss.elastic.co/t/dec-23rd-2021-es-aumentando-documentos-con-la-politica-geo-match/292462 "2021-12-23T08:00:39Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jsanz](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jsanz/32/53734_2.png) [@jsanz](https://discuss.elastic.co/u/jsanz)\
**Post date:** [December 23, 2021, 8:00am UTC](https://discuss.elastic.co/t/dec-23rd-2021-es-aumentando-documentos-con-la-politica-geo-match/292462/1 "2021-12-23T08:00:39Z")

</div>

> 🗣 This article is also available in [English](https://discuss.elastic.co/t/dec-23rd-2021-en-enriching-documents-with-the-geo-match-policy/289302)

Como tal vez sepas, el 19 de Septiembre de 2021 comenzó la [erupción del Cumbre Vieja](https://en.wikipedia.org/wiki/2021_Cumbre_Vieja_volcanic_eruption) en la isla de La Palma en las Islas Canarias, España. El gobierno de la isla comenzó inmediatamente a publicar levantamientos fotogramétricos con drones de los perímetros de los flujos de lava en su portal de Datos Abiertos ([ejemplo](https://www.opendatalapalma.es/datasets/perimetro-dron-211124/explore)). Mi idea fue entonces cargarlos en el _stack_ de Elastic para tratar de entender la evolución de este desastre natural.

Además de los flujos, existe también un juego de datos en el portal con los [edificios](https://www.opendatalapalma.es/datasets/edificaciones/explore?location=28.657424%2C-17.915888%2C18.57), por lo que vi que era una buena oportunidad para intersectar los flujos de lava con los edificios para ver cómo la erupción estaba afectando a viviendas, fábricas, etc.

> <https://twitter.com/NaqNab/status/1451054675495723011>

## Presentando la política _geo\_match_ para el _enrich processor_

En una _pipeline_ de ingesta se puede utilizar [enrich processor](https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html) para aumentar datos desde un índice de referencia a partir de un campo con contenido común o mediante una relación espacial entre los documentos del índice de refencia y los documentos siendo ingestados. Con la política [_geo\_match_](https://www.elastic.co/guide/en/elasticsearch/reference/current/put-enrich-policy-api.html), a partir de un índice con un campo geométrico, podemos transferir datos de estos documentos de referencia a un documento ingestado a partir de una relación espacial. En general lo que queremos es usar la relación de intersección espacial. Es decir, dado por ejemplo un índice de refencia con los límites de países, podemos transferir el nombre del país a cualquier documento con una geometría que esté dentro de dichos límites. Puedes aprender más sobre esta política en [este ejemplo](https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-match-enrich-policy-type.html) de la documentación de Elasticsearch y en un tutorial más largo sobre cómo usar esta pólitica para hacer geocodificación inversa en esta [entrada de blog](https://www.elastic.co/blog/how-to-map-custom-boundaries-in-kibana-with-reverse-geocoding).

En este caso que nos ocupa el índice de referencia serán los **flujos de lava** y los documentos aumentados serán los **edificios**.

## Preparando los perímetros de los flujos de lava

El primer asunto a atender es la carga del índice de referencia que se usará en la política `geo_match`. Conforme la erupción ha ido avanzando, el área de los perímetros de lava lo ha ido haciendo también. Es decir, dada una posición, varios perímetros pueden intersectar con ella, pero nosotros sólo queremos el primer perímetro publicado que afectó a la posición.

Por otro lado la carga de datos necesitaba de automatización para atender algunos problemas de formato y datos. En la [automatización](https://github.com/jsanz/cumbre-vieja/blob/main/src/footprints.py) añadí un paso para calcular la diferencia entre un perímetro y su predecesor, obteniendo algo así como un anillo en un nuevo campo de tipo `geo_shape` llamado `diff_geometry`. De esta forma, para este campo, una localización podría tener como máximo un único perímetro.

 ![drawing](https://us1.discourse-cdn.com/elastic/original/3X/c/a/ca2cc07b39a4a486365f6dfa85d5d17f732223d9.png)

Este es el código que encadena los métodos `difference` y `simplify` de la bibiloteca [shapely](https://shapely.readthedocs.io/en/stable/) para producir la geometría intersectada.

> <https://github.com/jsanz/cumbre-vieja/blob/d9a5eb6e11c739bb6b6236ce0e0186856de22e21/src/footprints.py#L123-L125>

## Cargando los edificios

El _script_ de procesado de datos [carga los edificios](https://github.com/jsanz/cumbre-vieja/blob/d9a5eb6e11c739bb6b6236ce0e0186856de22e21/src/buildings.py#L137-L166) si no se encuentran en el _cluster_. Tras descargar los datos del portal y asegurar que sus geometrías son válidas, el [`bulk` _helper_](https://elasticsearch-py.readthedocs.io/en/v7.15.2/helpers.html#bulk-helpers) del cliente Python de Elasticsearch se encarga de la subida de datos.

## Definiendo la politica de aumento de datos y la _pipeline_ de ingesta

Los perímetros se almacenan en un índice llamado `lapalma`, y queremos transferir a los edificios los campos `id` y `timestamp`, por lo que la política sería:

```auto
PUT /_enrich/policy/lapalma_lookup
{
  "geo_match": {
    "indices": "lapalma",
    "match_field": "diff_geometry",
    "enrich_fields": ["id", "timestamp"],
  }
}

```

El siguiente paso es ejecutar la política:

```auto
POST /_enrich/policy/lapalma_lookup/_execute

```

> ⚠ **¡Importante!** ⚠: Debemos ejecutar este último paso cada vez que haya una actualización en el índice de los perímetros de lava.

Con la política preparada, podemos añadirla a una _pipeline_ de ingesta. Esta _pipeline_ espera un campo de tipo geométrico que intersectará con el definido en la política. La política creará un nuevo campo llamado `footprints` en el que se almacenarán tanto el identificador como la fecha del índice de referencia. La _pipeline_ en un segundo paso borrará la geometría del perímetro, ya que ésta se añade por defecto y no la necesitamos en el documento enriquecido.

```auto
PUT _ingest/pipeline/buildings_footprints
{
  "description": "Enrich buildings with Cumbre Vieja footprints.",
  "processors": [
    {
      "enrich": {
        "field": "geometry",
        "policy_name": "lapalma_lookup",
        "target_field": "footprints",
        "shape_relation": "INTERSECTS",
        "ignore_missing": True,
        "ignore_failure": True,
      }
    },
    {
      "remove": {
        "field": "footprints.diff_geometry",
        "ignore_missing": True,
        "ignore_failure": True,
        "description": "Remove the shape field",
      }
    },
  ],
}

```

## Ejecutando la _pipeline_ de ingesta

Ahora que ya tenemos nuestra _pipeline_ lista, vamos a actualizar el índice de los edicifios utilizando la instrucción [`_update_by_query`](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update-by-query.html). Para optimizar el proceso no vamos a actualizar todos los documentos del índice, sino que vamos a restringir la consulta buscando los documentos que satisfacen dos condiciones:

1. Se encuentran dentro de las coordenadas que afectan a la zona de la erupción
2. No tienen un identificador de perímetro asignado

```auto
POST buildings/_update_by_query?pipeline=buildings_footprints
{
  "query": {
    "bool": {
      "must_not": [{ "exists": { "field": "footprints.id" } }],
      "filter": {
        "geo_bounding_box": {
          "geometry": {
            "top_left": { "lat": 28.647, "lon": -17.95 },
            "bottom_right": { "lat": 28.58, "lon": -17.83 },
          }
        }
      },
    }
  }
}

```

## Todo junto

A lo largo de esta entrada he utilizado la sintaxis de las Kibana _DevTools_ para facilitar su lectura, pero todas estas peticiones se ejecutan desde un [script en python](https://github.com/jsanz/cumbre-vieja/blob/main/src/app.py) dentro de una [Github Action](https://github.com/jsanz/cumbre-vieja/blob/main/.github/workflows/python-app.yml) tras cada cambio en el fichero que contiene los [identificadores de los perímetros](https://github.com/jsanz/cumbre-vieja/blob/main/src/data.py). Por desgracia no hay una forma sencilla de automatizar la publicación de nuevos perímetros, por lo que estos identificadores se tienen que introducir manualmente para a continuación automáticamente disparar todo el proceso de actualización ([commit de ejemplo](https://github.com/jsanz/cumbre-vieja/commit/915d7ebd376d5e56c610b59c9787a2c57f1ee6ca)).

Con los datos cargados en el _cluster_, ya podemos explorarlos con [Elastic Maps](https://ela.st/cumbre-vieja-eruption-map) y con un [cuadro de mandos de Kibana](https://ela.st/cumbre-vieja-eruption).

![05-animation-buildings](https://us1.discourse-cdn.com/elastic/original/3X/b/f/bf83679b36a9ad38ecfc49c61aca560852392ee0.gif)  
_[https://ela.st/cumbre-vieja-eruption-map](https://ela.st/cumbre-vieja-eruption-map)_

 ![06-dashboard](https://us1.discourse-cdn.com/elastic/original/3X/5/3/531fe15c457af21fbb2be4a99b093c7700325889.jpeg)  
_[https://ela.st/cumbre-vieja-eruption](https://ela.st/cumbre-vieja-eruption)_

¡Esto es todo! 👋

* * *

**Actualización** : se ha publicado en el blog de Elastic un artículo con algo más de información sobre el proyecto de seguimiento de este evento y en concreto del uso de Elastic Maps y _time slider_ para visualizar eventos que evolucionan en el tiempo

> **[How Elastic Maps can be used to track the devastating eruption of a volcano,...](https://www.elastic.co/blog/understanding-evolution-volcano-eruption-elastic-maps)**
>
> La Palma, in the Canary Islands (Spain), faced a major natural disaster with the eruption of the Cumbre Vieja volcano. Learn how Elastic Maps and Kibana were used to display and animate the evolution ...

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [January 20, 2022, 8:01am UTC](https://discuss.elastic.co/t/dec-23rd-2021-es-aumentando-documentos-con-la-politica-geo-match/292462/2 "2022-01-20T08:01:10Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
