2013-08-25 28 views
12

D3'ün jeo modülleri etrafında çalışıyorum. D3 ile ilgili bazı deneyimlerim var ama bu benim ilk kez jeo modülleri deniyorum. Başlangıçta ABD haritası (https://github.com/alignedleft/d3-book/edit/master/chapter_12/us-states.json) düzenleme Albers(dosyaları artık https://github.com/alignedleft/d3-book/releases/tag/v1.0 zip indirilebilir bulunabilir) projeksiyon görüntüler (https://github.com/alignedleft/d3-book/blob/master/chapter_12/04_fill.html itibaren) Aşağıdaki kodu alınır ve bir GeoJSON Hindistan (indiastates1 almaya değiştirdiniz. aşağıda json). Kod ABD dosyasıyla iyi çalışır, ancak Hindistan json dosyasıyla hiçbir şey göstermez. Burada bir şey eksik. Herhangi bir yardım takdir edilir. Projeksiyonunu mercator olarak değiştirdim.Harita d3.js ve geojson kullanarak görüntüleniyor

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <meta charset="utf-8"> 
     <title>D3: Setting path fills</title> 
     <script type="text/javascript" src="../d3/d3.v3.js"></script> 
     <style type="text/css"> 
      /* No style rules here yet */  
     </style> 
    </head> 
    <body> 
     <script type="text/javascript"> 

      //Width and height 
      var w = 500; 
      var h = 300; 

      //Define map projection 
      var projection = d3.geo.mercator() 
            .translate([w/2, h/2]) 
            .scale([500]); 

      //Define path generator 
      var path = d3.geo.path() 
          .projection(projection); 

      //Create SVG element 
      var svg = d3.select("body") 
         .append("svg") 
         .attr("width", w) 
         .attr("height", h); 

      //Load in GeoJSON data 
      d3.json("indiastates1.json", function(json) { 

       //Bind data and create one path per GeoJSON feature 
       svg.selectAll("path") 
        .data(json.features) 
        .enter() 
        .append("path") 
        .attr("d", path) 
        .style("fill", "steelblue"); 

      }); 

     </script> 
    </body> 
</html> 

indiastates1.json

