1km วงกลมรอบจุด lat-long- ในหลายสถานที่ในโลก


11

ฉันมีคะแนน lat-long-points หลายร้อยจุดกระจายอยู่ทั่วโลกและต้องสร้างวงกลมรูปหลายเหลี่ยมรอบแต่ละจุดด้วยรัศมี 1,000 เมตร ฉันเข้าใจว่าจุดต่าง ๆ จะต้องถูกฉายจากองศา (ความยาว lat) เป็นบางสิ่งบางอย่างด้วยหน่วยเมตร แต่จะทำอย่างไรได้โดยไม่ต้องค้นหาด้วยตนเองและกำหนดเขต UTM สำหรับแต่ละจุด

นี่คือความกังวลสำหรับจุดแรกในฟินแลนด์

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"))

แต่ด้วยจุดที่สอง (แคนาดา) มันไม่ทำงาน (เพราะผิดโซน UTM)

the.points.projected <- spTransform(the.points.sp[2, ], CRS( "+init=epsg:32635" ))

วิธีนี้สามารถทำได้โดยไม่ต้องรับด้วยตนเองและระบุจุดโซน UTM ต่อจุด? ฉันไม่มีข้อมูลต่อจุดมากกว่าความยาว lat

ปรับปรุง:

การใช้และการรวมคำตอบที่ยอดเยี่ยมจากทั้ง AndreJ และ Mike T นี่คือรหัสสำหรับทั้งเวอร์ชันและพล็อต พวกเขาต่างกันในทศนิยมลำดับที่ 4 หรือมากกว่านั้น แต่ทั้งสองคำตอบที่ดีมาก!

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

(ไม่แน่ใจว่าจะนำพล็อตเข้าสู่การอัพเดทได้อย่างไร)


1
ทางออกที่เป็นไปได้ในส่วนการค้นหาด้วยตนเอง: จะเกิดอะไรขึ้นถ้าคุณได้รับกริด UTM Zone และตัดกันด้วยคะแนนของคุณเพื่อให้คุณเพิ่มโซนที่เหมาะสมเป็นแอตทริบิวต์ แอตทริบิวต์อาจเป็นชื่อโซนหรือรหัส EPSG แต่สิ่งที่สามารถป้อนเข้าเป็นตัวแปรเพื่อเลือก CRS ที่เหมาะสมสำหรับแต่ละจุดโดยอัตโนมัติ
Chris W

1
ฉันมีปัญหากับ "ขนาด 1,000m" และวลี "circle-polygons" วงกลมรูปหลายเหลี่ยมของคุณต้องการกลุ่มที่ไม่มีที่สิ้นสุดซึ่งอยู่ห่างกัน 1,000 เมตรและการแปลงเป็น UTM (หรือระบบระนาบอื่น ๆ ) จะแนะนำข้อผิดพลาดให้มากขึ้น ระวังด้วยการใช้ "แน่นอน"
Spacedman

ใช่ฉันไม่ควรแสดงมันต่างออกไป ฉันหมายถึงว่า 1100m หรือ 900m จะปิดเกินไปและนั่นประมาณ 20 เซ็กเมนต์ในวงกลมก็โอเค
Chris

คำตอบ:


9

คล้ายกับ @AndreJ แต่ใช้การประมาณการแบบgnomicแบบไดนามิกฉันหมายถึงการฉายภาพแบบอะซิมุ ธ ที่มีระยะเวลาเท่ากันแบบไดนามิกเพื่อความแม่นยำยิ่งขึ้น การฉายภาพ AEQ ที่มีศูนย์กลางอยู่ที่แต่ละจุดจะคาดการณ์ระยะทางเท่ากันในทุกทิศทางเช่นวงกลมบัฟเฟอร์ (เครื่องฉายภาพ Mercator จะมีการบิดเบือนในทิศเหนือและทิศตะวันออกเนื่องจากมันล้อมรอบด้านข้างของทรงกระบอก)

ดังนั้นสำหรับจุดแรกของคุณรอบ ๆ ฟินแลนด์สตริง PROJ.4 จะมีลักษณะดังนี้:

+proj=aeqd +lat_0=63.293001 +lon_0=27.472918 +x_0=0 +y_0=0

ดังนั้นคุณสามารถสร้างฟังก์ชั่น R เพื่อสร้างการฉายแบบไดนามิกนี้:

aeqd.buffer <- function(p, r)
{
    stopifnot(length(p) == 1)
    aeqd <- sprintf("+proj=aeqd +lat_0=%s +lon_0=%s +x_0=0 +y_0=0",
                    p@coords[[2]], p@coords[[1]])
    projected <- spTransform(p, CRS(aeqd))
    buffered <- gBuffer(projected, width=r, byid=TRUE)
    spTransform(buffered, p@proj4string)
}

