2014-05-12 24 views
8

Tôi đang cố gắng vẽ chuyển động của một thực thể trên bản đồ google dưới dạng một tập hợp các đường được chỉ dẫn sử dụng ggmap. Hiện tại tôi đang sử dụng cuộc gọi geom_segment từ ggplot2 để vẽ các đoạn đường. Tuy nhiên, nơi có các chu kỳ trong chuyển động chẳng hạn như 1->2->1 các đường chồng lên nhau. Điều này làm cho khó hơn để tìm ra chuyển động từ hình ảnh hóa.Vẽ các đường cong giữa các điểm trong ggmap

Có cách nào để vẽ đường cong các đoạn đường để xử lý việc này không? Hoặc có bất kỳ phương pháp hay thư viện nào khác mà tôi có thể thử không?

+2

Có một số ý tưởng [ở đây] (http://stackoverflow.com/questions/20216179/plot-curved-lines-between-two-locations-in-ggplot2?rq=1) và [tại đây] (http: // là -r.tumblr.com/post/38459242505/beautiful-network-diagrams-with-ggplot2) có thể giúp ... – mmk

+0

Cảm ơn @mmk Tôi đã thử liên kết đầu tiên. tiếc là cách tiếp cận đó chỉ hoạt động với các giá trị Descartes và tôi đang đối phó với kinh độ và vĩ độ. Liên kết thứ 2 có vẻ đầy hứa hẹn. sẽ thử nó ra – Danaja

+1

Vui lòng cung cấp một ví dụ tái sản xuất tối thiểu để đi cùng với câu hỏi của bạn. –

Trả lời

1

Tôi nghĩ rằng những gì bạn đang tìm kiếm là các đường cong 'Bezier' (kiểm tra wikipedia để được giải thích kỹ lưỡng về chủ đề https://en.wikipedia.org/wiki/Bézier_curve). Trong R, điều này được thực hiện sử dụng một số gói khác nhau hoặc bạn có thể tạo riêng của bạn như sau:

#Load dependencies 
library(ggplot2) 
library(maptools) 
library(geosphere) 

#Identify countries of interest and their centroids (see https://www.cia.gov/library/publications/the-world-factbook/fields/2011.html) 
countries <- data.frame(
    Country=c("United States", "Iran"), 
    ISO3=c("USA","IRN"), 
    latitude=c(38,32), 
    longitude=c(-97,53), 
    stringsAsFactors=FALSE) 

#Get world map 
data(wrld_simpl) 
map.data <- fortify(wrld_simpl) 

#Set up map 
draw.map <- function(ylim=c(0,85)) { 
    ggplot(map.data, aes(x=long, y=lat, group=group)) + 
    geom_polygon(fill="grey") + 
    geom_path(size=0.1,color="white") + 
    coord_map("mercator", ylim=c(-60,120), xlim=c(-180,180)) + 
    theme(line = element_blank(), 
      text = element_blank()) 
} 

#Identify the points of the curve 
p1 <- c(countries$longitude[1], 
     countries$latitude[1]) 
p2 <- c(countries$longitude[2], 
     countries$latitude[2]) 

#Create function to draw Brezier curve 
bezier.curve <- function(p1, p2, p3) { 
    n <- seq(0,1,length.out=50) 
    bx <- (1-n)^2 * p1[[1]] + 
    (1-n) * n * 2 * p3[[1]] + 
    n^2 * p2[[1]] 
    by <- (1-n)^2 * p1[[2]] + 
    (1-n) * n * 2 * p3[[2]] + 
    n^2 * p2[[2]] 
    data.frame(lon=bx, lat=by) 
} 

bezier.arc <- function(p1, p2) { 
    intercept.long <- (p1[[1]] + p2[[1]])/2 
    intercept.lat <- 85 
    p3 <- c(intercept.long, intercept.lat) 
    bezier.curve(p1, p2, p3) 
} 

arc3 <- bezier.arc(p1,p2) 

bezier.uv.arc <- function(p1, p2) { 
    # Get unit vector from P1 to P2 
    u <- p2 - p1 
    u <- u/sqrt(sum(u*u)) 
    d <- sqrt(sum((p1-p2)^2)) 
    # Calculate third point for spline 
    m <- d/2 
    h <- floor(d * .2) 
    # Create new points in rotated space 
    pp1 <- c(0,0) 
    pp2 <- c(d,0) 
    pp3 <- c(m, h) 
    mx <- as.matrix(bezier.curve(pp1, pp2, pp3)) 
    # Now translate back to original coordinate space 
    theta <- acos(sum(u * c(1,0))) * sign(u[2]) 
    ct <- cos(theta) 
    st <- sin(theta) 
    tr <- matrix(c(ct, -1 * st, st, ct),ncol=2) 
    tt <- matrix(rep(p1,nrow(mx)),ncol=2,byrow=TRUE) 
    points <- tt + (mx %*% tr) 
    tmp.df <- data.frame(points) 
    colnames(tmp.df) <- c("lon","lat") 
    tmp.df 
} 

arc4 <- bezier.uv.arc(p1,p2) 

bezier.uv.merc.arc <- function(p1, p2) { 
    pp1 <- p1 
    pp2 <- p2 
    pp1[2] <- asinh(tan(p1[2]/180 * pi))/pi * 180 
    pp2[2] <- asinh(tan(p2[2]/180 * pi))/pi * 180 

    arc <- bezier.uv.arc(pp1,pp2) 
    arc$lat <- atan(sinh(arc$lat/180 * pi))/pi * 180 
    arc 
} 


arc5 <- bezier.uv.merc.arc(p1, p2) 
d <- data.frame(lat=c(32,38), 
       lon=c(53,-97)) 
draw.map() + 
    geom_path(data=as.data.frame(arc5), 
      aes(x=lon, y=lat, group=NULL)) + 
    geom_line(data=d, aes(x=lon, y=lat, group=NULL), 
      color="black", size=0.5) 

enter image description here

Xem thêm http://dsgeek.com/2013/06/08/DrawingArcsonMaps.html cho một lời giải thích kỹ hơn về đường cong Bezier sử dụng ggplot2

Các vấn đề liên quan