En cualquier aspecto del análisis geoespacial, verificar y garantizar el ajuste espacial y la conformidad de las proyecciones es una tarea fundamental. Para ello, debe definirse el sistema de referencia de coordenadas (en inglés CRS).
Un sistema de referencia de coordenadas (CRS) puede ser tan simple y arbitrario como la cuadrícula creada para muestrear una parcela o tan complejo como para utilizarse sobre todo el planeta. Se puede definir como un marco de referencia local, regional o global, basado en coordenadas, que se utiliza para representar gráficamente (en un mapa) las ubicaciones reales de entidades geográficas.
Los criterios para diferenciar los CRS son diversos, pero esencialmente se puede recurrir al :
• El marco de medición, que puede ser geográfico (coordenadas esféricas) o planimétrico (coordenadas proyectadas sobre un plano).
• La unidad de medición, generalmente metros para sistemas de coordenadas proyectadas o grados (latitud/longitud) para coordenadas geográficas.
Además, los CRS presentan otras características adicionales, como un esferoide de referencia, el datum y otros parámetros de proyección (uno o más paralelos estándar, meridiano central o posibles cambios en las direcciones de x e y) etc…
A partir de esos criterios, los sistemas de referencia de coordenadas se clasifican en dos grandes grupos:
• Sistema de coordenadas geográficas: las ubicaciones se definen en términos de valores de latitud y longitud (coordenadas medidas desde el centro de la Tierra) sobre una superficie esférica, de tres dimensiones, siendo la unidad de medida los grados. Esto supone que distancias y otros parámetros topográficos no pueden evaluarse con precisión.
• Sistemas de coordenadas proyectadas, también denominadas proyecciones cartográficas. Se basan en la proyección de una superficie curva sobre una superficie plana bidimensional, empleando fórmulas matemáticas para relacionar las coordenadas esféricaso con las coordenadas cartesianas (x, y) que definen las ubicaciones de las entidades geográficas. A diferencia del sistema de coordenadas geográficas, el sistema de coordenadas proyectadas permite cálculos como distancias, áreas constantes etc, pero todas incorporan algunas distorsiones en esas magnitudes. Algunas de las proyecciones más famosas son la ‘Mercator’, ‘UTM’, ‘Robinson’, ‘Lambert’, ‘Sinusoidal’ ‘Robinson’ y ‘Albers’. No existe una proyección mejor que otras; algunas pueden usarse para todo el planeta, mientras que otras son apropiadas solo para áreas pequeñas. Una de las características más importantes de la proyección es si es corresponde a las conocidas como de “áreas iguales” (la escala del mapa es constante) o las “conformes” (las formas como se ven en un globo). Ninguna proyección puede ser a la vez conforme y de áreas iguales (pero pueden ser aproximadamente ambas para áreas más pequeñas, por ejemplo, UTM o Lambert Equal Area para un área grande).
Tradicionalmente, las proyecciones en R usaron la notación
[PROJ.4[(ftp://ftp.remotesensing.org/proj/OF90-284.pdf ), nombre
de una biblioteca de software de código abierto. En esta notación, cada
proyección era identificada mediante una cadena de caracteres que
almacena los parámetros que describen tanto la proyección como el
sistema de coordenadas. Este formato es conocido como
proj4string
. Por ejemplo, un sistema de coordenadas
geográfico (no proyectado) que utiliza la proyección UTM para el centro
de la Península Ibérica (WGS 84/UTM 30N) se define por la siguiente
cadena de caracteres “+proj=longlat + datum=WGS84 +units=m
+no_defs +ellps=WGS84 +towgs84=0,0,0”.
• proj=longlat: los datos utilizan un sistema de coordenadas geográficas (latitud y longitud).
• datum=WGS84: el datum WGS84 (el datum hace referencia a un punto de origen de los ejes de coordenadas).
• ellps=WGS84: el elipsoide (como se calcula la esfericidad de la Tierra).
Hoy en día, a los sistemas de proyección más utilizados se les asigna un código EPSG, un código corto compilado originalmente por el European Petroleum Survey Group. Los códigos EPSG con los Sistemas de Referencia de Coordenadas (CRS) utilizados en la representación cartográfica de los servicios Web de Mapas (WMS) del Nodo IDE del MAPAMA son los siguientes (pulsar el enlance para ampliar información sobre cada código):
En coordenadas geográficas: EPSG:4230 (ED50) EPSG:4326 (WGS84) EPSG:4258 (ETRS89)
En coordenadas UTM: EPSG:32628 (WGS84 / UTM zone 28N) EPSG:32629 (WGS84 / UTM zone 29N) EPSG:32630 (WGS84 / UTM zone 30N) EPSG:32631 (WGS84 / UTM zone 31N) EPSG:25828 (ETRS89 / UTM zone 28N) EPSG:25829 (ETRS89 / UTM zone 29N) EPSG:25830 (ETRS89 / UTM zone 30N) EPSG:25831 (ETRS89 / UTM zone 31N) EPSG:23028 (ED50 / UTM zone 28N) EPSG:23029 (ED50 / UTM zone 29N) EPSG:23030 (ED50 / UTM zone 30N) EPSG:23031 (ED50 / UTM zone 31N)
Podemos conocer algo más sobre los sistemas de referencia en las siguientes páginas web: Sistemas de referencia. Coordinate Systems Worldwide En qué zona UTM me encuentro
Página web Spatial Reference
Es muy habitual que, a la hora de trabajar que diferentes fuentes de información, los objetos espaciales no estén proyectados, o puedan estarlo en diferentes CRS. Por ello, deben transformarse en un CRS común para realizar la mayoría de las operaciones típicas de un entorno SIG. Los casos más habituales de transformación de CRS son los siguientes:
• La asignación de un nuevo CRS a un objeto que no disponía de CRS previo.
• La transformación del CRS de un objeto a otro sistema de proyección.
En esta sesión se trabajará con los paquetes sf y raster.
library(sf)
## Linking to GEOS 3.9.1, GDAL 3.2.1, PROJ 7.2.1; sf_use_s2() is TRUE
library(raster)
## Loading required package: sp
El paquete raster contiene dos funciones relacionadas con las proyecciones y los CRS:
Para conocer el CRS:
• projection() • crs()
Para asignar un CRS
• projection(x) <- CRS(“+init=epsg:28992”)
Para cambiar el CRS de un objeto raster en otro CRS:
• nuevoRaster <- projectRaster(antiguoRaster, proj4string(nuevoCRS))
El ejercicio comienza creado un objeto ráster a partir de una matriz de datos.
<- matrix(1:36, 6, 6)
matriz matriz
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1 7 13 19 25 31
## [2,] 2 8 14 20 26 32
## [3,] 3 9 15 21 27 33
## [4,] 4 10 16 22 28 34
## [5,] 5 11 17 23 29 35
## [6,] 6 12 18 24 30 36
<- raster(matriz) borrame
Una vez creada, el objeto matriz
puede ser eliminado ya
que no será utilizado
rm(matriz)
Se puede consultar el CRS de un objeto ráster con las siguientes funciones.
projection(borrame)
## [1] NA
crs(borrame)
## Coordinate Reference System:
## Deprecated Proj.4 representation: NA
La información que proporcionan no es exactamente la misma, pero ambas funciones informan que el objeto ráster no posee sistema de referencia alguno. Para asignarle un CRS se puede actuar de varias maneras.
crs(borrame) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
crs(borrame)
## Coordinate Reference System:
## Deprecated Proj.4 representation: +proj=longlat +datum=WGS84 +no_defs
## WKT2 2019 representation:
## GEOGCRS["unknown",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]],
## ID["EPSG",6326]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8901]],
## CS[ellipsoidal,2],
## AXIS["longitude",east,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]],
## AXIS["latitude",north,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]]]
Otra posibilidad es usar el nuevo formato EPSG,
• Opción 1: con la notación
"+init=epsg:codigo_EPSG"
projection(borrame) <- CRS("+init=epsg:23030")
## Warning in showSRID(uprojargs, format = "PROJ", multiline = "NO", prefer_proj =
## prefer_proj): Discarded datum European_Datum_1950 in Proj4 definition
crs(borrame)
## Coordinate Reference System:
## Deprecated Proj.4 representation:
## +proj=utm +zone=30 +ellps=intl +units=m +no_defs
## WKT2 2019 representation:
## PROJCRS["ED50 / UTM zone 30N",
## BASEGEOGCRS["ED50",
## DATUM["European Datum 1950",
## ELLIPSOID["International 1924",6378388,297,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4230]],
## CONVERSION["UTM zone 30N",
## METHOD["Transverse Mercator",
## ID["EPSG",9807]],
## PARAMETER["Latitude of natural origin",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8801]],
## PARAMETER["Longitude of natural origin",-3,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8802]],
## PARAMETER["Scale factor at natural origin",0.9996,
## SCALEUNIT["unity",1],
## ID["EPSG",8805]],
## PARAMETER["False easting",500000,
## LENGTHUNIT["metre",1],
## ID["EPSG",8806]],
## PARAMETER["False northing",0,
## LENGTHUNIT["metre",1],
## ID["EPSG",8807]],
## ID["EPSG",16030]],
## CS[Cartesian,2],
## AXIS["(E)",east,
## ORDER[1],
## LENGTHUNIT["metre",1,
## ID["EPSG",9001]]],
## AXIS["(N)",north,
## ORDER[2],
## LENGTHUNIT["metre",1,
## ID["EPSG",9001]]],
## USAGE[
## SCOPE["unknown"],
## AREA["Europe - between 6°W and 0°W - Channel Islands (Jersey, Guernsey); France offshore; Gibraltar; Ireland offshore; Norway including Svalbard - offshore; Spain - onshore; United Kingdom - UKCS offshore."],
## BBOX[35.26,-6,80.53,0]]]
• Opción 2: escribiendo directamente el código EPSG.
projection(borrame) <- CRS("EPSG:25830")
## Warning in showSRID(SRS_string, format = "PROJ", multiline = "NO", prefer_proj
## = prefer_proj): Discarded datum European Terrestrial Reference System 1989 in
## Proj4 definition
crs(borrame)
## Coordinate Reference System:
## Deprecated Proj.4 representation:
## +proj=utm +zone=30 +ellps=GRS80 +units=m +no_defs
## WKT2 2019 representation:
## PROJCRS["ETRS89 / UTM zone 30N",
## BASEGEOGCRS["ETRS89",
## DATUM["European Terrestrial Reference System 1989",
## ELLIPSOID["GRS 1980",6378137,298.257222101,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4258]],
## CONVERSION["UTM zone 30N",
## METHOD["Transverse Mercator",
## ID["EPSG",9807]],
## PARAMETER["Latitude of natural origin",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8801]],
## PARAMETER["Longitude of natural origin",-3,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8802]],
## PARAMETER["Scale factor at natural origin",0.9996,
## SCALEUNIT["unity",1],
## ID["EPSG",8805]],
## PARAMETER["False easting",500000,
## LENGTHUNIT["metre",1],
## ID["EPSG",8806]],
## PARAMETER["False northing",0,
## LENGTHUNIT["metre",1],
## ID["EPSG",8807]]],
## CS[Cartesian,2],
## AXIS["(E)",east,
## ORDER[1],
## LENGTHUNIT["metre",1]],
## AXIS["(N)",north,
## ORDER[2],
## LENGTHUNIT["metre",1]],
## USAGE[
## SCOPE["Engineering survey, topographic mapping."],
## AREA["Europe between 6°W and 0°W: Faroe Islands offshore; Ireland - offshore; Jan Mayen - offshore; Norway including Svalbard - offshore; Spain - onshore and offshore."],
## BBOX[35.26,-6,80.53,0]],
## ID["EPSG",25830]]
crs(borrame) <- CRS("EPSG:23030")
## Warning in showSRID(SRS_string, format = "PROJ", multiline = "NO", prefer_proj =
## prefer_proj): Discarded datum European Datum 1950 in Proj4 definition
Cuando se trabaja con un gran número de objetos al mismo tiempo,
puede ser conveniente crear un objeto con la proyección a la que se
desea modificar todos ellos, y luego asignárselos a cada objeto mediante
la función raster::projectRaster
. Podrían utilizarse
distintas sintaxis:
proj4string
.<- "+proj=longlat +datum=WGS84 +no_defs"
proyeccion1 <- projectRaster(borrame,
borrame_proy1 crs = proyeccion1)
crs(borrame_proy1)
## Coordinate Reference System:
## Deprecated Proj.4 representation: +proj=longlat +datum=WGS84 +no_defs
## WKT2 2019 representation:
## GEOGCRS["unknown",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]],
## ID["EPSG",6326]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8901]],
## CS[ellipsoidal,2],
## AXIS["longitude",east,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]],
## AXIS["latitude",north,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]]]
EPSG
.<- "EPSG:4326"
proyeccion2 <- projectRaster(borrame,
borrame_proy2 crs = proyeccion2)
crs(borrame_proy2)
## Coordinate Reference System:
## Deprecated Proj.4 representation: +proj=longlat +datum=WGS84 +no_defs
## WKT2 2019 representation:
## GEOGCRS["WGS 84 (with axis order normalized for visualization)",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]],
## ID["EPSG",6326]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8901]],
## CS[ellipsoidal,2],
## AXIS["geodetic longitude (Lon)",east,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]],
## AXIS["geodetic latitude (Lat)",north,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]]]
El paquete raster dispone de la función
raster::compareCRS
para determinar si las proyecciones de
dos objetos espaciales son idénticas.
compareCRS(borrame_proy1, borrame_proy2)
## [1] TRUE
Para no llenar el Global Enviroment de objetos sin uso, se procede a su eliminación.
rm(matriz, borrame, borrame_proy1, borrame_proy2, proyeccion1, proyeccion2)
## Warning in rm(matriz, borrame, borrame_proy1, borrame_proy2, proyeccion1, :
## objeto 'matriz' no encontrado
La proyección y reproyección de datos ráster supone un problema que no tienen los objetos vectoriales: las nuevas ubicaciones de los píxeles no tienen por qué coincidir con las localizaciones antiguas una vez reproyectados, ya que han sido “obligadas” a encajarse en otras cuadrículas con una disposición diferente. Los píxeles de un objeto ráster poseen el mismo tamaño (en términos de las unidades del CRS aunque su tamaño real puede variar), por lo que no es posible transformar celda a celda.
El cálculo de los valores de los píxeles reproyectados se puede realizar a partir de los valores de los píxeles del ráster original. Por lo tanto, será necesario interpolar esos valores. Esto significa calcular un valor promedio ponderado de los píxeles circundantes más cercanos (cuatro píxeles en la práctica). Alternativamente, se podría usar el método de remuestreo del vecino más cercano, que recoge el valor del píxel más cercano, evitando así el promedio, pero esto tiende a dar resultados bastante pixelados y es formalmente menos correcto. Se recomienda:
Usar como método el del vecino más cercano (argumento “ngb”) si los valores son categóricos (por ejemplo, usos del suelo).
Si la variable del ráster es continúa (por ejemplo, la altitud)
la interpolación se realiza con el método bilineal
(argumento “bilinear”).
Además del suavizado de los valores originales, la reproyección de rásteres con cualquier método que no sea el del vecino más cercano es irreversible: no hay forma de volver a los valores originales. Por lo tanto, si tiene que elegir entre volver a proyectar datos vectoriales para que coincidan con su proyección ráster o volver a proyectar el ráster para que coincida con la proyección vectorial, se recomienda optar por proyectar los objetos vectoriales, que es, además, mucho más rápida.
A continuación se diseñará un objeto ráster formado por 81 celdas, a las que se incorporarán las coordenadas geográficas.
<- raster(ncol= 15, # Número de columnas del ráster
raster nrow= 15, # Número de filas
xmx= -2,xmn= -5, # Coordenadas del eje X (considerémoslas la longitud)
ymx= 42,ymn= 39) # Coordenadas del eje y (idem latitud)
Este objeto ráster se rellenará con los siguientes valores
values(raster) <- as.integer(runif(ncell(raster),
min = 1,
max= 6))
Llamando al objeto ráster se puede conocer las características de dicho objeto.
raster
## class : RasterLayer
## dimensions : 15, 15, 225 (nrow, ncol, ncell)
## resolution : 0.2, 0.2 (x, y)
## extent : -5, -2, 39, 42 (xmin, xmax, ymin, ymax)
## crs : +proj=longlat +datum=WGS84 +no_defs
## source : memory
## names : layer
## values : 1, 5 (min, max)
Por último, se representará gráficamente este objeto.
plot(raster)
text(raster, digits=1)
Para definir el CRS destino se debería usar a partir de este momento el código EPSG. Esto puede realizarse con varios tipos de sintaxis.
+init=epsg:CODIGO_EPSG
; la función
agreta automáticamente todos los parámetros de dicho CRS (ED50 / UTM
zone 30N).<- crs("+init=epsg:23030")
utm utm
## Coordinate Reference System:
## Deprecated Proj.4 representation:
## +proj=utm +zone=30 +ellps=intl +units=m +no_defs
## WKT2 2019 representation:
## PROJCRS["ED50 / UTM zone 30N",
## BASEGEOGCRS["ED50",
## DATUM["European Datum 1950",
## ELLIPSOID["International 1924",6378388,297,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4230]],
## CONVERSION["UTM zone 30N",
## METHOD["Transverse Mercator",
## ID["EPSG",9807]],
## PARAMETER["Latitude of natural origin",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8801]],
## PARAMETER["Longitude of natural origin",-3,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8802]],
## PARAMETER["Scale factor at natural origin",0.9996,
## SCALEUNIT["unity",1],
## ID["EPSG",8805]],
## PARAMETER["False easting",500000,
## LENGTHUNIT["metre",1],
## ID["EPSG",8806]],
## PARAMETER["False northing",0,
## LENGTHUNIT["metre",1],
## ID["EPSG",8807]],
## ID["EPSG",16030]],
## CS[Cartesian,2],
## AXIS["(E)",east,
## ORDER[1],
## LENGTHUNIT["metre",1,
## ID["EPSG",9001]]],
## AXIS["(N)",north,
## ORDER[2],
## LENGTHUNIT["metre",1,
## ID["EPSG",9001]]],
## USAGE[
## SCOPE["unknown"],
## AREA["Europe - between 6°W and 0°W - Channel Islands (Jersey, Guernsey); France offshore; Gibraltar; Ireland offshore; Norway including Svalbard - offshore; Spain - onshore; United Kingdom - UKCS offshore."],
## BBOX[35.26,-6,80.53,0]]]
La reproyección se realiza con la función
raster::projectRaster
, utilizando para ello el objeto
utm
con el CRS deseado. La reproyección puede realizarse
mediante dos métodos: el argumento method = ngb
significa
que se utiliza el método del vecino más próximo.
<- projectRaster(from = raster,
raster_proj_ngb crs = utm,
method= "ngb")
De la misma manera, el argumento method = bilinear
significa que la interpolación sigue el método bilineal.
<- projectRaster(from = raster,
raster_proj_bil crs = utm,
method= "bilinear")
En la siguiente imagen se representa el objeto ráster original y los resultantes de la reproyección con diferentes métodos.
# Dos filas, dos columnas
par(mfcol = c(2, 2))
# Gráficos
plot(raster, main = "Datos originales")
text(raster, digits=0, cex = 0.5)
plot(raster_proj_ngb, main = "Reproyección ngb")
text(raster_proj_ngb, digits=0, cex = 0.5)
plot(raster_proj_bil, main = "Reproyección bil")
text(raster_proj_bil, digits=0, cex = 0.5)
# Volvemos al estado original
par(mfcol = c(1, 1))
Obsérvese que, mientras en los datos originales el CRS sigue coordenadas geográficas (valores de latitud y longitud), en los objetos reproyectados con el nuevo CRS las unidades son metros.
Otra posibilidad de reproyección consiste en crear un objeto ráster
vacío y rellenarlo con los datos reproyectados de un fichero original.
Esto permite que la alineación del nuevo objeto sea más correcta y
precisa. El objeto raster_nuevo
se crea a partir del objeto
raster original raster
, pero como objeto vacío, con la
función projectExtent
. Esta última función está concebida
para crear objetos ráster vacíos, que sirvan para posteriores análisis.
Requiere dos argumentos:
• El nombre del objeto ráster cuyas dimensiones se desea “clonar”.
• El CRS que se desea asignar
<- projectExtent(raster,
raster_nuevo
utm) raster_nuevo
## class : RasterLayer
## dimensions : 15, 15, 225 (nrow, ncol, ncell)
## resolution : 17302.64, 22328.6 (x, y)
## extent : 326919.2, 586458.8, 4316989, 4651918 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +ellps=intl +units=m +no_defs
A este objeto vacío se le puede modificar la resolución original,
res(raster_nuevo)
## [1] 17302.64 22328.60
La nueva resolución espacial pasará a ser de 10000 metros en las dos
dimensiones x e y; si quisiéramos píxeles con diferentes resolución
espacial (x,y) la sintaxis podría ser c(10000,15000)
.
res(raster_nuevo) <- 10000
raster_nuevo
## class : RasterLayer
## dimensions : 33, 26, 858 (nrow, ncol, ncell)
## resolution : 10000, 10000 (x, y)
## extent : 326919.2, 586919.2, 4321918, 4651918 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +ellps=intl +units=m +no_defs
A continuación se reproyectará el objeto ráster original con la
resolución del raster vacío; sus valores se usarán para rellenar un
nuevo objeto ráster raster_nuevo_resol1000
<- projectRaster(raster,
raster_nuevo_resol1000
raster_nuevo, method = 'ngb')
raster_nuevo_resol1000
## class : RasterLayer
## dimensions : 33, 26, 858 (nrow, ncol, ncell)
## resolution : 10000, 10000 (x, y)
## extent : 326919.2, 586919.2, 4321918, 4651918 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +ellps=intl +units=m +no_defs
## source : memory
## names : layer
## values : 1, 5 (min, max)
Por último, para comprobar el resultado se procederá a su representación gráfica.
plot(raster_nuevo_resol1000, main = "Reproyección")
text(raster_nuevo_resol1000, digits=0, cex = 0.4)
rm(raster_nuevo, raster_nuevo_resol1000, raster_proj_bil, raster_proj_ngb, utm)
Es muy habitual también combinar objetos en formato ráster con objetos en formato vectorial. Es necesario, por lo tanto, que ambos formatos compartan el mismo CRS.
Podemos crear un objeto vectorial a partir de un objeto ráster. La
función extent()
extrae de un rasterLayer o un objeto
espacial (vector) un objeto extent
, en realidad, un marco
espacial que no contiene ni datos ni información sobre CRS.
<- extent(raster)
ext crs(ext)
## [1] NA
class(ext)
## [1] "Extent"
## attr(,"package")
## [1] "raster"
A continuación, transformaremos ese objeto extent
, que
sigue siendo un objeto ráster, en otro objeto espacial, pero ahora de la
clase sf
, que corresponde a un objeto vectorial. Para ello
se utilizarán dos funciones:
bbox
convierte la “caja” extent
en una caja similar bbox
que puede ser leída por el
paquetesf. Este objeto simplemente contiene las coordenadas del
objeto.<- st_bbox(ext)
caja caja
## xmin ymin xmax ymax
## -5 39 -2 42
st_as_sfc
transforma esas coordenadas en un
objeto sf
(un objeto vectorial, pero sólo sus dimensiones
espaciales).<- st_as_sfc(caja)
poligono rm(caja)
poligono
## Geometry set for 1 feature
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -5 ymin: 39 xmax: -2 ymax: 42
## CRS: NA
## POLYGON ((-5 39, -2 39, -2 42, -5 42, -5 39))
class(poligono)
## [1] "sfc_POLYGON" "sfc"
plot(poligono)
Sin embargo, este objeto carece de CRS. Para proporcionarle un CRS son posibles varias opciones
st_crs(objeto) = "EPSG:4326"
st_crs(poligono) <- "EPSG:4326"
poligono
## Geometry set for 1 feature
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -5 ymin: 39 xmax: -2 ymax: 42
## Geodetic CRS: WGS 84
## POLYGON ((-5 39, -2 39, -2 42, -5 42, -5 39))
st_set_crs()
, que devuelve el objeto con
el nuevo CRS:<- st_set_crs(poligono,
borrame1 "EPSG:4326")
borrame1
## Geometry set for 1 feature
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -5 ymin: 39 xmax: -2 ymax: 42
## Geodetic CRS: WGS 84
## POLYGON ((-5 39, -2 39, -2 42, -5 42, -5 39))
st_as_sf(... crs = "codigo EPSG")
.<- st_as_sf(poligono,
borrame2 "EPSG:4326")
borrame2
## Simple feature collection with 1 feature and 1 field
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -5 ymin: 39 xmax: -2 ymax: 42
## Geodetic CRS: WGS 84
## "EPSG:4326" x
## 1 EPSG:4326 POLYGON ((-5 39, -2 39, -2 ...
rm(ext, borrame1, borrame2)
La función sf::st_transform(x, crs)
transforma
(“reproyecta”) cualquier objeto vectorial a un nuevo CRS.
Por ejemplo, al objeto polígono
se le podría reasignar
otro CRS (reproyección de CRS a CRS), por ejemplo la proyección MODIS
Sinusoidal (EPSG: 6842; “+proj=sinu +lon_0=0 +x_0=0 +y_0=0
+a=6371007.181 +b=6371007.181 +units=m +no_defs”.
<- st_transform(poligono,
poligono_sinuosoidal "EPSG:6842")
A continuación, representaremos ambos objetos al mismo tiempo.
# Una fila, dos columnas
par(mfcol = c(1, 2))
# Gráficos
plot(poligono, axes = TRUE)
plot(poligono_sinuosoidal, axes = TRUE)
# Volvemos al estado original
par(mfcol = c(1, 1))
Si quisiéramos superponer el objeto ráster
y el objeto
poligono
habría que comprobar que poseen el mismo CRS. Si
fuera así, habría que utilizar uno común. Recuérdese que
raster
no posee ningún CRS, mientras que acabamos de
asignar un CRS a polígono
.
<- crs("+init=epsg:23030") # Objeto con el CRS
utm <- projectRaster(raster, # Reproyección del objeto raster (es necesario incluir argumento `crs =`)
raster_ED50 crs = utm)
<- st_transform(poligono, # Reproyección del objeto vectorial
poligono_ED50 crs = utm)
Para verificar que la transformación se ha realizado correctamente, podemos superponer uno encima de otro.
plot(raster_ED50)
plot(poligono_ED50, add = TRUE)
Como no son necesarios para la siguiente sesión, se eliminarán los siguientes objetos del Global Environment
rm(list=ls())
A continuación se revisan algunos procedimientos comunes para realizar estas transformaciones en R con datos reales. Primero, debe establecerse la carpeta dónde se encuentran los ficheros que serán utilizados en esta sesión.
setwd("D:/G174_OCW/Lab_3_preprocesamiento_imagenes_satelite/datos/proyeccion")
getwd()
## [1] "D:/G174_OCW/Lab_3_preprocesamiento_imagenes_satelite/datos/proyeccion"
Una vez creado dicha carpeta, se descargan los ficheros necesarios para esta actividad directamente desde el servidor web.
# download.file("https://personales.unican.es/rasillad/docencia/g174/preprocesamiento/datos/proyeccion.zip", # Nombre del fichero a descargar
# "./mi_carpeta/mi_fichero.zip", # Ruta y nombre del fichero a descargar
# method = "auto")
Y descomprimirse
#unzip("./mi_carpeta/mi_fichero.zip", # Ruta y nombre del fichero
# exdir = "./mi_carpeta/") # Ruta de la carpeta que lo contiene
Un procedimiento alternativo es realizar todo el proceso manualmente. Para ello, los ficheros necesarios para esta práctica se descargan aquí
En primer lugar se creará un fichero ráster A continuación se diseñará un objeto ráster formado por 81 celdas, con proyección geográfica.
<- raster(ncol= 9, # Número de columnas del ráster
mdt nrow= 9, # Número de filas
xmx= -3,xmn= -4.75, # Coordenadas del eje X (considerémoslas la longitud)
ymx= 41.5,ymn= 39.5) # Coordenadas del eje y (idem latitud)
values(mdt) <- as.integer(runif(ncell(mdt),
min = 1,
max= 30))
A continuación se importará un fichero con los bordes administrativos de la Comunidad de Madrid.
<- st_read("D:/G174_OCW/Lab_3_preprocesamiento_imagenes_satelite/datos/proyeccion/comunidad.shp") comunidad
## Reading layer `comunidad' from data source
## `D:\G174_OCW\Lab_3_preprocesamiento_imagenes_satelite\datos\proyeccion\comunidad.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 1 feature and 1 field
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 365635.7 ymin: 4415272 xmax: 495483.9 ymax: 4557310
## Projected CRS: WGS 84 / UTM zone 30N
plot(comunidad,
col = "red")
También se importará el límite administrativo del municipio de Madrid.
library(rgeoboundaries) # Paquete con las unidades administrativas (todo el planeta)
library(dplyr) # Paquete para filtrar/seleccionar unidades administrativas
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:raster':
##
## intersect, select, union
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
<- geoboundaries("Spain", "adm2") # Solicitamos la extracción de los municipios ("adm") de España
municipio <- filter(municipio, # Filtramos el límite del municipio de Madrid
municipio == "Madrid")
shapeName <- municipio[ , -c(2:5)] # Eliminamos columnas innecesarias municipio
Comprobamos el CRS de este nuevo objeto gráfico.
crs(municipio)
## Coordinate Reference System:
## Deprecated Proj.4 representation: +proj=longlat +datum=WGS84 +no_defs
## WKT2 2019 representation:
## GEOGCRS["WGS 84",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## CS[ellipsoidal,2],
## AXIS["latitude",north,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433]],
## AXIS["longitude",east,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4326]]
Es habitual que en la mayoría de los paquetes que ofrecen datos espaciales el CRS básico corresponda a un sistema de coordenadas geográficas. La conversión a proyectadas es muy más fácil y genera menos errores.
Si se intenta representar la combinación del objeto ráster
mdt
, y superpuesto el objeto vectorial
comunidad
aparece lo siguiente.
plot(mdt)
plot(st_geometry(comunidad),
col = "blue",
add = TRUE)
Si se intenta realizar lo mismo con el objeto ráster y el objeto
vectorial municipio
el resultado es el siguiente.
plot(mdt)
plot(st_geometry(municipio),
col = "red",
add = TRUE)
Por último, si se representan ambos límites administrativos, el resultado es el siguiente
plot(st_geometry(comunidad),
col = "lightgreen",
border = "gray")
plot(st_geometry(municipio),
col = "red", add = TRUE)
El problema se debe a que esos objetos poseen diferentes CRS.
compareCRS(comunidad, municipio)
## [1] FALSE
compareCRS(mdt, municipio)
## [1] TRUE
Debemos conocer cuál es el CRS de cada objeto. En el caso del objeto ráster:
crs(mdt)
## Coordinate Reference System:
## Deprecated Proj.4 representation: +proj=longlat +datum=WGS84 +no_defs
## WKT2 2019 representation:
## GEOGCRS["unknown",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]],
## ID["EPSG",6326]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8901]],
## CS[ellipsoidal,2],
## AXIS["longitude",east,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]],
## AXIS["latitude",north,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433,
## ID["EPSG",9122]]]]
En el caso de los objetos vectoriales
st_crs(comunidad)
## Coordinate Reference System:
## User input: WGS 84 / UTM zone 30N
## wkt:
## PROJCRS["WGS 84 / UTM zone 30N",
## BASEGEOGCRS["WGS 84",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4326]],
## CONVERSION["UTM zone 30N",
## METHOD["Transverse Mercator",
## ID["EPSG",9807]],
## PARAMETER["Latitude of natural origin",0,
## ANGLEUNIT["Degree",0.0174532925199433],
## ID["EPSG",8801]],
## PARAMETER["Longitude of natural origin",-3,
## ANGLEUNIT["Degree",0.0174532925199433],
## ID["EPSG",8802]],
## PARAMETER["Scale factor at natural origin",0.9996,
## SCALEUNIT["unity",1],
## ID["EPSG",8805]],
## PARAMETER["False easting",500000,
## LENGTHUNIT["metre",1],
## ID["EPSG",8806]],
## PARAMETER["False northing",0,
## LENGTHUNIT["metre",1],
## ID["EPSG",8807]]],
## CS[Cartesian,2],
## AXIS["(E)",east,
## ORDER[1],
## LENGTHUNIT["metre",1]],
## AXIS["(N)",north,
## ORDER[2],
## LENGTHUNIT["metre",1]],
## ID["EPSG",32630]]
st_crs(municipio)
## Coordinate Reference System:
## User input: WGS 84
## wkt:
## GEOGCRS["WGS 84",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## CS[ellipsoidal,2],
## AXIS["latitude",north,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433]],
## AXIS["longitude",east,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4326]]
El objeto comunidad
aparece en coordenadas proyectadas,
mientras que el objeto municipio
está proyectado en
coordenadas geográficas, al igual que objeto ráster. La función
plot()
considera que las coordenadas del objeto
comunidad
se encuentran fuera del marco espacial en el que
se inserta la capa municipio
y, por tanto, no la
representa, pero tampoco avisa del error ni proporciona un mensaje de
advertencia. Esto también se hace evidente si comparamos:
as.vector (extent(comunidad))
## [1] 365635.7 495483.9 4415271.9 4557310.2
as.vector(extent(municipio))
## [1] -3.888957 -3.518235 40.312064 40.643333
as.vector(extent(mdt))
## [1] -4.75 -3.00 39.50 41.50
projection(comunidad)
## [1] "+proj=utm +zone=30 +datum=WGS84 +units=m +no_defs"
projection (municipio)
## [1] "+proj=longlat +datum=WGS84 +no_defs"
projection(mdt)
## [1] "+proj=longlat +datum=WGS84 +no_defs"
Elegiremos como CRS común el sistema proyectado EPSG:23030 (ED50 / UTM zone 30N), que también es un sistema de coordenadas proyectadas. Hay varias posibilidades para realizar esta reproyección.
<- "EPSG:23030" reproj
A continuación, se transforma el sistema de referencia original del
objeto municipio
al nuevo CRS.
<- st_transform(comunidad,
comunidad_ED50 crs = reproj)
crs(comunidad_ED50)
## Coordinate Reference System:
## Deprecated Proj.4 representation:
## +proj=utm +zone=30 +ellps=intl +units=m +no_defs
## WKT2 2019 representation:
## PROJCRS["ED50 / UTM zone 30N",
## BASEGEOGCRS["ED50",
## DATUM["European Datum 1950",
## ELLIPSOID["International 1924",6378388,297,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4230]],
## CONVERSION["UTM zone 30N",
## METHOD["Transverse Mercator",
## ID["EPSG",9807]],
## PARAMETER["Latitude of natural origin",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8801]],
## PARAMETER["Longitude of natural origin",-3,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8802]],
## PARAMETER["Scale factor at natural origin",0.9996,
## SCALEUNIT["unity",1],
## ID["EPSG",8805]],
## PARAMETER["False easting",500000,
## LENGTHUNIT["metre",1],
## ID["EPSG",8806]],
## PARAMETER["False northing",0,
## LENGTHUNIT["metre",1],
## ID["EPSG",8807]]],
## CS[Cartesian,2],
## AXIS["(E)",east,
## ORDER[1],
## LENGTHUNIT["metre",1]],
## AXIS["(N)",north,
## ORDER[2],
## LENGTHUNIT["metre",1]],
## USAGE[
## SCOPE["Engineering survey, topographic mapping."],
## AREA["Europe - between 6°W and 0°W - Channel Islands (Jersey, Guernsey); France offshore; Gibraltar; Ireland offshore; Norway including Svalbard - offshore; Spain - onshore; United Kingdom - UKCS offshore."],
## BBOX[35.26,-6,80.53,0]],
## ID["EPSG",23030]]
Podríamos realizar lo mismo para reproyectar el objeto ráster.
<- projectRaster(mdt,
mdt_ED50 crs = reproj)
crs(mdt_ED50)
## Coordinate Reference System:
## Deprecated Proj.4 representation:
## +proj=utm +zone=30 +ellps=intl +units=m +no_defs
## WKT2 2019 representation:
## PROJCRS["ED50 / UTM zone 30N",
## BASEGEOGCRS["ED50",
## DATUM["European Datum 1950",
## ELLIPSOID["International 1924",6378388,297,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4230]],
## CONVERSION["UTM zone 30N",
## METHOD["Transverse Mercator",
## ID["EPSG",9807]],
## PARAMETER["Latitude of natural origin",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8801]],
## PARAMETER["Longitude of natural origin",-3,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8802]],
## PARAMETER["Scale factor at natural origin",0.9996,
## SCALEUNIT["unity",1],
## ID["EPSG",8805]],
## PARAMETER["False easting",500000,
## LENGTHUNIT["metre",1],
## ID["EPSG",8806]],
## PARAMETER["False northing",0,
## LENGTHUNIT["metre",1],
## ID["EPSG",8807]]],
## CS[Cartesian,2],
## AXIS["(E)",east,
## ORDER[1],
## LENGTHUNIT["metre",1]],
## AXIS["(N)",north,
## ORDER[2],
## LENGTHUNIT["metre",1]],
## USAGE[
## SCOPE["Engineering survey, topographic mapping."],
## AREA["Europe - between 6°W and 0°W - Channel Islands (Jersey, Guernsey); France offshore; Gibraltar; Ireland offshore; Norway including Svalbard - offshore; Spain - onshore; United Kingdom - UKCS offshore."],
## BBOX[35.26,-6,80.53,0]],
## ID["EPSG",23030]]
Ahora sí los límites administrativos coinciden.
plot(mdt_ED50)
plot(st_geometry(comunidad),
add = TRUE)
Otra posibilidad es la reproyección de un objeto vectorial, en este
caso, el objeto municipio
con el CRS de un objeto raster,
por ejemplo el objeto mdt_ED50
.
El CRS del objeto vectorial es el siguiente.
crs(municipio)
## Coordinate Reference System:
## Deprecated Proj.4 representation: +proj=longlat +datum=WGS84 +no_defs
## WKT2 2019 representation:
## GEOGCRS["WGS 84",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## CS[ellipsoidal,2],
## AXIS["latitude",north,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433]],
## AXIS["longitude",east,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4326]]
El CRS del objeto ráster aparece a continuación.
crs(mdt_ED50)
## Coordinate Reference System:
## Deprecated Proj.4 representation:
## +proj=utm +zone=30 +ellps=intl +units=m +no_defs
## WKT2 2019 representation:
## PROJCRS["ED50 / UTM zone 30N",
## BASEGEOGCRS["ED50",
## DATUM["European Datum 1950",
## ELLIPSOID["International 1924",6378388,297,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4230]],
## CONVERSION["UTM zone 30N",
## METHOD["Transverse Mercator",
## ID["EPSG",9807]],
## PARAMETER["Latitude of natural origin",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8801]],
## PARAMETER["Longitude of natural origin",-3,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8802]],
## PARAMETER["Scale factor at natural origin",0.9996,
## SCALEUNIT["unity",1],
## ID["EPSG",8805]],
## PARAMETER["False easting",500000,
## LENGTHUNIT["metre",1],
## ID["EPSG",8806]],
## PARAMETER["False northing",0,
## LENGTHUNIT["metre",1],
## ID["EPSG",8807]]],
## CS[Cartesian,2],
## AXIS["(E)",east,
## ORDER[1],
## LENGTHUNIT["metre",1]],
## AXIS["(N)",north,
## ORDER[2],
## LENGTHUNIT["metre",1]],
## USAGE[
## SCOPE["Engineering survey, topographic mapping."],
## AREA["Europe - between 6°W and 0°W - Channel Islands (Jersey, Guernsey); France offshore; Gibraltar; Ireland offshore; Norway including Svalbard - offshore; Spain - onshore; United Kingdom - UKCS offshore."],
## BBOX[35.26,-6,80.53,0]],
## ID["EPSG",23030]]
A continuación, mediante la función sf::st_transform
reproyectamos el objeto municipio
al nuevo sistema de
coordenadas, creando un nuevo objeto. En este caso, el argumento
crs = crs(mdt_ED50)
informa a R que tiene que utilizar como
CRS el que corresponde al objeto mdt_ED50
.
<- st_transform(municipio,
municipio_ED50 crs = crs(mdt_ED50))
Ahora sí los límites administrativos coinciden.
plot(mdt_ED50)
plot(st_geometry(comunidad_ED50),
col = "red", add = TRUE)
plot(st_geometry(municipio_ED50),
col = "yellow", add = TRUE)
Un último caso es la incorporación de otro objeto espacial que originalmente no dispone de proyección, porque ha sido importado como dataframe, por ejemplo, una serie de localidades (puntos). El procedimiento para asignar un CRS es algo más complicado.
Primero, se importa el fichero original (en formato .csv).
<- read.csv("D:/G174_OCW/Lab_3_preprocesamiento_imagenes_satelite/datos/proyeccion/meteo_mad.csv")
puntos str(puntos)
## 'data.frame': 9 obs. of 4 variables:
## $ cdg : int 82150 82190 82200 82210 82220 82230 82240 82260 82270
## $ estacion: chr " NAVACERRADA" " COLMENAR" " C. UNIVERSITARIA" " BARAJAS" ...
## $ lon : num -4.02 -3.73 -3.72 -3.57 -3.68 ...
## $ lat : num 40.8 40.6 40.5 40.5 40.4 ...
class(puntos)
## [1] "data.frame"
Puede observarse que estos datos contienen información espacial al
incluir dos columnas, una con la longitud de la localidad y otra con la
latitud. Aprovechando estos datos, el dataframe se convertirá en un
objeto espacial de la clase sf
(un objeto vectorial). Dado
que la localización de cada entidad está medida en grados, es necesario
asignar como CRS el Sistema de Coordenadas Geográficas
EPSG:4326
(WGS84).
<- st_as_sf(puntos,
puntos.sf coords = c("lon", "lat"),
crs = 4326)
class(puntos.sf)
## [1] "sf" "data.frame"
A partir de aquí, podríamos transformar el CRS del objeto
puntos.sf
al sistema común.
<- st_transform(puntos.sf,
meteo_ED50 crs = reproj)
meteo_ED50
## Simple feature collection with 9 features and 2 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: 414318.8 ymin: 4460848 xmax: 485993.5 ymax: 4517260
## Projected CRS: ED50 / UTM zone 30N
## cdg estacion geometry
## 1 82150 NAVACERRADA POINT (414318.8 4517260)
## 2 82190 COLMENAR POINT (438137.3 4500371)
## 3 82200 C. UNIVERSITARIA POINT (439309.5 4478159)
## 4 82210 BARAJAS POINT (452060.5 4482951)
## 5 82220 RETIRO POINT (442164.4 4474473)
## 6 82230 CUATRO VIENTOS POINT (433465.5 4469439)
## 7 82240 GETAFE POINT (438574.4 4460848)
## 8 82260 GUADALAJARA POINT (485993.5 4502013)
## 9 82270 TORREJON POINT (462316 4483225)
Finalmente, se pueden cartografiar ambos conjuntos de datos.
plot(mdt_ED50)
plot(st_geometry(comunidad_ED50),
col = "red", add = TRUE)
plot(st_geometry(municipio_ED50),
col = "yellow",
border = "darkgreen",
add = TRUE)
plot(st_geometry(meteo_ED50),
col = "blue",
add = TRUE)