En este ejercicio en lugar de hacer un “copia-pega” del ejercicio visto en clase quise ir un poco más allá e investigar el uso de google maps en R.
Para eso existe el paquete RgoogleMaps:
library(knitr)
library(rmarkdown)
library(PKI)
## Loading required package: base64enc
library(packrat)
library(ggplot2)
library(ggmap)
## Google's Terms of Service: https://cloud.google.com/maps-platform/terms/.
## Please cite ggmap if you use it! See citation("ggmap") for details.
library(RgoogleMaps)
Así mismo, tenemos que conectatnos a la API de google:
register_google(key = "AIzaSyBh8VFmf7FaA6d8PIADsTi8vVrVGEbE4Xg")
# this sets your google map permanently
register_google(key = "AIzaSyBh8VFmf7FaA6d8PIADsTi8vVrVGEbE4Xg", write = TRUE)
## Replacing old key (AIzaSyBh8VFmf7FaA6d8PIADsTi8vVrVGEbE4Xg) with new key in C:\Users\zapic\OneDrive\Documentos/.Renviron
has_google_key()
## [1] TRUE
google_key()
## [1] "AIzaSyBh8VFmf7FaA6d8PIADsTi8vVrVGEbE4Xg"
has_google_client()
## [1] FALSE
has_google_signature()
## [1] FALSE
scrub_key("key=d_5iD")
## [1] "key=xxx"
scrub_key("key=d_5iD", "[your \\1]")
## [1] "key=[your key]"
scrub_key("signature=d_5iD")
## [1] "signature=xxx"
scrub_key("client=a_5sS&signature=d_5iD")
## [1] "client=xxx&signature=xxx"
Vamos a hacer el ejemplo desde un restaurante. Aquí podemos ver cómo se muestra en el centro del mapa de google sin problema:
#Forma 1
localizacion = "Restaurante"
#Forma 2
localizacion=c(lon=-8.710249 ,lat=42.238533)
restaurante <- get_map(location=localizacion, zoom= 18, source="google",
maptype="roadmap", crop=TRUE)
## Source : https://maps.googleapis.com/maps/api/staticmap?center=42.238533,-8.710249&zoom=18&size=640x640&scale=2&maptype=roadmap&language=en-EN&key=xxx
ggmap(restaurante)
Existen distintas formas de visualización. En Satélite:
restaurante2 = get_map(location=localizacion, zoom= 19,
source="google", maptype="hybrid", crop=TRUE)
## Source : https://maps.googleapis.com/maps/api/staticmap?center=42.238533,-8.710249&zoom=19&size=640x640&scale=2&maptype=hybrid&language=en-EN&key=xxx
ggmap(restaurante2)
o en acuarela. Aquí las vias de mayor afluencia de tráfico coinciden con los colores más rojos:
restaurante3 = get_map(location=localizacion, zoom= 15,
source="stamen", maptype="watercolor", crop=TRUE)
## Source : https://maps.googleapis.com/maps/api/staticmap?center=42.238533,-8.710249&zoom=15&size=640x640&scale=2&maptype=terrain&key=xxx
## Source : http://tile.stamen.com/watercolor/15/15589/12133.jpg
## Source : http://tile.stamen.com/watercolor/15/15590/12133.jpg
## Source : http://tile.stamen.com/watercolor/15/15591/12133.jpg
## Source : http://tile.stamen.com/watercolor/15/15592/12133.jpg
## Source : http://tile.stamen.com/watercolor/15/15589/12134.jpg
## Source : http://tile.stamen.com/watercolor/15/15590/12134.jpg
## Source : http://tile.stamen.com/watercolor/15/15591/12134.jpg
## Source : http://tile.stamen.com/watercolor/15/15592/12134.jpg
## Source : http://tile.stamen.com/watercolor/15/15589/12135.jpg
## Source : http://tile.stamen.com/watercolor/15/15590/12135.jpg
## Source : http://tile.stamen.com/watercolor/15/15591/12135.jpg
## Source : http://tile.stamen.com/watercolor/15/15592/12135.jpg
## Source : http://tile.stamen.com/watercolor/15/15589/12136.jpg
## Source : http://tile.stamen.com/watercolor/15/15590/12136.jpg
## Source : http://tile.stamen.com/watercolor/15/15591/12136.jpg
## Source : http://tile.stamen.com/watercolor/15/15592/12136.jpg
ggmap(restaurante3)
#GEOLOCALIZACION
Usamos las mismas librerías nombradas en clase:
# Librerías
.packages = c("TSP","maps","sp","maptools","geosphere")
library(geosphere)
library(maptools)
## Loading required package: sp
## Checking rgeos availability: TRUE
library(rgdal)
## rgdal: version: 1.4-8, (SVN revision 845)
## Geospatial Data Abstraction Library extensions to R successfully loaded
## Loaded GDAL runtime: GDAL 2.2.3, released 2017/11/20
## Path to GDAL shared files: C:/Users/zapic/OneDrive/Documentos/R/win-library/3.6/rgdal/gdal
## GDAL binary built with GEOS: TRUE
## Loaded PROJ.4 runtime: Rel. 4.9.3, 15 August 2016, [PJ_VERSION: 493]
## Path to PROJ.4 shared files: C:/Users/zapic/OneDrive/Documentos/R/win-library/3.6/rgdal/proj
## Linking to sp version: 1.4-1
library(raster)
##
## Attaching package: 'raster'
## The following object is masked from 'package:packrat':
##
## init
library(maps)
library(mapdata)
library(ggmap)
library(marmap)
## Registered S3 methods overwritten by 'adehabitatMA':
## method from
## print.SpatialPixelsDataFrame sp
## print.SpatialPixels sp
##
## Attaching package: 'marmap'
## The following object is masked from 'package:raster':
##
## as.raster
## The following object is masked from 'package:grDevices':
##
## as.raster
library(lattice)
library(TSP)
Lo que vamos a estudiar es una ruta de reparto desde el restaurante a 6 clientes distintos:
rutas_vigo = read.csv2("rutas_vigo2.csv")
Aquí hay un error de escrituta. Aunque en el excel se escriba “lat” o “Lat” la primera columna siempre añade esto “ï..” no he conseguido arreglarlo…
#Cargamos las coordenadas de las ciudades en coords
coordenadas_vigo = cbind(rutas_vigo$long, rutas_vigo$lat)
#cargamos en spdf un dataframe con los puntos espaciales de las coordenadas
spdf_vigo = SpatialPointsDataFrame(coordenadas_vigo, rutas_vigo)
Estuidamos las distancias entre todos los clientes:
# calcular distancia real entre los puntos utilizando el método distHaversine que mide la distancia más corta entre dos puntos. Este método asume una tierra esférica, ignorando los efectos elipsoidales.
distancia_real_vigo<-distm(coordenadas_vigo,fun = distHaversine)
distancia_real_vigo
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 0.0000 360.6743 2313.327 3645.508 5460.918 1578.831
## [2,] 360.6743 0.0000 2029.261 3446.507 5484.261 1662.164
## [3,] 2313.3266 2029.2608 0.000 1638.901 4612.548 2097.559
## [4,] 3645.5078 3446.5067 1638.901 0.000 3407.657 2712.226
## [5,] 5460.9185 5484.2613 4612.548 3407.657 0.000 3891.346
## [6,] 1578.8306 1662.1638 2097.559 2712.226 3891.346 0.000
Podemos ver que estas distancias tienen sentido y están correctas.
#Necesitamos crear una matriz de distancias de tipo TSP para que funcione solve_TSP
tsp_vigo<-TSP(distancia_real_vigo)
tsp_vigo
## object of class 'TSP'
## 6 cities (distance 'unknown')
Generemos nuestro mapa de vigo usando ggmap con la fuente de google:
vigo=c(lon=-8.719431 ,lat=42.229714)
Vigo_basemap = ggmap::get_map(location=vigo, zoom= 14, source="google", maptype="roadmap", crop=TRUE)
## Source : https://maps.googleapis.com/maps/api/staticmap?center=42.229714,-8.719431&zoom=14&size=640x640&scale=2&maptype=roadmap&language=en-EN&key=xxx
ggmap(Vigo_basemap)
# mapa con nombres de lugares
plot(as(spdf_vigo, "Spatial"), axes=TRUE,xlim=c(-15,5),ylim=c(36,44))
plot(Vigo_basemap)
# se puede reducir el tamaño de los puntos reduciendo el valor de cex
points(spdf_vigo, pch=20, cex=3, col="black")
# añadir etiquetas de nombre de ciudad, modificar pos para poner texto encima, debajo, derecha o izquierad del punto
text(spdf_vigo$long,spdf_vigo$lat,labels=spdf_vigo$name,pos=4)
`
#HAY QUE CORRER TODO JUNTO PARA QUE SALGAN LOS PUNTOS
#Librerías
.packages = c("TSP","maps","sp","maptools","geosphere")
library(geosphere)
library(maptools)
library(rgdal)
library(raster)
library(maps)
library(mapdata)
library(ggmap)
library(marmap)
library(lattice)
# Validación
.inst <- .packages %in% installed.packages()
if(length(.packages[!.inst]) > 0)
suppressPackageStartupMessages(install.packages(.packages[!.inst]))
# Carga
suppressPackageStartupMessages(library("TSP"))
suppressPackageStartupMessages(library("sp"))
suppressPackageStartupMessages(library("maps"))
suppressPackageStartupMessages(library("maptools"))
suppressPackageStartupMessages(library("geosphere"))
rutas_vigo <- read.csv2("rutas_vigo2.csv")
rutas_vigo
## lat long name
## 1 42.23853 -8.710249 Restaurante
## 2 42.23874 -8.714616 Cliente_1
## 3 42.22769 -8.734188 Cliente_2
## 4 42.21330 -8.738445 Cliente_3
## 5 42.18950 -8.712457 Cliente_4
## 6 42.22437 -8.709138 Cliente_5
#Cargamos las coordenadas de las ciudades en coordenadas
coordenadas_vigo = cbind(rutas_vigo$long, rutas_vigo$lat)
#cargamos en spdf un dataframe con los puntos espaciales de las coordenadas
spdf_vigo = SpatialPointsDataFrame(coordenadas_vigo, rutas_vigo)
# calcular distancia real entre los puntos utilizando el método distHaversine que mide la distancia más corta entre dos puntos. Este método asume una tierra esférica, ignorando los efectos elipsoidales.
distancia_real_vigo<-distm(coordenadas_vigo,fun = distHaversine)
distancia_real_vigo
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 0.0000 360.6743 2313.327 3645.508 5460.918 1578.831
## [2,] 360.6743 0.0000 2029.261 3446.507 5484.261 1662.164
## [3,] 2313.3266 2029.2608 0.000 1638.901 4612.548 2097.559
## [4,] 3645.5078 3446.5067 1638.901 0.000 3407.657 2712.226
## [5,] 5460.9185 5484.2613 4612.548 3407.657 0.000 3891.346
## [6,] 1578.8306 1662.1638 2097.559 2712.226 3891.346 0.000
#Necesitamos crear una matriz de distancias de tipo TSP para que funcione solve_TSP
tsp_vigo<-TSP(distancia_real_vigo)
tsp_vigo
## object of class 'TSP'
## 6 cities (distance 'unknown')
#Descargamos el mapa de España, con level=1 lo tendremos por comunidad autónoma
vigo=c(lon=-8.719431 ,lat=42.229714)
Vigo_basemap = ggmap::get_map(location=vigo, zoom= 14, source="google", maptype="roadmap", crop=TRUE)
## Source : https://maps.googleapis.com/maps/api/staticmap?center=42.229714,-8.719431&zoom=14&size=640x640&scale=2&maptype=roadmap&language=en-EN&key=xxx
# mapa con nombres de los destinos#plot(as(spdf_vigo, "Spatial"), axes=TRUE,xlim=c(-50,50),ylim=c(50,50))
#ggmap(Vigo_basemap)
#points(spdf_vigo, pch=10, cex=2, col="red")
#text(spdf_vigo$long,spdf_vigo$lat,labels=spdf_vigo$name,pos=4)
Podemos ver que nos da un error… no pone los puntos tal y donde debería.
Como hemos dicho antes; vamos a calcular la ruta óptima para un repartidor del restaurante que tiene que atender a 6 clientes.
#Calculamos el tour con el método por defecto y decimos que empiece por el Cliente 1:
tour_vigo <- solve_TSP(tsp_vigo,method = "nn", start=1)
tour_vigo1 <- SpatialLines(list(Lines(list(Line(coordenadas_vigo[c(tour_vigo, tour_vigo[1]),])), ID="1")))
#Generamos el mapa otra vez:
#plot(as(spdf_vigo, "Spatial"), axes=TRUE,xlim=c(-10,5),ylim=c(36,44))
#ggmap(Vigo_basemap)
# se puede reducir el tamaño de los puntos reduciendo el valor de cex
#points(spdf_vigo, pch=20, cex=3, col="black")
# añadimos las etiquetas a cada destino:
#text(spdf_vigo$long,spdf_vigo$lat,labels=spdf_vigo$name,pos=4)
#Sacamos el tour más óptimo:
#plot(tour_vigo1, add=TRUE, col = "red")
#points(coordenadas_vigo, pch=3, cex=0.4, col="black")
tail(tour_vigo)
## 1 2 6 3 4 5
## 1 2 6 3 4 5
tour_vigo
## object of class 'TOUR'
## result of method 'nn' for 6 cities
## tour length: 14627.87
La ruta de reparto que nos proporciona es correcta:
\[ \begin{align*} Restaurante\Longrightarrow Cliente 2\Longrightarrow 6\Longrightarrow 3\Longrightarrow 4\Longrightarrow 5\end{align*} \]
En su momento conseguí que dibujase una ruta sobre el mapa de Vigo, donde los puntos no coincidian encima del mapa PERO la relación de situación y distancias entre ellos tenía sentido; pero algo toqué para tratar de mejorarlo y lo perdí sin poder recuperarlo.
Creo que el problema está en la lectura del CSV.
Aquí guardo una imagen de la ruta que podría salir.
png("rutas_vigo.png",
width=2400,height=1620,units="px",
pointsize=24,bg="white",res=300)
tour_vigo <- solve_TSP(tsp_vigo,method = "nn", start=1)
tour_vigo1 <- SpatialLines(list(Lines(list(Line(coordenadas_vigo[c(tour_vigo, tour_vigo[1]),])), ID="1")))
plot(as(spdf_vigo, "Spatial"), axes=TRUE,xlim=c(-10,5),ylim=c(36,44))
ggmap(Vigo_basemap)
points(spdf_vigo, pch=20, cex=3, col="black")
text(spdf_vigo$long,spdf_vigo$lat,labels=spdf_vigo$name,pos=4)
plot(tour_vigo1, add=TRUE, col = "red")
points(coordenadas_vigo, pch=3, cex=0.4, col="black")
tail(tour_vigo)
## 1 2 6 3 4 5
## 1 2 6 3 4 5
dev.off()
## png
## 2