จากนั้นทำสิ่งนี้สำหรับแคนาดา (รายการ 2):

aeqd.buffer(the.points.sp[2,], 1000)

1
จากหน้าวิกิพีเดีย: "ไม่มีการบิดเบือนเกิดขึ้นที่จุดสัมผัส แต่การบิดเบือนเพิ่มขึ้นอย่างรวดเร็วจากมัน" คุณได้ทำการคำนวณออฟเซ็ตตัวอย่างหรือยัง บางทีen.wikipedia.org/wiki/Azimuthal_equidistant_projectอาจเหมาะสมกว่า
AndreJ

2
การฉายภาพใด ๆที่มีมาตราส่วนที่ถูกต้องที่จุดกำเนิดของวงกลมและสอดคล้องกันจะทำได้ดีเพียงเพราะ 1,000 ม. มีขนาดเล็กมาก อย่างไรก็ตามสำหรับรัศมีที่มีขนาดใหญ่กว่านั้นการคาดการณ์ของ Gnomonic จะไม่ดี คุณอาจต้องการกำหนดระยะฉายภาพระยะเท่ากัน
whuber

2
ข้อเสนอแนะที่ยอดเยี่ยมการคาดการณ์ AEQ นั้นเห็นได้ชัดว่าทำงานได้ดีขึ้นมากสำหรับเทคนิคนี้ดังนั้นฉันจึงเลิกใช้ gnomic AEQP จะยังคงรักษาระยะทางที่ไกลกว่ามากเช่นในระยะ 10,000+ กม.
Mike T

1
ฉันอาจจะเข้าใจผิดรหัส แต่คุณจะต้องสร้างรูปหลายเหลี่ยมบัฟเฟอร์หนึ่งครั้งในการฉาย AEQD ใด ๆ (ศูนย์อยู่เสมอศูนย์, min coord อยู่เสมอ -1k, สูงสุดอยู่เสมอ + 1k จากนั้น unproject ให้ lat / lon โดยใช้ AEQD มีศูนย์กลางอยู่ที่แต่ละจุดที่คุณต้องได้รับค่า lat / lon ...
mkennedy

2
@mkennedy คุณมีจุดดี projectedแน่นอนเสมอที่ (0, 0) และbufferedมีคะแนน± 1,000 m ในx - และy -directions หากจำเป็นอย่างยิ่งที่จะต้องปรับปรุงให้ดีที่สุดให้ทำการแปลงบัฟเฟอร์คาร์ทีเซียนแบบง่าย ๆ จากไดนามิก AEQD เป็น WGS84
Mike T

4

แทนที่จะค้นหาโซน UTM ที่ถูกต้องคุณสามารถสร้างการฉายภาพตามขวางแบบกำหนดเองสำหรับทุกๆจุดด้วย

+proj=tmerc +lat_0=.... +lon_0=... +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs

วาดวงกลมในเส้นโครงนั้น พิกัดจุดสุดยอดของวงกลมที่คาดการณ์จะเหมือนกันเสมอดังนั้นคุณต้องสร้างเพียงครั้งเดียว สำหรับสิ่งต่อไปนี้เพียงแค่กำหนด CRS ที่กำหนดเองใหม่ให้กับพวกเขา

Reproject วงกลมเป็น EPSG: 4326 เพื่อใช้งานต่อไป

ภายในระยะ 1,000 เมตรวงกลมจะเกือบแน่นอน ถ้าไม่ได้ (หรือวงกลมขนาดใหญ่) ให้ใช้แทนaeqdtmerc


0

จะทำอย่างไรถ้าคุณใช้วิธีสร้าง 1,000 เมตรใน EPSG: 4326 รอบ ๆ แต่ละจุดของคุณ ถ้าต้องการแปลง EPSG: 4326 เป็นระบบพิกัดอื่น ๆ ข้อดีของการฉายจุดคือคุณไม่ต้องกังวลกับความโค้งของโลกด้วย EPSG: 4326


1
คุณจะสร้างบัฟเฟอร์ 1,000 ม. จาก EPSG ได้อย่างไร: 4326 ซึ่งมีหน่วยความยาวเป็นองศา
Mike T

วิธีหนึ่งที่ฉันจะทำเช่นนี้คือการสร้างบัฟเฟอร์ 1,000 เมตรใน EPSG: 32635 แปลงเป็น EPSG: 4326 และตอนนี้คุณจะมีหมายเลขที่คุณต้องการ
เกร็ก

1
นั่นเป็นวิธีการเดียวกันที่อธิบายไว้ในคำถามพร้อมกับข้อ จำกัด ของเทคนิคนี้
Mike T
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.