Ubicaciones de gasolineras Repsol en España

Repsol
gasolinera
servicio público
negocio
Autor/a
Afiliación

Javier Soler Contreras

Universitat de València

Fecha de publicación

30 de marzo de 2025

Input

La información que vamos a analizar incluye la localización de todas las gasolineras Repsol presentes en España. Esta información se ha obtenido de OpenStreetMaps (OSM).

A continuación se presenta otro detalle de interés acerca de OSM:

Descripción

En vez de exportar directamente los datos del sitio web, los extraeremos en R a través de una serie de comandos. Para facilitar proceso, filtraremos los datos de OSM a partir de unas etiquetas. Cada etiqueta representa una temática distinta.

Cargamos las librerías necesarias en R:

install.packages("dbscan", repos = "https://cran.rstudio.com/")
Installing package into 'C:/Users/scorp/AppData/Local/R/win-library/4.4'
(as 'lib' is unspecified)
package 'dbscan' successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\scorp\AppData\Local\Temp\RtmpMrq33d\downloaded_packages
Warning: package 'purrr' was built under R version 4.4.3
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.0.4     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
Linking to GEOS 3.12.2, GDAL 3.9.3, PROJ 9.4.1; sf_use_s2() is TRUE
Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright

Ya podemos empezar

Spain <- mapSpain::esp_get_country()
bbox_spain <- sf::st_bbox(Spain)
Spain <- st_transform(Spain, crs = 4326)

q1 <- bbox_spain %>%
  osmdata::opq(timeout = 2500) %>%
  osmdata::add_osm_feature("name", "Repsol") %>%
  osmdata::add_osm_feature("amenity", "fuel")

repsol <- osmdata_sf(q1)
repsol_sf <- repsol$osm_points
dim(repsol_sf)
[1] 10295   144

Como podemos observar, hemos obtenido un objeto sf con 10321 observaciones y 144 variables.

Ahora procedemos a realizar la representación gráfica.

library(leaflet)

repsol_sf %>%
  leaflet() %>%
  addTiles() %>%
  addPolygons(data = Spain, color = "gray", weight = 1, opacity = 0.5, fillOpacity = 0.1) %>%  # Mapa de España
  addCircles(
    lng = ~st_coordinates(geometry)[, 1],  # Coordenada X (longitud)
    lat = ~st_coordinates(geometry)[, 2],  # Coordenada Y (latitud)
    radius = 6,                           # Tamaño del círculo
    color = "blue",                       # Color del borde
    fillColor = "blue",                   # Color de relleno
    fillOpacity = 0.5,                    # Opacidad del relleno
    stroke = TRUE,                        # Mostrar borde
    weight = 1,                           # Grosor del borde
    popup = ~paste("<b>Repsol</b><br>", "Ubicación: ", name)  # Pop-up con el nombre de la ubicación
  ) %>%
  setView(lng = mean(bbox_spain[c("xmin", "xmax")]), lat = mean(bbox_spain[c("ymin", "ymax")]), zoom = 6)  # Centrado en España

Como podemos observar, tambien nos pone las Repsol que hay en Portugal y eso no lo queremos, por lo que vamos a realizar una serie de procedimientos para conseguir que salgan solo las que están dentro del territorio nacional español.

Tratamiento

Como hemos comentado anteriormente es importante considerar que, con las coordenadas que hemos establecido para España, también aparecen puntos para Portugal. Para solucionar este problema y mantenernos exclusivos con las Repsol de España, estableceremos un objeto llamado “spain_ccaa” con los datos y coordenadas particulares de cada Comunidad Autónoma. Lo realizamos utilizando la librería “MapSpain”.

Después de esto, se realiza una intersección entre la información previa y este nuevo objeto “spain_ccaa” para eliminar aquellas Repsol que no se encuentren en España.

spain_ccaa <- mapSpain::esp_get_ccaa(epsg="4326")

st_crs(spain_ccaa)
Coordinate Reference System:
  User input: EPSG:4326 
  wkt:
GEOGCRS["WGS 84",
    ENSEMBLE["World Geodetic System 1984 ensemble",
        MEMBER["World Geodetic System 1984 (Transit)"],
        MEMBER["World Geodetic System 1984 (G730)"],
        MEMBER["World Geodetic System 1984 (G873)"],
        MEMBER["World Geodetic System 1984 (G1150)"],
        MEMBER["World Geodetic System 1984 (G1674)"],
        MEMBER["World Geodetic System 1984 (G1762)"],
        MEMBER["World Geodetic System 1984 (G2139)"],
        MEMBER["World Geodetic System 1984 (G2296)"],
        ELLIPSOID["WGS 84",6378137,298.257223563,
            LENGTHUNIT["metre",1]],
        ENSEMBLEACCURACY[2.0]],
    PRIMEM["Greenwich",0,
        ANGLEUNIT["degree",0.0174532925199433]],
    CS[ellipsoidal,2],
        AXIS["geodetic latitude (Lat)",north,
            ORDER[1],
            ANGLEUNIT["degree",0.0174532925199433]],
        AXIS["geodetic longitude (Lon)",east,
            ORDER[2],
            ANGLEUNIT["degree",0.0174532925199433]],
    USAGE[
        SCOPE["Horizontal component of 3D system."],
        AREA["World."],
        BBOX[-90,-180,90,180]],
    ID["EPSG",4326]]