{"type":"FeatureCollection","features":[ 
{"type":"Feature","id":"IND","properties":{"name":"India"},"geometry":{"type":"Polygon","coordinates":[[[77.837451,35.49401],[78.912269,34.321936],[78.811086,33.506198],[79.208892,32.994395],[79.176129,32.48378],[78.458446,32.618164],[78.738894,31.515906],[79.721367,30.882715],[81.111256,30.183481],[80.476721,29.729865],[80.088425,28.79447],[81.057203,28.416095],[81.999987,27.925479],[83.304249,27.364506],[84.675018,27.234901],[85.251779,26.726198],[86.024393,26.630985],[87.227472,26.397898],[88.060238,26.414615],[88.174804,26.810405],[88.043133,27.445819],[88.120441,27.876542],[88.730326,28.086865],[88.814248,27.299316],[88.835643,27.098966],[89.744528,26.719403],[90.373275,26.875724],[91.217513,26.808648],[92.033484,26.83831],[92.103712,27.452614],[91.696657,27.771742],[92.503119,27.896876],[93.413348,28.640629],[94.56599,29.277438],[95.404802,29.031717],[96.117679,29.452802],[96.586591,28.83098],[96.248833,28.411031],[97.327114,28.261583],[97.402561,27.882536],[97.051989,27.699059],[97.133999,27.083774],[96.419366,27.264589],[95.124768,26.573572],[95.155153,26.001307],[94.603249,25.162495],[94.552658,24.675238],[94.106742,23.850741],[93.325188,24.078556],[93.286327,23.043658],[93.060294,22.703111],[93.166128,22.27846],[92.672721,22.041239],[92.146035,23.627499],[91.869928,23.624346],[91.706475,22.985264],[91.158963,23.503527],[91.46773,24.072639],[91.915093,24.130414],[92.376202,24.976693],[91.799596,25.147432],[90.872211,25.132601],[89.920693,25.26975],[89.832481,25.965082],[89.355094,26.014407],[88.563049,26.446526],[88.209789,25.768066],[88.931554,25.238692],[88.306373,24.866079],[88.084422,24.501657],[88.69994,24.233715],[88.52977,23.631142],[88.876312,22.879146],[89.031961,22.055708],[88.888766,21.690588],[88.208497,21.703172],[86.975704,21.495562],[87.033169,20.743308],[86.499351,20.151638],[85.060266,19.478579],[83.941006,18.30201],[83.189217,17.671221],[82.192792,17.016636],[82.191242,16.556664],[81.692719,16.310219],[80.791999,15.951972],[80.324896,15.899185],[80.025069,15.136415],[80.233274,13.835771],[80.286294,13.006261],[79.862547,12.056215],[79.857999,10.357275],[79.340512,10.308854],[78.885345,9.546136],[79.18972,9.216544],[78.277941,8.933047],[77.941165,8.252959],[77.539898,7.965535],[76.592979,8.899276],[76.130061,10.29963],[75.746467,11.308251],[75.396101,11.781245],[74.864816,12.741936],[74.616717,13.992583],[74.443859,14.617222],[73.534199,15.990652],[73.119909,17.92857],[72.820909,19.208234],[72.824475,20.419503],[72.630533,21.356009],[71.175273,20.757441],[70.470459,20.877331],[69.16413,22.089298],[69.644928,22.450775],[69.349597,22.84318],[68.176645,23.691965],[68.842599,24.359134],[71.04324,24.356524],[70.844699,25.215102],[70.282873,25.722229],[70.168927,26.491872],[69.514393,26.940966],[70.616496,27.989196],[71.777666,27.91318],[72.823752,28.961592],[73.450638,29.976413],[74.42138,30.979815],[74.405929,31.692639],[75.258642,32.271105],[74.451559,32.7649],[74.104294,33.441473],[73.749948,34.317699],[74.240203,34.748887],[75.757061,34.504923],[76.871722,34.653544],[77.837451,35.49401]]]}} 
]} 

cevap

10

Sen (veya tarayıcı) sadece yanlış yerde arıyor. Bence d3 bu geo projeksiyonları ile ABD'yi otomatik olarak merkezliyor. Yapmanız gereken tek şey, 'India' öğesini svg viewport'a taşımak için dönüşüm kullanmaktır. Özellikle, görünüm portunun kaynağını x, y piksellerinde koordinatlarla belirtilen bir konuma çevirmeniz gerekir - ya da en azından benim düşündüğüm şekilde. Hindistan görmek için ben

.attr("transform", "translate(-800,200)") 

çalıştı ve işi yapmak gibiydi.

Öğeyi incelerseniz, bu şeyleri seçmek oldukça kolaydır; daha sonra, dönüştürülecek bazı ipuçları vermek için yolu kullanabilirsiniz.

GÜNCELLEME

çok daha iyi bir yaklaşım, bu sorunun bu question and answer özetlendiği gibi merkezi ve böyle ölçeğini hesaplamak olacaktır olmaktır. Özellikle Jan ve Mike'ın cevabı mükemmel. Ayrıca, bu son google groups discussion kodundaki bir son açıklama da vardır.

+0

Çok teşekkürler. Anladım. Ben de krom gibi konsollarda benzer çizgilerden şüpheleniyorum, çünkü konsol herhangi bir hata atmadı ve svg öğeleri üzerinde cld edince, tarayıcıda bir yere vurgulamak gibi görünüyor ama nerede bilmiyordum! Bu yüzden yerini değiştirmek için doğru dönüşümü bulmak meselesiydi. Dönüşüm için doğru numaraları bulmakta deneme yanılma yaptınız mı? –

+1

