Tengo cientos de puntos lat-long repartidos por todo el mundo, y debo crear polígonos circulares alrededor de cada uno de ellos, con un radio de exactamente 1000 metros. Entiendo que los puntos se deben proyectar primero desde grados (lat largo) a algo con unidades de medidor, pero ¿cómo se puede hacer esto sin buscar y definir manualmente las zonas UTM para cada punto?
Aquí hay una idea para el primer punto en Finlandia.
library(sp)
library(rgdal)
library(rgeos)
the.points.latlong <- data.frame(
Country=c("Finland", "Canada", "Tanzania", "Bolivia", "France"),
lat=c(63.293001, 54.239631, -2.855123, -13.795272, 48.603949),
long=c(27.472918, -90.476303, 34.679950, -65.691146, 4.533465))
the.points.sp <- SpatialPointsDataFrame(the.points.latlong[, c("long", "lat")], data.frame(ID=seq(1:nrow(the.points.latlong))), proj4string=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84"))
the.points.projected <- spTransform(the.points.sp[1, ], CRS( "+init=epsg:32635" )) # Only first point (Finland)
the.circles.projected <- gBuffer(the.points.projected, width=1000, byid=TRUE)
plot(the.circles.projected)
points(the.points.projected)
the.circles.sp <- spTransform(the.circles.projected, CRS("+proj=longlat +ellps=WGS84 +datum=WGS84"))
Pero con el segundo punto (Canadá) no funciona (porque la zona UTM es incorrecta).
the.points.projected <- spTransform(the.points.sp[2, ], CRS( "+init=epsg:32635" ))
¿Cómo se puede hacer esto sin obtener y especificar manualmente la zona UTM punto por punto? No tengo más información por punto que lat largo.
Actualizar:
Usando y combinando las excelentes respuestas de AndreJ y Mike T, aquí está el código para ambas versiones y tramas. Son diferentes en el cuarto decimal más o menos, ¡pero ambas son muy buenas respuestas!
gnomic.buffer <- function(p, r) {
stopifnot(length(p) == 1)
gnom <- sprintf("+proj=gnom +lat_0=%s +lon_0=%s +x_0=0 +y_0=0",
p@coords[[2]], p@coords[[1]])
projected <- spTransform(p, CRS(gnom))
buffered <- gBuffer(projected, width=r, byid=TRUE)
spTransform(buffered, p@proj4string)
}
custom.buffer <- function(p, r) {
stopifnot(length(p) == 1)
cust <- sprintf("+proj=tmerc +lat_0=%s +lon_0=%s +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs",
p@coords[[2]], p@coords[[1]])
projected <- spTransform(p, CRS(cust))
buffered <- gBuffer(projected, width=r, byid=TRUE)
spTransform(buffered, p@proj4string)
}
test.1 <- gnomic.buffer(the.points.sp[2,], 1000)
test.2 <- custom.buffer(the.points.sp[2,], 1000)
library(ggplot2)
test.1.f <- fortify(test.1)
test.2.f <- fortify(test.2)
test.1.f$transf <- "gnomic"
test.2.f$transf <- "custom"
test.3.f <- rbind(test.1.f, test.2.f)
p <- ggplot(test.3.f, aes(x=long, y=lat, group=transf))
p <- p + geom_path()
p <- p + facet_wrap(~transf)
p
(No estoy seguro de cómo incluir la trama en la actualización).
fuente
Respuestas:
Similar a @AndreJ, pero usa una
proyección gnómicadinámica , me refiero a una proyección equidistante azimutal dinámica para una mayor precisión. Una proyección AEQ centrada en cada punto proyectará distancias iguales en todas las direcciones, como un círculo amortiguado. (Una proyección de Mercator tendrá algunas distorsiones en las direcciones norte y este, ya que se envuelve alrededor del lado de un cilindro).Entonces, para su primer punto alrededor de Finlandia, la cadena PROJ.4 se verá así :
Entonces puede hacer una función R para hacer esta proyección dinámica:
Luego haga algo como esto para Canadá (elemento 2):
fuente
projected
de hecho siempre está en (0, 0) ybuffered
tiene los puntos ± 1000 m en las direcciones x e y . Si fuera crítico optimizar esto, simplemente transforme una versión cartesiana simple del búfer del AEQD dinámico a WGS84.En lugar de buscar la zona UTM correcta, puede crear una proyección mercator transversal personalizada para cada punto con
Dibuja el círculo en esa proyección. Las coordenadas del vértice del círculo proyectado siempre serán las mismas, por lo que debe crearlas solo una vez. Para lo siguiente, simplemente asígneles el nuevo CRS personalizado.
Vuelva a proyectar el círculo a EPSG: 4326 para su uso posterior.
Dentro del rango de 1000m, el círculo será casi exacto. Si no (o para círculos más grandes), use en
aeqd
lugar detmerc
.fuente
¿Qué pasa si adoptas el enfoque de crear un 1000 metros en EPSG: 4326 alrededor de cada uno de tus puntos? Luego convierta el EPSG: 4326 a su otro sistema de coordenadas? La ventaja de proyectar el punto es que no tiene que preocuparse por la curvatura de la tierra con EPSG: 4326.
fuente