2013-06-11 21 views
7

Tôi muốn làm một chuyển đổi suôn sẻ giữa Alber/chính tả trong một ứng dụng nhỏ Tôi đang xây dựng, giống như ví dụ sau:Làm thế nào để làm chuyển đổi suôn sẻ cho chiếu lại bản đồ trong d3 js

http://mbostock.github.io/d3/talk/20111018/#27

Nó có vẻ như chuyển đổi suôn sẻ này bị phá vỡ trong v3 tuy nhiên, với một sự chuyển tiếp khá choppy của các đường dẫn bản đồ:

https://www.evernote.com/shard/s236/sh/46b002bd-9c5b-4e9b-87ef-270c303eb677/2eaeebb267a3fc59df5a8447bbbcc58b/res/37917835-5aad-4509-b534-31a3e3034762/Worst_Tornado_Outbreaks_of_All_Time-20130611-074050.jpg.jpg?resizeSmall&width=832

Mã là khá thẳng về phía trước, tôi khởi tạo bản đồ như Albers, sau đó chạy ortho() để cập nhật nó.

function ortho() { 
    var self = this, 
    h = 1000, 
    w = document.width; 

    this.projection = d3.geo.orthographic() 
    .scale(500) 
    .translate([ (w - 300)/2, h/2]) 
    .clipAngle(90) 
    .rotate([90, 0, 0]) 
    .precision(.1); 

    this.path = d3.geo.path() 
    .projection(this.projection); 

    //update path WITH transition 
    d3.selectAll('path') 
    .transition() 
    .duration(900) 
    .attr('d', app.path); 

} 

Bản đồ thay đổi từ albers thành orthographic, nhưng quá trình chuyển đổi không được mịn. Bất kỳ suy nghĩ nào cũng tuyệt vời.

Trả lời

17

Nếu bạn suy path bằng chuỗi xen ngây thơ D3 của (d3.interpolateString), sau đó số lượng tọa độ trong đường dẫn bắt đầu và số lượng của các tọa độ trong đường dẫn kết thúc phải phù hợp chính xác, kể cả trong cùng một thứ tự. Nhưng điều này gần như không bao giờ xảy ra do clipping, cuttingresampling. Shape interpolation là có thể (sử dụng multiplestrategies), nhưng đó là một vấn đề khó giải quyết trong trường hợp chung. Xem this explanation (một phần của số Path Transitions) vì sao nội suy ngây thơ không đủ.

Thay vì nội suy đường dẫn, bạn muốn nội suy phép chiếu. Nội suy phép chiếu không yêu cầu sự tương ứng chính xác giữa các tọa độ và do đó tránh các hiện vật nội suy. Xem các ví dụ cho một cuộc biểu tình:

Như trong ví dụ đầu tiên, đây là một thực hiện, bạn có thể sử dụng:

function interpolatedProjection(a, b) { 
    var projection = d3.geo.projection(raw).scale(1), 
     center = projection.center, 
     translate = projection.translate, 
     α; 

    function raw(λ, φ) { 
    var pa = a([λ *= 180/Math.PI, φ *= 180/Math.PI]), pb = b([λ, φ]); 
    return [(1 - α) * pa[0] + α * pb[0], (α - 1) * pa[1] - α * pb[1]]; 
    } 

    projection.alpha = function(_) { 
    if (!arguments.length) return α; 
    α = +_; 
    var ca = a.center(), cb = b.center(), 
     ta = a.translate(), tb = b.translate(); 
    center([(1 - α) * ca[0] + α * cb[0], (1 - α) * ca[1] + α * cb[1]]); 
    translate([(1 - α) * ta[0] + α * tb[0], (1 - α) * ta[1] + α * tb[1]]); 
    return projection; 
    }; 

    delete projection.scale; 
    delete projection.translate; 
    delete projection.center; 
    return projection.alpha(0); 
} 

Tạo phép chiếu nội suy bằng tw o chiếu ab, rồi đặt alpha được nội suy thành giá trị từ 0 (cho a) và 1 (cho b).

+3

Có thể nội suy clipAngle theo cách này không? Không có ví dụ nào chứng minh điều này - Tôi đang cố chuyển từ orthographic/90 sang equirectangular/180 và có rất nhiều hiện vật lạ – Casey