Bu, hesaplanan değerin (enlem, boylam, merkezi azimut, belirsizlik ve mesafe temelinde) bir sayı yerine papyon şekli olduğu bir tür "alan hesaplaması" gerektirir. Bu tür alan hesaplama yetenekleri ArcView 3.x'ten ArcGIS 8.x'e geçişte çok daha zor hale getirildiğinden ve hiçbir zaman tam olarak geri yüklenmediğinden, günümüzde Python, R'de veya bunun yerine her durumda komut dosyası kullanıyoruz: ancak düşünce süreci hala aynı.
Çalışma R
koduyla açıklayacağım . Özünde, bir işlev olarak kapsadığımız bir papyon şeklinin hesaplanması var. İşlev gerçekten çok basittir: yayın ucunda iki yay oluşturmak için, düzenli aralıklarla (azimut) bir dizi izlemesi gerekir. Bu, bir noktanın başlangıç (lon, lat) ve kat edilen mesafeye göre (lon, lat) koordinatlarını bulma yeteneğini gerektirir. Bu goto
, tüm ağır aritmetik kaldırmanın gerçekleştiği alt rutin ile yapılır . Gerisi sadece her şeyi uygulamak goto
ve sonra uygulamaktır.
bowtie <- function(azimuth, delta, origin=c(0,0), radius=1, eps=1) {
#
# On entry:
# azimuth and delta are in degrees.
# azimuth is east of north; delta should be positive.
# origin is (lon, lat) in degrees.
# radius is in meters.
# eps is in degrees: it is the angular spacing between vertices.
#
# On exit:
# returns an n by 2 array of (lon, lat) coordinates describing a "bowtie" shape.
#
# NB: we work in radians throughout, making conversions from and to degrees at the
# entry and exit.
#--------------------------------------------------------------------------------#
if (eps <= 0) stop("eps must be positive")
if (delta <= 0) stop ("delta must be positive")
if (delta > 90) stop ("delta must be between 0 and 90")
if (delta >= eps * 10^4) stop("eps is too small compared to delta")
if (origin[2] > 90 || origin[2] < -90) stop("origin must be in lon-lat")
a <- azimuth * pi/180; da <- delta * pi/180; de <- eps * pi/180
start <- origin * pi/180
#
# Precompute values for `goto`.
#
lon <- start[1]; lat <- start[2]
lat.c <- cos(lat); lat.s <- sin(lat)
radius.radians <- radius/6366710
radius.c <- cos(radius.radians); radius.s <- sin(radius.radians) * lat.c
#
# Find the point at a distance of `radius` from the origin at a bearing of theta.
# http://williams.best.vwh.net/avform.htm#Math
#
goto <- function(theta) {
lat1 <- asin(lat1.s <- lat.s * radius.c + radius.s * cos(theta))
dlon <- atan2(-sin(theta) * radius.s, radius.c - lat.s * lat1.s)
lon1 <- lon - dlon + pi %% (2*pi) - pi
c(lon1, lat1)
}
#
# Compute the perimeter vertices.
#
n.vertices <- ceiling(2*da/de)
bearings <- seq(from=a-da, to=a+da, length.out=n.vertices)
t(cbind(start,
sapply(bearings, goto),
start,
sapply(rev(bearings+pi), goto),
start) * 180/pi)
}
Bu, kayıtlarının zaten bir biçimde olması gereken bir tabloya uygulanması amaçlanmıştır: her biri konum, azimut, belirsizlik (her iki tarafa bir açı olarak) ve (isteğe bağlı olarak) papyon. Kuzey yarımkürenin her yerinde 1.000 bowties yerleştirerek böyle bir tabloyu simüle edelim:
n <- 1000
input <- data.frame(cbind(
id = 1:n,
lon = runif(n, -180, 180),
lat = asin(runif(n)) * 180/pi,
azimuth = runif(n, 0, 360),
delta = 90 * rbeta(n, 20, 70),
radius = 10^7/90 * rgamma(n, 10, scale=2/10)
))
Bu noktada, işler neredeyse herhangi bir alan hesaplaması kadar basittir. İşte burada:
shapes <- as.data.frame(do.call(rbind,
by(input, input$id,
function(d) cbind(d$id, bowtie(d$azimuth, d$delta, c(d$lon, d$lat), d$radius, 1)))))
(Zamanlama testleri R
saniyede yaklaşık 25.000 köşe noktası oluşturabildiğini gösterir . Varsayılan olarak, her azimut derecesi için bir eps
argüman vardır; bu, ile argüman üzerinden kullanıcı tarafından ayarlanabilir bowtie
.)
R
Bir kontrol olarak sonuçların kendi içinde basit bir çizim yapabilirsiniz :
colnames(shapes) <- c("id", "x", "y")
plot(shapes$x, shapes$y, type="n", xlab="Longitude", ylab="Latitude", main="Bowties")
temp <- by(shapes, shapes$id, function(d) lines(d$x, d$y, type="l", lwd=2, col=d$id))
Bir CBS'ye içe aktarmak üzere şekil dosyası çıktısı oluşturmak için shapefiles
paketi kullanın :
require(shapefiles)
write.shapefile(convert.to.shapefile(shapes, input, "id", 5), "f:/temp/bowties", arcgis=T)
Şimdi sonuçları vb. Yansıtabilirsiniz. Bu örnekte kuzey yarımkürenin stereografik bir izdüşümü kullanılmaktadır ve papyonlar belirsizlik miktarları ile renklendirilmiştir. (180 / -180 derece boylamına çok dikkatli bakarsanız, bu CBS'nin bu çizgiyi geçen papyonları nerede kırptığını göreceksiniz. Bu CBS ile ortak bir kusurdur; R
kodun kendisinde bir hata yansıtmaz .)