Mapa geológico interactivo con Folium

Python, Mapas, geopandas, folium

En esta ocasión, utilizaremos las librerías Folium y geopandas para la creación de un mapa geológico interactivo a partir de un archivo shapefile. El resultado final se muestra a continuación:

Instalación de las librerías

Folium nos permitirá la creación de mapas livianos e interactivos totalmente compatibles con el navegador. Por otro lado, debido a que Folium no acepta el formato shape (.shp) directamente, será necesario utilizar geopandas para la carga y transformación de nuestro archivo.

Para instalar las librerías es posible utilizar pip:

pip install geopandas folium

O mediante Anaconda:

conda install -c conda-forge geopandas folium

Luego de instaladas se importan las librerías:

import geopandas as gpd import folium

* Se recomienda la creación de un ambiente virtual para la instalación de las librerías. Para mayores detalles sobre los ambientes virtuales visita la documentación oficial de Python.

Carga y transformación de datos

En primer lugar, cargaremos nuestro archivo shape con la ayuda de geopandas.read_file(), este método nos entrega un GeoDataFrame que contiene la geometría y la información tabular asociada al archivo shape.

# Carga de datos shp_geologia = gpd.read_file("data/geologia_tumbes.shp") print(shp_geologia)
unidad_geo geometry
0 Depósitos Fluviales y Litorales MULTIPOLYGON (((-72.99436 -36.73458, -72.99422...
1 Batolito Costero del Sur MULTIPOLYGON (((-72.99405 -36.74629, -72.99269...
2 Formación Cosmito MULTIPOLYGON (((-73.01919 -36.79901, -73.02318...
3 Formación Andalién MULTIPOLYGON (((-73.05011 -36.78331, -73.04993...
4 Plutón Hualpén MULTIPOLYGON (((-73.19121 -36.74677, -73.19089...
5 Formación Quiriquina MULTIPOLYGON (((-72.99422 -36.73964, -72.99405...
6 Serie Occidental MULTIPOLYGON (((-73.16328 -36.80132, -73.17814...

Agregaremos además una nueva columna que tenga los colores de cada unidad geólogica (en este caso, en formato hexadecimal). Para esto necesitaremos un diccionario con los colores correspondientes, teniendo en cuenta que el nombre de la unidad debe coincidir exactamente con el que se define en el shape. Posteriormente, se crea una nueva columna y mediante el método Series.map(), el cual al ser aplicado en una serie reemplaza según una función o diccionario, se agregan los colores correspondientes a cada unidad a la tabla (más información sobre Series.map en la documentación oficial. Estos valores de color serán usados al momento de darle el estilo a nuestros polígonos en Folium.

# Agregar columna con colores al GeoDataFrame colores_unidades = { 'Depósitos Fluviales y Litorales': '#fff2ae', 'Batolito Costero del Sur': '#ef5845', 'Formación Andalién': '#ffff00', 'Formación Cosmito': '#a6611a', 'Formación Quiriquina': '#5cff51', 'Plutón Hualpén': '#d52dff', 'Serie Occidental': '#5d5d5d', } geologia["color_unidad"] = geologia["unidad_geo"].map(colores_unidades) print(geologia)
unidad_geo geometry color
0 Depósitos Fluviales y Litorales MULTIPOLYGON (((-72.99436 -36.73458, -72.99422... #fff2ae
1 Batolito Costero del Sur MULTIPOLYGON (((-72.99405 -36.74629, -72.99269... #ef5845
2 Formación Cosmito MULTIPOLYGON (((-73.01919 -36.79901, -73.02318... #a6611a
3 Formación Andalién MULTIPOLYGON (((-73.05011 -36.78331, -73.04993... #ffff00
4 Plutón Hualpén MULTIPOLYGON (((-73.19121 -36.74677, -73.19089... #d52dff
5 Formación Quiriquina MULTIPOLYGON (((-72.99422 -36.73964, -72.99405... #5cff51
6 Serie Occidental MULTIPOLYGON (((-73.16328 -36.80132, -73.17814... #5d5d5d

Creación del mapa interactivo

El siguiente paso corresponde a crear un objeto de mapa con folium.Map(). Esta clase nos permite durante la creación del objeto ajustar parámetros que determinarán las caracteristicas iniciales de nuestro mapa, en este caso location y zoom_start determinan el punto central del mapa y el nivel de acercamiento, respectivamente.

# Creacion de objeto mapa mapa_geologico = folium.Map(location=[-36.7, -73.1], zoom_start=11)

Posteriormente, se creará un objeto por separado para cada unidad, lo cual nos permitirá asignarle el nombre de la capa y el color del polígono individualmente, además de permitirnos activar y desactivar la capa respectiva en el mapa final. Para esto se crea un nuevo GeoDataFrame para cada unidad (gdf_unidad), lo cual se logra filtrando el GeoDataFrame original según el nombre de cada unidad en particular (obtenido en este caso iterando las claves de nuestro diccionario de colores).

Cada unidad se transforma en un objeto interpretable por folium mediante folium.GeoJson(), el cual acepta nuestra unidad en formato json, además de parámetros como el nombre, y una función de estilo, la que recibe una función que entregue un diccionario con los valores de estilo correspondientes, y donde se establece como color de relleno el valor de la columna de color definida anteriormente. Finalmente se agrega este objeto a nuestro mapa creado anteriormente (mapa_geologico), y se adjunta también un control de capas con folium.LayerControl que nos permitirá activar y desactivar cada unidad geológica por separado.

for unidad in colores_unidades.keys(): gdf_unidad = geologia.loc[geologia["unidad_geo"] == unidad] folium.GeoJson( gdf_unidad.to_json(), name=unidad, style_function=lambda json: { "fillColor": json["properties"]["color_unidad"], "fillOpacity": 0.85, "color": "grey", "weight": 0.5 }, tooltip=unidad ).add_to(mapa_geologico) folium.LayerControl().add_to(mapa_geologico) mapa_geologico

Finalmente podemos guardar nuestro mapa en formato html para poder compartirlo o integrarlo en alguna página web.

mapa_geologico.save("mapa_geologico.html")