st_crs(repsol_sf)
Coordinate Reference System:
  User input: EPSG:4326 
  wkt:
GEOGCRS["WGS 84",
    ENSEMBLE["World Geodetic System 1984 ensemble",
        MEMBER["World Geodetic System 1984 (Transit)"],
        MEMBER["World Geodetic System 1984 (G730)"],
        MEMBER["World Geodetic System 1984 (G873)"],
        MEMBER["World Geodetic System 1984 (G1150)"],
        MEMBER["World Geodetic System 1984 (G1674)"],
        MEMBER["World Geodetic System 1984 (G1762)"],
        ELLIPSOID["WGS 84",6378137,298.257223563,
            LENGTHUNIT["metre",1]],
        ENSEMBLEACCURACY[2.0]],
    PRIMEM["Greenwich",0,
        ANGLEUNIT["degree",0.0174532925199433]],
    CS[ellipsoidal,2],
        AXIS["geodetic latitude (Lat)",north,
            ORDER[1],
            ANGLEUNIT["degree",0.0174532925199433]],
        AXIS["geodetic longitude (Lon)",east,
            ORDER[2],
            ANGLEUNIT["degree",0.0174532925199433]],
    USAGE[
        SCOPE["Horizontal component of 3D system."],
        AREA["World."],
        BBOX[-90,-180,90,180]],
    ID["EPSG",4326]]

Vamos que los dos CRS coinciden por lo que podemos hacer la intersección sin ningún problema.

spain2 <- spain_ccaa %>% group_by(codauto) %>% summarise()
repsoldef <- st_intersection(repsol_sf,spain2)
Warning: attribute variables are assumed to be spatially constant throughout
all geometries
dim(repsoldef)
[1] 9031  145

Una vez ya hemos hecho la intersección ya vemos que se han reducido el número de observaciones.

Antes encontrabamos 10321 y ahora obtenemos 9057.

Por lo que, una vez realizado esto, procedemos a volver a graficar

repsoldef %>%
  leaflet::leaflet() %>%
  leaflet::addTiles() %>%
  leaflet::addCircles()

Parece que ya está todo correcto, pero si investigamos un poco nos daremos cuenta de que en España hay alrededor de 3200 estaciones de servicio Repsol, por lo que, ¿porque nos aparece que hayan más de 9000? ¿como es posible?

Esto podría ser resultado de que hay datos duplicados. Es posible que varios usuarios efectúen modificaciones/exportaciones de datos en la misma zona sin estar al tanto de las aportaciones de los demás, lo que podría derivar en datos duplicados.

También, nos hemos dado cuenta de que en cada gasolinera o cada punto donde hay una gasolinera Repsol hay, en la mayoría de sitios, 4 puntos. Lo que también nos da una pequeña explicación de la duplicación de datos.

Para poder darle solución a este problema, vamos a relizar clusters que unifiquen aquellas observaciones que se encuentren muy juntas.

Vamos a usar un valor épsilon de 0.00025, lo que más o menos equivaldría a unos 30 metros de distancia.

install.packages("dbscan", repos = "https://cran.rstudio.com/")
Installing package into 'C:/Users/scorp/AppData/Local/R/win-library/4.4'
(as 'lib' is unspecified)
package 'dbscan' successfully unpacked and MD5 sums checked

The downloaded binary packages are in
    C:\Users\scorp\AppData\Local\Temp\RtmpMrq33d\downloaded_packages
Warning: package 'dbscan' was built under R version 4.4.3

Adjuntando el paquete: 'dbscan'
The following object is masked from 'package:stats':

    as.dendrogram
coords <- sf::st_coordinates(repsoldef)
cluster <- dbscan(coords, eps = 0.00025, minPts = 1) 

clusters <- cluster$cluster
etiquetas <- as.factor(clusters)
repsoldef$cluster <- etiquetas
datosdef <- repsoldef[!duplicated(repsoldef$cluster), ]

Output

class(datosdef) 
[1] "sf"         "data.frame"
dim(datosdef)
[1] 3218  146

Una vez realizado todo estos procedimientos, nos damos cuenta que el df ha reducido considerablemente su tamaño, observamos que ha pasado de 10321 observaciones al principio del trabajo a 3223 observaciones ahora, lo que tiene mucho más sentido ya que en la página web de Repsol nos dicen que hay más de 3200 gasolineras por España.

Una vez obtenido todo esto, volvemos a graficar para obtener el gráfico definitivo.

datosdef %>%
  leaflet::leaflet() %>%
  leaflet::addTiles() %>%
  leaflet::addCircles()

Ahora, ya no hay datos fuera de los límites de España y además ya no hay presencia de duplicados.

A continuación guardaremos los datos en un fichero tipo “GPKG”.

sf::st_write(datosdef, "repsolspain.gpkg", delete_layer = TRUE)

El/los fichero(s) generados con este procedimiento/técnica/metodología se puede(n) descargar de aquí.



Proyectos de Innovación Educativa Emergente PIEE-2737007 y PIEE-3325394