Una API de Normalización y Geolocalización

Hagamos un breve ejercicio: con un lápiz y papel escribamos todas las variantes de, por ejemplo, una provincia de nuestra elección. Esta es mi lista:

  • Buenos Aires
  • Prov. de Bs. As.
  • PBA
  • Bs. As.
  • B. Aires

Para el ojo humano todas las variantes hacen referencia a la Provincia de Buenos Aires. Sin embargo, para los sistemas informáticos, son todas provincias diferentes. La falta de normalización de los nombres de calles, localidades, departamentos y provincias produce un serio problema.

Esto genera un nuevo desafío: ¿cómo hacemos para que nuestro sistema informático las reconozcan como una misma? Para solucionar este problema, la Dirección Nacional de Datos Abiertos creó una herramienta que permite normalizar y codificar los nombres de unidades territoriales de la Argentina (provincias, departamentos, municipios y localidades) y geolocalizar direcciones.

El Servicio de Normalización de Datos Geográficos es una API REST. Una API es una interfaz de programación de aplicaciones1, un conjunto de rutinas que provee acceso a funciones de un determinado software. Por ejemplo, cuando buscamos una dirección en el mapa de nuestros celulares, por detrás se está realizando una consulta a una API.

Supongamos que queremos consultar los departamentos de la provincia de Córdoba. A través de una consulta web, la API de GeoRef nos devuelve determinada información. Veamos, por ejemplo, la siguiente consulta.

https://apis.datos.gob.ar/georef/api/departamentos?formato=csv&provincia=cordoba&max=10

El resultado es el siguiente:

¿Qué significa cada uno de los términos que estamos utilizando? Es necesario hacer la siguiente aclaración: los parámetros empiezan después del ? y se separan por &. Entonces, ¿qué estamos consultando?

  • https://apis.datos.gob.ar/georef/api/: dirección básica
  • departamentos: unidad geográfica que nos interesa
  • ?formato=csv: formato en qué queremos que nos brinde los dato
  • &provincia=cordoba: provincia de la que estamos interesados consultar
  • &max=10: cantidad máxima de registro que nos interesa (esto se puede cambiar)

¿Te estás preguntando cómo funciona la API? Recibe un texto y lo divide según nombre y número. Luego compara el texto con el listado de textos que están en la base de datos y busca mejor aproximación2

El Servicio de Normalización de Datos Geográficos, o la API de GeoRef, tiene varios servicios. Nosotros vamos a revisar los siguientes: normalizar nombres de unidades territoriales y normalizar direcciones. Te invito a revisar la documentación sobre la API para conocer más en detalle todas las opciones y variantes.

GeoRef en R

Para trabajar con la API de GeoRef, vamos a utilizar el paquete georefar3, desarrollado por Patricio Del Boca. Dado que este paquete no se encuentra disponible en CRAN, para instalarlo hay que utlizar un paquete intermedio llamado devtools4.

# Instalacion del paquete "georefar"
# install.packages("devtools")
# devtools::install_github("pdelboca/georefar")

# Cargamos el paqute "georefar"
library(georefar)
library(tidyverse)

georefar hace que las consultas a la API sean más sencillas. Por ejemplo, utilizando la función get_departamentos(), obtendremos la misma información que anteriormente:

get_departamentos(provincia = "cordoba",
                  max = 10) %>% 
  knitr::kable()
centroide_lat centroide_lon id nombre provincia_id provincia_nombre
-31.71120 -64.30706 14147 Santa María 14 Córdoba
-31.70779 -65.15641 14126 San Alberto 14 Córdoba
-31.73303 -63.47692 14119 Río Segundo 14 Córdoba
-31.23940 -62.52603 14140 San Justo 14 Córdoba
-32.87845 -62.79143 14182 Unión 14 Córdoba
-32.28771 -63.77925 14161 Tercero Arriba 14 Córdoba
-33.33080 -64.49418 14098 Río Cuarto 14 Córdoba
-34.61707 -64.37876 14035 General Roca 14 Córdoba
-31.41707 -64.18322 14014 Capital 14 Córdoba
-33.32945 -63.60634 14056 Juárez Celman 14 Córdoba

GeoRef para normalizar nombres

Para normalizar nombres de unidades territoriales, vamos a crear un dataset muy sencillo que tendrá únicamente dos columnas: provincia y departamento. En ambas columnas vamos a escribir mal los nombres de forma intencional.

