Ich habe Hunderte von Lat-Long-Punkten auf der ganzen Welt verteilt und muss um jeden von ihnen Kreispolygone mit einem Radius von genau 1000 Metern erstellen. Ich verstehe, dass die Punkte zuerst von Grad (Lat lang) auf etwas mit Metereinheiten projiziert werden müssen, aber wie kann dies geschehen, ohne die UTM-Zonen für jeden Punkt manuell zu suchen und zu definieren?
Hier ist ein Mwe für den ersten Punkt in Finnland.
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"))
Aber mit dem zweiten Punkt (Kanada) funktioniert es nicht (weil falsche UTM-Zone).
the.points.projected <- spTransform(the.points.sp[2, ], CRS( "+init=epsg:32635" ))
Wie kann dies geschehen, ohne den UTM-Zonenpunkt pro Punkt manuell abzurufen und anzugeben? Ich habe nicht mehr Informationen pro Punkt als lat lang.
Aktualisieren:
Unter Verwendung und Kombination der großartigen Antworten von AndreJ und Mike T finden Sie hier den Code für beide Versionen und Diagramme. Sie unterscheiden sich auf der 4. Dezimalstelle oder so, aber beide sind sehr gute Antworten!
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
(Nicht sicher, wie der Plot in das Update aufgenommen werden soll).
quelle
Antworten:
Ähnlich wie bei @AndreJ, aber mit einer dynamischen
gnomischen Projektionmeine ich eine dynamische azimutale äquidistante Projektion für noch mehr Genauigkeit. Eine auf jeden Punkt zentrierte AEQ-Projektion projiziert gleiche Abstände in alle Richtungen, z. B. einen gepufferten Kreis. (Eine Mercator-Projektion weist einige Verzerrungen in Nord- und Ostrichtung auf, da sie sich um die Seite eines Zylinders wickelt.)Für Ihren ersten Punkt in Finnland sieht die PROJ.4-Zeichenfolge also folgendermaßen aus :
Sie können also eine R-Funktion erstellen, um diese dynamische Projektion zu erstellen:
Dann machen Sie so etwas für Kanada (Punkt 2):
quelle
projected
ist in der Tat immer bei (0, 0) undbuffered
hat die Punkte ± 1000 m in x- und y- Richtung. Wenn es wichtig war, dies zu optimieren, transformieren Sie einfach eine einfache kartesische Version des Puffers von der dynamischen AEQD in WGS84.Anstatt nach der richtigen UTM-Zone zu suchen, können Sie für jeden Punkt mit eine benutzerdefinierte transversale Mercator-Projektion erstellen
Zeichnen Sie den Kreis in dieser Projektion. Die projizierten Kreisscheitelpunktkoordinaten sind immer gleich, sodass Sie sie nur einmal erstellen müssen. Weisen Sie ihnen im Folgenden einfach das neue benutzerdefinierte CRS zu.
Projizieren Sie den Kreis zur weiteren Verwendung auf EPSG: 4326.
Im Bereich von 1000 m ist der Kreis fast genau. Wenn nicht (oder für größere Kreise), verwenden Sie
aeqd
anstelle vontmerc
.quelle
Was ist, wenn Sie in EPSG: 4326 um jeden Ihrer Punkte einen 1000-Meter-Ansatz erstellen? Konvertieren Sie dann das EPSG: 4326 in Ihr anderes Koordinatensystem? Der Vorteil der Projektion des Punktes besteht darin, dass Sie sich mit EPSG: 4326 keine Gedanken über die Krümmung der Erde machen müssen.
quelle