Yol (yani, bit = bit, M150.158 128.215, 486.1589Z'ye gider) size nerede gösterildiğini söyler. Bu örnekte, rakamlar yolun 150 olduğunu gösteriyor, örneğinizde ilk sayı yaklaşık 900'dü, bu yüzden ben sadece 800'ü gördük ve denetçi sadece üst tarafa gösterdi Ekranın Daha eksiksiz bir cevap için [this] deneyin (http://stackoverflow.com/questions/14492284/center-a-map-in-d3-given-a-geojson-object) – user1614080

0

Bu sorun, ABD haritasının ABD'yi ortalayacak şekilde konumlandırılmasından kaynaklanmaktadır. Büyük olasılıkla Hindistan dosyasını yüklediniz, ancak ekranın dışında olabilir veya görmesi çok küçük olabilir. Ölçek ve merkez değerlerini değiştirerek ve çevirerek düzeltmeyi manuel olarak yapabilirsiniz. ama daha iyi bir yaklaşım otomatik kod

var b = path.bounds(#data#), 
       s = .95/Math.max((b[1][0] - b[0][0])/width, (b[1][1] - b[0][1])/height), 
       //scaled the bounding box 
       t = [(width - s * (b[1][0] + b[0][0]))/2, (height - s * (b[1][1] + b[0][1]))/2]; 
// new projection 
       projection = d3.geo.mercator() 
          .scale(s).translate(t); 
       path = path.projection(projection); 
2

Bu özellik koleksiyonunda özellikleri (sadece bir veya tüm etrafında harita projeksiyonunu ortalamak nasıl gösteren basit bir örnek olduğu gelen ölçek ve çevirisini bulmaktır varsayılan), sadece bir özellikte yakınlaştırma özelliğine sahip linked Mike Bostock answer'u temel alır ve ayrıca tüm özellik koleksiyonlarının kullanılabileceğini gösteren d3.js geoJSON and bounds.

Kodunuza anahtar değişiklikler

şunlardır:

  • nötr biriyle ilk tercüme ve ölçek değiştirme:

    var projection = d3.geo.mercator() 
         .scale(1) 
         .translate([0, 0]); 
    
  • json yükledikten sonra, dinamik projeksiyon güncelleştirmek için kod ekleyerek sınırlayıcı kutusuna, tüm özellik koleksiyonu:

    var b = path.bounds(json), 
        s = .95/Math.max((b[1][0] - b[0][0])/w, (b[1][1] - b[0][1])/h), 
        t = [(w - s * (b[1][0] + b[0][0]))/2, (h - s * (b[1][1] + b[0][1]))/2]; 
    
        projection 
         .scale(s) 
         .translate(t); 
    

Yani güncellenen tam bir örnek şu şekilde görünecektir:

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <meta charset="utf-8"> 
     <title>D3: Setting path fills</title> 
     <script type="text/javascript" src="../d3/d3.v3.js"></script> 
     <style type="text/css"> 
      /* No style rules here yet */  
     </style> 
    </head> 
    <body> 
     <script type="text/javascript"> 

      //Width and height 
      var w = 500; 
      var h = 300; 

      //Define map projection 
      var projection = d3.geo.mercator() 
            .translate([0, 0]) 
            .scale(1); 

      //Define path generator 
      var path = d3.geo.path() 
          .projection(projection); 

      //Create SVG element 
      var svg = d3.select("body") 
         .append("svg") 
         .attr("width", w) 
         .attr("height", h); 

      //Load in GeoJSON data 
      d3.json("indiastates1.json", function(json) { 

       // Calculate bounding box transforms for entire collection 
       var b = path.bounds(json), 
       s = .95/Math.max((b[1][0] - b[0][0])/w, (b[1][1] - b[0][1])/h), 
       t = [(w - s * (b[1][0] + b[0][0]))/2, (h - s * (b[1][1] + b[0][1]))/2]; 

       // Update the projection  
       projection 
        .scale(s) 
        .translate(t); 


       //Bind data and create one path per GeoJSON feature 
       svg.selectAll("path") 
        .data(json.features) 
        .enter() 
        .append("path") 
        .attr("d", path) 
        .style("fill", "steelblue"); 

      }); 

     </script> 
    </body> 
</html>