# Armo dos categorias: Provincia y Departamento
provincia <- c("buenos aires", "Buenos Aires", "bsas", "bs as", "PBA", "Provincia de Buenos Aires")
departamento <- c("olavarria", "Olavarria", "olaBariaa", "la plata", "LA PLATA", "La PPlata")

# Armo un dataframe con ambas categorias
PBA <- data.frame(provincia, departamento)

PBA %>% knitr::kable()
provincia departamento
buenos aires olavarria
Buenos Aires Olavarria
bsas olaBariaa
bs as la plata
PBA LA PLATA
Provincia de Buenos Aires La PPlata

Primero arranquemos normalizando los nombres de las provincias. Para eso hacemos un loop que recorra cada una de las observaciones, realice una consulta y nos devuelva el nombre normalizado de la provincia en una columna nueva a la que llamaremos provincia_normalizada.

# Normalizando Provincia
for (i in 1:nrow(PBA)) {
  prov <- PBA$provincia[i]
  provincia.normalizada <- as.character(get_provincias(nombre = prov, max = 1)[4])
  PBA$provincia_normalizada[i] <- provincia.normalizada
}

Hagamos lo mismo con la columna departamento.

# Normalizando Departamento
for (i in 1:nrow(PBA)) {
  dpto <- PBA$departamento[i]
  dpto.normalizada <- as.character(get_departamentos(nombre = dpto, max = 1)[4])
  PBA$departamento_normalizada[i] <- dpto.normalizada
}

Veamos cómo queda finalmente nuestro dataset con nuestras nuevas columnas provincia_normalizada y departamento_normalizada.

PBA %>% knitr::kable()
provincia departamento provincia_normalizada departamento_normalizada
buenos aires olavarria Buenos Aires Olavarría
Buenos Aires Olavarria Buenos Aires Olavarría
bsas olaBariaa Buenos Aires NULL
bs as la plata Buenos Aires La Plata
PBA LA PLATA NULL La Plata
Provincia de Buenos Aires La PPlata NULL La Plata

Como podemos ver, la API no pudo normalizar las últimas dos observaciones de provincia ni olaBariaa debido a que se alejan mucho de la versión que existe en la base de datos de nombres de provincias. Sin embargo, vemos que no tiene ningún problema en discriminar mayúsculas, minúsculas y palabras mal escritas.

GeoRef para normalizar direcciones

La API de GeoRef también se puede utilizar para normalizar direcciones. Por ejemplo, aquí vamos a tratar de normalizar la dirección “Boedo 202, Lomas de Zamora”.

boedo <- normalizar_direccion("BOEDO 00202, LOMAS DE ZAMORA", departamento = "06490")
## No encoding supplied: defaulting to UTF-8.
boedo %>% knitr::kable()
altura_unidad altura_valor calle_categoria calle_cruce_1_categoria calle_cruce_1_id calle_cruce_1_nombre calle_cruce_2_categoria calle_cruce_2_id calle_cruce_2_nombre calle_id calle_nombre departamento_id departamento_nombre localidad_censal_id localidad_censal_nombre nomenclatura piso provincia_id provincia_nombre ubicacion_lat ubicacion_lon
NA 202 CALLE NA NA NA NA NA NA 0649001004335 MARIANO BOEDO 06490 Lomas de Zamora 06490010 Lomas de Zamora MARIANO BOEDO 202, Lomas de Zamora, Buenos Aires NA 06 Buenos Aires -34.75940 -58.40087
NA 202 CALLE NA NA NA NA NA NA 0649001002855 FELIPE BOERO 06490 Lomas de Zamora 06490010 Lomas de Zamora FELIPE BOERO 202, Lomas de Zamora, Buenos Aires NA 06 Buenos Aires -34.75396 -58.42918

En este caso, las mejores aproximaciones son BOEDO y BOERO. Luego, busca el número y asigna el segmento de las cuadras. Si tiene Latitud y Longitud, también lo provee.


  1. La sigla API proviene del inglés Application Programming Interface

  2. Si la palabra tiene 3 o menos caracteres, la API busca la el nombre exacto, si la palabra tiene entre 4 y 7 caracteres, la API permite una transformación y si tiene más de 8, permite 2 transformaciones.

  3. Copyright (c) 2018 Patricio Del Boca

  4. Es probable que tengas que instalarlo en tu computadora

Related